// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008-2014 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

#ifndef EIGEN_CWISE_UNARY_OP_H
#define EIGEN_CWISE_UNARY_OP_H

// IWYU pragma: private
#include "./InternalHeaderCheck.h"

namespace Eigen {

namespace internal {
template <typename UnaryOp, typename XprType>
struct traits<CwiseUnaryOp<UnaryOp, XprType> > : traits<XprType> {
  using Scalar = typename result_of<UnaryOp(const typename XprType::Scalar&)>::type;
  using XprTypeNested = typename XprType::Nested;
  using XprTypeNested_ = std::remove_reference_t<XprTypeNested>;
  enum { Flags = XprTypeNested_::Flags & RowMajorBit };
};
}  // namespace internal

template <typename UnaryOp, typename XprType, typename StorageKind>
class CwiseUnaryOpImpl;

/** \class CwiseUnaryOp
 * \ingroup Core_Module
 *
 * \brief Generic expression where a coefficient-wise unary operator is applied to an expression
 *
 * \tparam UnaryOp template functor implementing the operator
 * \tparam XprType the type of the expression to which we are applying the unary operator
 *
 * This class represents an expression where a unary operator is applied to an expression.
 * It is the return type of coefficient-wise operations taking a single input expression, such as unary negation
 * or MatrixBase::unaryExpr(). Operators mixing an expression and a scalar, such as the operator* in the expression
 * 3*matrix, are binary: the scalar is nested as a CwiseNullaryOp, so the return type is a specialization of
 * CwiseBinaryOp. A scalar carried inside the functor does not make the expression binary; ArrayBase::pow(const
 * ScalarExponent&) stores its exponent in the functor and still returns a CwiseUnaryOp.
 *
 * Most of the time, this is the only way that it is used, so you typically don't have to name
 * CwiseUnaryOp types explicitly.
 *
 * \sa MatrixBase::unaryExpr(const CustomUnaryOp &) const, class CwiseBinaryOp, class CwiseNullaryOp
 */
template <typename UnaryOp, typename XprType>
class CwiseUnaryOp : public CwiseUnaryOpImpl<UnaryOp, XprType, typename internal::traits<XprType>::StorageKind>,
                     internal::no_assignment_operator {
 public:
  using Base = typename CwiseUnaryOpImpl<UnaryOp, XprType, typename internal::traits<XprType>::StorageKind>::Base;
  EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseUnaryOp)
  using XprTypeNested = typename internal::ref_selector<XprType>::type;
  using NestedExpression = internal::remove_all_t<XprType>;

  EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE explicit CwiseUnaryOp(const XprType& xpr,
                                                                        const UnaryOp& func = UnaryOp())
      : m_xpr(xpr), m_functor(func) {}

  EIGEN_DEVICE_FUNC constexpr Index rows() const noexcept { return m_xpr.rows(); }
  EIGEN_DEVICE_FUNC constexpr Index cols() const noexcept { return m_xpr.cols(); }

  /** \returns the functor representing the unary operation */
  EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE const UnaryOp& functor() const { return m_functor; }

  /** \returns the nested expression */
  EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE const internal::remove_all_t<XprTypeNested>& nestedExpression()
      const {
    return m_xpr;
  }

  /** \returns the nested expression */
  EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE internal::remove_all_t<XprTypeNested>& nestedExpression() {
    return m_xpr;
  }

 protected:
  XprTypeNested m_xpr;
  const UnaryOp m_functor;
};

// Generic API dispatcher
template <typename UnaryOp, typename XprType, typename StorageKind>
class CwiseUnaryOpImpl : public internal::generic_xpr_base<CwiseUnaryOp<UnaryOp, XprType> >::type {
 public:
  using Base = typename internal::generic_xpr_base<CwiseUnaryOp<UnaryOp, XprType>>::type;
};

}  // end namespace Eigen

#endif  // EIGEN_CWISE_UNARY_OP_H
