idfxx 1.0.0
Modern C++23 components for ESP-IDF
Loading...
Searching...
No Matches
flags.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2026 Chris Leishman
3
4#pragma once
5
37#include <charconv>
38#include <concepts>
39#include <string>
40#include <type_traits>
41#include <utility>
42
43namespace idfxx {
44
55template<typename E>
56inline constexpr bool enable_flags_operators = false;
57
66template<typename E>
67concept flag_enum = std::is_enum_v<E> && enable_flags_operators<E>;
68
87template<flag_enum E>
88class flags {
89public:
91 using enum_type = E;
92
94 using underlying = std::underlying_type_t<E>;
95
96private:
97 underlying value_{};
98
100 constexpr explicit flags(underlying v) noexcept
101 : value_(v) {}
104public:
108 constexpr flags() noexcept = default;
109
118 constexpr flags(E e) noexcept
119 : value_(std::to_underlying(e)) {}
120
128 [[nodiscard]] constexpr flags operator|(flags other) const noexcept { return flags{value_ | other.value_}; }
129
137 constexpr flags& operator|=(flags other) noexcept {
138 value_ |= other.value_;
139 return *this;
140 }
141
149 [[nodiscard]] constexpr flags operator&(flags other) const noexcept { return flags{value_ & other.value_}; }
150
158 constexpr flags& operator&=(flags other) noexcept {
159 value_ &= other.value_;
160 return *this;
161 }
162
170 [[nodiscard]] constexpr flags operator^(flags other) const noexcept { return flags{value_ ^ other.value_}; }
171
179 constexpr flags& operator^=(flags other) noexcept {
180 value_ ^= other.value_;
181 return *this;
182 }
183
193 [[nodiscard]] constexpr flags operator-(flags other) const noexcept { return flags{value_ & ~other.value_}; }
194
202 constexpr flags& operator-=(flags other) noexcept {
203 value_ &= ~other.value_;
204 return *this;
205 }
206
215 [[nodiscard]] constexpr flags operator~() const noexcept { return flags{~value_}; }
216
227 [[nodiscard]] constexpr bool contains(flags other) const noexcept {
228 return other.value_ != 0 && (value_ & other.value_) == other.value_;
229 }
230
240 [[nodiscard]] constexpr bool contains_any(flags other) const noexcept { return (value_ & other.value_) != 0; }
241
247 [[nodiscard]] constexpr bool empty() const noexcept { return value_ == 0; }
248
254 [[nodiscard]] constexpr explicit operator bool() const noexcept { return value_ != 0; }
255
261 [[nodiscard]] constexpr underlying value() const noexcept { return value_; }
262
273 [[nodiscard]] static constexpr flags from_raw(underlying v) noexcept { return flags{v}; }
274
280 [[nodiscard]] constexpr bool operator==(flags const&) const noexcept = default;
281
289 [[nodiscard]] constexpr bool operator==(E e) const noexcept { return value_ == std::to_underlying(e); }
290};
291
300template<flag_enum E>
302
314template<flag_enum E>
315[[nodiscard]] constexpr flags<E> operator|(E a, E b) noexcept {
316 return flags<E>{a} | flags<E>{b};
317}
318
327template<flag_enum E>
328[[nodiscard]] constexpr flags<E> operator&(E a, E b) noexcept {
329 return flags<E>{a} & flags<E>{b};
330}
331
340template<flag_enum E>
341[[nodiscard]] constexpr flags<E> operator^(E a, E b) noexcept {
342 return flags<E>{a} ^ flags<E>{b};
343}
344
352template<flag_enum E>
353[[nodiscard]] constexpr flags<E> operator~(E a) noexcept {
354 return ~flags<E>{a};
355}
356
364template<flag_enum E>
365[[nodiscard]] inline std::string to_string(flags<E> f) {
366 using underlying = typename flags<E>::underlying;
367 char buf[2 + sizeof(underlying) * 2];
368 buf[0] = '0';
369 buf[1] = 'x';
370 auto [ptr, ec] = std::to_chars(buf + 2, buf + sizeof(buf), f.value(), 16);
371 return std::string(buf, ptr);
372}
373
374} // namespace idfxx
375
376#include "sdkconfig.h"
377#ifdef CONFIG_IDFXX_STD_FORMAT
379#include <algorithm>
380#include <format>
381namespace std {
382template<idfxx::flag_enum E>
383struct formatter<idfxx::flags<E>> {
384 constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
385
386 template<typename FormatContext>
387 auto format(idfxx::flags<E> f, FormatContext& ctx) const {
388 auto s = to_string(f);
389 return std::copy(s.begin(), s.end(), ctx.out());
390 }
391};
392} // namespace std
394#endif // CONFIG_IDFXX_STD_FORMAT
395
// end of idfxx_core_flags // end of idfxx_core
Type-safe set of flags from a scoped enum.
Definition flags.hpp:88
constexpr flags operator|(flags other) const noexcept
Combines flags using bitwise OR.
Definition flags.hpp:128
constexpr bool operator==(flags const &) const noexcept=default
Equality comparison between flags objects.
constexpr underlying value() const noexcept
Returns the underlying integral value.
Definition flags.hpp:261
std::underlying_type_t< E > underlying
The underlying integral type of the enum.
Definition flags.hpp:94
constexpr bool contains_any(flags other) const noexcept
Checks if any of the specified flags are set.
Definition flags.hpp:240
constexpr flags operator-(flags other) const noexcept
Clears specific flags (set difference).
Definition flags.hpp:193
constexpr bool contains(flags other) const noexcept
Checks if all specified flags are set.
Definition flags.hpp:227
constexpr flags() noexcept=default
Default constructor, initializes to empty flags (zero).
static constexpr flags from_raw(underlying v) noexcept
Constructs flags from a raw underlying value.
Definition flags.hpp:273
constexpr bool empty() const noexcept
Checks if no flags are set.
Definition flags.hpp:247
constexpr flags operator&(flags other) const noexcept
Intersects flags using bitwise AND.
Definition flags.hpp:149
constexpr bool operator==(E e) const noexcept
Equality comparison with an individual enum value.
Definition flags.hpp:289
constexpr flags operator^(flags other) const noexcept
Toggles flags using bitwise XOR.
Definition flags.hpp:170
constexpr flags & operator|=(flags other) noexcept
Combines flags in-place using bitwise OR.
Definition flags.hpp:137
constexpr flags & operator&=(flags other) noexcept
Intersects flags in-place using bitwise AND.
Definition flags.hpp:158
E enum_type
The scoped enum type.
Definition flags.hpp:91
constexpr flags operator~() const noexcept
Computes the bitwise complement.
Definition flags.hpp:215
constexpr flags & operator^=(flags other) noexcept
Toggles flags in-place using bitwise XOR.
Definition flags.hpp:179
constexpr flags & operator-=(flags other) noexcept
Clears specific flags in-place (set difference).
Definition flags.hpp:202
Concept for enums that have opted into flag operators.
Definition flags.hpp:67
std::string to_string(core_id c)
Returns a string representation of a CPU core identifier.
Definition cpu.hpp:52
constexpr flags< E > operator~(E a) noexcept
Computes the bitwise complement of an enum value.
Definition flags.hpp:353
constexpr bool enable_flags_operators
Opt-in trait for enabling flag operators on an enum.
Definition flags.hpp:56
constexpr flags< E > operator^(E a, E b) noexcept
Toggles two enum values into a flags object.
Definition flags.hpp:341
flags(E) -> flags< E >
Class template argument deduction guide.
constexpr flags< E > operator|(E a, E b) noexcept
Combines two enum values into a flags object.
Definition flags.hpp:315
constexpr flags< E > operator&(E a, E b) noexcept
Intersects two enum values into a flags object.
Definition flags.hpp:328