summaryrefslogtreecommitdiff
path: root/mfbt/MathAlgorithms.h
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2013-12-11 22:24:18 +0000
committer <>2014-07-24 09:30:59 +0000
commit59e2936f588aa945e8dcd6c737523c299067e9d0 (patch)
tree97e74980cc54baa19de5faa11f5a50a0121a48ea /mfbt/MathAlgorithms.h
downloadmozjs24-59e2936f588aa945e8dcd6c737523c299067e9d0.tar.gz
Imported from /home/lorry/working-area/delta_mozilla_mozjs24/mozjs-24.2.0.tar.bz2.HEADmozjs-24.2.0master
Diffstat (limited to 'mfbt/MathAlgorithms.h')
-rw-r--r--mfbt/MathAlgorithms.h147
1 files changed, 147 insertions, 0 deletions
diff --git a/mfbt/MathAlgorithms.h b/mfbt/MathAlgorithms.h
new file mode 100644
index 0000000..0a47810
--- /dev/null
+++ b/mfbt/MathAlgorithms.h
@@ -0,0 +1,147 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* mfbt maths algorithms. */
+
+#ifndef mozilla_MathAlgorithms_h_
+#define mozilla_MathAlgorithms_h_
+
+#include "mozilla/Assertions.h"
+#include "mozilla/StandardInteger.h"
+#include "mozilla/TypeTraits.h"
+
+#include <cmath>
+#include <limits.h>
+
+namespace mozilla {
+
+// Greatest Common Divisor
+template<typename IntegerType>
+MOZ_ALWAYS_INLINE IntegerType
+EuclidGCD(IntegerType a, IntegerType b)
+{
+ // Euclid's algorithm; O(N) in the worst case. (There are better
+ // ways, but we don't need them for the current use of this algo.)
+ MOZ_ASSERT(a > 0);
+ MOZ_ASSERT(b > 0);
+
+ while (a != b) {
+ if (a > b) {
+ a = a - b;
+ } else {
+ b = b - a;
+ }
+ }
+
+ return a;
+}
+
+// Least Common Multiple
+template<typename IntegerType>
+MOZ_ALWAYS_INLINE IntegerType
+EuclidLCM(IntegerType a, IntegerType b)
+{
+ // Divide first to reduce overflow risk.
+ return (a / EuclidGCD(a, b)) * b;
+}
+
+namespace detail {
+
+template<typename T>
+struct AllowDeprecatedAbsFixed : FalseType {};
+
+template<> struct AllowDeprecatedAbsFixed<int32_t> : TrueType {};
+template<> struct AllowDeprecatedAbsFixed<int64_t> : TrueType {};
+
+template<typename T>
+struct AllowDeprecatedAbs : AllowDeprecatedAbsFixed<T> {};
+
+template<> struct AllowDeprecatedAbs<int> : TrueType {};
+template<> struct AllowDeprecatedAbs<long> : TrueType {};
+
+} // namespace detail
+
+// DO NOT USE DeprecatedAbs. It exists only until its callers can be converted
+// to Abs below, and it will be removed when all callers have been changed.
+template<typename T>
+inline typename mozilla::EnableIf<detail::AllowDeprecatedAbs<T>::value, T>::Type
+DeprecatedAbs(const T t)
+{
+ // The absolute value of the smallest possible value of a signed-integer type
+ // won't fit in that type (on twos-complement systems -- and we're blithely
+ // assuming we're on such systems, for the non-<stdint.h> types listed above),
+ // so assert that the input isn't that value.
+ //
+ // This is the case if: the value is non-negative; or if adding one (giving a
+ // value in the range [-maxvalue, 0]), then negating (giving a value in the
+ // range [0, maxvalue]), doesn't produce maxvalue (because in twos-complement,
+ // (minvalue + 1) == -maxvalue).
+ MOZ_ASSERT(t >= 0 ||
+ -(t + 1) != T((1ULL << (CHAR_BIT * sizeof(T) - 1)) - 1),
+ "You can't negate the smallest possible negative integer!");
+ return t >= 0 ? t : -t;
+}
+
+namespace detail {
+
+// For now mozilla::Abs only takes intN_T, the signed natural types, and
+// float/double/long double. Feel free to add overloads for other standard,
+// signed types if you need them.
+
+template<typename T>
+struct AbsReturnTypeFixed;
+
+template<> struct AbsReturnTypeFixed<int8_t> { typedef uint8_t Type; };
+template<> struct AbsReturnTypeFixed<int16_t> { typedef uint16_t Type; };
+template<> struct AbsReturnTypeFixed<int32_t> { typedef uint32_t Type; };
+template<> struct AbsReturnTypeFixed<int64_t> { typedef uint64_t Type; };
+
+template<typename T>
+struct AbsReturnType : AbsReturnTypeFixed<T> {};
+
+template<> struct AbsReturnType<char> : EnableIf<char(-1) < char(0), unsigned char> {};
+template<> struct AbsReturnType<signed char> { typedef unsigned char Type; };
+template<> struct AbsReturnType<short> { typedef unsigned short Type; };
+template<> struct AbsReturnType<int> { typedef unsigned int Type; };
+template<> struct AbsReturnType<long> { typedef unsigned long Type; };
+template<> struct AbsReturnType<long long> { typedef unsigned long long Type; };
+template<> struct AbsReturnType<float> { typedef float Type; };
+template<> struct AbsReturnType<double> { typedef double Type; };
+template<> struct AbsReturnType<long double> { typedef long double Type; };
+
+} // namespace detail
+
+template<typename T>
+inline typename detail::AbsReturnType<T>::Type
+Abs(const T t)
+{
+ typedef typename detail::AbsReturnType<T>::Type ReturnType;
+ return t >= 0 ? ReturnType(t) : ~ReturnType(t) + 1;
+}
+
+template<>
+inline float
+Abs<float>(const float f)
+{
+ return std::fabs(f);
+}
+
+template<>
+inline double
+Abs<double>(const double d)
+{
+ return std::fabs(d);
+}
+
+template<>
+inline long double
+Abs<long double>(const long double d)
+{
+ return std::fabs(d);
+}
+
+} /* namespace mozilla */
+
+#endif /* mozilla_MathAlgorithms_h_ */