compatibility.cc 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. // -*- mode: c++; coding: utf-8 -*-
  2. /// @file compatibility.cc
  3. /// @brief Using std:: and ra:: together.
  4. // (c) Daniel Llorens - 2014, 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 "ra/ra.hh"
  11. #include "ra/test.hh"
  12. #include "ra/mpdebug.hh"
  13. using std::cout, std::endl, std::flush, ra::TestRecorder;
  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<int> 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 [ra03]
  28. tr.section("frame match ra::start on 1st axis, forbid unroll");
  29. {
  30. std::vector<int> 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<int> const a = { 10, 20, 30 };
  47. std::vector<int> 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<int> a { 1, 2, 3 };
  55. ra::start(a) *= 3;
  56. tr.test_eq(ra::start(std::vector<int> { 3, 6, 9 }), ra::start(a));
  57. }
  58. tr.section("automatic conversion of foreign vectors in mixed ops");
  59. {
  60. std::vector<int> 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("operators take foreign types");
  76. {
  77. std::vector<int> x = {1, 2, 3};
  78. tr.test_eq(6, sum(ra::start(x)));
  79. tr.test_eq(6, ra::sum(x));
  80. }
  81. tr.section("spot use of scalar");
  82. {
  83. struct W { int x; };
  84. ra::Big<W, 1> w = { {1}, {2} };
  85. tr.test_eq(ra::start({8, 9}), map([](auto && a, auto && b) { return a.x + b.x; }, w, ra::scalar(W {7})));
  86. }
  87. {
  88. int o[4];
  89. using O = decltype(o);
  90. O p[2];
  91. int q[2][4];
  92. cout << mp::type_name<decltype(o)>() << endl;
  93. cout << mp::type_name<decltype(p)>() << endl;
  94. cout << mp::type_name<decltype(q)>() << endl;
  95. cout << mp::type_name<decltype(ra::start(q))>() << endl;
  96. cout << mp::type_name<std::remove_all_extents_t<decltype(q)>>() << endl;
  97. }
  98. {
  99. int o[2];
  100. int p[3][2];
  101. int q[4][3][2];
  102. int r[][2] = {{1, 2}, {3, 4}};
  103. static_assert(std::is_same<ra::builtin_array_sizes_t<decltype(o)>,
  104. mp::int_list<2>>::value);
  105. static_assert(std::is_same<ra::builtin_array_sizes_t<decltype(p)>,
  106. mp::int_list<3, 2>>::value);
  107. static_assert(std::is_same<ra::builtin_array_sizes_t<decltype(q)>,
  108. mp::int_list<4, 3, 2>>::value);
  109. static_assert(std::is_same<ra::builtin_array_sizes_t<decltype(r)>,
  110. mp::int_list<2, 2>>::value);
  111. static_assert(std::rank<decltype(r)>::value==2);
  112. }
  113. tr.section("example from the manual [ma106]");
  114. {
  115. int p[] = {1, 2, 3};
  116. int * z = p;
  117. ra::Big<int, 1> q {1, 2, 3};
  118. q += p; // ok, q is ra::, p is foreign object with size info
  119. tr.test_eq(ra::start({2, 4, 6}), q);
  120. ra::start(p) += q; // can't redefine operator+=(int[]), foreign needs ra::start()
  121. tr.test_eq(ra::start({3, 6, 9}), p);
  122. // z += q; // error: raw pointer needs ra::ptr()
  123. ra::ptr(z) += p; // ok, size is determined by foreign object p
  124. tr.test_eq(ra::start({6, 12, 18}), p);
  125. }
  126. return tr.summary();
  127. }