1/*
2 * multi_array_ref_subarray_openfpm.hpp
3 *
4 * Created on: Jul 1, 2018
5 * Author: i-bird
6 */
7
8#ifndef MULTI_ARRAY_REF_SUBARRAY_OPENFPM_HPP_
9#define MULTI_ARRAY_REF_SUBARRAY_OPENFPM_HPP_
10
11#include "multi_array_view_openfpm.hpp"
12#include "multi_array_ref_base_openfpm.hpp"
13
14/*! \brief return the dimension of the sub_array
15 *
16 *
17 */
18template<typename vmpl>
19struct subar_dim
20{
21 typedef typename boost::mpl::at<vmpl,boost::mpl::int_<0>>::type type;
22};
23
24namespace openfpm {
25namespace detail {
26namespace multi_array {
27
28//
29// const_sub_array
30// multi_array's proxy class to allow multiple overloads of
31// operator[] in order to provide a clean multi-dimensional array
32// interface.
33template <typename T, std::size_t NumDims, typename vector, typename TPtr>
34class const_sub_array_openfpm : public openfpm::detail::multi_array::multi_array_impl_base_openfpm<T,NumDims,vector>
35{
36 typedef openfpm::detail::multi_array::multi_array_impl_base_openfpm<T,NumDims,vector> super_type;
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
43public:
44
45 typedef typename super_type::value_type value_type;
46 typedef typename super_type::const_reference const_reference;
47 typedef typename super_type::const_iterator const_iterator;
48 typedef typename super_type::const_reverse_iterator const_reverse_iterator;
49 typedef typename super_type::element element;
50 typedef typename super_type::size_type size_type;
51 typedef typename super_type::difference_type difference_type;
52 typedef typename super_type::index index;
53
54 // template typedefs
55 template <std::size_t NDims>
56 struct const_array_view {
57 typedef openfpm::detail::multi_array::const_multi_array_view_openfpm<T,NDims> type;
58 };
59
60 template <std::size_t NDims>
61 struct array_view {
62 typedef openfpm::detail::multi_array::multi_array_view_openfpm<T,NDims> type;
63 };
64
65 // Allow default copy constructor as well.
66
67 template <typename Ovector>
68 const_sub_array_openfpm (const const_sub_array_openfpm<T,NumDims,Ovector>& rhs)
69 :base_(rhs.base_), strides_(rhs.strides_)
70 {}
71
72 // const_sub_array always returns const types, regardless of its own
73 // constness.
74 inline __device__ __host__ const_reference operator[](index idx) const
75 {
76 return super_type::access(boost::type<const_reference>(),idx,strides(),base_);
77 }
78
79 template <typename IndexList>
80 const element& operator()(const IndexList& indices) const
81 {
82 boost::function_requires<boost::CollectionConcept<IndexList> >();
83 return super_type::access_element(boost::type<const element&>(),
84 indices,origin(),strides());
85 }
86
87 // see generate_array_view in base.hpp
88 template <int NDims>
89 __device__ __host__ typename const_array_view<NDims>::type
90 operator[](const boost::detail::multi_array::index_gen<NumDims,NDims>& indices) const
91 {
92 typedef typename const_array_view<NDims>::type return_type;
93 return super_type::generate_array_view(boost::type<return_type>(),
94 indices,
95 base_);
96 }
97
98 template <typename OPtr>
99 bool operator!=(const const_sub_array_openfpm<T,NumDims,OPtr>& rhs) const {
100 return !(*this == rhs);
101 }
102
103 template <typename OPtr>
104 bool operator>(const const_sub_array_openfpm<T,NumDims,OPtr>& rhs) const {
105 return rhs < *this;
106 }
107
108 template <typename OPtr>
109 bool operator<=(const const_sub_array_openfpm<T,NumDims,OPtr>& rhs) const {
110 return !(*this > rhs);
111 }
112
113 template <typename OPtr>
114 bool operator>=(const const_sub_array_openfpm<T,NumDims,OPtr>& rhs) const {
115 return !(*this < rhs);
116 }
117
118 TPtr origin() const { return base_; }
119 inline __host__ __device__ size_type size() const { return boost::mpl::at<vector,boost::mpl::int_<0>>::type::value; }
120 size_type max_size() const { return num_elements(); }
121 bool empty() const { return size() == 0; }
122 size_type num_dimensions() const { return NumDims; }
123 inline __host__ __device__ const index* strides() const { return strides_; }
124
125 size_type num_elements() const
126 {
127 return size_ct::type::value;
128 }
129
130 __device__ __host__ const_sub_array_openfpm (TPtr base, const index* strides)
131 :base_(base), strides_(strides)
132 {}
133
134#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
135protected:
136 template <typename,std::size_t,typename> friend class value_accessor_n_openfpm;
137 template <typename,std::size_t,typename,typename> friend class const_sub_array_openfpm;
138#else
139public: // Should be protected
140#endif
141
142
143 TPtr base_;
144 const index* strides_;
145private:
146 // const_sub_array cannot be assigned to (no deep copies!)
147 const_sub_array_openfpm& operator=(const const_sub_array_openfpm&);
148};
149
150//
151// sub_array
152// multi_array's proxy class to allow multiple overloads of
153// operator[] in order to provide a clean multi-dimensional array
154// interface.
155template <typename T, std::size_t NumDims, typename vector>
156class sub_array_openfpm : public const_sub_array_openfpm<T,NumDims,vector,T*>
157{
158 typedef const_sub_array_openfpm<T,NumDims,vector,T*> super_type;
159public:
160 typedef typename super_type::element element;
161 typedef typename super_type::reference reference;
162 typedef typename super_type::index index;
163 typedef typename super_type::size_type size_type;
164 typedef typename super_type::iterator iterator;
165 typedef typename super_type::reverse_iterator reverse_iterator;
166 typedef typename super_type::const_reference const_reference;
167 typedef typename super_type::const_iterator const_iterator;
168 typedef typename super_type::const_reverse_iterator const_reverse_iterator;
169 typedef int yes_is_multi_array;
170
171 // template typedefs
172 template <std::size_t NDims>
173 struct const_array_view {
174 typedef openfpm::detail::multi_array::const_multi_array_view_openfpm<T,NDims> type;
175 };
176
177 template <std::size_t NDims>
178 struct array_view {
179 typedef openfpm::detail::multi_array::multi_array_view_openfpm<T,NDims> type;
180 };
181
182 // Assignment from other ConstMultiArray types.
183 template <typename ConstMultiArray>
184 __device__ __host__ inline sub_array_openfpm& operator=(const ConstMultiArray& other)
185 {
186#ifdef SE_CLASS1
187
188 // make sure the dimensions agree
189 BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
190
191#endif
192 // iterator-based copy
193// std::copy(other.begin(),other.end(),begin());
194
195 for (int i = 0 ; i < (int)other.size() ; i++)
196 {this->operator[](i) = other[i];}
197 return *this;
198 }
199
200 __device__ __host__ sub_array_openfpm& operator=(const sub_array_openfpm& other)
201 {
202#ifdef SE_CLASS1
203 // make sure the dimensions agree
204 BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
205// BOOST_ASSERT(std::equal(other.shape(),
206// other.shape()+this->num_dimensions(),
207// this->shape()));
208#endif
209 // iterator-based copy
210 //std::copy(other.begin(),other.end(),begin());
211
212 for (int i = 0 ; i < (int)other.size() ; i++)
213 {this->operator[](i) = other[i];}
214 return *this;
215 }
216
217 __device__ __host__ T* origin() { return this->base_; }
218 __device__ __host__ const T* origin() const { return this->base_; }
219
220 __device__ __host__ reference operator[](index idx) {
221 return super_type::access(boost::type<reference>(),
222 idx,
223 this->strides(),
224 this->base_);
225 }
226
227 __device__ __host__ iterator begin()
228 {
229 return iterator(*this->index_bases(),origin(),
230 this->shape(),this->strides(),this->index_bases());
231 }
232
233 __device__ __host__ iterator end()
234 {
235 return iterator(*this->index_bases()+(index)*this->shape(),origin(),
236 this->shape(),this->strides(),this->index_bases());
237 }
238
239 // RG - rbegin() and rend() written naively to thwart MSVC ICE.
240 reverse_iterator rbegin() {
241 reverse_iterator ri(end());
242 return ri;
243 }
244
245 reverse_iterator rend() {
246 reverse_iterator ri(begin());
247 return ri;
248 }
249
250 //
251 // proxies
252 //
253
254 template <class IndexList>
255 const element& operator()(const IndexList& indices) const {
256 boost::function_requires<
257 boost::CollectionConcept<IndexList> >();
258 return super_type::operator()(indices);
259 }
260
261 const_reference __device__ __host__ operator[](index idx) const {
262 return super_type::operator[](idx);
263 }
264
265 const_iterator begin() const {
266 return super_type::begin();
267 }
268
269 const_iterator end() const {
270 return super_type::end();
271 }
272
273 const_reverse_iterator rbegin() const {
274 return super_type::rbegin();
275 }
276
277 const_reverse_iterator rend() const {
278 return super_type::rend();
279 }
280
281#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
282private:
283 template <typename,std::size_t,typename> friend class value_accessor_n_openfpm;
284#endif
285public: // should be private
286
287 inline __device__ __host__ sub_array_openfpm (T* base,
288 const index* strides)
289 :super_type(base,strides)
290 {}
291
292};
293
294} // namespace multi_array
295} // namespace detail
296//
297// traits classes to get sub_array types
298//
299template <typename Array, int N, typename vector>
300class subarray_gen_openfpm {
301 typedef typename Array::element element;
302public:
303 typedef openfpm::detail::multi_array::sub_array_openfpm<element,N,vector> type;
304};
305
306template <typename Array, int N, typename vector>
307class const_subarray_gen_openfpm {
308 typedef typename Array::element element;
309public:
310 typedef openfpm::detail::multi_array::const_sub_array_openfpm<element,N,vector> type;
311};
312} // namespace boost
313
314
315#endif /* MULTI_ARRAY_REF_SUBARRAY_OPENFPM_HPP_ */
316