allocators.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  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. #include <boost/core/lightweight_test.hpp>
  8. #include <boost/multi_array.hpp>
  9. #include <algorithm>
  10. template<class T>
  11. class creator {
  12. public:
  13. typedef T value_type;
  14. typedef T* pointer;
  15. typedef std::size_t size_type;
  16. typedef std::ptrdiff_t difference_type;
  17. template<class U>
  18. struct rebind {
  19. typedef creator<U> other;
  20. };
  21. creator(int state)
  22. : state_(state) { }
  23. template<class U>
  24. creator(const creator<U>& other)
  25. : state_(other.state()) { }
  26. T* allocate(std::size_t size) {
  27. return static_cast<T*>(::operator new(sizeof(T) * size));
  28. }
  29. void deallocate(T* ptr, std::size_t) {
  30. ::operator delete(ptr);
  31. }
  32. int state() const {
  33. return state_;
  34. }
  35. private:
  36. int state_;
  37. };
  38. template<class T, class U>
  39. inline bool
  40. operator==(const creator<T>& a, const creator<U>& b)
  41. {
  42. return a.state() == b.state();
  43. }
  44. template<class T, class U>
  45. inline bool
  46. operator!=(const creator<T>& a, const creator<U>& b)
  47. {
  48. return !(a == b);
  49. }
  50. void test(const double&, std::size_t*, int*, unsigned)
  51. {
  52. }
  53. template<class Array>
  54. void test(const Array& array, std::size_t* sizes, int* strides,
  55. unsigned elements)
  56. {
  57. BOOST_TEST(array.num_elements() == elements);
  58. BOOST_TEST(array.size() == *sizes);
  59. BOOST_TEST(std::equal(sizes, sizes + array.num_dimensions(), array.shape()));
  60. BOOST_TEST(std::equal(strides, strides + array.num_dimensions(),
  61. array.strides()));
  62. test(array[0], ++sizes, ++strides, elements / array.size());
  63. }
  64. bool test(const double& a, const double& b)
  65. {
  66. return a == b;
  67. }
  68. template<class A1, class A2>
  69. bool test(const A1& a1, const A2& a2)
  70. {
  71. typename A1::const_iterator i1 = a1.begin();
  72. typename A2::const_iterator i2 = a2.begin();
  73. for (; i1 != a1.end(); ++i1, ++i2) {
  74. if (!test(*i1, *i2)) {
  75. return false;
  76. }
  77. }
  78. return true;
  79. }
  80. int main()
  81. {
  82. typedef boost::multi_array<double, 3, creator<double> > type;
  83. creator<double> state(1);
  84. {
  85. type array(state);
  86. }
  87. boost::array<type::size_type, 3> sizes = { { 3, 3, 3 } };
  88. type::size_type elements = 27;
  89. {
  90. int strides[] = { 9, 3, 1 };
  91. type array(sizes, state);
  92. test(array, &sizes[0], strides, elements);
  93. }
  94. {
  95. int strides[] = { 1, 3, 9 };
  96. type array(sizes, boost::fortran_storage_order(), state);
  97. test(array, &sizes[0], strides, elements);
  98. }
  99. {
  100. int strides[] = { 9, 3, 1 };
  101. type::extent_gen extents;
  102. type array(extents[3][3][3], state);
  103. test(array, &sizes[0], strides, elements);
  104. }
  105. {
  106. type array1(sizes, state);
  107. std::vector<double> values(elements, 4.5);
  108. array1.assign(values.begin(), values.end());
  109. type array2(array1);
  110. int strides[] = { 9, 3, 1 };
  111. test(array2, &sizes[0], strides, elements);
  112. BOOST_TEST(test(array1, array2));
  113. }
  114. {
  115. type array1(sizes, state);
  116. type array2(sizes, state);
  117. std::vector<double> values(elements, 4.5);
  118. array1.assign(values.begin(), values.end());
  119. array2 = array1;
  120. int strides[] = { 9, 3, 1 };
  121. test(array2, &sizes[0], strides, elements);
  122. BOOST_TEST(test(array1, array2));
  123. }
  124. {
  125. type array1(sizes, state);
  126. std::vector<double> values(elements, 4.5);
  127. array1.assign(values.begin(), values.end());
  128. typedef type::subarray<2>::type other;
  129. other array2 = array1[1];
  130. other::value_type value = array2[0];
  131. BOOST_TEST(test(array1[1][0], value));
  132. BOOST_TEST(test(array2[0], value));
  133. }
  134. return boost::report_errors();
  135. }