diff --git a/dom/canvas/ClientWebGLContext.cpp b/dom/canvas/ClientWebGLContext.cpp index 37f95372ae23..7efc3df150ae 100644 --- a/dom/canvas/ClientWebGLContext.cpp +++ b/dom/canvas/ClientWebGLContext.cpp @@ -3728,7 +3728,7 @@ static std::string ToString(const js::Scalar::Type type) { break; } MOZ_ASSERT(false); - return std::string("#") + std::to_string(EnumValue(type)); + return std::string("#") + std::to_string(UnderlyingValue(type)); } ///////////////////////////////////////////////// diff --git a/dom/canvas/ClientWebGLContext.h b/dom/canvas/ClientWebGLContext.h index a62dadef160a..de26cf3bf5a0 100644 --- a/dom/canvas/ClientWebGLContext.h +++ b/dom/canvas/ClientWebGLContext.h @@ -208,7 +208,8 @@ struct NotLostData final { UniquePtr inProcess; webgl::ContextGenerationInfo state; - std::array, EnumValue(WebGLExtensionID::Max)> + std::array, + UnderlyingValue(WebGLExtensionID::Max)> extensions; explicit NotLostData(ClientWebGLContext& context); @@ -2076,7 +2077,7 @@ class ClientWebGLContext final : public nsICanvasRenderingContextInternal, public: bool IsExtensionEnabled(const WebGLExtensionID id) const { - return bool(mNotLost->extensions[EnumValue(id)]); + return bool(mNotLost->extensions[UnderlyingValue(id)]); } void AddCompressedFormat(GLenum); diff --git a/dom/canvas/WebGLContextExtensions.cpp b/dom/canvas/WebGLContextExtensions.cpp index ad00807fd9a8..db931de4d168 100644 --- a/dom/canvas/WebGLContextExtensions.cpp +++ b/dom/canvas/WebGLContextExtensions.cpp @@ -121,7 +121,7 @@ RefPtr ClientWebGLContext::GetExtension( if (!IsSupported(ext, callerType)) return nullptr; - auto& extSlot = mNotLost->extensions[EnumValue(ext)]; + auto& extSlot = mNotLost->extensions[UnderlyingValue(ext)]; if (MOZ_UNLIKELY(!extSlot)) { extSlot = [&]() -> RefPtr { switch (ext) { diff --git a/dom/canvas/WebGLContextValidate.cpp b/dom/canvas/WebGLContextValidate.cpp index 12e90a552c57..462f26258b20 100644 --- a/dom/canvas/WebGLContextValidate.cpp +++ b/dom/canvas/WebGLContextValidate.cpp @@ -184,7 +184,7 @@ bool WebGLContext::ValidateAttribArraySetter(uint32_t setterElemSize, static webgl::Limits MakeLimits(const WebGLContext& webgl) { webgl::Limits limits; - for (const auto i : IntegerRange(EnumValue(WebGLExtensionID::Max))) { + for (const auto i : IntegerRange(UnderlyingValue(WebGLExtensionID::Max))) { const auto ext = WebGLExtensionID(i); limits.supportedExtensions[ext] = webgl.IsExtensionSupported(ext); } diff --git a/dom/canvas/WebGLTypes.h b/dom/canvas/WebGLTypes.h index 775bf13c0303..edf29b97f61f 100644 --- a/dom/canvas/WebGLTypes.h +++ b/dom/canvas/WebGLTypes.h @@ -246,11 +246,6 @@ enum class WebGLExtensionID : uint8_t { Max }; -template -inline constexpr auto EnumValue(const T v) { - return static_cast::type>(v); -} - class UniqueBuffer { // Like UniquePtr<>, but for void* and malloc/calloc/free. void* mBuffer; diff --git a/mfbt/EnumTypeTraits.h b/mfbt/EnumTypeTraits.h index d15aeddd55e4..528e1db8a794 100644 --- a/mfbt/EnumTypeTraits.h +++ b/mfbt/EnumTypeTraits.h @@ -84,6 +84,30 @@ struct EnumTypeFitsWithin template struct MaxEnumValue; // no need to define the primary template +/** + * Get the underlying value of an enum, but typesafe. + * + * example: + * + * enum class Pet : int16_t { + * Cat, + * Dog, + * Fish + * }; + * enum class Plant { + * Flower, + * Tree, + * Vine + * }; + * UnderlyingValue(Pet::Fish) -> int16_t(2) + * UnderlyingValue(Plant::Tree) -> int(1) + */ +template +inline constexpr auto UnderlyingValue(const T v) { + static_assert(std::is_enum_v); + return static_cast::type>(v); +} + } // namespace mozilla #endif /* mozilla_EnumTypeTraits_h */ diff --git a/mfbt/tests/TestEnumTypeTraits.cpp b/mfbt/tests/TestEnumTypeTraits.cpp index 7951ee144de5..7fb0161bbcdc 100644 --- a/mfbt/tests/TestEnumTypeTraits.cpp +++ b/mfbt/tests/TestEnumTypeTraits.cpp @@ -3,8 +3,9 @@ * 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/IntegerTypeTraits.h" +#include "mozilla/Assertions.h" #include "mozilla/EnumTypeTraits.h" +#include "mozilla/IntegerTypeTraits.h" using namespace mozilla; @@ -29,7 +30,7 @@ static void TestShouldNotFit() { "Should not fit within"); } -int main() { +void TestFitForTypes() { // check for int8_t MAKE_FIXED_EMUM_FOR_TYPE(int8_t); TestShouldFit(); @@ -125,6 +126,33 @@ int main() { TestShouldNotFit(); TestShouldNotFit(); TestShouldNotFit(); +} +// - + +template +static constexpr void AssertSameTypeAndValue(T a, U b) { + static_assert(std::is_same_v); + MOZ_ASSERT(a == b); +} + +void TestUnderlyingValue() { + enum class Pet : int16_t { Cat, Dog, Fish }; + enum class Plant { Flower, Tree, Vine }; + + AssertSameTypeAndValue(UnderlyingValue(Pet::Cat), int16_t(0)); + AssertSameTypeAndValue(UnderlyingValue(Pet::Dog), int16_t(1)); + AssertSameTypeAndValue(UnderlyingValue(Pet::Fish), int16_t(2)); + + AssertSameTypeAndValue(UnderlyingValue(Plant::Flower), int(0)); + AssertSameTypeAndValue(UnderlyingValue(Plant::Tree), int(1)); + AssertSameTypeAndValue(UnderlyingValue(Plant::Vine), int(2)); +} + +// - + +int main() { + TestFitForTypes(); + TestUnderlyingValue(); return 0; }