Bug 1499346 [wpt PR 13540] - Use a common blank reference for wpt/css., a=testonly
[gecko.git] / mfbt / EnumTypeTraits.h
blob0783dd654b6f881ce526dc6d0b5d69761ea6a790
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 /* Type traits for enums. */
8 #ifndef mozilla_EnumTypeTraits_h
9 #define mozilla_EnumTypeTraits_h
11 #include <type_traits>
13 namespace mozilla {
15 namespace detail {
17 template<size_t EnumSize, bool EnumSigned, size_t StorageSize, bool StorageSigned>
18 struct EnumFitsWithinHelper;
20 // Signed enum, signed storage.
21 template<size_t EnumSize, size_t StorageSize>
22 struct EnumFitsWithinHelper<EnumSize, true, StorageSize, true>
23 : public std::integral_constant<bool, (EnumSize <= StorageSize)>
24 {};
26 // Signed enum, unsigned storage.
27 template<size_t EnumSize, size_t StorageSize>
28 struct EnumFitsWithinHelper<EnumSize, true, StorageSize, false>
29 : public std::integral_constant<bool, false>
30 {};
32 // Unsigned enum, signed storage.
33 template<size_t EnumSize, size_t StorageSize>
34 struct EnumFitsWithinHelper<EnumSize, false, StorageSize, true>
35 : public std::integral_constant<bool, (EnumSize * 2 <= StorageSize)>
36 {};
38 // Unsigned enum, unsigned storage.
39 template<size_t EnumSize, size_t StorageSize>
40 struct EnumFitsWithinHelper<EnumSize, false, StorageSize, false>
41 : public std::integral_constant<bool, (EnumSize <= StorageSize)>
42 {};
44 } // namespace detail
47 * Type trait that determines whether the enum type T can fit within the
48 * integral type Storage without data loss. This trait should be used with
49 * caution with an enum type whose underlying type has not been explicitly
50 * specified: for such enums, the C++ implementation is free to choose a type
51 * no smaller than int whose range encompasses all possible values of the enum.
52 * So for an enum with only small non-negative values, the underlying type may
53 * be either int or unsigned int, depending on the whims of the implementation.
55 template<typename T, typename Storage>
56 struct EnumTypeFitsWithin
57 : public detail::EnumFitsWithinHelper<
58 sizeof(T),
59 std::is_signed<typename std::underlying_type<T>::type>::value,
60 sizeof(Storage),
61 std::is_signed<Storage>::value
64 static_assert(std::is_enum<T>::value, "must provide an enum type");
65 static_assert(std::is_integral<Storage>::value, "must provide an integral type");
69 * Provides information about highest enum member value.
70 * Each specialization of struct MaxEnumValue should define
71 * "static constexpr unsigned int value".
73 * example:
75 * enum ExampleEnum
76 * {
77 * CAT = 0,
78 * DOG,
79 * HAMSTER
80 * };
82 * template <>
83 * struct MaxEnumValue<ExampleEnum>
84 * {
85 * static constexpr unsigned int value = static_cast<unsigned int>(HAMSTER);
86 * };
88 template <typename T>
89 struct MaxEnumValue; // no need to define the primary template
91 } // namespace mozilla
93 #endif /* mozilla_EnumTypeTraits_h */