Coverage Report

Created: 2024-07-18 11:41

src/zserio/Enums.h
Line
Count
Source
1
#ifndef ZSERIO_ENUMS_H_INC
2
#define ZSERIO_ENUMS_H_INC
3
4
#include <algorithm>
5
#include <cstddef>
6
#include <type_traits>
7
8
#include "zserio/CppRuntimeException.h"
9
#include "zserio/StringView.h"
10
#include "zserio/Types.h"
11
12
// This should be implemented in runtime library header.
13
namespace zserio
14
{
15
16
// forward declarations
17
class BitStreamReader;
18
class BitStreamWriter;
19
20
/**
21
 * Enum traits for Zserio enums.
22
 */
23
template <typename T>
24
struct EnumTraits
25
{};
26
27
/**
28
 * Gets ordinal number of the given enum item.
29
 *
30
 * \param value Enum item.
31
 *
32
 * \return Ordinal number of the enum item.
33
 */
34
template <typename T>
35
size_t enumToOrdinal(T value);
36
37
/**
38
 * Converts the given raw value to an appropriate enum item.
39
 *
40
 * \param rawValue Raw value of the proper underlying type.
41
 *
42
 * \return Enum item corresponding to the rawValue.
43
 *
44
 * \throw CppRuntimeException when the rawValue doesn't match to any enum item.
45
 */
46
template <typename T>
47
T valueToEnum(typename std::underlying_type<T>::type rawValue);
48
49
/**
50
 * Gets the underlying raw value of the given enum item.
51
 *
52
 * \param value Enum item.
53
 *
54
 * \return Raw value.
55
 */
56
template <typename T>
57
constexpr typename std::underlying_type<T>::type enumToValue(T value)
58
766
{
59
766
    return static_cast<typename std::underlying_type<T>::type>(value);
60
766
}
61
62
/**
63
 * Gets the hash code of the given enum item.
64
 *
65
 * \param value Enum item.
66
 *
67
 * \return Hash code of the enum item.
68
 */
69
template <typename T>
70
uint32_t enumHashCode(T value);
71
72
/**
73
 * Converts the given enum item name to an appropriate enum item.
74
 *
75
 * \param itemName Name of the enum item.
76
 *
77
 * \return Enum item corresponding to the itemName.
78
 *
79
 * \throw CppRuntimeException when the itemName doesn't match to any enum item.
80
 */
81
template <typename T>
82
T stringToEnum(StringView itemName)
83
5
{
84
5
    const auto foundIt = std::find_if(EnumTraits<T>::names.begin(), EnumTraits<T>::names.end(),
85
14
            [itemName](const char* enumItemName) { return itemName.compare(enumItemName) == 0; });
86
5
    if (foundIt == EnumTraits<T>::names.end())
87
1
    {
88
1
        throw CppRuntimeException("Enum item '")
89
1
                << itemName << "' doesn't exist in enum '" << EnumTraits<T>::enumName << "'!";
90
1
    }
91
92
4
    const size_t ordinal = static_cast<size_t>(std::distance(EnumTraits<T>::names.begin(), foundIt));
93
4
    return EnumTraits<T>::values[ordinal];
94
5
}
95
96
/**
97
 * Gets the name of the given enum item.
98
 *
99
 * \param value Enum item.
100
 *
101
 * \return Name of the enum item.
102
 */
103
template <typename T>
104
const char* enumToString(T value)
105
26
{
106
26
    return EnumTraits<T>::names[enumToOrdinal(value)];
107
26
}
108
109
/**
110
 * Initializes packing context for the given enum item.
111
 *
112
 * \param context Packing context.
113
 * \param value Enum item.
114
 */
115
template <typename PACKING_CONTEXT, typename T>
116
void initPackingContext(PACKING_CONTEXT& context, T value);
117
118
/**
119
 * Gets bit size of the given enum item.
120
 *
121
 * Note that T can be varuint, so bitSizeOf cannot return constant value and depends on the concrete item.
122
 *
123
 * \param value Enum item.
124
 *
125
 * \return Bit size of the enum item.
126
 */
127
template <typename T>
128
size_t bitSizeOf(T value);
129
130
/**
131
 * Gets bit size of the given enum item when it's inside a packed array.
132
 *
133
 * Note that T can be varuint, so bitSizeOf cannot return constant value and depends on the concrete item.
134
 *
135
 * \param context Packing context.
136
 * \param value Enum item.
137
 *
138
 * \return Bit size of the enum item.
139
 */
140
template <typename PACKING_CONTEXT, typename T>
141
size_t bitSizeOf(PACKING_CONTEXT& context, T value);
142
143
/**
144
 * Initializes offsets for the enum item.
145
 *
146
 * Note that T can be varuint, so initializeOffsets cannot return constant value and
147
 * depends on the concrete item.
148
 *
149
 * \param bitPosition Current bit position.
150
 * \param value Enum item.
151
 *
152
 * \return Updated bit position which points to the first bit after the enum item.
153
 */
154
template <typename T>
155
size_t initializeOffsets(size_t bitPosition, T value);
156
157
/**
158
 * Initializes offsets for the enum item when it's inside a packed array.
159
 *
160
 * Note that T can be varuint, so initializeOffsets cannot return constant value and
161
 * depends on the concrete item.
162
 *
163
 * \param context Packing context.
164
 * \param bitPosition Current bit position.
165
 * \param value Enum item.
166
 *
167
 * \return Updated bit position which points to the first bit after the enum item.
168
 */
169
template <typename PACKING_CONTEXT, typename T>
170
size_t initializeOffsets(PACKING_CONTEXT& context, size_t bitPosition, T value);
171
172
/**
173
 * Reads an enum item.
174
 *
175
 * \param in Bit stream reader.
176
 *
177
 * \return Enum item read from the bit stream.
178
 */
179
template <typename T>
180
T read(BitStreamReader& in);
181
182
/**
183
 * Reads an enum item which is inside a packed array.
184
 *
185
 * \param context Packing context.
186
 * \param in Bit stream reader.
187
 *
188
 * \return Enum item read from the bit stream.
189
 */
190
template <typename T, typename PACKING_CONTEXT>
191
T read(PACKING_CONTEXT& context, BitStreamReader& in);
192
193
/**
194
 * Writes the enum item to the given bit stream.
195
 *
196
 * \param out Bit stream writer.
197
 * \param value Enum item to write.
198
 */
199
template <typename T>
200
void write(BitStreamWriter& out, T value);
201
202
/**
203
 * Writes the enum item which is inside a packed array to the given bit stream.
204
 *
205
 * \param context Packing context.
206
 * \param out Bit stream writer.
207
 * \param value Enum item to write.
208
 */
209
template <typename PACKING_CONTEXT, typename T>
210
void write(PACKING_CONTEXT& context, BitStreamWriter& out, T value);
211
212
/**
213
 * Appends any enumeration value to the exception's description.
214
 *
215
 * \param exception Exception to modify.
216
 * \param value Enumeration value to append.
217
 *
218
 * \return Reference to the exception to allow operator chaining.
219
 */
220
template <typename T, typename std::enable_if<std::is_enum<T>::value, int>::type = 0>
221
CppRuntimeException& operator<<(CppRuntimeException& exception, T value)
222
1
{
223
1
    exception << enumToString(value);
224
1
    return exception;
225
1
}
226
227
} // namespace zserio
228
229
#endif // ZSERIO_ENUMS_H_INC