Espacios de nombres
Variantes
Acciones

std::ranges::ends_with

De cppreference.com
< cpp‎ | algorithm‎ | ranges
 
 
Biblioteca de algoritmos
Políticas de ejecución (C++17)
Operaciones de secuencia no modificantes
(C++11)(C++11)(C++11)
(C++17)
Operaciones de secuencia modificantes
Operaciones en almacenamiento no inicializado
Operaciones de partición
Operaciones de ordenación
(C++11)
Operaciones de búsqueda binaria
Operaciones de conjuntos (en rangos ordenados)
Operaciones de pila
(C++11)
Operaciones mínimo/máximo
(C++11)
(C++17)
Permutaciones
Operaciones numéricas
Bibliotecas C
 
Algoritmos restringidos
Operaciones de secuencia no modificantes
Operaciones de secuencia modificantes
Operaciones en almacenamiento sin inicializar
Operaciones de partición
Operaciones de ordenamiento
Operaciones de búsqueda binaria
Operaciones de conjuntos (en rangos ordenados)
Operaciones de montículo/montón
Operaciones de mínimo/máximo
Permutaciones
 
Definido en el archivo de encabezado <algorithm>
Signatura de la llamada
template< std::input_iterator I1, std::sentinel_for<I1> S1,

          std::input_iterator I2, std::sentinel_for<I2> S2,
          class Pred = ranges::equal_to,
          class Proj1 = std::identity, class Proj2 = std::identity >
requires (std::forward_iterator<I1> || std::sized_sentinel_for<S1, I1>) &&
         (std::forward_iterator<I2> || std::sized_sentinel_for<S2, I2>) &&
         std::indirectly_comparable<I1, I2, Pred, Proj1, Proj2>
constexpr bool ends_with( I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {},

                          Proj1 proj1 = {}, Proj2 proj2 = {} );
(1) (desde C++23)
template< ranges::input_range R1, ranges::input_range R2,

          class Pred = ranges::equal_to,
          class Proj1 = std::identity, class Proj2 = std::identity >
requires (ranges::forward_range<R1> || ranges::sized_range<R1>) &&
         (ranges::forward_range<R2> || ranges::sized_range<R2>) &&
         std::indirectly_comparable<ranges::iterator_t<R1>,
                                    ranges::iterator_t<R2>,
                                    Pred, Proj1, Proj2>
constexpr bool ends_with( R1&& r1, R2&& r2, Pred pred = {},

                          Proj1 proj1 = {}, Proj2 proj2 = {} );
(2) (desde C++23)

Comprueba si el segundo rango coincide con el sufijo del primer rango.

1) Sea N1 y N2 sea ranges::distance(first1, last1) y ranges::distance(first2, last2) respectivamente. Si N1 < N2, devuelve false. De lo contrario, devuelve true solo si cada elemento en el rango [first2last2) es igual al elemento correspondiente en [first1 + N1 - N2last1). La comparación se hace aplicando el predicado binario pred a los elementos en dos rangos proyectados por proj1 y proj2 respectivamente.
2) Igual que (1), pero usa r1 y r2 como los rangos fuente, como si usara ranges::begin(r1) como first1, ranges:begin(r2) como first2, ranges::end(r1) como last1, y ranges::end(r2) como last2.

Las entidades similares a funciones descritas en esta página son niebloids, es decir:

En la práctica, pueden implementarse como objetos función o con extensiones de compilador especiales.

Contenido

[editar] Parámetros

first1, last1 - El rango de los elementos a examinar.
r1 - El rango de los elementos a examinar.
first2, last2 - El rango de los elementos a usar como el sufijo.
r2 - El rango de los elementos a usar como el sufijo.
pred - El predicado binario que compara los elementos proyectados.
proj1 - La proyección a aplicar a los elementos del rango a examinar.
proj2 - La proyección a aplicar a los elementos del rango a usar como el sufijo.

[editar] Valor de retorno

true si el segundo rango coincide con el sufijo del primer rango, false de lo contrario.

[editar] Complejidad

