// 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
{
{ 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
{
&& 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>;
};
&& 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&>;
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; };
{
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;
// 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>&&,
&& 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);
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>
// [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>>
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>>
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>>
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>>
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>>
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>>;
/// [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>>;
};
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;
}
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
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>)
{
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);
/// [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);
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 = {})
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 = {})
{
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,
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,
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,
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,
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 = {})
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 = {})
}
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)
{
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)
{
}
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 = {})
{