ra-9.cc 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. // -*- mode: c++; coding: utf-8 -*-
  2. /// @file ra-9.cc
  3. /// @brief Regressions in array-in-ra::scalar
  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/mpdebug.hh"
  12. #include "ra/complex.hh"
  13. #include "ra/test.hh"
  14. #include "ra/ra.hh"
  15. using std::cout, std::endl, std::flush, std::tuple, ra::TestRecorder;
  16. using int2 = ra::Small<int, 2>;
  17. using int1 = ra::Small<int, 1>;
  18. int main()
  19. {
  20. TestRecorder tr(std::cout);
  21. tr.section("regression [ra21]");
  22. {
  23. ra::Big<int2, 1> b { {1, 10}, {2, 20}, {3, 30} };
  24. b += ra::scalar(int2 { 1, 0 });
  25. tr.test_eq(ra::Big<int2, 1> { {2, 10}, {3, 20}, {4, 30} }, b);
  26. ra::Big<int2, 1> c { {1, 0}, {2, 0}, {3, 0} };
  27. }
  28. tr.section("regression [ra22]");
  29. {
  30. ra::Big<int2, 1> b { {0, 10}, {0, 20}, {0, 30} };
  31. ra::Big<int2, 1> c { {1, 0}, {2, 0}, {3, 0} };
  32. tr.test_eq(ra::scalar("3\n2 0 3 0 4 0"), ra::scalar(format(c + ra::scalar(int2 { 1, 0 })))); // FIXME try both -O3 -O0
  33. b = c + ra::scalar(int2 { 1, 0 });
  34. tr.test_eq(ra::Big<int2, 1> { {2, 0}, {3, 0}, {4, 0} }, b);
  35. }
  36. tr.section("regression [ra24]");
  37. {
  38. {
  39. tr.test_eq(int1{91}, ra::scalar(int1{88}) + ra::scalar(int1{3}));
  40. }
  41. {
  42. auto a = int1{88};
  43. auto b = int1{3};
  44. tr.test_eq(int1{91}, a+b);
  45. }
  46. {
  47. auto a = ra::scalar(int1{88});
  48. auto b = ra::scalar(int1{3});
  49. tr.test_eq(int1{91}, a+b);
  50. }
  51. {
  52. auto a = ra::scalar(int1{88});
  53. auto b = ra::scalar(int1{3});
  54. tr.test_eq(int1{91}, ra::scalar(a)+ra::scalar(b));
  55. }
  56. }
  57. tr.section("regression [ra25]");
  58. {
  59. ra::Big<int1, 1> c { {7}, {8} };
  60. tr.test_eq(ra::scalar("2\n8 9"), ra::scalar(format(c+1)));
  61. }
  62. tr.section("regression [ra26]"); // This uses Scalar.at().
  63. {
  64. ra::Big<int1, 1> c { {7}, {8} };
  65. tr.test_eq(ra::scalar("2\n8 9"), ra::scalar(format(c+ra::scalar(int1{1}))));
  66. }
  67. tr.section("regression [ra23]");
  68. {
  69. // This is just to show that it works the same way with 'scalar' = int as with 'scalar' = int2.
  70. int x = 2;
  71. ra::Big<int, 1> c { 3, 4 };
  72. ra::scalar(x) += c + ra::scalar(99);
  73. tr.test_eq(2+3+99+4+99, x);
  74. }
  75. {
  76. int2 x {2, 0};
  77. ra::Big<int2, 1> c { {1, 3}, {2, 4} };
  78. ra::scalar(x) += c + ra::scalar(int2 { 1, 99 });
  79. tr.test_eq(int2{2, 0}+int2{1, 3}+int2{1, 99}+int2{2, 4}+int2{1, 99}, x);
  80. }
  81. tr.section("ra::start() on foreign types");
  82. {
  83. auto ref = std::array<int, 4> {12, 77, 44, 1};
  84. tr.test_eq(2, expr([](int i) { return i; },
  85. ra::start(std::vector<int> {1, 2, 3})).at(ra::Small<int, 1>{1}));
  86. tr.test_eq(ra::start(ref), expr([](int i) { return i; }, ra::start(std::array<int, 4> {12, 77, 44, 1})));
  87. // [ra1] these require ra::start and ra::Expr to forward in the constructor. Clue of why is in the ra::Unique case below.
  88. tr.test_eq(ra::start(ref), expr([](int i) { return i; }, ra::start(ra::Big<int, 1> {12, 77, 44, 1})));
  89. tr.test_eq(ra::start(ref), expr([](int i) { return i; }, ra::start(std::vector<int> {12, 77, 44, 1})));
  90. // these require ra::start and ra::Expr constructors to forward (otherwise CTE), but this makes sense, as argname is otherwise always an lref.
  91. ply_ravel(expr([](int i) { std::cout << "Bi: " << i << std::endl; return i; },
  92. ra::start(ra::Unique<int, 1> {12, 77, 44, 1})));
  93. // This depends on ra::Vector constructors moving the Unique through Expr's copying [ra35].
  94. tr.test_eq(ra::vector(ref), expr([](int i) { return i; }, ra::vector(ra::Unique<int, 1> {12, 77, 44, 1})));
  95. }
  96. // TODO Find out why the ra::Vector() constructors are needed for V=std::array but not for V=std::vector.
  97. tr.section("[ra35]");
  98. {
  99. std::array<int, 2> a1 = {1, 2};
  100. std::vector<int> a2 = {1, 2};
  101. auto va1 = ra::vector(a1);
  102. auto va2 = ra::vector(a2);
  103. tr.test(std::is_reference_v<decltype(va1.v)>);
  104. tr.test(std::is_reference_v<decltype(va2.v)>);
  105. cout << "&(va1.v[0]) " << &(va1.v[0]) << endl;
  106. cout << "&(va1.p__[0]) " << &(va1.p__[0]) << endl;
  107. cout << "&va1 " << &va1 << endl;
  108. tr.test_eq(ra::scalar(&(va1.v[0])), ra::scalar(&(va1.p__[0])));
  109. tr.test_eq(ra::scalar(&(va1.v[0])), ra::scalar(&(a1[0])));
  110. cout << "&(va2.v[0]) " << &(va2.v[0]) << endl;
  111. cout << "&(va2.p__[0]) " << &(va2.p__[0]) << endl;
  112. cout << "&va2 " << &va2 << endl;
  113. tr.test_eq(ra::scalar(&(va2.v[0])), ra::scalar(&(va2.p__[0])));
  114. tr.test_eq(ra::scalar(&(va2.v[0])), ra::scalar(&(a2[0])));
  115. cout << "---------" << endl;
  116. for_each([](auto && a, auto && b) { a = b; }, ra::vector(a1), 99);
  117. tr.test_eq(99, ra::start(a1));
  118. cout << "---------" << endl;
  119. auto fun1 = []() { return std::array<int, 2> {1, 2}; };
  120. auto fun2 = []() { return std::vector<int> {1, 2}; };
  121. auto v1 = ra::vector(fun1());
  122. auto v2 = ra::vector(fun2());
  123. tr.test(!std::is_reference_v<decltype(v1.v)>);
  124. tr.test(!std::is_reference_v<decltype(v2.v)>);
  125. cout << "&(v1.v[0]) " << &(v1.v[0]) << endl;
  126. cout << "&(v1.p__[0]) " << &(v1.p__[0]) << endl;
  127. cout << "&v1 " << &v1 << endl;
  128. tr.test_eq(ra::scalar(&(v1.v[0])), ra::scalar(&(v1.p__[0])));
  129. cout << "&(v2.v[0]) " << &(v2.v[0]) << endl;
  130. cout << "&(v2.p__[0]) " << &(v2.p__[0]) << endl;
  131. cout << "&v2 " << &v2 << endl;
  132. tr.test_eq(ra::scalar(&(v2.v[0])), ra::scalar(&(v2.p__[0])));
  133. tr.test_eq(ra::vector(fun1()), ra::iota(2, 1));
  134. tr.test_eq(ra::vector(fun2()), ra::iota(2, 1));
  135. }
  136. return tr.summary();
  137. }