Encabezado de la biblioteca estándar <ranges>
De cppreference.com
Este encabezado es parte de la bibloteca de ranges.
Alias de espacios de nombres
namespace std {
namespace views = ranges::views;
}
|
||
El alias del espacio de nombres std::views se proporciona como una abreviatura de std::ranges::views.
Sinopsis
#include <compare>
#include <initializer_list>
#include <iterator>
namespace std::ranges {
inline namespace /* no especificado */ {
// range access
inline constexpr /* no especificado */ begin = /* no especificado */;
inline constexpr /* no especificado */ end = /* no especificado */;
inline constexpr /* no especificado */ cbegin = /* no especificado */;
inline constexpr /* no especificado */ cend = /* no especificado */;
inline constexpr /* no especificado */ rbegin = /* no especificado */;
inline constexpr /* no especificado */ rend = /* no especificado */;
inline constexpr /* no especificado */ crbegin = /* no especificado */;
inline constexpr /* no especificado */ crend = /* no especificado */;
inline constexpr /* no especificado */ size = /* no especificado */;
inline constexpr /* no especificado */ ssize = /* no especificado */;
inline constexpr /* no especificado */ empty = /* no especificado */;
inline constexpr /* no especificado */ data = /* no especificado */;
inline constexpr /* no especificado */ cdata = /* no especificado */;
}
// ranges
template<class T>
concept range = /* véase descripción */;
template<class T>
inline constexpr bool enable_borrowed_range = false;
template<class T>
concept borrowed_range = /* véase descripción */;
template<class T>
using iterator_t = decltype(ranges::begin(declval<T&>()));
template<range R>
using sentinel_t = decltype(ranges::end(declval<R&>()));
template<range R>
using range_difference_t = iter_difference_t<iterator_t<R>>;
template<sized_range R>
using range_size_t = decltype(ranges::size(declval<R&>()));
template<range R>
using range_value_t = iter_value_t<iterator_t<R>>;
template<range R>
using range_reference_t = iter_reference_t<iterator_t<R>>;
template<range R>
using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<R>>;
// rangos con tamaño
template<class>
inline constexpr bool disable_sized_range = false;
template<class T>
concept sized_range = /* véase descripción */;
// vistas
template<class T>
inline constexpr bool enable_view = /* véase descripción */;
struct view_base {};
template<class T>
concept view = /* véase descripción */;
// otros refinamientos de rangos
template<class R, class T>
concept output_range = /* véase descripción */;
template<class T>
concept input_range = /* véase descripción */;
template<class T>
concept forward_range = /* véase descripción */;
template<class T>
concept bidirectional_range = /* véase descripción */;
template<class T>
concept random_access_range = /* véase descripción */;
template<class T>
concept contiguous_range = /* véase descripción */;
template<class T>
concept common_range = /* véase descripción */;
template<class T>
concept viewable_range = /* véase descripción */;
// plantilla de clase view_interface
template<class D>
requires is_class_v<D> && same_as<D, remove_cv_t<D>>
class view_interface;
// subrangos
enum class subrange_kind : bool { unsized, sized };
template<input_or_output_iterator I, sentinel_for<I> S = I,
subrange_kind K = /* véase descripción */>
requires (K == subrange_kind::sized || !sized_sentinel_for<S, I>)
class subrange;
template<class I, class S, subrange_kind K>
inline constexpr bool enable_borrowed_range<subrange<I, S, K>> = true;
// manejo de iteradores pendientes
struct dangling;
template<range R>
using borrowed_iterator_t = /* véase descripción */;
template<range R>
using borrowed_subrange_t = /* véase descripción */;
// vista vacía
template<class T>
requires is_object_v<T>
class empty_view;
template<class T>
inline constexpr bool enable_borrowed_range<empty_view<T>> = true;
namespace views {
template<class T>
inline constexpr empty_view<T> empty{};
}
// vista única
template<copy_constructible T>
requires is_object_v<T>
class single_view;
namespace views { inline constexpr /* no especificado */ single = /* no especificado */; }
template<bool Const, class T>
using /*maybe_const*/ = conditional_t<Const, const T, T>; // solo exposición
// vista iota
template<weakly_incrementable W, semiregular Bound = unreachable_sentinel_t>
requires /*weakly_equality_comparable_with*/<W, Bound> && copyable<W>
class iota_view;
template<class W, class Bound>
inline constexpr bool enable_borrowed_range<iota_view<W, Bound>> = true;
namespace views { inline constexpr /* no especificado */ iota = /* no especificado */; }
// istream view
template<movable Val, class CharT, class Traits = char_traits<CharT>>
requires /* véase descripción */
class basic_istream_view;
template<class Val>
using istream_view = basic_istream_view<Val, char>;
template<class Val>
using wistream_view = basic_istream_view<Val, wchar_t>;
namespace views {
template<class T>
inline constexpr /* no especificado */ istream = /* no especificado */; }
// vista all
namespace views {
inline constexpr /* no especificado */ all = /* no especificado */;
template<viewable_range R>
using all_t = decltype(all(declval<R>()));
}
template<range R>
requires is_object_v<R>
class ref_view;
template<class T>
inline constexpr bool enable_borrowed_range<ref_view<T>> = true;
// vista owning_view
template<range R>
requires /* véase descripción */
class owning_view;
template<class T>
inline constexpr bool enable_borrowed_range<owning_view<T>> =
enable_borrowed_range<T>;
// vista filter_view
template<input_range V, indirect_unary_predicate<iterator_t<V>> Pred>
requires view<V> && is_object_v<Pred>
class filter_view;
namespace views { inline constexpr /* no especificado */ filter = /* no especificado */; }
// vista transform_view
template<input_range V, copy_constructible F>
requires view<V> && is_object_v<F> &&
regular_invocable<F&, range_reference_t<V>> &&
/*can_reference*/<invoke_result_t<F&, range_reference_t<V>>>
class transform_view;
namespace views { inline constexpr /* no especificado */ transform = /* no especificado */; }
// vista take_view
template<view> class take_view;
template<class T>
inline constexpr bool enable_borrowed_range<take_view<T>> = enable_borrowed_range<T>;
namespace views { inline constexpr /* no especificado */ take = /* no especificado */; }
// vista take_while_view
template<view V, class Pred>
requires input_range<V> && is_object_v<Pred> &&
indirect_unary_predicate<const Pred, iterator_t<V>>
class take_while_view;
namespace views { inline constexpr /* no especificado */ take_while = /* no especificado */; }
// vista drop_view
template<view V>
class drop_view;
template<class T>
inline constexpr bool enable_borrowed_range<drop_view<T>> = enable_borrowed_range<T>;
namespace views { inline constexpr /* no especificado */ drop = /* no especificado */; }
// vista drop_while_view
template<view V, class Pred>
requires input_range<V> && is_object_v<Pred> &&
indirect_unary_predicate<const Pred, iterator_t<V>>
class drop_while_view;
template<class T, class Pred>
inline constexpr bool enable_borrowed_range<drop_while_view<T, Pred>> =
enable_borrowed_range<T>;
namespace views { inline constexpr /* no especificado */ drop_while = /* no especificado */; }
// vista join_view
template<input_range V>
requires view<V> && input_range<range_reference_t<V>>
class join_view;
namespace views { inline constexpr /* no especificado */ join = /* no especificado */; }
// vista lazy_split_view
template<class R>
concept /*tiny_range*/ = /* véase descripción */; // solo exposición
template<input_range V, forward_range Pattern>
requires view<V> && view<Pattern> &&
indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to>
&& (forward_range<V> || /*tiny_range*/<Pattern>)
class lazy_split_view;
// vista split_view
template<forward_range V, forward_range Pattern>
requires view<V> && view<Pattern> &&
indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to>
class split_view;
namespace views {
inline constexpr /* no especificado */ lazy_split = /* no especificado */;
inline constexpr /* no especificado */ split = /* no especificado */;
}
// vista counted
namespace views { inline constexpr /* no especificado */ counted = /* no especificado */; }
// vista common_view
template<view V>
requires (!common_range<V> && copyable<iterator_t<V>>)
class common_view;
template<class T>
inline constexpr bool enable_borrowed_range<common_view<T>> =
enable_borrowed_range<T>;
namespace views { inline constexpr /* no especificado */ common = /* no especificado */; }
// vista reverse_view
template<view V>
requires bidirectional_range<V>
class reverse_view;
template<class T>
inline constexpr bool enable_borrowed_range<reverse_view<T>> =
enable_borrowed_range<T>;
namespace views { inline constexpr /* no especificado */ reverse = /* no especificado */; }
// vista elements_view
template<input_range V, size_t N>
requires /* véase descripción */
class elements_view;
template<class T, size_t N>
inline constexpr bool enable_borrowed_range<elements_view<T, N>> =
enable_borrowed_range<T>;
template<class R>
using keys_view = elements_view<R, 0>;
template<class R>
using values_view = elements_view<R, 1>;
namespace views {
template<size_t N>
inline constexpr /* no especificado */ elements = /* no especificado */;
inline constexpr auto keys = elements<0>;
inline constexpr auto values = elements<1>;
}
// vista zip_view
template<input_range... Views>
requires (view<Views> && ...) && (sizeof...(Views) > 0)
class zip_view;
template<class... Views>
inline constexpr bool enable_borrowed_range<zip_view<Views...>> =
(enable_borrowed_range<Views> && ...);
namespace views { inline constexpr /* no especificado */ zip = /* no especificado */; }
// vista zip_transform_view
template<copy_constructible F, input_range... Views>
requires (view<Views> && ...) && (sizeof...(Views) > 0) && is_object_v<F> &&
regular_invocable<F&, range_reference_t<Views>...> &&
/*can_reference*/<invoke_result_t<F&, range_reference_t<Views>...>>
class zip_transform_view;
namespace views { inline constexpr /* no especificado */ zip_transform =
/* no especificado */; }
// vista adjacent_view
template<forward_range V, size_t N>
requires view<V> && (N > 0)
class adjacent_view;
template<class V, size_t N>
inline constexpr bool enable_borrowed_range<adjacent_view<V, N>> =
enable_borrowed_range<V>;
namespace views {
template<size_t N>
inline constexpr /* no especificado */ adjacent = /* no especificado */ ;
inline constexpr auto pairwise = adjacent<2>;
}
// vista adjacent_transform_view
template<forward_range V, copy_constructible F, size_t N>
requires /* véase descripción */
class adjacent_transform_view;
namespace views {
template<size_t N>
inline constexpr /* no especificado */ adjacent_transform = /* no especificado */;
inline constexpr auto pairwise_transform = adjacent_transform<2>;
}
}
namespace std {
namespace views = ranges::views;
template<class T> struct tuple_size;
template<size_t I, class T> struct tuple_element;
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;
};
template<class I, class S, ranges::subrange_kind K>
struct tuple_element<0, const ranges::subrange<I, S, K>> {
using type = I;
};
template<class I, class S, ranges::subrange_kind K>
struct tuple_element<1, const ranges::subrange<I, S, K>> {
using type = S;
};
}
Concepto range
namespace std::ranges {
template< class T >
concept range = requires(T& t) {
ranges::begin(t); // conservador de la igualdad para iteradores de avance
ranges::end(t);
};
}
Concepto sized_range
namespace std::ranges {
template< class T >
concept sized_range = range<T> &&
requires(T& t) {
ranges::size(t);
};
}
Concepto view
namespace std::ranges {
template<class T>
inline constexpr bool enable_view = derived_from<T, view_base>;
template<class T>
concept view = range<T>
&& movable<T>
&& enable_view<T>;
}
Concepto output_range
namespace std::ranges {
template<class R, class T>
concept output_range =
range<R> && output_iterator<iterator_t<R>, T>;
}
Concepto input_range
namespace std::ranges {
template<class T>
concept input_range =
range<T> && input_iterator<iterator_t<T>>;
}
Concepto forward_range
namespace std::ranges {
template<class T>
concept forward_range =
input_range<T> && forward_iterator<iterator_t<T>>;
}
Concepto bidirectional_range
namespace std::ranges {
template<class T>
concept bidirectional_range =
forward_range<T> && bidirectional_iterator<iterator_t<T>>;
}
Concepto random_access_range
namespace std::ranges {
template<class T>
concept random_access_range =
bidirectional_range<T> && random_access_iterator<iterator_t<T>>;
}
Concepto contiguous_range
namespace std::ranges {
template<class T>
concept contiguous_range =
random_access_range<T> && contiguous_iterator<iterator_t<T>> &&
requires(T& t) {
{ ranges::data(t) } -> same_as<add_pointer_t<range_reference_t<T>>>;
};
}
Concepto common_range
namespace std::ranges {
template<class T>
concept common_range =
range<T> && same_as<iterator_t<T>, sentinel_t<T>>;
}
Concepto viewable_range
namespace std::ranges {
template<class T>
concept viewable_range =
range<T> && (borrowed_range<T> || view<remove_cvref_t<T>>);
}
Conceptos auxiliares
namespace std::ranges { // no especificado, solo para la búsqueda de nombre
template<class R>
concept __SimpleView = // solo exposición
view<R> && range<const R> &&
same_as<iterator_t<R>, iterator_t<const R>> &&
same_as<sentinel_t<R>, sentinel_t<const R>>;
template<input_iterator I>
concept __HasArrow = // solo exposición
is_pointer_v<I> || requires(I i) { i.operator->(); };
template<class T, class U>
concept __DifferentFrom = // solo exposición
!same_as<remove_cvref_t<T>, remove_cvref_t<U>>;
template<class I>
concept __Decrementable = // solo exposición
__Incrementable<I> && requires(I i) {
{ --i } -> same_as<I&>;
{ i-- } -> same_as<I>;
};
template<class I>
concept __Advanceable = // solo exposición
__Decrementable<I> && totally_ordered<I> &&
requires(I i, const I j, const iter_difference_t<I> n) {
{ i += n } -> same_as<I&>;
{ i -= n } -> same_as<I&>;
I { j + n };
I { n + j };
I { j - n };
{ j - j } -> convertible_to<iter_difference_t<I>>;
};
}
Nota: Estos nombres son solo para exposición, no forman parte de la interfaz.
Plantilla de clase std::ranges::view_interface
namespace std::ranges {
template<class D>
requires is_class_v<D> && same_as<D, remove_cv_t<D>>
class view_interface : public view_base {
private:
constexpr D& derived() noexcept { // solo exposición
return static_cast<D&>(*this);
}
constexpr const D& derived() const noexcept { // solo exposición
return static_cast<const D&>(*this);
}
public:
constexpr bool empty() requires forward_range<D> {
return ranges::begin(derived()) == ranges::end(derived());
}
constexpr bool empty() const requires forward_range<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 contiguous_iterator<iterator_t<D>> {
return to_address(ranges::begin(derived()));
}
constexpr auto data() const
requires range<const D> && contiguous_iterator<iterator_t<const D>> {
return to_address(ranges::begin(derived()));
}
constexpr auto size() requires forward_range<D> &&
sized_sentinel_for<sentinel_t<D>, iterator_t<D>> {
return ranges::end(derived()) - ranges::begin(derived());
}
constexpr auto size() const requires forward_range<const D> &&
sized_sentinel_for<sentinel_t<const D>, iterator_t<const D>> {
return ranges::end(derived()) - ranges::begin(derived());
}
constexpr decltype(auto) front() requires forward_range<D>;
constexpr decltype(auto) front() const requires forward_range<const D>;
constexpr decltype(auto) back() requires bidirectional_range<D> && common_range<D>;
constexpr decltype(auto) back() const
requires bidirectional_range<const D> && common_range<const D>;
template<random_access_range R = D>
constexpr decltype(auto) operator[](range_difference_t<R> n) {
return ranges::begin(derived())[n];
}
template<random_access_range R = const D>
constexpr decltype(auto) operator[](range_difference_t<R> n) const {
return ranges::begin(derived())[n];
}
};
}
Plantilla de clase std::ranges::subrange
namespace std::ranges {
template<class From, class To>
concept __UsesNonqualificationPointerConversion = // solo exposición
is_pointer_v<From> && is_pointer_v<To> &&
!convertible_to<remove_pointer_t<From>(*)[], remove_pointer_t<To>(*)[]>;
template<class From, class To>
concept __ConvertibleToNonSlicing = // solo exposición
convertible_to<From, To> &&
!__UsesNonqualificationPointerConversion<decay_t<From>, decay_t<To>>;
template<class T>
concept __PairLike = // solo exposición
!is_reference_v<T> && requires(T t) {
typename tuple_size<T>::type; // se asegura de que tuple_size<T> esté completo
requires derived_from<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) } -> convertible_to<const tuple_element_t<0, T>&>;
{ get<1>(t) } -> convertible_to<const tuple_element_t<1, T>&>;
};
template<class T, class U, class V>
concept __PairLikeConvertibleFrom = // solo exposición
!range<T> && __PairLike<T> &&
constructible_from<T, U, V> &&
__ConvertibleToNonSlicing<U, tuple_element_t<0, T>> &&
convertible_to<V, tuple_element_t<1, T>>;
template<class T>
concept __IteratorSentinelPair = // solo exposición
!range<T> && __PairLike<T> &&
sentinel_for<tuple_element_t<1, T>, tuple_element_t<0, T>>;
template<input_or_output_iterator I, sentinel_for<I> S = I, subrange_kind K =
sized_sentinel_for<S, I> ? subrange_kind::sized : subrange_kind::unsized>
requires (K == subrange_kind::sized || !sized_sentinel_for<S, I>)
class subrange : public view_interface<subrange<I, S, K>> {
private:
static constexpr bool StoreSize = // solo exposición
K == subrange_kind::sized && !sized_sentinel_for<S, I>;
I begin_ = I(); // solo exposición
S end_ = S(); // solo exposición
__MakeUnsignedLikeT<iter_difference_t<I>> size_ = 0; // solo exposición; solo está presente
// cuando StoreSize es verdadero
public:
subrange() = default;
constexpr subrange(__ConvertibleToNonSlicing<I> auto i, S s) requires (!StoreSize);
constexpr subrange(__ConvertibleToNonSlicing<I> auto i, S s,
__MakeUnsignedLikeT<iter_difference_t<I>> n)
requires (K == subrange_kind::sized);
template<__DifferentFrom<subrange> R>
requires borrowed_range<R> &&
__ConvertibleToNonSlicing<iterator_t<R>, I> &&
convertible_to<sentinel_t<R>, S>
constexpr subrange(R&& r) requires (!StoreSize || sized_range<R>);
template<borrowed_range R>
requires __ConvertibleToNonSlicing<iterator_t<R>, I> &&
convertible_to<sentinel_t<R>, S>
constexpr subrange(R&& r, __MakeUnsignedLikeT<iter_difference_t<I>> n)
requires (K == subrange_kind::sized)
: subrange{ranges::begin(r), ranges::end(r), n}
{}
template<__DifferentFrom<subrange> PairLike>
requires __PairLikeConvertibleFrom<PairLike, const I&, const S&>
constexpr operator PairLike() const;
constexpr I begin() const requires copyable<I>;
[[nodiscard]] constexpr I begin() requires (!copyable<I>);
constexpr S end() const;
constexpr bool empty() const;
constexpr __MakeUnsignedLikeT<iter_difference_t<I>> size() const
requires (K == subrange_kind::sized);
[[nodiscard]] constexpr subrange next(iter_difference_t<I> n = 1) const &
requires forward_iterator<I>;
[[nodiscard]] constexpr subrange next(iter_difference_t<I> n = 1) &&;
[[nodiscard]] constexpr subrange prev(iter_difference_t<I> n = 1) const
requires bidirectional_iterator<I>;
constexpr subrange& advance(iter_difference_t<I> n);
};
template<input_or_output_iterator I, sentinel_for<I> S>
subrange(I, S) -> subrange<I, S>;
template<input_or_output_iterator I, sentinel_for<I> S>
subrange(I, S, __MakeUnsignedLikeT<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, __MakeUnsignedLikeT<iter_difference_t<tuple_element_t<0, P>>>) ->
subrange<tuple_element_t<0, P>, tuple_element_t<1, P>, subrange_kind::sized>;
template<borrowed_range R>
subrange(R&&) ->
subrange<iterator_t<R>, sentinel_t<R>,
(sized_range<R> || sized_sentinel_for<sentinel_t<R>, iterator_t<R>>)
? subrange_kind::sized : subrange_kind::unsized>;
template<borrowed_range R>
subrange(R&&, __MakeUnsignedLikeT<range_difference_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);
template<size_t N, class I, class S, subrange_kind K>
requires (N < 2)
constexpr auto get(subrange<I, S, K>&& r);
}
namespace std {
using ranges::get;
}
Clase std::ranges::dangling
namespace std::ranges {
struct dangling {
constexpr dangling() noexcept = default;
template<class... Args>
constexpr dangling(Args&&...) noexcept { }
};
}
Plantilla de clase 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 size_t size() noexcept { return 0; }
static constexpr bool empty() noexcept { return true; }
};
}
Plantilla de clase std::ranges::single_view
namespace std::ranges {
template<copy_constructible T>
requires is_object_v<T>
class single_view : public view_interface<single_view<T>> {
private:
__SemiregularBox<T> value_; // solo exposición
public:
single_view() = default;
constexpr explicit single_view(const T& t);
constexpr explicit single_view(T&& t);
template<class... Args>
requires constructible_from<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 size_t size() noexcept;
constexpr T* data() noexcept;
constexpr const T* data() const noexcept;
};
}
Plantilla de clase std::ranges::iota_view
namespace std::ranges {
template<class I>
concept __Decrementable = // solo exposición
/* véase definición */;
template<class I>
concept __Advanceable = // solo exposición
/* véase definición */;
template<weakly_incrementable W, semiregular Bound = unreachable_sentinel_t>
requires __WeaklyEqualityComparableWith<W, Bound> && semiregular<W>
class iota_view : public view_interface<iota_view<W, Bound>> {
private:
// class iota_view::iterator
struct iterator; // solo exposición
// class iota_view::sentinel
struct sentinel; // solo exposición
W value_ = W(); // solo exposición
Bound bound_ = Bound(); // solo exposición
public:
iota_view() = default;
constexpr explicit iota_view(W value);
constexpr iota_view(type_identity_t<W> value,
type_identity_t<Bound> bound);
constexpr iota_view(iterator first, sentinel last) : iota_view(*first, last.bound_) {}
constexpr iterator begin() const;
constexpr auto end() const;
constexpr iterator end() const requires same_as<W, Bound>;
constexpr auto size() const requires /* véase definición */;
};
template<class W, class Bound>
requires (!__IsIntegerLike<W> || !__IsIntegerLike<Bound> ||
(__IsSignedIntegerLike<W> == __IsSignedIntegerLike<Bound>))
iota_view(W, Bound) -> iota_view<W, Bound>;
}
Clase std::ranges::iota_view::iterator
namespace std::ranges {
template<weakly_incrementable W, semiregular Bound>
requires __WeaklyEqualityComparableWith<W, Bound>
struct iota_view<W, Bound>::iterator {
private:
W value_ = W(); // solo exposición
public:
using iterator_concept = /* véase definición */;
using iterator_category = input_iterator_tag;
using value_type = W;
using difference_type = /* __iota_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 equality_comparable<W>;
friend constexpr bool operator<(const iterator& x, const iterator& y)
requires totally_ordered<W>;
friend constexpr bool operator>(const iterator& x, const iterator& y)
requires totally_ordered<W>;
friend constexpr bool operator<=(const iterator& x, const iterator& y)
requires totally_ordered<W>;
friend constexpr bool operator>=(const iterator& x, const iterator& y)
requires totally_ordered<W>;
friend constexpr auto operator<=>(const iterator& x, const iterator& y)
requires totally_ordered<W> && three_way_comparable<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>;
};
}
Clase std::ranges::iota_view::sentinel
namespace std::ranges {
template<weakly_incrementable W, semiregular Bound>
requires __WeaklyEqualityComparableWith<W, Bound>
struct iota_view<W, Bound>::sentinel {
private:
Bound bound_ = Bound(); // solo exposición
public:
sentinel() = default;
constexpr explicit sentinel(Bound bound);
friend constexpr bool operator==(const iterator& x, const sentinel& y);
friend constexpr iter_difference_t<W> operator-(const iterator& x, const sentinel& y)
requires sized_sentinel_for<Bound, W>;
friend constexpr iter_difference_t<W> operator-(const sentinel& x, const iterator& y)
requires sized_sentinel_for<Bound, W>;
};
}
Plantilla de clase std::ranges::basic_istream_view
namespace std::ranges {
template<class Val, class CharT, class Traits>
concept __StreamExtractable = // solo exposición
requires(basic_istream<CharT, Traits>& is, Val& t) {
is >> t;
};
template<movable Val, class CharT, class Traits>
requires default_initializable<Val> &&
__StreamExtractable<Val, CharT, Traits>
class basic_istream_view
: public view_interface<basic_istream_view<Val, CharT, Traits>> {
public:
basic_istream_view() = default;
constexpr explicit basic_istream_view(basic_istream<CharT, Traits>& stream);
constexpr auto begin()
{
if (stream_) {
*stream_ >> object_;
}
return iterator{*this};
}
constexpr default_sentinel_t end() const noexcept;
private:
struct iterator; // solo exposición
basic_istream<CharT, Traits>* stream_ = nullptr; // solo exposición
Val object_ = Val(); // solo exposición
};
}
Plantilla de clase std::ranges::basic_istream_view::iterator
namespace std::ranges {
template<movable Val, class CharT, class Traits>
requires default_initializable<Val> && __StreamExtractable<Val, CharT, Traits>
class basic_istream_view<Val, CharT, Traits>::iterator { // solo exposición
public:
using iterator_concept = input_iterator_tag;
using difference_type = ptrdiff_t;
using value_type = Val;
iterator() = default;
constexpr explicit iterator(basic_istream_view& parent) noexcept;
iterator(const iterator&) = delete;
iterator(iterator&&) = default;
iterator& operator=(const iterator&) = delete;
iterator& operator=(iterator&&) = default;
iterator& operator++();
void operator++(int);
Val& operator*() const;
friend bool operator==(const iterator& x, default_sentinel_t);
private:
basic_istream_view* parent_ = nullptr; // solo exposición
};
}
Plantilla de clase 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; // solo exposición
public:
constexpr ref_view() noexcept = default;
template<__DifferentFrom<ref_view> T>
requires /* véase definición */
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 sized_range<R>
{ return ranges::size(*r_); }
constexpr auto data() const requires contiguous_range<R>
{ return ranges::data(*r_); }
};
template<class R>
ref_view(R&) -> ref_view<R>;
}
Plantilla de clase std::ranges::owning_view
namespace std::ranges {
template<range R>
requires movable<R> && (!/*is-initializer-list*/<R>)
class owning_view : public view_interface<owning_view<R>> {
private:
R r_ = R(); // solo exposición
public:
owning_view() requires default_initializable<R> = default;
constexpr owning_view(R&& t);
owning_view(owning_view&&) = default;
owning_view& operator=(owning_view&&) = default;
constexpr R& base() & { return r_; }
constexpr const R& base() const& { return r_; }
constexpr R&& base() && { return std::move(r_); }
constexpr const R&& base() const&& { return std::move(r_); }
constexpr iterator_t<R> begin() { return ranges::begin(r_); }
constexpr sentinel_t<R> end() { return ranges::end(r_); }
constexpr iterator_t<const R> begin() const requires range<const R>
{ return ranges::begin(r_); }
constexpr sentinel_t<const R> end() const requires range<const R>
{ return ranges::end(r_); }
constexpr bool empty()
requires requires { ranges::empty(r_); }
{ return ranges::empty(r_); }
constexpr bool empty() const
requires requires { ranges::empty(r_); }
{ return ranges::empty(r_); }
constexpr auto size() requires sized_range<R>
{ return ranges::size(r_); }
constexpr auto size() const requires sized_range<const R>
{ return ranges::size(r_); }
constexpr auto data() requires contiguous_range<R>
{ return ranges::data(r_); }
constexpr auto data() const requires contiguous_range<const R>
{ return ranges::data(r_); }
};
}
Plantilla de clase std::ranges::filter_view
namespace std::ranges {
template<input_range V, indirect_unary_predicate<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(); // solo exposición
__SemiregularBox<Pred> pred_; // solo exposición
// class filter_view::iterator
class iterator; // solo exposición
// class filter_view::sentinel
class sentinel; // solo exposición
public:
filter_view() = default;
constexpr filter_view(V base, Pred pred);
constexpr V base() const& requires copy_constructible<V> { return base_; }
constexpr V base() && { return std::move(base_); }
constexpr const Pred& pred() const;
constexpr iterator begin();
constexpr auto end() {
if constexpr (common_range<V>)
return iterator{*this, ranges::end(base_)};
else
return sentinel{*this};
}
};
template<class R, class Pred>
filter_view(R&&, Pred) -> filter_view<views::all_t<R>, Pred>;
}
Clase std::ranges::filter_view::iterator
namespace std::ranges {
template<input_range V, indirect_unary_predicate<iterator_t<V>> Pred>
requires view<V> && is_object_v<Pred>
class filter_view<V, Pred>::iterator {
private:
iterator_t<V> current_ = iterator_t<V>(); // solo exposición
filter_view* parent_ = nullptr; // solo exposición
public:
using iterator_concept = /* véase definición */;
using iterator_category = /* véase definición */;
using value_type = range_value_t<V>;
using difference_type = range_difference_t<V>;
iterator() = default;
constexpr iterator(filter_view& parent, iterator_t<V> current);
constexpr iterator_t<V> base() const &
requires copyable<iterator_t<V>>;
constexpr iterator_t<V> base() &&;
constexpr range_reference_t<V> operator*() const;
constexpr iterator_t<V> operator->() const
requires __HasArrow<iterator_t<V>> && copyable<iterator_t<V>>;
constexpr iterator& operator++();
constexpr void operator++(int);
constexpr iterator operator++(int) requires forward_range<V>;
constexpr iterator& operator--() requires bidirectional_range<V>;
constexpr iterator operator--(int) requires bidirectional_range<V>;
friend constexpr bool operator==(const iterator& x, const iterator& y)
requires equality_comparable<iterator_t<V>>;
friend constexpr range_rvalue_reference_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 indirectly_swappable<iterator_t<V>>;
};
}
Clase std::ranges::filter_view::sentinel
namespace std::ranges {
template<input_range V, indirect_unary_predicate<iterator_t<V>> Pred>
requires view<V> && is_object_v<Pred>
class filter_view<V, Pred>::sentinel {
private:
sentinel_t<V> end_ = sentinel_t<V>(); // solo exposición
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);
};
}
Plantilla de clase std::ranges::transform_view
namespace std::ranges {
template<input_range V, copy_constructible F>
requires view<V> && is_object_v<F> &&
regular_invocable<F&, range_reference_t<V>> &&
__CanReference<invoke_result_t<F&, range_reference_t<V>>>
class transform_view : public view_interface<transform_view<V, F>> {
private:
// plantilla de clase transform_view::iterator
template<bool> struct iterator; // solo exposición
// plantilla de clase transform_view::sentinel
template<bool> struct sentinel; // solo exposición
V base_ = V(); // solo exposición
__SemiregularBox<F> fun_; // solo exposición
public:
transform_view() = default;
constexpr transform_view(V base, F fun);
constexpr V base() const& requires copy_constructible<V> { return base_; }
constexpr V base() && { return std::move(base_); }
constexpr iterator<false> begin();
constexpr iterator<true> begin() const
requires range<const V> &&
regular_invocable<const F&, range_reference_t<const V>>;
constexpr sentinel<false> end();
constexpr iterator<false> end() requires common_range<V>;
constexpr sentinel<true> end() const
requires range<const V> &&
regular_invocable<const F&, range_reference_t<const V>>;
constexpr iterator<true> end() const
requires common_range<const V> &&
regular_invocable<const F&, range_reference_t<const V>>;
constexpr auto size() requires sized_range<V> { return ranges::size(base_); }
constexpr auto size() const requires sized_range<const V>
{ return ranges::size(base_); }
};
template<class R, class F>
transform_view(R&&, F) -> transform_view<views::all_t<R>, F>;
}
Plantilla de clase std::ranges::transform_view::iterator
namespace std::ranges {
template<input_range V, copy_constructible F>
requires view<V> && is_object_v<F> &&
regular_invocable<F&, range_reference_t<V>> &&
__CanReference<invoke_result_t<F&, range_reference_t<V>>>
template<bool Const>
class transform_view<V, F>::iterator {
private:
using Parent = // solo exposición
conditional_t<Const, const transform_view, transform_view>;
using Base = // solo exposición
conditional_t<Const, const V, V>;
iterator_t<Base> current_ = // solo exposición
iterator_t<Base>();
Parent* parent_ = nullptr; // solo exposición
public:
using iterator_concept = /* véase definición */;
using iterator_category = /* véase definición */;
using value_type =
remove_cvref_t<invoke_result_t<F&, range_reference_t<Base>>>;
using difference_type = range_difference_t<Base>;
iterator() = default;
constexpr iterator(Parent& parent, iterator_t<Base> current);
constexpr iterator(iterator<!Const> i)
requires Const && convertible_to<iterator_t<V>, iterator_t<Base>>;
constexpr iterator_t<Base> base() const &
requires copyable<iterator_t<Base>>;
constexpr iterator_t<Base> base() &&;
constexpr decltype(auto) operator*() const
{ return invoke(*parent_->fun_, *current_); }
constexpr iterator& operator++();
constexpr void operator++(int);
constexpr iterator operator++(int) requires forward_range<Base>;
constexpr iterator& operator--() requires bidirectional_range<Base>;
constexpr iterator operator--(int) requires bidirectional_range<Base>;
constexpr iterator& operator+=(difference_type n)
requires random_access_range<Base>;
constexpr iterator& operator-=(difference_type n)
requires random_access_range<Base>;
constexpr decltype(auto) operator[](difference_type n) const
requires random_access_range<Base>
{ return invoke(*parent_->fun_, current_[n]); }
friend constexpr bool operator==(const iterator& x, const iterator& y)
requires equality_comparable<iterator_t<Base>>;
friend constexpr bool operator<(const iterator& x, const iterator& y)
requires random_access_range<Base>;
friend constexpr bool operator>(const iterator& x, const iterator& y)
requires random_access_range<Base>;
friend constexpr bool operator<=(const iterator& x, const iterator& y)
requires random_access_range<Base>;
friend constexpr bool operator>=(const iterator& x, const iterator& y)
requires random_access_range<Base>;
friend constexpr auto operator<=>(const iterator& x, const iterator& y)
requires random_access_range<Base> && three_way_comparable<iterator_t<Base>>;
friend constexpr iterator operator+(iterator i, difference_type n)
requires random_access_range<Base>;
friend constexpr iterator operator+(difference_type n, iterator i)
requires random_access_range<Base>;
friend constexpr iterator operator-(iterator i, difference_type n)
requires random_access_range<Base>;
friend constexpr difference_type operator-(const iterator& x, const iterator& y)
requires random_access_range<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;
}
}
Plantilla de clase std::ranges::transform_view::sentinel
namespace std::ranges {
template<input_range V, copy_constructible F>
requires view<V> && is_object_v<F> &&
regular_invocable<F&, range_reference_t<V>> &&
__CanReference<invoke_result_t<F&, range_reference_t<V>>>
template<bool Const>
class transform_view<V, F>::sentinel {
private:
using Parent = // solo exposición
conditional_t<Const, const transform_view, transform_view>;
using Base = conditional_t<Const, const V, V>; // solo exposición
sentinel_t<Base> end_ = sentinel_t<Base>(); // solo exposición
public:
sentinel() = default;
constexpr explicit sentinel(sentinel_t<Base> end);
constexpr sentinel(sentinel<!Const> i)
requires Const && convertible_to<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 range_difference_t<Base>
operator-(const iterator<Const>& x, const sentinel& y)
requires sized_sentinel_for<sentinel_t<Base>, iterator_t<Base>>;
friend constexpr range_difference_t<Base>
operator-(const sentinel& y, const iterator<Const>& x)
requires sized_sentinel_for<sentinel_t<Base>, iterator_t<Base>>;
};
}
Plantilla de clase std::ranges::take_view
namespace std::ranges {
template<view V>
class take_view : public view_interface<take_view<V>> {
private:
V base_ = V(); // solo exposición
range_difference_t<V> count_ = 0; // solo exposición
// plantilla de clase take_view::sentinel
template<bool> struct sentinel; // solo exposición
public:
take_view() = default;
constexpr take_view(V base, range_difference_t<V> count);
constexpr V base() const& requires copy_constructible<V> { return base_; }
constexpr V base() && { return std::move(base_); }
constexpr auto begin() requires (!__SimpleView<V>) {
if constexpr (sized_range<V>) {
if constexpr (random_access_range<V>)
return ranges::begin(base_);
else {
auto sz = size();
return counted_iterator{ranges::begin(base_), sz};
}
} else
return counted_iterator{ranges::begin(base_), count_};
}
constexpr auto begin() const requires range<const V> {
if constexpr (sized_range<const V>) {
if constexpr (random_access_range<const V>)
return ranges::begin(base_);
else {
auto sz = size();
return counted_iterator{ranges::begin(base_), sz};
}
} else
return counted_iterator{ranges::begin(base_), count_};
}
constexpr auto end() requires (!__SimpleView<V>) {
if constexpr (sized_range<V>) {
if constexpr (random_access_range<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 (sized_range<const V>) {
if constexpr (random_access_range<const V>)
return ranges::begin(base_) + size();
else
return default_sentinel;
} else
return sentinel<true>{ranges::end(base_)};
}
constexpr auto size() requires sized_range<V> {
auto n = ranges::size(base_);
return ranges::min(n, static_cast<decltype(n)>(count_));
}
constexpr auto size() const requires sized_range<const V> {
auto n = ranges::size(base_);
return ranges::min(n, static_cast<decltype(n)>(count_));
}
};
template<range R>
take_view(R&&, range_difference_t<R>)
-> take_view<views::all_t<R>>;
}
Plantilla de clase std::ranges::take_view::sentinel
namespace std::ranges {
template<view V>
template<bool Const>
class take_view<V>::sentinel {
private:
using Base = conditional_t<Const, const V, V>; // solo exposición
using CI = counted_iterator<iterator_t<Base>>; // solo exposición
sentinel_t<Base> end_ = sentinel_t<Base>(); // solo exposición
public:
sentinel() = default;
constexpr explicit sentinel(sentinel_t<Base> end);
constexpr sentinel(sentinel<!Const> s)
requires Const && convertible_to<sentinel_t<V>, sentinel_t<Base>>;
constexpr sentinel_t<Base> base() const;
friend constexpr bool operator==(const CI& y, const sentinel& x);
};
}
Plantilla de clase std::ranges::take_while_view
namespace std::ranges {
template<view V, class Pred>
requires input_range<V> && is_object_v<Pred> &&
indirect_unary_predicate<const Pred, iterator_t<V>>
class take_while_view : public view_interface<take_while_view<V, Pred>> {
// plantilla de clase take_while_view::sentinel
template<bool> class sentinel; // solo exposición
V base_ = V(); // solo exposición
__SemiregularBox<Pred> pred_; // solo exposición
public:
take_while_view() = default;
constexpr take_while_view(V base, Pred pred);
constexpr V base() const& requires copy_constructible<V> { return base_; }
constexpr V base() && { return std::move(base_); }
constexpr const Pred& pred() const;
constexpr auto begin() requires (!__SimpleView<V>)
{ return ranges::begin(base_); }
constexpr auto begin() const requires range<const V>
{ return ranges::begin(base_); }
constexpr auto end() requires (!__SimpleView<V>)
{ return sentinel<false>(ranges::end(base_), addressof(*pred_)); }
constexpr auto end() const requires range<const V>
{ return sentinel<true>(ranges::end(base_), addressof(*pred_)); }
};
template<class R, class Pred>
take_while_view(R&&, Pred) -> take_while_view<views::all_t<R>, Pred>;
}
Plantilla de clase std::ranges::take_while_view::sentinel
namespace std::ranges {
template<view V, class Pred>
requires input_range<V> && is_object_v<Pred> &&
indirect_unary_predicate<const Pred, iterator_t<V>>
template<bool Const>
class take_while_view<V, Pred>::sentinel { // solo exposición
using Base = conditional_t<Const, const V, V>; // solo exposición
sentinel_t<Base> end_ = sentinel_t<Base>(); // solo exposición
const Pred* pred_ = nullptr; // solo exposición
public:
sentinel() = default;
constexpr explicit sentinel(sentinel_t<Base> end, const Pred* pred);
constexpr sentinel(sentinel<!Const> s)
requires Const && convertible_to<sentinel_t<V>, sentinel_t<Base>>;
constexpr sentinel_t<Base> base() const { return end_; }
friend constexpr bool operator==(const iterator_t<Base>& x, const sentinel& y);
};
}
Plantilla de clase std::ranges::drop_view
namespace std::ranges {
template<view V>
class drop_view : public view_interface<drop_view<V>> {
public:
drop_view() = default;
constexpr drop_view(V base, range_difference_t<V> count);
constexpr V base() const& requires copy_constructible<V> { return base_; }
constexpr V base() && { return std::move(base_); }
constexpr auto begin()
requires (!(__SimpleView<V> && random_access_range<V> && sized_range<const V>));
constexpr auto begin() const
requires random_access_range<const V> && sized_range<const V>;
constexpr auto end()
requires (!__SimpleView<V>)
{ return ranges::end(base_); }
constexpr auto end() const
requires range<const V>
{ return ranges::end(base_); }
constexpr auto size()
requires sized_range<V>
{
const auto s = ranges::size(base_);
const auto c = static_cast<decltype(s)>(count_);
return s < c ? 0 : s - c;
}
constexpr auto size() const
requires sized_range<const V>
{
const auto s = ranges::size(base_);
const auto c = static_cast<decltype(s)>(count_);
return s < c ? 0 : s - c;
}
private:
V base_ = V(); // solo exposición
range_difference_t<V> count_ = 0; // solo exposición
};
template<class R>
drop_view(R&&, range_difference_t<R>) -> drop_view<views::all_t<R>>;
}
Plantilla de clase std::ranges::drop_while_view
namespace std::ranges {
template<view V, class Pred>
requires input_range<V> && is_object_v<Pred> &&
indirect_unary_predicate<const Pred, iterator_t<V>>
class drop_while_view : public view_interface<drop_while_view<V, Pred>> {
public:
drop_while_view() = default;
constexpr drop_while_view(V base, Pred pred);
constexpr V base() const& requires copy_constructible<V> { return base_; }
constexpr V base() && { return std::move(base_); }
constexpr const Pred& pred() const;
constexpr auto begin();
constexpr auto end()
{ return ranges::end(base_); }
private:
V base_ = V(); // solo exposición
__SemiregularBox<Pred> pred_; // solo exposición
};
template<class R, class Pred>
drop_while_view(R&&, Pred) -> drop_while_view<views::all_t<R>, Pred>;
}
Plantilla de clase std::ranges::join_view
namespace std::ranges {
template<input_range V>
requires view<V> && input_range<range_reference_t<V>> &&
(is_reference_v<range_reference_t<V>> ||
view<range_value_t<V>>)
class join_view : public view_interface<join_view<V>> {
private:
using InnerRng = // solo exposición
range_reference_t<V>;
// plantilla de clase join_view::iterator
template<bool Const>
struct iterator; // solo exposición
// plantilla de clase join_view::sentinel
template<bool Const>
struct sentinel; // solo exposición
V base_ = V(); // solo exposición
views::all_t<InnerRng> inner_ = // solo exposición, solo está presente
views::all_t<InnerRng>(); // cuando !is_reference_v<InnerRng>
public:
join_view() = default;
constexpr explicit join_view(V base);
constexpr V base() const& requires copy_constructible<V> { return base_; }
constexpr V base() && { return std::move(base_); }
constexpr auto begin() {
constexpr bool use_const = __SimpleView<V> &&
is_reference_v<range_reference_t<V>>;
return iterator<use_const>{*this, ranges::begin(base_)};
}
constexpr auto begin() const
requires input_range<const V> &&
is_reference_v<range_reference_t<const V>> {
return iterator<true>{*this, ranges::begin(base_)};
}
constexpr auto end() {
if constexpr (forward_range<V> &&
is_reference_v<InnerRng> && forward_range<InnerRng> &&
common_range<V> && common_range<InnerRng>)
return iterator<__SimpleView<V>>{*this, ranges::end(base_)};
else
return sentinel<__SimpleView<V>>{*this};
}
constexpr auto end() const
requires input_range<const V> &&
is_reference_v<range_reference_t<const V>> {
if constexpr (forward_range<const V> &&
is_reference_v<range_reference_t<const V>> &&
forward_range<range_reference_t<const V>> &&
common_range<const V> &&
common_range<range_reference_t<const V>>)
return iterator<true>{*this, ranges::end(base_)};
else
return sentinel<true>{*this};
}
};
template<class R>
explicit join_view(R&&) -> join_view<views::all_t<R>>;
}
Plantilla de clase std::ranges::join_view::iterator
namespace std::ranges {
template<input_range V>
requires view<V> && input_range<range_reference_t<V>> &&
(is_reference_v<range_reference_t<V>> ||
view<range_value_t<V>>)
template<bool Const>
struct join_view<V>::iterator {
private:
using Parent = // solo exposición
conditional_t<Const, const join_view, join_view>;
using Base = conditional_t<Const, const V, V>; // solo exposición
static constexpr bool __RefIsGlvalue = // solo exposición
is_reference_v<range_reference_t<Base>>;
iterator_t<Base> outer_ = iterator_t<Base>(); // solo exposición
iterator_t<range_reference_t<Base>> inner_ = // solo exposición
iterator_t<range_reference_t<Base>>();
Parent* parent_ = nullptr; // solo exposición
constexpr void satisfy(); // solo exposición
public:
using iterator_concept = /* véase definición */;
using iterator_category = /* véase definición */;
using value_type = range_value_t<range_reference_t<Base>>;
using difference_type = /* véase definición */;
iterator() = default;
constexpr iterator(Parent& parent, iterator_t<Base> outer);
constexpr iterator(iterator<!Const> i)
requires Const &&
convertible_to<iterator_t<V>, iterator_t<Base>> &&
convertible_to<iterator_t<InnerRng>,
iterator_t<range_reference_t<Base>>>;
constexpr decltype(auto) operator*() const { return *inner_; }
constexpr iterator_t<Base> operator->() const
requires __HasArrow<iterator_t<Base>> && copyable<iterator_t<Base>>;
constexpr iterator& operator++();
constexpr void operator++(int);
constexpr iterator operator++(int)
requires __RefIsGlvalue && forward_range<Base> &&
forward_range<range_reference_t<Base>>;
constexpr iterator& operator--()
requires __RefIsGlvalue && bidirectional_range<Base> &&
bidirectional_range<range_reference_t<Base>> &&
common_range<range_reference_t<Base>>;
constexpr iterator operator--(int)
requires __RefIsGlvalue && bidirectional_range<Base> &&
bidirectional_range<range_reference_t<Base>> &&
common_range<range_reference_t<Base>>;
friend constexpr bool operator==(const iterator& x, const iterator& y)
requires __RefIsGlvalue && equality_comparable<iterator_t<Base>> &&
equality_comparable<iterator_t<range_reference_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_)));
};
}
Plantilla de clase std::ranges::join_view::sentinel
namespace std::ranges {
template<input_range V>
requires view<V> && input_range<range_reference_t<V>> &&
(is_reference_v<range_reference_t<V>> ||
view<range_value_t<V>>)
template<bool Const>
struct join_view<V>::sentinel {
private:
using Parent = // solo exposición
conditional_t<Const, const join_view, join_view>;
using Base = conditional_t<Const, const V, V>; // solo exposición
sentinel_t<Base> end_ = sentinel_t<Base>(); // solo exposición
public:
sentinel() = default;
constexpr explicit sentinel(Parent& parent);
constexpr sentinel(sentinel<!Const> s)
requires Const && convertible_to<sentinel_t<V>, sentinel_t<Base>>;
friend constexpr bool operator==(const iterator<Const>& x, const sentinel& y);
};
}
Plantilla de clase std::ranges::lazy_split_view
namespace std::ranges {
template<auto> struct __RequireConstant; // solo exposición
template<class R>
concept __TinyRange = // solo exposición
sized_range<R> &&
requires { typename __RequireConstant<remove_reference_t<R>::size()>; } &&
(remove_reference_t<R>::size() <= 1);
template<input_range V, forward_range Pattern>
requires view<V> && view<Pattern> &&
indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to> &&
(forward_range<V> || __TinyRange<Pattern>)
class lazy_split_view : public view_interface<lazy_split_view<V, Pattern>> {
private:
V base_ = V(); // solo exposición
Pattern pattern_ = Pattern(); // solo exposición
__NonPropagatingCache<iterator_t<V>> current_; // solo exposición, solo está presente
// if !forward_range<V>
// plantilla de clase lazy_split_view::__OuterIterator
template<bool> struct __OuterIterator; // solo exposición
// plantilla de clase lazy_split_view::__InnerIterator
template<bool> struct __InnerIterator; // solo exposición
public:
lazy_split_view()
requires default_initializable<V> && default_initializable<Pattern> = default;
constexpr lazy_split_view(V base, Pattern pattern);
template<input_range R>
requires constructible_from<V, views::all_t<R>> &&
constructible_from<Pattern, single_view<range_value_t<R>>>
constexpr lazy_split_view(R&& r, range_value_t<R> e);
constexpr V base() const& requires copy_constructible<V> { return base_; }
constexpr V base() && { return std::move(base_); }
constexpr auto begin() {
if constexpr (forward_range<V>)
return __OuterIterator<__SimpleView<V>>{*this, ranges::begin(base_)};
else {
current_ = ranges::begin(base_);
return __OuterIterator<false>{*this};
}
}
constexpr auto begin() const requires forward_range<V> && forward_range<const V> {
return __OuterIterator<true>{*this, ranges::begin(base_)};
}
constexpr auto end() requires forward_range<V> && common_range<V> {
return __OuterIterator<__SimpleView<V>>{*this, ranges::end(base_)};
}
constexpr auto end() const {
if constexpr (forward_range<V> && forward_range<const V> && common_range<const V>)
return __OuterIterator<true>{*this, ranges::end(base_)};
else
return default_sentinel;
}
};
template<class R, class P>
lazy_split_view(R&&, P&&) -> lazy_split_view<views::all_t<R>, views::all_t<P>>;
template<input_range R>
lazy_split_view(R&&, range_value_t<R>)
-> lazy_split_view<views::all_t<R>, single_view<range_value_t<R>>>;
}
Plantilla de clase std::ranges::lazy_split_view::outer_iterator
namespace std::ranges {
template<input_range V, forward_range Pattern>
requires view<V> && view<Pattern> &&
indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to> &&
(forward_range<V> || __TinyRange<Pattern>)
template<bool Const>
struct lazy_split_view<V, Pattern>::__OuterIterator {
private:
using Parent = __MaybeConst<Const, lazy_split_view>; // solo exposición
using Base = __MaybeConst<Const, V>; // solo exposición
Parent* parent_ = nullptr; // solo exposición
iterator_t<Base> current_ = iterator_t<Base>(); // solo exposición, solo está presente
// si V modela forward_range
bool trailing_empty_ = false; // solo exposición
public:
using iterator_concept =
conditional_t<forward_range<Base>, forward_iterator_tag, input_iterator_tag>;
using iterator_category = input_iterator_tag; // solo está presente si Base
// modela forward_range
// class lazy_split_view::__OuterIterator::value_type
struct value_type;
using difference_type = range_difference_t<Base>;
__OuterIterator() = default;
constexpr explicit __OuterIterator(Parent& parent)
requires (!forward_range<Base>);
constexpr __OuterIterator(Parent& parent, iterator_t<Base> current)
requires forward_range<Base>;
constexpr __OuterIterator(__OuterIterator<!Const> i)
requires Const && convertible_to<iterator_t<V>, iterator_t<Base>>;
constexpr value_type operator*() const;
constexpr __OuterIterator& operator++();
constexpr decltype(auto) operator++(int) {
if constexpr (forward_range<Base>) {
auto tmp = *this;
++*this;
return tmp;
} else
++*this;
}
friend constexpr bool operator==(const __OuterIterator& x, const __OuterIterator& y)
requires forward_range<Base>;
friend constexpr bool operator==(const __OuterIterator& x, default_sentinel_t);
};
}
Clase std::ranges::lazy_split_view::outer_iterator::value_type
namespace std::ranges {
template<input_range V, forward_range Pattern>
requires view<V> && view<Pattern> &&
indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to> &&
(forward_range<V> || __TinyRange<Pattern>)
template<bool Const>
struct lazy_split_view<V, Pattern>::__OuterIterator<Const>::value_type
: view_interface<value_type> {
private:
__OuterIterator i_ = __OuterIterator(); // solo exposición
public:
value_type() = default;
constexpr explicit value_type(__OuterIterator i);
constexpr __InnerIterator<Const> begin() const;
constexpr default_sentinel_t end() const;
};
}
Plantilla de clase std::ranges::lazy_split_view::inner_iterator
namespace std::ranges {
template<input_range V, forward_range Pattern>
requires view<V> && view<Pattern> &&
indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to> &&
(forward_range<V> || __TinyRange<Pattern>)
template<bool Const>
struct lazy_split_view<V, Pattern>::__InnerIterator {
private:
using Base = __MaybeConst<Const, V>; // solo exposición
__OuterIterator<Const> i_ = __OuterIterator<Const>(); // solo exposición
bool incremented_ = false; // solo exposición
public:
using iterator_concept = typename __OuterIterator<Const>::iterator_concept;
using iterator_category = /*véase descripción*/; // solo está presente si Base
// modela forward_range
using value_type = range_value_t<Base>;
using difference_type = range_difference_t<Base>;
__InnerIterator() = default;
constexpr explicit __InnerIterator(__OuterIterator<Const> i);
constexpr const iterator_t<Base>& base() const &;
constexpr iterator_t<Base> base() &&;
constexpr decltype(auto) operator*() const { return *i_.current; }
constexpr __InnerIterator& operator++();
constexpr decltype(auto) operator++(int) {
if constexpr (forward_range<Base>) {
auto tmp = *this;
++*this;
return tmp;
} else
++*this;
}
friend constexpr bool operator==(const __InnerIterator& x, const __InnerIterator& y)
requires forward_range<Base>;
friend constexpr bool operator==(const __InnerIterator& x, default_sentinel_t);
friend constexpr decltype(auto) iter_move(const __InnerIterator& i)
noexcept(noexcept(ranges::iter_move(i.i_.current))) {
return ranges::iter_move(i.i_.current);
}
friend constexpr void iter_swap(const __InnerIterator& x, const __InnerIterator& y)
noexcept(noexcept(ranges::iter_swap(x.i_.current, y.i_.current)))
requires indirectly_swappable<iterator_t<Base>>;
};
}
Plantilla de clase std::ranges::split_view
namespace std::ranges {
template<forward_range V, forward_range Pattern>
requires view<V> && view<Pattern> &&
indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to>
class split_view : public view_interface<split_view<V, Pattern>> {
private:
V base_ = V(); // solo exposición
Pattern pattern_ = Pattern(); // solo exposición
// class split_view::iterator
struct iterator; // solo exposición
// class split_view::sentinel
struct sentinel; // solo exposición
public:
split_view()
requires default_initializable<V> && default_initializable<Pattern> = default;
constexpr split_view(V base, Pattern pattern);
template<forward_range R>
requires constructible_from<V, views::all_t<R>> &&
constructible_from<Pattern, single_view<range_value_t<R>>>
constexpr split_view(R&& r, range_value_t<R> e);
constexpr V base() const& requires copyable<V> { return base_; }
constexpr V base() && { return std::move(base_); }
constexpr iterator begin();
constexpr auto end() {
if constexpr (common_range<V>) {
return iterator{*this, ranges::end(base_), {} };
} else {
return sentinel{*this};
}
}
constexpr subrange<iterator_t<V>> __FindNext(iterator_t<V>); // solo exposición
};
template<class R, class P>
split_view(R&&, P&&) -> split_view<views::all_t<R>, views::all_t<P>>;
template<forward_range R>
split_view(R&&, range_value_t<R>)
-> split_view<views::all_t<R>, single_view<range_value_t<R>>>;
}
Plantilla de clase std::ranges::split_view::iterator
namespace std::ranges {
template<forward_range V, forward_range Pattern>
requires view<V> && view<Pattern> &&
indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to>
class split_view<V, Pattern>::iterator {
private:
split_view* parent_ = nullptr; // solo exposición
iterator_t<V> cur_ = iterator_t<V>(); // solo exposición
subrange<iterator_t<V>> next_ = subrange<iterator_t<V>>(); // solo exposición
bool trailing_empty_ = false; // solo exposición
public:
using iterator_concept = forward_iterator_tag;
using iterator_category = input_iterator_tag;
using value_type = subrange<iterator_t<V>>;
using difference_type = range_difference_t<V>;
iterator() = default;
constexpr iterator(split_view& parent, iterator_t<V> current,
subrange<iterator_t<V>> next);
constexpr iterator_t<V> base() const;
constexpr value_type operator*() const;
constexpr iterator& operator++();
constexpr iterator operator++(int);
friend constexpr bool operator==(const iterator& x, const iterator& y);
};
}
Plantilla de clase std::ranges::split_view::sentinel
namespace std::ranges {
template<forward_range V, forward_range Pattern>
requires view<V> && view<Pattern> &&
indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to>
struct split_view<V, Pattern>::sentinel {
private:
sentinel_t<V> end_ = sentinel_t<V>(); // solo exposición
public:
sentinel() = default;
constexpr explicit sentinel(split_view& parent);
friend constexpr bool operator==(const iterator& x, const sentinel& y);
};
}
Plantilla de clase std::ranges::common_view
namespace std::ranges {
template<view V>
requires (!common_range<V> && copyable<iterator_t<V>>)
class common_view : public view_interface<common_view<V>> {
private:
V base_ = V(); // solo exposición
public:
common_view() = default;
constexpr explicit common_view(V r);
template<viewable_range R>
requires (!common_range<R> && constructible_from<V, views::all_t<R>>)
constexpr explicit common_view(R&& r);
constexpr V base() const& requires copy_constructible<V> { return base_; }
constexpr V base() && { return std::move(base_); }
constexpr auto begin() {
if constexpr (random_access_range<V> && sized_range<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 (random_access_range<const V> && sized_range<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 (random_access_range<V> && sized_range<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 (random_access_range<const V> && sized_range<const V>)
return ranges::begin(base_) + ranges::size(base_);
else
return common_iterator<iterator_t<const V>, sentinel_t<const V>>(ranges::end(base_));
}
constexpr auto size() requires sized_range<V> {
return ranges::size(base_);
}
constexpr auto size() const requires sized_range<const V> {
return ranges::size(base_);
}
};
template<class R>
common_view(R&&) -> common_view<views::all_t<R>>;
}
Plantilla de clase std::ranges::reverse_view
namespace std::ranges {
template<view V>
requires bidirectional_range<V>
class reverse_view : public view_interface<reverse_view<V>> {
private:
V base_ = V(); // solo exposición
public:
reverse_view() = default;
constexpr explicit reverse_view(V r);
constexpr V base() const& requires copy_constructible<V> { return base_; }
constexpr V base() && { return std::move(base_); }
constexpr reverse_iterator<iterator_t<V>> begin();
constexpr reverse_iterator<iterator_t<V>> begin() requires common_range<V>;
constexpr auto begin() const requires common_range<const V>;
constexpr reverse_iterator<iterator_t<V>> end();
constexpr auto end() const requires common_range<const V>;
constexpr auto size() requires sized_range<V> {
return ranges::size(base_);
}
constexpr auto size() const requires sized_range<const V> {
return ranges::size(base_);
}
};
template<class R>
reverse_view(R&&) -> reverse_view<views::all_t<R>>;
}
Plantilla de clase std::ranges::elements_view
namespace std::ranges {
template<class T, size_t N>
concept __HasTupleElement = // solo exposición
requires(T t) {
typename tuple_size<T>::type;
requires N < tuple_size_v<T>;
typename tuple_element_t<N, T>;
{ get<N>(t) } -> convertible_to<const tuple_element_t<N, T>&>;
};
template<input_range V, size_t N>
requires view<V> && __HasTupleElement<range_value_t<V>, N> &&
__HasTupleElement<remove_reference_t<range_reference_t<V>>, N>
class elements_view : public view_interface<elements_view<V, N>> {
public:
elements_view() = default;
constexpr explicit elements_view(V base);
constexpr V base() const& requires copy_constructible<V> { return base_; }
constexpr V base() && { return std::move(base_); }
constexpr auto begin() requires (!__SimpleView<V>)
{ return iterator<false>(ranges::begin(base_)); }
constexpr auto begin() const requires __SimpleView<V>
{ return iterator<true>(ranges::begin(base_)); }
constexpr auto end()
{ return sentinel<false>{ranges::end(base_)}; }
constexpr auto end() requires common_range<V>
{ return iterator<false>{ranges::end(base_)}; }
constexpr auto end() const requires range<const V>
{ return sentinel<true>{ranges::end(base_)}; }
constexpr auto end() const requires common_range<const V>
{ return iterator<true>{ranges::end(base_)}; }
constexpr auto size() requires sized_range<V>
{ return ranges::size(base_); }
constexpr auto size() const requires sized_range<const V>
{ return ranges::size(base_); }
private:
// plantilla de clase elements_view::iterator
template<bool> struct iterator; // solo exposición
// plantilla de clase elements_view::sentinel
template<bool> struct sentinel; // solo exposición
V base_ = V(); // solo exposición
};
}
Plantilla de clase std::ranges::elements_view::iterator
namespace std::ranges {
template<input_range V, size_t N>
requires view<V> && __HasTupleElement<range_value_t<V>, N> &&
__HasTupleElement<remove_reference_t<range_reference_t<V>>, N>
template<bool Const>
class elements_view<V, N>::iterator { // solo exposición
using Base = conditional_t<Const, const V, V>; // solo exposición
iterator_t<Base> current_ = iterator_t<Base>();
public:
using iterator_category = typename iterator_traits<iterator_t<Base>>::iterator_category;
using value_type = remove_cvref_t<tuple_element_t<N, range_value_t<Base>>>;
using difference_type = range_difference_t<Base>;
iterator() = default;
constexpr explicit iterator(iterator_t<Base> current);
constexpr iterator(iterator<!Const> i)
requires Const && convertible_to<iterator_t<V>, iterator_t<Base>>;
constexpr iterator_t<Base> base() const&
requires copyable<iterator_t<Base>>;
constexpr iterator_t<Base> base() &&;
constexpr decltype(auto) operator*() const
{ return get<N>(*current_); }
constexpr iterator& operator++();
constexpr void operator++(int) requires (!forward_range<Base>);
constexpr iterator operator++(int) requires forward_range<Base>;
constexpr iterator& operator--() requires bidirectional_range<Base>;
constexpr iterator operator--(int) requires bidirectional_range<Base>;
constexpr iterator& operator+=(difference_type x)
requires random_access_range<Base>;
constexpr iterator& operator-=(difference_type x)
requires random_access_range<Base>;
constexpr decltype(auto) operator[](difference_type n) const
requires random_access_range<Base>
{ return get<N>(*(current_ + n)); }
friend constexpr bool operator==(const iterator& x, const iterator& y)
requires equality_comparable<iterator_t<Base>>;
friend constexpr bool operator<(const iterator& x, const iterator& y)
requires random_access_range<Base>;
friend constexpr bool operator>(const iterator& x, const iterator& y)
requires random_access_range<Base>;
friend constexpr bool operator<=(const iterator& y, const iterator& y)
requires random_access_range<Base>;
friend constexpr bool operator>=(const iterator& x, const iterator& y)
requires random_access_range<Base>;
friend constexpr auto operator<=>(const iterator& x, const iterator& y)
requires random_access_range<Base> && three_way_comparable<iterator_t<Base>>;
friend constexpr iterator operator+(const iterator& x, difference_type y)
requires random_access_range<Base>;
friend constexpr iterator operator+(difference_type x, const iterator& y)
requires random_access_range<Base>;
friend constexpr iterator operator-(const iterator& x, difference_type y)
requires random_access_range<Base>;
friend constexpr difference_type operator-(const iterator& x, const iterator& y)
requires random_access_range<Base>;
};
}
Plantilla de clase std::ranges::elements_view::sentinel
namespace std::ranges {
template<input_range V, size_t N>
requires view<V> && __HasTupleElement<range_value_t<V>, N> &&
__HasTupleElement<remove_reference_t<range_reference_t<V>>, N>
template<bool Const>
class elements_view<V, N>::sentinel { // solo exposición
private:
using Base = conditional_t<Const, const V, V>; // solo exposición
sentinel_t<Base> end_ = sentinel_t<Base>(); // solo exposición
public:
sentinel() = default;
constexpr explicit sentinel(sentinel_t<Base> end);
constexpr sentinel(sentinel<!Const> other)
requires Const && convertible_to<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 range_difference_t<Base>
operator-(const iterator<Const>& x, const sentinel& y)
requires sized_sentinel_for<sentinel_t<Base>, iterator_t<Base>>;
friend constexpr range_difference_t<Base>
operator-(const sentinel& x, const iterator<Const>& y)
requires sized_sentinel_for<sentinel_t<Base>, iterator_t<Base>>;
};
}
Plantilla de clase std::ranges::zip_view
namespace std::ranges {
template<class... Rs>
concept __ZipIsCommon = // solo exposición
(sizeof...(Rs) == 1 && (common_range<Rs> && ...)) ||
(!(bidirectional_range<Rs> && ...) && (common_range<Rs> && ...)) ||
((random_access_range<Rs> && ...) && (sized_range<Rs> && ...));
template<class... Ts>
using TupleOrPair = /* véase a continuación */; // solo exposición
template<class F, class Tuple>
constexpr auto __TupleTransform(F&& f, Tuple&& tuple) { // solo exposición
return apply([&]<class... Ts>(Ts&&... elements) {
return TupleOrPair<invoke_result_t<F&, Ts>...>(
invoke(f, std::forward<Ts>(elements))...
);
}, std::forward<Tuple>(tuple));
}
template<class F, class Tuple>
constexpr void TupleForEach(F&& f, Tuple&& tuple) { // solo exposición
apply([&]<class... Ts>(Ts&&... elements) {
(invoke(f, std::forward<Ts>(elements)), ...);
}, std::forward<Tuple>(tuple));
}
template<input_range... Views>
requires (view<Views> && ...) && (sizeof...(Views) > 0)
class zip_view : public view_interface<zip_view<Views...>> {
tuple<Views...> views_; // solo exposición
// plantilla de clase zip_view::iterator
template<bool> class iterator; // solo exposición
// plantilla de clase zip_view::sentinel
template<bool> class sentinel; // solo exposición
public:
zip_view() = default;
constexpr explicit zip_view(Views... views);
constexpr auto begin() requires (!(__SimpleView<Views> && ...)) {
return iterator<false>(__TupleTransform(ranges::begin, views_));
}
constexpr auto begin() const requires (range<const Views> && ...) {
return iterator<true>(__TupleTransform(ranges::begin, views_));
}
constexpr auto end() requires (!(__SimpleView<Views> && ...)) {
if constexpr (!__ZipIsCommon<Views...>) {
return sentinel<false>(__TupleTransform(ranges::end, views_));
} else if constexpr ((random_access_range<Views> && ...)) {
return begin() + iter_difference_t<iterator<false>>(size());
} else {
return iterator<false>(__TupleTransform(ranges::end, views_));
}
}
constexpr auto end() const requires (range<const Views> && ...) {
if constexpr (!__ZipIsCommon<const Views...>) {
return sentinel<true>(__TupleTransform(ranges::end, views_));
} else if constexpr ((random_access_range<const Views> && ...)) {
return begin() + iter_difference_t<iterator<true>>(size());
} else {
return iterator<true>(__TupleTransform(ranges::end, views_));
}
}
constexpr auto size() requires (sized_range<Views> && ...);
constexpr auto size() const requires (sized_range<const Views> && ...);
};
template<class... Rs>
zip_view(Rs&&...) -> zip_view<views::all_t<Rs>...>;
}
Plantilla de clase std::ranges::zip_view::iterator
namespace std::ranges {
template<bool Const, class... Views>
concept __AllRandomAccess = // solo exposición
(random_access_range<__MaybeConst<Const, Views>> && ...);
template<bool Const, class... Views>
concept __AllBidirectional = // solo exposición
(bidirectional_range<__MaybeConst<Const, Views>> && ...);
template<bool Const, class... Views>
concept __AllForward = // solo exposición
(forward_range<__MaybeConst<Const, Views>> && ...);
template<input_range... Views>
requires (view<Views> && ...) && (sizeof...(Views) > 0)
template<bool Const>
class zip_view<Views...>::iterator {
TupleOrPair<iterator_t<__MaybeConst<Const, Views>>...> current_; // solo exposición
constexpr explicit iterator(TupleOrPair<iterator_t<__MaybeConst<Const, Views>>...>);
// solo exposición
public:
using iterator_category = input_iterator_tag; // no siempre está presente
using iterator_concept = /* véase a continuación */;
using value_type = TupleOrPair<range_value_t<__MaybeConst<Const, Views>>...>;
using difference_type = common_type_t<range_difference_t<__MaybeConst<Const, Views>>...>;
iterator() = default;
constexpr iterator(iterator<!Const> i)
requires Const && (convertible_to<iterator_t<Views>,
iterator_t<__MaybeConst<Const, Views>>> && ...);
constexpr auto operator*() const;
constexpr iterator& operator++();
constexpr void operator++(int);
constexpr iterator operator++(int) requires __AllForward<Const, Views...>;
constexpr iterator& operator--() requires __AllBidirectional<Const, Views...>;
constexpr iterator operator--(int) requires __AllBidirectional<Const, Views...>;
constexpr iterator& operator+=(difference_type x)
requires __AllRandomAccess<Const, Views...>;
constexpr iterator& operator-=(difference_type x)
requires __AllRandomAccess<Const, Views...>;
constexpr auto operator[](difference_type n) const
requires __AllRandomAccess<Const, Views...>;
friend constexpr bool operator==(const iterator& x, const iterator& y)
requires (equality_comparable<iterator_t<__MaybeConst<Const, Views>>> && ...);
friend constexpr bool operator<(const iterator& x, const iterator& y)
requires __AllRandomAccess<Const, Views...>;
friend constexpr bool operator>(const iterator& x, const iterator& y)
requires __AllRandomAccess<Const, Views...>;
friend constexpr bool operator<=(const iterator& x, const iterator& y)
requires __AllRandomAccess<Const, Views...>;
friend constexpr bool operator>=(const iterator& x, const iterator& y)
requires __AllRandomAccess<Const, Views...>;
friend constexpr auto operator<=>(const iterator& x, const iterator& y)
requires __AllRandomAccess<Const, Views...> &&
(three_way_comparable<iterator_t<__MaybeConst<Const, Views>>> && ...);
friend constexpr iterator operator+(const iterator& i, difference_type n)
requires __AllRandomAccess<Const, Views...>;
friend constexpr iterator operator+(difference_type n, const iterator& i)
requires __AllRandomAccess<Const, Views...>;
friend constexpr iterator operator-(const iterator& i, difference_type n)
requires __AllRandomAccess<Const, Views...>;
friend constexpr difference_type operator-(const iterator& x, const iterator& y)
requires (sized_sentinel_for<iterator_t<__MaybeConst<Const, Views>>,
iterator_t<__MaybeConst<Const, Views>>> && ...);
friend constexpr auto iter_move(const iterator& i)
noexcept(/* véase a continuación */);
friend constexpr void iter_swap(const iterator& l, const iterator& r)
noexcept(/* véase a continuación */)
requires (indirectly_swappable<iterator_t<__MaybeConst<Const, Views>>> && ...);
};
}
Plantilla de clase std::ranges::zip_view::sentinel
namespace std::ranges {
template<input_range... Views>
requires (view<Views> && ...) && (sizeof...(Views) > 0)
template<bool Const>
class zip_view<Views...>::sentinel {
TupleOrPair<sentinel_t<__MaybeConst<Const, Views>>...> end_; // solo exposición
constexpr explicit sentinel(TupleOrPair<sentinel_t<__MaybeConst<Const, Views>>...> end);
// solo exposición
public:
sentinel() = default;
constexpr sentinel(sentinel<!Const> i)
requires Const &&
(convertible_to<sentinel_t<Views>,
sentinel_t<__MaybeConst<Const, Views>>> && ...);
template<bool OtherConst>
requires (sentinel_for<sentinel_t<__MaybeConst<Const, Views>>,
iterator_t<__MaybeConst<OtherConst, Views>>> && ...)
friend constexpr bool operator==(const iterator<OtherConst>& x, const sentinel& y);
template<bool OtherConst>
requires (sized_sentinel_for<sentinel_t<__MaybeConst<Const, Views>>,
iterator_t<__MaybeConst<OtherConst, Views>>> && ...)
friend constexpr common_type_t<range_difference_t<__MaybeConst<OtherConst, Views>>...>
operator-(const iterator<OtherConst>& x, const sentinel& y);
template<bool OtherConst>
requires (sized_sentinel_for<sentinel_t<__MaybeConst<Const, Views>>,
iterator_t<__MaybeConst<OtherConst, Views>>> && ...)
friend constexpr common_type_t<range_difference_t<__MaybeConst<OtherConst, Views>>...>
operator-(const sentinel& y, const iterator<OtherConst>& x);
};
}
Plantilla de clase std::ranges::zip_transform_view
namespace std::ranges {
template<copy_constructible F, input_range... Views>
requires (view<Views> && ...) && (sizeof...(Views) > 0) && is_object_v<F> &&
regular_invocable<F&, range_reference_t<Views>...> &&
__CanReference<invoke_result_t<F&, range_reference_t<Views>...>>
class zip_transform_view : public view_interface<zip_transform_view<F, Views...>> {
__CopyableBox<F> fun_; // solo exposición
zip_view<Views...> zip_; // solo exposición
using InnerView = zip_view<Views...>; // solo exposición
template<bool Const>
using ziperator = iterator_t<__MaybeConst<Const, InnerView>>; // solo exposición
template<bool Const>
using zentinel = sentinel_t<__MaybeConst<Const, InnerView>>; // solo exposición
// plantilla de clase zip_transform_view::iterator
template<bool> class iterator; // solo exposición
// plantilla de clase zip_transform_view::sentinel
template<bool> class sentinel; // solo exposición
public:
zip_transform_view() = default;
constexpr explicit zip_transform_view(F fun, Views... views);
constexpr auto begin() { return iterator<false>(*this, zip_.begin()); }
constexpr auto begin() const
requires range<const InnerView> &&
regular_invocable<const F&, range_reference_t<const Views>...> {
return iterator<true>(*this, zip_.begin());
}
constexpr auto end() {
if constexpr (common_range<InnerView>) {
return iterator<false>(*this, zip_.end());
} else {
return sentinel<false>(zip_.end());
}
}
constexpr auto end() const
requires range<const InnerView> &&
regular_invocable<const F&, range_reference_t<const Views>...> {
if constexpr (common_range<const InnerView>) {
return iterator<true>(*this, zip_.end());
} else {
return sentinel<true>(zip_.end());
}
}
constexpr auto size() requires sized_range<InnerView> {
return zip_.size();
}
constexpr auto size() const requires sized_range<const InnerView> {
return zip_.size();
}
};
template<class F, class... Rs>
zip_transform_view(F, Rs&&...) -> zip_transform_view<F, views::all_t<Rs>...>;
}
Plantilla de clase std::ranges::zip_transform_view::iterator
namespace std::ranges {
template<copy_constructible F, input_range... Views>
requires (view<Views> && ...) && (sizeof...(Views) > 0) && is_object_v<F> &&
regular_invocable<F&, range_reference_t<Views>...> &&
__CanReference<invoke_result_t<F&, range_reference_t<Views>...>>
template<bool Const>
class zip_transform_view<F, Views...>::iterator {
using Parent = __MaybeConst<Const, zip_transform_view>; // solo exposición
using Base = __MaybeConst<Const, InnerView>; // solo exposición
Parent* parent_ = nullptr; // solo exposición
ziperator<Const> inner_; // solo exposición
constexpr iterator(Parent& parent, ziperator<Const> inner); // solo exposición
public:
using iterator_category = /* véase a continuación */; // no siempre está presente
using iterator_concept = typename ziperator<Const>::iterator_concept;
using value_type =
remove_cvref_t<invoke_result_t<__MaybeConst<Const, F>&,
range_reference_t<__MaybeConst<Const, Views>>...>>;
using difference_type = range_difference_t<Base>;
iterator() = default;
constexpr iterator(iterator<!Const> i)
requires Const && convertible_to<ziperator<false>, ziperator<Const>>;
constexpr decltype(auto) operator*() const noexcept(/* véase a continuación */);
constexpr iterator& operator++();
constexpr void operator++(int);
constexpr iterator operator++(int) requires forward_range<Base>;
constexpr iterator& operator--() requires bidirectional_range<Base>;
constexpr iterator operator--(int) requires bidirectional_range<Base>;
constexpr iterator& operator+=(difference_type x) requires random_access_range<Base>;
constexpr iterator& operator-=(difference_type x) requires random_access_range<Base>;
constexpr decltype(auto) operator[](difference_type n) const
requires random_access_range<Base>;
friend constexpr bool operator==(const iterator& x, const iterator& y)
requires equality_comparable<ziperator<Const>>;
friend constexpr bool operator<(const iterator& x, const iterator& y)
requires random_access_range<Base>;
friend constexpr bool operator>(const iterator& x, const iterator& y)
requires random_access_range<Base>;
friend constexpr bool operator<=(const iterator& x, const iterator& y)
requires random_access_range<Base>;
friend constexpr bool operator>=(const iterator& x, const iterator& y)
requires random_access_range<Base>;
friend constexpr auto operator<=>(const iterator& x, const iterator& y)
requires random_access_range<Base> && three_way_comparable<ziperator<Const>>;
friend constexpr iterator operator+(const iterator& i, difference_type n)
requires random_access_range<Base>;
friend constexpr iterator operator+(difference_type n, const iterator& i)
requires random_access_range<Base>;
friend constexpr iterator operator-(const iterator& i, difference_type n)
requires random_access_range<Base>;
friend constexpr difference_type operator-(const iterator& x, const iterator& y)
requires sized_sentinel_for<ziperator<Const>, ziperator<Const>>;
};
}
Plantilla de clase std::ranges::zip_transform_view::sentinel
namespace std::ranges {
template<copy_constructible F, input_range... Views>
requires (view<Views> && ...) && (sizeof...(Views) > 0) && is_object_v<F> &&
regular_invocable<F&, range_reference_t<Views>...> &&
__CanReference<invoke_result_t<F&, range_reference_t<Views>...>>
template<bool Const>
class zip_transform_view<F, Views...>::sentinel {
zentinel<Const> inner_; // solo exposición
constexpr explicit sentinel(zentinel<Const> inner); // solo exposición
public:
sentinel() = default;
constexpr sentinel(sentinel<!Const> i)
requires Const && convertible_to<zentinel<false>, zentinel<Const>>;
template<bool OtherConst>
requires sentinel_for<zentinel<Const>, ziperator<OtherConst>>
friend constexpr bool operator==(const iterator<OtherConst>& x, const sentinel& y);
template<bool OtherConst>
requires sized_sentinel_for<zentinel<Const>, ziperator<OtherConst>>
friend constexpr range_difference_t<__MaybeConst<OtherConst, InnerView>>
operator-(const iterator<OtherConst>& x, const sentinel& y);
template<bool OtherConst>
requires sized_sentinel_for<zentinel<Const>, ziperator<OtherConst>>
friend constexpr range_difference_t<__MaybeConst<OtherConst, InnerView>>
operator-(const sentinel& x, const iterator<OtherConst>& y);
};
}
Plantilla de clase std::ranges::adjacent_view
namespace std::ranges {
template<forward_range V, size_t N>
requires view<V> && (N > 0)
class adjacent_view : public view_interface<adjacent_view<V, N>> {
V base_ = V(); // solo exposición
// plantilla de clase adjacent_view::iterator
template<bool> class iterator; // solo exposición
// plantilla de clase adjacent_view::sentinel
template<bool> class sentinel; // solo exposición
struct AsSentinel{}; // solo exposición
public:
adjacent_view() requires default_initializable<V> = default;
constexpr explicit adjacent_view(V base);
constexpr auto begin() requires (!__SimpleView<V>) {
return iterator<false>(ranges::begin(base_), ranges::end(base_));
}
constexpr auto begin() const requires range<const V> {
return iterator<true>(ranges::begin(base_), ranges::end(base_));
}
constexpr auto end() requires (!__SimpleView<V>) {
if constexpr (common_range<V>) {
return iterator<false>(AsSentinel{}, ranges::begin(base_), ranges::end(base_));
} else {
return sentinel<false>(ranges::end(base_));
}
}
constexpr auto end() const requires range<const V> {
if constexpr (common_range<const V>) {
return iterator<true>(AsSentinel{}, ranges::begin(base_), ranges::end(base_));
} else {
return sentinel<true>(ranges::end(base_));
}
}
constexpr auto size() requires sized_range<V>;
constexpr auto size() const requires sized_range<const V>;
};
}
Plantilla de clase std::ranges::adjacent_view::iterator
namespace std::ranges {
template<forward_range V, size_t N>
requires view<V> && (N > 0)
template<bool Const>
class adjacent_view<V, N>::iterator {
using Base = __MaybeConst<Const, V>; // solo exposición
array<iterator_t<Base>, N> current_ = array<iterator_t<Base>, N>(); // solo exposición
constexpr iterator(iterator_t<Base> first, sentinel_t<Base> last); // solo exposición
constexpr iterator(AsSentinel, iterator_t<Base> first, iterator_t<Base> last);
// solo exposición
public:
using iterator_category = input_iterator_tag;
using iterator_concept = /* véase a continuación */;
// sea REPEAT(T, N) como un paquete de N tipos, donde cada uno denota el mismo tipo que T
using value_type = TupleOrPair</* REPEAT(range_value_t<Base>, N) */...>;
using difference_type = range_difference_t<Base>;
iterator() = default;
constexpr iterator(iterator<!Const> i)
requires Const && convertible_to<iterator_t<V>, iterator_t<Base>>;
constexpr auto operator*() const;
constexpr iterator& operator++();
constexpr iterator operator++(int);
constexpr iterator& operator--() requires bidirectional_range<Base>;
constexpr iterator operator--(int) requires bidirectional_range<Base>;
constexpr iterator& operator+=(difference_type x)
requires random_access_range<Base>;
constexpr iterator& operator-=(difference_type x)
requires random_access_range<Base>;
constexpr auto operator[](difference_type n) const
requires random_access_range<Base>;
friend constexpr bool operator==(const iterator& x, const iterator& y);
friend constexpr bool operator<(const iterator& x, const iterator& y)
requires random_access_range<Base>;
friend constexpr bool operator>(const iterator& x, const iterator& y)
requires random_access_range<Base>;
friend constexpr bool operator<=(const iterator& x, const iterator& y)
requires random_access_range<Base>;
friend constexpr bool operator>=(const iterator& x, const iterator& y)
requires random_access_range<Base>;
friend constexpr auto operator<=>(const iterator& x, const iterator& y)
requires random_access_range<Base> &&
three_way_comparable<iterator_t<Base>>;
friend constexpr iterator operator+(const iterator& i, difference_type n)
requires random_access_range<Base>;
friend constexpr iterator operator+(difference_type n, const iterator& i)
requires random_access_range<Base>;
friend constexpr iterator operator-(const iterator& i, difference_type n)
requires random_access_range<Base>;
friend constexpr difference_type operator-(const iterator& x, const iterator& y)
requires sized_sentinel_for<iterator_t<Base>, iterator_t<Base>>;
friend constexpr auto iter_move(const iterator& i)
noexcept(/* véase a continuación */);
friend constexpr void iter_swap(const iterator& l, const iterator& r)
noexcept(/* véase a continuación */)
requires indirectly_swappable<iterator_t<Base>>;
};
}
Plantilla de clase std::ranges::adjacent_view::sentinel
namespace std::ranges {
template<forward_range V, size_t N>
requires view<V> && (N > 0)
template<bool Const>
class adjacent_view<V, N>::sentinel {
using Base = __MaybeConst<Const, V>; // solo exposición
sentinel_t<Base> end_ = sentinel_t<Base>(); // solo exposición
constexpr explicit sentinel(sentinel_t<Base> end); // solo exposición
public:
sentinel() = default;
constexpr sentinel(sentinel<!Const> i)
requires Const && convertible_to<sentinel_t<V>, sentinel_t<Base>>;
template<bool OtherConst>
requires sentinel_for<sentinel_t<Base>,
iterator_t<__MaybeConst<OtherConst, V>>>
friend constexpr bool operator==(const iterator<OtherConst>& x, const sentinel& y);
template<bool OtherConst>
requires sized_sentinel_for<sentinel_t<Base>,
iterator_t<__MaybeConst<OtherConst, V>>>
friend constexpr range_difference_t<__MaybeConst<OtherConst, V>>
operator-(const iterator<OtherConst>& x, const sentinel& y);
template<bool OtherConst>
requires sized_sentinel_for<sentinel_t<Base>,
iterator_t<__MaybeConst<OtherConst, V>>>
friend constexpr range_difference_t<__MaybeConst<OtherConst, V>>
operator-(const sentinel& y, const iterator<OtherConst>& x);
};
}
Plantilla de clase std::ranges::adjacent_transform_view
namespace std::ranges {
template<forward_range V, copy_constructible F, size_t N>
requires view<V> && (N > 0) && is_object_v<F> &&
regular_invocable<F&, /* REPEAT(range_reference_t<V>, N) */...> &&
__CanReference<invoke_result_t<F&, /* REPEAT(range_reference_t<V>, N) */...>>
class adjacent_transform_view : public view_interface<adjacent_transform_view<V, F, N>> {
__CopyableBox<F> fun_; // solo exposición
adjacent_view<V, N> inner_; // solo exposición
using InnerView = adjacent_view<V, N>; // solo exposición
template<bool Const>
using InnerIterator = iterator_t<__MaybeConst<Const, InnerView>>; // solo exposición
template<bool Const>
using InnerSentinel = sentinel_t<__MaybeConst<Const, InnerView>>; // solo exposición
// plantilla de clase adjacent_transform_view::iterator
template<bool> class iterator; // solo exposición
// plantilla de clase adjacent_transform_view::sentinel
template<bool> class sentinel; // solo exposición
public:
adjacent_transform_view() = default;
constexpr explicit adjacent_transform_view(V base, F fun);
constexpr auto begin() {
return iterator<false>(*this, inner_.begin());
}
constexpr auto begin() const
requires range<const InnerView> &&
regular_invocable<const F&,
/* REPEAT(range_reference_t<const V>, N) */...> {
return iterator<true>(*this, inner_.begin());
}
constexpr auto end() {
if constexpr (common_range<InnerView>) {
return iterator<false>(*this, inner_.end());
} else {
return sentinel<false>(inner_.end());
}
}
constexpr auto end() const
requires range<const InnerView> &&
regular_invocable<const F&,
/* REPEAT(range_reference_t<const V>, N) */...> {
if constexpr (common_range<const InnerView>) {
return iterator<true>(*this, inner_.end());
} else {
return sentinel<true>(inner_.end());
}
}
constexpr auto size() requires sized_range<InnerView> {
return inner_.size();
}
constexpr auto size() const requires sized_range<const InnerView> {
return inner_.size();
}
};
}
Plantilla de clase std::ranges::adjacent_transform_view::iterator
namespace std::ranges {
template<forward_range V, copy_constructible F, size_t N>
requires view<V> && (N > 0) && is_object_v<F> &&
regular_invocable<F&, /* REPEAT(range_reference_t<V>, N) */...> &&
__CanReference<invoke_result_t<F&, /* REPEAT(range_reference_t<V>, N) */...>>
template<bool Const>
class adjacent_transform_view<F, V...>::iterator {
using Parent = __MaybeConst<Const, adjacent_transform_view>; // solo exposición
using Base = __MaybeConst<Const, V>; // solo exposición
Parent* parent_ = nullptr; // solo exposición
InnerIterator<Const> inner_; // solo exposición
constexpr iterator(Parent& parent, InnerIterator<Const> inner); // solo exposición
public:
using iterator_category = /* véase a continuación */;
using iterator_concept = typename InnerIterator<Const>::iterator_concept;
using value_type =
remove_cvref_t<invoke_result_t<__MaybeConst<Const, F>&,
/* REPEAT(range_reference_t<Base>, N) */...>>;
using difference_type = range_difference_t<Base>;
iterator() = default;
constexpr iterator(iterator<!Const> i)
requires Const && convertible_to<InnerIterator<false>, InnerIterator<Const>>;
constexpr decltype(auto) operator*() const noexcept(/* véase a continuación */);
constexpr iterator& operator++();
constexpr iterator operator++(int);
constexpr iterator& operator--() requires bidirectional_range<Base>;
constexpr iterator operator--(int) requires bidirectional_range<Base>;
constexpr iterator& operator+=(difference_type x) requires random_access_range<Base>;
constexpr iterator& operator-=(difference_type x) requires random_access_range<Base>;
constexpr decltype(auto) operator[](difference_type n) const
requires random_access_range<Base>;
friend constexpr bool operator==(const iterator& x, const iterator& y);
friend constexpr bool operator<(const iterator& x, const iterator& y)
requires random_access_range<Base>;
friend constexpr bool operator>(const iterator& x, const iterator& y)
requires random_access_range<Base>;
friend constexpr bool operator<=(const iterator& x, const iterator& y)
requires random_access_range<Base>;
friend constexpr bool operator>=(const iterator& x, const iterator& y)
requires random_access_range<Base>;
friend constexpr auto operator<=>(const iterator& x, const iterator& y)
requires random_access_range<Base> && three_way_comparable<InnerIterator<Const>>;
friend constexpr iterator operator+(const iterator& i, difference_type n)
requires random_access_range<Base>;
friend constexpr iterator operator+(difference_type n, const iterator& i)
requires random_access_range<Base>;
friend constexpr iterator operator-(const iterator& i, difference_type n)
requires random_access_range<Base>;
friend constexpr difference_type operator-(const iterator& x, const iterator& y)
requires sized_sentinel_for<InnerIterator<Const>, InnerIterator<Const>>;
};
}
Plantilla de clase std::ranges::adjacent_transform_view::sentinel
namespace std::ranges {
template<forward_range V, copy_constructible F, size_t N>
requires view<V> && (N > 0) && is_object_v<F> &&
regular_invocable<F&, REPEAT(range_reference_t<V>, N)...> &&
__CanReference<invoke_result_t<F&, /* REPEAT(range_reference_t<V>, N) */...>>
template<bool Const>
class adjacent_transform_view<V, F, N>::sentinel {
InnerSentinel<Const> inner_; // solo exposición
constexpr explicit sentinel(InnerSentinel<Const> inner); // solo exposición
public:
sentinel() = default;
constexpr sentinel(sentinel<!Const> i)
requires Const && convertible_to<InnerSentinel<false>, InnerSentinel<Const>>;
template<bool OtherConst>
requires sentinel_for<InnerSentinel<Const>, InnerSentinel<OtherConst>>
friend constexpr bool operator==(const iterator<OtherConst>& x, const sentinel& y);
template<bool OtherConst>
requires sized_sentinel_for<InnerSentinel<Const>, InnerSentinel<OtherConst>>
friend constexpr range_difference_t<__MaybeConst<OtherConst, InnerView>>
operator-(const iterator<OtherConst>& x, const sentinel& y);
template<bool OtherConst>
requires sized_sentinel_for<InnerSentinel<Const>, InnerSentinel<OtherConst>>
friend constexpr range_difference_t<__MaybeConst<OtherConst, InnerView>>
operator-(const sentinel& x, const iterator<OtherConst>& y);
};
}
