#pragma once #include "dispatch_methods.h" #include "ordered_pairs.h" #include #include #include #include #include #include #include namespace NEnumSerializationRuntime { /// Stores all information about enumeration except its real type template class TEnumDescriptionBase { public: using TRepresentationType = TEnumRepresentationType; using TEnumStringPair = ::NEnumSerializationRuntime::TEnumStringPair; /// 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; 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 TryFromString(const TStringBuf name) const; static std::pair TryFromStringFullScan(const TStringBuf name, const TInitializationData& enumInitData); static std::pair 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& 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; private: static bool MapFindResult(std::pair 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 EnumNames() const noexcept { return {TBase::TypelessEnumNames()}; } TMappedArrayView 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}; } }; }