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

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

namespace Eigen {

namespace internal {
struct symbolic_last_tag {};
}  // namespace internal

namespace placeholders {

typedef symbolic::SymbolExpr<internal::symbolic_last_tag> last_t;

/** \var last
 * \ingroup Core_Module
 *
 * Can be used as a parameter to Eigen::seq and Eigen::seqN functions to symbolically reference the last
 * element/row/columns of the underlying vector or matrix once passed to DenseBase::operator()(const RowIndices&, const
 * ColIndices&).
 *
 * This symbolic placeholder supports standard arithmetic operations.
 *
 * A typical usage example would be:
 * \code
 * using namespace Eigen;
 * using Eigen::placeholders::last;
 * VectorXd v(n);
 * v(seq(2,last-2)).setOnes();
 * \endcode
 *
 * \sa end
 */
static const last_t last;

}  // namespace placeholders

namespace internal {

// Replace symbolic last/end "keywords" by their true runtime value
inline Index eval_expr_given_size(Index x, Index /* size */) { return x; }

template <int N>
FixedInt<N> eval_expr_given_size(FixedInt<N> x, Index /*size*/) {
  return x;
}

template <typename Derived>
Index eval_expr_given_size(const symbolic::BaseExpr<Derived>& x, Index size) {
  return x.derived().eval(Eigen::placeholders::last = size - 1);
}

// Extract increment/step at compile time
template <typename T, typename EnableIf = void>
struct get_compile_time_incr {
  enum { value = UndefinedIncr };
};

// Analogue of std::get<0>(x), but tailored for our needs.
template <typename T>
EIGEN_CONSTEXPR Index first(const T& x) EIGEN_NOEXCEPT {
  return x.first();
}

// IndexedViewCompatibleType/makeIndexedViewCompatible turn an arbitrary object of type T into something usable by
// MatrixSlice The generic implementation is a no-op
template <typename T, int XprSize, typename EnableIf = void>
struct IndexedViewCompatibleType {
  typedef T type;
};

template <typename T, typename Q>
const T& makeIndexedViewCompatible(const T& x, Index /*size*/, Q) {
  return x;
}

//--------------------------------------------------------------------------------
// Handling of a single Index
//--------------------------------------------------------------------------------

struct SingleRange {
  enum { SizeAtCompileTime = 1 };
  SingleRange(Index val) : m_value(val) {}
  Index operator[](Index) const { return m_value; }
  static EIGEN_CONSTEXPR Index size() EIGEN_NOEXCEPT { return 1; }
  Index first() const EIGEN_NOEXCEPT { return m_value; }
  Index m_value;
};

template <>
struct get_compile_time_incr<SingleRange> {
  enum { value = 1 };  // 1 or 0 ??
};

// Turn a single index into something that looks like an array (i.e., that exposes a .size(), and operator[](int)
// methods)
template <typename T, int XprSize>
struct IndexedViewCompatibleType<T, XprSize, std::enable_if_t<internal::is_integral<T>::value>> {
  // Here we could simply use Array, but maybe it's less work for the compiler to use
  // a simpler wrapper as SingleRange
  // typedef Eigen::Array<Index,1,1> type;
  typedef SingleRange type;
};

template <typename T, int XprSize>
struct IndexedViewCompatibleType<T, XprSize, std::enable_if_t<symbolic::is_symbolic<T>::value>> {
  typedef SingleRange type;
};

template <typename T>
std::enable_if_t<symbolic::is_symbolic<T>::value, SingleRange> makeIndexedViewCompatible(const T& id, Index size,
                                                                                         SpecializedType) {
  return eval_expr_given_size(id, size);
}

//--------------------------------------------------------------------------------
// Handling of all
//--------------------------------------------------------------------------------

struct all_t {
  all_t() {}
};

// Convert a symbolic 'all' into a usable range type
template <int XprSize>
struct AllRange {
  enum { SizeAtCompileTime = XprSize };
  AllRange(Index size = XprSize) : m_size(size) {}
  EIGEN_CONSTEXPR Index operator[](Index i) const EIGEN_NOEXCEPT { return i; }
  EIGEN_CONSTEXPR Index size() const EIGEN_NOEXCEPT { return m_size.value(); }
  EIGEN_CONSTEXPR Index first() const EIGEN_NOEXCEPT { return 0; }
  variable_if_dynamic<Index, XprSize> m_size;
};

template <int XprSize>
struct IndexedViewCompatibleType<all_t, XprSize> {
  typedef AllRange<XprSize> type;
};

template <typename XprSizeType>
inline AllRange<get_fixed_value<XprSizeType>::value> makeIndexedViewCompatible(all_t, XprSizeType size,
                                                                               SpecializedType) {
  return AllRange<get_fixed_value<XprSizeType>::value>(size);
}

template <int Size>
struct get_compile_time_incr<AllRange<Size>> {
  enum { value = 1 };
};

}  // end namespace internal

namespace placeholders {

typedef symbolic::AddExpr<symbolic::SymbolExpr<internal::symbolic_last_tag>,
                          symbolic::ValueExpr<Eigen::internal::FixedInt<1>>>
    lastp1_t;
typedef Eigen::internal::all_t all_t;

/** \var lastp1
 * \ingroup Core_Module
 *
 * Can be used as a parameter to Eigen::seq and Eigen::seqN functions to symbolically
 * reference the last+1 element/row/columns of the underlying vector or matrix once
 * passed to DenseBase::operator()(const RowIndices&, const ColIndices&).
 *
 * This symbolic placeholder supports standard arithmetic operations.
 * It is essentially an alias to last+fix<1>.
 *
 * \sa last
 */
#ifdef EIGEN_PARSED_BY_DOXYGEN
static const auto lastp1 = last + fix<1>;
#else
// Using a FixedExpr<1> expression is important here to make sure the compiler
// can fully optimize the computation starting indices with zero overhead.
static const lastp1_t lastp1(last + fix<1>());
#endif

/** \var end
 * \ingroup Core_Module
 * \sa lastp1
 */
static const lastp1_t end = lastp1;

/** \var all
 * \ingroup Core_Module
 * Can be used as a parameter to DenseBase::operator()(const RowIndices&, const ColIndices&) to index all rows or
 * columns
 */
static const Eigen::internal::all_t all;

}  // namespace placeholders

}  // end namespace Eigen

#endif  // EIGEN_INDEXED_VIEW_HELPER_H
