IndexedViewHelper.h (6696B)
1 // This file is part of Eigen, a lightweight C++ template library 2 // for linear algebra. 3 // 4 // Copyright (C) 2017 Gael Guennebaud <gael.guennebaud@inria.fr> 5 // 6 // This Source Code Form is subject to the terms of the Mozilla 7 // Public License v. 2.0. If a copy of the MPL was not distributed 8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 9 10 11 #ifndef EIGEN_INDEXED_VIEW_HELPER_H 12 #define EIGEN_INDEXED_VIEW_HELPER_H 13 14 namespace Eigen { 15 16 namespace internal { 17 struct symbolic_last_tag {}; 18 } 19 20 /** \var last 21 * \ingroup Core_Module 22 * 23 * Can be used as a parameter to Eigen::seq and Eigen::seqN functions to symbolically reference the last element/row/columns 24 * of the underlying vector or matrix once passed to DenseBase::operator()(const RowIndices&, const ColIndices&). 25 * 26 * This symbolic placeholder supports standard arithmetic operations. 27 * 28 * A typical usage example would be: 29 * \code 30 * using namespace Eigen; 31 * using Eigen::last; 32 * VectorXd v(n); 33 * v(seq(2,last-2)).setOnes(); 34 * \endcode 35 * 36 * \sa end 37 */ 38 static const symbolic::SymbolExpr<internal::symbolic_last_tag> last; // PLEASE use Eigen::last instead of Eigen::placeholders::last 39 40 /** \var lastp1 41 * \ingroup Core_Module 42 * 43 * Can be used as a parameter to Eigen::seq and Eigen::seqN functions to symbolically 44 * reference the last+1 element/row/columns of the underlying vector or matrix once 45 * passed to DenseBase::operator()(const RowIndices&, const ColIndices&). 46 * 47 * This symbolic placeholder supports standard arithmetic operations. 48 * It is essentially an alias to last+fix<1>. 49 * 50 * \sa last 51 */ 52 #ifdef EIGEN_PARSED_BY_DOXYGEN 53 static const auto lastp1 = last+fix<1>; 54 #else 55 // Using a FixedExpr<1> expression is important here to make sure the compiler 56 // can fully optimize the computation starting indices with zero overhead. 57 static const symbolic::AddExpr<symbolic::SymbolExpr<internal::symbolic_last_tag>,symbolic::ValueExpr<Eigen::internal::FixedInt<1> > > lastp1(last+fix<1>()); 58 #endif 59 60 namespace internal { 61 62 // Replace symbolic last/end "keywords" by their true runtime value 63 inline Index eval_expr_given_size(Index x, Index /* size */) { return x; } 64 65 template<int N> 66 FixedInt<N> eval_expr_given_size(FixedInt<N> x, Index /*size*/) { return x; } 67 68 template<typename Derived> 69 Index eval_expr_given_size(const symbolic::BaseExpr<Derived> &x, Index size) 70 { 71 return x.derived().eval(last=size-1); 72 } 73 74 // Extract increment/step at compile time 75 template<typename T, typename EnableIf = void> struct get_compile_time_incr { 76 enum { value = UndefinedIncr }; 77 }; 78 79 // Analogue of std::get<0>(x), but tailored for our needs. 80 template<typename T> 81 EIGEN_CONSTEXPR Index first(const T& x) EIGEN_NOEXCEPT { return x.first(); } 82 83 // IndexedViewCompatibleType/makeIndexedViewCompatible turn an arbitrary object of type T into something usable by MatrixSlice 84 // The generic implementation is a no-op 85 template<typename T,int XprSize,typename EnableIf=void> 86 struct IndexedViewCompatibleType { 87 typedef T type; 88 }; 89 90 template<typename T,typename Q> 91 const T& makeIndexedViewCompatible(const T& x, Index /*size*/, Q) { return x; } 92 93 //-------------------------------------------------------------------------------- 94 // Handling of a single Index 95 //-------------------------------------------------------------------------------- 96 97 struct SingleRange { 98 enum { 99 SizeAtCompileTime = 1 100 }; 101 SingleRange(Index val) : m_value(val) {} 102 Index operator[](Index) const { return m_value; } 103 static EIGEN_CONSTEXPR Index size() EIGEN_NOEXCEPT { return 1; } 104 Index first() const EIGEN_NOEXCEPT { return m_value; } 105 Index m_value; 106 }; 107 108 template<> struct get_compile_time_incr<SingleRange> { 109 enum { value = 1 }; // 1 or 0 ?? 110 }; 111 112 // Turn a single index into something that looks like an array (i.e., that exposes a .size(), and operator[](int) methods) 113 template<typename T, int XprSize> 114 struct IndexedViewCompatibleType<T,XprSize,typename internal::enable_if<internal::is_integral<T>::value>::type> { 115 // Here we could simply use Array, but maybe it's less work for the compiler to use 116 // a simpler wrapper as SingleRange 117 //typedef Eigen::Array<Index,1,1> type; 118 typedef SingleRange type; 119 }; 120 121 template<typename T, int XprSize> 122 struct IndexedViewCompatibleType<T, XprSize, typename enable_if<symbolic::is_symbolic<T>::value>::type> { 123 typedef SingleRange type; 124 }; 125 126 127 template<typename T> 128 typename enable_if<symbolic::is_symbolic<T>::value,SingleRange>::type 129 makeIndexedViewCompatible(const T& id, Index size, SpecializedType) { 130 return eval_expr_given_size(id,size); 131 } 132 133 //-------------------------------------------------------------------------------- 134 // Handling of all 135 //-------------------------------------------------------------------------------- 136 137 struct all_t { all_t() {} }; 138 139 // Convert a symbolic 'all' into a usable range type 140 template<int XprSize> 141 struct AllRange { 142 enum { SizeAtCompileTime = XprSize }; 143 AllRange(Index size = XprSize) : m_size(size) {} 144 EIGEN_CONSTEXPR Index operator[](Index i) const EIGEN_NOEXCEPT { return i; } 145 EIGEN_CONSTEXPR Index size() const EIGEN_NOEXCEPT { return m_size.value(); } 146 EIGEN_CONSTEXPR Index first() const EIGEN_NOEXCEPT { return 0; } 147 variable_if_dynamic<Index,XprSize> m_size; 148 }; 149 150 template<int XprSize> 151 struct IndexedViewCompatibleType<all_t,XprSize> { 152 typedef AllRange<XprSize> type; 153 }; 154 155 template<typename XprSizeType> 156 inline AllRange<get_fixed_value<XprSizeType>::value> makeIndexedViewCompatible(all_t , XprSizeType size, SpecializedType) { 157 return AllRange<get_fixed_value<XprSizeType>::value>(size); 158 } 159 160 template<int Size> struct get_compile_time_incr<AllRange<Size> > { 161 enum { value = 1 }; 162 }; 163 164 } // end namespace internal 165 166 167 /** \var all 168 * \ingroup Core_Module 169 * Can be used as a parameter to DenseBase::operator()(const RowIndices&, const ColIndices&) to index all rows or columns 170 */ 171 static const Eigen::internal::all_t all; // PLEASE use Eigen::all instead of Eigen::placeholders::all 172 173 174 namespace placeholders { 175 typedef symbolic::SymbolExpr<internal::symbolic_last_tag> last_t; 176 typedef symbolic::AddExpr<symbolic::SymbolExpr<internal::symbolic_last_tag>,symbolic::ValueExpr<Eigen::internal::FixedInt<1> > > end_t; 177 typedef Eigen::internal::all_t all_t; 178 179 EIGEN_DEPRECATED static const all_t all = Eigen::all; // PLEASE use Eigen::all instead of Eigen::placeholders::all 180 EIGEN_DEPRECATED static const last_t last = Eigen::last; // PLEASE use Eigen::last instead of Eigen::placeholders::last 181 EIGEN_DEPRECATED static const end_t end = Eigen::lastp1; // PLEASE use Eigen::lastp1 instead of Eigen::placeholders::end 182 } 183 184 } // end namespace Eigen 185 186 #endif // EIGEN_INDEXED_VIEW_HELPER_H