// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// 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_ARRAY_H
#define EIGEN_ARRAY_H

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

namespace Eigen {

namespace internal {
template <typename Scalar_, int Rows_, int Cols_, int Options_, int MaxRows_, int MaxCols_>
struct traits<Array<Scalar_, Rows_, Cols_, Options_, MaxRows_, MaxCols_>>
    : traits<Matrix<Scalar_, Rows_, Cols_, Options_, MaxRows_, MaxCols_>> {
  typedef ArrayXpr XprKind;
  typedef ArrayBase<Array<Scalar_, Rows_, Cols_, Options_, MaxRows_, MaxCols_>> XprBase;
};
}  // namespace internal

/** \class Array
 * \ingroup Core_Module
 *
 * \brief General-purpose arrays with easy API for coefficient-wise operations
 *
 * The %Array class is very similar to the Matrix class. It provides
 * general-purpose one- and two-dimensional arrays. The difference between the
 * %Array and the %Matrix class is primarily in the API: the API for the
 * %Array class provides easy access to coefficient-wise operations, while the
 * API for the %Matrix class provides easy access to linear-algebra
 * operations.
 *
 * See documentation of class Matrix for detailed information on the template parameters
 * storage layout.
 *
 * This class can be extended with the help of the plugin mechanism described on the page
 * \ref TopicCustomizing_Plugins by defining the preprocessor symbol \c EIGEN_ARRAY_PLUGIN.
 *
 * \sa \blank \ref TutorialArrayClass, \ref TopicClassHierarchy
 */
template <typename Scalar_, int Rows_, int Cols_, int Options_, int MaxRows_, int MaxCols_>
class Array : public PlainObjectBase<Array<Scalar_, Rows_, Cols_, Options_, MaxRows_, MaxCols_>> {
 public:
  typedef PlainObjectBase<Array> Base;
  EIGEN_DENSE_PUBLIC_INTERFACE(Array)

  enum { Options = Options_ };
  typedef typename Base::PlainObject PlainObject;

 protected:
  template <typename Derived, typename OtherDerived, bool IsVector>
  friend struct internal::conservative_resize_like_impl;

  using Base::m_storage;

 public:
  using Base::base;
  using Base::coeff;
  using Base::coeffRef;

  /**
   * The usage of
   *   using Base::operator=;
   * fails on MSVC. Since the code below is working with GCC and MSVC, we skipped
   * the usage of 'using'. This should be done only for operator=.
   */
  template <typename OtherDerived>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Array& operator=(const EigenBase<OtherDerived>& other) {
    return Base::operator=(other);
  }

  /** Set all the entries to \a value.
   * \sa DenseBase::setConstant(), DenseBase::fill()
   */
  /* This overload is needed because the usage of
   *   using Base::operator=;
   * fails on MSVC. Since the code below is working with GCC and MSVC, we skipped
   * the usage of 'using'. This should be done only for operator=.
   */
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Array& operator=(const Scalar& value) {
    Base::setConstant(value);
    return *this;
  }

  /** Copies the value of the expression \a other into \c *this with automatic resizing.
   *
   * *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized),
   * it will be initialized.
   *
   * Note that copying a row-vector into a vector (and conversely) is allowed.
   * The resizing, if any, is then done in the appropriate way so that row-vectors
   * remain row-vectors and vectors remain vectors.
   */
  template <typename OtherDerived>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Array& operator=(const DenseBase<OtherDerived>& other) {
    return Base::_set(other);
  }

  /**
   * \brief Assigns arrays to each other.
   *
   * \note This is a special case of the templated operator=. Its purpose is
   * to prevent a default operator= from hiding the templated operator=.
   *
   * \callgraph
   */
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Array& operator=(const Array& other) { return Base::_set(other); }

  /** Default constructor.
   *
   * For fixed-size matrices, does nothing.
   *
   * For dynamic-size matrices, creates an empty matrix of size 0. Does not allocate any array. Such a matrix
   * is called a null matrix. This constructor is the unique way to create null matrices: resizing
   * a matrix to 0 is not supported.
   *
   * \sa resize(Index,Index)
   */
#ifdef EIGEN_INITIALIZE_COEFFS
  EIGEN_DEVICE_FUNC constexpr Array() : Base() { EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED }
#else
  EIGEN_DEVICE_FUNC constexpr Array() = default;
#endif
  /** \brief Move constructor */
  EIGEN_DEVICE_FUNC constexpr Array(Array&&) = default;
  EIGEN_DEVICE_FUNC Array& operator=(Array&& other) noexcept(std::is_nothrow_move_assignable<Scalar>::value) {
    Base::operator=(std::move(other));
    return *this;
  }

