* include/bits/iterator_concepts.h (iter_difference_t, iter_value_t): Use remove_cvref_t. (readable_traits): Rename to indirectly_readable_traits. (readable): Rename to indirectly_readable. (writable): Rename to indirectly_writable. (__detail::__iter_exchange_move): Do not use remove_reference_t. (indirectly_swappable): Adjust requires expression parameter types. expression. * include/bits/ranges_algo.h (ranges::transform, ranges::replace) (ranges::replace_if, ranges::generate_n, ranges::generate) (ranges::remove): Use new name for writable. * include/bits/stl_iterator.h (__detail::__common_iter_has_arrow): Use new name for readable. * include/ext/pointer.h (readable_traits<_Pointer_adapter<P>>): Use new name for readable_traits. * testsuite/24_iterators/associated_types/readable.traits.cc: Likewise. * testsuite/24_iterators/indirect_callable/projected.cc: Adjust for new definition of indirectly_readable.
Tested powerpc64le-linux, committed to master. I think this finishes our C++20 Ranges implementation!
commit c8dd2446f597e6d1581414a9c02ff329285181a9 Author: Jonathan Wakely <jwak...@redhat.com> Date: Thu Feb 6 11:21:25 2020 +0000 libstdc++: Implement P1878R1 "Constraining Readable Types" * include/bits/iterator_concepts.h (iter_difference_t, iter_value_t): Use remove_cvref_t. (readable_traits): Rename to indirectly_readable_traits. (readable): Rename to indirectly_readable. (writable): Rename to indirectly_writable. (__detail::__iter_exchange_move): Do not use remove_reference_t. (indirectly_swappable): Adjust requires expression parameter types. expression. * include/bits/ranges_algo.h (ranges::transform, ranges::replace) (ranges::replace_if, ranges::generate_n, ranges::generate) (ranges::remove): Use new name for writable. * include/bits/stl_iterator.h (__detail::__common_iter_has_arrow): Use new name for readable. * include/ext/pointer.h (readable_traits<_Pointer_adapter<P>>): Use new name for readable_traits. * testsuite/24_iterators/associated_types/readable.traits.cc: Likewise. * testsuite/24_iterators/indirect_callable/projected.cc: Adjust for new definition of indirectly_readable. diff --git a/libstdc++-v3/include/bits/iterator_concepts.h b/libstdc++-v3/include/bits/iterator_concepts.h index d9b8958d0a7..04c862a4b97 100644 --- a/libstdc++-v3/include/bits/iterator_concepts.h +++ b/libstdc++-v3/include/bits/iterator_concepts.h @@ -173,11 +173,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // ITER_TRAITS template<typename _Iter, typename _Tp = _Iter> using __iter_traits = typename __iter_traits_impl<_Iter, _Tp>::type; + + template<typename _Tp> + using __iter_diff_t = typename + __iter_traits<_Tp, incrementable_traits<_Tp>>::difference_type; } // namespace __detail template<typename _Tp> - using iter_difference_t = typename - __detail::__iter_traits<_Tp, incrementable_traits<_Tp>>::difference_type; + using iter_difference_t = __detail::__iter_diff_t<remove_cvref_t<_Tp>>; namespace __detail { @@ -188,35 +191,41 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { using value_type = remove_cv_t<_Tp>; }; } // namespace __detail - template<typename> struct readable_traits { }; + template<typename> struct indirectly_readable_traits { }; template<typename _Tp> - struct readable_traits<_Tp*> + struct indirectly_readable_traits<_Tp*> : __detail::__cond_value_type<_Tp> { }; template<typename _Iter> requires is_array_v<_Iter> - struct readable_traits<_Iter> + struct indirectly_readable_traits<_Iter> { using value_type = remove_cv_t<remove_extent_t<_Iter>>; }; template<typename _Iter> - struct readable_traits<const _Iter> - : readable_traits<_Iter> + struct indirectly_readable_traits<const _Iter> + : indirectly_readable_traits<_Iter> { }; template<typename _Tp> requires requires { typename _Tp::value_type; } - struct readable_traits<_Tp> + struct indirectly_readable_traits<_Tp> : __detail::__cond_value_type<typename _Tp::value_type> { }; template<typename _Tp> requires requires { typename _Tp::element_type; } - struct readable_traits<_Tp> + struct indirectly_readable_traits<_Tp> : __detail::__cond_value_type<typename _Tp::element_type> { }; + namespace __detail + { + template<typename _Tp> + using __iter_value_t = typename + __iter_traits<_Tp, indirectly_readable_traits<_Tp>>::value_type; + } // namespace __detail + template<typename _Tp> - using iter_value_t = typename - __detail::__iter_traits<_Tp, readable_traits<_Tp>>::value_type; + using iter_value_t = __detail::__iter_value_t<remove_cvref_t<_Tp>>; namespace __detail { @@ -235,11 +244,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION && requires(_Iter __it) { typename incrementable_traits<_Iter>::difference_type; - typename readable_traits<_Iter>::value_type; + typename indirectly_readable_traits<_Iter>::value_type; typename common_reference_t<iter_reference_t<_Iter>&&, - typename readable_traits<_Iter>::value_type&>; + typename indirectly_readable_traits<_Iter>::value_type&>; typename common_reference_t<decltype(*__it++)&&, - typename readable_traits<_Iter>::value_type&>; + typename indirectly_readable_traits<_Iter>::value_type&>; requires signed_integral<typename incrementable_traits<_Iter>::difference_type>; }; @@ -248,7 +257,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION && constructible_from<_Iter> && is_lvalue_reference_v<iter_reference_t<_Iter>> && same_as<remove_cvref_t<iter_reference_t<_Iter>>, - typename readable_traits<_Iter>::value_type> + typename indirectly_readable_traits<_Iter>::value_type> && requires(_Iter __it) { { __it++ } -> convertible_to<const _Iter&>; @@ -290,6 +299,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Iter> concept __iter_without_nested_types = !__iter_with_nested_types<_Iter>; + // FIXME: These have to be at namespace-scope because of PR 92103. template<typename _Iter, bool __use_arrow = false> struct __ptr { using type = void; }; @@ -376,7 +386,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { using iterator_category = typename __detail::__cat<_Iterator>::type; using value_type - = typename readable_traits<_Iterator>::value_type; + = typename indirectly_readable_traits<_Iterator>::value_type; using difference_type = typename incrementable_traits<_Iterator>::difference_type; using pointer = typename __detail::__ptr<_Iterator, true>::type; @@ -429,15 +439,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // ITER_CONCEPT template<typename _Iter> using __iter_concept = typename __iter_concept_impl<_Iter>::type; - } // namespace __detail - /// Requirements for types that are readable by applying operator*. template<typename _In> - concept readable = requires + concept __indirectly_readable_impl = requires(const _In __in) { typename iter_value_t<_In>; typename iter_reference_t<_In>; typename iter_rvalue_reference_t<_In>; + { *__in } -> same_as<iter_reference_t<_In>>; + { ranges::iter_move(__in) } -> same_as<iter_rvalue_reference_t<_In>>; } && common_reference_with<iter_reference_t<_In>&&, iter_value_t<_In>&> && common_reference_with<iter_reference_t<_In>&&, @@ -445,13 +455,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION && common_reference_with<iter_rvalue_reference_t<_In>&&, const iter_value_t<_In>&>; - template<readable _Tp> + } // namespace __detail + + /// Requirements for types that are readable by applying operator*. + template<typename _In> + concept indirectly_readable + = __detail::__indirectly_readable_impl<remove_cvref_t<_In>>; + + template<indirectly_readable _Tp> using iter_common_reference_t = common_reference_t<iter_reference_t<_Tp>, iter_value_t<_Tp>&>; /// Requirements for writing a value into an iterator's referenced object. template<typename _Out, typename _Tp> - concept writable = requires(_Out&& __o, _Tp&& __t) + concept indirectly_writable = requires(_Out&& __o, _Tp&& __t) { *__o = std::forward<_Tp>(__t); *std::forward<_Out>(__o) = std::forward<_Tp>(__t); @@ -523,13 +540,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Iter> concept input_iterator = input_or_output_iterator<_Iter> - && readable<_Iter> + && indirectly_readable<_Iter> && requires { typename __detail::__iter_concept<_Iter>; } && derived_from<__detail::__iter_concept<_Iter>, input_iterator_tag>; template<typename _Iter, typename _Tp> concept output_iterator = input_or_output_iterator<_Iter> - && writable<_Iter, _Tp> + && indirectly_writable<_Iter, _Tp> && requires(_Iter __i, _Tp&& __t) { *__i++ = std::forward<_Tp>(__t); }; template<typename _Iter> @@ -579,7 +596,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // [indirectcallable.indirectinvocable], indirect callables template<typename _Fn, typename _Iter> - concept indirectly_unary_invocable = readable<_Iter> + concept indirectly_unary_invocable = indirectly_readable<_Iter> && copy_constructible<_Fn> && invocable<_Fn&, iter_value_t<_Iter>&> && invocable<_Fn&, iter_reference_t<_Iter>> && invocable<_Fn&, iter_common_reference_t<_Iter>> @@ -587,7 +604,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION invoke_result_t<_Fn&, iter_reference_t<_Iter>>>; template<typename _Fn, typename _Iter> - concept indirectly_regular_unary_invocable = readable<_Iter> + concept indirectly_regular_unary_invocable = indirectly_readable<_Iter> && copy_constructible<_Fn> && regular_invocable<_Fn&, iter_value_t<_Iter>&> && regular_invocable<_Fn&, iter_reference_t<_Iter>> @@ -596,13 +613,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION invoke_result_t<_Fn&, iter_reference_t<_Iter>>>; template<typename _Fn, typename _Iter> - concept indirect_unary_predicate = readable<_Iter> + concept indirect_unary_predicate = indirectly_readable<_Iter> && copy_constructible<_Fn> && predicate<_Fn&, iter_value_t<_Iter>&> && predicate<_Fn&, iter_reference_t<_Iter>> && predicate<_Fn&, iter_common_reference_t<_Iter>>; template<typename _Fn, typename _I1, typename _I2> - concept indirect_binary_predicate = readable<_I1> && readable<_I2> + concept indirect_binary_predicate + = indirectly_readable<_I1> && indirectly_readable<_I2> && copy_constructible<_Fn> && predicate<_Fn&, iter_value_t<_I1>&, iter_value_t<_I2>&> && predicate<_Fn&, iter_value_t<_I1>&, iter_reference_t<_I2>> @@ -612,7 +630,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION iter_common_reference_t<_I2>>; template<typename _Fn, typename _I1, typename _I2 = _I1> - concept indirect_equivalence_relation = readable<_I1> && readable<_I2> + concept indirect_equivalence_relation + = indirectly_readable<_I1> && indirectly_readable<_I2> && copy_constructible<_Fn> && equivalence_relation<_Fn&, iter_value_t<_I1>&, iter_value_t<_I2>&> && equivalence_relation<_Fn&, iter_value_t<_I1>&, iter_reference_t<_I2>> @@ -623,7 +642,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION iter_common_reference_t<_I2>>; template<typename _Fn, typename _I1, typename _I2 = _I1> - concept indirect_strict_weak_order = readable<_I1> && readable<_I2> + concept indirect_strict_weak_order + = indirectly_readable<_I1> && indirectly_readable<_I2> && copy_constructible<_Fn> && strict_weak_order<_Fn&, iter_value_t<_I1>&, iter_value_t<_I2>&> && strict_weak_order<_Fn&, iter_value_t<_I1>&, iter_reference_t<_I2>> @@ -633,12 +653,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION iter_common_reference_t<_I2>>; template<typename _Fn, typename... _Is> - requires (readable<_Is> && ...) + requires (indirectly_readable<_Is> && ...) && invocable<_Fn, iter_reference_t<_Is>...> using indirect_result_t = invoke_result_t<_Fn, iter_reference_t<_Is>...>; /// [projected], projected - template<readable _Iter, indirectly_regular_unary_invocable<_Iter> _Proj> + template<indirectly_readable _Iter, + indirectly_regular_unary_invocable<_Iter> _Proj> struct projected { using value_type = remove_cvref_t<indirect_result_t<_Proj&, _Iter>>; @@ -655,23 +676,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// [alg.req.ind.move], concept `indirectly_movable` template<typename _In, typename _Out> - concept indirectly_movable = readable<_In> - && writable<_Out, iter_rvalue_reference_t<_In>>; + concept indirectly_movable = indirectly_readable<_In> + && indirectly_writable<_Out, iter_rvalue_reference_t<_In>>; template<typename _In, typename _Out> concept indirectly_movable_storable = indirectly_movable<_In, _Out> - && writable<_Out, iter_value_t<_In>> && movable<iter_value_t<_In>> + && indirectly_writable<_Out, iter_value_t<_In>> + && movable<iter_value_t<_In>> && constructible_from<iter_value_t<_In>, iter_rvalue_reference_t<_In>> && assignable_from<iter_value_t<_In>&, iter_rvalue_reference_t<_In>>; /// [alg.req.ind.copy], concept `indirectly_copyable` template<typename _In, typename _Out> - concept indirectly_copyable = readable<_In> - && writable<_Out, iter_reference_t<_In>>; + concept indirectly_copyable = indirectly_readable<_In> + && indirectly_writable<_Out, iter_reference_t<_In>>; template<typename _In, typename _Out> concept indirectly_copyable_storable = indirectly_copyable<_In, _Out> - && writable<_Out, const iter_value_t<_In>&> + && indirectly_writable<_Out, const iter_value_t<_In>&> && copyable<iter_value_t<_In>> && constructible_from<iter_value_t<_In>, iter_reference_t<_In>> && assignable_from<iter_value_t<_In>&, iter_reference_t<_In>>; @@ -692,12 +714,12 @@ namespace ranges }; template<typename _Xp, typename _Yp> - constexpr iter_value_t<remove_reference_t<_Xp>> + constexpr iter_value_t<_Xp> __iter_exchange_move(_Xp&& __x, _Yp&& __y) - noexcept(noexcept(iter_value_t<remove_reference_t<_Xp>>(iter_move(__x))) + noexcept(noexcept(iter_value_t<_Xp>(iter_move(__x))) && noexcept(*__x = iter_move(__y))) { - iter_value_t<remove_reference_t<_Xp>> __old_value(iter_move(__x)); + iter_value_t<_Xp> __old_value(iter_move(__x)); *__x = iter_move(__y); return __old_value; } @@ -712,8 +734,9 @@ namespace ranges if constexpr (__adl_iswap<_Tp, _Up>) return noexcept(iter_swap(std::declval<_Tp>(), std::declval<_Up>())); - else if constexpr (readable<_Tp> && readable<_Up> - && swappable_with<iter_reference_t<_Tp>, iter_reference_t<_Up>>) + else if constexpr (indirectly_readable<_Tp> + && indirectly_readable<_Up> + && swappable_with<iter_reference_t<_Tp>, iter_reference_t<_Up>>) return noexcept(ranges::swap(*std::declval<_Tp>(), *std::declval<_Up>())); else @@ -725,8 +748,8 @@ namespace ranges public: template<typename _Tp, typename _Up> requires __adl_iswap<_Tp, _Up> - || (readable<remove_reference_t<_Tp>> - && readable<remove_reference_t<_Up>> + || (indirectly_readable<remove_reference_t<_Tp>> + && indirectly_readable<remove_reference_t<_Up>> && swappable_with<iter_reference_t<_Tp>, iter_reference_t<_Up>>) || (indirectly_movable_storable<_Tp, _Up> && indirectly_movable_storable<_Up, _Tp>) @@ -736,8 +759,9 @@ namespace ranges { if constexpr (__adl_iswap<_Tp, _Up>) iter_swap(static_cast<_Tp&&>(__e1), static_cast<_Up&&>(__e2)); - else if constexpr (readable<_Tp> && readable<_Up> - && swappable_with<iter_reference_t<_Tp>, iter_reference_t<_Up>>) + else if constexpr (indirectly_readable<_Tp> + && indirectly_readable<_Up> + && swappable_with<iter_reference_t<_Tp>, iter_reference_t<_Up>>) ranges::swap(*__e1, *__e2); else *__e1 = __iter_exchange_move(__e2, __e1); @@ -754,8 +778,9 @@ namespace ranges /// [alg.req.ind.swap], concept `indirectly_swappable` template<typename _I1, typename _I2 = _I1> - concept indirectly_swappable = readable<_I1> && readable<_I2> - && requires(_I1& __i1, _I2& __i2) + concept indirectly_swappable + = indirectly_readable<_I1> && indirectly_readable<_I2> + && requires(const _I1 __i1, const _I2 __i2) { ranges::iter_swap(__i1, __i1); ranges::iter_swap(__i2, __i2); diff --git a/libstdc++-v3/include/bits/ranges_algo.h b/libstdc++-v3/include/bits/ranges_algo.h index 927c83c55b7..e065ff2a974 100644 --- a/libstdc++-v3/include/bits/ranges_algo.h +++ b/libstdc++-v3/include/bits/ranges_algo.h @@ -1219,7 +1219,9 @@ namespace ranges template<input_iterator _Iter, sentinel_for<_Iter> _Sent, weakly_incrementable _Out, copy_constructible _Fp, typename _Proj = identity> - requires writable<_Out, indirect_result_t<_Fp&, projected<_Iter, _Proj>>> + requires indirectly_writable<_Out, + indirect_result_t<_Fp&, + projected<_Iter, _Proj>>> constexpr unary_transform_result<_Iter, _Out> transform(_Iter __first1, _Sent __last1, _Out __result, _Fp __op, _Proj __proj = {}) @@ -1231,9 +1233,9 @@ namespace ranges template<input_range _Range, weakly_incrementable _Out, copy_constructible _Fp, typename _Proj = identity> - requires writable<_Out, - indirect_result_t<_Fp&, projected<iterator_t<_Range>, - _Proj>>> + requires indirectly_writable<_Out, + indirect_result_t<_Fp&, + projected<iterator_t<_Range>, _Proj>>> constexpr unary_transform_result<safe_iterator_t<_Range>, _Out> transform(_Range&& __r, _Out __result, _Fp __op, _Proj __proj = {}) { @@ -1268,8 +1270,10 @@ namespace ranges input_iterator _Iter2, sentinel_for<_Iter2> _Sent2, weakly_incrementable _Out, copy_constructible _Fp, typename _Proj1 = identity, typename _Proj2 = identity> - requires writable<_Out, indirect_result_t<_Fp&, projected<_Iter1, _Proj1>, - projected<_Iter2, _Proj2>>> + requires indirectly_writable<_Out, + indirect_result_t<_Fp&, + projected<_Iter1, _Proj1>, + projected<_Iter2, _Proj2>>> constexpr binary_transform_result<_Iter1, _Iter2, _Out> transform(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Out __result, _Fp __binary_op, @@ -1286,11 +1290,10 @@ namespace ranges template<input_range _Range1, input_range _Range2, weakly_incrementable _Out, copy_constructible _Fp, typename _Proj1 = identity, typename _Proj2 = identity> - requires writable<_Out, indirect_result_t<_Fp&, - projected<iterator_t<_Range1>, - _Proj1>, - projected<iterator_t<_Range2>, - _Proj2>>> + requires indirectly_writable<_Out, + indirect_result_t<_Fp&, + projected<iterator_t<_Range1>, _Proj1>, + projected<iterator_t<_Range2>, _Proj2>>> constexpr binary_transform_result<safe_iterator_t<_Range1>, safe_iterator_t<_Range2>, _Out> transform(_Range1&& __r1, _Range2&& __r2, _Out __result, @@ -1304,9 +1307,9 @@ namespace ranges template<input_iterator _Iter, sentinel_for<_Iter> _Sent, typename _Tp1, typename _Tp2, typename _Proj = identity> - requires writable<_Iter, const _Tp2&> && - indirect_binary_predicate<ranges::equal_to, - projected<_Iter, _Proj>, const _Tp1*> + requires indirectly_writable<_Iter, const _Tp2&> + && indirect_binary_predicate<ranges::equal_to, projected<_Iter, _Proj>, + const _Tp1*> constexpr _Iter replace(_Iter __first, _Sent __last, const _Tp1& __old_value, const _Tp2& __new_value, @@ -1320,10 +1323,10 @@ namespace ranges template<input_range _Range, typename _Tp1, typename _Tp2, typename _Proj = identity> - requires writable<iterator_t<_Range>, const _Tp2&> && - indirect_binary_predicate<ranges::equal_to, - projected<iterator_t<_Range>, _Proj>, - const _Tp1*> + requires indirectly_writable<iterator_t<_Range>, const _Tp2&> + && indirect_binary_predicate<ranges::equal_to, + projected<iterator_t<_Range>, _Proj>, + const _Tp1*> constexpr safe_iterator_t<_Range> replace(_Range&& __r, const _Tp1& __old_value, const _Tp2& __new_value, @@ -1336,7 +1339,7 @@ namespace ranges template<input_iterator _Iter, sentinel_for<_Iter> _Sent, typename _Tp, typename _Proj = identity, indirect_unary_predicate<projected<_Iter, _Proj>> _Pred> - requires writable<_Iter, const _Tp&> + requires indirectly_writable<_Iter, const _Tp&> constexpr _Iter replace_if(_Iter __first, _Sent __last, _Pred __pred, const _Tp& __new_value, _Proj __proj = {}) @@ -1349,7 +1352,7 @@ namespace ranges template<input_range _Range, typename _Tp, typename _Proj = identity, indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred> - requires writable<iterator_t<_Range>, const _Tp&> + requires indirectly_writable<iterator_t<_Range>, const _Tp&> constexpr safe_iterator_t<_Range> replace_if(_Range&& __r, _Pred __pred, const _Tp& __new_value, _Proj __proj = {}) @@ -1496,7 +1499,8 @@ namespace ranges } template<input_or_output_iterator _Out, copy_constructible _Fp> - requires invocable<_Fp&> && writable<_Out, invoke_result_t<_Fp&>> + requires invocable<_Fp&> + && indirectly_writable<_Out, invoke_result_t<_Fp&>> constexpr _Out generate_n(_Out __first, iter_difference_t<_Out> __n, _Fp __gen) { @@ -1507,7 +1511,8 @@ namespace ranges template<input_or_output_iterator _Out, sentinel_for<_Out> _Sent, copy_constructible _Fp> - requires invocable<_Fp&> && writable<_Out, invoke_result_t<_Fp&>> + requires invocable<_Fp&> + && indirectly_writable<_Out, invoke_result_t<_Fp&>> constexpr _Out generate(_Out __first, _Sent __last, _Fp __gen) { @@ -1573,10 +1578,10 @@ namespace ranges } template<forward_range _Range, typename _Tp, typename _Proj = identity> - requires permutable<iterator_t<_Range>> && - indirect_binary_predicate<ranges::equal_to, - projected<iterator_t<_Range>, _Proj>, - const _Tp*> + requires permutable<iterator_t<_Range>> + && indirect_binary_predicate<ranges::equal_to, + projected<iterator_t<_Range>, _Proj>, + const _Tp*> constexpr safe_subrange_t<_Range> remove(_Range&& __r, const _Tp& __value, _Proj __proj = {}) { diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h index 46804656801..4e70672924b 100644 --- a/libstdc++-v3/include/bits/stl_iterator.h +++ b/libstdc++-v3/include/bits/stl_iterator.h @@ -1417,7 +1417,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION }; template<typename _It> - concept __common_iter_has_arrow = readable<const _It> + concept __common_iter_has_arrow = indirectly_readable<const _It> && (requires(const _It& __it) { __it.operator->(); } || is_reference_v<iter_reference_t<_It>> || constructible_from<iter_value_t<_It>, iter_reference_t<_It>>); diff --git a/libstdc++-v3/include/ext/pointer.h b/libstdc++-v3/include/ext/pointer.h index 02d3e60169f..aef622e2e23 100644 --- a/libstdc++-v3/include/ext/pointer.h +++ b/libstdc++-v3/include/ext/pointer.h @@ -47,7 +47,7 @@ # include <bits/ptr_traits.h> #endif #if __cplusplus > 201703L -# include <iterator> // for readable_traits +# include <iterator> // for indirectly_readable_traits #endif namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) @@ -598,11 +598,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION }; #if __cpp_lib_concepts - template<typename _Storage_policy> - struct readable_traits<__gnu_cxx::_Pointer_adapter<_Storage_policy>> + template<typename _Policy> + struct indirectly_readable_traits<__gnu_cxx::_Pointer_adapter<_Policy>> { using value_type - = typename __gnu_cxx::_Pointer_adapter<_Storage_policy>::value_type; + = typename __gnu_cxx::_Pointer_adapter<_Policy>::value_type; }; #endif _GLIBCXX_END_NAMESPACE_VERSION diff --git a/libstdc++-v3/testsuite/24_iterators/associated_types/readable.traits.cc b/libstdc++-v3/testsuite/24_iterators/associated_types/readable.traits.cc index 724e6eaa02a..b503b0cdc1e 100644 --- a/libstdc++-v3/testsuite/24_iterators/associated_types/readable.traits.cc +++ b/libstdc++-v3/testsuite/24_iterators/associated_types/readable.traits.cc @@ -24,9 +24,9 @@ struct none; template<typename T> concept has_readable_traits_type - = requires { typename std::readable_traits<T>::value_type; }; + = requires { typename std::indirectly_readable_traits<T>::value_type; }; -// Check std::readable_traits<T>::value_type is U (or doesn't exist). +// Check std::indirectly_readable_traits<T>::value_type is U (or doesn't exist). template<typename T, typename U> concept check_readable_traits = (has_readable_traits_type<T> != std::same_as<U, none>); @@ -62,7 +62,7 @@ static_assert( check_readable_traits<const D, none> ); struct E { }; template<> - struct std::readable_traits<E> { using value_type = long; }; + struct std::indirectly_readable_traits<E> { using value_type = long; }; static_assert( check_readable_traits<E, long> ); static_assert( check_readable_traits<const E, long> ); @@ -103,7 +103,7 @@ static_assert( check_alias<F, std::iterator_traits<F>::value_type> ); struct G { }; template<> - struct std::readable_traits<G> { using value_type = G; }; + struct std::indirectly_readable_traits<G> { using value_type = G; }; template<> struct std::iterator_traits<G> { using value_type = int; }; // iterator_traits<G> is specialized, so use its value_type. @@ -111,7 +111,7 @@ static_assert( check_alias<G, std::iterator_traits<G>::value_type> ); struct H { }; template<> - struct std::readable_traits<H> { using value_type = H; }; + struct std::indirectly_readable_traits<H> { using value_type = H; }; template<> struct std::iterator_traits<H> { @@ -128,8 +128,8 @@ struct I using value_type = I; }; // iterator_traits<I> is not specialized, and no standard specialization -// matches, so use readable_traits. -static_assert( check_alias<I, std::readable_traits<I>::value_type> ); +// matches, so use indirectly_readable_traits. +static_assert( check_alias<I, std::indirectly_readable_traits<I>::value_type> ); struct J { diff --git a/libstdc++-v3/testsuite/24_iterators/indirect_callable/projected.cc b/libstdc++-v3/testsuite/24_iterators/indirect_callable/projected.cc index 3f01677856a..f6e4afb7dc9 100644 --- a/libstdc++-v3/testsuite/24_iterators/indirect_callable/projected.cc +++ b/libstdc++-v3/testsuite/24_iterators/indirect_callable/projected.cc @@ -29,9 +29,11 @@ static_assert(std::same_as<decltype(*std::declval<const PI<int*>&>()), int&>); struct X { using value_type = char*; - char* const& operator*() &; + char* const& operator*() const; }; -static_assert( std::readable<X> ); +static_assert( std::indirectly_readable<X> ); +static_assert( std::indirectly_readable<X&> ); +static_assert( std::indirectly_readable<const X> ); static_assert(std::same_as<PI<X>::value_type, char*>); static_assert(std::same_as<decltype(*std::declval<PI<X>&>()), char* const&>);