concepts.hpp 48 KB

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