From 38cfd84ad83ec8c506124c8073b4b8ae94aa7e9a Mon Sep 17 00:00:00 2001 From: Jeff Walden Date: Thu, 6 Jun 2013 18:47:51 -0700 Subject: [PATCH] Bug 798179 - Implement To BitwiseCast(From), abstracting the treatment of a value's bits as being of another type. r=froydnj --HG-- extra : rebase_source : e6c57c10f7035b2654eafdd5fa2b3c5d8882f282 --- mfbt/Casting.h | 21 +++++++++++++++++++++ mfbt/tests/TestCasting.cpp | 27 +++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/mfbt/Casting.h b/mfbt/Casting.h index b1e81c33fa90..07ba73100880 100644 --- a/mfbt/Casting.h +++ b/mfbt/Casting.h @@ -15,6 +15,27 @@ namespace mozilla { +/** + * Return a value of type |To|, containing the underlying bit pattern of |from|. + * + * |To| and |From| must be types of the same size; be careful of cross-platform + * size differences, or this might fail to compile on some but not all + * platforms. + */ +template +inline To +BitwiseCast(const From from) +{ + MOZ_STATIC_ASSERT(sizeof(From) == sizeof(To), + "To and From must have the same size"); + union { + From from; + To to; + } u; + u.from = from; + return u.to; +} + namespace detail { enum ToSignedness { ToIsSigned, ToIsUnsigned }; diff --git a/mfbt/tests/TestCasting.cpp b/mfbt/tests/TestCasting.cpp index 80c281f6fa19..1e19b07f04db 100644 --- a/mfbt/tests/TestCasting.cpp +++ b/mfbt/tests/TestCasting.cpp @@ -6,8 +6,33 @@ #include "mozilla/Casting.h" #include "mozilla/StandardInteger.h" +using mozilla::BitwiseCast; using mozilla::detail::IsInBounds; +template +struct UintUlongBitwiseCast; + +template +struct UintUlongBitwiseCast +{ + static void test() { + MOZ_ASSERT(BitwiseCast(Uint(8675309)) == Ulong(8675309)); + } +}; + +template +struct UintUlongBitwiseCast +{ + static void test() { } +}; + +static void +TestBitwiseCast() +{ + MOZ_ASSERT(BitwiseCast(int(8675309)) == int(8675309)); + UintUlongBitwiseCast::test(); +} + static void TestSameSize() { @@ -74,6 +99,8 @@ TestToSmallerSize() int main() { + TestBitwiseCast(); + TestSameSize(); TestToBiggerSize(); TestToSmallerSize();