std::ranges:: clamp
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
=
|
(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 :
- Les listes d'arguments de modèle explicites ne peuvent pas être spécifiées lors de l'appel de l'une d'entre elles.
- Aucune d'entre elles n'est visible pour la recherche dépendante des arguments .
- Lorsque l'une d'entre elles est trouvée par la recherche non qualifiée normale comme nom à gauche de l'opérateur d'appel de fonction, la recherche dépendante des arguments est inhibée.
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
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
|
(C++20)
|
renvoie la plus petite des valeurs données
(objet fonction algorithme) |
|
(C++20)
|
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) |