File indexing completed on 2026-05-03 08:14:02
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef _LIBCPP___RANGES_REND_H
0011 #define _LIBCPP___RANGES_REND_H
0012
0013 #include <__concepts/class_or_enum.h>
0014 #include <__concepts/same_as.h>
0015 #include <__config>
0016 #include <__iterator/concepts.h>
0017 #include <__iterator/readable_traits.h>
0018 #include <__iterator/reverse_iterator.h>
0019 #include <__ranges/access.h>
0020 #include <__ranges/rbegin.h>
0021 #include <__type_traits/decay.h>
0022 #include <__type_traits/is_reference.h>
0023 #include <__type_traits/remove_cvref.h>
0024 #include <__type_traits/remove_reference.h>
0025 #include <__utility/auto_cast.h>
0026
0027 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0028 # pragma GCC system_header
0029 #endif
0030
0031 _LIBCPP_BEGIN_NAMESPACE_STD
0032
0033 #if _LIBCPP_STD_VER >= 20
0034
0035
0036
0037 namespace ranges {
0038 namespace __rend {
0039 template <class _Tp>
0040 concept __member_rend = __can_borrow<_Tp> && requires(_Tp&& __t) {
0041 ranges::rbegin(__t);
0042 { _LIBCPP_AUTO_CAST(__t.rend()) } -> sentinel_for<decltype(ranges::rbegin(__t))>;
0043 };
0044
0045 void rend() = delete;
0046
0047 template <class _Tp>
0048 concept __unqualified_rend =
0049 !__member_rend<_Tp> && __can_borrow<_Tp> && __class_or_enum<remove_cvref_t<_Tp>> && requires(_Tp&& __t) {
0050 ranges::rbegin(__t);
0051 { _LIBCPP_AUTO_CAST(rend(__t)) } -> sentinel_for<decltype(ranges::rbegin(__t))>;
0052 };
0053
0054 template <class _Tp>
0055 concept __can_reverse = __can_borrow<_Tp> && !__member_rend<_Tp> && !__unqualified_rend<_Tp> && requires(_Tp&& __t) {
0056 { ranges::begin(__t) } -> same_as<decltype(ranges::end(__t))>;
0057 { ranges::begin(__t) } -> bidirectional_iterator;
0058 };
0059
0060 class __fn {
0061 public:
0062 template <class _Tp>
0063 requires __member_rend<_Tp>
0064 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
0065 noexcept(noexcept(_LIBCPP_AUTO_CAST(__t.rend()))) {
0066 return _LIBCPP_AUTO_CAST(__t.rend());
0067 }
0068
0069 template <class _Tp>
0070 requires __unqualified_rend<_Tp>
0071 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
0072 noexcept(noexcept(_LIBCPP_AUTO_CAST(rend(__t)))) {
0073 return _LIBCPP_AUTO_CAST(rend(__t));
0074 }
0075
0076 template <class _Tp>
0077 requires __can_reverse<_Tp>
0078 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
0079 noexcept(noexcept(ranges::begin(__t))) {
0080 return std::make_reverse_iterator(ranges::begin(__t));
0081 }
0082
0083 void operator()(auto&&) const = delete;
0084 };
0085 }
0086
0087 inline namespace __cpo {
0088 inline constexpr auto rend = __rend::__fn{};
0089 }
0090 }
0091
0092
0093
0094 namespace ranges {
0095 namespace __crend {
0096 struct __fn {
0097 template <class _Tp>
0098 requires is_lvalue_reference_v<_Tp&&>
0099 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
0100 noexcept(noexcept(ranges::rend(static_cast<const remove_reference_t<_Tp>&>(__t))))
0101 -> decltype(ranges::rend(static_cast<const remove_reference_t<_Tp>&>(__t))) {
0102 return ranges::rend(static_cast<const remove_reference_t<_Tp>&>(__t));
0103 }
0104
0105 template <class _Tp>
0106 requires is_rvalue_reference_v<_Tp&&>
0107 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const noexcept(
0108 noexcept(ranges::rend(static_cast<const _Tp&&>(__t)))) -> decltype(ranges::rend(static_cast<const _Tp&&>(__t))) {
0109 return ranges::rend(static_cast<const _Tp&&>(__t));
0110 }
0111 };
0112 }
0113
0114 inline namespace __cpo {
0115 inline constexpr auto crend = __crend::__fn{};
0116 }
0117 }
0118
0119 #endif
0120
0121 _LIBCPP_END_NAMESPACE_STD
0122
0123 #endif