11#ifndef EIGEN_INDEXED_VIEW_HELPER_H
12#define EIGEN_INDEXED_VIEW_HELPER_H
15#include "../InternalHeaderCheck.h"
20struct symbolic_last_tag {};
26namespace placeholders {
28using last_t = symbolic::SymbolExpr<internal::symbolic_last_tag>;
49static constexpr const last_t
last;
51using lastp1_t = symbolic::AddExpr<symbolic::SymbolExpr<internal::symbolic_last_tag>,
52 symbolic::ValueExpr<Eigen::internal::FixedInt<1>>>;
53using all_t = Eigen::internal::all_t;
67#ifdef EIGEN_PARSED_BY_DOXYGEN
72static constexpr lastp1_t
lastp1 = lastp1_t{};
86static constexpr Eigen::internal::all_t
all;
94template <
typename Expr,
int SizeAtCompileTime,
typename EnableIf =
void>
95struct SymbolicExpressionEvaluator {
96 static constexpr Index ValueAtCompileTime = Undefined;
97 static Index eval(
const Expr& expr, Index ) {
return static_cast<Index
>(expr); }
101template <
typename Expr,
int SizeAtCompileTime>
102struct SymbolicExpressionEvaluator<Expr, SizeAtCompileTime, std::enable_if_t<symbolic::is_symbolic<Expr>::value>> {
103 static constexpr Index ValueAtCompileTime =
105 static Index eval(
const Expr& expr, Index ) {
111template <
typename Expr>
112struct SymbolicExpressionEvaluator<Expr, Dynamic, std::enable_if_t<symbolic::is_symbolic<Expr>::value>> {
113 static constexpr Index ValueAtCompileTime = Undefined;
118template <
int N,
int SizeAtCompileTime>
119struct SymbolicExpressionEvaluator<FixedInt<N>, SizeAtCompileTime, void> {
120 static constexpr Index ValueAtCompileTime =
static_cast<Index
>(N);
121 static Index eval(
const FixedInt<N>& , Index ) {
return ValueAtCompileTime; }
130template <
typename T,
typename =
void>
131struct is_eigen_index_expression : std::false_type {};
134struct is_eigen_index_expression<T, std::enable_if_t<!std::is_same<T, typename T::PlainObject>::value>>
138template <
typename Indices,
int NestedSizeAtCompileTime,
typename EnableIf =
void>
139struct IndexedViewHelperIndicesWrapper {
140 using type = Indices;
141 static const type& CreateIndexSequence(
const Indices& indices, Index ) {
return indices; }
146template <
typename Indices,
int NestedSizeAtCompileTime>
147struct IndexedViewHelperIndicesWrapper<Indices, NestedSizeAtCompileTime,
148 std::enable_if_t<is_eigen_index_expression<Indices>::value>> {
149 using type =
typename Indices::PlainObject;
150 static type CreateIndexSequence(
const Indices& indices, Index ) {
return indices.eval(); }
154template <
typename Indices,
typename EnableIf =
void>
155struct IndexedViewHelper {
156 static constexpr Index FirstAtCompileTime = Undefined;
157 static constexpr Index SizeAtCompileTime = array_size<Indices>::value;
158 static constexpr Index IncrAtCompileTime = Undefined;
160 static constexpr Index first(
const Indices& indices) {
return static_cast<Index
>(indices[0]); }
161 static constexpr Index size(
const Indices& indices) {
return index_list_size(indices); }
162 static constexpr Index incr(
const Indices& ) {
return Undefined; }
169template <Index FirstAtCompileTime_, Index SizeAtCompileTime_, Index IncrAtCompileTime_>
170class ArithmeticSequenceRange {
172 static constexpr Index FirstAtCompileTime = FirstAtCompileTime_;
173 static constexpr Index SizeAtCompileTime = SizeAtCompileTime_;
174 static constexpr Index IncrAtCompileTime = IncrAtCompileTime_;
176 constexpr ArithmeticSequenceRange(Index first, Index size, Index incr) : m_first{first}, m_size{size}, m_incr{incr} {}
177 constexpr Index operator[](Index i)
const {
return first() + i * incr(); }
178 constexpr Index first() const noexcept {
return m_first.value(); }
179 constexpr Index size() const noexcept {
return m_size.value(); }
180 constexpr Index incr() const noexcept {
return m_incr.value(); }
183 variable_if_dynamicindex<Index, int(FirstAtCompileTime)> m_first;
184 variable_if_dynamic<Index, int(SizeAtCompileTime)> m_size;
185 variable_if_dynamicindex<Index, int(IncrAtCompileTime)> m_incr;
188template <
typename FirstType,
typename SizeType,
typename IncrType,
int NestedSizeAtCompileTime>
189struct IndexedViewHelperIndicesWrapper<ArithmeticSequence<FirstType, SizeType, IncrType>, NestedSizeAtCompileTime,
191 static constexpr Index EvalFirstAtCompileTime =
192 SymbolicExpressionEvaluator<FirstType, NestedSizeAtCompileTime>::ValueAtCompileTime;
193 static constexpr Index EvalSizeAtCompileTime =
194 SymbolicExpressionEvaluator<SizeType, NestedSizeAtCompileTime>::ValueAtCompileTime;
195 static constexpr Index EvalIncrAtCompileTime =
196 SymbolicExpressionEvaluator<IncrType, NestedSizeAtCompileTime>::ValueAtCompileTime;
198 static constexpr Index FirstAtCompileTime =
199 (int(EvalFirstAtCompileTime) == Undefined) ? Index(DynamicIndex) : EvalFirstAtCompileTime;
200 static constexpr Index SizeAtCompileTime =
201 (int(EvalSizeAtCompileTime) == Undefined) ? Index(Dynamic) : EvalSizeAtCompileTime;
202 static constexpr Index IncrAtCompileTime =
203 (int(EvalIncrAtCompileTime) == Undefined) ? Index(DynamicIndex) : EvalIncrAtCompileTime;
205 using Indices = ArithmeticSequence<FirstType, SizeType, IncrType>;
206 using type = ArithmeticSequenceRange<FirstAtCompileTime, SizeAtCompileTime, IncrAtCompileTime>;
208 static type CreateIndexSequence(
const Indices& indices, Index nested_size) {
210 SymbolicExpressionEvaluator<FirstType, NestedSizeAtCompileTime>::eval(indices.firstObject(), nested_size);
212 SymbolicExpressionEvaluator<SizeType, NestedSizeAtCompileTime>::eval(indices.sizeObject(), nested_size);
214 SymbolicExpressionEvaluator<IncrType, NestedSizeAtCompileTime>::eval(indices.incrObject(), nested_size);
215 return type(first, size, incr);
219template <Index FirstAtCompileTime_, Index SizeAtCompileTime_, Index IncrAtCompileTime_>
220struct IndexedViewHelper<ArithmeticSequenceRange<FirstAtCompileTime_, SizeAtCompileTime_, IncrAtCompileTime_>, void> {
222 using Indices = ArithmeticSequenceRange<FirstAtCompileTime_, SizeAtCompileTime_, IncrAtCompileTime_>;
223 static constexpr Index FirstAtCompileTime = Indices::FirstAtCompileTime;
224 static constexpr Index SizeAtCompileTime = Indices::SizeAtCompileTime;
225 static constexpr Index IncrAtCompileTime = Indices::IncrAtCompileTime;
226 static Index first(
const Indices& indices) {
return indices.first(); }
227 static Index size(
const Indices& indices) {
return indices.size(); }
228 static Index incr(
const Indices& indices) {
return indices.incr(); }
235template <Index ValueAtCompileTime>
238 static constexpr Index FirstAtCompileTime = ValueAtCompileTime;
239 static constexpr Index SizeAtCompileTime = Index(1);
240 static constexpr Index IncrAtCompileTime = Index(1);
242 constexpr SingleRange(Index v) noexcept : m_value(v) {}
243 constexpr Index operator[](Index)
const noexcept {
return first(); }
244 constexpr Index first() const noexcept {
return m_value.value(); }
245 constexpr Index size() const noexcept {
return SizeAtCompileTime; }
246 constexpr Index incr() const noexcept {
return IncrAtCompileTime; }
249 variable_if_dynamicindex<Index, int(ValueAtCompileTime)> m_value;
253struct is_single_range : std::false_type {};
255template <Index ValueAtCompileTime>
256struct is_single_range<SingleRange<ValueAtCompileTime>> : std::true_type {};
258template <
typename SingleIndex,
int NestedSizeAtCompileTime>
259struct IndexedViewHelperIndicesWrapper<
260 SingleIndex, NestedSizeAtCompileTime,
261 std::enable_if_t<std::is_integral<SingleIndex>::value || symbolic::is_symbolic<SingleIndex>::value>> {
262 static constexpr Index EvalValueAtCompileTime =
263 SymbolicExpressionEvaluator<SingleIndex, NestedSizeAtCompileTime>::ValueAtCompileTime;
264 static constexpr Index ValueAtCompileTime =
265 (int(EvalValueAtCompileTime) == Undefined) ? Index(DynamicIndex) : EvalValueAtCompileTime;
266 using type = SingleRange<ValueAtCompileTime>;
267 static type CreateIndexSequence(
const SingleIndex& index, Index nested_size) {
268 return type(SymbolicExpressionEvaluator<SingleIndex, NestedSizeAtCompileTime>::eval(index, nested_size));
272template <
int N,
int NestedSizeAtCompileTime>
273struct IndexedViewHelperIndicesWrapper<FixedInt<N>, NestedSizeAtCompileTime, void> {
274 using type = SingleRange<Index(N)>;
275 static type CreateIndexSequence(
const FixedInt<N>& ) {
return type(Index(N)); }
278template <Index ValueAtCompileTime>
279struct IndexedViewHelper<SingleRange<ValueAtCompileTime>, void> {
280 using Indices = SingleRange<ValueAtCompileTime>;
281 static constexpr Index FirstAtCompileTime = Indices::FirstAtCompileTime;
282 static constexpr Index SizeAtCompileTime = Indices::SizeAtCompileTime;
283 static constexpr Index IncrAtCompileTime = Indices::IncrAtCompileTime;
285 static constexpr Index first(
const Indices& indices) {
return indices.first(); }
286 static constexpr Index size(
const Indices& ) {
return SizeAtCompileTime; }
287 static constexpr Index incr(
const Indices& ) {
return IncrAtCompileTime; }
295template <Index SizeAtCompileTime_>
298 static constexpr Index FirstAtCompileTime = Index(0);
299 static constexpr Index SizeAtCompileTime = SizeAtCompileTime_;
300 static constexpr Index IncrAtCompileTime = Index(1);
301 constexpr AllRange(Index size) : m_size(size) {}
302 constexpr Index operator[](Index i)
const noexcept {
return i; }
303 constexpr Index first() const noexcept {
return FirstAtCompileTime; }
304 constexpr Index size() const noexcept {
return m_size.value(); }
305 constexpr Index incr() const noexcept {
return IncrAtCompileTime; }
308 variable_if_dynamic<Index, int(SizeAtCompileTime)> m_size;
311template <
int NestedSizeAtCompileTime>
312struct IndexedViewHelperIndicesWrapper<all_t, NestedSizeAtCompileTime, void> {
313 using type = AllRange<Index(NestedSizeAtCompileTime)>;
314 static type CreateIndexSequence(
const all_t& , Index nested_size) {
return type(nested_size); }
317template <Index SizeAtCompileTime_>
318struct IndexedViewHelper<AllRange<SizeAtCompileTime_>, void> {
319 using Indices = AllRange<SizeAtCompileTime_>;
320 static constexpr Index FirstAtCompileTime = Indices::FirstAtCompileTime;
321 static constexpr Index SizeAtCompileTime = Indices::SizeAtCompileTime;
322 static constexpr Index IncrAtCompileTime = Indices::IncrAtCompileTime;
324 static Index first(
const Indices& indices) {
return indices.first(); }
325 static Index size(
const Indices& indices) {
return indices.size(); }
326 static Index incr(
const Indices& indices) {
return indices.incr(); }
330template <
typename Derived,
typename RowIndices,
typename ColIndices,
typename EnableIf =
void>
331struct IndexedViewSelector;
333template <
typename Indices,
int SizeAtCompileTime>
334using IvcType =
typename internal::IndexedViewHelperIndicesWrapper<Indices, SizeAtCompileTime>::type;
336template <
int SizeAtCompileTime,
typename Indices>
337inline IvcType<Indices, SizeAtCompileTime> CreateIndexSequence(
size_t size,
const Indices& indices) {
338 return internal::IndexedViewHelperIndicesWrapper<Indices, SizeAtCompileTime>::CreateIndexSequence(indices, size);
342template <
typename Derived,
typename RowIndices,
typename ColIndices>
343struct IndexedViewSelector<Derived, RowIndices, ColIndices,
344 std::enable_if_t<internal::traits<
345 IndexedView<Derived, IvcType<RowIndices, Derived::RowsAtCompileTime>,
346 IvcType<ColIndices, Derived::ColsAtCompileTime>>>::ReturnAsIndexedView>> {
347 using ReturnType = IndexedView<Derived, IvcType<RowIndices, Derived::RowsAtCompileTime>,
348 IvcType<ColIndices, Derived::ColsAtCompileTime>>;
349 using ConstReturnType = IndexedView<const Derived, IvcType<RowIndices, Derived::RowsAtCompileTime>,
350 IvcType<ColIndices, Derived::ColsAtCompileTime>>;
352 static inline ReturnType run(Derived& derived,
const RowIndices& rowIndices,
const ColIndices& colIndices) {
353 return ReturnType(derived, CreateIndexSequence<Derived::RowsAtCompileTime>(derived.rows(), rowIndices),
354 CreateIndexSequence<Derived::ColsAtCompileTime>(derived.cols(), colIndices));
356 static inline ConstReturnType run(
const Derived& derived,
const RowIndices& rowIndices,
357 const ColIndices& colIndices) {
358 return ConstReturnType(derived, CreateIndexSequence<Derived::RowsAtCompileTime>(derived.rows(), rowIndices),
359 CreateIndexSequence<Derived::ColsAtCompileTime>(derived.cols(), colIndices));
364template <
typename Derived,
typename RowIndices,
typename ColIndices>
365struct IndexedViewSelector<
366 Derived, RowIndices, ColIndices,
367 std::enable_if_t<internal::traits<IndexedView<Derived, IvcType<RowIndices, Derived::RowsAtCompileTime>,
368 IvcType<ColIndices, Derived::ColsAtCompileTime>>>::ReturnAsBlock>> {
369 using ActualRowIndices = IvcType<RowIndices, Derived::RowsAtCompileTime>;
370 using ActualColIndices = IvcType<ColIndices, Derived::ColsAtCompileTime>;
371 using IndexedViewType = IndexedView<Derived, ActualRowIndices, ActualColIndices>;
372 using ConstIndexedViewType = IndexedView<const Derived, ActualRowIndices, ActualColIndices>;
373 using ReturnType =
typename internal::traits<IndexedViewType>::BlockType;
374 using ConstReturnType =
typename internal::traits<ConstIndexedViewType>::BlockType;
375 using RowHelper = internal::IndexedViewHelper<ActualRowIndices>;
376 using ColHelper = internal::IndexedViewHelper<ActualColIndices>;
378 static inline ReturnType run(Derived& derived,
const RowIndices& rowIndices,
const ColIndices& colIndices) {
379 auto actualRowIndices = CreateIndexSequence<Derived::RowsAtCompileTime>(derived.rows(), rowIndices);
380 auto actualColIndices = CreateIndexSequence<Derived::ColsAtCompileTime>(derived.cols(), colIndices);
381 return ReturnType(derived, RowHelper::first(actualRowIndices), ColHelper::first(actualColIndices),
382 RowHelper::size(actualRowIndices), ColHelper::size(actualColIndices));
384 static inline ConstReturnType run(
const Derived& derived,
const RowIndices& rowIndices,
385 const ColIndices& colIndices) {
386 auto actualRowIndices = CreateIndexSequence<Derived::RowsAtCompileTime>(derived.rows(), rowIndices);
387 auto actualColIndices = CreateIndexSequence<Derived::ColsAtCompileTime>(derived.cols(), colIndices);
388 return ConstReturnType(derived, RowHelper::first(actualRowIndices), ColHelper::first(actualColIndices),
389 RowHelper::size(actualRowIndices), ColHelper::size(actualColIndices));
394template <
typename Derived,
typename RowIndices,
typename ColIndices>
395struct IndexedViewSelector<
396 Derived, RowIndices, ColIndices,
397 std::enable_if_t<internal::traits<IndexedView<Derived, IvcType<RowIndices, Derived::RowsAtCompileTime>,
398 IvcType<ColIndices, Derived::ColsAtCompileTime>>>::ReturnAsScalar>> {
400 using ConstReturnType =
typename DenseBase<Derived>::CoeffReturnType;
401 using ActualRowIndices = IvcType<RowIndices, Derived::RowsAtCompileTime>;
402 using ActualColIndices = IvcType<ColIndices, Derived::ColsAtCompileTime>;
403 using RowHelper = internal::IndexedViewHelper<ActualRowIndices>;
404 using ColHelper = internal::IndexedViewHelper<ActualColIndices>;
405 static inline ReturnType run(Derived& derived,
const RowIndices& rowIndices,
const ColIndices& colIndices) {
406 auto actualRowIndices = CreateIndexSequence<Derived::RowsAtCompileTime>(derived.rows(), rowIndices);
407 auto actualColIndices = CreateIndexSequence<Derived::ColsAtCompileTime>(derived.cols(), colIndices);
408 return derived(RowHelper::first(actualRowIndices), ColHelper::first(actualColIndices));
410 static inline ConstReturnType run(
const Derived& derived,
const RowIndices& rowIndices,
411 const ColIndices& colIndices) {
412 auto actualRowIndices = CreateIndexSequence<Derived::RowsAtCompileTime>(derived.rows(), rowIndices);
413 auto actualColIndices = CreateIndexSequence<Derived::ColsAtCompileTime>(derived.cols(), colIndices);
414 return derived(RowHelper::first(actualRowIndices), ColHelper::first(actualColIndices));
419template <
typename Derived,
typename Indices,
typename EnableIf =
void>
420struct VectorIndexedViewSelector;
423template <
typename Derived,
typename Indices>
424struct VectorIndexedViewSelector<
426 std::enable_if_t<!internal::is_single_range<IvcType<Indices, Derived::SizeAtCompileTime>>::value &&
427 internal::IndexedViewHelper<IvcType<Indices, Derived::SizeAtCompileTime>>::IncrAtCompileTime !=
430 using ZeroIndex = internal::SingleRange<Index(0)>;
431 using RowMajorReturnType = IndexedView<Derived, ZeroIndex, IvcType<Indices, Derived::SizeAtCompileTime>>;
432 using ConstRowMajorReturnType = IndexedView<const Derived, ZeroIndex, IvcType<Indices, Derived::SizeAtCompileTime>>;
434 using ColMajorReturnType = IndexedView<Derived, IvcType<Indices, Derived::SizeAtCompileTime>, ZeroIndex>;
435 using ConstColMajorReturnType = IndexedView<const Derived, IvcType<Indices, Derived::SizeAtCompileTime>, ZeroIndex>;
437 using ReturnType = std::conditional_t<IsRowMajor, RowMajorReturnType, ColMajorReturnType>;
438 using ConstReturnType = std::conditional_t<IsRowMajor, ConstRowMajorReturnType, ConstColMajorReturnType>;
440 template <
bool UseRowMajor = IsRowMajor, std::enable_if_t<UseRowMajor,
bool> = true>
441 static inline RowMajorReturnType run(Derived& derived,
const Indices& indices) {
442 return RowMajorReturnType(derived, ZeroIndex(0),
443 CreateIndexSequence<Derived::ColsAtCompileTime>(derived.cols(), indices));
445 template <
bool UseRowMajor = IsRowMajor, std::enable_if_t<UseRowMajor,
bool> = true>
446 static inline ConstRowMajorReturnType run(
const Derived& derived,
const Indices& indices) {
447 return ConstRowMajorReturnType(derived, ZeroIndex(0),
448 CreateIndexSequence<Derived::ColsAtCompileTime>(derived.cols(), indices));
450 template <
bool UseRowMajor = IsRowMajor, std::enable_if_t<!UseRowMajor,
bool> = true>
451 static inline ColMajorReturnType run(Derived& derived,
const Indices& indices) {
452 return ColMajorReturnType(derived, CreateIndexSequence<Derived::RowsAtCompileTime>(derived.rows(), indices),
455 template <
bool UseRowMajor = IsRowMajor, std::enable_if_t<!UseRowMajor,
bool> = true>
456 static inline ConstColMajorReturnType run(
const Derived& derived,
const Indices& indices) {
457 return ConstColMajorReturnType(derived, CreateIndexSequence<Derived::RowsAtCompileTime>(derived.rows(), indices),
463template <
typename Derived,
typename Indices>
464struct VectorIndexedViewSelector<
466 std::enable_if_t<!internal::is_single_range<IvcType<Indices, Derived::SizeAtCompileTime>>::value &&
467 internal::IndexedViewHelper<IvcType<Indices, Derived::SizeAtCompileTime>>::IncrAtCompileTime ==
469 using Helper = internal::IndexedViewHelper<IvcType<Indices, Derived::SizeAtCompileTime>>;
470 using ReturnType = VectorBlock<Derived, Helper::SizeAtCompileTime>;
471 using ConstReturnType = VectorBlock<const Derived, Helper::SizeAtCompileTime>;
472 static inline ReturnType run(Derived& derived,
const Indices& indices) {
473 auto actualIndices = CreateIndexSequence<Derived::SizeAtCompileTime>(derived.size(), indices);
474 return ReturnType(derived, Helper::first(actualIndices), Helper::size(actualIndices));
476 static inline ConstReturnType run(
const Derived& derived,
const Indices& indices) {
477 auto actualIndices = CreateIndexSequence<Derived::SizeAtCompileTime>(derived.size(), indices);
478 return ConstReturnType(derived, Helper::first(actualIndices), Helper::size(actualIndices));
483template <
typename Derived,
typename Indices>
484struct VectorIndexedViewSelector<
486 std::enable_if_t<internal::is_single_range<IvcType<Indices, Derived::SizeAtCompileTime>>::value>> {
488 using ConstReturnType =
typename DenseBase<Derived>::CoeffReturnType;
489 using Helper = internal::IndexedViewHelper<IvcType<Indices, Derived::SizeAtCompileTime>>;
490 static inline ReturnType run(Derived& derived,
const Indices& indices) {
491 auto actualIndices = CreateIndexSequence<Derived::SizeAtCompileTime>(derived.size(), indices);
492 return derived(Helper::first(actualIndices));
494 static inline ConstReturnType run(
const Derived& derived,
const Indices& indices) {
495 auto actualIndices = CreateIndexSequence<Derived::SizeAtCompileTime>(derived.size(), indices);
496 return derived(Helper::first(actualIndices));
@ IsRowMajor
Definition DenseBase.h:167
typename internal::traits< Derived >::Scalar Scalar
Definition DenseBase.h:63
static constexpr const last_t last
Definition IndexedViewHelper.h:49
static constexpr Eigen::internal::all_t all
Definition IndexedViewHelper.h:86
static constexpr auto lastp1
Definition IndexedViewHelper.h:68
static constexpr lastp1_t end
Definition IndexedViewHelper.h:79