• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2002 The Trustees of Indiana University.
2 
3 // Use, modification and distribution is subject to the Boost Software
4 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6 
7 //  Boost.MultiArray Library
8 //  Authors: Ronald Garcia
9 //           Jeremy Siek
10 //           Andrew Lumsdaine
11 //  See http://www.boost.org/libs/multi_array for documentation.
12 
13 //
14 // constructors.cpp - Testing out the various constructor options
15 //
16 
17 
18 #include <boost/core/lightweight_test.hpp>
19 
20 #include <boost/multi_array.hpp>
21 #include <algorithm>
22 #include <list>
23 
check_shape(const double &,std::size_t *,int *,unsigned int)24 void check_shape(const double&, std::size_t*, int*, unsigned int)
25 {}
26 
27 template <class Array>
check_shape(const Array & A,std::size_t * sizes,int * strides,unsigned int num_elements)28 void check_shape(const Array& A,
29                  std::size_t* sizes,
30                  int* strides,
31                  unsigned int num_elements)
32 {
33   BOOST_TEST(A.num_elements() == num_elements);
34   BOOST_TEST(A.size() == *sizes);
35   BOOST_TEST(std::equal(sizes, sizes + A.num_dimensions(), A.shape()));
36   BOOST_TEST(std::equal(strides, strides + A.num_dimensions(), A.strides()));
37   check_shape(A[0], ++sizes, ++strides, num_elements / A.size());
38 }
39 
40 
equal(const double & a,const double & b)41 bool equal(const double& a, const double& b)
42 {
43   return a == b;
44 }
45 
46 template <typename ArrayA, typename ArrayB>
equal(const ArrayA & A,const ArrayB & B)47 bool equal(const ArrayA& A, const ArrayB& B)
48 {
49   typename ArrayA::const_iterator ia;
50   typename ArrayB::const_iterator ib = B.begin();
51   for (ia = A.begin(); ia != A.end(); ++ia, ++ib)
52     if (!::equal(*ia, *ib))
53       return false;
54   return true;
55 }
56 
57 
58 int
main()59 main()
60 {
61   typedef boost::multi_array<double, 3>::size_type size_type;
62   boost::array<size_type,3> sizes = { { 3, 3, 3 } };
63   int strides[] = { 9, 3, 1 };
64   size_type num_elements = 27;
65 
66   // Default multi_array constructor
67   {
68     boost::multi_array<double, 3> A;
69   }
70 
71   // Constructor 1, default storage order and allocator
72   {
73     boost::multi_array<double, 3> A(sizes);
74     check_shape(A, &sizes[0], strides, num_elements);
75 
76     double* ptr = 0;
77     boost::multi_array_ref<double,3> B(ptr,sizes);
78     check_shape(B, &sizes[0], strides, num_elements);
79 
80     const double* cptr = ptr;
81     boost::const_multi_array_ref<double,3> C(cptr,sizes);
82     check_shape(C, &sizes[0], strides, num_elements);
83   }
84 
85   // Constructor 1, fortran storage order and user-supplied allocator
86   {
87     typedef boost::multi_array<double, 3,
88       std::allocator<double> >::size_type size_type;
89     size_type num_elements = 27;
90     int col_strides[] = { 1, 3, 9 };
91 
92     boost::multi_array<double, 3,
93       std::allocator<double> > A(sizes,boost::fortran_storage_order());
94     check_shape(A, &sizes[0], col_strides, num_elements);
95 
96     double *ptr=0;
97     boost::multi_array_ref<double, 3>
98       B(ptr,sizes,boost::fortran_storage_order());
99     check_shape(B, &sizes[0], col_strides, num_elements);
100 
101     const double *cptr=ptr;
102     boost::const_multi_array_ref<double, 3>
103       C(cptr,sizes,boost::fortran_storage_order());
104     check_shape(C, &sizes[0], col_strides, num_elements);
105   }
106 
107   // Constructor 2, default storage order and allocator
108   {
109     typedef boost::multi_array<double, 3>::size_type size_type;
110     size_type num_elements = 27;
111 
112     boost::multi_array<double, 3>::extent_gen extents;
113     boost::multi_array<double, 3> A(extents[3][3][3]);
114     check_shape(A, &sizes[0], strides, num_elements);
115 
116     double *ptr=0;
117     boost::multi_array_ref<double, 3> B(ptr,extents[3][3][3]);
118     check_shape(B, &sizes[0], strides, num_elements);
119 
120     const double *cptr=ptr;
121     boost::const_multi_array_ref<double, 3> C(cptr,extents[3][3][3]);
122     check_shape(C, &sizes[0], strides, num_elements);
123   }
124 
125   // Copy Constructors
126   {
127     typedef boost::multi_array<double, 3>::size_type size_type;
128     size_type num_elements = 27;
129     std::vector<double> vals(27, 4.5);
130 
131     boost::multi_array<double, 3> A(sizes);
132     A.assign(vals.begin(),vals.end());
133     boost::multi_array<double, 3> B(A);
134     check_shape(B, &sizes[0], strides, num_elements);
135     BOOST_TEST(::equal(A, B));
136 
137     double ptr[27];
138     boost::multi_array_ref<double, 3> C(ptr,sizes);
139     A.assign(vals.begin(),vals.end());
140     boost::multi_array_ref<double, 3> D(C);
141     check_shape(D, &sizes[0], strides, num_elements);
142     BOOST_TEST(C.data() == D.data());
143 
144     const double* cptr = ptr;
145     boost::const_multi_array_ref<double, 3> E(cptr,sizes);
146     boost::const_multi_array_ref<double, 3> F(E);
147     check_shape(F, &sizes[0], strides, num_elements);
148     BOOST_TEST(E.data() == F.data());
149   }
150 
151 
152   // Conversion construction
153   {
154     typedef boost::multi_array<double, 3>::size_type size_type;
155     size_type num_elements = 27;
156     std::vector<double> vals(27, 4.5);
157 
158     boost::multi_array<double, 3> A(sizes);
159     A.assign(vals.begin(),vals.end());
160     boost::multi_array_ref<double, 3> B(A);
161     boost::const_multi_array_ref<double, 3> C(A);
162     check_shape(B, &sizes[0], strides, num_elements);
163     check_shape(C, &sizes[0], strides, num_elements);
164     BOOST_TEST(B.data() == A.data());
165     BOOST_TEST(C.data() == A.data());
166 
167     double ptr[27];
168     boost::multi_array_ref<double, 3> D(ptr,sizes);
169     D.assign(vals.begin(),vals.end());
170     boost::const_multi_array_ref<double, 3> E(D);
171     check_shape(E, &sizes[0], strides, num_elements);
172     BOOST_TEST(E.data() == D.data());
173   }
174 
175   // Assignment Operator
176   {
177     typedef boost::multi_array<double, 3>::size_type size_type;
178     size_type num_elements = 27;
179     std::vector<double> vals(27, 4.5);
180 
181     boost::multi_array<double, 3> A(sizes), B(sizes);
182     A.assign(vals.begin(),vals.end());
183     B = A;
184     check_shape(B, &sizes[0], strides, num_elements);
185     BOOST_TEST(::equal(A, B));
186 
187     double ptr1[27];
188     double ptr2[27];
189     boost::multi_array_ref<double, 3> C(ptr1,sizes), D(ptr2,sizes);
190     C.assign(vals.begin(),vals.end());
191     D = C;
192     check_shape(D, &sizes[0], strides, num_elements);
193     BOOST_TEST(::equal(C,D));
194   }
195 
196 
197   // subarray value_type is multi_array
198   {
199     typedef boost::multi_array<double,3> array;
200     typedef array::size_type size_type;
201     size_type num_elements = 27;
202     std::vector<double> vals(num_elements, 4.5);
203 
204     boost::multi_array<double, 3> A(sizes);
205     A.assign(vals.begin(),vals.end());
206 
207     typedef array::subarray<2>::type subarray;
208     subarray B = A[1];
209     subarray::value_type C = B[0];
210 
211     // should comparisons between the types work?
212     BOOST_TEST(::equal(A[1][0],C));
213     BOOST_TEST(::equal(B[0],C));
214   }
215   return boost::report_errors();
216 }
217 
218 
219