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