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 constexpr bool isContinuous() noexcept { return (Max_u_v - Min_u_v + 1) == count(); } // Is the enum continuous
164 static constexpr uint64_t MaxRep{(Max_u_v >= 64) ? std::numeric_limits<uint64_t>::max() : (1ULL << Max_u_v) - 1}; // largest representable value
165
166 template <E e>
167 static constexpr std::string_view getName()
168 {
169 constexpr auto tp{tpeek_v<e>.rfind(getSpec<SVal::Start, SType::Enum_t>())};
170 if constexpr (tp == std::string_view::npos) {
171 return {};
172 }
173 if constexpr (tpeek_v<e>[tp + getSpec<SVal::Start, SType::Enum_t>().size()] == getSpec<SVal::AnonStart, SType::Enum_t>()) {
174#if defined __clang__
175 if constexpr (tpeek_v<e>[tp + getSpec<SVal::Start, SType::enum_t>().size() + 1] == getSpec<SVal::AnonStart, SType::Enum_t>()) {
176 return {};
177 }
178#endif
179 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
180 if constexpr (constexpr auto lc{lstr.find_first_of(getSpec<SVal::End, SType::Enum_t>())}; lc != std::string_view::npos) {
181 return lstr.substr(getSpec<SVal::AnonStr, SType::Enum_t>().size() + 2, lc - (getSpec<SVal::AnonStr, SType::Enum_t>().size() + 2));
182 }
183 }
184 }
185 constexpr std::string_view result{tpeek_v<e>.substr(tp + getSpec<SVal::Start, SType::Enum_t>().size())};
186 if constexpr (constexpr auto lc{result.find_first_of(getSpec<SVal::End, SType::Enum_t>())}; lc != std::string_view::npos) {
187 return result.substr(0, lc);
188 } else {
189 return {};
190 }
191 }
192
193 static constexpr std::string_view removeScope(std::string_view s)
194 {
195 if (const auto lc{s.find_last_of(':')}; lc != std::string_view::npos) {
196 return s.substr(lc + 1);
197 }
198 return s;
199 }
200
201 static constexpr std::string_view findScope(std::string_view s)
202 {
203 const auto pos1 = s.rfind("::");
204 if (pos1 == std::string_view::npos) {
205 return s;
206 }
207 const auto pos2 = s.rfind("::", pos1 - 1);
208 if (pos2 == std::string_view::npos) {
209 return s.substr(0, pos1);
210 }
211 return s.substr(pos2 + 2, pos1 - pos2 - 2);
212 }
213
214 template <E e>
215 static constexpr auto getNameValue{getName<e>()};
216
217 template <bool with_scope, std::size_t... I>
218 static constexpr auto getNames(std::index_sequence<I...> /*unused*/)
219 {
220 if constexpr (with_scope) {
221 return std::array<std::string_view, sizeof...(I)>{getNameValue<Values[I]>...};
222 } else {
223 return std::array<std::string_view, sizeof...(I)>{removeScope(getNameValue<Values[I]>)...};
224 }
225 }
226
227 static constexpr auto Names{getNames<false>(std::make_index_sequence<count()>())}; // Enum names without scope
228 static constexpr auto NamesScoped{getNames<true>(std::make_index_sequence<count()>())}; // Enum names with scope
229 static constexpr auto Scope{findScope(NamesScoped.front())}; // Enum scope
230
231 static constexpr auto getLongestName() noexcept
232 {
233 size_t max{0};
234 for (size_t i{0}; i < count(); ++i) {
235 max = std::max(max, Names[i].size());
236 }
237 return max;
238 }
239
240 static constexpr auto NamesLongest{getLongestName()}; // Size of longest name
241
242 template <E e>
243 static constexpr std::string_view toString() noexcept
244 {
245 return getNameValue<e>();
246 }
247
248 static constexpr std::optional<E> fromString(std::string_view str) noexcept
249 {
250 for (std::size_t i{0}; i < count(); ++i) {
251 if (Names[i] == str || NamesScoped[i] == str) {
252 return Values[i];
253 }
254 }
255 return std::nullopt;
256 }
257
258 // Convert char to lower.
259 static constexpr unsigned char toLower(const unsigned char c) noexcept
260 {
261 return (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c;
262 }
263
264 // Are these chars equal (case-insensitive).
265 static constexpr bool isIEqual(const unsigned char a, const unsigned char b) noexcept
266 {
267 return toLower(a) == toLower(b);
268 }
269
270 // Case-insensitive comparision for string_view.
271 static constexpr bool isIEqual(std::string_view s1, std::string_view s2) noexcept
272 {
273 if (s1.size() != s2.size()) {
274 return false;
275 }
276 for (size_t i{0}; i < s1.size(); ++i) {
277 if (!isIEqual(s1[i], s2[i])) {
278 return false;
279 }
280 }
281 return true;
282 }
283
284 static constexpr std::string_view None{"none"};
285 static constexpr bool hasNone() noexcept
286 {
287 // check that enum does not contain memeber named 'none'
288 for (size_t i{0}; i < count(); ++i) {
289 if (isIEqual(Names[i], None)) {
290 return true;
291 }
292 }
293 return false;
294 }
295
296 static constexpr std::string_view All{"all"};
297 static constexpr bool hasAll() noexcept
298 {
299 // check that enum does not contain memeber named 'all'
300 for (size_t i{0}; i < count(); ++i) {
301 if (isIEqual(Names[i], All)) {
302 return true;
303 }
304 }
305 return false;
306 }
307};
308
309} // namespace details::enum_flags
310
311// Require an enum to fullfil what one would except from a bitset.
312template <typename E>
313concept EnumFlag = requires {
314 // range checks
315 requires details::enum_flags::FlagsHelper<E>::Min_u_v == 0; // the first bit should be at position 0
316 requires details::enum_flags::FlagsHelper<E>::Max_u_v < details::enum_flags::FlagsHelper<E>::count(); // the maximum is less than the total
317 requires details::enum_flags::FlagsHelper<E>::isContinuous(); // do not allow missing bits
318
319 // type checks
320 requires !details::enum_flags::FlagsHelper<E>::hasNone(); // added automatically
321 requires !details::enum_flags::FlagsHelper<E>::hasAll(); // added automatically
322};
323
345template <EnumFlag E>
347{
349 using U = std::underlying_type_t<E>;
350 U mBits{0};
351
352 // Converts enum to its underlying type.
353 constexpr auto to_underlying(E e) const noexcept
354 {
355 return static_cast<U>(e);
356 }
357
358 // Returns the bit representation of a flag.
359 constexpr auto to_bit(E e) const noexcept
360 {
361 return U(1) << to_underlying(e);
362 }
363
364 public:
365 // Default constructor.
366 constexpr explicit EnumFlags() = default;
367 // Constructor to initialize with a single flag.
368 constexpr explicit EnumFlags(E e) : mBits(to_bit(e)) {}
369 // Copy constructor.
370 constexpr EnumFlags(const EnumFlags&) = default;
371 // Move constructor.
372 constexpr EnumFlags(EnumFlags&&) = default;
373 // Constructor to initialize with the underlyiny type.
374 constexpr explicit EnumFlags(U u) : mBits(u) {}
375 // Initialize with a list of flags.
376 constexpr EnumFlags(std::initializer_list<E> flags) noexcept
377 {
378 std::for_each(flags.begin(), flags.end(), [this](const E f) noexcept { mBits |= to_bit(f); });
379 }
380 // Destructor.
381 constexpr ~EnumFlags() = default;
382
383 static constexpr U None{0}; // Represents no flags set.
384 static constexpr U All{H::MaxRep}; // Represents all flags set.
385
386 // Return list of all enum values
387 static constexpr auto getValues() noexcept
388 {
389 return H::Values;
390 }
391
392 // Return list of all enum Names
393 static constexpr auto getNames() noexcept
394 {
395 return H::Names;
396 }
397
398 // Sets flags from a string representation.
399 // This can be either from a number representation (binary or digits) or
400 // a concatenation of the enums members name e.g., 'Enum1|Enum2|...'
401 void set(const std::string& s, int base = 2)
402 {
403 // on throw restore previous state and rethrow
404 const U prev = mBits;
405 reset();
406 try {
407 setImpl(s, base);
408 } catch (const std::exception& e) {
409 mBits = prev;
410 throw;
411 }
412 }
413 // Returns the raw bitset value.
414 constexpr auto value() const noexcept
415 {
416 return mBits;
417 }
418
419 // Resets all flags.
420 constexpr void reset() noexcept
421 {
422 mBits = U(0);
423 }
424
425 // Resets a specific flag.
426 template <typename T>
427 requires std::is_same_v<T, E>
428 constexpr void reset(T t)
429 {
430 mBits &= ~to_bit(t);
431 }
432
433 // Tests if a specific flag is set.
434 template <typename T>
435 requires std::is_same_v<T, E>
436 [[nodiscard]] constexpr bool test(T t) const noexcept
437 {
438 return (mBits & to_bit(t)) != None;
439 }
440
441 // Sets a specific flag.
442 template <typename T>
443 requires std::is_same_v<T, E>
444 constexpr void set(T t) noexcept
445 {
446 mBits |= to_bit(t);
447 }
448
449 // Toggles a specific flag.
450 template <typename T>
451 requires std::is_same_v<T, E>
452 constexpr void toggle(T t) noexcept
453 {
454 mBits ^= to_bit(t);
455 }
456
457 // Checks if any flag is set.
458 [[nodiscard]] constexpr bool any() const noexcept
459 {
460 return mBits != None;
461 }
462
463 // Returns the bitset as a binary string.
464 [[nodiscard]] std::string string() const
465 {
466 std::ostringstream oss;
467 oss << std::bitset<H::count()>(mBits);
468 return oss.str();
469 }
470
471 // Returns the bitset as a pretty multiline binary string.
472 [[nodiscard]] std::string pstring(bool withNewline = false) const
473 {
474 std::ostringstream oss;
475 if (withNewline) {
476 oss << '\n';
477 }
478 oss << "0b";
479 const std::bitset<H::count()> bits(mBits);
480 oss << bits;
481 if constexpr (H::isScoped()) {
482 oss << " " << H::Scope;
483 }
484 oss << '\n';
485 for (size_t i = 0; i < H::count(); ++i) {
486 oss << " ";
487 for (size_t j = 0; j < H::count() - i - 1; ++j) {
488 oss << "┃";
489 }
490 oss << "┗";
491 for (size_t a{2 + i}; --a != 0U;) {
492 oss << "━";
493 }
494 oss << " " << std::setw(H::NamesLongest) << std::left
495 << H::Names[i] << " " << (bits[i] ? "[Active]" : "[Inactive]");
496 if (i != H::count() - 1) {
497 oss << "\n";
498 }
499 }
500 return oss.str();
501 }
502
503 // Checks if any flag is set (Boolean context).
504 constexpr explicit operator bool() const noexcept
505 {
506 return any();
507 }
508
509 // Check if given flag is set.
510 template <typename T>
511 requires std::is_same_v<T, E>
512 constexpr bool operator[](const T t) noexcept
513 {
514 return test(t);
515 }
516
517 // Checks if two flag sets are equal.
518 constexpr bool operator==(const EnumFlags& o) const noexcept
519 {
520 return mBits == o.mBits;
521 }
522
523 // Checks if two flag sets are not equal.
524 constexpr bool operator!=(const EnumFlags& o) const noexcept
525 {
526 return mBits != o.mBits;
527 }
528
529 // Copy assignment operator
530 constexpr EnumFlags& operator=(const EnumFlags& o) = default;
531
532 // Move assignment operator
533 constexpr EnumFlags& operator=(EnumFlags&& o) = default;
534
535 // Performs a bitwise OR with a flag.
536 template <typename T>
537 requires std::is_same_v<T, E>
538 constexpr EnumFlags& operator|=(T t) noexcept
539 {
540 mBits |= to_bit(t);
541 return *this;
542 }
543
544 // Performs a bitwise AND with a flag.
545 template <typename T>
546 requires std::is_same_v<T, E>
547 constexpr EnumFlags& operator&=(T t) noexcept
548 {
549 mBits &= to_bit(t);
550 return *this;
551 }
552
553 // Returns a flag set with a bitwise AND.
554 template <typename T>
555 requires std::is_same_v<T, E>
556 constexpr EnumFlags operator&(T t) const noexcept
557 {
558 return EnumFlags(mBits & to_bit(t));
559 }
560
561 // Returns a flag set with all bits inverted.
562 constexpr EnumFlags operator~() const noexcept
563 {
564 return EnumFlags(~mBits);
565 }
566
567 // Performs a bitwise OR with another flag set.
568 constexpr EnumFlags operator|(const EnumFlags& o) const noexcept
569 {
570 return EnumFlags(mBits | o.mBits);
571 }
572
573 // Performs a bitwise OR assignment.
574 constexpr EnumFlags& operator|=(const EnumFlags& o) noexcept
575 {
576 mBits |= o.mBits;
577 return *this;
578 }
579
580 // Performs a bitwise XOR with another flag set.
581 constexpr EnumFlags operator^(const EnumFlags& o) const noexcept
582 {
583 return Flags(mBits ^ o.mBits);
584 }
585
586 // Performs a bitwise XOR assignment.
587 constexpr EnumFlags& operator^=(const EnumFlags& o) noexcept
588 {
589 mBits ^= o.mBits;
590 return *this;
591 }
592
593 // Checks if all specified flags are set.
594 template <typename... Ts>
595 constexpr bool all_of(Ts... flags) const noexcept
596 {
597 return ((test(flags) && ...));
598 }
599
600 // Checks if none of the specified flags are set.
601 template <typename... Ts>
602 constexpr bool none_of(Ts... flags) const noexcept
603 {
604 return (!(test(flags) || ...));
605 }
606
607 // Serializes the flag set to a string.
608 [[nodiscard]] std::string serialize() const
609 {
610 return std::to_string(mBits);
611 }
612
613 // Deserializes a string into the flag set.
614 void deserialize(const std::string& data)
615 {
616 uint64_t v = std::stoul(data);
617 if (v > H::MaxRep) {
618 throw std::out_of_range("Values exceeds enum range.");
619 }
620 mBits = static_cast<U>(v);
621 }
622
623 // Counts the number of set bits (active flags).
624 [[nodiscard]] constexpr size_t count() const noexcept
625 {
626 size_t c{0};
627 for (size_t i{H::Min_u_v}; i < H::Max_u_v; ++i) {
628 if ((mBits & (U(1) << i)) != U(0)) {
629 ++c;
630 }
631 }
632 return c;
633 }
634
635 // Returns the union of two flag sets.
636 constexpr EnumFlags union_with(const EnumFlags& o) const noexcept
637 {
638 return EnumFlags(mBits | o.mBits);
639 }
640
641 // Returns the intersection of two flag sets.
642 constexpr EnumFlags intersection_with(const EnumFlags& o) const noexcept
643 {
644 return EnumFlags(mBits & o.mBits);
645 }
646
647 // Checks if all flags in another Flags object are present in the current object.
648 constexpr bool contains(const EnumFlags& other) const noexcept
649 {
650 return (mBits & other.mBits) == other.mBits;
651 }
652
653 private:
654 // Set implemnetation, bits was zeroed before.
655 void setImpl(const std::string& s, int base = 2)
656 {
657 if (std::all_of(s.begin(), s.end(), [](unsigned char c) { return std::isdigit(c); })) {
658 if (base == 2) { // check of only 0 and 1 in string
659 if (!std::all_of(s.begin(), s.end(), [](char c) { return c == '0' || c == '1'; })) {
660 throw std::invalid_argument("Invalid binary string.");
661 }
662 }
663 uint64_t v = std::stoul(s, nullptr, base);
664 if (v > H::MaxRep) {
665 throw std::out_of_range("Values exceeds enum range.");
666 }
667 mBits = static_cast<U>(v);
668 } else if (std::all_of(s.begin(), s.end(), [](unsigned char c) { return std::isalnum(c) != 0 || c == '|' || c == ' ' || c == ':'; })) {
669 std::string cs{s};
670 std::transform(cs.begin(), cs.end(), cs.begin(), [](unsigned char c) { return std::tolower(c); });
671 if (cs == H::All) {
672 mBits = All;
673 } else if (cs == H::None) {
674 mBits = None;
675 } else {
676 for (const auto& tok : Str::tokenize(s, '|')) {
677 if (auto e = H::fromString(tok)) {
678 mBits |= to_bit(*e);
679 } else {
680 throw std::invalid_argument(tok + " is not a valid enum value!");
681 }
682 }
683 }
684 } else {
685 throw std::invalid_argument("Cannot parse string!");
686 }
687 }
688};
689
690template <EnumFlag E>
691std::ostream& operator<<(std::ostream& os, const EnumFlags<E>& f)
692{
693 os << f.pstring(true);
694 return os;
695}
696
697} // namespace o2::utils
698
699#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:347
constexpr EnumFlags(E e)
Definition EnumFlags.h:368
constexpr bool all_of(Ts... flags) const noexcept
Definition EnumFlags.h:595
constexpr EnumFlags operator|(const EnumFlags &o) const noexcept
Definition EnumFlags.h:568
constexpr EnumFlags & operator=(const EnumFlags &o)=default
static constexpr U All
Definition EnumFlags.h:384
constexpr bool operator[](const T t) noexcept
Definition EnumFlags.h:512
constexpr bool operator==(const EnumFlags &o) const noexcept
Definition EnumFlags.h:518
constexpr void reset(T t)
Definition EnumFlags.h:428
std::string serialize() const
Definition EnumFlags.h:608
constexpr EnumFlags operator&(T t) const noexcept
Definition EnumFlags.h:556
constexpr size_t count() const noexcept
Definition EnumFlags.h:624
constexpr EnumFlags(std::initializer_list< E > flags) noexcept
Definition EnumFlags.h:376
constexpr bool operator!=(const EnumFlags &o) const noexcept
Definition EnumFlags.h:524
constexpr EnumFlags()=default
constexpr EnumFlags & operator|=(T t) noexcept
Definition EnumFlags.h:538
constexpr bool any() const noexcept
Definition EnumFlags.h:458
constexpr EnumFlags union_with(const EnumFlags &o) const noexcept
Definition EnumFlags.h:636
static constexpr auto getValues() noexcept
Definition EnumFlags.h:387
constexpr auto value() const noexcept
Definition EnumFlags.h:414
constexpr void reset() noexcept
Definition EnumFlags.h:420
constexpr EnumFlags(const EnumFlags &)=default
constexpr EnumFlags operator~() const noexcept
Definition EnumFlags.h:562
constexpr EnumFlags operator^(const EnumFlags &o) const noexcept
Definition EnumFlags.h:581
constexpr EnumFlags & operator=(EnumFlags &&o)=default
constexpr ~EnumFlags()=default
constexpr EnumFlags intersection_with(const EnumFlags &o) const noexcept
Definition EnumFlags.h:642
void deserialize(const std::string &data)
Definition EnumFlags.h:614
static constexpr U None
Definition EnumFlags.h:383
constexpr void toggle(T t) noexcept
Definition EnumFlags.h:452
void set(const std::string &s, int base=2)
Definition EnumFlags.h:401
constexpr EnumFlags(EnumFlags &&)=default
constexpr EnumFlags(U u)
Definition EnumFlags.h:374
constexpr EnumFlags & operator&=(T t) noexcept
Definition EnumFlags.h:547
constexpr bool none_of(Ts... flags) const noexcept
Definition EnumFlags.h:602
std::string string() const
Definition EnumFlags.h:464
static constexpr auto getNames() noexcept
Definition EnumFlags.h:393
constexpr EnumFlags & operator^=(const EnumFlags &o) noexcept
Definition EnumFlags.h:587
std::string pstring(bool withNewline=false) const
Definition EnumFlags.h:472
constexpr bool contains(const EnumFlags &other) const noexcept
Definition EnumFlags.h:648
constexpr bool test(T t) const noexcept
Definition EnumFlags.h:436
constexpr void set(T t) noexcept
Definition EnumFlags.h:444
constexpr EnumFlags & operator|=(const EnumFlags &o) noexcept
Definition EnumFlags.h:574
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:691
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:201
static constexpr bool hasNone() noexcept
Definition EnumFlags.h:285
static constexpr std::string_view None
Definition EnumFlags.h:284
static constexpr auto getLongestName() noexcept
Definition EnumFlags.h:231
static constexpr bool isIEqual(const unsigned char a, const unsigned char b) noexcept
Definition EnumFlags.h:265
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:296
static constexpr bool isIEqual(std::string_view s1, std::string_view s2) noexcept
Definition EnumFlags.h:271
static consteval const char * tpeek() noexcept
Definition EnumFlags.h:68
static constexpr auto getNames(std::index_sequence< I... >)
Definition EnumFlags.h:218
static constexpr std::string_view tpeek_v
Definition EnumFlags.h:74
static constexpr bool hasAll() noexcept
Definition EnumFlags.h:297
static constexpr std::string_view getName()
Definition EnumFlags.h:167
static constexpr bool isValid() noexcept
Definition EnumFlags.h:112
static constexpr unsigned char toLower(const unsigned char c) noexcept
Definition EnumFlags.h:259
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:193
static constexpr std::optional< E > fromString(std::string_view str) noexcept
Definition EnumFlags.h:248
static constexpr bool isScoped() noexcept
Definition EnumFlags.h:61
static constexpr bool isContinuous() noexcept
Definition EnumFlags.h:163
static constexpr std::string_view toString() noexcept
Definition EnumFlags.h:243
static constexpr auto getSpec() noexcept
Definition EnumFlags.h:99
constexpr size_t max
VectorOfTObjectPtrs other
const std::string str