#pragma once #include #include #include #include #include #include class IOutputStream; namespace NEnumSerializationRuntime { /// Stores all information about enumeration except its real type template class TEnumDescriptionBase { public: using TRepresentationType = TEnumRepresentationType; struct TEnumStringPair { const TRepresentationType Key; const TStringBuf Name; }; /// Refers initialization data stored in constexpr-friendly format struct TInitializationData { const TArrayRef NamesInitializer; const TArrayRef ValuesInitializer; const TArrayRef CppNamesInitializer; const TStringBuf CppNamesPrefix; const TStringBuf ClassName; }; public: TEnumDescriptionBase(const TInitializationData& enumInitData); ~TEnumDescriptionBase(); const TString& ToString(TRepresentationType key) const; std::pair TryFromString(const TStringBuf name) const; TRepresentationType FromString(const TStringBuf name) const; void Out(IOutputStream* os, const TRepresentationType key) const; const TString& AllEnumNames() const noexcept { return AllNames; } const TVector& AllEnumCppNames() const noexcept { return AllCppNames; } const TMap& TypelessEnumNames() const noexcept { return Names; } const TVector& TypelessEnumValues() const noexcept { return AllValues; } private: TMap Names; TMap Values; TString AllNames; TVector AllCppNames; TString ClassName; TVector AllValues; }; /// Wraps TEnumDescriptionBase and performs on-demand casts template ::TType> class TEnumDescription: public NDetail::TMappedViewBase, private TEnumDescriptionBase { public: using TBase = TEnumDescriptionBase; using TCast = NDetail::TMappedViewBase; using TBase::AllEnumCppNames; using TBase::AllEnumNames; using typename TBase::TEnumStringPair; using typename TBase::TRepresentationType; using typename TBase::TInitializationData; 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 { const auto findResult = TBase::TryFromString(name); if (findResult.first) { ret = TCast::CastFromRepresentationType(findResult.second); return true; } return false; } EEnum FromString(const TStringBuf name) const { return TCast::CastFromRepresentationType(TBase::FromString(name)); } TMappedDictView EnumNames() const noexcept { return {TBase::TypelessEnumNames()}; } TMappedArrayView AllEnumValues() const noexcept { return {TBase::TypelessEnumValues()}; } void Out(IOutputStream* os, const EEnum key) const { TBase::Out(os, TCast::CastToRepresentationType(key)); } static constexpr TEnumStringPair EnumStringPair(const EEnum key, const TStringBuf name) noexcept { return {TCast::CastToRepresentationType(key), name}; } }; }