| // 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 |
| |
| namespace Eigen { |
| |
| namespace internal { |
| struct symbolic_last_tag {}; |
| } |
| |
| /** \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::last; |
| * VectorXd v(n); |
| * v(seq(2,last-2)).setOnes(); |
| * \endcode |
| * |
| * \sa end |
| */ |
| static const symbolic::SymbolExpr<internal::symbolic_last_tag> last; // PLEASE use Eigen::last instead of Eigen::placeholders::last |
| |
| /** \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 symbolic::AddExpr<symbolic::SymbolExpr<internal::symbolic_last_tag>,symbolic::ValueExpr<Eigen::internal::FixedInt<1> > > lastp1(last+fix<1>()); |
| #endif |
| |
| 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(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,typename internal::enable_if<internal::is_integral<T>::value>::type> { |
| // 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, typename enable_if<symbolic::is_symbolic<T>::value>::type> { |
| typedef SingleRange type; |
| }; |
| |
| |
| template<typename T> |
| typename enable_if<symbolic::is_symbolic<T>::value,SingleRange>::type |
| 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 |
| |
| |
| /** \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; // PLEASE use Eigen::all instead of Eigen::placeholders::all |
| |
| |
| namespace placeholders { |
| typedef symbolic::SymbolExpr<internal::symbolic_last_tag> last_t; |
| typedef symbolic::AddExpr<symbolic::SymbolExpr<internal::symbolic_last_tag>,symbolic::ValueExpr<Eigen::internal::FixedInt<1> > > end_t; |
| typedef Eigen::internal::all_t all_t; |
| |
| EIGEN_DEPRECATED static const all_t all = Eigen::all; // PLEASE use Eigen::all instead of Eigen::placeholders::all |
| EIGEN_DEPRECATED static const last_t last = Eigen::last; // PLEASE use Eigen::last instead of Eigen::placeholders::last |
| EIGEN_DEPRECATED static const end_t end = Eigen::lastp1; // PLEASE use Eigen::lastp1 instead of Eigen::placeholders::end |
| } |
| |
| } // end namespace Eigen |
| |
| #endif // EIGEN_INDEXED_VIEW_HELPER_H |