constructors.cpp 6.3 KB

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