diff --git a/libcxx/include/__iterator/common_iterator.h b/libcxx/include/__iterator/common_iterator.h index 7ec384b2034a0..a59063d245d9c 100644 --- a/libcxx/include/__iterator/common_iterator.h +++ b/libcxx/include/__iterator/common_iterator.h @@ -28,6 +28,7 @@ #include <__memory/addressof.h> #include <__type_traits/conditional.h> #include <__type_traits/is_pointer.h> +#include <__type_traits/is_referenceable.h> #include <__utility/declval.h> #include @@ -157,7 +158,7 @@ class common_iterator { ++*this; return __tmp; } else if constexpr (requires(_Iter& __i) { - { *__i++ } -> __can_reference; + { *__i++ } -> __referenceable; } || !__can_use_postfix_proxy<_Iter>) { return std::__unchecked_get<_Iter>(__hold_)++; } else { diff --git a/libcxx/include/__iterator/concepts.h b/libcxx/include/__iterator/concepts.h index 9e4c456e211b6..ddfc84ed710cb 100644 --- a/libcxx/include/__iterator/concepts.h +++ b/libcxx/include/__iterator/concepts.h @@ -38,6 +38,7 @@ #include <__type_traits/is_pointer.h> #include <__type_traits/is_primary_template.h> #include <__type_traits/is_reference.h> +#include <__type_traits/is_referenceable.h> #include <__type_traits/remove_cv.h> #include <__type_traits/remove_cvref.h> #include <__utility/forward.h> @@ -132,7 +133,7 @@ concept incrementable = regular<_Ip> && weakly_incrementable<_Ip> && requires(_I // [iterator.concept.iterator] template concept input_or_output_iterator = requires(_Ip __i) { - { *__i } -> __can_reference; + { *__i } -> __referenceable; } && weakly_incrementable<_Ip>; // [iterator.concept.sentinel] diff --git a/libcxx/include/__iterator/iter_move.h b/libcxx/include/__iterator/iter_move.h index ba8aed3c0ffbb..5cc16152593c3 100644 --- a/libcxx/include/__iterator/iter_move.h +++ b/libcxx/include/__iterator/iter_move.h @@ -14,6 +14,7 @@ #include <__config> #include <__iterator/iterator_traits.h> #include <__type_traits/is_reference.h> +#include <__type_traits/is_referenceable.h> #include <__type_traits/remove_cvref.h> #include <__utility/declval.h> #include <__utility/forward.h> @@ -90,7 +91,7 @@ inline constexpr auto iter_move = __iter_move::__fn{}; template <__dereferenceable _Tp> requires requires(_Tp& __t) { - { ranges::iter_move(__t) } -> __can_reference; + { ranges::iter_move(__t) } -> __referenceable; } using iter_rvalue_reference_t = decltype(ranges::iter_move(std::declval<_Tp&>())); diff --git a/libcxx/include/__iterator/iterator_traits.h b/libcxx/include/__iterator/iterator_traits.h index 9b524c254b390..931f00ba18e85 100644 --- a/libcxx/include/__iterator/iterator_traits.h +++ b/libcxx/include/__iterator/iterator_traits.h @@ -32,6 +32,7 @@ #include <__type_traits/is_object.h> #include <__type_traits/is_primary_template.h> #include <__type_traits/is_reference.h> +#include <__type_traits/is_referenceable.h> #include <__type_traits/is_valid_expansion.h> #include <__type_traits/nat.h> #include <__type_traits/remove_const.h> @@ -48,15 +49,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 -template -using __with_reference _LIBCPP_NODEBUG = _Tp&; - -template -concept __can_reference = requires { typename __with_reference<_Tp>; }; - template concept __dereferenceable = requires(_Tp& __t) { - { *__t } -> __can_reference; // not required to be equality-preserving + { *__t } -> __referenceable; // not required to be equality-preserving }; // [iterator.traits] @@ -138,9 +133,9 @@ struct __has_iterator_typedefs { namespace __iterator_traits_detail { template concept __cpp17_iterator = requires(_Ip __i) { - { *__i } -> __can_reference; + { *__i } -> __referenceable; { ++__i } -> same_as<_Ip&>; - { *__i++ } -> __can_reference; + { *__i++ } -> __referenceable; } && copyable<_Ip>; template diff --git a/libcxx/include/__ranges/transform_view.h b/libcxx/include/__ranges/transform_view.h index 74a3b4f684fd0..ae85dfa452d72 100644 --- a/libcxx/include/__ranges/transform_view.h +++ b/libcxx/include/__ranges/transform_view.h @@ -38,6 +38,7 @@ #include <__type_traits/is_nothrow_constructible.h> #include <__type_traits/is_object.h> #include <__type_traits/is_reference.h> +#include <__type_traits/is_referenceable.h> #include <__type_traits/maybe_const.h> #include <__type_traits/remove_cvref.h> #include <__utility/forward.h> @@ -63,7 +64,7 @@ concept __regular_invocable_with_range_ref = regular_invocable<_Fn, range_refere template concept __transform_view_constraints = view<_View> && is_object_v<_Fn> && regular_invocable<_Fn&, range_reference_t<_View>> && - __can_reference>>; + __is_referenceable_v>>; # if _LIBCPP_STD_VER >= 23 template diff --git a/libcxx/include/__type_traits/is_referenceable.h b/libcxx/include/__type_traits/is_referenceable.h index 994c36b63d07f..3a9d2858ba4c9 100644 --- a/libcxx/include/__type_traits/is_referenceable.h +++ b/libcxx/include/__type_traits/is_referenceable.h @@ -24,6 +24,11 @@ inline const bool __is_referenceable_v = false; template inline const bool __is_referenceable_v<_Tp, __void_t<_Tp&> > = true; +#if _LIBCPP_STD_VER >= 20 +template +concept __referenceable = __is_referenceable_v<_Tp>; +#endif + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP___TYPE_TRAITS_IS_REFERENCEABLE_H