2 //===----------------------------------------------------------------------===//
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 //===----------------------------------------------------------------------===//
9 #ifndef _LIBCPP___RANGES_ACCESS_H
10 #define _LIBCPP___RANGES_ACCESS_H
13 #include <__iterator/concepts.h>
14 #include <__iterator/readable_traits.h>
15 #include <__ranges/enable_borrowed_range.h>
16 #include <__utility/as_const.h>
17 #include <__utility/auto_cast.h>
19 #include <type_traits>
21 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
22 #pragma GCC system_header
25 _LIBCPP_BEGIN_NAMESPACE_STD
27 #if !defined(_LIBCPP_HAS_NO_RANGES)
31 concept __can_borrow =
32 is_lvalue_reference_v<_Tp> || enable_borrowed_range<remove_cvref_t<_Tp>>;
35 // [range.access.begin]
40 concept __member_begin =
43 { _LIBCPP_AUTO_CAST(__t.begin()) } -> input_or_output_iterator;
46 void begin(auto&) = delete;
47 void begin(const auto&) = delete;
50 concept __unqualified_begin =
51 !__member_begin<_Tp> &&
53 __class_or_enum<remove_cvref_t<_Tp>> &&
54 requires(_Tp && __t) {
55 { _LIBCPP_AUTO_CAST(begin(__t)) } -> input_or_output_iterator;
60 requires is_array_v<remove_cv_t<_Tp>>
61 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp& __t) const noexcept
67 requires __member_begin<_Tp>
68 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
69 noexcept(noexcept(_LIBCPP_AUTO_CAST(__t.begin())))
71 return _LIBCPP_AUTO_CAST(__t.begin());
75 requires __unqualified_begin<_Tp>
76 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
77 noexcept(noexcept(_LIBCPP_AUTO_CAST(begin(__t))))
79 return _LIBCPP_AUTO_CAST(begin(__t));
82 void operator()(auto&&) const = delete;
86 inline namespace __cpo {
87 inline constexpr auto begin = __begin::__fn{};
95 using iterator_t = decltype(ranges::begin(declval<_Tp&>()));
103 concept __member_end =
105 requires(_Tp&& __t) {
106 typename iterator_t<_Tp>;
107 { _LIBCPP_AUTO_CAST(__t.end()) } -> sentinel_for<iterator_t<_Tp>>;
110 void end(auto&) = delete;
111 void end(const auto&) = delete;
114 concept __unqualified_end =
115 !__member_end<_Tp> &&
117 __class_or_enum<remove_cvref_t<_Tp>> &&
118 requires(_Tp && __t) {
119 typename iterator_t<_Tp>;
120 { _LIBCPP_AUTO_CAST(end(__t)) } -> sentinel_for<iterator_t<_Tp>>;
125 template <class _Tp, size_t _Np>
126 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp (&__t)[_Np]) const noexcept
127 requires (sizeof(*__t) != 0) // Disallow incomplete element types.
133 requires __member_end<_Tp>
134 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
135 noexcept(noexcept(_LIBCPP_AUTO_CAST(__t.end())))
137 return _LIBCPP_AUTO_CAST(__t.end());
141 requires __unqualified_end<_Tp>
142 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
143 noexcept(noexcept(_LIBCPP_AUTO_CAST(end(__t))))
145 return _LIBCPP_AUTO_CAST(end(__t));
148 void operator()(auto&&) const = delete;
152 inline namespace __cpo {
153 inline constexpr auto end = __end::__fn{};
155 } // namespace ranges
157 // [range.access.cbegin]
163 requires invocable<decltype(ranges::begin), _Tp const&>
164 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp& __t) const
165 noexcept(noexcept(ranges::begin(_VSTD::as_const(__t))))
167 return ranges::begin(_VSTD::as_const(__t));
171 requires is_rvalue_reference_v<_Tp> && invocable<decltype(ranges::begin), _Tp const&&>
172 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
173 noexcept(noexcept(ranges::begin(static_cast<_Tp const&&>(__t))))
175 return ranges::begin(static_cast<_Tp const&&>(__t));
180 inline namespace __cpo {
181 inline constexpr auto cbegin = __cbegin::__fn{};
183 } // namespace ranges
185 // [range.access.cend]
191 requires invocable<decltype(ranges::end), _Tp const&>
192 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp& __t) const
193 noexcept(noexcept(ranges::end(_VSTD::as_const(__t))))
195 return ranges::end(_VSTD::as_const(__t));
199 requires is_rvalue_reference_v<_Tp> && invocable<decltype(ranges::end), _Tp const&&>
200 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
201 noexcept(noexcept(ranges::end(static_cast<_Tp const&&>(__t))))
203 return ranges::end(static_cast<_Tp const&&>(__t));
208 inline namespace __cpo {
209 inline constexpr auto cend = __cend::__fn{};
211 } // namespace ranges
213 #endif // !defined(_LIBCPP_HAS_NO_RANGES)
215 _LIBCPP_END_NAMESPACE_STD
217 #endif // _LIBCPP___RANGES_ACCESS_H