ndarray
NumPy-friendly multidimensional arrays in C++
Loading...
Searching...
No Matches
ViewBuilder.h
Go to the documentation of this file.
1// -*- c++ -*-
2/*
3 * Copyright (c) 2010-2012, Jim Bosch
4 * All rights reserved.
5 *
6 * ndarray is distributed under a simple BSD-like license;
7 * see the LICENSE file that should be present in the root
8 * of the source distribution, or alternately available at:
9 * https://github.com/ndarray/ndarray
10 */
11#ifndef NDARRAY_DETAIL_ViewBuilder_h_INCLUDED
12#define NDARRAY_DETAIL_ViewBuilder_h_INCLUDED
13
18#include "ndarray/views.h"
19#include <boost/fusion/include/push_back.hpp>
20#include <boost/fusion/include/pop_back.hpp>
21#include <boost/fusion/include/front.hpp>
22#include <boost/fusion/include/back.hpp>
23#include <boost/fusion/include/vector.hpp>
24#include <boost/fusion/include/reverse_view.hpp>
25#include <boost/fusion/include/mpl.hpp>
26#include <boost/fusion/include/at.hpp>
27#include <boost/fusion/include/at_c.hpp>
28#include <boost/fusion/tuple.hpp>
29#include <boost/mpl/count.hpp>
30#include <boost/mpl/size.hpp>
31#include <boost/mpl/fold.hpp>
32
33namespace ndarray {
34namespace detail {
35
40template <typename T, int M, int N>
42 T * _data;
43 typename Core<M>::ConstPtr _input;
44 typename Core<N>::Ptr _output;
45
47 T * data,
48 typename Core<M>::ConstPtr const & input,
49 typename Core<N>::Ptr const & output
50 ) : _data(data), _input(input), _output(output) {}
51
52 template <int M1, int N1>
54 _data(other._data), _input(other._input), _output(other._output) {}
55};
56
57template <int N, int C, int I>
58struct Dimensions {
59 typedef boost::mpl::int_<N> ND; // Number of dimensions in output array
60 typedef boost::mpl::int_<C> RMC; // Number of contiguous dimensions in output array, from end.
61 typedef boost::mpl::int_<I> IDX; // Current dimension of input array being processed.
62 typedef boost::mpl::int_<N-I> N_I;
63};
64
65template <typename Index> struct IndexTraits;
66
67template <>
68struct IndexTraits<ndarray::index::Slice> {
69
70 template <typename D>
71 struct Append {
72 typedef Dimensions<
73 D::ND::value,
74 ((D::RMC::value < D::N_I::value) ? D::RMC::value : (D::N_I::value - 1)),
75 (D::IDX::value + 1)
76 > Type;
77 };
78
80 template <typename T, int M, int N> struct TransformCoreResult {
81 typedef CoreTransformer<T,M-1,N-1> Type;
82 };
83
85 template <typename T, int M, int N>
86 static CoreTransformer<T,M-1,N-1> transformCore(
88 ) {
89 NDARRAY_ASSERT(index.step > 0);
90 NDARRAY_ASSERT(index.start <= index.stop);
91 NDARRAY_ASSERT(index.start >= 0);
92 NDARRAY_ASSERT(index.stop <= t._input->getSize());
93 t._data += index.start * t._input->getStride();
94 t._output->setSize(index.computeSize());
95 t._output->setStride(t._input->getStride() * index.step);
96 return t;
97 }
98
99};
100
101template <>
102struct IndexTraits<ndarray::index::Range> {
103
104 template <typename D>
105 struct Append {
106 typedef Dimensions<
107 D::ND::value,
108 ((D::RMC::value < D::N_I::value) ? D::RMC::value : D::N_I::value),
109 (D::IDX::value + 1)
110 > Type;
111 };
112
114 template <typename T, int M, int N> struct TransformCoreResult {
115 typedef CoreTransformer<T,M-1,N-1> Type;
116 };
117
119 template <typename T, int M, int N>
122 ) {
123 NDARRAY_ASSERT(index.start <= index.stop);
124 NDARRAY_ASSERT(index.start >= 0);
125 NDARRAY_ASSERT(index.stop <= t._input->getSize());
126 t._data += index.start * t._input->getStride();
127 t._output->setSize(index.stop - index.start);
128 t._output->setStride(t._input->getStride());
129 return t;
130 }
131};
132
133template <>
134struct IndexTraits<ndarray::index::Full> {
135
136 template <typename D>
137 struct Append {
138 typedef Dimensions<
139 D::ND::value,
140 D::RMC::value,
141 (D::IDX::value + 1)
142 > Type;
143 };
144
146 template <typename T, int M, int N> struct TransformCoreResult {
147 typedef CoreTransformer<T,M-1,N-1> Type;
148 };
149
151 template <typename T, int M, int N>
154 ) {
155 t._output->setSize(t._input->getSize());
156 t._output->setStride(t._input->getStride());
157 return t;
158 }
159};
160
161template <>
162struct IndexTraits<ndarray::index::Scalar> {
163
164 template <typename D>
165 struct Append {
166 typedef Dimensions<
167 (D::ND::value - 1),
168 ((D::RMC::value < (D::N_I::value - 1)) ? D::RMC::value : (D::N_I::value - 1)),
169 D::IDX::value
170 > Type;
171 };
172
174 template <typename T, int M, int N> struct TransformCoreResult {
175 typedef CoreTransformer<T,M-1,N> Type;
176 };
177
179 template <typename T, int M, int N>
182 ) {
183 NDARRAY_ASSERT(index.n >= 0);
184 NDARRAY_ASSERT(index.n < t._input->getSize());
185 t._data += index.n * t._input->getStride();
186 return t;
187 }
188};
189
190template <typename T, int M, int N, typename Index>
191typename IndexTraits<Index>::template TransformCoreResult<T,M,N>::Type
192transformCore(Index const & index, CoreTransformer<T,M,N> & t) {
193 return IndexTraits<Index>::transformCore(index, t);
194}
195
197
198 template <typename State, typename Index>
199 struct apply {
200 typedef typename IndexTraits<Index>::template Append<State>::Type type;
201 };
202
203};
204
205template <int N, int C, typename Seq_, bool isColumnMajor = (C < 0)>
206struct ViewTraits;
207
208template <int N, int C, typename Seq_>
210
211 typedef typename boost::mpl::fold< Seq_, Dimensions<N,C,0>, AppendIndex >::type Dims;
212
213 typedef typename Dims::ND ND;
214 typedef typename Dims::RMC RMC;
215
216};
217
218template <int N, int C, typename Seq_>
219struct ViewTraits<N,C,Seq_,true> {
220
221 typedef typename boost::mpl::fold<
222 boost::fusion::reverse_view< typename boost::fusion::result_of::as_vector<Seq_>::type >,
223 Dimensions<N,-C,0>, AppendIndex
224 >::type Dims;
225
226 typedef typename Dims::ND ND;
227 typedef typename boost::mpl::negate<typename Dims::RMC>::type RMC;
228
229};
230
235template <int N, typename Seq_, bool IsNormalized=(boost::mpl::template size<Seq_>::type::value==N)>
237
238 typedef typename boost::fusion::result_of::push_back<Seq_ const,index::Full>::type Next;
239
240 typedef typename ViewNormalizer<N,Next>::Output Output;
241
242 static Output apply(Seq_ const & input) {
244 boost::fusion::push_back(input, index::Full())
245 );
246 }
247};
248
249template <int N, typename Seq_>
251 typedef typename boost::fusion::result_of::as_vector<Seq_>::type Output;
252 static Output apply(Seq_ const & input) { return boost::fusion::as_vector(input); }
253};
254
259template <typename Array_, typename InSeq>
262 typedef typename Traits::Element Element;
263 typedef typename Traits::ND InputND;
264 typedef typename Traits::RMC InputRMC;
265 typedef typename Traits::Core InputCore;
266 typedef boost::mpl::bool_<(InputRMC::value < 0)> IsColumnMajor;
267
269 typedef typename ViewNormalizer<InputND::value,InSeq>::Output NormSeq;
271
272 typedef typename OutputTraits::ND OutputND;
273 typedef typename OutputTraits::RMC OutputRMC;
274
277
278 static OutputArray apply(Array_ const & array, InSeq const & seq) {
280 array.getData(),
282 OutputCore::create(array.getManager())
283 );
284 NormSeq normSeq = Normalizer::apply(seq);
285 std::pair<Element*,typename OutputCore::Ptr> final = process(normSeq, initial);
286 return ArrayAccess< OutputArray >::construct(final.first, final.second);
287 }
288
289 template <int M, int N>
290 static std::pair<Element*,typename OutputCore::Ptr>
291 process(NormSeq const & seq, CoreTransformer<Element,M,N> t) {
292 return process(seq, transformCore(boost::fusion::at_c<(InputND::value-M)>(seq), t));
293 }
294
295 static std::pair<Element*,typename OutputCore::Ptr>
296 process(NormSeq const & seq, CoreTransformer<Element,0,0> t) {
297 return std::make_pair(t._data, boost::static_pointer_cast<OutputCore>(t._output));
298 }
299
300};
301
306template <typename Array_, typename Seq_>
308buildView(Array_ const & array, Seq_ const & seq) {
309 return ViewBuilder<Array_,Seq_>::apply(array, seq);
310};
311
312} // namespace detail
313
314} // namespace ndarray
315
316#endif // !NDARRAY_DETAIL_ViewBuilder_h_INCLUDED
A proxy class for Array with deep assignment operators.
Definition ArrayRef.h:34
Definition ArrayAccess.h:26
Definition Core.h:47
Size getSize() const
Return the size of the Nth dimension.
Definition Core.h:88
boost::intrusive_ptr< Core > Ptr
intrusive_ptr to Core
Definition Core.h:51
boost::intrusive_ptr< Core const > ConstPtr
const intrusive_ptr to Core
Definition Core.h:52
Offset getStride() const
Return the stride of the Nth dimension.
Definition Core.h:91
Traits for expressions.
Definition ExpressionTraits.h:30
Definition ViewBuilder.h:199
Definition ViewBuilder.h:196
Definition ViewBuilder.h:41
Definition ViewBuilder.h:58
static CoreTransformer< T, M-1, N-1 > transformCore(ndarray::index::Full const &, CoreTransformer< T, M, N > &t)
Apply a full dimension index.
Definition ViewBuilder.h:152
static CoreTransformer< T, M-1, N-1 > transformCore(ndarray::index::Range const &index, CoreTransformer< T, M, N > &t)
Apply a range index.
Definition ViewBuilder.h:120
static CoreTransformer< T, M-1, N > transformCore(ndarray::index::Scalar const &index, CoreTransformer< T, M, N > &t)
Apply a scalar dimension index.
Definition ViewBuilder.h:180
static CoreTransformer< T, M-1, N-1 > transformCore(ndarray::index::Slice const &index, CoreTransformer< T, M, N > &t)
Apply a slice index.
Definition ViewBuilder.h:86
Definition ViewBuilder.h:65
Definition ViewBuilder.h:260
Definition ViewBuilder.h:236
Definition ViewBuilder.h:206
Empty structure marking a view of an entire dimension.
Definition views.h:54
Simple structure defining a contiguous range of indices.
Definition views.h:44
Structure marking a single element of a dimension.
Definition views.h:59
Simple structure defining a noncontiguous range of indices.
Definition views.h:31
Public interface for arbitrary views into arrays.