compatibility.cc 6.7 KB

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