Standard library header <ranges>
This header is part of the ranges library.
Namespace aliases
namespace std {
namespace view = ranges::view;
}
|
The namespace alias std::view is provided as a shorthand for std::ranges::view.
Concepts |
|
Range concepts |
|
Defined in namespace std::ranges |
|
|---|---|
specifies that a type is a range, that is, it provides a begin iterator and an end sentinel (concept) |
|
| specifies that a range knows its size in constant time (concept) |
|
| specifies that a range is a view, that is, it has constant time copy/move/assignment (concept) |
|
specifies a range whose iterator type satisfies InputIterator (concept) |
|
specifies a range whose iterator type satisfies OutputIterator (concept) |
|
specifies a range whose iterator type satisfies ForwardIterator (concept) |
|
specifies a range whose iterator type satisfies BidirectionalIterator (concept) |
|
specifies a range whose iterator type satisfies RandomAccessIterator (concept) |
|
specifies a range whose iterator type satisfies ContiguousIterator (concept) |
|
| specifies that a range has identical iterator and sentinel types (concept) |
|
specifies the requirements for a Range to be safely convertible to a View (concept) |
|
Classes |
|
Range primitives |
|
Defined in namespace std::ranges |
|
| obtains the iterator and sentinel types of a range (alias template) |
|
Views |
|
Defined in namespace std::ranges |
|
helper class template for defining Views, using the curiously recurring template pattern (class template) |
|
combines an iterator-sentinel pair into a View (class template) |
|
Dangling iterator handling |
|
Defined in namespace std::ranges |
|
a placeholder type indicating that an iterator or a subrange should not be returned since it would be dangling (class) |
|
obtains iterator type or subrange type of a Range which also models __ForwardingRange (alias template) |
|
Factories |
|
Defined in namespace std::ranges |
|
an empty View with no elements (class template) (variable template) |
|
a View that contains a single element of a specified value (class template) (customization point object) |
|
a View consisting of a sequence generated by repeatedly incrementing an initial value (class template) (customization point object) |
|
| creates a subrange from an iterator and a count (customization point object) |
|
Adaptors |
|
Defined in namespace std::ranges |
|
a View that includes all elements of a Range (alias template) (range adaptor object) |
|
a View of the elements of some other Range (class template) |
|
a View that consists of the elements of a Range that satisfies a predicate (class template) (range adaptor object) |
|
a View of a sequence that applies a transformation function to each element (class template) (range adaptor object) |
|
a View consisting of the first N elements of another View (class template) (range adaptor object) |
|
a View consisting of the sequence obtained from flattening a View of Ranges (class template) (range adaptor object) |
|
a View over the subranges obtained from splitting another View using a delimiter (class template) (range adaptor object) |
|
converts a View into a CommonRange (class template) (range adaptor object) |
|
a View that iterates over the elements of another bidirectional view in reverse order (class template) (range adaptor object) |
|
Customization point objects |
|
Range access |
|
Defined in namespace std::ranges |
|
| returns an iterator to the beginning of a range (customization point object) |
|
| returns an iterator to the end of a range (customization point object) |
|
| returns a reverse iterator to a range (customization point object) |
|
| returns a reverse end iterator to a range (customization point object) |
|
| obtains the size of a range whose size can be calculated in constant time (customization point object) |
|
| checks whether a range is empty (customization point object) |
|
| obtains a pointer to the beginning of a contiguous range (customization point object) |
|
Synopsis
#include <initializer_list>
#include <iterator>
namespace std::ranges {
inline namespace /* unspecified */ {
// range access
inline constexpr /* unspecified */ begin = /* unspecified */;
inline constexpr /* unspecified */ end = /* unspecified */;
inline constexpr /* unspecified */ cbegin = /* unspecified */;
inline constexpr /* unspecified */ cend = /* unspecified */;
inline constexpr /* unspecified */ rbegin = /* unspecified */;
inline constexpr /* unspecified */ rend = /* unspecified */;
inline constexpr /* unspecified */ crbegin = /* unspecified */;
inline constexpr /* unspecified */ crend = /* unspecified */;
inline constexpr /* unspecified */ size = /* unspecified */;
inline constexpr /* unspecified */ empty = /* unspecified */;
inline constexpr /* unspecified */ data = /* unspecified */;
inline constexpr /* unspecified */ cdata = /* unspecified */;
}
// ranges
template<class T>
using iterator_t = decltype(ranges::begin(declval<T&>()));
template<class T>
using sentinel_t = decltype(ranges::end(declval<T&>()));
template<class T>
concept Range = /* see definition */;
// sized ranges
template<class>
inline constexpr bool disable_sized_range = false;
template<class T>
concept SizedRange = /* see definition */;
// views
template<class T>
inline constexpr bool enable_view = /* see definition */;
struct view_base { };
template<class T>
concept View = /* see definition */;
// other range refinements
template<class R, class T>
concept OutputRange = /* see definition */;
template<class T>
concept InputRange = /* see definition */;
template<class T>
concept ForwardRange = /* see definition */;
template<class T>
concept BidirectionalRange = /* see definition */;
template<class T>
concept RandomAccessRange = /* see definition */;
template<class T>
concept ContiguousRange = /* see definition */;
template<class T>
concept CommonRange = /* see definition */;
template<class T>
concept ViewableRange = /* see definition */;
// class template view_interface
template<class D>
requires is_class_v<D> && Same<D, remove_cv_t<D>>
class view_interface;
// sub-ranges
enum class subrange_kind : bool { unsized, sized };
template<Iterator I, Sentinel<I> S = I, subrange_kind K = /* see definition */>
requires (K == subrange_kind::sized || !SizedSentinel<S, I>)
class subrange;
// dangling iterator handling
struct dangling;
template<Range R>
using safe_iterator_t = conditional_t<__ForwardingRange<R>, iterator_t<R>, dangling>;
template<Range R>
using safe_subrange_t =
conditional_t<__ForwardingRange<R>, subrange<iterator_t<R>>, dangling>;
// empty view
template<class T>
requires is_object_v<T>
class empty_view;
namespace view {
template<class T>
inline constexpr empty_view<T> empty{};
}
// single view
template<CopyConstructible T>
requires is_object_v<T>
class single_view;
namespace view { inline constexpr /* unspecified */ single = /* unspecified */; }
// iota view
template<WeaklyIncrementable W, Semiregular Bound = unreachable_sentinel_t>
requires __WeaklyEqualityComparableWith<W, Bound>
class iota_view;
namespace view { inline constexpr /* unspecified */ iota = /* unspecified */; }
// all view
namespace view { inline constexpr /* unspecified */ all = /* unspecified */; }
template<ViewableRange R>
using all_view = decltype(view::all(declval<R>()));
template<Range R>
requires is_object_v<R>
class ref_view;
// filter view
template<InputRange V, IndirectUnaryPredicate<iterator_t<V>> Pred>
requires View<V> && is_object_v<Pred>
class filter_view;
namespace view { inline constexpr /* unspecified */ filter = /* unspecified */; }
// transform view
template<InputRange V, CopyConstructible F>
requires View<V> && is_object_v<F> &&
RegularInvocable<F&, iter_reference_t<iterator_t<V>>>
class transform_view;
namespace view { inline constexpr /* unspecified */ transform = /* unspecified */; }
// take view
template<View> class take_view;
namespace view { inline constexpr /* unspecified */ take = /* unspecified */; }
// join view
template<InputRange V>
requires View<V> && InputRange<iter_reference_t<iterator_t<V>>> &&
(is_reference_v<iter_reference_t<iterator_t<V>>> ||
View<iter_value_t<iterator_t<V>>>)
class join_view;
namespace view { inline constexpr /* unspecified */ join = /* unspecified */; }
// split view
template<class R>
concept __TinyRange = /* see definition */; // exposition only
template<InputRange V, ForwardRange Pattern>
requires View<V> && View<Pattern> &&
IndirectlyComparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to> &&
(ForwardRange<V> || __TinyRange<Pattern>)
class split_view;
namespace view { inline constexpr /* unspecified */ split = /* unspecified */; }
// counted view
namespace view { inline constexpr /* unspecified */ counted = /* unspecified */; }
// common view
template<View V>
requires (!CommonRange<V>)
class common_view;
namespace view { inline constexpr /* unspecified */ common = /* unspecified */; }
// reverse view
template<View V>
requires BidirectionalRange<V>
class reverse_view;
namespace view { inline constexpr /* unspecified */ reverse = /* unspecified */; }
}
namespace std {
namespace view = ranges::view;
template<class I, class S, ranges::subrange_kind K>
struct tuple_size<ranges::subrange<I, S, K>>
: integral_constant<size_t, 2> {};
template<class I, class S, ranges::subrange_kind K>
struct tuple_element<0, ranges::subrange<I, S, K>> {
using type = I;
};
template<class I, class S, ranges::subrange_kind K>
struct tuple_element<1, ranges::subrange<I, S, K>> {
using type = S;
};
}Concept Range
namespace std::ranges {
template<class T>
concept __RangeImpl = // exposition only
requires(T&& t) {
ranges::begin(std::forward<T>(t));// sometimes equality-preserving (see definition)
ranges::end(std::forward<T>(t));
};
template<class T>
concept Range = __RangeImpl<T&>;
template<class T>
concept __ForwardingRange = // exposition only
Range<T> && __RangeImpl<T>;
}Concept SizedRange
namespace std::ranges {
template<class T>
concept SizedRange =
Range<T> &&
!disable_sized_range<remove_cvref_t<T>> &&
requires(T& t) { ranges::size(t); };
}Concept View
namespace std::ranges {
template<class T>
inline constexpr bool enable_view = /* see definition */;
template<class T>
concept View =
Range<T> && Semiregular<T> && enable_view<T>;
}Concept OutputRange
namespace std::ranges {
template<class R, class T>
concept OutputRange =
Range<R> && OutputIterator<iterator_t<R>, T>;
}Concept InputRange
namespace std::ranges {
template<class T>
concept InputRange =
Range<T> && InputIterator<iterator_t<T>>;
}Concept ForwardRange
namespace std::ranges {
template<class T>
concept ForwardRange =
InputRange<T> && ForwardIterator<iterator_t<T>>;
}Concept BidirectionalRange
namespace std::ranges {
template<class T>
concept BidirectionalRange =
ForwardRange<T> && BidirectionalIterator<iterator_t<T>>;
}Concept RandomAccessRange
namespace std::ranges {
template<class T>
concept RandomAccessRange =
BidirectionalRange<T> && RandomAccessIterator<iterator_t<T>>;
}Concept ContiguousRange
namespace std::ranges {
template<class T>
concept ContiguousRange =
RandomAccessRange<T> && ContiguousIterator<iterator_t<T>> &&
requires(T& t) {
{ ranges::data(t) } -> Same<add_pointer_t<iter_reference_t<iterator_t<T>>>>;
};
}Concept CommonRange
namespace std::ranges {
template<class T>
concept CommonRange =
Range<T> && Same<iterator_t<T>, sentinel_t<T>>;
}Concept ViewableRange
namespace std::ranges {
template<class T>
concept ViewableRange =
Range<T> && (__ForwardingRange<T> || View<decay_t<T>>);
}Helper concepts
namespace std::ranges { // unspecified, for name lookup only
template<class R>
concept __SimpleView = // exposition only
View<R> && Range<const R> &&
Same<iterator_t<R>, iterator_t<const R>> &&
Same<sentinel_t<R>, sentinel_t<const R>>;
template<InputIterator I>
concept __HasArrow = // exposition only
is_pointer_v<I> || requires(I i) { i.operator->(); };
template<class T, class U>
concept __NotSameAs = // exposition only
!Same<remove_cvref_t<T>, remove_cvref_t<U>>;
template<class I>
concept _Decrementable = // exposition only
Incrementable<I> && requires(I i) {
{ --i } -> Same<I&>;
{ i-- } -> Same<I>;
};
template<class I>
concept _Advanceable = // exposition only
_Decrementable<I> && StrictTotallyOrdered<I> &&
requires(I i, const I j, const iter_difference_t<I> n) {
{ i += n } -> Same<I&>;
{ i -= n } -> Same<I&>;
{ j + n } -> Same<I>;
{ n + j } -> Same<I>;
{ j - n } -> Same<I>;
{ j - j } -> Same<iter_difference_t<I>>;
};
}Note: These names are only for exposition, they are not part of the interface.
Class template std::ranges::view_interface
namespace std::ranges {
template<class D>
requires is_class_v<D> && Same<D, remove_cv_t<D>>
class view_interface : public view_base {
private:
constexpr D& derived() noexcept { // exposition only
return static_cast<D&>(*this);
}
constexpr const D& derived() const noexcept { // exposition only
return static_cast<const D&>(*this);
}
public:
constexpr bool empty() requires ForwardRange<D> {
return ranges::begin(derived()) == ranges::end(derived());
}
constexpr bool empty() const requires ForwardRange<const D> {
return ranges::begin(derived()) == ranges::end(derived());
}
constexpr explicit operator bool()
requires requires { ranges::empty(derived()); } {
return !ranges::empty(derived());
}
constexpr explicit operator bool() const
requires requires { ranges::empty(derived()); } {
return !ranges::empty(derived());
}
constexpr auto data() requires ContiguousIterator<iterator_t<D>> {
return ranges::empty(derived()) ? nullptr : addressof(*ranges::begin(derived()));
}
constexpr auto data() const
requires Range<const D> && ContiguousIterator<iterator_t<const D>> {
return ranges::empty(derived()) ? nullptr : addressof(*ranges::begin(derived()));
}
constexpr auto size() requires ForwardRange<D> &&
SizedSentinel<sentinel_t<D>, iterator_t<D>> {
return ranges::end(derived()) - ranges::begin(derived());
}
constexpr auto size() const requires ForwardRange<const D> &&
SizedSentinel<sentinel_t<const D>, iterator_t<const D>> {
return ranges::end(derived()) - ranges::begin(derived());
}
constexpr decltype(auto) front() requires ForwardRange<D>;
constexpr decltype(auto) front() const requires ForwardRange<const D>;
constexpr decltype(auto) back() requires BidirectionalRange<D> && CommonRange<D>;
constexpr decltype(auto) back() const
requires BidirectionalRange<const D> && CommonRange<const D>;
template<RandomAccessRange R = D>
constexpr decltype(auto) operator[](iter_difference_t<iterator_t<R>> n) {
return ranges::begin(derived())[n];
}
template<RandomAccessRange R = const D>
constexpr decltype(auto) operator[](iter_difference_t<iterator_t<R>> n) const {
return ranges::begin(derived())[n];
}
};
}Class template std::ranges::subrange
namespace std::ranges {
template<class T>
concept __PairLike = // exposition only
!is_reference_v<T> && requires(T t) {
typename tuple_size<T>::type; // ensures tuple_size<T> is complete
requires DerivedFrom<tuple_size<T>, integral_constant<size_t, 2>>;
typename tuple_element_t<0, remove_const_t<T>>;
typename tuple_element_t<1, remove_const_t<T>>;
{ get<0>(t) } -> const tuple_element_t<0, T>&;
{ get<1>(t) } -> const tuple_element_t<1, T>&;
};
template<class T, class U, class V>
concept __PairLikeConvertibleTo = // exposition only
!Range<T> && __PairLike<remove_reference_t<T>> &&
requires(T&& t) {
{ get<0>(std::forward<T>(t)) } -> ConvertibleTo<U>;
{ get<1>(std::forward<T>(t)) } -> ConvertibleTo<V>;
};
template<class T, class U, class V>
concept __PairLikeConvertibleFrom = // exposition only
!Range<T> && __PairLike<T> && Constructible<T, U, V>;
template<class T>
concept __IteratorSentinelPair = // exposition only
!Range<T> && __PairLike<T> &&
Sentinel<tuple_element_t<1, T>, tuple_element_t<0, T>>;
template<Iterator I, Sentinel<I> S = I, subrange_kind K =
SizedSentinel<S, I> ? subrange_kind::sized : subrange_kind::unsized>
requires (K == subrange_kind::sized || !SizedSentinel<S, I>)
class subrange : public view_interface<subrange<I, S, K>> {
private:
static constexpr bool StoreSize = // exposition only
K == subrange_kind::sized && !SizedSentinel<S, I>;
I begin_ = I(); // exposition only
S end_ = S(); // exposition only
iter_difference_t<I> size_ = 0; // exposition only; present only
// when StoreSize is true
public:
subrange() = default;
constexpr subrange(I i, S s) requires (!StoreSize);
constexpr subrange(I i, S s, iter_difference_t<I> n)
requires (K == subrange_kind::sized);
template<__NotSameAs<subrange> R>
requires __ForwardingRange<R> &&
ConvertibleTo<iterator_t<R>, I> && ConvertibleTo<sentinel_t<R>, S>
constexpr subrange(R&& r) requires (!StoreSize || SizedRange<R>);
template<__ForwardingRange R>
requires ConvertibleTo<iterator_t<R>, I> && ConvertibleTo<sentinel_t<R>, S>
constexpr subrange(R&& r, iter_difference_t<I> n)
requires (K == subrange_kind::sized)
: subrange{ranges::begin(r), ranges::end(r), n}
{}
template<__NotSameAs<subrange> PairLike>
requires __PairLikeConvertibleTo<PairLike, I, S>
constexpr subrange(PairLike&& r) requires (!StoreSize)
: subrange{std::get<0>(std::forward<PairLike>(r)),
std::get<1>(std::forward<PairLike>(r))}
{}
template<__PairLikeConvertibleTo<I, S> PairLike>
constexpr subrange(PairLike&& r, iter_difference_t<I> n)
requires (K == subrange_kind::sized)
: subrange{std::get<0>(std::forward<PairLike>(r)),
std::get<1>(std::forward<PairLike>(r)), n}
{}
template<__NotSameAs<subrange> PairLike>
requires __PairLikeConvertibleFrom<PairLike, const I&, const S&>
constexpr operator PairLike() const;
constexpr I begin() const;
constexpr S end() const;
constexpr bool empty() const;
constexpr iter_difference_t<I> size() const
requires (K == subrange_kind::sized);
[[nodiscard]] constexpr subrange next(iter_difference_t<I> n = 1) const;
[[nodiscard]] constexpr subrange prev(iter_difference_t<I> n = 1) const
requires BidirectionalIterator<I>;
constexpr subrange& advance(iter_difference_t<I> n);
friend constexpr I begin(subrange&& r) { return r.begin(); }
friend constexpr S end(subrange&& r) { return r.end(); }
};
template<Iterator I, Sentinel<I> S>
subrange(I, S, iter_difference_t<I>) -> subrange<I, S, subrange_kind::sized>;
template<__IteratorSentinelPair P>
subrange(P) -> subrange<tuple_element_t<0, P>, tuple_element_t<1, P>>;
template<__IteratorSentinelPair P>
subrange(P, iter_difference_t<tuple_element_t<0, P>>) ->
subrange<tuple_element_t<0, P>, tuple_element_t<1, P>, subrange_kind::sized>;
template<__ForwardingRange R>
subrange(R&&) ->
subrange<iterator_t<R>, sentinel_t<R>,
(SizedRange<R> || SizedSentinel<sentinel_t<R>, iterator_t<R>>)
? subrange_kind::sized : subrange_kind::unsized>;
template<__ForwardingRange R>
subrange(R&&, iter_difference_t<iterator_t<R>>) ->
subrange<iterator_t<R>, sentinel_t<R>, subrange_kind::sized>;
template<size_t N, class I, class S, subrange_kind K>
requires (N < 2)
constexpr auto get(const subrange<I, S, K>& r);
}
namespace std {
using ranges::get;
}Class std::ranges::dangling
namespace std::ranges {
struct dangling {
constexpr dangling() noexcept = default;
template<class... Args>
constexpr dangling(Args&&...) noexcept { }
};
}Class template std::ranges::empty_view
namespace std::ranges {
template<class T>
requires is_object_v<T>
class empty_view : public view_interface<empty_view<T>> {
public:
static constexpr T* begin() noexcept { return nullptr; }
static constexpr T* end() noexcept { return nullptr; }
static constexpr T* data() noexcept { return nullptr; }
static constexpr ptrdiff_t size() noexcept { return 0; }
static constexpr bool empty() noexcept { return true; }
friend constexpr T* begin(empty_view) noexcept { return nullptr; }
friend constexpr T* end(empty_view) noexcept { return nullptr; }
};
}Class template std::ranges::empty_view
namespace std::ranges {
template<CopyConstructible T>
requires is_object_v<T>
class single_view : public view_interface<single_view<T>> {
private:
semiregular<T> value_; // exposition only
public:
single_view() = default;
constexpr explicit single_view(const T& t);
constexpr explicit single_view(T&& t);
template<class... Args>
requires Constructible<T, Args...>
constexpr single_view(in_place_t, Args&&... args);
constexpr T* begin() noexcept;
constexpr const T* begin() const noexcept;
constexpr T* end() noexcept;
constexpr const T* end() const noexcept;
static constexpr ptrdiff_t size() noexcept;
constexpr T* data() noexcept;
constexpr const T* data() const noexcept;
};
}Class template std::ranges::iota_view
namespace std::ranges {
template<class I>
concept _Decrementable = // exposition only
/* see definition */;
template<class I>
concept _Advanceable = // exposition only
/* see definition */;
template<WeaklyIncrementable W, Semiregular Bound = unreachable_sentinel_t>
requires __WeaklyEqualityComparableWith<W, Bound>
class iota_view : public view_interface<iota_view<W, Bound>> {
private:
// class iota_view::iterator
struct iterator; // exposition only
// class iota_view::sentinel
struct sentinel; // exposition only
W value_ = W(); // exposition only
Bound bound_ = Bound(); // exposition only
public:
iota_view() = default;
constexpr explicit iota_view(W value);
constexpr iota_view(type_identity_t<W> value,
type_identity_t<Bound> bound);
constexpr iterator begin() const;
constexpr sentinel end() const;
constexpr iterator end() const requires Same<W, Bound>;
constexpr auto size() const
requires (Same<W, Bound> && _Advanceable<W>) ||
(Integral<W> && Integral<Bound>) ||
SizedSentinel<Bound, W>
{ return bound_ - value_; }
};
template<class W, class Bound>
requires (!Integral<W> || !Integral<Bound> || is_signed_v<W> == is_signed_v<Bound>)
iota_view(W, Bound) -> iota_view<W, Bound>;
}Class std::ranges::iota_view::iterator
namespace std::ranges {
template<class W, class Bound>
struct iota_view<W, Bound>::iterator {
private:
W value_ = W(); // exposition only
public:
using iterator_category = /* see definition */;
using value_type = W;
using difference_type = iter_difference_t<W>;
iterator() = default;
constexpr explicit iterator(W value);
constexpr W operator*() const noexcept(is_nothrow_copy_constructible_v<W>);
constexpr iterator& operator++();
constexpr void operator++(int);
constexpr iterator operator++(int) requires Incrementable<W>;
constexpr iterator& operator--() requires _Decrementable<W>;
constexpr iterator operator--(int) requires _Decrementable<W>;
constexpr iterator& operator+=(difference_type n)
requires _Advanceable<W>;
constexpr iterator& operator-=(difference_type n)
requires _Advanceable<W>;
constexpr W operator[](difference_type n) const
requires _Advanceable<W>;
friend constexpr bool operator==(const iterator& x, const iterator& y)
requires EqualityComparable<W>;
friend constexpr bool operator!=(const iterator& x, const iterator& y)
requires EqualityComparable<W>;
friend constexpr bool operator<(const iterator& x, const iterator& y)
requires StrictTotallyOrdered<W>;
friend constexpr bool operator>(const iterator& x, const iterator& y)
requires StrictTotallyOrdered<W>;
friend constexpr bool operator<=(const iterator& x, const iterator& y)
requires StrictTotallyOrdered<W>;
friend constexpr bool operator>=(const iterator& x, const iterator& y)
requires StrictTotallyOrdered<W>;
friend constexpr iterator operator+(iterator i, difference_type n)
requires _Advanceable<W>;
friend constexpr iterator operator+(difference_type n, iterator i)
requires _Advanceable<W>;
friend constexpr iterator operator-(iterator i, difference_type n)
requires _Advanceable<W>;
friend constexpr difference_type operator-(const iterator& x, const iterator& y)
requires _Advanceable<W>;
};
}Class std::ranges::iota_view::sentinel
namespace std::ranges {
template<class W, class Bound>
struct iota_view<W, Bound>::sentinel {
private:
Bound bound_ = Bound(); // exposition only
public:
sentinel() = default;
constexpr explicit sentinel(Bound bound);
friend constexpr bool operator==(const iterator& x, const sentinel& y);
friend constexpr bool operator==(const sentinel& x, const iterator& y);
friend constexpr bool operator!=(const iterator& x, const sentinel& y);
friend constexpr bool operator!=(const sentinel& x, const iterator& y);
};
}Class template std::ranges::ref_view
namespace std::ranges {
template<Range R>
requires is_object_v<R>
class ref_view : public view_interface<ref_view<R>> {
private:
R* r_ = nullptr; // exposition only
public:
constexpr ref_view() noexcept = default;
template<__NotSameAs<ref_view> T>
requires /* see definition */
constexpr ref_view(T&& t);
constexpr R& base() const { return *r_; }
constexpr iterator_t<R> begin() const { return ranges::begin(*r_); }
constexpr sentinel_t<R> end() const { return ranges::end(*r_); }
constexpr bool empty() const
requires requires { ranges::empty(*r_); }
{ return ranges::empty(*r_); }
constexpr auto size() const requires SizedRange<R>
{ return ranges::size(*r_); }
constexpr auto data() const requires ContiguousRange<R>
{ return ranges::data(*r_); }
friend constexpr iterator_t<R> begin(ref_view r)
{ return r.begin(); }
friend constexpr sentinel_t<R> end(ref_view r)
{ return r.end(); }
};
template<class R>
ref_view(R&) -> ref_view<R>;
}Class template std::ranges::filter_view
namespace std::ranges {
template<InputRange V, IndirectUnaryPredicate<iterator_t<V>> Pred>
requires View<V> && is_object_v<Pred>
class filter_view : public view_interface<filter_view<V, Pred>> {
private:
V base_ = V(); // exposition only
semiregular<Pred> pred_; // exposition only
// class filter_view::iterator
class iterator; // exposition only
// class filter_view::sentinel
class sentinel; // exposition only
public:
filter_view() = default;
constexpr filter_view(V base, Pred pred);
template<InputRange R>
requires ViewableRange<R> && Constructible<V, all_view<R>>
constexpr filter_view(R&& r, Pred pred);
constexpr V base() const;
constexpr iterator begin();
constexpr auto end() {
if constexpr (CommonRange<V>)
return iterator{*this, ranges::end(base_)};
else
return sentinel{*this};
}
};
template<class R, class Pred>
filter_view(R&&, Pred) -> filter_view<all_view<R>, Pred>;
}Class std::ranges::filter_view::iterator
namespace std::ranges {
template<class V, class Pred>
class filter_view<V, Pred>::iterator {
private:
iterator_t<V> current_ = iterator_t<V>(); // exposition only
filter_view* parent_ = nullptr; // exposition only
public:
using iterator_concept = /* see definition */;
using iterator_category = /* see definition */;
using value_type = iter_value_t<iterator_t<V>>;
using difference_type = iter_difference_t<iterator_t<V>>;
iterator() = default;
constexpr iterator(filter_view& parent, iterator_t<V> current);
constexpr iterator_t<V> base() const;
constexpr iter_reference_t<iterator_t<V>> operator*() const;
constexpr iterator_t<V> operator->() const
requires has-arrow<iterator_t<V>>;
constexpr iterator& operator++();
constexpr void operator++(int);
constexpr iterator operator++(int) requires ForwardRange<V>;
constexpr iterator& operator--() requires BidirectionalRange<V>;
constexpr iterator operator--(int) requires BidirectionalRange<V>;
friend constexpr bool operator==(const iterator& x, const iterator& y)
requires EqualityComparable<iterator_t<V>>;
friend constexpr bool operator!=(const iterator& x, const iterator& y)
requires EqualityComparable<iterator_t<V>>;
friend constexpr iter_rvalue_reference_t<iterator_t<V>> iter_move(const iterator& i)
noexcept(noexcept(ranges::iter_move(i.current_)));
friend constexpr void iter_swap(const iterator& x, const iterator& y)
noexcept(noexcept(ranges::iter_swap(x.current_, y.current_)))
requires IndirectlySwappable<iterator_t<V>>;
};
}Class std::ranges::filter_view::sentinel
namespace std::ranges {
template<class V, class Pred>
class filter_view<V, Pred>::sentinel {
private:
sentinel_t<V> end_ = sentinel_t<V>(); // exposition only
public:
sentinel() = default;
constexpr explicit sentinel(filter_view& parent);
constexpr sentinel_t<V> base() const;
friend constexpr bool operator==(const iterator& x, const sentinel& y);
friend constexpr bool operator==(const sentinel& x, const iterator& y);
friend constexpr bool operator!=(const iterator& x, const sentinel& y);
friend constexpr bool operator!=(const sentinel& x, const iterator& y);
};
}Class template std::ranges::transform_view
namespace std::ranges {
template<InputRange V, CopyConstructible F>
requires View<V> && is_object_v<F> &&
RegularInvocable<F&, iter_reference_t<iterator_t<V>>>
class transform_view : public view_interface<transform_view<V, F>> {
private:
// class template transform_view::iterator
template<bool> struct iterator; // exposition only
// class template transform_view::sentinel
template<bool> struct sentinel; // exposition only
V base_ = V(); // exposition only
semiregular<F> fun_; // exposition only
public:
transform_view() = default;
constexpr transform_view(V base, F fun);
template<InputRange R>
requires ViewableRange<R> && Constructible<V, all_view<R>>
constexpr transform_view(R&& r, F fun);
constexpr V base() const;
constexpr iterator<false> begin();
constexpr iterator<true> begin() const
requires Range<const V> &&
RegularInvocable<const F&, iter_reference_t<iterator_t<const V>>>;
constexpr sentinel<false> end();
constexpr iterator<false> end() requires CommonRange<V>;
constexpr sentinel<true> end() const
requires Range<const V> &&
RegularInvocable<const F&, iter_reference_t<iterator_t<const V>>>;
constexpr iterator<true> end() const
requires CommonRange<const V> &&
RegularInvocable<const F&, iter_reference_t<iterator_t<const V>>>;
constexpr auto size() requires SizedRange<V> { return ranges::size(base_); }
constexpr auto size() const requires SizedRange<const V>
{ return ranges::size(base_); }
};
template<class R, class F>
transform_view(R&&, F) -> transform_view<all_view<R>, F>;
}Class template std::ranges::transform_view::iterator
namespace std::ranges {
template<class V, class F>
template<bool Const>
class transform_view<V, F>::iterator {
private:
using Parent = // exposition only
conditional_t<Const, const transform_view, transform_view>;
using Base = // exposition only
conditional_t<Const, const V, V>;
iterator_t<Base> current_ = // exposition only
iterator_t<Base>();
Parent* parent_ = nullptr; // exposition only
public:
using iterator_concept = /* see definition */;
using iterator_category = /* see definition */;
using value_type =
remove_cvref_t<invoke_result_t<F&, iter_reference_t<iterator_t<Base>>>>;
using difference_type = iter_difference_t<iterator_t<Base>>;
iterator() = default;
constexpr iterator(Parent& parent, iterator_t<Base> current);
constexpr iterator(iterator<!Const> i)
requires Const && ConvertibleTo<iterator_t<V>, iterator_t<Base>>;
constexpr iterator_t<Base> base() const;
constexpr decltype(auto) operator*() const
{ return invoke(*parent_->fun_, *current_); }
constexpr iterator& operator++();
constexpr void operator++(int);
constexpr iterator operator++(int) requires ForwardRange<Base>;
constexpr iterator& operator--() requires BidirectionalRange<Base>;
constexpr iterator operator--(int) requires BidirectionalRange<Base>;
constexpr iterator& operator+=(difference_type n)
requires RandomAccessRange<Base>;
constexpr iterator& operator-=(difference_type n)
requires RandomAccessRange<Base>;
constexpr decltype(auto) operator[](difference_type n) const
requires RandomAccessRange<Base>
{ return invoke(*parent_->fun_, current_[n]); }
friend constexpr bool operator==(const iterator& x, const iterator& y)
requires EqualityComparable<iterator_t<Base>>;
friend constexpr bool operator!=(const iterator& x, const iterator& y)
requires EqualityComparable<iterator_t<Base>>;
friend constexpr bool operator<(const iterator& x, const iterator& y)
requires RandomAccessRange<Base>;
friend constexpr bool operator>(const iterator& x, const iterator& y)
requires RandomAccessRange<Base>;
friend constexpr bool operator<=(const iterator& x, const iterator& y)
requires RandomAccessRange<Base>;
friend constexpr bool operator>=(const iterator& x, const iterator& y)
requires RandomAccessRange<Base>;
friend constexpr iterator operator+(iterator i, difference_type n)
requires RandomAccessRange<Base>;
friend constexpr iterator operator+(difference_type n, iterator i)
requires RandomAccessRange<Base>;
friend constexpr iterator operator-(iterator i, difference_type n)
requires RandomAccessRange<Base>;
friend constexpr difference_type operator-(const iterator& x, const iterator& y)
requires RandomAccessRange<Base>;
friend constexpr decltype(auto) iter_move(const iterator& i)
noexcept(noexcept(invoke(*i.parent_->fun_, *i.current_)))
{
if constexpr (is_lvalue_reference_v<decltype(*i)>)
return std::move(*i);
else
return *i;
}
friend constexpr void iter_swap(const iterator& x, const iterator& y)
noexcept(noexcept(ranges::iter_swap(x.current_, y.current_)))
requires IndirectlySwappable<iterator_t<Base>>;
};
}Class template std::ranges::transform_view::sentinel
namespace std::ranges {
template<class V, class F>
template<bool Const>
class transform_view<V, F>::sentinel {
private:
using Parent = // exposition only
conditional_t<Const, const transform_view, transform_view>;
using Base = conditional_t<Const, const V, V>; // exposition only
sentinel_t<Base> end_ = sentinel_t<Base>(); // exposition only
public:
sentinel() = default;
constexpr explicit sentinel(sentinel_t<Base> end);
constexpr sentinel(sentinel<!Const> i)
requires Const && ConvertibleTo<sentinel_t<V>, sentinel_t<Base>>;
constexpr sentinel_t<Base> base() const;
friend constexpr bool operator==(const iterator<Const>& x, const sentinel& y);
friend constexpr bool operator==(const sentinel& x, const iterator<Const>& y);
friend constexpr bool operator!=(const iterator<Const>& x, const sentinel& y);
friend constexpr bool operator!=(const sentinel& x, const iterator<Const>& y);
friend constexpr iter_difference_t<iterator_t<Base>>
operator-(const iterator<Const>& x, const sentinel& y)
requires SizedSentinel<sentinel_t<Base>, iterator_t<Base>>;
friend constexpr iter_difference_t<iterator_t<Base>>
operator-(const sentinel& y, const iterator<Const>& x)
requires SizedSentinel<sentinel_t<Base>, iterator_t<Base>>;
};
}Class template std::ranges::take_view
namespace std::ranges {
template<View V>
class take_view : public view_interface<take_view<V>> {
private:
V base_ = V(); // exposition only
iter_difference_t<iterator_t<V>> count_ = 0; // exposition only
// class template take_view::sentinel
template<bool> struct sentinel; // exposition only
public:
take_view() = default;
constexpr take_view(V base, iter_difference_t<iterator_t<V>> count);
template<ViewableRange R>
requires Constructible<V, all_view<R>>
constexpr take_view(R&& r, iter_difference_t<iterator_t<V>> count);
constexpr V base() const;
constexpr auto begin() requires (!__SimpleView<V>) {
if constexpr (SizedRange<V>) {
if constexpr (RandomAccessRange<V>)
return ranges::begin(base_);
else
return counted_iterator{ranges::begin(base_), size()};
} else
return counted_iterator{ranges::begin(base_), count_};
}
constexpr auto begin() const requires Range<const V> {
if constexpr (SizedRange<const V>) {
if constexpr (RandomAccessRange<const V>)
return ranges::begin(base_);
else
return counted_iterator{ranges::begin(base_), size()};
} else
return counted_iterator{ranges::begin(base_), count_};
}
constexpr auto end() requires (!__SimpleView<V>) {
if constexpr (SizedRange<V>) {
if constexpr (RandomAccessRange<V>)
return ranges::begin(base_) + size();
else
return default_sentinel;
} else
return sentinel<false>{ranges::end(base_)};
}
constexpr auto end() const requires Range<const V> {
if constexpr (SizedRange<const V>) {
if constexpr (RandomAccessRange<const V>)
return ranges::begin(base_) + size();
else
return default_sentinel;
} else
return sentinel<true>{ranges::end(base_)};
}
constexpr auto size() requires SizedRange<V> {
auto n = ranges::size(base_);
return ranges::min(n, static_cast<decltype(n)>(count_));
}
constexpr auto size() const requires SizedRange<const V> {
auto n = ranges::size(base_);
return ranges::min(n, static_cast<decltype(n)>(count_));
}
};
template<Range R>
take_view(R&&, iter_difference_t<iterator_t<R>>)
-> take_view<all_view<R>>;
}Class template std::ranges::take_view::sentinel
namespace std::ranges {
template<class V>
template<bool Const>
class take_view<V>::sentinel {
private:
using Base = conditional_t<Const, const V, V>; // exposition only
using CI = counted_iterator<iterator_t<Base>>; // exposition only
sentinel_t<Base> end_ = sentinel_t<Base>(); // exposition only
public:
sentinel() = default;
constexpr explicit sentinel(sentinel_t<Base> end);
constexpr sentinel(sentinel<!Const> s)
requires Const && ConvertibleTo<sentinel_t<V>, sentinel_t<Base>>;
constexpr sentinel_t<Base> base() const;
friend constexpr bool operator==(const sentinel& x, const CI& y);
friend constexpr bool operator==(const CI& y, const sentinel& x);
friend constexpr bool operator!=(const sentinel& x, const CI& y);
friend constexpr bool operator!=(const CI& y, const sentinel& x);
};
}Class template std::ranges::join_view
namespace std::ranges {
template<InputRange V>
requires View<V> && InputRange<iter_reference_t<iterator_t<V>>> &&
(is_reference_v<iter_reference_t<iterator_t<V>>> ||
View<iter_value_t<iterator_t<V>>>)
class join_view : public view_interface<join_view<V>> {
private:
using InnerRng = // exposition only
iter_reference_t<iterator_t<V>>;
// class template join_view::iterator
template<bool Const>
struct iterator; // exposition only
// class template join_view::sentinel
template<bool Const>
struct sentinel; // exposition only
V base_ = V(); // exposition only
all_view<InnerRng> inner_ = // exposition only, present only when
all_view<InnerRng>(); // !is_reference_v<InnerRng>
public:
join_view() = default;
constexpr explicit join_view(V base);
template<InputRange R>
requires ViewableRange<R> && Constructible<V, all_view<R>>
constexpr explicit join_view(R&& r);
constexpr auto begin() {
return iterator<__SimpleView<V>>{*this, ranges::begin(base_)};
}
constexpr auto begin() const
requires InputRange<const V> &&
is_reference_v<iter_reference_t<iterator_t<const V>>> {
return iterator<true>{*this, ranges::begin(base_)};
}
constexpr auto end() {
if constexpr (ForwardRange<V> &&
is_reference_v<InnerRng> && ForwardRange<InnerRng> &&
CommonRange<V> && CommonRange<InnerRng>)
return iterator<__SimpleView<V>>{*this, ranges::end(base_)};
else
return sentinel<__SimpleView<V>>{*this};
}
constexpr auto end() const
requires InputRange<const V> &&
is_reference_v<iter_reference_t<iterator_t<const V>>> {
if constexpr (ForwardRange<const V> &&
is_reference_v<iter_reference_t<iterator_t<const V>>> &&
ForwardRange<iter_reference_t<iterator_t<const V>>> &&
CommonRange<const V> &&
CommonRange<iter_reference_t<iterator_t<const V>>>)
return iterator<true>{*this, ranges::end(base_)};
else
return sentinel<true>{*this};
}
};
template<class R>
explicit join_view(R&&) -> join_view<all_view<R>>;
}Class template std::ranges::join_view::iterator
namespace std::ranges {
template<class V>
template<bool Const>
struct join_view<V>::iterator {
private:
using Parent = // exposition only
conditional_t<Const, const join_view, join_view>;
using Base = conditional_t<Const, const V, V>; // exposition only
static constexpr bool ref_is_glvalue = // exposition only
is_reference_v<iter_reference_t<iterator_t<Base>>>;
iterator_t<Base> outer_ = iterator_t<Base>(); // exposition only
iterator_t<iter_reference_t<iterator_t<Base>>> inner_ = // exposition only
iterator_t<iter_reference_t<iterator_t<Base>>>();
Parent* parent_ = nullptr; // exposition only
constexpr void satisfy(); // exposition only
public:
using iterator_concept = /* see definition */;
using iterator_category = /* see definition */;
using value_type =
iter_value_t<iterator_t<iter_reference_t<iterator_t<Base>>>>;
using difference_type = /* see definition */;
iterator() = default;
constexpr iterator(Parent& parent, iterator_t<V> outer);
constexpr iterator(iterator<!Const> i)
requires Const &&
ConvertibleTo<iterator_t<V>, iterator_t<Base>> &&
ConvertibleTo<iterator_t<InnerRng>,
iterator_t<iter_reference_t<iterator_t<Base>>>>;
constexpr decltype(auto) operator*() const { return *inner_; }
constexpr iterator_t<Base> operator->() const
requires __HasArrow<iterator_t<Base>>;
constexpr iterator& operator++();
constexpr void operator++(int);
constexpr iterator operator++(int)
requires ref_is_glvalue && ForwardRange<Base> &&
ForwardRange<iter_reference_t<iterator_t<Base>>>;
constexpr iterator& operator--()
requires ref_is_glvalue && BidirectionalRange<Base> &&
BidirectionalRange<iter_reference_t<iterator_t<Base>>>;
constexpr iterator operator--(int)
requires ref_is_glvalue && BidirectionalRange<Base> &&
BidirectionalRange<iter_reference_t<iterator_t<Base>>>;
friend constexpr bool operator==(const iterator& x, const iterator& y)
requires ref_is_glvalue && EqualityComparable<iterator_t<Base>> &&
EqualityComparable<iterator_t<iter_reference_t<iterator_t<Base>>>>;
friend constexpr bool operator!=(const iterator& x, const iterator& y)
requires ref_is_glvalue && EqualityComparable<iterator_t<Base>> &&
EqualityComparable<iterator_t<iter_reference_t<iterator_t<Base>>>>;
friend constexpr decltype(auto) iter_move(const iterator& i)
noexcept(noexcept(ranges::iter_move(i.inner_))) {
return ranges::iter_move(i.inner_);
}
friend constexpr void iter_swap(const iterator& x, const iterator& y)
noexcept(noexcept(ranges::iter_swap(x.inner_, y.inner_)));
};
}Class template std::ranges::join_view::sentinel
namespace std::ranges {
template<class V>
template<bool Const>
struct join_view<V>::sentinel {
private:
using Parent = // exposition only
conditional_t<Const, const join_view, join_view>;
using Base = conditional_t<Const, const V, V>; // exposition only
sentinel_t<Base> end_ = sentinel_t<Base>(); // exposition only
public:
sentinel() = default;
constexpr explicit sentinel(Parent& parent);
constexpr sentinel(sentinel<!Const> s)
requires Const && ConvertibleTo<sentinel_t<V>, sentinel_t<Base>>;
friend constexpr bool operator==(const iterator<Const>& x, const sentinel& y);
friend constexpr bool operator==(const sentinel& x, const iterator<Const>& y);
friend constexpr bool operator!=(const iterator<Const>& x, const sentinel& y);
friend constexpr bool operator!=(const sentinel& x, const iterator<Const>& y);
};
}Class template std::ranges::split_view
namespace std::ranges {
template<auto> struct __require_constant; // exposition only
template<class R>
concept __TinyRange = // exposition only
SizedRange<R> &&
requires { typename __require_constant<remove_reference_t<R>::size()>; } &&
(remove_reference_t<R>::size() <= 1);
template<InputRange V, ForwardRange Pattern>
requires View<V> && View<Pattern> &&
IndirectlyComparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to> &&
(ForwardRange<V> || __TinyRange<Pattern>)
class split_view : public view_interface<split_view<V, Pattern>> {
private:
V base_ = V(); // exposition only
Pattern pattern_ = Pattern(); // exposition only
iterator_t<V> current_ = iterator_t<V>(); // exposition only, present only if
// !ForwardRange<V>
// class template split_view::outer_iterator
template<bool> struct outer_iterator; // exposition only
// class template split_view::inner_iterator
template<bool> struct inner_iterator; // exposition only
public:
split_view() = default;
constexpr split_view(V base, Pattern pattern);
template<InputRange R, ForwardRange P>
requires Constructible<V, all_view<R>> &&
Constructible<Pattern, all_view<P>>
constexpr split_view(R&& r, P&& p);
template<InputRange R>
requires Constructible<V, all_view<R>> &&
Constructible<Pattern, single_view<iter_value_t<iterator_t<R>>>>
constexpr split_view(R&& r, iter_value_t<iterator_t<R>> e);
constexpr auto begin() {
if constexpr (ForwardRange<V>)
return outer_iterator<__SimpleView<V>>{*this, ranges::begin(base_)};
else {
current_ = ranges::begin(base_);
return outer_iterator<false>{*this};
}
}
constexpr auto begin() const requires ForwardRange<V> && ForwardRange<const V> {
return outer_iterator<true>{*this, ranges::begin(base_)};
}
constexpr auto end() requires ForwardRange<V> && CommonRange<V> {
return outer_iterator<__SimpleView<V>>{*this, ranges::end(base_)};
}
constexpr auto end() const {
if constexpr (ForwardRange<V> && ForwardRange<const V> && CommonRange<const V>)
return outer_iterator<true>{*this, ranges::end(base_)};
else
return default_sentinel;
}
};
template<class R, class P>
split_view(R&&, P&&) -> split_view<all_view<R>, all_view<P>>;
template<InputRange R>
split_view(R&&, iter_value_t<iterator_t<R>>)
-> split_view<all_view<R>, single_view<iter_value_t<iterator_t<R>>>>;
}Class template std::ranges::split_view::outer_iterator
namespace std::ranges {
template<class V, class Pattern>
template<bool Const>
struct split_view<V, Pattern>::outer_iterator {
private:
using Parent = // exposition only
conditional_t<Const, const split_view, split_view>;
using Base = // exposition only
conditional_t<Const, const V, V>;
Parent* parent_ = nullptr; // exposition only
iterator_t<Base> current_ = // exposition only, present only
iterator_t<Base>(); // if V models ForwardRange
public:
using iterator_concept =
conditional_t<ForwardRange<Base>, forward_iterator_tag, input_iterator_tag>;
using iterator_category = input_iterator_tag;
struct value_type;
using difference_type = iter_difference_t<iterator_t<Base>>;
outer_iterator() = default;
constexpr explicit outer_iterator(Parent& parent)
requires (!ForwardRange<Base>);
constexpr outer_iterator(Parent& parent, iterator_t<Base> current)
requires ForwardRange<Base>;
constexpr outer_iterator(outer_iterator<!Const> i)
requires Const && ConvertibleTo<iterator_t<V>, iterator_t<const V>>;
constexpr value_type operator*() const;
constexpr outer_iterator& operator++();
constexpr decltype(auto) operator++(int) {
if constexpr (ForwardRange<Base>) {
auto tmp = *this;
++*this;
return tmp;
} else
++*this;
}
friend constexpr bool operator==(const outer_iterator& x, const outer_iterator& y)
requires ForwardRange<Base>;
friend constexpr bool operator!=(const outer_iterator& x, const outer_iterator& y)
requires ForwardRange<Base>;
friend constexpr bool operator==(const outer_iterator& x, default_sentinel_t);
friend constexpr bool operator==(default_sentinel_t, const outer_iterator& x);
friend constexpr bool operator!=(const outer_iterator& x, default_sentinel_t y);
friend constexpr bool operator!=(default_sentinel_t y, const outer_iterator& x);
};
}Class std::ranges::split_view::outer_iterator::value_type
namespace std::ranges {
template<class V, class Pattern>
template<bool Const>
struct split_view<V, Pattern>::outer_iterator<Const>::value_type {
private:
outer_iterator i_ = outer_iterator(); // exposition only
public:
value_type() = default;
constexpr explicit value_type(outer_iterator i);
constexpr inner_iterator<Const> begin() const;
constexpr default_sentinel_t end() const;
};
}Class template std::ranges::split_view::inner_iterator
namespace std::ranges {
template<class V, class Pattern>
template<bool Const>
struct split_view<V, Pattern>::inner_iterator {
private:
using Base =
conditional_t<Const, const V, V>; // exposition only
outer_iterator<Const> i_ = outer_iterator<Const>(); // exposition only
bool incremented_ = false; // exposition only
public:
using iterator_concept = typename outer_iterator<Const>::iterator_concept;
using iterator_category = /* see definition */;
using value_type = iter_value_t<iterator_t<Base>>;
using difference_type = iter_difference_t<iterator_t<Base>>;
inner_iterator() = default;
constexpr explicit inner_iterator(outer_iterator<Const> i);
constexpr decltype(auto) operator*() const { return *i_.current; }
constexpr inner_iterator& operator++();
constexpr decltype(auto) operator++(int) {
if constexpr (ForwardRange<V>) {
auto tmp = *this;
++*this;
return tmp;
} else
++*this;
}
friend constexpr bool operator==(const inner_iterator& x, const inner_iterator& y)
requires ForwardRange<Base>;
friend constexpr bool operator!=(const inner_iterator& x, const inner_iterator& y)
requires ForwardRange<Base>;
friend constexpr bool operator==(const inner_iterator& x, default_sentinel_t);
friend constexpr bool operator==(default_sentinel_t, const inner_iterator& x);
friend constexpr bool operator!=(const inner_iterator& x, default_sentinel_t y);
friend constexpr bool operator!=(default_sentinel_t y, const inner_iterator& x);
friend constexpr decltype(auto) iter_move(const inner_iterator& i)
noexcept(noexcept(ranges::iter_move(i.i_.current))) {
return ranges::iter_move(i.i_.current);
}
friend constexpr void iter_swap(const inner_iterator& x, const inner_iterator& y)
noexcept(noexcept(ranges::iter_swap(x.i_.current, y.i_.current)))
requires IndirectlySwappable<iterator_t<Base>>;
};
}Class template std::ranges::common_view
namespace std::ranges {
template<View V>
requires (!CommonRange<V>)
class common_view : public view_interface<common_view<V>> {
private:
V base_ = V(); // exposition only
public:
common_view() = default;
constexpr explicit common_view(V r);
template<ViewableRange R>
requires (!CommonRange<R> && Constructible<V, all_view<R>>)
constexpr explicit common_view(R&& r);
constexpr V base() const;
constexpr auto size() requires SizedRange<V> {
return ranges::size(base_);
}
constexpr auto size() const requires SizedRange<const V> {
return ranges::size(base_);
}
constexpr auto begin() {
if constexpr (RandomAccessRange<V> && SizedRange<V>)
return ranges::begin(base_);
else
return common_iterator<iterator_t<V>, sentinel_t<V>>(ranges::begin(base_));
}
constexpr auto begin() const requires Range<const V> {
if constexpr (RandomAccessRange<const V> && SizedRange<const V>)
return ranges::begin(base_);
else
return
common_iterator<iterator_t<const V>, sentinel_t<const V>>(ranges::begin(base_));
}
constexpr auto end() {
if constexpr (RandomAccessRange<V> && SizedRange<V>)
return ranges::begin(base_) + ranges::size(base_);
else
return common_iterator<iterator_t<V>, sentinel_t<V>>(ranges::end(base_));
}
constexpr auto end() const requires Range<const V> {
if constexpr (RandomAccessRange<const V> && SizedRange<const V>)
return ranges::begin(base_) + ranges::size(base_);
else
return
common_iterator<iterator_t<const V>, sentinel_t<const V>>(ranges::end(base_));
}
};
template<class R>
common_view(R&&) -> common_view<all_view<R>>;
}Class template std::ranges::reverse_view
namespace std::ranges {
template<View V>
requires BidirectionalRange<V>
class reverse_view : public view_interface<reverse_view<V>> {
private:
V base_ = V(); // exposition only
public:
reverse_view() = default;
constexpr explicit reverse_view(V r);
template<ViewableRange R>
requires BidirectionalRange<R> && Constructible<V, all_view<R>>
constexpr explicit reverse_view(R&& r);
constexpr V base() const;
constexpr reverse_iterator<iterator_t<V>> begin();
constexpr reverse_iterator<iterator_t<V>> begin() requires CommonRange<V>;
constexpr reverse_iterator<iterator_t<const V>> begin() const
requires CommonRange<const V>;
constexpr reverse_iterator<iterator_t<V>> end();
constexpr reverse_iterator<iterator_t<const V>> end() const
requires CommonRange<const V>;
constexpr auto size() requires SizedRange<V> {
return ranges::size(base_);
}
constexpr auto size() const requires SizedRange<const V> {
return ranges::size(base_);
}
};
template<class R>
reverse_view(R&&) -> reverse_view<all_view<R>>;
}
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
http://en.cppreference.com/w/cpp/header/ranges