dfx 0.1.0
Linux-based dynamic dataflow executor
Loading...
Searching...
No Matches
Flags.hpp File Reference

Typesafe enum bitmask wrapper and helper macros. More...

Include dependency graph for Flags.hpp:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

class  dfx::Utils::Flags< Enum >
 Typesafe bitmask wrapper for enum flags. More...

Concepts

concept  dfx::Utils::IsEnum
 Concept matching any enumeration type. This is used to constrain Flags to be instantiated only with enum types.

Macros

#define DECLARE_FLAGS(FlagsName, Enum)
 Declare a convenient alias for dfx::Utils::Flags<Enum>.
#define DECLARE_OPERATOR_FOR_FLAGS(FlagsName)
 Declare a free operator| to combine two enum values into a Flags.
#define DECLARE_STD_FORMATTER_FOR_FLAGS(FlagsName)
 Declare a std::formatter<FlagsName> that prints set flags joined by |.

Detailed Description

Typesafe enum bitmask wrapper and helper macros.

This header provides dfx::Utils::Flags<Enum>, a small utility class wrapping an enum used as a bitmask (flag enum), plus a few convenience macros to create aliases and boilerplate operators / formatters.

What you get

Typical usage

1) Define the enum and register its string mapping (see EnumString.hpp):

enum class Mode : uint32_t
{
Read = 0x01,
Write = 0x02,
Exec = 0x04,
};
// In a header:
// In one .cpp:
Mode::Read, "read",
Mode::Write, "write",
Mode::Exec, "exec"
);
#define DECLARE_ENUM_STRING_FUNCTIONS(E)
Declare the enum string API (and std::formatter) for enum type E.
Definition EnumString.hpp:327
#define DEFINE_ENUM_STRING(Enum,...)
Define the full enum string API for Enum (definitions + maps + value lists).
Definition EnumString.hpp:307

2) Declare the flag type and helpers:

DECLARE_FLAGS(Modes, Mode);
#define DECLARE_OPERATOR_FOR_FLAGS(FlagsName)
Declare a free operator| to combine two enum values into a Flags.
Definition Flags.hpp:291
#define DECLARE_STD_FORMATTER_FOR_FLAGS(FlagsName)
Declare a std::formatter<FlagsName> that prints set flags joined by |.
Definition Flags.hpp:308
#define DECLARE_FLAGS(FlagsName, Enum)
Declare a convenient alias for dfx::Utils::Flags<Enum>.
Definition Flags.hpp:275

3) Use it:

Modes m = Mode::Read | Mode::Write;
m.setFlag(Mode::Exec, false);
if (m.testFlag(Mode::Read)) { ... }
std::string s = std::format("{}", m); // "read|write"

Notes / caveats

  • Flags<Enum> does not validate your enum values. If you put non-bit values in the enum, results are entirely on you.
  • DECLARE_STD_FORMATTER_FOR_FLAGS enumerates all values returned by dfx::Enum::allValues<Enum>(). If that list contains combined flags (e.g. ReadWrite = Read|Write), those combined names may also appear in formatted output when their bits are set.

Macro Definition Documentation

◆ DECLARE_FLAGS

#define DECLARE_FLAGS ( FlagsName,
Enum )
Value:
using FlagsName = ::dfx::Utils::Flags<Enum>
Typesafe bitmask wrapper for enum flags.
Definition Flags.hpp:137

Declare a convenient alias for dfx::Utils::Flags<Enum>.

Parameters
FlagsNameAlias name to create.
EnumEnum type used as the flag bitmask.
enum class Mode : uint32_t { Read = 1, Write = 2 };
DECLARE_FLAGS(Modes, Mode);

◆ DECLARE_OPERATOR_FOR_FLAGS

#define DECLARE_OPERATOR_FOR_FLAGS ( FlagsName)
Value:
[[nodiscard]] constexpr ::dfx::Utils::Flags<FlagsName::enum_type> operator|(FlagsName::enum_type f1, FlagsName::enum_type f2) noexcept \
{ return ::dfx::Utils::Flags<FlagsName::enum_type>({ f1, f2 }); }

Declare a free operator| to combine two enum values into a Flags.

This enables expressions like:

Modes m = Mode::Read | Mode::Write;
Parameters
FlagsNameThe Flags alias/type (e.g. Modes) for which to generate the operator.
Note
The operator returns dfx::Utils::Flags<FlagsName::enum_type>

◆ DECLARE_STD_FORMATTER_FOR_FLAGS

#define DECLARE_STD_FORMATTER_FOR_FLAGS ( FlagsName)
Value:
template<> \
struct std::formatter<FlagsName> : public formatter<std::string_view> \
{ \
auto format(FlagsName const & f, format_context & ctx) const \
{ \
std::vector<FlagsName::enum_type> vec; \
for (auto const & value : ::dfx::Enum::allValues<FlagsName::enum_type>()) \
if (f.testFlag(value)) \
vec.emplace_back(value); \
return formatter<std::string_view>::format(std::format("{}", ::dfx::Utils::join(vec, "|")), ctx); \
} \
}
std::vector< E > const & allValues() noexcept=delete
Return all enum values registered for E, in the order provided to the macro. Deleted by default; prov...
constexpr JoinedView< Range > join(Range const &range, std::string_view delimiter) noexcept
Create a JoinedView from a range and a delimiter.
Definition Join.hpp:73

Declare a std::formatter<FlagsName> that prints set flags joined by |.

The formatter enumerates all possible flags using dfx::Enum::allValues<Enum>() (provided by EnumString.hpp macros), retains those present in the flag set, then formats them as: flag1|flag2|flag3.

Parameters
FlagsNameThe Flags alias/type for which to generate a formatter.
Warning
Requires that dfx::Enum::allValues<FlagsName::enum_type>() is available. In practice this means the enum must have been registered via the EnumString macros.