aboutsummaryrefslogtreecommitdiffstats
path: root/tools/enum_parser/enum_serialization_runtime/enum_runtime.cpp
diff options
context:
space:
mode:
authorarcadia-devtools <arcadia-devtools@yandex-team.ru>2022-06-01 15:35:19 +0300
committerarcadia-devtools <arcadia-devtools@yandex-team.ru>2022-06-01 15:35:19 +0300
commit8e7094c87fa7ad049e6ea600a5f90f1c97d683bd (patch)
treed3e66d7ea5843080db0f65be0b7752538f69a84b /tools/enum_parser/enum_serialization_runtime/enum_runtime.cpp
parente13a5fc9fa49c7a6508a49f29e21a15fd9dac9ec (diff)
downloadydb-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.cpp120
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>