21 #ifndef __utl_concepts_stl_h__ 22 #define __utl_concepts_stl_h__ 45 using cref_ =
const std::remove_reference_t<T>&;
48 using _ref_t = std::add_lvalue_reference_t<T>;
50 template <
typename _T1,
typename _T2,
typename _Ret =_T1>
61 template <
class T,
class U>
70 template <
class Derived,
class Base>
72 std::is_base_of<Base, Derived>::value &&
73 std::is_convertible<const volatile Derived*, const volatile Base*>::value;
79 template <
class From,
class To>
82 std::is_convertible<From, To>::value &&
83 requires(From (&f)()) {
93 namespace common_impl {
97 template<
class T,
class U>
99 decltype(
false ? std::declval<T(&)()>()() : std::declval<U(&)()>()());
103 static_assert(!std::is_reference<From>::value);
104 template<
class To>
using apply = To;
108 template<
class To>
using apply =
const To;
112 template<
class To>
using apply =
volatile To;
116 template<
class To>
using apply =
const volatile To;
118 template<
class From,
class To>
123 using __cref = std::add_lvalue_reference_t<const std::remove_reference_t<T>>;
126 template<
class T,
class U,
class =
void>
128 static_assert(std::is_reference<T>::value,
"");
129 static_assert(std::is_reference<U>::value,
"");
132 template<
class T,
class U>
136 template<
class T,
class U>
143 template<
class T,
class U,
class R = __common_ref<T&, U&>>
146 template<
class T,
class U>
153 template<
class T,
class U>
162 template<
class T,
class U>
170 template<
class T,
class U>
183 template<
class U>
using apply =
const U;
187 template<
class U>
using apply =
volatile U;
191 template<
class U>
using apply =
const volatile U;
195 template<
class U>
using apply =
196 std::add_lvalue_reference_t<meta::invoke<__xref<T>, U>>;
200 template<
class U>
using apply =
201 std::add_rvalue_reference_t<meta::invoke<__xref<T>, U>>;
206 template<
class>
class,
207 template<
class>
class 211 template<
class T,
class U>
224 template<
class... Ts>
236 template<
class T,
class U,
class...>
238 : std::common_type<T, U> {};
241 template<
class T,
class U>
247 template<
class T,
class U,
class...>
252 template<
class T,
class U>
258 template <
class T,
class U,
class...>
262 template <
class T,
class U>
268 template<
class T,
class U>
272 template<
class T,
class U,
class V,
class... W>
276 common_reference_t<T, U>, V, W...
280 template<
typename...Ts>
283 template<
typename... Ts>
292 template <
class T,
class U>
295 ConvertibleTo<T, common_reference_t<T, U>> &&
296 ConvertibleTo<U, common_reference_t<T, U>>;
300 template <
class T,
class U>
303 Same<std::common_type_t<T, U>, std::common_type_t<U, T>> &&
305 static_cast<std::common_type_t<T, U>
>(std::declval<T>());
306 static_cast<std::common_type_t<T, U>
>(std::declval<U>());
321 Same<std::common_type_t<T, U>, std::common_type_t<U, T>>;
355 template <
typename T>
358 template <
typename T>
365 template<
class LHS,
class RHS>
368 std::is_lvalue_reference<LHS>::value &&
372 requires(LHS lhs, RHS&& rhs) {
373 lhs = std::forward<RHS>(rhs);
375 decltype(lhs = std::forward<RHS>(rhs)), LHS
379 std::is_assignable<LHS, RHS>::value;
385 #if CXX_VER < CXX_VER_STD_17 387 namespace swappable_with_impl {
388 struct is_swappable_with_ {
390 template<
typename _Tp,
393 = decltype(
std::swap(std::declval<_Tp&>(), std::declval<_Up&>())),
395 = decltype(
std::swap(std::declval<_Up&>(), std::declval<_Tp&>()))>
398 template<
typename,
typename>
static meta::false_ check(...);
401 template <
typename _Tp,
typename _Up>
403 : swappable_with_impl::is_swappable_with_ {
404 using type = decltype(check<_Tp, _Up>(0));
412 template<
class T,
class U>
437 template <
class T,
class... Args>
439 Destructible<T> && std::is_constructible<T, Args...>::value;
453 Constructible<T, T> && ConvertibleTo<T, T>;
460 MoveConstructible<T> &&
461 Constructible<T, _ref_t<T>> && ConvertibleTo<_ref_t<T>, T> &&
462 Constructible<T, const _ref_t<T>> && ConvertibleTo<const _ref_t<T>, T> &&
463 Constructible<T, const T> && ConvertibleTo<const T, T>;
470 std::is_object<T>::value &&
471 MoveConstructible<T> &&
472 Assignable<_ref_t<T>, T> &&
481 CopyConstructible<T> &&
492 Movable<remove_cvref_t<B>> &&
493 requires(
const std::remove_reference_t<B>& b1,
494 const std::remove_reference_t<B>& b2,
const bool a) {
495 requires ConvertibleTo<const std::remove_reference_t<B>&,
bool>;
496 !b1; requires ConvertibleTo<decltype(!b1), bool>;
497 b1 && a; requires Same<decltype(b1 && a), bool>;
498 b1 || a; requires Same<decltype(b1 || a), bool>;
499 b1 && b2; requires Same<decltype(b1 && b2), bool>;
500 a && b2; requires Same<decltype(a && b2), bool>;
501 b1 || b2; requires Same<decltype(b1 || b2), bool>;
502 a || b2; requires Same<decltype(a || b2), bool>;
503 b1 == b2; requires ConvertibleTo<decltype(b1 == b2), bool>;
504 b1 == a; requires ConvertibleTo<decltype(b1 == a), bool>;
505 a == b2; requires ConvertibleTo<decltype(a == b2), bool>;
506 b1 != b2; requires ConvertibleTo<decltype(b1 != b2), bool>;
507 b1 != a; requires ConvertibleTo<decltype(b1 != a), bool>;
508 a != b2; requires ConvertibleTo<decltype(a != b2), bool>;
529 template <
typename B,
typename =
void>
534 template <
typename B>
536 meta::use_if_same_t<bool, decltype(!std::declval<cref_<B>>())>,
537 meta::use_if_same_t<bool, decltype(std::declval<cref_<B>>() == std::declval<cref_<B>>())>,
538 meta::use_if_same_t<bool, decltype(std::declval<cref_<B>>() != std::declval<cref_<B>>())>,
539 meta::use_if_same_t<bool, decltype(std::declval<cref_<B>>() && std::declval<cref_<B>>())>,
540 meta::use_if_same_t<bool, decltype(std::declval<cref_<B>>() || std::declval<cref_<B>>())>
545 template <
typename B>
552 Movable<remove_cvref_t<B>> &&
554 ConvertibleTo<const _ref_t<B>,
bool> &&
555 Same<meta::true_, details::is_boolean_t<B>>;
560 template <
typename T,
typename U,
typename =
void>
565 template <
typename T,
typename U>
567 meta::use_if_same_t<bool, decltype(std::declval<cref_<T>>() == std::declval<cref_<U>>())>,
568 meta::use_if_same_t<bool, decltype(std::declval<cref_<T>>() != std::declval<cref_<U>>())>,
569 meta::use_if_same_t<bool, decltype(std::declval<cref_<U>>() == std::declval<cref_<T>>())>,
570 meta::use_if_same_t<bool, decltype(std::declval<cref_<U>>() != std::declval<cref_<T>>())>
575 template <
typename T,
typename U>
581 template <
class T,
class U>
584 requires(
const std::remove_reference_t<T>& t,
585 const std::remove_reference_t<U>& u) {
586 t == u; requires Boolean<decltype(t == u)>;
587 t != u; requires Boolean<decltype(t != u)>;
588 u == t; requires Boolean<decltype(u == t)>;
589 u != t; requires Boolean<decltype(u != t)>;
592 Same<meta::true_, details::is_weakly_equality_comparable_with_t<T, U>>;
598 template <
class T,
class U>
600 EqualityComparable<T> &&
601 EqualityComparable<U> &&
609 WeaklyEqualityComparableWith<T, U>;
616 EqualityComparable<T> &&
617 requires(
const std::remove_reference_t<T>& a,
618 const std::remove_reference_t<T>& b) {
619 a < b; requires Boolean<decltype(a < b)>;
620 a > b; requires Boolean<decltype(a > b)>;
621 a <= b; requires Boolean<decltype(a <= b)>;
622 a >= b; requires Boolean<decltype(a >= b)>;
626 template <
typename T,
typename =
void>
631 template <
typename T>
633 meta::use_if_same_t<bool, decltype(std::declval<cref_<T>>() < std::declval<cref_<T>>())>,
634 meta::use_if_same_t<bool, decltype(std::declval<cref_<T>>() > std::declval<cref_<T>>())>,
635 meta::use_if_same_t<bool, decltype(std::declval<cref_<T>>() <= std::declval<cref_<T>>())>,
636 meta::use_if_same_t<bool, decltype(std::declval<cref_<T>>() >= std::declval<cref_<T>>())>
641 template <
typename T>
648 EqualityComparable<T> &&
649 Same <meta::true_, details::is_strict_totally_ordered_t<T>>;
653 template <
class T,
class U>
655 StrictTotallyOrdered<T> &&
656 StrictTotallyOrdered<U> &&
667 EqualityComparableWith<T, U> &&
668 requires(
const std::remove_reference_t<T>& t,
669 const std::remove_reference_t<U>& u) {
670 t < u; requires Boolean<decltype(t < u)>;
671 t > u; requires Boolean<decltype(t > u)>;
672 t <= u; requires Boolean<decltype(t <= u)>;
673 t >= u; requires Boolean<decltype(t >= u)>;
674 u < t; requires Boolean<decltype(u < t)>;
675 u > t; requires Boolean<decltype(u > t)>;
676 u <= t; requires Boolean<decltype(u <= t)>;
677 u >= t; requires Boolean<decltype(u >= t)>;
681 template <
typename T,
typename U,
typename =
void>
686 template <
typename T,
typename U>
688 meta::use_if_same_t<bool, decltype(std::declval<cref_<T>>() < std::declval<cref_<U>>())>,
689 meta::use_if_same_t<bool, decltype(std::declval<cref_<T>>() > std::declval<cref_<U>>())>,
690 meta::use_if_same_t<bool, decltype(std::declval<cref_<T>>() <= std::declval<cref_<U>>())>,
691 meta::use_if_same_t<bool, decltype(std::declval<cref_<T>>() >= std::declval<cref_<U>>())>,
692 meta::use_if_same_t<bool, decltype(std::declval<cref_<U>>() < std::declval<cref_<T>>())>,
693 meta::use_if_same_t<bool, decltype(std::declval<cref_<U>>() > std::declval<cref_<T>>())>,
694 meta::use_if_same_t<bool, decltype(std::declval<cref_<U>>() <= std::declval<cref_<T>>())>,
695 meta::use_if_same_t<bool, decltype(std::declval<cref_<U>>() >= std::declval<cref_<T>>())>
700 template <
typename T,
typename U>
705 template <
class T,
class U>
707 StrictTotallyOrdered<T> &&
708 StrictTotallyOrdered<U> &&
709 EqualityComparableWith<T, U> &&
710 Same <meta::true_, details::is_strict_totally_ordered_with_t<T, U>>;
730 std::is_scalar<T>::value && Regular<T>;
737 std::is_arithmetic<T>::value && Scalar<T> && StrictTotallyOrdered<T>;
744 std::is_floating_point<T>::value && Arithmetic<T>;
749 template <
class F,
class... Args>
755 template<
class F,
class... Args >
758 template <
class F,
class... Args >
763 template <
class R,
class T,
class U>
765 Predicate<R, T, T> && Predicate<R, U, U> &&
766 Predicate<R, T, U> && Predicate<R, U, T>;
768 template <
class R,
class T,
class U >
std::is_swappable is_swappable
_utlConcept SwappableWith
_utlConcept WeaklyEqualityComparableWith
#define _utlConcept
utl concept keyword syntax wrapper
void void_t
void_t type alias
_utlConcept StrictWeakOrder
_utlConcept FloatingPoint
decltype(false ? std::declval< T(&)()>()() :std::declval< U(&)()>()()) __cond_res
meta::eval< __common_ref_< T, U > > __common_ref
const std::remove_reference_t< T > & cref_
_utlConcept StrictTotallyOrdered
_utlConcept ConvertibleTo
std::add_lvalue_reference_t< const std::remove_reference_t< T > > __cref
_utlConcept CopyAssignable
std::add_rvalue_reference_t< meta::invoke< __xref< T >, U > > apply
meta::eval< meta::enable_if< meta::same_< _T1, _T2 >::value, _Ret > > use_if_same_t
meta::eval< is_strict_totally_ordered_< T > > is_strict_totally_ordered_t
meta::eval< common_reference< Ts... > > common_reference_t
_utlConcept CommonReference
invoke() and invoke traits implementation
_utlConcept EqualityComparableWith
__cond_res< __copy_cv< T, U > &, __copy_cv< U, T > &> __lref_res
std::add_lvalue_reference_t< meta::invoke< __xref< T >, U > > apply
STL's core language concepts.
_utlConcept MoveAssignable
_utlConcept RegularInvocable
_utlConcept DefaultConstructible
_utlConcept CopyConstructible
std::remove_cv_t< std::remove_reference_t< T > > remove_cvref_t
meta::eval< is_boolean_< B > > is_boolean_t
_utlConcept EqualityComparable
_utlConcept StrictTotallyOrderedWith
meta::eval< invoke_result< _Callable, _Args... > > invoke_result_t
invoke_result_t (for C++14)
_utlConcept MoveConstructible
std::add_lvalue_reference_t< T > _ref_t
_utlConcept UnsignedIntegral
std::remove_reference_t< R > && __rref_res
meta::eval< common_reference< Ts... > > common_reference_t
meta::invoke< __copy_cv_< From >, To > __copy_cv
_utlConcept Constructible
meta::eval< is_weakly_equality_comparable_with_< T, U > > is_weakly_equality_comparable_with_t
meta::eval< is_strict_totally_ordered_with_< T, U > > is_strict_totally_ordered_with_t
void swap(array< _Tp, _Nm > &lhs, array< _Tp, _Nm > &rhs) noexcept(noexcept(lhs.swap(rhs)))
meta::eval< basic_common_reference< remove_cvref_t< T >, remove_cvref_t< U >, __xref< T >::template apply, __xref< U >::template apply > > __basic_common_reference_t
_utlConcept SignedIntegral
Implementation detail main forward header.
std::is_invocable trait for C++11
std::is_swappable_with is_swappable_with