diff options
author | arcadia-devtools <arcadia-devtools@yandex-team.ru> | 2022-06-01 15:35:19 +0300 |
---|---|---|
committer | arcadia-devtools <arcadia-devtools@yandex-team.ru> | 2022-06-01 15:35:19 +0300 |
commit | 8e7094c87fa7ad049e6ea600a5f90f1c97d683bd (patch) | |
tree | d3e66d7ea5843080db0f65be0b7752538f69a84b /tools/enum_parser/enum_serialization_runtime/enum_runtime.cpp | |
parent | e13a5fc9fa49c7a6508a49f29e21a15fd9dac9ec (diff) | |
download | ydb-8e7094c87fa7ad049e6ea600a5f90f1c97d683bd.tar.gz |
intermediate changes
ref:b1e863e3aa12b888b40dd5ec36411ca050a25bd8
Diffstat (limited to 'tools/enum_parser/enum_serialization_runtime/enum_runtime.cpp')
-rw-r--r-- | tools/enum_parser/enum_serialization_runtime/enum_runtime.cpp | 120 |
1 files changed, 119 insertions, 1 deletions
diff --git a/tools/enum_parser/enum_serialization_runtime/enum_runtime.cpp b/tools/enum_parser/enum_serialization_runtime/enum_runtime.cpp index 2e7cc7f826..465f46b3e0 100644 --- a/tools/enum_parser/enum_serialization_runtime/enum_runtime.cpp +++ b/tools/enum_parser/enum_serialization_runtime/enum_runtime.cpp @@ -1,5 +1,6 @@ #include "enum_runtime.h" +#include <util/generic/algorithm.h> #include <util/generic/map.h> #include <util/generic/yexception.h> #include <util/stream/output.h> @@ -28,11 +29,57 @@ namespace NEnumSerializationRuntime { return {false, TRepresentationType()}; } + template <class TContainer, class TNeedle, class TGetKey> + static typename TContainer::value_type const* FindPtrInSortedContainer(const TContainer& vec, const TNeedle& needle, TGetKey&& getKey) { + const auto it = LowerBoundBy(vec.begin(), vec.end(), needle, getKey); + if (it == vec.end()) { + return nullptr; + } + if (getKey(*it) != needle) { + return nullptr; + } + return std::addressof(*it); + } + + template <typename TEnumRepresentationType> + std::pair<bool, TEnumRepresentationType> TEnumDescriptionBase<TEnumRepresentationType>::TryFromStringSorted(const TStringBuf name, const TInitializationData& enumInitData) { + const auto& vec = enumInitData.ValuesInitializer; + const auto* ptr = FindPtrInSortedContainer(vec, name, std::mem_fn(&TEnumStringPair::Name)); + if (ptr) { + return {true, ptr->Key}; + } + return {false, TRepresentationType()}; + } + + template <typename TEnumRepresentationType> + std::pair<bool, TEnumRepresentationType> TEnumDescriptionBase<TEnumRepresentationType>::TryFromStringFullScan(const TStringBuf name, const TInitializationData& enumInitData) { + const auto& vec = enumInitData.ValuesInitializer; + const auto* ptr = FindIfPtr(vec, [&](const auto& item) { return item.Name == name; }); + if (ptr) { + return {true, ptr->Key}; + } + 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> + [[noreturn]] static void ThrowUndefinedNameException(const TStringBuf name, const typename TEnumDescriptionBase<TEnumRepresentationType>::TInitializationData& enumInitData) { + auto exc = __LOCATION__ + yexception() << "Key '" << name << "' not found in enum " << enumInitData.ClassName << ". Valid options are: "; + const auto& vec = enumInitData.NamesInitializer; + for (size_t i = 0; i < vec.size(); ++i) { + if (i != 0) { + exc << ", "; + } + exc << '\'' << vec[i].Name << '\''; + } + exc << ". "; + throw exc; + } + + template <typename TEnumRepresentationType> auto TEnumDescriptionBase<TEnumRepresentationType>::FromString(const TStringBuf name) const -> TRepresentationType { const auto findResult = TryFromString(name); if (Y_LIKELY(findResult.first)) { @@ -42,8 +89,79 @@ namespace NEnumSerializationRuntime { } template <typename TEnumRepresentationType> + TEnumRepresentationType TEnumDescriptionBase<TEnumRepresentationType>::FromStringFullScan(const TStringBuf name, const TInitializationData& enumInitData) { + const auto findResult = TryFromStringFullScan(name, enumInitData); + if (Y_LIKELY(findResult.first)) { + return findResult.second; + } + ThrowUndefinedNameException<TEnumRepresentationType>(name, enumInitData); + } + + template <typename TEnumRepresentationType> + TEnumRepresentationType TEnumDescriptionBase<TEnumRepresentationType>::FromStringSorted(const TStringBuf name, const TInitializationData& enumInitData) { + const auto findResult = TryFromStringSorted(name, enumInitData); + if (Y_LIKELY(findResult.first)) { + return findResult.second; + } + ThrowUndefinedNameException<TEnumRepresentationType>(name, enumInitData); + } + + template <typename TEnumRepresentationType> + TStringBuf TEnumDescriptionBase<TEnumRepresentationType>::ToStringBuf(TRepresentationType key) const { + return this->ToString(key); + } + + template <typename TEnumRepresentationType> + TStringBuf TEnumDescriptionBase<TEnumRepresentationType>::ToStringBufFullScan(const TRepresentationType key, const TInitializationData& enumInitData) { + const auto& vec = enumInitData.NamesInitializer; + const auto* ptr = FindIfPtr(vec, [&](const auto& item) { return item.Key == key; }); + if (Y_UNLIKELY(!ptr)) { + ThrowUndefinedValueException(key, enumInitData.ClassName); + } + return ptr->Name; + } + + template <typename TEnumRepresentationType> + TStringBuf TEnumDescriptionBase<TEnumRepresentationType>::ToStringBufSorted(const TRepresentationType key, const TInitializationData& enumInitData) { + const auto& vec = enumInitData.NamesInitializer; + const auto* ptr = FindPtrInSortedContainer(vec, key, std::mem_fn(&TEnumStringPair::Key)); + if (Y_UNLIKELY(!ptr)) { + ThrowUndefinedValueException(key, enumInitData.ClassName); + } + return ptr->Name; + } + + template <typename TEnumRepresentationType> + TStringBuf TEnumDescriptionBase<TEnumRepresentationType>::ToStringBufDirect(const TRepresentationType key, const TInitializationData& enumInitData) { + const auto& vec = enumInitData.NamesInitializer; + if (Y_UNLIKELY(vec.empty() || key < vec.front().Key)) { + ThrowUndefinedValueException(key, enumInitData.ClassName); + } + const size_t index = static_cast<size_t>(key - vec.front().Key); + if (Y_UNLIKELY(index >= vec.size())) { + ThrowUndefinedValueException(key, enumInitData.ClassName); + } + return vec[index].Name; + } + + template <typename TEnumRepresentationType> void TEnumDescriptionBase<TEnumRepresentationType>::Out(IOutputStream* os, const TRepresentationType key) const { - (*os) << this->ToString(key); + (*os) << this->ToStringBuf(key); + } + + template <typename TEnumRepresentationType> + void TEnumDescriptionBase<TEnumRepresentationType>::OutFullScan(IOutputStream* os, const TRepresentationType key, const TInitializationData& enumInitData) { + (*os) << ToStringBufFullScan(key, enumInitData); + } + + template <typename TEnumRepresentationType> + void TEnumDescriptionBase<TEnumRepresentationType>::OutSorted(IOutputStream* os, const TRepresentationType key, const TInitializationData& enumInitData) { + (*os) << ToStringBufSorted(key, enumInitData); + } + + template <typename TEnumRepresentationType> + void TEnumDescriptionBase<TEnumRepresentationType>::OutDirect(IOutputStream* os, const TRepresentationType key, const TInitializationData& enumInitData) { + (*os) << ToStringBufDirect(key, enumInitData); } template <typename TEnumRepresentationType> |