]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/libcxx/include/__ranges/access.h
Merge llvm-project main llvmorg-15-init-15358-g53dc0f10787
[FreeBSD/FreeBSD.git] / contrib / llvm-project / libcxx / include / __ranges / access.h
1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
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
7 //
8 //===----------------------------------------------------------------------===//
9 #ifndef _LIBCPP___RANGES_ACCESS_H
10 #define _LIBCPP___RANGES_ACCESS_H
11
12 #include <__concepts/class_or_enum.h>
13 #include <__config>
14 #include <__iterator/concepts.h>
15 #include <__iterator/readable_traits.h>
16 #include <__ranges/enable_borrowed_range.h>
17 #include <__utility/auto_cast.h>
18 #include <type_traits>
19
20 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21 #  pragma GCC system_header
22 #endif
23
24 _LIBCPP_BEGIN_NAMESPACE_STD
25
26 #if _LIBCPP_STD_VER > 17
27
28 namespace ranges {
29   template <class _Tp>
30   concept __can_borrow =
31     is_lvalue_reference_v<_Tp> || enable_borrowed_range<remove_cvref_t<_Tp>>;
32 } // namespace ranges
33
34 // [range.access.begin]
35
36 namespace ranges {
37 namespace __begin {
38   template <class _Tp>
39   concept __member_begin =
40     __can_borrow<_Tp> &&
41     __workaround_52970<_Tp> &&
42     requires(_Tp&& __t) {
43       { _LIBCPP_AUTO_CAST(__t.begin()) } -> input_or_output_iterator;
44     };
45
46   void begin(auto&) = delete;
47   void begin(const auto&) = delete;
48
49   template <class _Tp>
50   concept __unqualified_begin =
51     !__member_begin<_Tp> &&
52     __can_borrow<_Tp> &&
53     __class_or_enum<remove_cvref_t<_Tp>> &&
54     requires(_Tp && __t) {
55       { _LIBCPP_AUTO_CAST(begin(__t)) } -> input_or_output_iterator;
56     };
57
58   struct __fn {
59     template <class _Tp>
60     [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp (&__t)[]) const noexcept
61       requires (sizeof(_Tp) >= 0)  // Disallow incomplete element types.
62     {
63       return __t + 0;
64     }
65
66     template <class _Tp, size_t _Np>
67     [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp (&__t)[_Np]) const noexcept
68       requires (sizeof(_Tp) >= 0)  // Disallow incomplete element types.
69     {
70       return __t + 0;
71     }
72
73     template <class _Tp>
74       requires __member_begin<_Tp>
75     [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
76       noexcept(noexcept(_LIBCPP_AUTO_CAST(__t.begin())))
77     {
78       return _LIBCPP_AUTO_CAST(__t.begin());
79     }
80
81     template <class _Tp>
82       requires __unqualified_begin<_Tp>
83     [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
84       noexcept(noexcept(_LIBCPP_AUTO_CAST(begin(__t))))
85     {
86       return _LIBCPP_AUTO_CAST(begin(__t));
87     }
88
89     void operator()(auto&&) const = delete;
90   };
91 } // namespace __begin
92
93 inline namespace __cpo {
94   inline constexpr auto begin = __begin::__fn{};
95 } // namespace __cpo
96 } // namespace ranges
97
98 // [range.range]
99
100 namespace ranges {
101   template <class _Tp>
102   using iterator_t = decltype(ranges::begin(declval<_Tp&>()));
103 } // namespace ranges
104
105 // [range.access.end]
106
107 namespace ranges {
108 namespace __end {
109   template <class _Tp>
110   concept __member_end =
111     __can_borrow<_Tp> &&
112     __workaround_52970<_Tp> &&
113     requires(_Tp&& __t) {
114       typename iterator_t<_Tp>;
115       { _LIBCPP_AUTO_CAST(__t.end()) } -> sentinel_for<iterator_t<_Tp>>;
116     };
117
118   void end(auto&) = delete;
119   void end(const auto&) = delete;
120
121   template <class _Tp>
122   concept __unqualified_end =
123     !__member_end<_Tp> &&
124     __can_borrow<_Tp> &&
125     __class_or_enum<remove_cvref_t<_Tp>> &&
126     requires(_Tp && __t) {
127       typename iterator_t<_Tp>;
128       { _LIBCPP_AUTO_CAST(end(__t)) } -> sentinel_for<iterator_t<_Tp>>;
129     };
130
131   struct __fn {
132     template <class _Tp, size_t _Np>
133     [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp (&__t)[_Np]) const noexcept
134       requires (sizeof(_Tp) >= 0)  // Disallow incomplete element types.
135     {
136       return __t + _Np;
137     }
138
139     template <class _Tp>
140       requires __member_end<_Tp>
141     [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
142       noexcept(noexcept(_LIBCPP_AUTO_CAST(__t.end())))
143     {
144       return _LIBCPP_AUTO_CAST(__t.end());
145     }
146
147     template <class _Tp>
148       requires __unqualified_end<_Tp>
149     [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
150       noexcept(noexcept(_LIBCPP_AUTO_CAST(end(__t))))
151     {
152       return _LIBCPP_AUTO_CAST(end(__t));
153     }
154
155     void operator()(auto&&) const = delete;
156   };
157 } // namespace __end
158
159 inline namespace __cpo {
160   inline constexpr auto end = __end::__fn{};
161 } // namespace __cpo
162 } // namespace ranges
163
164 // [range.access.cbegin]
165
166 namespace ranges {
167 namespace __cbegin {
168   struct __fn {
169     template <class _Tp>
170       requires is_lvalue_reference_v<_Tp&&>
171     [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
172     constexpr auto operator()(_Tp&& __t) const
173       noexcept(noexcept(ranges::begin(static_cast<const remove_reference_t<_Tp>&>(__t))))
174       -> decltype(      ranges::begin(static_cast<const remove_reference_t<_Tp>&>(__t)))
175       { return          ranges::begin(static_cast<const remove_reference_t<_Tp>&>(__t)); }
176
177     template <class _Tp>
178       requires is_rvalue_reference_v<_Tp&&>
179     [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
180     constexpr auto operator()(_Tp&& __t) const
181       noexcept(noexcept(ranges::begin(static_cast<const _Tp&&>(__t))))
182       -> decltype(      ranges::begin(static_cast<const _Tp&&>(__t)))
183       { return          ranges::begin(static_cast<const _Tp&&>(__t)); }
184   };
185 } // namespace __cbegin
186
187 inline namespace __cpo {
188   inline constexpr auto cbegin = __cbegin::__fn{};
189 } // namespace __cpo
190 } // namespace ranges
191
192 // [range.access.cend]
193
194 namespace ranges {
195 namespace __cend {
196   struct __fn {
197     template <class _Tp>
198       requires is_lvalue_reference_v<_Tp&&>
199     [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
200     constexpr auto operator()(_Tp&& __t) const
201       noexcept(noexcept(ranges::end(static_cast<const remove_reference_t<_Tp>&>(__t))))
202       -> decltype(      ranges::end(static_cast<const remove_reference_t<_Tp>&>(__t)))
203       { return          ranges::end(static_cast<const remove_reference_t<_Tp>&>(__t)); }
204
205     template <class _Tp>
206       requires is_rvalue_reference_v<_Tp&&>
207     [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
208     constexpr auto operator()(_Tp&& __t) const
209       noexcept(noexcept(ranges::end(static_cast<const _Tp&&>(__t))))
210       -> decltype(      ranges::end(static_cast<const _Tp&&>(__t)))
211       { return          ranges::end(static_cast<const _Tp&&>(__t)); }
212   };
213 } // namespace __cend
214
215 inline namespace __cpo {
216   inline constexpr auto cend = __cend::__fn{};
217 } // namespace __cpo
218 } // namespace ranges
219
220 #endif // _LIBCPP_STD_VER > 17
221
222 _LIBCPP_END_NAMESPACE_STD
223
224 #endif // _LIBCPP___RANGES_ACCESS_H