tor-browser

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

double-conversion-utils.h (16050B)


      1 // © 2018 and later: Unicode, Inc. and others.
      2 // License & terms of use: http://www.unicode.org/copyright.html
      3 //
      4 // From the double-conversion library. Original license:
      5 //
      6 // Copyright 2010 the V8 project authors. All rights reserved.
      7 // Redistribution and use in source and binary forms, with or without
      8 // modification, are permitted provided that the following conditions are
      9 // met:
     10 //
     11 //     * Redistributions of source code must retain the above copyright
     12 //       notice, this list of conditions and the following disclaimer.
     13 //     * Redistributions in binary form must reproduce the above
     14 //       copyright notice, this list of conditions and the following
     15 //       disclaimer in the documentation and/or other materials provided
     16 //       with the distribution.
     17 //     * Neither the name of Google Inc. nor the names of its
     18 //       contributors may be used to endorse or promote products derived
     19 //       from this software without specific prior written permission.
     20 //
     21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     32 
     33 // ICU PATCH: ifdef around UCONFIG_NO_FORMATTING
     34 #include "unicode/utypes.h"
     35 #if !UCONFIG_NO_FORMATTING
     36 
     37 #ifndef DOUBLE_CONVERSION_UTILS_H_
     38 #define DOUBLE_CONVERSION_UTILS_H_
     39 
     40 // Use DOUBLE_CONVERSION_NON_PREFIXED_MACROS to get unprefixed macros as was
     41 // the case in double-conversion releases prior to 3.1.6
     42 
     43 #include <cstdlib>
     44 #include <cstring>
     45 
     46 // For pre-C++11 compatibility
     47 #if __cplusplus >= 201103L
     48 #define DOUBLE_CONVERSION_NULLPTR nullptr
     49 #else
     50 #define DOUBLE_CONVERSION_NULLPTR NULL
     51 #endif
     52 
     53 // ICU PATCH: Use U_ASSERT instead of <assert.h>
     54 #include "uassert.h"
     55 #ifndef DOUBLE_CONVERSION_ASSERT
     56 #define DOUBLE_CONVERSION_ASSERT(condition)         \
     57    U_ASSERT(condition)
     58 #endif
     59 #if defined(DOUBLE_CONVERSION_NON_PREFIXED_MACROS) && !defined(ASSERT)
     60 #define ASSERT DOUBLE_CONVERSION_ASSERT
     61 #endif
     62 
     63 #ifndef DOUBLE_CONVERSION_UNIMPLEMENTED
     64 #define DOUBLE_CONVERSION_UNIMPLEMENTED() (abort())
     65 #endif
     66 #if defined(DOUBLE_CONVERSION_NON_PREFIXED_MACROS) && !defined(UNIMPLEMENTED)
     67 #define UNIMPLEMENTED DOUBLE_CONVERSION_UNIMPLEMENTED
     68 #endif
     69 
     70 #ifndef DOUBLE_CONVERSION_NO_RETURN
     71 #ifdef _MSC_VER
     72 #define DOUBLE_CONVERSION_NO_RETURN __declspec(noreturn)
     73 #else
     74 #define DOUBLE_CONVERSION_NO_RETURN __attribute__((noreturn))
     75 #endif
     76 #endif
     77 #if defined(DOUBLE_CONVERSION_NON_PREFIXED_MACROS) && !defined(NO_RETURN)
     78 #define NO_RETURN DOUBLE_CONVERSION_NO_RETURN
     79 #endif
     80 
     81 #ifndef DOUBLE_CONVERSION_UNREACHABLE
     82 #ifdef _MSC_VER
     83 void DOUBLE_CONVERSION_NO_RETURN abort_noreturn();
     84 inline void abort_noreturn() { abort(); }
     85 #define DOUBLE_CONVERSION_UNREACHABLE()   (abort_noreturn())
     86 #else
     87 #define DOUBLE_CONVERSION_UNREACHABLE()   (abort())
     88 #endif
     89 #endif
     90 #if defined(DOUBLE_CONVERSION_NON_PREFIXED_MACROS) && !defined(UNREACHABLE)
     91 #define UNREACHABLE DOUBLE_CONVERSION_UNREACHABLE
     92 #endif
     93 
     94 // Not all compilers support __has_attribute and combining a check for both
     95 // ifdef and __has_attribute on the same preprocessor line isn't portable.
     96 #ifdef __has_attribute
     97 #   define DOUBLE_CONVERSION_HAS_ATTRIBUTE(x) __has_attribute(x)
     98 #else
     99 #   define DOUBLE_CONVERSION_HAS_ATTRIBUTE(x) 0
    100 #endif
    101 
    102 #ifndef DOUBLE_CONVERSION_UNUSED
    103 #if DOUBLE_CONVERSION_HAS_ATTRIBUTE(unused)
    104 #define DOUBLE_CONVERSION_UNUSED __attribute__((unused))
    105 #else
    106 #define DOUBLE_CONVERSION_UNUSED
    107 #endif
    108 #endif
    109 #if defined(DOUBLE_CONVERSION_NON_PREFIXED_MACROS) && !defined(UNUSED)
    110 #define UNUSED DOUBLE_CONVERSION_UNUSED
    111 #endif
    112 
    113 #if DOUBLE_CONVERSION_HAS_ATTRIBUTE(uninitialized)
    114 #define DOUBLE_CONVERSION_STACK_UNINITIALIZED __attribute__((uninitialized))
    115 #else
    116 #define DOUBLE_CONVERSION_STACK_UNINITIALIZED
    117 #endif
    118 #if defined(DOUBLE_CONVERSION_NON_PREFIXED_MACROS) && !defined(STACK_UNINITIALIZED)
    119 #define STACK_UNINITIALIZED DOUBLE_CONVERSION_STACK_UNINITIALIZED
    120 #endif
    121 
    122 // Double operations detection based on target architecture.
    123 // Linux uses a 80bit wide floating point stack on x86. This induces double
    124 // rounding, which in turn leads to wrong results.
    125 // An easy way to test if the floating-point operations are correct is to
    126 // evaluate: 89255.0/1e22. If the floating-point stack is 64 bits wide then
    127 // the result is equal to 89255e-22.
    128 // The best way to test this, is to create a division-function and to compare
    129 // the output of the division with the expected result. (Inlining must be
    130 // disabled.)
    131 // On Linux,x86 89255e-22 != Div_double(89255.0/1e22)
    132 //
    133 // For example:
    134 /*
    135 // -- in div.c
    136 double Div_double(double x, double y) { return x / y; }
    137 
    138 // -- in main.c
    139 double Div_double(double x, double y);  // Forward declaration.
    140 
    141 int main(int argc, char** argv) {
    142  return Div_double(89255.0, 1e22) == 89255e-22;
    143 }
    144 */
    145 // Run as follows ./main || echo "correct"
    146 //
    147 // If it prints "correct" then the architecture should be here, in the "correct" section.
    148 #if defined(_M_X64) || defined(__x86_64__) || \
    149    defined(__ARMEL__) || defined(__avr32__) || defined(_M_ARM) || defined(_M_ARM64) || \
    150    defined(__hppa__) || defined(__ia64__) || \
    151    defined(__mips__) || \
    152    defined(__loongarch__) || \
    153    defined(__nios2__) || defined(__ghs) || \
    154    defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__) || \
    155    defined(_POWER) || defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \
    156    defined(__sparc__) || defined(__sparc) || defined(__s390__) || \
    157    defined(__SH4__) || defined(__alpha__) || \
    158    defined(_MIPS_ARCH_MIPS32R2) || defined(__ARMEB__) ||\
    159    defined(__AARCH64EL__) || defined(__aarch64__) || defined(__AARCH64EB__) || \
    160    defined(__riscv) || defined(__e2k__) || \
    161    defined(__or1k__) || defined(__arc__) || defined(__ARC64__) || \
    162    defined(__microblaze__) || defined(__XTENSA__) || \
    163    defined(__EMSCRIPTEN__) || defined(__wasm32__)
    164 #define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1
    165 #elif defined(__mc68000__) || \
    166    defined(__pnacl__) || defined(__native_client__)
    167 #undef DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS
    168 #elif defined(_M_IX86) || defined(__i386__) || defined(__i386)
    169 #if defined(_WIN32)
    170 // Windows uses a 64bit wide floating point stack.
    171 #define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1
    172 #else
    173 #undef DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS
    174 #endif  // _WIN32
    175 #else
    176 #error Target architecture was not detected as supported by Double-Conversion.
    177 #endif
    178 #if defined(DOUBLE_CONVERSION_NON_PREFIXED_MACROS) && !defined(CORRECT_DOUBLE_OPERATIONS)
    179 #define CORRECT_DOUBLE_OPERATIONS DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS
    180 #endif
    181 
    182 #if defined(_WIN32) && !defined(__MINGW32__)
    183 
    184 typedef signed char int8_t;
    185 typedef unsigned char uint8_t;
    186 typedef short int16_t;  // NOLINT
    187 typedef unsigned short uint16_t;  // NOLINT
    188 typedef int int32_t;
    189 typedef unsigned int uint32_t;
    190 typedef __int64 int64_t;
    191 typedef unsigned __int64 uint64_t;
    192 // intptr_t and friends are defined in crtdefs.h through stdio.h.
    193 
    194 #else
    195 
    196 #include <stdint.h>
    197 
    198 #endif
    199 
    200 typedef uint16_t uc16;
    201 
    202 // The following macro works on both 32 and 64-bit platforms.
    203 // Usage: instead of writing 0x1234567890123456
    204 //      write DOUBLE_CONVERSION_UINT64_2PART_C(0x12345678,90123456);
    205 #define DOUBLE_CONVERSION_UINT64_2PART_C(a, b) (((static_cast<uint64_t>(a) << 32) + 0x##b##u))
    206 #if defined(DOUBLE_CONVERSION_NON_PREFIXED_MACROS) && !defined(UINT64_2PART_C)
    207 #define UINT64_2PART_C DOUBLE_CONVERSION_UINT64_2PART_C
    208 #endif
    209 
    210 // The expression DOUBLE_CONVERSION_ARRAY_SIZE(a) is a compile-time constant of type
    211 // size_t which represents the number of elements of the given
    212 // array. You should only use DOUBLE_CONVERSION_ARRAY_SIZE on statically allocated
    213 // arrays.
    214 #ifndef DOUBLE_CONVERSION_ARRAY_SIZE
    215 #define DOUBLE_CONVERSION_ARRAY_SIZE(a)                                   \
    216  ((sizeof(a) / sizeof(*(a))) /                         \
    217  static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
    218 #endif
    219 #if defined(DOUBLE_CONVERSION_NON_PREFIXED_MACROS) && !defined(ARRAY_SIZE)
    220 #define ARRAY_SIZE DOUBLE_CONVERSION_ARRAY_SIZE
    221 #endif
    222 
    223 // A macro to disallow the evil copy constructor and operator= functions
    224 // This should be used in the private: declarations for a class
    225 #ifndef DOUBLE_CONVERSION_DISALLOW_COPY_AND_ASSIGN
    226 #define DOUBLE_CONVERSION_DISALLOW_COPY_AND_ASSIGN(TypeName)      \
    227  TypeName(const TypeName&);                    \
    228  void operator=(const TypeName&)
    229 #endif
    230 #if defined(DOUBLE_CONVERSION_NON_PREFIXED_MACROS) && !defined(DC_DISALLOW_COPY_AND_ASSIGN)
    231 #define DC_DISALLOW_COPY_AND_ASSIGN DOUBLE_CONVERSION_DISALLOW_COPY_AND_ASSIGN
    232 #endif
    233 
    234 // A macro to disallow all the implicit constructors, namely the
    235 // default constructor, copy constructor and operator= functions.
    236 //
    237 // This should be used in the private: declarations for a class
    238 // that wants to prevent anyone from instantiating it. This is
    239 // especially useful for classes containing only static methods.
    240 #ifndef DOUBLE_CONVERSION_DISALLOW_IMPLICIT_CONSTRUCTORS
    241 #define DOUBLE_CONVERSION_DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
    242  TypeName();                                    \
    243  DOUBLE_CONVERSION_DISALLOW_COPY_AND_ASSIGN(TypeName)
    244 #endif
    245 #if defined(DOUBLE_CONVERSION_NON_PREFIXED_MACROS) && !defined(DC_DISALLOW_IMPLICIT_CONSTRUCTORS)
    246 #define DC_DISALLOW_IMPLICIT_CONSTRUCTORS DOUBLE_CONVERSION_DISALLOW_IMPLICIT_CONSTRUCTORS
    247 #endif
    248 
    249 // ICU PATCH: Wrap in ICU namespace
    250 U_NAMESPACE_BEGIN
    251 
    252 namespace double_conversion {
    253 
    254 inline int StrLength(const char* string) {
    255  size_t length = strlen(string);
    256  DOUBLE_CONVERSION_ASSERT(length == static_cast<size_t>(static_cast<int>(length)));
    257  return static_cast<int>(length);
    258 }
    259 
    260 // This is a simplified version of V8's Vector class.
    261 template <typename T>
    262 class Vector {
    263 public:
    264  Vector() : start_(DOUBLE_CONVERSION_NULLPTR), length_(0) {}
    265  Vector(T* data, int len) : start_(data), length_(len) {
    266    DOUBLE_CONVERSION_ASSERT(len == 0 || (len > 0 && data != DOUBLE_CONVERSION_NULLPTR));
    267  }
    268 
    269  // Returns a vector using the same backing storage as this one,
    270  // spanning from and including 'from', to but not including 'to'.
    271  Vector<T> SubVector(int from, int to) {
    272    DOUBLE_CONVERSION_ASSERT(to <= length_);
    273    DOUBLE_CONVERSION_ASSERT(from < to);
    274    DOUBLE_CONVERSION_ASSERT(0 <= from);
    275    return Vector<T>(start() + from, to - from);
    276  }
    277 
    278  // Returns the length of the vector.
    279  int length() const { return length_; }
    280 
    281  // Returns whether or not the vector is empty.
    282  bool is_empty() const { return length_ == 0; }
    283 
    284  // Returns the pointer to the start of the data in the vector.
    285  T* start() const { return start_; }
    286 
    287  // Access individual vector elements - checks bounds in debug mode.
    288  T& operator[](int index) const {
    289    DOUBLE_CONVERSION_ASSERT(0 <= index && index < length_);
    290    return start_[index];
    291  }
    292 
    293  T& first() { return start_[0]; }
    294 
    295  T& last() { return start_[length_ - 1]; }
    296 
    297  void pop_back() {
    298    DOUBLE_CONVERSION_ASSERT(!is_empty());
    299    --length_;
    300  }
    301 
    302 private:
    303  T* start_;
    304  int length_;
    305 };
    306 
    307 
    308 // Helper class for building result strings in a character buffer. The
    309 // purpose of the class is to use safe operations that checks the
    310 // buffer bounds on all operations in debug mode.
    311 class StringBuilder {
    312 public:
    313  StringBuilder(char* buffer, int buffer_size)
    314      : buffer_(buffer, buffer_size), position_(0) { }
    315 
    316  ~StringBuilder() { if (!is_finalized()) Finalize(); }
    317 
    318  int size() const { return buffer_.length(); }
    319 
    320  // Get the current position in the builder.
    321  int position() const {
    322    DOUBLE_CONVERSION_ASSERT(!is_finalized());
    323    return position_;
    324  }
    325 
    326  // Reset the position.
    327  void Reset() { position_ = 0; }
    328 
    329  // Add a single character to the builder. It is not allowed to add
    330  // 0-characters; use the Finalize() method to terminate the string
    331  // instead.
    332  void AddCharacter(char c) {
    333    DOUBLE_CONVERSION_ASSERT(c != '\0');
    334    DOUBLE_CONVERSION_ASSERT(!is_finalized() && position_ < buffer_.length());
    335    buffer_[position_++] = c;
    336  }
    337 
    338  // Add an entire string to the builder. Uses strlen() internally to
    339  // compute the length of the input string.
    340  void AddString(const char* s) {
    341    AddSubstring(s, StrLength(s));
    342  }
    343 
    344  // Add the first 'n' characters of the given string 's' to the
    345  // builder. The input string must have enough characters.
    346  void AddSubstring(const char* s, int n) {
    347    DOUBLE_CONVERSION_ASSERT(!is_finalized() && position_ + n < buffer_.length());
    348    DOUBLE_CONVERSION_ASSERT(static_cast<size_t>(n) <= strlen(s));
    349    memmove(&buffer_[position_], s, static_cast<size_t>(n));
    350    position_ += n;
    351  }
    352 
    353 
    354  // Add character padding to the builder. If count is non-positive,
    355  // nothing is added to the builder.
    356  void AddPadding(char c, int count) {
    357    for (int i = 0; i < count; i++) {
    358      AddCharacter(c);
    359    }
    360  }
    361 
    362  // Finalize the string by 0-terminating it and returning the buffer.
    363  char* Finalize() {
    364    DOUBLE_CONVERSION_ASSERT(!is_finalized() && position_ < buffer_.length());
    365    buffer_[position_] = '\0';
    366    // Make sure nobody managed to add a 0-character to the
    367    // buffer while building the string.
    368    DOUBLE_CONVERSION_ASSERT(strlen(buffer_.start()) == static_cast<size_t>(position_));
    369    position_ = -1;
    370    DOUBLE_CONVERSION_ASSERT(is_finalized());
    371    return buffer_.start();
    372  }
    373 
    374 private:
    375  Vector<char> buffer_;
    376  int position_;
    377 
    378  bool is_finalized() const { return position_ < 0; }
    379 
    380  DOUBLE_CONVERSION_DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder);
    381 };
    382 
    383 // The type-based aliasing rule allows the compiler to assume that pointers of
    384 // different types (for some definition of different) never alias each other.
    385 // Thus the following code does not work:
    386 //
    387 // float f = foo();
    388 // int fbits = *(int*)(&f);
    389 //
    390 // The compiler 'knows' that the int pointer can't refer to f since the types
    391 // don't match, so the compiler may cache f in a register, leaving random data
    392 // in fbits.  Using C++ style casts makes no difference, however a pointer to
    393 // char data is assumed to alias any other pointer.  This is the 'memcpy
    394 // exception'.
    395 //
    396 // Bit_cast uses the memcpy exception to move the bits from a variable of one
    397 // type of a variable of another type.  Of course the end result is likely to
    398 // be implementation dependent.  Most compilers (gcc-4.2 and MSVC 2005)
    399 // will completely optimize BitCast away.
    400 //
    401 // There is an additional use for BitCast.
    402 // Recent gccs will warn when they see casts that may result in breakage due to
    403 // the type-based aliasing rule.  If you have checked that there is no breakage
    404 // you can use BitCast to cast one pointer type to another.  This confuses gcc
    405 // enough that it can no longer see that you have cast one pointer type to
    406 // another thus avoiding the warning.
    407 template <class Dest, class Source>
    408 Dest BitCast(const Source& source) {
    409  // Compile time assertion: sizeof(Dest) == sizeof(Source)
    410  // A compile error here means your Dest and Source have different sizes.
    411 #if __cplusplus >= 201103L
    412  static_assert(sizeof(Dest) == sizeof(Source),
    413                "source and destination size mismatch");
    414 #else
    415  DOUBLE_CONVERSION_UNUSED
    416  typedef char VerifySizesAreEqual[sizeof(Dest) == sizeof(Source) ? 1 : -1];
    417 #endif
    418 
    419  Dest dest;
    420  memmove(&dest, &source, sizeof(dest));
    421  return dest;
    422 }
    423 
    424 template <class Dest, class Source>
    425 Dest BitCast(Source* source) {
    426  return BitCast<Dest>(reinterpret_cast<uintptr_t>(source));
    427 }
    428 
    429 }  // namespace double_conversion
    430 
    431 // ICU PATCH: Close ICU namespace
    432 U_NAMESPACE_END
    433 
    434 #endif  // DOUBLE_CONVERSION_UTILS_H_
    435 #endif // ICU PATCH: close #if !UCONFIG_NO_FORMATTING