8#ifndef ARRAY_OPENFPM_HPP_
9#define ARRAY_OPENFPM_HPP_
11#include <boost/detail/workaround.hpp>
13#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
15# pragma warning(disable:4996)
16# pragma warning(disable:4510)
17# pragma warning(disable:4610)
22#include <boost/assert.hpp>
23#include <boost/static_assert.hpp>
24#include <boost/swap.hpp>
27#include <boost/throw_exception.hpp>
31#include <boost/config.hpp>
36 template<
class T, std::
size_t N,
typename ids_type = std::
size_t>
46 typedef const T* const_iterator;
48 typedef const T& const_reference;
49 typedef ids_type size_type;
50 typedef std::ptrdiff_t difference_type;
53 iterator begin() {
return elems; }
54 const_iterator begin()
const {
return elems; }
55 const_iterator cbegin()
const {
return elems; }
57 iterator end() {
return elems+N; }
58 const_iterator end()
const {
return elems+N; }
59 const_iterator cend()
const {
return elems+N; }
62#if !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
63 typedef std::reverse_iterator<iterator> reverse_iterator;
64 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
65#elif defined(_RWSTD_NO_CLASS_PARTIAL_SPEC)
66 typedef std::reverse_iterator<iterator, std::random_access_iterator_tag,
67 value_type, reference, iterator, difference_type> reverse_iterator;
68 typedef std::reverse_iterator<const_iterator, std::random_access_iterator_tag,
69 value_type, const_reference, const_iterator, difference_type> const_reverse_iterator;
72 typedef std::reverse_iterator<iterator,T> reverse_iterator;
73 typedef std::reverse_iterator<const_iterator,T> const_reverse_iterator;
76 reverse_iterator rbegin() {
return reverse_iterator(end()); }
77 const_reverse_iterator rbegin()
const {
return const_reverse_iterator(end());}
78 const_reverse_iterator crbegin()
const {
return const_reverse_iterator(end());}
80 reverse_iterator rend() {
return reverse_iterator(begin()); }
81 const_reverse_iterator rend()
const {
return const_reverse_iterator(begin());}
82 const_reverse_iterator crend()
const {
return const_reverse_iterator(begin());}
85 __device__ __host__ reference operator[](size_type i)
87 return BOOST_ASSERT_MSG( i < N,
"out of range" ), elems[i];
90 __device__ __host__ const_reference operator[](size_type i)
const
92 return BOOST_ASSERT_MSG( i < N,
"out of range" ), elems[i];
96 reference at(size_type i) {
return rangecheck(i), elems[i]; }
97 const_reference at(size_type i)
const {
return rangecheck(i), elems[i]; }
105 BOOST_CONSTEXPR const_reference front()
const
115 BOOST_CONSTEXPR const_reference back()
const
121 static BOOST_CONSTEXPR size_type size() {
return N; }
122 static BOOST_CONSTEXPR
bool empty() {
return false; }
123 static BOOST_CONSTEXPR size_type max_size() {
return N; }
124 enum { static_size = N };
129 for (size_type i = 0; i < N; ++i)
130 {boost::swap(elems[i],y.elems[i]);}
134 inline __device__ __host__
const T* data()
const {
return elems; }
135 inline __device__ __host__ T* data() {
return elems; }
138 T* c_array() {
return elems; }
141 template <
typename T2>
144 std::copy(rhs.begin(),rhs.end(), begin());
149 void assign (
const T& value) { fill ( value ); }
150 void fill (
const T& value)
152 std::fill_n(begin(),size(),value);
156 static BOOST_CONSTEXPR
bool rangecheck (size_type i)
157 {
return i > size() ? boost::throw_exception(std::out_of_range (
"array<>: index out of range")), true :
true;}
166 typedef T value_type;
168 typedef const T* const_iterator;
169 typedef T& reference;
170 typedef const T& const_reference;
171 typedef std::size_t size_type;
172 typedef std::ptrdiff_t difference_type;
175 iterator begin() {
return iterator(
reinterpret_cast< T *
>(
this ) ); }
176 const_iterator begin()
const {
return const_iterator(
reinterpret_cast< const T *
>(
this ) ); }
177 const_iterator cbegin()
const {
return const_iterator(
reinterpret_cast< const T *
>(
this ) ); }
179 iterator end() {
return begin(); }
180 const_iterator end()
const {
return begin(); }
181 const_iterator cend()
const {
return cbegin(); }
184#if !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
185 typedef std::reverse_iterator<iterator> reverse_iterator;
186 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
187#elif defined(_RWSTD_NO_CLASS_PARTIAL_SPEC)
188 typedef std::reverse_iterator<iterator, std::random_access_iterator_tag,
189 value_type, reference, iterator, difference_type> reverse_iterator;
190 typedef std::reverse_iterator<const_iterator, std::random_access_iterator_tag,
191 value_type, const_reference, const_iterator, difference_type> const_reverse_iterator;
194 typedef std::reverse_iterator<iterator,T> reverse_iterator;
195 typedef std::reverse_iterator<const_iterator,T> const_reverse_iterator;
198 reverse_iterator rbegin() {
return reverse_iterator(end()); }
199 const_reverse_iterator rbegin()
const {
200 return const_reverse_iterator(end());
202 const_reverse_iterator crbegin()
const {
203 return const_reverse_iterator(end());
206 reverse_iterator rend() {
return reverse_iterator(begin()); }
207 const_reverse_iterator rend()
const {
208 return const_reverse_iterator(begin());
210 const_reverse_iterator crend()
const {
211 return const_reverse_iterator(begin());
215 reference operator[](size_type )
217 return failed_rangecheck();
220 const_reference operator[](size_type )
const
222 return failed_rangecheck();
226 reference at(size_type ) {
return failed_rangecheck(); }
227 const_reference at(size_type )
const {
return failed_rangecheck(); }
232 return failed_rangecheck();
235 BOOST_CONSTEXPR const_reference front()
const
237 return failed_rangecheck();
242 return failed_rangecheck();
245 BOOST_CONSTEXPR const_reference back()
const
247 return failed_rangecheck();
251 static BOOST_CONSTEXPR size_type size() {
return 0; }
252 static BOOST_CONSTEXPR
bool empty() {
return true; }
253 static BOOST_CONSTEXPR size_type max_size() {
return 0; }
254 enum { static_size = 0 };
259 const T* data()
const {
return 0; }
260 T* data() {
return 0; }
263 T* c_array() {
return 0; }
266 template <
typename T2>
271 void assign (
const T& value) { fill ( value ); }
272 void fill (
const T& ) {}
275 static reference failed_rangecheck ()
277 std::out_of_range e(
"attempt to access element of an empty array");
278 boost::throw_exception(e);
279#if defined(BOOST_NO_EXCEPTIONS) || (!defined(BOOST_MSVC) && !defined(__PATHSCALE__))
285 static T placeholder;
292 template<
class T, std::
size_t N>
294 return std::equal(x.begin(), x.end(), y.begin());
296 template<
class T, std::
size_t N>
297 bool operator< (
const array<T,N>& x,
const array<T,N>& y) {
298 return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
300 template<
class T, std::
size_t N>
301 bool operator!= (
const array<T,N>& x,
const array<T,N>& y) {
304 template<
class T, std::
size_t N>
305 bool operator> (
const array<T,N>& x,
const array<T,N>& y) {
308 template<
class T, std::
size_t N>
309 bool operator<= (
const array<T,N>& x,
const array<T,N>& y) {
312 template<
class T, std::
size_t N>
313 bool operator>= (
const array<T,N>& x,
const array<T,N>& y) {
318 template<
class T, std::
size_t N>
319 inline void swap (array<T,N>& x, array<T,N>& y)
322#if defined(__SUNPRO_CC)
330 template <
typename T, std::
size_t N>
struct c_array
337 template <
typename T, std::
size_t N>
344 template <
typename T, std::
size_t N>
351 template <
typename T, std::
size_t N>
358 template <
typename T, std::
size_t N>
366 template <
class It> std::size_t hash_range(It, It);
368 template<
class T, std::
size_t N>
369 std::size_t hash_value(
const array<T,N>& arr)
371 return openfpm::hash_range(arr.begin(), arr.end());
374 template <
size_t Idx,
typename T,
size_t N>
377 BOOST_STATIC_ASSERT_MSG ( Idx < N,
"boost::get<>(boost::array &) index out of range" );
381 template <
size_t Idx,
typename T,
size_t N>
384 BOOST_STATIC_ASSERT_MSG ( Idx < N,
"boost::get<>(const boost::array &) index out of range" );
390#ifndef BOOST_NO_CXX11_HDR_ARRAY
393 template <
size_t Idx,
typename T,
size_t N>
396 BOOST_STATIC_ASSERT_MSG ( Idx < N,
"std::get<>(boost::array &) index out of range" );
400 template <
size_t Idx,
typename T,
size_t N>
403 BOOST_STATIC_ASSERT_MSG ( Idx < N,
"std::get<>(const boost::array &) index out of range" );
409#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
convert a type into constant type