Home | History | Annotate | Download | only in i18n
      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 #include <stdlib.h>
     41 #include <string.h>
     42 
     43 // ICU PATCH: Use U_ASSERT instead of <assert.h>
     44 #include "uassert.h"
     45 #define ASSERT U_ASSERT
     46 
     47 #ifndef UNIMPLEMENTED
     48 #define UNIMPLEMENTED() (abort())
     49 #endif
     50 #ifndef DOUBLE_CONVERSION_NO_RETURN
     51 #ifdef _MSC_VER
     52 #define DOUBLE_CONVERSION_NO_RETURN __declspec(noreturn)
     53 #else
     54 #define DOUBLE_CONVERSION_NO_RETURN __attribute__((noreturn))
     55 #endif
     56 #endif
     57 #ifndef UNREACHABLE
     58 #ifdef _MSC_VER
     59 void DOUBLE_CONVERSION_NO_RETURN abort_noreturn();
     60 inline void abort_noreturn() { abort(); }
     61 #define UNREACHABLE()   (abort_noreturn())
     62 #else
     63 #define UNREACHABLE()   (abort())
     64 #endif
     65 #endif
     66 
     67 
     68 // Double operations detection based on target architecture.
     69 // Linux uses a 80bit wide floating point stack on x86. This induces double
     70 // rounding, which in turn leads to wrong results.
     71 // An easy way to test if the floating-point operations are correct is to
     72 // evaluate: 89255.0/1e22. If the floating-point stack is 64 bits wide then
     73 // the result is equal to 89255e-22.
     74 // The best way to test this, is to create a division-function and to compare
     75 // the output of the division with the expected result. (Inlining must be
     76 // disabled.)
     77 // On Linux,x86 89255e-22 != Div_double(89255.0/1e22)
     78 // ICU PATCH: Enable ARM32 & ARM64 builds for Windows with 'defined(_M_ARM) || defined(_M_ARM64)'.
     79 #if defined(_M_X64) || defined(__x86_64__) || \
     80     defined(__ARMEL__) || defined(__avr32__) || defined(_M_ARM) || defined(_M_ARM64) || \
     81     defined(__hppa__) || defined(__ia64__) || \
     82     defined(__mips__) || \
     83     defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__) || \
     84     defined(_POWER) || defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \
     85     defined(__sparc__) || defined(__sparc) || defined(__s390__) || \
     86     defined(__SH4__) || defined(__alpha__) || \
     87     defined(_MIPS_ARCH_MIPS32R2) || \
     88     defined(__AARCH64EL__) || defined(__aarch64__) || \
     89     defined(__riscv)
     90 #define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1
     91 #elif defined(__mc68000__)
     92 #undef DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS
     93 #elif defined(_M_IX86) || defined(__i386__) || defined(__i386)
     94 #if defined(_WIN32)
     95 // Windows uses a 64bit wide floating point stack.
     96 #define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1
     97 #else
     98 #undef DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS
     99 #endif  // _WIN32
    100 #else
    101 #error Target architecture was not detected as supported by Double-Conversion.
    102 #endif
    103 
    104 #if defined(__GNUC__)
    105 #define DOUBLE_CONVERSION_UNUSED __attribute__((unused))
    106 #else
    107 #define DOUBLE_CONVERSION_UNUSED
    108 #endif
    109 
    110 #if defined(_WIN32) && !defined(__MINGW32__)
    111 
    112 typedef signed char int8_t;
    113 typedef unsigned char uint8_t;
    114 typedef short int16_t;  // NOLINT
    115 typedef unsigned short uint16_t;  // NOLINT
    116 typedef int int32_t;
    117 typedef unsigned int uint32_t;
    118 typedef __int64 int64_t;
    119 typedef unsigned __int64 uint64_t;
    120 // intptr_t and friends are defined in crtdefs.h through stdio.h.
    121 
    122 #else
    123 
    124 #include <stdint.h>
    125 
    126 #endif
    127 
    128 typedef uint16_t uc16;
    129 
    130 // The following macro works on both 32 and 64-bit platforms.
    131 // Usage: instead of writing 0x1234567890123456
    132 //      write UINT64_2PART_C(0x12345678,90123456);
    133 #define UINT64_2PART_C(a, b) (((static_cast<uint64_t>(a) << 32) + 0x##b##u))
    134 
    135 
    136 // The expression ARRAY_SIZE(a) is a compile-time constant of type
    137 // size_t which represents the number of elements of the given
    138 // array. You should only use ARRAY_SIZE on statically allocated
    139 // arrays.
    140 #ifndef ARRAY_SIZE
    141 #define ARRAY_SIZE(a)                                   \
    142   ((sizeof(a) / sizeof(*(a))) /                         \
    143   static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
    144 #endif
    145 
    146 // A macro to disallow the evil copy constructor and operator= functions
    147 // This should be used in the private: declarations for a class
    148 #ifndef DISALLOW_COPY_AND_ASSIGN
    149 #define DISALLOW_COPY_AND_ASSIGN(TypeName)      \
    150   TypeName(const TypeName&);                    \
    151   void operator=(const TypeName&)
    152 #endif
    153 
    154 // A macro to disallow all the implicit constructors, namely the
    155 // default constructor, copy constructor and operator= functions.
    156 //
    157 // This should be used in the private: declarations for a class
    158 // that wants to prevent anyone from instantiating it. This is
    159 // especially useful for classes containing only static methods.
    160 #ifndef DISALLOW_IMPLICIT_CONSTRUCTORS
    161 #define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
    162   TypeName();                                    \
    163   DISALLOW_COPY_AND_ASSIGN(TypeName)
    164 #endif
    165 
    166 // ICU PATCH: Wrap in ICU namespace
    167 U_NAMESPACE_BEGIN
    168 
    169 namespace double_conversion {
    170 
    171 static const int kCharSize = sizeof(char);
    172 
    173 // Returns the maximum of the two parameters.
    174 template <typename T>
    175 static T Max(T a, T b) {
    176   return a < b ? b : a;
    177 }
    178 
    179 
    180 // Returns the minimum of the two parameters.
    181 template <typename T>
    182 static T Min(T a, T b) {
    183   return a < b ? a : b;
    184 }
    185 
    186 
    187 inline int StrLength(const char* string) {
    188   size_t length = strlen(string);
    189   ASSERT(length == static_cast<size_t>(static_cast<int>(length)));
    190   return static_cast<int>(length);
    191 }
    192 
    193 // This is a simplified version of V8's Vector class.
    194 template <typename T>
    195 class Vector {
    196  public:
    197   Vector() : start_(NULL), length_(0) {}
    198   Vector(T* data, int len) : start_(data), length_(len) {
    199     ASSERT(len == 0 || (len > 0 && data != NULL));
    200   }
    201 
    202   // Returns a vector using the same backing storage as this one,
    203   // spanning from and including 'from', to but not including 'to'.
    204   Vector<T> SubVector(int from, int to) {
    205     ASSERT(to <= length_);
    206     ASSERT(from < to);
    207     ASSERT(0 <= from);
    208     return Vector<T>(start() + from, to - from);
    209   }
    210 
    211   // Returns the length of the vector.
    212   int length() const { return length_; }
    213 
    214   // Returns whether or not the vector is empty.
    215   bool is_empty() const { return length_ == 0; }
    216 
    217   // Returns the pointer to the start of the data in the vector.
    218   T* start() const { return start_; }
    219 
    220   // Access individual vector elements - checks bounds in debug mode.
    221   T& operator[](int index) const {
    222     ASSERT(0 <= index && index < length_);
    223     return start_[index];
    224   }
    225 
    226   T& first() { return start_[0]; }
    227 
    228   T& last() { return start_[length_ - 1]; }
    229 
    230  private:
    231   T* start_;
    232   int length_;
    233 };
    234 
    235 
    236 // Helper class for building result strings in a character buffer. The
    237 // purpose of the class is to use safe operations that checks the
    238 // buffer bounds on all operations in debug mode.
    239 class StringBuilder {
    240  public:
    241   StringBuilder(char* buffer, int buffer_size)
    242       : buffer_(buffer, buffer_size), position_(0) { }
    243 
    244   ~StringBuilder() { if (!is_finalized()) Finalize(); }
    245 
    246   int size() const { return buffer_.length(); }
    247 
    248   // Get the current position in the builder.
    249   int position() const {
    250     ASSERT(!is_finalized());
    251     return position_;
    252   }
    253 
    254   // Reset the position.
    255   void Reset() { position_ = 0; }
    256 
    257   // Add a single character to the builder. It is not allowed to add
    258   // 0-characters; use the Finalize() method to terminate the string
    259   // instead.
    260   void AddCharacter(char c) {
    261     ASSERT(c != '\0');
    262     ASSERT(!is_finalized() && position_ < buffer_.length());
    263     buffer_[position_++] = c;
    264   }
    265 
    266   // Add an entire string to the builder. Uses strlen() internally to
    267   // compute the length of the input string.
    268   void AddString(const char* s) {
    269     AddSubstring(s, StrLength(s));
    270   }
    271 
    272   // Add the first 'n' characters of the given string 's' to the
    273   // builder. The input string must have enough characters.
    274   void AddSubstring(const char* s, int n) {
    275     ASSERT(!is_finalized() && position_ + n < buffer_.length());
    276     ASSERT(static_cast<size_t>(n) <= strlen(s));
    277     memmove(&buffer_[position_], s, n * kCharSize);
    278     position_ += n;
    279   }
    280 
    281 
    282   // Add character padding to the builder. If count is non-positive,
    283   // nothing is added to the builder.
    284   void AddPadding(char c, int count) {
    285     for (int i = 0; i < count; i++) {
    286       AddCharacter(c);
    287     }
    288   }
    289 
    290   // Finalize the string by 0-terminating it and returning the buffer.
    291   char* Finalize() {
    292     ASSERT(!is_finalized() && position_ < buffer_.length());
    293     buffer_[position_] = '\0';
    294     // Make sure nobody managed to add a 0-character to the
    295     // buffer while building the string.
    296     ASSERT(strlen(buffer_.start()) == static_cast<size_t>(position_));
    297     position_ = -1;
    298     ASSERT(is_finalized());
    299     return buffer_.start();
    300   }
    301 
    302  private:
    303   Vector<char> buffer_;
    304   int position_;
    305 
    306   bool is_finalized() const { return position_ < 0; }
    307 
    308   DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder);
    309 };
    310 
    311 // The type-based aliasing rule allows the compiler to assume that pointers of
    312 // different types (for some definition of different) never alias each other.
    313 // Thus the following code does not work:
    314 //
    315 // float f = foo();
    316 // int fbits = *(int*)(&f);
    317 //
    318 // The compiler 'knows' that the int pointer can't refer to f since the types
    319 // don't match, so the compiler may cache f in a register, leaving random data
    320 // in fbits.  Using C++ style casts makes no difference, however a pointer to
    321 // char data is assumed to alias any other pointer.  This is the 'memcpy
    322 // exception'.
    323 //
    324 // Bit_cast uses the memcpy exception to move the bits from a variable of one
    325 // type of a variable of another type.  Of course the end result is likely to
    326 // be implementation dependent.  Most compilers (gcc-4.2 and MSVC 2005)
    327 // will completely optimize BitCast away.
    328 //
    329 // There is an additional use for BitCast.
    330 // Recent gccs will warn when they see casts that may result in breakage due to
    331 // the type-based aliasing rule.  If you have checked that there is no breakage
    332 // you can use BitCast to cast one pointer type to another.  This confuses gcc
    333 // enough that it can no longer see that you have cast one pointer type to
    334 // another thus avoiding the warning.
    335 template <class Dest, class Source>
    336 inline Dest BitCast(const Source& source) {
    337   // Compile time assertion: sizeof(Dest) == sizeof(Source)
    338   // A compile error here means your Dest and Source have different sizes.
    339   DOUBLE_CONVERSION_UNUSED
    340       typedef char VerifySizesAreEqual[sizeof(Dest) == sizeof(Source) ? 1 : -1];
    341 
    342   Dest dest;
    343   memmove(&dest, &source, sizeof(dest));
    344   return dest;
    345 }
    346 
    347 template <class Dest, class Source>
    348 inline Dest BitCast(Source* source) {
    349   return BitCast<Dest>(reinterpret_cast<uintptr_t>(source));
    350 }
    351 
    352 }  // namespace double_conversion
    353 
    354 // ICU PATCH: Close ICU namespace
    355 U_NAMESPACE_END
    356 
    357 #endif  // DOUBLE_CONVERSION_UTILS_H_
    358 #endif // ICU PATCH: close #if !UCONFIG_NO_FORMATTING
    359