IndexedViewMethods.h
Go to the documentation of this file.
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 #if !defined(EIGEN_PARSED_BY_DOXYGEN)
12 
13 protected:
14 // define some aliases to ease readability
15 
16 template <typename Indices>
17 using IvcRowType = typename internal::IndexedViewCompatibleType<Indices, RowsAtCompileTime>::type;
18 
19 template <typename Indices>
20 using IvcColType = typename internal::IndexedViewCompatibleType<Indices, ColsAtCompileTime>::type;
21 
22 template <typename Indices>
23 using IvcType = typename internal::IndexedViewCompatibleType<Indices, SizeAtCompileTime>::type;
24 
25 typedef typename internal::IndexedViewCompatibleType<Index, 1>::type IvcIndex;
26 
27 template <typename Indices>
28 inline IvcRowType<Indices> ivcRow(const Indices& indices) const {
30  indices, internal::variable_if_dynamic<Index, RowsAtCompileTime>(derived().rows()), Specialized);
31 }
32 
33 template <typename Indices>
34 inline IvcColType<Indices> ivcCol(const Indices& indices) const {
36  indices, internal::variable_if_dynamic<Index, ColsAtCompileTime>(derived().cols()), Specialized);
37 }
38 
39 template <typename Indices>
40 inline IvcType<Indices> ivcSize(const Indices& indices) const {
42  indices, internal::variable_if_dynamic<Index, SizeAtCompileTime>(derived().size()), Specialized);
43 }
44 
45 // this helper class assumes internal::valid_indexed_view_overload<RowIndices, ColIndices>::value == true
46 template <typename RowIndices, typename ColIndices,
47  bool UseSymbolic = internal::traits<IndexedView<Derived, IvcRowType<RowIndices>, IvcColType<ColIndices>>>::ReturnAsScalar,
48  bool UseBlock = internal::traits<IndexedView<Derived, IvcRowType<RowIndices>, IvcColType<ColIndices>>>::ReturnAsBlock,
49  bool UseGeneric = internal::traits<IndexedView<Derived, IvcRowType<RowIndices>, IvcColType<ColIndices>>>::ReturnAsIndexedView>
50 struct IndexedViewSelector;
51 
52 // Generic
53 template <typename RowIndices, typename ColIndices>
54 struct IndexedViewSelector<RowIndices, ColIndices, false, false, true> {
55  using ReturnType = IndexedView<Derived, IvcRowType<RowIndices>, IvcColType<ColIndices>>;
56  using ConstReturnType = IndexedView<const Derived, IvcRowType<RowIndices>, IvcColType<ColIndices>>;
57 
58  static inline ReturnType run(Derived& derived, const RowIndices& rowIndices, const ColIndices& colIndices) {
59  return ReturnType(derived, derived.ivcRow(rowIndices), derived.ivcCol(colIndices));
60  }
61  static inline ConstReturnType run(const Derived& derived, const RowIndices& rowIndices,
62  const ColIndices& colIndices) {
63  return ConstReturnType(derived, derived.ivcRow(rowIndices), derived.ivcCol(colIndices));
64  }
65 };
66 
67 // Block
68 template <typename RowIndices, typename ColIndices>
69 struct IndexedViewSelector<RowIndices, ColIndices, false, true, false> {
70  using IndexedViewType = IndexedView<Derived, IvcRowType<RowIndices>, IvcColType<ColIndices>>;
71  using ConstIndexedViewType = IndexedView<const Derived, IvcRowType<RowIndices>, IvcColType<ColIndices>>;
72  using ReturnType = typename internal::traits<IndexedViewType>::BlockType;
73  using ConstReturnType = typename internal::traits<ConstIndexedViewType>::BlockType;
74 
75  static inline ReturnType run(Derived& derived, const RowIndices& rowIndices, const ColIndices& colIndices) {
76  IvcRowType<RowIndices> actualRowIndices = derived.ivcRow(rowIndices);
77  IvcColType<ColIndices> actualColIndices = derived.ivcCol(colIndices);
78  return ReturnType(derived, internal::first(actualRowIndices), internal::first(actualColIndices),
79  internal::index_list_size(actualRowIndices), internal::index_list_size(actualColIndices));
80  }
81  static inline ConstReturnType run(const Derived& derived, const RowIndices& rowIndices,
82  const ColIndices& colIndices) {
83  IvcRowType<RowIndices> actualRowIndices = derived.ivcRow(rowIndices);
84  IvcColType<ColIndices> actualColIndices = derived.ivcCol(colIndices);
85  return ConstReturnType(derived, internal::first(actualRowIndices), internal::first(actualColIndices),
86  internal::index_list_size(actualRowIndices), internal::index_list_size(actualColIndices));
87  }
88 };
89 
90 // Symbolic
91 template <typename RowIndices, typename ColIndices>
92 struct IndexedViewSelector<RowIndices, ColIndices, true, false, false> {
93  using ReturnType = typename DenseBase<Derived>::Scalar&;
94  using ConstReturnType = typename DenseBase<Derived>::CoeffReturnType;
95 
96  static inline ReturnType run(Derived& derived, const RowIndices& rowIndices, const ColIndices& colIndices) {
97  return derived(internal::eval_expr_given_size(rowIndices, derived.rows()),
98  internal::eval_expr_given_size(colIndices, derived.cols()));
99  }
100  static inline ConstReturnType run(const Derived& derived, const RowIndices& rowIndices,
101  const ColIndices& colIndices) {
102  return derived(internal::eval_expr_given_size(rowIndices, derived.rows()),
103  internal::eval_expr_given_size(colIndices, derived.cols()));
104  }
105 };
106 
107 // this helper class assumes internal::is_valid_index_type<Indices>::value == false
108 template <typename Indices,
109  bool UseSymbolic = symbolic::is_symbolic<Indices>::value,
110  bool UseBlock = !UseSymbolic && internal::get_compile_time_incr<IvcType<Indices>>::value == 1,
111  bool UseGeneric = !UseSymbolic && !UseBlock>
112 struct VectorIndexedViewSelector;
113 
114 // Generic
115 template <typename Indices>
116 struct VectorIndexedViewSelector<Indices, false, false, true> {
117 
118  static constexpr bool IsRowMajor = DenseBase<Derived>::IsRowMajor;
119 
120  using RowMajorReturnType = IndexedView<Derived, IvcIndex, IvcType<Indices>>;
121  using ConstRowMajorReturnType = IndexedView<const Derived, IvcIndex, IvcType<Indices>>;
122 
123  using ColMajorReturnType = IndexedView<Derived, IvcType<Indices>, IvcIndex>;
124  using ConstColMajorReturnType = IndexedView<const Derived, IvcType<Indices>, IvcIndex>;
125 
126  using ReturnType = typename internal::conditional<IsRowMajor, RowMajorReturnType, ColMajorReturnType>::type;
127  using ConstReturnType =
128  typename internal::conditional<IsRowMajor, ConstRowMajorReturnType, ConstColMajorReturnType>::type;
129 
130  template <bool UseRowMajor = IsRowMajor, std::enable_if_t<UseRowMajor, bool> = true>
131  static inline RowMajorReturnType run(Derived& derived, const Indices& indices) {
132  return RowMajorReturnType(derived, IvcIndex(0), derived.ivcCol(indices));
133  }
134  template <bool UseRowMajor = IsRowMajor, std::enable_if_t<UseRowMajor, bool> = true>
135  static inline ConstRowMajorReturnType run(const Derived& derived, const Indices& indices) {
136  return ConstRowMajorReturnType(derived, IvcIndex(0), derived.ivcCol(indices));
137  }
138  template <bool UseRowMajor = IsRowMajor, std::enable_if_t<!UseRowMajor, bool> = true>
139  static inline ColMajorReturnType run(Derived& derived, const Indices& indices) {
140  return ColMajorReturnType(derived, derived.ivcRow(indices), IvcIndex(0));
141  }
142  template <bool UseRowMajor = IsRowMajor, std::enable_if_t<!UseRowMajor, bool> = true>
143  static inline ConstColMajorReturnType run(const Derived& derived, const Indices& indices) {
144  return ConstColMajorReturnType(derived, derived.ivcRow(indices), IvcIndex(0));
145  }
146 };
147 
148 // Block
149 template <typename Indices>
150 struct VectorIndexedViewSelector<Indices, false, true, false> {
151 
152  using ReturnType = VectorBlock<Derived, internal::array_size<Indices>::value>;
153  using ConstReturnType = VectorBlock<const Derived, internal::array_size<Indices>::value>;
154 
155  static inline ReturnType run(Derived& derived, const Indices& indices) {
156  IvcType<Indices> actualIndices = derived.ivcSize(indices);
157  return ReturnType(derived, internal::first(actualIndices), internal::index_list_size(actualIndices));
158  }
159  static inline ConstReturnType run(const Derived& derived, const Indices& indices) {
160  IvcType<Indices> actualIndices = derived.ivcSize(indices);
161  return ConstReturnType(derived, internal::first(actualIndices), internal::index_list_size(actualIndices));
162  }
163 };
164 
165 // Symbolic
166 template <typename Indices>
167 struct VectorIndexedViewSelector<Indices, true, false, false> {
168 
169  using ReturnType = typename DenseBase<Derived>::Scalar&;
170  using ConstReturnType = typename DenseBase<Derived>::CoeffReturnType;
171 
172  static inline ReturnType run(Derived& derived, const Indices& id) {
173  return derived(internal::eval_expr_given_size(id, derived.size()));
174  }
175  static inline ConstReturnType run(const Derived& derived, const Indices& id) {
176  return derived(internal::eval_expr_given_size(id, derived.size()));
177  }
178 };
179 
180 // SFINAE dummy types
181 
182 template <typename RowIndices, typename ColIndices>
183 using EnableOverload = std::enable_if_t<
184  internal::valid_indexed_view_overload<RowIndices, ColIndices>::value && internal::is_lvalue<Derived>::value, bool>;
185 
186 template <typename RowIndices, typename ColIndices>
187 using EnableConstOverload =
188  std::enable_if_t<internal::valid_indexed_view_overload<RowIndices, ColIndices>::value, bool>;
189 
190 template <typename Indices>
191 using EnableVectorOverload =
192  std::enable_if_t<!internal::is_valid_index_type<Indices>::value && internal::is_lvalue<Derived>::value, bool>;
193 
194 template <typename Indices>
195 using EnableConstVectorOverload = std::enable_if_t<!internal::is_valid_index_type<Indices>::value, bool>;
196 
197 public:
198 
199 // Public API for 2D matrices/arrays
200 
201 // non-const versions
202 
203 template <typename RowIndices, typename ColIndices>
204 using IndexedViewType = typename IndexedViewSelector<RowIndices, ColIndices>::ReturnType;
205 
206 template <typename RowIndices, typename ColIndices, EnableOverload<RowIndices, ColIndices> = true>
207 IndexedViewType<RowIndices, ColIndices> operator()(const RowIndices& rowIndices, const ColIndices& colIndices) {
208  return IndexedViewSelector<RowIndices, ColIndices>::run(derived(), rowIndices, colIndices);
209 }
210 
211 template <typename RowType, size_t RowSize, typename ColIndices, typename RowIndices = Array<RowType, RowSize, 1>,
212  EnableOverload<RowIndices, ColIndices> = true>
213 IndexedViewType<RowIndices, ColIndices> operator()(const RowType (&rowIndices)[RowSize], const ColIndices& colIndices) {
214  return IndexedViewSelector<RowIndices, ColIndices>::run(derived(), RowIndices{rowIndices}, colIndices);
215 }
216 
217 template <typename RowIndices, typename ColType, size_t ColSize, typename ColIndices = Array<ColType, ColSize, 1>,
218  EnableOverload<RowIndices, ColIndices> = true>
219 IndexedViewType<RowIndices, ColIndices> operator()(const RowIndices& rowIndices, const ColType (&colIndices)[ColSize]) {
220  return IndexedViewSelector<RowIndices, ColIndices>::run(derived(), rowIndices, ColIndices{colIndices});
221 }
222 
223 template <typename RowType, size_t RowSize, typename ColType, size_t ColSize,
224  typename RowIndices = Array<RowType, RowSize, 1>, typename ColIndices = Array<ColType, ColSize, 1>,
225  EnableOverload<RowIndices, ColIndices> = true>
226 IndexedViewType<RowIndices, ColIndices> operator()(const RowType (&rowIndices)[RowSize],
227  const ColType (&colIndices)[ColSize]) {
228  return IndexedViewSelector<RowIndices, ColIndices>::run(derived(), RowIndices{rowIndices}, ColIndices{colIndices});
229 }
230 
231 // const versions
232 
233 template <typename RowIndices, typename ColIndices>
234 using ConstIndexedViewType = typename IndexedViewSelector<RowIndices, ColIndices>::ConstReturnType;
235 
236 template <typename RowIndices, typename ColIndices, EnableConstOverload<RowIndices, ColIndices> = true>
237 ConstIndexedViewType<RowIndices, ColIndices> operator()(const RowIndices& rowIndices,
238  const ColIndices& colIndices) const {
239  return IndexedViewSelector<RowIndices, ColIndices>::run(derived(), rowIndices, colIndices);
240 }
241 
242 template <typename RowType, size_t RowSize, typename ColIndices, typename RowIndices = Array<RowType, RowSize, 1>,
243  EnableConstOverload<RowIndices, ColIndices> = true>
244 ConstIndexedViewType<RowIndices, ColIndices> operator()(const RowType (&rowIndices)[RowSize],
245  const ColIndices& colIndices) const {
246  return IndexedViewSelector<RowIndices, ColIndices>::run(derived(), RowIndices{rowIndices}, colIndices);
247 }
248 
249 template <typename RowIndices, typename ColType, size_t ColSize, typename ColIndices = Array<ColType, ColSize, 1>,
250  EnableConstOverload<RowIndices, ColIndices> = true>
251 ConstIndexedViewType<RowIndices, ColIndices> operator()(const RowIndices& rowIndices,
252  const ColType (&colIndices)[ColSize]) const {
253  return IndexedViewSelector<RowIndices, ColIndices>::run(derived(), rowIndices, ColIndices{colIndices});
254 }
255 
256 template <typename RowType, size_t RowSize, typename ColType, size_t ColSize,
257  typename RowIndices = Array<RowType, RowSize, 1>, typename ColIndices = Array<ColType, ColSize, 1>,
258  EnableConstOverload<RowIndices, ColIndices> = true>
259 ConstIndexedViewType<RowIndices, ColIndices> operator()(const RowType (&rowIndices)[RowSize],
260  const ColType (&colIndices)[ColSize]) const {
261  return IndexedViewSelector<RowIndices, ColIndices>::run(derived(), RowIndices{rowIndices}, ColIndices{colIndices});
262 }
263 
264 // Public API for 1D vectors/arrays
265 
266 // non-const versions
267 
268 template <typename Indices>
269 using VectorIndexedViewType = typename VectorIndexedViewSelector<Indices>::ReturnType;
270 
271 template <typename Indices, EnableVectorOverload<Indices> = true>
272 VectorIndexedViewType<Indices> operator()(const Indices& indices) {
274  return VectorIndexedViewSelector<Indices>::run(derived(), indices);
275 }
276 
277 template <typename IndexType, size_t Size, typename Indices = Array<IndexType, Size, 1>,
278  EnableVectorOverload<Indices> = true>
279 VectorIndexedViewType<Indices> operator()(const IndexType (&indices)[Size]) {
281  return VectorIndexedViewSelector<Indices>::run(derived(), Indices{indices});
282 }
283 
284 // const versions
285 
286 template <typename Indices>
287 using ConstVectorIndexedViewType = typename VectorIndexedViewSelector<Indices>::ConstReturnType;
288 
289 template <typename Indices, EnableConstVectorOverload<Indices> = true>
290 ConstVectorIndexedViewType<Indices> operator()(const Indices& indices) const {
292  return VectorIndexedViewSelector<Indices>::run(derived(), indices);
293 }
294 
295 template <typename IndexType, size_t Size, typename Indices = Array<IndexType, Size, 1>,
296  EnableConstVectorOverload<Indices> = true>
297 ConstVectorIndexedViewType<Indices> operator()(const IndexType (&indices)[Size]) const {
299  return VectorIndexedViewSelector<Indices>::run(derived(), Indices{indices});
300 }
301 
302 #else // EIGEN_PARSED_BY_DOXYGEN
303 
338 template<typename RowIndices, typename ColIndices>
339 IndexedView_or_Block
340 operator()(const RowIndices& rowIndices, const ColIndices& colIndices);
341 
346 template<typename Indices>
347 IndexedView_or_VectorBlock
348 operator()(const Indices& indices);
349 
350 #endif // EIGEN_PARSED_BY_DOXYGEN
IndexedView_or_Block operator()(const RowIndices &rowIndices, const ColIndices &colIndices)
#define EIGEN_STATIC_ASSERT_VECTOR_ONLY(TYPE)
Definition: StaticAssert.h:36
Index eval_expr_given_size(Index x, Index)
EIGEN_CONSTEXPR Index first(const T &x) EIGEN_NOEXCEPT
ArithmeticSequence< Index, typename make_size_type< SizeType >::type, IncrType > makeIndexedViewCompatible(const ArithmeticSequence< FirstType, SizeType, IncrType > &ids, Index size, SpecializedType)
EIGEN_CONSTEXPR auto index_list_size(const T &x)
Definition: Meta.h:241
@ Specialized
Definition: Constants.h:312