// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// SPDX-License-Identifier: MPL-2.0

// This file is a base class plugin containing common coefficient wise functions.

#ifndef EIGEN_PARSED_BY_DOXYGEN

/** \internal the return type of conjugate() */
using ConjugateReturnType =
    std::conditional_t<NumTraits<Scalar>::IsComplex,
                       const CwiseUnaryOp<internal::scalar_conjugate_op<Scalar>, const Derived>, const Derived&>;
/** \internal the return type of real() const */
using RealReturnType =
    std::conditional_t<NumTraits<Scalar>::IsComplex,
                       const CwiseUnaryOp<internal::scalar_real_op<Scalar>, const Derived>, const Derived&>;
/** \internal the return type of real() */
using NonConstRealReturnType =
    std::conditional_t<NumTraits<Scalar>::IsComplex, CwiseUnaryView<internal::scalar_real_ref_op<Scalar>, Derived>,
                       Derived&>;
/** \internal the return type of imag() const */
using ImagReturnType = CwiseUnaryOp<internal::scalar_imag_op<Scalar>, const Derived>;
/** \internal the return type of imag(). The imaginary part of a real-valued object is identically zero and not an
 * lvalue, so for real scalars the non-const overload returns the same read-only zero expression as the const one
 * instead of a writable view (whose functor would return a dangling reference to a temporary; see issue #3096). */
using NonConstImagReturnType =
    std::conditional_t<NumTraits<Scalar>::IsComplex, CwiseUnaryView<internal::scalar_imag_ref_op<Scalar>, Derived>,
                       ImagReturnType>;

using NegativeReturnType = CwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const Derived>;

#endif  // not EIGEN_PARSED_BY_DOXYGEN

/// \returns an expression of the opposite of \c *this
///
EIGEN_DOC_UNARY_ADDONS(operator-, opposite)
///
EIGEN_DEVICE_FUNC constexpr inline const NegativeReturnType operator-() const { return NegativeReturnType(derived()); }

template <class NewType>
struct CastXpr {
  using Type = typename internal::cast_return_type<
      Derived, const CwiseUnaryOp<internal::core_cast_op<Scalar, NewType>, const Derived>>::type;
};

/// \returns an expression of \c *this with the \a Scalar type casted to
/// \a NewScalar.
///
/// The template parameter \a NewScalar is the type we are casting the scalars to.
///
EIGEN_DOC_UNARY_ADDONS(cast, conversion function)
///
/// \sa class CwiseUnaryOp
///
template <typename NewType>
EIGEN_DEVICE_FUNC constexpr typename CastXpr<NewType>::Type cast() const {
  return typename CastXpr<NewType>::Type(derived());
}

/// \returns an expression of the complex conjugate of \c *this.
///
EIGEN_DOC_UNARY_ADDONS(conjugate, complex conjugate)
///
/// \sa <a href="group__CoeffwiseMathFunctions.html#cwisetable_conj">Math functions</a>, MatrixBase::adjoint()
EIGEN_DEVICE_FUNC constexpr inline ConjugateReturnType conjugate() const { return ConjugateReturnType(derived()); }

/// \returns an expression of the complex conjugate of \c *this if Cond==true, returns derived() otherwise.
///
EIGEN_DOC_UNARY_ADDONS(conjugate, complex conjugate)
///
/// \sa conjugate()
template <bool Cond>
EIGEN_DEVICE_FUNC constexpr inline std::conditional_t<Cond, ConjugateReturnType, const Derived&> conjugateIf() const {
  typedef std::conditional_t<Cond, ConjugateReturnType, const Derived&> ReturnType;
  return ReturnType(derived());
}

/// \returns a read-only expression of the real part of \c *this.
///
EIGEN_DOC_UNARY_ADDONS(real, real part function)
///
/// \sa imag(), realView()
EIGEN_DEVICE_FUNC constexpr inline RealReturnType real() const { return RealReturnType(derived()); }

/// \returns a read-only expression of the imaginary part of \c *this.
///
EIGEN_DOC_UNARY_ADDONS(imag, imaginary part function)
///
/// \sa real(), realView()
EIGEN_DEVICE_FUNC constexpr inline const ImagReturnType imag() const { return ImagReturnType(derived()); }

/// \brief Apply a unary operator coefficient-wise
/// \param[in]  func  Functor implementing the unary operator
/// \tparam  CustomUnaryOp Type of \a func
/// \returns An expression of a custom coefficient-wise unary operator \a func of *this
///
/// A lambda can be used to adapt a normal function to the functor interface expected by this method.
///
/// Example:
/// \include class_CwiseUnaryOp_ptrfun.cpp
/// Output: \verbinclude class_CwiseUnaryOp_ptrfun.out
///
/// Genuine functors allow for more possibilities, for instance it may contain a state.
///
/// Example:
/// \include class_CwiseUnaryOp.cpp
/// Output: \verbinclude class_CwiseUnaryOp.out
///
EIGEN_DOC_UNARY_ADDONS(unaryExpr, unary function)
///
/// \sa unaryViewExpr, binaryExpr, class CwiseUnaryOp
///
template <typename CustomUnaryOp>
EIGEN_DEVICE_FUNC constexpr inline const CwiseUnaryOp<CustomUnaryOp, const Derived> unaryExpr(
    const CustomUnaryOp& func = CustomUnaryOp()) const {
  return CwiseUnaryOp<CustomUnaryOp, const Derived>(derived(), func);
}

/// \returns a const expression of a custom coefficient-wise unary operator \a func of *this
///
/// The template parameter \a CustomUnaryOp is the type of the functor
/// of the custom unary operator.
///
/// Example:
/// \include class_CwiseUnaryOp.cpp
/// Output: \verbinclude class_CwiseUnaryOp.out
///
EIGEN_DOC_UNARY_ADDONS(unaryViewExpr, unary function)
///
/// \sa unaryExpr, binaryExpr, class CwiseUnaryOp
///
template <typename CustomViewOp>
EIGEN_DEVICE_FUNC constexpr inline const CwiseUnaryView<CustomViewOp, const Derived> unaryViewExpr(
    const CustomViewOp& func = CustomViewOp()) const {
  return CwiseUnaryView<CustomViewOp, const Derived>(derived(), func);
}

/// \returns a non-const expression of a custom coefficient-wise unary view \a func of *this
///
/// The template parameter \a CustomUnaryOp is the type of the functor
/// of the custom unary operator.
///
EIGEN_DOC_UNARY_ADDONS(unaryViewExpr, unary function)
///
/// \sa unaryExpr, binaryExpr, class CwiseUnaryOp
///
template <typename CustomViewOp>
EIGEN_DEVICE_FUNC constexpr inline CwiseUnaryView<CustomViewOp, Derived> unaryViewExpr(
    const CustomViewOp& func = CustomViewOp()) {
  return CwiseUnaryView<CustomViewOp, Derived>(derived(), func);
}

/// \returns a non const expression of the real part of \c *this.
///
EIGEN_DOC_UNARY_ADDONS(real, real part function)
///
/// \sa imag(), realView()
EIGEN_DEVICE_FUNC constexpr inline NonConstRealReturnType real() { return NonConstRealReturnType(derived()); }

/// \returns a non const expression of the imaginary part of \c *this.
/// For real-valued objects the imaginary part is identically zero and not writable; this then returns the
/// same read-only zero expression as the const overload.
///
EIGEN_DOC_UNARY_ADDONS(imag, imaginary part function)
///
/// \sa real(), realView()
EIGEN_DEVICE_FUNC constexpr inline NonConstImagReturnType imag() { return NonConstImagReturnType(derived()); }
