No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

concepts.hpp 48KB

hace 5 años
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164
  1. /// \file
  2. // CPP, the Concepts PreProcessor library
  3. //
  4. // Copyright Eric Niebler 2018-present
  5. // Copyright (c) 2018-present, Facebook, Inc.
  6. //
  7. // Use, modification and distribution is subject to the
  8. // Boost Software License, Version 1.0. (See accompanying
  9. // file LICENSE_1_0.txt or copy at
  10. // http://www.boost.org/LICENSE_1_0.txt)
  11. //
  12. // This source code is licensed under the MIT license found in the
  13. // LICENSE file in the root directory of this source tree.
  14. //
  15. // Project home: https://github.com/ericniebler/range-v3
  16. //
  17. #ifndef CPP_CONCEPTS_HPP
  18. #define CPP_CONCEPTS_HPP
  19. // clang-format off
  20. #include <initializer_list>
  21. #include <utility>
  22. #include <type_traits>
  23. #include <concepts/swap.hpp>
  24. #include <concepts/type_traits.hpp>
  25. // disable buggy compatibility warning about "requires" and "concept" being
  26. // C++20 keywords.
  27. #if defined(__clang__) || defined(__GNUC__)
  28. #define CPP_PP_IGNORE_CXX2A_COMPAT_BEGIN \
  29. _Pragma("GCC diagnostic push") \
  30. _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"") \
  31. _Pragma("GCC diagnostic ignored \"-Wpragmas\"") \
  32. _Pragma("GCC diagnostic ignored \"-Wc++2a-compat\"") \
  33. _Pragma("GCC diagnostic ignored \"-Wfloat-equal\"") \
  34. /**/
  35. #define CPP_PP_IGNORE_CXX2A_COMPAT_END \
  36. _Pragma("GCC diagnostic pop")
  37. #else
  38. #define CPP_PP_IGNORE_CXX2A_COMPAT_BEGIN
  39. #define CPP_PP_IGNORE_CXX2A_COMPAT_END
  40. #endif
  41. #if defined(_MSC_VER) && !defined(__clang__)
  42. #define CPP_WORKAROUND_MSVC_779763 // FATAL_UNREACHABLE calling constexpr function via template parameter
  43. #define CPP_WORKAROUND_MSVC_780775 // Incorrect substitution in function template return type
  44. #define CPP_WORKAROUND_MSVC_784772 // Failure to invoke *explicit* bool conversion in a constant expression
  45. #endif
  46. #if !defined(CPP_CXX_CONCEPTS)
  47. #ifdef CPP_DOXYGEN_INVOKED
  48. #define CPP_CXX_CONCEPTS 201800L
  49. #elif defined(__cpp_concepts) && __cpp_concepts > 0
  50. // gcc-6 concepts are too buggy to use
  51. #if !defined(__GNUC__) || defined(__clang__) || __GNUC__ >= 7
  52. #define CPP_CXX_CONCEPTS __cpp_concepts
  53. #else
  54. #define CPP_CXX_CONCEPTS 0L
  55. #endif
  56. #else
  57. #define CPP_CXX_CONCEPTS 0L
  58. #endif
  59. #endif
  60. CPP_PP_IGNORE_CXX2A_COMPAT_BEGIN
  61. #define CPP_PP_CHECK(...) CPP_PP_CHECK_N(__VA_ARGS__, 0,)
  62. #define CPP_PP_CHECK_N(x, n, ...) n
  63. #define CPP_PP_PROBE(x) x, 1,
  64. #define CPP_PP_PROBE_N(x, n) x, n,
  65. // CPP_CXX_VA_OPT
  66. #ifndef CPP_CXX_VA_OPT
  67. #if __cplusplus > 201703L
  68. #define CPP_CXX_VA_OPT_(...) CPP_PP_CHECK(__VA_OPT__(,) 1)
  69. #define CPP_CXX_VA_OPT CPP_CXX_VA_OPT_(~)
  70. #else
  71. #define CPP_CXX_VA_OPT 0
  72. #endif
  73. #endif // CPP_CXX_VA_OPT
  74. #define CPP_PP_CAT_(X, ...) X ## __VA_ARGS__
  75. #define CPP_PP_CAT(X, ...) CPP_PP_CAT_(X, __VA_ARGS__)
  76. #define CPP_PP_CAT2_(X, ...) X ## __VA_ARGS__
  77. #define CPP_PP_CAT2(X, ...) CPP_PP_CAT2_(X, __VA_ARGS__)
  78. #define CPP_PP_EVAL(X, ...) X(__VA_ARGS__)
  79. #define CPP_PP_EVAL2(X, ...) X(__VA_ARGS__)
  80. #define CPP_PP_EXPAND(...) __VA_ARGS__
  81. #define CPP_PP_EAT(...)
  82. #define CPP_PP_IS_PAREN(x) CPP_PP_CHECK(CPP_PP_IS_PAREN_PROBE x)
  83. #define CPP_PP_IS_PAREN_PROBE(...) CPP_PP_PROBE(~)
  84. #define CPP_PP_COUNT(...) \
  85. CPP_PP_COUNT_(__VA_ARGS__, \
  86. 50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31, \
  87. 30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11, \
  88. 10,9,8,7,6,5,4,3,2,1,) \
  89. /**/
  90. #define CPP_PP_COUNT_( \
  91. _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \
  92. _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \
  93. _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \
  94. _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \
  95. _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, N, ...) \
  96. N \
  97. /**/
  98. #define CPP_PP_IIF(BIT) CPP_PP_CAT_(CPP_PP_IIF_, BIT)
  99. #define CPP_PP_IIF_0(TRUE, ...) __VA_ARGS__
  100. #define CPP_PP_IIF_1(TRUE, ...) TRUE
  101. #define CPP_PP_LPAREN (
  102. #define CPP_PP_NOT(BIT) CPP_PP_CAT_(CPP_PP_NOT_, BIT)
  103. #define CPP_PP_NOT_0 1
  104. #define CPP_PP_NOT_1 0
  105. #define CPP_PP_EMPTY()
  106. #define CPP_PP_COMMA() ,
  107. #define CPP_PP_LBRACE() {
  108. #define CPP_PP_RBRACE() }
  109. #define CPP_PP_COMMA_IIF(X) \
  110. CPP_PP_IIF(X)(CPP_PP_EMPTY, CPP_PP_COMMA)() \
  111. /**/
  112. #define CPP_assert(...) \
  113. static_assert(static_cast<bool>(__VA_ARGS__), \
  114. "Concept assertion failed : " #__VA_ARGS__) \
  115. /**/
  116. #define CPP_assert_msg static_assert
  117. #ifdef CPP_WORKAROUND_MSVC_784772
  118. #define CPP_EXPLICIT /**/
  119. #else
  120. #define CPP_EXPLICIT explicit
  121. #endif
  122. ////////////////////////////////////////////////////////////////////////////////
  123. // CPP_def
  124. // For defining concepts with a syntax similar to C++20. For example:
  125. //
  126. // CPP_def(
  127. // // The assignable_from concept from the C++20
  128. // template(typename T, typename U)
  129. // concept assignable_from,
  130. // requires (T t, U &&u) (
  131. // t = (U &&) u,
  132. // ::concepts::requires_<same_as<decltype(t = (U &&) u), T>>
  133. // ) &&
  134. // std::is_lvalue_reference_v<T>
  135. // );
  136. #define CPP_def(DECL, ...) \
  137. CPP_PP_EVAL( \
  138. CPP_PP_DECL_DEF, \
  139. CPP_PP_CAT(CPP_PP_DEF_DECL_, DECL), \
  140. __VA_ARGS__) \
  141. /**/
  142. #define CPP_PP_DECL_DEF_NAME(...) \
  143. CPP_PP_CAT(CPP_PP_DEF_, __VA_ARGS__), \
  144. /**/
  145. #define CPP_PP_DECL_DEF(TPARAM, NAME, ...) \
  146. CPP_PP_CAT(CPP_PP_DECL_DEF_, CPP_PP_IS_PAREN(NAME))( \
  147. TPARAM, \
  148. NAME, \
  149. __VA_ARGS__) \
  150. /**/
  151. // The defn is of the form:
  152. // template(typename A, typename B = void, typename... Rest)
  153. // (concept Name)(A, B, Rest...),
  154. // // requirements...
  155. #define CPP_PP_DECL_DEF_1(TPARAM, NAME, ...) \
  156. CPP_PP_EVAL2( \
  157. CPP_PP_DECL_DEF_IMPL, \
  158. TPARAM, \
  159. CPP_PP_DECL_DEF_NAME NAME, \
  160. __VA_ARGS__) \
  161. /**/
  162. // The defn is of the form:
  163. // template(typename A, typename B)
  164. // concept Name,
  165. // // requirements...
  166. // Compute the template arguments (A, B) from the template introducer.
  167. #define CPP_PP_DECL_DEF_0(TPARAM, NAME, ...) \
  168. CPP_PP_DECL_DEF_IMPL( \
  169. TPARAM, \
  170. CPP_PP_CAT(CPP_PP_DEF_, NAME), \
  171. (CPP_PP_CAT(CPP_PP_AUX_, TPARAM)), \
  172. __VA_ARGS__) \
  173. /**/
  174. // Expand the template definition into a struct and template alias like:
  175. // struct NameConcept {
  176. // template<typename A, typename B>
  177. // static auto Requires_(/* args (optional)*/) ->
  178. // decltype(/*requirements...*/);
  179. // template<typename A, typename B>
  180. // static constexpr auto is_satisfied_by(int) ->
  181. // decltype(bool(&Requires_<A,B>)) { return true; }
  182. // template<typename A, typename B>
  183. // static constexpr bool is_satisfied_by(long) { return false; }
  184. // };
  185. // template<typename A, typename B>
  186. // inline constexpr bool Name = NameConcept::is_satisfied_by<A, B>(0);
  187. #if CPP_CXX_CONCEPTS
  188. // No requires expression
  189. #define CPP_PP_DEF_IMPL_0(...) \
  190. __VA_ARGS__ \
  191. /**/
  192. // Requires expression
  193. #define CPP_PP_DEF_IMPL_1(...) \
  194. CPP_PP_CAT(CPP_PP_DEF_IMPL_1_, __VA_ARGS__) \
  195. /**/
  196. #define CPP_PP_DEF_IMPL_1_requires \
  197. requires CPP_PP_DEF_IMPL_1_REQUIRES \
  198. /**/
  199. #define CPP_PP_DEF_IMPL_1_REQUIRES(...) \
  200. (__VA_ARGS__) CPP_PP_DEF_IMPL_1_REQUIRES_BODY \
  201. /**/
  202. #define CPP_PP_DEF_IMPL_1_REQUIRES_BODY(...) \
  203. { __VA_ARGS__; } \
  204. /**/
  205. #ifdef CPP_DOXYGEN_INVOKED
  206. #define CPP_PP_DECL_DEF_IMPL(TPARAM, NAME, ARGS, ...) \
  207. CPP_PP_CAT(CPP_PP_DEF_, TPARAM) \
  208. META_CONCEPT NAME = CPP_PP_DEF_IMPL(__VA_ARGS__,)(__VA_ARGS__) \
  209. /**/
  210. #else
  211. #define CPP_PP_DECL_DEF_IMPL(TPARAM, NAME, ARGS, ...) \
  212. inline namespace _eager_ { \
  213. CPP_PP_CAT(CPP_PP_DEF_, TPARAM) \
  214. META_CONCEPT NAME = CPP_PP_DEF_IMPL(__VA_ARGS__,)(__VA_ARGS__); \
  215. } \
  216. struct CPP_PP_CAT(NAME, _concept) { \
  217. CPP_PP_CAT(CPP_PP_DEF_, TPARAM) \
  218. struct Eval { \
  219. using Concept = CPP_PP_CAT(NAME, _concept); \
  220. CPP_EXPLICIT constexpr operator bool() const noexcept { \
  221. return (bool) _eager_::NAME<CPP_PP_EXPAND ARGS>; \
  222. } \
  223. constexpr auto operator!() const noexcept { \
  224. return ::concepts::detail::not_<Eval>{}; \
  225. } \
  226. template<typename That> \
  227. constexpr auto operator&&(That) const noexcept { \
  228. return ::concepts::detail::and_<Eval, That>{}; \
  229. } \
  230. }; \
  231. }; \
  232. namespace lazy { \
  233. CPP_PP_CAT(CPP_PP_DEF_, TPARAM) \
  234. CPP_INLINE_VAR constexpr auto NAME = \
  235. CPP_PP_CAT(NAME, _concept)::Eval<CPP_PP_EXPAND ARGS>{}; \
  236. } \
  237. namespace defer { \
  238. using namespace _eager_; \
  239. } \
  240. using _concepts_int_ = int \
  241. /**/
  242. #endif
  243. #else
  244. // No requires expression:
  245. #define CPP_PP_DEF_IMPL_0(...) \
  246. () -> ::concepts::detail::enable_if_t<int, static_cast<bool>(__VA_ARGS__)> \
  247. /**/
  248. // Requires expression:
  249. #define CPP_PP_DEF_IMPL_1(...) \
  250. CPP_PP_CAT(CPP_PP_DEF_IMPL_1_, __VA_ARGS__) )> \
  251. /**/
  252. #define CPP_PP_DEF_IMPL_1_requires(...) \
  253. (__VA_ARGS__) -> ::concepts::detail::enable_if_t<int, \
  254. static_cast<bool>(::concepts::detail::requires_ CPP_PP_DEF_REQUIRES_BODY \
  255. /**/
  256. #define CPP_PP_DEF_REQUIRES_BODY(...) \
  257. <decltype(__VA_ARGS__, void())>() \
  258. /**/
  259. #ifdef CPP_WORKAROUND_MSVC_780775
  260. #define CPP_PP_DECL_DEF_IMPL_HACK(ARGS) \
  261. template<typename C_ = Concept, \
  262. decltype(&C_::template Requires_<CPP_PP_EXPAND ARGS>) = nullptr> \
  263. static constexpr bool impl(int) noexcept { return true; } \
  264. /**/
  265. #else
  266. #define CPP_PP_DECL_DEF_IMPL_HACK(ARGS) \
  267. template<typename C_ = Concept> \
  268. static constexpr decltype( \
  269. &C_::template Requires_<CPP_PP_EXPAND ARGS>, true) \
  270. impl(int) noexcept { return true; } \
  271. /**/
  272. #endif
  273. #define CPP_PP_DECL_DEF_IMPL(TPARAM, NAME, ARGS, ...) \
  274. struct CPP_PP_CAT(NAME, _concept) { \
  275. using Concept = CPP_PP_CAT(NAME, _concept); \
  276. CPP_PP_IGNORE_CXX2A_COMPAT_BEGIN \
  277. CPP_PP_CAT(CPP_PP_DEF_, TPARAM) \
  278. static auto Requires_ CPP_PP_DEF_IMPL(__VA_ARGS__,)(__VA_ARGS__); \
  279. CPP_PP_IGNORE_CXX2A_COMPAT_END \
  280. CPP_PP_CAT(CPP_PP_DEF_, TPARAM) \
  281. struct Eval { \
  282. CPP_PP_DECL_DEF_IMPL_HACK(ARGS) \
  283. static constexpr bool impl(long) noexcept { return false; } \
  284. CPP_EXPLICIT constexpr operator bool() const noexcept { \
  285. return Eval::impl(0); \
  286. } \
  287. constexpr auto operator!() const noexcept { \
  288. return ::concepts::detail::not_<Eval>{}; \
  289. } \
  290. template<typename That> \
  291. constexpr auto operator&&(That) const noexcept { \
  292. return ::concepts::detail::and_<Eval, That>{}; \
  293. } \
  294. }; \
  295. }; \
  296. CPP_PP_CAT(CPP_PP_DEF_, TPARAM) \
  297. CPP_INLINE_VAR constexpr bool NAME = \
  298. (bool)CPP_PP_CAT(NAME, _concept)::Eval<CPP_PP_EXPAND ARGS>{}; \
  299. namespace lazy { \
  300. CPP_PP_CAT(CPP_PP_DEF_, TPARAM) \
  301. CPP_INLINE_VAR constexpr auto NAME = \
  302. CPP_PP_CAT(NAME, _concept)::Eval<CPP_PP_EXPAND ARGS>{}; \
  303. } \
  304. namespace defer { \
  305. using namespace lazy; \
  306. } \
  307. using _concepts_int_ = int \
  308. /**/
  309. #endif
  310. #define CPP_PP_REQUIRES_PROBE_requires \
  311. CPP_PP_PROBE(~) \
  312. /**/
  313. #define CPP_PP_DEF_IMPL(REQUIRES, ...) \
  314. CPP_PP_CAT( \
  315. CPP_PP_DEF_IMPL_IS_PAREN_, \
  316. CPP_PP_IS_PAREN(REQUIRES))(REQUIRES) \
  317. /**/
  318. #define CPP_PP_DEF_IMPL_IS_PAREN_0(REQUIRES) \
  319. CPP_PP_CAT( \
  320. CPP_PP_DEF_IMPL_, \
  321. CPP_PP_CHECK(CPP_PP_CAT(CPP_PP_REQUIRES_PROBE_, REQUIRES))) \
  322. /**/
  323. #define CPP_PP_DEF_IMPL_IS_PAREN_1(REQUIRES) \
  324. CPP_PP_DEF_IMPL_0 \
  325. /**/
  326. #define CPP_PP_DEF_DECL_template(...) \
  327. template(__VA_ARGS__), \
  328. /**/
  329. #define CPP_PP_DEF_template(...) \
  330. template<__VA_ARGS__> \
  331. /**/
  332. #define CPP_PP_DEF_concept
  333. #define CPP_PP_DEF_class
  334. #define CPP_PP_DEF_typename
  335. #define CPP_PP_DEF_int
  336. #define CPP_PP_DEF_bool
  337. #define CPP_PP_DEF_size_t
  338. #define CPP_PP_DEF_unsigned
  339. #define CPP_PP_AUX_template(...) \
  340. CPP_PP_CAT2( \
  341. CPP_PP_TPARAM_, \
  342. CPP_PP_COUNT(__VA_ARGS__))(__VA_ARGS__) \
  343. /**/
  344. #define CPP_PP_TPARAM_1(_1) \
  345. CPP_PP_CAT2(CPP_PP_DEF_, _1)
  346. #define CPP_PP_TPARAM_2(_1, ...) \
  347. CPP_PP_CAT2(CPP_PP_DEF_, _1), CPP_PP_TPARAM_1(__VA_ARGS__)
  348. #define CPP_PP_TPARAM_3(_1, ...) \
  349. CPP_PP_CAT2(CPP_PP_DEF_, _1), CPP_PP_TPARAM_2(__VA_ARGS__)
  350. #define CPP_PP_TPARAM_4(_1, ...) \
  351. CPP_PP_CAT2(CPP_PP_DEF_, _1), CPP_PP_TPARAM_3(__VA_ARGS__)
  352. #define CPP_PP_TPARAM_5(_1, ...) \
  353. CPP_PP_CAT2(CPP_PP_DEF_, _1), CPP_PP_TPARAM_4(__VA_ARGS__)
  354. #define CPP_PP_PROBE_EMPTY_PROBE_CPP_PP_PROBE_EMPTY \
  355. CPP_PP_PROBE(~) \
  356. #define CPP_PP_PROBE_EMPTY()
  357. #define CPP_PP_IS_NOT_EMPTY(...) \
  358. CPP_PP_CHECK(CPP_PP_CAT(CPP_PP_PROBE_EMPTY_PROBE_, \
  359. CPP_PP_PROBE_EMPTY __VA_ARGS__ ())) \
  360. /**/
  361. ////////////////////////////////////////////////////////////////////////////////
  362. // CPP_template
  363. // Usage:
  364. // CPP_template(typename A, typename B)
  365. // (requires Concept1<A> && Concept2<B>)
  366. // void foo(A a, B b)
  367. // {}
  368. #if CPP_CXX_CONCEPTS
  369. #define CPP_template(...) \
  370. template<__VA_ARGS__> CPP_PP_EXPAND \
  371. /**/
  372. #define CPP_template_def CPP_template \
  373. /**/
  374. #define CPP_member
  375. #define CPP_ctor(TYPE) TYPE CPP_CTOR_IMPL_1_
  376. #define CPP_CTOR_IMPL_1_(...) \
  377. (__VA_ARGS__) CPP_PP_EXPAND \
  378. /**/
  379. #else
  380. #define CPP_template \
  381. CPP_template_sfinae \
  382. /**/
  383. #define CPP_template_def CPP_template_def_sfinae \
  384. /**/
  385. #define CPP_member CPP_member_sfinae
  386. #define CPP_ctor CPP_ctor_sfinae
  387. #endif
  388. #define CPP_template_sfinae(...) \
  389. template<__VA_ARGS__ CPP_TEMPLATE_SFINAE_AUX_ \
  390. /**/
  391. #define CPP_TEMPLATE_SFINAE_AUX_(...) , \
  392. bool CPP_false_ = false, \
  393. ::concepts::detail::enable_if_t<int, \
  394. static_cast<bool>(\
  395. CPP_PP_CAT(CPP_TEMPLATE_SFINAE_AUX_3_, __VA_ARGS__)) || \
  396. CPP_false_> = 0> \
  397. /**/
  398. #define CPP_template_def_sfinae(...) \
  399. template<__VA_ARGS__ CPP_TEMPLATE_DEF_SFINAE_AUX_ \
  400. /**/
  401. #define CPP_TEMPLATE_DEF_SFINAE_AUX_(...) , \
  402. bool CPP_false_, \
  403. ::concepts::detail::enable_if_t<int, \
  404. static_cast<bool>( \
  405. CPP_PP_CAT(CPP_TEMPLATE_SFINAE_AUX_3_, __VA_ARGS__)) || \
  406. CPP_false_>> \
  407. /**/
  408. #define CPP_TEMPLATE_SFINAE_AUX_3_requires
  409. #define CPP_member_sfinae \
  410. CPP_broken_friend_member \
  411. /**/
  412. #define CPP_ctor_sfinae(TYPE) TYPE CPP_CTOR_SFINAE_IMPL_1_
  413. #define CPP_CTOR_SFINAE_IMPL_1_(...) \
  414. (__VA_ARGS__ \
  415. CPP_PP_COMMA_IIF( \
  416. CPP_PP_NOT(CPP_PP_IS_NOT_EMPTY(__VA_ARGS__))) \
  417. CPP_CTOR_SFINAE_REQUIRES \
  418. /**/
  419. #define CPP_CTOR_SFINAE_PROBE_NOEXCEPT_noexcept \
  420. CPP_PP_PROBE(~) \
  421. /**/
  422. #define CPP_CTOR_SFINAE_MAKE_PROBE(FIRST,...) \
  423. CPP_PP_CAT(CPP_CTOR_SFINAE_PROBE_NOEXCEPT_, FIRST) \
  424. /**/
  425. #define CPP_CTOR_SFINAE_REQUIRES(...) \
  426. CPP_PP_CAT(CPP_CTOR_SFINAE_REQUIRES_, \
  427. CPP_PP_CHECK(CPP_CTOR_SFINAE_MAKE_PROBE(__VA_ARGS__,)))(__VA_ARGS__) \
  428. /**/
  429. // No noexcept-clause:
  430. #define CPP_CTOR_SFINAE_REQUIRES_0(...) \
  431. ::concepts::detail::enable_if_t< \
  432. ::concepts::detail::Nil, \
  433. CPP_false(::concepts::detail::xNil{}) || \
  434. static_cast<bool>( \
  435. CPP_PP_CAT(CPP_TEMPLATE_SFINAE_AUX_3_, __VA_ARGS__))> = {}) \
  436. /**/
  437. // Yes noexcept-clause:
  438. #define CPP_CTOR_SFINAE_REQUIRES_1(...) \
  439. ::concepts::detail::enable_if_t< \
  440. ::concepts::detail::Nil, \
  441. CPP_false(::concepts::detail::xNil{}) || \
  442. static_cast<bool>(CPP_PP_CAT(CPP_TEMPLATE_SFINAE_AUX_3_, CPP_PP_CAT( \
  443. CPP_CTOR_SFINAE_EAT_NOEXCEPT_, __VA_ARGS__)))> = {}) \
  444. CPP_PP_EXPAND( \
  445. CPP_PP_CAT(CPP_CTOR_SFINAE_SHOW_NOEXCEPT_, __VA_ARGS__))) \
  446. /**/
  447. #define CPP_CTOR_SFINAE_EAT_NOEXCEPT_noexcept(...)
  448. #define CPP_CTOR_SFINAE_SHOW_NOEXCEPT_noexcept(...) \
  449. noexcept(__VA_ARGS__) CPP_PP_EAT CPP_PP_LPAREN \
  450. /**/
  451. #ifdef CPP_DOXYGEN_INVOKED
  452. #define CPP_broken_friend_ret(...) \
  453. __VA_ARGS__ CPP_PP_EXPAND \
  454. /**/
  455. #else
  456. #define CPP_broken_friend_ret(...) \
  457. ::concepts::detail::enable_if_t<__VA_ARGS__, \
  458. CPP_BROKEN_FRIEND_RETURN_TYPE_AUX_ \
  459. /**/
  460. #define CPP_BROKEN_FRIEND_RETURN_TYPE_AUX_(...) \
  461. CPP_BROKEN_FRIEND_RETURN_TYPE_AUX_3_(CPP_PP_CAT( \
  462. CPP_TEMPLATE_AUX_2_, __VA_ARGS__)) \
  463. /**/
  464. #define CPP_TEMPLATE_AUX_2_requires
  465. #define CPP_BROKEN_FRIEND_RETURN_TYPE_AUX_3_(...) \
  466. static_cast<bool>(__VA_ARGS__) || CPP_false(::concepts::detail::xNil{})> \
  467. /**/
  468. #ifdef CPP_WORKAROUND_MSVC_779763
  469. #define CPP_broken_friend_member \
  470. template<::concepts::detail::CPP_false_t const &CPP_false = \
  471. ::concepts::detail::CPP_false_> \
  472. /**/
  473. #else // ^^^ workaround / no workaround vvv
  474. #define CPP_broken_friend_member \
  475. template<bool (&CPP_false)(::concepts::detail::xNil) = \
  476. ::concepts::detail::CPP_false> \
  477. /**/
  478. #endif // CPP_WORKAROUND_MSVC_779763
  479. #endif
  480. #if CPP_CXX_CONCEPTS
  481. #define CPP_ret(...) \
  482. __VA_ARGS__ CPP_PP_EXPAND \
  483. /**/
  484. #else
  485. #define CPP_ret \
  486. CPP_broken_friend_ret \
  487. /**/
  488. #endif
  489. ////////////////////////////////////////////////////////////////////////////////
  490. // CPP_fun
  491. #if CPP_CXX_CONCEPTS
  492. #define CPP_FUN_IMPL_1_(...) \
  493. (__VA_ARGS__) \
  494. CPP_PP_EXPAND \
  495. /**/
  496. #define CPP_fun(X) X CPP_FUN_IMPL_1_
  497. #else
  498. #define CPP_FUN_IMPL_1_(...) \
  499. (__VA_ARGS__ \
  500. CPP_PP_COMMA_IIF( \
  501. CPP_PP_NOT(CPP_PP_IS_NOT_EMPTY(__VA_ARGS__))) \
  502. CPP_FUN_IMPL_REQUIRES \
  503. /**/
  504. #define CPP_FUN_IMPL_REQUIRES(...) \
  505. CPP_FUN_IMPL_SELECT_CONST_(__VA_ARGS__,)(__VA_ARGS__) \
  506. /**/
  507. #define CPP_FUN_IMPL_SELECT_CONST_(MAYBE_CONST, ...) \
  508. CPP_PP_CAT(CPP_FUN_IMPL_SELECT_CONST_, \
  509. CPP_PP_CHECK(CPP_PP_CAT( \
  510. CPP_PP_PROBE_CONST_PROBE_, MAYBE_CONST))) \
  511. /**/
  512. #define CPP_PP_PROBE_CONST_PROBE_const CPP_PP_PROBE(~)
  513. #define CPP_FUN_IMPL_SELECT_CONST_1(...) \
  514. CPP_PP_EVAL( \
  515. CPP_FUN_IMPL_SELECT_CONST_NOEXCEPT_, \
  516. CPP_PP_CAT(CPP_FUN_IMPL_EAT_CONST_, __VA_ARGS__),)( \
  517. CPP_PP_CAT(CPP_FUN_IMPL_EAT_CONST_, __VA_ARGS__)) \
  518. /**/
  519. #define CPP_FUN_IMPL_SELECT_CONST_NOEXCEPT_(MAYBE_NOEXCEPT, ...) \
  520. CPP_PP_CAT(CPP_FUN_IMPL_SELECT_CONST_NOEXCEPT_, \
  521. CPP_PP_CHECK(CPP_PP_CAT( \
  522. CPP_PP_PROBE_NOEXCEPT_PROBE_, MAYBE_NOEXCEPT))) \
  523. /**/
  524. #define CPP_PP_PROBE_NOEXCEPT_PROBE_noexcept CPP_PP_PROBE(~)
  525. #define CPP_FUN_IMPL_SELECT_CONST_NOEXCEPT_0(...) \
  526. ::concepts::detail::enable_if_t< \
  527. ::concepts::detail::Nil, \
  528. static_cast<bool>( \
  529. CPP_PP_CAT(CPP_FUN_IMPL_EAT_REQUIRES_, __VA_ARGS__)) || \
  530. CPP_false(::concepts::detail::xNil{})> = {}) const \
  531. /**/
  532. #define CPP_FUN_IMPL_SELECT_CONST_NOEXCEPT_1(...) \
  533. ::concepts::detail::enable_if_t< \
  534. ::concepts::detail::Nil, \
  535. static_cast<bool>(CPP_PP_CAT(CPP_FUN_IMPL_EAT_REQUIRES_, CPP_PP_CAT( \
  536. CPP_FUN_IMPL_EAT_NOEXCEPT_, __VA_ARGS__))) || \
  537. CPP_false(::concepts::detail::xNil{})> = {}) const CPP_PP_EXPAND( \
  538. CPP_PP_CAT(CPP_FUN_IMPL_SHOW_NOEXCEPT_, __VA_ARGS__))) \
  539. /**/
  540. #define CPP_FUN_IMPL_EAT_NOEXCEPT_noexcept(...)
  541. #define CPP_FUN_IMPL_SHOW_NOEXCEPT_noexcept(...) \
  542. noexcept(__VA_ARGS__) CPP_PP_EAT CPP_PP_LPAREN \
  543. /**/
  544. #define CPP_FUN_IMPL_EAT_NOEXCEPT_noexcept(...)
  545. #define CPP_FUN_IMPL_EXPAND_NOEXCEPT_noexcept(...) \
  546. noexcept(__VA_ARGS__) \
  547. /**/
  548. #define CPP_FUN_IMPL_SELECT_CONST_0(...) \
  549. CPP_FUN_IMPL_SELECT_NONCONST_NOEXCEPT_(__VA_ARGS__,)(__VA_ARGS__) \
  550. /**/
  551. #define CPP_FUN_IMPL_SELECT_NONCONST_NOEXCEPT_(MAYBE_NOEXCEPT, ...) \
  552. CPP_PP_CAT(CPP_FUN_IMPL_SELECT_NONCONST_NOEXCEPT_, \
  553. CPP_PP_CHECK(CPP_PP_CAT( \
  554. CPP_PP_PROBE_NOEXCEPT_PROBE_, MAYBE_NOEXCEPT))) \
  555. /**/
  556. #define CPP_FUN_IMPL_SELECT_NONCONST_NOEXCEPT_0(...) \
  557. ::concepts::detail::enable_if_t< \
  558. ::concepts::detail::Nil, \
  559. static_cast<bool>( \
  560. CPP_PP_CAT(CPP_FUN_IMPL_EAT_REQUIRES_, __VA_ARGS__)) || \
  561. CPP_false(::concepts::detail::xNil{})> = {}) \
  562. /**/
  563. #define CPP_FUN_IMPL_SELECT_NONCONST_NOEXCEPT_1(...) \
  564. ::concepts::detail::enable_if_t< \
  565. ::concepts::detail::Nil, \
  566. static_cast<bool>(CPP_PP_CAT(CPP_FUN_IMPL_EAT_REQUIRES_, CPP_PP_CAT( \
  567. CPP_FUN_IMPL_EAT_NOEXCEPT_, __VA_ARGS__))) || \
  568. CPP_false(::concepts::detail::xNil{})> = {}) \
  569. CPP_PP_EXPAND(CPP_PP_CAT(CPP_FUN_IMPL_SHOW_NOEXCEPT_, __VA_ARGS__))) \
  570. /**/
  571. #define CPP_FUN_IMPL_EAT_CONST_const
  572. #define CPP_FUN_IMPL_EAT_REQUIRES_requires
  573. ////////////////////////////////////////////////////////////////////////////////
  574. // CPP_fun
  575. // Usage:
  576. // template <typename A, typename B>
  577. // void CPP_fun(foo)(A a, B b)([const]opt [noexcept(true)]opt
  578. // requires Concept1<A> && Concept2<B>)
  579. // {}
  580. //
  581. // Note: This macro cannot be used when the last function argument is a
  582. // parameter pack.
  583. #define CPP_fun(X) X CPP_FUN_IMPL_1_
  584. #endif
  585. ////////////////////////////////////////////////////////////////////////////////
  586. // CPP_auto_fun
  587. // Usage:
  588. // template <typename A, typename B>
  589. // auto CPP_auto_fun(foo)(A a, B b)([const]opt [noexcept(true)]opt)opt
  590. // (
  591. // return a + b
  592. // )
  593. #define CPP_auto_fun(X) X CPP_AUTO_FUN_IMPL_
  594. #define CPP_AUTO_FUN_IMPL_(...) (__VA_ARGS__) CPP_AUTO_FUN_RETURNS_
  595. #define CPP_AUTO_FUN_RETURNS_(...) \
  596. CPP_AUTO_FUN_SELECT_RETURNS_(__VA_ARGS__,)(__VA_ARGS__) \
  597. /**/
  598. #define CPP_AUTO_FUN_SELECT_RETURNS_(MAYBE_CONST, ...) \
  599. CPP_PP_CAT(CPP_AUTO_FUN_RETURNS_CONST_, \
  600. CPP_PP_CHECK(CPP_PP_CAT( \
  601. CPP_PP_PROBE_CONST_MUTABLE_PROBE_, MAYBE_CONST))) \
  602. /**/
  603. #define CPP_PP_PROBE_CONST_MUTABLE_PROBE_const CPP_PP_PROBE_N(~, 1)
  604. #define CPP_PP_PROBE_CONST_MUTABLE_PROBE_mutable CPP_PP_PROBE_N(~, 2)
  605. #define CPP_PP_EAT_MUTABLE_mutable
  606. #define CPP_AUTO_FUN_RETURNS_CONST_2(...) \
  607. CPP_PP_CAT(CPP_PP_EAT_MUTABLE_, __VA_ARGS__) CPP_AUTO_FUN_RETURNS_CONST_0
  608. #define CPP_AUTO_FUN_RETURNS_CONST_1(...) \
  609. __VA_ARGS__ CPP_AUTO_FUN_RETURNS_CONST_0 \
  610. /**/
  611. #define CPP_AUTO_FUN_RETURNS_CONST_0(...) \
  612. CPP_PP_EVAL(CPP_AUTO_FUN_DECLTYPE_NOEXCEPT_, \
  613. CPP_PP_CAT(CPP_AUTO_FUN_RETURNS_, __VA_ARGS__)) \
  614. /**/
  615. #define CPP_AUTO_FUN_RETURNS_return
  616. #ifdef __cpp_guaranteed_copy_elision
  617. #define CPP_AUTO_FUN_DECLTYPE_NOEXCEPT_(...) \
  618. noexcept(noexcept(__VA_ARGS__)) -> decltype(__VA_ARGS__) \
  619. { return (__VA_ARGS__); } \
  620. /**/
  621. #else
  622. #define CPP_AUTO_FUN_DECLTYPE_NOEXCEPT_(...) \
  623. noexcept(noexcept(decltype(__VA_ARGS__)(__VA_ARGS__))) -> \
  624. decltype(__VA_ARGS__) \
  625. { return (__VA_ARGS__); } \
  626. /**/
  627. #endif
  628. namespace concepts
  629. {
  630. template<bool B>
  631. using bool_ = std::integral_constant<bool, B>;
  632. #if defined(__cpp_fold_expressions) && __cpp_fold_expressions >= 201603
  633. template<bool...Bs>
  634. CPP_INLINE_VAR constexpr bool and_v = (Bs &&...);
  635. template<bool...Bs>
  636. CPP_INLINE_VAR constexpr bool or_v = (Bs ||...);
  637. #else
  638. namespace detail
  639. {
  640. template<bool...>
  641. struct bools;
  642. } // namespace detail
  643. template<bool...Bs>
  644. CPP_INLINE_VAR constexpr bool and_v =
  645. META_IS_SAME(detail::bools<Bs..., true>, detail::bools<true, Bs...>);
  646. template<bool...Bs>
  647. CPP_INLINE_VAR constexpr bool or_v =
  648. !META_IS_SAME(detail::bools<Bs..., false>, detail::bools<false, Bs...>);
  649. #endif
  650. namespace detail
  651. {
  652. template<typename>
  653. constexpr bool requires_()
  654. {
  655. return true;
  656. }
  657. template<typename T, typename U>
  658. struct and_;
  659. template<typename T>
  660. struct not_
  661. {
  662. CPP_EXPLICIT constexpr operator bool() const noexcept
  663. {
  664. return !(bool) T{};
  665. }
  666. constexpr auto operator!() const noexcept
  667. {
  668. return T{};
  669. }
  670. template<typename That>
  671. constexpr auto operator&&(That) const noexcept
  672. {
  673. return and_<not_, That>{};
  674. }
  675. };
  676. template<typename T, typename U>
  677. struct and_
  678. {
  679. static constexpr bool impl(std::false_type) noexcept
  680. {
  681. return false;
  682. }
  683. static constexpr bool impl(std::true_type) noexcept
  684. {
  685. return (bool) U{};
  686. }
  687. CPP_EXPLICIT constexpr operator bool() const noexcept
  688. {
  689. return and_::impl(bool_<(bool) T{}>{});
  690. }
  691. constexpr auto operator!() const noexcept
  692. {
  693. return not_<and_>{};
  694. }
  695. template<typename That>
  696. constexpr auto operator&&(That) const noexcept
  697. {
  698. return detail::and_<and_, That>{};
  699. }
  700. };
  701. template<typename...>
  702. struct identity
  703. {
  704. template<typename T>
  705. using invoke = T;
  706. };
  707. template<typename T, bool Enable>
  708. using enable_if_t = meta::invoke<identity<std::enable_if_t<Enable>>, T>;
  709. struct Nil
  710. {};
  711. #ifdef CPP_WORKAROUND_MSVC_779763
  712. enum class xNil {};
  713. struct CPP_false_t
  714. {
  715. constexpr bool operator()(Nil) const noexcept
  716. {
  717. return false;
  718. }
  719. constexpr bool operator()(xNil) const noexcept
  720. {
  721. return false;
  722. }
  723. };
  724. CPP_INLINE_VAR constexpr CPP_false_t CPP_false_{};
  725. constexpr bool CPP_false(xNil)
  726. {
  727. return false;
  728. }
  729. #else
  730. using xNil = Nil;
  731. #endif
  732. constexpr bool CPP_false(Nil)
  733. {
  734. return false;
  735. }
  736. template<typename T>
  737. using remove_cvref_t =
  738. typename std::remove_cv<typename std::remove_reference<T>::type>::type;
  739. CPP_def
  740. (
  741. template(typename T, typename U)
  742. concept weakly_equality_comparable_with_,
  743. requires (detail::as_cref_t<T> t, detail::as_cref_t<U> u)
  744. (
  745. (t == u) ? 1 : 0,
  746. (t != u) ? 1 : 0,
  747. (u == t) ? 1 : 0,
  748. (u != t) ? 1 : 0
  749. )
  750. );
  751. } // namespace detail
  752. #if defined(__clang__) || defined(_MSC_VER)
  753. template<bool B>
  754. ::concepts::detail::enable_if_t<void, B> requires_()
  755. {}
  756. #else
  757. template<bool B>
  758. CPP_INLINE_VAR constexpr ::concepts::detail::enable_if_t<int, B> requires_ = 0;
  759. #endif
  760. inline namespace defs
  761. {
  762. ////////////////////////////////////////////////////////////////////////////////////////
  763. // Utility concepts
  764. ////////////////////////////////////////////////////////////////////////////////////////
  765. CPP_def
  766. (
  767. template(bool B)
  768. (concept is_true)(B),
  769. B
  770. );
  771. CPP_def
  772. (
  773. template(typename... Args)
  774. (concept type)(Args...),
  775. true
  776. );
  777. CPP_def
  778. (
  779. template(class T, template<typename...> class Trait, typename... Args)
  780. (concept satisfies)(T, Trait, Args...),
  781. static_cast<bool>(Trait<T, Args...>::type::value)
  782. );
  783. ////////////////////////////////////////////////////////////////////////////////////////
  784. // Core language concepts
  785. ////////////////////////////////////////////////////////////////////////////////////////
  786. CPP_def
  787. (
  788. template(typename A, typename B)
  789. concept same_as,
  790. META_IS_SAME(A, B) && META_IS_SAME(B, A)
  791. );
  792. /// \cond
  793. CPP_def
  794. (
  795. template(typename A, typename B)
  796. concept not_same_as_,
  797. (!same_as<detail::remove_cvref_t<A>, detail::remove_cvref_t<B>>)
  798. );
  799. // Workaround bug in the Standard Library:
  800. // From cannot be an incomplete class type despite that
  801. // is_convertible<X, Y> should be equivalent to is_convertible<X&&, Y>
  802. // in such a case.
  803. CPP_def
  804. (
  805. template(typename From, typename To)
  806. concept implicitly_convertible_to,
  807. std::is_convertible<typename std::add_rvalue_reference<From>::type, To>::value
  808. );
  809. CPP_def
  810. (
  811. template(typename From, typename To)
  812. concept explicitly_convertible_to,
  813. requires (From (&from)())
  814. (
  815. static_cast<To>(from())
  816. )
  817. );
  818. /// \endcond
  819. CPP_def
  820. (
  821. template(typename From, typename To)
  822. concept convertible_to,
  823. implicitly_convertible_to<From, To> &&
  824. explicitly_convertible_to<From, To>
  825. );
  826. CPP_def
  827. (
  828. template(typename T, typename U)
  829. concept derived_from,
  830. META_IS_BASE_OF(U, T) &&
  831. convertible_to<T const volatile *, U const volatile *>
  832. );
  833. CPP_def
  834. (
  835. template(typename T, typename U)
  836. concept common_reference_with,
  837. same_as<common_reference_t<T, U>, common_reference_t<U, T>> &&
  838. convertible_to<T, common_reference_t<T, U>> &&
  839. convertible_to<U, common_reference_t<T, U>>
  840. );
  841. CPP_def
  842. (
  843. template(typename T, typename U)
  844. concept common_with,
  845. same_as<common_type_t<T, U>, common_type_t<U, T>> &&
  846. convertible_to<T, common_type_t<T, U>> &&
  847. convertible_to<U, common_type_t<T, U>> &&
  848. common_reference_with<
  849. typename std::add_lvalue_reference<T const>::type,
  850. typename std::add_lvalue_reference<U const>::type> &&
  851. common_reference_with<
  852. typename std::add_lvalue_reference<common_type_t<T, U>>::type,
  853. common_reference_t<
  854. typename std::add_lvalue_reference<T const>::type,
  855. typename std::add_lvalue_reference<U const>::type>>
  856. );
  857. CPP_def
  858. (
  859. template(typename T)
  860. concept integral,
  861. std::is_integral<T>::value
  862. );
  863. CPP_def
  864. (
  865. template(typename T)
  866. concept signed_integral,
  867. integral<T> &&
  868. std::is_signed<T>::value
  869. );
  870. CPP_def
  871. (
  872. template(typename T)
  873. concept unsigned_integral,
  874. integral<T> &&
  875. !signed_integral<T>
  876. );
  877. CPP_def
  878. (
  879. template(typename T, typename U)
  880. concept assignable_from,
  881. requires (T t, U &&u)
  882. (
  883. t = (U &&) u,
  884. requires_<same_as<T, decltype(t = (U &&) u)>>
  885. ) &&
  886. std::is_lvalue_reference<T>::value
  887. );
  888. CPP_def
  889. (
  890. template(typename T)
  891. concept swappable,
  892. requires (T &t, T &u)
  893. (
  894. concepts::swap(t, u)
  895. )
  896. );
  897. CPP_def
  898. (
  899. template(typename T, typename U)
  900. concept swappable_with,
  901. requires (T &&t, U &&u)
  902. (
  903. concepts::swap((T &&) t, (T &&) t),
  904. concepts::swap((U &&) u, (U &&) u),
  905. concepts::swap((U &&) u, (T &&) t),
  906. concepts::swap((T &&) t, (U &&) u)
  907. ) &&
  908. common_reference_with<detail::as_cref_t<T>, detail::as_cref_t<U>>
  909. );
  910. ////////////////////////////////////////////////////////////////////////////////////////////
  911. // Comparison concepts
  912. ////////////////////////////////////////////////////////////////////////////////////////////
  913. CPP_def
  914. (
  915. template(typename T)
  916. concept equality_comparable,
  917. detail::weakly_equality_comparable_with_<T, T>
  918. );
  919. CPP_def
  920. (
  921. template(typename T, typename U)
  922. concept equality_comparable_with,
  923. equality_comparable<T> &&
  924. equality_comparable<U> &&
  925. detail::weakly_equality_comparable_with_<T, U> &&
  926. common_reference_with<detail::as_cref_t<T>, detail::as_cref_t<U>> &&
  927. equality_comparable<
  928. common_reference_t<detail::as_cref_t<T>, detail::as_cref_t<U>>>
  929. );
  930. CPP_def
  931. (
  932. template(typename T)
  933. concept totally_ordered,
  934. requires (detail::as_cref_t<T> t, detail::as_cref_t<T> u)
  935. (
  936. t < u ? 1 : 0,
  937. t > u ? 1 : 0,
  938. u <= t ? 1 : 0,
  939. u >= t ? 1 : 0
  940. ) &&
  941. equality_comparable<T>
  942. );
  943. CPP_def
  944. (
  945. template(typename T, typename U)
  946. concept totally_ordered_with,
  947. requires (detail::as_cref_t<T> t, detail::as_cref_t<U> u)
  948. (
  949. t < u ? 1 : 0,
  950. t > u ? 1 : 0,
  951. t <= u ? 1 : 0,
  952. t >= u ? 1 : 0,
  953. u < t ? 1 : 0,
  954. u > t ? 1 : 0,
  955. u <= t ? 1 : 0,
  956. u >= t ? 1 : 0
  957. ) &&
  958. totally_ordered<T> &&
  959. totally_ordered<U> &&
  960. equality_comparable_with<T, U> &&
  961. common_reference_with<detail::as_cref_t<T>, detail::as_cref_t<U>> &&
  962. totally_ordered<
  963. common_reference_t<detail::as_cref_t<T>, detail::as_cref_t<U>>>
  964. );
  965. ////////////////////////////////////////////////////////////////////////////////////////////
  966. // Object concepts
  967. ////////////////////////////////////////////////////////////////////////////////////////////
  968. CPP_def
  969. (
  970. template(typename T)
  971. concept destructible,
  972. std::is_nothrow_destructible<T>::value
  973. );
  974. CPP_def
  975. (
  976. template(typename T, typename... Args)
  977. (concept constructible_from)(T, Args...),
  978. destructible<T> &&
  979. META_IS_CONSTRUCTIBLE(T, Args...)
  980. );
  981. CPP_def
  982. (
  983. template(typename T)
  984. concept default_constructible,
  985. constructible_from<T>
  986. );
  987. CPP_def
  988. (
  989. template(typename T)
  990. concept move_constructible,
  991. constructible_from<T, T> &&
  992. convertible_to<T, T>
  993. );
  994. CPP_def
  995. (
  996. template(typename T)
  997. concept copy_constructible,
  998. move_constructible<T> &&
  999. constructible_from<T, T &> &&
  1000. constructible_from<T, T const &> &&
  1001. constructible_from<T, T const> &&
  1002. convertible_to<T &, T> &&
  1003. convertible_to<T const &, T> &&
  1004. convertible_to<T const, T>
  1005. );
  1006. CPP_def
  1007. (
  1008. template(typename T)
  1009. concept movable,
  1010. std::is_object<T>::value &&
  1011. move_constructible<T> &&
  1012. assignable_from<T &, T> &&
  1013. swappable<T>
  1014. );
  1015. CPP_def
  1016. (
  1017. template(typename T)
  1018. concept copyable,
  1019. copy_constructible<T> &&
  1020. movable<T> &&
  1021. assignable_from<T &, T const &>
  1022. );
  1023. CPP_def
  1024. (
  1025. template(typename T)
  1026. concept semiregular,
  1027. copyable<T> &&
  1028. default_constructible<T>
  1029. // Axiom: copies are independent. See Fundamentals of Generic Programming
  1030. // http://www.stepanovpapers.com/DeSt98.pdf
  1031. );
  1032. CPP_def
  1033. (
  1034. template(typename T)
  1035. concept regular,
  1036. semiregular<T> &&
  1037. equality_comparable<T>
  1038. );
  1039. } // inline namespace defs
  1040. template<typename Concept, typename... Args>
  1041. struct is_satisfied_by
  1042. : meta::bool_<static_cast<bool>(typename Concept::template Eval<Args...>{})>
  1043. {};
  1044. // For automatically generating tags corresponding to concept
  1045. // subsumption relationships, for use with tag dispatching.
  1046. template<typename Concept, typename Base = meta::nil_>
  1047. struct tag
  1048. : Base
  1049. {};
  1050. template<typename Concepts, typename... Ts>
  1051. using tag_of =
  1052. meta::reverse_fold<
  1053. meta::find_if<
  1054. Concepts,
  1055. meta::bind_back<meta::quote<is_satisfied_by>, Ts...>>,
  1056. meta::nil_,
  1057. meta::flip<meta::quote<tag>>>;
  1058. } // namespace concepts
  1059. CPP_PP_IGNORE_CXX2A_COMPAT_END
  1060. #endif // RANGES_V3_UTILITY_CONCEPTS_HPP