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 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP___CXX03___RANGES_ACCESS_H
11 #define _LIBCPP___CXX03___RANGES_ACCESS_H
13 #include <__cxx03/__concepts/class_or_enum.h>
14 #include <__cxx03/__config>
15 #include <__cxx03/__iterator/concepts.h>
16 #include <__cxx03/__iterator/readable_traits.h>
17 #include <__cxx03/__ranges/enable_borrowed_range.h>
18 #include <__cxx03/__type_traits/decay.h>
19 #include <__cxx03/__type_traits/is_reference.h>
20 #include <__cxx03/__type_traits/remove_cvref.h>
21 #include <__cxx03/__type_traits/remove_reference.h>
22 #include <__cxx03/__utility/auto_cast.h>
23 #include <__cxx03/__utility/declval.h>
24 #include <__cxx03/cstddef>
26 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
27 # pragma GCC system_header
30 _LIBCPP_BEGIN_NAMESPACE_STD
32 #if _LIBCPP_STD_VER >= 20
36 concept __can_borrow
= is_lvalue_reference_v
<_Tp
> || enable_borrowed_range
<remove_cvref_t
<_Tp
>>;
39 // [range.access.begin]
44 concept __member_begin
= __can_borrow
<_Tp
> && requires(_Tp
&& __t
) {
45 { _LIBCPP_AUTO_CAST(__t
.begin()) } -> input_or_output_iterator
;
48 void begin() = delete;
51 concept __unqualified_begin
=
52 !__member_begin
<_Tp
> && __can_borrow
<_Tp
> && __class_or_enum
<remove_cvref_t
<_Tp
>> && requires(_Tp
&& __t
) {
53 { _LIBCPP_AUTO_CAST(begin(__t
)) } -> input_or_output_iterator
;
58 [[nodiscard
]] _LIBCPP_HIDE_FROM_ABI
constexpr auto operator()(_Tp (&__t
)[]) const noexcept
59 requires(sizeof(_Tp
) >= 0) // Disallow incomplete element types.
64 template <class _Tp
, size_t _Np
>
65 [[nodiscard
]] _LIBCPP_HIDE_FROM_ABI
constexpr auto operator()(_Tp (&__t
)[_Np
]) const noexcept
66 requires(sizeof(_Tp
) >= 0) // Disallow incomplete element types.
72 requires __member_begin
<_Tp
>
73 [[nodiscard
]] _LIBCPP_HIDE_FROM_ABI
constexpr auto operator()(_Tp
&& __t
) const
74 noexcept(noexcept(_LIBCPP_AUTO_CAST(__t
.begin()))) {
75 return _LIBCPP_AUTO_CAST(__t
.begin());
79 requires __unqualified_begin
<_Tp
>
80 [[nodiscard
]] _LIBCPP_HIDE_FROM_ABI
constexpr auto operator()(_Tp
&& __t
) const
81 noexcept(noexcept(_LIBCPP_AUTO_CAST(begin(__t
)))) {
82 return _LIBCPP_AUTO_CAST(begin(__t
));
85 void operator()(auto&&) const = delete;
87 } // namespace __begin
89 inline namespace __cpo
{
90 inline constexpr auto begin
= __begin::__fn
{};
98 using iterator_t
= decltype(ranges::begin(std::declval
<_Tp
&>()));
101 // [range.access.end]
106 concept __member_end
= __can_borrow
<_Tp
> && requires(_Tp
&& __t
) {
107 typename iterator_t
<_Tp
>;
108 { _LIBCPP_AUTO_CAST(__t
.end()) } -> sentinel_for
<iterator_t
<_Tp
>>;
114 concept __unqualified_end
=
115 !__member_end
<_Tp
> && __can_borrow
<_Tp
> && __class_or_enum
<remove_cvref_t
<_Tp
>> && requires(_Tp
&& __t
) {
116 typename iterator_t
<_Tp
>;
117 { _LIBCPP_AUTO_CAST(end(__t
)) } -> sentinel_for
<iterator_t
<_Tp
>>;
121 template <class _Tp
, size_t _Np
>
122 [[nodiscard
]] _LIBCPP_HIDE_FROM_ABI
constexpr auto operator()(_Tp (&__t
)[_Np
]) const noexcept
123 requires(sizeof(_Tp
) >= 0) // Disallow incomplete element types.
129 requires __member_end
<_Tp
>
130 [[nodiscard
]] _LIBCPP_HIDE_FROM_ABI
constexpr auto operator()(_Tp
&& __t
) const
131 noexcept(noexcept(_LIBCPP_AUTO_CAST(__t
.end()))) {
132 return _LIBCPP_AUTO_CAST(__t
.end());
136 requires __unqualified_end
<_Tp
>
137 [[nodiscard
]] _LIBCPP_HIDE_FROM_ABI
constexpr auto operator()(_Tp
&& __t
) const
138 noexcept(noexcept(_LIBCPP_AUTO_CAST(end(__t
)))) {
139 return _LIBCPP_AUTO_CAST(end(__t
));
142 void operator()(auto&&) const = delete;
146 inline namespace __cpo
{
147 inline constexpr auto end
= __end::__fn
{};
149 } // namespace ranges
151 // [range.access.cbegin]
157 requires is_lvalue_reference_v
<_Tp
&&>
158 [[nodiscard
]] _LIBCPP_HIDE_FROM_ABI
constexpr auto operator()(_Tp
&& __t
) const
159 noexcept(noexcept(ranges::begin(static_cast<const remove_reference_t
<_Tp
>&>(__t
))))
160 -> decltype(ranges::begin(static_cast<const remove_reference_t
<_Tp
>&>(__t
))) {
161 return ranges::begin(static_cast<const remove_reference_t
<_Tp
>&>(__t
));
165 requires is_rvalue_reference_v
<_Tp
&&>
166 [[nodiscard
]] _LIBCPP_HIDE_FROM_ABI
constexpr auto operator()(_Tp
&& __t
) const
167 noexcept(noexcept(ranges::begin(static_cast<const _Tp
&&>(__t
))))
168 -> decltype(ranges::begin(static_cast<const _Tp
&&>(__t
))) {
169 return ranges::begin(static_cast<const _Tp
&&>(__t
));
172 } // namespace __cbegin
174 inline namespace __cpo
{
175 inline constexpr auto cbegin
= __cbegin::__fn
{};
177 } // namespace ranges
179 // [range.access.cend]
185 requires is_lvalue_reference_v
<_Tp
&&>
186 [[nodiscard
]] _LIBCPP_HIDE_FROM_ABI
constexpr auto operator()(_Tp
&& __t
) const
187 noexcept(noexcept(ranges::end(static_cast<const remove_reference_t
<_Tp
>&>(__t
))))
188 -> decltype(ranges::end(static_cast<const remove_reference_t
<_Tp
>&>(__t
))) {
189 return ranges::end(static_cast<const remove_reference_t
<_Tp
>&>(__t
));
193 requires is_rvalue_reference_v
<_Tp
&&>
194 [[nodiscard
]] _LIBCPP_HIDE_FROM_ABI
constexpr auto operator()(_Tp
&& __t
) const noexcept(
195 noexcept(ranges::end(static_cast<const _Tp
&&>(__t
)))) -> decltype(ranges::end(static_cast<const _Tp
&&>(__t
))) {
196 return ranges::end(static_cast<const _Tp
&&>(__t
));
199 } // namespace __cend
201 inline namespace __cpo
{
202 inline constexpr auto cend
= __cend::__fn
{};
204 } // namespace ranges
206 #endif // _LIBCPP_STD_VER >= 20
208 _LIBCPP_END_NAMESPACE_STD
210 #endif // _LIBCPP___CXX03___RANGES_ACCESS_H