1 | /* |
2 | * multi_array_iterator_openfpm.hpp |
3 | * |
4 | * Created on: Jul 7, 2018 |
5 | * Author: i-bird |
6 | */ |
7 | |
8 | #ifndef MULTI_ARRAY_ITERATOR_OPENFPM_HPP_ |
9 | #define MULTI_ARRAY_ITERATOR_OPENFPM_HPP_ |
10 | |
11 | |
12 | |
13 | // |
14 | // iterator.hpp - implementation of iterators for the |
15 | // multi-dimensional array class |
16 | // |
17 | |
18 | #include "boost/iterator/iterator_facade.hpp" |
19 | #include <algorithm> |
20 | #include <cstddef> |
21 | #include <iterator> |
22 | //#include "util/boost/boost_multi_array_base_openfpm.hpp" |
23 | #include "util/cuda_util.hpp" |
24 | |
25 | namespace openfpm { |
26 | namespace detail { |
27 | namespace multi_array { |
28 | |
29 | template <class T> |
30 | struct operator_arrow_proxy_openfpm |
31 | { |
32 | operator_arrow_proxy_openfpm(T const& px) : value_(px) {} |
33 | T* operator->() const { return &value_; } |
34 | // This function is needed for MWCW and BCC, which won't call operator-> |
35 | // again automatically per 13.3.1.2 para 8 |
36 | operator T*() const { return &value_; } |
37 | mutable T value_; |
38 | }; |
39 | |
40 | ///////////////////////////////////////////////////////////////////////// |
41 | // iterator components |
42 | ///////////////////////////////////////////////////////////////////////// |
43 | |
44 | template <typename T, typename TPtr, typename NumDims, typename vector, typename Reference, |
45 | typename IteratorCategory> |
46 | class array_iterator_openfpm; |
47 | |
48 | template <typename T, typename TPtr, typename NumDims, typename vector, typename Reference, |
49 | typename IteratorCategory> |
50 | class array_iterator_openfpm |
51 | : public |
52 | boost::iterator_facade< |
53 | array_iterator_openfpm<T,TPtr,NumDims,vector,Reference,IteratorCategory> |
54 | , typename associated_types_openfpm<T,NumDims,vector>::value_type |
55 | , IteratorCategory |
56 | , Reference |
57 | > |
58 | , private |
59 | value_accessor_generator_openfpm<T,NumDims,vector>::type |
60 | { |
61 | friend class iterator_core_access; |
62 | typedef detail::multi_array::associated_types_openfpm<T,NumDims,vector> access_t; |
63 | |
64 | typedef boost::iterator_facade< |
65 | array_iterator_openfpm<T,TPtr,NumDims,vector,Reference,IteratorCategory> |
66 | , typename detail::multi_array::associated_types_openfpm<T,NumDims,vector>::value_type |
67 | , boost::random_access_traversal_tag |
68 | , Reference |
69 | > facade_type; |
70 | |
71 | typedef typename access_t::index index; |
72 | typedef typename access_t::size_type size_type; |
73 | |
74 | #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS |
75 | template <typename, typename, typename, typename, typename, typename> |
76 | friend class array_iterator_openfpm; |
77 | #else |
78 | public: |
79 | #endif |
80 | |
81 | index idx_; |
82 | TPtr base_; |
83 | const size_type extent; |
84 | const index* strides_; |
85 | |
86 | public: |
87 | // Typedefs to circumvent ambiguities between parent classes |
88 | typedef typename facade_type::reference reference; |
89 | typedef typename facade_type::value_type value_type; |
90 | typedef typename facade_type::difference_type difference_type; |
91 | |
92 | __device__ __host__ array_iterator_openfpm() {} |
93 | |
94 | __device__ __host__ array_iterator_openfpm(index idx,TPtr base, const size_type extent, const index* strides) |
95 | :idx_(idx), base_(base), extent(extent),strides_(strides) |
96 | {} |
97 | |
98 | template <typename OPtr, typename ORef, typename Cat> |
99 | array_iterator_openfpm( |
100 | const array_iterator_openfpm<T,OPtr,NumDims,vector,ORef,Cat>& rhs |
101 | , typename boost::enable_if_convertible<OPtr,TPtr>::type* = 0 |
102 | ) |
103 | : idx_(rhs.idx_), base_(rhs.base_), extent(rhs.extent),strides_(rhs.strides_) |
104 | { } |
105 | |
106 | |
107 | // RG - we make our own operator-> |
108 | operator_arrow_proxy_openfpm<reference> |
109 | operator->() const |
110 | { |
111 | return operator_arrow_proxy_openfpm<reference>(this->dereference()); |
112 | } |
113 | |
114 | |
115 | reference dereference() const |
116 | { |
117 | typedef typename value_accessor_generator_openfpm<T,NumDims,vector>::type accessor; |
118 | return accessor::access(boost::type<reference>(), |
119 | idx_, |
120 | strides_, |
121 | base_); |
122 | } |
123 | |
124 | void increment() { ++idx_; } |
125 | void decrement() { --idx_; } |
126 | |
127 | template <class IteratorAdaptor> |
128 | bool equal(IteratorAdaptor& rhs) const { |
129 | const std::size_t N = NumDims::value; |
130 | return (idx_ == rhs.idx_) && |
131 | (base_ == rhs.base_) && |
132 | (extent == rhs.extent) && |
133 | ( (strides_ == rhs.strides_) || |
134 | std::equal(strides_,strides_+N,rhs.strides_) ); |
135 | } |
136 | |
137 | template <class DifferenceType> |
138 | void advance(DifferenceType n) { |
139 | idx_ += n; |
140 | } |
141 | |
142 | template <class IteratorAdaptor> |
143 | typename facade_type::difference_type |
144 | distance_to(IteratorAdaptor& rhs) const { |
145 | return rhs.idx_ - idx_; |
146 | } |
147 | |
148 | |
149 | }; |
150 | |
151 | } // namespace multi_array |
152 | } // namespace detail |
153 | } // namespace boost |
154 | |
155 | |
156 | |
157 | |
158 | #endif /* MULTI_ARRAY_ITERATOR_OPENFPM_HPP_ */ |
159 | |