// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2007-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
// Copyright (C) 2008 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/.

#ifndef EIGEN_MAPBASE_H
#define EIGEN_MAPBASE_H

#define EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)                                                               \
  EIGEN_STATIC_ASSERT((int(internal::evaluator<Derived>::Flags) & LinearAccessBit) || Derived::IsVectorAtCompileTime, \
                      YOU_ARE_TRYING_TO_USE_AN_INDEX_BASED_ACCESSOR_ON_AN_EXPRESSION_THAT_DOES_NOT_SUPPORT_THAT)

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

namespace Eigen {

/** \ingroup Core_Module
 *
 * \brief Base class for dense Map and Block expression with direct access
 *
 * This base class provides the const low-level accessors (e.g. coeff, coeffRef) of dense
 * Map and Block objects with direct access.
 * Typical users do not have to directly deal with this class.
 *
 * This class can be extended by through the macro plugin \c EIGEN_MAPBASE_PLUGIN.
 * See \link TopicCustomizing_Plugins customizing Eigen \endlink for details.
 *
 * The \c Derived class has to provide the following two methods describing the memory layout:
 *  \code Index innerStride() const; \endcode
 *  \code Index outerStride() const; \endcode
 *
 * \sa class Map, class Block
 */
template <typename Derived>
class MapBase<Derived, ReadOnlyAccessors> : public internal::dense_xpr_base<Derived>::type {
 public:
  typedef typename internal::dense_xpr_base<Derived>::type Base;
  enum {
    RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
    ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
    InnerStrideAtCompileTime = internal::traits<Derived>::InnerStrideAtCompileTime,
    SizeAtCompileTime = Base::SizeAtCompileTime
  };

  typedef typename internal::traits<Derived>::StorageKind StorageKind;
  typedef typename internal::traits<Derived>::Scalar Scalar;
  typedef typename internal::packet_traits<Scalar>::type PacketScalar;
  typedef typename NumTraits<Scalar>::Real RealScalar;
  typedef std::conditional_t<bool(internal::is_lvalue<Derived>::value), Scalar*, const Scalar*> PointerType;

  using Base::derived;
  //    using Base::RowsAtCompileTime;
  //    using Base::ColsAtCompileTime;
  //    using Base::SizeAtCompileTime;
  using Base::Flags;
  using Base::IsRowMajor;
  using Base::IsVectorAtCompileTime;
  using Base::MaxColsAtCompileTime;
  using Base::MaxRowsAtCompileTime;
  using Base::MaxSizeAtCompileTime;

  using Base::coeff;
  using Base::coeffRef;
  using Base::cols;
  using Base::eval;
  using Base::lazyAssign;
  using Base::rows;
  using Base::size;

  using Base::colStride;
  using Base::innerStride;
  using Base::outerStride;
  using Base::rowStride;

  // bug 217 - compile error on ICC 11.1
  using Base::operator=;

  typedef typename Base::CoeffReturnType CoeffReturnType;

  /** \copydoc DenseBase::rows() */
  EIGEN_DEVICE_FUNC constexpr Index rows() const noexcept { return m_rows.value(); }
  /** \copydoc DenseBase::cols() */
  EIGEN_DEVICE_FUNC constexpr Index cols() const noexcept { return m_cols.value(); }

  /** Returns a pointer to the first coefficient of the matrix or vector.
   *
   * \note When addressing this data, make sure to honor the strides returned by innerStride() and outerStride().
   *
   * \sa innerStride(), outerStride()
   */
  EIGEN_DEVICE_FUNC constexpr const Scalar* data() const { return m_data; }

  /** \copydoc PlainObjectBase::coeff(Index,Index) const */
  EIGEN_DEVICE_FUNC constexpr inline const Scalar& coeff(Index rowId, Index colId) const {
    return m_data[colId * colStride() + rowId * rowStride()];
  }

  /** \copydoc PlainObjectBase::coeff(Index) const */
  EIGEN_DEVICE_FUNC constexpr inline const Scalar& coeff(Index index) const {
    EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
    return m_data[index * innerStride()];
  }

