aboutsummaryrefslogtreecommitdiffstats
path: root/tools/enum_parser/enum_serialization_runtime/enum_runtime.h
blob: 7c85ed3934a3517d2432428c02e06937eaf51a55 (plain) (blame)
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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#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;

        // ToString
        // Return reference to singleton preallocated string
        const TString& ToString(const EEnum key) const {
            return TBase::ToString(TCast::CastToRepresentationType(key));
        }

        // ToStringBuf
        TStringBuf ToStringBuf(EEnum key) const {
            return TBase::ToStringBuf(TCast::CastToRepresentationType(key));
        }
        static TStringBuf ToStringBufFullScan(const EEnum key, const TInitializationData& enumInitData) {
            return TBase::ToStringBufFullScan(TCast::CastToRepresentationType(key), enumInitData);
        }
        static TStringBuf ToStringBufSorted(const EEnum key, const TInitializationData& enumInitData) {
            return TBase::ToStringBufSorted(TCast::CastToRepresentationType(key), enumInitData);
        }
        static TStringBuf ToStringBufDirect(const EEnum key, const TInitializationData& enumInitData) {
            return TBase::ToStringBufDirect(TCast::CastToRepresentationType(key), enumInitData);
        }

        // TryFromString-like functons
        // Return false for unknown enumeration names
        bool FromString(const TStringBuf name, EEnum& ret) const {
            return MapFindResult(TBase::TryFromString(name), ret);
        }
        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);
        }

        // FromString
        // Throw exception for unknown enumeration names
        EEnum FromString(const TStringBuf name) const {
            return TCast::CastFromRepresentationType(TBase::FromString(name));
        }
        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));
        }

        // Inspection
        TMappedDictView<EEnum, TString> EnumNames() const noexcept {
            return {TBase::TypelessEnumNames()};
        }

        TMappedArrayView<EEnum> AllEnumValues() const noexcept {
            return {TBase::TypelessEnumValues()};
        }

        // Out
        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};
        }
    };
}