EnumFlags.h (8 lines of code) (raw):
// Copyright (c) Facebook, Inc. and its affiliates.
//
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#pragma once
#include "impl/EnumFlagsDetails.h"
/* MY_ENUMFLAGS_DEF(NAME, UINT_TYPE, ARGS)
Enum flags type definition. Can be in global, and namespace scope only. See
MY_ENUMFLAGS below for details. */
#define MY_ENUMFLAGS_DEF(NAME, UINT_TYPE, ...) \
MY_ENUMFLAGS_DEF_IMPL(NAME, UINT_TYPE, __VA_ARGS__)
/* MY_ENUMFLAGS_ALIAS(NAME)
Enum type alias. Can be in any scope. See MY_ENUMFLAGS for details. */
#define MY_ENUMFLAGS_ALIAS(NAME) using NAME = enum_wrapper_::NAME##Impl
/* MY_ENUMFLAGS(NAME, UINT_TYPE, ARGS)
Enum flag type. Can be in global, and namespace scope only.
NAME: Name of the enum flag class.
UINT_TYPE: unsigned integral type.
ARGS: Tuple of enums, such as (foo, bar, da).
For example ``MY_ENUMFLAGS(MyFlags, uint32_t, (foo, bar, daz));`` defines an
enum class
enum class MyFlags : uint32_t {
none = 0,
foo = 1,
bar = 2,
daz = 4
};
with the following free functions:
// Bitwise or
MyFlags operator|(MyFlags left, MyFlags right);
// Bitwise and
MyFlags operator&(MyFlags left, MyFlags right);
// Sets corresponding bit to 1, if string is single flag (i.e. "foo", "bar"
// or "daz"). Returns false otherwise.
bool trySetFlagFromString(MyFlags& value, const std::string& str);
// Return true if ``value`` contains all flags in ``mask``.
bool hasMask(MyFlags value, MyFlags mask);
// Enables bits in mask.
void setMask(MyFlags& value, MyFlags mask);
// Clear bits in mask.
void clearMask(MyFlags& value, MyFlags mask);
// Toggle bits.
void toggleMask(MyFlags& value, MyFlags mask);
// Returns true if value is a single flag (i.e. Foo::foo, Foo::bar or
// Foo::daz)
bool isSingleFlag(MyFlags value);
// Returns string representation of enabled flags
// (e.g. {"foo", "bar"} for `MyFlags::foo | MyFlags::bar')
std::vector<std::string> toStrings(MyFlags value);
// Return pretty string representation
// (e.g. "{bar (=2), daz (=4)}" for `MyFlags::bar | MyFlags::daz').
std::string toPretty(MyFlags value);
// Returns number of flags (i.e. 3).
constexpr size_t getCount(MyFlags) {
return 3u;
}
// Returns array of names:
std::array<string_view, 3> getNames(MyFlags) {
return {"foo", "bar", "daz"};
}
// Return string of names:
constexpr string_view getStringOfNames(MyFlags) {
return "{foo, bar, daz}";
}
// Returns array of values:
constexpr std::array<uint32_t, 3u> getValues(MyFlags) {
return {1, 2, 4};
}
string_view getTypeName(MyFlags) {
return "MyFlags";
}
// Note: When adding new flags to an exisiting enum, we want to add such flag
// at the end.
MY_ENUMFLAGS(MyFlags, uint32_t, (foo, bar));
generates
enum class MyFlags : uint32_t {
none = 0,
foo = 1,
bar = 2
};
Now adding "daz" to the end, we get
MY_ENUMFLAGS(MyFlags, uint32_t, (foo, bar, daz));
which generates
enum class MyFlags : uint32_t {
none = 0,
foo = 1,
bar = 2,
daz = 4
};
And hence the order of exiting flags (foo, bar) is respected and their
values do not change.
*/
#define MY_ENUMFLAGS(NAME, UINT_TYPE, ...) \
MY_ENUMFLAGS_DEF(NAME, UINT_TYPE, __VA_ARGS__) \
MY_ENUMFLAGS_ALIAS(NAME)