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

/** \returns an expression of the difference of \c *this and \a other
 *
 * \note Subtraction is not supported for \c bool coefficients. Cast to a signed integer type first.
 *
 * \note If you want to subtract a given scalar from all coefficients, see Cwise::operator-().
 *
 * \sa class CwiseBinaryOp, operator-=()
 */
EIGEN_MAKE_CWISE_BINARY_OP(operator-, internal::scalar_difference_op)

/** \returns an expression of the sum of \c *this and \a other
 *
 * \note If you want to add a given scalar to all coefficients, see Cwise::operator+().
 *
 * \sa class CwiseBinaryOp, operator+=()
 */
EIGEN_MAKE_CWISE_BINARY_OP(operator+, internal::scalar_sum_op)

/** \returns an expression of a custom coefficient-wise operator \a func of *this and \a other
 *
 * The template parameter \a CustomBinaryOp is the type of the functor
 * of the custom operator (see class CwiseBinaryOp for an example)
 *
 * Here is an example illustrating the use of custom functors:
 * \include class_CwiseBinaryOp.cpp
 * Output: \verbinclude class_CwiseBinaryOp.out
 *
 * \sa class CwiseBinaryOp, operator+(), operator-(), cwiseProduct()
 */
template <typename CustomBinaryOp, typename OtherDerived>
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE const CwiseBinaryOp<CustomBinaryOp, const Derived, const OtherDerived>
binaryExpr(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived>& other,
           const CustomBinaryOp& func = CustomBinaryOp()) const {
  return CwiseBinaryOp<CustomBinaryOp, const Derived, const OtherDerived>(derived(), other.derived(), func);
}

/** \returns an expression of \c *this scaled by the scalar factor \a scalar
 *
 * \tparam T is the scalar type of \a scalar. It must be compatible with the scalar type of the given expression.
 */
EIGEN_MAKE_SCALAR_BINARY_OP(operator*, internal::scalar_product_op)

/** \returns an expression of \c *this divided by the scalar value \a scalar
 *
 * \tparam T is the scalar type of \a scalar. It must be compatible with the scalar type of the given expression.
 */
EIGEN_MAKE_SCALAR_BINARY_OP_ONTHERIGHT(operator/, internal::scalar_quotient_op)

/** \returns an expression of the coefficient-wise boolean \b and operator of \c *this and \a other
 *
 * Example: \include Cwise_boolean_and.cpp
 * Output: \verbinclude Cwise_boolean_and.out
 *
 * \sa operator||(), select()
 */
template <typename OtherDerived>
EIGEN_DEVICE_FUNC constexpr inline const CwiseBinaryOp<internal::scalar_boolean_and_op<Scalar>, const Derived,
                                                       const OtherDerived>
operator&&(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived>& other) const {
  return CwiseBinaryOp<internal::scalar_boolean_and_op<Scalar>, const Derived, const OtherDerived>(derived(),
                                                                                                   other.derived());
}

/** \returns an expression of the coefficient-wise boolean \b or operator of \c *this and \a other
 *
 * Example: \include Cwise_boolean_or.cpp
 * Output: \verbinclude Cwise_boolean_or.out
 *
 * \sa operator&&(), select()
 */
template <typename OtherDerived>
EIGEN_DEVICE_FUNC constexpr inline const CwiseBinaryOp<internal::scalar_boolean_or_op<Scalar>, const Derived,
                                                       const OtherDerived>
operator||(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived>& other) const {
  return CwiseBinaryOp<internal::scalar_boolean_or_op<Scalar>, const Derived, const OtherDerived>(derived(),
                                                                                                  other.derived());
}

/** \returns an expression of the bitwise \b and operator of \c *this and \a other
 *
 * \sa operator|(), operator^()
 */
template <typename OtherDerived>
EIGEN_DEVICE_FUNC constexpr inline const CwiseBinaryOp<internal::scalar_bitwise_and_op<Scalar>, const Derived,
                                                       const OtherDerived>
operator&(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived>& other) const {
  return CwiseBinaryOp<internal::scalar_bitwise_and_op<Scalar>, const Derived, const OtherDerived>(derived(),
                                                                                                   other.derived());
}

/** \returns an expression of the bitwise \b or operator of \c *this and \a other
 *
 * \sa operator&(), operator^()
 */
template <typename OtherDerived>
EIGEN_DEVICE_FUNC constexpr inline const CwiseBinaryOp<internal::scalar_bitwise_or_op<Scalar>, const Derived,
                                                       const OtherDerived>
operator|(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived>& other) const {
  return CwiseBinaryOp<internal::scalar_bitwise_or_op<Scalar>, const Derived, const OtherDerived>(derived(),
                                                                                                  other.derived());
}

/** \returns an expression of the bitwise xor operator of *this and \a other
 * \sa operator&(), operator|()
 */
template <typename OtherDerived>
EIGEN_DEVICE_FUNC constexpr inline const CwiseBinaryOp<internal::scalar_bitwise_xor_op<Scalar>, const Derived,
                                                       const OtherDerived>
operator^(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived>& other) const {
  return CwiseBinaryOp<internal::scalar_bitwise_xor_op<Scalar>, const Derived, const OtherDerived>(derived(),
                                                                                                   other.derived());
}
