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