big-0.cc 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. // -*- mode: c++; coding: utf-8 -*-
  2. /// @file big-0.cc
  3. /// @brief Tests specific to Container. Constructors.
  4. // (c) Daniel Llorens - 2017
  5. // This library is free software; you can redistribute it and/or modify it under
  6. // the terms of the GNU Lesser General Public License as published by the Free
  7. // Software Foundation; either version 3 of the License, or (at your option) any
  8. // later version.
  9. #include <iostream>
  10. #include <iterator>
  11. #include "ra/ra.hh"
  12. #include "ra/test.hh"
  13. #include "ra/mpdebug.hh"
  14. using std::cout, std::endl, std::flush, ra::TestRecorder;
  15. int main(int argc, char * * argv)
  16. {
  17. TestRecorder tr;
  18. tr.section("constructors");
  19. {
  20. tr.section("regression with some shape arguments (fixed rank)");
  21. {
  22. ra::Big<int, 1> sizes = {5};
  23. ra::Big<double, 1> a(sizes, ra::none);
  24. a = 33.;
  25. tr.test_eq(5, a.size());
  26. tr.test_eq(33, a);
  27. }
  28. tr.section("regression with implicitly declared View constructors [ra38]. Reduced from examples/maxwell.cc");
  29. {
  30. ra::Big<int, 1> A = {1, 2};
  31. ra::Big<int, 1> X = {0, 0};
  32. X(ra::all) = A();
  33. tr.test_eq(ra::start({1, 2}), X);
  34. }
  35. tr.section("need for explicit View::operator=(View const & x) [ra34]");
  36. {
  37. ra::Big<int, 1> a {0, 1, 2, 3, 4, 5};
  38. auto const va = a();
  39. ra::Big<int, 1> x(va); // replacing default operator= by copy-to-view.
  40. tr.test_eq(ra::iota(6), x);
  41. }
  42. tr.section("init list constructors handle implicit conversions");
  43. {
  44. ra::Big<int, 2> a({int(3), ssize_t(2)}, {0, 1, 2, 3, 4, 5});
  45. tr.test_eq(ra::_0 * 2 + ra::_1, a);
  46. tr.test_eq(3, a.size(0));
  47. tr.test_eq(2, a.size(1));
  48. }
  49. }
  50. tr.section("should-fail constructors");
  51. {
  52. tr.section("shape errors detected at ct FIXME cannot test ct errors yet [ra42]");
  53. {
  54. // ra::Big<int, 2> a({2, 3, 1}, 99); // does not compile
  55. // ra::Big<int, 2> b({2, 3, 1}, {1, 2, 3, 4, 5, 6}); // does not compile
  56. // ra::Big<int, 2> c({2, 3, 1}, ra::none); // does not compile
  57. // ra::Big<int, 2> d(2, ra::none); // does not compile (maybe it should? by rank extension)
  58. }
  59. tr.section("shape errors detected at ct FIXME cannot test ct errors yet [ra42]");
  60. {
  61. // ra::Big<double, 0> a({3, 4}, 3.); cout << a << endl; // does not compile
  62. }
  63. tr.section("init from init list fails at ct if rank != 1 FIXME cannot test ct errors yet [ra42]");
  64. {
  65. // ra::Big<double, 2> a {1, 2, 3, 4, 5, 6}; cout << a << endl; // does not compile
  66. }
  67. tr.section("bad rank with ct size X && type shape argument FIXME cannot test ct errors yet [ra42]");
  68. {
  69. // ra::Big<double, 2> a(ra::Small<int, 3>{2, 3, 4}, 99.); cout << a << endl; // does not compile
  70. }
  71. }
  72. tr.section("any rank 1 expression for the shape argument");
  73. {
  74. ra::Big<int, 2> a (2+ra::iota(2), {0, 1, 2, 3, 4, 5});
  75. tr.test_eq(ra::Small<int, 2, 3> {{0, 1, 2}, {3, 4, 5}}, a);
  76. }
  77. tr.section("even non-drivable expressions if the rank is fixed");
  78. {
  79. ra::Big<int, 2> a(ra::_0 + 2, {0, 1, 2, 3, 4, 5});
  80. tr.test_eq(ra::Small<int, 2, 3> {{0, 1, 2}, {3, 4, 5}}, a);
  81. }
  82. tr.section("also on raw views");
  83. {
  84. int ap[6] = {0, 1, 2, 3, 4, 5};
  85. ra::View<int *, 2> a(2+ra::iota(2), ap); // TODO [ra28]
  86. tr.test_eq(2, a.size(0));
  87. tr.test_eq(3, a.size(1));
  88. tr.test_eq(ra::Small<int, 2, 3> {{0, 1, 2}, {3, 4, 5}}, a);
  89. tr.test_eq(ra::scalar(ap), ra::scalar(a.data()));
  90. }
  91. tr.section("also on raw views with var rank");
  92. {
  93. int ap[6] = {0, 1, 2, 3, 4, 5};
  94. ra::View<int *> a(2+ra::iota(2), ap); // FIXME [ra28]
  95. tr.test_eq(2, a.size(0));
  96. tr.test_eq(3, a.size(1));
  97. tr.test_eq(ra::Small<int, 2, 3> {{0, 1, 2}, {3, 4, 5}}, a);
  98. tr.test_eq(ra::scalar(ap), ra::scalar(a.data()));
  99. }
  100. tr.section("nested braces operator=");
  101. {
  102. ra::Big<int, 2> a({2, 3}, {0, 1, 2, 3, 4, 5});
  103. auto ap = a.data();
  104. a = {{4, 5, 6}, {7, 8, 9}}; // this uses operator=(nested_braces_r)
  105. tr.test_eq(ra::scalar(ap), ra::scalar(a.data()));
  106. tr.test_eq(ra::iota(6, 4), ra::ptr(a.data()));
  107. a = {{{4, 5, 6}, {7, 8, 9}}}; // this uses the nested_braces_r constructor (!!)
  108. tr.skip().test_eq(ra::scalar(ap), ra::scalar(a.data())); // FIXME fairly dangerous!
  109. tr.test_eq(2, a.size(0));
  110. tr.test_eq(3, a.size(1));
  111. tr.test_eq(ra::iota(6, 4), ra::ptr(a.data()));
  112. }
  113. tr.section("nested braces constructor");
  114. {
  115. ra::Big<int, 2> a = {{4, 5, 6}, {7, 8, 9}};
  116. tr.test_eq(2, a.size(0));
  117. tr.test_eq(3, a.size(1));
  118. tr.test_eq(ra::iota(6, 4), ra::ptr(a.data()));
  119. }
  120. tr.section("nested braces for nested type I");
  121. {
  122. ra::Big<ra::Small<int, 2>, 2> a({2, 2}, { {1, 2}, {2, 3}, {4, 5}, {6, 7} });
  123. ra::Big<ra::Small<int, 2>, 2> b({{{1, 2}, {2, 3}}, {{4, 5}, {6, 7}}});
  124. ra::Big<ra::Small<int, 2>, 2> c {{{1, 2}, {2, 3}}, {{4, 5}, {6, 7}}};
  125. ra::Big<ra::Small<int, 2>, 2> d = {{{1, 2}, {2, 3}}, {{4, 5}, {6, 7}}};
  126. tr.test_eq(a, b);
  127. }
  128. tr.section("nested braces for nested type II");
  129. {
  130. int x[2][3] = {{1, 2, 3}, {4, 5, 6}};
  131. int y[2][3] = {{10, 20, 30}, {40, 50, 60}};
  132. ra::Big<ra::Small<int, 2, 3>, 1> a = {x, y};
  133. tr.test_eq(ra::_0*3+ra::_1 + 1, a(0));
  134. tr.test_eq(10*(ra::_0*3+ra::_1 + 1), a(1));
  135. }
  136. tr.section("nested braces for nested type II");
  137. {
  138. int x[2][3] = {{1, 2, 3}, {4, 5, 6}};
  139. int y[2][3] = {{10, 20, 30}, {40, 50, 60}};
  140. ra::Big<ra::Small<int, 2, 3>, 1> a = {x, y};
  141. tr.test_eq(ra::_0*3+ra::_1 + 1, a(0));
  142. tr.test_eq(10*(ra::_0*3+ra::_1 + 1), a(1));
  143. }
  144. tr.section("nested braces for nested type III");
  145. {
  146. int x[4] = {1, 2, 3, 4};
  147. int y[6] = {10, 20, 30, 40, 50, 60};
  148. ra::Big<ra::Big<int, 1>, 1> a = {x, y};
  149. tr.test_eq(ra::iota(4, 1), a(0));
  150. tr.test_eq(ra::iota(6, 10, 10), a(1));
  151. }
  152. tr.section("nested braces for nested type IV");
  153. {
  154. ra::Big<ra::Big<int, 1>, 1> a = {{1, 2, 3, 4}, {10, 20, 30, 40, 50, 60}};
  155. tr.test_eq(ra::iota(4, 1), a(0));
  156. tr.test_eq(ra::iota(6, 10, 10), a(1));
  157. }
  158. tr.section("nested braces for nested type V [ra45]");
  159. {
  160. int u[3] = { 1, 2, 3 };
  161. ra::Big<int, 1> v = u;
  162. ra::Small<ra::Big<int, 1>, 1> b = { {u} }; // ok; broken with { u }
  163. tr.test_eq(ra::iota(3, 1), b(0));
  164. ra::Small<ra::Big<int, 1>, 1> c = { v }; // ok
  165. tr.test_eq(ra::iota(3, 1), c(0));
  166. ra::Small<ra::Big<int, 1>, 1> d = { {1, 2, 3} }; // ok
  167. tr.test_eq(ra::iota(3, 1), d(0));
  168. auto x = ra::iota(3, 1);
  169. ra::Small<ra::Big<int, 1>, 1> f = { {x} }; // ok; broken with { x }
  170. tr.test_eq(ra::iota(3, 1), f(0));
  171. // ra::Small<int, 3> w = { 1, 2, 3 };
  172. // ra::Small<ra::Big<int, 1>, 1> e = { w }; // broken with { w }, ct error with { {w} }
  173. // tr.test_eq(ra::iota(3, 1), e(0));
  174. }
  175. tr.section("nested braces for nested type VI");
  176. {
  177. ra::Small<ra::Big<double, 1>, 3> g = { { 1 }, { 1, 2 }, { 1, 2, 3 } };
  178. tr.test_eq(ra::start({1}), g[0]);
  179. tr.test_eq(ra::start({1, 2}), g[1]);
  180. tr.test_eq(ra::start({1, 2, 3}), g[2]);
  181. }
  182. // FIXME This works for Small, would be nice here as well. Right now this calls the 2-elem constructor shape, content instead of the braces constructor, since intializer_list<T> doesn't match. I'd need multiple args, as in Small.
  183. // tr.section("free constructor FIXME");
  184. // {
  185. // ra::Big<int, 2> a = {{1, 2}, ra::iota(2, 33)};
  186. // tr.test_eq(1, a(0, 0));
  187. // tr.test_eq(2, a(0, 1));
  188. // tr.test_eq(33, a(1, 0));
  189. // tr.test_eq(34, a(1, 1));
  190. // }
  191. tr.section("at() takes foreign vector");
  192. {
  193. ra::Big<double, 2> a({3, 3}, ra::_0 + 10*ra::_1);
  194. std::array<int, 2> b = {2, 2};
  195. tr.test_eq(22, a.at(b));
  196. }
  197. tr.section("default constructor of var rank");
  198. {
  199. ra::Big<int> a {};
  200. ra::Big<int, 1> b {};
  201. tr.test_eq(b.rank(), a.rank());
  202. tr.test_eq(b.size(0), a.size(0));
  203. tr.test_eq(1, a.rank());
  204. tr.test_eq(0, a.size(0));
  205. }
  206. return tr.summary();
  207. }