Coverage Report

Created: 2023-12-13 14:58

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