STL: Remove !_HAS_EXACT_COMPOUND_REQUIREMENT fallback (#301)

Fixes #299.
This commit is contained in:
S. B. Tam 2019-11-16 09:16:01 +08:00 коммит произвёл Stephan T. Lavavej
Родитель 1648f3de58
Коммит 6a96a3b0bc
4 изменённых файлов: 0 добавлений и 126 удалений

Просмотреть файл

@ -100,11 +100,7 @@ template <class _LTy, class _RTy>
concept assignable_from = is_lvalue_reference_v<_LTy>
&& common_reference_with<const remove_reference_t<_LTy>&, const remove_reference_t<_RTy>&>
&& requires(_LTy _Left, _RTy&& _Right) {
#if _HAS_EXACT_COMPOUND_REQUIREMENT
{ _Left = static_cast<_RTy&&>(_Right) } -> same_as<_LTy>;
#else // ^^^ _HAS_EXACT_COMPOUND_REQUIREMENT / !_HAS_EXACT_COMPOUND_REQUIREMENT vvv
_Left = static_cast<_RTy&&>(_Right); requires same_as<_LTy, decltype(_Left = static_cast<_RTy&&>(_Right))>;
#endif // _HAS_EXACT_COMPOUND_REQUIREMENT
};
// swappable and swappable_with are defined below, since they depend on move_constructible.
@ -222,7 +218,6 @@ concept movable = is_object_v<_Ty> && move_constructible<_Ty> && assignable_from
template <class _Ty>
concept _STL_BOOLEAN_CONCEPT = movable<remove_cvref_t<_Ty>>
&& requires(const remove_reference_t<_Ty>& __x, const remove_reference_t<_Ty>& __y, const bool __b) {
#if _HAS_EXACT_COMPOUND_REQUIREMENT
{ __x } -> convertible_to<bool>;
{ !__x } -> convertible_to<bool>;
{ __x && __y } -> same_as<bool>;
@ -237,39 +232,16 @@ concept _STL_BOOLEAN_CONCEPT = movable<remove_cvref_t<_Ty>>
{ __x != __y } -> convertible_to<bool>;
{ __x != __b } -> convertible_to<bool>;
{ __b != __y } -> convertible_to<bool>;
#else // ^^^ _HAS_EXACT_COMPOUND_REQUIREMENT / !_HAS_EXACT_COMPOUND_REQUIREMENT vvv
requires convertible_to<const remove_reference_t<_Ty>&, bool>;
!__x; requires convertible_to<decltype(!__x), bool>;
__x && __y; requires same_as<decltype(__x && __y), bool>;
__x && __b; requires same_as<decltype(__x && __b), bool>;
__b && __y; requires same_as<decltype(__b && __y), bool>;
__x || __y; requires same_as<decltype(__x || __y), bool>;
__x || __b; requires same_as<decltype(__x || __b), bool>;
__b || __y; requires same_as<decltype(__b || __y), bool>;
__x == __y; requires convertible_to<decltype(__x == __y), bool>;
__x == __b; requires convertible_to<decltype(__x == __b), bool>;
__b == __y; requires convertible_to<decltype(__b == __y), bool>;
__x != __y; requires convertible_to<decltype(__x != __y), bool>;
__x != __b; requires convertible_to<decltype(__x != __b), bool>;
__b != __y; requires convertible_to<decltype(__b != __y), bool>;
#endif // _HAS_EXACT_COMPOUND_REQUIREMENT
};
// CONCEPT _Weakly_equality_comparable_with
template <class _Ty1, class _Ty2>
concept _Weakly_equality_comparable_with =
requires(const remove_reference_t<_Ty1>& __t, const remove_reference_t<_Ty2>& __u) {
#if _HAS_EXACT_COMPOUND_REQUIREMENT
{ __t == __u } -> _STL_BOOLEAN_CONCEPT;
{ __t != __u } -> _STL_BOOLEAN_CONCEPT;
{ __u == __t } -> _STL_BOOLEAN_CONCEPT;
{ __u != __t } -> _STL_BOOLEAN_CONCEPT;
#else // ^^^ _HAS_EXACT_COMPOUND_REQUIREMENT / !_HAS_EXACT_COMPOUND_REQUIREMENT vvv
__t == __u; requires _STL_BOOLEAN_CONCEPT<decltype(__t == __u)>;
__t != __u; requires _STL_BOOLEAN_CONCEPT<decltype(__t != __u)>;
__u == __t; requires _STL_BOOLEAN_CONCEPT<decltype(__u == __t)>;
__u != __t; requires _STL_BOOLEAN_CONCEPT<decltype(__u != __t)>;
#endif // _HAS_EXACT_COMPOUND_REQUIREMENT
};
// CONCEPT equality_comparable
@ -287,17 +259,10 @@ concept equality_comparable_with = equality_comparable<_Ty1> && equality_compara
template <class _Ty>
concept totally_ordered = equality_comparable<_Ty>
&& requires(const remove_reference_t<_Ty>& __x, const remove_reference_t<_Ty>& __y) {
#if _HAS_EXACT_COMPOUND_REQUIREMENT
{ __x < __y } -> _STL_BOOLEAN_CONCEPT;
{ __x > __y } -> _STL_BOOLEAN_CONCEPT;
{ __x <= __y } -> _STL_BOOLEAN_CONCEPT;
{ __x >= __y } -> _STL_BOOLEAN_CONCEPT;
#else // ^^^ _HAS_EXACT_COMPOUND_REQUIREMENT / !_HAS_EXACT_COMPOUND_REQUIREMENT vvv
__x < __y; requires _STL_BOOLEAN_CONCEPT<decltype(__x < __y)>;
__x > __y; requires _STL_BOOLEAN_CONCEPT<decltype(__x > __y)>;
__x <= __y; requires _STL_BOOLEAN_CONCEPT<decltype(__x <= __y)>;
__x >= __y; requires _STL_BOOLEAN_CONCEPT<decltype(__x >= __y)>;
#endif // _HAS_EXACT_COMPOUND_REQUIREMENT
};
// CONCEPT totally_ordered_with
@ -307,7 +272,6 @@ concept totally_ordered_with = totally_ordered<_Ty1> && totally_ordered<_Ty2>
&& totally_ordered<common_reference_t<const remove_reference_t<_Ty1>&, const remove_reference_t<_Ty2>&>>
&& equality_comparable_with<_Ty1, _Ty2>
&& requires(const remove_reference_t<_Ty1>& __t, const remove_reference_t<_Ty2>& __u) {
#if _HAS_EXACT_COMPOUND_REQUIREMENT
{ __t < __u } -> _STL_BOOLEAN_CONCEPT;
{ __t > __u } -> _STL_BOOLEAN_CONCEPT;
{ __t <= __u } -> _STL_BOOLEAN_CONCEPT;
@ -316,16 +280,6 @@ concept totally_ordered_with = totally_ordered<_Ty1> && totally_ordered<_Ty2>
{ __u > __t } -> _STL_BOOLEAN_CONCEPT;
{ __u <= __t } -> _STL_BOOLEAN_CONCEPT;
{ __u >= __t } -> _STL_BOOLEAN_CONCEPT;
#else // ^^^ _HAS_EXACT_COMPOUND_REQUIREMENT / !_HAS_EXACT_COMPOUND_REQUIREMENT vvv
__t < __u; requires _STL_BOOLEAN_CONCEPT<decltype(__t < __u)>;
__t > __u; requires _STL_BOOLEAN_CONCEPT<decltype(__t > __u)>;
__t <= __u; requires _STL_BOOLEAN_CONCEPT<decltype(__t <= __u)>;
__t >= __u; requires _STL_BOOLEAN_CONCEPT<decltype(__t >= __u)>;
__u < __t; requires _STL_BOOLEAN_CONCEPT<decltype(__u < __t)>;
__u > __t; requires _STL_BOOLEAN_CONCEPT<decltype(__u > __t)>;
__u <= __t; requires _STL_BOOLEAN_CONCEPT<decltype(__u <= __t)>;
__u >= __t; requires _STL_BOOLEAN_CONCEPT<decltype(__u >= __t)>;
#endif // _HAS_EXACT_COMPOUND_REQUIREMENT
};
// CONCEPT copyable

Просмотреть файл

@ -62,13 +62,8 @@ struct _Require_constant; // not defined; _Require_constant<E> is a valid type i
// clang-format off
template <class _Ty>
concept uniform_random_bit_generator = invocable<_Ty&> && unsigned_integral<invoke_result_t<_Ty&>> && requires {
#if _HAS_EXACT_COMPOUND_REQUIREMENT
{ (_Ty::min)() } -> same_as<invoke_result_t<_Ty&>>;
{ (_Ty::max)() } -> same_as<invoke_result_t<_Ty&>>;
#else // ^^^ _HAS_EXACT_COMPOUND_REQUIREMENT / !_HAS_EXACT_COMPOUND_REQUIREMENT vvv
(_Ty::min)(); requires same_as<decltype((_Ty::min)()), invoke_result_t<_Ty&>>;
(_Ty::max)(); requires same_as<decltype((_Ty::max)()), invoke_result_t<_Ty&>>;
#endif // _HAS_EXACT_COMPOUND_REQUIREMENT
#if 1 // Implement the PR for LWG-3150
typename _Require_constant<(_Ty::min)()>;
typename _Require_constant<(_Ty::max)()>;

Просмотреть файл

@ -217,11 +217,7 @@ concept _Can_reference = requires { typename _With_reference<_Ty>; };
// CONCEPT _Dereferenceable
template <class _Ty>
concept _Dereferenceable = requires(_Ty& __t) {
#if _HAS_EXACT_COMPOUND_REQUIREMENT
{ *__t } -> _Can_reference;
#else // ^^^ _HAS_EXACT_COMPOUND_REQUIREMENT / !_HAS_EXACT_COMPOUND_REQUIREMENT vvv
*__t; requires _Can_reference<decltype(*__t)>;
#endif // _HAS_EXACT_COMPOUND_REQUIREMENT
};
// clang-format on
@ -290,11 +286,7 @@ struct incrementable_traits<_Ty> {
// clang-format off
template <class _Ty>
concept _Can_difference = requires(const _Ty& __a, const _Ty& __b) {
#if _HAS_EXACT_COMPOUND_REQUIREMENT
{ __a - __b } -> integral;
#else // ^^^ _HAS_EXACT_COMPOUND_REQUIREMENT / !_HAS_EXACT_COMPOUND_REQUIREMENT vvv
__a - __b; requires integral<decltype(__a - __b)>;
#endif // _HAS_EXACT_COMPOUND_REQUIREMENT
};
template <class _Ty>
@ -405,15 +397,9 @@ struct _Iter_traits_difference<false> {
// clang-format off
template <class _It>
concept _Cpp17_iterator = copyable<_It> && requires(_It __i) {
#if _HAS_EXACT_COMPOUND_REQUIREMENT
{ *__i } -> _Can_reference;
{ ++__i } -> same_as<_It&>;
{ *__i++ } -> _Can_reference;
#else // ^^^ _HAS_EXACT_COMPOUND_REQUIREMENT / !_HAS_EXACT_COMPOUND_REQUIREMENT vvv
*__i; requires _Can_reference<decltype(*__i)>;
++__i; requires same_as<decltype(++__i), _It&>;
*__i++; requires _Can_reference<decltype(*__i++)>;
#endif // _HAS_EXACT_COMPOUND_REQUIREMENT
};
template <class _It>
@ -491,21 +477,12 @@ struct _Iter_traits_category4<false> {
template <class _It>
concept _Cpp17_random_delta = totally_ordered<_It>
&& requires(_It __i, typename incrementable_traits<_It>::difference_type __n) {
#if _HAS_EXACT_COMPOUND_REQUIREMENT
{ __i += __n } -> same_as<_It&>;
{ __i -= __n } -> same_as<_It&>;
{ __i + __n } -> same_as<_It>;
{ __n + __i } -> same_as<_It>;
{ __i - __n } -> same_as<_It>;
{ __i - __i } -> same_as<decltype(__n)>;
#else // ^^^ _HAS_EXACT_COMPOUND_REQUIREMENT / !_HAS_EXACT_COMPOUND_REQUIREMENT vvv
__i += __n; requires same_as<decltype(__i += __n), _It&>;
__i -= __n; requires same_as<decltype(__i -= __n), _It&>;
__i + __n; requires same_as<decltype(__i + __n), _It>;
__n + __i; requires same_as<decltype(__n + __i), _It>;
__i - __n; requires same_as<decltype(__i - __n), _It>;
__i - __i; requires same_as<decltype(__i - __i), decltype(__n)>;
#endif // _HAS_EXACT_COMPOUND_REQUIREMENT
{ __i[__n] } -> convertible_to<iter_reference_t<_It>>;
};
// clang-format on
@ -525,11 +502,7 @@ struct _Iter_traits_category3<false> {
// clang-format off
template <class _It>
concept _Cpp17_bidi_delta = requires(_It __i) {
#if _HAS_EXACT_COMPOUND_REQUIREMENT
{ --__i } -> same_as<_It&>;
#else // ^^^ _HAS_EXACT_COMPOUND_REQUIREMENT / !_HAS_EXACT_COMPOUND_REQUIREMENT vvv
--__i; requires same_as<decltype(--__i), _It&>;
#endif // _HAS_EXACT_COMPOUND_REQUIREMENT
{ __i-- } -> convertible_to<const _It&>;
requires same_as<decltype(*__i--), iter_reference_t<_It>>;
};
@ -675,11 +648,7 @@ namespace ranges {
// clang-format off
template <class _Ty>
requires _Dereferenceable<_Ty> && requires(_Ty& __t) {
#if _HAS_EXACT_COMPOUND_REQUIREMENT
{ _STD ranges::iter_move(__t) } -> _Can_reference;
#else // ^^^ _HAS_EXACT_COMPOUND_REQUIREMENT / !_HAS_EXACT_COMPOUND_REQUIREMENT vvv
_STD ranges::iter_move(__t); requires _Can_reference<decltype(_STD ranges::iter_move(__t))>;
#endif // _HAS_EXACT_COMPOUND_REQUIREMENT
}
using iter_rvalue_reference_t = decltype(_STD ranges::iter_move(_STD declval<_Ty&>()));
@ -713,32 +682,20 @@ template <class _Ty>
concept weakly_incrementable = default_initializable<_Ty> && movable<_Ty> && requires(_Ty __i) {
typename iter_difference_t<_Ty>;
requires signed_integral<iter_difference_t<_Ty>>;
#if _HAS_EXACT_COMPOUND_REQUIREMENT
{ ++__i } -> same_as<_Ty&>;
#else // ^^^ _HAS_EXACT_COMPOUND_REQUIREMENT / !_HAS_EXACT_COMPOUND_REQUIREMENT vvv
++__i; requires same_as<decltype(++__i), _Ty&>;
#endif // _HAS_EXACT_COMPOUND_REQUIREMENT
__i++;
};
// CONCEPT incrementable
template <class _Ty>
concept incrementable = regular<_Ty> && weakly_incrementable<_Ty> && requires(_Ty __t) {
#if _HAS_EXACT_COMPOUND_REQUIREMENT
{ __t++ } -> same_as<_Ty>;
#else // ^^^ _HAS_EXACT_COMPOUND_REQUIREMENT / !_HAS_EXACT_COMPOUND_REQUIREMENT vvv
__t++; requires same_as<decltype(__t++), _Ty>;
#endif // _HAS_EXACT_COMPOUND_REQUIREMENT
};
// CONCEPT input_or_output_iterator
template <class _It>
concept input_or_output_iterator = requires(_It __i) {
#if _HAS_EXACT_COMPOUND_REQUIREMENT
{ *__i } -> _Can_reference;
#else // ^^^ _HAS_EXACT_COMPOUND_REQUIREMENT / !_HAS_EXACT_COMPOUND_REQUIREMENT vvv
*__i; requires _Can_reference<decltype(*__i)>;
#endif // _HAS_EXACT_COMPOUND_REQUIREMENT
requires weakly_incrementable<_It>;
};
@ -756,13 +713,8 @@ inline constexpr bool disable_sized_sentinel = false;
template <class _Se, class _It>
concept sized_sentinel_for = sentinel_for<_Se, _It> && !disable_sized_sentinel<remove_cv_t<_Se>, remove_cv_t<_It>>
&& requires(const _It& __i, const _Se& __s) {
#if _HAS_EXACT_COMPOUND_REQUIREMENT
{ __s - __i } -> same_as<iter_difference_t<_It>>;
{ __i - __s } -> same_as<iter_difference_t<_It>>;
#else // ^^^ _HAS_EXACT_COMPOUND_REQUIREMENT / !_HAS_EXACT_COMPOUND_REQUIREMENT vvv
__s - __i; requires same_as<decltype(__s - __i), iter_difference_t<_It>>;
__i - __s; requires same_as<decltype(__i - __s), iter_difference_t<_It>>;
#endif // _HAS_EXACT_COMPOUND_REQUIREMENT
};
// clang-format on
@ -827,13 +779,8 @@ concept forward_iterator = input_iterator<_It> && derived_from<_Iter_concept<_It
template <class _It>
concept bidirectional_iterator = forward_iterator<_It> && derived_from<_Iter_concept<_It>, bidirectional_iterator_tag>
&& requires(_It __i) {
#if _HAS_EXACT_COMPOUND_REQUIREMENT
{ --__i } -> same_as<_It&>;
{ __i-- } -> same_as<_It>;
#else // ^^^ _HAS_EXACT_COMPOUND_REQUIREMENT / !_HAS_EXACT_COMPOUND_REQUIREMENT vvv
--__i; requires same_as<decltype(--__i), _It&>;
__i--; requires same_as<decltype(__i--), _It>;
#endif // _HAS_EXACT_COMPOUND_REQUIREMENT
};
// CONCEPT random_access_iterator
@ -841,21 +788,12 @@ template <class _It>
concept random_access_iterator = bidirectional_iterator<_It>
&& derived_from<_Iter_concept<_It>, random_access_iterator_tag> && totally_ordered<_It>
&& sized_sentinel_for<_It, _It> && requires(_It __i, const _It __j, const iter_difference_t<_It> __n) {
#if _HAS_EXACT_COMPOUND_REQUIREMENT
{ __i += __n } -> same_as<_It&>;
{ __j + __n } -> same_as<_It>;
{ __n + __j } -> same_as<_It>;
{ __i -= __n } -> same_as<_It&>;
{ __j - __n } -> same_as<_It>;
{ __j[__n] } -> same_as<iter_reference_t<_It>>;
#else // ^^^ _HAS_EXACT_COMPOUND_REQUIREMENT / !_HAS_EXACT_COMPOUND_REQUIREMENT vvv
__i += __n; requires same_as<decltype(__i += __n), _It&>;
__j + __n; requires same_as<decltype(__j + __n), _It>;
__n + __j; requires same_as<decltype(__n + __j), _It>;
__i -= __n; requires same_as<decltype(__i -= __n), _It&>;
__j - __n; requires same_as<decltype(__j - __n), _It>;
__j[__n]; requires same_as<decltype(__j[__n]), iter_reference_t<_It>>;
#endif // _HAS_EXACT_COMPOUND_REQUIREMENT
};
// CONCEPT contiguous_iterator
@ -865,11 +803,7 @@ concept contiguous_iterator = random_access_iterator<_It>
&& is_lvalue_reference_v<iter_reference_t<_It>>
&& same_as<iter_value_t<_It>, remove_cvref_t<iter_reference_t<_It>>>
&& requires(const _It& __i) {
#if _HAS_EXACT_COMPOUND_REQUIREMENT
{ _STD to_address(__i) } -> same_as<add_pointer_t<iter_reference_t<_It>>>;
#else // ^^^ _HAS_EXACT_COMPOUND_REQUIREMENT / !_HAS_EXACT_COMPOUND_REQUIREMENT vvv
_STD to_address(__i); requires same_as<decltype(_STD to_address(__i)), add_pointer_t<iter_reference_t<_It>>>;
#endif // _HAS_EXACT_COMPOUND_REQUIREMENT
};
// CONCEPT indirectly_movable

Просмотреть файл

@ -953,15 +953,6 @@
#if defined(__cpp_concepts) && __cpp_concepts > 201507L
#define __cpp_lib_concepts 201907L
// "Detect" P1084's exact-type-and-value-category semantics for trailing-return-types in compound requirements
#ifndef _HAS_EXACT_COMPOUND_REQUIREMENT
#if __cpp_concepts >= 201811L
#define _HAS_EXACT_COMPOUND_REQUIREMENT 1
#else // ^^^ post-P1084 concepts / pre-P1084 concepts vvv
#define _HAS_EXACT_COMPOUND_REQUIREMENT 0
#endif // __cpp_concepts >= 201811L
#endif // _HAS_EXACT_COMPOUND_REQUIREMENT
// P0898R3 (as modified by P1754R1) std::boolean
#ifndef _HAS_STD_BOOLEAN
#define _HAS_STD_BOOLEAN 1