15ffd83dbSDimitry Andric// -*- C++ -*- 25ffd83dbSDimitry Andric//===-------------------------- concepts ----------------------------------===// 35ffd83dbSDimitry Andric// 45ffd83dbSDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 55ffd83dbSDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 65ffd83dbSDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 75ffd83dbSDimitry Andric// 85ffd83dbSDimitry Andric//===----------------------------------------------------------------------===// 95ffd83dbSDimitry Andric 105ffd83dbSDimitry Andric#ifndef _LIBCPP_CONCEPTS 115ffd83dbSDimitry Andric#define _LIBCPP_CONCEPTS 125ffd83dbSDimitry Andric 135ffd83dbSDimitry Andric/* 145ffd83dbSDimitry Andric concepts synopsis 155ffd83dbSDimitry Andricnamespace std { 165ffd83dbSDimitry Andric // [concepts.lang], language-related concepts 175ffd83dbSDimitry Andric // [concept.same], concept same_as 185ffd83dbSDimitry Andric template<class T, class U> 195ffd83dbSDimitry Andric concept same_as = see below; 205ffd83dbSDimitry Andric 215ffd83dbSDimitry Andric // [concept.derived], concept derived_from 225ffd83dbSDimitry Andric template<class Derived, class Base> 235ffd83dbSDimitry Andric concept derived_from = see below; 245ffd83dbSDimitry Andric 255ffd83dbSDimitry Andric // [concept.convertible], concept convertible_to 265ffd83dbSDimitry Andric template<class From, class To> 275ffd83dbSDimitry Andric concept convertible_to = see below; 285ffd83dbSDimitry Andric 295ffd83dbSDimitry Andric // [concept.commonref], concept common_reference_with 305ffd83dbSDimitry Andric template<class T, class U> 315ffd83dbSDimitry Andric concept common_reference_with = see below; 325ffd83dbSDimitry Andric 335ffd83dbSDimitry Andric // [concept.common], concept common_with 345ffd83dbSDimitry Andric template<class T, class U> 355ffd83dbSDimitry Andric concept common_with = see below; 365ffd83dbSDimitry Andric 375ffd83dbSDimitry Andric // [concepts.arithmetic], arithmetic concepts 385ffd83dbSDimitry Andric template<class T> 395ffd83dbSDimitry Andric concept integral = see below; 405ffd83dbSDimitry Andric template<class T> 415ffd83dbSDimitry Andric concept signed_integral = see below; 425ffd83dbSDimitry Andric template<class T> 435ffd83dbSDimitry Andric concept unsigned_integral = see below; 445ffd83dbSDimitry Andric template<class T> 455ffd83dbSDimitry Andric concept floating_point = see below; 465ffd83dbSDimitry Andric 475ffd83dbSDimitry Andric // [concept.assignable], concept assignable_from 485ffd83dbSDimitry Andric template<class LHS, class RHS> 495ffd83dbSDimitry Andric concept assignable_from = see below; 505ffd83dbSDimitry Andric 515ffd83dbSDimitry Andric // [concept.swappable], concept swappable 525ffd83dbSDimitry Andric namespace ranges { 535ffd83dbSDimitry Andric inline namespace unspecified { 545ffd83dbSDimitry Andric inline constexpr unspecified swap = unspecified; 555ffd83dbSDimitry Andric } 565ffd83dbSDimitry Andric } 575ffd83dbSDimitry Andric template<class T> 585ffd83dbSDimitry Andric concept swappable = see below; 595ffd83dbSDimitry Andric template<class T, class U> 605ffd83dbSDimitry Andric concept swappable_with = see below; 615ffd83dbSDimitry Andric 625ffd83dbSDimitry Andric // [concept.destructible], concept destructible 635ffd83dbSDimitry Andric template<class T> 645ffd83dbSDimitry Andric concept destructible = see below; 655ffd83dbSDimitry Andric 665ffd83dbSDimitry Andric // [concept.constructible], concept constructible_from 675ffd83dbSDimitry Andric template<class T, class... Args> 685ffd83dbSDimitry Andric concept constructible_from = see below; 695ffd83dbSDimitry Andric 70*fe6060f1SDimitry Andric // [concept.default.init], concept default_initializable 715ffd83dbSDimitry Andric template<class T> 72*fe6060f1SDimitry Andric concept default_initializable = see below; 735ffd83dbSDimitry Andric 745ffd83dbSDimitry Andric // [concept.moveconstructible], concept move_constructible 755ffd83dbSDimitry Andric template<class T> 765ffd83dbSDimitry Andric concept move_constructible = see below; 775ffd83dbSDimitry Andric 785ffd83dbSDimitry Andric // [concept.copyconstructible], concept copy_constructible 795ffd83dbSDimitry Andric template<class T> 805ffd83dbSDimitry Andric concept copy_constructible = see below; 815ffd83dbSDimitry Andric 825ffd83dbSDimitry Andric // [concept.equalitycomparable], concept equality_comparable 835ffd83dbSDimitry Andric template<class T> 845ffd83dbSDimitry Andric concept equality_comparable = see below; 855ffd83dbSDimitry Andric template<class T, class U> 865ffd83dbSDimitry Andric concept equality_comparable_with = see below; 875ffd83dbSDimitry Andric 885ffd83dbSDimitry Andric // [concept.totallyordered], concept totally_ordered 895ffd83dbSDimitry Andric template<class T> 905ffd83dbSDimitry Andric concept totally_ordered = see below; 915ffd83dbSDimitry Andric template<class T, class U> 925ffd83dbSDimitry Andric concept totally_ordered_with = see below; 935ffd83dbSDimitry Andric 945ffd83dbSDimitry Andric // [concepts.object], object concepts 955ffd83dbSDimitry Andric template<class T> 965ffd83dbSDimitry Andric concept movable = see below; 975ffd83dbSDimitry Andric template<class T> 985ffd83dbSDimitry Andric concept copyable = see below; 995ffd83dbSDimitry Andric template<class T> 1005ffd83dbSDimitry Andric concept semiregular = see below; 1015ffd83dbSDimitry Andric template<class T> 1025ffd83dbSDimitry Andric concept regular = see below; 1035ffd83dbSDimitry Andric 1045ffd83dbSDimitry Andric // [concepts.callable], callable concepts 1055ffd83dbSDimitry Andric // [concept.invocable], concept invocable 1065ffd83dbSDimitry Andric template<class F, class... Args> 1075ffd83dbSDimitry Andric concept invocable = see below; 1085ffd83dbSDimitry Andric 1095ffd83dbSDimitry Andric // [concept.regularinvocable], concept regular_invocable 1105ffd83dbSDimitry Andric template<class F, class... Args> 1115ffd83dbSDimitry Andric concept regular_invocable = see below; 1125ffd83dbSDimitry Andric 1135ffd83dbSDimitry Andric // [concept.predicate], concept predicate 1145ffd83dbSDimitry Andric template<class F, class... Args> 1155ffd83dbSDimitry Andric concept predicate = see below; 1165ffd83dbSDimitry Andric 1175ffd83dbSDimitry Andric // [concept.relation], concept relation 1185ffd83dbSDimitry Andric template<class R, class T, class U> 1195ffd83dbSDimitry Andric concept relation = see below; 1205ffd83dbSDimitry Andric 1215ffd83dbSDimitry Andric // [concept.equiv], concept equivalence_relation 1225ffd83dbSDimitry Andric template<class R, class T, class U> 1235ffd83dbSDimitry Andric concept equivalence_relation = see below; 1245ffd83dbSDimitry Andric 1255ffd83dbSDimitry Andric // [concept.strictweakorder], concept strict_weak_order 1265ffd83dbSDimitry Andric template<class R, class T, class U> 1275ffd83dbSDimitry Andric concept strict_weak_order = see below; 1285ffd83dbSDimitry Andric} 1295ffd83dbSDimitry Andric 1305ffd83dbSDimitry Andric*/ 1315ffd83dbSDimitry Andric 1325ffd83dbSDimitry Andric#include <__config> 133*fe6060f1SDimitry Andric#include <__functional/invoke.h> 134*fe6060f1SDimitry Andric#include <__functional_base> 1355ffd83dbSDimitry Andric#include <type_traits> 136*fe6060f1SDimitry Andric#include <utility> 1375ffd83dbSDimitry Andric#include <version> 1385ffd83dbSDimitry Andric 1395ffd83dbSDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 1405ffd83dbSDimitry Andric#pragma GCC system_header 1415ffd83dbSDimitry Andric#endif 1425ffd83dbSDimitry Andric 1435ffd83dbSDimitry Andric_LIBCPP_PUSH_MACROS 1445ffd83dbSDimitry Andric#include <__undef_macros> 1455ffd83dbSDimitry Andric 1465ffd83dbSDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 1475ffd83dbSDimitry Andric 148*fe6060f1SDimitry Andric#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS) 1495ffd83dbSDimitry Andric 1505ffd83dbSDimitry Andric// [concept.same] 1515ffd83dbSDimitry Andric 1525ffd83dbSDimitry Andrictemplate<class _Tp, class _Up> 1535ffd83dbSDimitry Andricconcept __same_as_impl = _VSTD::_IsSame<_Tp, _Up>::value; 1545ffd83dbSDimitry Andric 1555ffd83dbSDimitry Andrictemplate<class _Tp, class _Up> 1565ffd83dbSDimitry Andricconcept same_as = __same_as_impl<_Tp, _Up> && __same_as_impl<_Up, _Tp>; 1575ffd83dbSDimitry Andric 158*fe6060f1SDimitry Andric// [concept.derived] 159*fe6060f1SDimitry Andrictemplate<class _Dp, class _Bp> 160*fe6060f1SDimitry Andricconcept derived_from = 161*fe6060f1SDimitry Andric is_base_of_v<_Bp, _Dp> && 162*fe6060f1SDimitry Andric is_convertible_v<const volatile _Dp*, const volatile _Bp*>; 163*fe6060f1SDimitry Andric 164*fe6060f1SDimitry Andric// [concept.convertible] 165*fe6060f1SDimitry Andrictemplate<class _From, class _To> 166*fe6060f1SDimitry Andricconcept convertible_to = 167*fe6060f1SDimitry Andric is_convertible_v<_From, _To> && 168*fe6060f1SDimitry Andric requires(add_rvalue_reference_t<_From> (&__f)()) { 169*fe6060f1SDimitry Andric static_cast<_To>(__f()); 170*fe6060f1SDimitry Andric }; 171*fe6060f1SDimitry Andric 172*fe6060f1SDimitry Andric// [concept.commonref] 173*fe6060f1SDimitry Andrictemplate<class _Tp, class _Up> 174*fe6060f1SDimitry Andricconcept common_reference_with = 175*fe6060f1SDimitry Andric same_as<common_reference_t<_Tp, _Up>, common_reference_t<_Up, _Tp>> && 176*fe6060f1SDimitry Andric convertible_to<_Tp, common_reference_t<_Tp, _Up>> && 177*fe6060f1SDimitry Andric convertible_to<_Up, common_reference_t<_Tp, _Up>>; 178*fe6060f1SDimitry Andric 179*fe6060f1SDimitry Andric// [concept.common] 180*fe6060f1SDimitry Andrictemplate<class _Tp, class _Up> 181*fe6060f1SDimitry Andricconcept common_with = 182*fe6060f1SDimitry Andric same_as<common_type_t<_Tp, _Up>, common_type_t<_Up, _Tp>> && 183*fe6060f1SDimitry Andric requires { 184*fe6060f1SDimitry Andric static_cast<common_type_t<_Tp, _Up>>(declval<_Tp>()); 185*fe6060f1SDimitry Andric static_cast<common_type_t<_Tp, _Up>>(declval<_Up>()); 186*fe6060f1SDimitry Andric } && 187*fe6060f1SDimitry Andric common_reference_with< 188*fe6060f1SDimitry Andric add_lvalue_reference_t<const _Tp>, 189*fe6060f1SDimitry Andric add_lvalue_reference_t<const _Up>> && 190*fe6060f1SDimitry Andric common_reference_with< 191*fe6060f1SDimitry Andric add_lvalue_reference_t<common_type_t<_Tp, _Up>>, 192*fe6060f1SDimitry Andric common_reference_t< 193*fe6060f1SDimitry Andric add_lvalue_reference_t<const _Tp>, 194*fe6060f1SDimitry Andric add_lvalue_reference_t<const _Up>>>; 195*fe6060f1SDimitry Andric 196*fe6060f1SDimitry Andric// [concepts.arithmetic], arithmetic concepts 197*fe6060f1SDimitry Andrictemplate<class _Tp> 198*fe6060f1SDimitry Andricconcept integral = is_integral_v<_Tp>; 199*fe6060f1SDimitry Andric 200*fe6060f1SDimitry Andrictemplate<class _Tp> 201*fe6060f1SDimitry Andricconcept signed_integral = integral<_Tp> && is_signed_v<_Tp>; 202*fe6060f1SDimitry Andric 203*fe6060f1SDimitry Andrictemplate<class _Tp> 204*fe6060f1SDimitry Andricconcept unsigned_integral = integral<_Tp> && !signed_integral<_Tp>; 205*fe6060f1SDimitry Andric 206*fe6060f1SDimitry Andrictemplate<class _Tp> 207*fe6060f1SDimitry Andricconcept floating_point = is_floating_point_v<_Tp>; 208*fe6060f1SDimitry Andric 209*fe6060f1SDimitry Andric// [concept.assignable] 210*fe6060f1SDimitry Andrictemplate<class _Lhs, class _Rhs> 211*fe6060f1SDimitry Andricconcept assignable_from = 212*fe6060f1SDimitry Andric is_lvalue_reference_v<_Lhs> && 213*fe6060f1SDimitry Andric common_reference_with<__make_const_lvalue_ref<_Lhs>, __make_const_lvalue_ref<_Rhs>> && 214*fe6060f1SDimitry Andric requires (_Lhs __lhs, _Rhs&& __rhs) { 215*fe6060f1SDimitry Andric { __lhs = _VSTD::forward<_Rhs>(__rhs) } -> same_as<_Lhs>; 216*fe6060f1SDimitry Andric }; 217*fe6060f1SDimitry Andric 218e8d8bef9SDimitry Andric// [concept.destructible] 219e8d8bef9SDimitry Andric 220e8d8bef9SDimitry Andrictemplate<class _Tp> 221*fe6060f1SDimitry Andricconcept destructible = is_nothrow_destructible_v<_Tp>; 222e8d8bef9SDimitry Andric 223*fe6060f1SDimitry Andric// [concept.constructible] 224*fe6060f1SDimitry Andrictemplate<class _Tp, class... _Args> 225*fe6060f1SDimitry Andricconcept constructible_from = 226*fe6060f1SDimitry Andric destructible<_Tp> && is_constructible_v<_Tp, _Args...>; 227*fe6060f1SDimitry Andric 228*fe6060f1SDimitry Andric// [concept.default.init] 229*fe6060f1SDimitry Andric 230*fe6060f1SDimitry Andrictemplate<class _Tp> 231*fe6060f1SDimitry Andricconcept __default_initializable = requires { ::new _Tp; }; 232*fe6060f1SDimitry Andric 233*fe6060f1SDimitry Andrictemplate<class _Tp> 234*fe6060f1SDimitry Andricconcept default_initializable = constructible_from<_Tp> && 235*fe6060f1SDimitry Andric requires { _Tp{}; } && __default_initializable<_Tp>; 236*fe6060f1SDimitry Andric 237*fe6060f1SDimitry Andric// [concept.moveconstructible] 238*fe6060f1SDimitry Andrictemplate<class _Tp> 239*fe6060f1SDimitry Andricconcept move_constructible = 240*fe6060f1SDimitry Andric constructible_from<_Tp, _Tp> && convertible_to<_Tp, _Tp>; 241*fe6060f1SDimitry Andric 242*fe6060f1SDimitry Andric// [concept.copyconstructible] 243*fe6060f1SDimitry Andrictemplate<class _Tp> 244*fe6060f1SDimitry Andricconcept copy_constructible = 245*fe6060f1SDimitry Andric move_constructible<_Tp> && 246*fe6060f1SDimitry Andric constructible_from<_Tp, _Tp&> && convertible_to<_Tp&, _Tp> && 247*fe6060f1SDimitry Andric constructible_from<_Tp, const _Tp&> && convertible_to<const _Tp&, _Tp> && 248*fe6060f1SDimitry Andric constructible_from<_Tp, const _Tp> && convertible_to<const _Tp, _Tp>; 249*fe6060f1SDimitry Andric 250*fe6060f1SDimitry Andric// Whether a type is a class type or enumeration type according to the Core wording. 251*fe6060f1SDimitry Andrictemplate<class _Tp> 252*fe6060f1SDimitry Andricconcept __class_or_enum = is_class_v<_Tp> || is_union_v<_Tp> || is_enum_v<_Tp>; 253*fe6060f1SDimitry Andric 254*fe6060f1SDimitry Andric// [concept.swappable] 255*fe6060f1SDimitry Andricnamespace ranges::__swap { 256*fe6060f1SDimitry Andric // Deleted to inhibit ADL 257*fe6060f1SDimitry Andric template<class _Tp> 258*fe6060f1SDimitry Andric void swap(_Tp&, _Tp&) = delete; 259*fe6060f1SDimitry Andric 260*fe6060f1SDimitry Andric 261*fe6060f1SDimitry Andric // [1] 262*fe6060f1SDimitry Andric template<class _Tp, class _Up> 263*fe6060f1SDimitry Andric concept __unqualified_swappable_with = 264*fe6060f1SDimitry Andric (__class_or_enum<remove_cvref_t<_Tp>> || __class_or_enum<remove_cvref_t<_Up>>) && 265*fe6060f1SDimitry Andric requires(_Tp&& __t, _Up&& __u) { 266*fe6060f1SDimitry Andric swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); 267*fe6060f1SDimitry Andric }; 268*fe6060f1SDimitry Andric 269*fe6060f1SDimitry Andric struct __fn; 270*fe6060f1SDimitry Andric 271*fe6060f1SDimitry Andric template<class _Tp, class _Up, size_t _Size> 272*fe6060f1SDimitry Andric concept __swappable_arrays = 273*fe6060f1SDimitry Andric !__unqualified_swappable_with<_Tp(&)[_Size], _Up(&)[_Size]> && 274*fe6060f1SDimitry Andric extent_v<_Tp> == extent_v<_Up> && 275*fe6060f1SDimitry Andric requires(_Tp(& __t)[_Size], _Up(& __u)[_Size], const __fn& __swap) { 276*fe6060f1SDimitry Andric __swap(__t[0], __u[0]); 277*fe6060f1SDimitry Andric }; 278*fe6060f1SDimitry Andric 279*fe6060f1SDimitry Andric template<class _Tp> 280*fe6060f1SDimitry Andric concept __exchangeable = 281*fe6060f1SDimitry Andric !__unqualified_swappable_with<_Tp&, _Tp&> && 282*fe6060f1SDimitry Andric move_constructible<_Tp> && 283*fe6060f1SDimitry Andric assignable_from<_Tp&, _Tp>; 284*fe6060f1SDimitry Andric 285*fe6060f1SDimitry Andric struct __fn { 286*fe6060f1SDimitry Andric // 2.1 `S` is `(void)swap(E1, E2)`* if `E1` or `E2` has class or enumeration type and... 287*fe6060f1SDimitry Andric // *The name `swap` is used here unqualified. 288*fe6060f1SDimitry Andric template<class _Tp, class _Up> 289*fe6060f1SDimitry Andric requires __unqualified_swappable_with<_Tp, _Up> 290*fe6060f1SDimitry Andric constexpr void operator()(_Tp&& __t, _Up&& __u) const 291*fe6060f1SDimitry Andric noexcept(noexcept(swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) 292*fe6060f1SDimitry Andric { 293*fe6060f1SDimitry Andric swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); 294*fe6060f1SDimitry Andric } 295*fe6060f1SDimitry Andric 296*fe6060f1SDimitry Andric // 2.2 Otherwise, if `E1` and `E2` are lvalues of array types with equal extent and... 297*fe6060f1SDimitry Andric template<class _Tp, class _Up, size_t _Size> 298*fe6060f1SDimitry Andric requires __swappable_arrays<_Tp, _Up, _Size> 299*fe6060f1SDimitry Andric constexpr void operator()(_Tp(& __t)[_Size], _Up(& __u)[_Size]) const 300*fe6060f1SDimitry Andric noexcept(noexcept((*this)(*__t, *__u))) 301*fe6060f1SDimitry Andric { 302*fe6060f1SDimitry Andric // TODO(cjdb): replace with `ranges::swap_ranges`. 303*fe6060f1SDimitry Andric for (size_t __i = 0; __i < _Size; ++__i) { 304*fe6060f1SDimitry Andric (*this)(__t[__i], __u[__i]); 305*fe6060f1SDimitry Andric } 306*fe6060f1SDimitry Andric } 307*fe6060f1SDimitry Andric 308*fe6060f1SDimitry Andric // 2.3 Otherwise, if `E1` and `E2` are lvalues of the same type `T` that models... 309*fe6060f1SDimitry Andric template<__exchangeable _Tp> 310*fe6060f1SDimitry Andric constexpr void operator()(_Tp& __x, _Tp& __y) const 311*fe6060f1SDimitry Andric noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_move_assignable_v<_Tp>) 312*fe6060f1SDimitry Andric { 313*fe6060f1SDimitry Andric __y = _VSTD::exchange(__x, _VSTD::move(__y)); 314*fe6060f1SDimitry Andric } 315*fe6060f1SDimitry Andric }; 316*fe6060f1SDimitry Andric} // namespace ranges::__swap 317*fe6060f1SDimitry Andric 318*fe6060f1SDimitry Andricnamespace ranges::inline __cpo { 319*fe6060f1SDimitry Andric inline constexpr auto swap = __swap::__fn{}; 320*fe6060f1SDimitry Andric} // namespace ranges::__cpo 321*fe6060f1SDimitry Andric 322*fe6060f1SDimitry Andrictemplate<class _Tp> 323*fe6060f1SDimitry Andricconcept swappable = requires(_Tp& __a, _Tp& __b) { ranges::swap(__a, __b); }; 324*fe6060f1SDimitry Andric 325*fe6060f1SDimitry Andrictemplate<class _Tp, class _Up> 326*fe6060f1SDimitry Andricconcept swappable_with = 327*fe6060f1SDimitry Andric common_reference_with<_Tp, _Up> && 328*fe6060f1SDimitry Andric requires(_Tp&& __t, _Up&& __u) { 329*fe6060f1SDimitry Andric ranges::swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Tp>(__t)); 330*fe6060f1SDimitry Andric ranges::swap(_VSTD::forward<_Up>(__u), _VSTD::forward<_Up>(__u)); 331*fe6060f1SDimitry Andric ranges::swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); 332*fe6060f1SDimitry Andric ranges::swap(_VSTD::forward<_Up>(__u), _VSTD::forward<_Tp>(__t)); 333*fe6060f1SDimitry Andric }; 334*fe6060f1SDimitry Andric 335*fe6060f1SDimitry Andric// [concept.booleantestable] 336*fe6060f1SDimitry Andrictemplate<class _Tp> 337*fe6060f1SDimitry Andricconcept __boolean_testable_impl = convertible_to<_Tp, bool>; 338*fe6060f1SDimitry Andric 339*fe6060f1SDimitry Andrictemplate<class _Tp> 340*fe6060f1SDimitry Andricconcept __boolean_testable = __boolean_testable_impl<_Tp> && requires(_Tp&& __t) { 341*fe6060f1SDimitry Andric { !std::forward<_Tp>(__t) } -> __boolean_testable_impl; 342*fe6060f1SDimitry Andric}; 343*fe6060f1SDimitry Andric 344*fe6060f1SDimitry Andric// [concept.equalitycomparable] 345*fe6060f1SDimitry Andrictemplate<class _Tp, class _Up> 346*fe6060f1SDimitry Andricconcept __weakly_equality_comparable_with = 347*fe6060f1SDimitry Andric requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) { 348*fe6060f1SDimitry Andric { __t == __u } -> __boolean_testable; 349*fe6060f1SDimitry Andric { __t != __u } -> __boolean_testable; 350*fe6060f1SDimitry Andric { __u == __t } -> __boolean_testable; 351*fe6060f1SDimitry Andric { __u != __t } -> __boolean_testable; 352*fe6060f1SDimitry Andric }; 353*fe6060f1SDimitry Andric 354*fe6060f1SDimitry Andrictemplate<class _Tp> 355*fe6060f1SDimitry Andricconcept equality_comparable = __weakly_equality_comparable_with<_Tp, _Tp>; 356*fe6060f1SDimitry Andric 357*fe6060f1SDimitry Andrictemplate<class _Tp, class _Up> 358*fe6060f1SDimitry Andricconcept equality_comparable_with = 359*fe6060f1SDimitry Andric equality_comparable<_Tp> && equality_comparable<_Up> && 360*fe6060f1SDimitry Andric common_reference_with<__make_const_lvalue_ref<_Tp>, __make_const_lvalue_ref<_Up>> && 361*fe6060f1SDimitry Andric equality_comparable< 362*fe6060f1SDimitry Andric common_reference_t< 363*fe6060f1SDimitry Andric __make_const_lvalue_ref<_Tp>, 364*fe6060f1SDimitry Andric __make_const_lvalue_ref<_Up>>> && 365*fe6060f1SDimitry Andric __weakly_equality_comparable_with<_Tp, _Up>; 366*fe6060f1SDimitry Andric 367*fe6060f1SDimitry Andric// [concept.totallyordered] 368*fe6060f1SDimitry Andric 369*fe6060f1SDimitry Andrictemplate<class _Tp, class _Up> 370*fe6060f1SDimitry Andricconcept __partially_ordered_with = 371*fe6060f1SDimitry Andric requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) { 372*fe6060f1SDimitry Andric { __t < __u } -> __boolean_testable; 373*fe6060f1SDimitry Andric { __t > __u } -> __boolean_testable; 374*fe6060f1SDimitry Andric { __t <= __u } -> __boolean_testable; 375*fe6060f1SDimitry Andric { __t >= __u } -> __boolean_testable; 376*fe6060f1SDimitry Andric { __u < __t } -> __boolean_testable; 377*fe6060f1SDimitry Andric { __u > __t } -> __boolean_testable; 378*fe6060f1SDimitry Andric { __u <= __t } -> __boolean_testable; 379*fe6060f1SDimitry Andric { __u >= __t } -> __boolean_testable; 380*fe6060f1SDimitry Andric }; 381*fe6060f1SDimitry Andric 382*fe6060f1SDimitry Andrictemplate<class _Tp> 383*fe6060f1SDimitry Andricconcept totally_ordered = equality_comparable<_Tp> && __partially_ordered_with<_Tp, _Tp>; 384*fe6060f1SDimitry Andric 385*fe6060f1SDimitry Andrictemplate<class _Tp, class _Up> 386*fe6060f1SDimitry Andricconcept totally_ordered_with = 387*fe6060f1SDimitry Andric totally_ordered<_Tp> && totally_ordered<_Up> && 388*fe6060f1SDimitry Andric equality_comparable_with<_Tp, _Up> && 389*fe6060f1SDimitry Andric totally_ordered< 390*fe6060f1SDimitry Andric common_reference_t< 391*fe6060f1SDimitry Andric __make_const_lvalue_ref<_Tp>, 392*fe6060f1SDimitry Andric __make_const_lvalue_ref<_Up>>> && 393*fe6060f1SDimitry Andric __partially_ordered_with<_Tp, _Up>; 394*fe6060f1SDimitry Andric 395*fe6060f1SDimitry Andric// [concepts.object] 396*fe6060f1SDimitry Andrictemplate<class _Tp> 397*fe6060f1SDimitry Andricconcept movable = 398*fe6060f1SDimitry Andric is_object_v<_Tp> && 399*fe6060f1SDimitry Andric move_constructible<_Tp> && 400*fe6060f1SDimitry Andric assignable_from<_Tp&, _Tp> && 401*fe6060f1SDimitry Andric swappable<_Tp>; 402*fe6060f1SDimitry Andric 403*fe6060f1SDimitry Andrictemplate<class _Tp> 404*fe6060f1SDimitry Andricconcept copyable = 405*fe6060f1SDimitry Andric copy_constructible<_Tp> && 406*fe6060f1SDimitry Andric movable<_Tp> && 407*fe6060f1SDimitry Andric assignable_from<_Tp&, _Tp&> && 408*fe6060f1SDimitry Andric assignable_from<_Tp&, const _Tp&> && 409*fe6060f1SDimitry Andric assignable_from<_Tp&, const _Tp>; 410*fe6060f1SDimitry Andric 411*fe6060f1SDimitry Andrictemplate<class _Tp> 412*fe6060f1SDimitry Andricconcept semiregular = copyable<_Tp> && default_initializable<_Tp>; 413*fe6060f1SDimitry Andric 414*fe6060f1SDimitry Andrictemplate<class _Tp> 415*fe6060f1SDimitry Andricconcept regular = semiregular<_Tp> && equality_comparable<_Tp>; 416*fe6060f1SDimitry Andric 417*fe6060f1SDimitry Andric// [concept.invocable] 418*fe6060f1SDimitry Andrictemplate<class _Fn, class... _Args> 419*fe6060f1SDimitry Andricconcept invocable = requires(_Fn&& __fn, _Args&&... __args) { 420*fe6060f1SDimitry Andric _VSTD::invoke(_VSTD::forward<_Fn>(__fn), _VSTD::forward<_Args>(__args)...); // not required to be equality preserving 421*fe6060f1SDimitry Andric}; 422*fe6060f1SDimitry Andric 423*fe6060f1SDimitry Andric// [concept.regular.invocable] 424*fe6060f1SDimitry Andrictemplate<class _Fn, class... _Args> 425*fe6060f1SDimitry Andricconcept regular_invocable = invocable<_Fn, _Args...>; 426*fe6060f1SDimitry Andric 427*fe6060f1SDimitry Andric// [concept.predicate] 428*fe6060f1SDimitry Andrictemplate<class _Fn, class... _Args> 429*fe6060f1SDimitry Andricconcept predicate = 430*fe6060f1SDimitry Andric regular_invocable<_Fn, _Args...> && __boolean_testable<invoke_result_t<_Fn, _Args...>>; 431*fe6060f1SDimitry Andric 432*fe6060f1SDimitry Andric// [concept.relation] 433*fe6060f1SDimitry Andrictemplate<class _Rp, class _Tp, class _Up> 434*fe6060f1SDimitry Andricconcept relation = 435*fe6060f1SDimitry Andric predicate<_Rp, _Tp, _Tp> && predicate<_Rp, _Up, _Up> && 436*fe6060f1SDimitry Andric predicate<_Rp, _Tp, _Up> && predicate<_Rp, _Up, _Tp>; 437*fe6060f1SDimitry Andric 438*fe6060f1SDimitry Andric// [concept.equiv] 439*fe6060f1SDimitry Andrictemplate<class _Rp, class _Tp, class _Up> 440*fe6060f1SDimitry Andricconcept equivalence_relation = relation<_Rp, _Tp, _Up>; 441*fe6060f1SDimitry Andric 442*fe6060f1SDimitry Andric// [concept.strictweakorder] 443*fe6060f1SDimitry Andrictemplate<class _Rp, class _Tp, class _Up> 444*fe6060f1SDimitry Andricconcept strict_weak_order = relation<_Rp, _Tp, _Up>; 445*fe6060f1SDimitry Andric 446*fe6060f1SDimitry Andrictemplate<class _Tp, class _Up> 447*fe6060f1SDimitry Andricconcept __different_from = !same_as<remove_cvref_t<_Tp>, remove_cvref_t<_Up>>; 448*fe6060f1SDimitry Andric 449*fe6060f1SDimitry Andric#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS) 4505ffd83dbSDimitry Andric 4515ffd83dbSDimitry Andric_LIBCPP_END_NAMESPACE_STD 4525ffd83dbSDimitry Andric 4535ffd83dbSDimitry Andric_LIBCPP_POP_MACROS 4545ffd83dbSDimitry Andric 4555ffd83dbSDimitry Andric#endif // _LIBCPP_CONCEPTS 456