mfbt/double-conversion/utils.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/mfbt/double-conversion/utils.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,298 @@
     1.4 +// Copyright 2010 the V8 project authors. All rights reserved.
     1.5 +// Redistribution and use in source and binary forms, with or without
     1.6 +// modification, are permitted provided that the following conditions are
     1.7 +// met:
     1.8 +//
     1.9 +//     * Redistributions of source code must retain the above copyright
    1.10 +//       notice, this list of conditions and the following disclaimer.
    1.11 +//     * Redistributions in binary form must reproduce the above
    1.12 +//       copyright notice, this list of conditions and the following
    1.13 +//       disclaimer in the documentation and/or other materials provided
    1.14 +//       with the distribution.
    1.15 +//     * Neither the name of Google Inc. nor the names of its
    1.16 +//       contributors may be used to endorse or promote products derived
    1.17 +//       from this software without specific prior written permission.
    1.18 +//
    1.19 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    1.20 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    1.21 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    1.22 +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    1.23 +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    1.24 +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    1.25 +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    1.26 +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    1.27 +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    1.28 +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    1.29 +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    1.30 +
    1.31 +#ifndef DOUBLE_CONVERSION_UTILS_H_
    1.32 +#define DOUBLE_CONVERSION_UTILS_H_
    1.33 +
    1.34 +#include <stdlib.h>
    1.35 +#include <string.h>
    1.36 +
    1.37 +#include "mozilla/Assertions.h"
    1.38 +#ifndef ASSERT
    1.39 +#define ASSERT(condition)      MOZ_ASSERT(condition)
    1.40 +#endif
    1.41 +#ifndef UNIMPLEMENTED
    1.42 +#define UNIMPLEMENTED() MOZ_CRASH()
    1.43 +#endif
    1.44 +#ifndef UNREACHABLE
    1.45 +#define UNREACHABLE()   MOZ_CRASH()
    1.46 +#endif
    1.47 +
    1.48 +// Double operations detection based on target architecture.
    1.49 +// Linux uses a 80bit wide floating point stack on x86. This induces double
    1.50 +// rounding, which in turn leads to wrong results.
    1.51 +// An easy way to test if the floating-point operations are correct is to
    1.52 +// evaluate: 89255.0/1e22. If the floating-point stack is 64 bits wide then
    1.53 +// the result is equal to 89255e-22.
    1.54 +// The best way to test this, is to create a division-function and to compare
    1.55 +// the output of the division with the expected result. (Inlining must be
    1.56 +// disabled.)
    1.57 +// On Linux,x86 89255e-22 != Div_double(89255.0/1e22)
    1.58 +#if defined(_M_X64) || defined(__x86_64__) || \
    1.59 +    defined(__ARMEL__) || defined(__avr32__) || \
    1.60 +    defined(__hppa__) || defined(__ia64__) || \
    1.61 +    defined(__mips__) || \
    1.62 +    defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__) || \
    1.63 +    defined(__sparc__) || defined(__sparc) || defined(__s390__) || \
    1.64 +    defined(__SH4__) || defined(__alpha__) || \
    1.65 +    defined(_MIPS_ARCH_MIPS32R2) || \
    1.66 +    defined(__AARCH64EL__)
    1.67 +#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1
    1.68 +#elif defined(_M_IX86) || defined(__i386__) || defined(__i386)
    1.69 +#if defined(_WIN32)
    1.70 +// Windows uses a 64bit wide floating point stack.
    1.71 +#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1
    1.72 +#else
    1.73 +#undef DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS
    1.74 +#endif  // _WIN32
    1.75 +#else
    1.76 +#error Target architecture was not detected as supported by Double-Conversion.
    1.77 +#endif
    1.78 +
    1.79 +
    1.80 +#include <stdint.h>
    1.81 +
    1.82 +// The following macro works on both 32 and 64-bit platforms.
    1.83 +// Usage: instead of writing 0x1234567890123456
    1.84 +//      write UINT64_2PART_C(0x12345678,90123456);
    1.85 +#define UINT64_2PART_C(a, b) (((static_cast<uint64_t>(a) << 32) + 0x##b##u))
    1.86 +
    1.87 +
    1.88 +// The expression ARRAY_SIZE(a) is a compile-time constant of type
    1.89 +// size_t which represents the number of elements of the given
    1.90 +// array. You should only use ARRAY_SIZE on statically allocated
    1.91 +// arrays.
    1.92 +#ifndef ARRAY_SIZE
    1.93 +#define ARRAY_SIZE(a)                                   \
    1.94 +  ((sizeof(a) / sizeof(*(a))) /                         \
    1.95 +  static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
    1.96 +#endif
    1.97 +
    1.98 +// A macro to disallow the evil copy constructor and operator= functions
    1.99 +// This should be used in the private: declarations for a class
   1.100 +#ifndef DISALLOW_COPY_AND_ASSIGN
   1.101 +#define DISALLOW_COPY_AND_ASSIGN(TypeName)      \
   1.102 +  TypeName(const TypeName&);                    \
   1.103 +  void operator=(const TypeName&)
   1.104 +#endif
   1.105 +
   1.106 +// A macro to disallow all the implicit constructors, namely the
   1.107 +// default constructor, copy constructor and operator= functions.
   1.108 +//
   1.109 +// This should be used in the private: declarations for a class
   1.110 +// that wants to prevent anyone from instantiating it. This is
   1.111 +// especially useful for classes containing only static methods.
   1.112 +#ifndef DISALLOW_IMPLICIT_CONSTRUCTORS
   1.113 +#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
   1.114 +  TypeName();                                    \
   1.115 +  DISALLOW_COPY_AND_ASSIGN(TypeName)
   1.116 +#endif
   1.117 +
   1.118 +namespace double_conversion {
   1.119 +
   1.120 +static const int kCharSize = sizeof(char);
   1.121 +
   1.122 +// Returns the maximum of the two parameters.
   1.123 +template <typename T>
   1.124 +static T Max(T a, T b) {
   1.125 +  return a < b ? b : a;
   1.126 +}
   1.127 +
   1.128 +
   1.129 +// Returns the minimum of the two parameters.
   1.130 +template <typename T>
   1.131 +static T Min(T a, T b) {
   1.132 +  return a < b ? a : b;
   1.133 +}
   1.134 +
   1.135 +
   1.136 +inline int StrLength(const char* string) {
   1.137 +  size_t length = strlen(string);
   1.138 +  ASSERT(length == static_cast<size_t>(static_cast<int>(length)));
   1.139 +  return static_cast<int>(length);
   1.140 +}
   1.141 +
   1.142 +// This is a simplified version of V8's Vector class.
   1.143 +template <typename T>
   1.144 +class Vector {
   1.145 + public:
   1.146 +  Vector() : start_(NULL), length_(0) {}
   1.147 +  Vector(T* data, int length) : start_(data), length_(length) {
   1.148 +    ASSERT(length == 0 || (length > 0 && data != NULL));
   1.149 +  }
   1.150 +
   1.151 +  // Returns a vector using the same backing storage as this one,
   1.152 +  // spanning from and including 'from', to but not including 'to'.
   1.153 +  Vector<T> SubVector(int from, int to) {
   1.154 +    ASSERT(to <= length_);
   1.155 +    ASSERT(from < to);
   1.156 +    ASSERT(0 <= from);
   1.157 +    return Vector<T>(start() + from, to - from);
   1.158 +  }
   1.159 +
   1.160 +  // Returns the length of the vector.
   1.161 +  int length() const { return length_; }
   1.162 +
   1.163 +  // Returns whether or not the vector is empty.
   1.164 +  bool is_empty() const { return length_ == 0; }
   1.165 +
   1.166 +  // Returns the pointer to the start of the data in the vector.
   1.167 +  T* start() const { return start_; }
   1.168 +
   1.169 +  // Access individual vector elements - checks bounds in debug mode.
   1.170 +  T& operator[](int index) const {
   1.171 +    ASSERT(0 <= index && index < length_);
   1.172 +    return start_[index];
   1.173 +  }
   1.174 +
   1.175 +  T& first() { return start_[0]; }
   1.176 +
   1.177 +  T& last() { return start_[length_ - 1]; }
   1.178 +
   1.179 + private:
   1.180 +  T* start_;
   1.181 +  int length_;
   1.182 +};
   1.183 +
   1.184 +
   1.185 +// Helper class for building result strings in a character buffer. The
   1.186 +// purpose of the class is to use safe operations that checks the
   1.187 +// buffer bounds on all operations in debug mode.
   1.188 +class StringBuilder {
   1.189 + public:
   1.190 +  StringBuilder(char* buffer, int size)
   1.191 +      : buffer_(buffer, size), position_(0) { }
   1.192 +
   1.193 +  ~StringBuilder() { if (!is_finalized()) Finalize(); }
   1.194 +
   1.195 +  int size() const { return buffer_.length(); }
   1.196 +
   1.197 +  // Get the current position in the builder.
   1.198 +  int position() const {
   1.199 +    ASSERT(!is_finalized());
   1.200 +    return position_;
   1.201 +  }
   1.202 +
   1.203 +  // Reset the position.
   1.204 +  void Reset() { position_ = 0; }
   1.205 +
   1.206 +  // Add a single character to the builder. It is not allowed to add
   1.207 +  // 0-characters; use the Finalize() method to terminate the string
   1.208 +  // instead.
   1.209 +  void AddCharacter(char c) {
   1.210 +    ASSERT(c != '\0');
   1.211 +    ASSERT(!is_finalized() && position_ < buffer_.length());
   1.212 +    buffer_[position_++] = c;
   1.213 +  }
   1.214 +
   1.215 +  // Add an entire string to the builder. Uses strlen() internally to
   1.216 +  // compute the length of the input string.
   1.217 +  void AddString(const char* s) {
   1.218 +    AddSubstring(s, StrLength(s));
   1.219 +  }
   1.220 +
   1.221 +  // Add the first 'n' characters of the given string 's' to the
   1.222 +  // builder. The input string must have enough characters.
   1.223 +  void AddSubstring(const char* s, int n) {
   1.224 +    ASSERT(!is_finalized() && position_ + n < buffer_.length());
   1.225 +    ASSERT(static_cast<size_t>(n) <= strlen(s));
   1.226 +    memmove(&buffer_[position_], s, n * kCharSize);
   1.227 +    position_ += n;
   1.228 +  }
   1.229 +
   1.230 +
   1.231 +  // Add character padding to the builder. If count is non-positive,
   1.232 +  // nothing is added to the builder.
   1.233 +  void AddPadding(char c, int count) {
   1.234 +    for (int i = 0; i < count; i++) {
   1.235 +      AddCharacter(c);
   1.236 +    }
   1.237 +  }
   1.238 +
   1.239 +  // Finalize the string by 0-terminating it and returning the buffer.
   1.240 +  char* Finalize() {
   1.241 +    ASSERT(!is_finalized() && position_ < buffer_.length());
   1.242 +    buffer_[position_] = '\0';
   1.243 +    // Make sure nobody managed to add a 0-character to the
   1.244 +    // buffer while building the string.
   1.245 +    ASSERT(strlen(buffer_.start()) == static_cast<size_t>(position_));
   1.246 +    position_ = -1;
   1.247 +    ASSERT(is_finalized());
   1.248 +    return buffer_.start();
   1.249 +  }
   1.250 +
   1.251 + private:
   1.252 +  Vector<char> buffer_;
   1.253 +  int position_;
   1.254 +
   1.255 +  bool is_finalized() const { return position_ < 0; }
   1.256 +
   1.257 +  DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder);
   1.258 +};
   1.259 +
   1.260 +// The type-based aliasing rule allows the compiler to assume that pointers of
   1.261 +// different types (for some definition of different) never alias each other.
   1.262 +// Thus the following code does not work:
   1.263 +//
   1.264 +// float f = foo();
   1.265 +// int fbits = *(int*)(&f);
   1.266 +//
   1.267 +// The compiler 'knows' that the int pointer can't refer to f since the types
   1.268 +// don't match, so the compiler may cache f in a register, leaving random data
   1.269 +// in fbits.  Using C++ style casts makes no difference, however a pointer to
   1.270 +// char data is assumed to alias any other pointer.  This is the 'memcpy
   1.271 +// exception'.
   1.272 +//
   1.273 +// Bit_cast uses the memcpy exception to move the bits from a variable of one
   1.274 +// type of a variable of another type.  Of course the end result is likely to
   1.275 +// be implementation dependent.  Most compilers (gcc-4.2 and MSVC 2005)
   1.276 +// will completely optimize BitCast away.
   1.277 +//
   1.278 +// There is an additional use for BitCast.
   1.279 +// Recent gccs will warn when they see casts that may result in breakage due to
   1.280 +// the type-based aliasing rule.  If you have checked that there is no breakage
   1.281 +// you can use BitCast to cast one pointer type to another.  This confuses gcc
   1.282 +// enough that it can no longer see that you have cast one pointer type to
   1.283 +// another thus avoiding the warning.
   1.284 +template <class Dest, class Source>
   1.285 +inline Dest BitCast(const Source& source) {
   1.286 +  static_assert(sizeof(Dest) == sizeof(Source),
   1.287 +                "BitCast's source and destination types must be the same size");
   1.288 +
   1.289 +  Dest dest;
   1.290 +  memmove(&dest, &source, sizeof(dest));
   1.291 +  return dest;
   1.292 +}
   1.293 +
   1.294 +template <class Dest, class Source>
   1.295 +inline Dest BitCast(Source* source) {
   1.296 +  return BitCast<Dest>(reinterpret_cast<uintptr_t>(source));
   1.297 +}
   1.298 +
   1.299 +}  // namespace double_conversion
   1.300 +
   1.301 +#endif  // DOUBLE_CONVERSION_UTILS_H_

mercurial