| // 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 {}; | |
| struct all_t {}; | |
| } // 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 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; | |
| /** \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 constexpr 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 constexpr lastp1_t lastp1 = lastp1_t{}; | |
| #endif | |
| /** \var end | |
| * \ingroup Core_Module | |
| * \sa lastp1 | |
| */ | |
| static constexpr 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 constexpr Eigen::internal::all_t all; | |
| } // namespace placeholders | |
| namespace internal { | |
| // Evaluate a symbolic expression or constant given the "size" of an object, allowing | |
| // any symbols like `last` to be evaluated. The default here assumes a dynamic constant. | |
| template <typename Expr, int SizeAtCompileTime, typename EnableIf = void> | |
| struct SymbolicExpressionEvaluator { | |
| static constexpr Index ValueAtCompileTime = Undefined; | |
| static Index eval(const Expr& expr, Index /*size*/) { return static_cast<Index>(expr); } | |
| }; | |
| // Symbolic expression with size known at compile-time. | |
| 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 /*size*/) { | |
| return expr.eval(Eigen::placeholders::last = fix<SizeAtCompileTime - 1>); | |
| } | |
| }; | |
| // Symbolic expression with dynamic size. | |
| 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); } | |
| }; | |
| // Fixed int. | |
| 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>& /*expr*/, Index /*size*/) { return ValueAtCompileTime; } | |
| }; | |
| //-------------------------------------------------------------------------------- | |
| // Handling of generic indices (e.g. array) | |
| //-------------------------------------------------------------------------------- | |
| // Potentially wrap indices in a type that is better-suited for IndexedView evaluation. | |
| template <typename Indices, int NestedSizeAtCompileTime, typename EnableIf = void> | |
| struct IndexedViewHelperIndicesWrapper { | |
| using type = Indices; | |
| static const type& CreateIndexSequence(const Indices& indices, Index /*nested_size*/) { return indices; } | |
| }; | |
| // Extract compile-time and runtime first, size, increments. | |
| 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& /*indices*/) { return Undefined; } | |
| }; | |
| //-------------------------------------------------------------------------------- | |
| // Handling of ArithmeticSequence | |
| //-------------------------------------------------------------------------------- | |
| 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) : m_first{first}, m_size{size}, m_incr{incr} {} | |
| constexpr Index operator[](Index i) const { return first() + i * incr(); } | |
| constexpr Index first() const noexcept { return m_first.value(); } | |
| constexpr Index size() const noexcept { return m_size.value(); } | |
| constexpr Index incr() const noexcept { return m_incr.value(); } | |
| private: | |
| variable_if_dynamicindex<Index, int(FirstAtCompileTime)> m_first; | |
| variable_if_dynamic<Index, int(SizeAtCompileTime)> m_size; | |
| variable_if_dynamicindex<Index, int(IncrAtCompileTime)> m_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(); } | |
| }; | |
| //-------------------------------------------------------------------------------- | |
| // Handling of a single index. | |
| //-------------------------------------------------------------------------------- | |
| template <Index ValueAtCompileTime> | |
| class SingleRange { | |
| public: | |
| static constexpr Index FirstAtCompileTime = ValueAtCompileTime; | |
| static constexpr Index SizeAtCompileTime = Index(1); | |
| static constexpr Index IncrAtCompileTime = Index(1); // Needs to be 1 to be treated as block-like. | |
| constexpr SingleRange(Index v) noexcept : m_value(v) {} | |
| constexpr Index operator[](Index) const noexcept { return first(); } | |
| constexpr Index first() const noexcept { return m_value.value(); } | |
| constexpr Index size() const noexcept { return SizeAtCompileTime; } | |
| constexpr Index incr() const noexcept { return IncrAtCompileTime; } | |
| private: | |
| variable_if_dynamicindex<Index, int(ValueAtCompileTime)> m_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>& /*index*/) { 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& /*indices*/) { return SizeAtCompileTime; } | |
| static constexpr Index incr(const Indices& /*indices*/) { return IncrAtCompileTime; } | |
| }; | |
| //-------------------------------------------------------------------------------- | |
| // Handling of all | |
| //-------------------------------------------------------------------------------- | |
| // Convert a symbolic 'all' into a usable range type | |
| 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) : m_size(size) {} | |
| constexpr Index operator[](Index i) const noexcept { return i; } | |
| constexpr Index first() const noexcept { return FirstAtCompileTime; } | |
| constexpr Index size() const noexcept { return m_size.value(); } | |
| constexpr Index incr() const noexcept { return IncrAtCompileTime; } | |
| private: | |
| variable_if_dynamic<Index, int(SizeAtCompileTime)> m_size; | |
| }; | |
| template <int NestedSizeAtCompileTime> | |
| struct IndexedViewHelperIndicesWrapper<all_t, NestedSizeAtCompileTime, void> { | |
| using type = AllRange<Index(NestedSizeAtCompileTime)>; | |
| static type CreateIndexSequence(const all_t& /*indices*/, 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(); } | |
| }; | |
| // this helper class assumes internal::valid_indexed_view_overload<RowIndices, ColIndices>::value == true | |
| 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); | |
| } | |
| // Generic | |
| 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)); | |
| } | |
| }; | |
| // Block | |
| 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)); | |
| } | |
| }; | |
| // Scalar | |
| 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)); | |
| } | |
| }; | |
| // this helper class assumes internal::is_valid_index_type<Indices>::value == false | |
| template <typename Derived, typename Indices, typename EnableIf = void> | |
| struct VectorIndexedViewSelector; | |
| // Generic | |
| 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)); | |
| } | |
| }; | |
| // Block | |
| 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)); | |
| } | |
| }; | |
| // Symbolic | |
| 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)); | |
| } | |
| }; | |
| } // end namespace internal | |
| } // end namespace Eigen | |
| #endif // EIGEN_INDEXED_VIEW_HELPER_H |