  /** \brief Construct a row or column vector with fixed size from an arbitrary number of coefficients.
   *
   * \only_for_vectors
   *
   * This constructor is for 1D array or vectors with more than 4 coefficients.
   *
   * \warning To construct a column (resp. row) vector of fixed length, the number of values passed to this
   * constructor must match the fixed number of rows (resp. columns) of \c *this.
   *
   *
   * Example: \include Array_variadic_ctor.cpp
   * Output: \verbinclude Array_variadic_ctor.out
   *
   * \sa Array(const std::initializer_list<std::initializer_list<Scalar>>&)
   * \sa Array(const Scalar&), Array(const Scalar&,const Scalar&)
   */
  template <typename... ArgTypes>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Array(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3,
                                              const ArgTypes&... args)
      : Base(a0, a1, a2, a3, args...) {}

  /** \brief Constructs an array and initializes it from the coefficients given as initializer-lists grouped by row.
   *
   * In the general case, the constructor takes a list of rows, each row being represented as a list of coefficients:
   *
   * Example: \include Array_initializer_list_23.cpp
   * Output: \verbinclude Array_initializer_list_23.out
   *
   * Each of the inner initializer lists must contain the exact same number of elements, otherwise an assertion is
   * triggered.
   *
   * In the case of a compile-time column 1D array, implicit transposition from a single row is allowed.
   * Therefore <code> Array<int,Dynamic,1>{{1,2,3,4,5}}</code> is legal and the more verbose syntax
   * <code>Array<int,Dynamic,1>{{1},{2},{3},{4},{5}}</code> can be avoided:
   *
   * Example: \include Array_initializer_list_vector.cpp
   * Output: \verbinclude Array_initializer_list_vector.out
   *
   * In the case of fixed-sized arrays, the initializer list sizes must exactly match the array sizes,
   * and implicit transposition is allowed for compile-time 1D arrays only.
   *
   * \sa  Array(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args)
   */
  EIGEN_DEVICE_FUNC constexpr Array(const std::initializer_list<std::initializer_list<Scalar>>& list) : Base(list) {}

#ifndef EIGEN_PARSED_BY_DOXYGEN
  template <typename T>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit Array(const T& x) {
    Base::template _init1<T>(x);
  }

  template <typename T0, typename T1>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Array(const T0& val0, const T1& val1) {
    this->template _init2<T0, T1>(val0, val1);
  }

#else
  /** \brief Constructs a fixed-sized array initialized with coefficients starting at \a data */
  EIGEN_DEVICE_FUNC explicit Array(const Scalar* data);
  /** Constructs a vector or row-vector with given dimension. \only_for_vectors
   *
   * Note that this is only useful for dynamic-size vectors. For fixed-size vectors,
   * it is redundant to pass the dimension here, so it makes more sense to use the default
   * constructor Array() instead.
   */
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit Array(Index dim);
  /** constructs an initialized 1x1 Array with the given coefficient
   * \sa Array(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args) */
  Array(const Scalar& value);
  /** constructs an uninitialized array with \a rows rows and \a cols columns.
   *
   * This is useful for dynamic-size arrays. For fixed-size arrays,
   * it is redundant to pass these parameters, so one should use the default constructor
   * Array() instead. */
  Array(Index rows, Index cols);
  /** constructs an initialized 2D vector with given coefficients
   * \sa Array(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args) */
  Array(const Scalar& val0, const Scalar& val1);
#endif  // end EIGEN_PARSED_BY_DOXYGEN

  /** constructs an initialized 3D vector with given coefficients
   * \sa Array(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args)
   */
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2) {
    EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Array, 3)
    m_storage.data()[0] = val0;
    m_storage.data()[1] = val1;
    m_storage.data()[2] = val2;
  }
  /** constructs an initialized 4D vector with given coefficients
   * \sa Array(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args)
   */
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2,
                                              const Scalar& val3) {
    EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Array, 4)
    m_storage.data()[0] = val0;
    m_storage.data()[1] = val1;
    m_storage.data()[2] = val2;
    m_storage.data()[3] = val3;
  }

  /** Copy constructor */
  EIGEN_DEVICE_FUNC constexpr Array(const Array&) = default;

 private:
  struct PrivateType {};

 public:
  /** \sa MatrixBase::operator=(const EigenBase<OtherDerived>&) */
  template <typename OtherDerived>
  EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Array(
      const EigenBase<OtherDerived>& other,
      std::enable_if_t<std::is_convertible<typename OtherDerived::Scalar, Scalar>::value, PrivateType> = PrivateType())
      : Base(other.derived()) {}

  EIGEN_DEVICE_FUNC constexpr Index innerStride() const noexcept { return 1; }
  EIGEN_DEVICE_FUNC constexpr Index outerStride() const noexcept { return this->innerSize(); }

