Add rive::math::msb()

Adds a method that can be used to find the location of the most significant bit of a uint32_t.

Diffs=
cbc6ba291 Add rive::math::msb() (#5777)

Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com>
diff --git a/.rive_head b/.rive_head
index 1e13964..1e45a30 100644
--- a/.rive_head
+++ b/.rive_head
@@ -1 +1 @@
-58cc495802007c308ee4aa7b27dd755baaff7492
+cbc6ba291319eb8c3f05894c859dfc86cc4dddea
diff --git a/include/rive/math/math_types.hpp b/include/rive/math/math_types.hpp
index 1b6db5f..a830408 100644
--- a/include/rive/math/math_types.hpp
+++ b/include/rive/math/math_types.hpp
@@ -59,10 +59,31 @@
     RIVE_INLINE_MEMCPY(&dst, &src, sizeof(Dst));
     return dst;
 }
+
+// Returns the 1-based index of the most significat bit in x.
+//
+//   0    -> 0
+//   1    -> 1
+//   2..3 -> 2
+//   4..7 -> 3
+//   ...
+//
+RIVE_ALWAYS_INLINE static uint32_t msb(uint32_t x)
+{
+    if (x == 0)
+    {
+        return 0; // __builtin_clz is undefined for x=0, and the double method doesn't work either.
+    }
+#if defined(__clang__) || defined(__GNUC__)
+    return 32 - __builtin_clz(x);
+#else
+    uint64_t doubleBits = bit_cast<uint64_t>(static_cast<double>(x));
+    return (doubleBits >> 52) - 1022;
+#endif
+}
 } // namespace math
 
 template <typename T> T lerp(const T& a, const T& b, float t) { return a + (b - a) * t; }
-
 } // namespace rive
 
 #endif
diff --git a/test/math_test.cpp b/test/math_test.cpp
index 7057b84..63bfabf 100644
--- a/test/math_test.cpp
+++ b/test/math_test.cpp
@@ -60,3 +60,23 @@
     CHECK(math::bit_cast<float>((1u << 31) | 0x7f800000) == -kInf);
     CHECK(std::isnan(math::bit_cast<float>(0x7fc00000)));
 }
+
+// Check math::nextlog2.
+TEST_CASE("nextlog2", "[math]")
+{
+    CHECK(math::msb(0) == 0);
+    CHECK(math::msb(1) == 1);
+    CHECK(math::msb(2) == 2);
+    CHECK(math::msb(3) == 2);
+    CHECK(math::msb(4) == 3);
+    CHECK(math::msb(5) == 3);
+    CHECK(math::msb(6) == 3);
+    CHECK(math::msb(7) == 3);
+    CHECK(math::msb(8) == 4);
+    CHECK(math::msb(9) == 4);
+    for (int i = 0; i < 29; ++i)
+    {
+        CHECK(math::msb(10 << i) == 4 + i);
+    }
+    CHECK(math::msb(0xffffffff) == 32);
+}