From 086c044dc34dfc0f74fbe41f4ecb402b2cd34884 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 03:13:33 +0200 Subject: Merging upstream version 125.0.1. Signed-off-by: Daniel Baumann --- mfbt/ArrayUtils.h | 8 ++-- mfbt/EnumTypeTraits.h | 82 +++++++++++++++++++++++++++----------- mfbt/EnumeratedArray.h | 29 ++++++++------ mfbt/RefPtr.h | 4 +- mfbt/ThreadLocal.h | 2 +- mfbt/tests/TestEnumeratedArray.cpp | 12 +++++- 6 files changed, 93 insertions(+), 44 deletions(-) (limited to 'mfbt') 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 class Array; -template +template class EnumeratedArray; /* @@ -64,9 +64,9 @@ constexpr size_t ArrayLength(const Array& aArr) { return N; } -template -constexpr size_t ArrayLength(const EnumeratedArray& aArr) { - return size_t(N); +template +constexpr size_t ArrayLength(const EnumeratedArray& 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 - * { - * static constexpr unsigned int value = static_cast(HAMSTER); - * }; - */ -template -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::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 + * { + * static constexpr ExampleEnumvalue = HAMSTER; + * }; + */ + +template +struct MinContiguousEnumValue { + static constexpr T value = static_cast(0); +}; + +template +struct MaxContiguousEnumValue; + +template +struct MaxEnumValue { + static constexpr auto value = MaxContiguousEnumValue::value; +}; + +// Provides the min and max values for a contiguous enum (requires at least +// MaxContiguousEnumValue to be defined). +template +struct ContiguousEnumValues { + static constexpr auto min = MinContiguousEnumValue::value; + static constexpr auto max = MaxContiguousEnumValue::value; +}; + +// Provides the total number of values for a contiguous enum (requires at least +// MaxContiguousEnumValue to be defined). +template +struct ContiguousEnumSize { + static constexpr size_t value = + UnderlyingValue(ContiguousEnumValues::max) + 1 - + UnderlyingValue(ContiguousEnumValues::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 #include "mozilla/Array.h" +#include "EnumTypeTraits.h" namespace mozilla { @@ -33,19 +34,23 @@ namespace mozilla { * Count * }; * - * EnumeratedArray headCount; + * EnumeratedArray 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 +template ::value> class EnumeratedArray { - public: - static const size_t kSize = size_t(SizeAsEnumValue); - private: - typedef Array ArrayType; + static_assert(UnderlyingValue(MinContiguousEnumValue::value) == 0, + "All indexes would need to be corrected if min != 0"); + + using ArrayType = Array; ArrayType mArray; @@ -56,16 +61,16 @@ class EnumeratedArray { MOZ_IMPLICIT constexpr EnumeratedArray(Args&&... aArgs) : mArray{std::forward(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&& aRefPtr) : mRawPtr(aRefPtr.mRawPtr) { + RefPtr(RefPtr&& aRefPtr) noexcept : mRawPtr(aRefPtr.mRawPtr) { aRefPtr.mRawPtr = nullptr; } @@ -224,7 +224,7 @@ class MOZ_IS_REFPTR RefPtr { template >> - RefPtr& operator=(RefPtr&& aRefPtr) { + RefPtr& operator=(RefPtr&& 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::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; +template <> +struct mozilla::MaxContiguousEnumValue { + static constexpr AnimalSpecies value = AnimalSpecies::Pig; +}; + +using TestArray = EnumeratedArray; 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); -- cgit v1.2.3