tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

wrapping_math.h (1742B)


      1 // Copyright 2023 The Chromium Authors
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef BASE_NUMERICS_WRAPPING_MATH_H_
      6 #define BASE_NUMERICS_WRAPPING_MATH_H_
      7 
      8 #include <type_traits>
      9 
     10 namespace base {
     11 
     12 // Returns `a + b` with overflow defined to wrap around, i.e. modulo 2^N where N
     13 // is the bit width of `T`.
     14 template <typename T>
     15 inline constexpr T WrappingAdd(T a, T b) {
     16  static_assert(std::is_integral_v<T>);
     17  // Unsigned arithmetic wraps, so convert to the corresponding unsigned type.
     18  // Note that, if `T` is smaller than `int`, e.g. `int16_t`, the values are
     19  // promoted to `int`, which brings us back to undefined overflow. This is fine
     20  // here because the sum of any two `int16_t`s fits in `int`, but `WrappingMul`
     21  // will need a more complex implementation.
     22  using Unsigned = std::make_unsigned_t<T>;
     23  return static_cast<T>(static_cast<Unsigned>(a) + static_cast<Unsigned>(b));
     24 }
     25 
     26 // Returns `a - b` with overflow defined to wrap around, i.e. modulo 2^N where N
     27 // is the bit width of `T`.
     28 template <typename T>
     29 inline constexpr T WrappingSub(T a, T b) {
     30  static_assert(std::is_integral_v<T>);
     31  // Unsigned arithmetic wraps, so convert to the corresponding unsigned type.
     32  // Note that, if `T` is smaller than `int`, e.g. `int16_t`, the values are
     33  // promoted to `int`, which brings us back to undefined overflow. This is fine
     34  // here because the difference of any two `int16_t`s fits in `int`, but
     35  // `WrappingMul` will need a more complex implementation.
     36  using Unsigned = std::make_unsigned_t<T>;
     37  return static_cast<T>(static_cast<Unsigned>(a) - static_cast<Unsigned>(b));
     38 }
     39 
     40 }  // namespace base
     41 
     42 #endif  // BASE_NUMERICS_WRAPPING_MATH_H_