• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 Glen Joseph Fernandes
2 // (glenjofe@gmail.com)
3 //
4 // Distributed under the Boost Software License, Version 1.0.
5 // (See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7 
8 #include <boost/core/lightweight_test.hpp>
9 #include <boost/multi_array.hpp>
10 #include <algorithm>
11 
12 template<class T>
13 class creator {
14 public:
15   typedef T value_type;
16   typedef T* pointer;
17   typedef std::size_t size_type;
18   typedef std::ptrdiff_t difference_type;
19 
20   template<class U>
21   struct rebind {
22     typedef creator<U> other;
23   };
24 
creator(int state)25   creator(int state)
26     : state_(state) { }
27 
28   template<class U>
creator(const creator<U> & other)29   creator(const creator<U>& other)
30     : state_(other.state()) { }
31 
allocate(std::size_t size)32   T* allocate(std::size_t size) {
33     return static_cast<T*>(::operator new(sizeof(T) * size));
34   }
35 
deallocate(T * ptr,std::size_t)36   void deallocate(T* ptr, std::size_t) {
37     ::operator delete(ptr);
38   }
39 
state() const40   int state() const {
41     return state_;
42   }
43 
44 private:
45   int state_;
46 };
47 
48 template<class T, class U>
49 inline bool
operator ==(const creator<T> & a,const creator<U> & b)50 operator==(const creator<T>& a, const creator<U>& b)
51 {
52   return a.state() == b.state();
53 }
54 
55 template<class T, class U>
56 inline bool
operator !=(const creator<T> & a,const creator<U> & b)57 operator!=(const creator<T>& a, const creator<U>& b)
58 {
59   return !(a == b);
60 }
61 
test(const double &,std::size_t *,int *,unsigned)62 void test(const double&, std::size_t*, int*, unsigned)
63 {
64 }
65 
66 template<class Array>
test(const Array & array,std::size_t * sizes,int * strides,unsigned elements)67 void test(const Array& array, std::size_t* sizes, int* strides,
68     unsigned elements)
69 {
70   BOOST_TEST(array.num_elements() == elements);
71   BOOST_TEST(array.size() == *sizes);
72   BOOST_TEST(std::equal(sizes, sizes + array.num_dimensions(), array.shape()));
73   BOOST_TEST(std::equal(strides, strides + array.num_dimensions(),
74     array.strides()));
75   test(array[0], ++sizes, ++strides, elements / array.size());
76 }
77 
test(const double & a,const double & b)78 bool test(const double& a, const double& b)
79 {
80   return a == b;
81 }
82 
83 template<class A1, class A2>
test(const A1 & a1,const A2 & a2)84 bool test(const A1& a1, const A2& a2)
85 {
86   typename A1::const_iterator i1 = a1.begin();
87   typename A2::const_iterator i2 = a2.begin();
88   for (; i1 != a1.end(); ++i1, ++i2) {
89     if (!test(*i1, *i2)) {
90       return false;
91     }
92   }
93   return true;
94 }
95 
main()96 int main()
97 {
98   typedef boost::multi_array<double, 3, creator<double> > type;
99   creator<double> state(1);
100   {
101     type array(state);
102   }
103   boost::array<type::size_type, 3> sizes = { { 3, 3, 3 } };
104   type::size_type elements = 27;
105   {
106     int strides[] = { 9, 3, 1 };
107     type array(sizes, state);
108     test(array, &sizes[0], strides, elements);
109   }
110   {
111     int strides[] = { 1, 3, 9 };
112     type array(sizes, boost::fortran_storage_order(), state);
113     test(array, &sizes[0], strides, elements);
114   }
115   {
116     int strides[] = { 9, 3, 1 };
117     type::extent_gen extents;
118     type array(extents[3][3][3], state);
119     test(array, &sizes[0], strides, elements);
120   }
121   {
122     type array1(sizes, state);
123     std::vector<double> values(elements, 4.5);
124     array1.assign(values.begin(), values.end());
125     type array2(array1);
126     int strides[] = { 9, 3, 1 };
127     test(array2, &sizes[0], strides, elements);
128     BOOST_TEST(test(array1, array2));
129   }
130   {
131     type array1(sizes, state);
132     type array2(sizes, state);
133     std::vector<double> values(elements, 4.5);
134     array1.assign(values.begin(), values.end());
135     array2 = array1;
136     int strides[] = { 9, 3, 1 };
137     test(array2, &sizes[0], strides, elements);
138     BOOST_TEST(test(array1, array2));
139   }
140   {
141     type array1(sizes, state);
142     std::vector<double> values(elements, 4.5);
143     array1.assign(values.begin(), values.end());
144     typedef type::subarray<2>::type other;
145     other array2 = array1[1];
146     other::value_type value = array2[0];
147     BOOST_TEST(test(array1[1][0], value));
148     BOOST_TEST(test(array2[0], value));
149   }
150   return boost::report_errors();
151 }
152