1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
|
#pragma once
#include "dispatch_methods.h"
#include "ordered_pairs.h"
#include <util/generic/array_ref.h>
#include <util/generic/strbuf.h>
#include <util/generic/string.h>
#include <util/generic/vector.h>
#include <util/generic/serialized_enum.h>
#include <util/stream/fwd.h>
#include <utility>
namespace NEnumSerializationRuntime {
/// Stores all information about enumeration except its real type
template <typename TEnumRepresentationType>
class TEnumDescriptionBase {
public:
using TRepresentationType = TEnumRepresentationType;
using TEnumStringPair = ::NEnumSerializationRuntime::TEnumStringPair<TRepresentationType>;
/// Refers initialization data stored in constexpr-friendly format
struct TInitializationData {
const TArrayRef<const TEnumStringPair> NamesInitializer;
const TArrayRef<const TEnumStringPair> ValuesInitializer;
const TArrayRef<const TStringBuf> CppNamesInitializer;
const TStringBuf CppNamesPrefix;
const TStringBuf ClassName;
};
public:
TEnumDescriptionBase(const TInitializationData& enumInitData);
~TEnumDescriptionBase();
const TString& ToString(TRepresentationType key) const;
TStringBuf ToStringBuf(TRepresentationType key) const;
static TStringBuf ToStringBufFullScan(const TRepresentationType key, const TInitializationData& enumInitData);
static TStringBuf ToStringBufSorted(const TRepresentationType key, const TInitializationData& enumInitData);
static TStringBuf ToStringBufDirect(const TRepresentationType key, const TInitializationData& enumInitData);
std::pair<bool, TRepresentationType> TryFromString(const TStringBuf name) const;
static std::pair<bool, TRepresentationType> TryFromStringFullScan(const TStringBuf name, const TInitializationData& enumInitData);
static std::pair<bool, TRepresentationType> TryFromStringSorted(const TStringBuf name, const TInitializationData& enumInitData);
TRepresentationType FromString(const TStringBuf name) const;
static TRepresentationType FromStringFullScan(const TStringBuf name, const TInitializationData& enumInitData);
static TRepresentationType FromStringSorted(const TStringBuf name, const TInitializationData& enumInitData);
void Out(IOutputStream* os, const TRepresentationType key) const;
static void OutFullScan(IOutputStream* os, const TRepresentationType key, const TInitializationData& enumInitData);
static void OutSorted(IOutputStream* os, const TRepresentationType key, const TInitializationData& enumInitData);
static void OutDirect(IOutputStream* os, const TRepresentationType key, const TInitializationData& enumInitData);
const TString& AllEnumNames() const noexcept {
return AllNames;
}
const TVector<TString>& AllEnumCppNames() const noexcept {
return AllCppNames;
}
const TMap<TRepresentationType, TString>& TypelessEnumNames() const noexcept {
return Names;
}
const TVector<TRepresentationType>& TypelessEnumValues() const noexcept {
return AllValues;
}
private:
TMap<TRepresentationType, TString> Names;
TMap<TStringBuf, TRepresentationType> Values;
TString AllNames;
TVector<TString> AllCppNames;
TString ClassName;
TVector<TRepresentationType> AllValues;
};
/// Wraps TEnumDescriptionBase and performs on-demand casts
template <typename EEnum, typename TEnumRepresentationType = typename NDetail::TSelectEnumRepresentationType<EEnum>::TType>
class TEnumDescription: public NDetail::TMappedViewBase<EEnum, TEnumRepresentationType>, private TEnumDescriptionBase<TEnumRepresentationType> {
public:
using TBase = TEnumDescriptionBase<TEnumRepresentationType>;
using TCast = NDetail::TMappedViewBase<EEnum, TEnumRepresentationType>;
using TBase::AllEnumCppNames;
using TBase::AllEnumNames;
using typename TBase::TEnumStringPair;
using typename TBase::TRepresentationType;
using typename TBase::TInitializationData;
private:
static bool MapFindResult(std::pair<bool, TEnumRepresentationType> findResult, EEnum& ret) {
if (findResult.first) {
ret = TCast::CastFromRepresentationType(findResult.second);
return true;
}
return false;
}
public:
using TBase::TBase;
const TString& ToString(const EEnum key) const {
return TBase::ToString(TCast::CastToRepresentationType(key));
}
bool FromString(const TStringBuf name, EEnum& ret) const {
return MapFindResult(TBase::TryFromString(name), ret);
}
EEnum FromString(const TStringBuf name) const {
return TCast::CastFromRepresentationType(TBase::FromString(name));
}
static bool TryFromStringFullScan(const TStringBuf name, EEnum& ret, const TInitializationData& enumInitData) {
return MapFindResult(TBase::TryFromStringFullScan(name, enumInitData), ret);
}
static bool TryFromStringSorted(const TStringBuf name, EEnum& ret, const TInitializationData& enumInitData) {
return MapFindResult(TBase::TryFromStringSorted(name, enumInitData), ret);
}
static EEnum FromStringFullScan(const TStringBuf name, const TInitializationData& enumInitData) {
return TCast::CastFromRepresentationType(TBase::FromStringFullScan(name, enumInitData));
}
static EEnum FromStringSorted(const TStringBuf name, const TInitializationData& enumInitData) {
return TCast::CastFromRepresentationType(TBase::FromStringSorted(name, enumInitData));
}
TMappedDictView<EEnum, TString> EnumNames() const noexcept {
return {TBase::TypelessEnumNames()};
}
TMappedArrayView<EEnum> AllEnumValues() const noexcept {
return {TBase::TypelessEnumValues()};
}
void Out(IOutputStream* os, const EEnum key) const {
TBase::Out(os, TCast::CastToRepresentationType(key));
}
static void OutFullScan(IOutputStream* os, const EEnum key, const TInitializationData& enumInitData) {
TBase::OutFullScan(os, TCast::CastToRepresentationType(key), enumInitData);
}
static void OutSorted(IOutputStream* os, const EEnum key, const TInitializationData& enumInitData) {
TBase::OutSorted(os, TCast::CastToRepresentationType(key), enumInitData);
}
static void OutDirect(IOutputStream* os, const EEnum key, const TInitializationData& enumInitData) {
TBase::OutDirect(os, TCast::CastToRepresentationType(key), enumInitData);
}
static constexpr TEnumStringPair EnumStringPair(const EEnum key, const TStringBuf name) noexcept {
return {TCast::CastToRepresentationType(key), name};
}
};
}
|