Zrythm v2.0.0-DEV
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
enum_utils.h
1// SPDX-FileCopyrightText: © 2026 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3
4#pragma once
5
6#if defined(__GNUC__) || defined(__clang__)
7# pragma GCC diagnostic push
8# pragma GCC diagnostic ignored "-Wshadow"
9#elifdef _MSC_VER
10# pragma warning(push)
11# pragma warning(disable : 4458) // declaration hides class member
12#endif
13
14#include <magic_enum.hpp>
15#include <magic_enum_format.hpp>
16
17#if defined(__GNUC__) || defined(__clang__)
18# pragma GCC diagnostic pop
19#elifdef _MSC_VER
20# pragma warning(pop)
21#endif
22
23#include "utils/utf8_string.h"
24
25#include <QObject>
26
27#include <fmt/format.h>
28
29using namespace magic_enum::bitwise_operators;
30
31#define ENUM_INT_TO_VALUE_CONST(_enum, _int) \
32 (magic_enum::enum_value<_enum, _int> ())
33#define ENUM_INT_TO_VALUE(_enum, _int) (magic_enum::enum_value<_enum> (_int))
34#define ENUM_VALUE_TO_INT(_val) (magic_enum::enum_integer (_val))
35
36#define ENUM_ENABLE_BITSET(_enum) \
37 template <> struct magic_enum::customize::enum_range<_enum> \
38 { \
39 static constexpr bool is_flags = true; \
40 }
41#define ENUM_BITSET(_enum, _val) (magic_enum::containers::bitset<_enum> (_val))
42#define ENUM_BITSET_TEST(_val, _other_val) \
43 /* (ENUM_BITSET (_enum, _val).test (_other_val)) */ \
44 (static_cast<std::underlying_type_t<decltype (_val)>> (_val) \
45 & static_cast<std::underlying_type_t<decltype (_val)>> (_other_val))
46
49#define ENUM_BITSET_TO_STRING(_enum, _val) \
50 (ENUM_BITSET (_enum, _val).to_string ().data ())
51
52#define ENUM_COUNT(_enum) (magic_enum::enum_count<_enum> ())
53#define ENUM_NAME(_val) (magic_enum::enum_name (_val).data ())
54#define ENUM_NAME_FROM_INT(_enum, _int) \
55 ENUM_NAME (ENUM_INT_TO_VALUE (_enum, _int))
56
57#define VA_ARGS_SIZE(...) \
58 std::tuple_size<decltype (std::make_tuple (__VA_ARGS__))>::value
59
60#define DEFINE_ENUM_FORMATTER(enum_type, enum_name, ...) \
61 namespace fmt \
62 { \
63 template <> struct formatter<enum_type> \
64 { \
65 bool translate_ = false; \
66 template <typename ParseContext> constexpr auto parse (ParseContext &ctx) \
67 { \
68 auto it = ctx.begin (); \
69 translate_ = (it != ctx.end () && *it == 't'); \
70 return it + translate_; \
71 } \
72\
73 template <typename FormatContext> \
74 auto format (const enum_type &val, FormatContext &ctx) const \
75 { \
76 static constexpr std::array<const char *, VA_ARGS_SIZE (__VA_ARGS__)> \
77 enum_strings = { __VA_ARGS__ }; \
78 const char * str = enum_strings.at (static_cast<int> (val)); \
79 return format_to ( \
80 ctx.out (), FMT_STRING ("{}"), \
81 translate_ \
82 ? zrythm::utils::Utf8String::from_qstring (QObject::tr (str)).c_str () \
83 : str); \
84 } \
85 }; \
86 } \
87\
88 inline const char * const * enum_name##_get_strings () \
89 { \
90 static constexpr std::array<const char *, VA_ARGS_SIZE (__VA_ARGS__)> \
91 enum_strings = { __VA_ARGS__ }; \
92 return enum_strings.data (); \
93 } \
94\
95 inline zrythm::utils::Utf8String \
96 enum_name##_to_string (enum_type val, bool translate = false) \
97 { \
98 if (translate) \
99 { \
100 return zrythm::utils::Utf8String::from_utf8_encoded_string ( \
101 fmt::format ("{:t}", val)); \
102 } \
103 return zrythm::utils::Utf8String::from_utf8_encoded_string ( \
104 fmt::format ("{}", val)); \
105 } \
106\
107 inline enum_type enum_name##_from_string ( \
108 const zrythm::utils::Utf8String &str, bool translate = false) \
109 { \
110 for (size_t i = 0; i < VA_ARGS_SIZE (__VA_ARGS__); ++i) \
111 { \
112 if ( \
113 str == enum_name##_to_string (static_cast<enum_type> (i), translate)) \
114 { \
115 return static_cast<enum_type> (i); \
116 } \
117 } \
118 throw std::runtime_error ( \
119 fmt::format ("Enum value from '{}' not found", str)); \
120 return static_cast<enum_type> (0); \
121 }