diff --git a/mfbt/DefineEnum.h b/mfbt/DefineEnum.h index afcff10e5212..a195c840229c 100644 --- a/mfbt/DefineEnum.h +++ b/mfbt/DefineEnum.h @@ -10,6 +10,7 @@ #define mozilla_DefineEnum_h #include // for size_t +#include // for std::ostream #include "mozilla/MacroArgs.h" // for MOZ_ARG_COUNT #include "mozilla/MacroForEach.h" // for MOZ_FOR_EACH @@ -84,6 +85,14 @@ * and have names prefixed with "s" instead of "k" as per * naming convention. * + * - A |_TOSTRING| variant, which generates an EnumValueToString function, + * converting the enum items to strings, and implements an "operator<<", + * providing a consistent way to convert enums to strings by + * mozilla::ToString function regardless of their definition context. + * For users needing C-string compatibility for logging in restricted + * contexts or performance sensitive applications, EnumValueToString is + * preferred. + * * (and combinations of these). */ @@ -153,4 +162,58 @@ MOZ_DEFINE_ENUM_AT_CLASS_SCOPE_IMPL(aEnumName, class, \ : aBaseName, aEnumerators) +#define MOZ_DEFINE_ENUM_TO_ENUM_TEXT(aEnumeratorDecl) #aEnumeratorDecl + +#define MOZ_DEFINE_ENUM_TOSTRING_FUNC_IMPL(aEnumName, aEnumerators, aFriend) \ + inline static const char* EnumValueToString(const aEnumName& aEnum) { \ + static constexpr const char* kMappedStrings[] = {MOZ_FOR_EACH_SEPARATED( \ + MOZ_DEFINE_ENUM_TO_ENUM_TEXT, (, ), (), aEnumerators)}; \ + return kMappedStrings[static_cast(aEnum)]; \ + } \ + aFriend inline std::ostream& operator<<(std::ostream& aStream, \ + const aEnumName& aEnum) { \ + aStream << EnumValueToString(aEnum); \ + return aStream; \ + } + +#define MOZ_DEFINE_ENUM_TOSTRING_FUNC(aEnumName, aEnumerators) \ + MOZ_DEFINE_ENUM_TOSTRING_FUNC_IMPL(aEnumName, aEnumerators, ) + +#define MOZ_DEFINE_ENUM_TOSTRING_FUNC_IN_CLASS(aEnumName, aEnumerators) \ + MOZ_DEFINE_ENUM_TOSTRING_FUNC_IMPL(aEnumName, aEnumerators, friend) + +#define MOZ_DEFINE_ENUM_WITH_BASE_AND_TOSTRING(aEnumName, aBaseName, \ + aEnumerators) \ + MOZ_DEFINE_ENUM_WITH_BASE(aEnumName, aBaseName, aEnumerators) \ + MOZ_DEFINE_ENUM_TOSTRING_FUNC(aEnumName, aEnumerators) + +#define MOZ_DEFINE_ENUM_CLASS_WITH_TOSTRING(aEnumName, aEnumerators) \ + MOZ_DEFINE_ENUM_CLASS(aEnumName, aEnumerators) \ + MOZ_DEFINE_ENUM_TOSTRING_FUNC(aEnumName, aEnumerators) + +#define MOZ_DEFINE_ENUM_CLASS_WITH_BASE_AND_TOSTRING(aEnumName, aBaseName, \ + aEnumerators) \ + MOZ_DEFINE_ENUM_CLASS_WITH_BASE(aEnumName, aBaseName, aEnumerators) \ + MOZ_DEFINE_ENUM_TOSTRING_FUNC(aEnumName, aEnumerators) + +#define MOZ_DEFINE_ENUM_WITH_TOSTRING_AT_CLASS_SCOPE(aEnumName, aEnumerators) \ + MOZ_DEFINE_ENUM_AT_CLASS_SCOPE(aEnumName, aEnumerators) \ + MOZ_DEFINE_ENUM_TOSTRING_FUNC_IN_CLASS(aEnumName, aEnumerators) + +#define MOZ_DEFINE_ENUM_WITH_BASE_AND_TOSTRING_AT_CLASS_SCOPE( \ + aEnumName, aBaseName, aEnumerators) \ + MOZ_DEFINE_ENUM_WITH_BASE_AT_CLASS_SCOPE(aEnumName, aBaseName, aEnumerators) \ + MOZ_DEFINE_ENUM_TOSTRING_FUNC_IN_CLASS(aEnumName, aEnumerators) + +#define MOZ_DEFINE_ENUM_CLASS_WITH_TOSTRING_AT_CLASS_SCOPE(aEnumName, \ + aEnumerators) \ + MOZ_DEFINE_ENUM_CLASS_AT_CLASS_SCOPE(aEnumName, aEnumerators) \ + MOZ_DEFINE_ENUM_TOSTRING_FUNC_IN_CLASS(aEnumName, aEnumerators) + +#define MOZ_DEFINE_ENUM_CLASS_WITH_BASE_AND_TOSTRING_AT_CLASS_SCOPE( \ + aEnumName, aBaseName, aEnumerators) \ + MOZ_DEFINE_ENUM_CLASS_WITH_BASE_AT_CLASS_SCOPE(aEnumName, aBaseName, \ + aEnumerators) \ + MOZ_DEFINE_ENUM_TOSTRING_FUNC_IN_CLASS(aEnumName, aEnumerators) + #endif // mozilla_DefineEnum_h