Archivo de encabezado de la biblioteca estándar <ranges>
De cppreference.com
Este encabezado es parte de la bibloteca de ranges.
[editar] 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
.
Conceptos | |
Conceptos de rangos | |
Definido en el espacio de nombres
std::ranges | |
Especifica que un tipo es un rango. Es decir, proporciona un iterador begin y un centinela end . (concepto) | |
(C++20) |
Especifica que un tipo es un rango (range ) e iteradores obtenidos a partir de una expresión de él pueden devolverse de forma segura sin peligro de que queden pendientes. (concepto) |
Especifica que un rango conoce su tamaño en tiempo constante. (concepto) | |
Especifica que un rango es una vista. Es decir, realiza copia, movimiento y asignación en tiempo constante. (concepto) | |
Especifica un rango cuyo tipo de iterador satisface a input_iterator . (concepto) | |
Especifica un rango cuyo tipo de iterador satisface a output_iterator . (concepto) | |
Especifica un rango cuyo tipo de iterador satisface a forward_iterator . (concepto) | |
Especifica un rango cuyo tipo de iterador satisface a bidirectional_iterator . (concepto) | |
Especifica un rango cuyo tipo de iterador satisface a random_access_iterator . (concepto) | |
Especifica un rango cuyo tipo de iterador satisface a contiguous_iterator . (concepto) | |
Especifica que un rango tiene tipos de iterador y centinela idénticos. (concepto) | |
Especifica los requerimientos para un rango (range ) para que sea convertible de forma segura a una vista (view ). (concepto) | |
Clases | |
Primitivas de rangos | |
Definido en el espacio de nombres
std::ranges | |
Obtiene los tipos asociados de un rango. (plantilla de alias) | |
Vistas | |
Definido en el espacio de nombres
std::ranges | |
(C++20) |
Plantilla de clase auxiliar para definir una vista (view ), usando el patrón de plantilla curiosamente recurrente (CRTP). (plantilla de clase) |
(C++20) |
Combina un par iterador-centinela en una vista (view ). (plantilla de clase) |
Manejo de iteradores pendientes | |
Definido en el espacio de nombres
std::ranges | |
(C++20) |
Un tipo marcador de posición que indica que un iterador o un subrango (subrange ) no debe devolverse ya que quedaría pendiente. (clase) |
Obtiene el tipo iterador o tipo subrango (subrange ) de un rango prestado (borrowed_range ). (plantilla de alias) | |
Fábricas | |
Definido en el espacio de nombres
std::ranges | |
Una vista (view ) sin elementos. (plantilla de clase) (plantilla de variables) | |
Una vista (view ) que contiene un solo elemento de un valor específico. (plantilla de clase) (objeto punto de personalización) | |
(C++20) |
Una vista (view ) que consiste en una secuencia generada al incrementar repetidamente un valor inicial. (plantilla de clase) (objeto punto de personalización) |
Una vista (view ) que consiste en los elementos obtenidos mediante la aplicación sucesiva del operador de extracción (operator>>) sobre el flujo de entrada asociado. (plantilla de clase) (objeto punto de personalización) | |
Adaptadores | |
Definido en el espacio de nombres
std::ranges | |
(C++20) |
Una vista (view ) que incluye todos los elementos de un rango (range ). (plantilla de alias) (objeto adaptador de rango) |
(C++20) |
Una vista (view ) de los elementos de algún otro rango (range ). (plantilla de clase) |
(C++20) |
Una vista (view ) con propiedad única de algún rango (range ). (plantilla de clase) |
Una vista (view ) que consiste en los elementos de un rango (range ) que satisface un predicado. (plantilla de clase) (objeto adaptador de rango) | |
Una vista (view ) de una secuencia que aplica una función de transformación a cada elemento. (plantilla de clase) (objeto adaptador de rango) | |
(C++20) |
Una vista (view ) que consiste de los primeros N elementos de otra vista. (plantilla de clase) (objeto adaptador de rango) |
Una vista (view ) que consiste en los elementos iniciales de otra vista, hasta el primer elemento sobre el que un predicado devuelva falso. (plantilla de clase) (objeto adaptador de rango) | |
(C++20) |
Una vista (view ) que consiste en los elementos de otra vista, saltándose los primeros N elementos. (plantilla de clase) (objeto adaptador de rango) |
Una vista (view ) que consiste en los elementos de otra vista, saltándose la subsecuencia inicial de elementos hasta el primer elemento donde el predicado devuelva falso. (plantilla de clase) (objeto adaptador de rango) | |
(C++20) |
Una vista (view ) que consiste en la secuencia obtenida al aplanar una vista de rangos (range ). (plantilla de clase) (objeto adaptador de rango) |
Una vista (view ) sobre los subrangos obtenidos al separar otra vista (view ) usando un delimitador. (plantilla de clase) (objeto adaptador de rango) | |
Una vista (view ) sobre los subrangos obtenidos al dividir otra vista usando un delimitador. (plantilla de clase) (objeto adaptador de rango) | |
(C++20) |
Crea un subrango a partir de un iterador y una cuenta. (objeto punto de personalización) |
Convierte una vista (view ) a un rango común (common_range ). (plantilla de clase) (objeto adaptador de rango) | |
Una vista (view ) que itera sobre los elementos de otra vista bidirectional en orden inverso. (plantilla de clase) (objeto adaptador de rango) | |
Toma una vista (view ) que consiste en valores similares a tuplas y a un número N y produce una vista del N-ésimo elemento de cada tupla. (plantilla de clase) (objeto adaptador de rango) | |
(C++20) |
Toma una vista (view ) que consiste en valores similares a pares y produce una vista de los primeros elementos de cada par. (plantilla de clase) (objeto adaptador de rango) |
Toma una vista (view ) que consiste valores similares a pares y produce una vista de los segundos elementos de cada par. (plantilla de clase) (objeto adaptador de rango) | |
(C++23) |
Una vista (view ) que consiste en tuplas o referencias a elementos correspondientes de las vistas adaptadas. (plantilla de clase) (objeto punto de personalización) |
Una vista (view ) que consiste en tuplas del resultado de aplicar una función de transformación a los elementos correspondientes de las vistas adaptadas. (plantilla de clase) (objeto punto de personalización) | |
Una vista (view ) que consiste en tuplas de referencias a elementos adyacentes de la vista adaptada. (plantilla de clase) (objeto adaptador de rango) | |
Una vista (vista) que consiste en tuplas del resultado de aplicar una función de transformación a elementos adyacentes de la vista adaptada. (plantilla de clase) (objeto adaptador de rango) | |
Objetos de punto de personalización | |
Acceso a rangos | |
Definido en el espacio de nombres
std::ranges | |
(C++20) |
Devuelve un iterador al principio de un rango. (objeto punto de personalización) |
(C++20) |
Devuelve un iterador al final de un rango (objeto punto de personalización) |
(C++20) |
Devuelve un iterador al inicio de un rango de solo lectura. (objeto punto de personalización) |
(C++20) |
Devuelve un centinela que indica el fin de un rango de solo lectura (objeto punto de personalización) |
(C++20) |
Devuelve un iterador inverso a un rango (objeto punto de personalización) |
(C++20) |
Devuelve un iterador final inverso a un rango (objeto punto de personalización) |
(C++20) |
Devuelve un iterador inverso a un rango de solo lectura (objeto punto de personalización) |
(C++20) |
Devuelve un iterador inverso al final de un rango de solo lectura (objeto punto de personalización) |
(C++20) |
Obtiene el tamaño de un rango cuyo tamaño puede calcularse en tiempo constante. (objeto punto de personalización) |
(C++20) |
Obtiene el tamaño de un rango cuyo tamaño puede calcularse en tiempo constante y lo convierte a un entero con signo. (objeto punto de personalización) |
(C++20) |
Comprueba si un rango está vacío. (objeto punto de personalización) |
(C++20) |
Obtiene un puntero al principio de un rango contiguo (objeto punto de personalización) |
(C++20) |
Obtiene un puntero al inicio de un rango contiguo de solo lectura (objeto punto de personalización) |
Enumeraciones | |
Definido en el espacio de nombres
std::ranges | |
(C++20) |
Especifica si un subrango (std::ranges::subrange) modela std::ranges::sized_range. (enum) |
[editar] 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; }; }
[editar] 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); }; }
[editar] Concepto sized_range
namespace std::ranges { template< class T > concept sized_range = range<T> && requires(T& t) { ranges::size(t); }; }
[editar] 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>; }
[editar] Concepto output_range
namespace std::ranges { template<class R, class T> concept output_range = range<R> && output_iterator<iterator_t<R>, T>; }
[editar] Concepto input_range
namespace std::ranges { template<class T> concept input_range = range<T> && input_iterator<iterator_t<T>>; }
[editar] Concepto forward_range
namespace std::ranges { template<class T> concept forward_range = input_range<T> && forward_iterator<iterator_t<T>>; }
[editar] Concepto bidirectional_range
namespace std::ranges { template<class T> concept bidirectional_range = forward_range<T> && bidirectional_iterator<iterator_t<T>>; }
[editar] Concepto random_access_range
namespace std::ranges { template<class T> concept random_access_range = bidirectional_range<T> && random_access_iterator<iterator_t<T>>; }
[editar] 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>>>; }; }
[editar] Concepto common_range
namespace std::ranges { template<class T> concept common_range = range<T> && same_as<iterator_t<T>, sentinel_t<T>>; }
[editar] Concepto viewable_range
namespace std::ranges { template<class T> concept viewable_range = range<T> && (borrowed_range<T> || view<remove_cvref_t<T>>); }
[editar] 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.
[editar] 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]; } }; }
[editar] 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; }
[editar] Clase std::ranges::dangling
namespace std::ranges { struct dangling { constexpr dangling() noexcept = default; template<class... Args> constexpr dangling(Args&&...) noexcept { } }; }
[editar] 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; } }; }
[editar] 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; }; }
[editar] 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>; }
[editar] 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>; }; }
[editar] 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>; }; }
[editar] 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 }; }
[editar] 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 }; }
[editar] 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>; }
[editar] 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_); } }; }
[editar] 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>; }
[editar] 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>>; }; }
[editar] 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); }; }
[editar] 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>; }
[editar] 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; } }
[editar] 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>>; }; }
[editar] 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>>; }
[editar] 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); }; }
[editar] 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>; }
[editar] 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); }; }
[editar] 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>>; }
[editar] 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>; }
[editar] 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>>; }
[editar] 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_))); }; }
[editar] 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); }; }
[editar] 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>>>; }
[editar] 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); }; }
[editar] 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; }; }
[editar] 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>>; }; }
[editar] 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>>>; }
[editar] 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); }; }
[editar] 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); }; }
[editar] 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>>; }
[editar] 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>>; }
[editar] 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 }; }
[editar] 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>; }; }
[editar] 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>>; }; }
[editar] 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>...>; }
[editar] 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>>> && ...); }; }
[editar] 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); }; }
[editar] 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>...>; }
[editar] 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>>; }; }
[editar] 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); }; }
[editar] 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>; }; }
[editar] 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>>; }; }
[editar] 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); }; }
[editar] 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(); } }; }
[editar] 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>>; }; }
[editar] 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); }; }