aboutsummaryrefslogtreecommitdiffstats
path: root/tools/enum_parser/enum_serialization_runtime
diff options
context:
space:
mode:
authorDevtools Arcadia <arcadia-devtools@yandex-team.ru>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /tools/enum_parser/enum_serialization_runtime
downloadydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'tools/enum_parser/enum_serialization_runtime')
-rw-r--r--tools/enum_parser/enum_serialization_runtime/README.md2
-rw-r--r--tools/enum_parser/enum_serialization_runtime/enum_runtime.cpp100
-rw-r--r--tools/enum_parser/enum_serialization_runtime/enum_runtime.h116
-rw-r--r--tools/enum_parser/enum_serialization_runtime/ya.make13
4 files changed, 231 insertions, 0 deletions
diff --git a/tools/enum_parser/enum_serialization_runtime/README.md b/tools/enum_parser/enum_serialization_runtime/README.md
new file mode 100644
index 0000000000..7d2cbae4ce
--- /dev/null
+++ b/tools/enum_parser/enum_serialization_runtime/README.md
@@ -0,0 +1,2 @@
+This library should not be used or referred directly.
+Use `GENERATE_ENUM_SERIALIZATION_WITH_HEADER` and `GENERATE_ENUM_SERIALIZATION` macros instead.
diff --git a/tools/enum_parser/enum_serialization_runtime/enum_runtime.cpp b/tools/enum_parser/enum_serialization_runtime/enum_runtime.cpp
new file mode 100644
index 0000000000..73d38b396a
--- /dev/null
+++ b/tools/enum_parser/enum_serialization_runtime/enum_runtime.cpp
@@ -0,0 +1,100 @@
+#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<TString, TRepresentationType> mapNameToValue;
+ const bool bijectiveHint = (namesInitializer.data() == valuesInitializer.data() && namesInitializer.size() == valuesInitializer.size());
+ if (bijectiveHint) {
+ for (const TEnumStringPair& it : namesInitializer) {
+ TString name{it.Name};
+ mapValueToName.emplace(it.Key, name);
+ mapNameToValue.emplace(std::move(name), it.Key);
+ }
+ } else {
+ for (const TEnumStringPair& it : namesInitializer) {
+ mapValueToName.emplace(it.Key, TString(it.Name));
+ }
+ for (const TEnumStringPair& it : valuesInitializer) {
+ mapNameToValue.emplace(TString(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>;
+}
diff --git a/tools/enum_parser/enum_serialization_runtime/enum_runtime.h b/tools/enum_parser/enum_serialization_runtime/enum_runtime.h
new file mode 100644
index 0000000000..f157d43109
--- /dev/null
+++ b/tools/enum_parser/enum_serialization_runtime/enum_runtime.h
@@ -0,0 +1,116 @@
+#pragma once
+
+#include <util/generic/array_ref.h>
+#include <util/generic/strbuf.h>
+#include <util/generic/string.h>
+#include <util/generic/vector.h>
+#include <util/generic/serialized_enum.h>
+
+#include <utility>
+
+class IOutputStream;
+
+namespace NEnumSerializationRuntime {
+ /// Stores all information about enumeration except its real type
+ template <typename TEnumRepresentationType>
+ 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<const TEnumStringPair> NamesInitializer;
+ const TArrayRef<const TEnumStringPair> ValuesInitializer;
+ const TArrayRef<const TStringBuf> CppNamesInitializer;
+ const TStringBuf CppNamesPrefix;
+ const TStringBuf ClassName;
+ };
+
+ public:
+ TEnumDescriptionBase(const TInitializationData& enumInitData);
+ ~TEnumDescriptionBase();
+
+ const TString& ToString(TRepresentationType key) const;
+ std::pair<bool, TRepresentationType> 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<TString>& AllEnumCppNames() const noexcept {
+ return AllCppNames;
+ }
+
+ const TMap<TRepresentationType, TString>& TypelessEnumNames() const noexcept {
+ return Names;
+ }
+
+ const TVector<TRepresentationType>& TypelessEnumValues() const noexcept {
+ return AllValues;
+ }
+
+ private:
+ TMap<TRepresentationType, TString> Names;
+ TMap<TString, TRepresentationType> Values;
+ TString AllNames;
+ TVector<TString> AllCppNames;
+ TString ClassName;
+ TVector<TRepresentationType> AllValues;
+ };
+
+ /// Wraps TEnumDescriptionBase and performs on-demand casts
+ template <typename EEnum, typename TEnumRepresentationType = typename NDetail::TSelectEnumRepresentationType<EEnum>::TType>
+ class TEnumDescription: public NDetail::TMappedViewBase<EEnum, TEnumRepresentationType>, private TEnumDescriptionBase<TEnumRepresentationType> {
+ public:
+ using TBase = TEnumDescriptionBase<TEnumRepresentationType>;
+ using TCast = NDetail::TMappedViewBase<EEnum, TEnumRepresentationType>;
+ 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<EEnum, TString> EnumNames() const noexcept {
+ return {TBase::TypelessEnumNames()};
+ }
+
+ TMappedArrayView<EEnum> 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};
+ }
+ };
+}
diff --git a/tools/enum_parser/enum_serialization_runtime/ya.make b/tools/enum_parser/enum_serialization_runtime/ya.make
new file mode 100644
index 0000000000..c18e4aee10
--- /dev/null
+++ b/tools/enum_parser/enum_serialization_runtime/ya.make
@@ -0,0 +1,13 @@
+LIBRARY()
+
+OWNER(
+ g:util
+ swarmer
+)
+
+SRCS(
+ enum_runtime.cpp
+)
+
+
+END()