OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
 
Loading...
Searching...
No Matches
multi_array_view_openfpm.hpp
1/*
2 * multi_array_view_openfpm.hpp
3 *
4 * Created on: Jul 1, 2018
5 * Author: i-bird
6 */
7
8#ifndef MULTI_ARRAY_VIEW_OPENFPM_HPP_
9#define MULTI_ARRAY_VIEW_OPENFPM_HPP_
10
11//#include "util/boost/boost_multi_array_base_openfpm.hpp"
12#include "boost/utility/enable_if.hpp"
13#include "boost/multi_array/index_gen.hpp"
14
15namespace openfpm {
16namespace detail {
17namespace multi_array {
18
19
20
21// TPtr = const T* defaulted in base.hpp
22template <typename T, std::size_t NumDims, typename vector>
24{
26public:
27 typedef typename super_type::value_type value_type;
28 typedef typename super_type::const_reference const_reference;
30 typedef typename super_type::const_reverse_iterator const_reverse_iterator;
31 typedef typename super_type::element element;
32 typedef typename super_type::size_type size_type;
33 typedef typename super_type::difference_type difference_type;
34 typedef typename super_type::index index;
35 typedef typename super_type::extent_range extent_range;
36 typedef T * TPtr;
37
38 typedef typename boost::mpl::accumulate<vector,
39 typename boost::mpl::int_<1>,
40 typename boost::mpl::multiplies<typename boost::mpl::_2,typename boost::mpl::_1> >::type size_ct;
41
42 // template typedefs
43 template <std::size_t NDims>
46 };
47
48 template <std::size_t NDims>
51 };
52
53 template <typename OPtr>
56 base_(other.base_), origin_offset_(other.origin_offset_),
57 num_elements_(other.num_elements_),
58 stride_list_(other.stride_list_), index_base_list_(other.index_base_list_)
59 { }
60
61
62 template <class BaseList>
63#ifdef BOOST_NO_SFINAE
64 void
65#else
66 typename
67 boost::disable_if<typename boost::is_integral<BaseList>::type,void >::type
68#endif
69 reindex(const BaseList& values)
70 {
71 boost::function_requires<
72 boost::CollectionConcept<BaseList> >();
73 boost::detail::multi_array::
74 copy_n(values.begin(),num_dimensions(),index_base_list_.begin());
75 origin_offset_ =
76 this->calculate_indexing_offset(stride_list_,index_base_list_);
77 }
78
79 void reindex(index value)
80 {
81 index_base_list_.assign(value);
82 origin_offset_ =
83 this->calculate_indexing_offset(stride_list_,index_base_list_);
84 }
85
86 size_type num_dimensions() const { return NumDims; }
87
88 size_type size() const { return extent; }
89 size_type max_size() const { return num_elements(); }
90 bool empty() const { return size() == 0; }
91
92 __device__ __host__ const index* strides() const {
93 return stride_list_.data();
94 }
95
96 __device__ __host__ const T* origin() const { return base_+origin_offset_; }
97
98 size_type num_elements() const { return num_elements_; }
99
100 __device__ __host__ const index* index_bases() const {
101 return index_base_list_.data();
102 }
103
104 template <typename IndexList>
105 const element& operator()(IndexList indices) const
106 {
107 boost::function_requires<boost::CollectionConcept<IndexList> >();
108 return super_type::access_element(boost::type<const element&>(),
109 indices,origin(),strides(),index_bases());
110 }
111
112 // Only allow const element access
113 __device__ __host__ const_reference operator[](index idx) const {
114 return super_type::access(boost::type<const_reference>(),
115 idx,origin(),strides(),
116 index_bases());
117 }
118
119 // see generate_array_view in base.hpp
120 template <int NDims>
121 __device__ __host__ typename const_array_view_openfpm<NDims>::type
122 operator[](const boost::detail::multi_array::index_gen<NumDims,NDims>& indices) const
123 {
124 typedef typename const_array_view_openfpm<NDims>::type return_type;
125 return
126 super_type::generate_array_view(boost::type<return_type>(),
127 indices,
128 strides(),
129 index_bases(),
130 origin());
131 }
132
133 const_iterator begin() const {
134 return const_iterator(*index_bases(),origin(),strides(),index_bases());
135 }
136
137 const_reverse_iterator rend() const {
138 return const_reverse_iterator(begin());
139 }
140
141 template <typename OPtr>
142 bool operator!=(const const_multi_array_view_openfpm<T,NumDims,OPtr>& rhs) const
143 {
144 return !(*this == rhs);
145 }
146
147 template <typename OPtr>
148 bool operator>(const
149 const_multi_array_view_openfpm<T,NumDims,OPtr>& rhs)
150 const {
151 return rhs < *this;
152 }
153
154 template <typename OPtr>
155 bool operator<=(const
156 const_multi_array_view_openfpm<T,NumDims,OPtr>& rhs)
157 const {
158 return !(*this > rhs);
159 }
160
161 template <typename OPtr>
162 bool operator>=(const
163 const_multi_array_view_openfpm<T,NumDims,OPtr>& rhs)
164 const {
165 return !(*this < rhs);
166 }
167
168
169#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
170protected:
171 template <typename,std::size_t,typename> friend class multi_array_impl_base_openfpm;
172 template <typename,std::size_t,typename> friend class const_multi_array_view_openfpm;
173#else
174public: // should be protected
175#endif
176
177 // This constructor is used by multi_array_impl_base::generate_array_view
178 // to create strides
179 template <typename ExtentType, typename Index>
180 explicit const_multi_array_view_openfpm(TPtr base,
181 const ExtentType extent,
182 const boost::array<Index,NumDims>& strides):
183 base_(base), origin_offset_(0) ,extent(extent)
184 {
185
186 index_base_list_.assign(0);
187
188 // Get the extents and strides
189 boost::detail::multi_array::
190 copy_n(strides.begin(),NumDims,stride_list_.begin());
191
192 // Calculate the array size
193 num_elements_ = extent * size_ct::type::value;
194 }
195
196 typedef boost::array<index,NumDims> index_list;
197
198 TPtr base_;
199 index origin_offset_;
200 size_type num_elements_;
201 size_type extent;
202 index_list stride_list_;
203 index_list index_base_list_;
204
205private:
206 // const_multi_array_view cannot be assigned to (no deep copies!)
207 const_multi_array_view_openfpm& operator=(const const_multi_array_view_openfpm& other);
208};
209
210
211template <typename T, std::size_t NumDims>
213 public const_multi_array_view_openfpm<T,NumDims,T*>
214{
216public:
217 typedef typename super_type::value_type value_type;
218 typedef typename super_type::reference reference;
219 typedef typename super_type::iterator iterator;
220 typedef typename super_type::reverse_iterator reverse_iterator;
221 typedef typename super_type::const_reference const_reference;
223 typedef typename super_type::const_reverse_iterator const_reverse_iterator;
224 typedef typename super_type::element element;
225 typedef typename super_type::size_type size_type;
226 typedef typename super_type::difference_type difference_type;
227 typedef typename super_type::index index;
228 typedef typename super_type::extent_range extent_range;
229
230 // template typedefs
231 template <std::size_t NDims>
233 {
235 };
236
237 template <std::size_t NDims>
240 };
241
242 // Assignment from other ConstMultiArray types.
243 template <typename ConstMultiArray>
244 multi_array_view_openfpm& operator=(const ConstMultiArray& other) {
245 boost::function_requires<
246 boost::multi_array_concepts::
247 ConstMultiArrayConcept<ConstMultiArray,NumDims> >();
248
249 // make sure the dimensions agree
250 BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
251 BOOST_ASSERT(std::equal(other.shape(),other.shape()+this->num_dimensions(),
252 this->shape()));
253 // iterator-based copy
254 std::copy(other.begin(),other.end(),begin());
255 return *this;
256 }
257
258
259 multi_array_view_openfpm& operator=(const multi_array_view_openfpm& other) {
260 if (&other != this) {
261 // make sure the dimensions agree
262 BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
263 BOOST_ASSERT(std::equal(other.shape(),
264 other.shape()+this->num_dimensions(),
265 this->shape()));
266 // iterator-based copy
267 std::copy(other.begin(),other.end(),begin());
268 }
269 return *this;
270 }
271
272 element* origin() { return this->base_+this->origin_offset_; }
273
274 template <class IndexList>
275 element& operator()(const IndexList& indices) {
276 boost::function_requires<
277 boost::CollectionConcept<IndexList> >();
278 return super_type::access_element(boost::type<element&>(),
279 indices,origin(),
280 this->shape(),this->strides(),
281 this->index_bases());
282 }
283
284
285 reference operator[](index idx) {
286 return super_type::access(boost::type<reference>(),
287 idx,origin(),
288 this->shape(),this->strides(),
289 this->index_bases());
290 }
291
292
293 // see generate_array_view in base.hpp
294/* template <int NDims>
295 typename array_view_openfpm<NDims>::type
296 operator[](const boost::detail::multi_array::
297 index_gen<NumDims,NDims>& indices) {
298 typedef typename array_view_openfpm<NDims>::type return_type;
299 return
300 super_type::generate_array_view(boost::type<return_type>(),
301 indices,
302 this->shape(),
303 this->strides(),
304 this->index_bases(),
305 origin());
306 }*/
307
308
309 iterator begin() {
310 return iterator(*this->index_bases(),origin(),
311 this->shape(),this->strides(),
312 this->index_bases());
313 }
314
315 iterator end() {
316 return iterator(*this->index_bases()+(index)*this->shape(),origin(),
317 this->shape(),this->strides(),
318 this->index_bases());
319 }
320
321 reverse_iterator rbegin() {
322 return reverse_iterator(end());
323 }
324
325 reverse_iterator rend() {
326 return reverse_iterator(begin());
327 }
328
329 // Using declarations don't seem to work for g++
330 // These are the proxies to work around this.
331
332 const element* origin() const { return super_type::origin(); }
333
334 template <class IndexList>
335 const element& operator()(const IndexList& indices) const {
336 boost::function_requires<
337 boost::CollectionConcept<IndexList> >();
338 return super_type::operator()(indices);
339 }
340
341 const_reference operator[](index idx) const {
342 return super_type::operator[](idx);
343 }
344
345 // see generate_array_view in base.hpp
346/* template <int NDims>
347 typename const_array_view_openfpm<NDims>::type
348 operator[](const boost::detail::multi_array::
349 index_gen<NumDims,NDims>& indices)
350 const {
351 return super_type::operator[](indices);
352 }*/
353
354 const_iterator begin() const {
355 return super_type::begin();
356 }
357
358 const_iterator end() const {
359 return super_type::end();
360 }
361
362 const_reverse_iterator rbegin() const {
363 return super_type::rbegin();
364 }
365
366 const_reverse_iterator rend() const {
367 return super_type::rend();
368 }
369
370#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
371private:
372 template <typename,std::size_t> friend class multi_array_impl_base;
373#else
374public: // should be private
375#endif
376
377 // constructor used by multi_array_impl_base::generate_array_view to
378 // generate array views
379 template <typename ExtentList, typename Index>
380 explicit multi_array_view_openfpm(T* base,
381 const ExtentList& extents,
382 const openfpm::array<Index,NumDims>& strides) :
383 super_type(base,extents,strides) { }
384
385};
386
387} // namespace multi_array
388} // namespace detail
389
390//
391// traits classes to get array_view types
392//
393template <typename Array, int N>
395 typedef typename Array::element element;
396public:
398};
399
400template <typename Array, int N>
402 typedef typename Array::element element;
403public:
405};
406
407} // namespace boost
408
409
410
411#endif /* MULTI_ARRAY_VIEW_OPENFPM_HPP_ */
This class is a trick to indicate the compiler a specific specialization pattern.
Definition memory_c.hpp:240
Implementation of 1-D std::vector like structure.
convert a type into constant type