Namespaces
Variants

std:: add_sat

From cppreference.net
Saturation arithmetic
Functions
add_sat
(C++26)
(C++26)
(C++26)
(C++26)
Определено в заголовке <numeric>
template < class T >
constexpr T add_sat ( T x, T y ) noexcept ;
(начиная с C++26)

Вычисляет насыщающее сложение x + y . Эта операция (в отличие от встроенных арифметических операций над целыми числами ) ведёт себя так, как если бы это была математическая операция с бесконечным диапазоном. Пусть q обозначает результат такой операции. Возвращает:

  • q , если q может быть представлено как значение типа T . В противном случае,
  • наибольшее или наименьшее значение типа T , в зависимости от того, какое из них ближе к q .

Эта перегрузка участвует в разрешении перегрузки только если T является целочисленным типом , то есть: signed char , short , int , long , long long , расширенным знаковым целочисленным типом или беззнаковой версией таких типов. В частности, T не должен быть (возможно, cv-квалифицированным) bool , char , wchar_t , char8_t , char16_t , и char32_t , так как эти типы не предназначены для арифметических операций.

Содержание

Параметры

x, y - целочисленные значения

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

Насыщенное x + y .

Примечания

В отличие от встроенных арифметических операторов для целых чисел, integral promotion не применяется к аргументам x и y .

Если переданы два аргумента разного типа, вызов не компилируется, т.е. поведение относительно вывода аргументов шаблона такое же, как для std::min или std::max .

Большинство современных аппаратных архитектур имеют эффективную поддержку насыщающей арифметики для SIMD векторов , включая SSE2 для x86 и NEON для ARM .

Макрос тестирования возможностей Значение Стандарт Возможность
__cpp_lib_saturation_arithmetic 202311L (C++26) Арифметика с насыщением

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

См. libstdc++ (gcc) .

Пример

Может быть просмотрено на Compiler Explorer .

#include <climits>
#include <limits>
#include <numeric>
static_assert(CHAR_BIT == 8);
static_assert(UCHAR_MAX == 255);
int main()
{
    constexpr int a = std::add_sat(3, 4); // насыщения не происходит, T = int
    static_assert(a == 7);
    constexpr unsigned char b = std::add_sat<unsigned char>(UCHAR_MAX, 4); // насыщение
    static_assert(b == UCHAR_MAX);
    constexpr unsigned char c = std::add_sat(UCHAR_MAX, 4); // нет насыщения, T = int
        // add_sat(int, int) возвращает int tmp == 259,
        // затем присваивание усекает 259 % 256 == 3
    static_assert(c == 3);
//  unsigned char d = std::add_sat(252, c); // Ошибка: противоречивые выводы для T
    constexpr unsigned char e = std::add_sat<unsigned char>(251, a); // насыщение
    static_assert(e == UCHAR_MAX);
        // 251 имеет тип T = unsigned char, `a` преобразуется в значение unsigned char;
        // может вызвать предупреждение о преобразовании int -> unsigned char для `a`
    constexpr signed char f = std::add_sat<signed char>(-123, -3); // нет насыщения
    static_assert(f == -126);
    constexpr signed char g = std::add_sat<signed char>(-123, -13); // насыщение
    static_assert(g == std::numeric_limits<signed char>::min()); // g == -128
}

Смотрите также

(C++26)
операция насыщающего вычитания для двух целых чисел
(шаблон функции)
(C++26)
операция насыщающего умножения для двух целых чисел
(шаблон функции)
(C++26)
операция насыщающего деления для двух целых чисел
(шаблон функции)
возвращает целочисленное значение, ограниченное диапазоном другого целочисленного типа
(шаблон функции)
(C++17)
ограничивает значение между парой граничных значений
(шаблон функции)
(C++20)
проверяет, находится ли целочисленное значение в диапазоне заданного целочисленного типа
(шаблон функции)
[static]
возвращает наименьшее конечное значение заданного не-вещественного типа или наименьшее положительное нормализованное значение заданного вещественного типа
(открытая статическая функция-член std::numeric_limits<T> )
[static]
возвращает наибольшее конечное значение заданного типа
(открытая статическая функция-член std::numeric_limits<T> )

Внешние ссылки

1. Безусловная реализация насыщающей арифметики — Locklessinc.com, 2012
2. C++ Weekly - Эпизод 459 - Насыщающие математические операции в C++26 — Youtube.com, 2024-12-16