summaryrefslogtreecommitdiffstats
path: root/mfbt/EnumTypeTraits.h
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /mfbt/EnumTypeTraits.h
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'mfbt/EnumTypeTraits.h')
-rw-r--r--mfbt/EnumTypeTraits.h70
1 files changed, 70 insertions, 0 deletions
diff --git a/mfbt/EnumTypeTraits.h b/mfbt/EnumTypeTraits.h
new file mode 100644
index 000000000..223eaf8c0
--- /dev/null
+++ b/mfbt/EnumTypeTraits.h
@@ -0,0 +1,70 @@
+/* -*- 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/. */
+
+/* Type traits for enums. */
+
+#ifndef mozilla_EnumTypeTraits_h
+#define mozilla_EnumTypeTraits_h
+
+#include <type_traits>
+
+namespace mozilla {
+
+namespace detail {
+
+template<size_t EnumSize, bool EnumSigned, size_t StorageSize, bool StorageSigned>
+struct EnumFitsWithinHelper;
+
+// Signed enum, signed storage.
+template<size_t EnumSize, size_t StorageSize>
+struct EnumFitsWithinHelper<EnumSize, true, StorageSize, true>
+ : public std::integral_constant<bool, (EnumSize <= StorageSize)>
+{};
+
+// Signed enum, unsigned storage.
+template<size_t EnumSize, size_t StorageSize>
+struct EnumFitsWithinHelper<EnumSize, true, StorageSize, false>
+ : public std::integral_constant<bool, false>
+{};
+
+// Unsigned enum, signed storage.
+template<size_t EnumSize, size_t StorageSize>
+struct EnumFitsWithinHelper<EnumSize, false, StorageSize, true>
+ : public std::integral_constant<bool, (EnumSize * 2 <= StorageSize)>
+{};
+
+// Unsigned enum, unsigned storage.
+template<size_t EnumSize, size_t StorageSize>
+struct EnumFitsWithinHelper<EnumSize, false, StorageSize, false>
+ : public std::integral_constant<bool, (EnumSize <= StorageSize)>
+{};
+
+} // namespace detail
+
+/*
+ * Type trait that determines whether the enum type T can fit within the
+ * integral type Storage without data loss. This trait should be used with
+ * caution with an enum type whose underlying type has not been explicitly
+ * specified: for such enums, the C++ implementation is free to choose a type
+ * no smaller than int whose range encompasses all possible values of the enum.
+ * So for an enum with only small non-negative values, the underlying type may
+ * be either int or unsigned int, depending on the whims of the implementation.
+ */
+template<typename T, typename Storage>
+struct EnumTypeFitsWithin
+ : public detail::EnumFitsWithinHelper<
+ sizeof(T),
+ std::is_signed<typename std::underlying_type<T>::type>::value,
+ sizeof(Storage),
+ std::is_signed<Storage>::value
+ >
+{
+ static_assert(std::is_enum<T>::value, "must provide an enum type");
+ static_assert(std::is_integral<Storage>::value, "must provide an integral type");
+};
+
+} // namespace mozilla
+
+#endif /* mozilla_EnumTypeTraits_h */