Project
Loading...
Searching...
No Matches
EnumFlags.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11#ifndef O2_FRAMEWORK_FLAGS_H_
12#define O2_FRAMEWORK_FLAGS_H_
13
14#include <algorithm>
15#include <array>
16#include <concepts>
17#include <exception>
18#include <ostream>
19#include <source_location>
20#include <stdexcept>
21#include <string_view>
22#include <tuple>
23#include <type_traits>
24#include <string>
25#include <sstream>
26#include <limits>
27#include <bitset>
28#include <initializer_list>
29#include <cstdint>
30#include <cstddef>
31#include <cctype>
32#include <utility>
33#include <optional>
34#include <iostream>
35#include <iomanip>
36
38
39namespace o2::utils
40{
41
42namespace details::enum_flags
43{
44
45// Require that an enum with an underlying unsigned type.
46template <typename E>
47concept EnumFlagHelper = requires {
48 requires std::is_enum_v<E>;
49 requires std::is_unsigned_v<std::underlying_type_t<E>>;
50 requires std::same_as<E, std::decay_t<E>>;
51};
52
53// Static constexpr only helper struct to implement modicum of enum reflection
54// functions and also check via concepts expected properties of the enum.
55// This is very much inspired by much more extensive libraries like magic_enum.
56// Inspiration by its c++20 version (https://github.com/fix8mt/conjure_enum).
57template <EnumFlagHelper E>
58struct FlagsHelper final {
59 using U = std::underlying_type_t<E>;
60
61 static constexpr bool isScoped() noexcept
62 {
63 return std::is_enum_v<E> && !std::is_convertible_v<E, std::underlying_type_t<E>>;
64 }
65
66 // Return line at given position.
67 template <E e>
68 static consteval const char* tpeek() noexcept
69 {
70 return std::source_location::current().function_name();
71 }
72 // string_view value of function above
73 template <E e>
74 static constexpr std::string_view tpeek_v{tpeek<e>()};
75
76 // Compiler Specifics
77 static constexpr auto CSpecifics{std::to_array<
78 std::tuple<std::string_view, char, std::string_view, char>>({
79#if defined __clang__
80 {"e = ", ']', "(anonymous namespace)", '('},
81 {"T = ", ']', "(anonymous namespace)", '('},
82#else // assuming __GNUC__
83 {"e = ", ';', "<unnamed>", '<'},
84 {"T = ", ']', "{anonymous}", '{'},
85#endif
86 })};
87 enum class SVal : uint8_t { Start,
88 End,
89 AnonStr,
90 AnonStart };
91 enum class SType : uint8_t { Enum_t,
92 Type_t,
93 eT0,
94 eT1,
95 eT2,
96 eT3 };
97 // Extract a compiler specification.
98 template <SVal v, SType t>
99 static constexpr auto getSpec() noexcept
100 {
101 return std::get<static_cast<size_t>(v)>(CSpecifics[static_cast<size_t>(t)]);
102 }
103
104 // Range that is scanned by the compiler
105 static constexpr size_t MinScan{0};
106 static constexpr size_t MarginScan{1}; // Scan one past to check for overpopulation
107 static constexpr size_t MaxUnderScan{std::numeric_limits<U>::digits}; // Maximum digits the underlying type has
108 static constexpr size_t MaxScan{MaxUnderScan + MarginScan};
109
110 // Checks if a given 'localation' contains an enum.
111 template <E e>
112 static constexpr bool isValid() noexcept
113 {
114 constexpr auto tp{tpeek_v<e>.rfind(getSpec<SVal::Start, SType::Enum_t>())};
115 if constexpr (tp == std::string_view::npos) {
116 return false;
117 }
118#if defined __clang__
119 else if constexpr (tpeek_v<e>[tp + getSpec<SVal::Start, SType::Enum_t>().size()] == '(') {
120 if constexpr (tpeek_v<e>[tp + getSpec<SVal::Start, SType::Enum_t>().size() + 1] == '(') {
121 return false;
122 }
123 if constexpr (tpeek_v<e>.find(getSpec<SVal::AnonStr, SType::Enum_t>(), tp + getSpec<SVal::Start, SType::Enum_t>().size()) != std::string_view::npos) {
124 return true;
125 }
126 } else if constexpr (tpeek_v<e>.find_first_of(getSpec<SVal::End, SType::Enum_t>(), tp + getSpec<SVal::Start, SType::Enum_t>().size()) != std::string_view::npos) {
127 // check if this is an anonymous enum
128 return true;
129 }
130 return false;
131#else
132 else if constexpr (tpeek_v<e>[tp + getSpec<SVal::Start, SType::Enum_t>().size()] != '(' && tpeek_v<e>.find_first_of(getSpec<SVal::End, SType::Enum_t>(), tp + getSpec<SVal::Start, SType::Enum_t>().size()) != std::string_view::npos) {
133 return true;
134 } else {
135 return false;
136 }
137#endif
138 }
139
140 // Extract which values are present in the enum by checking all values in
141 // the min-max-range above.
142 template <size_t... I>
143 static constexpr auto getValues(std::index_sequence<I...> /*unused*/) noexcept
144 {
145 constexpr std::array<bool, sizeof...(I)> valid{isValid<static_cast<E>(MinScan + I)>()...};
146 constexpr auto count{std::count_if(valid.cbegin(), valid.cend(), [](bool v) noexcept { return v; })};
147 static_assert(count > 0, "Requiring non-empty enum!");
148 static_assert(count <= MaxUnderScan, "Underlying type of enum has less digits than given expected!");
149 std::array<E, count> values{};
150 for (size_t idx{}, n{}; n < count; ++idx) {
151 if (valid[idx]) {
152 values[n++] = static_cast<E>(MinScan + idx);
153 }
154 }
155 return values;
156 }
157 static constexpr auto Values{getValues(std::make_index_sequence<MaxScan - MinScan - MarginScan>())}; // Enum Values
158 static constexpr auto count() noexcept { return Values.size(); } // Number of enum members
159 static constexpr auto Min_v{Values.front()}; // Enum first entry
160 static constexpr auto Max_v{Values.back()}; // Enum last entry
161 static constexpr auto Min_u_v{static_cast<size_t>(Min_v)}; // Enum first entry as size_t
162 static constexpr auto Max_u_v{static_cast<size_t>(Max_v)}; // Enum last entry as size_t
163 static_assert(Max_u_v < std::numeric_limits<U>::digits, "Max Bit is beyond allow range defered from underlying type");
164 static constexpr bool isContinuous() noexcept { return (Max_u_v - Min_u_v + 1) == count(); } // Is the enum continuous
165 static constexpr auto MaxRep{((1ULL << (static_cast<unsigned long long>(Max_u_v - Min_u_v) + 1ULL)) - 1ULL) << Min_u_v}; // largest representable value
166
167 template <E e>
168 static constexpr std::string_view getName()
169 {
170 constexpr auto tp{tpeek_v<e>.rfind(getSpec<SVal::Start, SType::Enum_t>())};
171 if constexpr (tp == std::string_view::npos) {
172 return {};
173 }
174 if constexpr (tpeek_v<e>[tp + getSpec<SVal::Start, SType::Enum_t>().size()] == getSpec<SVal::AnonStart, SType::Enum_t>()) {
175#if defined __clang__
176 if constexpr (tpeek_v<e>[tp + getSpec<SVal::Start, SType::enum_t>().size() + 1] == getSpec<SVal::AnonStart, SType::Enum_t>()) {
177 return {};
178 }
179#endif
180 if (constexpr auto lstr{tpeek_v<e>.substr(tp + getSpec<SVal::Start, SType::Enum_t>().size())}; lstr.find(getSpec<SVal::AnonStr, SType::Enum_t>()) != std::string_view::npos) { // is anon
181 if constexpr (constexpr auto lc{lstr.find_first_of(getSpec<SVal::End, SType::Enum_t>())}; lc != std::string_view::npos) {
182 return lstr.substr(getSpec<SVal::AnonStr, SType::Enum_t>().size() + 2, lc - (getSpec<SVal::AnonStr, SType::Enum_t>().size() + 2));
183 }
184 }
185 }
186 constexpr std::string_view result{tpeek_v<e>.substr(tp + getSpec<SVal::Start, SType::Enum_t>().size())};
187 if constexpr (constexpr auto lc{result.find_first_of(getSpec<SVal::End, SType::Enum_t>())}; lc != std::string_view::npos) {
188 return result.substr(0, lc);
189 } else {
190 return {};
191 }
192 }
193
194 static constexpr std::string_view removeScope(std::string_view s)
195 {
196 if (const auto lc{s.find_last_of(':')}; lc != std::string_view::npos) {
197 return s.substr(lc + 1);
198 }
199 return s;
200 }
201
202 static constexpr std::string_view findScope(std::string_view s)
203 {
204 const auto pos1 = s.rfind("::");
205 if (pos1 == std::string_view::npos) {
206 return s;
207 }
208 const auto pos2 = s.rfind("::", pos1 - 1);
209 if (pos2 == std::string_view::npos) {
210 return s.substr(0, pos1);
211 }
212 return s.substr(pos2 + 2, pos1 - pos2 - 2);
213 }
214
215 template <E e>
216 static constexpr auto getNameValue{getName<e>()};
217
218 template <bool with_scope, std::size_t... I>
219 static constexpr auto getNames(std::index_sequence<I...> /*unused*/)
220 {
221 if constexpr (with_scope) {
222 return std::array<std::string_view, sizeof...(I)>{getNameValue<Values[I]>...};
223 } else {
224 return std::array<std::string_view, sizeof...(I)>{removeScope(getNameValue<Values[I]>)...};
225 }
226 }
227
228 static constexpr auto Names{getNames<false>(std::make_index_sequence<count()>())}; // Enum names without scope
229 static constexpr auto NamesScoped{getNames<true>(std::make_index_sequence<count()>())}; // Enum names with scope
230 static constexpr auto Scope{findScope(NamesScoped.front())}; // Enum scope
231
232 static constexpr auto getLongestName() noexcept
233 {
234 size_t max{0};
235 for (size_t i{0}; i < count(); ++i) {
236 max = std::max(max, Names[i].size());
237 }
238 return max;
239 }
240
241 static constexpr auto NamesLongest{getLongestName()}; // Size of longest name
242
243 template <E e>
244 static constexpr std::string_view toString() noexcept
245 {
246 return getNameValue<e>();
247 }
248
249 static constexpr std::optional<E> fromString(std::string_view str) noexcept
250 {
251 for (std::size_t i{0}; i < count(); ++i) {
252 if (Names[i] == str || NamesScoped[i] == str) {
253 return Values[i];
254 }
255 }
256 return std::nullopt;
257 }
258
259 // Convert char to lower.
260 static constexpr unsigned char toLower(const unsigned char c) noexcept
261 {
262 return (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c;
263 }
264
265 // Are these chars equal (case-insensitive).
266 static constexpr bool isIEqual(const unsigned char a, const unsigned char b) noexcept
267 {
268 return toLower(a) == toLower(b);
269 }
270
271 // Case-insensitive comparision for string_view.
272 static constexpr bool isIEqual(std::string_view s1, std::string_view s2) noexcept
273 {
274 if (s1.size() != s2.size()) {
275 return false;
276 }
277 for (size_t i{0}; i < s1.size(); ++i) {
278 if (!isIEqual(s1[i], s2[i])) {
279 return false;
280 }
281 }
282 return true;
283 }
284
285 static constexpr std::string_view None{"none"};
286 static constexpr bool hasNone() noexcept
287 {
288 // check that enum does not contain memeber named 'none'
289 for (size_t i{0}; i < count(); ++i) {
290 if (isIEqual(Names[i], None)) {
291 return true;
292 }
293 }
294 return false;
295 }
296
297 static constexpr std::string_view All{"all"};
298 static constexpr bool hasAll() noexcept
299 {
300 // check that enum does not contain memeber named 'all'
301 for (size_t i{0}; i < count(); ++i) {
302 if (isIEqual(Names[i], All)) {
303 return true;
304 }
305 }
306 return false;
307 }
308};
309
310} // namespace details::enum_flags
311
312// Require an enum to fullfil what one would except from a bitset.
313template <typename E>
314concept EnumFlag = requires {
315 // range checks
316 requires details::enum_flags::FlagsHelper<E>::Min_u_v == 0; // the first bit should be at position 0
317 requires details::enum_flags::FlagsHelper<E>::Max_u_v < details::enum_flags::FlagsHelper<E>::count(); // the maximum is less than the total
318 requires details::enum_flags::FlagsHelper<E>::isContinuous(); // do not allow missing bits
319
320 // type checks
321 requires !details::enum_flags::FlagsHelper<E>::hasNone(); // added automatically
322 requires !details::enum_flags::FlagsHelper<E>::hasAll(); // added automatically
323};
324
346template <EnumFlag E>
348{
350 using U = std::underlying_type_t<E>;
351 U mBits{0};
352
353 // Converts enum to its underlying type.
354 constexpr auto to_underlying(E e) const noexcept
355 {
356 return static_cast<U>(e);
357 }
358
359 // Returns the bit representation of a flag.
360 constexpr auto to_bit(E e) const noexcept
361 {
362 return U(1) << to_underlying(e);
363 }
364
365 public:
366 // Default constructor.
367 constexpr explicit EnumFlags() = default;
368 // Constructor to initialize with a single flag.
369 constexpr explicit EnumFlags(E e) : mBits(to_bit(e)) {}
370 // Copy constructor.
371 constexpr EnumFlags(const EnumFlags&) = default;
372 // Move constructor.
373 constexpr EnumFlags(EnumFlags&&) = default;
374 // Constructor to initialize with the underlyiny type.
375 constexpr explicit EnumFlags(U u) : mBits(u) {}
376 // Initialize with a list of flags.
377 constexpr EnumFlags(std::initializer_list<E> flags) noexcept
378 {
379 std::for_each(flags.begin(), flags.end(), [this](const E f) noexcept { mBits |= to_bit(f); });
380 }
381 // Destructor.
382 constexpr ~EnumFlags() = default;
383
384 static constexpr U None{0}; // Represents no flags set.
385 static constexpr U All{H::MaxRep}; // Represents all flags set.
386
387 // Return list of all enum values
388 static constexpr auto getValues() noexcept
389 {
390 return H::Values;
391 }
392
393 // Return list of all enum Names
394 static constexpr auto getNames() noexcept
395 {
396 return H::Names;
397 }
398
399 // Sets flags from a string representation.
400 // This can be either from a number representation (binary or digits) or
401 // a concatenation of the enums members name e.g., 'Enum1|Enum2|...'
402 void set(const std::string& s = "", int base = 2)
403 {
404 // on throw restore previous state and rethrow
405 const U prev = mBits;
406 reset();
407 if (s.empty()) { // no-op
408 return;
409 }
410 try {
411 setImpl(s, base);
412 } catch (const std::exception& e) {
413 mBits = prev;
414 throw;
415 }
416 }
417 // Returns the raw bitset value.
418 constexpr auto value() const noexcept
419 {
420 return mBits;
421 }
422
423 // Resets all flags.
424 constexpr void reset() noexcept
425 {
426 mBits = U(0);
427 }
428
429 // Resets a specific flag.
430 template <typename T>
431 requires std::is_same_v<T, E>
432 constexpr void reset(T t)
433 {
434 mBits &= ~to_bit(t);
435 }
436
437 // Tests if a specific flag is set.
438 template <typename T>
439 requires std::is_same_v<T, E>
440 [[nodiscard]] constexpr bool test(T t) const noexcept
441 {
442 return (mBits & to_bit(t)) != None;
443 }
444
445 // Sets a specific flag.
446 template <typename T>
447 requires std::is_same_v<T, E>
448 constexpr void set(T t) noexcept
449 {
450 mBits |= to_bit(t);
451 }
452
453 // Toggles a specific flag.
454 template <typename T>
455 requires std::is_same_v<T, E>
456 constexpr void toggle(T t) noexcept
457 {
458 mBits ^= to_bit(t);
459 }
460
461 // Checks if any flag is set.
462 [[nodiscard]] constexpr bool any() const noexcept
463 {
464 return mBits != None;
465 }
466
467 // Returns the bitset as a binary string.
468 [[nodiscard]] std::string string() const
469 {
470 std::ostringstream oss;
471 oss << std::bitset<H::count()>(mBits);
472 return oss.str();
473 }
474
475 // Returns the bitset as a pretty multiline binary string.
476 [[nodiscard]] std::string pstring(bool withNewline = false) const
477 {
478 std::ostringstream oss;
479 if (withNewline) {
480 oss << '\n';
481 }
482 oss << "0b";
483 const std::bitset<H::count()> bits(mBits);
484 oss << bits;
485 if constexpr (H::isScoped()) {
486 oss << " " << H::Scope;
487 }
488 oss << '\n';
489 for (size_t i = 0; i < H::count(); ++i) {
490 oss << " ";
491 for (size_t j = 0; j < H::count() - i - 1; ++j) {
492 oss << "┃";
493 }
494 oss << "┗";
495 for (size_t a{2 + i}; --a != 0U;) {
496 oss << "━";
497 }
498 oss << " " << std::setw(H::NamesLongest) << std::left
499 << H::Names[i] << " " << (bits[i] ? "[Active]" : "[Inactive]");
500 if (i != H::count() - 1) {
501 oss << "\n";
502 }
503 }
504 return oss.str();
505 }
506
507 // Checks if any flag is set (Boolean context).
508 constexpr explicit operator bool() const noexcept
509 {
510 return any();
511 }
512
513 // Check if given flag is set.
514 template <typename T>
515 requires std::is_same_v<T, E>
516 constexpr bool operator[](const T t) noexcept
517 {
518 return test(t);
519 }
520
521 // Checks if two flag sets are equal.
522 constexpr bool operator==(const EnumFlags& o) const noexcept
523 {
524 return mBits == o.mBits;
525 }
526
527 // Checks if two flag sets are not equal.
528 constexpr bool operator!=(const EnumFlags& o) const noexcept
529 {
530 return mBits != o.mBits;
531 }
532
533 // Copy assignment operator
534 constexpr EnumFlags& operator=(const EnumFlags& o) = default;
535
536 // Move assignment operator
537 constexpr EnumFlags& operator=(EnumFlags&& o) = default;
538
539 // Performs a bitwise OR with a flag.
540 template <typename T>
541 requires std::is_same_v<T, E>
542 constexpr EnumFlags& operator|=(T t) noexcept
543 {
544 mBits |= to_bit(t);
545 return *this;
546 }
547
548 // Performs a bitwise AND with a flag.
549 template <typename T>
550 requires std::is_same_v<T, E>
551 constexpr EnumFlags& operator&=(T t) noexcept
552 {
553 mBits &= to_bit(t);
554 return *this;
555 }
556
557 // Returns a flag set with a bitwise AND.
558 template <typename T>
559 requires std::is_same_v<T, E>
560 constexpr EnumFlags operator&(T t) const noexcept
561 {
562 return EnumFlags(mBits & to_bit(t));
563 }
564
565 // Returns a flag set with all bits inverted.
566 constexpr EnumFlags operator~() const noexcept
567 {
568 return EnumFlags(~mBits);
569 }
570
571 // Performs a bitwise OR with another flag set.
572 constexpr EnumFlags operator|(const EnumFlags& o) const noexcept
573 {
574 return EnumFlags(mBits | o.mBits);
575 }
576
577 // Performs a bitwise OR assignment.
578 constexpr EnumFlags& operator|=(const EnumFlags& o) noexcept
579 {
580 mBits |= o.mBits;
581 return *this;
582 }
583
584 // Performs a bitwise XOR with another flag set.
585 constexpr EnumFlags operator^(const EnumFlags& o) const noexcept
586 {
587 return Flags(mBits ^ o.mBits);
588 }
589
590 // Performs a bitwise XOR assignment.
591 constexpr EnumFlags& operator^=(const EnumFlags& o) noexcept
592 {
593 mBits ^= o.mBits;
594 return *this;
595 }
596
597 // Checks if all specified flags are set.
598 template <typename... Ts>
599 constexpr bool all_of(Ts... flags) const noexcept
600 {
601 return ((test(flags) && ...));
602 }
603
604 // Checks if none of the specified flags are set.
605 template <typename... Ts>
606 constexpr bool none_of(Ts... flags) const noexcept
607 {
608 return (!(test(flags) || ...));
609 }
610
611 // Serializes the flag set to a string.
612 [[nodiscard]] std::string serialize() const
613 {
614 return std::to_string(mBits);
615 }
616
617 // Deserializes a string into the flag set.
618 void deserialize(const std::string& data)
619 {
620 uint64_t v = std::stoul(data);
621 if (v > H::MaxRep) {
622 throw std::out_of_range("Values exceeds enum range.");
623 }
624 mBits = static_cast<U>(v);
625 }
626
627 // Counts the number of set bits (active flags).
628 [[nodiscard]] constexpr size_t count() const noexcept
629 {
630 size_t c{0};
631 for (size_t i{H::Min_u_v}; i < H::Max_u_v; ++i) {
632 if ((mBits & (U(1) << i)) != U(0)) {
633 ++c;
634 }
635 }
636 return c;
637 }
638
639 // Returns the union of two flag sets.
640 constexpr EnumFlags union_with(const EnumFlags& o) const noexcept
641 {
642 return EnumFlags(mBits | o.mBits);
643 }
644
645 // Returns the intersection of two flag sets.
646 constexpr EnumFlags intersection_with(const EnumFlags& o) const noexcept
647 {
648 return EnumFlags(mBits & o.mBits);
649 }
650
651 // Checks if all flags in another Flags object are present in the current object.
652 constexpr bool contains(const EnumFlags& other) const noexcept
653 {
654 return (mBits & other.mBits) == other.mBits;
655 }
656
657 private:
658 // Set implemnetation, bits was zeroed before.
659 void setImpl(const std::string& s, int base = 2)
660 {
661 if (std::all_of(s.begin(), s.end(), [](unsigned char c) { return std::isdigit(c); })) {
662 if (base == 2) { // check of only 0 and 1 in string
663 if (!std::all_of(s.begin(), s.end(), [](char c) { return c == '0' || c == '1'; })) {
664 throw std::invalid_argument("Invalid binary string.");
665 }
666 }
667 uint64_t v = std::stoul(s, nullptr, base);
668 if (v > H::MaxRep) {
669 throw std::out_of_range("Values exceeds enum range.");
670 }
671 mBits = static_cast<U>(v);
672 } else if (std::all_of(s.begin(), s.end(), [](unsigned char c) { return std::isalnum(c) != 0 || c == '|' || c == ' ' || c == ':' || c == ','; })) {
673 std::string cs{s};
674 std::transform(cs.begin(), cs.end(), cs.begin(), [](unsigned char c) { return std::tolower(c); });
675 if (cs == H::All) {
676 mBits = All;
677 } else if (cs == H::None) {
678 mBits = None;
679 } else {
680 char token = (s.find(',') != std::string::npos) ? ',' : '|';
681 for (const auto& tok : Str::tokenize(s, token)) {
682 if (auto e = H::fromString(tok)) {
683 mBits |= to_bit(*e);
684 } else {
685 throw std::invalid_argument(tok + " is not a valid enum value!");
686 }
687 }
688 }
689 } else {
690 throw std::invalid_argument("Cannot parse string!");
691 }
692 }
693};
694
695template <EnumFlag E>
696std::ostream& operator<<(std::ostream& os, const EnumFlags<E>& f)
697{
698 os << f.pstring(true);
699 return os;
700}
701
702} // namespace o2::utils
703
704#endif
int32_t i
bool o
uint32_t j
Definition RawData.h:0
uint32_t c
Definition RawData.h:2
Classs to aggregate and manage enum-based on-off flags.
Definition EnumFlags.h:348
constexpr EnumFlags(E e)
Definition EnumFlags.h:369
constexpr bool all_of(Ts... flags) const noexcept
Definition EnumFlags.h:599
constexpr EnumFlags operator|(const EnumFlags &o) const noexcept
Definition EnumFlags.h:572
constexpr EnumFlags & operator=(const EnumFlags &o)=default
static constexpr U All
Definition EnumFlags.h:385
constexpr bool operator[](const T t) noexcept
Definition EnumFlags.h:516
constexpr bool operator==(const EnumFlags &o) const noexcept
Definition EnumFlags.h:522
constexpr void reset(T t)
Definition EnumFlags.h:432
std::string serialize() const
Definition EnumFlags.h:612
constexpr EnumFlags operator&(T t) const noexcept
Definition EnumFlags.h:560
constexpr size_t count() const noexcept
Definition EnumFlags.h:628
constexpr EnumFlags(std::initializer_list< E > flags) noexcept
Definition EnumFlags.h:377
constexpr bool operator!=(const EnumFlags &o) const noexcept
Definition EnumFlags.h:528
constexpr EnumFlags()=default
constexpr EnumFlags & operator|=(T t) noexcept
Definition EnumFlags.h:542
constexpr bool any() const noexcept
Definition EnumFlags.h:462
constexpr EnumFlags union_with(const EnumFlags &o) const noexcept
Definition EnumFlags.h:640
static constexpr auto getValues() noexcept
Definition EnumFlags.h:388
constexpr auto value() const noexcept
Definition EnumFlags.h:418
constexpr void reset() noexcept
Definition EnumFlags.h:424
constexpr EnumFlags(const EnumFlags &)=default
constexpr EnumFlags operator~() const noexcept
Definition EnumFlags.h:566
constexpr EnumFlags operator^(const EnumFlags &o) const noexcept
Definition EnumFlags.h:585
constexpr EnumFlags & operator=(EnumFlags &&o)=default
constexpr ~EnumFlags()=default
constexpr EnumFlags intersection_with(const EnumFlags &o) const noexcept
Definition EnumFlags.h:646
void deserialize(const std::string &data)
Definition EnumFlags.h:618
static constexpr U None
Definition EnumFlags.h:384
constexpr void toggle(T t) noexcept
Definition EnumFlags.h:456
constexpr EnumFlags(EnumFlags &&)=default
void set(const std::string &s="", int base=2)
Definition EnumFlags.h:402
constexpr EnumFlags(U u)
Definition EnumFlags.h:375
constexpr EnumFlags & operator&=(T t) noexcept
Definition EnumFlags.h:551
constexpr bool none_of(Ts... flags) const noexcept
Definition EnumFlags.h:606
std::string string() const
Definition EnumFlags.h:468
static constexpr auto getNames() noexcept
Definition EnumFlags.h:394
constexpr EnumFlags & operator^=(const EnumFlags &o) noexcept
Definition EnumFlags.h:591
std::string pstring(bool withNewline=false) const
Definition EnumFlags.h:476
constexpr bool contains(const EnumFlags &other) const noexcept
Definition EnumFlags.h:652
constexpr bool test(T t) const noexcept
Definition EnumFlags.h:440
constexpr void set(T t) noexcept
Definition EnumFlags.h:448
constexpr EnumFlags & operator|=(const EnumFlags &o) noexcept
Definition EnumFlags.h:578
GLdouble n
Definition glcorearb.h:1982
GLint GLsizei count
Definition glcorearb.h:399
GLuint64EXT * result
Definition glcorearb.h:5662
GLsizeiptr size
Definition glcorearb.h:659
const GLdouble * v
Definition glcorearb.h:832
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s1
Definition glcorearb.h:5034
GLdouble f
Definition glcorearb.h:310
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLenum GLsizei GLsizei GLint * values
Definition glcorearb.h:1576
GLboolean * data
Definition glcorearb.h:298
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const void * bits
Definition glcorearb.h:4150
GLbitfield flags
Definition glcorearb.h:1570
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
const std::vector< std::string > tokenize(const std::string_view input, const std::string_view pattern)
Definition Utils.cxx:40
std::ostream & operator<<(std::ostream &os, const EnumFlags< E > &f)
Definition EnumFlags.h:696
std::string to_string(gsl::span< T, Size > span)
Definition common.h:52
FIXME: do not use data model tables.
Marks an empty item in the context.
static constexpr std::string_view findScope(std::string_view s)
Definition EnumFlags.h:202
static constexpr bool hasNone() noexcept
Definition EnumFlags.h:286
static constexpr std::string_view None
Definition EnumFlags.h:285
static constexpr auto getLongestName() noexcept
Definition EnumFlags.h:232
static constexpr bool isIEqual(const unsigned char a, const unsigned char b) noexcept
Definition EnumFlags.h:266
static constexpr auto count() noexcept
Definition EnumFlags.h:158
std::underlying_type_t< E > U
Definition EnumFlags.h:59
static constexpr std::string_view All
Definition EnumFlags.h:297
static constexpr bool isIEqual(std::string_view s1, std::string_view s2) noexcept
Definition EnumFlags.h:272
static consteval const char * tpeek() noexcept
Definition EnumFlags.h:68
static constexpr auto getNames(std::index_sequence< I... >)
Definition EnumFlags.h:219
static constexpr std::string_view tpeek_v
Definition EnumFlags.h:74
static constexpr bool hasAll() noexcept
Definition EnumFlags.h:298
static constexpr std::string_view getName()
Definition EnumFlags.h:168
static constexpr bool isValid() noexcept
Definition EnumFlags.h:112
static constexpr unsigned char toLower(const unsigned char c) noexcept
Definition EnumFlags.h:260
static constexpr auto getValues(std::index_sequence< I... >) noexcept
Definition EnumFlags.h:143
static constexpr std::string_view removeScope(std::string_view s)
Definition EnumFlags.h:194
static constexpr std::optional< E > fromString(std::string_view str) noexcept
Definition EnumFlags.h:249
static constexpr bool isScoped() noexcept
Definition EnumFlags.h:61
static constexpr bool isContinuous() noexcept
Definition EnumFlags.h:164
static constexpr std::string_view toString() noexcept
Definition EnumFlags.h:244
static constexpr auto getSpec() noexcept
Definition EnumFlags.h:99
constexpr size_t max
VectorOfTObjectPtrs other
const std::string str