// 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/.
// SPDX-License-Identifier: 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 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:
  using Base = typename internal::dense_xpr_base<Derived>::type;
  enum {
    RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
    ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
    InnerStrideAtCompileTime = internal::traits<Derived>::InnerStrideAtCompileTime,
    SizeAtCompileTime = Base::SizeAtCompileTime
  };

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

  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=;

  using CoeffReturnType = typename Base::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, std::enable_if_t<(internal::traits<T>::Alignment > 0), int> = 0>
  EIGEN_DEVICE_FUNC void checkSanity() 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:
    constexpr 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, std::enable_if_t<internal::traits<T>::Alignment == 0, int> = 0>
  EIGEN_DEVICE_FUNC void checkSanity() 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> {
  using ReadOnlyMapBase = MapBase<Derived, ReadOnlyAccessors>;

 public:
  using Base = MapBase<Derived, ReadOnlyAccessors>;

  using Scalar = typename Base::Scalar;
  using PacketScalar = typename Base::PacketScalar;
  using StorageIndex = typename Base::StorageIndex;
  using PointerType = typename Base::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;

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

  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
