Namespaces
Variants

std::ranges:: clamp

From cppreference.net
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy , ranges::sort , ...
Execution policies (C++17)
Non-modifying sequence operations
Batch operations
(C++17)
Search operations
Modifying sequence operations
Copy operations
(C++11)
(C++11)
Swap operations
Transformation operations
Generation operations
Removing operations
Order-changing operations
(until C++17) (C++11)
(C++20) (C++20)
Sampling operations
(C++17)

Sorting and related operations
Partitioning operations
Sorting operations
Binary search operations
(on partitioned ranges)
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Lexicographical comparison operations
Permutation operations
C library
Numeric operations
Operations on uninitialized memory
Constrained algorithms
All names in this menu belong to namespace std::ranges
Non-modifying sequence operations
Modifying sequence operations
Partitioning operations
Sorting operations
Binary search operations (on sorted ranges)
Set operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Permutation operations
Fold operations
Operations on uninitialized storage
Return types
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 std:: invoke ( proj, v ) se situe dans l'intervalle [ std:: invoke ( proj, lo ) , std:: invoke ( proj, hi ) ] , retourne v ; sinon retourne la limite la plus proche.

Le comportement n'est pas défini si std:: invoke ( proj, lo ) est supérieur à std:: invoke ( proj, hi ) .

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

Table des matières

Paramètres

v - la valeur à limiter
lo, hi - les bornes entre lesquelles limiter 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 maximum 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

Capturing the result of std::ranges::clamp by reference produces a dangling reference if one of the parameters is a temporary and that parameter is returned:
int n = -1;
const int& r = std::ranges::clamp(n, 0, 255); // r est pendante

Si v est équivalent à l'une des bornes, retourne une référence à v , et non à la borne.

Cette fonction ne doit 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 modifiait 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é que sur v une seule 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 à ceci 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 << "[brut] [" << 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';
    // Fonction de projection
    const auto stoi = [](std::string s) { return std::stoi(s); };
    // Identique au-dessus, mais avec des chaînes
    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 :

[brut] [-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

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