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
12template<class T>
13class creator {
14public:
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
25 creator(int state)
26 : state_(state) { }
27
28 template<class U>
29 creator(const creator<U>& other)
30 : state_(other.state()) { }
31
32 T* allocate(std::size_t size) {
33 return static_cast<T*>(::operator new(sizeof(T) * size));
34 }
35
36 void deallocate(T* ptr, std::size_t) {
37 ::operator delete(ptr);
38 }
39
40 int state() const {
41 return state_;
42 }
43
44private:
45 int state_;
46};
47
48template<class T, class U>
49inline bool
50operator==(const creator<T>& a, const creator<U>& b)
51{
52 return a.state() == b.state();
53}
54
55template<class T, class U>
56inline bool
57operator!=(const creator<T>& a, const creator<U>& b)
58{
59 return !(a == b);
60}
61
62void test(const double&, std::size_t*, int*, unsigned)
63{
64}
65
66template<class Array>
67void 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
78bool test(const double& a, const double& b)
79{
80 return a == b;
81}
82
83template<class A1, class A2>
84bool 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
96int 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 = { .elems: { 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: &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: &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: &sizes[0], strides, elements);
120 }
121 {
122 type array1(sizes, state);
123 std::vector<double> values(elements, 4.5);
124 array1.assign(begin: values.begin(), end: values.end());
125 type array2(array1);
126 int strides[] = { 9, 3, 1 };
127 test(array: array2, sizes: &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(begin: values.begin(), end: values.end());
135 array2 = array1;
136 int strides[] = { 9, 3, 1 };
137 test(array: array2, sizes: &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(begin: values.begin(), end: 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

source code of boost/libs/multi_array/test/allocators.cpp