stl-compat.cc 3.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. // -*- mode: c++; coding: utf-8 -*-
  2. // ra-ra/test - Using STL algos & types together with ra::.
  3. // (c) Daniel Llorens - 2014
  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. // ra:: iterators are only partially STL compatible, because of copiability,
  9. // lack of random access (which for the STL also means linear, but at least for
  10. // 1D expressions it should be available), etc. Check some cases here.
  11. #include <ranges>
  12. #include <iostream>
  13. #include <iterator>
  14. #include "ra/test.hh"
  15. using std::cout, std::endl, std::flush, ra::TestRecorder;
  16. int main()
  17. {
  18. TestRecorder tr;
  19. tr.section("random access iterators");
  20. {
  21. // TODO rank-0 begin()/end() in ra::Small
  22. // TODO others?
  23. }
  24. tr.section("copyable iterators, but not random access");
  25. {
  26. {
  27. ra::Big<int, 1> a = { 1, 2, 3 };
  28. ra::Big<int, 1> b = { 0, 0, 0 };
  29. std::transform(a.begin(), a.end(), b.begin(), [](int a) { return -a; });
  30. tr.test_eq(a, -b);
  31. }
  32. {
  33. ra::Big<int, 2> a({2, 3}, ra::_0 - 2*ra::_1);
  34. ra::Big<int, 2> b({2, 3}, 99);
  35. std::transform(a.begin(), a.end(), b.begin(), [](int a) { return -a; });
  36. tr.test_eq(a, -b);
  37. }
  38. {
  39. ra::Small<int, 2, 3> a(ra::_0 - 2*ra::_1);
  40. ra::Small<int, 2, 3> b(99);
  41. std::transform(a.begin(), a.end(), b.begin(), [](int a) { return -a; });
  42. tr.test_eq(a, -b);
  43. }
  44. }
  45. tr.section("raw pointers");
  46. {
  47. ra::Big<int, 1> a = {1, 2, 3};
  48. int b[] = { +1, -1, +1 };
  49. tr.test_eq(ra::Small<int, 3> {2, 1, 4}, a + ra::ptr(b));
  50. ra::ptr(b) = ra::Small<int, 3> {7, 4, 5};
  51. tr.test_eq(ra::Small<int, 3> {7, 4, 5}, ra::ptr(b));
  52. int cp[3] = {1, 2, 3};
  53. // ra::Big<int, 1> c({3}, &cp[0]); // forbidden, confusing for higher rank c (pointer matches as rank 1).
  54. ra::Big<int, 1> c({3}, ra::ptr(cp));
  55. tr.test_eq(ra::Small<int, 3> {1, 2, 3}, c);
  56. ra::Big<int, 1> d(3, ra::ptr(cp)); // alt shape
  57. tr.test_eq(ra::Small<int, 3> {1, 2, 3}, d);
  58. }
  59. tr.section("ptr with other iterators");
  60. {
  61. std::vector a = {1, 2, 3};
  62. ra::Small<int, 3> b = ra::ptr(a.begin());
  63. tr.test_eq(ra::Small<int, 3> {1, 2, 3}, b);
  64. }
  65. tr.section("[ra12] check that begin() and end() match for empty views");
  66. {
  67. ra::Big<int, 3> aa({0, 2, 3}, 0.);
  68. auto a = aa(ra::all, 1);
  69. tr.info("begin ", a.begin().ii.c.p, " end ", a.end().ii.c.p).test(a.begin()==a.end());
  70. }
  71. tr.section("foreign vectors from std::");
  72. {
  73. tr.info("adapted std::array has static size").test_eq(3, size_s(ra::start(std::array {1, 2, 0})));
  74. tr.info("adapted std::vector has dynamic size").test_eq(ra::DIM_ANY, size_s(ra::start(std::vector {1, 2, 0})));
  75. }
  76. tr.section("std::string");
  77. {
  78. tr.info("std::string is is_foreign_vector unless registered as is_scalar")
  79. .test_eq(ra::is_scalar<std::string> ? 0 : 1, ra::rank_s(std::string("hello")));
  80. tr.info("explicit adaption to rank 1 is possible").test_eq(5, size(ra::vector(std::string("hello"))));
  81. tr.info("note the difference with a char array").test_eq(6, ra::size("hello"));
  82. }
  83. tr.section("other std::ranges");
  84. {
  85. tr.test_eq(15, size(ra::start(std::ranges::iota_view(-5, 10))));
  86. tr.info("adapted std::ranges::iota_view has dynamic size")
  87. .test_eq(ra::DIM_ANY, size_s(ra::start(std::ranges::iota_view(-5, 10))));
  88. tr.test_eq(ra::iota(15, -5), std::ranges::iota_view(-5, 10));
  89. }
  90. return tr.summary();
  91. }