  /** \copydoc PlainObjectBase::coeffRef(Index,Index) const */
  EIGEN_DEVICE_FUNC constexpr inline const Scalar& coeffRef(Index rowId, Index colId) const {
    return this->m_data[colId * colStride() + rowId * rowStride()];
  }

  /** \copydoc PlainObjectBase::coeffRef(Index) const */
  EIGEN_DEVICE_FUNC constexpr inline const Scalar& coeffRef(Index index) const {
    EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
    return this->m_data[index * innerStride()];
  }

  /** \internal */
  template <int LoadMode>
  inline PacketScalar packet(Index rowId, Index colId) const {
    return internal::ploadt<PacketScalar, LoadMode>(m_data + (colId * colStride() + rowId * rowStride()));
  }

  /** \internal */
  template <int LoadMode>
  inline PacketScalar packet(Index index) const {
    EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
    return internal::ploadt<PacketScalar, LoadMode>(m_data + index * innerStride());
  }

  /** \internal Constructor for fixed size matrices or vectors */
  EIGEN_DEVICE_FUNC constexpr explicit inline MapBase(PointerType dataPtr)
      : m_data(dataPtr), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime) {
    EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
    checkSanity<Derived>();
  }

  /** \internal Constructor for dynamically sized vectors */
  EIGEN_DEVICE_FUNC constexpr inline MapBase(PointerType dataPtr, Index vecSize)
      : m_data(dataPtr),
        m_rows(RowsAtCompileTime == Dynamic ? vecSize : Index(RowsAtCompileTime)),
        m_cols(ColsAtCompileTime == Dynamic ? vecSize : Index(ColsAtCompileTime)) {
    EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
    eigen_assert(vecSize >= 0);
    eigen_assert(dataPtr == 0 || SizeAtCompileTime == Dynamic || SizeAtCompileTime == vecSize);
    checkSanity<Derived>();
  }

  /** \internal Constructor for dynamically sized matrices */
  EIGEN_DEVICE_FUNC constexpr inline MapBase(PointerType dataPtr, Index rows, Index cols)
      : m_data(dataPtr), m_rows(rows), m_cols(cols) {
    eigen_assert((dataPtr == 0) || (rows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows) &&
                                    cols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols)));
    checkSanity<Derived>();
  }

#ifdef EIGEN_MAPBASE_PLUGIN
#include EIGEN_MAPBASE_PLUGIN
#endif

 protected:
  EIGEN_DEFAULT_COPY_CONSTRUCTOR(MapBase)
  EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(MapBase)

  template <typename T>
  EIGEN_DEVICE_FUNC void checkSanity(std::enable_if_t<(internal::traits<T>::Alignment > 0), void*> = 0) const {
// Temporary macro to allow scalars to not be properly aligned.  This is while we sort out failures
// in TensorFlow Lite that are currently relying on this UB.
#ifndef EIGEN_ALLOW_UNALIGNED_SCALARS
    // Pointer must be aligned to the Scalar type, otherwise we get UB.
    eigen_assert((std::uintptr_t(m_data) % alignof(Scalar) == 0) && "data is not scalar-aligned");
#endif
#if EIGEN_MAX_ALIGN_BYTES > 0
    // innerStride() is not set yet when this function is called, so we optimistically assume the lowest plausible
    // value:
    const Index minInnerStride = InnerStrideAtCompileTime == Dynamic ? 1 : Index(InnerStrideAtCompileTime);
    EIGEN_ONLY_USED_FOR_DEBUG(minInnerStride);
    eigen_assert((((std::uintptr_t(m_data) % internal::traits<Derived>::Alignment) == 0) ||
                  (cols() * rows() * minInnerStride * sizeof(Scalar)) < internal::traits<Derived>::Alignment) &&
                 "data is not aligned");
#endif
  }

  template <typename T>
  EIGEN_DEVICE_FUNC void checkSanity(std::enable_if_t<internal::traits<T>::Alignment == 0, void*> = 0) const {
#ifndef EIGEN_ALLOW_UNALIGNED_SCALARS
    // Pointer must be aligned to the Scalar type, otherwise we get UB.
    eigen_assert((std::uintptr_t(m_data) % alignof(Scalar) == 0) && "data is not scalar-aligned");
#endif
  }

  PointerType m_data;
  const internal::variable_if_dynamic<Index, RowsAtCompileTime> m_rows;
  const internal::variable_if_dynamic<Index, ColsAtCompileTime> m_cols;
};

