#ifndef EIGEN_INDEXED_VIEW_HELPER_H
#define EIGEN_INDEXED_VIEW_HELPER_H
#include "../InternalHeaderCheck.h"
namespace Eigen {
namespace internal {
struct symbolic_last_tag {};
struct all_t {};
}
namespace placeholders {
typedef symbolic::SymbolExpr<internal::symbolic_last_tag> last_t;
static constexpr const last_t last;
typedef symbolic::AddExpr<symbolic::SymbolExpr<internal::symbolic_last_tag>,
symbolic::ValueExpr<Eigen::internal::FixedInt<1>>>
lastp1_t;
typedef Eigen::internal::all_t all_t;
#ifdef EIGEN_PARSED_BY_DOXYGEN
static constexpr auto lastp1 = last + fix<1>;
#else
static constexpr lastp1_t lastp1 = lastp1_t{};
#endif
static constexpr lastp1_t end = lastp1;
static constexpr Eigen::internal::all_t all;
}
namespace internal {
template <typename Expr, int SizeAtCompileTime, typename EnableIf = void>
struct SymbolicExpressionEvaluator {
static constexpr Index ValueAtCompileTime = Undefined;
static Index eval(const Expr& expr, Index ) { return static_cast<Index>(expr); }
};
template <typename Expr, int SizeAtCompileTime>
struct SymbolicExpressionEvaluator<Expr, SizeAtCompileTime, std::enable_if_t<symbolic::is_symbolic<Expr>::value>> {
static constexpr Index ValueAtCompileTime =
Expr::Derived::eval_at_compile_time(Eigen::placeholders::last = fix<SizeAtCompileTime - 1>);
static Index eval(const Expr& expr, Index ) {
return expr.eval(Eigen::placeholders::last = fix<SizeAtCompileTime - 1>);
}
};
template <typename Expr>
struct SymbolicExpressionEvaluator<Expr, Dynamic, std::enable_if_t<symbolic::is_symbolic<Expr>::value>> {
static constexpr Index ValueAtCompileTime = Undefined;
static Index eval(const Expr& expr, Index size) { return expr.eval(Eigen::placeholders::last = size - 1); }
};
template <int N, int SizeAtCompileTime>
struct SymbolicExpressionEvaluator<FixedInt<N>, SizeAtCompileTime, void> {
static constexpr Index ValueAtCompileTime = static_cast<Index>(N);
static Index eval(const FixedInt<N>& , Index ) { return ValueAtCompileTime; }
};
template <typename Indices, int NestedSizeAtCompileTime, typename EnableIf = void>
struct IndexedViewHelperIndicesWrapper {
using type = Indices;
static const type& CreateIndexSequence(const Indices& indices, Index ) { return indices; }
};
template <typename Indices, typename EnableIf = void>
struct IndexedViewHelper {
static constexpr Index FirstAtCompileTime = Undefined;
static constexpr Index SizeAtCompileTime = array_size<Indices>::value;
static constexpr Index IncrAtCompileTime = Undefined;
static constexpr Index first(const Indices& indices) { return static_cast<Index>(indices[0]); }
static constexpr Index size(const Indices& indices) { return index_list_size(indices); }
static constexpr Index incr(const Indices& ) { return Undefined; }
};
template <Index FirstAtCompileTime_, Index SizeAtCompileTime_, Index IncrAtCompileTime_>
class ArithmeticSequenceRange {
public:
static constexpr Index FirstAtCompileTime = FirstAtCompileTime_;
static constexpr Index SizeAtCompileTime = SizeAtCompileTime_;
static constexpr Index IncrAtCompileTime = IncrAtCompileTime_;
constexpr ArithmeticSequenceRange(Index first, Index size, Index incr) : first_{first}, size_{size}, incr_{incr} {}
constexpr Index operator[](Index i) const { return first() + i * incr(); }
constexpr Index first() const noexcept { return first_.value(); }
constexpr Index size() const noexcept { return size_.value(); }
constexpr Index incr() const noexcept { return incr_.value(); }
private:
variable_if_dynamicindex<Index, int(FirstAtCompileTime)> first_;
variable_if_dynamic<Index, int(SizeAtCompileTime)> size_;
variable_if_dynamicindex<Index, int(IncrAtCompileTime)> incr_;
};
template <typename FirstType, typename SizeType, typename IncrType, int NestedSizeAtCompileTime>
struct IndexedViewHelperIndicesWrapper<ArithmeticSequence<FirstType, SizeType, IncrType>, NestedSizeAtCompileTime,
void> {
static constexpr Index EvalFirstAtCompileTime =
SymbolicExpressionEvaluator<FirstType, NestedSizeAtCompileTime>::ValueAtCompileTime;
static constexpr Index EvalSizeAtCompileTime =
SymbolicExpressionEvaluator<SizeType, NestedSizeAtCompileTime>::ValueAtCompileTime;
static constexpr Index EvalIncrAtCompileTime =
SymbolicExpressionEvaluator<IncrType, NestedSizeAtCompileTime>::ValueAtCompileTime;
static constexpr Index FirstAtCompileTime =
(int(EvalFirstAtCompileTime) == Undefined) ? Index(DynamicIndex) : EvalFirstAtCompileTime;
static constexpr Index SizeAtCompileTime =
(int(EvalSizeAtCompileTime) == Undefined) ? Index(Dynamic) : EvalSizeAtCompileTime;
static constexpr Index IncrAtCompileTime =
(int(EvalIncrAtCompileTime) == Undefined) ? Index(DynamicIndex) : EvalIncrAtCompileTime;
using Indices = ArithmeticSequence<FirstType, SizeType, IncrType>;
using type = ArithmeticSequenceRange<FirstAtCompileTime, SizeAtCompileTime, IncrAtCompileTime>;
static type CreateIndexSequence(const Indices& indices, Index nested_size) {
Index first =
SymbolicExpressionEvaluator<FirstType, NestedSizeAtCompileTime>::eval(indices.firstObject(), nested_size);
Index size =
SymbolicExpressionEvaluator<SizeType, NestedSizeAtCompileTime>::eval(indices.sizeObject(), nested_size);
Index incr =
SymbolicExpressionEvaluator<IncrType, NestedSizeAtCompileTime>::eval(indices.incrObject(), nested_size);
return type(first, size, incr);
}
};
template <Index FirstAtCompileTime_, Index SizeAtCompileTime_, Index IncrAtCompileTime_>
struct IndexedViewHelper<ArithmeticSequenceRange<FirstAtCompileTime_, SizeAtCompileTime_, IncrAtCompileTime_>, void> {
public:
using Indices = ArithmeticSequenceRange<FirstAtCompileTime_, SizeAtCompileTime_, IncrAtCompileTime_>;
static constexpr Index FirstAtCompileTime = Indices::FirstAtCompileTime;
static constexpr Index SizeAtCompileTime = Indices::SizeAtCompileTime;
static constexpr Index IncrAtCompileTime = Indices::IncrAtCompileTime;
static Index first(const Indices& indices) { return indices.first(); }
static Index size(const Indices& indices) { return indices.size(); }
static Index incr(const Indices& indices) { return indices.incr(); }
};
template <Index ValueAtCompileTime>
class SingleRange {
public:
static constexpr Index FirstAtCompileTime = ValueAtCompileTime;
static constexpr Index SizeAtCompileTime = Index(1);
static constexpr Index IncrAtCompileTime = Index(1);
constexpr SingleRange(Index v) noexcept : value_(v) {}
constexpr Index operator[](Index) const noexcept { return first(); }
constexpr Index first() const noexcept { return value_.value(); }
constexpr Index size() const noexcept { return SizeAtCompileTime; }
constexpr Index incr() const noexcept { return IncrAtCompileTime; }
private:
variable_if_dynamicindex<Index, int(ValueAtCompileTime)> value_;
};
template <typename T>
struct is_single_range : public std::false_type {};
template <Index ValueAtCompileTime>
struct is_single_range<SingleRange<ValueAtCompileTime>> : public std::true_type {};
template <typename SingleIndex, int NestedSizeAtCompileTime>
struct IndexedViewHelperIndicesWrapper<
SingleIndex, NestedSizeAtCompileTime,
std::enable_if_t<std::is_integral<SingleIndex>::value || symbolic::is_symbolic<SingleIndex>::value>> {
static constexpr Index EvalValueAtCompileTime =
SymbolicExpressionEvaluator<SingleIndex, NestedSizeAtCompileTime>::ValueAtCompileTime;
static constexpr Index ValueAtCompileTime =
(int(EvalValueAtCompileTime) == Undefined) ? Index(DynamicIndex) : EvalValueAtCompileTime;
using type = SingleRange<ValueAtCompileTime>;
static type CreateIndexSequence(const SingleIndex& index, Index nested_size) {
return type(SymbolicExpressionEvaluator<SingleIndex, NestedSizeAtCompileTime>::eval(index, nested_size));
}
};
template <int N, int NestedSizeAtCompileTime>
struct IndexedViewHelperIndicesWrapper<FixedInt<N>, NestedSizeAtCompileTime, void> {
using type = SingleRange<Index(N)>;
static type CreateIndexSequence(const FixedInt<N>& ) { return type(Index(N)); }
};
template <Index ValueAtCompileTime>
struct IndexedViewHelper<SingleRange<ValueAtCompileTime>, void> {
using Indices = SingleRange<ValueAtCompileTime>;
static constexpr Index FirstAtCompileTime = Indices::FirstAtCompileTime;
static constexpr Index SizeAtCompileTime = Indices::SizeAtCompileTime;
static constexpr Index IncrAtCompileTime = Indices::IncrAtCompileTime;
static constexpr Index first(const Indices& indices) { return indices.first(); }
static constexpr Index size(const Indices& ) { return SizeAtCompileTime; }
static constexpr Index incr(const Indices& ) { return IncrAtCompileTime; }
};
template <Index SizeAtCompileTime_>
class AllRange {
public:
static constexpr Index FirstAtCompileTime = Index(0);
static constexpr Index SizeAtCompileTime = SizeAtCompileTime_;
static constexpr Index IncrAtCompileTime = Index(1);
constexpr AllRange(Index size) : size_(size) {}
constexpr Index operator[](Index i) const noexcept { return i; }
constexpr Index first() const noexcept { return FirstAtCompileTime; }
constexpr Index size() const noexcept { return size_.value(); }
constexpr Index incr() const noexcept { return IncrAtCompileTime; }
private:
variable_if_dynamic<Index, int(SizeAtCompileTime)> size_;
};
template <int NestedSizeAtCompileTime>
struct IndexedViewHelperIndicesWrapper<all_t, NestedSizeAtCompileTime, void> {
using type = AllRange<Index(NestedSizeAtCompileTime)>;
static type CreateIndexSequence(const all_t& , Index nested_size) { return type(nested_size); }
};
template <Index SizeAtCompileTime_>
struct IndexedViewHelper<AllRange<SizeAtCompileTime_>, void> {
using Indices = AllRange<SizeAtCompileTime_>;
static constexpr Index FirstAtCompileTime = Indices::FirstAtCompileTime;
static constexpr Index SizeAtCompileTime = Indices::SizeAtCompileTime;
static constexpr Index IncrAtCompileTime = Indices::IncrAtCompileTime;
static Index first(const Indices& indices) { return indices.first(); }
static Index size(const Indices& indices) { return indices.size(); }
static Index incr(const Indices& indices) { return indices.incr(); }
};
template <typename Derived, typename RowIndices, typename ColIndices, typename EnableIf = void>
struct IndexedViewSelector;
template <typename Indices, int SizeAtCompileTime>
using IvcType = typename internal::IndexedViewHelperIndicesWrapper<Indices, SizeAtCompileTime>::type;
template <int SizeAtCompileTime, typename Indices>
inline IvcType<Indices, SizeAtCompileTime> CreateIndexSequence(size_t size, const Indices& indices) {
return internal::IndexedViewHelperIndicesWrapper<Indices, SizeAtCompileTime>::CreateIndexSequence(indices, size);
}
template <typename Derived, typename RowIndices, typename ColIndices>
struct IndexedViewSelector<Derived, RowIndices, ColIndices,
std::enable_if_t<internal::traits<
IndexedView<Derived, IvcType<RowIndices, Derived::RowsAtCompileTime>,
IvcType<ColIndices, Derived::ColsAtCompileTime>>>::ReturnAsIndexedView>> {
using ReturnType = IndexedView<Derived, IvcType<RowIndices, Derived::RowsAtCompileTime>,
IvcType<ColIndices, Derived::ColsAtCompileTime>>;
using ConstReturnType = IndexedView<const Derived, IvcType<RowIndices, Derived::RowsAtCompileTime>,
IvcType<ColIndices, Derived::ColsAtCompileTime>>;
static inline ReturnType run(Derived& derived, const RowIndices& rowIndices, const ColIndices& colIndices) {
return ReturnType(derived, CreateIndexSequence<Derived::RowsAtCompileTime>(derived.rows(), rowIndices),
CreateIndexSequence<Derived::ColsAtCompileTime>(derived.cols(), colIndices));
}
static inline ConstReturnType run(const Derived& derived, const RowIndices& rowIndices,
const ColIndices& colIndices) {
return ConstReturnType(derived, CreateIndexSequence<Derived::RowsAtCompileTime>(derived.rows(), rowIndices),
CreateIndexSequence<Derived::ColsAtCompileTime>(derived.cols(), colIndices));
}
};
template <typename Derived, typename RowIndices, typename ColIndices>
struct IndexedViewSelector<
Derived, RowIndices, ColIndices,
std::enable_if_t<internal::traits<IndexedView<Derived, IvcType<RowIndices, Derived::RowsAtCompileTime>,
IvcType<ColIndices, Derived::ColsAtCompileTime>>>::ReturnAsBlock>> {
using ActualRowIndices = IvcType<RowIndices, Derived::RowsAtCompileTime>;
using ActualColIndices = IvcType<ColIndices, Derived::ColsAtCompileTime>;
using IndexedViewType = IndexedView<Derived, ActualRowIndices, ActualColIndices>;
using ConstIndexedViewType = IndexedView<const Derived, ActualRowIndices, ActualColIndices>;
using ReturnType = typename internal::traits<IndexedViewType>::BlockType;
using ConstReturnType = typename internal::traits<ConstIndexedViewType>::BlockType;
using RowHelper = internal::IndexedViewHelper<ActualRowIndices>;
using ColHelper = internal::IndexedViewHelper<ActualColIndices>;
static inline ReturnType run(Derived& derived, const RowIndices& rowIndices, const ColIndices& colIndices) {
auto actualRowIndices = CreateIndexSequence<Derived::RowsAtCompileTime>(derived.rows(), rowIndices);
auto actualColIndices = CreateIndexSequence<Derived::ColsAtCompileTime>(derived.cols(), colIndices);
return ReturnType(derived, RowHelper::first(actualRowIndices), ColHelper::first(actualColIndices),
RowHelper::size(actualRowIndices), ColHelper::size(actualColIndices));
}
static inline ConstReturnType run(const Derived& derived, const RowIndices& rowIndices,
const ColIndices& colIndices) {
auto actualRowIndices = CreateIndexSequence<Derived::RowsAtCompileTime>(derived.rows(), rowIndices);
auto actualColIndices = CreateIndexSequence<Derived::ColsAtCompileTime>(derived.cols(), colIndices);
return ConstReturnType(derived, RowHelper::first(actualRowIndices), ColHelper::first(actualColIndices),
RowHelper::size(actualRowIndices), ColHelper::size(actualColIndices));
}
};
template <typename Derived, typename RowIndices, typename ColIndices>
struct IndexedViewSelector<
Derived, RowIndices, ColIndices,
std::enable_if_t<internal::traits<IndexedView<Derived, IvcType<RowIndices, Derived::RowsAtCompileTime>,
IvcType<ColIndices, Derived::ColsAtCompileTime>>>::ReturnAsScalar>> {
using ReturnType = typename DenseBase<Derived>::Scalar&;
using ConstReturnType = typename DenseBase<Derived>::CoeffReturnType;
using ActualRowIndices = IvcType<RowIndices, Derived::RowsAtCompileTime>;
using ActualColIndices = IvcType<ColIndices, Derived::ColsAtCompileTime>;
using RowHelper = internal::IndexedViewHelper<ActualRowIndices>;
using ColHelper = internal::IndexedViewHelper<ActualColIndices>;
static inline ReturnType run(Derived& derived, const RowIndices& rowIndices, const ColIndices& colIndices) {
auto actualRowIndices = CreateIndexSequence<Derived::RowsAtCompileTime>(derived.rows(), rowIndices);
auto actualColIndices = CreateIndexSequence<Derived::ColsAtCompileTime>(derived.cols(), colIndices);
return derived(RowHelper::first(actualRowIndices), ColHelper::first(actualColIndices));
}
static inline ConstReturnType run(const Derived& derived, const RowIndices& rowIndices,
const ColIndices& colIndices) {
auto actualRowIndices = CreateIndexSequence<Derived::RowsAtCompileTime>(derived.rows(), rowIndices);
auto actualColIndices = CreateIndexSequence<Derived::ColsAtCompileTime>(derived.cols(), colIndices);
return derived(RowHelper::first(actualRowIndices), ColHelper::first(actualColIndices));
}
};
template <typename Derived, typename Indices, typename EnableIf = void>
struct VectorIndexedViewSelector;
template <typename Derived, typename Indices>
struct VectorIndexedViewSelector<
Derived, Indices,
std::enable_if_t<!internal::is_single_range<IvcType<Indices, Derived::SizeAtCompileTime>>::value &&
internal::IndexedViewHelper<IvcType<Indices, Derived::SizeAtCompileTime>>::IncrAtCompileTime !=
1>> {
static constexpr bool IsRowMajor = DenseBase<Derived>::IsRowMajor;
using ZeroIndex = internal::SingleRange<Index(0)>;
using RowMajorReturnType = IndexedView<Derived, ZeroIndex, IvcType<Indices, Derived::SizeAtCompileTime>>;
using ConstRowMajorReturnType = IndexedView<const Derived, ZeroIndex, IvcType<Indices, Derived::SizeAtCompileTime>>;
using ColMajorReturnType = IndexedView<Derived, IvcType<Indices, Derived::SizeAtCompileTime>, ZeroIndex>;
using ConstColMajorReturnType = IndexedView<const Derived, IvcType<Indices, Derived::SizeAtCompileTime>, ZeroIndex>;
using ReturnType = typename internal::conditional<IsRowMajor, RowMajorReturnType, ColMajorReturnType>::type;
using ConstReturnType =
typename internal::conditional<IsRowMajor, ConstRowMajorReturnType, ConstColMajorReturnType>::type;
template <bool UseRowMajor = IsRowMajor, std::enable_if_t<UseRowMajor, bool> = true>
static inline RowMajorReturnType run(Derived& derived, const Indices& indices) {
return RowMajorReturnType(derived, ZeroIndex(0),
CreateIndexSequence<Derived::ColsAtCompileTime>(derived.cols(), indices));
}
template <bool UseRowMajor = IsRowMajor, std::enable_if_t<UseRowMajor, bool> = true>
static inline ConstRowMajorReturnType run(const Derived& derived, const Indices& indices) {
return ConstRowMajorReturnType(derived, ZeroIndex(0),
CreateIndexSequence<Derived::ColsAtCompileTime>(derived.cols(), indices));
}
template <bool UseRowMajor = IsRowMajor, std::enable_if_t<!UseRowMajor, bool> = true>
static inline ColMajorReturnType run(Derived& derived, const Indices& indices) {
return ColMajorReturnType(derived, CreateIndexSequence<Derived::RowsAtCompileTime>(derived.rows(), indices),
ZeroIndex(0));
}
template <bool UseRowMajor = IsRowMajor, std::enable_if_t<!UseRowMajor, bool> = true>
static inline ConstColMajorReturnType run(const Derived& derived, const Indices& indices) {
return ConstColMajorReturnType(derived, CreateIndexSequence<Derived::RowsAtCompileTime>(derived.rows(), indices),
ZeroIndex(0));
}
};
template <typename Derived, typename Indices>
struct VectorIndexedViewSelector<
Derived, Indices,
std::enable_if_t<!internal::is_single_range<IvcType<Indices, Derived::SizeAtCompileTime>>::value &&
internal::IndexedViewHelper<IvcType<Indices, Derived::SizeAtCompileTime>>::IncrAtCompileTime ==
1>> {
using Helper = internal::IndexedViewHelper<IvcType<Indices, Derived::SizeAtCompileTime>>;
using ReturnType = VectorBlock<Derived, Helper::SizeAtCompileTime>;
using ConstReturnType = VectorBlock<const Derived, Helper::SizeAtCompileTime>;
static inline ReturnType run(Derived& derived, const Indices& indices) {
auto actualIndices = CreateIndexSequence<Derived::SizeAtCompileTime>(derived.size(), indices);
return ReturnType(derived, Helper::first(actualIndices), Helper::size(actualIndices));
}
static inline ConstReturnType run(const Derived& derived, const Indices& indices) {
auto actualIndices = CreateIndexSequence<Derived::SizeAtCompileTime>(derived.size(), indices);
return ConstReturnType(derived, Helper::first(actualIndices), Helper::size(actualIndices));
}
};
template <typename Derived, typename Indices>
struct VectorIndexedViewSelector<
Derived, Indices,
std::enable_if_t<internal::is_single_range<IvcType<Indices, Derived::SizeAtCompileTime>>::value>> {
using ReturnType = typename DenseBase<Derived>::Scalar&;
using ConstReturnType = typename DenseBase<Derived>::CoeffReturnType;
using Helper = internal::IndexedViewHelper<IvcType<Indices, Derived::SizeAtCompileTime>>;
static inline ReturnType run(Derived& derived, const Indices& indices) {
auto actualIndices = CreateIndexSequence<Derived::SizeAtCompileTime>(derived.size(), indices);
return derived(Helper::first(actualIndices));
}
static inline ConstReturnType run(const Derived& derived, const Indices& indices) {
auto actualIndices = CreateIndexSequence<Derived::SizeAtCompileTime>(derived.size(), indices);
return derived(Helper::first(actualIndices));
}
};
}
}
#endif