| 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 | |
| 10 | #ifndef _LIBCPP_RANGES |
| 11 | #define _LIBCPP_RANGES |
| 12 | |
| 13 | /* |
| 14 | |
| 15 | #include <compare> // see [compare.syn] |
| 16 | #include <initializer_list> // see [initializer.list.syn] |
| 17 | #include <iterator> // see [iterator.synopsis] |
| 18 | |
| 19 | namespace std::ranges { |
| 20 | inline namespace unspecified { |
| 21 | // [range.access], range access |
| 22 | inline constexpr unspecified begin = unspecified; |
| 23 | inline constexpr unspecified end = unspecified; |
| 24 | inline constexpr unspecified cbegin = unspecified; |
| 25 | inline constexpr unspecified cend = unspecified; |
| 26 | |
| 27 | inline constexpr unspecified size = unspecified; |
| 28 | inline constexpr unspecified ssize = unspecified; |
| 29 | } |
| 30 | |
| 31 | // [range.range], ranges |
| 32 | template<class T> |
| 33 | concept range = see below; |
| 34 | |
| 35 | template<class T> |
| 36 | inline constexpr bool enable_borrowed_range = false; |
| 37 | |
| 38 | template<class T> |
| 39 | using iterator_t = decltype(ranges::begin(declval<T&>())); |
| 40 | template<range R> |
| 41 | using sentinel_t = decltype(ranges::end(declval<R&>())); |
| 42 | template<range R> |
| 43 | using range_difference_t = iter_difference_t<iterator_t<R>>; |
| 44 | template<sized_range R> |
| 45 | using range_size_t = decltype(ranges::size(declval<R&>())); |
| 46 | template<range R> |
| 47 | using range_value_t = iter_value_t<iterator_t<R>>; |
| 48 | template<range R> |
| 49 | using range_reference_t = iter_reference_t<iterator_t<R>>; |
| 50 | template<range R> |
| 51 | using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<R>>; |
| 52 | template <range R> |
| 53 | using range_common_reference_t = iter_common_reference_t<iterator_t<R>>; |
| 54 | |
| 55 | // [range.sized], sized ranges |
| 56 | template<class> |
| 57 | inline constexpr bool disable_sized_range = false; |
| 58 | |
| 59 | template<class T> |
| 60 | concept sized_range = ...; |
| 61 | |
| 62 | // [range.view], views |
| 63 | template<class T> |
| 64 | inline constexpr bool enable_view = ...; |
| 65 | |
| 66 | struct view_base { }; |
| 67 | |
| 68 | template<class T> |
| 69 | concept view = ...; |
| 70 | |
| 71 | // [range.refinements], other range refinements |
| 72 | template<class R, class T> |
| 73 | concept output_range = see below; |
| 74 | |
| 75 | template<class T> |
| 76 | concept input_range = see below; |
| 77 | |
| 78 | template<class T> |
| 79 | concept forward_range = see below; |
| 80 | |
| 81 | template<class T> |
| 82 | concept bidirectional_range = see below; |
| 83 | |
| 84 | template<class T> |
| 85 | concept random_access_range = see below; |
| 86 | |
| 87 | template<class T> |
| 88 | concept contiguous_range = see below; |
| 89 | |
| 90 | template <class _Tp> |
| 91 | concept common_range = see below; |
| 92 | |
| 93 | template<class T> |
| 94 | concept viewable_range = see below; |
| 95 | |
| 96 | // [range.adaptor.object], range adaptor objects |
| 97 | template<class D> |
| 98 | requires is_class_v<D> && same_as<D, remove_cv_t<D>> |
| 99 | class range_adaptor_closure { }; // Since c++23 |
| 100 | |
| 101 | // [view.interface], class template view_interface |
| 102 | template<class D> |
| 103 | requires is_class_v<D> && same_as<D, remove_cv_t<D>> |
| 104 | class view_interface; |
| 105 | |
| 106 | // [range.subrange], sub-ranges |
| 107 | enum class subrange_kind : bool { unsized, sized }; |
| 108 | |
| 109 | template<input_or_output_iterator I, sentinel_for<I> S = I, subrange_kind K = see below> |
| 110 | requires (K == subrange_kind::sized || !sized_sentinel_for<S, I>) |
| 111 | class subrange; |
| 112 | |
| 113 | template<class I, class S, subrange_kind K> |
| 114 | inline constexpr bool enable_borrowed_range<subrange<I, S, K>> = true; |
| 115 | |
| 116 | // [range.dangling], dangling iterator handling |
| 117 | struct dangling; |
| 118 | |
| 119 | template<range R> |
| 120 | using borrowed_iterator_t = see below; |
| 121 | |
| 122 | template<range R> |
| 123 | using borrowed_subrange_t = see below; |
| 124 | |
| 125 | // [range.elements], elements view |
| 126 | template<input_range V, size_t N> |
| 127 | requires see below |
| 128 | class elements_view; |
| 129 | |
| 130 | template<class T, size_t N> |
| 131 | inline constexpr bool enable_borrowed_range<elements_view<T, N>> = |
| 132 | enable_borrowed_range<T>; |
| 133 | |
| 134 | template<class R> |
| 135 | using keys_view = elements_view<R, 0>; |
| 136 | template<class R> |
| 137 | using values_view = elements_view<R, 1>; |
| 138 | |
| 139 | namespace views { |
| 140 | template<size_t N> |
| 141 | inline constexpr unspecified elements = unspecified; |
| 142 | inline constexpr auto keys = elements<0>; |
| 143 | inline constexpr auto values = elements<1>; |
| 144 | } |
| 145 | |
| 146 | // [range.utility.conv], range conversions |
| 147 | template<class C, input_range R, class... Args> requires (!view<C>) |
| 148 | constexpr C to(R&& r, Args&&... args); // Since C++23 |
| 149 | template<template<class...> class C, input_range R, class... Args> |
| 150 | constexpr auto to(R&& r, Args&&... args); // Since C++23 |
| 151 | template<class C, class... Args> requires (!view<C>) |
| 152 | constexpr auto to(Args&&... args); // Since C++23 |
| 153 | template<template<class...> class C, class... Args> |
| 154 | constexpr auto to(Args&&... args); // Since C++23 |
| 155 | |
| 156 | // [range.empty], empty view |
| 157 | template<class T> |
| 158 | requires is_object_v<T> |
| 159 | class empty_view; |
| 160 | |
| 161 | template<class T> |
| 162 | inline constexpr bool enable_borrowed_range<empty_view<T>> = true; |
| 163 | |
| 164 | namespace views { |
| 165 | template<class T> |
| 166 | inline constexpr empty_view<T> empty{}; |
| 167 | } |
| 168 | |
| 169 | // [range.all], all view |
| 170 | namespace views { |
| 171 | inline constexpr unspecified all = unspecified; |
| 172 | |
| 173 | template<viewable_range R> |
| 174 | using all_t = decltype(all(declval<R>())); |
| 175 | } |
| 176 | |
| 177 | template<range R> |
| 178 | requires is_object_v<R> |
| 179 | class ref_view; |
| 180 | |
| 181 | template<class T> |
| 182 | inline constexpr bool enable_borrowed_range<ref_view<T>> = true; |
| 183 | |
| 184 | template<range R> |
| 185 | requires see below |
| 186 | class owning_view; |
| 187 | |
| 188 | template<class T> |
| 189 | inline constexpr bool enable_borrowed_range<owning_view<T>> = enable_borrowed_range<T>; |
| 190 | |
| 191 | // [range.filter], filter view |
| 192 | template<input_range V, indirect_unary_predicate<iterator_t<V>> Pred> |
| 193 | requires view<V> && is_object_v<Pred> |
| 194 | class filter_view; |
| 195 | |
| 196 | namespace views { |
| 197 | inline constexpr unspecified filter = unspecified; |
| 198 | } |
| 199 | |
| 200 | // [range.drop], drop view |
| 201 | template<view V> |
| 202 | class drop_view; |
| 203 | |
| 204 | template<class T> |
| 205 | inline constexpr bool enable_borrowed_range<drop_view<T>> = enable_borrowed_range<T>; |
| 206 | |
| 207 | // [range.drop.while], drop while view |
| 208 | template<view V, class Pred> |
| 209 | requires input_range<V> && is_object_v<Pred> && |
| 210 | indirect_unary_predicate<const Pred, iterator_t<V>> |
| 211 | class drop_while_view; |
| 212 | |
| 213 | template<class T, class Pred> |
| 214 | inline constexpr bool enable_borrowed_range<drop_while_view<T, Pred>> = |
| 215 | enable_borrowed_range<T>; |
| 216 | |
| 217 | namespace views { inline constexpr unspecified drop_while = unspecified; } |
| 218 | |
| 219 | // [range.transform], transform view |
| 220 | template<input_range V, copy_constructible F> |
| 221 | requires view<V> && is_object_v<F> && |
| 222 | regular_invocable<F&, range_reference_t<V>> && |
| 223 | can-reference<invoke_result_t<F&, range_reference_t<V>>> |
| 224 | class transform_view; |
| 225 | |
| 226 | // [range.counted], counted view |
| 227 | namespace views { inline constexpr unspecified counted = unspecified; } |
| 228 | |
| 229 | // [range.common], common view |
| 230 | template<view V> |
| 231 | requires (!common_range<V> && copyable<iterator_t<V>>) |
| 232 | class common_view; |
| 233 | |
| 234 | // [range.reverse], reverse view |
| 235 | template<view V> |
| 236 | requires bidirectional_range<V> |
| 237 | class reverse_view; |
| 238 | |
| 239 | template<class T> |
| 240 | inline constexpr bool enable_borrowed_range<reverse_view<T>> = enable_borrowed_range<T>; |
| 241 | |
| 242 | template<class T> |
| 243 | inline constexpr bool enable_borrowed_range<common_view<T>> = enable_borrowed_range<T>; |
| 244 | |
| 245 | // [range.take], take view |
| 246 | template<view> class take_view; |
| 247 | |
| 248 | template<class T> |
| 249 | inline constexpr bool enable_borrowed_range<take_view<T>> = enable_borrowed_range<T>; |
| 250 | |
| 251 | // [range.take.while], take while view |
| 252 | template<view V, class Pred> |
| 253 | requires input_range<V> && is_object_v<Pred> && |
| 254 | indirect_unary_predicate<const Pred, iterator_t<V>> |
| 255 | class take_while_view; |
| 256 | |
| 257 | namespace views { inline constexpr unspecified take_while = unspecified; } |
| 258 | |
| 259 | template<copy_constructible T> |
| 260 | requires is_object_v<T> |
| 261 | class single_view; |
| 262 | |
| 263 | template<weakly_incrementable W, semiregular Bound = unreachable_sentinel_t> |
| 264 | requires weakly-equality-comparable-with<W, Bound> && copyable<W> |
| 265 | class iota_view; |
| 266 | |
| 267 | template<class W, class Bound> |
| 268 | inline constexpr bool enable_borrowed_range<iota_view<W, Bound>> = true; |
| 269 | |
| 270 | // [range.repeat], repeat view |
| 271 | template<class T> |
| 272 | concept integer-like-with-usable-difference-type = // exposition only |
| 273 | is-signed-integer-like<T> || (is-integer-like<T> && weakly_incrementable<T>); |
| 274 | |
| 275 | template<move_constructible T, semiregular Bound = unreachable_sentinel_t> |
| 276 | requires (is_object_v<T> && same_as<T, remove_cv_t<T>> && |
| 277 | (integer-like-with-usable-difference-type<Bound> || |
| 278 | same_as<Bound, unreachable_sentinel_t>)) |
| 279 | class repeat_view; |
| 280 | |
| 281 | namespace views { inline constexpr unspecified repeat = unspecified; } |
| 282 | |
| 283 | // [range.join], join view |
| 284 | template<input_range V> |
| 285 | requires view<V> && input_range<range_reference_t<V>> |
| 286 | class join_view; |
| 287 | |
| 288 | // [range.join.with], join with view |
| 289 | template<input_range V, forward_range Pattern> |
| 290 | requires view<V> && input_range<range_reference_t<V>> |
| 291 | && view<Pattern> |
| 292 | && concatable<range_reference_t<V>, Pattern> |
| 293 | class join_with_view; // since C++23 |
| 294 | |
| 295 | namespace views { inline constexpr unspecified join_with = unspecified; } // since C++23 |
| 296 | |
| 297 | // [range.lazy.split], lazy split view |
| 298 | template<class R> |
| 299 | concept tiny-range = see below; // exposition only |
| 300 | |
| 301 | template<input_range V, forward_range Pattern> |
| 302 | requires view<V> && view<Pattern> && |
| 303 | indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to> && |
| 304 | (forward_range<V> || tiny-range<Pattern>) |
| 305 | class lazy_split_view; |
| 306 | |
| 307 | // [range.split], split view |
| 308 | template<forward_range V, forward_range Pattern> |
| 309 | requires view<V> && view<Pattern> && |
| 310 | indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to> |
| 311 | class split_view; |
| 312 | |
| 313 | namespace views { |
| 314 | inline constexpr unspecified lazy_split = unspecified; |
| 315 | inline constexpr unspecified split = unspecified; |
| 316 | } |
| 317 | |
| 318 | // [range.istream], istream view |
| 319 | template<movable Val, class CharT, class Traits = char_traits<CharT>> |
| 320 | requires see below |
| 321 | class basic_istream_view; |
| 322 | |
| 323 | template<class Val> |
| 324 | using istream_view = basic_istream_view<Val, char>; |
| 325 | |
| 326 | template<class Val> |
| 327 | using wistream_view = basic_istream_view<Val, wchar_t>; |
| 328 | |
| 329 | namespace views { template<class T> inline constexpr unspecified istream = unspecified; } |
| 330 | |
| 331 | // [range.zip], zip view |
| 332 | template<input_range... Views> |
| 333 | requires (view<Views> && ...) && (sizeof...(Views) > 0) |
| 334 | class zip_view; // C++23 |
| 335 | |
| 336 | template<class... Views> |
| 337 | inline constexpr bool enable_borrowed_range<zip_view<Views...>> = // C++23 |
| 338 | (enable_borrowed_range<Views> && ...); |
| 339 | |
| 340 | namespace views { inline constexpr unspecified zip = unspecified; } // C++23 |
| 341 | |
| 342 | // [range.as.rvalue] |
| 343 | template <view V> |
| 344 | requires input_range<V> |
| 345 | class as_rvalue_view; // C++23 |
| 346 | |
| 347 | namespace views { inline constexpr unspecified as_rvalue ) unspecified; } // C++23 |
| 348 | |
| 349 | [range.chunk.by] |
| 350 | template<forward_range V, indirect_binary_predicate<iterator_t<V>, iterator_t<V>> Pred> |
| 351 | requires view<V> && is_object_v<Pred> |
| 352 | class chunk_by_view; // C++23 |
| 353 | |
| 354 | namespace views { inline constexpr unspecified chunk_by = unspecified; } // C++23 |
| 355 | } |
| 356 | |
| 357 | namespace std { |
| 358 | namespace views = ranges::views; |
| 359 | |
| 360 | template<class T> struct tuple_size; |
| 361 | template<size_t I, class T> struct tuple_element; |
| 362 | |
| 363 | template<class I, class S, ranges::subrange_kind K> |
| 364 | struct tuple_size<ranges::subrange<I, S, K>> |
| 365 | : integral_constant<size_t, 2> {}; |
| 366 | |
| 367 | template<class I, class S, ranges::subrange_kind K> |
| 368 | struct tuple_element<0, ranges::subrange<I, S, K>> { |
| 369 | using type = I; |
| 370 | }; |
| 371 | |
| 372 | template<class I, class S, ranges::subrange_kind K> |
| 373 | struct tuple_element<1, ranges::subrange<I, S, K>> { |
| 374 | using type = S; |
| 375 | }; |
| 376 | |
| 377 | template<class I, class S, ranges::subrange_kind K> |
| 378 | struct tuple_element<0, const ranges::subrange<I, S, K>> { |
| 379 | using type = I; |
| 380 | }; |
| 381 | |
| 382 | template<class I, class S, ranges::subrange_kind K> |
| 383 | struct tuple_element<1, const ranges::subrange<I, S, K>> { |
| 384 | using type = S; |
| 385 | }; |
| 386 | |
| 387 | struct from_range_t { explicit from_range_t() = default; }; // Since C++23 |
| 388 | inline constexpr from_range_t from_range{}; // Since C++23 |
| 389 | } |
| 390 | */ |
| 391 | |
| 392 | #if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS) |
| 393 | # include <__cxx03/__config> |
| 394 | #else |
| 395 | # include <__config> |
| 396 | |
| 397 | # if _LIBCPP_STD_VER >= 20 |
| 398 | # include <__ranges/access.h> |
| 399 | # include <__ranges/all.h> |
| 400 | # include <__ranges/common_view.h> |
| 401 | # include <__ranges/concepts.h> |
| 402 | # include <__ranges/counted.h> |
| 403 | # include <__ranges/dangling.h> |
| 404 | # include <__ranges/data.h> |
| 405 | # include <__ranges/drop_view.h> |
| 406 | # include <__ranges/drop_while_view.h> |
| 407 | # include <__ranges/elements_view.h> |
| 408 | # include <__ranges/empty.h> |
| 409 | # include <__ranges/empty_view.h> |
| 410 | # include <__ranges/enable_borrowed_range.h> |
| 411 | # include <__ranges/enable_view.h> |
| 412 | # include <__ranges/filter_view.h> |
| 413 | # include <__ranges/iota_view.h> |
| 414 | # include <__ranges/join_view.h> |
| 415 | # include <__ranges/lazy_split_view.h> |
| 416 | # include <__ranges/rbegin.h> |
| 417 | # include <__ranges/ref_view.h> |
| 418 | # include <__ranges/rend.h> |
| 419 | # include <__ranges/reverse_view.h> |
| 420 | # include <__ranges/single_view.h> |
| 421 | # include <__ranges/size.h> |
| 422 | # include <__ranges/split_view.h> |
| 423 | # include <__ranges/subrange.h> |
| 424 | # include <__ranges/take_view.h> |
| 425 | # include <__ranges/take_while_view.h> |
| 426 | # include <__ranges/transform_view.h> |
| 427 | # include <__ranges/view_interface.h> |
| 428 | # include <__ranges/views.h> |
| 429 | |
| 430 | # if _LIBCPP_HAS_LOCALIZATION |
| 431 | # include <__ranges/istream_view.h> |
| 432 | # endif |
| 433 | # endif |
| 434 | |
| 435 | # if _LIBCPP_STD_VER >= 23 |
| 436 | # include <__ranges/as_rvalue_view.h> |
| 437 | # include <__ranges/chunk_by_view.h> |
| 438 | # include <__ranges/from_range.h> |
| 439 | # include <__ranges/join_with_view.h> |
| 440 | # include <__ranges/repeat_view.h> |
| 441 | # include <__ranges/to.h> |
| 442 | # include <__ranges/zip_view.h> |
| 443 | # endif |
| 444 | |
| 445 | # include <version> |
| 446 | |
| 447 | // standard-mandated includes |
| 448 | |
| 449 | // [ranges.syn] |
| 450 | # include <compare> |
| 451 | # include <initializer_list> |
| 452 | # include <iterator> |
| 453 | |
| 454 | // [tuple.helper] |
| 455 | # include <__tuple/tuple_element.h> |
| 456 | # include <__tuple/tuple_size.h> |
| 457 | |
| 458 | # if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 459 | # pragma GCC system_header |
| 460 | # endif |
| 461 | |
| 462 | # if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 463 | # include <cstdlib> |
| 464 | # include <iosfwd> |
| 465 | # include <type_traits> |
| 466 | # endif |
| 467 | #endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS) |
| 468 | |
| 469 | #endif // _LIBCPP_RANGES |
| 470 | |