Generalmente lineal: a lo sumo min(N1, N2) aplicaciones del predicado y ambas proyecciones. El predicado y ambas proyecciones no se aplican si N1 < N2.

Si tanto N1 como N2 se pueden calcular en tiempo constante (es decir, ambos pares de tipo iterador-centinela modelan sized_sentinel_for, o ambos tipos de rango modelan sized_range) y N1 < N2, la complejidad del tiempo es constante.

[editar] Posible implementación

struct ends_with_fn
{
    template<std::input_iterator I1, std::sentinel_for<I1> S1,
             std::input_iterator I2, std::sentinel_for<I2> S2,
             class Pred = ranges::equal_to,
             class Proj1 = std::identity, class Proj2 = std::identity>
    requires (std::forward_iterator<I1> || std::sized_sentinel_for<S1, I1>) &&
             (std::forward_iterator<I2> || std::sized_sentinel_for<S2, I2>) &&
             std::indirectly_comparable<I1, I2, Pred, Proj1, Proj2>
    constexpr bool operator()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {},
                              Proj1 proj1 = {}, Proj2 proj2 = {}) const
    {
        const auto n1 = ranges::distance(first1, last1);
        const auto n2 = ranges::distance(first2, last2);
        if (n1 < n2)
            return false;
        ranges::advance(first1, n1 - n2);
        return ranges::equal(std::move(first1), std::move(last1),
                             std::move(first2), std::move(last2),
                             std::move(pred), std::move(proj1), std::move(proj2));
    }
 
    template<ranges::input_range R1, ranges::input_range R2,
             class Pred = ranges::equal_to,
             class Proj1 = std::identity, class Proj2 = std::identity>
    requires (ranges::forward_range<R1> || ranges::sized_range<R1>) &&
             (ranges::forward_range<R2> || ranges::sized_range<R2>) &&
             std::indirectly_comparable<ranges::iterator_t<R1>,
                                        ranges::iterator_t<R2>,
                                        Pred, Proj1, Proj2>
    constexpr bool operator()(R1&& r1, R2&& r2, Pred pred = {},
                              Proj1 proj1 = {}, Proj2 proj2 = {}) const
    {
        return (*this)(ranges::begin(r1), ranges::end(r1),
                       ranges::begin(r2), ranges::end(r2),
                       std::move(pred), std::move(proj1), std::move(proj2));
    }
};
 
inline constexpr ends_with_fn ends_with {};

[editar] Notas

Macro de Prueba de característica Valor Estándar Comentario
__cpp_lib_ranges_starts_ends_with 202106L (C++23) std::ranges::starts_with, std::ranges::ends_with

[editar] Ejemplo

#include <algorithm>
#include <array>
#include <iostream>
 
int main()
{
    std::cout
        << std::boolalpha
        << std::ranges::ends_with("static_cast", "cast") << '\n'
        << std::ranges::ends_with("const_cast", "cast") << '\n'
        << std::ranges::ends_with("reinterpret_cast", "cast") << '\n'
        << std::ranges::ends_with("dynamic_cast", "cast") << '\n'
        << std::ranges::ends_with("move", "cast") << '\n'
        << std::ranges::ends_with("move_if_noexcept", "cast") << '\n'
        << std::ranges::ends_with("forward", "cast") << '\n';
    static_assert(
        !  std::ranges::ends_with("as_const", "cast") and
        !! std::ranges::ends_with("bit_cast", "cast") and
        !  std::ranges::ends_with("to_underlying", "cast") and
        !! std::ranges::ends_with(std::array {1,2,3,4}, std::array {3,4}) and
        !  std::ranges::ends_with(std::array {1,2,3,4}, std::array {4,5})
        );
}

Salida:

true
true
true
true
false
false
false

[editar] Véase también

Verifica si un rango comienza con otro rango.
(niebloid) [editar]
(C++20)
Comprueba si la cadena termina con el sufijo dado
(función miembro pública de std::basic_string) [editar]
(C++20)
Comprueba si la vista sobre cadena termina con un sufijo dado.
(función miembro pública de std::basic_string_view<CharT,Traits>) [editar]