blob: 2e7cc7f8267877cf0112a88ed0b6e7c37a0ffab7 (
plain) (
tree)
|
|
#include "enum_runtime.h"
#include <util/generic/map.h>
#include <util/generic/yexception.h>
#include <util/stream/output.h>
namespace NEnumSerializationRuntime {
template <typename TEnumRepresentationType>
[[noreturn]] static void ThrowUndefinedValueException(const TEnumRepresentationType key, const TStringBuf className) {
throw yexception() << "Undefined value " << key << " in " << className << ". ";
}
template <typename TEnumRepresentationType>
const TString& TEnumDescriptionBase<TEnumRepresentationType>::ToString(TRepresentationType key) const {
const auto it = Names.find(key);
if (Y_LIKELY(it != Names.end())) {
return it->second;
}
ThrowUndefinedValueException(key, ClassName);
}
template <typename TEnumRepresentationType>
std::pair<bool, TEnumRepresentationType> TEnumDescriptionBase<TEnumRepresentationType>::TryFromString(const TStringBuf name) const {
const auto it = Values.find(name);
if (it != Values.end()) {
return {true, it->second};
}
return {false, TRepresentationType()};
}
[[noreturn]] static void ThrowUndefinedNameException(const TStringBuf name, const TStringBuf className, const TStringBuf allEnumNames) {
ythrow yexception() << "Key '" << name << "' not found in enum " << className << ". Valid options are: " << allEnumNames << ". ";
}
template <typename TEnumRepresentationType>
auto TEnumDescriptionBase<TEnumRepresentationType>::FromString(const TStringBuf name) const -> TRepresentationType {
const auto findResult = TryFromString(name);
if (Y_LIKELY(findResult.first)) {
return findResult.second;
}
ThrowUndefinedNameException(name, ClassName, AllEnumNames());
}
template <typename TEnumRepresentationType>
void TEnumDescriptionBase<TEnumRepresentationType>::Out(IOutputStream* os, const TRepresentationType key) const {
(*os) << this->ToString(key);
}
template <typename TEnumRepresentationType>
TEnumDescriptionBase<TEnumRepresentationType>::TEnumDescriptionBase(const TInitializationData& enumInitData)
: ClassName(enumInitData.ClassName)
{
const TArrayRef<const TEnumStringPair>& namesInitializer = enumInitData.NamesInitializer;
const TArrayRef<const TEnumStringPair>& valuesInitializer = enumInitData.ValuesInitializer;
const TArrayRef<const TStringBuf>& cppNamesInitializer = enumInitData.CppNamesInitializer;
TMap<TRepresentationType, TString> mapValueToName;
TMap<TStringBuf, TRepresentationType> mapNameToValue;
for (const TEnumStringPair& it : namesInitializer) {
mapValueToName.emplace(it.Key, TString(it.Name));
}
for (const TEnumStringPair& it : valuesInitializer) {
mapNameToValue.emplace(it.Name, it.Key);
}
Names = std::move(mapValueToName);
Values = std::move(mapNameToValue);
AllValues.reserve(Names.size());
for (const auto& it : Names) {
if (!AllNames.empty()) {
AllNames += ", ";
}
AllNames += TString::Join('\'', it.second, '\'');
AllValues.push_back(it.first);
}
AllCppNames.reserve(cppNamesInitializer.size());
for (const auto& cn : cppNamesInitializer) {
AllCppNames.push_back(TString::Join(enumInitData.CppNamesPrefix, cn));
}
}
template <typename TEnumRepresentationType>
TEnumDescriptionBase<TEnumRepresentationType>::~TEnumDescriptionBase() = default;
// explicit instantiation
template class TEnumDescriptionBase<int>;
template class TEnumDescriptionBase<unsigned>;
template class TEnumDescriptionBase<long long>;
template class TEnumDescriptionBase<unsigned long long>;
}
|