dfx 0.1.0
Linux-based dynamic dataflow executor
Loading...
Searching...
No Matches
Flags.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2025 Vincent Leroy
2// SPDX-License-Identifier: MIT
3//
4// This file is part of dfx.
5//
6// Licensed under the MIT License. See the LICENSE file in the project root
7// for full license information.
8
9#pragma once
10
11// Standard includes
12#include <format>
13#include <initializer_list>
14#include <string_view>
15#include <type_traits>
16#include <vector>
17
18// Project includes
19#include "EnumString.hpp"
20#include "Join.hpp"
21
92
93namespace dfx::Utils
94{
101template<typename T>
102concept IsEnum = std::is_enum_v<T>;
103
135template<IsEnum Enum>
136class Flags
137{
138public:
141
143 using value_type = std::underlying_type_t<Enum>;
144
145public:
147 constexpr Flags() noexcept = default;
148
151 constexpr Flags(enum_type e) noexcept
152 : _value { static_cast<value_type>(e) }
153 {}
154
159 constexpr Flags(std::initializer_list<enum_type> f) noexcept
160 {
161 for (auto const & val : f)
162 _value |= static_cast<value_type>(val);
163 }
164
170 constexpr Flags<enum_type> & setFlag(enum_type flag, bool on = true) noexcept
171 { return on ? (*this |= flag) : (*this &= ~static_cast<value_type>(flag)); }
172
179 [[nodiscard]] constexpr bool testFlag(enum_type flag) const noexcept
180 { return (_value & static_cast<value_type>(flag)) == static_cast<value_type>(flag); }
181
186 [[nodiscard]] constexpr bool testAnyFlag(Flags<enum_type> const & flags) const noexcept
187 { return (_value & flags._value) != 0; }
188
193 [[nodiscard]] constexpr bool testAllFlags(Flags<enum_type> const & flags) const noexcept
194 { return (_value & flags._value) == flags._value; }
195
197 [[nodiscard]] constexpr bool operator==(Flags<enum_type> const & other) const noexcept { return _value == other._value; }
199 [[nodiscard]] constexpr bool operator!=(Flags<enum_type> const & other) const noexcept { return !(*this == other); }
201 [[nodiscard]] constexpr bool operator==(enum_type flag) const noexcept { return testAllFlags(flag); }
203 [[nodiscard]] constexpr bool operator!=(enum_type flag) const noexcept { return !(*this == flag); }
204
205 // Implicit conversion operators
211 [[nodiscard]] constexpr operator enum_type() const noexcept { return static_cast<enum_type>(_value); }
215 [[nodiscard]] constexpr operator value_type() const noexcept { return _value; }
216
217 // logical and operations
219 [[nodiscard]] constexpr Flags<enum_type> operator&(enum_type mask) const noexcept { return Flags(_value & static_cast<value_type>(mask)); }
221 [[nodiscard]] constexpr Flags<enum_type> operator&(Flags<enum_type> mask) const noexcept { return _value & mask._value; }
223 constexpr Flags<enum_type> & operator&=(enum_type mask) noexcept { _value &= static_cast<value_type>(mask); return *this; }
225 constexpr Flags<enum_type> & operator&=(Flags<enum_type> mask) noexcept { _value &= mask._value; return *this; }
226
227 // logical or operations
229 [[nodiscard]] constexpr Flags<enum_type> operator|(enum_type mask) const noexcept { return _value | static_cast<value_type>(mask); }
231 [[nodiscard]] constexpr Flags<enum_type> operator|(Flags<enum_type> mask) const noexcept { return _value | mask._value; }
233 constexpr Flags<enum_type> & operator|=(enum_type mask) noexcept { _value |= static_cast<value_type>(mask); return *this; }
235 constexpr Flags<enum_type> & operator|=(Flags<enum_type> mask) noexcept { _value |= mask._value; return *this; }
236
237 // logical xor operations
239 [[nodiscard]] constexpr Flags<enum_type> operator^(enum_type mask) const noexcept { return _value ^ static_cast<value_type>(mask); }
241 [[nodiscard]] constexpr Flags<enum_type> operator^(Flags<enum_type> mask) const noexcept { return _value ^ mask._value; }
243 constexpr Flags<enum_type> & operator^=(enum_type mask) noexcept { _value ^= static_cast<value_type>(mask); return *this; }
245 constexpr Flags<enum_type> & operator^=(Flags<enum_type> mask) noexcept { _value ^= mask._value; return *this; }
246
247 // unary operations
249 [[nodiscard]] constexpr Flags<enum_type> operator~() const noexcept { return ~_value; }
251 [[nodiscard]] constexpr bool operator!() const noexcept { return !_value; }
252
253private:
254 constexpr Flags(value_type val)
255 : _value { val }
256 {}
257
258private:
259 value_type _value = 0;
260};
261} // !namespace dfx::Utils
262
275#define DECLARE_FLAGS(FlagsName, Enum) \
276 using FlagsName = ::dfx::Utils::Flags<Enum>
277
291#define DECLARE_OPERATOR_FOR_FLAGS(FlagsName) \
292 [[nodiscard]] constexpr ::dfx::Utils::Flags<FlagsName::enum_type> operator|(FlagsName::enum_type f1, FlagsName::enum_type f2) noexcept \
293 { return ::dfx::Utils::Flags<FlagsName::enum_type>({ f1, f2 }); }
294
308#define DECLARE_STD_FORMATTER_FOR_FLAGS(FlagsName) \
309 template<> \
310 struct std::formatter<FlagsName> : public formatter<std::string_view> \
311 { \
312 auto format(FlagsName const & f, format_context & ctx) const \
313 { \
314 std::vector<FlagsName::enum_type> vec; \
315 for (auto const & value : ::dfx::Enum::allValues<FlagsName::enum_type>()) \
316 if (f.testFlag(value)) \
317 vec.emplace_back(value); \
318 return formatter<std::string_view>::format(std::format("{}", ::dfx::Utils::join(vec, "|")), ctx); \
319 } \
320 }
Macro-based enum <-> string utilities for dfx.
constexpr Flags(std::initializer_list< enum_type > f) noexcept
Construct from an initializer-list of flags. All provided flags are OR-ed into the resulting mask.
Definition Flags.hpp:159
constexpr Flags< enum_type > & setFlag(enum_type flag, bool on=true) noexcept
Set or clear a single flag.
Definition Flags.hpp:170
constexpr Flags< enum_type > operator&(Flags< enum_type > mask) const noexcept
Bitwise AND with another flag set.
Definition Flags.hpp:221
constexpr Flags< enum_type > operator|(Flags< enum_type > mask) const noexcept
Bitwise OR with another flag set.
Definition Flags.hpp:231
constexpr Flags< enum_type > operator~() const noexcept
Bitwise NOT.
Definition Flags.hpp:249
constexpr bool operator==(Flags< enum_type > const &other) const noexcept
Equality comparison between two flag sets.
Definition Flags.hpp:197
constexpr Flags< enum_type > & operator|=(enum_type mask) noexcept
In-place bitwise OR with an enum mask.
Definition Flags.hpp:233
constexpr Flags< enum_type > & operator&=(enum_type mask) noexcept
In-place bitwise AND with an enum mask.
Definition Flags.hpp:223
constexpr bool testAnyFlag(Flags< enum_type > const &flags) const noexcept
Test whether any bit from flags is set.
Definition Flags.hpp:186
Enum enum_type
The wrapped enum type.
Definition Flags.hpp:140
constexpr Flags< enum_type > operator^(enum_type mask) const noexcept
Bitwise XOR with an enum mask.
Definition Flags.hpp:239
constexpr bool operator!=(Flags< enum_type > const &other) const noexcept
Inequality comparison between two flag sets.
Definition Flags.hpp:199
constexpr Flags< enum_type > & operator&=(Flags< enum_type > mask) noexcept
In-place bitwise AND with another flag set.
Definition Flags.hpp:225
constexpr Flags< enum_type > & operator^=(Flags< enum_type > mask) noexcept
In-place bitwise XOR with another flag set.
Definition Flags.hpp:245
constexpr Flags< enum_type > operator^(Flags< enum_type > mask) const noexcept
Bitwise XOR with another flag set.
Definition Flags.hpp:241
constexpr bool testFlag(enum_type flag) const noexcept
Test whether a given flag is set.
Definition Flags.hpp:179
constexpr bool operator!() const noexcept
Logical negation.
Definition Flags.hpp:251
constexpr bool testAllFlags(Flags< enum_type > const &flags) const noexcept
Test whether all bits from flags are set.
Definition Flags.hpp:193
constexpr Flags< enum_type > operator|(enum_type mask) const noexcept
Bitwise OR with an enum mask.
Definition Flags.hpp:229
constexpr Flags< enum_type > & operator^=(enum_type mask) noexcept
In-place bitwise XOR with an enum mask.
Definition Flags.hpp:243
constexpr bool operator!=(enum_type flag) const noexcept
Negated form of operator==(enum_type).
Definition Flags.hpp:203
constexpr Flags< enum_type > operator&(enum_type mask) const noexcept
Bitwise AND with an enum mask.
Definition Flags.hpp:219
constexpr bool operator==(enum_type flag) const noexcept
Compare the flag set against a single enum mask.
Definition Flags.hpp:201
constexpr Flags() noexcept=default
Construct an empty flag set (value = 0).
constexpr Flags< enum_type > & operator|=(Flags< enum_type > mask) noexcept
In-place bitwise OR with another flag set.
Definition Flags.hpp:235
std::underlying_type_t< Enum > value_type
The underlying integer storage type.
Definition Flags.hpp:143
Concept matching any enumeration type. This is used to constrain Flags to be instantiated only with e...
Definition Flags.hpp:102
Enum string conversion and enumeration utilities.
Definition EnumString.hpp:120
Definition SystemConfigCommandHandler.hpp:15