astrotypes  0.0
MultiArray.h
Go to the documentation of this file.
1 /*
2  * MIT License
3  *
4  * Copyright (c) 2018 PulsarSearchSoft
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 #ifndef PSS_ASTROTYPES_MULTIARRAY_H
25 #define PSS_ASTROTYPES_MULTIARRAY_H
26 
27 #include "Slice.h"
28 #include "DimensionSize.h"
29 #include "DimensionIndex.h"
30 #include <vector>
31 
32 namespace pss {
33 namespace astrotypes {
34 
41 template<typename Alloc, typename T, template<typename> class SliceMixin, typename FirstDimension, typename... OtherDimensions>
42 class MultiArray : MultiArray<Alloc, T, SliceMixin, OtherDimensions...>
43 {
44  typedef MultiArray<Alloc, T, SliceMixin, OtherDimensions...> BaseT;
45  typedef MultiArray<Alloc, T, SliceMixin, FirstDimension, OtherDimensions...> SelfType;
46  typedef std::vector<T, Alloc> Container;
47 
48  public:
49  typedef typename BaseT::iterator iterator;
51  typedef typename BaseT::value_type value_type;
52 
53  public:
59  template<typename Dim>
60  struct OperatorSliceType;
61 
67  template<typename Dim>
68  struct ConstOperatorSliceType;
69 
70  typedef SliceMixin<Slice<false, SelfType, SliceMixin, FirstDimension, OtherDimensions...>> SliceType;
71  typedef SliceMixin<Slice<true, SelfType, SliceMixin, FirstDimension, OtherDimensions...>> ConstSliceType;
72  typedef typename SliceType::template OperatorSliceType<FirstDimension>::type ReducedDimensionSliceType;
73  typedef typename ConstSliceType::template ConstOperatorSliceType<FirstDimension>::type ConstReducedDimensionSliceType;
74 
75  typedef T& reference_type;
76  typedef T const& const_reference_type;
77 
78  public:
79  template<typename Dim, typename... Dims>
81 
83  explicit MultiArray(MultiArray const&) = default;
84 
86  // @details will copy the memory from the object tranposing it in the process
87  // to the required memory order
88  template<typename DimensionType, typename Enable=typename std::enable_if<
89  has_dimensions<DimensionType, FirstDimension, OtherDimensions...>::value
90  && !has_exact_dimensions<FirstDimension, OtherDimensions...>::value>::type>
91  explicit MultiArray(DimensionType const&);
92 
98  inline iterator begin();
99  inline iterator end();
100  inline const_iterator begin() const;
101  inline const_iterator end() const;
102  inline const_iterator cbegin() const;
103  inline const_iterator cend() const;
104 
121  ReducedDimensionSliceType operator[](DimensionIndex<FirstDimension> index);
122  ConstReducedDimensionSliceType operator[](DimensionIndex<FirstDimension> index) const;
123 
124  template<typename Dim>
125  typename std::enable_if<has_dimension<MultiArray, Dim>::value
126  && !std::is_same<Dim, FirstDimension>::value
127  , typename OperatorSliceType<Dim>::type>::type
129 
130  template<typename Dim>
131  typename std::enable_if<has_dimension<MultiArray, Dim>::value
132  && !std::is_same<Dim, FirstDimension>::value
133  , typename ConstOperatorSliceType<Dim>::type>::type
134  operator[](DimensionIndex<Dim> const&) const;
135 
156  template<typename Dim, typename... Dims>
157  SliceType slice(DimensionSpan<Dim> const& range, DimensionSpan<Dims> const&...);
158 
159  template<typename Dim, typename... Dims>
160  ConstSliceType slice(DimensionSpan<Dim> const& range, DimensionSpan<Dims> const&...) const;
161 
165  template<typename... Dimensions>
166  void resize(DimensionSize<Dimensions>... size);
167 
173  template<typename Dim, typename... Dimensions>
174  void resize(DimensionSize<Dim>, DimensionSize<Dimensions>... size, T const& value);
175 
182  template<typename Dim>
183  typename std::enable_if<std::is_same<Dim, FirstDimension>::value, DimensionSize<FirstDimension>>::type
184  size() const;
185 
186  template<typename Dim>
187  typename std::enable_if<!std::is_same<Dim, FirstDimension>::value, DimensionSize<Dim>>::type
188  size() const;
189 
190  template<typename Dim>
191  typename std::enable_if<std::is_same<Dim, FirstDimension>::value, DimensionSize<FirstDimension>>::type
192  dimension() const;
193 
194  template<typename Dim>
195  typename std::enable_if<!std::is_same<Dim, FirstDimension>::value, DimensionSize<Dim>>::type
196  dimension() const;
197 
201  std::size_t data_size() const;
202 
206  bool operator==(MultiArray const&) const;
207 
211  bool equal_size(MultiArray const&) const;
212 
213  protected:
214  template<typename... Dims>
215  MultiArray(typename std::enable_if<arg_helper<FirstDimension, Dims...>::value, bool>::type disable_resize_tag
216  , DimensionSize<Dims> const&...);
217 
218  template<typename DimensionType>
219  MultiArray(typename std::enable_if<has_dimensions<DimensionType, FirstDimension, OtherDimensions...>::value, bool>::type disable_transpose_tag
220  , DimensionType const& d);
221 
222  template<typename Dimension, typename... Dims>
223  typename std::enable_if<!arg_helper<FirstDimension, Dimension, Dims...>::value, void>::type
224  do_resize(std::size_t total, DimensionSize<Dimension> size, DimensionSize<Dims>... sizes);
225 
226  template<typename Dimension, typename... Dims>
227  typename std::enable_if<!arg_helper<FirstDimension, Dimension, Dims...>::value, void>::type
228  do_resize(std::size_t total, DimensionSize<Dimension> size, DimensionSize<Dims>... sizes, T const& value);
229 
230  template<typename Dimension, typename... Dims>
231  typename std::enable_if<arg_helper<FirstDimension, Dimension, Dims...>::value, void>::type
232  do_resize(std::size_t total, DimensionSize<Dimension> size, DimensionSize<Dims>... sizes);
233 
234  template<typename Dimension, typename... Dims>
235  typename std::enable_if<arg_helper<FirstDimension, Dimension, Dims...>::value, void>::type
236  do_resize(std::size_t total, DimensionSize<Dimension> size, DimensionSize<Dims>... sizes, T const& value);
237 
238  void do_resize(std::size_t total);
239  void do_resize(std::size_t total, T const& value);
240 
241  template<typename SelfSlice, typename OtherSlice>
242  void do_transpose(SelfSlice&, OtherSlice const&);
243 
244  private:
246 };
247 
248 // specialisation for single dimension arrays
249 template<typename Alloc, typename T, template<typename> class SliceMixin, typename FirstDimension>
250 class MultiArray<Alloc, T, SliceMixin, FirstDimension>
251 {
253  typedef std::vector<T, Alloc> Container;
254 
255  public:
261  template<typename Dim>
262  struct OperatorSliceType;
263 
269  template<typename Dim>
270  struct ConstOperatorSliceType;
271 
272  typedef SliceMixin<Slice<false, SelfType, SliceMixin, FirstDimension>> SliceType;
273  typedef SliceMixin<Slice<true, SelfType, SliceMixin, FirstDimension>> ConstSliceType;
274  typedef typename Container::iterator iterator;
275  typedef typename Container::const_iterator const_iterator;
276 
277  typedef T& reference_type;
278  typedef T const& const_reference_type;
279  typedef T value_type;
280 
281  public:
282  template<typename Dim, typename... Dims>
283  MultiArray(DimensionSize<Dim> const& size, DimensionSize<Dims> const&... sizes);
284  explicit MultiArray(MultiArray const&) = default;
285  ~MultiArray();
286 
287 
291  reference_type operator[](DimensionIndex<FirstDimension> index);
292  const_reference_type operator[](DimensionIndex<FirstDimension> index) const;
293 
295  template<typename Dim>
296  typename std::enable_if<std::is_same<Dim, FirstDimension>::value, DimensionSize<FirstDimension>>::type
297  size() const;
298 
299  template<typename Dim>
300  typename std::enable_if<!std::is_same<Dim, FirstDimension>::value, DimensionSize<Dim>>::type
301  size() const;
302 
303  template<typename Dim>
304  typename std::enable_if<std::is_same<Dim, FirstDimension>::value, DimensionSize<FirstDimension>>::type
305  dimension() const;
306 
307  template<typename Dim>
308  typename std::enable_if<!std::is_same<Dim, FirstDimension>::value, DimensionSize<Dim>>::type
309  dimension() const;
310 
314  std::size_t data_size() const;
315 
319  template<typename Dimension>
320  void resize(DimensionSize<Dimension> size);
321 
325  template<typename Dimension>
326  void resize(DimensionSize<Dimension> size, T const& value);
327 
331  bool operator==(MultiArray const&) const;
332 
336  bool equal_size(MultiArray const&) const;
337 
339  inline iterator begin();
340  inline const_iterator begin() const;
341  inline const_iterator cbegin() const;
342  inline iterator end();
343  inline const_iterator end() const;
344  inline const_iterator cend() const;
345 
346  protected:
347  template<typename... Dims>
348  MultiArray(typename std::enable_if<arg_helper<FirstDimension, Dims...>::value, bool>::type disable_resize_tag
349  , DimensionSize<Dims> const&...);
350 
351  template<typename DimensionType>
352  MultiArray(typename std::enable_if<has_dimension<DimensionType, FirstDimension>::value, bool>::type disable_transpose_tag
353  , DimensionType const& d);
354 
356  template<typename Dimension, typename... Dims>
357  typename std::enable_if<arg_helper<FirstDimension, Dimension, Dims...>::value, void>::type
358  do_resize(std::size_t total_size, DimensionSize<Dimension> size, DimensionSize<Dims>...);
359 
360  template<typename Dimension, typename... Dims>
361  typename std::enable_if<arg_helper<FirstDimension, Dimension, Dims...>::value, void>::type
362  do_resize(std::size_t total_size, DimensionSize<Dimension> size, DimensionSize<Dims>..., T const& value);
363 
364  template<typename... Dims>
365  typename std::enable_if<!arg_helper<FirstDimension, Dims...>::value, void>::type
366  do_resize(std::size_t total_size, DimensionSize<Dims>...);
367 
368  template<typename... Dims>
369  typename std::enable_if<!arg_helper<FirstDimension, Dims...>::value, void>::type
370  do_resize(std::size_t total_size, DimensionSize<Dims>..., T const& value);
371 
372  template<typename SelfSlice, typename OtherSlice>
373  void do_transpose(SelfSlice&, OtherSlice const&);
374 
375  private:
377  std::vector<T> _data;
378 };
379 
380 template<typename Alloc, typename T, template<typename> class SliceMixin, typename Dimension>
381 struct has_dimension<MultiArray<Alloc, T, SliceMixin, Dimension>, Dimension> : public std::true_type
382 {};
383 
384 template<typename Alloc, typename T, template<typename> class SliceMixin, typename Dimension>
385 struct has_exact_dimensions<MultiArray<Alloc, T, SliceMixin, Dimension>, Dimension> : public std::true_type
386 {};
387 
388 template<typename Alloc, typename T, template<typename> class SliceMixin, typename Dimension1, typename Dimension2, typename... Dimensions>
389 struct has_exact_dimensions<MultiArray<Alloc, T, SliceMixin, Dimension1, Dimension2, Dimensions...>, Dimension1, Dimension2, Dimensions...> : public std::true_type
390 {};
391 
392 } // namespace astrotypes
393 } // namespace pss
394 
395 #include "detail/MultiArray.cpp"
396 
397 #endif // PSS_ASTROTYPES_MULTIARRAY_H
const_iterator cend() const
Definition: MultiArray.cpp:169
BaseT::iterator iterator
Definition: MultiArray.h:49
A tagged dimensionIndex variable.
Defines a contiguous range over dimension in index.
Definition: DimensionSpan.h:41
std::enable_if< std::is_same< Dim, FirstDimension >::value, DimensionSize< FirstDimension > >::type size() const
return a slice of the specified dimension spanning the index_range provided
std::size_t data_size() const
the total size of data in all dimensions
Definition: MultiArray.cpp:313
ConstSliceType::template ConstOperatorSliceType< FirstDimension >::type ConstReducedDimensionSliceType
Definition: MultiArray.h:73
Representation of a Slice through a Data Array.
Definition: Slice.h:105
MultiArray(DimensionSize< Dim > size, DimensionSize< Dims >...sizes)
Definition: MultiArray.cpp:88
std::enable_if<!arg_helper< FirstDimension, Dimension, Dims...>::value, void >::type do_resize(std::size_t total, DimensionSize< Dimension > size, DimensionSize< Dims >...sizes)
SliceMixin< Slice< false, SelfType, SliceMixin, FirstDimension, OtherDimensions...> > SliceType
Definition: MultiArray.h:68
SliceMixin< Slice< true, SelfType, SliceMixin, FirstDimension, OtherDimensions...> > ConstSliceType
Definition: MultiArray.h:71
void do_transpose(SelfSlice &, OtherSlice const &)
const_iterator cbegin() const
Definition: MultiArray.cpp:151
ReducedDimensionSliceType operator[](DimensionIndex< FirstDimension > index)
take a slice of width 1 data at the specified index of the first dimension
Definition: MultiArray.cpp:175
bool operator==(MultiArray const &) const
compare data in the two arrays
Definition: MultiArray.cpp:325
return true if the Dimensions provided match exactly those of the structure T (including order) ...
Definition: TypeTraits.h:107
A compile time dimesion tagging of size_t.
Definition: DimensionSize.h:39
BaseT::value_type value_type
Definition: MultiArray.h:51
BaseT::const_iterator const_iterator
Definition: MultiArray.h:50
return true if the all Dimensions provided are represented in the structure
Definition: TypeTraits.h:84
SliceType::template OperatorSliceType< FirstDimension >::type ReducedDimensionSliceType
Definition: MultiArray.h:72
iterator begin()
iterators acting over he entire data structure
Definition: MultiArray.cpp:139
SliceMixin< Slice< true, SelfType, SliceMixin, FirstDimension > > ConstSliceType
Definition: MultiArray.h:273
bool equal_size(MultiArray const &) const
return true if the sizes of each dimension are equivalent
Definition: MultiArray.cpp:319
return true if the Dimension is represented in the structure
Definition: TypeTraits.h:71
SliceMixin< Slice< false, SelfType, SliceMixin, FirstDimension > > SliceType
Definition: MultiArray.h:270
template classes to specify multiple dimension arrays with explicit dimension types ...
Definition: MultiArray.h:42
std::enable_if< std::is_same< Dim, FirstDimension >::value, DimensionSize< FirstDimension > >::type dimension() const