C/C++ API Reference
Loading...
Searching...
No Matches
saturating_arithmetic.h
1// Copyright 2025 The Pigweed Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4// use this file except in compliance with the License. You may obtain a copy of
5// the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12// License for the specific language governing permissions and limitations under
13// the License.
14#pragma once
15
16#if __has_include(<version>)
17#include <version>
18#endif // __has_include(<version>)
19
20#ifdef __cpp_lib_saturation_arithmetic
21
22#include <numeric>
23
24namespace pw {
25
27
28using std::add_sat;
29using std::mul_sat;
30
31} // namespace pw
32
33#else
34
35#include <limits>
36#include <type_traits>
37
38#include "pw_numeric/checked_arithmetic.h"
39
40// Polyfills of C++26's saturating arithmetic operations in <numeric>.
41
42namespace pw {
43
45
52template <typename T>
53constexpr T add_sat(T lhs, T rhs) noexcept {
54 static_assert(std::is_integral_v<T>);
55 if (T sum = 0; CheckedAdd(lhs, rhs, sum)) {
56 return sum;
57 }
58 if constexpr (std::is_unsigned_v<T>) {
59 return std::numeric_limits<T>::max();
60 } else { // since it overflowed, the operands had the same sign
61 if (lhs < 0) {
62 return std::numeric_limits<T>::min();
63 }
64 return std::numeric_limits<T>::max();
65 }
66}
67
74template <typename T>
75constexpr T mul_sat(T lhs, T rhs) noexcept {
76 static_assert(std::is_integral_v<T>);
77 if (T product = 0; CheckedMul(lhs, rhs, product)) {
78 return product;
79 }
80 if constexpr (std::is_unsigned_v<T>) {
81 return std::numeric_limits<T>::max();
82 } else { // determine sign of result by comparing signs of the factors
83 if ((lhs < 0) == (rhs < 0)) {
84 return std::numeric_limits<T>::max();
85 }
86 return std::numeric_limits<T>::min();
87 }
88}
89
90} // namespace pw
91
92#endif // __cpp_lib_saturation_arithmetic
constexpr T mul_sat(T lhs, T rhs) noexcept
Definition: saturating_arithmetic.h:75
constexpr T add_sat(T lhs, T rhs) noexcept
Definition: saturating_arithmetic.h:53
constexpr bool CheckedAdd(A a, B b, T &result)
Definition: checked_arithmetic.h:70
constexpr bool CheckedMul(A a, B b, T &result)
Definition: checked_arithmetic.h:206
The Pigweed namespace.
Definition: alignment.h:27