]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/libcxx/include/__ranges/access.h
Merge llvm-project main llvmorg-14-init-13186-g0c553cc1af2e
[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 <__config>
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>
18 #include <concepts>
19 #include <type_traits>
20
21 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
22 #pragma GCC system_header
23 #endif
24
25 _LIBCPP_BEGIN_NAMESPACE_STD
26
27 #if !defined(_LIBCPP_HAS_NO_RANGES)
28
29 namespace ranges {
30   template <class _Tp>
31   concept __can_borrow =
32     is_lvalue_reference_v<_Tp> || enable_borrowed_range<remove_cvref_t<_Tp>>;
33 } // namespace ranges
34
35 // [range.access.begin]
36
37 namespace ranges {
38 namespace __begin {
39   template <class _Tp>
40   concept __member_begin =
41     __can_borrow<_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       requires is_array_v<remove_cv_t<_Tp>>
61     [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp& __t) const noexcept
62     {
63       return __t;
64     }
65
66     template <class _Tp>
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())))
70     {
71       return _LIBCPP_AUTO_CAST(__t.begin());
72     }
73
74     template <class _Tp>
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))))
78     {
79       return _LIBCPP_AUTO_CAST(begin(__t));
80     }
81
82     void operator()(auto&&) const = delete;
83   };
84 }
85
86 inline namespace __cpo {
87   inline constexpr auto begin = __begin::__fn{};
88 } // namespace __cpo
89 } // namespace ranges
90
91 // [range.range]
92
93 namespace ranges {
94   template <class _Tp>
95   using iterator_t = decltype(ranges::begin(declval<_Tp&>()));
96 } // namespace ranges
97
98 // [range.access.end]
99
100 namespace ranges {
101 namespace __end {
102   template <class _Tp>
103   concept __member_end =
104     __can_borrow<_Tp> &&
105     requires(_Tp&& __t) {
106       typename iterator_t<_Tp>;
107       { _LIBCPP_AUTO_CAST(__t.end()) } -> sentinel_for<iterator_t<_Tp>>;
108     };
109
110   void end(auto&) = delete;
111   void end(const auto&) = delete;
112
113   template <class _Tp>
114   concept __unqualified_end =
115     !__member_end<_Tp> &&
116     __can_borrow<_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>>;
121     };
122
123   class __fn {
124   public:
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.
128     {
129       return __t + _Np;
130     }
131
132     template <class _Tp>
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())))
136     {
137       return _LIBCPP_AUTO_CAST(__t.end());
138     }
139
140     template <class _Tp>
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))))
144     {
145       return _LIBCPP_AUTO_CAST(end(__t));
146     }
147
148     void operator()(auto&&) const = delete;
149   };
150 }
151
152 inline namespace __cpo {
153   inline constexpr auto end = __end::__fn{};
154 } // namespace __cpo
155 } // namespace ranges
156
157 // [range.access.cbegin]
158
159 namespace ranges {
160 namespace __cbegin {
161   struct __fn {
162     template <class _Tp>
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))))
166     {
167       return ranges::begin(_VSTD::as_const(__t));
168     }
169
170     template <class _Tp>
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))))
174     {
175       return ranges::begin(static_cast<_Tp const&&>(__t));
176     }
177   };
178 }
179
180 inline namespace __cpo {
181   inline constexpr auto cbegin = __cbegin::__fn{};
182 } // namespace __cpo
183 } // namespace ranges
184
185 // [range.access.cend]
186
187 namespace ranges {
188 namespace __cend {
189   struct __fn {
190     template <class _Tp>
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))))
194     {
195       return ranges::end(_VSTD::as_const(__t));
196     }
197
198     template <class _Tp>
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))))
202     {
203       return ranges::end(static_cast<_Tp const&&>(__t));
204     }
205   };
206 }
207
208 inline namespace __cpo {
209   inline constexpr auto cend = __cend::__fn{};
210 } // namespace __cpo
211 } // namespace ranges
212
213 #endif // !defined(_LIBCPP_HAS_NO_RANGES)
214
215 _LIBCPP_END_NAMESPACE_STD
216
217 #endif // _LIBCPP___RANGES_ACCESS_H