OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
 
Loading...
Searching...
No Matches
multi_array_ref_base_openfpm.hpp
1/*
2 * multi_array_ref_openfpm_base.hpp
3 *
4 * Created on: Jun 30, 2018
5 * Author: i-bird
6 */
7
8#ifndef MULTI_ARRAY_REF_OPENFPM_BASE_HPP_
9#define MULTI_ARRAY_REF_OPENFPM_BASE_HPP_
10
11#include "types.hpp"
12#include <boost/mpl/size_t.hpp>
13#include "boost/iterator/reverse_iterator.hpp"
14#include "storage_order.hpp"
15#include <boost/mpl/at.hpp>
16#include <boost/mpl/size.hpp>
17#include <boost/mpl/pop_front.hpp>
18#include <boost/type.hpp>
19
20namespace openfpm
21{
22
24// class declarations
26
27//template<typename T, std::size_t NumDims, typename Allocator = std::allocator<T> >
28//class multi_array_openfpm;
29
30template <typename T, int NumDims, typename vector>
31class multi_array_ref_openfpm;
32
33// This is a public interface for use by end users!
34namespace multi_array_types
35{
36 typedef openfpm::detail::multi_array::size_type size_type;
37 typedef std::ptrdiff_t difference_type;
38 typedef openfpm::detail::multi_array::index index;
39}
40
41
42namespace detail {
43namespace multi_array {
44
45template <typename T, std::size_t NumDims, typename vector>
46class sub_array_openfpm;
47
48template <typename T, std::size_t NumDims, typename vector, typename TPtr = const T*>
49class const_sub_array_openfpm;
50
51 template <typename T, typename TPtr, typename NumDims, typename vector, typename Reference,
52 typename IteratorCategory>
53class array_iterator_openfpm;
54
55template <typename T, std::size_t NumDims, typename TPtr = const T*>
56class const_multi_array_view_openfpm;
57
58template <typename T, std::size_t NumDims>
59class multi_array_view_openfpm;
60
61
63// class interfaces
65
67{
68public:
69 typedef multi_array_types::size_type size_type;
70 typedef multi_array_types::difference_type difference_type;
71 typedef multi_array_types::index index;
72};
73
74//
75// value_accessor_n
76// contains the routines for accessing elements from
77// N-dimensional views.
78//
79template<typename T, std::size_t NumDims, typename vector>
81{
83public:
84 typedef typename super_type::index index;
85
86 //
87 // public typedefs used by classes that inherit from this base
88 //
89 typedef T element;
90 typedef openfpm::multi_array_ref_openfpm<T,NumDims-1,typename boost::mpl::pop_front<vector>::type> value_type;
91 typedef sub_array_openfpm<T,NumDims-1,typename boost::mpl::pop_front<vector>::type> reference;
92 typedef const_sub_array_openfpm<T,NumDims-1,typename boost::mpl::pop_front<vector>::type> const_reference;
93
94protected:
95
96 // used by array operator[] and iterators to get reference types.
97 template <typename Reference, typename TPtr>
98 __device__ __host__ inline Reference access(boost::type<Reference>,
99 index idx,
100 const index* strides,
101 TPtr base) const
102 {
103 TPtr newbase = base + idx * strides[0];
104 return Reference(newbase,strides+1);
105 }
106
107 __device__ __host__ value_accessor_n_openfpm() { }
108 __device__ __host__ ~value_accessor_n_openfpm() { }
109};
110
111template <class T> inline __device__ __host__ void ignore_unused_variable_warning_ofp(T const&) {}
112
113//
114// value_accessor_one
115// contains the routines for accessing reference elements from
116// 1-dimensional views.
117//
118template<typename T, typename vector>
120{
122public:
123 typedef typename super_type::index index;
124 //
125 // public typedefs for use by classes that inherit it.
126 //
127 typedef T element;
128 typedef T value_type;
129 typedef T& reference;
130 typedef T const& const_reference;
131
132protected:
133
134 // used by array operator[] and iterators to get reference types.
135 template <typename Reference, typename TPtr>
136 inline __device__ __host__ Reference access(boost::type<Reference>,index idx,
137 const index* strides,
138 TPtr base) const
139 {
140 return *(base + idx * strides[0]);
141 }
142
143 // used by array operator[] and iterators to get reference types.
144 template <typename Reference, typename TPtr>
145 inline __device__ __host__ Reference access(boost::type<Reference>,index idx,TPtr base, const index* strides) const
146 {
147 BOOST_ASSERT(size_type(idx < boost::mpl::at<vector,boost::mpl::int_<0>>::type::value));
148 return *(base + idx * strides[0]);
149 }
150
151 __device__ __host__ value_accessor_one_openfpm() { }
152 __device__ __host__ ~value_accessor_one_openfpm() { }
153};
154
155
157// choose value accessor begins
158//
159
160template <typename T, std::size_t NumDims,typename vector>
162{
164};
165
166template <typename T,typename vector>
168{
170};
171
172template <typename T, typename NumDims, typename vector>
174{
175 BOOST_STATIC_CONSTANT(std::size_t, dimensionality = NumDims::value);
176
177 typedef typename
178 boost::mpl::eval_if_c<(dimensionality == 1),
181 >::type type;
182};
183
184
185template <class T, class NumDims, typename vector>
187{};
188
189//
190// choose value accessor ends
192
193// Due to some imprecision in the C++ Standard,
194// MSVC 2010 is broken in debug mode: it requires
195// that an Output Iterator have output_iterator_tag in its iterator_category if
196// that iterator is not bidirectional_iterator or random_access_iterator.
197#if BOOST_WORKAROUND(BOOST_MSVC, >= 1600)
198struct mutable_iterator_tag
199 : boost::random_access_traversal_tag, std::input_iterator_tag
200{
201 operator std::output_iterator_tag() const {
202 return std::output_iterator_tag();
203 }
204};
205#endif
206
207
209// multi_array_base
211template <typename T, std::size_t NumDims, typename vector>
212class multi_array_impl_base_openfpm: public value_accessor_generator_openfpm<T,boost::mpl::size_t<NumDims>,vector>::type
213{
215public:
216
217 typedef typename types::index index;
218 typedef typename types::size_type size_type;
219 typedef typename types::element element;
220 typedef typename types::value_type value_type;
221 typedef typename types::reference reference;
222 typedef typename types::const_reference const_reference;
223
224 template <std::size_t NDims>
225 struct subarray
226 {
228 };
229
230 template <std::size_t NDims>
232 {
234 };
235
236 template <std::size_t NDims>
238 {
240 };
241
242 template <std::size_t NDims>
244 {
245 public:
247 };
248
249#if BOOST_WORKAROUND(BOOST_MSVC, >= 1600)
250 // Deal with VC 2010 output_iterator_tag requirement
252 mutable_iterator_tag> iterator;
253#else
255 boost::random_access_traversal_tag> iterator;
256#endif
258 boost::random_access_traversal_tag> const_iterator;
259
260 typedef ::boost::reverse_iterator<iterator> reverse_iterator;
261 typedef ::boost::reverse_iterator<const_iterator> const_reverse_iterator;
262
263 BOOST_STATIC_CONSTANT(std::size_t, dimensionality = NumDims);
264
265protected:
266
267 __device__ __host__ multi_array_impl_base_openfpm() { }
268 __device__ __host__ ~multi_array_impl_base_openfpm() { }
269
270
271 template <typename Stride_list, typename Extent_type>
272 void compute_strides(Stride_list& stride_list, Extent_type& extent,
273 const general_storage_order<NumDims>& storage)
274 {
275 // invariant: stride = the stride for dimension n
276 index stride = 1;
277 for (size_type n = 0; n != NumDims; ++n)
278 {
279 // The stride for this dimension is the product of the
280 // lengths of the ranks minor to it.
281 stride_list[storage.ordering(n)] = stride;
282
283 if (storage.ordering(n) == 0)
284 {stride *= extent;}
285 else
286 {
287 switch(storage.ordering(n))
288 {
289 case 1:
291 break;
292 case 2:
294 break;
295 case 3:
297 break;
298 case 4:
300 break;
301 case 5:
303 break;
304 case 6:
306 break;
307 case 7:
309 break;
310 case 8:
312 break;
313 case 9:
315 break;
316 case 10:
318 break;
319 case 11:
321 break;
322 case 12:
324 break;
325 case 13:
327 break;
328 case 14:
330 break;
331 case 15:
333 break;
334 }
335 }
336 }
337 }
338
339 // Used by operator() in our array classes
340 template <typename Reference, typename IndexList, typename TPtr>
341 Reference access_element(boost::type<Reference>,
342 const IndexList& indices,
343 TPtr base,
344 const size_type* extents,
345 const index* strides,
346 const index* index_bases) const
347 {
348 boost::function_requires<
349 boost::CollectionConcept<IndexList> >();
350 ignore_unused_variable_warning(index_bases);
351 ignore_unused_variable_warning(extents);
352#ifdef SE_CLASS1
353 for (size_type i = 0; i != NumDims; ++i)
354 {
355 BOOST_ASSERT(indices[i] - index_bases[i] >= 0);
356 BOOST_ASSERT(size_type(indices[i] - index_bases[i]) < extents[i]);
357 }
358#endif
359
360 index offset = 0;
361 {
362 typename IndexList::const_iterator i = indices.begin();
363 size_type n = 0;
364 while (n != NumDims)
365 {
366 offset += (*i) * strides[n];
367 ++n;
368 ++i;
369 }
370 }
371 return base[offset];
372 }
373};
374
375} // namespace multi_array
376} // namespace detail
377
378} // namespace openfpm
379
380
381#endif /* MULTI_ARRAY_REF_OPENFPM_BASE_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