compatibility.cc 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. // -*- mode: c++; coding: utf-8 -*-
  2. // ra-ra/test - Using builtin types and std:: together with ra::.
  3. // (c) Daniel Llorens - 2014, 2017
  4. // This library is free software; you can redistribute it and/or modify it under
  5. // the terms of the GNU Lesser General Public License as published by the Free
  6. // Software Foundation; either version 3 of the License, or (at your option) any
  7. // later version.
  8. #include <ranges>
  9. #include <iostream>
  10. #include "ra/test.hh"
  11. #include "mpdebug.hh"
  12. using std::cout, std::endl, std::flush, std::string, ra::TestRecorder;
  13. using ra::int_c, ra::mp::int_list;
  14. int main()
  15. {
  16. TestRecorder tr;
  17. tr.section("Tests for std:: types");
  18. {
  19. tr.section("frame match ra::start on 1st axis");
  20. {
  21. std::vector const a = { 1, 2, 3 };
  22. ra::Big<int, 2> b ({3, 2}, ra::start(a));
  23. tr.test_eq(a[0], b(0));
  24. tr.test_eq(a[1], b(1));
  25. tr.test_eq(a[2], b(2));
  26. }
  27. // TODO actually whether unroll is avoided depends on ply, have a way to require it [ra3]
  28. tr.section("frame match ra::start on 1st axis, forbid unroll");
  29. {
  30. std::vector const a = { 1, 2, 3 };
  31. ra::Big<int, 3> b ({3, 4, 2}, ra::none);
  32. transpose({0, 2, 1}, b) = ra::start(a);
  33. tr.test_eq(a[0], b(0));
  34. tr.test_eq(a[1], b(1));
  35. tr.test_eq(a[2], b(2));
  36. }
  37. tr.section("frame match ra::start on some axis other than 1st");
  38. {
  39. {
  40. ra::Big<int, 1> const a = { 10, 20, 30 };
  41. ra::Big<int, 1> const b = { 1, 2 };
  42. ra::Big<int, 2> c = map(ra::wrank<0, 1>([](int a, int b) { return a + b; }), a, b);
  43. tr.test_eq(ra::Big<int, 2>({3, 2}, {11, 12, 21, 22, 31, 32}), c);
  44. }
  45. {
  46. std::vector const a = { 10, 20, 30 };
  47. std::vector const b = { 1, 2 };
  48. ra::Big<int, 2> c = map(ra::wrank<0, 1>([](int a, int b) { return a + b; }), a, b);
  49. tr.test_eq(ra::Big<int, 2>({3, 2}, {11, 12, 21, 22, 31, 32}), c);
  50. }
  51. }
  52. tr.section("= operators on ra::start");
  53. {
  54. std::vector a { 1, 2, 3 };
  55. ra::start(a) *= 3;
  56. tr.test_eq(ra::start(std::vector { 3, 6, 9 }), ra::start(a));
  57. }
  58. tr.section("automatic conversion of foreign vectors in mixed ops");
  59. {
  60. std::vector a { 1, 2, 3 };
  61. ra::Big<int, 1> b { 10, 20, 30 };
  62. tr.test_eq(ra::start({11, 22, 33}), a+b);
  63. }
  64. }
  65. tr.section("builtin arrays as foreign arrays");
  66. {
  67. int const a[] = {1, 2, 3};
  68. tr.info("builtin array is enough to drive").test_eq(ra::start({1, 3, 5}), (ra::_0 + a));
  69. int const b[][3] = {{1, 2, 3}, {4, 5, 6}};
  70. tr.info("builtin array handles 2 dimensions").test_eq(ra::Small<int, 2, 3>{1, 1, 1, 5, 5, 5}, (ra::_0 + b - ra::_1));
  71. int const c[2][2][2][2] = {{{{0, 1}, {2, 3}}, {{4, 5}, {6, 7}}}, {{{8, 9}, {10, 11}}, {{12, 13}, {14, 15}}}};
  72. tr.info("builtin array handles 4 dimensions").test_eq(ra::Small<int, 2, 2, 2, 2>(ra::_0*8 + ra::_1*4 + ra::_2*2 + ra::_3), c);
  73. // ra::start(c) = 99; // FIXME test that this fails at ct.
  74. }
  75. tr.section("builtin arrays shape/size/rank");
  76. {
  77. // cf small-0.cc
  78. int a[3][4] = {};
  79. tr.test_eq(2, int_c<ra::rank(a)>::value);
  80. tr.test_eq(3, int_c<ra::shape(a)[0]>::value);
  81. tr.test_eq(4, int_c<ra::shape(a)[1]>::value);
  82. tr.test_eq(12, int_c<ra::size(a)>::value);
  83. }
  84. tr.section("operators take foreign types");
  85. {
  86. std::vector x = {1, 2, 3};
  87. tr.test_eq(6, sum(ra::start(x)));
  88. tr.test_eq(6, ra::sum(x));
  89. }
  90. tr.section("spot use of scalar");
  91. {
  92. struct W { int x; };
  93. ra::Big<W, 1> w = { {1}, {2} };
  94. tr.test_eq(ra::start({8, 9}), map([](auto && a, auto && b) { return a.x + b.x; }, w, ra::scalar(W {7})));
  95. }
  96. {
  97. int o[4];
  98. using O = decltype(o);
  99. O p[2];
  100. int q[2][4];
  101. cout << ra::mp::type_name<decltype(o)>() << endl;
  102. cout << ra::mp::type_name<decltype(p)>() << endl;
  103. cout << ra::mp::type_name<decltype(q)>() << endl;
  104. cout << ra::mp::type_name<decltype(ra::start(q))>() << endl;
  105. cout << ra::mp::type_name<std::remove_all_extents_t<decltype(q)>>() << endl;
  106. }
  107. {
  108. int o[2];
  109. static_assert(1==ra::rank(o));
  110. static_assert(2==ra::start(o).len(0));
  111. int p[3][2];
  112. static_assert(2==ra::rank(p));
  113. static_assert(3==ra::shape(p)[0]);
  114. static_assert(2==ra::shape(p)[1]);
  115. int q[4][3][2];
  116. static_assert(3==ra::rank(q));
  117. static_assert(4==ra::shape(q)[0]);
  118. static_assert(3==ra::shape(q)[1]);
  119. static_assert(2==ra::shape(q)[2]);
  120. static_assert(3==ra::start(q).rank());
  121. static_assert(4==ra::start(q).len(0));
  122. static_assert(3==ra::start(q).len(1));
  123. static_assert(2==ra::start(q).len(2));
  124. int r[][2] = {{1, 2}, {3, 4}};
  125. static_assert(std::rank<decltype(r)>::value==2);
  126. static_assert(2==ra::rank(r));
  127. static_assert(2==ra::shape(r)[0]);
  128. static_assert(2==ra::shape(r)[1]);
  129. }
  130. tr.section("example from the manual [ma106]");
  131. {
  132. int p[] = {1, 2, 3};
  133. int * z = p;
  134. ra::Big<int, 1> q {1, 2, 3};
  135. q += p; // ok, q is ra::, p is foreign object with size info
  136. tr.test_eq(ra::start({2, 4, 6}), q);
  137. ra::start(p) += q; // can't redefine operator+=(int[]), foreign needs ra::start()
  138. tr.test_eq(ra::start({3, 6, 9}), p);
  139. // z += q; // error: raw pointer needs ra::ptr()
  140. ra::ptr(z) += p; // ok, size is determined by foreign object p
  141. tr.test_eq(ra::start({6, 12, 18}), p);
  142. }
  143. tr.section("char arrays");
  144. {
  145. auto quote = [](auto && o) { return ra::format(o); };
  146. {
  147. char hello[] = "hello";
  148. tr.test_eq(string("hello"), quote(hello)); // not ra:: types
  149. tr.test_eq(string("hello"), quote(ra::scalar(hello)));
  150. tr.test_eq(std::vector<char> {'h', 'e', 'l', 'l', 'o', 0}, ra::start(hello));
  151. tr.test_eq(6, size_s(ra::start(hello)));
  152. tr.test_eq(6, size_s(ra::ptr(hello)));
  153. tr.test_eq(ra::ptr(string("hello\0")), ra::ptr((char *)hello)); // char by char
  154. }
  155. cout << endl;
  156. {
  157. char const * hello = "hello";
  158. tr.test_eq(string("hello"), quote(hello));
  159. tr.test_eq(ra::scalar(string("hello")), ra::scalar(hello));
  160. // cout << ra::start(hello) << endl; // cannot be start()ed
  161. // cout << ra::ptr(hello) << endl; // same, but FIXME improve error message
  162. }
  163. }
  164. return tr.summary();
  165. }