LSSTApplications  10.0+286,10.0+36,10.0+46,10.0-2-g4f67435,10.1+152,10.1+37,11.0,11.0+1,11.0-1-g47edd16,11.0-1-g60db491,11.0-1-g7418c06,11.0-2-g04d2804,11.0-2-g68503cd,11.0-2-g818369d,11.0-2-gb8b8ce7
LSSTDataManagementBasePackage
ViewBuilder.h
Go to the documentation of this file.
1 // -*- c++ -*-
2 /*
3  * LSST Data Management System
4  * Copyright 2008, 2009, 2010, 2011 LSST Corporation.
5  *
6  * This product includes software developed by the
7  * LSST Project (http://www.lsst.org/).
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the LSST License Statement and
20  * the GNU General Public License along with this program. If not,
21  * see <http://www.lsstcorp.org/LegalNotices/>.
22  */
23 #ifndef NDARRAY_DETAIL_ViewBuilder_h_INCLUDED
24 #define NDARRAY_DETAIL_ViewBuilder_h_INCLUDED
25 
30 #include "ndarray/views.h"
31 #include <boost/fusion/include/push_back.hpp>
32 #include <boost/fusion/include/pop_back.hpp>
33 #include <boost/fusion/include/front.hpp>
34 #include <boost/fusion/include/back.hpp>
35 #include <boost/fusion/include/vector.hpp>
36 #include <boost/fusion/include/reverse_view.hpp>
37 #include <boost/fusion/include/mpl.hpp>
38 #include <boost/fusion/include/at.hpp>
39 #include <boost/fusion/include/at_c.hpp>
40 #include <boost/fusion/tuple.hpp>
41 #include <boost/mpl/count.hpp>
42 #include <boost/mpl/size.hpp>
43 #include <boost/mpl/fold.hpp>
44 
45 namespace ndarray {
46 namespace detail {
47 
52 template <typename T, int M, int N>
54  T * _data;
57 
59  T * data,
60  typename Core<M>::ConstPtr const & input,
61  typename Core<N>::Ptr const & output
62  ) : _data(data), _input(input), _output(output) {}
63 
64  template <int M1, int N1>
66  _data(other._data), _input(other._input), _output(other._output) {}
67 };
68 
69 template <int N, int C, int I>
70 struct Dimensions {
71  typedef boost::mpl::int_<N> ND; // Number of dimensions in output array
72  typedef boost::mpl::int_<C> RMC; // Number of contiguous dimensions in output array, from end.
73  typedef boost::mpl::int_<I> IDX; // Current dimension of input array being processed.
74  typedef boost::mpl::int_<N-I> N_I;
75 };
76 
77 template <typename Index> struct IndexTraits;
78 
79 template <>
80 struct IndexTraits<ndarray::index::Slice> {
81 
82  template <typename D>
83  struct Append {
84  typedef Dimensions<
85  D::ND::value,
86  ((D::RMC::value < D::N_I::value) ? D::RMC::value : (D::N_I::value - 1)),
87  (D::IDX::value + 1)
88  > Type;
89  };
90 
92  template <typename T, int M, int N> struct TransformCoreResult {
93  typedef CoreTransformer<T,M-1,N-1> Type;
94  };
95 
97  template <typename T, int M, int N>
98  static CoreTransformer<T,M-1,N-1> transformCore(
100  ) {
101  NDARRAY_ASSERT(index.step > 0);
102  NDARRAY_ASSERT(index.start <= index.stop);
103  NDARRAY_ASSERT(index.start >= 0);
104  NDARRAY_ASSERT(index.stop <= t._input->getSize());
105  t._data += index.start * t._input->getStride();
106  t._output->setSize(index.computeSize());
107  t._output->setStride(t._input->getStride() * index.step);
108  return t;
109  }
110 
111 };
112 
113 template <>
114 struct IndexTraits<ndarray::index::Range> {
115 
116  template <typename D>
117  struct Append {
118  typedef Dimensions<
119  D::ND::value,
120  ((D::RMC::value < D::N_I::value) ? D::RMC::value : D::N_I::value),
121  (D::IDX::value + 1)
122  > Type;
123  };
124 
126  template <typename T, int M, int N> struct TransformCoreResult {
127  typedef CoreTransformer<T,M-1,N-1> Type;
128  };
129 
131  template <typename T, int M, int N>
132  static CoreTransformer<T,M-1,N-1> transformCore(
134  ) {
135  NDARRAY_ASSERT(index.start <= index.stop);
136  NDARRAY_ASSERT(index.start >= 0);
137  NDARRAY_ASSERT(index.stop <= t._input->getSize());
138  t._data += index.start * t._input->getStride();
139  t._output->setSize(index.stop - index.start);
140  t._output->setStride(t._input->getStride());
141  return t;
142  }
143 };
144 
145 template <>
146 struct IndexTraits<ndarray::index::Full> {
147 
148  template <typename D>
149  struct Append {
150  typedef Dimensions<
151  D::ND::value,
152  D::RMC::value,
153  (D::IDX::value + 1)
154  > Type;
155  };
156 
158  template <typename T, int M, int N> struct TransformCoreResult {
159  typedef CoreTransformer<T,M-1,N-1> Type;
160  };
161 
163  template <typename T, int M, int N>
164  static CoreTransformer<T,M-1,N-1> transformCore(
166  ) {
167  t._output->setSize(t._input->getSize());
168  t._output->setStride(t._input->getStride());
169  return t;
170  }
171 };
172 
173 template <>
174 struct IndexTraits<ndarray::index::Scalar> {
175 
176  template <typename D>
177  struct Append {
178  typedef Dimensions<
179  (D::ND::value - 1),
180  ((D::RMC::value < (D::N_I::value - 1)) ? D::RMC::value : (D::N_I::value - 1)),
181  (D::IDX::value + 1)
182  > Type;
183  };
184 
186  template <typename T, int M, int N> struct TransformCoreResult {
187  typedef CoreTransformer<T,M-1,N> Type;
188  };
189 
191  template <typename T, int M, int N>
194  ) {
195  NDARRAY_ASSERT(index.n >= 0);
196  NDARRAY_ASSERT(index.n < t._input->getSize());
197  t._data += index.n * t._input->getStride();
198  return t;
199  }
200 };
201 
202 template <typename T, int M, int N, typename Index>
203 typename IndexTraits<Index>::template TransformCoreResult<T,M,N>::Type
204 transformCore(Index const & index, CoreTransformer<T,M,N> & t) {
205  return IndexTraits<Index>::transformCore(index, t);
206 }
207 
208 struct AppendIndex {
209 
210  template <typename State, typename Index>
211  struct apply {
212  typedef typename IndexTraits<Index>::template Append<State>::Type type;
213  };
214 
215 };
216 
217 template <int N, int C, typename Seq_, bool isColumnMajor = (C < 0)>
218 struct ViewTraits;
219 
220 template <int N, int C, typename Seq_>
222 
223  typedef typename boost::mpl::fold< Seq_, Dimensions<N,C,0>, AppendIndex >::type Dims;
224 
225  typedef typename Dims::ND ND;
226  typedef typename Dims::RMC RMC;
227 
228 };
229 
230 template <int N, int C, typename Seq_>
231 struct ViewTraits<N,C,Seq_,true> {
232 
233  typedef typename boost::mpl::fold<
234  boost::fusion::reverse_view< typename boost::fusion::result_of::as_vector<Seq_>::type >,
235  Dimensions<N,-C,0>, AppendIndex
236  >::type Dims;
237 
238  typedef typename Dims::ND ND;
239  typedef typename boost::mpl::negate<typename Dims::RMC>::type RMC;
240 
241 };
242 
247 template <int N, typename Seq_, bool IsNormalized=(boost::mpl::template size<Seq_>::type::value==N)>
249 
250  typedef typename boost::fusion::result_of::push_back<Seq_ const,index::Full>::type Next;
251 
253 
254  static Output apply(Seq_ const & input) {
256  boost::fusion::push_back(input, index::Full())
257  );
258  }
259 };
260 
261 template <int N, typename Seq_>
262 struct ViewNormalizer<N,Seq_,true> {
263  typedef typename boost::fusion::result_of::as_vector<Seq_>::type Output;
264  static Output apply(Seq_ const & input) { return boost::fusion::as_vector(input); }
265 };
266 
271 template <typename Array_, typename InSeq>
272 struct ViewBuilder {
274  typedef typename Traits::Element Element;
275  typedef typename Traits::ND InputND;
276  typedef typename Traits::RMC InputRMC;
277  typedef typename Traits::Core InputCore;
278  typedef boost::mpl::bool_<(InputRMC::value < 0)> IsColumnMajor;
279 
283 
284  typedef typename OutputTraits::ND OutputND;
285  typedef typename OutputTraits::RMC OutputRMC;
286 
289 
290  static OutputArray apply(Array_ const & array, InSeq const & seq) {
292  array.getData(),
294  OutputCore::create(array.getManager())
295  );
296  NormSeq normSeq = Normalizer::apply(seq);
297  std::pair<Element*,typename OutputCore::Ptr> final = process(normSeq, initial);
298  return ArrayAccess< OutputArray >::construct(final.first, final.second);
299  }
300 
301  template <int M, int N>
302  static std::pair<Element*,typename OutputCore::Ptr>
304  return process(seq, transformCore(boost::fusion::at_c<(InputND::value-M)>(seq), t));
305  }
306 
307  static std::pair<Element*,typename OutputCore::Ptr>
309  return std::make_pair(t._data, boost::static_pointer_cast<OutputCore>(t._output));
310  }
311 
312 };
313 
318 template <typename Array_, typename Seq_>
319 typename ViewBuilder<Array_, Seq_>::OutputArray
320 buildView(Array_ const & array, Seq_ const & seq) {
321  return ViewBuilder<Array_,Seq_>::apply(array, seq);
322 };
323 
324 } // namespace detail
325 
326 } // namespace ndarray
327 
328 #endif // !NDARRAY_DETAIL_ViewBuilder_h_INCLUDED
Core< M >::ConstPtr _input
Definition: ViewBuilder.h:55
A proxy class for Array with deep assignment operators.
Definition: ArrayRef.h:46
static Ptr create(Vector< int, M > const &shape, Vector< int, M > const &strides, Manager::Ptr const &manager=Manager::Ptr())
Create a Core::Ptr with the given shape, strides, and manager.
Definition: Core.h:68
int getStride() const
Return the stride of the Nth dimension.
Definition: Core.h:103
ViewTraits< InputND::value, InputRMC::value, NormSeq > OutputTraits
Definition: ViewBuilder.h:282
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:164
int getSize() const
Return the size of the Nth dimension.
Definition: Core.h:100
boost::mpl::int_< I > IDX
Definition: ViewBuilder.h:73
boost::fusion::result_of::as_vector< Seq_ >::type Output
Definition: ViewBuilder.h:263
Dimensions< (D::ND::value-1),((D::RMC::value< (D::N_I::value-1))?D::RMC::value:(D::N_I::value-1)),(D::IDX::value+1) > Type
Definition: ViewBuilder.h:182
IndexTraits< Index >::template TransformCoreResult< T, M, N >::Type transformCore(Index const &index, CoreTransformer< T, M, N > &t)
Definition: ViewBuilder.h:204
boost::intrusive_ptr< Core > Ptr
intrusive_ptr to Core
Definition: Core.h:63
Simple structure defining a contiguous range of indices.
Definition: views.h:54
boost::mpl::fold< Seq_, Dimensions< N, C, 0 >, AppendIndex >::type Dims
Definition: ViewBuilder.h:223
ViewNormalizer< InputND::value, InSeq > Normalizer
Definition: ViewBuilder.h:280
ViewNormalizer< N, Next >::Output Output
Definition: ViewBuilder.h:252
ExpressionTraits< Array_ > Traits
Definition: ViewBuilder.h:273
static Array_ construct(Element *data, CorePtr const &core)
Definition: ArrayAccess.h:48
boost::mpl::int_< C > RMC
Definition: ViewBuilder.h:72
Core< OutputND::value > OutputCore
Definition: ViewBuilder.h:288
Simple structure defining a noncontiguous range of indices.
Definition: views.h:41
boost::mpl::negate< typename Dims::RMC >::type RMC
Definition: ViewBuilder.h:239
static std::pair< Element *, typename OutputCore::Ptr > process(NormSeq const &seq, CoreTransformer< Element, M, N > t)
Definition: ViewBuilder.h:303
static Output apply(Seq_ const &input)
Definition: ViewBuilder.h:264
OutputTraits::ND OutputND
Definition: ViewBuilder.h:284
#define NDARRAY_ASSERT(ARG)
Definition: ndarray_fwd.h:51
CoreTransformer(CoreTransformer< T, M1, N1 > const &other)
Definition: ViewBuilder.h:65
static std::pair< Element *, typename OutputCore::Ptr > process(NormSeq const &seq, CoreTransformer< Element, 0, 0 > t)
Definition: ViewBuilder.h:308
IndexTraits< Index >::template Append< State >::Type type
Definition: ViewBuilder.h:212
Traits for expressions.
int computeSize() const
Definition: views.h:48
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:132
Empty structure marking a view of an entire dimension.
Definition: views.h:64
boost::mpl::bool_<(InputRMC::value< 0)> IsColumnMajor
Definition: ViewBuilder.h:278
boost::mpl::int_< N > ND
Definition: ViewBuilder.h:71
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:192
static OutputArray apply(Array_ const &array, InSeq const &seq)
Definition: ViewBuilder.h:290
Structure marking a single element of a dimension.
Definition: views.h:69
static CorePtr const & getCore(Array_ const &array)
Definition: ArrayAccess.h:44
static Output apply(Seq_ const &input)
Definition: ViewBuilder.h:254
ViewNormalizer< InputND::value, InSeq >::Output NormSeq
Definition: ViewBuilder.h:281
OutputTraits::RMC OutputRMC
Definition: ViewBuilder.h:285
ArrayRef< Element, OutputND::value, OutputRMC::value > OutputArray
Definition: ViewBuilder.h:287
boost::fusion::result_of::push_back< Seq_ const, index::Full >::type Next
Definition: ViewBuilder.h:250
boost::mpl::fold< boost::fusion::reverse_view< typename boost::fusion::result_of::as_vector< Seq_ >::type >, Dimensions< N,-C, 0 >, AppendIndex >::type Dims
Definition: ViewBuilder.h:236
CoreTransformer(T *data, typename Core< M >::ConstPtr const &input, typename Core< N >::Ptr const &output)
Definition: ViewBuilder.h:58
boost::mpl::int_< N-I > N_I
Definition: ViewBuilder.h:74
Public interface for arbitrary views into arrays.
ViewBuilder< Array_, Seq_ >::OutputArray buildView(Array_ const &array, Seq_ const &seq)
Definition: ViewBuilder.h:320
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:98
Dimensions< D::ND::value,((D::RMC::value< D::N_I::value)?D::RMC::value:(D::N_I::value-1)),(D::IDX::value+1) > Type
Definition: ViewBuilder.h:88