From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- mfbt/EnumTypeTraits.h | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 mfbt/EnumTypeTraits.h (limited to 'mfbt/EnumTypeTraits.h') diff --git a/mfbt/EnumTypeTraits.h b/mfbt/EnumTypeTraits.h new file mode 100644 index 0000000000..528e1db8a7 --- /dev/null +++ b/mfbt/EnumTypeTraits.h @@ -0,0 +1,113 @@ +/* -*- 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 +#include + +namespace mozilla { + +namespace detail { + +template +struct EnumFitsWithinHelper; + +// Signed enum, signed storage. +template +struct EnumFitsWithinHelper + : public std::integral_constant {}; + +// Signed enum, unsigned storage. +template +struct EnumFitsWithinHelper + : public std::integral_constant {}; + +// Unsigned enum, signed storage. +template +struct EnumFitsWithinHelper + : public std::integral_constant {}; + +// Unsigned enum, unsigned storage. +template +struct EnumFitsWithinHelper + : public std::integral_constant {}; + +} // 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 +struct EnumTypeFitsWithin + : public detail::EnumFitsWithinHelper< + sizeof(T), + std::is_signed::type>::value, + sizeof(Storage), std::is_signed::value> { + static_assert(std::is_enum::value, "must provide an enum type"); + static_assert(std::is_integral::value, + "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. + * + * 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 */ -- cgit v1.2.3