Namespaces
Variants

std::ranges::clamp

De fr.cppreference.net
 
 
Bibliothèque d'algorithmes
Algorithmes contraints et algorithmes sur plages (C++20)
Algorithmes contraints, p. ex. ranges::copy, ranges::sort, ...
Opérations de séquence non modifiantes    
Opérations par lot
(C++17)
Opérations de recherche
Opérations de séquence modifiantes
Opérations de copie
(C++11)
(C++11)
Opérations d'échange
Opérations de transformation
Opérations de génération
Opérations de suppression
Opérations de changement d'ordre
(jusqu'à C++17)(C++11)
(C++20)(C++20)
Opérations d'échantillonnage
(C++17)

Tri et opérations connexes
Opérations de partitionnement
(C++11)    

Opérations de tri
Opérations de recherche binaire
(sur plages partitionnées)
Opérations ensemblistes (sur plages triées)
Opérations de fusion (sur plages triées)
Opérations de tas
Opérations minimum/maximum
(C++11)
(C++17)
Opérations de comparaison lexicographique
Opérations de permutation


 
Algorithmes contraints
Tous les noms de ce menu appartiennent à l'espace de noms std::ranges
Opérations de séquence non modifiantes
Opérations de séquence modifiantes
Opérations de partitionnement
Opérations de tri
Opérations de recherche binaire (sur plages triées)
       
       
Opérations ensemblistes (sur plages triées)
Opérations de tas
Opérations minimum/maximum
       
       
Opérations de permutation
Opérations de pliage
Opérations sur le stockage non initialisé
Types de retour
 
Défini dans l'en-tête <algorithm>
Signature d'appel
template< class T, class Proj = std::identity,
          std::indirect_strict_weak_order<std::projected<const T*, Proj>> Comp =
              ranges::less >
constexpr const T&
    clamp( const T& v, const T& lo, const T& hi, Comp comp = {}, Proj proj = {} );
(depuis C++20)

Si la valeur de v est comprise entre [lohi], retourne v ; sinon retourne la limite la plus proche.

Le comportement est indéfini si lo est supérieur à hi.

Les entités de type fonction décrites sur cette page sont des objets fonctions d'algorithmes (informellement appelés niebloides), c'est-à-dire :

Paramètres

v - la valeur à clamper
lo, hi - les limites entre lesquelles clamper v (v)
comp - la comparaison à appliquer aux éléments projetés
proj - la projection à appliquer à v, lo et hi

Valeur de retour

Référence à lo si la valeur projetée de v est inférieure à la valeur projetée de lo, référence à hi si la valeur projetée de hi est inférieure à la valeur projetée de v, sinon référence à v.

Complexité

Au plus deux comparaisons et trois applications de la projection.

Implémentation possible

struct clamp_fn
{
    template<class T, class Proj = std::identity,
             std::indirect_strict_weak_order<std::projected<const T*, Proj>>
                 Comp = std::ranges::less>
    constexpr const T& operator()(const T& v, const T& lo, const T& hi,
                                  Comp comp = {}, Proj proj = {}) const
    {
        auto&& pv = std::invoke(proj, v);

        if (std::invoke(comp, std::forward<decltype(pv)>(pv), std::invoke(proj, lo)))
            return lo;

        if (std::invoke(comp, std::invoke(proj, hi), std::forward<decltype(pv)>(pv)))
            return hi;

        return v;
    }
};

inline constexpr clamp_fn clamp;

Notes

Capturer le résultat de std::ranges::clamp par référence produit une référence pendante si l'un des paramètres est une temporaire et que ce paramètre est retourné :

int n = -1;
const int& r = std::ranges::clamp(n, 0, 255); // r is dangling

Si v est équivalent à l'une ou l'autre limite, retourne une référence à v, pas à la limite.

Cette fonction ne devrait pas être utilisée avec à la fois une projection qui retourne par valeur et un comparateur qui prend des arguments par valeur à moins qu'un déplacement du type de résultat de la projection vers le type de paramètre du comparateur soit équivalent à une copie. Si la comparaison via std::invoke modifie le résultat de la projection, le comportement est indéfini en raison de des exigences sémantiques de std::regular_invocable (subsumées par std::indirect_strict_weak_order).

La norme exige que la catégorie de valeur du résultat de la projection soit préservée, et proj ne peut être appelé sur v qu'une fois, ce qui signifie qu'un résultat de projection qui est une prvalue doit être mis en cache et déplacé deux fois pour les deux appels au comparateur.

  • libstdc++ n'est pas conforme à cela et passe toujours le résultat de la projection comme une lvalue.
  • libc++ exécutait auparavant la projection deux fois, ce qui a été corrigé dans Clang 18.
  • MSVC STL exécutait auparavant la projection deux fois, ce qui a été corrigé dans VS 2022 17.2.

Exemple

#include <algorithm>
#include <cstdint>
#include <iomanip>
#include <iostream>
#include <string>

using namespace std::literals;
namespace ranges = std::ranges;

int main()
{
    std::cout << "[raw] [" << INT8_MIN << ',' << INT8_MAX << "] "
                 "[0" << ',' << UINT8_MAX << "]\n";
    for (int const v : {-129, -128, -1, 0, 42, 127, 128, 255, 256})
        std::cout << std::setw(4) << v
                  << std::setw(11) << ranges::clamp(v, INT8_MIN, INT8_MAX)
                  << std::setw(8) << ranges::clamp(v, 0, UINT8_MAX) << '\n';
    std::cout << std::string(23, '-') << '\n';

    // Projection function
    const auto stoi = [](std::string s) { return std::stoi(s); };

    // Same as above, but with strings
    for (std::string const v : {"-129", "-128", "-1", "0", "42",
                                "127", "128", "255", "256"})
        std::cout << std::setw(4) << v
                  << std::setw(11) << ranges::clamp(v, "-128"s, "127"s, {}, stoi)
                  << std::setw(8) << ranges::clamp(v, "0"s, "255"s, {}, stoi)
                  << '\n';
}

Sortie :

[raw] [-128,127] [0,255]
-129       -128       0
-128       -128       0
  -1         -1       0
   0          0       0
  42         42      42
 127        127     127
 128        127     128
 255        127     255
 256        127     255
-----------------------
-129       -128       0
-128       -128       0
  -1         -1       0
   0          0       0
  42         42      42
 127        127     127
 128        127     128
 255        127     255
 256        127     255

Voir aussi

retourne la plus petite des valeurs données
(objet fonction algorithme)
retourne la plus grande des valeurs données
(objet fonction algorithme)
(C++20)
vérifie si une valeur entière est dans l'intervalle d'un type entier donné
(modèle de fonction)
(C++17)
clamp une valeur entre une paire de valeurs limites
(modèle de fonction)