134 constexpr Derived & derived()
noexcept
136 CPP_assert(derived_from<Derived, view_interface>);
137 return static_cast<Derived &
>(*this);
140 constexpr Derived
const &
derived() const noexcept
142 CPP_assert(derived_from<Derived, view_interface>);
143 return static_cast<Derived
const &
>(*this);
154 constexpr auto empty() const noexcept
156 requires (detail::has_fixed_size_<Cardinality>))
158 return Cardinality == 0;
161 template(
bool True =
true)(
162 requires True AND (Cardinality < 0) AND (Cardinality != infinite) AND
164 constexpr
bool empty()
165 noexcept(noexcept(
bool(ranges::size(std::declval<D<True> &>()) == 0)))
167 return ranges::size(derived()) == 0;
170 template(
bool True =
true)(
171 requires True AND (Cardinality < 0) AND (Cardinality != infinite) AND
172 (!forward_range<D<True>
const>) AND sized_range<D<True> const>)
173 constexpr
bool empty() const
174 noexcept(noexcept(
bool(ranges::size(std::declval<D<True> const &>()) == 0)))
176 return ranges::size(derived()) == 0;
179 template(
bool True =
true)(
180 requires True AND (!detail::has_fixed_size_<Cardinality>) AND
181 forward_range<D<True>>)
182 constexpr bool empty()
noexcept(
183 noexcept(bool(ranges::begin(std::declval<D<True> &>()) ==
184 ranges::end(std::declval<D<True> &>()))))
186 return bool(ranges::begin(derived()) == ranges::end(derived()));
189 template(
bool True =
true)(
190 requires True AND (!detail::has_fixed_size_<Cardinality>) AND
191 forward_range<D<True>
const>)
192 constexpr bool empty()
const
193 noexcept(
noexcept(bool(ranges::begin(std::declval<D<True>
const &>()) ==
194 ranges::end(std::declval<D<True>
const &>()))))
196 return bool(ranges::begin(derived()) == ranges::end(derived()));
198 CPP_template_gcc_workaround(
bool True =
true)(
199 requires True && detail::can_empty_<D<True>>)
200 constexpr explicit operator bool()
201 noexcept(
noexcept(ranges::empty(std::declval<D<True> &>())))
203 return !ranges::empty(derived());
207 CPP_template_gcc_workaround(
bool True =
true)(
208 requires True && detail::can_empty_<D<True>
const>)
209 constexpr explicit operator bool()
const
210 noexcept(
noexcept(ranges::empty(std::declval<D<True>
const &>())))
212 return !ranges::empty(derived());
217 template(
bool True =
true,
int = 42)(
218 requires True AND (Cardinality >= 0))
219 static constexpr std::size_t
size()
noexcept
221 return static_cast<std::size_t
>(Cardinality);
226 template(
bool True =
true)(
227 requires True AND (Cardinality < 0) AND
228 sized_sentinel_for<sentinel_t<D<True>>, iterator_t<D<True>>> AND
229 forward_range<D<True>>)
232 using size_type = detail::iter_size_t<iterator_t<D<True>>>;
233 return static_cast<size_type
>(derived().end() - derived().begin());
236 template(
bool True =
true)(
237 requires True AND (Cardinality < 0) AND
238 sized_sentinel_for<sentinel_t<D<True>
const>,
239 iterator_t<D<True>
const>> AND
240 forward_range<D<True>
const>)
243 using size_type = detail::iter_size_t<iterator_t<D<True>>>;
244 return static_cast<size_type
>(derived().end() - derived().begin());
247 template(
bool True =
true)(
248 requires True AND forward_range<D<True>>)
249 constexpr range_reference_t<D<True>>
front()
251 return *derived().begin();
254 template(
bool True =
true)(
255 requires True AND forward_range<D<True>
const>)
256 constexpr range_reference_t<D<True>
const>
front()
const
258 return *derived().begin();
261 template(
bool True =
true)(
262 requires True AND common_range<D<True>> AND bidirectional_range<D<True>>)
263 constexpr range_reference_t<D<True>>
back()
265 return *prev(derived().end());
268 template(
bool True =
true)(
269 requires True AND common_range<D<True>
const> AND
270 bidirectional_range<D<True>
const>)
271 constexpr range_reference_t<D<True>
const>
back()
const
273 return *prev(derived().end());
276 template(
bool True =
true)(
277 requires True AND random_access_range<D<True>>)
278 constexpr range_reference_t<D<True>> operator[](range_difference_t<D<True>> n)
280 return derived().begin()[n];
283 template(
bool True =
true)(
284 requires True AND random_access_range<D<True>
const>)
285 constexpr range_reference_t<D<True>
const>
286 operator[](range_difference_t<D<True>> n)
const
288 return derived().begin()[n];
292 template(
bool True =
true)(
293 requires True AND contiguous_iterator<
iterator_t<D<True>>>)
294 constexpr std::add_pointer_t<range_reference_t<D<True>>> data()
296 return std::addressof(*ranges::begin(derived()));
299 template(
bool True =
true)(
300 requires True AND contiguous_iterator<
iterator_t<D<True>
const>>)
301 constexpr std::add_pointer_t<range_reference_t<D<True>
const>> data() const
303 return std::addressof(*ranges::begin(derived()));
307 template(
bool True =
true)(
308 requires True AND random_access_range<D<True>> AND sized_range<D<True>>)
309 constexpr range_reference_t<D<True>>
at(range_difference_t<D<True>> n)
311 using size_type = range_size_t<Derived>;
312 if(n < 0 || size_type(n) >= ranges::size(derived()))
314 throw std::out_of_range(
"view_interface::at");
316 return derived().begin()[n];
319 template(
bool True =
true)(
320 requires True AND random_access_range<D<True>
const> AND
321 sized_range<D<True>
const>)
322 constexpr range_reference_t<D<True>
const>
at(range_difference_t<D<True>> n)
const
324 using size_type = range_size_t<Derived const>;
325 if(n < 0 || size_type(n) >= ranges::size(derived()))
327 throw std::out_of_range(
"view_interface::at");
329 return derived().begin()[n];
333 template(
bool True =
true,
typename Slice = views::slice_fn)(
334 requires True AND input_range<D<True> &>)
336 operator[](detail::slice_bounds<range_difference_t<D<True>>> offs) &
338 return Slice{}(derived(), offs.from, offs.to);
341 template(
bool True =
true,
typename Slice = views::slice_fn)(
342 requires True AND input_range<D<True>
const &>)
344 operator[](detail::slice_bounds<range_difference_t<D<True>>> offs)
const &
346 return Slice{}(derived(), offs.from, offs.to);
349 template(
bool True =
true,
typename Slice = views::slice_fn)(
350 requires True AND input_range<D<True>>)
352 operator[](detail::slice_bounds<range_difference_t<D<True>>> offs) &&
354 return Slice{}(detail::move(derived()), offs.from, offs.to);
358 template(
bool True =
true,
typename Slice = views::slice_fn)(
359 requires True AND input_range<D<True> &> AND sized_range<D<True> &>)
361 operator[](detail::slice_bounds<range_difference_t<D<True>>,
362 detail::from_end_of_t<D<True>>> offs) &
364 return Slice{}(derived(), offs.from, offs.to);
367 template(
bool True =
true,
typename Slice = views::slice_fn)(
368 requires True AND input_range<D<True>
const &> AND
369 sized_range<D<True>
const &>)
371 operator[](detail::slice_bounds<range_difference_t<D<True>>,
372 detail::from_end_of_t<D<True>>> offs)
const &
374 return Slice{}(derived(), offs.from, offs.to);
377 template(
bool True =
true,
typename Slice = views::slice_fn)(
378 requires True AND input_range<D<True>> AND sized_range<D<True>>)
380 operator[](detail::slice_bounds<range_difference_t<D<True>>,
381 detail::from_end_of_t<D<True>>> offs) &&
383 return Slice{}(detail::move(derived()), offs.from, offs.to);
387 template(
bool True =
true,
typename Slice = views::slice_fn)(
388 requires True AND (forward_range<D<True> &> ||
389 (input_range<D<True> &> && sized_range<D<True> &>)))
391 operator[](detail::slice_bounds<detail::from_end_of_t<D<True>>,
392 detail::from_end_of_t<D<True>>> offs) &
394 return Slice{}(derived(), offs.from, offs.to);
397 template(
bool True =
true,
typename Slice = views::slice_fn)(
399 (forward_range<D<True>
const &> ||
400 (input_range<D<True>
const &> && sized_range<D<True>
const &>)))
402 operator[](detail::slice_bounds<detail::from_end_of_t<D<True>>,
403 detail::from_end_of_t<D<True>>> offs)
const &
405 return Slice{}(derived(), offs.from, offs.to);
408 template(
bool True =
true,
typename Slice = views::slice_fn)(
410 (forward_range<D<True>> ||
411 (input_range<D<True>> && sized_range<D<True>>)))
413 operator[](detail::slice_bounds<detail::from_end_of_t<D<True>>,
414 detail::from_end_of_t<D<True>>> offs) &&
416 return Slice{}(detail::move(derived()), offs.from, offs.to);
420 template(
bool True =
true,
typename Slice = views::slice_fn)(
421 requires True AND input_range<D<True> &>)
423 operator[](detail::slice_bounds<range_difference_t<D<True>>, end_fn> offs) &
425 return Slice{}(derived(), offs.from, offs.to);
428 template(
bool True =
true,
typename Slice = views::slice_fn)(
429 requires True AND input_range<D<True>
const &>)
431 operator[](detail::slice_bounds<range_difference_t<D<True>>, end_fn> offs)
const &
433 return Slice{}(derived(), offs.from, offs.to);
436 template(
bool True =
true,
typename Slice = views::slice_fn)(
437 requires True AND input_range<D<True>>)
439 operator[](detail::slice_bounds<range_difference_t<D<True>>, end_fn> offs) &&
441 return Slice{}(detail::move(derived()), offs.from, offs.to);
445 template(
bool True =
true,
typename Slice = views::slice_fn)(
447 (forward_range<D<True> &> ||
448 (input_range<D<True> &> && sized_range<D<True> &>)))
450 operator[](detail::slice_bounds<detail::from_end_of_t<D<True>>, end_fn> offs) &
452 return Slice{}(derived(), offs.from, offs.to);
455 template(
bool True =
true,
typename Slice = views::slice_fn)(
457 (forward_range<D<True>
const &> ||
458 (input_range<D<True>
const &> && sized_range<D<True>
const &>)))
461 detail::slice_bounds<detail::from_end_of_t<D<True>>, end_fn> offs)
const &
463 return Slice{}(derived(), offs.from, offs.to);
466 template(
bool True =
true,
typename Slice = views::slice_fn)(
468 (forward_range<D<True>> ||
469 (input_range<D<True>> && sized_range<D<True>>)))
471 operator[](detail::slice_bounds<detail::from_end_of_t<D<True>>, end_fn> offs) &&
473 return Slice{}(detail::move(derived()), offs.from, offs.to);
476#ifndef RANGES_V3_DISABLE_IO
478 template<
bool True = true>
479 friend auto operator<<(std::ostream & sout, Derived
const & rng)
480 -> CPP_broken_friend_ret(std::ostream &)(
481 requires True && input_range<D<True>
const>)
483 return detail::print_rng_(sout, rng);
486 template<
bool True = true>
487 friend auto operator<<(std::ostream & sout, Derived & rng)
488 -> CPP_broken_friend_ret(std::ostream &)(
489 requires True && (!range<D<True>
const>) && input_range<D<True>>)
491 return detail::print_rng_(sout, rng);
494 template<
bool True = true>
495 friend auto operator<<(std::ostream & sout, Derived && rng)
496 -> CPP_broken_friend_ret(std::ostream &)(
497 requires True && (!range<D<True>
const>) && input_range<D<True>>)
499 return detail::print_rng_(sout, rng);