1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mfbt/decimal/Decimal.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,213 @@ 1.4 +/* 1.5 + * Copyright (C) 2012 Google Inc. All rights reserved. 1.6 + * 1.7 + * Redistribution and use in source and binary forms, with or without 1.8 + * modification, are permitted provided that the following conditions are 1.9 + * met: 1.10 + * 1.11 + * * Redistributions of source code must retain the above copyright 1.12 + * notice, this list of conditions and the following disclaimer. 1.13 + * * Redistributions in binary form must reproduce the above 1.14 + * copyright notice, this list of conditions and the following disclaimer 1.15 + * in the documentation and/or other materials provided with the 1.16 + * distribution. 1.17 + * * Neither the name of Google Inc. nor the names of its 1.18 + * contributors may be used to endorse or promote products derived from 1.19 + * this software without specific prior written permission. 1.20 + * 1.21 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.22 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.23 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1.24 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1.25 + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1.26 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1.27 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.28 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.29 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.30 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1.31 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.32 + */ 1.33 + 1.34 +/** 1.35 + * Imported from: 1.36 + * http://src.chromium.org/viewvc/blink/trunk/Source/core/platform/Decimal.h 1.37 + * Check hg log for the svn rev of the last update from Blink core. 1.38 + */ 1.39 + 1.40 +#ifndef Decimal_h 1.41 +#define Decimal_h 1.42 + 1.43 +#include "mozilla/Assertions.h" 1.44 +#include <stdint.h> 1.45 +#include "mozilla/Types.h" 1.46 + 1.47 +#include <string> 1.48 + 1.49 +#ifndef ASSERT 1.50 +#define DEFINED_ASSERT_FOR_DECIMAL_H 1 1.51 +#define ASSERT MOZ_ASSERT 1.52 +#endif 1.53 + 1.54 +// To use WTF_MAKE_FAST_ALLOCATED we'd need: 1.55 +// http://src.chromium.org/viewvc/blink/trunk/Source/wtf/FastMalloc.h 1.56 +// Since we don't allocate Decimal objects, no need. 1.57 +#define WTF_MAKE_FAST_ALLOCATED \ 1.58 + void ignore_this_dummy_method() MOZ_DELETE 1.59 + 1.60 +namespace WebCore { 1.61 + 1.62 +namespace DecimalPrivate { 1.63 +class SpecialValueHandler; 1.64 +} 1.65 + 1.66 +// This class represents decimal base floating point number. 1.67 +// 1.68 +// FIXME: Once all C++ compiler support decimal type, we should replace this 1.69 +// class to compiler supported one. See below URI for current status of decimal 1.70 +// type for C++: // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1977.html 1.71 +class Decimal { 1.72 + WTF_MAKE_FAST_ALLOCATED; 1.73 +public: 1.74 + enum Sign { 1.75 + Positive, 1.76 + Negative, 1.77 + }; 1.78 + 1.79 + // You should not use EncodedData other than unit testing. 1.80 + class EncodedData { 1.81 + // For accessing FormatClass. 1.82 + friend class Decimal; 1.83 + friend class DecimalPrivate::SpecialValueHandler; 1.84 + public: 1.85 + EncodedData(Sign, int exponent, uint64_t coefficient); 1.86 + 1.87 + bool operator==(const EncodedData&) const; 1.88 + bool operator!=(const EncodedData& another) const { return !operator==(another); } 1.89 + 1.90 + uint64_t coefficient() const { return m_coefficient; } 1.91 + int countDigits() const; 1.92 + int exponent() const { return m_exponent; } 1.93 + bool isFinite() const { return !isSpecial(); } 1.94 + bool isInfinity() const { return m_formatClass == ClassInfinity; } 1.95 + bool isNaN() const { return m_formatClass == ClassNaN; } 1.96 + bool isSpecial() const { return m_formatClass == ClassInfinity || m_formatClass == ClassNaN; } 1.97 + bool isZero() const { return m_formatClass == ClassZero; } 1.98 + Sign sign() const { return m_sign; } 1.99 + void setSign(Sign sign) { m_sign = sign; } 1.100 + 1.101 + private: 1.102 + enum FormatClass { 1.103 + ClassInfinity, 1.104 + ClassNormal, 1.105 + ClassNaN, 1.106 + ClassZero, 1.107 + }; 1.108 + 1.109 + EncodedData(Sign, FormatClass); 1.110 + FormatClass formatClass() const { return m_formatClass; } 1.111 + 1.112 + uint64_t m_coefficient; 1.113 + int16_t m_exponent; 1.114 + FormatClass m_formatClass; 1.115 + Sign m_sign; 1.116 + }; 1.117 + 1.118 + MFBT_API Decimal(int32_t = 0); 1.119 + MFBT_API Decimal(Sign, int exponent, uint64_t coefficient); 1.120 + MFBT_API Decimal(const Decimal&); 1.121 + 1.122 + MFBT_API Decimal& operator=(const Decimal&); 1.123 + MFBT_API Decimal& operator+=(const Decimal&); 1.124 + MFBT_API Decimal& operator-=(const Decimal&); 1.125 + MFBT_API Decimal& operator*=(const Decimal&); 1.126 + MFBT_API Decimal& operator/=(const Decimal&); 1.127 + 1.128 + MFBT_API Decimal operator-() const; 1.129 + 1.130 + MFBT_API bool operator==(const Decimal&) const; 1.131 + MFBT_API bool operator!=(const Decimal&) const; 1.132 + MFBT_API bool operator<(const Decimal&) const; 1.133 + MFBT_API bool operator<=(const Decimal&) const; 1.134 + MFBT_API bool operator>(const Decimal&) const; 1.135 + MFBT_API bool operator>=(const Decimal&) const; 1.136 + 1.137 + MFBT_API Decimal operator+(const Decimal&) const; 1.138 + MFBT_API Decimal operator-(const Decimal&) const; 1.139 + MFBT_API Decimal operator*(const Decimal&) const; 1.140 + MFBT_API Decimal operator/(const Decimal&) const; 1.141 + 1.142 + int exponent() const 1.143 + { 1.144 + ASSERT(isFinite()); 1.145 + return m_data.exponent(); 1.146 + } 1.147 + 1.148 + bool isFinite() const { return m_data.isFinite(); } 1.149 + bool isInfinity() const { return m_data.isInfinity(); } 1.150 + bool isNaN() const { return m_data.isNaN(); } 1.151 + bool isNegative() const { return sign() == Negative; } 1.152 + bool isPositive() const { return sign() == Positive; } 1.153 + bool isSpecial() const { return m_data.isSpecial(); } 1.154 + bool isZero() const { return m_data.isZero(); } 1.155 + 1.156 + MFBT_API Decimal abs() const; 1.157 + MFBT_API Decimal ceiling() const; 1.158 + MFBT_API Decimal floor() const; 1.159 + MFBT_API Decimal remainder(const Decimal&) const; 1.160 + MFBT_API Decimal round() const; 1.161 + 1.162 + MFBT_API double toDouble() const; 1.163 + // Note: toString method supports infinity and nan but fromString not. 1.164 + MFBT_API std::string toString() const; 1.165 + MFBT_API bool toString(char* strBuf, size_t bufLength) const; 1.166 + 1.167 + static MFBT_API Decimal fromDouble(double); 1.168 + // fromString supports following syntax EBNF: 1.169 + // number ::= sign? digit+ ('.' digit*) (exponent-marker sign? digit+)? 1.170 + // | sign? '.' digit+ (exponent-marker sign? digit+)? 1.171 + // sign ::= '+' | '-' 1.172 + // exponent-marker ::= 'e' | 'E' 1.173 + // digit ::= '0' | '1' | ... | '9' 1.174 + // Note: fromString doesn't support "infinity" and "nan". 1.175 + static MFBT_API Decimal fromString(const std::string& aValue); 1.176 + static MFBT_API Decimal infinity(Sign); 1.177 + static MFBT_API Decimal nan(); 1.178 + static MFBT_API Decimal zero(Sign); 1.179 + 1.180 + // You should not use below methods. We expose them for unit testing. 1.181 + MFBT_API explicit Decimal(const EncodedData&); 1.182 + const EncodedData& value() const { return m_data; } 1.183 + 1.184 +private: 1.185 + struct AlignedOperands { 1.186 + uint64_t lhsCoefficient; 1.187 + uint64_t rhsCoefficient; 1.188 + int exponent; 1.189 + }; 1.190 + 1.191 + MFBT_API Decimal(double); 1.192 + MFBT_API Decimal compareTo(const Decimal&) const; 1.193 + 1.194 + static MFBT_API AlignedOperands alignOperands(const Decimal& lhs, const Decimal& rhs); 1.195 + static inline Sign invertSign(Sign sign) { return sign == Negative ? Positive : Negative; } 1.196 + 1.197 + Sign sign() const { return m_data.sign(); } 1.198 + 1.199 + EncodedData m_data; 1.200 +}; 1.201 + 1.202 +} // namespace WebCore 1.203 + 1.204 +namespace mozilla { 1.205 + typedef WebCore::Decimal Decimal; 1.206 +} 1.207 + 1.208 +#undef WTF_MAKE_FAST_ALLOCATED 1.209 + 1.210 +#ifdef DEFINED_ASSERT_FOR_DECIMAL_H 1.211 +#undef DEFINED_ASSERT_FOR_DECIMAL_H 1.212 +#undef ASSERT 1.213 +#endif 1.214 + 1.215 +#endif // Decimal_h 1.216 +