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 auto MaxRep{((1 << (Max_u_v - Min_u_v + 1)) - 1) << Min_u_v}; // 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 if (s.empty()) { // no-op
407 return;
408 }
409 try {
410 setImpl(s, base);
411 } catch (const std::exception& e) {
412 mBits = prev;
413 throw;
414 }
415 }
416 // Returns the raw bitset value.
417 constexpr auto value() const noexcept
418 {
419 return mBits;
420 }
421
422 // Resets all flags.
423 constexpr void reset() noexcept
424 {
425 mBits = U(0);
426 }
427
428 // Resets a specific flag.
429 template <typename T>
430 requires std::is_same_v<T, E>
431 constexpr void reset(T t)
432 {
433 mBits &= ~to_bit(t);
434 }
435
436 // Tests if a specific flag is set.
437 template <typename T>
438 requires std::is_same_v<T, E>
439 [[nodiscard]] constexpr bool test(T t) const noexcept
440 {
441 return (mBits & to_bit(t)) != None;
442 }
443
444 // Sets a specific flag.
445 template <typename T>
446 requires std::is_same_v<T, E>
447 constexpr void set(T t) noexcept
448 {
449 mBits |= to_bit(t);
450 }
451
452 // Toggles a specific flag.
453 template <typename T>
454 requires std::is_same_v<T, E>
455 constexpr void toggle(T t) noexcept
456 {
457 mBits ^= to_bit(t);
458 }
459
460 // Checks if any flag is set.
461 [[nodiscard]] constexpr bool any() const noexcept
462 {
463 return mBits != None;
464 }
465
466 // Returns the bitset as a binary string.
467 [[nodiscard]] std::string string() const
468 {
469 std::ostringstream oss;
470 oss << std::bitset<H::count()>(mBits);
471 return oss.str();
472 }
473
474 // Returns the bitset as a pretty multiline binary string.
475 [[nodiscard]] std::string pstring(bool withNewline = false) const
476 {
477 std::ostringstream oss;
478 if (withNewline) {
479 oss << '\n';
480 }
481 oss << "0b";
482 const std::bitset<H::count()> bits(mBits);
483 oss << bits;
484 if constexpr (H::isScoped()) {
485 oss << " " << H::Scope;
486 }
487 oss << '\n';
488 for (size_t i = 0; i < H::count(); ++i) {
489 oss << " ";
490 for (size_t j = 0; j < H::count() - i - 1; ++j) {
491 oss << "┃";
492 }
493 oss << "┗";
494 for (size_t a{2 + i}; --a != 0U;) {
495 oss << "━";
496 }
497 oss << " " << std::setw(H::NamesLongest) << std::left
498 << H::Names[i] << " " << (bits[i] ? "[Active]" : "[Inactive]");
499 if (i != H::count() - 1) {
500 oss << "\n";
501 }
502 }
503 return oss.str();
504 }
505
506 // Checks if any flag is set (Boolean context).
507 constexpr explicit operator bool() const noexcept
508 {
509 return any();
510 }
511
512 // Check if given flag is set.
513 template <typename T>
514 requires std::is_same_v<T, E>
515 constexpr bool operator[](const T t) noexcept
516 {
517 return test(t);
518 }
519
520 // Checks if two flag sets are equal.
521 constexpr bool operator==(const EnumFlags& o) const noexcept
522 {
523 return mBits == o.mBits;
524 }
525
526 // Checks if two flag sets are not equal.
527 constexpr bool operator!=(const EnumFlags& o) const noexcept
528 {
529 return mBits != o.mBits;
530 }
531
532 // Copy assignment operator
533 constexpr EnumFlags& operator=(const EnumFlags& o) = default;
534
535 // Move assignment operator
536 constexpr EnumFlags& operator=(EnumFlags&& o) = default;
537
538 // Performs a bitwise OR with a flag.
539 template <typename T>
540 requires std::is_same_v<T, E>
541 constexpr EnumFlags& operator|=(T t) noexcept
542 {
543 mBits |= to_bit(t);
544 return *this;
545 }
546
547 // Performs a bitwise AND with a flag.
548 template <typename T>
549 requires std::is_same_v<T, E>
550 constexpr EnumFlags& operator&=(T t) noexcept
551 {
552 mBits &= to_bit(t);
553 return *this;
554 }
555
556 // Returns a flag set with a bitwise AND.
557 template <typename T>
558 requires std::is_same_v<T, E>
559 constexpr EnumFlags operator&(T t) const noexcept
560 {
561 return EnumFlags(mBits & to_bit(t));
562 }
563
564 // Returns a flag set with all bits inverted.
565 constexpr EnumFlags operator~() const noexcept
566 {
567 return EnumFlags(~mBits);
568 }
569
570 // Performs a bitwise OR with another flag set.
571 constexpr EnumFlags operator|(const EnumFlags& o) const noexcept
572 {
573 return EnumFlags(mBits | o.mBits);
574 }
575
576 // Performs a bitwise OR assignment.
577 constexpr EnumFlags& operator|=(const EnumFlags& o) noexcept
578 {
579 mBits |= o.mBits;
580 return *this;
581 }
582
583 // Performs a bitwise XOR with another flag set.
584 constexpr EnumFlags operator^(const EnumFlags& o) const noexcept
585 {
586 return Flags(mBits ^ o.mBits);
587 }
588
589 // Performs a bitwise XOR assignment.
590 constexpr EnumFlags& operator^=(const EnumFlags& o) noexcept
591 {
592 mBits ^= o.mBits;
593 return *this;
594 }
595
596 // Checks if all specified flags are set.
597 template <typename... Ts>
598 constexpr bool all_of(Ts... flags) const noexcept
599 {
600 return ((test(flags) && ...));
601 }
602
603 // Checks if none of the specified flags are set.
604 template <typename... Ts>
605 constexpr bool none_of(Ts... flags) const noexcept
606 {
607 return (!(test(flags) || ...));
608 }
609
610 // Serializes the flag set to a string.
611 [[nodiscard]] std::string serialize() const
612 {
613 return std::to_string(mBits);
614 }
615
616 // Deserializes a string into the flag set.
617 void deserialize(const std::string& data)
618 {
619 uint64_t v = std::stoul(data);
620 if (v > H::MaxRep) {
621 throw std::out_of_range("Values exceeds enum range.");
622 }
623 mBits = static_cast<U>(v);
624 }
625
626 // Counts the number of set bits (active flags).
627 [[nodiscard]] constexpr size_t count() const noexcept
628 {
629 size_t c{0};
630 for (size_t i{H::Min_u_v}; i < H::Max_u_v; ++i) {
631 if ((mBits & (U(1) << i)) != U(0)) {
632 ++c;
633 }
634 }
635 return c;
636 }
637
638 // Returns the union of two flag sets.
639 constexpr EnumFlags union_with(const EnumFlags& o) const noexcept
640 {
641 return EnumFlags(mBits | o.mBits);
642 }
643
644 // Returns the intersection of two flag sets.
645 constexpr EnumFlags intersection_with(const EnumFlags& o) const noexcept
646 {
647 return EnumFlags(mBits & o.mBits);
648 }
649
650 // Checks if all flags in another Flags object are present in the current object.
651 constexpr bool contains(const EnumFlags& other) const noexcept
652 {
653 return (mBits & other.mBits) == other.mBits;
654 }
655
656 private:
657 // Set implemnetation, bits was zeroed before.
658 void setImpl(const std::string& s, int base = 2)
659 {
660 if (std::all_of(s.begin(), s.end(), [](unsigned char c) { return std::isdigit(c); })) {
661 if (base == 2) { // check of only 0 and 1 in string
662 if (!std::all_of(s.begin(), s.end(), [](char c) { return c == '0' || c == '1'; })) {
663 throw std::invalid_argument("Invalid binary string.");
664 }
665 }
666 uint64_t v = std::stoul(s, nullptr, base);
667 if (v > H::MaxRep) {
668 throw std::out_of_range("Values exceeds enum range.");
669 }
670 mBits = static_cast<U>(v);
671 } else if (std::all_of(s.begin(), s.end(), [](unsigned char c) { return std::isalnum(c) != 0 || c == '|' || c == ' ' || c == ':' || c == ','; })) {
672 std::string cs{s};
673 std::transform(cs.begin(), cs.end(), cs.begin(), [](unsigned char c) { return std::tolower(c); });
674 if (cs == H::All) {
675 mBits = All;
676 } else if (cs == H::None) {
677 mBits = None;
678 } else {
679 char token = (s.find(',') != std::string::npos) ? ',' : '|';
680 for (const auto& tok : Str::tokenize(s, token)) {
681 if (auto e = H::fromString(tok)) {
682 mBits |= to_bit(*e);
683 } else {
684 throw std::invalid_argument(tok + " is not a valid enum value!");
685 }
686 }
687 }
688 } else {
689 throw std::invalid_argument("Cannot parse string!");
690 }
691 }
692};
693
694template <EnumFlag E>
695std::ostream& operator<<(std::ostream& os, const EnumFlags<E>& f)
696{
697 os << f.pstring(true);
698 return os;
699}
700
701} // namespace o2::utils
702
703#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:598
constexpr EnumFlags operator|(const EnumFlags &o) const noexcept
Definition EnumFlags.h:571
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:515
constexpr bool operator==(const EnumFlags &o) const noexcept
Definition EnumFlags.h:521
constexpr void reset(T t)
Definition EnumFlags.h:431
std::string serialize() const
Definition EnumFlags.h:611
constexpr EnumFlags operator&(T t) const noexcept
Definition EnumFlags.h:559
constexpr size_t count() const noexcept
Definition EnumFlags.h:627
constexpr EnumFlags(std::initializer_list< E > flags) noexcept
Definition EnumFlags.h:376
constexpr bool operator!=(const EnumFlags &o) const noexcept
Definition EnumFlags.h:527
constexpr EnumFlags()=default
constexpr EnumFlags & operator|=(T t) noexcept
Definition EnumFlags.h:541
constexpr bool any() const noexcept
Definition EnumFlags.h:461
constexpr EnumFlags union_with(const EnumFlags &o) const noexcept
Definition EnumFlags.h:639
static constexpr auto getValues() noexcept
Definition EnumFlags.h:387
constexpr auto value() const noexcept
Definition EnumFlags.h:417
constexpr void reset() noexcept
Definition EnumFlags.h:423
constexpr EnumFlags(const EnumFlags &)=default
constexpr EnumFlags operator~() const noexcept
Definition EnumFlags.h:565
constexpr EnumFlags operator^(const EnumFlags &o) const noexcept
Definition EnumFlags.h:584
constexpr EnumFlags & operator=(EnumFlags &&o)=default
constexpr ~EnumFlags()=default
constexpr EnumFlags intersection_with(const EnumFlags &o) const noexcept
Definition EnumFlags.h:645
void deserialize(const std::string &data)
Definition EnumFlags.h:617
static constexpr U None
Definition EnumFlags.h:383
constexpr void toggle(T t) noexcept
Definition EnumFlags.h:455
constexpr EnumFlags(EnumFlags &&)=default
void set(const std::string &s="", int base=2)
Definition EnumFlags.h:401
constexpr EnumFlags(U u)
Definition EnumFlags.h:374
constexpr EnumFlags & operator&=(T t) noexcept
Definition EnumFlags.h:550
constexpr bool none_of(Ts... flags) const noexcept
Definition EnumFlags.h:605
std::string string() const
Definition EnumFlags.h:467
static constexpr auto getNames() noexcept
Definition EnumFlags.h:393
constexpr EnumFlags & operator^=(const EnumFlags &o) noexcept
Definition EnumFlags.h:590
std::string pstring(bool withNewline=false) const
Definition EnumFlags.h:475
constexpr bool contains(const EnumFlags &other) const noexcept
Definition EnumFlags.h:651
constexpr bool test(T t) const noexcept
Definition EnumFlags.h:439
constexpr void set(T t) noexcept
Definition EnumFlags.h:447
constexpr EnumFlags & operator|=(const EnumFlags &o) noexcept
Definition EnumFlags.h:577
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:695
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