- tmp/tmpa9j4yfnd/{from.md → to.md} +1911 -318
tmp/tmpa9j4yfnd/{from.md → to.md}
RENAMED
|
@@ -21,552 +21,585 @@ components for range primitives and range generators as summarized in
|
|
| 21 |
|
| 22 |
|
| 23 |
## Header `<ranges>` synopsis <a id="ranges.syn">[[ranges.syn]]</a>
|
| 24 |
|
| 25 |
``` cpp
|
|
|
|
| 26 |
#include <compare> // see [compare.syn]
|
| 27 |
#include <initializer_list> // see [initializer.list.syn]
|
| 28 |
#include <iterator> // see [iterator.synopsis]
|
| 29 |
|
| 30 |
namespace std::ranges {
|
| 31 |
inline namespace unspecified {
|
| 32 |
// [range.access], range access
|
| 33 |
-
inline constexpr unspecified begin = unspecified;
|
| 34 |
-
inline constexpr unspecified end = unspecified;
|
| 35 |
-
inline constexpr unspecified cbegin = unspecified;
|
| 36 |
-
inline constexpr unspecified cend = unspecified;
|
| 37 |
-
inline constexpr unspecified rbegin = unspecified;
|
| 38 |
-
inline constexpr unspecified rend = unspecified;
|
| 39 |
-
inline constexpr unspecified crbegin = unspecified;
|
| 40 |
-
inline constexpr unspecified crend = unspecified;
|
| 41 |
|
| 42 |
-
inline constexpr unspecified size = unspecified;
|
| 43 |
-
inline constexpr unspecified
|
| 44 |
-
inline constexpr unspecified
|
| 45 |
-
inline constexpr unspecified
|
| 46 |
-
inline constexpr unspecified
|
|
|
|
| 47 |
}
|
| 48 |
|
| 49 |
// [range.range], ranges
|
| 50 |
template<class T>
|
| 51 |
-
concept range = see below;
|
| 52 |
|
| 53 |
template<class T>
|
| 54 |
-
constexpr bool enable_borrowed_range = false;
|
| 55 |
|
| 56 |
template<class T>
|
| 57 |
-
concept borrowed_range = see below;
|
| 58 |
|
| 59 |
template<class T>
|
| 60 |
-
using iterator_t = decltype(ranges::begin(declval<T&>()));
|
| 61 |
template<range R>
|
| 62 |
-
using sentinel_t = decltype(ranges::end(declval<R&>()));
|
| 63 |
template<range R>
|
| 64 |
-
using const_iterator_t =
|
| 65 |
template<range R>
|
| 66 |
-
using const_sentinel_t =
|
| 67 |
template<range R>
|
| 68 |
-
using range_difference_t = iter_difference_t<iterator_t<R>>;
|
| 69 |
template<sized_range R>
|
| 70 |
-
using range_size_t = decltype(ranges::size(declval<R&>()));
|
| 71 |
template<range R>
|
| 72 |
-
using range_value_t = iter_value_t<iterator_t<R>>;
|
| 73 |
template<range R>
|
| 74 |
-
using range_reference_t = iter_reference_t<iterator_t<R>>;
|
| 75 |
template<range R>
|
| 76 |
-
using range_const_reference_t = iter_const_reference_t<iterator_t<R>>;
|
| 77 |
template<range R>
|
| 78 |
-
using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<R>>;
|
| 79 |
template<range R>
|
| 80 |
-
using range_common_reference_t = iter_common_reference_t<iterator_t<R>>;
|
| 81 |
|
| 82 |
// [range.sized], sized ranges
|
| 83 |
template<class>
|
| 84 |
-
constexpr bool disable_sized_range = false;
|
| 85 |
|
| 86 |
template<class T>
|
| 87 |
-
concept
|
|
|
|
|
|
|
|
|
|
| 88 |
|
| 89 |
// [range.view], views
|
| 90 |
template<class T>
|
| 91 |
-
constexpr bool enable_view = see below;
|
| 92 |
|
| 93 |
-
struct view_base {};
|
| 94 |
|
| 95 |
template<class T>
|
| 96 |
-
concept view = see below;
|
| 97 |
|
| 98 |
// [range.refinements], other range refinements
|
| 99 |
template<class R, class T>
|
| 100 |
-
concept output_range = see below;
|
| 101 |
|
| 102 |
template<class T>
|
| 103 |
-
concept input_range = see below;
|
| 104 |
|
| 105 |
template<class T>
|
| 106 |
-
concept forward_range = see below;
|
| 107 |
|
| 108 |
template<class T>
|
| 109 |
-
concept bidirectional_range = see below;
|
| 110 |
|
| 111 |
template<class T>
|
| 112 |
-
concept random_access_range = see below;
|
| 113 |
|
| 114 |
template<class T>
|
| 115 |
-
concept contiguous_range = see below;
|
| 116 |
|
| 117 |
template<class T>
|
| 118 |
-
concept common_range = see below;
|
| 119 |
|
| 120 |
template<class T>
|
| 121 |
-
concept viewable_range = see below;
|
| 122 |
|
| 123 |
template<class T>
|
| 124 |
-
concept constant_range = see below;
|
|
|
|
|
|
|
|
|
|
| 125 |
|
| 126 |
// [view.interface], class template view_interface
|
| 127 |
template<class D>
|
| 128 |
requires is_class_v<D> && same_as<D, remove_cv_t<D>>
|
| 129 |
-
class view_interface;
|
| 130 |
|
| 131 |
// [range.subrange], sub-ranges
|
| 132 |
-
enum class subrange_kind : bool { unsized, sized };
|
| 133 |
|
| 134 |
template<input_or_output_iterator I, sentinel_for<I> S = I, subrange_kind K = see below>
|
| 135 |
requires (K == subrange_kind::sized || !sized_sentinel_for<S, I>)
|
| 136 |
-
class subrange;
|
| 137 |
|
| 138 |
template<class I, class S, subrange_kind K>
|
| 139 |
-
constexpr bool enable_borrowed_range<subrange<I, S, K>> = true;
|
| 140 |
|
| 141 |
template<size_t N, class I, class S, subrange_kind K>
|
| 142 |
requires ((N == 0 && copyable<I>) || N == 1)
|
| 143 |
-
constexpr auto get(const subrange<I, S, K>& r);
|
| 144 |
|
| 145 |
template<size_t N, class I, class S, subrange_kind K>
|
| 146 |
requires (N < 2)
|
| 147 |
-
constexpr auto get(subrange<I, S, K>&& r);
|
| 148 |
}
|
| 149 |
|
| 150 |
namespace std {
|
| 151 |
-
using ranges::get;
|
| 152 |
}
|
| 153 |
|
| 154 |
namespace std::ranges {
|
| 155 |
// [range.dangling], dangling iterator handling
|
| 156 |
-
struct dangling;
|
| 157 |
|
| 158 |
// [range.elementsof], class template elements_of
|
| 159 |
template<range R, class Allocator = allocator<byte>>
|
| 160 |
-
struct elements_of;
|
| 161 |
|
| 162 |
template<range R>
|
| 163 |
-
using borrowed_iterator_t = see below;
|
| 164 |
|
| 165 |
template<range R>
|
| 166 |
-
using borrowed_subrange_t = see below;
|
| 167 |
|
| 168 |
// [range.utility.conv], range conversions
|
| 169 |
template<class C, input_range R, class... Args> requires (!view<C>)
|
| 170 |
-
constexpr C to(R&& r, Args&&... args);
|
| 171 |
template<template<class...> class C, input_range R, class... Args>
|
| 172 |
-
constexpr auto to(R&& r, Args&&... args);
|
| 173 |
template<class C, class... Args> requires (!view<C>)
|
| 174 |
-
constexpr auto to(Args&&... args);
|
| 175 |
template<template<class...> class C, class... Args>
|
| 176 |
-
constexpr auto to(Args&&... args);
|
| 177 |
|
| 178 |
// [range.empty], empty view
|
| 179 |
template<class T>
|
| 180 |
requires is_object_v<T>
|
| 181 |
-
class empty_view;
|
| 182 |
|
| 183 |
template<class T>
|
| 184 |
-
constexpr bool enable_borrowed_range<empty_view<T>> = true;
|
| 185 |
|
| 186 |
namespace views {
|
| 187 |
template<class T>
|
| 188 |
-
constexpr empty_view<T> empty{};
|
| 189 |
}
|
| 190 |
|
| 191 |
// [range.single], single view
|
| 192 |
template<move_constructible T>
|
| 193 |
requires is_object_v<T>
|
| 194 |
-
class single_view;
|
| 195 |
|
| 196 |
-
namespace views { inline constexpr unspecified single = unspecified; }
|
| 197 |
|
| 198 |
template<bool Const, class T>
|
| 199 |
using maybe-const = conditional_t<Const, const T, T>; // exposition only
|
| 200 |
|
| 201 |
// [range.iota], iota view
|
| 202 |
template<weakly_incrementable W, semiregular Bound = unreachable_sentinel_t>
|
| 203 |
requires weakly-equality-comparable-with<W, Bound> && copyable<W>
|
| 204 |
-
class iota_view;
|
| 205 |
|
| 206 |
template<class W, class Bound>
|
| 207 |
-
constexpr bool enable_borrowed_range<iota_view<W, Bound>> = true;
|
| 208 |
|
| 209 |
-
namespace views {
|
|
|
|
|
|
|
|
|
|
| 210 |
|
| 211 |
// [range.repeat], repeat view
|
| 212 |
template<move_constructible T, semiregular Bound = unreachable_sentinel_t>
|
| 213 |
requires see below
|
| 214 |
-
class repeat_view;
|
| 215 |
|
| 216 |
-
namespace views { inline constexpr unspecified repeat = unspecified; }
|
| 217 |
|
| 218 |
// [range.istream], istream view
|
| 219 |
template<movable Val, class CharT, class Traits = char_traits<CharT>>
|
| 220 |
requires see below
|
| 221 |
-
class basic_istream_view;
|
| 222 |
template<class Val>
|
| 223 |
-
using istream_view = basic_istream_view<Val, char>;
|
| 224 |
template<class Val>
|
| 225 |
-
using wistream_view = basic_istream_view<Val, wchar_t>;
|
| 226 |
|
| 227 |
-
namespace views {
|
|
|
|
|
|
|
| 228 |
|
| 229 |
// [range.adaptor.object], range adaptor objects
|
| 230 |
template<class D>
|
| 231 |
requires is_class_v<D> && same_as<D, remove_cv_t<D>>
|
| 232 |
-
class range_adaptor_closure { };
|
| 233 |
|
| 234 |
// [range.all], all view
|
| 235 |
namespace views {
|
| 236 |
-
inline constexpr unspecified all = unspecified;
|
| 237 |
|
| 238 |
template<viewable_range R>
|
| 239 |
-
using all_t = decltype(all(declval<R>()));
|
| 240 |
}
|
| 241 |
|
| 242 |
// [range.ref.view], ref view
|
| 243 |
template<range R>
|
| 244 |
requires is_object_v<R>
|
| 245 |
-
class ref_view;
|
| 246 |
|
| 247 |
template<class T>
|
| 248 |
-
constexpr bool enable_borrowed_range<ref_view<T>> = true;
|
| 249 |
|
| 250 |
// [range.owning.view], owning view
|
| 251 |
template<range R>
|
| 252 |
requires see below
|
| 253 |
-
class owning_view;
|
| 254 |
|
| 255 |
template<class T>
|
| 256 |
-
constexpr bool enable_borrowed_range<owning_view<T>> =
|
| 257 |
enable_borrowed_range<T>;
|
| 258 |
|
| 259 |
// [range.as.rvalue], as rvalue view
|
| 260 |
template<view V>
|
| 261 |
requires input_range<V>
|
| 262 |
-
class as_rvalue_view;
|
| 263 |
|
| 264 |
template<class T>
|
| 265 |
-
constexpr bool enable_borrowed_range<as_rvalue_view<T>> =
|
| 266 |
enable_borrowed_range<T>;
|
| 267 |
|
| 268 |
-
namespace views { inline constexpr unspecified as_rvalue = unspecified; }
|
| 269 |
|
| 270 |
// [range.filter], filter view
|
| 271 |
template<input_range V, indirect_unary_predicate<iterator_t<V>> Pred>
|
| 272 |
requires view<V> && is_object_v<Pred>
|
| 273 |
-
class filter_view;
|
| 274 |
|
| 275 |
-
namespace views { inline constexpr unspecified filter = unspecified; }
|
| 276 |
|
| 277 |
// [range.transform], transform view
|
| 278 |
template<input_range V, move_constructible F>
|
| 279 |
requires view<V> && is_object_v<F> &&
|
| 280 |
regular_invocable<F&, range_reference_t<V>> &&
|
| 281 |
can-reference<invoke_result_t<F&, range_reference_t<V>>>
|
| 282 |
-
class transform_view;
|
| 283 |
|
| 284 |
-
namespace views { inline constexpr unspecified transform = unspecified; }
|
| 285 |
|
| 286 |
// [range.take], take view
|
| 287 |
-
template<view> class take_view;
|
| 288 |
|
| 289 |
template<class T>
|
| 290 |
-
constexpr bool enable_borrowed_range<take_view<T>> =
|
| 291 |
enable_borrowed_range<T>;
|
| 292 |
|
| 293 |
-
namespace views { inline constexpr unspecified take = unspecified; }
|
| 294 |
|
| 295 |
// [range.take.while], take while view
|
| 296 |
template<view V, class Pred>
|
| 297 |
requires input_range<V> && is_object_v<Pred> &&
|
| 298 |
indirect_unary_predicate<const Pred, iterator_t<V>>
|
| 299 |
-
class take_while_view;
|
| 300 |
|
| 301 |
-
namespace views { inline constexpr unspecified take_while = unspecified; }
|
| 302 |
|
| 303 |
// [range.drop], drop view
|
| 304 |
template<view V>
|
| 305 |
-
class drop_view;
|
| 306 |
|
| 307 |
template<class T>
|
| 308 |
-
constexpr bool enable_borrowed_range<drop_view<T>> =
|
| 309 |
enable_borrowed_range<T>;
|
| 310 |
|
| 311 |
-
namespace views { inline constexpr unspecified drop = unspecified; }
|
| 312 |
|
| 313 |
// [range.drop.while], drop while view
|
| 314 |
template<view V, class Pred>
|
| 315 |
requires input_range<V> && is_object_v<Pred> &&
|
| 316 |
indirect_unary_predicate<const Pred, iterator_t<V>>
|
| 317 |
-
class drop_while_view;
|
| 318 |
|
| 319 |
template<class T, class Pred>
|
| 320 |
-
constexpr bool enable_borrowed_range<drop_while_view<T, Pred>> =
|
| 321 |
enable_borrowed_range<T>;
|
| 322 |
|
| 323 |
-
namespace views { inline constexpr unspecified drop_while = unspecified; }
|
| 324 |
|
| 325 |
// [range.join], join view
|
| 326 |
template<input_range V>
|
| 327 |
requires view<V> && input_range<range_reference_t<V>>
|
| 328 |
-
class join_view;
|
| 329 |
|
| 330 |
-
namespace views { inline constexpr unspecified join = unspecified; }
|
| 331 |
|
| 332 |
// [range.join.with], join with view
|
| 333 |
-
template<class R, class P>
|
| 334 |
-
concept compatible-joinable-ranges = see below; // exposition only
|
| 335 |
-
|
| 336 |
template<input_range V, forward_range Pattern>
|
| 337 |
-
requires
|
| 338 |
-
|
| 339 |
-
&& compatible-joinable-ranges<range_reference_t<V>, Pattern>
|
| 340 |
-
class join_with_view; // freestanding
|
| 341 |
|
| 342 |
-
namespace views { inline constexpr unspecified join_with = unspecified; }
|
| 343 |
|
| 344 |
// [range.lazy.split], lazy split view
|
| 345 |
template<class R>
|
| 346 |
concept tiny-range = see below; // exposition only
|
| 347 |
|
| 348 |
template<input_range V, forward_range Pattern>
|
| 349 |
requires view<V> && view<Pattern> &&
|
| 350 |
indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to> &&
|
| 351 |
(forward_range<V> || tiny-range<Pattern>)
|
| 352 |
-
class lazy_split_view;
|
| 353 |
|
| 354 |
// [range.split], split view
|
| 355 |
template<forward_range V, forward_range Pattern>
|
| 356 |
requires view<V> && view<Pattern> &&
|
| 357 |
indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to>
|
| 358 |
-
class split_view;
|
| 359 |
|
| 360 |
namespace views {
|
| 361 |
-
inline constexpr unspecified lazy_split = unspecified;
|
| 362 |
-
inline constexpr unspecified split = unspecified;
|
| 363 |
}
|
| 364 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 365 |
// [range.counted], counted view
|
| 366 |
-
namespace views { inline constexpr unspecified counted = unspecified; }
|
| 367 |
|
| 368 |
// [range.common], common view
|
| 369 |
template<view V>
|
| 370 |
requires (!common_range<V> && copyable<iterator_t<V>>)
|
| 371 |
-
class common_view;
|
| 372 |
|
| 373 |
template<class T>
|
| 374 |
-
constexpr bool enable_borrowed_range<common_view<T>> =
|
| 375 |
enable_borrowed_range<T>;
|
| 376 |
|
| 377 |
-
namespace views { inline constexpr unspecified common = unspecified; }
|
| 378 |
|
| 379 |
// [range.reverse], reverse view
|
| 380 |
template<view V>
|
| 381 |
requires bidirectional_range<V>
|
| 382 |
-
class reverse_view;
|
| 383 |
|
| 384 |
template<class T>
|
| 385 |
-
constexpr bool enable_borrowed_range<reverse_view<T>> =
|
| 386 |
enable_borrowed_range<T>;
|
| 387 |
|
| 388 |
-
namespace views { inline constexpr unspecified reverse = unspecified; }
|
| 389 |
|
| 390 |
// [range.as.const], as const view
|
| 391 |
template<input_range R>
|
| 392 |
-
constexpr auto& possibly-const-range(R& r) {
|
| 393 |
-
if constexpr (
|
| 394 |
return const_cast<const R&>(r);
|
| 395 |
} else {
|
| 396 |
return r;
|
| 397 |
}
|
| 398 |
}
|
| 399 |
|
| 400 |
template<view V>
|
| 401 |
requires input_range<V>
|
| 402 |
-
class as_const_view;
|
| 403 |
|
| 404 |
template<class T>
|
| 405 |
-
constexpr bool enable_borrowed_range<as_const_view<T>> =
|
| 406 |
enable_borrowed_range<T>;
|
| 407 |
|
| 408 |
-
namespace views { inline constexpr unspecified as_const = unspecified; }
|
| 409 |
|
| 410 |
// [range.elements], elements view
|
| 411 |
template<input_range V, size_t N>
|
| 412 |
requires see below
|
| 413 |
-
class elements_view;
|
| 414 |
|
| 415 |
template<class T, size_t N>
|
| 416 |
-
constexpr bool enable_borrowed_range<elements_view<T, N>> =
|
| 417 |
enable_borrowed_range<T>;
|
| 418 |
|
| 419 |
template<class R>
|
| 420 |
-
using keys_view = elements_view<R, 0>;
|
| 421 |
template<class R>
|
| 422 |
-
using values_view = elements_view<R, 1>;
|
| 423 |
|
| 424 |
namespace views {
|
| 425 |
template<size_t N>
|
| 426 |
-
constexpr unspecified elements = unspecified;
|
| 427 |
-
inline constexpr auto keys = elements<0>;
|
| 428 |
-
inline constexpr auto values = elements<1>;
|
| 429 |
}
|
| 430 |
|
| 431 |
// [range.enumerate], enumerate view
|
| 432 |
-
template<
|
| 433 |
-
requires
|
| 434 |
-
class enumerate_view;
|
| 435 |
|
| 436 |
template<class View>
|
| 437 |
-
constexpr bool enable_borrowed_range<enumerate_view<View>> =
|
| 438 |
enable_borrowed_range<View>;
|
| 439 |
|
| 440 |
-
namespace views { inline constexpr unspecified enumerate = unspecified; }
|
| 441 |
|
| 442 |
// [range.zip], zip view
|
| 443 |
template<input_range... Views>
|
| 444 |
requires (view<Views> && ...) && (sizeof...(Views) > 0)
|
| 445 |
-
class zip_view;
|
| 446 |
|
| 447 |
template<class... Views>
|
| 448 |
-
constexpr bool enable_borrowed_range<zip_view<Views...>> =
|
| 449 |
(enable_borrowed_range<Views> && ...);
|
| 450 |
|
| 451 |
-
namespace views { inline constexpr unspecified zip = unspecified; }
|
| 452 |
|
| 453 |
// [range.zip.transform], zip transform view
|
| 454 |
template<move_constructible F, input_range... Views>
|
| 455 |
requires (view<Views> && ...) && (sizeof...(Views) > 0) && is_object_v<F> &&
|
| 456 |
regular_invocable<F&, range_reference_t<Views>...> &&
|
| 457 |
can-reference<invoke_result_t<F&, range_reference_t<Views>...>>
|
| 458 |
-
class zip_transform_view;
|
| 459 |
|
| 460 |
-
namespace views { inline constexpr unspecified zip_transform = unspecified; }
|
| 461 |
|
| 462 |
// [range.adjacent], adjacent view
|
| 463 |
template<forward_range V, size_t N>
|
| 464 |
requires view<V> && (N > 0)
|
| 465 |
-
class adjacent_view;
|
| 466 |
|
| 467 |
template<class V, size_t N>
|
| 468 |
-
constexpr bool enable_borrowed_range<adjacent_view<V, N>> =
|
| 469 |
enable_borrowed_range<V>;
|
| 470 |
|
| 471 |
namespace views {
|
| 472 |
template<size_t N>
|
| 473 |
-
constexpr unspecified adjacent = unspecified;
|
| 474 |
-
inline constexpr auto pairwise = adjacent<2>;
|
| 475 |
}
|
| 476 |
|
| 477 |
// [range.adjacent.transform], adjacent transform view
|
| 478 |
template<forward_range V, move_constructible F, size_t N>
|
| 479 |
requires see below
|
| 480 |
-
class adjacent_transform_view;
|
| 481 |
|
| 482 |
namespace views {
|
| 483 |
template<size_t N>
|
| 484 |
-
constexpr unspecified adjacent_transform = unspecified;
|
| 485 |
-
inline constexpr auto pairwise_transform = adjacent_transform<2>;
|
| 486 |
}
|
| 487 |
|
| 488 |
// [range.chunk], chunk view
|
| 489 |
template<view V>
|
| 490 |
requires input_range<V>
|
| 491 |
-
class chunk_view;
|
| 492 |
|
| 493 |
template<view V>
|
| 494 |
requires forward_range<V>
|
| 495 |
-
class chunk_view<V>;
|
| 496 |
|
| 497 |
template<class V>
|
| 498 |
-
constexpr bool enable_borrowed_range<chunk_view<V>> =
|
| 499 |
forward_range<V> && enable_borrowed_range<V>;
|
| 500 |
|
| 501 |
-
namespace views { inline constexpr unspecified chunk = unspecified; }
|
| 502 |
|
| 503 |
// [range.slide], slide view
|
| 504 |
template<forward_range V>
|
| 505 |
requires view<V>
|
| 506 |
-
class slide_view;
|
| 507 |
|
| 508 |
template<class V>
|
| 509 |
-
constexpr bool enable_borrowed_range<slide_view<V>> =
|
| 510 |
-
enable_borrowed_range<V>;
|
| 511 |
|
| 512 |
-
namespace views { inline constexpr unspecified slide = unspecified; }
|
| 513 |
|
| 514 |
// [range.chunk.by], chunk by view
|
| 515 |
template<forward_range V, indirect_binary_predicate<iterator_t<V>, iterator_t<V>> Pred>
|
| 516 |
requires view<V> && is_object_v<Pred>
|
| 517 |
-
class chunk_by_view;
|
| 518 |
|
| 519 |
-
namespace views { inline constexpr unspecified chunk_by = unspecified; }
|
| 520 |
|
| 521 |
// [range.stride], stride view
|
| 522 |
template<input_range V>
|
| 523 |
requires view<V>
|
| 524 |
-
class stride_view;
|
| 525 |
|
| 526 |
template<class V>
|
| 527 |
-
constexpr bool enable_borrowed_range<stride_view<V>> =
|
| 528 |
enable_borrowed_range<V>;
|
| 529 |
|
| 530 |
-
namespace views { inline constexpr unspecified stride = unspecified; }
|
| 531 |
|
| 532 |
// [range.cartesian], cartesian product view
|
| 533 |
template<input_range First, forward_range... Vs>
|
| 534 |
requires (view<First> && ... && view<Vs>)
|
| 535 |
-
class cartesian_product_view;
|
| 536 |
|
| 537 |
-
namespace views { inline constexpr unspecified cartesian_product = unspecified; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 538 |
}
|
| 539 |
|
| 540 |
namespace std {
|
| 541 |
-
namespace views = ranges::views;
|
| 542 |
|
| 543 |
-
template<class T> struct tuple_size;
|
| 544 |
-
template<size_t I, class T> struct tuple_element;
|
| 545 |
|
| 546 |
template<class I, class S, ranges::subrange_kind K>
|
| 547 |
-
struct tuple_size<ranges::subrange<I, S, K>>
|
| 548 |
: integral_constant<size_t, 2> {};
|
| 549 |
template<class I, class S, ranges::subrange_kind K>
|
| 550 |
-
struct tuple_element<0, ranges::subrange<I, S, K>> {
|
| 551 |
-
using type = I;
|
| 552 |
};
|
| 553 |
template<class I, class S, ranges::subrange_kind K>
|
| 554 |
-
struct tuple_element<1, ranges::subrange<I, S, K>> {
|
| 555 |
-
using type = S;
|
| 556 |
};
|
| 557 |
template<class I, class S, ranges::subrange_kind K>
|
| 558 |
-
struct tuple_element<0, const ranges::subrange<I, S, K>> {
|
| 559 |
-
using type = I;
|
| 560 |
};
|
| 561 |
template<class I, class S, ranges::subrange_kind K>
|
| 562 |
-
struct tuple_element<1, const ranges::subrange<I, S, K>> {
|
| 563 |
-
using type = S;
|
| 564 |
};
|
| 565 |
|
| 566 |
-
struct from_range_t { explicit from_range_t() = default; };
|
| 567 |
-
inline constexpr from_range_t from_range{};
|
| 568 |
}
|
| 569 |
```
|
| 570 |
|
| 571 |
Within this Clause, for an integer-like type `X`
|
| 572 |
[[iterator.concept.winc]], `make-unsigned-like-t<X>` denotes
|
|
@@ -584,11 +617,11 @@ type of the same width as `X`.
|
|
| 584 |
|
| 585 |
### General <a id="range.access.general">[[range.access.general]]</a>
|
| 586 |
|
| 587 |
In addition to being available via inclusion of the `<ranges>` header,
|
| 588 |
the customization point objects in [[range.access]] are available when
|
| 589 |
-
`<iterator>` is included.
|
| 590 |
|
| 591 |
Within [[range.access]], the *reified object* of a subexpression `E`
|
| 592 |
denotes
|
| 593 |
|
| 594 |
- the same object as `E` if `E` is a glvalue, or
|
|
@@ -846,10 +879,37 @@ denotes the reified object for `E`. If `ranges::size(t)` is ill-formed,
|
|
| 846 |
`ranges::ssize(E)` is ill-formed. Otherwise let `D` be
|
| 847 |
`make-signed-like-t<decltype(ranges::{}size(t))>`, or `ptrdiff_t` if it
|
| 848 |
is wider than that type; `ranges::ssize(E)` is expression-equivalent to
|
| 849 |
`static_cast<D>(ranges::size(t))`.
|
| 850 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 851 |
### `ranges::empty` <a id="range.prim.empty">[[range.prim.empty]]</a>
|
| 852 |
|
| 853 |
The name `ranges::empty` denotes a customization point object
|
| 854 |
[[customization.point.object]].
|
| 855 |
|
|
@@ -906,11 +966,11 @@ pointer to object type. — *end note*]
|
|
| 906 |
|
| 907 |
### `ranges::cdata` <a id="range.prim.cdata">[[range.prim.cdata]]</a>
|
| 908 |
|
| 909 |
``` cpp
|
| 910 |
template<class T>
|
| 911 |
-
constexpr auto as-const-pointer(const T* p) { return p; }
|
| 912 |
```
|
| 913 |
|
| 914 |
The name `ranges::cdata` denotes a customization point object
|
| 915 |
[[customization.point.object]]. Given a subexpression `E` with type `T`,
|
| 916 |
let `t` be an lvalue that denotes the reified object for `E`. Then:
|
|
@@ -964,14 +1024,10 @@ template<class T>
|
|
| 964 |
ranges::begin(t); // sometimes equality-preserving (see below)
|
| 965 |
ranges::end(t);
|
| 966 |
};
|
| 967 |
```
|
| 968 |
|
| 969 |
-
The required expressions `ranges::begin(t)` and `ranges::end(t)` of the
|
| 970 |
-
`range` concept do not require implicit expression
|
| 971 |
-
variations [[concepts.equality]].
|
| 972 |
-
|
| 973 |
Given an expression `t` such that `decltype((t))` is `T&`, `T` models
|
| 974 |
`range` only if
|
| 975 |
|
| 976 |
- \[`ranges::begin(t)`, `ranges::end(t)`) denotes a
|
| 977 |
range [[iterator.requirements.general]],
|
|
@@ -1025,20 +1081,48 @@ models `borrowed_range` because
|
|
| 1025 |
- `S`’s iterators do not have validity tied to the lifetime of an `S`
|
| 1026 |
object because they are “borrowed” from some other range.
|
| 1027 |
|
| 1028 |
— *end example*]
|
| 1029 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1030 |
### Sized ranges <a id="range.sized">[[range.sized]]</a>
|
| 1031 |
|
| 1032 |
-
The `sized_range` concept refines `
|
| 1033 |
-
number of elements in the range can be determined
|
| 1034 |
-
time using `ranges::size`.
|
| 1035 |
|
| 1036 |
``` cpp
|
| 1037 |
template<class T>
|
| 1038 |
concept sized_range =
|
| 1039 |
-
|
| 1040 |
```
|
| 1041 |
|
| 1042 |
Given an lvalue `t` of type `remove_reference_t<T>`, `T` models
|
| 1043 |
`sized_range` only if
|
| 1044 |
|
|
@@ -1060,11 +1144,11 @@ template<class>
|
|
| 1060 |
*Remarks:* Pursuant to [[namespace.std]], users may specialize
|
| 1061 |
`disable_sized_range` for cv-unqualified program-defined types. Such
|
| 1062 |
specializations shall be usable in constant expressions [[expr.const]]
|
| 1063 |
and have type `const bool`.
|
| 1064 |
|
| 1065 |
-
[*Note 1*: `disable_sized_range` allows use of range types with the
|
| 1066 |
library that satisfy but do not in fact model
|
| 1067 |
`sized_range`. — *end note*]
|
| 1068 |
|
| 1069 |
### Views <a id="range.view">[[range.view]]</a>
|
| 1070 |
|
|
@@ -1076,11 +1160,11 @@ constructing range adaptor pipelines [[range.adaptors]].
|
|
| 1076 |
template<class T>
|
| 1077 |
concept view =
|
| 1078 |
range<T> && movable<T> && enable_view<T>;
|
| 1079 |
```
|
| 1080 |
|
| 1081 |
-
`T` models `view` only if
|
| 1082 |
|
| 1083 |
- `T` has 𝑂(1) move construction; and
|
| 1084 |
- move assignment of an object of type `T` is no more complex than
|
| 1085 |
destruction followed by move construction; and
|
| 1086 |
- if N copies and/or moves are made from an object of type `T` that
|
|
@@ -1124,12 +1208,12 @@ For a type `T`, *`is-derived-from-view-interface`*`<T>` is `true` if and
|
|
| 1124 |
only if `T` has exactly one public base class `view_interface<U>` for
|
| 1125 |
some type `U` and `T` has no base classes of type `view_interface<V>`
|
| 1126 |
for any other type `V`.
|
| 1127 |
|
| 1128 |
*Remarks:* Pursuant to [[namespace.std]], users may specialize
|
| 1129 |
-
`enable_view` to `true` for cv-unqualified program-defined types
|
| 1130 |
-
model `view`, and `false` for types
|
| 1131 |
shall be usable in constant expressions [[expr.const]] and have type
|
| 1132 |
`const bool`.
|
| 1133 |
|
| 1134 |
### Other range refinements <a id="range.refinements">[[range.refinements]]</a>
|
| 1135 |
|
|
@@ -1215,32 +1299,45 @@ type whose elements are not modifiable.
|
|
| 1215 |
template<class T>
|
| 1216 |
concept constant_range =
|
| 1217 |
input_range<T> && constant-iterator<iterator_t<T>>;
|
| 1218 |
```
|
| 1219 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1220 |
## Range utilities <a id="range.utility">[[range.utility]]</a>
|
| 1221 |
|
| 1222 |
### General <a id="range.utility.general">[[range.utility.general]]</a>
|
| 1223 |
|
| 1224 |
The components in [[range.utility]] are general utilities for
|
| 1225 |
representing and manipulating ranges.
|
| 1226 |
|
| 1227 |
### Helper concepts <a id="range.utility.helpers">[[range.utility.helpers]]</a>
|
| 1228 |
|
| 1229 |
-
Many of the types in
|
| 1230 |
-
|
| 1231 |
|
| 1232 |
``` cpp
|
| 1233 |
template<class R>
|
| 1234 |
concept simple-view = // exposition only
|
| 1235 |
view<R> && range<const R> &&
|
| 1236 |
same_as<iterator_t<R>, iterator_t<const R>> &&
|
| 1237 |
same_as<sentinel_t<R>, sentinel_t<const R>>;
|
| 1238 |
|
| 1239 |
template<class I>
|
| 1240 |
concept has-arrow = // exposition only
|
| 1241 |
-
input_iterator<I> && (is_pointer_v<I> || requires(I i) { i.operator->(); });
|
| 1242 |
|
| 1243 |
template<class T, class U>
|
| 1244 |
concept different-from = // exposition only
|
| 1245 |
!same_as<remove_cvref_t<T>, remove_cvref_t<U>>;
|
| 1246 |
|
|
@@ -1354,21 +1451,21 @@ shall be complete, and model both `derived_from<view_interface<D>>` and
|
|
| 1354 |
``` cpp
|
| 1355 |
constexpr decltype(auto) front() requires forward_range<D>;
|
| 1356 |
constexpr decltype(auto) front() const requires forward_range<const D>;
|
| 1357 |
```
|
| 1358 |
|
| 1359 |
-
|
| 1360 |
|
| 1361 |
*Effects:* Equivalent to: `return *ranges::begin(`*`derived`*`());`
|
| 1362 |
|
| 1363 |
``` cpp
|
| 1364 |
constexpr decltype(auto) back() requires bidirectional_range<D> && common_range<D>;
|
| 1365 |
constexpr decltype(auto) back() const
|
| 1366 |
requires bidirectional_range<const D> && common_range<const D>;
|
| 1367 |
```
|
| 1368 |
|
| 1369 |
-
|
| 1370 |
|
| 1371 |
*Effects:* Equivalent to:
|
| 1372 |
`return *ranges::prev(ranges::end(`*`derived`*`()));`
|
| 1373 |
|
| 1374 |
### Sub-ranges <a id="range.subrange">[[range.subrange]]</a>
|
|
@@ -1435,21 +1532,21 @@ namespace std::ranges {
|
|
| 1435 |
template<different-from<subrange> PairLike>
|
| 1436 |
requires pair-like-convertible-from<PairLike, const I&, const S&>
|
| 1437 |
constexpr operator PairLike() const;
|
| 1438 |
|
| 1439 |
constexpr I begin() const requires copyable<I>;
|
| 1440 |
-
|
| 1441 |
constexpr S end() const;
|
| 1442 |
|
| 1443 |
constexpr bool empty() const;
|
| 1444 |
constexpr make-unsigned-like-t<iter_difference_t<I>> size() const
|
| 1445 |
requires (K == subrange_kind::sized);
|
| 1446 |
|
| 1447 |
-
|
| 1448 |
requires forward_iterator<I>;
|
| 1449 |
-
|
| 1450 |
-
|
| 1451 |
requires bidirectional_iterator<I>;
|
| 1452 |
constexpr subrange& advance(iter_difference_t<I> n);
|
| 1453 |
};
|
| 1454 |
|
| 1455 |
template<input_or_output_iterator I, sentinel_for<I> S>
|
|
@@ -1528,11 +1625,11 @@ constexpr I begin() const requires copyable<I>;
|
|
| 1528 |
```
|
| 1529 |
|
| 1530 |
*Effects:* Equivalent to: `return `*`begin_`*`;`
|
| 1531 |
|
| 1532 |
``` cpp
|
| 1533 |
-
|
| 1534 |
```
|
| 1535 |
|
| 1536 |
*Effects:* Equivalent to: `return std::move(`*`begin_`*`);`
|
| 1537 |
|
| 1538 |
``` cpp
|
|
@@ -1557,11 +1654,11 @@ constexpr make-unsigned-like-t<iter_difference_t<I>> size() const
|
|
| 1557 |
- If *StoreSize* is `true`, equivalent to: `return `*`size_`*`;`
|
| 1558 |
- Otherwise, equivalent to:
|
| 1559 |
`return `*`to-unsigned-like`*`(`*`end_`*` - `*`begin_`*`);`
|
| 1560 |
|
| 1561 |
``` cpp
|
| 1562 |
-
|
| 1563 |
requires forward_iterator<I>;
|
| 1564 |
```
|
| 1565 |
|
| 1566 |
*Effects:* Equivalent to:
|
| 1567 |
|
|
@@ -1570,22 +1667,22 @@ auto tmp = *this;
|
|
| 1570 |
tmp.advance(n);
|
| 1571 |
return tmp;
|
| 1572 |
```
|
| 1573 |
|
| 1574 |
``` cpp
|
| 1575 |
-
|
| 1576 |
```
|
| 1577 |
|
| 1578 |
*Effects:* Equivalent to:
|
| 1579 |
|
| 1580 |
``` cpp
|
| 1581 |
advance(n);
|
| 1582 |
return std::move(*this);
|
| 1583 |
```
|
| 1584 |
|
| 1585 |
``` cpp
|
| 1586 |
-
|
| 1587 |
requires bidirectional_iterator<I>;
|
| 1588 |
```
|
| 1589 |
|
| 1590 |
*Effects:* Equivalent to:
|
| 1591 |
|
|
@@ -1749,30 +1846,38 @@ constexpr bool reservable-container = // exposition only
|
|
| 1749 |
{ c.capacity() } -> same_as<decltype(n)>;
|
| 1750 |
{ c.max_size() } -> same_as<decltype(n)>;
|
| 1751 |
};
|
| 1752 |
```
|
| 1753 |
|
| 1754 |
-
Let *`container-
|
| 1755 |
|
| 1756 |
``` cpp
|
| 1757 |
template<class Container, class Ref>
|
| 1758 |
-
constexpr bool container-
|
| 1759 |
requires(Container& c, Ref&& ref) {
|
| 1760 |
-
requires (requires { c.
|
|
|
|
|
|
|
| 1761 |
requires { c.insert(c.end(), std::forward<Ref>(ref)); });
|
| 1762 |
};
|
| 1763 |
```
|
| 1764 |
|
| 1765 |
-
Let *`container-
|
| 1766 |
|
| 1767 |
``` cpp
|
| 1768 |
-
template<class
|
| 1769 |
-
constexpr auto container-
|
| 1770 |
-
|
| 1771 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1772 |
else
|
| 1773 |
-
|
|
|
|
| 1774 |
}
|
| 1775 |
```
|
| 1776 |
|
| 1777 |
#### `ranges::to` <a id="range.utility.conv.to">[[range.utility.conv.to]]</a>
|
| 1778 |
|
|
@@ -1808,21 +1913,22 @@ the following manner:
|
|
| 1808 |
``` cpp
|
| 1809 |
C(ranges::begin(r), ranges::end(r), std::forward<Args>(args)...)
|
| 1810 |
```
|
| 1811 |
- Otherwise, if
|
| 1812 |
- `constructible_from<C, Args...>` is `true`, and
|
| 1813 |
-
- *`container-
|
| 1814 |
|
| 1815 |
``` cpp
|
| 1816 |
C c(std::forward<Args>(args)...);
|
| 1817 |
-
if constexpr (
|
| 1818 |
-
c.reserve(static_cast<range_size_t<C>>(ranges::
|
| 1819 |
-
ranges::
|
| 1820 |
```
|
|
|
|
| 1821 |
- Otherwise, if `input_range<range_reference_t<R>>` is `true`:
|
| 1822 |
``` cpp
|
| 1823 |
-
to<C>(r | views::transform([](auto&& elem) {
|
| 1824 |
return to<range_value_t<C>>(std::forward<decltype(elem)>(elem));
|
| 1825 |
}), std::forward<Args>(args)...);
|
| 1826 |
```
|
| 1827 |
- Otherwise, the program is ill-formed.
|
| 1828 |
|
|
@@ -1973,10 +2079,11 @@ namespace std::ranges {
|
|
| 1973 |
|
| 1974 |
constexpr T* begin() noexcept;
|
| 1975 |
constexpr const T* begin() const noexcept;
|
| 1976 |
constexpr T* end() noexcept;
|
| 1977 |
constexpr const T* end() const noexcept;
|
|
|
|
| 1978 |
static constexpr size_t size() noexcept;
|
| 1979 |
constexpr T* data() noexcept;
|
| 1980 |
constexpr const T* data() const noexcept;
|
| 1981 |
};
|
| 1982 |
|
|
@@ -2018,10 +2125,16 @@ constexpr T* end() noexcept;
|
|
| 2018 |
constexpr const T* end() const noexcept;
|
| 2019 |
```
|
| 2020 |
|
| 2021 |
*Effects:* Equivalent to: `return data() + 1;`
|
| 2022 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2023 |
``` cpp
|
| 2024 |
static constexpr size_t size() noexcept;
|
| 2025 |
```
|
| 2026 |
|
| 2027 |
*Effects:* Equivalent to: `return 1;`
|
|
@@ -2041,22 +2154,28 @@ constexpr const T* data() const noexcept;
|
|
| 2041 |
an initial value.
|
| 2042 |
|
| 2043 |
The name `views::iota` denotes a customization point object
|
| 2044 |
[[customization.point.object]]. Given subexpressions `E` and `F`, the
|
| 2045 |
expressions `views::iota(E)` and `views::iota(E, F)` are
|
| 2046 |
-
expression-equivalent to `iota_view(E)
|
| 2047 |
-
respectively.
|
| 2048 |
|
| 2049 |
[*Example 1*:
|
| 2050 |
|
| 2051 |
``` cpp
|
| 2052 |
for (int i : views::iota(1, 10))
|
| 2053 |
cout << i << ' '; // prints 1 2 3 4 5 6 7 8 9
|
| 2054 |
```
|
| 2055 |
|
| 2056 |
— *end example*]
|
| 2057 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2058 |
#### Class template `iota_view` <a id="range.iota.view">[[range.iota.view]]</a>
|
| 2059 |
|
| 2060 |
``` cpp
|
| 2061 |
namespace std::ranges {
|
| 2062 |
template<class I>
|
|
@@ -2086,10 +2205,11 @@ namespace std::ranges {
|
|
| 2086 |
|
| 2087 |
constexpr iterator begin() const;
|
| 2088 |
constexpr auto end() const;
|
| 2089 |
constexpr iterator end() const requires same_as<W, Bound>;
|
| 2090 |
|
|
|
|
| 2091 |
constexpr auto size() const requires see below;
|
| 2092 |
};
|
| 2093 |
|
| 2094 |
template<class W, class Bound>
|
| 2095 |
requires (!is-integer-like<W> || !is-integer-like<Bound> ||
|
|
@@ -2233,10 +2353,16 @@ else
|
|
| 2233 |
constexpr iterator end() const requires same_as<W, Bound>;
|
| 2234 |
```
|
| 2235 |
|
| 2236 |
*Effects:* Equivalent to: `return `*`iterator`*`{`*`bound_`*`};`
|
| 2237 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2238 |
``` cpp
|
| 2239 |
constexpr auto size() const requires see below;
|
| 2240 |
```
|
| 2241 |
|
| 2242 |
*Effects:* Equivalent to:
|
|
@@ -2599,12 +2725,12 @@ friend constexpr iter_difference_t<W> operator-(const sentinel& x, const iterato
|
|
| 2599 |
the same value.
|
| 2600 |
|
| 2601 |
The name `views::repeat` denotes a customization point object
|
| 2602 |
[[customization.point.object]]. Given subexpressions `E` and `F`, the
|
| 2603 |
expressions `views::repeat(E)` and `views::repeat(E, F)` are
|
| 2604 |
-
expression-equivalent to `repeat_view(E)
|
| 2605 |
-
respectively.
|
| 2606 |
|
| 2607 |
[*Example 1*:
|
| 2608 |
|
| 2609 |
``` cpp
|
| 2610 |
for (int i : views::repeat(17, 4))
|
|
@@ -2651,12 +2777,12 @@ namespace std::ranges {
|
|
| 2651 |
constexpr unreachable_sentinel_t end() const noexcept;
|
| 2652 |
|
| 2653 |
constexpr auto size() const requires (!same_as<Bound, unreachable_sentinel_t>);
|
| 2654 |
};
|
| 2655 |
|
| 2656 |
-
template<class T, class Bound>
|
| 2657 |
-
repeat_view(T, Bound) -> repeat_view<T, Bound>;
|
| 2658 |
}
|
| 2659 |
```
|
| 2660 |
|
| 2661 |
``` cpp
|
| 2662 |
constexpr explicit repeat_view(const T& value, Bound bound = Bound())
|
|
@@ -3215,11 +3341,11 @@ exactly like `optional<T>` with the following differences:
|
|
| 3215 |
- Otherwise, `movable-box<T>` should store only a `T` if either `T`
|
| 3216 |
models `movable` or `is_nothrow_move_constructible_v<T>` is `true`.
|
| 3217 |
|
| 3218 |
### Non-propagating cache <a id="range.nonprop.cache">[[range.nonprop.cache]]</a>
|
| 3219 |
|
| 3220 |
-
Some types in
|
| 3221 |
exposition-only class template *`non-propagating-{}cache`*.
|
| 3222 |
`non-propagating-cache<T>` behaves exactly like `optional<T>` with the
|
| 3223 |
following differences:
|
| 3224 |
|
| 3225 |
- `non-propagating-cache<T>` constrains its type parameter `T` with
|
|
@@ -3294,10 +3420,20 @@ namespace std::ranges {
|
|
| 3294 |
|
| 3295 |
template<class T>
|
| 3296 |
constexpr T& as-lvalue(T&& t) { // exposition only
|
| 3297 |
return static_cast<T&>(t);
|
| 3298 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3299 |
}
|
| 3300 |
```
|
| 3301 |
|
| 3302 |
### All view <a id="range.all">[[range.all]]</a>
|
| 3303 |
|
|
@@ -3341,10 +3477,13 @@ namespace std::ranges {
|
|
| 3341 |
{ return ranges::empty(*r_); }
|
| 3342 |
|
| 3343 |
constexpr auto size() const requires sized_range<R>
|
| 3344 |
{ return ranges::size(*r_); }
|
| 3345 |
|
|
|
|
|
|
|
|
|
|
| 3346 |
constexpr auto data() const requires contiguous_range<R>
|
| 3347 |
{ return ranges::data(*r_); }
|
| 3348 |
};
|
| 3349 |
|
| 3350 |
template<class R>
|
|
@@ -3414,10 +3553,15 @@ namespace std::ranges {
|
|
| 3414 |
constexpr auto size() requires sized_range<R>
|
| 3415 |
{ return ranges::size(r_); }
|
| 3416 |
constexpr auto size() const requires sized_range<const R>
|
| 3417 |
{ return ranges::size(r_); }
|
| 3418 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3419 |
constexpr auto data() requires contiguous_range<R>
|
| 3420 |
{ return ranges::data(r_); }
|
| 3421 |
constexpr auto data() const requires contiguous_range<const R>
|
| 3422 |
{ return ranges::data(r_); }
|
| 3423 |
};
|
|
@@ -3442,11 +3586,11 @@ to replace copying with moving.
|
|
| 3442 |
The name `views::as_rvalue` denotes a range adaptor object
|
| 3443 |
[[range.adaptor.object]]. Let `E` be an expression and let `T` be
|
| 3444 |
`decltype((E))`. The expression `views::as_rvalue(E)` is
|
| 3445 |
expression-equivalent to:
|
| 3446 |
|
| 3447 |
-
- `views::all(E)` if
|
| 3448 |
`same_as<range_rvalue_reference_t<T>, range_reference_t<T>>` is
|
| 3449 |
`true`.
|
| 3450 |
- Otherwise, `as_rvalue_view(E)`.
|
| 3451 |
|
| 3452 |
[*Example 1*:
|
|
@@ -3496,10 +3640,15 @@ namespace std::ranges {
|
|
| 3496 |
}
|
| 3497 |
}
|
| 3498 |
|
| 3499 |
constexpr auto size() requires sized_range<V> { return ranges::size(base_); }
|
| 3500 |
constexpr auto size() const requires sized_range<const V> { return ranges::size(base_); }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3501 |
};
|
| 3502 |
|
| 3503 |
template<class R>
|
| 3504 |
as_rvalue_view(R&&) -> as_rvalue_view<views::all_t<R>>;
|
| 3505 |
}
|
|
@@ -3883,10 +4032,15 @@ namespace std::ranges {
|
|
| 3883 |
regular_invocable<const F&, range_reference_t<const V>>;
|
| 3884 |
|
| 3885 |
constexpr auto size() requires sized_range<V> { return ranges::size(base_); }
|
| 3886 |
constexpr auto size() const requires sized_range<const V>
|
| 3887 |
{ return ranges::size(base_); }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3888 |
};
|
| 3889 |
|
| 3890 |
template<class R, class F>
|
| 3891 |
transform_view(R&&, F) -> transform_view<views::all_t<R>, F>;
|
| 3892 |
}
|
|
@@ -4466,10 +4620,26 @@ namespace std::ranges {
|
|
| 4466 |
|
| 4467 |
constexpr auto size() const requires sized_range<const V> {
|
| 4468 |
auto n = ranges::size(base_);
|
| 4469 |
return ranges::min(n, static_cast<decltype(n)>(count_));
|
| 4470 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4471 |
};
|
| 4472 |
|
| 4473 |
template<class R>
|
| 4474 |
take_view(R&&, range_difference_t<R>)
|
| 4475 |
-> take_view<views::all_t<R>>;
|
|
@@ -4719,12 +4889,12 @@ expression `views::drop(E, F)` is expression-equivalent to:
|
|
| 4719 |
then
|
| 4720 |
`U(ranges::begin(E) + std::min<D>(ranges::distance(E), F), ranges::end(E))`,
|
| 4721 |
except that `E` is evaluated only once, where `U` is
|
| 4722 |
`span<typename T::element_type>` if `T` is a specialization of `span`
|
| 4723 |
and `T` otherwise.
|
| 4724 |
-
- Otherwise, if `T` is a specialization of `subrange`
|
| 4725 |
-
|
| 4726 |
`T(ranges::begin(E) + std::min<D>(ranges::distance(E), F), ranges::{}end(E),
|
| 4727 |
to-unsigned-like(ranges::distance(E) -
|
| 4728 |
std::min<D>(ranges::distance(E), F)))`, except that `E` and `F` are
|
| 4729 |
each evaluated only once.
|
| 4730 |
- Otherwise, if `T` is a specialization of `repeat_view`
|
|
@@ -4785,10 +4955,20 @@ namespace std::ranges {
|
|
| 4785 |
const auto s = ranges::size(base_);
|
| 4786 |
const auto c = static_cast<decltype(s)>(count_);
|
| 4787 |
return s < c ? 0 : s - c;
|
| 4788 |
}
|
| 4789 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4790 |
private:
|
| 4791 |
V base_ = V(); // exposition only
|
| 4792 |
range_difference_t<V> count_ = 0; // exposition only
|
| 4793 |
};
|
| 4794 |
|
|
@@ -5291,11 +5471,11 @@ friend constexpr void iter_swap(const iterator& x, const iterator& y)
|
|
| 5291 |
noexcept(noexcept(ranges::iter_swap(*x.inner_, *y.inner_)))
|
| 5292 |
requires indirectly_swappable<InnerIter>;
|
| 5293 |
```
|
| 5294 |
|
| 5295 |
*Effects:* Equivalent to:
|
| 5296 |
-
`
|
| 5297 |
|
| 5298 |
#### Class template `join_view::sentinel` <a id="range.join.sentinel">[[range.join.sentinel]]</a>
|
| 5299 |
|
| 5300 |
``` cpp
|
| 5301 |
namespace std::ranges {
|
|
@@ -5370,23 +5550,17 @@ for (char c : vs | views::join_with('-')) {
|
|
| 5370 |
|
| 5371 |
#### Class template `join_with_view` <a id="range.join.with.view">[[range.join.with.view]]</a>
|
| 5372 |
|
| 5373 |
``` cpp
|
| 5374 |
namespace std::ranges {
|
| 5375 |
-
template<class R, class P>
|
| 5376 |
-
concept compatible-joinable-ranges = // exposition only
|
| 5377 |
-
common_with<range_value_t<R>, range_value_t<P>> &&
|
| 5378 |
-
common_reference_with<range_reference_t<R>, range_reference_t<P>> &&
|
| 5379 |
-
common_reference_with<range_rvalue_reference_t<R>, range_rvalue_reference_t<P>>;
|
| 5380 |
-
|
| 5381 |
template<class R>
|
| 5382 |
concept bidirectional-common = bidirectional_range<R> && common_range<R>; // exposition only
|
| 5383 |
|
| 5384 |
template<input_range V, forward_range Pattern>
|
| 5385 |
requires view<V> && input_range<range_reference_t<V>>
|
| 5386 |
&& view<Pattern>
|
| 5387 |
-
&&
|
| 5388 |
class join_with_view : public view_interface<join_with_view<V, Pattern>> {
|
| 5389 |
using InnerRng = range_reference_t<V>; // exposition only
|
| 5390 |
|
| 5391 |
V base_ = V(); // exposition only
|
| 5392 |
non-propagating-cache<iterator_t<V>> outer_it_; // exposition only, present only
|
|
@@ -5428,11 +5602,12 @@ namespace std::ranges {
|
|
| 5428 |
}
|
| 5429 |
constexpr auto begin() const
|
| 5430 |
requires forward_range<const V> &&
|
| 5431 |
forward_range<const Pattern> &&
|
| 5432 |
is_reference_v<range_reference_t<const V>> &&
|
| 5433 |
-
input_range<range_reference_t<const V>>
|
|
|
|
| 5434 |
return iterator<true>{*this, ranges::begin(base_)};
|
| 5435 |
}
|
| 5436 |
|
| 5437 |
constexpr auto end() {
|
| 5438 |
if constexpr (forward_range<V> &&
|
|
@@ -5443,11 +5618,12 @@ namespace std::ranges {
|
|
| 5443 |
return sentinel<simple-view<V> && simple-view<Pattern>>{*this};
|
| 5444 |
}
|
| 5445 |
constexpr auto end() const
|
| 5446 |
requires forward_range<const V> && forward_range<const Pattern> &&
|
| 5447 |
is_reference_v<range_reference_t<const V>> &&
|
| 5448 |
-
input_range<range_reference_t<const V>>
|
|
|
|
| 5449 |
using InnerConstRng = range_reference_t<const V>;
|
| 5450 |
if constexpr (forward_range<InnerConstRng> &&
|
| 5451 |
common_range<const V> && common_range<InnerConstRng>)
|
| 5452 |
return iterator<true>{*this, ranges::end(base_)};
|
| 5453 |
else
|
|
@@ -5485,11 +5661,11 @@ and *pattern\_* with `views::single(std::move(e))`.
|
|
| 5485 |
|
| 5486 |
``` cpp
|
| 5487 |
namespace std::ranges {
|
| 5488 |
template<input_range V, forward_range Pattern>
|
| 5489 |
requires view<V> && input_range<range_reference_t<V>>
|
| 5490 |
-
&& view<Pattern> &&
|
| 5491 |
template<bool Const>
|
| 5492 |
class join_with_view<V, Pattern>::iterator {
|
| 5493 |
using Parent = maybe-const<Const, join_with_view>; // exposition only
|
| 5494 |
using Base = maybe-const<Const, V>; // exposition only
|
| 5495 |
using InnerBase = range_reference_t<Base>; // exposition only
|
|
@@ -5588,11 +5764,11 @@ as follows:
|
|
| 5588 |
iter_reference_t<PatternIter>>>
|
| 5589 |
```
|
| 5590 |
|
| 5591 |
is `false`, `iterator_category` denotes `input_iterator_tag`.
|
| 5592 |
- Otherwise, if *OUTERC*, *INNERC*, and *PATTERNC* each model
|
| 5593 |
-
`derived_from<
|
| 5594 |
*`PatternBase`* each model `common_range`, `iterator_category` denotes
|
| 5595 |
`bidirectional_iterator_tag`.
|
| 5596 |
- Otherwise, if *OUTERC*, *INNERC*, and *PATTERNC* each model
|
| 5597 |
`derived_from<forward_iterator_tag>`, `iterator_category` denotes
|
| 5598 |
`forward_iterator_tag`.
|
|
@@ -5656,20 +5832,20 @@ constexpr void satisfy();
|
|
| 5656 |
``` cpp
|
| 5657 |
while (true) {
|
| 5658 |
if (inner_it_.index() == 0) {
|
| 5659 |
if (std::get<0>(inner_it_) != ranges::end(parent_->pattern_))
|
| 5660 |
break;
|
| 5661 |
-
inner_it_.emplace<1>(ranges::begin(update-inner()));
|
| 5662 |
} else {
|
| 5663 |
if (std::get<1>(inner_it_) != ranges::end(get-inner()))
|
| 5664 |
break;
|
| 5665 |
if (++outer() == ranges::end(parent_->base_)) {
|
| 5666 |
if constexpr (ref-is-glvalue)
|
| 5667 |
-
inner_it_.emplace<0>();
|
| 5668 |
break;
|
| 5669 |
}
|
| 5670 |
-
inner_it_.emplace<0>(ranges::begin(parent_->pattern_));
|
| 5671 |
}
|
| 5672 |
}
|
| 5673 |
```
|
| 5674 |
|
| 5675 |
[*Note 1*: `join_with_view` iterators use the *satisfy* function to
|
|
@@ -5686,11 +5862,11 @@ constexpr explicit iterator(Parent& parent)
|
|
| 5686 |
first overload, also initializes *outer_it\_* with `std::move(outer)`.
|
| 5687 |
Then, equivalent to:
|
| 5688 |
|
| 5689 |
``` cpp
|
| 5690 |
if (outer() != ranges::end(parent_->base_)) {
|
| 5691 |
-
inner_it_.emplace<1>(ranges::begin(update-inner()));
|
| 5692 |
satisfy();
|
| 5693 |
}
|
| 5694 |
```
|
| 5695 |
|
| 5696 |
``` cpp
|
|
@@ -5703,13 +5879,13 @@ constexpr iterator(iterator<!Const> i)
|
|
| 5703 |
*Effects:* Initializes *outer_it\_* with `std::move(i.`*`outer_it_`*`)`
|
| 5704 |
and *parent\_* with `i.`*`parent_`*. Then, equivalent to:
|
| 5705 |
|
| 5706 |
``` cpp
|
| 5707 |
if (i.inner_it_.index() == 0)
|
| 5708 |
-
inner_it_.emplace<0>(std::get<0>(std::move(i.inner_it_)));
|
| 5709 |
else
|
| 5710 |
-
inner_it_.emplace<1>(std::get<1>(std::move(i.inner_it_)));
|
| 5711 |
```
|
| 5712 |
|
| 5713 |
[*Note 2*: `Const` can only be `true` when *Base* models
|
| 5714 |
`forward_range`. — *end note*]
|
| 5715 |
|
|
@@ -5765,27 +5941,27 @@ constexpr iterator& operator--()
|
|
| 5765 |
*Effects:* Equivalent to:
|
| 5766 |
|
| 5767 |
``` cpp
|
| 5768 |
if (outer_it_ == ranges::end(parent_->base_)) {
|
| 5769 |
auto&& inner = *--outer_it_;
|
| 5770 |
-
inner_it_.emplace<1>(ranges::end(inner));
|
| 5771 |
}
|
| 5772 |
|
| 5773 |
while (true) {
|
| 5774 |
if (inner_it_.index() == 0) {
|
| 5775 |
auto& it = std::get<0>(inner_it_);
|
| 5776 |
if (it == ranges::begin(parent_->pattern_)) {
|
| 5777 |
auto&& inner = *--outer_it_;
|
| 5778 |
-
inner_it_.emplace<1>(ranges::end(inner));
|
| 5779 |
} else {
|
| 5780 |
break;
|
| 5781 |
}
|
| 5782 |
} else {
|
| 5783 |
auto& it = std::get<1>(inner_it_);
|
| 5784 |
auto&& inner = *outer_it_;
|
| 5785 |
if (it == ranges::begin(inner)) {
|
| 5786 |
-
inner_it_.emplace<0>(ranges::end(parent_->pattern_));
|
| 5787 |
} else {
|
| 5788 |
break;
|
| 5789 |
}
|
| 5790 |
}
|
| 5791 |
}
|
|
@@ -5823,11 +5999,11 @@ return x.outer_it_ == y.outer_it_ && x.inner_it_ == y.inner_it_;
|
|
| 5823 |
|
| 5824 |
``` cpp
|
| 5825 |
namespace std::ranges {
|
| 5826 |
template<input_range V, forward_range Pattern>
|
| 5827 |
requires view<V> && input_range<range_reference_t<V>>
|
| 5828 |
-
&& view<Pattern> &&
|
| 5829 |
template<bool Const>
|
| 5830 |
class join_with_view<V, Pattern>::sentinel {
|
| 5831 |
using Parent = maybe-const<Const, join_with_view>; // exposition only
|
| 5832 |
using Base = maybe-const<Const, V>; // exposition only
|
| 5833 |
sentinel_t<Base> end_ = sentinel_t<Base>(); // exposition only
|
|
@@ -6072,12 +6248,13 @@ constexpr outer-iterator(Parent& parent, iterator_t<Base> current)
|
|
| 6072 |
``` cpp
|
| 6073 |
constexpr outer-iterator(outer-iterator<!Const> i)
|
| 6074 |
requires Const && convertible_to<iterator_t<V>, iterator_t<Base>>;
|
| 6075 |
```
|
| 6076 |
|
| 6077 |
-
*Effects:* Initializes *parent\_* with `i.`*`parent_`*
|
| 6078 |
-
|
|
|
|
| 6079 |
|
| 6080 |
``` cpp
|
| 6081 |
constexpr value_type operator*() const;
|
| 6082 |
```
|
| 6083 |
|
|
@@ -6152,14 +6329,13 @@ namespace std::ranges {
|
|
| 6152 |
struct lazy_split_view<V, Pattern>::outer-iterator<Const>::value_type
|
| 6153 |
: view_interface<value_type> {
|
| 6154 |
private:
|
| 6155 |
outer-iterator i_ = outer-iterator(); // exposition only
|
| 6156 |
|
| 6157 |
-
|
| 6158 |
-
value_type() = default;
|
| 6159 |
-
constexpr explicit value_type(outer-iterator i);
|
| 6160 |
|
|
|
|
| 6161 |
constexpr inner-iterator<Const> begin() const;
|
| 6162 |
constexpr default_sentinel_t end() const noexcept;
|
| 6163 |
};
|
| 6164 |
}
|
| 6165 |
```
|
|
@@ -6197,11 +6373,11 @@ namespace std::ranges {
|
|
| 6197 |
using Base = maybe-const<Const, V>; // exposition only
|
| 6198 |
outer-iterator<Const> i_ = outer-iterator<Const>(); // exposition only
|
| 6199 |
bool incremented_ = false; // exposition only
|
| 6200 |
|
| 6201 |
public:
|
| 6202 |
-
using iterator_concept =
|
| 6203 |
|
| 6204 |
using iterator_category = see belownc; // present only if Base
|
| 6205 |
// models forward_range
|
| 6206 |
using value_type = range_value_t<Base>;
|
| 6207 |
using difference_type = range_difference_t<Base>;
|
|
@@ -6492,17 +6668,17 @@ constexpr iterator(split_view& parent, iterator_t<V> current, subrange<iterator_
|
|
| 6492 |
|
| 6493 |
``` cpp
|
| 6494 |
constexpr iterator_t<V> base() const;
|
| 6495 |
```
|
| 6496 |
|
| 6497 |
-
*Effects:* Equivalent to `return `*`cur_`*`;`
|
| 6498 |
|
| 6499 |
``` cpp
|
| 6500 |
constexpr value_type operator*() const;
|
| 6501 |
```
|
| 6502 |
|
| 6503 |
-
*Effects:* Equivalent to `return {`*`cur_`*`, `*`next_`*`.begin()};`
|
| 6504 |
|
| 6505 |
``` cpp
|
| 6506 |
constexpr iterator& operator++();
|
| 6507 |
```
|
| 6508 |
|
|
@@ -6577,10 +6753,798 @@ friend constexpr bool operator==(const iterator& x, const sentinel& y);
|
|
| 6577 |
```
|
| 6578 |
|
| 6579 |
*Effects:* Equivalent to:
|
| 6580 |
`return x.`*`cur_`*` == y.`*`end_`*` && !x.`*`trailing_empty_`*`;`
|
| 6581 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6582 |
### Counted view <a id="range.counted">[[range.counted]]</a>
|
| 6583 |
|
| 6584 |
A counted view presents a view of the elements of the counted range
|
| 6585 |
[[iterator.requirements.general]] `i`+\[0, `n`) for an iterator `i` and
|
| 6586 |
non-negative integer `n`.
|
|
@@ -6657,11 +7621,11 @@ namespace std::ranges {
|
|
| 6657 |
constexpr explicit common_view(V r);
|
| 6658 |
|
| 6659 |
constexpr V base() const & requires copy_constructible<V> { return base_; }
|
| 6660 |
constexpr V base() && { return std::move(base_); }
|
| 6661 |
|
| 6662 |
-
constexpr auto begin() {
|
| 6663 |
if constexpr (random_access_range<V> && sized_range<V>)
|
| 6664 |
return ranges::begin(base_);
|
| 6665 |
else
|
| 6666 |
return common_iterator<iterator_t<V>, sentinel_t<V>>(ranges::begin(base_));
|
| 6667 |
}
|
|
@@ -6671,11 +7635,11 @@ namespace std::ranges {
|
|
| 6671 |
return ranges::begin(base_);
|
| 6672 |
else
|
| 6673 |
return common_iterator<iterator_t<const V>, sentinel_t<const V>>(ranges::begin(base_));
|
| 6674 |
}
|
| 6675 |
|
| 6676 |
-
constexpr auto end() {
|
| 6677 |
if constexpr (random_access_range<V> && sized_range<V>)
|
| 6678 |
return ranges::begin(base_) + ranges::distance(base_);
|
| 6679 |
else
|
| 6680 |
return common_iterator<iterator_t<V>, sentinel_t<V>>(ranges::end(base_));
|
| 6681 |
}
|
|
@@ -6691,10 +7655,17 @@ namespace std::ranges {
|
|
| 6691 |
return ranges::size(base_);
|
| 6692 |
}
|
| 6693 |
constexpr auto size() const requires sized_range<const V> {
|
| 6694 |
return ranges::size(base_);
|
| 6695 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6696 |
};
|
| 6697 |
|
| 6698 |
template<class R>
|
| 6699 |
common_view(R&&) -> common_view<views::all_t<R>>;
|
| 6700 |
}
|
|
@@ -6716,25 +7687,20 @@ iterates the same elements in reverse order.
|
|
| 6716 |
The name `views::reverse` denotes a range adaptor object
|
| 6717 |
[[range.adaptor.object]]. Given a subexpression `E`, the expression
|
| 6718 |
`views::reverse(E)` is expression-equivalent to:
|
| 6719 |
|
| 6720 |
- If the type of `E` is a (possibly cv-qualified) specialization of
|
| 6721 |
-
`reverse_view`,
|
| 6722 |
- Otherwise, if the type of `E` is cv
|
| 6723 |
`subrange<reverse_iterator<I>, reverse_iterator<I>, K>` for some
|
| 6724 |
iterator type `I` and value `K` of type `subrange_kind`,
|
| 6725 |
-
- if `K` is `subrange_kind::sized`,
|
| 6726 |
-
`
|
| 6727 |
-
|
| 6728 |
-
```
|
| 6729 |
-
- otherwise, equivalent to:
|
| 6730 |
-
``` cpp
|
| 6731 |
-
subrange<I, I, K>(E.end().base(), E.begin().base())
|
| 6732 |
-
```
|
| 6733 |
|
| 6734 |
However, in either case `E` is evaluated only once.
|
| 6735 |
-
- Otherwise,
|
| 6736 |
|
| 6737 |
[*Example 1*:
|
| 6738 |
|
| 6739 |
``` cpp
|
| 6740 |
vector<int> is {0,1,2,3,4};
|
|
@@ -6774,10 +7740,17 @@ namespace std::ranges {
|
|
| 6774 |
}
|
| 6775 |
|
| 6776 |
constexpr auto size() const requires sized_range<const V> {
|
| 6777 |
return ranges::size(base_);
|
| 6778 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6779 |
};
|
| 6780 |
|
| 6781 |
template<class R>
|
| 6782 |
reverse_view(R&&) -> reverse_view<views::all_t<R>>;
|
| 6783 |
}
|
|
@@ -6878,10 +7851,15 @@ namespace std::ranges {
|
|
| 6878 |
constexpr auto end() requires (!simple-view<V>) { return ranges::cend(base_); }
|
| 6879 |
constexpr auto end() const requires range<const V> { return ranges::cend(base_); }
|
| 6880 |
|
| 6881 |
constexpr auto size() requires sized_range<V> { return ranges::size(base_); }
|
| 6882 |
constexpr auto size() const requires sized_range<const V> { return ranges::size(base_); }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6883 |
};
|
| 6884 |
|
| 6885 |
template<class R>
|
| 6886 |
as_const_view(R&&) -> as_const_view<views::all_t<R>>;
|
| 6887 |
}
|
|
@@ -7002,10 +7980,16 @@ namespace std::ranges {
|
|
| 7002 |
{ return ranges::size(base_); }
|
| 7003 |
|
| 7004 |
constexpr auto size() const requires sized_range<const V>
|
| 7005 |
{ return ranges::size(base_); }
|
| 7006 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7007 |
private:
|
| 7008 |
// [range.elements.iterator], class template elements_view::iterator
|
| 7009 |
template<bool> class iterator; // exposition only
|
| 7010 |
|
| 7011 |
// [range.elements.sentinel], class template elements_view::sentinel
|
|
@@ -7394,13 +8378,13 @@ friend constexpr range_difference_t<maybe-const<OtherConst, V>>
|
|
| 7394 |
#### Overview <a id="range.enumerate.overview">[[range.enumerate.overview]]</a>
|
| 7395 |
|
| 7396 |
`enumerate_view` is a view whose elements represent both the position
|
| 7397 |
and value from a sequence of elements.
|
| 7398 |
|
| 7399 |
-
The name `views::enumerate` denotes a range adaptor object
|
| 7400 |
-
subexpression `E`, the expression
|
| 7401 |
-
expression-equivalent to
|
| 7402 |
`enumerate_view<views::all_t<decltype((E))>>(E)`.
|
| 7403 |
|
| 7404 |
[*Example 1*:
|
| 7405 |
|
| 7406 |
``` cpp
|
|
@@ -7436,27 +8420,32 @@ namespace std::ranges {
|
|
| 7436 |
{ return iterator<false>(ranges::begin(base_), 0); }
|
| 7437 |
constexpr auto begin() const requires range-with-movable-references<const V>
|
| 7438 |
{ return iterator<true>(ranges::begin(base_), 0); }
|
| 7439 |
|
| 7440 |
constexpr auto end() requires (!simple-view<V>) {
|
| 7441 |
-
if constexpr (common_range<V> && sized_range<V>)
|
| 7442 |
return iterator<false>(ranges::end(base_), ranges::distance(base_));
|
| 7443 |
else
|
| 7444 |
return sentinel<false>(ranges::end(base_));
|
| 7445 |
}
|
| 7446 |
constexpr auto end() const requires range-with-movable-references<const V> {
|
| 7447 |
-
if constexpr (common_range<const V> && sized_range<const V>)
|
| 7448 |
return iterator<true>(ranges::end(base_), ranges::distance(base_));
|
| 7449 |
else
|
| 7450 |
return sentinel<true>(ranges::end(base_));
|
| 7451 |
}
|
| 7452 |
|
| 7453 |
constexpr auto size() requires sized_range<V>
|
| 7454 |
{ return ranges::size(base_); }
|
| 7455 |
constexpr auto size() const requires sized_range<const V>
|
| 7456 |
{ return ranges::size(base_); }
|
| 7457 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7458 |
constexpr V base() const & requires copy_constructible<V> { return base_; }
|
| 7459 |
constexpr V base() && { return std::move(base_); }
|
| 7460 |
};
|
| 7461 |
|
| 7462 |
template<class R>
|
|
@@ -7532,11 +8521,11 @@ namespace std::ranges {
|
|
| 7532 |
requires random_access_range<Base>;
|
| 7533 |
friend constexpr iterator operator+(difference_type x, const iterator& y)
|
| 7534 |
requires random_access_range<Base>;
|
| 7535 |
friend constexpr iterator operator-(const iterator& x, difference_type y)
|
| 7536 |
requires random_access_range<Base>;
|
| 7537 |
-
friend constexpr difference_type operator-(const iterator& x, const iterator& y);
|
| 7538 |
|
| 7539 |
friend constexpr auto iter_move(const iterator& i)
|
| 7540 |
noexcept(noexcept(ranges::iter_move(i.current_)) &&
|
| 7541 |
is_nothrow_move_constructible_v<range_rvalue_reference_t<Base>>) {
|
| 7542 |
return tuple<difference_type,
|
|
@@ -7714,11 +8703,11 @@ auto temp = x;
|
|
| 7714 |
temp -= y;
|
| 7715 |
return temp;
|
| 7716 |
```
|
| 7717 |
|
| 7718 |
``` cpp
|
| 7719 |
-
friend constexpr difference_type operator-(const iterator& x, const iterator& y);
|
| 7720 |
```
|
| 7721 |
|
| 7722 |
*Effects:* Equivalent to: `return x.`*`pos_`*` - y.`*`pos_`*`;`
|
| 7723 |
|
| 7724 |
#### Class template `enumerate_view::sentinel` <a id="range.enumerate.sentinel">[[range.enumerate.sentinel]]</a>
|
|
@@ -7925,20 +8914,10 @@ return apply([](auto... sizes) {
|
|
| 7925 |
|
| 7926 |
#### Class template `zip_view::iterator` <a id="range.zip.iterator">[[range.zip.iterator]]</a>
|
| 7927 |
|
| 7928 |
``` cpp
|
| 7929 |
namespace std::ranges {
|
| 7930 |
-
template<bool Const, class... Views>
|
| 7931 |
-
concept all-random-access = // exposition only
|
| 7932 |
-
(random_access_range<maybe-const<Const, Views>> && ...);
|
| 7933 |
-
template<bool Const, class... Views>
|
| 7934 |
-
concept all-bidirectional = // exposition only
|
| 7935 |
-
(bidirectional_range<maybe-const<Const, Views>> && ...);
|
| 7936 |
-
template<bool Const, class... Views>
|
| 7937 |
-
concept all-forward = // exposition only
|
| 7938 |
-
(forward_range<maybe-const<Const, Views>> && ...);
|
| 7939 |
-
|
| 7940 |
template<input_range... Views>
|
| 7941 |
requires (view<Views> && ...) && (sizeof...(Views) > 0)
|
| 7942 |
template<bool Const>
|
| 7943 |
class zip_view<Views...>::iterator {
|
| 7944 |
tuple<iterator_t<maybe-const<Const, Views>>...> current_; // exposition only
|
|
@@ -8305,11 +9284,11 @@ template<bool OtherConst>
|
|
| 8305 |
iterator_t<maybe-const<OtherConst, Views>>> && ...)
|
| 8306 |
friend constexpr common_type_t<range_difference_t<maybe-const<OtherConst, Views>>...>
|
| 8307 |
operator-(const sentinel& y, const iterator<OtherConst>& x);
|
| 8308 |
```
|
| 8309 |
|
| 8310 |
-
*Effects:* Equivalent to `return -(x - y);`
|
| 8311 |
|
| 8312 |
### Zip transform view <a id="range.zip.transform">[[range.zip.transform]]</a>
|
| 8313 |
|
| 8314 |
#### Overview <a id="range.zip.transform.overview">[[range.zip.transform.overview]]</a>
|
| 8315 |
|
|
@@ -8440,11 +9419,11 @@ namespace std::ranges {
|
|
| 8440 |
|
| 8441 |
constexpr iterator(Parent& parent, ziperator<Const> inner); // exposition only
|
| 8442 |
|
| 8443 |
public:
|
| 8444 |
using iterator_category = see belownc; // not always present
|
| 8445 |
-
using iterator_concept =
|
| 8446 |
using value_type =
|
| 8447 |
remove_cvref_t<invoke_result_t<maybe-const<Const, F>&,
|
| 8448 |
range_reference_t<maybe-const<Const, Views>>...>>;
|
| 8449 |
using difference_type = range_difference_t<Base>;
|
| 8450 |
|
|
@@ -8743,11 +9722,12 @@ resulting view is empty.
|
|
| 8743 |
The name `views::adjacent<N>` denotes a range adaptor object
|
| 8744 |
[[range.adaptor.object]]. Given a subexpression `E` and a constant
|
| 8745 |
expression `N`, the expression `views::adjacent<N>(E)` is
|
| 8746 |
expression-equivalent to
|
| 8747 |
|
| 8748 |
-
- `((void)E, auto(views::empty<tuple<>>))` if `N` is equal to `0`
|
|
|
|
| 8749 |
- otherwise, `adjacent_view<views::all_t<decltype((E))>, N>(E)`.
|
| 8750 |
|
| 8751 |
[*Example 1*:
|
| 8752 |
|
| 8753 |
``` cpp
|
|
@@ -8811,10 +9791,13 @@ namespace std::ranges {
|
|
| 8811 |
}
|
| 8812 |
}
|
| 8813 |
|
| 8814 |
constexpr auto size() requires sized_range<V>;
|
| 8815 |
constexpr auto size() const requires sized_range<const V>;
|
|
|
|
|
|
|
|
|
|
| 8816 |
};
|
| 8817 |
}
|
| 8818 |
```
|
| 8819 |
|
| 8820 |
``` cpp
|
|
@@ -8836,10 +9819,25 @@ using CT = common_type_t<ST, size_t>;
|
|
| 8836 |
auto sz = static_cast<CT>(ranges::size(base_));
|
| 8837 |
sz -= std::min<CT>(sz, N - 1);
|
| 8838 |
return static_cast<ST>(sz);
|
| 8839 |
```
|
| 8840 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8841 |
#### Class template `adjacent_view::iterator` <a id="range.adjacent.iterator">[[range.adjacent.iterator]]</a>
|
| 8842 |
|
| 8843 |
``` cpp
|
| 8844 |
namespace std::ranges {
|
| 8845 |
template<forward_range V, size_t N>
|
|
@@ -9232,13 +10230,14 @@ resulting view is empty.
|
|
| 9232 |
|
| 9233 |
The name `views::adjacent_transform<N>` denotes a range adaptor object
|
| 9234 |
[[range.adaptor.object]]. Given subexpressions `E` and `F` and a
|
| 9235 |
constant expression `N`:
|
| 9236 |
|
| 9237 |
-
- If `N` is equal to `0`
|
| 9238 |
-
|
| 9239 |
-
|
|
|
|
| 9240 |
- Otherwise, the expression `views::adjacent_transform<N>(E, F)` is
|
| 9241 |
expression-equivalent to
|
| 9242 |
`adjacent_transform_view<views::all_t<decltype((E))>, decay_t<decltype((F))>, N>(E, F)`.
|
| 9243 |
|
| 9244 |
[*Example 1*:
|
|
@@ -9279,11 +10278,11 @@ namespace std::ranges {
|
|
| 9279 |
|
| 9280 |
public:
|
| 9281 |
adjacent_transform_view() = default;
|
| 9282 |
constexpr explicit adjacent_transform_view(V base, F fun);
|
| 9283 |
|
| 9284 |
-
constexpr V base() const & requires copy_constructible<
|
| 9285 |
constexpr V base() && { return std::move(inner_).base(); }
|
| 9286 |
|
| 9287 |
constexpr auto begin() {
|
| 9288 |
return iterator<false>(*this, inner_.begin());
|
| 9289 |
}
|
|
@@ -9317,10 +10316,18 @@ namespace std::ranges {
|
|
| 9317 |
}
|
| 9318 |
|
| 9319 |
constexpr auto size() const requires sized_range<const InnerView> {
|
| 9320 |
return inner_.size();
|
| 9321 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9322 |
};
|
| 9323 |
}
|
| 9324 |
```
|
| 9325 |
|
| 9326 |
``` cpp
|
|
@@ -9347,11 +10354,11 @@ namespace std::ranges {
|
|
| 9347 |
|
| 9348 |
constexpr iterator(Parent& parent, inner-iterator<Const> inner); // exposition only
|
| 9349 |
|
| 9350 |
public:
|
| 9351 |
using iterator_category = see below;
|
| 9352 |
-
using iterator_concept =
|
| 9353 |
using value_type =
|
| 9354 |
remove_cvref_t<invoke_result_t<maybe-const<Const, F>&,
|
| 9355 |
REPEAT(range_reference_t<Base>, N)...>>;
|
| 9356 |
using difference_type = range_difference_t<Base>;
|
| 9357 |
|
|
@@ -9621,11 +10628,11 @@ constexpr sentinel(sentinel<!Const> i)
|
|
| 9621 |
template<bool OtherConst>
|
| 9622 |
requires sentinel_for<inner-sentinel<Const>, inner-iterator<OtherConst>>
|
| 9623 |
friend constexpr bool operator==(const iterator<OtherConst>& x, const sentinel& y);
|
| 9624 |
```
|
| 9625 |
|
| 9626 |
-
*Effects:* Equivalent to `return x.`*`inner_`*` == y.`*`inner_`*`;`
|
| 9627 |
|
| 9628 |
``` cpp
|
| 9629 |
template<bool OtherConst>
|
| 9630 |
requires sized_sentinel_for<inner-sentinel<Const>, inner-iterator<OtherConst>>
|
| 9631 |
friend constexpr range_difference_t<maybe-const<OtherConst, InnerView>>
|
|
@@ -9635,11 +10642,11 @@ template<bool OtherConst>
|
|
| 9635 |
requires sized_sentinel_for<inner-sentinel<Const>, inner-iterator<OtherConst>>
|
| 9636 |
friend constexpr range_difference_t<maybe-const<OtherConst, InnerView>>
|
| 9637 |
operator-(const sentinel& x, const iterator<OtherConst>& y);
|
| 9638 |
```
|
| 9639 |
|
| 9640 |
-
*Effects:* Equivalent to `return x.`*`inner_`*` - y.`*`inner_`*`;`
|
| 9641 |
|
| 9642 |
### Chunk view <a id="range.chunk">[[range.chunk]]</a>
|
| 9643 |
|
| 9644 |
#### Overview <a id="range.chunk.overview">[[range.chunk.overview]]</a>
|
| 9645 |
|
|
@@ -9708,10 +10715,13 @@ namespace std::ranges {
|
|
| 9708 |
constexpr outer-iterator begin();
|
| 9709 |
constexpr default_sentinel_t end() const noexcept;
|
| 9710 |
|
| 9711 |
constexpr auto size() requires sized_range<V>;
|
| 9712 |
constexpr auto size() const requires sized_range<const V>;
|
|
|
|
|
|
|
|
|
|
| 9713 |
};
|
| 9714 |
|
| 9715 |
template<class R>
|
| 9716 |
chunk_view(R&&, range_difference_t<R>) -> chunk_view<views::all_t<R>>;
|
| 9717 |
}
|
|
@@ -9753,10 +10763,22 @@ constexpr auto size() const requires sized_range<const V>;
|
|
| 9753 |
|
| 9754 |
``` cpp
|
| 9755 |
return to-unsigned-like(div-ceil(ranges::distance(base_), n_));
|
| 9756 |
```
|
| 9757 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9758 |
#### Class `chunk_view::outer-iterator` <a id="range.chunk.outer.iter">[[range.chunk.outer.iter]]</a>
|
| 9759 |
|
| 9760 |
``` cpp
|
| 9761 |
namespace std::ranges {
|
| 9762 |
template<view V>
|
|
@@ -9872,10 +10894,12 @@ namespace std::ranges {
|
|
| 9872 |
constexpr inner-iterator begin() const noexcept;
|
| 9873 |
constexpr default_sentinel_t end() const noexcept;
|
| 9874 |
|
| 9875 |
constexpr auto size() const
|
| 9876 |
requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>;
|
|
|
|
|
|
|
| 9877 |
};
|
| 9878 |
}
|
| 9879 |
```
|
| 9880 |
|
| 9881 |
``` cpp
|
|
@@ -9906,10 +10930,20 @@ constexpr auto size() const
|
|
| 9906 |
``` cpp
|
| 9907 |
return to-unsigned-like(ranges::min(parent_->remainder_,
|
| 9908 |
ranges::end(parent_->base_) - *parent_->current_));
|
| 9909 |
```
|
| 9910 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9911 |
#### Class `chunk_view::inner-iterator` <a id="range.chunk.inner.iter">[[range.chunk.inner.iter]]</a>
|
| 9912 |
|
| 9913 |
``` cpp
|
| 9914 |
namespace std::ranges {
|
| 9915 |
template<view V>
|
|
@@ -10084,10 +11118,13 @@ namespace std::ranges {
|
|
| 10084 |
}
|
| 10085 |
}
|
| 10086 |
|
| 10087 |
constexpr auto size() requires sized_range<V>;
|
| 10088 |
constexpr auto size() const requires sized_range<const V>;
|
|
|
|
|
|
|
|
|
|
| 10089 |
};
|
| 10090 |
}
|
| 10091 |
```
|
| 10092 |
|
| 10093 |
``` cpp
|
|
@@ -10108,10 +11145,22 @@ constexpr auto size() const requires sized_range<const V>;
|
|
| 10108 |
|
| 10109 |
``` cpp
|
| 10110 |
return to-unsigned-like(div-ceil(ranges::distance(base_), n_));
|
| 10111 |
```
|
| 10112 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10113 |
#### Class template `chunk_view::iterator` for forward ranges <a id="range.chunk.fwd.iter">[[range.chunk.fwd.iter]]</a>
|
| 10114 |
|
| 10115 |
``` cpp
|
| 10116 |
namespace std::ranges {
|
| 10117 |
template<view V>
|
|
@@ -10484,10 +11533,13 @@ namespace std::ranges {
|
|
| 10484 |
requires (!(simple-view<V> && slide-caches-nothing<const V>));
|
| 10485 |
constexpr auto end() const requires slide-caches-nothing<const V>;
|
| 10486 |
|
| 10487 |
constexpr auto size() requires sized_range<V>;
|
| 10488 |
constexpr auto size() const requires sized_range<const V>;
|
|
|
|
|
|
|
|
|
|
| 10489 |
};
|
| 10490 |
|
| 10491 |
template<class R>
|
| 10492 |
slide_view(R&&, range_difference_t<R>) -> slide_view<views::all_t<R>>;
|
| 10493 |
}
|
|
@@ -10571,10 +11623,24 @@ constexpr auto size() const requires sized_range<const V>;
|
|
| 10571 |
auto sz = ranges::distance(base_) - n_ + 1;
|
| 10572 |
if (sz < 0) sz = 0;
|
| 10573 |
return to-unsigned-like(sz);
|
| 10574 |
```
|
| 10575 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10576 |
#### Class template `slide_view::iterator` <a id="range.slide.iterator">[[range.slide.iterator]]</a>
|
| 10577 |
|
| 10578 |
``` cpp
|
| 10579 |
namespace std::ranges {
|
| 10580 |
template<forward_range V>
|
|
@@ -11238,10 +12304,13 @@ namespace std::ranges {
|
|
| 11238 |
}
|
| 11239 |
}
|
| 11240 |
|
| 11241 |
constexpr auto size() requires sized_range<V>;
|
| 11242 |
constexpr auto size() const requires sized_range<const V>;
|
|
|
|
|
|
|
|
|
|
| 11243 |
};
|
| 11244 |
|
| 11245 |
template<class R>
|
| 11246 |
stride_view(R&&, range_difference_t<R>) -> stride_view<views::all_t<R>>;
|
| 11247 |
}
|
|
@@ -11271,10 +12340,22 @@ constexpr auto size() const requires sized_range<const V>;
|
|
| 11271 |
|
| 11272 |
``` cpp
|
| 11273 |
return to-unsigned-like(div-ceil(ranges::distance(base_), stride_));
|
| 11274 |
```
|
| 11275 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11276 |
#### Class template `stride_view::iterator` <a id="range.stride.iterator">[[range.stride.iterator]]</a>
|
| 11277 |
|
| 11278 |
``` cpp
|
| 11279 |
namespace std::ranges {
|
| 11280 |
template<input_range V>
|
|
@@ -11432,11 +12513,11 @@ return *this;
|
|
| 11432 |
|
| 11433 |
``` cpp
|
| 11434 |
constexpr void operator++(int);
|
| 11435 |
```
|
| 11436 |
|
| 11437 |
-
*Effects:* Equivalent to
|
| 11438 |
|
| 11439 |
``` cpp
|
| 11440 |
constexpr iterator operator++(int) requires forward_range<Base>;
|
| 11441 |
```
|
| 11442 |
|
|
@@ -11674,11 +12755,11 @@ namespace std::ranges {
|
|
| 11674 |
concept cartesian-product-is-bidirectional = // exposition only
|
| 11675 |
(bidirectional_range<maybe-const<Const, First>> && ... &&
|
| 11676 |
(bidirectional_range<maybe-const<Const, Vs>>
|
| 11677 |
&& cartesian-product-common-arg<maybe-const<Const, Vs>>));
|
| 11678 |
|
| 11679 |
-
template<class First, class...
|
| 11680 |
concept cartesian-product-is-common = // exposition only
|
| 11681 |
cartesian-product-common-arg<First>;
|
| 11682 |
|
| 11683 |
template<class... Vs>
|
| 11684 |
concept cartesian-product-is-sized = // exposition only
|
|
@@ -12217,10 +13298,500 @@ ranges::iter_swap(std::get<i>(l.current_), std::get<i>(r.current_))
|
|
| 12217 |
the following expressions:
|
| 12218 |
|
| 12219 |
- `noexcept(ranges::iter_swap(std::get<`i`>(l.`*`current_`*`), std::get<`i`>(r.`*`current_`*`)))`
|
| 12220 |
for every integer 0 ≤ i ≤ `sizeof...(Vs)`.
|
| 12221 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12222 |
## Range generators <a id="coro.generator">[[coro.generator]]</a>
|
| 12223 |
|
| 12224 |
### Overview <a id="coroutine.generator.overview">[[coroutine.generator.overview]]</a>
|
| 12225 |
|
| 12226 |
Class template `generator` presents a view of the elements yielded by
|
|
@@ -12252,29 +13823,29 @@ void f() {
|
|
| 12252 |
### Header `<generator>` synopsis <a id="generator.syn">[[generator.syn]]</a>
|
| 12253 |
|
| 12254 |
``` cpp
|
| 12255 |
namespace std {
|
| 12256 |
// [coro.generator.class], class template generator
|
| 12257 |
-
template<class Ref, class
|
| 12258 |
class generator;
|
| 12259 |
|
| 12260 |
namespace pmr {
|
| 12261 |
-
template<class
|
| 12262 |
-
using generator = std::generator<
|
| 12263 |
}
|
| 12264 |
}
|
| 12265 |
```
|
| 12266 |
|
| 12267 |
### Class template `generator` <a id="coro.generator.class">[[coro.generator.class]]</a>
|
| 12268 |
|
| 12269 |
``` cpp
|
| 12270 |
namespace std {
|
| 12271 |
-
template<class Ref, class
|
| 12272 |
-
class generator : public ranges::view_interface<generator<Ref,
|
| 12273 |
private:
|
| 12274 |
-
using value = conditional_t<is_void_v<
|
| 12275 |
-
using reference = conditional_t<is_void_v<
|
| 12276 |
|
| 12277 |
// [coro.generator.iterator], class generator::iterator
|
| 12278 |
class iterator; // exposition only
|
| 12279 |
|
| 12280 |
public:
|
|
@@ -12333,11 +13904,11 @@ undefined.
|
|
| 12333 |
generator(generator&& other) noexcept;
|
| 12334 |
```
|
| 12335 |
|
| 12336 |
*Effects:* Initializes *coroutine\_* with
|
| 12337 |
`exchange(other.`*`coroutine_`*`, {})` and *active\_* with
|
| 12338 |
-
`exchange(other.active_, nullptr)`.
|
| 12339 |
|
| 12340 |
[*Note 1*: Iterators previously obtained from `other` are not
|
| 12341 |
invalidated; they become iterators into `*this`. — *end note*]
|
| 12342 |
|
| 12343 |
``` cpp
|
|
@@ -12397,12 +13968,12 @@ default_sentinel_t end() const noexcept;
|
|
| 12397 |
|
| 12398 |
### Class `generator::promise_type` <a id="coro.generator.promise">[[coro.generator.promise]]</a>
|
| 12399 |
|
| 12400 |
``` cpp
|
| 12401 |
namespace std {
|
| 12402 |
-
template<class Ref, class
|
| 12403 |
-
class generator<Ref,
|
| 12404 |
public:
|
| 12405 |
generator get_return_object() noexcept;
|
| 12406 |
|
| 12407 |
suspend_always initial_suspend() const noexcept { return {}; }
|
| 12408 |
auto final_suspend() noexcept;
|
|
@@ -12414,29 +13985,30 @@ namespace std {
|
|
| 12414 |
constructible_from<remove_cvref_t<yielded>, const remove_reference_t<yielded>&>;
|
| 12415 |
|
| 12416 |
template<class R2, class V2, class Alloc2, class Unused>
|
| 12417 |
requires same_as<typename generator<R2, V2, Alloc2>::yielded, yielded>
|
| 12418 |
auto yield_value(ranges::elements_of<generator<R2, V2, Alloc2>&&, Unused> g) noexcept;
|
|
|
|
|
|
|
|
|
|
| 12419 |
|
| 12420 |
template<ranges::input_range R, class Alloc>
|
| 12421 |
requires convertible_to<ranges::range_reference_t<R>, yielded>
|
| 12422 |
-
auto yield_value(ranges::elements_of<R, Alloc> r)
|
| 12423 |
|
| 12424 |
void await_transform() = delete;
|
| 12425 |
|
| 12426 |
void return_void() const noexcept {}
|
| 12427 |
void unhandled_exception();
|
| 12428 |
|
| 12429 |
void* operator new(size_t size)
|
| 12430 |
requires same_as<Allocator, void> || default_initializable<Allocator>;
|
| 12431 |
|
| 12432 |
template<class Alloc, class... Args>
|
| 12433 |
-
requires same_as<Allocator, void> || convertible_to<const Alloc&, Allocator>
|
| 12434 |
void* operator new(size_t size, allocator_arg_t, const Alloc& alloc, const Args&...);
|
| 12435 |
|
| 12436 |
template<class This, class Alloc, class... Args>
|
| 12437 |
-
requires same_as<Allocator, void> || convertible_to<const Alloc&, Allocator>
|
| 12438 |
void* operator new(size_t size, const This&, allocator_arg_t, const Alloc& alloc,
|
| 12439 |
const Args&...);
|
| 12440 |
|
| 12441 |
void operator delete(void* pointer, size_t size) noexcept;
|
| 12442 |
|
|
@@ -12503,10 +14075,13 @@ object.
|
|
| 12503 |
|
| 12504 |
``` cpp
|
| 12505 |
template<class R2, class V2, class Alloc2, class Unused>
|
| 12506 |
requires same_as<typename generator<R2, V2, Alloc2>::yielded, yielded>
|
| 12507 |
auto yield_value(ranges::elements_of<generator<R2, V2, Alloc2>&&, Unused> g) noexcept;
|
|
|
|
|
|
|
|
|
|
| 12508 |
```
|
| 12509 |
|
| 12510 |
*Preconditions:* A handle referring to the coroutine whose promise
|
| 12511 |
object is `*this` is at the top of `*`*`active_`* of some `generator`
|
| 12512 |
object `x`. The coroutine referred to by `g.range.`*`coroutine_`* is
|
|
@@ -12519,24 +14094,24 @@ into which `g.range` is moved, whose member `await_ready` returns
|
|
| 12519 |
execution of the coroutine referred to by `g.range.`*`coroutine_`*, and
|
| 12520 |
whose member `await_resume` evaluates `rethrow_exception(`*`except_`*`)`
|
| 12521 |
if `bool(`*`except_`*`)` is `true`. If `bool(`*`except_`*`)` is `false`,
|
| 12522 |
the `await_resume` member has no effects.
|
| 12523 |
|
| 12524 |
-
*Remarks:* A *yield-expression* that calls
|
| 12525 |
-
[[expr.yield]].
|
| 12526 |
|
| 12527 |
``` cpp
|
| 12528 |
template<ranges::input_range R, class Alloc>
|
| 12529 |
requires convertible_to<ranges::range_reference_t<R>, yielded>
|
| 12530 |
-
auto yield_value(ranges::elements_of<R, Alloc> r)
|
| 12531 |
```
|
| 12532 |
|
| 12533 |
*Effects:* Equivalent to:
|
| 12534 |
|
| 12535 |
``` cpp
|
| 12536 |
auto nested = [](allocator_arg_t, Alloc, ranges::iterator_t<R> i, ranges::sentinel_t<R> s)
|
| 12537 |
-
-> generator<yielded,
|
| 12538 |
for (; i != s; ++i) {
|
| 12539 |
co_yield static_cast<yielded>(*i);
|
| 12540 |
}
|
| 12541 |
};
|
| 12542 |
return yield_value(ranges::elements_of(nested(
|
|
@@ -12561,15 +14136,13 @@ is `*this` is the sole element of `*x.`*`active_`*, equivalent to
|
|
| 12561 |
``` cpp
|
| 12562 |
void* operator new(size_t size)
|
| 12563 |
requires same_as<Allocator, void> || default_initializable<Allocator>;
|
| 12564 |
|
| 12565 |
template<class Alloc, class... Args>
|
| 12566 |
-
requires same_as<Allocator, void> || convertible_to<const Alloc&, Allocator>
|
| 12567 |
void* operator new(size_t size, allocator_arg_t, const Alloc& alloc, const Args&...);
|
| 12568 |
|
| 12569 |
template<class This, class Alloc, class... Args>
|
| 12570 |
-
requires same_as<Allocator, void> || convertible_to<const Alloc&, Allocator>
|
| 12571 |
void* operator new(size_t size, const This&, allocator_arg_t, const Alloc& alloc,
|
| 12572 |
const Args&...);
|
| 12573 |
```
|
| 12574 |
|
| 12575 |
Let `A` be
|
|
@@ -12580,11 +14153,14 @@ Let `A` be
|
|
| 12580 |
|
| 12581 |
Let `B` be `allocator_traits<A>::template rebind_alloc<U>` where `U` is
|
| 12582 |
an unspecified type whose size and alignment are both
|
| 12583 |
\_\_STDCPP_DEFAULT_NEW_ALIGNMENT\_\_.
|
| 12584 |
|
| 12585 |
-
*Mandates:* `allocator_traits<B>::pointer` is a pointer type.
|
|
|
|
|
|
|
|
|
|
| 12586 |
|
| 12587 |
*Effects:* Initializes an allocator `b` of type `B` with `A(alloc)`, for
|
| 12588 |
the overloads with a function parameter `alloc`, and with `A()`
|
| 12589 |
otherwise. Uses `b` to allocate storage for the smallest array of `U`
|
| 12590 |
sufficient to provide storage for a coroutine state of size `size`, and
|
|
@@ -12606,12 +14182,12 @@ allocator equivalent to that used to allocate it.
|
|
| 12606 |
|
| 12607 |
### Class `generator::iterator` <a id="coro.generator.iterator">[[coro.generator.iterator]]</a>
|
| 12608 |
|
| 12609 |
``` cpp
|
| 12610 |
namespace std {
|
| 12611 |
-
template<class Ref, class
|
| 12612 |
-
class generator<Ref,
|
| 12613 |
public:
|
| 12614 |
using value_type = value;
|
| 12615 |
using difference_type = ptrdiff_t;
|
| 12616 |
|
| 12617 |
iterator(iterator&& other) noexcept;
|
|
@@ -12678,10 +14254,11 @@ friend bool operator==(const iterator& i, default_sentinel_t);
|
|
| 12678 |
```
|
| 12679 |
|
| 12680 |
*Effects:* Equivalent to: `return i.`*`coroutine_`*`.done();`
|
| 12681 |
|
| 12682 |
<!-- Link reference definitions -->
|
|
|
|
| 12683 |
[basic.lookup.argdep]: basic.md#basic.lookup.argdep
|
| 12684 |
[concepts.equality]: concepts.md#concepts.equality
|
| 12685 |
[containers]: containers.md#containers
|
| 12686 |
[conv.rval]: expr.md#conv.rval
|
| 12687 |
[coro.generator]: #coro.generator
|
|
@@ -12695,10 +14272,11 @@ friend bool operator==(const iterator& i, default_sentinel_t);
|
|
| 12695 |
[dcl.init.general]: dcl.md#dcl.init.general
|
| 12696 |
[expr.await]: expr.md#expr.await
|
| 12697 |
[expr.const]: expr.md#expr.const
|
| 12698 |
[expr.yield]: expr.md#expr.yield
|
| 12699 |
[generator.syn]: #generator.syn
|
|
|
|
| 12700 |
[iterator.concept.bidir]: iterators.md#iterator.concept.bidir
|
| 12701 |
[iterator.concept.forward]: iterators.md#iterator.concept.forward
|
| 12702 |
[iterator.concept.iterator]: iterators.md#iterator.concept.iterator
|
| 12703 |
[iterator.concept.output]: iterators.md#iterator.concept.output
|
| 12704 |
[iterator.concept.random.access]: iterators.md#iterator.concept.random.access
|
|
@@ -12730,16 +14308,22 @@ friend bool operator==(const iterator& i, default_sentinel_t);
|
|
| 12730 |
[range.adjacent.transform.sentinel]: #range.adjacent.transform.sentinel
|
| 12731 |
[range.adjacent.transform.view]: #range.adjacent.transform.view
|
| 12732 |
[range.adjacent.view]: #range.adjacent.view
|
| 12733 |
[range.all]: #range.all
|
| 12734 |
[range.all.general]: #range.all.general
|
|
|
|
| 12735 |
[range.as.const]: #range.as.const
|
| 12736 |
[range.as.const.overview]: #range.as.const.overview
|
| 12737 |
[range.as.const.view]: #range.as.const.view
|
| 12738 |
[range.as.rvalue]: #range.as.rvalue
|
| 12739 |
[range.as.rvalue.overview]: #range.as.rvalue.overview
|
| 12740 |
[range.as.rvalue.view]: #range.as.rvalue.view
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12741 |
[range.cartesian]: #range.cartesian
|
| 12742 |
[range.cartesian.iterator]: #range.cartesian.iterator
|
| 12743 |
[range.cartesian.overview]: #range.cartesian.overview
|
| 12744 |
[range.cartesian.view]: #range.cartesian.view
|
| 12745 |
[range.chunk]: #range.chunk
|
|
@@ -12755,10 +14339,14 @@ friend bool operator==(const iterator& i, default_sentinel_t);
|
|
| 12755 |
[range.chunk.view.fwd]: #range.chunk.view.fwd
|
| 12756 |
[range.chunk.view.input]: #range.chunk.view.input
|
| 12757 |
[range.common]: #range.common
|
| 12758 |
[range.common.overview]: #range.common.overview
|
| 12759 |
[range.common.view]: #range.common.view
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12760 |
[range.counted]: #range.counted
|
| 12761 |
[range.dangling]: #range.dangling
|
| 12762 |
[range.drop]: #range.drop
|
| 12763 |
[range.drop.overview]: #range.drop.overview
|
| 12764 |
[range.drop.view]: #range.drop.view
|
|
@@ -12816,10 +14404,11 @@ friend bool operator==(const iterator& i, default_sentinel_t);
|
|
| 12816 |
[range.owning.view]: #range.owning.view
|
| 12817 |
[range.prim.cdata]: #range.prim.cdata
|
| 12818 |
[range.prim.data]: #range.prim.data
|
| 12819 |
[range.prim.empty]: #range.prim.empty
|
| 12820 |
[range.prim.size]: #range.prim.size
|
|
|
|
| 12821 |
[range.prim.ssize]: #range.prim.ssize
|
| 12822 |
[range.range]: #range.range
|
| 12823 |
[range.ref.view]: #range.ref.view
|
| 12824 |
[range.refinements]: #range.refinements
|
| 12825 |
[range.repeat]: #range.repeat
|
|
@@ -12860,10 +14449,14 @@ friend bool operator==(const iterator& i, default_sentinel_t);
|
|
| 12860 |
[range.take.view]: #range.take.view
|
| 12861 |
[range.take.while]: #range.take.while
|
| 12862 |
[range.take.while.overview]: #range.take.while.overview
|
| 12863 |
[range.take.while.sentinel]: #range.take.while.sentinel
|
| 12864 |
[range.take.while.view]: #range.take.while.view
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12865 |
[range.transform]: #range.transform
|
| 12866 |
[range.transform.iterator]: #range.transform.iterator
|
| 12867 |
[range.transform.overview]: #range.transform.overview
|
| 12868 |
[range.transform.sentinel]: #range.transform.sentinel
|
| 12869 |
[range.transform.view]: #range.transform.view
|
|
|
|
| 21 |
|
| 22 |
|
| 23 |
## Header `<ranges>` synopsis <a id="ranges.syn">[[ranges.syn]]</a>
|
| 24 |
|
| 25 |
``` cpp
|
| 26 |
+
// mostly freestanding
|
| 27 |
#include <compare> // see [compare.syn]
|
| 28 |
#include <initializer_list> // see [initializer.list.syn]
|
| 29 |
#include <iterator> // see [iterator.synopsis]
|
| 30 |
|
| 31 |
namespace std::ranges {
|
| 32 |
inline namespace unspecified {
|
| 33 |
// [range.access], range access
|
| 34 |
+
inline constexpr unspecified begin = unspecified;
|
| 35 |
+
inline constexpr unspecified end = unspecified;
|
| 36 |
+
inline constexpr unspecified cbegin = unspecified;
|
| 37 |
+
inline constexpr unspecified cend = unspecified;
|
| 38 |
+
inline constexpr unspecified rbegin = unspecified;
|
| 39 |
+
inline constexpr unspecified rend = unspecified;
|
| 40 |
+
inline constexpr unspecified crbegin = unspecified;
|
| 41 |
+
inline constexpr unspecified crend = unspecified;
|
| 42 |
|
| 43 |
+
inline constexpr unspecified size = unspecified;
|
| 44 |
+
inline constexpr unspecified reserve_hint = unspecified;
|
| 45 |
+
inline constexpr unspecified ssize = unspecified;
|
| 46 |
+
inline constexpr unspecified empty = unspecified;
|
| 47 |
+
inline constexpr unspecified data = unspecified;
|
| 48 |
+
inline constexpr unspecified cdata = unspecified;
|
| 49 |
}
|
| 50 |
|
| 51 |
// [range.range], ranges
|
| 52 |
template<class T>
|
| 53 |
+
concept range = see below;
|
| 54 |
|
| 55 |
template<class T>
|
| 56 |
+
constexpr bool enable_borrowed_range = false;
|
| 57 |
|
| 58 |
template<class T>
|
| 59 |
+
concept borrowed_range = see below;
|
| 60 |
|
| 61 |
template<class T>
|
| 62 |
+
using iterator_t = decltype(ranges::begin(declval<T&>()));
|
| 63 |
template<range R>
|
| 64 |
+
using sentinel_t = decltype(ranges::end(declval<R&>()));
|
| 65 |
template<range R>
|
| 66 |
+
using const_iterator_t = decltype(ranges::cbegin(declval<R&>()));
|
| 67 |
template<range R>
|
| 68 |
+
using const_sentinel_t = decltype(ranges::cend(declval<R&>()));
|
| 69 |
template<range R>
|
| 70 |
+
using range_difference_t = iter_difference_t<iterator_t<R>>;
|
| 71 |
template<sized_range R>
|
| 72 |
+
using range_size_t = decltype(ranges::size(declval<R&>()));
|
| 73 |
template<range R>
|
| 74 |
+
using range_value_t = iter_value_t<iterator_t<R>>;
|
| 75 |
template<range R>
|
| 76 |
+
using range_reference_t = iter_reference_t<iterator_t<R>>;
|
| 77 |
template<range R>
|
| 78 |
+
using range_const_reference_t = iter_const_reference_t<iterator_t<R>>;
|
| 79 |
template<range R>
|
| 80 |
+
using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<R>>;
|
| 81 |
template<range R>
|
| 82 |
+
using range_common_reference_t = iter_common_reference_t<iterator_t<R>>;
|
| 83 |
|
| 84 |
// [range.sized], sized ranges
|
| 85 |
template<class>
|
| 86 |
+
constexpr bool disable_sized_range = false;
|
| 87 |
|
| 88 |
template<class T>
|
| 89 |
+
concept approximately_sized_range = see below;
|
| 90 |
+
|
| 91 |
+
template<class T>
|
| 92 |
+
concept sized_range = see below;
|
| 93 |
|
| 94 |
// [range.view], views
|
| 95 |
template<class T>
|
| 96 |
+
constexpr bool enable_view = see below;
|
| 97 |
|
| 98 |
+
struct view_base {};
|
| 99 |
|
| 100 |
template<class T>
|
| 101 |
+
concept view = see below;
|
| 102 |
|
| 103 |
// [range.refinements], other range refinements
|
| 104 |
template<class R, class T>
|
| 105 |
+
concept output_range = see below;
|
| 106 |
|
| 107 |
template<class T>
|
| 108 |
+
concept input_range = see below;
|
| 109 |
|
| 110 |
template<class T>
|
| 111 |
+
concept forward_range = see below;
|
| 112 |
|
| 113 |
template<class T>
|
| 114 |
+
concept bidirectional_range = see below;
|
| 115 |
|
| 116 |
template<class T>
|
| 117 |
+
concept random_access_range = see below;
|
| 118 |
|
| 119 |
template<class T>
|
| 120 |
+
concept contiguous_range = see below;
|
| 121 |
|
| 122 |
template<class T>
|
| 123 |
+
concept common_range = see below;
|
| 124 |
|
| 125 |
template<class T>
|
| 126 |
+
concept viewable_range = see below;
|
| 127 |
|
| 128 |
template<class T>
|
| 129 |
+
concept constant_range = see below;
|
| 130 |
+
|
| 131 |
+
template<class T>
|
| 132 |
+
concept sized-random-access-range = see belownc; // exposition only
|
| 133 |
|
| 134 |
// [view.interface], class template view_interface
|
| 135 |
template<class D>
|
| 136 |
requires is_class_v<D> && same_as<D, remove_cv_t<D>>
|
| 137 |
+
class view_interface;
|
| 138 |
|
| 139 |
// [range.subrange], sub-ranges
|
| 140 |
+
enum class subrange_kind : bool { unsized, sized };
|
| 141 |
|
| 142 |
template<input_or_output_iterator I, sentinel_for<I> S = I, subrange_kind K = see below>
|
| 143 |
requires (K == subrange_kind::sized || !sized_sentinel_for<S, I>)
|
| 144 |
+
class subrange;
|
| 145 |
|
| 146 |
template<class I, class S, subrange_kind K>
|
| 147 |
+
constexpr bool \libspec{enable_borrowed_range}{subrange}<subrange<I, S, K>> = true;
|
| 148 |
|
| 149 |
template<size_t N, class I, class S, subrange_kind K>
|
| 150 |
requires ((N == 0 && copyable<I>) || N == 1)
|
| 151 |
+
constexpr auto get(const subrange<I, S, K>& r);
|
| 152 |
|
| 153 |
template<size_t N, class I, class S, subrange_kind K>
|
| 154 |
requires (N < 2)
|
| 155 |
+
constexpr auto get(subrange<I, S, K>&& r);
|
| 156 |
}
|
| 157 |
|
| 158 |
namespace std {
|
| 159 |
+
using ranges::get;
|
| 160 |
}
|
| 161 |
|
| 162 |
namespace std::ranges {
|
| 163 |
// [range.dangling], dangling iterator handling
|
| 164 |
+
struct dangling;
|
| 165 |
|
| 166 |
// [range.elementsof], class template elements_of
|
| 167 |
template<range R, class Allocator = allocator<byte>>
|
| 168 |
+
struct elements_of; // hosted
|
| 169 |
|
| 170 |
template<range R>
|
| 171 |
+
using borrowed_iterator_t = see below;
|
| 172 |
|
| 173 |
template<range R>
|
| 174 |
+
using borrowed_subrange_t = see below;
|
| 175 |
|
| 176 |
// [range.utility.conv], range conversions
|
| 177 |
template<class C, input_range R, class... Args> requires (!view<C>)
|
| 178 |
+
constexpr C to(R&& r, Args&&... args);
|
| 179 |
template<template<class...> class C, input_range R, class... Args>
|
| 180 |
+
constexpr auto to(R&& r, Args&&... args);
|
| 181 |
template<class C, class... Args> requires (!view<C>)
|
| 182 |
+
constexpr auto to(Args&&... args);
|
| 183 |
template<template<class...> class C, class... Args>
|
| 184 |
+
constexpr auto to(Args&&... args);
|
| 185 |
|
| 186 |
// [range.empty], empty view
|
| 187 |
template<class T>
|
| 188 |
requires is_object_v<T>
|
| 189 |
+
class empty_view;
|
| 190 |
|
| 191 |
template<class T>
|
| 192 |
+
constexpr bool \libspec{enable_borrowed_range}{empty_view}<empty_view<T>> = true;
|
| 193 |
|
| 194 |
namespace views {
|
| 195 |
template<class T>
|
| 196 |
+
constexpr empty_view<T> empty{};
|
| 197 |
}
|
| 198 |
|
| 199 |
// [range.single], single view
|
| 200 |
template<move_constructible T>
|
| 201 |
requires is_object_v<T>
|
| 202 |
+
class single_view;
|
| 203 |
|
| 204 |
+
namespace views { inline constexpr unspecified single = unspecified; }
|
| 205 |
|
| 206 |
template<bool Const, class T>
|
| 207 |
using maybe-const = conditional_t<Const, const T, T>; // exposition only
|
| 208 |
|
| 209 |
// [range.iota], iota view
|
| 210 |
template<weakly_incrementable W, semiregular Bound = unreachable_sentinel_t>
|
| 211 |
requires weakly-equality-comparable-with<W, Bound> && copyable<W>
|
| 212 |
+
class iota_view;
|
| 213 |
|
| 214 |
template<class W, class Bound>
|
| 215 |
+
constexpr bool \libspec{enable_borrowed_range}{iota_view}<iota_view<W, Bound>> = true;
|
| 216 |
|
| 217 |
+
namespace views {
|
| 218 |
+
inline constexpr unspecified iota = unspecified;
|
| 219 |
+
inline constexpr unspecified indices = unspecified;
|
| 220 |
+
}
|
| 221 |
|
| 222 |
// [range.repeat], repeat view
|
| 223 |
template<move_constructible T, semiregular Bound = unreachable_sentinel_t>
|
| 224 |
requires see below
|
| 225 |
+
class repeat_view;
|
| 226 |
|
| 227 |
+
namespace views { inline constexpr unspecified repeat = unspecified; }
|
| 228 |
|
| 229 |
// [range.istream], istream view
|
| 230 |
template<movable Val, class CharT, class Traits = char_traits<CharT>>
|
| 231 |
requires see below
|
| 232 |
+
class basic_istream_view; // hosted
|
| 233 |
template<class Val>
|
| 234 |
+
using istream_view = basic_istream_view<Val, char>; // hosted
|
| 235 |
template<class Val>
|
| 236 |
+
using wistream_view = basic_istream_view<Val, wchar_t>; // hosted
|
| 237 |
|
| 238 |
+
namespace views {
|
| 239 |
+
template<class T> constexpr unspecified istream = unspecified; // hosted
|
| 240 |
+
}
|
| 241 |
|
| 242 |
// [range.adaptor.object], range adaptor objects
|
| 243 |
template<class D>
|
| 244 |
requires is_class_v<D> && same_as<D, remove_cv_t<D>>
|
| 245 |
+
class range_adaptor_closure { };
|
| 246 |
|
| 247 |
// [range.all], all view
|
| 248 |
namespace views {
|
| 249 |
+
inline constexpr unspecified all = unspecified;
|
| 250 |
|
| 251 |
template<viewable_range R>
|
| 252 |
+
using all_t = decltype(all(declval<R>()));
|
| 253 |
}
|
| 254 |
|
| 255 |
// [range.ref.view], ref view
|
| 256 |
template<range R>
|
| 257 |
requires is_object_v<R>
|
| 258 |
+
class ref_view;
|
| 259 |
|
| 260 |
template<class T>
|
| 261 |
+
constexpr bool \libspec{enable_borrowed_range}{ref_view}<ref_view<T>> = true;
|
| 262 |
|
| 263 |
// [range.owning.view], owning view
|
| 264 |
template<range R>
|
| 265 |
requires see below
|
| 266 |
+
class owning_view;
|
| 267 |
|
| 268 |
template<class T>
|
| 269 |
+
constexpr bool \libspec{enable_borrowed_range}{owning_view}<owning_view<T>> =
|
| 270 |
enable_borrowed_range<T>;
|
| 271 |
|
| 272 |
// [range.as.rvalue], as rvalue view
|
| 273 |
template<view V>
|
| 274 |
requires input_range<V>
|
| 275 |
+
class as_rvalue_view;
|
| 276 |
|
| 277 |
template<class T>
|
| 278 |
+
constexpr bool \libspec{enable_borrowed_range}{as_rvalue_view}<as_rvalue_view<T>> =
|
| 279 |
enable_borrowed_range<T>;
|
| 280 |
|
| 281 |
+
namespace views { inline constexpr unspecified as_rvalue = unspecified; }
|
| 282 |
|
| 283 |
// [range.filter], filter view
|
| 284 |
template<input_range V, indirect_unary_predicate<iterator_t<V>> Pred>
|
| 285 |
requires view<V> && is_object_v<Pred>
|
| 286 |
+
class filter_view;
|
| 287 |
|
| 288 |
+
namespace views { inline constexpr unspecified filter = unspecified; }
|
| 289 |
|
| 290 |
// [range.transform], transform view
|
| 291 |
template<input_range V, move_constructible F>
|
| 292 |
requires view<V> && is_object_v<F> &&
|
| 293 |
regular_invocable<F&, range_reference_t<V>> &&
|
| 294 |
can-reference<invoke_result_t<F&, range_reference_t<V>>>
|
| 295 |
+
class transform_view;
|
| 296 |
|
| 297 |
+
namespace views { inline constexpr unspecified transform = unspecified; }
|
| 298 |
|
| 299 |
// [range.take], take view
|
| 300 |
+
template<view> class take_view;
|
| 301 |
|
| 302 |
template<class T>
|
| 303 |
+
constexpr bool \libspec{enable_borrowed_range}{take_view}<take_view<T>> =
|
| 304 |
enable_borrowed_range<T>;
|
| 305 |
|
| 306 |
+
namespace views { inline constexpr unspecified take = unspecified; }
|
| 307 |
|
| 308 |
// [range.take.while], take while view
|
| 309 |
template<view V, class Pred>
|
| 310 |
requires input_range<V> && is_object_v<Pred> &&
|
| 311 |
indirect_unary_predicate<const Pred, iterator_t<V>>
|
| 312 |
+
class take_while_view;
|
| 313 |
|
| 314 |
+
namespace views { inline constexpr unspecified take_while = unspecified; }
|
| 315 |
|
| 316 |
// [range.drop], drop view
|
| 317 |
template<view V>
|
| 318 |
+
class drop_view;
|
| 319 |
|
| 320 |
template<class T>
|
| 321 |
+
constexpr bool \libspec{enable_borrowed_range}{drop_view}<drop_view<T>> =
|
| 322 |
enable_borrowed_range<T>;
|
| 323 |
|
| 324 |
+
namespace views { inline constexpr unspecified drop = unspecified; }
|
| 325 |
|
| 326 |
// [range.drop.while], drop while view
|
| 327 |
template<view V, class Pred>
|
| 328 |
requires input_range<V> && is_object_v<Pred> &&
|
| 329 |
indirect_unary_predicate<const Pred, iterator_t<V>>
|
| 330 |
+
class drop_while_view;
|
| 331 |
|
| 332 |
template<class T, class Pred>
|
| 333 |
+
constexpr bool \libspec{enable_borrowed_range}{drop_while_view}<drop_while_view<T, Pred>> =
|
| 334 |
enable_borrowed_range<T>;
|
| 335 |
|
| 336 |
+
namespace views { inline constexpr unspecified drop_while = unspecified; }
|
| 337 |
|
| 338 |
// [range.join], join view
|
| 339 |
template<input_range V>
|
| 340 |
requires view<V> && input_range<range_reference_t<V>>
|
| 341 |
+
class join_view;
|
| 342 |
|
| 343 |
+
namespace views { inline constexpr unspecified join = unspecified; }
|
| 344 |
|
| 345 |
// [range.join.with], join with view
|
|
|
|
|
|
|
|
|
|
| 346 |
template<input_range V, forward_range Pattern>
|
| 347 |
+
requires see below
|
| 348 |
+
class join_with_view;
|
|
|
|
|
|
|
| 349 |
|
| 350 |
+
namespace views { inline constexpr unspecified join_with = unspecified; }
|
| 351 |
|
| 352 |
// [range.lazy.split], lazy split view
|
| 353 |
template<class R>
|
| 354 |
concept tiny-range = see below; // exposition only
|
| 355 |
|
| 356 |
template<input_range V, forward_range Pattern>
|
| 357 |
requires view<V> && view<Pattern> &&
|
| 358 |
indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to> &&
|
| 359 |
(forward_range<V> || tiny-range<Pattern>)
|
| 360 |
+
class lazy_split_view;
|
| 361 |
|
| 362 |
// [range.split], split view
|
| 363 |
template<forward_range V, forward_range Pattern>
|
| 364 |
requires view<V> && view<Pattern> &&
|
| 365 |
indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to>
|
| 366 |
+
class split_view;
|
| 367 |
|
| 368 |
namespace views {
|
| 369 |
+
inline constexpr unspecified lazy_split = unspecified;
|
| 370 |
+
inline constexpr unspecified split = unspecified;
|
| 371 |
}
|
| 372 |
|
| 373 |
+
// [range.concat], concat view
|
| 374 |
+
template<input_range... Views>
|
| 375 |
+
requires see below
|
| 376 |
+
class concat_view;
|
| 377 |
+
|
| 378 |
+
namespace views { inline constexpr unspecified concat = unspecified; }
|
| 379 |
+
|
| 380 |
// [range.counted], counted view
|
| 381 |
+
namespace views { inline constexpr unspecified counted = unspecified; }
|
| 382 |
|
| 383 |
// [range.common], common view
|
| 384 |
template<view V>
|
| 385 |
requires (!common_range<V> && copyable<iterator_t<V>>)
|
| 386 |
+
class common_view;
|
| 387 |
|
| 388 |
template<class T>
|
| 389 |
+
constexpr bool \libspec{enable_borrowed_range}{common_view}<common_view<T>> =
|
| 390 |
enable_borrowed_range<T>;
|
| 391 |
|
| 392 |
+
namespace views { inline constexpr unspecified common = unspecified; }
|
| 393 |
|
| 394 |
// [range.reverse], reverse view
|
| 395 |
template<view V>
|
| 396 |
requires bidirectional_range<V>
|
| 397 |
+
class reverse_view;
|
| 398 |
|
| 399 |
template<class T>
|
| 400 |
+
constexpr bool \libspec{enable_borrowed_range}{reverse_view}<reverse_view<T>> =
|
| 401 |
enable_borrowed_range<T>;
|
| 402 |
|
| 403 |
+
namespace views { inline constexpr unspecified reverse = unspecified; }
|
| 404 |
|
| 405 |
// [range.as.const], as const view
|
| 406 |
template<input_range R>
|
| 407 |
+
constexpr auto& possibly-const-range(R& r) noexcept { // exposition only
|
| 408 |
+
if constexpr (input_range<const R>) {
|
| 409 |
return const_cast<const R&>(r);
|
| 410 |
} else {
|
| 411 |
return r;
|
| 412 |
}
|
| 413 |
}
|
| 414 |
|
| 415 |
template<view V>
|
| 416 |
requires input_range<V>
|
| 417 |
+
class as_const_view;
|
| 418 |
|
| 419 |
template<class T>
|
| 420 |
+
constexpr bool \libspec{enable_borrowed_range}{as_const_view}<as_const_view<T>> =
|
| 421 |
enable_borrowed_range<T>;
|
| 422 |
|
| 423 |
+
namespace views { inline constexpr unspecified as_const = unspecified; }
|
| 424 |
|
| 425 |
// [range.elements], elements view
|
| 426 |
template<input_range V, size_t N>
|
| 427 |
requires see below
|
| 428 |
+
class elements_view;
|
| 429 |
|
| 430 |
template<class T, size_t N>
|
| 431 |
+
constexpr bool \libspec{enable_borrowed_range}{elements_view}<elements_view<T, N>> =
|
| 432 |
enable_borrowed_range<T>;
|
| 433 |
|
| 434 |
template<class R>
|
| 435 |
+
using keys_view = elements_view<R, 0>;
|
| 436 |
template<class R>
|
| 437 |
+
using values_view = elements_view<R, 1>;
|
| 438 |
|
| 439 |
namespace views {
|
| 440 |
template<size_t N>
|
| 441 |
+
constexpr unspecified elements = unspecified;
|
| 442 |
+
inline constexpr auto keys = elements<0>;
|
| 443 |
+
inline constexpr auto values = elements<1>;
|
| 444 |
}
|
| 445 |
|
| 446 |
// [range.enumerate], enumerate view
|
| 447 |
+
template<view V>
|
| 448 |
+
requires see below
|
| 449 |
+
class enumerate_view;
|
| 450 |
|
| 451 |
template<class View>
|
| 452 |
+
constexpr bool \libspec{enable_borrowed_range}{enumerate_view}<enumerate_view<View>> =
|
| 453 |
enable_borrowed_range<View>;
|
| 454 |
|
| 455 |
+
namespace views { inline constexpr unspecified enumerate = unspecified; }
|
| 456 |
|
| 457 |
// [range.zip], zip view
|
| 458 |
template<input_range... Views>
|
| 459 |
requires (view<Views> && ...) && (sizeof...(Views) > 0)
|
| 460 |
+
class zip_view;
|
| 461 |
|
| 462 |
template<class... Views>
|
| 463 |
+
constexpr bool \libspec{enable_borrowed_range}{zip_view}<zip_view<Views...>> =
|
| 464 |
(enable_borrowed_range<Views> && ...);
|
| 465 |
|
| 466 |
+
namespace views { inline constexpr unspecified zip = unspecified; }
|
| 467 |
|
| 468 |
// [range.zip.transform], zip transform view
|
| 469 |
template<move_constructible F, input_range... Views>
|
| 470 |
requires (view<Views> && ...) && (sizeof...(Views) > 0) && is_object_v<F> &&
|
| 471 |
regular_invocable<F&, range_reference_t<Views>...> &&
|
| 472 |
can-reference<invoke_result_t<F&, range_reference_t<Views>...>>
|
| 473 |
+
class zip_transform_view;
|
| 474 |
|
| 475 |
+
namespace views { inline constexpr unspecified zip_transform = unspecified; }
|
| 476 |
|
| 477 |
// [range.adjacent], adjacent view
|
| 478 |
template<forward_range V, size_t N>
|
| 479 |
requires view<V> && (N > 0)
|
| 480 |
+
class adjacent_view;
|
| 481 |
|
| 482 |
template<class V, size_t N>
|
| 483 |
+
constexpr bool \libspec{enable_borrowed_range}{adjacent_view}<adjacent_view<V, N>> =
|
| 484 |
enable_borrowed_range<V>;
|
| 485 |
|
| 486 |
namespace views {
|
| 487 |
template<size_t N>
|
| 488 |
+
constexpr unspecified adjacent = unspecified;
|
| 489 |
+
inline constexpr auto pairwise = adjacent<2>;
|
| 490 |
}
|
| 491 |
|
| 492 |
// [range.adjacent.transform], adjacent transform view
|
| 493 |
template<forward_range V, move_constructible F, size_t N>
|
| 494 |
requires see below
|
| 495 |
+
class adjacent_transform_view;
|
| 496 |
|
| 497 |
namespace views {
|
| 498 |
template<size_t N>
|
| 499 |
+
constexpr unspecified adjacent_transform = unspecified;
|
| 500 |
+
inline constexpr auto pairwise_transform = adjacent_transform<2>;
|
| 501 |
}
|
| 502 |
|
| 503 |
// [range.chunk], chunk view
|
| 504 |
template<view V>
|
| 505 |
requires input_range<V>
|
| 506 |
+
class chunk_view;
|
| 507 |
|
| 508 |
template<view V>
|
| 509 |
requires forward_range<V>
|
| 510 |
+
class chunk_view<V>;
|
| 511 |
|
| 512 |
template<class V>
|
| 513 |
+
constexpr bool \libspec{enable_borrowed_range}{chunk_view}<chunk_view<V>> =
|
| 514 |
forward_range<V> && enable_borrowed_range<V>;
|
| 515 |
|
| 516 |
+
namespace views { inline constexpr unspecified chunk = unspecified; }
|
| 517 |
|
| 518 |
// [range.slide], slide view
|
| 519 |
template<forward_range V>
|
| 520 |
requires view<V>
|
| 521 |
+
class slide_view;
|
| 522 |
|
| 523 |
template<class V>
|
| 524 |
+
constexpr bool \libspec{enable_borrowed_range}{slide_view}<slide_view<V>> =
|
| 525 |
+
enable_borrowed_range<V>;
|
| 526 |
|
| 527 |
+
namespace views { inline constexpr unspecified slide = unspecified; }
|
| 528 |
|
| 529 |
// [range.chunk.by], chunk by view
|
| 530 |
template<forward_range V, indirect_binary_predicate<iterator_t<V>, iterator_t<V>> Pred>
|
| 531 |
requires view<V> && is_object_v<Pred>
|
| 532 |
+
class chunk_by_view;
|
| 533 |
|
| 534 |
+
namespace views { inline constexpr unspecified chunk_by = unspecified; }
|
| 535 |
|
| 536 |
// [range.stride], stride view
|
| 537 |
template<input_range V>
|
| 538 |
requires view<V>
|
| 539 |
+
class stride_view;
|
| 540 |
|
| 541 |
template<class V>
|
| 542 |
+
constexpr bool \libspec{enable_borrowed_range}{stride_view}<stride_view<V>> =
|
| 543 |
enable_borrowed_range<V>;
|
| 544 |
|
| 545 |
+
namespace views { inline constexpr unspecified stride = unspecified; }
|
| 546 |
|
| 547 |
// [range.cartesian], cartesian product view
|
| 548 |
template<input_range First, forward_range... Vs>
|
| 549 |
requires (view<First> && ... && view<Vs>)
|
| 550 |
+
class cartesian_product_view;
|
| 551 |
|
| 552 |
+
namespace views { inline constexpr unspecified cartesian_product = unspecified; }
|
| 553 |
+
|
| 554 |
+
// [range.cache.latest], cache latest view
|
| 555 |
+
template<input_range V>
|
| 556 |
+
requires view<V>
|
| 557 |
+
class cache_latest_view;
|
| 558 |
+
|
| 559 |
+
namespace views { inline constexpr unspecified cache_latest = unspecified; }
|
| 560 |
+
|
| 561 |
+
// [range.to.input], to input view
|
| 562 |
+
template<input_range V>
|
| 563 |
+
requires view<V>
|
| 564 |
+
class to_input_view;
|
| 565 |
+
|
| 566 |
+
template<class V>
|
| 567 |
+
constexpr bool enable_borrowed_range<to_input_view<V>> =
|
| 568 |
+
enable_borrowed_range<V>;
|
| 569 |
+
|
| 570 |
+
namespace views { inline constexpr unspecified to_input = unspecified; }
|
| 571 |
}
|
| 572 |
|
| 573 |
namespace std {
|
| 574 |
+
namespace views = ranges::views;
|
| 575 |
|
| 576 |
+
template<class T> struct tuple_size;
|
| 577 |
+
template<size_t I, class T> struct tuple_element;
|
| 578 |
|
| 579 |
template<class I, class S, ranges::subrange_kind K>
|
| 580 |
+
struct tuple_size<ranges::subrange<I, S, K>>
|
| 581 |
: integral_constant<size_t, 2> {};
|
| 582 |
template<class I, class S, ranges::subrange_kind K>
|
| 583 |
+
struct tuple_element<0, ranges::subrange<I, S, K>> {
|
| 584 |
+
using type = I;
|
| 585 |
};
|
| 586 |
template<class I, class S, ranges::subrange_kind K>
|
| 587 |
+
struct tuple_element<1, ranges::subrange<I, S, K>> {
|
| 588 |
+
using type = S;
|
| 589 |
};
|
| 590 |
template<class I, class S, ranges::subrange_kind K>
|
| 591 |
+
struct tuple_element<0, const ranges::subrange<I, S, K>> {
|
| 592 |
+
using type = I;
|
| 593 |
};
|
| 594 |
template<class I, class S, ranges::subrange_kind K>
|
| 595 |
+
struct tuple_element<1, const ranges::subrange<I, S, K>> {
|
| 596 |
+
using type = S;
|
| 597 |
};
|
| 598 |
|
| 599 |
+
struct from_range_t { explicit from_range_t() = default; };
|
| 600 |
+
inline constexpr from_range_t from_range{};
|
| 601 |
}
|
| 602 |
```
|
| 603 |
|
| 604 |
Within this Clause, for an integer-like type `X`
|
| 605 |
[[iterator.concept.winc]], `make-unsigned-like-t<X>` denotes
|
|
|
|
| 617 |
|
| 618 |
### General <a id="range.access.general">[[range.access.general]]</a>
|
| 619 |
|
| 620 |
In addition to being available via inclusion of the `<ranges>` header,
|
| 621 |
the customization point objects in [[range.access]] are available when
|
| 622 |
+
the header `<iterator>` is included.
|
| 623 |
|
| 624 |
Within [[range.access]], the *reified object* of a subexpression `E`
|
| 625 |
denotes
|
| 626 |
|
| 627 |
- the same object as `E` if `E` is a glvalue, or
|
|
|
|
| 879 |
`ranges::ssize(E)` is ill-formed. Otherwise let `D` be
|
| 880 |
`make-signed-like-t<decltype(ranges::{}size(t))>`, or `ptrdiff_t` if it
|
| 881 |
is wider than that type; `ranges::ssize(E)` is expression-equivalent to
|
| 882 |
`static_cast<D>(ranges::size(t))`.
|
| 883 |
|
| 884 |
+
### `ranges::reserve_hint` <a id="range.prim.size.hint">[[range.prim.size.hint]]</a>
|
| 885 |
+
|
| 886 |
+
The name `ranges::reserve_hint` denotes a customization point object
|
| 887 |
+
[[customization.point.object]].
|
| 888 |
+
|
| 889 |
+
Given a subexpression `E` with type `T`, let `t` be an lvalue that
|
| 890 |
+
denotes the reified object for `E`. Then:
|
| 891 |
+
|
| 892 |
+
- If `ranges::size(E)` is a valid expression, `ranges::reserve_hint(E)`
|
| 893 |
+
is expression-equivalent to `ranges::size(E)`.
|
| 894 |
+
- Otherwise, if `auto(t.reserve_hint())` is a valid expression of
|
| 895 |
+
integer-like type [[iterator.concept.winc]], `ranges::reserve_hint(E)`
|
| 896 |
+
is expression-equivalent to `auto(t.reserve_hint())`.
|
| 897 |
+
- Otherwise, if `T` is a class or enumeration type and
|
| 898 |
+
`auto(reserve_hint(t))` is a valid expression of integer-like type
|
| 899 |
+
where the meaning of `reserve_hint` is established as-if by performing
|
| 900 |
+
argument-dependent lookup only [[basic.lookup.argdep]], then
|
| 901 |
+
`ranges::reserve_hint(E)` is expression-equivalent to that expression.
|
| 902 |
+
- Otherwise, `ranges::reserve_hint(E)` is ill-formed.
|
| 903 |
+
|
| 904 |
+
[*Note 1*: Diagnosable ill-formed cases above result in substitution
|
| 905 |
+
failure when `ranges::reserve_hint(E)` appears in the immediate context
|
| 906 |
+
of a template instantiation. — *end note*]
|
| 907 |
+
|
| 908 |
+
[*Note 2*: Whenever `ranges::reserve_hint(E)` is a valid expression,
|
| 909 |
+
its type is integer-like. — *end note*]
|
| 910 |
+
|
| 911 |
### `ranges::empty` <a id="range.prim.empty">[[range.prim.empty]]</a>
|
| 912 |
|
| 913 |
The name `ranges::empty` denotes a customization point object
|
| 914 |
[[customization.point.object]].
|
| 915 |
|
|
|
|
| 966 |
|
| 967 |
### `ranges::cdata` <a id="range.prim.cdata">[[range.prim.cdata]]</a>
|
| 968 |
|
| 969 |
``` cpp
|
| 970 |
template<class T>
|
| 971 |
+
constexpr auto as-const-pointer(const T* p) noexcept { return p; } // exposition only
|
| 972 |
```
|
| 973 |
|
| 974 |
The name `ranges::cdata` denotes a customization point object
|
| 975 |
[[customization.point.object]]. Given a subexpression `E` with type `T`,
|
| 976 |
let `t` be an lvalue that denotes the reified object for `E`. Then:
|
|
|
|
| 1024 |
ranges::begin(t); // sometimes equality-preserving (see below)
|
| 1025 |
ranges::end(t);
|
| 1026 |
};
|
| 1027 |
```
|
| 1028 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1029 |
Given an expression `t` such that `decltype((t))` is `T&`, `T` models
|
| 1030 |
`range` only if
|
| 1031 |
|
| 1032 |
- \[`ranges::begin(t)`, `ranges::end(t)`) denotes a
|
| 1033 |
range [[iterator.requirements.general]],
|
|
|
|
| 1081 |
- `S`’s iterators do not have validity tied to the lifetime of an `S`
|
| 1082 |
object because they are “borrowed” from some other range.
|
| 1083 |
|
| 1084 |
— *end example*]
|
| 1085 |
|
| 1086 |
+
### Approximately sized ranges <a id="range.approximately.sized">[[range.approximately.sized]]</a>
|
| 1087 |
+
|
| 1088 |
+
The `approximately_sized_range` concept refines `range` with the
|
| 1089 |
+
requirement that an approximation of the number of elements in the range
|
| 1090 |
+
can be determined in amortized constant time using
|
| 1091 |
+
`ranges::reserve_hint`.
|
| 1092 |
+
|
| 1093 |
+
``` cpp
|
| 1094 |
+
template<class T>
|
| 1095 |
+
concept approximately_sized_range =
|
| 1096 |
+
range<T> && requires(T& t) { ranges::reserve_hint(t); };
|
| 1097 |
+
```
|
| 1098 |
+
|
| 1099 |
+
Given an lvalue `t` of type `remove_reference_t<T>`, `T` models
|
| 1100 |
+
`approximately_sized_range` only if
|
| 1101 |
+
|
| 1102 |
+
- `ranges::reserve_hint(t)` is amortized 𝑂(1), does not modify `t`, and
|
| 1103 |
+
has a value that is not negative and is representable in
|
| 1104 |
+
`range_difference_t<T>`, and
|
| 1105 |
+
- if `iterator_t<T>` models `forward_iterator`,
|
| 1106 |
+
`ranges::reserve_hint(t)` is well-defined regardless of the evaluation
|
| 1107 |
+
of `ranges::begin(t)`. \[*Note 1*: `ranges::reserve_hint(t)` is
|
| 1108 |
+
otherwise not required to be well-defined after evaluating
|
| 1109 |
+
`ranges::begin(t)`. For example, it is possible for
|
| 1110 |
+
`ranges::reserve_hint(t)` to be well-defined for an whose iterator
|
| 1111 |
+
type does not model `forward_iterator` only if evaluated before the
|
| 1112 |
+
first call to `ranges::begin(t)`. — *end note*]
|
| 1113 |
+
|
| 1114 |
### Sized ranges <a id="range.sized">[[range.sized]]</a>
|
| 1115 |
|
| 1116 |
+
The `sized_range` concept refines `approximately_sized_range` with the
|
| 1117 |
+
requirement that the number of elements in the range can be determined
|
| 1118 |
+
in amortized constant time using `ranges::size`.
|
| 1119 |
|
| 1120 |
``` cpp
|
| 1121 |
template<class T>
|
| 1122 |
concept sized_range =
|
| 1123 |
+
approximately_sized_range<T> && requires(T& t) { ranges::size(t); };
|
| 1124 |
```
|
| 1125 |
|
| 1126 |
Given an lvalue `t` of type `remove_reference_t<T>`, `T` models
|
| 1127 |
`sized_range` only if
|
| 1128 |
|
|
|
|
| 1144 |
*Remarks:* Pursuant to [[namespace.std]], users may specialize
|
| 1145 |
`disable_sized_range` for cv-unqualified program-defined types. Such
|
| 1146 |
specializations shall be usable in constant expressions [[expr.const]]
|
| 1147 |
and have type `const bool`.
|
| 1148 |
|
| 1149 |
+
[*Note 1*: `disable_sized_range` allows use of `range` types with the
|
| 1150 |
library that satisfy but do not in fact model
|
| 1151 |
`sized_range`. — *end note*]
|
| 1152 |
|
| 1153 |
### Views <a id="range.view">[[range.view]]</a>
|
| 1154 |
|
|
|
|
| 1160 |
template<class T>
|
| 1161 |
concept view =
|
| 1162 |
range<T> && movable<T> && enable_view<T>;
|
| 1163 |
```
|
| 1164 |
|
| 1165 |
+
`T` models `view` only if
|
| 1166 |
|
| 1167 |
- `T` has 𝑂(1) move construction; and
|
| 1168 |
- move assignment of an object of type `T` is no more complex than
|
| 1169 |
destruction followed by move construction; and
|
| 1170 |
- if N copies and/or moves are made from an object of type `T` that
|
|
|
|
| 1208 |
only if `T` has exactly one public base class `view_interface<U>` for
|
| 1209 |
some type `U` and `T` has no base classes of type `view_interface<V>`
|
| 1210 |
for any other type `V`.
|
| 1211 |
|
| 1212 |
*Remarks:* Pursuant to [[namespace.std]], users may specialize
|
| 1213 |
+
`enable_view` to `true` for cv-unqualified program-defined types that
|
| 1214 |
+
model `view`, and `false` for types that do not. Such specializations
|
| 1215 |
shall be usable in constant expressions [[expr.const]] and have type
|
| 1216 |
`const bool`.
|
| 1217 |
|
| 1218 |
### Other range refinements <a id="range.refinements">[[range.refinements]]</a>
|
| 1219 |
|
|
|
|
| 1299 |
template<class T>
|
| 1300 |
concept constant_range =
|
| 1301 |
input_range<T> && constant-iterator<iterator_t<T>>;
|
| 1302 |
```
|
| 1303 |
|
| 1304 |
+
The exposition-only concept `sized-random-access-range` specifies the
|
| 1305 |
+
requirements of a `range` type that is sized and allows random access to
|
| 1306 |
+
its elements.
|
| 1307 |
+
|
| 1308 |
+
``` cpp
|
| 1309 |
+
template<class T>
|
| 1310 |
+
concept sized-random-access-range = // exposition only
|
| 1311 |
+
random_access_range<T> && sized_range<T>;
|
| 1312 |
+
```
|
| 1313 |
+
|
| 1314 |
+
[*Note 1*: This concept constrains some parallel algorithm overloads;
|
| 1315 |
+
see [[algorithms]]. — *end note*]
|
| 1316 |
+
|
| 1317 |
## Range utilities <a id="range.utility">[[range.utility]]</a>
|
| 1318 |
|
| 1319 |
### General <a id="range.utility.general">[[range.utility.general]]</a>
|
| 1320 |
|
| 1321 |
The components in [[range.utility]] are general utilities for
|
| 1322 |
representing and manipulating ranges.
|
| 1323 |
|
| 1324 |
### Helper concepts <a id="range.utility.helpers">[[range.utility.helpers]]</a>
|
| 1325 |
|
| 1326 |
+
Many of the types in [[range.utility]] are specified in terms of the
|
| 1327 |
+
following exposition-only concepts:
|
| 1328 |
|
| 1329 |
``` cpp
|
| 1330 |
template<class R>
|
| 1331 |
concept simple-view = // exposition only
|
| 1332 |
view<R> && range<const R> &&
|
| 1333 |
same_as<iterator_t<R>, iterator_t<const R>> &&
|
| 1334 |
same_as<sentinel_t<R>, sentinel_t<const R>>;
|
| 1335 |
|
| 1336 |
template<class I>
|
| 1337 |
concept has-arrow = // exposition only
|
| 1338 |
+
input_iterator<I> && (is_pointer_v<I> || requires(const I i) { i.operator->(); });
|
| 1339 |
|
| 1340 |
template<class T, class U>
|
| 1341 |
concept different-from = // exposition only
|
| 1342 |
!same_as<remove_cvref_t<T>, remove_cvref_t<U>>;
|
| 1343 |
|
|
|
|
| 1451 |
``` cpp
|
| 1452 |
constexpr decltype(auto) front() requires forward_range<D>;
|
| 1453 |
constexpr decltype(auto) front() const requires forward_range<const D>;
|
| 1454 |
```
|
| 1455 |
|
| 1456 |
+
`!empty()` is `true`.
|
| 1457 |
|
| 1458 |
*Effects:* Equivalent to: `return *ranges::begin(`*`derived`*`());`
|
| 1459 |
|
| 1460 |
``` cpp
|
| 1461 |
constexpr decltype(auto) back() requires bidirectional_range<D> && common_range<D>;
|
| 1462 |
constexpr decltype(auto) back() const
|
| 1463 |
requires bidirectional_range<const D> && common_range<const D>;
|
| 1464 |
```
|
| 1465 |
|
| 1466 |
+
`!empty()` is `true`.
|
| 1467 |
|
| 1468 |
*Effects:* Equivalent to:
|
| 1469 |
`return *ranges::prev(ranges::end(`*`derived`*`()));`
|
| 1470 |
|
| 1471 |
### Sub-ranges <a id="range.subrange">[[range.subrange]]</a>
|
|
|
|
| 1532 |
template<different-from<subrange> PairLike>
|
| 1533 |
requires pair-like-convertible-from<PairLike, const I&, const S&>
|
| 1534 |
constexpr operator PairLike() const;
|
| 1535 |
|
| 1536 |
constexpr I begin() const requires copyable<I>;
|
| 1537 |
+
constexpr I begin() requires (!copyable<I>);
|
| 1538 |
constexpr S end() const;
|
| 1539 |
|
| 1540 |
constexpr bool empty() const;
|
| 1541 |
constexpr make-unsigned-like-t<iter_difference_t<I>> size() const
|
| 1542 |
requires (K == subrange_kind::sized);
|
| 1543 |
|
| 1544 |
+
constexpr subrange next(iter_difference_t<I> n = 1) const &
|
| 1545 |
requires forward_iterator<I>;
|
| 1546 |
+
constexpr subrange next(iter_difference_t<I> n = 1) &&;
|
| 1547 |
+
constexpr subrange prev(iter_difference_t<I> n = 1) const
|
| 1548 |
requires bidirectional_iterator<I>;
|
| 1549 |
constexpr subrange& advance(iter_difference_t<I> n);
|
| 1550 |
};
|
| 1551 |
|
| 1552 |
template<input_or_output_iterator I, sentinel_for<I> S>
|
|
|
|
| 1625 |
```
|
| 1626 |
|
| 1627 |
*Effects:* Equivalent to: `return `*`begin_`*`;`
|
| 1628 |
|
| 1629 |
``` cpp
|
| 1630 |
+
constexpr I begin() requires (!copyable<I>);
|
| 1631 |
```
|
| 1632 |
|
| 1633 |
*Effects:* Equivalent to: `return std::move(`*`begin_`*`);`
|
| 1634 |
|
| 1635 |
``` cpp
|
|
|
|
| 1654 |
- If *StoreSize* is `true`, equivalent to: `return `*`size_`*`;`
|
| 1655 |
- Otherwise, equivalent to:
|
| 1656 |
`return `*`to-unsigned-like`*`(`*`end_`*` - `*`begin_`*`);`
|
| 1657 |
|
| 1658 |
``` cpp
|
| 1659 |
+
constexpr subrange next(iter_difference_t<I> n = 1) const &
|
| 1660 |
requires forward_iterator<I>;
|
| 1661 |
```
|
| 1662 |
|
| 1663 |
*Effects:* Equivalent to:
|
| 1664 |
|
|
|
|
| 1667 |
tmp.advance(n);
|
| 1668 |
return tmp;
|
| 1669 |
```
|
| 1670 |
|
| 1671 |
``` cpp
|
| 1672 |
+
constexpr subrange next(iter_difference_t<I> n = 1) &&;
|
| 1673 |
```
|
| 1674 |
|
| 1675 |
*Effects:* Equivalent to:
|
| 1676 |
|
| 1677 |
``` cpp
|
| 1678 |
advance(n);
|
| 1679 |
return std::move(*this);
|
| 1680 |
```
|
| 1681 |
|
| 1682 |
``` cpp
|
| 1683 |
+
constexpr subrange prev(iter_difference_t<I> n = 1) const
|
| 1684 |
requires bidirectional_iterator<I>;
|
| 1685 |
```
|
| 1686 |
|
| 1687 |
*Effects:* Equivalent to:
|
| 1688 |
|
|
|
|
| 1846 |
{ c.capacity() } -> same_as<decltype(n)>;
|
| 1847 |
{ c.max_size() } -> same_as<decltype(n)>;
|
| 1848 |
};
|
| 1849 |
```
|
| 1850 |
|
| 1851 |
+
Let *`container-appendable`* be defined as follows:
|
| 1852 |
|
| 1853 |
``` cpp
|
| 1854 |
template<class Container, class Ref>
|
| 1855 |
+
constexpr bool container-appendable = // exposition only
|
| 1856 |
requires(Container& c, Ref&& ref) {
|
| 1857 |
+
requires (requires { c.emplace_back(std::forward<Ref>(ref)); } ||
|
| 1858 |
+
requires { c.push_back(std::forward<Ref>(ref)); } ||
|
| 1859 |
+
requires { c.emplace(c.end(), std::forward<Ref>(ref)); } ||
|
| 1860 |
requires { c.insert(c.end(), std::forward<Ref>(ref)); });
|
| 1861 |
};
|
| 1862 |
```
|
| 1863 |
|
| 1864 |
+
Let *`container-append`* be defined as follows:
|
| 1865 |
|
| 1866 |
``` cpp
|
| 1867 |
+
template<class Container>
|
| 1868 |
+
constexpr auto container-append(Container& c) { // exposition only
|
| 1869 |
+
return [&c]<class Ref>(Ref&& ref) {
|
| 1870 |
+
if constexpr (requires { c.emplace_back(declval<Ref>()); })
|
| 1871 |
+
c.emplace_back(std::forward<Ref>(ref));
|
| 1872 |
+
else if constexpr (requires { c.push_back(declval<Ref>()); })
|
| 1873 |
+
c.push_back(std::forward<Ref>(ref));
|
| 1874 |
+
else if constexpr (requires { c.emplace(c.end(), declval<Ref>()); })
|
| 1875 |
+
c.emplace(c.end(), std::forward<Ref>(ref));
|
| 1876 |
else
|
| 1877 |
+
c.insert(c.end(), std::forward<Ref>(ref));
|
| 1878 |
+
};
|
| 1879 |
}
|
| 1880 |
```
|
| 1881 |
|
| 1882 |
#### `ranges::to` <a id="range.utility.conv.to">[[range.utility.conv.to]]</a>
|
| 1883 |
|
|
|
|
| 1913 |
``` cpp
|
| 1914 |
C(ranges::begin(r), ranges::end(r), std::forward<Args>(args)...)
|
| 1915 |
```
|
| 1916 |
- Otherwise, if
|
| 1917 |
- `constructible_from<C, Args...>` is `true`, and
|
| 1918 |
+
- *`container-appendable`*`<C, range_reference_t<R>>` is `true`:
|
| 1919 |
|
| 1920 |
``` cpp
|
| 1921 |
C c(std::forward<Args>(args)...);
|
| 1922 |
+
if constexpr (approximately_sized_range<R> && reservable-container<C>)
|
| 1923 |
+
c.reserve(static_cast<range_size_t<C>>(ranges::reserve_hint(r)));
|
| 1924 |
+
ranges::for_each(r, container-append(c));
|
| 1925 |
```
|
| 1926 |
+
- Otherwise, the program is ill-formed.
|
| 1927 |
- Otherwise, if `input_range<range_reference_t<R>>` is `true`:
|
| 1928 |
``` cpp
|
| 1929 |
+
to<C>(ref_view(r) | views::transform([](auto&& elem) {
|
| 1930 |
return to<range_value_t<C>>(std::forward<decltype(elem)>(elem));
|
| 1931 |
}), std::forward<Args>(args)...);
|
| 1932 |
```
|
| 1933 |
- Otherwise, the program is ill-formed.
|
| 1934 |
|
|
|
|
| 2079 |
|
| 2080 |
constexpr T* begin() noexcept;
|
| 2081 |
constexpr const T* begin() const noexcept;
|
| 2082 |
constexpr T* end() noexcept;
|
| 2083 |
constexpr const T* end() const noexcept;
|
| 2084 |
+
static constexpr bool empty() noexcept;
|
| 2085 |
static constexpr size_t size() noexcept;
|
| 2086 |
constexpr T* data() noexcept;
|
| 2087 |
constexpr const T* data() const noexcept;
|
| 2088 |
};
|
| 2089 |
|
|
|
|
| 2125 |
constexpr const T* end() const noexcept;
|
| 2126 |
```
|
| 2127 |
|
| 2128 |
*Effects:* Equivalent to: `return data() + 1;`
|
| 2129 |
|
| 2130 |
+
``` cpp
|
| 2131 |
+
static constexpr bool empty() noexcept;
|
| 2132 |
+
```
|
| 2133 |
+
|
| 2134 |
+
*Effects:* Equivalent to: `return false;`
|
| 2135 |
+
|
| 2136 |
``` cpp
|
| 2137 |
static constexpr size_t size() noexcept;
|
| 2138 |
```
|
| 2139 |
|
| 2140 |
*Effects:* Equivalent to: `return 1;`
|
|
|
|
| 2154 |
an initial value.
|
| 2155 |
|
| 2156 |
The name `views::iota` denotes a customization point object
|
| 2157 |
[[customization.point.object]]. Given subexpressions `E` and `F`, the
|
| 2158 |
expressions `views::iota(E)` and `views::iota(E, F)` are
|
| 2159 |
+
expression-equivalent to `iota_view<decay_t<decltype((E))>>(E)` and
|
| 2160 |
+
`iota_view(E, F)`, respectively.
|
| 2161 |
|
| 2162 |
[*Example 1*:
|
| 2163 |
|
| 2164 |
``` cpp
|
| 2165 |
for (int i : views::iota(1, 10))
|
| 2166 |
cout << i << ' '; // prints 1 2 3 4 5 6 7 8 9
|
| 2167 |
```
|
| 2168 |
|
| 2169 |
— *end example*]
|
| 2170 |
|
| 2171 |
+
The name `views::indices` denotes a customization point object
|
| 2172 |
+
[[customization.point.object]]. Given subexpression `E`, let `T` be
|
| 2173 |
+
`remove_cvref_t<decltype((E))>`. `views::indices(E)` is
|
| 2174 |
+
expression-equivalent to `views::iota(T(0), E)` if `is-integer-like<T>`
|
| 2175 |
+
is `true`, and ill-formed otherwise.
|
| 2176 |
+
|
| 2177 |
#### Class template `iota_view` <a id="range.iota.view">[[range.iota.view]]</a>
|
| 2178 |
|
| 2179 |
``` cpp
|
| 2180 |
namespace std::ranges {
|
| 2181 |
template<class I>
|
|
|
|
| 2205 |
|
| 2206 |
constexpr iterator begin() const;
|
| 2207 |
constexpr auto end() const;
|
| 2208 |
constexpr iterator end() const requires same_as<W, Bound>;
|
| 2209 |
|
| 2210 |
+
constexpr bool empty() const;
|
| 2211 |
constexpr auto size() const requires see below;
|
| 2212 |
};
|
| 2213 |
|
| 2214 |
template<class W, class Bound>
|
| 2215 |
requires (!is-integer-like<W> || !is-integer-like<Bound> ||
|
|
|
|
| 2353 |
constexpr iterator end() const requires same_as<W, Bound>;
|
| 2354 |
```
|
| 2355 |
|
| 2356 |
*Effects:* Equivalent to: `return `*`iterator`*`{`*`bound_`*`};`
|
| 2357 |
|
| 2358 |
+
``` cpp
|
| 2359 |
+
constexpr bool empty() const;
|
| 2360 |
+
```
|
| 2361 |
+
|
| 2362 |
+
*Effects:* Equivalent to: `return `*`value_`*` == `*`bound_`*`;`
|
| 2363 |
+
|
| 2364 |
``` cpp
|
| 2365 |
constexpr auto size() const requires see below;
|
| 2366 |
```
|
| 2367 |
|
| 2368 |
*Effects:* Equivalent to:
|
|
|
|
| 2725 |
the same value.
|
| 2726 |
|
| 2727 |
The name `views::repeat` denotes a customization point object
|
| 2728 |
[[customization.point.object]]. Given subexpressions `E` and `F`, the
|
| 2729 |
expressions `views::repeat(E)` and `views::repeat(E, F)` are
|
| 2730 |
+
expression-equivalent to `repeat_view<decay_t<decltype((E))>>(E)` and
|
| 2731 |
+
`repeat_view(E, F)`, respectively.
|
| 2732 |
|
| 2733 |
[*Example 1*:
|
| 2734 |
|
| 2735 |
``` cpp
|
| 2736 |
for (int i : views::repeat(17, 4))
|
|
|
|
| 2777 |
constexpr unreachable_sentinel_t end() const noexcept;
|
| 2778 |
|
| 2779 |
constexpr auto size() const requires (!same_as<Bound, unreachable_sentinel_t>);
|
| 2780 |
};
|
| 2781 |
|
| 2782 |
+
template<class T, class Bound = unreachable_sentinel_t>
|
| 2783 |
+
repeat_view(T, Bound = Bound()) -> repeat_view<T, Bound>;
|
| 2784 |
}
|
| 2785 |
```
|
| 2786 |
|
| 2787 |
``` cpp
|
| 2788 |
constexpr explicit repeat_view(const T& value, Bound bound = Bound())
|
|
|
|
| 3341 |
- Otherwise, `movable-box<T>` should store only a `T` if either `T`
|
| 3342 |
models `movable` or `is_nothrow_move_constructible_v<T>` is `true`.
|
| 3343 |
|
| 3344 |
### Non-propagating cache <a id="range.nonprop.cache">[[range.nonprop.cache]]</a>
|
| 3345 |
|
| 3346 |
+
Some types in [[range.adaptors]] are specified in terms of an
|
| 3347 |
exposition-only class template *`non-propagating-{}cache`*.
|
| 3348 |
`non-propagating-cache<T>` behaves exactly like `optional<T>` with the
|
| 3349 |
following differences:
|
| 3350 |
|
| 3351 |
- `non-propagating-cache<T>` constrains its type parameter `T` with
|
|
|
|
| 3420 |
|
| 3421 |
template<class T>
|
| 3422 |
constexpr T& as-lvalue(T&& t) { // exposition only
|
| 3423 |
return static_cast<T&>(t);
|
| 3424 |
}
|
| 3425 |
+
|
| 3426 |
+
template<bool Const, class... Views>
|
| 3427 |
+
concept all-random-access = // exposition only
|
| 3428 |
+
(random_access_range<maybe-const<Const, Views>> && ...);
|
| 3429 |
+
template<bool Const, class... Views>
|
| 3430 |
+
concept all-bidirectional = // exposition only
|
| 3431 |
+
(bidirectional_range<maybe-const<Const, Views>> && ...);
|
| 3432 |
+
template<bool Const, class... Views>
|
| 3433 |
+
concept all-forward = // exposition only
|
| 3434 |
+
(forward_range<maybe-const<Const, Views>> && ...);
|
| 3435 |
}
|
| 3436 |
```
|
| 3437 |
|
| 3438 |
### All view <a id="range.all">[[range.all]]</a>
|
| 3439 |
|
|
|
|
| 3477 |
{ return ranges::empty(*r_); }
|
| 3478 |
|
| 3479 |
constexpr auto size() const requires sized_range<R>
|
| 3480 |
{ return ranges::size(*r_); }
|
| 3481 |
|
| 3482 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<R>
|
| 3483 |
+
{ return ranges::reserve_hint(*r_); }
|
| 3484 |
+
|
| 3485 |
constexpr auto data() const requires contiguous_range<R>
|
| 3486 |
{ return ranges::data(*r_); }
|
| 3487 |
};
|
| 3488 |
|
| 3489 |
template<class R>
|
|
|
|
| 3553 |
constexpr auto size() requires sized_range<R>
|
| 3554 |
{ return ranges::size(r_); }
|
| 3555 |
constexpr auto size() const requires sized_range<const R>
|
| 3556 |
{ return ranges::size(r_); }
|
| 3557 |
|
| 3558 |
+
constexpr auto reserve_hint() requires approximately_sized_range<R>
|
| 3559 |
+
{ return ranges::reserve_hint(r_); }
|
| 3560 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const R>
|
| 3561 |
+
{ return ranges::reserve_hint(r_); }
|
| 3562 |
+
|
| 3563 |
constexpr auto data() requires contiguous_range<R>
|
| 3564 |
{ return ranges::data(r_); }
|
| 3565 |
constexpr auto data() const requires contiguous_range<const R>
|
| 3566 |
{ return ranges::data(r_); }
|
| 3567 |
};
|
|
|
|
| 3586 |
The name `views::as_rvalue` denotes a range adaptor object
|
| 3587 |
[[range.adaptor.object]]. Let `E` be an expression and let `T` be
|
| 3588 |
`decltype((E))`. The expression `views::as_rvalue(E)` is
|
| 3589 |
expression-equivalent to:
|
| 3590 |
|
| 3591 |
+
- `views::all(E)` if `T` models `input_range` and
|
| 3592 |
`same_as<range_rvalue_reference_t<T>, range_reference_t<T>>` is
|
| 3593 |
`true`.
|
| 3594 |
- Otherwise, `as_rvalue_view(E)`.
|
| 3595 |
|
| 3596 |
[*Example 1*:
|
|
|
|
| 3640 |
}
|
| 3641 |
}
|
| 3642 |
|
| 3643 |
constexpr auto size() requires sized_range<V> { return ranges::size(base_); }
|
| 3644 |
constexpr auto size() const requires sized_range<const V> { return ranges::size(base_); }
|
| 3645 |
+
|
| 3646 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>
|
| 3647 |
+
{ return ranges::reserve_hint(base_); }
|
| 3648 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>
|
| 3649 |
+
{ return ranges::reserve_hint(base_); }
|
| 3650 |
};
|
| 3651 |
|
| 3652 |
template<class R>
|
| 3653 |
as_rvalue_view(R&&) -> as_rvalue_view<views::all_t<R>>;
|
| 3654 |
}
|
|
|
|
| 4032 |
regular_invocable<const F&, range_reference_t<const V>>;
|
| 4033 |
|
| 4034 |
constexpr auto size() requires sized_range<V> { return ranges::size(base_); }
|
| 4035 |
constexpr auto size() const requires sized_range<const V>
|
| 4036 |
{ return ranges::size(base_); }
|
| 4037 |
+
|
| 4038 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>
|
| 4039 |
+
{ return ranges::reserve_hint(base_); }
|
| 4040 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>
|
| 4041 |
+
{ return ranges::reserve_hint(base_); }
|
| 4042 |
};
|
| 4043 |
|
| 4044 |
template<class R, class F>
|
| 4045 |
transform_view(R&&, F) -> transform_view<views::all_t<R>, F>;
|
| 4046 |
}
|
|
|
|
| 4620 |
|
| 4621 |
constexpr auto size() const requires sized_range<const V> {
|
| 4622 |
auto n = ranges::size(base_);
|
| 4623 |
return ranges::min(n, static_cast<decltype(n)>(count_));
|
| 4624 |
}
|
| 4625 |
+
|
| 4626 |
+
constexpr auto reserve_hint() {
|
| 4627 |
+
if constexpr (approximately_sized_range<V>) {
|
| 4628 |
+
auto n = static_cast<range_difference_t<V>>(ranges::reserve_hint(base_));
|
| 4629 |
+
return to-unsigned-like(ranges::min(n, count_));
|
| 4630 |
+
}
|
| 4631 |
+
return to-unsigned-like(count_);
|
| 4632 |
+
}
|
| 4633 |
+
|
| 4634 |
+
constexpr auto reserve_hint() const {
|
| 4635 |
+
if constexpr (approximately_sized_range<const V>) {
|
| 4636 |
+
auto n = static_cast<range_difference_t<const V>>(ranges::reserve_hint(base_));
|
| 4637 |
+
return to-unsigned-like(ranges::min(n, count_));
|
| 4638 |
+
}
|
| 4639 |
+
return to-unsigned-like(count_);
|
| 4640 |
+
}
|
| 4641 |
};
|
| 4642 |
|
| 4643 |
template<class R>
|
| 4644 |
take_view(R&&, range_difference_t<R>)
|
| 4645 |
-> take_view<views::all_t<R>>;
|
|
|
|
| 4889 |
then
|
| 4890 |
`U(ranges::begin(E) + std::min<D>(ranges::distance(E), F), ranges::end(E))`,
|
| 4891 |
except that `E` is evaluated only once, where `U` is
|
| 4892 |
`span<typename T::element_type>` if `T` is a specialization of `span`
|
| 4893 |
and `T` otherwise.
|
| 4894 |
+
- Otherwise, if `T` is a specialization of `subrange` that models
|
| 4895 |
+
`random_access_range` and `sized_range`, then
|
| 4896 |
`T(ranges::begin(E) + std::min<D>(ranges::distance(E), F), ranges::{}end(E),
|
| 4897 |
to-unsigned-like(ranges::distance(E) -
|
| 4898 |
std::min<D>(ranges::distance(E), F)))`, except that `E` and `F` are
|
| 4899 |
each evaluated only once.
|
| 4900 |
- Otherwise, if `T` is a specialization of `repeat_view`
|
|
|
|
| 4955 |
const auto s = ranges::size(base_);
|
| 4956 |
const auto c = static_cast<decltype(s)>(count_);
|
| 4957 |
return s < c ? 0 : s - c;
|
| 4958 |
}
|
| 4959 |
|
| 4960 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V> {
|
| 4961 |
+
const auto s = static_cast<range_difference_t<V>>(ranges::reserve_hint(base_));
|
| 4962 |
+
return to-unsigned-like(s < count_ ? 0 : s - count_);
|
| 4963 |
+
}
|
| 4964 |
+
|
| 4965 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V> {
|
| 4966 |
+
const auto s = static_cast<range_difference_t<const V>>(ranges::reserve_hint(base_));
|
| 4967 |
+
return to-unsigned-like(s < count_ ? 0 : s - count_);
|
| 4968 |
+
}
|
| 4969 |
+
|
| 4970 |
private:
|
| 4971 |
V base_ = V(); // exposition only
|
| 4972 |
range_difference_t<V> count_ = 0; // exposition only
|
| 4973 |
};
|
| 4974 |
|
|
|
|
| 5471 |
noexcept(noexcept(ranges::iter_swap(*x.inner_, *y.inner_)))
|
| 5472 |
requires indirectly_swappable<InnerIter>;
|
| 5473 |
```
|
| 5474 |
|
| 5475 |
*Effects:* Equivalent to:
|
| 5476 |
+
`ranges::iter_swap(*x.`*`inner_`*`, *y.`*`inner_`*`);`
|
| 5477 |
|
| 5478 |
#### Class template `join_view::sentinel` <a id="range.join.sentinel">[[range.join.sentinel]]</a>
|
| 5479 |
|
| 5480 |
``` cpp
|
| 5481 |
namespace std::ranges {
|
|
|
|
| 5550 |
|
| 5551 |
#### Class template `join_with_view` <a id="range.join.with.view">[[range.join.with.view]]</a>
|
| 5552 |
|
| 5553 |
``` cpp
|
| 5554 |
namespace std::ranges {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5555 |
template<class R>
|
| 5556 |
concept bidirectional-common = bidirectional_range<R> && common_range<R>; // exposition only
|
| 5557 |
|
| 5558 |
template<input_range V, forward_range Pattern>
|
| 5559 |
requires view<V> && input_range<range_reference_t<V>>
|
| 5560 |
&& view<Pattern>
|
| 5561 |
+
&& concatable<range_reference_t<V>, Pattern>
|
| 5562 |
class join_with_view : public view_interface<join_with_view<V, Pattern>> {
|
| 5563 |
using InnerRng = range_reference_t<V>; // exposition only
|
| 5564 |
|
| 5565 |
V base_ = V(); // exposition only
|
| 5566 |
non-propagating-cache<iterator_t<V>> outer_it_; // exposition only, present only
|
|
|
|
| 5602 |
}
|
| 5603 |
constexpr auto begin() const
|
| 5604 |
requires forward_range<const V> &&
|
| 5605 |
forward_range<const Pattern> &&
|
| 5606 |
is_reference_v<range_reference_t<const V>> &&
|
| 5607 |
+
input_range<range_reference_t<const V>> &&
|
| 5608 |
+
concatable<range_reference_t<const V>, const Pattern> {
|
| 5609 |
return iterator<true>{*this, ranges::begin(base_)};
|
| 5610 |
}
|
| 5611 |
|
| 5612 |
constexpr auto end() {
|
| 5613 |
if constexpr (forward_range<V> &&
|
|
|
|
| 5618 |
return sentinel<simple-view<V> && simple-view<Pattern>>{*this};
|
| 5619 |
}
|
| 5620 |
constexpr auto end() const
|
| 5621 |
requires forward_range<const V> && forward_range<const Pattern> &&
|
| 5622 |
is_reference_v<range_reference_t<const V>> &&
|
| 5623 |
+
input_range<range_reference_t<const V>> &&
|
| 5624 |
+
concatable<range_reference_t<const V>, const Pattern> {
|
| 5625 |
using InnerConstRng = range_reference_t<const V>;
|
| 5626 |
if constexpr (forward_range<InnerConstRng> &&
|
| 5627 |
common_range<const V> && common_range<InnerConstRng>)
|
| 5628 |
return iterator<true>{*this, ranges::end(base_)};
|
| 5629 |
else
|
|
|
|
| 5661 |
|
| 5662 |
``` cpp
|
| 5663 |
namespace std::ranges {
|
| 5664 |
template<input_range V, forward_range Pattern>
|
| 5665 |
requires view<V> && input_range<range_reference_t<V>>
|
| 5666 |
+
&& view<Pattern> && concatable<range_reference_t<V>, Pattern>
|
| 5667 |
template<bool Const>
|
| 5668 |
class join_with_view<V, Pattern>::iterator {
|
| 5669 |
using Parent = maybe-const<Const, join_with_view>; // exposition only
|
| 5670 |
using Base = maybe-const<Const, V>; // exposition only
|
| 5671 |
using InnerBase = range_reference_t<Base>; // exposition only
|
|
|
|
| 5764 |
iter_reference_t<PatternIter>>>
|
| 5765 |
```
|
| 5766 |
|
| 5767 |
is `false`, `iterator_category` denotes `input_iterator_tag`.
|
| 5768 |
- Otherwise, if *OUTERC*, *INNERC*, and *PATTERNC* each model
|
| 5769 |
+
`derived_from<bidirectional_iterator_tag>` and *`InnerBase`* and
|
| 5770 |
*`PatternBase`* each model `common_range`, `iterator_category` denotes
|
| 5771 |
`bidirectional_iterator_tag`.
|
| 5772 |
- Otherwise, if *OUTERC*, *INNERC*, and *PATTERNC* each model
|
| 5773 |
`derived_from<forward_iterator_tag>`, `iterator_category` denotes
|
| 5774 |
`forward_iterator_tag`.
|
|
|
|
| 5832 |
``` cpp
|
| 5833 |
while (true) {
|
| 5834 |
if (inner_it_.index() == 0) {
|
| 5835 |
if (std::get<0>(inner_it_) != ranges::end(parent_->pattern_))
|
| 5836 |
break;
|
| 5837 |
+
inner_it_.template emplace<1>(ranges::begin(update-inner()));
|
| 5838 |
} else {
|
| 5839 |
if (std::get<1>(inner_it_) != ranges::end(get-inner()))
|
| 5840 |
break;
|
| 5841 |
if (++outer() == ranges::end(parent_->base_)) {
|
| 5842 |
if constexpr (ref-is-glvalue)
|
| 5843 |
+
inner_it_.template emplace<0>();
|
| 5844 |
break;
|
| 5845 |
}
|
| 5846 |
+
inner_it_.template emplace<0>(ranges::begin(parent_->pattern_));
|
| 5847 |
}
|
| 5848 |
}
|
| 5849 |
```
|
| 5850 |
|
| 5851 |
[*Note 1*: `join_with_view` iterators use the *satisfy* function to
|
|
|
|
| 5862 |
first overload, also initializes *outer_it\_* with `std::move(outer)`.
|
| 5863 |
Then, equivalent to:
|
| 5864 |
|
| 5865 |
``` cpp
|
| 5866 |
if (outer() != ranges::end(parent_->base_)) {
|
| 5867 |
+
inner_it_.template emplace<1>(ranges::begin(update-inner()));
|
| 5868 |
satisfy();
|
| 5869 |
}
|
| 5870 |
```
|
| 5871 |
|
| 5872 |
``` cpp
|
|
|
|
| 5879 |
*Effects:* Initializes *outer_it\_* with `std::move(i.`*`outer_it_`*`)`
|
| 5880 |
and *parent\_* with `i.`*`parent_`*. Then, equivalent to:
|
| 5881 |
|
| 5882 |
``` cpp
|
| 5883 |
if (i.inner_it_.index() == 0)
|
| 5884 |
+
inner_it_.template emplace<0>(std::get<0>(std::move(i.inner_it_)));
|
| 5885 |
else
|
| 5886 |
+
inner_it_.template emplace<1>(std::get<1>(std::move(i.inner_it_)));
|
| 5887 |
```
|
| 5888 |
|
| 5889 |
[*Note 2*: `Const` can only be `true` when *Base* models
|
| 5890 |
`forward_range`. — *end note*]
|
| 5891 |
|
|
|
|
| 5941 |
*Effects:* Equivalent to:
|
| 5942 |
|
| 5943 |
``` cpp
|
| 5944 |
if (outer_it_ == ranges::end(parent_->base_)) {
|
| 5945 |
auto&& inner = *--outer_it_;
|
| 5946 |
+
inner_it_.template emplace<1>(ranges::end(inner));
|
| 5947 |
}
|
| 5948 |
|
| 5949 |
while (true) {
|
| 5950 |
if (inner_it_.index() == 0) {
|
| 5951 |
auto& it = std::get<0>(inner_it_);
|
| 5952 |
if (it == ranges::begin(parent_->pattern_)) {
|
| 5953 |
auto&& inner = *--outer_it_;
|
| 5954 |
+
inner_it_.template emplace<1>(ranges::end(inner));
|
| 5955 |
} else {
|
| 5956 |
break;
|
| 5957 |
}
|
| 5958 |
} else {
|
| 5959 |
auto& it = std::get<1>(inner_it_);
|
| 5960 |
auto&& inner = *outer_it_;
|
| 5961 |
if (it == ranges::begin(inner)) {
|
| 5962 |
+
inner_it_.template emplace<0>(ranges::end(parent_->pattern_));
|
| 5963 |
} else {
|
| 5964 |
break;
|
| 5965 |
}
|
| 5966 |
}
|
| 5967 |
}
|
|
|
|
| 5999 |
|
| 6000 |
``` cpp
|
| 6001 |
namespace std::ranges {
|
| 6002 |
template<input_range V, forward_range Pattern>
|
| 6003 |
requires view<V> && input_range<range_reference_t<V>>
|
| 6004 |
+
&& view<Pattern> && concatable<range_reference_t<V>, Pattern>
|
| 6005 |
template<bool Const>
|
| 6006 |
class join_with_view<V, Pattern>::sentinel {
|
| 6007 |
using Parent = maybe-const<Const, join_with_view>; // exposition only
|
| 6008 |
using Base = maybe-const<Const, V>; // exposition only
|
| 6009 |
sentinel_t<Base> end_ = sentinel_t<Base>(); // exposition only
|
|
|
|
| 6248 |
``` cpp
|
| 6249 |
constexpr outer-iterator(outer-iterator<!Const> i)
|
| 6250 |
requires Const && convertible_to<iterator_t<V>, iterator_t<Base>>;
|
| 6251 |
```
|
| 6252 |
|
| 6253 |
+
*Effects:* Initializes *parent\_* with `i.`*`parent_`*, *current\_* with
|
| 6254 |
+
`std::move(i.`*`current_`*`)`, and *trailing_empty\_* with
|
| 6255 |
+
`i.`*`trailing_empty_`*.
|
| 6256 |
|
| 6257 |
``` cpp
|
| 6258 |
constexpr value_type operator*() const;
|
| 6259 |
```
|
| 6260 |
|
|
|
|
| 6329 |
struct lazy_split_view<V, Pattern>::outer-iterator<Const>::value_type
|
| 6330 |
: view_interface<value_type> {
|
| 6331 |
private:
|
| 6332 |
outer-iterator i_ = outer-iterator(); // exposition only
|
| 6333 |
|
| 6334 |
+
constexpr explicit value_type(outer-iterator i); // exposition only
|
|
|
|
|
|
|
| 6335 |
|
| 6336 |
+
public:
|
| 6337 |
constexpr inner-iterator<Const> begin() const;
|
| 6338 |
constexpr default_sentinel_t end() const noexcept;
|
| 6339 |
};
|
| 6340 |
}
|
| 6341 |
```
|
|
|
|
| 6373 |
using Base = maybe-const<Const, V>; // exposition only
|
| 6374 |
outer-iterator<Const> i_ = outer-iterator<Const>(); // exposition only
|
| 6375 |
bool incremented_ = false; // exposition only
|
| 6376 |
|
| 6377 |
public:
|
| 6378 |
+
using iterator_concept = outer-iterator<Const>::iterator_concept;
|
| 6379 |
|
| 6380 |
using iterator_category = see belownc; // present only if Base
|
| 6381 |
// models forward_range
|
| 6382 |
using value_type = range_value_t<Base>;
|
| 6383 |
using difference_type = range_difference_t<Base>;
|
|
|
|
| 6668 |
|
| 6669 |
``` cpp
|
| 6670 |
constexpr iterator_t<V> base() const;
|
| 6671 |
```
|
| 6672 |
|
| 6673 |
+
*Effects:* Equivalent to: `return `*`cur_`*`;`
|
| 6674 |
|
| 6675 |
``` cpp
|
| 6676 |
constexpr value_type operator*() const;
|
| 6677 |
```
|
| 6678 |
|
| 6679 |
+
*Effects:* Equivalent to: `return {`*`cur_`*`, `*`next_`*`.begin()};`
|
| 6680 |
|
| 6681 |
``` cpp
|
| 6682 |
constexpr iterator& operator++();
|
| 6683 |
```
|
| 6684 |
|
|
|
|
| 6753 |
```
|
| 6754 |
|
| 6755 |
*Effects:* Equivalent to:
|
| 6756 |
`return x.`*`cur_`*` == y.`*`end_`*` && !x.`*`trailing_empty_`*`;`
|
| 6757 |
|
| 6758 |
+
### Concat view <a id="range.concat">[[range.concat]]</a>
|
| 6759 |
+
|
| 6760 |
+
#### Overview <a id="range.concat.overview">[[range.concat.overview]]</a>
|
| 6761 |
+
|
| 6762 |
+
`concat_view` presents a view that concatenates all the underlying
|
| 6763 |
+
ranges.
|
| 6764 |
+
|
| 6765 |
+
The name `views::concat` denotes a customization point object
|
| 6766 |
+
[[customization.point.object]]. Given a pack of subexpressions `Es...`,
|
| 6767 |
+
the expression `views::concat(Es...)` is expression-equivalent to
|
| 6768 |
+
|
| 6769 |
+
- `views::all(Es...)` if `Es` is a pack with only one element whose type
|
| 6770 |
+
models `input_range`,
|
| 6771 |
+
- otherwise, `concat_view(Es...)`.
|
| 6772 |
+
|
| 6773 |
+
[*Example 1*:
|
| 6774 |
+
|
| 6775 |
+
``` cpp
|
| 6776 |
+
vector<int> v1{1, 2, 3}, v2{4, 5}, v3{};
|
| 6777 |
+
array a{6, 7, 8};
|
| 6778 |
+
auto s = views::single(9);
|
| 6779 |
+
for (auto&& i : views::concat(v1, v2, v3, a, s)) {
|
| 6780 |
+
print("{} ", i); // prints 1 2 3 4 5 6 7 8 9
|
| 6781 |
+
}
|
| 6782 |
+
```
|
| 6783 |
+
|
| 6784 |
+
— *end example*]
|
| 6785 |
+
|
| 6786 |
+
#### Class template `concat_view` <a id="range.concat.view">[[range.concat.view]]</a>
|
| 6787 |
+
|
| 6788 |
+
``` cpp
|
| 6789 |
+
namespace std::ranges {
|
| 6790 |
+
template<class... Rs>
|
| 6791 |
+
using concat-reference-t = common_reference_t<range_reference_t<Rs>...>; // exposition only
|
| 6792 |
+
template<class... Rs>
|
| 6793 |
+
using concat-value-t = common_type_t<range_value_t<Rs>...>; // exposition only
|
| 6794 |
+
template<class... Rs>
|
| 6795 |
+
using concat-rvalue-reference-t = // exposition only
|
| 6796 |
+
common_reference_t<range_rvalue_reference_t<Rs>...>;
|
| 6797 |
+
|
| 6798 |
+
template<class... Rs>
|
| 6799 |
+
concept concat-indirectly-readable = see below; // exposition only
|
| 6800 |
+
template<class... Rs>
|
| 6801 |
+
concept concatable = see below; // exposition only
|
| 6802 |
+
template<bool Const, class... Rs>
|
| 6803 |
+
concept concat-is-random-access = see below; // exposition only
|
| 6804 |
+
template<bool Const, class... Rs>
|
| 6805 |
+
concept concat-is-bidirectional = see below; // exposition only
|
| 6806 |
+
|
| 6807 |
+
template<input_range... Views>
|
| 6808 |
+
requires (view<Views> && ...) && (sizeof...(Views) > 0) &&
|
| 6809 |
+
concatable<Views...>
|
| 6810 |
+
class concat_view : public view_interface<concat_view<Views...>> {
|
| 6811 |
+
|
| 6812 |
+
tuple<Views...> views_; // exposition only
|
| 6813 |
+
|
| 6814 |
+
// [range.concat.iterator], class template concat_view::iterator
|
| 6815 |
+
template<bool> class iterator; // exposition only
|
| 6816 |
+
|
| 6817 |
+
public:
|
| 6818 |
+
constexpr concat_view() = default;
|
| 6819 |
+
constexpr explicit concat_view(Views... views);
|
| 6820 |
+
|
| 6821 |
+
constexpr iterator<false> begin() requires (!(simple-view<Views> && ...));
|
| 6822 |
+
constexpr iterator<true> begin() const
|
| 6823 |
+
requires (range<const Views> && ...) && concatable<const Views...>;
|
| 6824 |
+
|
| 6825 |
+
constexpr auto end() requires (!(simple-view<Views> && ...));
|
| 6826 |
+
constexpr auto end() const
|
| 6827 |
+
requires (range<const Views> && ...) && concatable<const Views...>;
|
| 6828 |
+
|
| 6829 |
+
constexpr auto size() requires (sized_range<Views> && ...);
|
| 6830 |
+
constexpr auto size() const requires (sized_range<const Views> && ...);
|
| 6831 |
+
};
|
| 6832 |
+
|
| 6833 |
+
template<class... R>
|
| 6834 |
+
concat_view(R&&...) -> concat_view<views::all_t<R>...>;
|
| 6835 |
+
}
|
| 6836 |
+
```
|
| 6837 |
+
|
| 6838 |
+
``` cpp
|
| 6839 |
+
template<class... Rs>
|
| 6840 |
+
concept concat-indirectly-readable = see below; // exposition only
|
| 6841 |
+
```
|
| 6842 |
+
|
| 6843 |
+
The exposition-only `concat-indirectly-readable` concept is equivalent
|
| 6844 |
+
to:
|
| 6845 |
+
|
| 6846 |
+
``` cpp
|
| 6847 |
+
template<class Ref, class RRef, class It>
|
| 6848 |
+
concept concat-indirectly-readable-impl = // exposition only
|
| 6849 |
+
requires (const It it) {
|
| 6850 |
+
{ *it } -> convertible_to<Ref>;
|
| 6851 |
+
{ ranges::iter_move(it) } -> convertible_to<RRef>;
|
| 6852 |
+
};
|
| 6853 |
+
|
| 6854 |
+
template<class... Rs>
|
| 6855 |
+
concept concat-indirectly-readable = // exposition only
|
| 6856 |
+
common_reference_with<concat-reference-t<Rs...>&&,
|
| 6857 |
+
concat-value-t<Rs...>&> &&
|
| 6858 |
+
common_reference_with<concat-reference-t<Rs...>&&,
|
| 6859 |
+
concat-rvalue-reference-t<Rs...>&&> &&
|
| 6860 |
+
common_reference_with<concat-rvalue-reference-t<Rs...>&&,
|
| 6861 |
+
concat-value-t<Rs...> const&> &&
|
| 6862 |
+
(concat-indirectly-readable-impl<concat-reference-t<Rs...>,
|
| 6863 |
+
concat-rvalue-reference-t<Rs...>,
|
| 6864 |
+
iterator_t<Rs>> && ...);
|
| 6865 |
+
```
|
| 6866 |
+
|
| 6867 |
+
``` cpp
|
| 6868 |
+
template<class... Rs>
|
| 6869 |
+
concept concatable = see below; // exposition only
|
| 6870 |
+
```
|
| 6871 |
+
|
| 6872 |
+
The exposition-only `concatable` concept is equivalent to:
|
| 6873 |
+
|
| 6874 |
+
``` cpp
|
| 6875 |
+
template<class... Rs>
|
| 6876 |
+
concept concatable = requires { // exposition only
|
| 6877 |
+
typename concat-reference-t<Rs...>;
|
| 6878 |
+
typename concat-value-t<Rs...>;
|
| 6879 |
+
typename concat-rvalue-reference-t<Rs...>;
|
| 6880 |
+
} && concat-indirectly-readable<Rs...>;
|
| 6881 |
+
```
|
| 6882 |
+
|
| 6883 |
+
``` cpp
|
| 6884 |
+
template<bool Const, class... Rs>
|
| 6885 |
+
concept concat-is-random-access = see below; // exposition only
|
| 6886 |
+
```
|
| 6887 |
+
|
| 6888 |
+
Let `Fs` be the pack that consists of all elements of `Rs` except the
|
| 6889 |
+
last element, then *`concat-is-random-access`* is equivalent to:
|
| 6890 |
+
|
| 6891 |
+
``` cpp
|
| 6892 |
+
template<bool Const, class... Rs>
|
| 6893 |
+
concept concat-is-random-access = // exposition only
|
| 6894 |
+
all-random-access<Const, Rs...> &&
|
| 6895 |
+
(common_range<maybe-const<Const, Fs>> && ...);
|
| 6896 |
+
```
|
| 6897 |
+
|
| 6898 |
+
``` cpp
|
| 6899 |
+
template<bool Const, class... Rs>
|
| 6900 |
+
concept concat-is-bidirectional = see below; // exposition only
|
| 6901 |
+
```
|
| 6902 |
+
|
| 6903 |
+
Let `Fs` be the pack that consists of all elements of `Rs` except the
|
| 6904 |
+
last element, then *`concat-is-bidirectional`* is equivalent to:
|
| 6905 |
+
|
| 6906 |
+
``` cpp
|
| 6907 |
+
template<bool Const, class... Rs>
|
| 6908 |
+
concept concat-is-bidirectional = // exposition only
|
| 6909 |
+
all-bidirectional<Const, Rs...> &&
|
| 6910 |
+
(common_range<maybe-const<Const, Fs>> && ...);
|
| 6911 |
+
```
|
| 6912 |
+
|
| 6913 |
+
``` cpp
|
| 6914 |
+
constexpr explicit concat_view(Views... views);
|
| 6915 |
+
```
|
| 6916 |
+
|
| 6917 |
+
*Effects:* Initializes *views\_* with `std::move(views)...`.
|
| 6918 |
+
|
| 6919 |
+
``` cpp
|
| 6920 |
+
constexpr iterator<false> begin() requires (!(simple-view<Views> && ...));
|
| 6921 |
+
constexpr iterator<true> begin() const
|
| 6922 |
+
requires (range<const Views> && ...) && concatable<const Views...>;
|
| 6923 |
+
```
|
| 6924 |
+
|
| 6925 |
+
*Effects:* Let *is-const* be `true` for the const-qualified overload,
|
| 6926 |
+
and `false` otherwise. Equivalent to:
|
| 6927 |
+
|
| 6928 |
+
``` cpp
|
| 6929 |
+
iterator<is-const> it(this, in_place_index<0>, ranges::begin(std::get<0>(views_)));
|
| 6930 |
+
it.template satisfy<0>();
|
| 6931 |
+
return it;
|
| 6932 |
+
```
|
| 6933 |
+
|
| 6934 |
+
``` cpp
|
| 6935 |
+
constexpr auto end() requires (!(simple-view<Views> && ...));
|
| 6936 |
+
constexpr auto end() const
|
| 6937 |
+
requires (range<const Views> && ...) && concatable<const Views...>;
|
| 6938 |
+
```
|
| 6939 |
+
|
| 6940 |
+
*Effects:* Let *is-const* be `true` for the const-qualified overload,
|
| 6941 |
+
and `false` otherwise. Equivalent to:
|
| 6942 |
+
|
| 6943 |
+
``` cpp
|
| 6944 |
+
constexpr auto N = sizeof...(Views);
|
| 6945 |
+
if constexpr (common_range<maybe-const<is-const, Views...[N - 1]>>) {
|
| 6946 |
+
return iterator<is-const>(this, in_place_index<N - 1>,
|
| 6947 |
+
ranges::end(std::get<N - 1>(views_)));
|
| 6948 |
+
} else {
|
| 6949 |
+
return default_sentinel;
|
| 6950 |
+
}
|
| 6951 |
+
```
|
| 6952 |
+
|
| 6953 |
+
``` cpp
|
| 6954 |
+
constexpr auto size() requires (sized_range<Views> && ...);
|
| 6955 |
+
constexpr auto size() const requires (sized_range<const Views> && ...);
|
| 6956 |
+
```
|
| 6957 |
+
|
| 6958 |
+
*Effects:* Equivalent to:
|
| 6959 |
+
|
| 6960 |
+
``` cpp
|
| 6961 |
+
return apply(
|
| 6962 |
+
[](auto... sizes) {
|
| 6963 |
+
using CT = make-unsigned-like-t<common_type_t<decltype(sizes)...>>;
|
| 6964 |
+
return (CT(sizes) + ...);
|
| 6965 |
+
},
|
| 6966 |
+
tuple-transform(ranges::size, views_));
|
| 6967 |
+
```
|
| 6968 |
+
|
| 6969 |
+
#### Class `concat_view::iterator` <a id="range.concat.iterator">[[range.concat.iterator]]</a>
|
| 6970 |
+
|
| 6971 |
+
``` cpp
|
| 6972 |
+
namespace std::ranges {
|
| 6973 |
+
template<input_range... Views>
|
| 6974 |
+
requires (view<Views> && ...) && (sizeof...(Views) > 0) &&
|
| 6975 |
+
concatable<Views...>
|
| 6976 |
+
template<bool Const>
|
| 6977 |
+
class concat_view<Views...>::iterator {
|
| 6978 |
+
|
| 6979 |
+
public:
|
| 6980 |
+
using iterator_category = see below; // not always present
|
| 6981 |
+
using iterator_concept = see below;
|
| 6982 |
+
using value_type = concat-value-t<maybe-const<Const, Views>...>;
|
| 6983 |
+
using difference_type = common_type_t<range_difference_t<maybe-const<Const, Views>>...>;
|
| 6984 |
+
|
| 6985 |
+
private:
|
| 6986 |
+
using base-iter = // exposition only
|
| 6987 |
+
variant<iterator_t<maybe-const<Const, Views>>...>;
|
| 6988 |
+
|
| 6989 |
+
maybe-const<Const, concat_view>* parent_ = nullptr; // exposition only
|
| 6990 |
+
base-iter it_; // exposition only
|
| 6991 |
+
|
| 6992 |
+
template<size_t N>
|
| 6993 |
+
constexpr void satisfy(); // exposition only
|
| 6994 |
+
template<size_t N>
|
| 6995 |
+
constexpr void prev(); // exposition only
|
| 6996 |
+
|
| 6997 |
+
template<size_t N>
|
| 6998 |
+
constexpr void advance-fwd(difference_type offset, // exposition only
|
| 6999 |
+
difference_type steps);
|
| 7000 |
+
template<size_t N>
|
| 7001 |
+
constexpr void advance-bwd(difference_type offset, // exposition only
|
| 7002 |
+
difference_type steps);
|
| 7003 |
+
|
| 7004 |
+
template<class... Args>
|
| 7005 |
+
constexpr explicit iterator(maybe-const<Const, concat_view>* parent, // exposition only
|
| 7006 |
+
Args&&... args)
|
| 7007 |
+
requires constructible_from<base-iter, Args&&...>;
|
| 7008 |
+
|
| 7009 |
+
public:
|
| 7010 |
+
iterator() = default;
|
| 7011 |
+
|
| 7012 |
+
constexpr iterator(iterator<!Const> i)
|
| 7013 |
+
requires Const && (convertible_to<iterator_t<Views>, iterator_t<const Views>> && ...);
|
| 7014 |
+
|
| 7015 |
+
constexpr decltype(auto) operator*() const;
|
| 7016 |
+
constexpr iterator& operator++();
|
| 7017 |
+
constexpr void operator++(int);
|
| 7018 |
+
constexpr iterator operator++(int)
|
| 7019 |
+
requires all-forward<Const, Views...>;
|
| 7020 |
+
constexpr iterator& operator--()
|
| 7021 |
+
requires concat-is-bidirectional<Const, Views...>;
|
| 7022 |
+
constexpr iterator operator--(int)
|
| 7023 |
+
requires concat-is-bidirectional<Const, Views...>;
|
| 7024 |
+
constexpr iterator& operator+=(difference_type n)
|
| 7025 |
+
requires concat-is-random-access<Const, Views...>;
|
| 7026 |
+
constexpr iterator& operator-=(difference_type n)
|
| 7027 |
+
requires concat-is-random-access<Const, Views...>;
|
| 7028 |
+
constexpr decltype(auto) operator[](difference_type n) const
|
| 7029 |
+
requires concat-is-random-access<Const, Views...>;
|
| 7030 |
+
|
| 7031 |
+
friend constexpr bool operator==(const iterator& x, const iterator& y)
|
| 7032 |
+
requires (equality_comparable<iterator_t<maybe-const<Const, Views>>> && ...);
|
| 7033 |
+
friend constexpr bool operator==(const iterator& it, default_sentinel_t);
|
| 7034 |
+
friend constexpr bool operator<(const iterator& x, const iterator& y)
|
| 7035 |
+
requires all-random-access<Const, Views...>;
|
| 7036 |
+
friend constexpr bool operator>(const iterator& x, const iterator& y)
|
| 7037 |
+
requires all-random-access<Const, Views...>;
|
| 7038 |
+
friend constexpr bool operator<=(const iterator& x, const iterator& y)
|
| 7039 |
+
requires all-random-access<Const, Views...>;
|
| 7040 |
+
friend constexpr bool operator>=(const iterator& x, const iterator& y)
|
| 7041 |
+
requires all-random-access<Const, Views...>;
|
| 7042 |
+
friend constexpr auto operator<=>(const iterator& x, const iterator& y)
|
| 7043 |
+
requires (all-random-access<Const, Views...> &&
|
| 7044 |
+
(three_way_comparable<iterator_t<maybe-const<Const, Views>>> && ...));
|
| 7045 |
+
friend constexpr iterator operator+(const iterator& it, difference_type n)
|
| 7046 |
+
requires concat-is-random-access<Const, Views...>;
|
| 7047 |
+
friend constexpr iterator operator+(difference_type n, const iterator& it)
|
| 7048 |
+
requires concat-is-random-access<Const, Views...>;
|
| 7049 |
+
friend constexpr iterator operator-(const iterator& it, difference_type n)
|
| 7050 |
+
requires concat-is-random-access<Const, Views...>;
|
| 7051 |
+
friend constexpr difference_type operator-(const iterator& x, const iterator& y)
|
| 7052 |
+
requires concat-is-random-access<Const, Views...>;
|
| 7053 |
+
friend constexpr difference_type operator-(const iterator& x, default_sentinel_t)
|
| 7054 |
+
requires see below;
|
| 7055 |
+
friend constexpr difference_type operator-(default_sentinel_t, const iterator& x)
|
| 7056 |
+
requires see below;
|
| 7057 |
+
friend constexpr decltype(auto) iter_move(const iterator& it) noexcept(see below);
|
| 7058 |
+
friend constexpr void iter_swap(const iterator& x, const iterator& y) noexcept(see below)
|
| 7059 |
+
requires see below;
|
| 7060 |
+
};
|
| 7061 |
+
}
|
| 7062 |
+
```
|
| 7063 |
+
|
| 7064 |
+
`iterator::iterator_concept` is defined as follows:
|
| 7065 |
+
|
| 7066 |
+
- If `concat-is-random-access<Const, Views...>` is modeled, then
|
| 7067 |
+
`iterator_concept` denotes `random_access_iterator_tag`.
|
| 7068 |
+
- Otherwise, if `concat-is-bidirectional<Const, Views...>` is modeled,
|
| 7069 |
+
then `iterator_concept` denotes `bidirectional_iterator_tag`.
|
| 7070 |
+
- Otherwise, if `all-forward<Const, Views...>` is modeled, then
|
| 7071 |
+
`iterator_concept` denotes `forward_iterator_tag`.
|
| 7072 |
+
- Otherwise, `iterator_concept` denotes `input_iterator_tag`.
|
| 7073 |
+
|
| 7074 |
+
The member *typedef-name* `iterator_category` is defined if and only if
|
| 7075 |
+
`all-forward<Const, Views...>` is modeled. In that case,
|
| 7076 |
+
`iterator::iterator_category` is defined as follows:
|
| 7077 |
+
|
| 7078 |
+
- If `is_reference_v<concat-reference-t<maybe-const<Const, Views>...>>`
|
| 7079 |
+
is `false`, then `iterator_category` denotes `input_iterator_tag`.
|
| 7080 |
+
- Otherwise, let `Cs` denote the pack of types
|
| 7081 |
+
`iterator_traits<iterator_t<maybe-const<Const, Views>>>::iterator_category...`.
|
| 7082 |
+
- If
|
| 7083 |
+
`(derived_from<Cs, random_access_iterator_tag> && ...) && concat-is-random-ac-{cess}<Const, Views...>`
|
| 7084 |
+
is `true`, `iterator_category` denotes `random_access_iterator_tag`.
|
| 7085 |
+
- Otherwise, if
|
| 7086 |
+
`(derived_from<Cs, bidirectional_iterator_tag> && ...) && concat-is-{bidirectional}<Const, Views...>`
|
| 7087 |
+
is `true`, `iterator_category` denotes `bidirectional_iterator_tag`.
|
| 7088 |
+
- Otherwise, if `(derived_from<Cs, forward_iterator_tag> && ...)` is
|
| 7089 |
+
`true`, `iterator_category` denotes `forward_iterator_tag`.
|
| 7090 |
+
- Otherwise, `iterator_category` denotes `input_iterator_tag`.
|
| 7091 |
+
|
| 7092 |
+
``` cpp
|
| 7093 |
+
template<size_t N>
|
| 7094 |
+
constexpr void satisfy();
|
| 7095 |
+
```
|
| 7096 |
+
|
| 7097 |
+
*Effects:* Equivalent to:
|
| 7098 |
+
|
| 7099 |
+
``` cpp
|
| 7100 |
+
if constexpr (N < (sizeof...(Views) - 1)) {
|
| 7101 |
+
if (std::get<N>(it_) == ranges::end(std::get<N>(parent_->views_))) {
|
| 7102 |
+
it_.template emplace<N + 1>(ranges::begin(std::get<N + 1>(parent_->views_)));
|
| 7103 |
+
satisfy<N + 1>();
|
| 7104 |
+
}
|
| 7105 |
+
}
|
| 7106 |
+
```
|
| 7107 |
+
|
| 7108 |
+
``` cpp
|
| 7109 |
+
template<size_t N>
|
| 7110 |
+
constexpr void prev();
|
| 7111 |
+
```
|
| 7112 |
+
|
| 7113 |
+
*Effects:* Equivalent to:
|
| 7114 |
+
|
| 7115 |
+
``` cpp
|
| 7116 |
+
if constexpr (N == 0) {
|
| 7117 |
+
--std::get<0>(it_);
|
| 7118 |
+
} else {
|
| 7119 |
+
if (std::get<N>(it_) == ranges::begin(std::get<N>(parent_->views_))) {
|
| 7120 |
+
it_.template emplace<N - 1>(ranges::end(std::get<N - 1>(parent_->views_)));
|
| 7121 |
+
prev<N - 1>();
|
| 7122 |
+
} else {
|
| 7123 |
+
--std::get<N>(it_);
|
| 7124 |
+
}
|
| 7125 |
+
}
|
| 7126 |
+
```
|
| 7127 |
+
|
| 7128 |
+
``` cpp
|
| 7129 |
+
template<size_t N>
|
| 7130 |
+
constexpr void advance-fwd(difference_type offset, difference_type steps);
|
| 7131 |
+
```
|
| 7132 |
+
|
| 7133 |
+
*Effects:* Equivalent to:
|
| 7134 |
+
|
| 7135 |
+
``` cpp
|
| 7136 |
+
using underlying_diff_type = iter_difference_t<variant_alternative_t<N, base-iter>>;
|
| 7137 |
+
if constexpr (N == sizeof...(Views) - 1) {
|
| 7138 |
+
std::get<N>(it_) += static_cast<underlying_diff_type>(steps);
|
| 7139 |
+
} else {
|
| 7140 |
+
auto n_size = ranges::distance(std::get<N>(parent_->views_));
|
| 7141 |
+
if (offset + steps < n_size) {
|
| 7142 |
+
std::get<N>(it_) += static_cast<underlying_diff_type>(steps);
|
| 7143 |
+
} else {
|
| 7144 |
+
it_.template emplace<N + 1>(ranges::begin(std::get<N + 1>(parent_->views_)));
|
| 7145 |
+
advance-fwd<N + 1>(0, offset + steps - n_size);
|
| 7146 |
+
}
|
| 7147 |
+
}
|
| 7148 |
+
```
|
| 7149 |
+
|
| 7150 |
+
``` cpp
|
| 7151 |
+
template<size_t N>
|
| 7152 |
+
constexpr void advance-bwd(difference_type offset, difference_type steps);
|
| 7153 |
+
```
|
| 7154 |
+
|
| 7155 |
+
*Effects:* Equivalent to:
|
| 7156 |
+
|
| 7157 |
+
``` cpp
|
| 7158 |
+
using underlying_diff_type = iter_difference_t<variant_alternative_t<N, base-iter>>;
|
| 7159 |
+
if constexpr (N == 0) {
|
| 7160 |
+
std::get<N>(it_) -= static_cast<underlying_diff_type>(steps);
|
| 7161 |
+
} else {
|
| 7162 |
+
if (offset >= steps) {
|
| 7163 |
+
std::get<N>(it_) -= static_cast<underlying_diff_type>(steps);
|
| 7164 |
+
} else {
|
| 7165 |
+
auto prev_size = ranges::distance(std::get<N - 1>(parent_->views_));
|
| 7166 |
+
it_.template emplace<N - 1>(ranges::end(std::get<N - 1>(parent_->views_)));
|
| 7167 |
+
advance-bwd<N - 1>(prev_size, steps - offset);
|
| 7168 |
+
}
|
| 7169 |
+
}
|
| 7170 |
+
```
|
| 7171 |
+
|
| 7172 |
+
``` cpp
|
| 7173 |
+
template<class... Args>
|
| 7174 |
+
constexpr explicit iterator(maybe-const<Const, concat_view>* parent,
|
| 7175 |
+
Args&&... args)
|
| 7176 |
+
requires constructible_from<base-iter, Args&&...>;
|
| 7177 |
+
```
|
| 7178 |
+
|
| 7179 |
+
*Effects:* Initializes *parent\_* with `parent`, and initializes *it\_*
|
| 7180 |
+
with `std::forward<Args>(args)...`.
|
| 7181 |
+
|
| 7182 |
+
``` cpp
|
| 7183 |
+
constexpr iterator(iterator<!Const> it)
|
| 7184 |
+
requires Const &&
|
| 7185 |
+
(convertible_to<iterator_t<Views>, iterator_t<const Views>> && ...);
|
| 7186 |
+
```
|
| 7187 |
+
|
| 7188 |
+
*Preconditions:* `it.`*`it_`*`.valueless_by_exception()` is `false`.
|
| 7189 |
+
|
| 7190 |
+
*Effects:* Initializes *parent\_* with `it.`*`parent_`*, and let i be
|
| 7191 |
+
`it.`*`it_`*`.index()`, initializes *it\_* with
|
| 7192 |
+
*`base-iter`*`(in_place_index<`i`>, std::get<`i`>(std::move(it.`*`it_`*`)))`.
|
| 7193 |
+
|
| 7194 |
+
``` cpp
|
| 7195 |
+
constexpr decltype(auto) operator*() const;
|
| 7196 |
+
```
|
| 7197 |
+
|
| 7198 |
+
*Preconditions:* *`it_`*`.valueless_by_exception()` is `false`.
|
| 7199 |
+
|
| 7200 |
+
*Effects:* Equivalent to:
|
| 7201 |
+
|
| 7202 |
+
``` cpp
|
| 7203 |
+
using reference = concat-reference-t<maybe-const<Const, Views>...>;
|
| 7204 |
+
return std::visit([](auto&& it) -> reference { return *it; },
|
| 7205 |
+
it_);
|
| 7206 |
+
```
|
| 7207 |
+
|
| 7208 |
+
``` cpp
|
| 7209 |
+
constexpr iterator& operator++();
|
| 7210 |
+
```
|
| 7211 |
+
|
| 7212 |
+
*Preconditions:* *`it_`*`.valueless_by_exception()` is `false`.
|
| 7213 |
+
|
| 7214 |
+
*Effects:* Let i be *`it_`*`.index()`. Equivalent to:
|
| 7215 |
+
|
| 7216 |
+
``` cpp
|
| 7217 |
+
++std::get<i>(it_);
|
| 7218 |
+
satisfy<i>();
|
| 7219 |
+
return *this;
|
| 7220 |
+
```
|
| 7221 |
+
|
| 7222 |
+
``` cpp
|
| 7223 |
+
constexpr void operator++(int);
|
| 7224 |
+
```
|
| 7225 |
+
|
| 7226 |
+
*Effects:* Equivalent to:
|
| 7227 |
+
|
| 7228 |
+
``` cpp
|
| 7229 |
+
++*this;
|
| 7230 |
+
```
|
| 7231 |
+
|
| 7232 |
+
``` cpp
|
| 7233 |
+
constexpr iterator operator++(int)
|
| 7234 |
+
requires all-forward<Const, Views...>;
|
| 7235 |
+
```
|
| 7236 |
+
|
| 7237 |
+
*Effects:* Equivalent to:
|
| 7238 |
+
|
| 7239 |
+
``` cpp
|
| 7240 |
+
auto tmp = *this;
|
| 7241 |
+
++*this;
|
| 7242 |
+
return tmp;
|
| 7243 |
+
```
|
| 7244 |
+
|
| 7245 |
+
``` cpp
|
| 7246 |
+
constexpr iterator& operator--()
|
| 7247 |
+
requires concat-is-bidirectional<Const, Views...>;
|
| 7248 |
+
```
|
| 7249 |
+
|
| 7250 |
+
*Preconditions:* *`it_`*`.valueless_by_exception()` is `false`.
|
| 7251 |
+
|
| 7252 |
+
*Effects:* Let i be *`it_`*`.index()`. Equivalent to:
|
| 7253 |
+
|
| 7254 |
+
``` cpp
|
| 7255 |
+
prev<i>();
|
| 7256 |
+
return *this;
|
| 7257 |
+
```
|
| 7258 |
+
|
| 7259 |
+
``` cpp
|
| 7260 |
+
constexpr iterator operator--(int)
|
| 7261 |
+
requires concat-is-bidirectional<Const, Views...>;
|
| 7262 |
+
```
|
| 7263 |
+
|
| 7264 |
+
*Effects:* Equivalent to:
|
| 7265 |
+
|
| 7266 |
+
``` cpp
|
| 7267 |
+
auto tmp = *this;
|
| 7268 |
+
--*this;
|
| 7269 |
+
return tmp;
|
| 7270 |
+
```
|
| 7271 |
+
|
| 7272 |
+
``` cpp
|
| 7273 |
+
constexpr iterator& operator+=(difference_type n)
|
| 7274 |
+
requires concat-is-random-access<Const, Views...>;
|
| 7275 |
+
```
|
| 7276 |
+
|
| 7277 |
+
*Preconditions:* *`it_`*`.valueless_by_exception()` is `false`.
|
| 7278 |
+
|
| 7279 |
+
*Effects:* Let i be *`it_`*`.index()`. Equivalent to:
|
| 7280 |
+
|
| 7281 |
+
``` cpp
|
| 7282 |
+
if (n > 0) {
|
| 7283 |
+
advance-fwd<i>(std::get<i>(it_) - ranges::begin(std::get<i>(parent_->views_)), n);
|
| 7284 |
+
} else if (n < 0) {
|
| 7285 |
+
advance-bwd<i>(std::get<i>(it_) - ranges::begin(std::get<i>(parent_->views_)), -n);
|
| 7286 |
+
}
|
| 7287 |
+
return *this;
|
| 7288 |
+
```
|
| 7289 |
+
|
| 7290 |
+
``` cpp
|
| 7291 |
+
constexpr iterator& operator-=(difference_type n)
|
| 7292 |
+
requires concat-is-random-access<Const, Views...>;
|
| 7293 |
+
```
|
| 7294 |
+
|
| 7295 |
+
*Effects:* Equivalent to:
|
| 7296 |
+
|
| 7297 |
+
``` cpp
|
| 7298 |
+
*this += -n;
|
| 7299 |
+
return *this;
|
| 7300 |
+
```
|
| 7301 |
+
|
| 7302 |
+
``` cpp
|
| 7303 |
+
constexpr decltype(auto) operator[](difference_type n) const
|
| 7304 |
+
requires concat-is-random-access<Const, Views...>;
|
| 7305 |
+
```
|
| 7306 |
+
|
| 7307 |
+
*Effects:* Equivalent to:
|
| 7308 |
+
|
| 7309 |
+
``` cpp
|
| 7310 |
+
return *((*this) + n);
|
| 7311 |
+
```
|
| 7312 |
+
|
| 7313 |
+
``` cpp
|
| 7314 |
+
friend constexpr bool operator==(const iterator& x, const iterator& y)
|
| 7315 |
+
requires (equality_comparable<iterator_t<maybe-const<Const, Views>>> && ...);
|
| 7316 |
+
```
|
| 7317 |
+
|
| 7318 |
+
*Preconditions:* `x.`*`it_`*`.valueless_by_exception()` and
|
| 7319 |
+
`y.`*`it_`*`.valueless_by_exception()` are each `false`.
|
| 7320 |
+
|
| 7321 |
+
*Effects:* Equivalent to:
|
| 7322 |
+
|
| 7323 |
+
``` cpp
|
| 7324 |
+
return x.it_ == y.it_;
|
| 7325 |
+
```
|
| 7326 |
+
|
| 7327 |
+
``` cpp
|
| 7328 |
+
friend constexpr bool operator==(const iterator& it, default_sentinel_t);
|
| 7329 |
+
```
|
| 7330 |
+
|
| 7331 |
+
*Preconditions:* `it.`*`it_`*`.valueless_by_exception()` is `false`.
|
| 7332 |
+
|
| 7333 |
+
*Effects:* Equivalent to:
|
| 7334 |
+
|
| 7335 |
+
``` cpp
|
| 7336 |
+
constexpr auto last_idx = sizeof...(Views) - 1;
|
| 7337 |
+
return it.it_.index() == last_idx &&
|
| 7338 |
+
std::get<last_idx>(it.it_) == ranges::end(std::get<last_idx>(it.parent_->views_));
|
| 7339 |
+
```
|
| 7340 |
+
|
| 7341 |
+
``` cpp
|
| 7342 |
+
friend constexpr bool operator<(const iterator& x, const iterator& y)
|
| 7343 |
+
requires all-random-access<Const, Views...>;
|
| 7344 |
+
friend constexpr bool operator>(const iterator& x, const iterator& y)
|
| 7345 |
+
requires all-random-access<Const, Views...>;
|
| 7346 |
+
friend constexpr bool operator<=(const iterator& x, const iterator& y)
|
| 7347 |
+
requires all-random-access<Const, Views...>;
|
| 7348 |
+
friend constexpr bool operator>=(const iterator& x, const iterator& y)
|
| 7349 |
+
requires all-random-access<Const, Views...>;
|
| 7350 |
+
friend constexpr auto operator<=>(const iterator& x, const iterator& y)
|
| 7351 |
+
requires (all-random-access<Const, Views...> &&
|
| 7352 |
+
(three_way_comparable<iterator_t<maybe-const<Const, Views>>> && ...));
|
| 7353 |
+
```
|
| 7354 |
+
|
| 7355 |
+
*Preconditions:* `x.`*`it_`*`.valueless_by_exception()` and
|
| 7356 |
+
`y.`*`it_`*`.valueless_by_exception()` are each `false`.
|
| 7357 |
+
|
| 7358 |
+
Let op be the operator.
|
| 7359 |
+
|
| 7360 |
+
*Effects:* Equivalent to:
|
| 7361 |
+
|
| 7362 |
+
``` cpp
|
| 7363 |
+
return x.it_ op y.it_;
|
| 7364 |
+
```
|
| 7365 |
+
|
| 7366 |
+
``` cpp
|
| 7367 |
+
friend constexpr iterator operator+(const iterator& it, difference_type n)
|
| 7368 |
+
requires concat-is-random-access<Const, Views...>;
|
| 7369 |
+
```
|
| 7370 |
+
|
| 7371 |
+
*Effects:* Equivalent to:
|
| 7372 |
+
|
| 7373 |
+
``` cpp
|
| 7374 |
+
auto temp = it;
|
| 7375 |
+
temp += n;
|
| 7376 |
+
return temp;
|
| 7377 |
+
```
|
| 7378 |
+
|
| 7379 |
+
``` cpp
|
| 7380 |
+
friend constexpr iterator operator+(difference_type n, const iterator& it)
|
| 7381 |
+
requires concat-is-random-access<Const, Views...>;
|
| 7382 |
+
```
|
| 7383 |
+
|
| 7384 |
+
*Effects:* Equivalent to:
|
| 7385 |
+
|
| 7386 |
+
``` cpp
|
| 7387 |
+
return it + n;
|
| 7388 |
+
```
|
| 7389 |
+
|
| 7390 |
+
``` cpp
|
| 7391 |
+
friend constexpr iterator operator-(const iterator& it, difference_type n)
|
| 7392 |
+
requires concat-is-random-access<Const, Views...>;
|
| 7393 |
+
```
|
| 7394 |
+
|
| 7395 |
+
*Effects:* Equivalent to:
|
| 7396 |
+
|
| 7397 |
+
``` cpp
|
| 7398 |
+
auto temp = it;
|
| 7399 |
+
temp -= n;
|
| 7400 |
+
return temp;
|
| 7401 |
+
```
|
| 7402 |
+
|
| 7403 |
+
``` cpp
|
| 7404 |
+
friend constexpr difference_type operator-(const iterator& x, const iterator& y)
|
| 7405 |
+
requires concat-is-random-access<Const, Views...>;
|
| 7406 |
+
```
|
| 7407 |
+
|
| 7408 |
+
*Preconditions:* `x.`*`it_`*`.valueless_by_exception()` and
|
| 7409 |
+
`y.`*`it_`*`.valueless_by_exception()` are each `false`.
|
| 7410 |
+
|
| 7411 |
+
*Effects:* Let i_`x` denote `x.`*`it_`*`.index()` and i_`y` denote
|
| 7412 |
+
`y.`*`it_`*`.index()`.
|
| 7413 |
+
|
| 7414 |
+
- If i_`x`` > `i_`y`, let d_`y` be
|
| 7415 |
+
`ranges::distance(std::get<`i_`y``>(y.`*`it_`*`), ranges::end(std::get<`i_`y``>(y.`*`parent_`*`->`*`views_`*`)))`,
|
| 7416 |
+
d_`x` be
|
| 7417 |
+
`ranges::distance(ranges::begin(std::get<`i_`x``>(x.`*`parent_`*`->`*`views_`*`)), std::get<`i_`x``>(x.`*`it_`*`))`.
|
| 7418 |
+
Let s denote the sum of the sizes of all the ranges
|
| 7419 |
+
`std::get<`i`>(x.`*`parent_`*`->`*`views_`*`)` for every integer i in
|
| 7420 |
+
the range \[i_`y`` + 1`, i_`x`) if there is any, and `0` otherwise, of
|
| 7421 |
+
type `difference_type`, equivalent to:
|
| 7422 |
+
``` cpp
|
| 7423 |
+
return $d_y$ + s + $d_x$;
|
| 7424 |
+
```
|
| 7425 |
+
- otherwise, if i_`x`` < `i_`y` is `true`, equivalent to:
|
| 7426 |
+
``` cpp
|
| 7427 |
+
return -(y - x);
|
| 7428 |
+
```
|
| 7429 |
+
- otherwise, equivalent to:
|
| 7430 |
+
``` cpp
|
| 7431 |
+
return std::get<$i_x$>(x.it_) - std::get<$i_y$>(y.it_);
|
| 7432 |
+
```
|
| 7433 |
+
|
| 7434 |
+
``` cpp
|
| 7435 |
+
friend constexpr difference_type operator-(const iterator& x, default_sentinel_t)
|
| 7436 |
+
requires see below;
|
| 7437 |
+
```
|
| 7438 |
+
|
| 7439 |
+
*Preconditions:* `x.`*`it_`*`.valueless_by_exception()` is `false`.
|
| 7440 |
+
|
| 7441 |
+
*Effects:* Let i_`x` denote `x.`*`it_`*`.index()`, d_`x` be
|
| 7442 |
+
`ranges::distance(std::get<`i_`x``>(x.`*`it_`*`), ranges::end(std::get<`i_`x``>(x.`*`parent_`*`->`*`views_`*`)))`.
|
| 7443 |
+
Let s denote the sum of the sizes of all the ranges
|
| 7444 |
+
`std::get<`i`>(x.`*`parent_`*`->`*`views_`*`)` for every integer i in
|
| 7445 |
+
the range \[i_`x`` + 1`, `sizeof...(Views)`) if there is any, and `0`
|
| 7446 |
+
otherwise, of type difference_type, equivalent to:
|
| 7447 |
+
|
| 7448 |
+
``` cpp
|
| 7449 |
+
return -($d_x$ + s);
|
| 7450 |
+
```
|
| 7451 |
+
|
| 7452 |
+
*Remarks:* Let `Fs` be the pack that consists of all elements of `Views`
|
| 7453 |
+
except the first element, the expression in the *requires-clause* is
|
| 7454 |
+
equivalent to:
|
| 7455 |
+
|
| 7456 |
+
``` cpp
|
| 7457 |
+
(sized_sentinel_for<sentinel_t<maybe-const<Const, Views>>,
|
| 7458 |
+
iterator_t<maybe-const<Const, Views>>> && ...) &&
|
| 7459 |
+
(sized_range<maybe-const<Const, Fs>> && ...)
|
| 7460 |
+
```
|
| 7461 |
+
|
| 7462 |
+
``` cpp
|
| 7463 |
+
friend constexpr difference_type operator-(default_sentinel_t, const iterator& x)
|
| 7464 |
+
requires see below;
|
| 7465 |
+
```
|
| 7466 |
+
|
| 7467 |
+
*Effects:* Equivalent to:
|
| 7468 |
+
|
| 7469 |
+
``` cpp
|
| 7470 |
+
return -(x - default_sentinel);
|
| 7471 |
+
```
|
| 7472 |
+
|
| 7473 |
+
*Remarks:* Let `Fs` be the pack that consists of all elements of `Views`
|
| 7474 |
+
except the first element, the expression in the *requires-clause* is
|
| 7475 |
+
equivalent to:
|
| 7476 |
+
|
| 7477 |
+
``` cpp
|
| 7478 |
+
(sized_sentinel_for<sentinel_t<maybe-const<Const, Views>>,
|
| 7479 |
+
iterator_t<maybe-const<Const, Views>>> && ...) &&
|
| 7480 |
+
(sized_range<maybe-const<Const, Fs>> && ...)
|
| 7481 |
+
```
|
| 7482 |
+
|
| 7483 |
+
``` cpp
|
| 7484 |
+
friend constexpr decltype(auto) iter_move(const iterator& it) noexcept(see below);
|
| 7485 |
+
```
|
| 7486 |
+
|
| 7487 |
+
*Preconditions:* `it.`*`it_`*`.valueless_by_exception()` is `false`.
|
| 7488 |
+
|
| 7489 |
+
*Effects:* Equivalent to:
|
| 7490 |
+
|
| 7491 |
+
``` cpp
|
| 7492 |
+
return std::visit([](const auto& i)
|
| 7493 |
+
-> concat-rvalue-reference-t<maybe-const<Const, Views>...> {
|
| 7494 |
+
return ranges::iter_move(i);
|
| 7495 |
+
},
|
| 7496 |
+
it.it_);
|
| 7497 |
+
```
|
| 7498 |
+
|
| 7499 |
+
*Remarks:* The exception specification is equivalent to:
|
| 7500 |
+
|
| 7501 |
+
``` cpp
|
| 7502 |
+
((is_nothrow_invocable_v<decltype(ranges::iter_move),
|
| 7503 |
+
const iterator_t<maybe-const<Const, Views>>&> &&
|
| 7504 |
+
is_nothrow_convertible_v<range_rvalue_reference_t<maybe-const<Const, Views>>,
|
| 7505 |
+
concat-rvalue-reference-t<maybe-const<Const, Views>...>>) &&
|
| 7506 |
+
...)
|
| 7507 |
+
```
|
| 7508 |
+
|
| 7509 |
+
``` cpp
|
| 7510 |
+
friend constexpr void iter_swap(const iterator& x, const iterator& y) noexcept(see below)
|
| 7511 |
+
requires see below;
|
| 7512 |
+
```
|
| 7513 |
+
|
| 7514 |
+
*Preconditions:* `x.`*`it_`*`.valueless_by_exception()` and
|
| 7515 |
+
`y.`*`it_`*`.valueless_by_exception()` are each `false`.
|
| 7516 |
+
|
| 7517 |
+
*Effects:* Equivalent to:
|
| 7518 |
+
|
| 7519 |
+
``` cpp
|
| 7520 |
+
std::visit([&](const auto& it1, const auto& it2) {
|
| 7521 |
+
if constexpr (is_same_v<decltype(it1), decltype(it2)>) {
|
| 7522 |
+
ranges::iter_swap(it1, it2);
|
| 7523 |
+
} else {
|
| 7524 |
+
ranges::swap(*x, *y);
|
| 7525 |
+
}
|
| 7526 |
+
},
|
| 7527 |
+
x.it_, y.it_);
|
| 7528 |
+
```
|
| 7529 |
+
|
| 7530 |
+
*Remarks:* The exception specification is equivalent to
|
| 7531 |
+
|
| 7532 |
+
``` cpp
|
| 7533 |
+
(noexcept(ranges::swap(*x, *y)) && ... && noexcept(ranges::iter_swap(its, its)))
|
| 7534 |
+
```
|
| 7535 |
+
|
| 7536 |
+
where `its` is a pack of lvalues of type
|
| 7537 |
+
`const iterator_t<`*`maybe-const`*`<Const, Views>>` respectively.
|
| 7538 |
+
|
| 7539 |
+
The expression in the *requires-clause* is equivalent to
|
| 7540 |
+
|
| 7541 |
+
``` cpp
|
| 7542 |
+
swappable_with<iter_reference_t<iterator>, iter_reference_t<iterator>> &&
|
| 7543 |
+
(... && indirectly_swappable<iterator_t<maybe-const<Const, Views>>>)
|
| 7544 |
+
```
|
| 7545 |
+
|
| 7546 |
### Counted view <a id="range.counted">[[range.counted]]</a>
|
| 7547 |
|
| 7548 |
A counted view presents a view of the elements of the counted range
|
| 7549 |
[[iterator.requirements.general]] `i`+\[0, `n`) for an iterator `i` and
|
| 7550 |
non-negative integer `n`.
|
|
|
|
| 7621 |
constexpr explicit common_view(V r);
|
| 7622 |
|
| 7623 |
constexpr V base() const & requires copy_constructible<V> { return base_; }
|
| 7624 |
constexpr V base() && { return std::move(base_); }
|
| 7625 |
|
| 7626 |
+
constexpr auto begin() requires (!simple-view<V>) {
|
| 7627 |
if constexpr (random_access_range<V> && sized_range<V>)
|
| 7628 |
return ranges::begin(base_);
|
| 7629 |
else
|
| 7630 |
return common_iterator<iterator_t<V>, sentinel_t<V>>(ranges::begin(base_));
|
| 7631 |
}
|
|
|
|
| 7635 |
return ranges::begin(base_);
|
| 7636 |
else
|
| 7637 |
return common_iterator<iterator_t<const V>, sentinel_t<const V>>(ranges::begin(base_));
|
| 7638 |
}
|
| 7639 |
|
| 7640 |
+
constexpr auto end() requires (!simple-view<V>) {
|
| 7641 |
if constexpr (random_access_range<V> && sized_range<V>)
|
| 7642 |
return ranges::begin(base_) + ranges::distance(base_);
|
| 7643 |
else
|
| 7644 |
return common_iterator<iterator_t<V>, sentinel_t<V>>(ranges::end(base_));
|
| 7645 |
}
|
|
|
|
| 7655 |
return ranges::size(base_);
|
| 7656 |
}
|
| 7657 |
constexpr auto size() const requires sized_range<const V> {
|
| 7658 |
return ranges::size(base_);
|
| 7659 |
}
|
| 7660 |
+
|
| 7661 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V> {
|
| 7662 |
+
return ranges::reserve_hint(base_);
|
| 7663 |
+
}
|
| 7664 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V> {
|
| 7665 |
+
return ranges::reserve_hint(base_);
|
| 7666 |
+
}
|
| 7667 |
};
|
| 7668 |
|
| 7669 |
template<class R>
|
| 7670 |
common_view(R&&) -> common_view<views::all_t<R>>;
|
| 7671 |
}
|
|
|
|
| 7687 |
The name `views::reverse` denotes a range adaptor object
|
| 7688 |
[[range.adaptor.object]]. Given a subexpression `E`, the expression
|
| 7689 |
`views::reverse(E)` is expression-equivalent to:
|
| 7690 |
|
| 7691 |
- If the type of `E` is a (possibly cv-qualified) specialization of
|
| 7692 |
+
`reverse_view`, then `E.base()`.
|
| 7693 |
- Otherwise, if the type of `E` is cv
|
| 7694 |
`subrange<reverse_iterator<I>, reverse_iterator<I>, K>` for some
|
| 7695 |
iterator type `I` and value `K` of type `subrange_kind`,
|
| 7696 |
+
- if `K` is `subrange_kind::sized`, then
|
| 7697 |
+
`subrange<I, I, K>(E.end().base(), E.begin().base(), E.size())`;
|
| 7698 |
+
- otherwise, `subrange<I, I, K>(E.end().base(), E.begin().base())`.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7699 |
|
| 7700 |
However, in either case `E` is evaluated only once.
|
| 7701 |
+
- Otherwise, `reverse_view{E}`.
|
| 7702 |
|
| 7703 |
[*Example 1*:
|
| 7704 |
|
| 7705 |
``` cpp
|
| 7706 |
vector<int> is {0,1,2,3,4};
|
|
|
|
| 7740 |
}
|
| 7741 |
|
| 7742 |
constexpr auto size() const requires sized_range<const V> {
|
| 7743 |
return ranges::size(base_);
|
| 7744 |
}
|
| 7745 |
+
|
| 7746 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V> {
|
| 7747 |
+
return ranges::reserve_hint(base_);
|
| 7748 |
+
}
|
| 7749 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V> {
|
| 7750 |
+
return ranges::reserve_hint(base_);
|
| 7751 |
+
}
|
| 7752 |
};
|
| 7753 |
|
| 7754 |
template<class R>
|
| 7755 |
reverse_view(R&&) -> reverse_view<views::all_t<R>>;
|
| 7756 |
}
|
|
|
|
| 7851 |
constexpr auto end() requires (!simple-view<V>) { return ranges::cend(base_); }
|
| 7852 |
constexpr auto end() const requires range<const V> { return ranges::cend(base_); }
|
| 7853 |
|
| 7854 |
constexpr auto size() requires sized_range<V> { return ranges::size(base_); }
|
| 7855 |
constexpr auto size() const requires sized_range<const V> { return ranges::size(base_); }
|
| 7856 |
+
|
| 7857 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>
|
| 7858 |
+
{ return ranges::reserve_hint(base_); }
|
| 7859 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>
|
| 7860 |
+
{ return ranges::reserve_hint(base_); }
|
| 7861 |
};
|
| 7862 |
|
| 7863 |
template<class R>
|
| 7864 |
as_const_view(R&&) -> as_const_view<views::all_t<R>>;
|
| 7865 |
}
|
|
|
|
| 7980 |
{ return ranges::size(base_); }
|
| 7981 |
|
| 7982 |
constexpr auto size() const requires sized_range<const V>
|
| 7983 |
{ return ranges::size(base_); }
|
| 7984 |
|
| 7985 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>
|
| 7986 |
+
{ return ranges::reserve_hint(base_); }
|
| 7987 |
+
|
| 7988 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>
|
| 7989 |
+
{ return ranges::reserve_hint(base_); }
|
| 7990 |
+
|
| 7991 |
private:
|
| 7992 |
// [range.elements.iterator], class template elements_view::iterator
|
| 7993 |
template<bool> class iterator; // exposition only
|
| 7994 |
|
| 7995 |
// [range.elements.sentinel], class template elements_view::sentinel
|
|
|
|
| 8378 |
#### Overview <a id="range.enumerate.overview">[[range.enumerate.overview]]</a>
|
| 8379 |
|
| 8380 |
`enumerate_view` is a view whose elements represent both the position
|
| 8381 |
and value from a sequence of elements.
|
| 8382 |
|
| 8383 |
+
The name `views::enumerate` denotes a range adaptor object
|
| 8384 |
+
[[range.adaptor.object]]. Given a subexpression `E`, the expression
|
| 8385 |
+
`views::enumerate(E)` is expression-equivalent to
|
| 8386 |
`enumerate_view<views::all_t<decltype((E))>>(E)`.
|
| 8387 |
|
| 8388 |
[*Example 1*:
|
| 8389 |
|
| 8390 |
``` cpp
|
|
|
|
| 8420 |
{ return iterator<false>(ranges::begin(base_), 0); }
|
| 8421 |
constexpr auto begin() const requires range-with-movable-references<const V>
|
| 8422 |
{ return iterator<true>(ranges::begin(base_), 0); }
|
| 8423 |
|
| 8424 |
constexpr auto end() requires (!simple-view<V>) {
|
| 8425 |
+
if constexpr (forward_range<V> && common_range<V> && sized_range<V>)
|
| 8426 |
return iterator<false>(ranges::end(base_), ranges::distance(base_));
|
| 8427 |
else
|
| 8428 |
return sentinel<false>(ranges::end(base_));
|
| 8429 |
}
|
| 8430 |
constexpr auto end() const requires range-with-movable-references<const V> {
|
| 8431 |
+
if constexpr (forward_range<const V> && common_range<const V> && sized_range<const V>)
|
| 8432 |
return iterator<true>(ranges::end(base_), ranges::distance(base_));
|
| 8433 |
else
|
| 8434 |
return sentinel<true>(ranges::end(base_));
|
| 8435 |
}
|
| 8436 |
|
| 8437 |
constexpr auto size() requires sized_range<V>
|
| 8438 |
{ return ranges::size(base_); }
|
| 8439 |
constexpr auto size() const requires sized_range<const V>
|
| 8440 |
{ return ranges::size(base_); }
|
| 8441 |
|
| 8442 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>
|
| 8443 |
+
{ return ranges::reserve_hint(base_); }
|
| 8444 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>
|
| 8445 |
+
{ return ranges::reserve_hint(base_); }
|
| 8446 |
+
|
| 8447 |
constexpr V base() const & requires copy_constructible<V> { return base_; }
|
| 8448 |
constexpr V base() && { return std::move(base_); }
|
| 8449 |
};
|
| 8450 |
|
| 8451 |
template<class R>
|
|
|
|
| 8521 |
requires random_access_range<Base>;
|
| 8522 |
friend constexpr iterator operator+(difference_type x, const iterator& y)
|
| 8523 |
requires random_access_range<Base>;
|
| 8524 |
friend constexpr iterator operator-(const iterator& x, difference_type y)
|
| 8525 |
requires random_access_range<Base>;
|
| 8526 |
+
friend constexpr difference_type operator-(const iterator& x, const iterator& y) noexcept;
|
| 8527 |
|
| 8528 |
friend constexpr auto iter_move(const iterator& i)
|
| 8529 |
noexcept(noexcept(ranges::iter_move(i.current_)) &&
|
| 8530 |
is_nothrow_move_constructible_v<range_rvalue_reference_t<Base>>) {
|
| 8531 |
return tuple<difference_type,
|
|
|
|
| 8703 |
temp -= y;
|
| 8704 |
return temp;
|
| 8705 |
```
|
| 8706 |
|
| 8707 |
``` cpp
|
| 8708 |
+
friend constexpr difference_type operator-(const iterator& x, const iterator& y) noexcept;
|
| 8709 |
```
|
| 8710 |
|
| 8711 |
*Effects:* Equivalent to: `return x.`*`pos_`*` - y.`*`pos_`*`;`
|
| 8712 |
|
| 8713 |
#### Class template `enumerate_view::sentinel` <a id="range.enumerate.sentinel">[[range.enumerate.sentinel]]</a>
|
|
|
|
| 8914 |
|
| 8915 |
#### Class template `zip_view::iterator` <a id="range.zip.iterator">[[range.zip.iterator]]</a>
|
| 8916 |
|
| 8917 |
``` cpp
|
| 8918 |
namespace std::ranges {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8919 |
template<input_range... Views>
|
| 8920 |
requires (view<Views> && ...) && (sizeof...(Views) > 0)
|
| 8921 |
template<bool Const>
|
| 8922 |
class zip_view<Views...>::iterator {
|
| 8923 |
tuple<iterator_t<maybe-const<Const, Views>>...> current_; // exposition only
|
|
|
|
| 9284 |
iterator_t<maybe-const<OtherConst, Views>>> && ...)
|
| 9285 |
friend constexpr common_type_t<range_difference_t<maybe-const<OtherConst, Views>>...>
|
| 9286 |
operator-(const sentinel& y, const iterator<OtherConst>& x);
|
| 9287 |
```
|
| 9288 |
|
| 9289 |
+
*Effects:* Equivalent to: `return -(x - y);`
|
| 9290 |
|
| 9291 |
### Zip transform view <a id="range.zip.transform">[[range.zip.transform]]</a>
|
| 9292 |
|
| 9293 |
#### Overview <a id="range.zip.transform.overview">[[range.zip.transform.overview]]</a>
|
| 9294 |
|
|
|
|
| 9419 |
|
| 9420 |
constexpr iterator(Parent& parent, ziperator<Const> inner); // exposition only
|
| 9421 |
|
| 9422 |
public:
|
| 9423 |
using iterator_category = see belownc; // not always present
|
| 9424 |
+
using iterator_concept = ziperator<Const>::iterator_concept;
|
| 9425 |
using value_type =
|
| 9426 |
remove_cvref_t<invoke_result_t<maybe-const<Const, F>&,
|
| 9427 |
range_reference_t<maybe-const<Const, Views>>...>>;
|
| 9428 |
using difference_type = range_difference_t<Base>;
|
| 9429 |
|
|
|
|
| 9722 |
The name `views::adjacent<N>` denotes a range adaptor object
|
| 9723 |
[[range.adaptor.object]]. Given a subexpression `E` and a constant
|
| 9724 |
expression `N`, the expression `views::adjacent<N>(E)` is
|
| 9725 |
expression-equivalent to
|
| 9726 |
|
| 9727 |
+
- `((void)E, auto(views::empty<tuple<>>))` if `N` is equal to `0` and
|
| 9728 |
+
`decltype((E))` models `forward_range`,
|
| 9729 |
- otherwise, `adjacent_view<views::all_t<decltype((E))>, N>(E)`.
|
| 9730 |
|
| 9731 |
[*Example 1*:
|
| 9732 |
|
| 9733 |
``` cpp
|
|
|
|
| 9791 |
}
|
| 9792 |
}
|
| 9793 |
|
| 9794 |
constexpr auto size() requires sized_range<V>;
|
| 9795 |
constexpr auto size() const requires sized_range<const V>;
|
| 9796 |
+
|
| 9797 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>;
|
| 9798 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
|
| 9799 |
};
|
| 9800 |
}
|
| 9801 |
```
|
| 9802 |
|
| 9803 |
``` cpp
|
|
|
|
| 9819 |
auto sz = static_cast<CT>(ranges::size(base_));
|
| 9820 |
sz -= std::min<CT>(sz, N - 1);
|
| 9821 |
return static_cast<ST>(sz);
|
| 9822 |
```
|
| 9823 |
|
| 9824 |
+
``` cpp
|
| 9825 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>;
|
| 9826 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
|
| 9827 |
+
```
|
| 9828 |
+
|
| 9829 |
+
*Effects:* Equivalent to:
|
| 9830 |
+
|
| 9831 |
+
``` cpp
|
| 9832 |
+
using DT = range_difference_t<decltype((base_))>;
|
| 9833 |
+
using CT = common_type_t<DT, size_t>;
|
| 9834 |
+
auto sz = static_cast<CT>(ranges::reserve_hint(base_));
|
| 9835 |
+
sz -= std::min<CT>(sz, N - 1);
|
| 9836 |
+
return to-unsigned-like(sz);
|
| 9837 |
+
```
|
| 9838 |
+
|
| 9839 |
#### Class template `adjacent_view::iterator` <a id="range.adjacent.iterator">[[range.adjacent.iterator]]</a>
|
| 9840 |
|
| 9841 |
``` cpp
|
| 9842 |
namespace std::ranges {
|
| 9843 |
template<forward_range V, size_t N>
|
|
|
|
| 10230 |
|
| 10231 |
The name `views::adjacent_transform<N>` denotes a range adaptor object
|
| 10232 |
[[range.adaptor.object]]. Given subexpressions `E` and `F` and a
|
| 10233 |
constant expression `N`:
|
| 10234 |
|
| 10235 |
+
- If `N` is equal to `0` and `decltype((E))` models `forward_range`,
|
| 10236 |
+
`views::adjacent_transform<N>(E, F)` is expression-equivalent to
|
| 10237 |
+
`((void)E, views::zip_transform(F))`, except that the evaluations of
|
| 10238 |
+
`E` and `F` are indeterminately sequenced.
|
| 10239 |
- Otherwise, the expression `views::adjacent_transform<N>(E, F)` is
|
| 10240 |
expression-equivalent to
|
| 10241 |
`adjacent_transform_view<views::all_t<decltype((E))>, decay_t<decltype((F))>, N>(E, F)`.
|
| 10242 |
|
| 10243 |
[*Example 1*:
|
|
|
|
| 10278 |
|
| 10279 |
public:
|
| 10280 |
adjacent_transform_view() = default;
|
| 10281 |
constexpr explicit adjacent_transform_view(V base, F fun);
|
| 10282 |
|
| 10283 |
+
constexpr V base() const & requires copy_constructible<V> { return inner_.base(); }
|
| 10284 |
constexpr V base() && { return std::move(inner_).base(); }
|
| 10285 |
|
| 10286 |
constexpr auto begin() {
|
| 10287 |
return iterator<false>(*this, inner_.begin());
|
| 10288 |
}
|
|
|
|
| 10316 |
}
|
| 10317 |
|
| 10318 |
constexpr auto size() const requires sized_range<const InnerView> {
|
| 10319 |
return inner_.size();
|
| 10320 |
}
|
| 10321 |
+
|
| 10322 |
+
constexpr auto reserve_hint() requires approximately_sized_range<InnerView> {
|
| 10323 |
+
return inner_.reserve_hint();
|
| 10324 |
+
}
|
| 10325 |
+
|
| 10326 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const InnerView> {
|
| 10327 |
+
return inner_.reserve_hint();
|
| 10328 |
+
}
|
| 10329 |
};
|
| 10330 |
}
|
| 10331 |
```
|
| 10332 |
|
| 10333 |
``` cpp
|
|
|
|
| 10354 |
|
| 10355 |
constexpr iterator(Parent& parent, inner-iterator<Const> inner); // exposition only
|
| 10356 |
|
| 10357 |
public:
|
| 10358 |
using iterator_category = see below;
|
| 10359 |
+
using iterator_concept = inner-iterator<Const>::iterator_concept;
|
| 10360 |
using value_type =
|
| 10361 |
remove_cvref_t<invoke_result_t<maybe-const<Const, F>&,
|
| 10362 |
REPEAT(range_reference_t<Base>, N)...>>;
|
| 10363 |
using difference_type = range_difference_t<Base>;
|
| 10364 |
|
|
|
|
| 10628 |
template<bool OtherConst>
|
| 10629 |
requires sentinel_for<inner-sentinel<Const>, inner-iterator<OtherConst>>
|
| 10630 |
friend constexpr bool operator==(const iterator<OtherConst>& x, const sentinel& y);
|
| 10631 |
```
|
| 10632 |
|
| 10633 |
+
*Effects:* Equivalent to: `return x.`*`inner_`*` == y.`*`inner_`*`;`
|
| 10634 |
|
| 10635 |
``` cpp
|
| 10636 |
template<bool OtherConst>
|
| 10637 |
requires sized_sentinel_for<inner-sentinel<Const>, inner-iterator<OtherConst>>
|
| 10638 |
friend constexpr range_difference_t<maybe-const<OtherConst, InnerView>>
|
|
|
|
| 10642 |
requires sized_sentinel_for<inner-sentinel<Const>, inner-iterator<OtherConst>>
|
| 10643 |
friend constexpr range_difference_t<maybe-const<OtherConst, InnerView>>
|
| 10644 |
operator-(const sentinel& x, const iterator<OtherConst>& y);
|
| 10645 |
```
|
| 10646 |
|
| 10647 |
+
*Effects:* Equivalent to: `return x.`*`inner_`*` - y.`*`inner_`*`;`
|
| 10648 |
|
| 10649 |
### Chunk view <a id="range.chunk">[[range.chunk]]</a>
|
| 10650 |
|
| 10651 |
#### Overview <a id="range.chunk.overview">[[range.chunk.overview]]</a>
|
| 10652 |
|
|
|
|
| 10715 |
constexpr outer-iterator begin();
|
| 10716 |
constexpr default_sentinel_t end() const noexcept;
|
| 10717 |
|
| 10718 |
constexpr auto size() requires sized_range<V>;
|
| 10719 |
constexpr auto size() const requires sized_range<const V>;
|
| 10720 |
+
|
| 10721 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>;
|
| 10722 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
|
| 10723 |
};
|
| 10724 |
|
| 10725 |
template<class R>
|
| 10726 |
chunk_view(R&&, range_difference_t<R>) -> chunk_view<views::all_t<R>>;
|
| 10727 |
}
|
|
|
|
| 10763 |
|
| 10764 |
``` cpp
|
| 10765 |
return to-unsigned-like(div-ceil(ranges::distance(base_), n_));
|
| 10766 |
```
|
| 10767 |
|
| 10768 |
+
``` cpp
|
| 10769 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>;
|
| 10770 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
|
| 10771 |
+
```
|
| 10772 |
+
|
| 10773 |
+
*Effects:* Equivalent to:
|
| 10774 |
+
|
| 10775 |
+
``` cpp
|
| 10776 |
+
auto s = static_cast<range_difference_t<decltype((base_))>>(ranges::reserve_hint(base_));
|
| 10777 |
+
return to-unsigned-like(div-ceil(s, n_));
|
| 10778 |
+
```
|
| 10779 |
+
|
| 10780 |
#### Class `chunk_view::outer-iterator` <a id="range.chunk.outer.iter">[[range.chunk.outer.iter]]</a>
|
| 10781 |
|
| 10782 |
``` cpp
|
| 10783 |
namespace std::ranges {
|
| 10784 |
template<view V>
|
|
|
|
| 10894 |
constexpr inner-iterator begin() const noexcept;
|
| 10895 |
constexpr default_sentinel_t end() const noexcept;
|
| 10896 |
|
| 10897 |
constexpr auto size() const
|
| 10898 |
requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>;
|
| 10899 |
+
|
| 10900 |
+
constexpr auto reserve_hint() const noexcept;
|
| 10901 |
};
|
| 10902 |
}
|
| 10903 |
```
|
| 10904 |
|
| 10905 |
``` cpp
|
|
|
|
| 10930 |
``` cpp
|
| 10931 |
return to-unsigned-like(ranges::min(parent_->remainder_,
|
| 10932 |
ranges::end(parent_->base_) - *parent_->current_));
|
| 10933 |
```
|
| 10934 |
|
| 10935 |
+
``` cpp
|
| 10936 |
+
constexpr auto reserve_hint() const noexcept;
|
| 10937 |
+
```
|
| 10938 |
+
|
| 10939 |
+
*Effects:* Equivalent to:
|
| 10940 |
+
|
| 10941 |
+
``` cpp
|
| 10942 |
+
return to-unsigned-like(parent_->remainder_);
|
| 10943 |
+
```
|
| 10944 |
+
|
| 10945 |
#### Class `chunk_view::inner-iterator` <a id="range.chunk.inner.iter">[[range.chunk.inner.iter]]</a>
|
| 10946 |
|
| 10947 |
``` cpp
|
| 10948 |
namespace std::ranges {
|
| 10949 |
template<view V>
|
|
|
|
| 11118 |
}
|
| 11119 |
}
|
| 11120 |
|
| 11121 |
constexpr auto size() requires sized_range<V>;
|
| 11122 |
constexpr auto size() const requires sized_range<const V>;
|
| 11123 |
+
|
| 11124 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>;
|
| 11125 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
|
| 11126 |
};
|
| 11127 |
}
|
| 11128 |
```
|
| 11129 |
|
| 11130 |
``` cpp
|
|
|
|
| 11145 |
|
| 11146 |
``` cpp
|
| 11147 |
return to-unsigned-like(div-ceil(ranges::distance(base_), n_));
|
| 11148 |
```
|
| 11149 |
|
| 11150 |
+
``` cpp
|
| 11151 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>;
|
| 11152 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
|
| 11153 |
+
```
|
| 11154 |
+
|
| 11155 |
+
*Effects:* Equivalent to:
|
| 11156 |
+
|
| 11157 |
+
``` cpp
|
| 11158 |
+
auto s = static_cast<range_difference_t<decltype((base_))>>(ranges::reserve_hint(base_));
|
| 11159 |
+
return to-unsigned-like(div-ceil(s, n_));
|
| 11160 |
+
```
|
| 11161 |
+
|
| 11162 |
#### Class template `chunk_view::iterator` for forward ranges <a id="range.chunk.fwd.iter">[[range.chunk.fwd.iter]]</a>
|
| 11163 |
|
| 11164 |
``` cpp
|
| 11165 |
namespace std::ranges {
|
| 11166 |
template<view V>
|
|
|
|
| 11533 |
requires (!(simple-view<V> && slide-caches-nothing<const V>));
|
| 11534 |
constexpr auto end() const requires slide-caches-nothing<const V>;
|
| 11535 |
|
| 11536 |
constexpr auto size() requires sized_range<V>;
|
| 11537 |
constexpr auto size() const requires sized_range<const V>;
|
| 11538 |
+
|
| 11539 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>;
|
| 11540 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
|
| 11541 |
};
|
| 11542 |
|
| 11543 |
template<class R>
|
| 11544 |
slide_view(R&&, range_difference_t<R>) -> slide_view<views::all_t<R>>;
|
| 11545 |
}
|
|
|
|
| 11623 |
auto sz = ranges::distance(base_) - n_ + 1;
|
| 11624 |
if (sz < 0) sz = 0;
|
| 11625 |
return to-unsigned-like(sz);
|
| 11626 |
```
|
| 11627 |
|
| 11628 |
+
``` cpp
|
| 11629 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>;
|
| 11630 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
|
| 11631 |
+
```
|
| 11632 |
+
|
| 11633 |
+
*Effects:* Equivalent to:
|
| 11634 |
+
|
| 11635 |
+
``` cpp
|
| 11636 |
+
auto sz = static_cast<range_difference_t<decltype((base_))>>(ranges::reserve_hint(base_)) -
|
| 11637 |
+
n_ + 1;
|
| 11638 |
+
if (sz < 0) sz = 0;
|
| 11639 |
+
return to-unsigned-like(sz);
|
| 11640 |
+
```
|
| 11641 |
+
|
| 11642 |
#### Class template `slide_view::iterator` <a id="range.slide.iterator">[[range.slide.iterator]]</a>
|
| 11643 |
|
| 11644 |
``` cpp
|
| 11645 |
namespace std::ranges {
|
| 11646 |
template<forward_range V>
|
|
|
|
| 12304 |
}
|
| 12305 |
}
|
| 12306 |
|
| 12307 |
constexpr auto size() requires sized_range<V>;
|
| 12308 |
constexpr auto size() const requires sized_range<const V>;
|
| 12309 |
+
|
| 12310 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>;
|
| 12311 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
|
| 12312 |
};
|
| 12313 |
|
| 12314 |
template<class R>
|
| 12315 |
stride_view(R&&, range_difference_t<R>) -> stride_view<views::all_t<R>>;
|
| 12316 |
}
|
|
|
|
| 12340 |
|
| 12341 |
``` cpp
|
| 12342 |
return to-unsigned-like(div-ceil(ranges::distance(base_), stride_));
|
| 12343 |
```
|
| 12344 |
|
| 12345 |
+
``` cpp
|
| 12346 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>;
|
| 12347 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
|
| 12348 |
+
```
|
| 12349 |
+
|
| 12350 |
+
*Effects:* Equivalent to:
|
| 12351 |
+
|
| 12352 |
+
``` cpp
|
| 12353 |
+
auto s = static_cast<range_difference_t<decltype((base_))>>(ranges::reserve_hint(base_));
|
| 12354 |
+
return to-unsigned-like(div-ceil(s, stride_));
|
| 12355 |
+
```
|
| 12356 |
+
|
| 12357 |
#### Class template `stride_view::iterator` <a id="range.stride.iterator">[[range.stride.iterator]]</a>
|
| 12358 |
|
| 12359 |
``` cpp
|
| 12360 |
namespace std::ranges {
|
| 12361 |
template<input_range V>
|
|
|
|
| 12513 |
|
| 12514 |
``` cpp
|
| 12515 |
constexpr void operator++(int);
|
| 12516 |
```
|
| 12517 |
|
| 12518 |
+
*Effects:* Equivalent to `++*this;`
|
| 12519 |
|
| 12520 |
``` cpp
|
| 12521 |
constexpr iterator operator++(int) requires forward_range<Base>;
|
| 12522 |
```
|
| 12523 |
|
|
|
|
| 12755 |
concept cartesian-product-is-bidirectional = // exposition only
|
| 12756 |
(bidirectional_range<maybe-const<Const, First>> && ... &&
|
| 12757 |
(bidirectional_range<maybe-const<Const, Vs>>
|
| 12758 |
&& cartesian-product-common-arg<maybe-const<Const, Vs>>));
|
| 12759 |
|
| 12760 |
+
template<class First, class...>
|
| 12761 |
concept cartesian-product-is-common = // exposition only
|
| 12762 |
cartesian-product-common-arg<First>;
|
| 12763 |
|
| 12764 |
template<class... Vs>
|
| 12765 |
concept cartesian-product-is-sized = // exposition only
|
|
|
|
| 13298 |
the following expressions:
|
| 13299 |
|
| 13300 |
- `noexcept(ranges::iter_swap(std::get<`i`>(l.`*`current_`*`), std::get<`i`>(r.`*`current_`*`)))`
|
| 13301 |
for every integer 0 ≤ i ≤ `sizeof...(Vs)`.
|
| 13302 |
|
| 13303 |
+
### Cache latest view <a id="range.cache.latest">[[range.cache.latest]]</a>
|
| 13304 |
+
|
| 13305 |
+
#### Overview <a id="range.cache.latest.overview">[[range.cache.latest.overview]]</a>
|
| 13306 |
+
|
| 13307 |
+
`cache_latest_view` caches the last-accessed element of its underlying
|
| 13308 |
+
sequence so that the element does not have to be recomputed on repeated
|
| 13309 |
+
access.
|
| 13310 |
+
|
| 13311 |
+
[*Note 1*: This is useful if computation of the element to produce is
|
| 13312 |
+
expensive. — *end note*]
|
| 13313 |
+
|
| 13314 |
+
The name `views::cache_latest` denotes a range adaptor object
|
| 13315 |
+
[[range.adaptor.object]]. Let `E` be an expression. The expression
|
| 13316 |
+
`views::cache_latest(E)` is expression-equivalent to
|
| 13317 |
+
`cache_latest_view(E)`.
|
| 13318 |
+
|
| 13319 |
+
#### Class template `cache_latest_view` <a id="range.cache.latest.view">[[range.cache.latest.view]]</a>
|
| 13320 |
+
|
| 13321 |
+
``` cpp
|
| 13322 |
+
namespace std::ranges {
|
| 13323 |
+
template<input_range V>
|
| 13324 |
+
requires view<V>
|
| 13325 |
+
class cache_latest_view : public view_interface<cache_latest_view<V>> {
|
| 13326 |
+
V base_ = V(); // exposition only
|
| 13327 |
+
using cache-t = conditional_t<is_reference_v<range_reference_t<V>>, // exposition only
|
| 13328 |
+
add_pointer_t<range_reference_t<V>>,
|
| 13329 |
+
range_reference_t<V>>;
|
| 13330 |
+
|
| 13331 |
+
non-propagating-cache<cache-t> cache_; // exposition only
|
| 13332 |
+
|
| 13333 |
+
// [range.cache.latest.iterator], class cache_latest_view::iterator
|
| 13334 |
+
class iterator; // exposition only
|
| 13335 |
+
// [range.cache.latest.sentinel], class cache_latest_view::sentinel
|
| 13336 |
+
class sentinel; // exposition only
|
| 13337 |
+
|
| 13338 |
+
public:
|
| 13339 |
+
cache_latest_view() requires default_initializable<V> = default;
|
| 13340 |
+
constexpr explicit cache_latest_view(V base);
|
| 13341 |
+
|
| 13342 |
+
constexpr V base() const & requires copy_constructible<V> { return base_; }
|
| 13343 |
+
constexpr V base() && { return std::move(base_); }
|
| 13344 |
+
|
| 13345 |
+
constexpr auto begin();
|
| 13346 |
+
constexpr auto end();
|
| 13347 |
+
|
| 13348 |
+
constexpr auto size() requires sized_range<V>;
|
| 13349 |
+
constexpr auto size() const requires sized_range<const V>;
|
| 13350 |
+
|
| 13351 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>;
|
| 13352 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
|
| 13353 |
+
};
|
| 13354 |
+
|
| 13355 |
+
template<class R>
|
| 13356 |
+
cache_latest_view(R&&) -> cache_latest_view<views::all_t<R>>;
|
| 13357 |
+
}
|
| 13358 |
+
```
|
| 13359 |
+
|
| 13360 |
+
``` cpp
|
| 13361 |
+
constexpr explicit cache_latest_view(V base);
|
| 13362 |
+
```
|
| 13363 |
+
|
| 13364 |
+
*Effects:* Initializes *base\_* with `std::move(base)`.
|
| 13365 |
+
|
| 13366 |
+
``` cpp
|
| 13367 |
+
constexpr auto begin();
|
| 13368 |
+
```
|
| 13369 |
+
|
| 13370 |
+
*Effects:* Equivalent to: `return `*`iterator`*`(*this);`
|
| 13371 |
+
|
| 13372 |
+
``` cpp
|
| 13373 |
+
constexpr auto end();
|
| 13374 |
+
```
|
| 13375 |
+
|
| 13376 |
+
*Effects:* Equivalent to: `return `*`sentinel`*`(*this);`
|
| 13377 |
+
|
| 13378 |
+
``` cpp
|
| 13379 |
+
constexpr auto size() requires sized_range<V>;
|
| 13380 |
+
constexpr auto size() const requires sized_range<const V>;
|
| 13381 |
+
```
|
| 13382 |
+
|
| 13383 |
+
*Effects:* Equivalent to: `return ranges::size(`*`base_`*`);`
|
| 13384 |
+
|
| 13385 |
+
``` cpp
|
| 13386 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>;
|
| 13387 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
|
| 13388 |
+
```
|
| 13389 |
+
|
| 13390 |
+
*Effects:* Equivalent to: `return ranges::reserve_hint(`*`base_`*`);`
|
| 13391 |
+
|
| 13392 |
+
#### Class `cache_latest_view::iterator` <a id="range.cache.latest.iterator">[[range.cache.latest.iterator]]</a>
|
| 13393 |
+
|
| 13394 |
+
``` cpp
|
| 13395 |
+
namespace std::ranges {
|
| 13396 |
+
template<input_range V>
|
| 13397 |
+
requires view<V>
|
| 13398 |
+
class cache_latest_view<V>::iterator {
|
| 13399 |
+
cache_latest_view* parent_; // exposition only
|
| 13400 |
+
iterator_t<V> current_; // exposition only
|
| 13401 |
+
|
| 13402 |
+
constexpr explicit iterator(cache_latest_view& parent); // exposition only
|
| 13403 |
+
|
| 13404 |
+
public:
|
| 13405 |
+
using difference_type = range_difference_t<V>;
|
| 13406 |
+
using value_type = range_value_t<V>;
|
| 13407 |
+
using iterator_concept = input_iterator_tag;
|
| 13408 |
+
|
| 13409 |
+
iterator(iterator&&) = default;
|
| 13410 |
+
iterator& operator=(iterator&&) = default;
|
| 13411 |
+
|
| 13412 |
+
constexpr iterator_t<V> base() &&;
|
| 13413 |
+
constexpr const iterator_t<V>& base() const & noexcept;
|
| 13414 |
+
|
| 13415 |
+
constexpr range_reference_t<V>& operator*() const;
|
| 13416 |
+
|
| 13417 |
+
constexpr iterator& operator++();
|
| 13418 |
+
constexpr void operator++(int);
|
| 13419 |
+
|
| 13420 |
+
friend constexpr range_rvalue_reference_t<V> iter_move(const iterator& i)
|
| 13421 |
+
noexcept(noexcept(ranges::iter_move(i.current_)));
|
| 13422 |
+
|
| 13423 |
+
friend constexpr void iter_swap(const iterator& x, const iterator& y)
|
| 13424 |
+
noexcept(noexcept(ranges::iter_swap(x.current_, y.current_)))
|
| 13425 |
+
requires indirectly_swappable<iterator_t<V>>;
|
| 13426 |
+
};
|
| 13427 |
+
}
|
| 13428 |
+
```
|
| 13429 |
+
|
| 13430 |
+
``` cpp
|
| 13431 |
+
constexpr explicit iterator(cache_latest_view& parent);
|
| 13432 |
+
```
|
| 13433 |
+
|
| 13434 |
+
*Effects:* Initializes *current\_* with
|
| 13435 |
+
`ranges::begin(parent.`*`base_`*`)` and *parent\_* with
|
| 13436 |
+
`addressof(parent)`.
|
| 13437 |
+
|
| 13438 |
+
``` cpp
|
| 13439 |
+
constexpr iterator_t<V> base() &&;
|
| 13440 |
+
```
|
| 13441 |
+
|
| 13442 |
+
*Returns:* `std::move(`*`current_`*`)`.
|
| 13443 |
+
|
| 13444 |
+
``` cpp
|
| 13445 |
+
constexpr const iterator_t<V>& base() const & noexcept;
|
| 13446 |
+
```
|
| 13447 |
+
|
| 13448 |
+
*Returns:* *current\_*.
|
| 13449 |
+
|
| 13450 |
+
``` cpp
|
| 13451 |
+
constexpr iterator& operator++();
|
| 13452 |
+
```
|
| 13453 |
+
|
| 13454 |
+
*Effects:* Equivalent to:
|
| 13455 |
+
|
| 13456 |
+
``` cpp
|
| 13457 |
+
parent_->cache_.reset();
|
| 13458 |
+
++current_;
|
| 13459 |
+
return *this;
|
| 13460 |
+
```
|
| 13461 |
+
|
| 13462 |
+
``` cpp
|
| 13463 |
+
constexpr void operator++(int);
|
| 13464 |
+
```
|
| 13465 |
+
|
| 13466 |
+
*Effects:* Equivalent to: `++*this`.
|
| 13467 |
+
|
| 13468 |
+
``` cpp
|
| 13469 |
+
constexpr range_reference_t<V>& operator*() const;
|
| 13470 |
+
```
|
| 13471 |
+
|
| 13472 |
+
*Effects:* Equivalent to:
|
| 13473 |
+
|
| 13474 |
+
``` cpp
|
| 13475 |
+
if constexpr (is_reference_v<range_reference_t<V>>) {
|
| 13476 |
+
if (!parent_->cache_) {
|
| 13477 |
+
parent_->cache_ = addressof(as-lvalue(*current_));
|
| 13478 |
+
}
|
| 13479 |
+
return **parent_->cache_;
|
| 13480 |
+
} else {
|
| 13481 |
+
if (!parent_->cache_) {
|
| 13482 |
+
parent_->cache_.emplace-deref(current_);
|
| 13483 |
+
}
|
| 13484 |
+
return *parent_->cache_;
|
| 13485 |
+
}
|
| 13486 |
+
```
|
| 13487 |
+
|
| 13488 |
+
[*Note 1*: Evaluations of `operator*` on the same iterator object can
|
| 13489 |
+
conflict [[intro.races]]. — *end note*]
|
| 13490 |
+
|
| 13491 |
+
``` cpp
|
| 13492 |
+
friend constexpr range_rvalue_reference_t<V> iter_move(const iterator& i)
|
| 13493 |
+
noexcept(noexcept(ranges::iter_move(i.current_)));
|
| 13494 |
+
```
|
| 13495 |
+
|
| 13496 |
+
*Effects:* Equivalent to: `return ranges::iter_move(i.`*`current_`*`);`
|
| 13497 |
+
|
| 13498 |
+
``` cpp
|
| 13499 |
+
friend constexpr void iter_swap(const iterator& x, const iterator& y)
|
| 13500 |
+
noexcept(noexcept(ranges::iter_swap(x.current_, y.current_)))
|
| 13501 |
+
requires indirectly_swappable<iterator_t<V>>;
|
| 13502 |
+
```
|
| 13503 |
+
|
| 13504 |
+
*Effects:* Equivalent to
|
| 13505 |
+
`ranges::iter_swap(x.`*`current_`*`, y.`*`current_`*`)`.
|
| 13506 |
+
|
| 13507 |
+
#### Class `cache_latest_view::sentinel` <a id="range.cache.latest.sentinel">[[range.cache.latest.sentinel]]</a>
|
| 13508 |
+
|
| 13509 |
+
``` cpp
|
| 13510 |
+
namespace std::ranges {
|
| 13511 |
+
template<input_range V>
|
| 13512 |
+
requires view<V>
|
| 13513 |
+
class cache_latest_view<V>::sentinel {
|
| 13514 |
+
sentinel_t<V> end_ = sentinel_t<V>(); // exposition only
|
| 13515 |
+
|
| 13516 |
+
constexpr explicit sentinel(cache_latest_view& parent); // exposition only
|
| 13517 |
+
|
| 13518 |
+
public:
|
| 13519 |
+
sentinel() = default;
|
| 13520 |
+
|
| 13521 |
+
constexpr sentinel_t<V> base() const;
|
| 13522 |
+
|
| 13523 |
+
friend constexpr bool operator==(const iterator& x, const sentinel& y);
|
| 13524 |
+
|
| 13525 |
+
friend constexpr range_difference_t<V> operator-(const iterator& x, const sentinel& y)
|
| 13526 |
+
requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>;
|
| 13527 |
+
friend constexpr range_difference_t<V> operator-(const sentinel& x, const iterator& y)
|
| 13528 |
+
requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>;
|
| 13529 |
+
};
|
| 13530 |
+
}
|
| 13531 |
+
```
|
| 13532 |
+
|
| 13533 |
+
``` cpp
|
| 13534 |
+
constexpr explicit sentinel(cache_latest_view& parent);
|
| 13535 |
+
```
|
| 13536 |
+
|
| 13537 |
+
*Effects:* Initializes *end\_* with `ranges::end(parent.`*`base_`*`)`.
|
| 13538 |
+
|
| 13539 |
+
``` cpp
|
| 13540 |
+
constexpr sentinel_t<V> base() const;
|
| 13541 |
+
```
|
| 13542 |
+
|
| 13543 |
+
*Returns:* *end\_*.
|
| 13544 |
+
|
| 13545 |
+
``` cpp
|
| 13546 |
+
friend constexpr bool operator==(const iterator& x, const sentinel& y);
|
| 13547 |
+
```
|
| 13548 |
+
|
| 13549 |
+
*Returns:* `x.`*`current_`*` == y.`*`end_`*.
|
| 13550 |
+
|
| 13551 |
+
``` cpp
|
| 13552 |
+
friend constexpr range_difference_t<V> operator-(const iterator& x, const sentinel& y)
|
| 13553 |
+
requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>;
|
| 13554 |
+
```
|
| 13555 |
+
|
| 13556 |
+
*Returns:* `x.`*`current_`*` - y.`*`end_`*.
|
| 13557 |
+
|
| 13558 |
+
``` cpp
|
| 13559 |
+
friend constexpr range_difference_t<V> operator-(const sentinel& x, const iterator& y)
|
| 13560 |
+
requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>;
|
| 13561 |
+
```
|
| 13562 |
+
|
| 13563 |
+
*Returns:* `x.`*`end_`*` - y.`*`current_`*.
|
| 13564 |
+
|
| 13565 |
+
### To input view <a id="range.to.input">[[range.to.input]]</a>
|
| 13566 |
+
|
| 13567 |
+
#### Overview <a id="range.to.input.overview">[[range.to.input.overview]]</a>
|
| 13568 |
+
|
| 13569 |
+
`to_input_view` presents a view of an underlying sequence as an
|
| 13570 |
+
input-only non-common range.
|
| 13571 |
+
|
| 13572 |
+
[*Note 1*: This is useful to avoid overhead that can be necessary to
|
| 13573 |
+
provide support for the operations needed for greater iterator
|
| 13574 |
+
strength. — *end note*]
|
| 13575 |
+
|
| 13576 |
+
The name `views::to_input` denotes a range adaptor object
|
| 13577 |
+
[[range.adaptor.object]]. Let `E` be an expression and let `T` be
|
| 13578 |
+
`decltype((E))`. The expression `views::to_input(E)` is
|
| 13579 |
+
expression-equivalent to:
|
| 13580 |
+
|
| 13581 |
+
- `views::all(E)` if `T` models `input_range`, does not satisfy
|
| 13582 |
+
`common_range`, and does not satisfy `forward_range`.
|
| 13583 |
+
- Otherwise, `to_input_view(E)`.
|
| 13584 |
+
|
| 13585 |
+
#### Class template `to_input_view` <a id="range.to.input.view">[[range.to.input.view]]</a>
|
| 13586 |
+
|
| 13587 |
+
``` cpp
|
| 13588 |
+
namespace std::ranges {
|
| 13589 |
+
template<input_range V>
|
| 13590 |
+
requires view<V>
|
| 13591 |
+
class to_input_view : public view_interface<to_input_view<V>> {
|
| 13592 |
+
V base_ = V(); // exposition only
|
| 13593 |
+
|
| 13594 |
+
// [range.to.input.iterator], class template to_input_view::iterator
|
| 13595 |
+
template<bool Const> class iterator; // exposition only
|
| 13596 |
+
|
| 13597 |
+
public:
|
| 13598 |
+
to_input_view() requires default_initializable<V> = default;
|
| 13599 |
+
constexpr explicit to_input_view(V base);
|
| 13600 |
+
|
| 13601 |
+
constexpr V base() const & requires copy_constructible<V> { return base_; }
|
| 13602 |
+
constexpr V base() && { return std::move(base_); }
|
| 13603 |
+
|
| 13604 |
+
constexpr auto begin() requires (!simple-view<V>);
|
| 13605 |
+
constexpr auto begin() const requires range<const V>;
|
| 13606 |
+
|
| 13607 |
+
constexpr auto end() requires (!simple-view<V>);
|
| 13608 |
+
constexpr auto end() const requires range<const V>;
|
| 13609 |
+
|
| 13610 |
+
constexpr auto size() requires sized_range<V>;
|
| 13611 |
+
constexpr auto size() const requires sized_range<const V>;
|
| 13612 |
+
|
| 13613 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>;
|
| 13614 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
|
| 13615 |
+
};
|
| 13616 |
+
|
| 13617 |
+
template<class R>
|
| 13618 |
+
to_input_view(R&&) -> to_input_view<views::all_t<R>>;
|
| 13619 |
+
}
|
| 13620 |
+
```
|
| 13621 |
+
|
| 13622 |
+
``` cpp
|
| 13623 |
+
constexpr explicit to_input_view(V base);
|
| 13624 |
+
```
|
| 13625 |
+
|
| 13626 |
+
*Effects:* Initializes *base\_* with `std::move(base)`.
|
| 13627 |
+
|
| 13628 |
+
``` cpp
|
| 13629 |
+
constexpr auto begin() requires (!simple-view<V>);
|
| 13630 |
+
```
|
| 13631 |
+
|
| 13632 |
+
*Effects:* Equivalent to:
|
| 13633 |
+
`return `*`iterator`*`<false>(ranges::begin(`*`base_`*`));`
|
| 13634 |
+
|
| 13635 |
+
``` cpp
|
| 13636 |
+
constexpr auto begin() const requires range<const V>;
|
| 13637 |
+
```
|
| 13638 |
+
|
| 13639 |
+
*Effects:* Equivalent to:
|
| 13640 |
+
`return `*`iterator`*`<true>(ranges::begin(`*`base_`*`));`
|
| 13641 |
+
|
| 13642 |
+
``` cpp
|
| 13643 |
+
constexpr auto end() requires (!simple-view<V>);
|
| 13644 |
+
constexpr auto end() const requires range<const V>;
|
| 13645 |
+
```
|
| 13646 |
+
|
| 13647 |
+
*Effects:* Equivalent to: `return ranges::end(`*`base_`*`);`
|
| 13648 |
+
|
| 13649 |
+
``` cpp
|
| 13650 |
+
constexpr auto size() requires sized_range<V>;
|
| 13651 |
+
constexpr auto size() const requires sized_range<const V>;
|
| 13652 |
+
```
|
| 13653 |
+
|
| 13654 |
+
*Effects:* Equivalent to: `return ranges::size(`*`base_`*`);`
|
| 13655 |
+
|
| 13656 |
+
``` cpp
|
| 13657 |
+
constexpr auto reserve_hint() requires approximately_sized_range<V>;
|
| 13658 |
+
constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
|
| 13659 |
+
```
|
| 13660 |
+
|
| 13661 |
+
*Effects:* Equivalent to: `return ranges::reserve_hint(`*`base_`*`);`
|
| 13662 |
+
|
| 13663 |
+
#### Class template `to_input_view::iterator` <a id="range.to.input.iterator">[[range.to.input.iterator]]</a>
|
| 13664 |
+
|
| 13665 |
+
``` cpp
|
| 13666 |
+
namespace std::ranges {
|
| 13667 |
+
template<input_range V>
|
| 13668 |
+
requires view<V>
|
| 13669 |
+
template<bool Const>
|
| 13670 |
+
class to_input_view<V>::iterator {
|
| 13671 |
+
using Base = maybe-const<Const, V>; // exposition only
|
| 13672 |
+
|
| 13673 |
+
iterator_t<Base> current_ = iterator_t<Base>(); // exposition only
|
| 13674 |
+
|
| 13675 |
+
constexpr explicit iterator(iterator_t<Base> current); // exposition only
|
| 13676 |
+
|
| 13677 |
+
public:
|
| 13678 |
+
using difference_type = range_difference_t<Base>;
|
| 13679 |
+
using value_type = range_value_t<Base>;
|
| 13680 |
+
using iterator_concept = input_iterator_tag;
|
| 13681 |
+
|
| 13682 |
+
iterator() requires default_initializable<iterator_t<Base>> = default;
|
| 13683 |
+
|
| 13684 |
+
iterator(iterator&&) = default;
|
| 13685 |
+
iterator& operator=(iterator&&) = default;
|
| 13686 |
+
|
| 13687 |
+
constexpr iterator(iterator<!Const> i)
|
| 13688 |
+
requires Const && convertible_to<iterator_t<V>, iterator_t<Base>>;
|
| 13689 |
+
|
| 13690 |
+
constexpr iterator_t<Base> base() &&;
|
| 13691 |
+
constexpr const iterator_t<Base>& base() const & noexcept;
|
| 13692 |
+
|
| 13693 |
+
constexpr decltype(auto) operator*() const { return *current_; }
|
| 13694 |
+
|
| 13695 |
+
constexpr iterator& operator++();
|
| 13696 |
+
constexpr void operator++(int);
|
| 13697 |
+
|
| 13698 |
+
friend constexpr bool operator==(const iterator& x, const sentinel_t<Base>& y);
|
| 13699 |
+
|
| 13700 |
+
friend constexpr difference_type operator-(const sentinel_t<Base>& y, const iterator& x)
|
| 13701 |
+
requires sized_sentinel_for<sentinel_t<Base>, iterator_t<Base>>;
|
| 13702 |
+
friend constexpr difference_type operator-(const iterator& x, const sentinel_t<Base>& y)
|
| 13703 |
+
requires sized_sentinel_for<sentinel_t<Base>, iterator_t<Base>>;
|
| 13704 |
+
|
| 13705 |
+
friend constexpr range_rvalue_reference_t<Base> iter_move(const iterator& i)
|
| 13706 |
+
noexcept(noexcept(ranges::iter_move(i.current_)));
|
| 13707 |
+
|
| 13708 |
+
friend constexpr void iter_swap(const iterator& x, const iterator& y)
|
| 13709 |
+
noexcept(noexcept(ranges::iter_swap(x.current_, y.current_)))
|
| 13710 |
+
requires indirectly_swappable<iterator_t<Base>>;
|
| 13711 |
+
};
|
| 13712 |
+
}
|
| 13713 |
+
```
|
| 13714 |
+
|
| 13715 |
+
``` cpp
|
| 13716 |
+
constexpr explicit iterator(iterator_t<Base> current);
|
| 13717 |
+
```
|
| 13718 |
+
|
| 13719 |
+
*Effects:* Initializes *current\_* with `std::move(current)`.
|
| 13720 |
+
|
| 13721 |
+
``` cpp
|
| 13722 |
+
constexpr iterator(iterator<!Const> i)
|
| 13723 |
+
requires Const && convertible_to<iterator_t<V>, iterator_t<Base>>;
|
| 13724 |
+
```
|
| 13725 |
+
|
| 13726 |
+
*Effects:* Initializes *current\_* with `std::move(i.`*`current_`*`)`.
|
| 13727 |
+
|
| 13728 |
+
``` cpp
|
| 13729 |
+
constexpr iterator_t<Base> base() &&;
|
| 13730 |
+
```
|
| 13731 |
+
|
| 13732 |
+
*Returns:* `std::move(`*`current_`*`)`.
|
| 13733 |
+
|
| 13734 |
+
``` cpp
|
| 13735 |
+
constexpr const iterator_t<Base>& base() const & noexcept;
|
| 13736 |
+
```
|
| 13737 |
+
|
| 13738 |
+
*Returns:* *current\_*.
|
| 13739 |
+
|
| 13740 |
+
``` cpp
|
| 13741 |
+
constexpr iterator& operator++();
|
| 13742 |
+
```
|
| 13743 |
+
|
| 13744 |
+
*Effects:* Equivalent to:
|
| 13745 |
+
|
| 13746 |
+
``` cpp
|
| 13747 |
+
++current_;
|
| 13748 |
+
return *this;
|
| 13749 |
+
```
|
| 13750 |
+
|
| 13751 |
+
``` cpp
|
| 13752 |
+
constexpr void operator++(int);
|
| 13753 |
+
```
|
| 13754 |
+
|
| 13755 |
+
*Effects:* Equivalent to: `++*this;`
|
| 13756 |
+
|
| 13757 |
+
``` cpp
|
| 13758 |
+
friend constexpr bool operator==(const iterator& x, const sentinel_t<Base>& y);
|
| 13759 |
+
```
|
| 13760 |
+
|
| 13761 |
+
*Returns:* `x.`*`current_`*` == y`.
|
| 13762 |
+
|
| 13763 |
+
``` cpp
|
| 13764 |
+
friend constexpr difference_type operator-(const sentinel_t<Base>& y, const iterator& x)
|
| 13765 |
+
requires sized_sentinel_for<sentinel_t<Base>, iterator_t<Base>>;
|
| 13766 |
+
```
|
| 13767 |
+
|
| 13768 |
+
*Returns:* `y - x.`*`current_`*.
|
| 13769 |
+
|
| 13770 |
+
``` cpp
|
| 13771 |
+
friend constexpr difference_type operator-(const iterator& x, const sentinel_t<Base>& y)
|
| 13772 |
+
requires sized_sentinel_for<sentinel_t<Base>, iterator_t<Base>>;
|
| 13773 |
+
```
|
| 13774 |
+
|
| 13775 |
+
*Returns:* `x.`*`current_`*` - y`.
|
| 13776 |
+
|
| 13777 |
+
``` cpp
|
| 13778 |
+
friend constexpr range_rvalue_reference_t<Base> iter_move(const iterator& i)
|
| 13779 |
+
noexcept(noexcept(ranges::iter_move(i.current_)));
|
| 13780 |
+
```
|
| 13781 |
+
|
| 13782 |
+
*Effects:* Equivalent to: `return ranges::iter_move(i.`*`current_`*`);`
|
| 13783 |
+
|
| 13784 |
+
``` cpp
|
| 13785 |
+
friend constexpr void iter_swap(const iterator& x, const iterator& y)
|
| 13786 |
+
noexcept(noexcept(ranges::iter_swap(x.current_, y.current_)))
|
| 13787 |
+
requires indirectly_swappable<iterator_t<Base>>;
|
| 13788 |
+
```
|
| 13789 |
+
|
| 13790 |
+
*Effects:* Equivalent to:
|
| 13791 |
+
`ranges::iter_swap(x.`*`current_`*`, y.`*`current_`*`);`
|
| 13792 |
+
|
| 13793 |
## Range generators <a id="coro.generator">[[coro.generator]]</a>
|
| 13794 |
|
| 13795 |
### Overview <a id="coroutine.generator.overview">[[coroutine.generator.overview]]</a>
|
| 13796 |
|
| 13797 |
Class template `generator` presents a view of the elements yielded by
|
|
|
|
| 13823 |
### Header `<generator>` synopsis <a id="generator.syn">[[generator.syn]]</a>
|
| 13824 |
|
| 13825 |
``` cpp
|
| 13826 |
namespace std {
|
| 13827 |
// [coro.generator.class], class template generator
|
| 13828 |
+
template<class Ref, class Val = void, class Allocator = void>
|
| 13829 |
class generator;
|
| 13830 |
|
| 13831 |
namespace pmr {
|
| 13832 |
+
template<class Ref, class Val = void>
|
| 13833 |
+
using generator = std::generator<Ref, Val, polymorphic_allocator<>>;
|
| 13834 |
}
|
| 13835 |
}
|
| 13836 |
```
|
| 13837 |
|
| 13838 |
### Class template `generator` <a id="coro.generator.class">[[coro.generator.class]]</a>
|
| 13839 |
|
| 13840 |
``` cpp
|
| 13841 |
namespace std {
|
| 13842 |
+
template<class Ref, class Val = void, class Allocator = void>
|
| 13843 |
+
class generator : public ranges::view_interface<generator<Ref, Val, Allocator>> {
|
| 13844 |
private:
|
| 13845 |
+
using value = conditional_t<is_void_v<Val>, remove_cvref_t<Ref>, Val>; // exposition only
|
| 13846 |
+
using reference = conditional_t<is_void_v<Val>, Ref&&, Ref>; // exposition only
|
| 13847 |
|
| 13848 |
// [coro.generator.iterator], class generator::iterator
|
| 13849 |
class iterator; // exposition only
|
| 13850 |
|
| 13851 |
public:
|
|
|
|
| 13904 |
generator(generator&& other) noexcept;
|
| 13905 |
```
|
| 13906 |
|
| 13907 |
*Effects:* Initializes *coroutine\_* with
|
| 13908 |
`exchange(other.`*`coroutine_`*`, {})` and *active\_* with
|
| 13909 |
+
`exchange(other.`*`active_`*`, nullptr)`.
|
| 13910 |
|
| 13911 |
[*Note 1*: Iterators previously obtained from `other` are not
|
| 13912 |
invalidated; they become iterators into `*this`. — *end note*]
|
| 13913 |
|
| 13914 |
``` cpp
|
|
|
|
| 13968 |
|
| 13969 |
### Class `generator::promise_type` <a id="coro.generator.promise">[[coro.generator.promise]]</a>
|
| 13970 |
|
| 13971 |
``` cpp
|
| 13972 |
namespace std {
|
| 13973 |
+
template<class Ref, class Val, class Allocator>
|
| 13974 |
+
class generator<Ref, Val, Allocator>::promise_type {
|
| 13975 |
public:
|
| 13976 |
generator get_return_object() noexcept;
|
| 13977 |
|
| 13978 |
suspend_always initial_suspend() const noexcept { return {}; }
|
| 13979 |
auto final_suspend() noexcept;
|
|
|
|
| 13985 |
constructible_from<remove_cvref_t<yielded>, const remove_reference_t<yielded>&>;
|
| 13986 |
|
| 13987 |
template<class R2, class V2, class Alloc2, class Unused>
|
| 13988 |
requires same_as<typename generator<R2, V2, Alloc2>::yielded, yielded>
|
| 13989 |
auto yield_value(ranges::elements_of<generator<R2, V2, Alloc2>&&, Unused> g) noexcept;
|
| 13990 |
+
template<class R2, class V2, class Alloc2, class Unused>
|
| 13991 |
+
requires same_as<typename generator<R2, V2, Alloc2>::yielded, yielded>
|
| 13992 |
+
auto yield_value(ranges::elements_of<generator<R2, V2, Alloc2>&, Unused> g) noexcept;
|
| 13993 |
|
| 13994 |
template<ranges::input_range R, class Alloc>
|
| 13995 |
requires convertible_to<ranges::range_reference_t<R>, yielded>
|
| 13996 |
+
auto yield_value(ranges::elements_of<R, Alloc> r);
|
| 13997 |
|
| 13998 |
void await_transform() = delete;
|
| 13999 |
|
| 14000 |
void return_void() const noexcept {}
|
| 14001 |
void unhandled_exception();
|
| 14002 |
|
| 14003 |
void* operator new(size_t size)
|
| 14004 |
requires same_as<Allocator, void> || default_initializable<Allocator>;
|
| 14005 |
|
| 14006 |
template<class Alloc, class... Args>
|
|
|
|
| 14007 |
void* operator new(size_t size, allocator_arg_t, const Alloc& alloc, const Args&...);
|
| 14008 |
|
| 14009 |
template<class This, class Alloc, class... Args>
|
|
|
|
| 14010 |
void* operator new(size_t size, const This&, allocator_arg_t, const Alloc& alloc,
|
| 14011 |
const Args&...);
|
| 14012 |
|
| 14013 |
void operator delete(void* pointer, size_t size) noexcept;
|
| 14014 |
|
|
|
|
| 14075 |
|
| 14076 |
``` cpp
|
| 14077 |
template<class R2, class V2, class Alloc2, class Unused>
|
| 14078 |
requires same_as<typename generator<R2, V2, Alloc2>::yielded, yielded>
|
| 14079 |
auto yield_value(ranges::elements_of<generator<R2, V2, Alloc2>&&, Unused> g) noexcept;
|
| 14080 |
+
template<class R2, class V2, class Alloc2, class Unused>
|
| 14081 |
+
requires same_as<typename generator<R2, V2, Alloc2>::yielded, yielded>
|
| 14082 |
+
auto yield_value(ranges::elements_of<generator<R2, V2, Alloc2>&, Unused> g) noexcept;
|
| 14083 |
```
|
| 14084 |
|
| 14085 |
*Preconditions:* A handle referring to the coroutine whose promise
|
| 14086 |
object is `*this` is at the top of `*`*`active_`* of some `generator`
|
| 14087 |
object `x`. The coroutine referred to by `g.range.`*`coroutine_`* is
|
|
|
|
| 14094 |
execution of the coroutine referred to by `g.range.`*`coroutine_`*, and
|
| 14095 |
whose member `await_resume` evaluates `rethrow_exception(`*`except_`*`)`
|
| 14096 |
if `bool(`*`except_`*`)` is `true`. If `bool(`*`except_`*`)` is `false`,
|
| 14097 |
the `await_resume` member has no effects.
|
| 14098 |
|
| 14099 |
+
*Remarks:* A *yield-expression* that calls one of these functions has
|
| 14100 |
+
type `void` [[expr.yield]].
|
| 14101 |
|
| 14102 |
``` cpp
|
| 14103 |
template<ranges::input_range R, class Alloc>
|
| 14104 |
requires convertible_to<ranges::range_reference_t<R>, yielded>
|
| 14105 |
+
auto yield_value(ranges::elements_of<R, Alloc> r);
|
| 14106 |
```
|
| 14107 |
|
| 14108 |
*Effects:* Equivalent to:
|
| 14109 |
|
| 14110 |
``` cpp
|
| 14111 |
auto nested = [](allocator_arg_t, Alloc, ranges::iterator_t<R> i, ranges::sentinel_t<R> s)
|
| 14112 |
+
-> generator<yielded, void, Alloc> {
|
| 14113 |
for (; i != s; ++i) {
|
| 14114 |
co_yield static_cast<yielded>(*i);
|
| 14115 |
}
|
| 14116 |
};
|
| 14117 |
return yield_value(ranges::elements_of(nested(
|
|
|
|
| 14136 |
``` cpp
|
| 14137 |
void* operator new(size_t size)
|
| 14138 |
requires same_as<Allocator, void> || default_initializable<Allocator>;
|
| 14139 |
|
| 14140 |
template<class Alloc, class... Args>
|
|
|
|
| 14141 |
void* operator new(size_t size, allocator_arg_t, const Alloc& alloc, const Args&...);
|
| 14142 |
|
| 14143 |
template<class This, class Alloc, class... Args>
|
|
|
|
| 14144 |
void* operator new(size_t size, const This&, allocator_arg_t, const Alloc& alloc,
|
| 14145 |
const Args&...);
|
| 14146 |
```
|
| 14147 |
|
| 14148 |
Let `A` be
|
|
|
|
| 14153 |
|
| 14154 |
Let `B` be `allocator_traits<A>::template rebind_alloc<U>` where `U` is
|
| 14155 |
an unspecified type whose size and alignment are both
|
| 14156 |
\_\_STDCPP_DEFAULT_NEW_ALIGNMENT\_\_.
|
| 14157 |
|
| 14158 |
+
*Mandates:* `allocator_traits<B>::pointer` is a pointer type. For the
|
| 14159 |
+
overloads with a template parameter `Alloc`,
|
| 14160 |
+
`same_as<Allocator, void> || convertible_to<const Alloc&, Allocator>` is
|
| 14161 |
+
modeled.
|
| 14162 |
|
| 14163 |
*Effects:* Initializes an allocator `b` of type `B` with `A(alloc)`, for
|
| 14164 |
the overloads with a function parameter `alloc`, and with `A()`
|
| 14165 |
otherwise. Uses `b` to allocate storage for the smallest array of `U`
|
| 14166 |
sufficient to provide storage for a coroutine state of size `size`, and
|
|
|
|
| 14182 |
|
| 14183 |
### Class `generator::iterator` <a id="coro.generator.iterator">[[coro.generator.iterator]]</a>
|
| 14184 |
|
| 14185 |
``` cpp
|
| 14186 |
namespace std {
|
| 14187 |
+
template<class Ref, class Val, class Allocator>
|
| 14188 |
+
class generator<Ref, Val, Allocator>::iterator {
|
| 14189 |
public:
|
| 14190 |
using value_type = value;
|
| 14191 |
using difference_type = ptrdiff_t;
|
| 14192 |
|
| 14193 |
iterator(iterator&& other) noexcept;
|
|
|
|
| 14254 |
```
|
| 14255 |
|
| 14256 |
*Effects:* Equivalent to: `return i.`*`coroutine_`*`.done();`
|
| 14257 |
|
| 14258 |
<!-- Link reference definitions -->
|
| 14259 |
+
[algorithms]: algorithms.md#algorithms
|
| 14260 |
[basic.lookup.argdep]: basic.md#basic.lookup.argdep
|
| 14261 |
[concepts.equality]: concepts.md#concepts.equality
|
| 14262 |
[containers]: containers.md#containers
|
| 14263 |
[conv.rval]: expr.md#conv.rval
|
| 14264 |
[coro.generator]: #coro.generator
|
|
|
|
| 14272 |
[dcl.init.general]: dcl.md#dcl.init.general
|
| 14273 |
[expr.await]: expr.md#expr.await
|
| 14274 |
[expr.const]: expr.md#expr.const
|
| 14275 |
[expr.yield]: expr.md#expr.yield
|
| 14276 |
[generator.syn]: #generator.syn
|
| 14277 |
+
[intro.races]: basic.md#intro.races
|
| 14278 |
[iterator.concept.bidir]: iterators.md#iterator.concept.bidir
|
| 14279 |
[iterator.concept.forward]: iterators.md#iterator.concept.forward
|
| 14280 |
[iterator.concept.iterator]: iterators.md#iterator.concept.iterator
|
| 14281 |
[iterator.concept.output]: iterators.md#iterator.concept.output
|
| 14282 |
[iterator.concept.random.access]: iterators.md#iterator.concept.random.access
|
|
|
|
| 14308 |
[range.adjacent.transform.sentinel]: #range.adjacent.transform.sentinel
|
| 14309 |
[range.adjacent.transform.view]: #range.adjacent.transform.view
|
| 14310 |
[range.adjacent.view]: #range.adjacent.view
|
| 14311 |
[range.all]: #range.all
|
| 14312 |
[range.all.general]: #range.all.general
|
| 14313 |
+
[range.approximately.sized]: #range.approximately.sized
|
| 14314 |
[range.as.const]: #range.as.const
|
| 14315 |
[range.as.const.overview]: #range.as.const.overview
|
| 14316 |
[range.as.const.view]: #range.as.const.view
|
| 14317 |
[range.as.rvalue]: #range.as.rvalue
|
| 14318 |
[range.as.rvalue.overview]: #range.as.rvalue.overview
|
| 14319 |
[range.as.rvalue.view]: #range.as.rvalue.view
|
| 14320 |
+
[range.cache.latest]: #range.cache.latest
|
| 14321 |
+
[range.cache.latest.iterator]: #range.cache.latest.iterator
|
| 14322 |
+
[range.cache.latest.overview]: #range.cache.latest.overview
|
| 14323 |
+
[range.cache.latest.sentinel]: #range.cache.latest.sentinel
|
| 14324 |
+
[range.cache.latest.view]: #range.cache.latest.view
|
| 14325 |
[range.cartesian]: #range.cartesian
|
| 14326 |
[range.cartesian.iterator]: #range.cartesian.iterator
|
| 14327 |
[range.cartesian.overview]: #range.cartesian.overview
|
| 14328 |
[range.cartesian.view]: #range.cartesian.view
|
| 14329 |
[range.chunk]: #range.chunk
|
|
|
|
| 14339 |
[range.chunk.view.fwd]: #range.chunk.view.fwd
|
| 14340 |
[range.chunk.view.input]: #range.chunk.view.input
|
| 14341 |
[range.common]: #range.common
|
| 14342 |
[range.common.overview]: #range.common.overview
|
| 14343 |
[range.common.view]: #range.common.view
|
| 14344 |
+
[range.concat]: #range.concat
|
| 14345 |
+
[range.concat.iterator]: #range.concat.iterator
|
| 14346 |
+
[range.concat.overview]: #range.concat.overview
|
| 14347 |
+
[range.concat.view]: #range.concat.view
|
| 14348 |
[range.counted]: #range.counted
|
| 14349 |
[range.dangling]: #range.dangling
|
| 14350 |
[range.drop]: #range.drop
|
| 14351 |
[range.drop.overview]: #range.drop.overview
|
| 14352 |
[range.drop.view]: #range.drop.view
|
|
|
|
| 14404 |
[range.owning.view]: #range.owning.view
|
| 14405 |
[range.prim.cdata]: #range.prim.cdata
|
| 14406 |
[range.prim.data]: #range.prim.data
|
| 14407 |
[range.prim.empty]: #range.prim.empty
|
| 14408 |
[range.prim.size]: #range.prim.size
|
| 14409 |
+
[range.prim.size.hint]: #range.prim.size.hint
|
| 14410 |
[range.prim.ssize]: #range.prim.ssize
|
| 14411 |
[range.range]: #range.range
|
| 14412 |
[range.ref.view]: #range.ref.view
|
| 14413 |
[range.refinements]: #range.refinements
|
| 14414 |
[range.repeat]: #range.repeat
|
|
|
|
| 14449 |
[range.take.view]: #range.take.view
|
| 14450 |
[range.take.while]: #range.take.while
|
| 14451 |
[range.take.while.overview]: #range.take.while.overview
|
| 14452 |
[range.take.while.sentinel]: #range.take.while.sentinel
|
| 14453 |
[range.take.while.view]: #range.take.while.view
|
| 14454 |
+
[range.to.input]: #range.to.input
|
| 14455 |
+
[range.to.input.iterator]: #range.to.input.iterator
|
| 14456 |
+
[range.to.input.overview]: #range.to.input.overview
|
| 14457 |
+
[range.to.input.view]: #range.to.input.view
|
| 14458 |
[range.transform]: #range.transform
|
| 14459 |
[range.transform.iterator]: #range.transform.iterator
|
| 14460 |
[range.transform.overview]: #range.transform.overview
|
| 14461 |
[range.transform.sentinel]: #range.transform.sentinel
|
| 14462 |
[range.transform.view]: #range.transform.view
|