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 using UMax = uint64_t; // max represetable type
61
62 static constexpr bool isScoped() noexcept
63 {
64 return std::is_enum_v<E> && !std::is_convertible_v<E, std::underlying_type_t<E>>;
65 }
66
67 // Return line at given position.
68 template <E e>
69 static consteval const char* tpeek() noexcept
70 {
71 return std::source_location::current().function_name();
72 }
73 // string_view value of function above
74 template <E e>
75 static constexpr std::string_view tpeek_v{tpeek<e>()};
76
77 // Compiler Specifics
78 static constexpr auto CSpecifics{std::to_array<
79 std::tuple<std::string_view, char, std::string_view, char>>({
80#if defined __clang__
81 {"e = ", ']', "(anonymous namespace)", '('},
82 {"T = ", ']', "(anonymous namespace)", '('},
83#else // assuming __GNUC__
84 {"e = ", ';', "<unnamed>", '<'},
85 {"T = ", ']', "{anonymous}", '{'},
86#endif
87 })};
88 enum class SVal : uint8_t { Start,
89 End,
90 AnonStr,
91 AnonStart };
92 enum class SType : uint8_t { Enum_t,
93 Type_t,
94 eT0,
95 eT1,
96 eT2,
97 eT3 };
98 // Extract a compiler specification.
99 template <SVal v, SType t>
100 static constexpr auto getSpec() noexcept
101 {
102 return std::get<static_cast<size_t>(v)>(CSpecifics[static_cast<size_t>(t)]);
103 }
104
105 // Range that is scanned by the compiler
106 static constexpr size_t MinScan{0};
107 static constexpr size_t MarginScan{1}; // Scan one past to check for overpopulation
108 static constexpr size_t MaxUnderScan{std::numeric_limits<U>::digits}; // Maximum digits the underlying type has
109 static constexpr size_t MaxScan{MaxUnderScan + MarginScan};
110
111 // Checks if a given 'localation' contains an enum.
112 template <E e>
113 static constexpr bool isValid() noexcept
114 {
115 constexpr auto tp{tpeek_v<e>.rfind(getSpec<SVal::Start, SType::Enum_t>())};
116 if constexpr (tp == std::string_view::npos) {
117 return false;
118 }
119#if defined __clang__
120 else if constexpr (tpeek_v<e>[tp + getSpec<SVal::Start, SType::Enum_t>().size()] == '(') {
121 if constexpr (tpeek_v<e>[tp + getSpec<SVal::Start, SType::Enum_t>().size() + 1] == '(') {
122 return false;
123 }
124 if constexpr (tpeek_v<e>.find(getSpec<SVal::AnonStr, SType::Enum_t>(), tp + getSpec<SVal::Start, SType::Enum_t>().size()) != std::string_view::npos) {
125 return true;
126 }
127 } 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) {
128 // check if this is an anonymous enum
129 return true;
130 }
131 return false;
132#else
133 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) {
134 return true;
135 } else {
136 return false;
137 }
138#endif
139 }
140
141 // Extract which values are present in the enum by checking all values in
142 // the min-max-range above.
143 template <size_t... I>
144 static constexpr auto getValues(std::index_sequence<I...> /*unused*/) noexcept
145 {
146 constexpr std::array<bool, sizeof...(I)> valid{isValid<static_cast<E>(MinScan + I)>()...};
147 constexpr auto count{std::count_if(valid.cbegin(), valid.cend(), [](bool v) noexcept { return v; })};
148 static_assert(count > 0, "EnumFlag requires at least one enum value. Check that your enum has consecutive values starting from 0.");
149 static_assert(count <= MaxUnderScan, "Too many enum values for underlying type. Consider using a larger underlying type or fewer enum values.");
150 std::array<E, count> values{};
151 for (size_t idx{}, n{}; n < count; ++idx) {
152 if (valid[idx]) {
153 values[n++] = static_cast<E>(MinScan + idx);
154 }
155 }
156 return values;
157 }
158 static constexpr auto Values{getValues(std::make_index_sequence<MaxScan - MinScan - MarginScan>())}; // Enum Values
159 static constexpr auto count() noexcept { return Values.size(); } // Number of enum members
160 static constexpr auto Min_v{Values.front()}; // Enum first entry
161 static constexpr auto Max_v{Values.back()}; // Enum last entry
162 static constexpr auto Min_u_v{static_cast<size_t>(Min_v)}; // Enum first entry as size_t
163 static constexpr auto Max_u_v{static_cast<size_t>(Max_v)}; // Enum last entry as size_t
164 static_assert(Max_u_v < std::numeric_limits<U>::digits, "Max Bit is beyond allow range defered from underlying type");
165 static constexpr bool isContinuous() noexcept { return (Max_u_v - Min_u_v + 1) == count(); } // Is the enum continuous
166 static constexpr UMax makeMaxRep(size_t min, size_t max)
167 {
168 const size_t width = max - min + 1;
169 if (width >= std::numeric_limits<UMax>::digits) {
170 return std::numeric_limits<UMax>::max();
171 }
172 return ((UMax(1) << width) - 1) << min;
173 }
174 static constexpr auto MaxRep{makeMaxRep(Min_u_v, Max_u_v)}; // largest representable value
175
176 template <E e>
177 static constexpr std::string_view getName()
178 {
179 constexpr auto tp{tpeek_v<e>.rfind(getSpec<SVal::Start, SType::Enum_t>())};
180 if constexpr (tp == std::string_view::npos) {
181 return {};
182 }
183 if constexpr (tpeek_v<e>[tp + getSpec<SVal::Start, SType::Enum_t>().size()] == getSpec<SVal::AnonStart, SType::Enum_t>()) {
184#if defined __clang__
185 if constexpr (tpeek_v<e>[tp + getSpec<SVal::Start, SType::Enum_t>().size() + 1] == getSpec<SVal::AnonStart, SType::Enum_t>()) {
186 return {};
187 }
188#endif
189 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
190 if constexpr (constexpr auto lc{lstr.find_first_of(getSpec<SVal::End, SType::Enum_t>())}; lc != std::string_view::npos) {
191 return lstr.substr(getSpec<SVal::AnonStr, SType::Enum_t>().size() + 2, lc - (getSpec<SVal::AnonStr, SType::Enum_t>().size() + 2));
192 }
193 }
194 }
195 constexpr std::string_view result{tpeek_v<e>.substr(tp + getSpec<SVal::Start, SType::Enum_t>().size())};
196 if constexpr (constexpr auto lc{result.find_first_of(getSpec<SVal::End, SType::Enum_t>())}; lc != std::string_view::npos) {
197 return result.substr(0, lc);
198 } else {
199 return {};
200 }
201 }
202
203 static constexpr std::string_view removeScope(std::string_view s)
204 {
205 if (const auto lc{s.find_last_of(':')}; lc != std::string_view::npos) {
206 return s.substr(lc + 1);
207 }
208 return s;
209 }
210
211 static constexpr std::string_view findScope(std::string_view s)
212 {
213 const auto pos1 = s.rfind("::");
214 if (pos1 == std::string_view::npos) {
215 return s;
216 }
217 const auto pos2 = s.rfind("::", pos1 - 1);
218 if (pos2 == std::string_view::npos) {
219 return s.substr(0, pos1);
220 }
221 return s.substr(pos2 + 2, pos1 - pos2 - 2);
222 }
223
224 template <E e>
225 static constexpr auto getNameValue{getName<e>()};
226
227 template <bool with_scope, size_t... I>
228 static constexpr auto getNames(std::index_sequence<I...> /*unused*/)
229 {
230 if constexpr (with_scope) {
231 return std::array<std::string_view, sizeof...(I)>{getNameValue<Values[I]>...};
232 } else {
233 return std::array<std::string_view, sizeof...(I)>{removeScope(getNameValue<Values[I]>)...};
234 }
235 }
236
237 static constexpr auto Names{getNames<false>(std::make_index_sequence<count()>())}; // Enum names without scope
238 static constexpr auto NamesScoped{getNames<true>(std::make_index_sequence<count()>())}; // Enum names with scope
239 static constexpr auto Scope{findScope(NamesScoped.front())}; // Enum scope
240
241 static constexpr auto getLongestName() noexcept
242 {
243 size_t max{0};
244 for (size_t i{0}; i < count(); ++i) {
245 max = std::max(max, Names[i].size());
246 }
247 return max;
248 }
249
250 static constexpr auto NamesLongest{getLongestName()}; // Size of longest name
251
252 template <E e>
253 static constexpr std::string_view toString() noexcept
254 {
255 return getNameValue<e>();
256 }
257
258 static constexpr std::optional<E> fromString(std::string_view str) noexcept
259 {
260 for (size_t i{0}; i < count(); ++i) {
261 if (Names[i] == str || NamesScoped[i] == str) {
262 return Values[i];
263 }
264 }
265 return std::nullopt;
266 }
267
268 // Convert char to lower.
269 static constexpr unsigned char toLower(const unsigned char c) noexcept
270 {
271 return (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c;
272 }
273
274 // Are these chars equal (case-insensitive).
275 static constexpr bool isIEqual(const unsigned char a, const unsigned char b) noexcept
276 {
277 return toLower(a) == toLower(b);
278 }
279
280 // Case-insensitive comparision for string_view.
281 static constexpr bool isIEqual(std::string_view s1, std::string_view s2) noexcept
282 {
283 if (s1.size() != s2.size()) {
284 return false;
285 }
286 for (size_t i{0}; i < s1.size(); ++i) {
287 if (!isIEqual(s1[i], s2[i])) {
288 return false;
289 }
290 }
291 return true;
292 }
293
294 static constexpr std::string_view None{"none"};
295 static constexpr bool hasNone() noexcept
296 {
297 // check that enum does not contain memeber named 'none'
298 for (size_t i{0}; i < count(); ++i) {
299 if (isIEqual(Names[i], None)) {
300 return true;
301 }
302 }
303 return false;
304 }
305
306 static constexpr std::string_view All{"all"};
307 static constexpr bool hasAll() noexcept
308 {
309 // check that enum does not contain memeber named 'all'
310 for (size_t i{0}; i < count(); ++i) {
311 if (isIEqual(Names[i], All)) {
312 return true;
313 }
314 }
315 return false;
316 }
317};
318
319} // namespace details::enum_flags
320
321// Require an enum to fullfil what one would except from a bitset.
322template <typename E>
323concept EnumFlag = requires {
324 // range checks
325 requires details::enum_flags::FlagsHelper<E>::Min_u_v == 0; // the first bit should be at position 0
326 requires details::enum_flags::FlagsHelper<E>::Max_u_v < details::enum_flags::FlagsHelper<E>::count(); // the maximum is less than the total
327 requires details::enum_flags::FlagsHelper<E>::isContinuous(); // do not allow missing bits
328
329 // type checks
330 requires !details::enum_flags::FlagsHelper<E>::hasNone(); // added automatically
331 requires !details::enum_flags::FlagsHelper<E>::hasAll(); // added automatically
332};
333
355template <EnumFlag E>
357{
359 using U = std::underlying_type_t<E>;
360 U mBits{0};
361
362 // Converts enum to its underlying type.
363 constexpr auto to_underlying(E e) const noexcept
364 {
365 return static_cast<U>(e);
366 }
367
368 // Returns the bit representation of a flag.
369 constexpr auto to_bit(E e) const noexcept
370 {
371 return U(1) << to_underlying(e);
372 }
373
374 public:
375 // Default constructor.
376 constexpr explicit EnumFlags() = default;
377 // Constructor to initialize with a single flag.
378 constexpr explicit EnumFlags(E e) : mBits(to_bit(e)) {}
379 // Copy constructor.
380 constexpr EnumFlags(const EnumFlags&) = default;
381 // Move constructor.
382 constexpr EnumFlags(EnumFlags&&) = default;
383 // Constructor to initialize with the underlying type.
384 constexpr explicit EnumFlags(U u) : mBits(u) {}
385 // Initialize with a list of flags.
386 constexpr EnumFlags(std::initializer_list<E> flags) noexcept
387 {
388 std::for_each(flags.begin(), flags.end(), [this](const E f) noexcept { mBits |= to_bit(f); });
389 }
390 // Init from a string.
391 EnumFlags(const std::string& str)
392 {
393 set(str);
394 }
395 // Destructor.
396 constexpr ~EnumFlags() = default;
397
398 static constexpr U None{0}; // Represents no flags set.
399 static constexpr U All{H::MaxRep}; // Represents all flags set.
400
401 // Return list of all enum values
402 static constexpr auto getValues() noexcept
403 {
404 return H::Values;
405 }
406
407 // Return list of all enum Names
408 static constexpr auto getNames() noexcept
409 {
410 return H::Names;
411 }
412
413 // Sets flags from a string representation.
414 // This can be either from a number representation (binary or digits) or
415 // a concatenation of the enums members name e.g., 'Enum1|Enum2|...'
416 void set(const std::string& s = "", int base = 2)
417 {
418 // on throw restore previous state and rethrow
419 const U prev = mBits;
420 reset();
421 if (s.empty()) { // no-op
422 return;
423 }
424 try {
425 setImpl(s, base);
426 } catch (const std::exception& e) {
427 mBits = prev;
428 throw;
429 }
430 }
431 // Returns the raw bitset value.
432 [[nodiscard]] constexpr auto value() const noexcept
433 {
434 return mBits;
435 }
436
437 // Resets all flags.
438 constexpr void reset() noexcept
439 {
440 mBits = U(0);
441 }
442
443 // Resets a specific flag.
444 template <typename T>
445 requires std::is_same_v<T, E>
446 constexpr void reset(T t)
447 {
448 mBits &= ~to_bit(t);
449 }
450
451 // Tests if a specific flag is set.
452 template <typename T>
453 requires std::is_same_v<T, E>
454 [[nodiscard]] constexpr bool test(T t) const noexcept
455 {
456 return (mBits & to_bit(t)) != None;
457 }
458
459 // Tests if all specified flags are set.
460 template <typename... Ts>
461 [[nodiscard]] constexpr bool test(Ts... flags) const noexcept
462 {
463 return ((test(flags) && ...));
464 }
465
466 // Sets a specific flag.
467 template <typename T>
468 requires std::is_same_v<T, E>
469 constexpr void set(T t) noexcept
470 {
471 mBits |= to_bit(t);
472 }
473
474 // Toggles a specific flag.
475 template <typename T>
476 requires std::is_same_v<T, E>
477 constexpr void toggle(T t) noexcept
478 {
479 mBits ^= to_bit(t);
480 }
481
482 // Checks if any flag is set.
483 [[nodiscard]] constexpr bool any() const noexcept
484 {
485 return mBits != None;
486 }
487
488 // Checks if all flags are set.
489 [[nodiscard]] constexpr bool all() const noexcept
490 {
491 return mBits == All;
492 }
493
494 // Returns the bitset as a binary string.
495 [[nodiscard]] std::string string() const
496 {
497 std::ostringstream oss;
498 oss << std::bitset<H::count()>(mBits);
499 return oss.str();
500 }
501
502 // Returns the bitset as a pretty multiline binary string.
503 [[nodiscard]] std::string pstring(bool withNewline = false) const
504 {
505 std::ostringstream oss;
506 if (withNewline) {
507 oss << '\n';
508 }
509 oss << "0b";
510 const std::bitset<H::count()> bits(mBits);
511 oss << bits;
512 if constexpr (H::isScoped()) {
513 oss << " " << H::Scope;
514 }
515 oss << '\n';
516 for (size_t i = 0; i < H::count(); ++i) {
517 oss << " ";
518 for (size_t j = 0; j < H::count() - i - 1; ++j) {
519 oss << "┃";
520 }
521 oss << "┗";
522 for (size_t a{2 + i}; --a != 0U;) {
523 oss << "━";
524 }
525 oss << " " << std::setw(H::NamesLongest) << std::left
526 << H::Names[i] << " " << (bits[i] ? "[Active]" : "[Inactive]");
527 if (i != H::count() - 1) {
528 oss << "\n";
529 }
530 }
531 return oss.str();
532 }
533
534 // Checks if any flag is set (Boolean context).
535 [[nodiscard]] constexpr explicit operator bool() const noexcept
536 {
537 return any();
538 }
539
540 // Check if given flag is set.
541 template <typename T>
542 requires std::is_same_v<T, E>
543 [[nodiscard]] constexpr bool operator[](const T t) const noexcept
544 {
545 return test(t);
546 }
547
548 // Checks if two flag sets are equal.
549 [[nodiscard]] constexpr bool operator==(const EnumFlags& o) const noexcept
550 {
551 return mBits == o.mBits;
552 }
553
554 // Checks if two flag sets are not equal.
555 [[nodiscard]] constexpr bool operator!=(const EnumFlags& o) const noexcept
556 {
557 return mBits != o.mBits;
558 }
559
560 // Copy assignment operator
561 constexpr EnumFlags& operator=(const EnumFlags& o) = default;
562
563 // Move assignment operator
564 constexpr EnumFlags& operator=(EnumFlags&& o) = default;
565
566 // Performs a bitwise OR with a flag.
567 template <typename T>
568 requires std::is_same_v<T, E>
569 constexpr EnumFlags& operator|=(T t) noexcept
570 {
571 mBits |= to_bit(t);
572 return *this;
573 }
574
575 // Performs a bitwise AND with a flag.
576 template <typename T>
577 requires std::is_same_v<T, E>
578 constexpr EnumFlags& operator&=(T t) noexcept
579 {
580 mBits &= to_bit(t);
581 return *this;
582 }
583
584 // Returns a flag set with a bitwise AND.
585 template <typename T>
586 requires std::is_same_v<T, E>
587 constexpr EnumFlags operator&(T t) const noexcept
588 {
589 return EnumFlags(mBits & to_bit(t));
590 }
591
592 // Returns a flag set with all bits inverted.
593 constexpr EnumFlags operator~() const noexcept
594 {
595 return EnumFlags(~mBits);
596 }
597
598 // Performs a bitwise OR with another flag set.
599 constexpr EnumFlags operator|(const EnumFlags& o) const noexcept
600 {
601 return EnumFlags(mBits | o.mBits);
602 }
603
604 // Performs a bitwise OR assignment.
605 constexpr EnumFlags& operator|=(const EnumFlags& o) noexcept
606 {
607 mBits |= o.mBits;
608 return *this;
609 }
610
611 // Performs a bitwise XOR with another flag set.
612 constexpr EnumFlags operator^(const EnumFlags& o) const noexcept
613 {
614 return EnumFlags(mBits ^ o.mBits);
615 }
616
617 // Performs a bitwise and with another flag set.
618 constexpr EnumFlags operator&(const EnumFlags& o) const noexcept
619 {
620 return EnumFlags(mBits & o.mBits);
621 }
622
623 // Performs a bitwise XOR assignment.
624 constexpr EnumFlags& operator^=(const EnumFlags& o) noexcept
625 {
626 mBits ^= o.mBits;
627 return *this;
628 }
629
630 // Checks if all specified flags are set.
631 template <typename... Ts>
632 [[nodiscard]] constexpr bool all_of(Ts... flags) const noexcept
633 {
634 return test(flags...);
635 }
636
637 // Checks if none of the specified flags are set.
638 template <typename... Ts>
639 [[nodiscard]] constexpr bool none_of(Ts... flags) const noexcept
640 {
641 return (!(test(flags) || ...));
642 }
643
644 // Serializes the flag set to a string.
645 [[nodiscard]] std::string serialize() const
646 {
647 return std::to_string(mBits);
648 }
649
650 // Deserializes a string into the flag set.
651 void deserialize(const std::string& data)
652 {
653 typename H::UMax v = std::stoul(data);
654 if (v > H::MaxRep) {
655 throw std::out_of_range("Values exceeds enum range.");
656 }
657 mBits = static_cast<U>(v);
658 }
659
660 // Counts the number of set bits (active flags).
661 [[nodiscard]] constexpr size_t count() const noexcept
662 {
663 return std::popcount(mBits);
664 }
665
666 // Returns the union of two flag sets.
667 [[nodiscard]] constexpr EnumFlags union_with(const EnumFlags& o) const noexcept
668 {
669 return EnumFlags(mBits | o.mBits);
670 }
671
672 // Returns the intersection of two flag sets.
673 [[nodiscard]] constexpr EnumFlags intersection_with(const EnumFlags& o) const noexcept
674 {
675 return EnumFlags(mBits & o.mBits);
676 }
677
678 // Checks if all flags in another Flags object are present in the current object.
679 [[nodiscard]] constexpr bool contains(const EnumFlags& other) const noexcept
680 {
681 return (mBits & other.mBits) == other.mBits;
682 }
683
684 private:
685 // Set implementation, bits was zeroed before.
686 void setImpl(const std::string& s, int base = 2)
687 {
688 if (std::all_of(s.begin(), s.end(), [](unsigned char c) { return std::isdigit(c); })) {
689 if (base == 2) { // check of only 0 and 1 in string
690 if (!std::all_of(s.begin(), s.end(), [](char c) { return c == '0' || c == '1'; })) {
691 throw std::invalid_argument("Invalid binary string.");
692 }
693 }
694 typename H::UMax v = std::stoul(s, nullptr, base);
695 if (v > H::MaxRep) {
696 throw std::out_of_range("Values exceeds enum range.");
697 }
698 mBits = static_cast<U>(v);
699 } else if (std::all_of(s.begin(), s.end(), [](unsigned char c) { return std::isalnum(c) != 0 || c == '|' || c == ' ' || c == ':' || c == ',' || c == ';'; })) {
700 std::string cs{s};
701 std::transform(cs.begin(), cs.end(), cs.begin(), [](unsigned char c) { return std::tolower(c); });
702 if (cs == H::All) {
703 mBits = All;
704 } else if (cs == H::None) {
705 mBits = None;
706 } else {
707 // accept as delimiter ' ', '|', ';', ','
708 char token = ' ';
709 std::string::size_type pos = s.find_first_of(",|;");
710 if (pos != std::string::npos) {
711 token = s[pos];
712 }
713 for (const auto& tok : Str::tokenize(s, token)) {
714 if (auto e = H::fromString(tok)) {
715 mBits |= to_bit(*e);
716 } else {
717 throw std::invalid_argument(tok + " is not a valid enum value!");
718 }
719 }
720 }
721 } else {
722 throw std::invalid_argument("Cannot parse string!");
723 }
724 }
725};
726
727template <EnumFlag E>
728std::ostream& operator<<(std::ostream& os, const EnumFlags<E>& f)
729{
730 os << f.pstring(true);
731 return os;
732}
733
734} // namespace o2::utils
735
736#endif
int32_t i
uint16_t pos
Definition RawData.h:3
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:357
constexpr EnumFlags(E e)
Definition EnumFlags.h:378
constexpr bool all_of(Ts... flags) const noexcept
Definition EnumFlags.h:632
constexpr EnumFlags operator|(const EnumFlags &o) const noexcept
Definition EnumFlags.h:599
constexpr EnumFlags & operator=(const EnumFlags &o)=default
static constexpr U All
Definition EnumFlags.h:399
constexpr bool operator[](const T t) const noexcept
Definition EnumFlags.h:543
constexpr bool operator==(const EnumFlags &o) const noexcept
Definition EnumFlags.h:549
constexpr void reset(T t)
Definition EnumFlags.h:446
std::string serialize() const
Definition EnumFlags.h:645
constexpr EnumFlags operator&(T t) const noexcept
Definition EnumFlags.h:587
constexpr size_t count() const noexcept
Definition EnumFlags.h:661
constexpr EnumFlags(std::initializer_list< E > flags) noexcept
Definition EnumFlags.h:386
constexpr bool operator!=(const EnumFlags &o) const noexcept
Definition EnumFlags.h:555
constexpr EnumFlags()=default
constexpr EnumFlags & operator|=(T t) noexcept
Definition EnumFlags.h:569
constexpr bool any() const noexcept
Definition EnumFlags.h:483
constexpr EnumFlags union_with(const EnumFlags &o) const noexcept
Definition EnumFlags.h:667
static constexpr auto getValues() noexcept
Definition EnumFlags.h:402
constexpr auto value() const noexcept
Definition EnumFlags.h:432
constexpr void reset() noexcept
Definition EnumFlags.h:438
constexpr EnumFlags(const EnumFlags &)=default
constexpr EnumFlags operator~() const noexcept
Definition EnumFlags.h:593
constexpr EnumFlags operator^(const EnumFlags &o) const noexcept
Definition EnumFlags.h:612
constexpr EnumFlags & operator=(EnumFlags &&o)=default
constexpr ~EnumFlags()=default
constexpr EnumFlags intersection_with(const EnumFlags &o) const noexcept
Definition EnumFlags.h:673
void deserialize(const std::string &data)
Definition EnumFlags.h:651
static constexpr U None
Definition EnumFlags.h:398
constexpr void toggle(T t) noexcept
Definition EnumFlags.h:477
constexpr bool all() const noexcept
Definition EnumFlags.h:489
constexpr EnumFlags(EnumFlags &&)=default
void set(const std::string &s="", int base=2)
Definition EnumFlags.h:416
constexpr EnumFlags(U u)
Definition EnumFlags.h:384
constexpr EnumFlags & operator&=(T t) noexcept
Definition EnumFlags.h:578
constexpr bool none_of(Ts... flags) const noexcept
Definition EnumFlags.h:639
constexpr EnumFlags operator&(const EnumFlags &o) const noexcept
Definition EnumFlags.h:618
std::string string() const
Definition EnumFlags.h:495
static constexpr auto getNames() noexcept
Definition EnumFlags.h:408
constexpr EnumFlags & operator^=(const EnumFlags &o) noexcept
Definition EnumFlags.h:624
std::string pstring(bool withNewline=false) const
Definition EnumFlags.h:503
constexpr bool contains(const EnumFlags &other) const noexcept
Definition EnumFlags.h:679
constexpr bool test(Ts... flags) const noexcept
Definition EnumFlags.h:461
constexpr bool test(T t) const noexcept
Definition EnumFlags.h:454
constexpr void set(T t) noexcept
Definition EnumFlags.h:469
constexpr EnumFlags & operator|=(const EnumFlags &o) noexcept
Definition EnumFlags.h:605
EnumFlags(const std::string &str)
Definition EnumFlags.h:391
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
GLint GLsizei width
Definition glcorearb.h:270
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:728
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:211
static constexpr bool hasNone() noexcept
Definition EnumFlags.h:295
static constexpr std::string_view None
Definition EnumFlags.h:294
static constexpr UMax makeMaxRep(size_t min, size_t max)
Definition EnumFlags.h:166
static constexpr auto getLongestName() noexcept
Definition EnumFlags.h:241
static constexpr bool isIEqual(const unsigned char a, const unsigned char b) noexcept
Definition EnumFlags.h:275
static constexpr auto count() noexcept
Definition EnumFlags.h:159
std::underlying_type_t< E > U
Definition EnumFlags.h:59
static constexpr std::string_view All
Definition EnumFlags.h:306
static constexpr bool isIEqual(std::string_view s1, std::string_view s2) noexcept
Definition EnumFlags.h:281
static consteval const char * tpeek() noexcept
Definition EnumFlags.h:69
static constexpr auto getNames(std::index_sequence< I... >)
Definition EnumFlags.h:228
static constexpr std::string_view tpeek_v
Definition EnumFlags.h:75
static constexpr bool hasAll() noexcept
Definition EnumFlags.h:307
static constexpr std::string_view getName()
Definition EnumFlags.h:177
static constexpr bool isValid() noexcept
Definition EnumFlags.h:113
static constexpr unsigned char toLower(const unsigned char c) noexcept
Definition EnumFlags.h:269
static constexpr auto getValues(std::index_sequence< I... >) noexcept
Definition EnumFlags.h:144
static constexpr std::string_view removeScope(std::string_view s)
Definition EnumFlags.h:203
static constexpr std::optional< E > fromString(std::string_view str) noexcept
Definition EnumFlags.h:258
static constexpr bool isScoped() noexcept
Definition EnumFlags.h:62
static constexpr bool isContinuous() noexcept
Definition EnumFlags.h:165
static constexpr std::string_view toString() noexcept
Definition EnumFlags.h:253
static constexpr auto getSpec() noexcept
Definition EnumFlags.h:100
constexpr size_t min
constexpr size_t max
VectorOfTObjectPtrs other
const std::string str