#ifdef EIGEN_ARRAY_PLUGIN
#include EIGEN_ARRAY_PLUGIN
#endif

 private:
  template <typename MatrixType, typename OtherDerived, bool SwapPointers>
  friend struct internal::matrix_swap_impl;
};

/** \defgroup arraytypedefs Global array typedefs
 * \ingroup Core_Module
 *
 * %Eigen defines several typedef shortcuts for most common 1D and 2D array types.
 *
 * The general patterns are the following:
 *
 * \c ArrayRowsColsType where \c Rows and \c Cols can be \c 2,\c 3,\c 4 for fixed size square matrices or \c X for
 * dynamic size, and where \c Type can be \c i for integer, \c f for float, \c d for double, \c cf for complex float, \c
 * cd for complex double.
 *
 * For example, \c Array33d is a fixed-size 3x3 array type of doubles, and \c ArrayXXf is a dynamic-size matrix of
 * floats.
 *
 * There are also \c ArraySizeType which are self-explanatory. For example, \c Array4cf is
 * a fixed-size 1D array of 4 complex floats.
 *
 * Template alias are also defined for common sizes.
 * They follow the same pattern as above except that the scalar type suffix is replaced by a
 * template parameter, i.e.:
 *   - `ArrayRowsCols<Type>` where `Rows` and `Cols` can be \c 2,\c 3,\c 4, or \c X for fixed or dynamic size.
 *   - `ArraySize<Type>` where `Size` can be \c 2,\c 3,\c 4 or \c X for fixed or dynamic size 1D arrays.
 *
 * \sa class Array
 */

#define EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, Size, SizeSuffix)        \
  /** \ingroup arraytypedefs */                                              \
  typedef Array<Type, Size, Size> Array##SizeSuffix##SizeSuffix##TypeSuffix; \
  /** \ingroup arraytypedefs */                                              \
  typedef Array<Type, Size, 1> Array##SizeSuffix##TypeSuffix;

#define EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, Size)  \
  /** \ingroup arraytypedefs */                                  \
  typedef Array<Type, Size, Dynamic> Array##Size##X##TypeSuffix; \
  /** \ingroup arraytypedefs */                                  \
  typedef Array<Type, Dynamic, Size> Array##X##Size##TypeSuffix;

#define EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(Type, TypeSuffix) \
  EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, 2, 2)           \
  EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, 3, 3)           \
  EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, 4, 4)           \
  EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, Dynamic, X)     \
  EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, 2)        \
  EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, 3)        \
  EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, 4)

EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(int, i)
EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(float, f)
EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(double, d)
EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(std::complex<float>, cf)
EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(std::complex<double>, cd)

#undef EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES
#undef EIGEN_MAKE_ARRAY_TYPEDEFS
#undef EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS

#define EIGEN_MAKE_ARRAY_TYPEDEFS(Size, SizeSuffix)              \
  /** \ingroup arraytypedefs */                                  \
  template <typename Type>                                       \
  using Array##SizeSuffix##SizeSuffix = Array<Type, Size, Size>; \
  /** \ingroup arraytypedefs */                                  \
  template <typename Type>                                       \
  using Array##SizeSuffix = Array<Type, Size, 1>;

#define EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Size)        \
  /** \ingroup arraytypedefs */                      \
  template <typename Type>                           \
  using Array##Size##X = Array<Type, Size, Dynamic>; \
  /** \ingroup arraytypedefs */                      \
  template <typename Type>                           \
  using Array##X##Size = Array<Type, Dynamic, Size>;

EIGEN_MAKE_ARRAY_TYPEDEFS(2, 2)
EIGEN_MAKE_ARRAY_TYPEDEFS(3, 3)
EIGEN_MAKE_ARRAY_TYPEDEFS(4, 4)
EIGEN_MAKE_ARRAY_TYPEDEFS(Dynamic, X)
EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(2)
EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(3)
EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(4)

#undef EIGEN_MAKE_ARRAY_TYPEDEFS
#undef EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS

#define EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, SizeSuffix) \
  using Eigen::Matrix##SizeSuffix##TypeSuffix;                               \
  using Eigen::Vector##SizeSuffix##TypeSuffix;                               \
  using Eigen::RowVector##SizeSuffix##TypeSuffix;

#define EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(TypeSuffix)       \
  EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 2) \
  EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 3) \
  EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 4) \
  EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, X)

#define EIGEN_USING_ARRAY_TYPEDEFS        \
  EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(i)  \
  EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(f)  \
  EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(d)  \
  EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(cf) \
  EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(cd)

}  // end namespace Eigen

#endif  // EIGEN_ARRAY_H
