Spec-Zone.ru › C++

std::clamp

Определено в заголовке <algorithm>
template< class T >
constexpr const T& clamp( const T& v, const T& lo, const T& hi );
(1) (с C++17)
template< class T, class Compare >
constexpr const T& clamp( const T& v, const T& lo, const T& hi, Compare comp );
(2) (с C++17)
1) Если v меньше lo, возвращает lo; в противном случае, если hi меньше v, возвращает hi; в противном случае, возвращает v.
Использует operator< для сравнения значений.
2) Аналогично (1), но использует comp для сравнения значений.

Поведение не определено, если значение lo больше hi.

Параметры

v - значение, которое необходимо ограничить
lo,hi - пределы, для ограничения значения v
comp - объект-функция сравнения (т.е. объект, удовлетворяющий требованиям Compare), который возвращает true, если первый аргумент меньше второго.

Подпись функции сравнения должна быть эквивалентной следующей:

bool cmp(const Type1& a, const Type2& b);

Хотя подпись не обязательно должна содержать const&, функция не должна изменять объекты, переданные ей, и должна быть способна принимать все значения типа (возможно, const) Type1 и Type2 независимо от категории значения (следовательно, Type1& недопустимо, а также Type1 если для Type1 перемещение эквивалентно копированию(с C++11)).
Типы Type1 и Type2 должны быть такими, чтобы объект типа T можно было неявно преобразовать в оба из них.

Требования к типу
-T должен удовлетворять требованиям LessThanComparable для использования перегрузок (1). Однако, если NaN избегается, T может быть типом с плавающей точкой.

Возвращаемое значение

Ссылка на lo если v меньше lo, ссылка на hi если hi меньше v, в противном случае ссылка на v.

Сложность

Максимум две сравнения.

Возможная реализация

clamp (1)
template<class T>
constexpr const T& clamp(const T& v, const T& lo, const T& hi)
{
    return clamp(v, lo, hi, less{});
}
clamp (2)
template<class T, class Compare>
constexpr const T& clamp(const T& v, const T& lo, const T& hi, Compare comp)
{
    return comp(v, lo) ? lo : comp(hi, v) ? hi : v;
}

Примечания

Получение результата std::clamp по ссылке создаёт висячую ссылку, если один из параметров является временным, и этот параметр возвращается:
int n = -1;
const int& r = std::clamp(n, 0, 255); // r is dangling

Если v эквивалентен одному из пределов, возвращается ссылка на v, а не на предел.

Макрокоманда проверки возможностей Значение Std Возможность
__cpp_lib_clamp 201603L (C++17) std::clamp

Пример

#include <algorithm>
#include <cstdint>
#include <iomanip>
#include <iostream>
 
int main()
{
    std::cout << " raw   clamped to int8_t   clamped to uint8_t\n";
    for (const int v : {-129, -128, -1, 0, 42, 127, 128, 255, 256})
    {
        std::cout 
            << std::setw(04) << v
            << std::setw(20) << std::clamp(v, INT8_MIN, INT8_MAX)
            << std::setw(21) << std::clamp(v, 0, UINT8_MAX) << '\n';
    }
}

Вывод:

 raw   clamped to int8_t   clamped to uint8_t
-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

См. также

min
возвращает меньшее из заданных значений
(шаблон функции)
max
возвращает большее из заданных значений
(шаблон функции)
in_range
(C++20)
проверяет, находится ли целочисленное значение в диапазоне заданного целочисленного типа
(шаблон функции)
ranges::clamp
(C++20)
ограничивает значение между двумя границами
(niebloid)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/algorithm/clamp

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API