/** \ingroup Core_Module
 *
 * \brief Base class for non-const dense Map and Block expression with direct access
 *
 * This base class provides the non-const low-level accessors (e.g. coeff and coeffRef) of
 * dense Map and Block objects with direct access.
 * It inherits MapBase<Derived, ReadOnlyAccessors> which defines the const variant for reading specific entries.
 *
 * \sa class Map, class Block
 */
template <typename Derived>
class MapBase<Derived, WriteAccessors> : public MapBase<Derived, ReadOnlyAccessors> {
  typedef MapBase<Derived, ReadOnlyAccessors> ReadOnlyMapBase;

 public:
  typedef MapBase<Derived, ReadOnlyAccessors> Base;

  typedef typename Base::Scalar Scalar;
  typedef typename Base::PacketScalar PacketScalar;
  typedef typename Base::StorageIndex StorageIndex;
  typedef typename Base::PointerType PointerType;

  using Base::coeff;
  using Base::coeffRef;
  using Base::cols;
  using Base::derived;
  using Base::rows;
  using Base::size;

  using Base::colStride;
  using Base::innerStride;
  using Base::outerStride;
  using Base::rowStride;

  typedef std::conditional_t<internal::is_lvalue<Derived>::value, Scalar, const Scalar> ScalarWithConstIfNotLvalue;

  EIGEN_DEVICE_FUNC constexpr const Scalar* data() const { return this->m_data; }
  EIGEN_DEVICE_FUNC constexpr ScalarWithConstIfNotLvalue* data() {
    return this->m_data;
  }  // no const-cast here so non-const-correct code will give a compile error

  EIGEN_DEVICE_FUNC constexpr inline ScalarWithConstIfNotLvalue& coeffRef(Index row, Index col) {
    return this->m_data[col * colStride() + row * rowStride()];
  }

  EIGEN_DEVICE_FUNC constexpr inline ScalarWithConstIfNotLvalue& coeffRef(Index index) {
    EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
    return this->m_data[index * innerStride()];
  }

  template <int StoreMode>
  inline void writePacket(Index row, Index col, const PacketScalar& val) {
    internal::pstoret<Scalar, PacketScalar, StoreMode>(this->m_data + (col * colStride() + row * rowStride()), val);
  }

  template <int StoreMode>
  inline void writePacket(Index index, const PacketScalar& val) {
    EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
    internal::pstoret<Scalar, PacketScalar, StoreMode>(this->m_data + index * innerStride(), val);
  }

  EIGEN_DEVICE_FUNC constexpr explicit inline MapBase(PointerType dataPtr) : Base(dataPtr) {}
  EIGEN_DEVICE_FUNC constexpr inline MapBase(PointerType dataPtr, Index vecSize) : Base(dataPtr, vecSize) {}
  EIGEN_DEVICE_FUNC constexpr inline MapBase(PointerType dataPtr, Index rows, Index cols) : Base(dataPtr, rows, cols) {}

  EIGEN_DEVICE_FUNC Derived& operator=(const MapBase& other) {
    ReadOnlyMapBase::Base::operator=(other);
    return derived();
  }

  // In theory we could simply refer to Base:Base::operator=, but MSVC does not like Base::Base,
  // see bugs 821 and 920.
  using ReadOnlyMapBase::Base::operator=;

 protected:
  EIGEN_DEFAULT_COPY_CONSTRUCTOR(MapBase)
  EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(MapBase)
};

#undef EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS

}  // end namespace Eigen

#endif  // EIGEN_MAPBASE_H
