tor-browser

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

Uint8Clamped.h (4974B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * vim: set ts=8 sts=2 et sw=2 tw=80:
      3 * This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef vm_Uint8Clamped_h
      8 #define vm_Uint8Clamped_h
      9 
     10 #include <algorithm>
     11 #include <limits>
     12 #include <limits.h>
     13 #include <stdint.h>
     14 #include <type_traits>
     15 
     16 namespace js {
     17 
     18 extern uint32_t ClampDoubleToUint8(const double x);
     19 
     20 class uint8_clamped final {
     21  uint8_t val;
     22 
     23  template <typename IntT>
     24  static constexpr uint8_t ClampIntToUint8(IntT x) {
     25    static_assert(std::is_integral_v<IntT>);
     26 
     27    if constexpr (std::numeric_limits<IntT>::max() < 255) {
     28      return std::clamp<IntT>(x, 0, std::numeric_limits<IntT>::max());
     29    } else {
     30      return std::clamp<IntT>(x, 0, 255);
     31    }
     32  }
     33 
     34 public:
     35  constexpr uint8_clamped() = default;
     36  constexpr uint8_clamped(const uint8_clamped&) = default;
     37 
     38  constexpr explicit uint8_clamped(uint8_t x) : val(x) {}
     39  constexpr explicit uint8_clamped(uint16_t x) : val(ClampIntToUint8(x)) {}
     40  constexpr explicit uint8_clamped(uint32_t x) : val(ClampIntToUint8(x)) {}
     41  constexpr explicit uint8_clamped(uint64_t x) : val(ClampIntToUint8(x)) {}
     42  constexpr explicit uint8_clamped(int8_t x) : val(ClampIntToUint8(x)) {}
     43  constexpr explicit uint8_clamped(int16_t x) : val(ClampIntToUint8(x)) {}
     44  constexpr explicit uint8_clamped(int32_t x) : val(ClampIntToUint8(x)) {}
     45  constexpr explicit uint8_clamped(int64_t x) : val(ClampIntToUint8(x)) {}
     46  explicit uint8_clamped(double x) : val(uint8_t(ClampDoubleToUint8(x))) {}
     47 
     48  constexpr uint8_clamped& operator=(const uint8_clamped&) = default;
     49 
     50  // Invoke constructors for the assignment helpers.
     51 
     52  constexpr uint8_clamped& operator=(uint8_t x) {
     53    *this = uint8_clamped{x};
     54    return *this;
     55  }
     56 
     57  constexpr uint8_clamped& operator=(uint16_t x) {
     58    *this = uint8_clamped{x};
     59    return *this;
     60  }
     61 
     62  constexpr uint8_clamped& operator=(uint32_t x) {
     63    *this = uint8_clamped{x};
     64    return *this;
     65  }
     66 
     67  constexpr uint8_clamped& operator=(uint64_t x) {
     68    *this = uint8_clamped{x};
     69    return *this;
     70  }
     71 
     72  constexpr uint8_clamped& operator=(int8_t x) {
     73    *this = uint8_clamped{x};
     74    return *this;
     75  }
     76 
     77  constexpr uint8_clamped& operator=(int16_t x) {
     78    *this = uint8_clamped{x};
     79    return *this;
     80  }
     81 
     82  constexpr uint8_clamped& operator=(int32_t x) {
     83    *this = uint8_clamped{x};
     84    return *this;
     85  }
     86 
     87  constexpr uint8_clamped& operator=(int64_t x) {
     88    *this = uint8_clamped{x};
     89    return *this;
     90  }
     91 
     92  uint8_clamped& operator=(const double x) {
     93    *this = uint8_clamped{x};
     94    return *this;
     95  }
     96 
     97  constexpr operator uint8_t() const { return val; }
     98 };
     99 
    100 static_assert(sizeof(uint8_clamped) == 1,
    101              "uint8_clamped must be layout-compatible with uint8_t");
    102 
    103 static_assert(std::is_trivial_v<uint8_clamped>,
    104              "uint8_clamped must be trivial to be eligible for memcpy/memset "
    105              "optimizations");
    106 
    107 }  // namespace js
    108 
    109 template <>
    110 class std::numeric_limits<js::uint8_clamped> {
    111 public:
    112  static constexpr bool is_specialized = true;
    113  static constexpr bool is_signed = false;
    114  static constexpr bool is_integer = true;
    115  static constexpr bool is_exact = true;
    116  static constexpr bool has_infinity = false;
    117  static constexpr bool has_quiet_NaN = false;
    118  static constexpr bool has_signaling_NaN = false;
    119  static constexpr std::float_denorm_style has_denorm = std::denorm_absent;
    120  static constexpr bool has_denorm_loss = false;
    121  static constexpr std::float_round_style round_style = std::round_toward_zero;
    122  static constexpr bool is_iec559 = false;
    123  static constexpr bool is_bounded = true;
    124  static constexpr bool is_modulo = false;
    125  static constexpr int digits = CHAR_BIT;
    126  static constexpr int digits10 = int(digits * /* std::log10(2) */ 0.30102999);
    127  static constexpr int max_digits10 = 0;
    128  static constexpr int radix = 2;
    129  static constexpr int min_exponent = 0;
    130  static constexpr int min_exponent10 = 0;
    131  static constexpr int max_exponent = 0;
    132  static constexpr int max_exponent10 = 0;
    133  static constexpr bool traps = true;
    134  static constexpr bool tinyness_before = false;
    135 
    136  static constexpr auto min() noexcept { return js::uint8_clamped{0}; }
    137  static constexpr auto lowest() noexcept { return min(); }
    138  static constexpr auto max() noexcept { return js::uint8_clamped{255}; }
    139  static constexpr auto epsilon() noexcept { return js::uint8_clamped{0}; }
    140  static constexpr auto round_error() noexcept { return js::uint8_clamped{0}; }
    141  static constexpr auto infinity() noexcept { return js::uint8_clamped{0}; }
    142  static constexpr auto quiet_NaN() noexcept { return js::uint8_clamped{0}; }
    143  static constexpr auto signaling_NaN() noexcept {
    144    return js::uint8_clamped{0};
    145  }
    146  static constexpr auto denorm_min() noexcept { return js::uint8_clamped{0}; }
    147 };
    148 
    149 #endif  // vm_Uint8Clamped_h