Bug 781313 - Move the euclidGcd and lcm algos form nsStyleAnimation.cpp to mfbt/MathAlgorithms.h r=dbaron,luke
authorRaphael Catolino <rcatolino@mozilla.com>
Sun, 26 Aug 2012 22:58:23 -0300
changeset 103518 b2ad6e5fc690e5fd561ef698d0bf8e0f291d9d04
parent 103517 810398e25284f42214eed1ec0d7dc9d85787d9b4
child 103519 64980ac7c48b3fc1fe72c5830cdb42e4f819a2fc
push idunknown
push userunknown
push dateunknown
reviewersdbaron, luke
bugs781313
milestone17.0a1
Bug 781313 - Move the euclidGcd and lcm algos form nsStyleAnimation.cpp to mfbt/MathAlgorithms.h r=dbaron,luke
layout/style/nsStyleAnimation.cpp
mfbt/MathAlgorithms.h
mfbt/exported_headers.mk
--- a/layout/style/nsStyleAnimation.cpp
+++ b/layout/style/nsStyleAnimation.cpp
@@ -1,16 +1,17 @@
 /* -*- 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/. */
 
 /* Utilities for animation of computed style values */
 
 #include "mozilla/Util.h"
+#include "mozilla/MathAlgorithms.h"
 
 #include "nsStyleAnimation.h"
 #include "nsCOMArray.h"
 #include "nsIStyleRule.h"
 #include "mozilla/css/StyleRule.h"
 #include "nsString.h"
 #include "nsStyleContext.h"
 #include "nsStyleSet.h"
@@ -237,43 +238,16 @@ ToPrimitive(nsCSSValue::Array* aArray)
       break;
     }
     default:
       arr = aArray;
   }
   return arr.forget();
 }
 
-// Greatest Common Divisor
-static uint32_t
-gcd(uint32_t a, uint32_t b)
-{
-  // Euclid's algorithm; O(N) in the worst case.  (There are better
-  // ways, but we don't need them for stroke-dasharray animation.)
-  NS_ABORT_IF_FALSE(a > 0 && b > 0, "positive numbers expected");
-
-  while (a != b) {
-    if (a > b) {
-      a = a - b;
-    } else {
-      b = b - a;
-    }
-  }
-
-  return a;
-}
-
-// Least Common Multiple
-static uint32_t
-lcm(uint32_t a, uint32_t b)
-{
-  // Divide first to reduce overflow risk.
-  return (a / gcd(a, b)) * b;
-}
-
 inline void
 nscoordToCSSValue(nscoord aCoord, nsCSSValue& aCSSValue)
 {
   aCSSValue.SetFloatValue(nsPresContext::AppUnitsToFloatCSSPixels(aCoord),
                           eCSSUnit_Pixel);
 }
 
 // Like nsStyleCoord::Calc, but with length in float pixels instead of nscoord.
@@ -1948,17 +1922,17 @@ nsStyleAnimation::AddWeighted(nsCSSPrope
           (list1->mValue.GetUnit() != eCSSUnit_None || len1 == 1) &&
           (list2->mValue.GetUnit() != eCSSUnit_None || len2 == 1),
           "multi-value valuelist with 'none' as first element");
         return false;
       }
 
       nsAutoPtr<nsCSSValueList> result;
       nsCSSValueList **resultTail = getter_Transfers(result);
-      for (uint32_t i = 0, i_end = lcm(len1, len2); i != i_end; ++i) {
+      for (uint32_t i = 0, i_end = EuclidLCM<uint32_t>(len1, len2); i != i_end; ++i) {
         const nsCSSValue &v1 = list1->mValue;
         const nsCSSValue &v2 = list2->mValue;
         NS_ABORT_IF_FALSE(v1.GetUnit() == eCSSUnit_Number ||
                           v1.GetUnit() == eCSSUnit_Percent, "unexpected");
         NS_ABORT_IF_FALSE(v2.GetUnit() == eCSSUnit_Number ||
                           v2.GetUnit() == eCSSUnit_Percent, "unexpected");
         if (v1.GetUnit() != v2.GetUnit()) {
           // Can't animate between lengths and percentages (until calc()).
new file mode 100644
--- /dev/null
+++ b/mfbt/MathAlgorithms.h
@@ -0,0 +1,47 @@
+/* -*- 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"
+
+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 mozilla */
+
+#endif  /* mozilla_MathAlgorithms_h_ */
--- a/mfbt/exported_headers.mk
+++ b/mfbt/exported_headers.mk
@@ -14,16 +14,17 @@ EXPORTS_mozilla += \
   BloomFilter.h \
   CheckedInt.h \
   Constants.h \
   FloatingPoint.h \
   GuardObjects.h \
   HashFunctions.h \
   Likely.h \
   LinkedList.h \
+  MathAlgorithms.h \
   MSStdInt.h \
   RangedPtr.h \
   RefPtr.h \
   Scoped.h \
   StandardInteger.h \
   SHA1.h \
   ThreadLocal.h \
   TypeTraits.h \