# std::clamp

From cppreference.com
< cpp‎ | algorithm

Defined in header `<algorithm>` |  |
template<class T> constexpr const T& clamp( const T& v, const T& lo, const T& hi ); | (1) | (since C++17)
template<class T, class Compare> constexpr const T& clamp( const T& v, const T& lo, const T& hi, Compare comp ); | (2) | (since C++17)

1) If `v` compares less than `lo`, returns `lo`; otherwise if `hi` compares less than `v`, returns `hi`; otherwise returns `v`. Uses operator< to compare the values.
2) Same as (1), but uses `comp` to compare the values.

The behavior is undefined if the value of `lo` is greater than `hi`

### Parameters

v | - | the value to clamp
lo,hi | - | the boundaries to clamp `v` to
comp | - | comparison function object (i.e. an object that satisfies the requirements of Compare) which returns ​true if the first argument is less than the second. The signature of the comparison function should be equivalent to the following: bool cmp(const Type1 &a, const Type2 &b); While the signature does not need to have const &, the function must not modify the objects passed to it and must be able to accept all values of type (possibly const) `Type1` and `Type2` regardless of value category (thus, Type1 & is not allowed, nor is Type1 unless for `Type1` a move is equivalent to a copy (since C++11)). The types Type1 and Type2 must be such that an object of type T can be implicitly converted to both of them. ​
Type requirements
- `T` must meet the requirements of LessThanComparable in order to use overloads (1).

### Return value

Reference to `lo` if `v` is less than `lo`, reference to `hi` if `hi` is less than `v`, otherwise reference to `v`.

### Complexity

At most two comparisons.

### Possible implementation

First version
    template<class T>
    constexpr const T& clamp( const T& v, const T& lo, const T& hi )
    {
        return clamp( v, lo, hi, std::less<>() );
    }
Second version
    template<class T, class Compare>
    constexpr const T& clamp( const T& v, const T& lo, const T& hi, Compare comp )
    {
        return assert( !comp(hi, lo) ),
            comp(v, lo) ? lo : comp(hi, v) ? hi : v;
    }

### Notes

Capturing the result of `std::clamp` by reference if one of the parameters is rvalue produces a dangling reference if that parameter is returned:

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

If `v` compares equivalent to either bound, returns a reference to `v`, not the bound.

Only works for floating-point `T` if `NaN`s are avoided.

### Example

Run this code

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

    int main()
    {
        std::mt19937 g(std::random_device{}());
        std::uniform_int_distribution<> d(-300, 300);
        std::cout << " raw   clamped to int8_t   clamped to uint8_t\n";
        for(int n = 0; n < 5; ++n) {
            int v = d(g);
            std::cout << std::setw(4) << v
                      << std::setw(20) << std::clamp(v, INT8_MIN, INT8_MAX)
                      << std::setw(21) << std::clamp(v, 0, UINT8_MAX) << '\n';
        }
    }

Possible output:

    .raw   clamped to int8_t   clamped to uint8_t
     168                 127                  168
     128                 127                  128
    -137                -128                    0
      40                  40                   40
     -66                 -66                    0

### See also

min | returns the smaller of the given values (function template)
max | returns the greater of the given values (function template)

Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/algorithm/clamp&oldid=103572"