concepts.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. // Range v3 library
  2. //
  3. // Copyright Eric Niebler 2014-present
  4. // Copyright Google LLC 2020-present
  5. //
  6. // Use, modification and distribution is subject to the
  7. // Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. //
  11. // Project home: https://github.com/ericniebler/range-v3
  12. //#define RANGES_USE_LEGACY_CONCEPTS 1
  13. #include <sstream>
  14. #include <vector>
  15. #include <concepts/concepts.hpp>
  16. #include <range/v3/iterator/concepts.hpp>
  17. #include <range/v3/iterator/traits.hpp>
  18. #include <range/v3/range/concepts.hpp>
  19. #include <range/v3/range/traits.hpp>
  20. #include <range/v3/view/istream.hpp>
  21. #include <range/v3/iterator/common_iterator.hpp>
  22. #include "../simple_test.hpp"
  23. struct moveonly
  24. {
  25. moveonly(moveonly&&) = default;
  26. moveonly& operator=(moveonly&&) = default;
  27. };
  28. struct nonmovable
  29. {
  30. nonmovable(nonmovable const &) = delete;
  31. nonmovable& operator=(nonmovable const &) = delete;
  32. };
  33. struct nondefaultconstructible
  34. {
  35. nondefaultconstructible(int) {}
  36. };
  37. struct NotDestructible
  38. {
  39. ~NotDestructible() = delete;
  40. };
  41. struct IntComparable
  42. {
  43. operator int() const;
  44. friend bool operator==(IntComparable, IntComparable);
  45. friend bool operator!=(IntComparable, IntComparable);
  46. friend bool operator<(IntComparable, IntComparable);
  47. friend bool operator>(IntComparable, IntComparable);
  48. friend bool operator<=(IntComparable, IntComparable);
  49. friend bool operator>=(IntComparable, IntComparable);
  50. friend bool operator==(int, IntComparable);
  51. friend bool operator!=(int, IntComparable);
  52. friend bool operator==(IntComparable, int);
  53. friend bool operator!=(IntComparable, int);
  54. friend bool operator<(int, IntComparable);
  55. friend bool operator<(IntComparable, int);
  56. friend bool operator>(int, IntComparable);
  57. friend bool operator>(IntComparable, int);
  58. friend bool operator<=(int, IntComparable);
  59. friend bool operator<=(IntComparable, int);
  60. friend bool operator>=(int, IntComparable);
  61. friend bool operator>=(IntComparable, int);
  62. };
  63. struct IntSwappable
  64. {
  65. operator int() const;
  66. friend void swap(int &, IntSwappable);
  67. friend void swap(IntSwappable, int &);
  68. friend void swap(IntSwappable, IntSwappable);
  69. };
  70. static_assert(ranges::same_as<int, int>, "");
  71. static_assert(ranges::same_as<void, void>, "");
  72. static_assert(ranges::same_as<void const, void const>, "");
  73. static_assert(!ranges::same_as<int&, int>, "");
  74. static_assert(!ranges::same_as<void, void const>, "");
  75. static_assert(!ranges::same_as<void(), void(*)()>, "");
  76. static_assert(ranges::convertible_to<int, int>, "");
  77. static_assert(ranges::convertible_to<short&, short const&>, "");
  78. static_assert(ranges::convertible_to<int, short>, "");
  79. static_assert(!ranges::convertible_to<int&, short&>, "");
  80. static_assert(!ranges::convertible_to<int, void>, "");
  81. static_assert(!ranges::convertible_to<int, int&>, "");
  82. static_assert(ranges::unsigned_integral<unsigned>, "");
  83. static_assert(!ranges::unsigned_integral<int>, "");
  84. static_assert(ranges::assignable_from<int&, int>, "");
  85. static_assert(!ranges::assignable_from<int const&, int>, "");
  86. static_assert(!ranges::assignable_from<int, int>, "");
  87. static_assert(ranges::destructible<int>, "");
  88. static_assert(ranges::destructible<const int>, "");
  89. static_assert(!ranges::destructible<void>, "");
  90. static_assert(ranges::destructible<int&>, "");
  91. static_assert(!ranges::destructible<void()>, "");
  92. static_assert(ranges::destructible<void(*)()>, "");
  93. static_assert(ranges::destructible<void(&)()>, "");
  94. static_assert(!ranges::destructible<int[]>, "");
  95. static_assert(ranges::destructible<int[2]>, "");
  96. static_assert(ranges::destructible<int(*)[2]>, "");
  97. static_assert(ranges::destructible<int(&)[2]>, "");
  98. static_assert(ranges::destructible<moveonly>, "");
  99. static_assert(ranges::destructible<nonmovable>, "");
  100. static_assert(!ranges::destructible<NotDestructible>, "");
  101. static_assert(ranges::constructible_from<int>, "");
  102. static_assert(ranges::constructible_from<int const>, "");
  103. static_assert(!ranges::constructible_from<void>, "");
  104. static_assert(!ranges::constructible_from<int const &>, "");
  105. static_assert(!ranges::constructible_from<int ()>, "");
  106. static_assert(!ranges::constructible_from<int(&)()>, "");
  107. static_assert(!ranges::constructible_from<int[]>, "");
  108. static_assert(ranges::constructible_from<int[5]>, "");
  109. static_assert(!ranges::constructible_from<nondefaultconstructible>, "");
  110. static_assert(ranges::constructible_from<int const(&)[5], int(&)[5]>, "");
  111. static_assert(!ranges::constructible_from<int, int(&)[3]>, "");
  112. static_assert(ranges::constructible_from<int, int>, "");
  113. static_assert(ranges::constructible_from<int, int&>, "");
  114. static_assert(ranges::constructible_from<int, int&&>, "");
  115. static_assert(ranges::constructible_from<int, const int>, "");
  116. static_assert(ranges::constructible_from<int, const int&>, "");
  117. static_assert(ranges::constructible_from<int, const int&&>, "");
  118. static_assert(!ranges::constructible_from<int&, int>, "");
  119. static_assert(ranges::constructible_from<int&, int&>, "");
  120. static_assert(!ranges::constructible_from<int&, int&&>, "");
  121. static_assert(!ranges::constructible_from<int&, const int>, "");
  122. static_assert(!ranges::constructible_from<int&, const int&>, "");
  123. static_assert(!ranges::constructible_from<int&, const int&&>, "");
  124. static_assert(ranges::constructible_from<const int&, int>, "");
  125. static_assert(ranges::constructible_from<const int&, int&>, "");
  126. static_assert(ranges::constructible_from<const int&, int&&>, "");
  127. static_assert(ranges::constructible_from<const int&, const int>, "");
  128. static_assert(ranges::constructible_from<const int&, const int&>, "");
  129. static_assert(ranges::constructible_from<const int&, const int&&>, "");
  130. static_assert(ranges::constructible_from<int&&, int>, "");
  131. static_assert(!ranges::constructible_from<int&&, int&>, "");
  132. static_assert(ranges::constructible_from<int&&, int&&>, "");
  133. static_assert(!ranges::constructible_from<int&&, const int>, "");
  134. static_assert(!ranges::constructible_from<int&&, const int&>, "");
  135. static_assert(!ranges::constructible_from<int&&, const int&&>, "");
  136. static_assert(ranges::constructible_from<const int&&, int>, "");
  137. static_assert(!ranges::constructible_from<const int&&, int&>, "");
  138. static_assert(ranges::constructible_from<const int&&, int&&>, "");
  139. static_assert(ranges::constructible_from<const int&&, const int>, "");
  140. static_assert(!ranges::constructible_from<const int&&, const int&>, "");
  141. static_assert(ranges::constructible_from<const int&&, const int&&>, "");
  142. struct XXX
  143. {
  144. XXX() = default;
  145. XXX(XXX&&) = delete;
  146. explicit XXX(int) {}
  147. };
  148. static_assert(ranges::constructible_from<XXX, int>, "");
  149. static_assert(!ranges::move_constructible<XXX>, "");
  150. static_assert(!ranges::movable<XXX>, "");
  151. static_assert(!ranges::semiregular<XXX>, "");
  152. static_assert(!ranges::regular<XXX>, "");
  153. static_assert(ranges::default_constructible<int>, "");
  154. static_assert(ranges::default_constructible<int const>, "");
  155. static_assert(!ranges::default_constructible<int const &>, "");
  156. static_assert(!ranges::default_constructible<int ()>, "");
  157. static_assert(!ranges::default_constructible<int(&)()>, "");
  158. static_assert(!ranges::default_constructible<int[]>, "");
  159. static_assert(ranges::default_constructible<int[5]>, "");
  160. static_assert(!ranges::default_constructible<nondefaultconstructible>, "");
  161. static_assert(ranges::move_constructible<int>, "");
  162. static_assert(ranges::move_constructible<const int>, "");
  163. static_assert(ranges::move_constructible<int &>, "");
  164. static_assert(ranges::move_constructible<int &&>, "");
  165. static_assert(ranges::move_constructible<const int &>, "");
  166. static_assert(ranges::move_constructible<const int &&>, "");
  167. static_assert(ranges::destructible<moveonly>, "");
  168. static_assert(ranges::constructible_from<moveonly, moveonly>, "");
  169. static_assert(ranges::move_constructible<moveonly>, "");
  170. static_assert(!ranges::move_constructible<nonmovable>, "");
  171. static_assert(ranges::move_constructible<nonmovable &>, "");
  172. static_assert(ranges::move_constructible<nonmovable &&>, "");
  173. static_assert(ranges::move_constructible<const nonmovable &>, "");
  174. static_assert(ranges::move_constructible<const nonmovable &&>, "");
  175. static_assert(ranges::copy_constructible<int>, "");
  176. static_assert(ranges::copy_constructible<const int>, "");
  177. static_assert(ranges::copy_constructible<int &>, "");
  178. static_assert(!ranges::copy_constructible<int &&>, "");
  179. static_assert(ranges::copy_constructible<const int &>, "");
  180. static_assert(!ranges::copy_constructible<const int &&>, "");
  181. static_assert(!ranges::copy_constructible<moveonly>, "");
  182. static_assert(!ranges::copy_constructible<nonmovable>, "");
  183. static_assert(ranges::copy_constructible<nonmovable &>, "");
  184. static_assert(!ranges::copy_constructible<nonmovable &&>, "");
  185. static_assert(ranges::copy_constructible<const nonmovable &>, "");
  186. static_assert(!ranges::copy_constructible<const nonmovable &&>, "");
  187. static_assert(ranges::movable<int>, "");
  188. static_assert(!ranges::movable<int const>, "");
  189. static_assert(ranges::movable<moveonly>, "");
  190. static_assert(!ranges::movable<nonmovable>, "");
  191. static_assert(ranges::copyable<int>, "");
  192. static_assert(!ranges::copyable<int const>, "");
  193. static_assert(!ranges::copyable<moveonly>, "");
  194. static_assert(!ranges::copyable<nonmovable>, "");
  195. // static_assert(ranges::predicate<std::less<int>, int, int>, "");
  196. // static_assert(!ranges::predicate<std::less<int>, char*, int>, "");
  197. static_assert(ranges::input_iterator<int*>, "");
  198. static_assert(!ranges::input_iterator<int>, "");
  199. static_assert(ranges::forward_iterator<int*>, "");
  200. static_assert(!ranges::forward_iterator<int>, "");
  201. static_assert(ranges::bidirectional_iterator<int*>, "");
  202. static_assert(!ranges::bidirectional_iterator<int>, "");
  203. static_assert(ranges::random_access_iterator<int*>, "");
  204. static_assert(!ranges::random_access_iterator<int>, "");
  205. static_assert(ranges::contiguous_iterator<int*>, "");
  206. static_assert(!ranges::contiguous_iterator<int>, "");
  207. static_assert(ranges::view_<ranges::istream_view<int>>, "");
  208. static_assert(ranges::input_iterator<ranges::iterator_t<ranges::istream_view<int>>>, "");
  209. static_assert(!ranges::view_<int>, "");
  210. static_assert(ranges::common_range<std::vector<int> >, "");
  211. static_assert(ranges::common_range<std::vector<int> &>, "");
  212. static_assert(!ranges::view_<std::vector<int>>, "");
  213. static_assert(!ranges::view_<std::vector<int> &>, "");
  214. static_assert(ranges::random_access_iterator<ranges::iterator_t<std::vector<int> const &>>, "");
  215. static_assert(!ranges::common_range<ranges::istream_view<int>>, "");
  216. static_assert(ranges::predicate<std::less<int>, int, int>, "");
  217. static_assert(!ranges::predicate<std::less<int>, char*, int>, "");
  218. static_assert(ranges::output_iterator<int *, int>, "");
  219. static_assert(!ranges::output_iterator<int const *, int>, "");
  220. static_assert(ranges::swappable<int &>, "");
  221. static_assert(ranges::swappable<int>, "");
  222. static_assert(!ranges::swappable<int const &>, "");
  223. static_assert(ranges::swappable<IntSwappable>, "");
  224. static_assert(ranges::swappable_with<IntSwappable, int &>, "");
  225. static_assert(!ranges::swappable_with<IntSwappable, int const &>, "");
  226. static_assert(ranges::totally_ordered<int>, "");
  227. static_assert(ranges::common_with<int, IntComparable>, "");
  228. static_assert(ranges::common_reference_with<int &, IntComparable &>, "");
  229. static_assert(ranges::totally_ordered_with<int, IntComparable>, "");
  230. static_assert(ranges::totally_ordered_with<IntComparable, int>, "");
  231. static_assert(ranges::detail::weakly_equality_comparable_with_<int, int>, "");
  232. static_assert(ranges::equality_comparable<int>, "");
  233. static_assert(ranges::equality_comparable_with<int, int>, "");
  234. static_assert(ranges::equality_comparable_with<int, IntComparable>, "");
  235. static_assert(ranges::equality_comparable_with<int &, IntComparable &>, "");
  236. #if __cplusplus > 201703L && __has_include(<compare>) && \
  237. defined(__cpp_concepts) && defined(__cpp_impl_three_way_comparison)
  238. #include <compare>
  239. static_assert(ranges::three_way_comparable<int>);
  240. static_assert(ranges::three_way_comparable<int, std::partial_ordering>);
  241. static_assert(ranges::three_way_comparable<int, std::weak_ordering>);
  242. static_assert(ranges::three_way_comparable<int, std::strong_ordering>);
  243. static_assert(ranges::three_way_comparable_with<int, IntComparable>);
  244. static_assert(ranges::three_way_comparable_with<int, IntComparable, std::partial_ordering>);
  245. static_assert(ranges::three_way_comparable_with<int, IntComparable, std::weak_ordering>);
  246. static_assert(ranges::three_way_comparable_with<int, IntComparable, std::strong_ordering>);
  247. static_assert(ranges::three_way_comparable_with<IntComparable, int>);
  248. static_assert(ranges::three_way_comparable_with<IntComparable, int, std::partial_ordering>);
  249. static_assert(ranges::three_way_comparable_with<IntComparable, int, std::weak_ordering>);
  250. static_assert(ranges::three_way_comparable_with<IntComparable, int, std::strong_ordering>);
  251. #endif // supports spaceship
  252. static_assert(
  253. std::is_same<
  254. ranges::common_range_tag_of<std::vector<int>>,
  255. ranges::common_range_tag
  256. >::value, "");
  257. static_assert(
  258. std::is_same<
  259. ranges::sized_range_tag_of<std::vector<int>>,
  260. ranges::sized_range_tag
  261. >::value, "");
  262. static_assert(ranges::view_<ranges::istream_view<int>>, "");
  263. static_assert(!ranges::common_range<ranges::istream_view<int>>, "");
  264. static_assert(!ranges::sized_range<ranges::istream_view<int>>, "");
  265. struct myview : ranges::view_base {
  266. const char *begin();
  267. const char *end();
  268. };
  269. CPP_assert(ranges::view_<myview>);
  270. CPP_template(class T)
  271. (requires ranges::regular<T>)
  272. constexpr bool is_regular(T&&)
  273. {
  274. return true;
  275. }
  276. CPP_template(class T)
  277. (requires (!ranges::regular<T>))
  278. constexpr bool is_regular(T&&)
  279. {
  280. return false;
  281. }
  282. static_assert(is_regular(42), "");
  283. static_assert(!is_regular(XXX{}), "");
  284. int main()
  285. {
  286. return test_result();
  287. }