astrotypes  0.0
Slice.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_SLICE_H
25 #define PSS_ASTROTYPES_MULTIARRAY_SLICE_H
26 #include "DimensionSpan.h"
27 #include "SliceIterator.h"
28 #include "TypeTraits.h"
29 #include "detail/SlicePosition.h"
30 #include <utility>
31 
32 namespace pss {
33 namespace astrotypes {
34 
35 template<typename T, typename... Dims>
36 struct arg_helper : public std::false_type
37 {
38 };
39 
40 template<typename T, typename... Dims>
41 struct arg_helper<T, T, Dims...> : public std::true_type
42 {
43  static inline
44  T&& arg(T&& arg, Dims&&...)
45  { return std::forward<T>(arg); }
46 };
47 
48 template<typename T, typename Dim, typename... Dims>
49 struct arg_helper<T, Dim, Dims...> : public arg_helper<T, Dims...>
50 {
51  typedef arg_helper<T, Dims...> BaseT;
52 
53  static inline
54  T&& arg(Dim&&, Dims&&...args)
55  { return BaseT::arg(std::forward<Dims>(args)...); }
56 };
57 
72 
73 template<typename ParentT, typename ExcludeDimension>
75  typedef ParentT Parent;
76  typedef std::tuple<ExcludeDimension> ExcludeTuple;
77 };
78 
79 template<typename Traits, typename ExcludeDimension, typename D>
80 struct InternalSliceTraits<InternalSliceTraits<Traits, D>, ExcludeDimension> : public InternalSliceTraits<Traits, D>
81 {
82  private:
84  public:
85  typedef typename BaseT::Parent Parent;
87 };
88 
89 template<typename TraitsT>
91 {
92  typedef std::tuple<> ExcludeTuple;
93  typedef TraitsT Parent;
94 };
95 
96 template<typename TraitsT, typename D>
98 {
101 };
102 
103 template<bool is_const, typename SliceTraitsT, template<typename> class SliceMixin, typename Dimension, typename... Dimensions>
104 //class Slice : private Slice<is_const, SliceTraitsT, SliceMixin, Dimensions...>
105 class Slice : private Slice<is_const, InternalSliceTraits<SliceTraitsT, Dimension>, SliceMixin, Dimensions...>
106 {
107  typedef typename SliceTraitsHelper<SliceTraitsT>::Parent ParentT;
108  typedef Slice<is_const, InternalSliceTraits<SliceTraitsT, Dimension>, SliceMixin, Dimensions...> BaseT;
109  typedef Slice<is_const, SliceTraitsT, SliceMixin, Dimension, Dimensions...> SelfType;
110  typedef typename ParentT::value_type value_type;
111  typedef Dimension SelfDimension;
112 
113  typedef typename ParentT::const_iterator parent_const_iterator;
114  typedef typename std::conditional<is_const, parent_const_iterator, typename ParentT::iterator>::type parent_iterator;
115 
116  protected:
118  typedef std::tuple<Dimension, Dimensions...> DimensionTuple;
119 
120  public:
122  // @tparam Dim the dimension that will be called
123  // @param type The type that will we returned by the operator[DimensionIndex<Dim>]
124  template<typename Dim>
125  struct OperatorSliceType;
126 
127  template<typename Dim>
129 
130  typedef typename std::conditional<is_const, const ParentT, ParentT>::type Parent;
132  typedef SliceIterator<SliceMixin<SelfType>, true> const_iterator;
133  typedef SliceMixin<Slice<is_const, SliceTraitsT, SliceMixin, Dimension, Dimensions...>> SliceType;
134  typedef SliceMixin<BaseT> ReducedSliceType;
135  typedef SliceMixin<Slice<true, SliceTraitsT, SliceMixin, Dimension, Dimensions...>> ConstSliceType;
136  typedef SliceMixin<Slice<true, InternalSliceTraits<SliceTraitsT, Dimension>, SliceMixin, Dimensions...>> ConstReducedSliceType;
137 
138  public:
139  template<typename Dim, typename... Dims>
140  Slice( typename std::enable_if<arg_helper<Dimension, Dim, Dims...>::value, Parent&>::type parent
141  , DimensionSpan<Dim> const&
142  , DimensionSpan<Dims> const& ...);
143 
144  template<typename Dim, typename... Dims>
145  Slice( typename std::enable_if<!arg_helper<Dimension, Dim, Dims...>::value, Parent&>::type parent
146  , DimensionSpan<Dim> const&
147  , DimensionSpan<Dims> const& ...);
148 
149  static constexpr std::size_t rank = 1 + sizeof...(Dimensions);
150 
154  std::size_t data_size() const;
155 
175  template<typename Dim>
176  typename std::enable_if<std::is_same<Dim, Dimension>::value, DimensionSize<Dimension>>::type
177  size() const;
178 
179  template<typename Dim>
180  typename std::enable_if<!std::is_same<Dim, Dimension>::value, DimensionSize<Dim>>::type
181  size() const;
182 
183  template<typename Dim>
184  typename std::enable_if<std::is_same<Dim, Dimension>::value, DimensionSize<Dimension>>::type
185  dimension() const;
186 
187  template<typename Dim>
188  typename std::enable_if<!std::is_same<Dim, Dimension>::value, DimensionSize<Dim>>::type
189  dimension() const;
190 
194  //Slice<is_const, SliceTraitsT, SliceMixin, Dimensions...> operator[](DimensionIndex<Dimension>) const;
197 
198  template<typename Dim>
199  typename std::enable_if<arg_helper<Dim, Dimensions...>::value
200  && !std::is_same<Dim, Dimension>::value, typename ConstOperatorSliceType<Dim>::type>::type
201  operator[](DimensionIndex<Dim> const&) const;
202 
203  template<typename Dim>
204  typename std::enable_if<arg_helper<Dim, Dimensions...>::value
205  && !std::is_same<Dim, Dimension>::value, typename OperatorSliceType<Dim>::type>::type
207 
214  template<typename... Dims>
215  typename std::enable_if<arg_helper<Dimension, Dims...>::value, SliceType>::type
216  slice(DimensionSpan<Dims> const&... spans);
217 
218  template<typename... Dims>
219  typename std::enable_if<!arg_helper<Dimension, Dims...>::value, SliceType>::type
220  slice(DimensionSpan<Dims> const&... spans);
221 
222  template<typename... Dims>
223  typename std::enable_if<arg_helper<Dimension, Dims...>::value, Slice<true, SliceTraitsT, SliceMixin, Dimension, Dimensions...>>::type
224  slice(DimensionSpan<Dims> const&... spans) const;
225 
226  template<typename... Dims>
227  typename std::enable_if<!arg_helper<Dimension, Dims...>::value, Slice<true, SliceTraitsT, SliceMixin, Dimension, Dimensions...>>::type
228  slice(DimensionSpan<Dims> const&... spans) const;
229 
230 
234  iterator begin();
235  const_iterator begin() const;
236  const_iterator cbegin() const;
237 
241  iterator end();
242  const_iterator end() const;
243  const_iterator cend() const;
244 
248  Parent& parent() const;
249 
253  template<bool const_type>
255 
256  protected:
259  friend typename impl_iterator::BaseT;
260  friend typename impl_iterator::ImplT;
261  friend typename impl_const_iterator::BaseT;
262  friend typename impl_const_iterator::ImplT;
263 
264 
265  protected:
266  template<bool, typename P, template<typename> class, typename D, typename... Ds> friend class Slice;
267 
268  template<typename IteratorT> bool increment_it(IteratorT& current, SlicePosition<rank>& pos) const;
269  template<typename IteratorDifferenceT> IteratorDifferenceT diff_it(IteratorDifferenceT const& diff) const;
270 
271  // return the size of memory occupied by the lowest dimension
272  std::size_t contiguous_span() const;
273 
274  // return the span of all lower dimensions than this one (i.e an index of +1 in this dimension)
275  std::size_t base_span() const;
276  std::size_t diff_base_span() const;
277 
278  // ptr to the start of the block
279  parent_iterator const& base_ptr() const;
280  parent_iterator& base_ptr();
281 
282  parent_iterator const& offset(parent_iterator const&); // init the offset relative to the top parent
283 
284  // init for inheriting classes only
285  template<typename... Dims>
287  , typename std::enable_if<arg_helper<Dimension, Dims...>::value, Parent&>::type parent
288  , DimensionSpan<Dims> const& ... spans);
289 
290  template<typename... Dims>
292  , typename std::enable_if<!arg_helper<Dimension, Dims...>::value, Parent&>::type parent
293  , DimensionSpan<Dims> const& ... spans);
294 
295  template<typename... Dims>
297  , typename std::enable_if<!arg_helper<Dimension, Dims...>::value, Slice>::type const& copy
298  , DimensionSpan<Dims> const&... spans );
299 
300  template<typename... Dims>
302  , typename std::enable_if<!arg_helper<Dimension, Dims...>::value, Slice>::type const& copy
303  , DimensionSpan<Dims> const&... spans );
304 
305  template<typename... Dims>
307  , typename std::enable_if<arg_helper<Dimension, Dims...>::value, Slice>::type const& copy
308  , DimensionSpan<Dims> const&... spans );
309 
310  template<typename... Dims>
312  , typename std::enable_if<arg_helper<Dimension, Dims...>::value, Slice>::type const& copy
313  , DimensionSpan<Dims> const&... spans );
314 
315  // increment pointer by a n * span length
316  SelfType& operator+=(std::size_t n);
317 
318  // increment pointer by a n * base span length
320 
324  impl_iterator impl_begin();
325  impl_const_iterator impl_begin() const;
326  impl_const_iterator impl_cbegin() const;
327 
331  impl_iterator impl_end();
332  impl_const_iterator impl_end() const;
333  impl_const_iterator impl_cend() const;
334 
335  private:
336  friend typename iterator::BaseT;
337  friend typename iterator::ImplT;
338  friend typename const_iterator::BaseT;
339  friend typename const_iterator::ImplT;
340 
341  private:
343  DimensionSize<Dimension> _base_span;
344  parent_iterator _ptr; // start of block
345 };
346 
347 // specialisation for 0 dimensional slice
348 // which should return a single element
349 template<bool is_const, typename SliceTraitsT, template<typename> class SliceMixin, typename Dimension>
350 class Slice<is_const, SliceTraitsT, SliceMixin, Dimension>
351 {
353  typedef typename SliceTraitsHelper<SliceTraitsT>::Parent ParentT;
354  typedef typename ParentT::const_iterator parent_const_iterator;
355  typedef typename std::conditional<is_const, parent_const_iterator, typename ParentT::iterator>::type parent_iterator;
356  typedef Dimension SelfDimension;
357 
358  protected:
360  typedef std::tuple<Dimension> DimensionTuple;
361 
362  public:
363  template<typename Dim>
364  struct OperatorSliceType;
365 
366  template<typename Dim>
367  struct ConstOperatorSliceType;
368 
369  typedef typename std::iterator_traits<parent_iterator>::reference reference_type;
370  typedef typename std::iterator_traits<parent_const_iterator>::reference const_reference_type;
371  typedef typename std::conditional<is_const, const ParentT, ParentT>::type Parent;
374  typedef parent_iterator iterator;
375  typedef parent_const_iterator const_iterator;
376 
377  public:
378  Slice(Parent& parent, DimensionSpan<Dimension> const&);
379  Slice(Slice const&);
380  ~Slice();
381 
382  static constexpr std::size_t rank = 1;
383 
387  Slice& operator=(Slice const&);
388 
392  std::size_t data_size() const;
393 
397  template<typename Dim>
398  typename std::enable_if<std::is_same<Dim, Dimension>::value, DimensionSize<Dimension>>::type
399  size() const;
400 
404  template<typename Dim>
405  constexpr
406  typename std::enable_if<((!std::is_same<Dim, Dimension>::value) && (!has_dimension<Parent, Dim>::value))
407  , DimensionSize<Dim>>::type
408  size() const;
409 
414  template<typename Dim>
415  constexpr
416  typename std::enable_if<(!std::is_same<Dim, Dimension>::value)
418  , DimensionSize<Dim>>::type
419  size() const;
420 
424  template<typename Dim>
425  typename std::enable_if<std::is_same<Dim, Dimension>::value, DimensionSize<Dimension>>::type
426  dimension() const;
427 
431  template<typename Dim>
432  constexpr
433  typename std::enable_if<((!std::is_same<Dim, Dimension>::value) && (!has_dimension<Parent, Dim>::value))
434  , DimensionSize<Dim>>::type
435  dimension() const;
436 
441  template<typename Dim>
442  constexpr
443  typename std::enable_if<(!std::is_same<Dim, Dimension>::value)
445  , DimensionSize<Dim>>::type
446  dimension() const;
447 
451  reference_type operator[](std::size_t index) const;
452  reference_type operator[](DimensionIndex<Dimension> const& index) const;
453 
454  // specialisations for implicit (i.e Parent has dimension but Slice does not)
455  template<typename Dim, typename Enable=typename std::enable_if<has_dimension<Parent, Dim>::value
456  && !std::is_same<Dim, Dimension>::value>::type>
457  SelfType const& operator[](DimensionIndex<Dim> const&) const { return *this; }
458 
459  // specialisations for implicit (i.e Parent has dimension but Slice does not)
460  template<typename Dim, typename Enable=typename std::enable_if<has_dimension<Parent, Dim>::value
461  && !std::is_same<Dim, Dimension>::value>::type>
462  SelfType& operator[](DimensionIndex<Dim> const&) { return *this; }
463 
467  ConstSliceType slice(DimensionSpan<Dimension> const& span) const;
468  SliceType slice(DimensionSpan<Dimension> const& span);
469 
473  parent_iterator begin();
474  parent_const_iterator begin() const;
475  parent_const_iterator cbegin() const;
476 
480  parent_iterator end();
481  parent_const_iterator end() const;
482  parent_const_iterator cend() const;
483 
487  template<bool is_const_>
489 
493  Parent& parent() const;
494 
495  protected:
496  template<bool, typename P, template<typename> class, typename D, typename... Ds> friend class Slice;
497 
498  template<typename IteratorT> bool increment_it(IteratorT& current, SlicePosition<rank>& pos) const;
499  template<typename IteratorDifferenceT> static IteratorDifferenceT diff_it(IteratorDifferenceT const& diff);
500 
501  // return the size of memory occupied by the lowest dimension
502  std::size_t contiguous_span() const;
503 
504  // same as size() - to support base_span calls from higher dimensions
505  std::size_t base_span() const;
506 
507  // number of elements between the blocks end and its beginning
508  // 1 Base_ptr less than base_span
509  std::size_t diff_base_span() const;
510 
511  // ptr to the start of the block
512  parent_iterator const& base_ptr() const;
513  parent_iterator& base_ptr();
514 
515  parent_iterator const& offset(parent_iterator const&); // init the offset relative to the top parent
516 
517  SelfType& operator+=(DimensionSize<Dimension> const&);
518  SelfType& operator+=(std::size_t n);
519 
520 
521  protected:
522  template<typename... Dims>
524  , typename std::enable_if<arg_helper<Dimension, Dims...>::value, Parent&>::type parent
525  , DimensionSpan<Dims> const&... spans);
526 
527  template<typename... Dims>
529  , typename std::enable_if<!arg_helper<Dimension, Dims...>::value, Parent&>::type parent
530  , DimensionSpan<Dims> const&... spans);
531 
532  template<typename... Dims>
533  Slice( typename std::enable_if<!arg_helper<Dimension, Dims...>::value, copy_resize_construct_base_tag const&>::type
534  , Slice const& copy
535  , DimensionSpan<Dims> const&... spans );
536 
537  template<typename... Dims>
538  Slice( typename std::enable_if<arg_helper<Dimension, Dims...>::value, copy_resize_construct_base_tag const&>::type
539  , Slice const& copy
540  , DimensionSpan<Dims> const&... spans );
541 
542  private:
544  DimensionSize<Dimension> _base_span;
545  Parent* _parent;
546  parent_iterator _ptr; // start, to extent _ptr + _span
547 };
548 
549 } // namespace astrotypes
550 } // namespace pss
551 
552 #include "detail/Slice.cpp"
553 
554 #endif // PSS_ASTROTYPES_MULTIARRAY_SLICE_H
SelfType const & operator[](DimensionIndex< Dim > const &) const
Definition: Slice.h:457
Slice< true, SliceTraitsT, SliceMixin, Dimension > ConstSliceType
Definition: Slice.h:373
iterator end()
iterator pointing to just after the last element
Definition: Slice.cpp:455
produces a tuple type with params form all provided Tuples
Definition: TypeTraits.h:294
A tagged dimensionIndex variable.
iterator begin()
iterator pointing to the first element in the slice
Definition: Slice.cpp:437
bool operator==(Slice< const_type, SliceTraitsT, SliceMixin, Dimension, Dimensions...> const &) const
compare two arrays
Definition: Slice.cpp:546
SliceMixin< Slice< true, InternalSliceTraits< SliceTraitsT, Dimension >, SliceMixin, Dimensions...> > ConstReducedSliceType
Definition: Slice.h:136
SliceIterator< SliceMixin< SelfType >, is_const > iterator
Definition: Slice.h:131
Defines a contiguous range over dimension in index.
Definition: DimensionSpan.h:41
SliceMixin< Slice< is_const, SliceTraitsT, SliceMixin, Dimension, Dimensions...> > SliceType
Definition: Slice.h:133
parent_iterator const & offset(parent_iterator const &)
Definition: Slice.cpp:274
ConstOperatorSliceTypeHelper< Dim, Slice >::type type
Definition: Slice.cpp:148
std::size_t contiguous_span() const
Definition: Slice.cpp:293
static T && arg(T &&arg, Dims &&...)
Definition: Slice.h:44
static constexpr std::size_t rank
Definition: Slice.h:149
std::iterator_traits< parent_const_iterator >::reference const_reference_type
Definition: Slice.h:370
OperatorSliceTypeHelper< Dim, Slice >::type type
Definition: Slice.cpp:141
SliceMixin< BaseT > ReducedSliceType
Definition: Slice.h:134
Representation of a Slice through a Data Array.
Definition: Slice.h:105
SliceIterator< SelfType, true > impl_const_iterator
Definition: Slice.h:258
impl_iterator impl_begin()
iterator pointing to the first element in the slice
Definition: Slice.cpp:479
std::enable_if< std::is_same< Dim, Dimension >::value, DimensionSize< Dimension > >::type size() const
impl_const_iterator impl_cbegin() const
Definition: Slice.cpp:491
std::size_t diff_base_span() const
Definition: Slice.cpp:287
std::tuple< ExcludeDimension > ExcludeTuple
Definition: Slice.h:76
std::enable_if< arg_helper< Dimension, Dims...>::value, SliceType >::type slice(DimensionSpan< Dims > const &...spans)
Take a sub-slice from this slice pass a DimensionSpan object for each dimension you wish ...
InternalSliceTraits< TraitsT, D >::ExcludeTuple ExcludeTuple
Definition: Slice.h:99
static T && arg(Dim &&, Dims &&...args)
Definition: Slice.h:54
SliceTraitsHelper< SliceTraitsT >::ExcludeTuple ExcludeTuple
Definition: Slice.h:359
represents a point in an
Definition: SlicePosition.h:37
SelfType & operator+=(std::size_t n)
Definition: Slice.cpp:388
const_iterator cend() const
Definition: Slice.cpp:467
parent_iterator const & base_ptr() const
Definition: Slice.cpp:305
Parent & parent() const
return refernce to the parent object the Slice is based on
Definition: Slice.cpp:473
impl_const_iterator impl_cend() const
Definition: Slice.cpp:509
provides a template to determine the returned type of an operator[]
Definition: Slice.cpp:139
join_tuples< typename BaseT::ExcludeTuple, std::tuple< ExcludeDimension > >::type ExcludeTuple
Definition: Slice.h:86
A compile time dimesion tagging of size_t.
Definition: DimensionSize.h:39
impl_iterator impl_end()
iterator pointing to just after the last element
Definition: Slice.cpp:497
IteratorDifferenceT diff_it(IteratorDifferenceT const &diff) const
Definition: Slice.cpp:534
SliceIterator< SelfType, is_const > impl_iterator
Definition: Slice.h:257
bool increment_it(IteratorT &current, SlicePosition< rank > &pos) const
Definition: Slice.cpp:516
std::size_t base_span() const
Definition: Slice.cpp:281
OperatorSliceType< Dimension >::type operator[](DimensionIndex< Dimension >)
Take a slice in the specified dimension with a span of 1.
Definition: Slice.cpp:350
InternalSliceTraits< TraitsT, D >::Parent Parent
Definition: Slice.h:100
std::size_t data_size() const
the total number of data members in this slice
Definition: Slice.cpp:311
Slice< is_const, SliceTraitsT, SliceMixin, Dimension > SliceType
Definition: Slice.h:372
SliceMixin< Slice< true, SliceTraitsT, SliceMixin, Dimension, Dimensions...> > ConstSliceType
Definition: Slice.h:135
std::conditional< is_const, const ParentT, ParentT >::type Parent
Definition: Slice.h:128
return true if the Dimension is represented in the structure
Definition: TypeTraits.h:71
std::conditional< is_const, const ParentT, ParentT >::type Parent
Definition: Slice.h:371
std::tuple< Dimension, Dimensions...> DimensionTuple
Definition: Slice.h:118
friend class Slice
Definition: Slice.h:266
std::iterator_traits< parent_iterator >::reference reference_type
Definition: Slice.h:367
const_iterator cbegin() const
Definition: Slice.cpp:449
SliceTraitsHelper< SliceTraitsT >::ExcludeTuple ExcludeTuple
Definition: Slice.h:117
SliceIterator< SliceMixin< SelfType >, true > const_iterator
Definition: Slice.h:132
std::enable_if< std::is_same< Dim, Dimension >::value, DimensionSize< Dimension > >::type dimension() const
SelfType & operator[](DimensionIndex< Dim > const &)
Definition: Slice.h:462