1*4d6fc14bSjoerg// -*- C++ -*- 2*4d6fc14bSjoerg//===-------------------------- concepts ----------------------------------===// 3*4d6fc14bSjoerg// 4*4d6fc14bSjoerg// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5*4d6fc14bSjoerg// See https://llvm.org/LICENSE.txt for license information. 6*4d6fc14bSjoerg// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7*4d6fc14bSjoerg// 8*4d6fc14bSjoerg//===----------------------------------------------------------------------===// 9*4d6fc14bSjoerg 10*4d6fc14bSjoerg#ifndef _LIBCPP_CONCEPTS 11*4d6fc14bSjoerg#define _LIBCPP_CONCEPTS 12*4d6fc14bSjoerg 13*4d6fc14bSjoerg/* 14*4d6fc14bSjoerg concepts synopsis 15*4d6fc14bSjoergnamespace std { 16*4d6fc14bSjoerg // [concepts.lang], language-related concepts 17*4d6fc14bSjoerg // [concept.same], concept same_as 18*4d6fc14bSjoerg template<class T, class U> 19*4d6fc14bSjoerg concept same_as = see below; 20*4d6fc14bSjoerg 21*4d6fc14bSjoerg // [concept.derived], concept derived_from 22*4d6fc14bSjoerg template<class Derived, class Base> 23*4d6fc14bSjoerg concept derived_from = see below; 24*4d6fc14bSjoerg 25*4d6fc14bSjoerg // [concept.convertible], concept convertible_to 26*4d6fc14bSjoerg template<class From, class To> 27*4d6fc14bSjoerg concept convertible_to = see below; 28*4d6fc14bSjoerg 29*4d6fc14bSjoerg // [concept.commonref], concept common_reference_with 30*4d6fc14bSjoerg template<class T, class U> 31*4d6fc14bSjoerg concept common_reference_with = see below; 32*4d6fc14bSjoerg 33*4d6fc14bSjoerg // [concept.common], concept common_with 34*4d6fc14bSjoerg template<class T, class U> 35*4d6fc14bSjoerg concept common_with = see below; 36*4d6fc14bSjoerg 37*4d6fc14bSjoerg // [concepts.arithmetic], arithmetic concepts 38*4d6fc14bSjoerg template<class T> 39*4d6fc14bSjoerg concept integral = see below; 40*4d6fc14bSjoerg template<class T> 41*4d6fc14bSjoerg concept signed_integral = see below; 42*4d6fc14bSjoerg template<class T> 43*4d6fc14bSjoerg concept unsigned_integral = see below; 44*4d6fc14bSjoerg template<class T> 45*4d6fc14bSjoerg concept floating_point = see below; 46*4d6fc14bSjoerg 47*4d6fc14bSjoerg // [concept.assignable], concept assignable_from 48*4d6fc14bSjoerg template<class LHS, class RHS> 49*4d6fc14bSjoerg concept assignable_from = see below; 50*4d6fc14bSjoerg 51*4d6fc14bSjoerg // [concept.swappable], concept swappable 52*4d6fc14bSjoerg namespace ranges { 53*4d6fc14bSjoerg inline namespace unspecified { 54*4d6fc14bSjoerg inline constexpr unspecified swap = unspecified; 55*4d6fc14bSjoerg } 56*4d6fc14bSjoerg } 57*4d6fc14bSjoerg template<class T> 58*4d6fc14bSjoerg concept swappable = see below; 59*4d6fc14bSjoerg template<class T, class U> 60*4d6fc14bSjoerg concept swappable_with = see below; 61*4d6fc14bSjoerg 62*4d6fc14bSjoerg // [concept.destructible], concept destructible 63*4d6fc14bSjoerg template<class T> 64*4d6fc14bSjoerg concept destructible = see below; 65*4d6fc14bSjoerg 66*4d6fc14bSjoerg // [concept.constructible], concept constructible_from 67*4d6fc14bSjoerg template<class T, class... Args> 68*4d6fc14bSjoerg concept constructible_from = see below; 69*4d6fc14bSjoerg 70*4d6fc14bSjoerg // [concept.default.init], concept default_initializable 71*4d6fc14bSjoerg template<class T> 72*4d6fc14bSjoerg concept default_initializable = see below; 73*4d6fc14bSjoerg 74*4d6fc14bSjoerg // [concept.moveconstructible], concept move_constructible 75*4d6fc14bSjoerg template<class T> 76*4d6fc14bSjoerg concept move_constructible = see below; 77*4d6fc14bSjoerg 78*4d6fc14bSjoerg // [concept.copyconstructible], concept copy_constructible 79*4d6fc14bSjoerg template<class T> 80*4d6fc14bSjoerg concept copy_constructible = see below; 81*4d6fc14bSjoerg 82*4d6fc14bSjoerg // [concept.equalitycomparable], concept equality_comparable 83*4d6fc14bSjoerg template<class T> 84*4d6fc14bSjoerg concept equality_comparable = see below; 85*4d6fc14bSjoerg template<class T, class U> 86*4d6fc14bSjoerg concept equality_comparable_with = see below; 87*4d6fc14bSjoerg 88*4d6fc14bSjoerg // [concept.totallyordered], concept totally_ordered 89*4d6fc14bSjoerg template<class T> 90*4d6fc14bSjoerg concept totally_ordered = see below; 91*4d6fc14bSjoerg template<class T, class U> 92*4d6fc14bSjoerg concept totally_ordered_with = see below; 93*4d6fc14bSjoerg 94*4d6fc14bSjoerg // [concepts.object], object concepts 95*4d6fc14bSjoerg template<class T> 96*4d6fc14bSjoerg concept movable = see below; 97*4d6fc14bSjoerg template<class T> 98*4d6fc14bSjoerg concept copyable = see below; 99*4d6fc14bSjoerg template<class T> 100*4d6fc14bSjoerg concept semiregular = see below; 101*4d6fc14bSjoerg template<class T> 102*4d6fc14bSjoerg concept regular = see below; 103*4d6fc14bSjoerg 104*4d6fc14bSjoerg // [concepts.callable], callable concepts 105*4d6fc14bSjoerg // [concept.invocable], concept invocable 106*4d6fc14bSjoerg template<class F, class... Args> 107*4d6fc14bSjoerg concept invocable = see below; 108*4d6fc14bSjoerg 109*4d6fc14bSjoerg // [concept.regularinvocable], concept regular_invocable 110*4d6fc14bSjoerg template<class F, class... Args> 111*4d6fc14bSjoerg concept regular_invocable = see below; 112*4d6fc14bSjoerg 113*4d6fc14bSjoerg // [concept.predicate], concept predicate 114*4d6fc14bSjoerg template<class F, class... Args> 115*4d6fc14bSjoerg concept predicate = see below; 116*4d6fc14bSjoerg 117*4d6fc14bSjoerg // [concept.relation], concept relation 118*4d6fc14bSjoerg template<class R, class T, class U> 119*4d6fc14bSjoerg concept relation = see below; 120*4d6fc14bSjoerg 121*4d6fc14bSjoerg // [concept.equiv], concept equivalence_relation 122*4d6fc14bSjoerg template<class R, class T, class U> 123*4d6fc14bSjoerg concept equivalence_relation = see below; 124*4d6fc14bSjoerg 125*4d6fc14bSjoerg // [concept.strictweakorder], concept strict_weak_order 126*4d6fc14bSjoerg template<class R, class T, class U> 127*4d6fc14bSjoerg concept strict_weak_order = see below; 128*4d6fc14bSjoerg} 129*4d6fc14bSjoerg 130*4d6fc14bSjoerg*/ 131*4d6fc14bSjoerg 132*4d6fc14bSjoerg#include <__config> 133*4d6fc14bSjoerg#include <__functional_base> 134*4d6fc14bSjoerg#include <type_traits> 135*4d6fc14bSjoerg#include <utility> 136*4d6fc14bSjoerg#include <version> 137*4d6fc14bSjoerg 138*4d6fc14bSjoerg#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 139*4d6fc14bSjoerg#pragma GCC system_header 140*4d6fc14bSjoerg#endif 141*4d6fc14bSjoerg 142*4d6fc14bSjoerg_LIBCPP_PUSH_MACROS 143*4d6fc14bSjoerg#include <__undef_macros> 144*4d6fc14bSjoerg 145*4d6fc14bSjoerg_LIBCPP_BEGIN_NAMESPACE_STD 146*4d6fc14bSjoerg 147*4d6fc14bSjoerg#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS) 148*4d6fc14bSjoerg 149*4d6fc14bSjoerg// [concept.same] 150*4d6fc14bSjoerg 151*4d6fc14bSjoergtemplate<class _Tp, class _Up> 152*4d6fc14bSjoergconcept __same_as_impl = _VSTD::_IsSame<_Tp, _Up>::value; 153*4d6fc14bSjoerg 154*4d6fc14bSjoergtemplate<class _Tp, class _Up> 155*4d6fc14bSjoergconcept same_as = __same_as_impl<_Tp, _Up> && __same_as_impl<_Up, _Tp>; 156*4d6fc14bSjoerg 157*4d6fc14bSjoerg// [concept.derived] 158*4d6fc14bSjoergtemplate<class _Dp, class _Bp> 159*4d6fc14bSjoergconcept derived_from = 160*4d6fc14bSjoerg is_base_of_v<_Bp, _Dp> && 161*4d6fc14bSjoerg is_convertible_v<const volatile _Dp*, const volatile _Bp*>; 162*4d6fc14bSjoerg 163*4d6fc14bSjoerg// [concept.convertible] 164*4d6fc14bSjoergtemplate<class _From, class _To> 165*4d6fc14bSjoergconcept convertible_to = 166*4d6fc14bSjoerg is_convertible_v<_From, _To> && 167*4d6fc14bSjoerg requires(add_rvalue_reference_t<_From> (&__f)()) { 168*4d6fc14bSjoerg static_cast<_To>(__f()); 169*4d6fc14bSjoerg }; 170*4d6fc14bSjoerg 171*4d6fc14bSjoerg// [concept.commonref] 172*4d6fc14bSjoergtemplate<class _Tp, class _Up> 173*4d6fc14bSjoergconcept common_reference_with = 174*4d6fc14bSjoerg same_as<common_reference_t<_Tp, _Up>, common_reference_t<_Up, _Tp>> && 175*4d6fc14bSjoerg convertible_to<_Tp, common_reference_t<_Tp, _Up>> && 176*4d6fc14bSjoerg convertible_to<_Up, common_reference_t<_Tp, _Up>>; 177*4d6fc14bSjoerg 178*4d6fc14bSjoerg// [concept.common] 179*4d6fc14bSjoergtemplate<class _Tp, class _Up> 180*4d6fc14bSjoergconcept common_with = 181*4d6fc14bSjoerg same_as<common_type_t<_Tp, _Up>, common_type_t<_Up, _Tp>> && 182*4d6fc14bSjoerg requires { 183*4d6fc14bSjoerg static_cast<common_type_t<_Tp, _Up>>(declval<_Tp>()); 184*4d6fc14bSjoerg static_cast<common_type_t<_Tp, _Up>>(declval<_Up>()); 185*4d6fc14bSjoerg } && 186*4d6fc14bSjoerg common_reference_with< 187*4d6fc14bSjoerg add_lvalue_reference_t<const _Tp>, 188*4d6fc14bSjoerg add_lvalue_reference_t<const _Up>> && 189*4d6fc14bSjoerg common_reference_with< 190*4d6fc14bSjoerg add_lvalue_reference_t<common_type_t<_Tp, _Up>>, 191*4d6fc14bSjoerg common_reference_t< 192*4d6fc14bSjoerg add_lvalue_reference_t<const _Tp>, 193*4d6fc14bSjoerg add_lvalue_reference_t<const _Up>>>; 194*4d6fc14bSjoerg 195*4d6fc14bSjoerg// [concepts.arithmetic], arithmetic concepts 196*4d6fc14bSjoergtemplate<class _Tp> 197*4d6fc14bSjoergconcept integral = is_integral_v<_Tp>; 198*4d6fc14bSjoerg 199*4d6fc14bSjoergtemplate<class _Tp> 200*4d6fc14bSjoergconcept signed_integral = integral<_Tp> && is_signed_v<_Tp>; 201*4d6fc14bSjoerg 202*4d6fc14bSjoergtemplate<class _Tp> 203*4d6fc14bSjoergconcept unsigned_integral = integral<_Tp> && !signed_integral<_Tp>; 204*4d6fc14bSjoerg 205*4d6fc14bSjoergtemplate<class _Tp> 206*4d6fc14bSjoergconcept floating_point = is_floating_point_v<_Tp>; 207*4d6fc14bSjoerg 208*4d6fc14bSjoerg// [concept.assignable] 209*4d6fc14bSjoergtemplate<class _Lhs, class _Rhs> 210*4d6fc14bSjoergconcept assignable_from = 211*4d6fc14bSjoerg is_lvalue_reference_v<_Lhs> && 212*4d6fc14bSjoerg common_reference_with<__make_const_lvalue_ref<_Lhs>, __make_const_lvalue_ref<_Rhs>> && 213*4d6fc14bSjoerg requires (_Lhs __lhs, _Rhs&& __rhs) { 214*4d6fc14bSjoerg { __lhs = _VSTD::forward<_Rhs>(__rhs) } -> same_as<_Lhs>; 215*4d6fc14bSjoerg }; 216*4d6fc14bSjoerg 217*4d6fc14bSjoerg// [concept.destructible] 218*4d6fc14bSjoerg 219*4d6fc14bSjoergtemplate<class _Tp> 220*4d6fc14bSjoergconcept destructible = is_nothrow_destructible_v<_Tp>; 221*4d6fc14bSjoerg 222*4d6fc14bSjoerg// [concept.constructible] 223*4d6fc14bSjoergtemplate<class _Tp, class... _Args> 224*4d6fc14bSjoergconcept constructible_from = 225*4d6fc14bSjoerg destructible<_Tp> && is_constructible_v<_Tp, _Args...>; 226*4d6fc14bSjoerg 227*4d6fc14bSjoerg// [concept.default.init] 228*4d6fc14bSjoerg 229*4d6fc14bSjoergtemplate<class _Tp> 230*4d6fc14bSjoergconcept __default_initializable = requires { ::new _Tp; }; 231*4d6fc14bSjoerg 232*4d6fc14bSjoergtemplate<class _Tp> 233*4d6fc14bSjoergconcept default_initializable = constructible_from<_Tp> && 234*4d6fc14bSjoerg requires { _Tp{}; } && __default_initializable<_Tp>; 235*4d6fc14bSjoerg 236*4d6fc14bSjoerg// [concept.moveconstructible] 237*4d6fc14bSjoergtemplate<class _Tp> 238*4d6fc14bSjoergconcept move_constructible = 239*4d6fc14bSjoerg constructible_from<_Tp, _Tp> && convertible_to<_Tp, _Tp>; 240*4d6fc14bSjoerg 241*4d6fc14bSjoerg// [concept.copyconstructible] 242*4d6fc14bSjoergtemplate<class _Tp> 243*4d6fc14bSjoergconcept copy_constructible = 244*4d6fc14bSjoerg move_constructible<_Tp> && 245*4d6fc14bSjoerg constructible_from<_Tp, _Tp&> && convertible_to<_Tp&, _Tp> && 246*4d6fc14bSjoerg constructible_from<_Tp, const _Tp&> && convertible_to<const _Tp&, _Tp> && 247*4d6fc14bSjoerg constructible_from<_Tp, const _Tp> && convertible_to<const _Tp, _Tp>; 248*4d6fc14bSjoerg 249*4d6fc14bSjoerg// Whether a type is a class type or enumeration type according to the Core wording. 250*4d6fc14bSjoergtemplate<class _Tp> 251*4d6fc14bSjoergconcept __class_or_enum = is_class_v<_Tp> || is_union_v<_Tp> || is_enum_v<_Tp>; 252*4d6fc14bSjoerg 253*4d6fc14bSjoerg// [concept.swappable] 254*4d6fc14bSjoergnamespace ranges::__swap { 255*4d6fc14bSjoerg // Deleted to inhibit ADL 256*4d6fc14bSjoerg template<class _Tp> 257*4d6fc14bSjoerg void swap(_Tp&, _Tp&) = delete; 258*4d6fc14bSjoerg 259*4d6fc14bSjoerg 260*4d6fc14bSjoerg // [1] 261*4d6fc14bSjoerg template<class _Tp, class _Up> 262*4d6fc14bSjoerg concept __unqualified_swappable_with = 263*4d6fc14bSjoerg (__class_or_enum<remove_cvref_t<_Tp>> || __class_or_enum<remove_cvref_t<_Up>>) && 264*4d6fc14bSjoerg requires(_Tp&& __t, _Up&& __u) { 265*4d6fc14bSjoerg swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); 266*4d6fc14bSjoerg }; 267*4d6fc14bSjoerg 268*4d6fc14bSjoerg struct __fn; 269*4d6fc14bSjoerg 270*4d6fc14bSjoerg template<class _Tp, class _Up, size_t _Size> 271*4d6fc14bSjoerg concept __swappable_arrays = 272*4d6fc14bSjoerg !__unqualified_swappable_with<_Tp(&)[_Size], _Up(&)[_Size]> && 273*4d6fc14bSjoerg extent_v<_Tp> == extent_v<_Up> && 274*4d6fc14bSjoerg requires(_Tp(& __t)[_Size], _Up(& __u)[_Size], const __fn& __swap) { 275*4d6fc14bSjoerg __swap(__t[0], __u[0]); 276*4d6fc14bSjoerg }; 277*4d6fc14bSjoerg 278*4d6fc14bSjoerg template<class _Tp> 279*4d6fc14bSjoerg concept __exchangeable = 280*4d6fc14bSjoerg !__unqualified_swappable_with<_Tp&, _Tp&> && 281*4d6fc14bSjoerg move_constructible<_Tp> && 282*4d6fc14bSjoerg assignable_from<_Tp&, _Tp>; 283*4d6fc14bSjoerg 284*4d6fc14bSjoerg struct __fn { 285*4d6fc14bSjoerg // 2.1 `S` is `(void)swap(E1, E2)`* if `E1` or `E2` has class or enumeration type and... 286*4d6fc14bSjoerg // *The name `swap` is used here unqualified. 287*4d6fc14bSjoerg template<class _Tp, class _Up> 288*4d6fc14bSjoerg requires __unqualified_swappable_with<_Tp, _Up> 289*4d6fc14bSjoerg constexpr void operator()(_Tp&& __t, _Up&& __u) const 290*4d6fc14bSjoerg noexcept(noexcept(swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) 291*4d6fc14bSjoerg { 292*4d6fc14bSjoerg swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); 293*4d6fc14bSjoerg } 294*4d6fc14bSjoerg 295*4d6fc14bSjoerg // 2.2 Otherwise, if `E1` and `E2` are lvalues of array types with equal extent and... 296*4d6fc14bSjoerg template<class _Tp, class _Up, size_t _Size> 297*4d6fc14bSjoerg requires __swappable_arrays<_Tp, _Up, _Size> 298*4d6fc14bSjoerg constexpr void operator()(_Tp(& __t)[_Size], _Up(& __u)[_Size]) const 299*4d6fc14bSjoerg noexcept(noexcept((*this)(*__t, *__u))) 300*4d6fc14bSjoerg { 301*4d6fc14bSjoerg // TODO(cjdb): replace with `ranges::swap_ranges`. 302*4d6fc14bSjoerg for (size_t __i = 0; __i < _Size; ++__i) { 303*4d6fc14bSjoerg (*this)(__t[__i], __u[__i]); 304*4d6fc14bSjoerg } 305*4d6fc14bSjoerg } 306*4d6fc14bSjoerg 307*4d6fc14bSjoerg // 2.3 Otherwise, if `E1` and `E2` are lvalues of the same type `T` that models... 308*4d6fc14bSjoerg template<__exchangeable _Tp> 309*4d6fc14bSjoerg constexpr void operator()(_Tp& __x, _Tp& __y) const 310*4d6fc14bSjoerg noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_move_assignable_v<_Tp>) 311*4d6fc14bSjoerg { 312*4d6fc14bSjoerg __y = _VSTD::exchange(__x, _VSTD::move(__y)); 313*4d6fc14bSjoerg } 314*4d6fc14bSjoerg }; 315*4d6fc14bSjoerg} // namespace ranges::__swap 316*4d6fc14bSjoerg 317*4d6fc14bSjoergnamespace ranges::inline __cpo { 318*4d6fc14bSjoerg inline constexpr auto swap = __swap::__fn{}; 319*4d6fc14bSjoerg} // namespace ranges::__cpo 320*4d6fc14bSjoerg 321*4d6fc14bSjoergtemplate<class _Tp> 322*4d6fc14bSjoergconcept swappable = requires(_Tp& __a, _Tp& __b) { ranges::swap(__a, __b); }; 323*4d6fc14bSjoerg 324*4d6fc14bSjoergtemplate<class _Tp, class _Up> 325*4d6fc14bSjoergconcept swappable_with = 326*4d6fc14bSjoerg common_reference_with<_Tp, _Up> && 327*4d6fc14bSjoerg requires(_Tp&& __t, _Up&& __u) { 328*4d6fc14bSjoerg ranges::swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Tp>(__t)); 329*4d6fc14bSjoerg ranges::swap(_VSTD::forward<_Up>(__u), _VSTD::forward<_Up>(__u)); 330*4d6fc14bSjoerg ranges::swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); 331*4d6fc14bSjoerg ranges::swap(_VSTD::forward<_Up>(__u), _VSTD::forward<_Tp>(__t)); 332*4d6fc14bSjoerg }; 333*4d6fc14bSjoerg 334*4d6fc14bSjoerg// [concept.booleantestable] 335*4d6fc14bSjoergtemplate<class _Tp> 336*4d6fc14bSjoergconcept __boolean_testable_impl = convertible_to<_Tp, bool>; 337*4d6fc14bSjoerg 338*4d6fc14bSjoergtemplate<class _Tp> 339*4d6fc14bSjoergconcept __boolean_testable = __boolean_testable_impl<_Tp> && requires(_Tp&& __t) { 340*4d6fc14bSjoerg { !std::forward<_Tp>(__t) } -> __boolean_testable_impl; 341*4d6fc14bSjoerg}; 342*4d6fc14bSjoerg 343*4d6fc14bSjoerg// [concept.equalitycomparable] 344*4d6fc14bSjoergtemplate<class _Tp, class _Up> 345*4d6fc14bSjoergconcept __weakly_equality_comparable_with = 346*4d6fc14bSjoerg requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) { 347*4d6fc14bSjoerg { __t == __u } -> __boolean_testable; 348*4d6fc14bSjoerg { __t != __u } -> __boolean_testable; 349*4d6fc14bSjoerg { __u == __t } -> __boolean_testable; 350*4d6fc14bSjoerg { __u != __t } -> __boolean_testable; 351*4d6fc14bSjoerg }; 352*4d6fc14bSjoerg 353*4d6fc14bSjoergtemplate<class _Tp> 354*4d6fc14bSjoergconcept equality_comparable = __weakly_equality_comparable_with<_Tp, _Tp>; 355*4d6fc14bSjoerg 356*4d6fc14bSjoergtemplate<class _Tp, class _Up> 357*4d6fc14bSjoergconcept equality_comparable_with = 358*4d6fc14bSjoerg equality_comparable<_Tp> && equality_comparable<_Up> && 359*4d6fc14bSjoerg common_reference_with<__make_const_lvalue_ref<_Tp>, __make_const_lvalue_ref<_Up>> && 360*4d6fc14bSjoerg equality_comparable< 361*4d6fc14bSjoerg common_reference_t< 362*4d6fc14bSjoerg __make_const_lvalue_ref<_Tp>, 363*4d6fc14bSjoerg __make_const_lvalue_ref<_Up>>> && 364*4d6fc14bSjoerg __weakly_equality_comparable_with<_Tp, _Up>; 365*4d6fc14bSjoerg 366*4d6fc14bSjoerg// [concept.totallyordered] 367*4d6fc14bSjoerg 368*4d6fc14bSjoergtemplate<class _Tp, class _Up> 369*4d6fc14bSjoergconcept __partially_ordered_with = 370*4d6fc14bSjoerg requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) { 371*4d6fc14bSjoerg { __t < __u } -> __boolean_testable; 372*4d6fc14bSjoerg { __t > __u } -> __boolean_testable; 373*4d6fc14bSjoerg { __t <= __u } -> __boolean_testable; 374*4d6fc14bSjoerg { __t >= __u } -> __boolean_testable; 375*4d6fc14bSjoerg { __u < __t } -> __boolean_testable; 376*4d6fc14bSjoerg { __u > __t } -> __boolean_testable; 377*4d6fc14bSjoerg { __u <= __t } -> __boolean_testable; 378*4d6fc14bSjoerg { __u >= __t } -> __boolean_testable; 379*4d6fc14bSjoerg }; 380*4d6fc14bSjoerg 381*4d6fc14bSjoergtemplate<class _Tp> 382*4d6fc14bSjoergconcept totally_ordered = equality_comparable<_Tp> && __partially_ordered_with<_Tp, _Tp>; 383*4d6fc14bSjoerg 384*4d6fc14bSjoergtemplate<class _Tp, class _Up> 385*4d6fc14bSjoergconcept totally_ordered_with = 386*4d6fc14bSjoerg totally_ordered<_Tp> && totally_ordered<_Up> && 387*4d6fc14bSjoerg equality_comparable_with<_Tp, _Up> && 388*4d6fc14bSjoerg totally_ordered< 389*4d6fc14bSjoerg common_reference_t< 390*4d6fc14bSjoerg __make_const_lvalue_ref<_Tp>, 391*4d6fc14bSjoerg __make_const_lvalue_ref<_Up>>> && 392*4d6fc14bSjoerg __partially_ordered_with<_Tp, _Up>; 393*4d6fc14bSjoerg 394*4d6fc14bSjoerg// [concepts.object] 395*4d6fc14bSjoergtemplate<class _Tp> 396*4d6fc14bSjoergconcept movable = 397*4d6fc14bSjoerg is_object_v<_Tp> && 398*4d6fc14bSjoerg move_constructible<_Tp> && 399*4d6fc14bSjoerg assignable_from<_Tp&, _Tp> && 400*4d6fc14bSjoerg swappable<_Tp>; 401*4d6fc14bSjoerg 402*4d6fc14bSjoergtemplate<class _Tp> 403*4d6fc14bSjoergconcept copyable = 404*4d6fc14bSjoerg copy_constructible<_Tp> && 405*4d6fc14bSjoerg movable<_Tp> && 406*4d6fc14bSjoerg assignable_from<_Tp&, _Tp&> && 407*4d6fc14bSjoerg assignable_from<_Tp&, const _Tp&> && 408*4d6fc14bSjoerg assignable_from<_Tp&, const _Tp>; 409*4d6fc14bSjoerg 410*4d6fc14bSjoergtemplate<class _Tp> 411*4d6fc14bSjoergconcept semiregular = copyable<_Tp> && default_initializable<_Tp>; 412*4d6fc14bSjoerg 413*4d6fc14bSjoergtemplate<class _Tp> 414*4d6fc14bSjoergconcept regular = semiregular<_Tp> && equality_comparable<_Tp>; 415*4d6fc14bSjoerg 416*4d6fc14bSjoerg// [concept.invocable] 417*4d6fc14bSjoergtemplate<class _Fn, class... _Args> 418*4d6fc14bSjoergconcept invocable = requires(_Fn&& __fn, _Args&&... __args) { 419*4d6fc14bSjoerg _VSTD::invoke(_VSTD::forward<_Fn>(__fn), _VSTD::forward<_Args>(__args)...); // not required to be equality preserving 420*4d6fc14bSjoerg}; 421*4d6fc14bSjoerg 422*4d6fc14bSjoerg// [concept.regular.invocable] 423*4d6fc14bSjoergtemplate<class _Fn, class... _Args> 424*4d6fc14bSjoergconcept regular_invocable = invocable<_Fn, _Args...>; 425*4d6fc14bSjoerg 426*4d6fc14bSjoerg// [concept.predicate] 427*4d6fc14bSjoergtemplate<class _Fn, class... _Args> 428*4d6fc14bSjoergconcept predicate = 429*4d6fc14bSjoerg regular_invocable<_Fn, _Args...> && __boolean_testable<invoke_result_t<_Fn, _Args...>>; 430*4d6fc14bSjoerg 431*4d6fc14bSjoerg// [concept.relation] 432*4d6fc14bSjoergtemplate<class _Rp, class _Tp, class _Up> 433*4d6fc14bSjoergconcept relation = 434*4d6fc14bSjoerg predicate<_Rp, _Tp, _Tp> && predicate<_Rp, _Up, _Up> && 435*4d6fc14bSjoerg predicate<_Rp, _Tp, _Up> && predicate<_Rp, _Up, _Tp>; 436*4d6fc14bSjoerg 437*4d6fc14bSjoerg// [concept.equiv] 438*4d6fc14bSjoergtemplate<class _Rp, class _Tp, class _Up> 439*4d6fc14bSjoergconcept equivalence_relation = relation<_Rp, _Tp, _Up>; 440*4d6fc14bSjoerg 441*4d6fc14bSjoerg// [concept.strictweakorder] 442*4d6fc14bSjoergtemplate<class _Rp, class _Tp, class _Up> 443*4d6fc14bSjoergconcept strict_weak_order = relation<_Rp, _Tp, _Up>; 444*4d6fc14bSjoerg 445*4d6fc14bSjoerg#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS) 446*4d6fc14bSjoerg 447*4d6fc14bSjoerg_LIBCPP_END_NAMESPACE_STD 448*4d6fc14bSjoerg 449*4d6fc14bSjoerg_LIBCPP_POP_MACROS 450*4d6fc14bSjoerg 451*4d6fc14bSjoerg#endif // _LIBCPP_CONCEPTS 452