summaryrefslogtreecommitdiffstats
path: root/mfbt
diff options
context:
space:
mode:
Diffstat (limited to 'mfbt')
-rw-r--r--mfbt/ArrayUtils.h8
-rw-r--r--mfbt/EnumTypeTraits.h82
-rw-r--r--mfbt/EnumeratedArray.h29
-rw-r--r--mfbt/RefPtr.h4
-rw-r--r--mfbt/ThreadLocal.h2
-rw-r--r--mfbt/tests/TestEnumeratedArray.cpp12
6 files changed, 93 insertions, 44 deletions
diff --git a/mfbt/ArrayUtils.h b/mfbt/ArrayUtils.h
index 0d55bb1f65..78eec5daba 100644
--- a/mfbt/ArrayUtils.h
+++ b/mfbt/ArrayUtils.h
@@ -27,7 +27,7 @@ namespace mozilla {
template <typename T, size_t Length>
class Array;
-template <typename IndexType, IndexType SizeAsEnumValue, typename ValueType>
+template <typename IndexType, typename ValueType, size_t Size>
class EnumeratedArray;
/*
@@ -64,9 +64,9 @@ constexpr size_t ArrayLength(const Array<T, N>& aArr) {
return N;
}
-template <typename E, E N, typename T>
-constexpr size_t ArrayLength(const EnumeratedArray<E, N, T>& aArr) {
- return size_t(N);
+template <typename E, typename T, size_t N>
+constexpr size_t ArrayLength(const EnumeratedArray<E, T, N>& aArr) {
+ return N;
}
/*
diff --git a/mfbt/EnumTypeTraits.h b/mfbt/EnumTypeTraits.h
index 528e1db8a7..09ead3d0e9 100644
--- a/mfbt/EnumTypeTraits.h
+++ b/mfbt/EnumTypeTraits.h
@@ -61,29 +61,6 @@ struct EnumTypeFitsWithin
"must provide an integral type");
};
-/*
- * Provides information about highest enum member value.
- * Each specialization of struct MaxEnumValue should define
- * "static constexpr unsigned int value".
- *
- * example:
- *
- * enum ExampleEnum
- * {
- * CAT = 0,
- * DOG,
- * HAMSTER
- * };
- *
- * template <>
- * struct MaxEnumValue<ExampleEnum>
- * {
- * static constexpr unsigned int value = static_cast<unsigned int>(HAMSTER);
- * };
- */
-template <typename T>
-struct MaxEnumValue; // no need to define the primary template
-
/**
* Get the underlying value of an enum, but typesafe.
*
@@ -108,6 +85,65 @@ inline constexpr auto UnderlyingValue(const T v) {
return static_cast<typename std::underlying_type<T>::type>(v);
}
+/*
+ * Specialize either MaxContiguousEnumValue or MaxEnumValue to provide the
+ * highest enum member value for an enum class. Note that specializing
+ * MaxContiguousEnumValue will make MaxEnumValue just take its value from the
+ * MaxContiguousEnumValue specialization.
+ *
+ * Specialize MinContiguousEnumValue and MaxContiguousEnumValue to provide both
+ * lowest and highest enum member values for an enum class with contiguous
+ * values.
+ *
+ * Each specialization of these structs should define "static constexpr" member
+ * variable named "value".
+ *
+ * example:
+ *
+ * enum ExampleEnum
+ * {
+ * CAT = 0,
+ * DOG,
+ * HAMSTER
+ * };
+ *
+ * template <>
+ * struct MaxEnumValue<ExampleEnum>
+ * {
+ * static constexpr ExampleEnumvalue = HAMSTER;
+ * };
+ */
+
+template <typename T>
+struct MinContiguousEnumValue {
+ static constexpr T value = static_cast<T>(0);
+};
+
+template <typename T>
+struct MaxContiguousEnumValue;
+
+template <typename T>
+struct MaxEnumValue {
+ static constexpr auto value = MaxContiguousEnumValue<T>::value;
+};
+
+// Provides the min and max values for a contiguous enum (requires at least
+// MaxContiguousEnumValue to be defined).
+template <typename T>
+struct ContiguousEnumValues {
+ static constexpr auto min = MinContiguousEnumValue<T>::value;
+ static constexpr auto max = MaxContiguousEnumValue<T>::value;
+};
+
+// Provides the total number of values for a contiguous enum (requires at least
+// MaxContiguousEnumValue to be defined).
+template <typename T>
+struct ContiguousEnumSize {
+ static constexpr size_t value =
+ UnderlyingValue(ContiguousEnumValues<T>::max) + 1 -
+ UnderlyingValue(ContiguousEnumValues<T>::min);
+};
+
} // namespace mozilla
#endif /* mozilla_EnumTypeTraits_h */
diff --git a/mfbt/EnumeratedArray.h b/mfbt/EnumeratedArray.h
index f6edff4875..ba902d94b9 100644
--- a/mfbt/EnumeratedArray.h
+++ b/mfbt/EnumeratedArray.h
@@ -12,6 +12,7 @@
#include <utility>
#include "mozilla/Array.h"
+#include "EnumTypeTraits.h"
namespace mozilla {
@@ -33,19 +34,23 @@ namespace mozilla {
* Count
* };
*
- * EnumeratedArray<AnimalSpecies, AnimalSpecies::Count, int> headCount;
+ * EnumeratedArray<AnimalSpecies, int, AnimalSpecies::Count> headCount;
*
* headCount[AnimalSpecies::Cow] = 17;
* headCount[AnimalSpecies::Sheep] = 30;
*
+ * If the enum class has contiguous values and provides a specialization of
+ * mozilla::MaxContiguousEnumValue then the size will be calculated as the max
+ * value + 1.
*/
-template <typename IndexType, IndexType SizeAsEnumValue, typename ValueType>
+template <typename Enum, typename ValueType,
+ size_t Size = ContiguousEnumSize<Enum>::value>
class EnumeratedArray {
- public:
- static const size_t kSize = size_t(SizeAsEnumValue);
-
private:
- typedef Array<ValueType, kSize> ArrayType;
+ static_assert(UnderlyingValue(MinContiguousEnumValue<Enum>::value) == 0,
+ "All indexes would need to be corrected if min != 0");
+
+ using ArrayType = Array<ValueType, Size>;
ArrayType mArray;
@@ -56,16 +61,16 @@ class EnumeratedArray {
MOZ_IMPLICIT constexpr EnumeratedArray(Args&&... aArgs)
: mArray{std::forward<Args>(aArgs)...} {}
- ValueType& operator[](IndexType aIndex) { return mArray[size_t(aIndex)]; }
+ ValueType& operator[](Enum aIndex) { return mArray[size_t(aIndex)]; }
- const ValueType& operator[](IndexType aIndex) const {
+ const ValueType& operator[](Enum aIndex) const {
return mArray[size_t(aIndex)];
}
- typedef typename ArrayType::iterator iterator;
- typedef typename ArrayType::const_iterator const_iterator;
- typedef typename ArrayType::reverse_iterator reverse_iterator;
- typedef typename ArrayType::const_reverse_iterator const_reverse_iterator;
+ using iterator = typename ArrayType::iterator;
+ using const_iterator = typename ArrayType::const_iterator;
+ using reverse_iterator = typename ArrayType::reverse_iterator;
+ using const_reverse_iterator = typename ArrayType::const_reverse_iterator;
// Methods for range-based for loops.
iterator begin() { return mArray.begin(); }
diff --git a/mfbt/RefPtr.h b/mfbt/RefPtr.h
index 343e78d61e..27f22356ba 100644
--- a/mfbt/RefPtr.h
+++ b/mfbt/RefPtr.h
@@ -97,7 +97,7 @@ class MOZ_IS_REFPTR RefPtr {
}
}
- RefPtr(RefPtr<T>&& aRefPtr) : mRawPtr(aRefPtr.mRawPtr) {
+ RefPtr(RefPtr<T>&& aRefPtr) noexcept : mRawPtr(aRefPtr.mRawPtr) {
aRefPtr.mRawPtr = nullptr;
}
@@ -224,7 +224,7 @@ class MOZ_IS_REFPTR RefPtr {
template <typename I,
typename = std::enable_if_t<std::is_convertible_v<I*, T*>>>
- RefPtr<T>& operator=(RefPtr<I>&& aRefPtr) {
+ RefPtr<T>& operator=(RefPtr<I>&& aRefPtr) noexcept {
assign_assuming_AddRef(aRefPtr.forget().take());
return *this;
}
diff --git a/mfbt/ThreadLocal.h b/mfbt/ThreadLocal.h
index 55c9fbcac6..891b2cdd5d 100644
--- a/mfbt/ThreadLocal.h
+++ b/mfbt/ThreadLocal.h
@@ -240,7 +240,7 @@ inline void ThreadLocal<T, Storage>::set(const T aValue) {
# define MOZ_THREAD_LOCAL(TYPE) \
thread_local ::mozilla::detail::ThreadLocal< \
TYPE, ::mozilla::detail::ThreadLocalNativeStorage>
-#elif defined(HAVE_THREAD_TLS_KEYWORD)
+#elif defined(HAVE_THREAD_TLS_KEYWORD) && !defined(MOZ_LINKER)
# define MOZ_THREAD_LOCAL(TYPE) \
__thread ::mozilla::detail::ThreadLocal< \
TYPE, ::mozilla::detail::ThreadLocalNativeStorage>
diff --git a/mfbt/tests/TestEnumeratedArray.cpp b/mfbt/tests/TestEnumeratedArray.cpp
index dfc1a37f17..d5ec9ebbb3 100644
--- a/mfbt/tests/TestEnumeratedArray.cpp
+++ b/mfbt/tests/TestEnumeratedArray.cpp
@@ -4,17 +4,25 @@
* 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/ArrayUtils.h"
#include "mozilla/EnumeratedArray.h"
+#include "mozilla/EnumTypeTraits.h"
using mozilla::EnumeratedArray;
-enum class AnimalSpecies { Cow, Sheep, Pig, Count };
+enum class AnimalSpecies { Cow, Sheep, Pig };
-using TestArray = EnumeratedArray<AnimalSpecies, AnimalSpecies::Count, int>;
+template <>
+struct mozilla::MaxContiguousEnumValue<AnimalSpecies> {
+ static constexpr AnimalSpecies value = AnimalSpecies::Pig;
+};
+
+using TestArray = EnumeratedArray<AnimalSpecies, int>;
void TestInitialValueByConstructor() {
// Style 1
TestArray headCount(1, 2, 3);
+ MOZ_RELEASE_ASSERT(mozilla::ArrayLength(headCount) == 3);
MOZ_RELEASE_ASSERT(headCount[AnimalSpecies::Cow] == 1);
MOZ_RELEASE_ASSERT(headCount[AnimalSpecies::Sheep] == 2);
MOZ_RELEASE_ASSERT(headCount[AnimalSpecies::Pig] == 3);