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); }; }

