1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mfbt/IntegerTypeTraits.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,119 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +/* Helpers to manipulate integer types that don't fit in TypeTraits.h */ 1.11 + 1.12 +#ifndef mozilla_IntegerTypeTraits_h 1.13 +#define mozilla_IntegerTypeTraits_h 1.14 + 1.15 +#include "mozilla/TypeTraits.h" 1.16 +#include <stdint.h> 1.17 + 1.18 +namespace mozilla { 1.19 + 1.20 +namespace detail { 1.21 + 1.22 +/** 1.23 + * StdintTypeForSizeAndSignedness returns the stdint integer type 1.24 + * of given size (can be 1, 2, 4 or 8) and given signedness 1.25 + * (false means unsigned, true means signed). 1.26 + */ 1.27 +template<size_t Size, bool Signedness> 1.28 +struct StdintTypeForSizeAndSignedness; 1.29 + 1.30 +template<> 1.31 +struct StdintTypeForSizeAndSignedness<1, true> 1.32 +{ typedef int8_t Type; }; 1.33 + 1.34 +template<> 1.35 +struct StdintTypeForSizeAndSignedness<1, false> 1.36 +{ typedef uint8_t Type; }; 1.37 + 1.38 +template<> 1.39 +struct StdintTypeForSizeAndSignedness<2, true> 1.40 +{ typedef int16_t Type; }; 1.41 + 1.42 +template<> 1.43 +struct StdintTypeForSizeAndSignedness<2, false> 1.44 +{ typedef uint16_t Type; }; 1.45 + 1.46 +template<> 1.47 +struct StdintTypeForSizeAndSignedness<4, true> 1.48 +{ typedef int32_t Type; }; 1.49 + 1.50 +template<> 1.51 +struct StdintTypeForSizeAndSignedness<4, false> 1.52 +{ typedef uint32_t Type; }; 1.53 + 1.54 +template<> 1.55 +struct StdintTypeForSizeAndSignedness<8, true> 1.56 +{ typedef int64_t Type; }; 1.57 + 1.58 +template<> 1.59 +struct StdintTypeForSizeAndSignedness<8, false> 1.60 +{ typedef uint64_t Type; }; 1.61 + 1.62 +} // namespace detail 1.63 + 1.64 +template<size_t Size> 1.65 +struct UnsignedStdintTypeForSize 1.66 + : detail::StdintTypeForSizeAndSignedness<Size, false> 1.67 +{}; 1.68 + 1.69 +template<typename IntegerType> 1.70 +struct PositionOfSignBit 1.71 +{ 1.72 + static_assert(IsIntegral<IntegerType>::value, "PositionOfSignBit is only for integral types"); 1.73 + // 8 here should be CHAR_BIT from limits.h, but the world has moved on. 1.74 + static const size_t value = 8 * sizeof(IntegerType) - 1; 1.75 +}; 1.76 + 1.77 +/** 1.78 + * MinValue returns the minimum value of the given integer type as a 1.79 + * compile-time constant, which std::numeric_limits<IntegerType>::min() 1.80 + * cannot do in c++98. 1.81 + */ 1.82 +template<typename IntegerType> 1.83 +struct MinValue 1.84 +{ 1.85 + private: 1.86 + static_assert(IsIntegral<IntegerType>::value, "MinValue is only for integral types"); 1.87 + 1.88 + typedef typename MakeUnsigned<IntegerType>::Type UnsignedIntegerType; 1.89 + static const size_t PosOfSignBit = PositionOfSignBit<IntegerType>::value; 1.90 + 1.91 + public: 1.92 + // Bitwise ops may return a larger type, that's why we cast explicitly. 1.93 + // In C++, left bit shifts on signed values is undefined by the standard 1.94 + // unless the shifted value is representable. 1.95 + // Notice that signed-to-unsigned conversions are always well-defined in 1.96 + // the standard as the value congruent to 2**n, as expected. By contrast, 1.97 + // unsigned-to-signed is only well-defined if the value is representable. 1.98 + static const IntegerType value = 1.99 + IsSigned<IntegerType>::value 1.100 + ? IntegerType(UnsignedIntegerType(1) << PosOfSignBit) 1.101 + : IntegerType(0); 1.102 +}; 1.103 + 1.104 +/** 1.105 + * MaxValue returns the maximum value of the given integer type as a 1.106 + * compile-time constant, which std::numeric_limits<IntegerType>::max() 1.107 + * cannot do in c++98. 1.108 + */ 1.109 +template<typename IntegerType> 1.110 +struct MaxValue 1.111 +{ 1.112 + static_assert(IsIntegral<IntegerType>::value, "MaxValue is only for integral types"); 1.113 + 1.114 + // Tricksy, but covered by the CheckedInt unit test. 1.115 + // Relies on the type of MinValue<IntegerType>::value 1.116 + // being IntegerType. 1.117 + static const IntegerType value = ~MinValue<IntegerType>::value; 1.118 +}; 1.119 + 1.120 +} // namespace mozilla 1.121 + 1.122 +#endif // mozilla_IntegerTypeTraits_h