diff options
Diffstat (limited to 'mfbt')
-rw-r--r-- | mfbt/ArrayUtils.h | 8 | ||||
-rw-r--r-- | mfbt/EnumTypeTraits.h | 82 | ||||
-rw-r--r-- | mfbt/EnumeratedArray.h | 29 | ||||
-rw-r--r-- | mfbt/RefPtr.h | 4 | ||||
-rw-r--r-- | mfbt/ThreadLocal.h | 2 | ||||
-rw-r--r-- | mfbt/tests/TestEnumeratedArray.cpp | 12 |
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); |