types.cc 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. // -*- mode: c++; coding: utf-8 -*-
  2. // ra-ra/test - Show what types conform to what type predicates.
  3. // (c) Daniel Llorens - 2016-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 <chrono>
  9. #include <numeric>
  10. #include <typeinfo>
  11. #include <iostream>
  12. #include "ra/test.hh"
  13. #include "mpdebug.hh"
  14. #ifdef __STDCPP_FLOAT128_T__
  15. #include <stdfloat>
  16. #endif
  17. using std::cout, std::endl, std::flush, ra::TestRecorder;
  18. using ra::mp::int_list, ra::mp::nil;
  19. template <class A>
  20. void
  21. test_predicates(char const * type, TestRecorder & tr,
  22. bool ra, bool slice, bool iterator, bool scalar, bool fov)
  23. {
  24. cout << std::string(90-size(std::string(type)), ' ') << type << " : "
  25. << (ra::is_ra<A> ? "ra " : "")
  26. << (ra::SliceConcept<A> ? "slice " : "")
  27. << (ra::IteratorConcept<A> ? "iterator " : "")
  28. << (ra::is_scalar<A> ? "scalar " : "")
  29. << (ra::is_fov<A> ? "fov " : "")
  30. << (ra::is_builtin_array<A> ? "builtinarray " : "")
  31. << (std::ranges::range<A> ? "range " : "")
  32. << (std::is_const_v<A> ? "const " : "")
  33. << (std::is_lvalue_reference_v<A> ? "ref " : "") << endl;
  34. tr.quiet().info(type).info("ra").test_eq(ra, ra::is_ra<A>);
  35. tr.quiet().info(type).info("slice").test_eq(slice, ra::SliceConcept<A>);
  36. tr.quiet().info(type).info("Iterator").test_eq(iterator, ra::IteratorConcept<A>);
  37. tr.quiet().info(type).info("scalar").test_eq(scalar, ra::is_scalar<A>);
  38. tr.quiet().info(type).info("fov").test_eq(fov, ra::is_fov<A>);
  39. tr.quiet().info(type).info("std::ranges::range").test_eq(std::ranges::range<A>, std::ranges::range<A>);
  40. }
  41. // Not registered with is_scalar_def.
  42. struct Unreg { int x; };
  43. // prefer decltype(declval(...)) to https://stackoverflow.com/a/13842784 the latter drops const
  44. #define TESTPRED(A, ...) test_predicates <A> (STRINGIZE(A), tr __VA_OPT__(,) __VA_ARGS__)
  45. int main()
  46. {
  47. TestRecorder tr(std::cout, TestRecorder::NOISY);
  48. {
  49. using T = std::chrono::duration<long int, std::ratio<1, 1000000000>>;
  50. ra::Big<T, 1> a;
  51. static_assert(std::is_same_v<ra::value_t<decltype(a)>, T>);
  52. ra::Small<T const, 1> ac;
  53. static_assert(std::is_same_v<ra::value_t<decltype(ac)>, T const>);
  54. static_assert(std::is_same_v<ra::ncvalue_t<decltype(ac)>, T>);
  55. ra::Small<T, 1> an;
  56. static_assert(std::is_same_v<ra::value_t<decltype(an)>, T>);
  57. static_assert(std::is_same_v<ra::ncvalue_t<decltype(an)>, T>);
  58. }
  59. {
  60. TESTPRED(decltype(std::declval<ra::ViewSmall<ra::Dim, int_list<3>, int_list<1>>>()),
  61. true, true, false, false, false);
  62. TESTPRED(int,
  63. false, false, false, true, false);
  64. TESTPRED(ra::int_c<3>,
  65. false, false, false, true, false);
  66. TESTPRED(ra::dim_c<0>,
  67. false, false, false, true, false);
  68. TESTPRED(std::complex<double>,
  69. false, false, false, true, false);
  70. #ifdef __STDCPP_FLOAT128_T__
  71. TESTPRED(std::float128_t,
  72. false, false, false, true, false);
  73. TESTPRED(std::complex<std::float128_t>,
  74. false, false, false, true, false);
  75. #endif
  76. TESTPRED(decltype(std::declval<ra::Unique<int, 2>>()),
  77. true, true, false, false, false);
  78. TESTPRED(decltype(std::declval<ra::Unique<int, 2>>()) const,
  79. true, true, false, false, false);
  80. TESTPRED(decltype(std::declval<ra::Unique<int, 2>>()) &,
  81. true, true, false, false, false);
  82. TESTPRED(decltype(std::declval<ra::ViewBig<int, 2>>()),
  83. true, true, false, false, false);
  84. TESTPRED(decltype(ra::Unique<int, 2>().iter()),
  85. true, false, true, false, false);
  86. static_assert(ra::IteratorConcept<decltype(ra::Unique<int, 2>().iter())>);
  87. TESTPRED(decltype(ra::Unique<int, 1>().iter()) &,
  88. true, false, true, false, false);
  89. TESTPRED(decltype(ra::iota(5)),
  90. true, false, true, false, false);
  91. TESTPRED(decltype(ra::iota<0>()),
  92. true, false, true, false, false);
  93. // is_iterator (by RA_IS_DEF) but not IteratorConcept, since it cannot be traversed.
  94. TESTPRED(decltype(ra::iota<0>()) const,
  95. true, false, false, false, false);
  96. TESTPRED(decltype(ra::iota<0>()) &,
  97. true, false, true, false, false);
  98. TESTPRED(decltype(std::declval<ra::Small<int, 2>>()),
  99. true, true, false, false, false);
  100. TESTPRED(decltype(ra::Small<int, 2>().iter()),
  101. true, false, true, false, false);
  102. TESTPRED(decltype(ra::Small<int, 2, 2>()()),
  103. true, true, false, false, false);
  104. TESTPRED(decltype(ra::Small<int, 2, 2>().iter()),
  105. true, false, true, false, false);
  106. TESTPRED(decltype(ra::Small<int, 2>()+3),
  107. true, false, true, false, false);
  108. TESTPRED(decltype(3+ra::Big<int>()),
  109. true, false, true, false, false);
  110. TESTPRED(std::vector<int>,
  111. false, false, false, false, true);
  112. TESTPRED(decltype(ra::start(std::vector<int> {})),
  113. true, false, true, false, false);
  114. TESTPRED(int *,
  115. false, false, false, false, false);
  116. TESTPRED(decltype(std::ranges::iota_view(-5, 10)),
  117. false, false, false, false, true);
  118. // std::string can be registered as is_scalar or not [ra13]. Use ra::ptr(std::string) or ra::scalar(std::string) to get the other behavior.
  119. if constexpr(ra::is_scalar<std::string>) {
  120. TESTPRED(std::string,
  121. false, false, false, true, false);
  122. } else {
  123. TESTPRED(std::string,
  124. false, false, false, false, true);
  125. }
  126. TESTPRED(Unreg,
  127. false, false, false, false, false);
  128. TESTPRED(int [4],
  129. false, false, false, false, false);
  130. TESTPRED(int (&) [3],
  131. false, false, false, false, false);
  132. TESTPRED(decltype("cstring"),
  133. false, false, false, false, false);
  134. }
  135. tr.section("establish meaning of selectors (TODO / convert to TestRecorder)");
  136. {
  137. static_assert(ra::SliceConcept<ra::ViewBig<int, 0>>);
  138. static_assert(ra::SliceConcept<ra::ViewBig<int, 2>>);
  139. static_assert(ra::SliceConcept<ra::ViewSmall<int, int_list<>, int_list<>>>);
  140. static_assert(ra::is_ra<ra::Small<int>>, "bad is_ra Small");
  141. static_assert(ra::is_ra<ra::ViewSmall<int, nil, nil>>, "bad is_ra ViewSmall");
  142. static_assert(ra::is_ra<ra::Unique<int, 0>>, "bad is_ra Unique");
  143. static_assert(ra::is_ra<ra::ViewBig<int, 0>>, "bad is_ra View");
  144. static_assert(ra::is_ra<ra::Small<int, 1>>, "bad is_ra Small");
  145. static_assert(ra::is_ra<ra::ViewSmall<int, int_list<1>, int_list<1>>>, "bad is_ra ViewSmall");
  146. static_assert(ra::is_ra<ra::Unique<int, 1>>, "bad is_ra Unique");
  147. static_assert(ra::is_ra<ra::ViewBig<int, 1>>, "bad is_ra View");
  148. static_assert(ra::is_ra<ra::ViewBig<int>>, "bad is_ra View");
  149. using Scalar = decltype(ra::scalar(3));
  150. using Vector = decltype(ra::start({1, 2, 3}));
  151. static_assert(ra::is_ra_scalar<Scalar>, "bad is_ra_scalar Scalar");
  152. static_assert(ra::is_ra<decltype(ra::scalar(3))>, "bad is_ra Scalar");
  153. static_assert(ra::is_ra<Vector>, "bad is_ra Vector");
  154. static_assert(!ra::is_ra<int *>, "bad is_ra int *");
  155. static_assert(ra::is_scalar<double>, "bad is_scalar real");
  156. static_assert(ra::is_scalar<std::complex<double>>, "bad is_scalar complex");
  157. static_assert(ra::is_scalar<int>, "bad is_scalar int");
  158. static_assert(!ra::is_scalar<decltype(ra::scalar(3))>, "bad is_scalar Scalar");
  159. static_assert(!ra::is_scalar<Vector>, "bad is_scalar Scalar");
  160. static_assert(!ra::is_scalar<decltype(ra::start(3))>, "bad is_scalar Scalar");
  161. int a = 3;
  162. static_assert(!ra::is_scalar<decltype(ra::start(a))>, "bad is_scalar Scalar");
  163. // a regression.
  164. static_assert(ra::is_zero_or_scalar<ra::Scalar<int>>, "bad");
  165. static_assert(!ra::is_ra_pos<ra::Scalar<int>>, "bad");
  166. static_assert(!ra::is_zero_or_scalar<decltype(ra::iota<0>())>, "bad");
  167. static_assert(ra::is_ra_pos<decltype(ra::iota<0>())>, "bad");
  168. static_assert(ra::is_ra_pos<ra::Expr<std::multiplies<>, std::tuple<decltype(ra::iota<0>()), ra::Scalar<int>>>>, "bad");
  169. static_assert(ra::is_ra_pos<ra::Pick<std::tuple<Vector, Vector, Vector>>>, "bad");
  170. }
  171. tr.section("builtin arrays");
  172. {
  173. int const a[] = {1, 2, 3};
  174. int b[] = {1, 2, 3};
  175. int c[][2] = {{1, 2}, {4, 5}};
  176. static_assert(ra::is_builtin_array<decltype(a) &>);
  177. static_assert(ra::is_builtin_array<decltype(a)>);
  178. static_assert(ra::is_builtin_array<decltype(b) &>);
  179. static_assert(ra::is_builtin_array<decltype(b)>);
  180. static_assert(ra::is_builtin_array<decltype(c) &>);
  181. static_assert(ra::is_builtin_array<decltype(c)>);
  182. tr.test_eq(1, ra::rank_s(a));
  183. tr.test_eq(1, ra::rank_s(b));
  184. tr.test_eq(2, ra::rank_s(c));
  185. tr.test_eq(3, ra::size(a));
  186. tr.test_eq(3, ra::size(b));
  187. tr.test_eq(4, ra::size(c));
  188. tr.test_eq(3, ra::size_s(a));
  189. tr.test_eq(3, ra::size_s(b));
  190. tr.test_eq(4, ra::size_s(c));
  191. }
  192. tr.section("adaptors I");
  193. {
  194. tr.test_eq(2, size_s(ra::start(std::array<int, 2> { 1, 2 })));
  195. tr.test_eq(2, ra::size_s(std::array<int, 2> { 1, 2 }));
  196. tr.test_eq(ra::ANY, ra::size_s<decltype(ra::start(std::vector<int> { 1, 2, 3}))>());
  197. tr.test_eq(ra::ANY, ra::size_s<decltype(std::vector<int> { 1, 2, 3})>());
  198. tr.test_eq(2, ra::start(std::array<int, 2> { 1, 2 }).len_s(0));
  199. tr.test_eq(ra::ANY, ra::start(std::vector<int> { 1, 2, 3 }).len_s(0));
  200. tr.test_eq(1, ra::rank_s<decltype(ra::start(std::array<int, 2> { 1, 2 }))>());
  201. tr.test_eq(1, ra::rank_s<decltype(ra::start(std::vector<int> { 1, 2, 3 }))>());
  202. tr.test_eq(1, ra::start(std::array<int, 2> { 1, 2 }).rank());
  203. tr.test_eq(1, ra::start(std::vector<int> { 1, 2, 3 }).rank());
  204. }
  205. tr.section("adaptors II");
  206. {
  207. static_assert(ra::is_iterator<decltype(ra::ptr(std::array { 1, 2 }))>);
  208. static_assert(ra::is_iterator<decltype(ra::start(std::array { 1, 2 }))>);
  209. }
  210. return tr.summary();
  211. }