author | Jeff Walden <jwalden@mit.edu> |
Thu, 06 Jun 2013 18:47:51 -0700 | |
changeset 134659 | 57c346bd9ec3e19b545f17848fa3c4f6d28cef37 |
parent 134658 | 3f3ab64fea609645aafa1dce55ba2a6c842a4d93 |
child 134660 | e4473d563e0f290a838efcd2a21c348774ec558b |
push id | 24810 |
push user | ryanvm@gmail.com |
push date | Wed, 12 Jun 2013 01:03:01 +0000 |
treeherder | mozilla-central@cc35f8929768 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | froydnj |
bugs | 798179 |
milestone | 24.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
mfbt/Casting.h | file | annotate | diff | comparison | revisions | |
mfbt/tests/TestCasting.cpp | file | annotate | diff | comparison | revisions |
--- a/mfbt/Casting.h +++ b/mfbt/Casting.h @@ -10,16 +10,37 @@ #include "mozilla/Assertions.h" #include "mozilla/TypeTraits.h" #include <limits.h> 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<typename To, typename From> +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 }; enum FromSignedness { FromIsSigned, FromIsUnsigned }; template<typename From, typename To, FromSignedness = IsSigned<From>::value ? FromIsSigned : FromIsUnsigned,
--- a/mfbt/tests/TestCasting.cpp +++ b/mfbt/tests/TestCasting.cpp @@ -1,18 +1,43 @@ /* -*- 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/. */ #include "mozilla/Casting.h" #include "mozilla/StandardInteger.h" +using mozilla::BitwiseCast; using mozilla::detail::IsInBounds; +template<typename Uint, typename Ulong, bool = (sizeof(Uint) == sizeof(Ulong))> +struct UintUlongBitwiseCast; + +template<typename Uint, typename Ulong> +struct UintUlongBitwiseCast<Uint, Ulong, true> +{ + static void test() { + MOZ_ASSERT(BitwiseCast<Ulong>(Uint(8675309)) == Ulong(8675309)); + } +}; + +template<typename Uint, typename Ulong> +struct UintUlongBitwiseCast<Uint, Ulong, false> +{ + static void test() { } +}; + +static void +TestBitwiseCast() +{ + MOZ_ASSERT(BitwiseCast<int>(int(8675309)) == int(8675309)); + UintUlongBitwiseCast<unsigned int, unsigned long>::test(); +} + static void TestSameSize() { MOZ_ASSERT((IsInBounds<int16_t, int16_t>(int16_t(0)))); MOZ_ASSERT((IsInBounds<int16_t, int16_t>(int16_t(INT16_MIN)))); MOZ_ASSERT((IsInBounds<int16_t, int16_t>(int16_t(INT16_MAX)))); MOZ_ASSERT((IsInBounds<uint16_t, uint16_t>(uint16_t(UINT16_MAX)))); MOZ_ASSERT((IsInBounds<uint16_t, int16_t>(uint16_t(0)))); @@ -69,12 +94,14 @@ TestToSmallerSize() MOZ_ASSERT((IsInBounds<int64_t, uint32_t>(int64_t(UINT32_MAX) - 1))); MOZ_ASSERT((IsInBounds<int64_t, uint32_t>(int64_t(UINT32_MAX)))); MOZ_ASSERT((!IsInBounds<int64_t, uint32_t>(int64_t(UINT32_MAX) + 1))); } int main() { + TestBitwiseCast(); + TestSameSize(); TestToBiggerSize(); TestToSmallerSize(); }