diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/scheme/scimpl.h | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/scheme/scimpl.h')
-rw-r--r-- | library/cpp/scheme/scimpl.h | 858 |
1 files changed, 858 insertions, 0 deletions
diff --git a/library/cpp/scheme/scimpl.h b/library/cpp/scheme/scimpl.h new file mode 100644 index 0000000000..4f68f16290 --- /dev/null +++ b/library/cpp/scheme/scimpl.h @@ -0,0 +1,858 @@ +#pragma once + +#include "scheme.h" + +#include <util/stream/output.h> + +namespace NSc { + struct TValue::TScCore : TAtomicRefCount<TScCore, TDestructor>, TNonCopyable { + TPoolPtr Pool; + double FloatNumber = 0; + i64 IntNumber = 0; + TStringBuf String; + TDict Dict; + TArray Array; + TValue::EType ValueType = TValue::EType::Null; + + TScCore(TPoolPtr& p) + : Pool(p) + , Dict(Pool->Get()) + , Array(Pool->Get()) + { + } + + bool IsNull() const { + return TValue::EType::Null == ValueType; + } + + bool IsBool() const { + return TValue::EType::Bool == ValueType; + } + + bool IsIntNumber() const { + return TValue::EType::IntNumber == ValueType || IsBool(); + } + + bool IsNumber() const { + return TValue::EType::FloatNumber == ValueType || IsIntNumber(); + } + + bool IsString() const { + return TValue::EType::String == ValueType; + } + + bool IsArray() const { + return TValue::EType::Array == ValueType; + } + + bool IsDict() const { + return TValue::EType::Dict == ValueType; + } + + bool HasChildren() const { + return GetDict().size() + GetArray().size(); + } + + void SetNull() { + ValueType = TValue::EType::Null; + } + + void SetArray() { + if (Y_LIKELY(IsArray())) { + return; + } + + ValueType = TValue::EType::Array; + Array.clear(); + } + + void SetDict() { + if (Y_LIKELY(IsDict())) { + return; + } + + ValueType = TValue::EType::Dict; + Dict.clear(); + } + + void SetNumber(double n) { + ValueType = TValue::EType::FloatNumber; + FloatNumber = n; + } + + void SetIntNumber(i64 n) { + ValueType = TValue::EType::IntNumber; + IntNumber = n; + } + + void SetBool(bool b) { + ValueType = TValue::EType::Bool; + IntNumber = b; + } + + void SetString(TStringBuf s) { + SetOwnedString(Pool->AppendBuf(s)); + } + + void SetOwnedString(TStringBuf s) { + ValueType = TValue::EType::String; + String = s; + } + + double& GetNumberMutable(double defaultnum) { + switch (ValueType) { + case TValue::EType::Bool: + SetNumber(bool(IntNumber)); + break; + case TValue::EType::IntNumber: + SetNumber(IntNumber); + break; + case TValue::EType::FloatNumber: + break; + default: + SetNumber(defaultnum); + break; + } + + return FloatNumber; + } + + i64& GetIntNumberMutable(i64 defaultnum) { + switch (ValueType) { + case TValue::EType::Bool: + SetIntNumber(bool(IntNumber)); + break; + case TValue::EType::IntNumber: + break; + case TValue::EType::FloatNumber: + SetIntNumber(FloatNumber); + break; + default: + SetIntNumber(defaultnum); + break; + } + + return IntNumber; + } + + void ClearArray() { + if (!IsArray()) { + return; + } + + Array.clear(); + } + + void ClearDict() { + if (!IsDict()) { + return; + } + + Dict.clear(); + } + + double GetNumber(double d = 0) const { + switch (ValueType) { + case TValue::EType::Bool: + return (bool)IntNumber; + case TValue::EType::IntNumber: + return IntNumber; + case TValue::EType::FloatNumber: + return FloatNumber; + default: + return d; + } + } + + i64 GetIntNumber(i64 n = 0) const { + switch (ValueType) { + case TValue::EType::Bool: + return (bool)IntNumber; + case TValue::EType::IntNumber: + return IntNumber; + case TValue::EType::FloatNumber: + return FloatNumber; + default: + return n; + } + } + + bool GetBool(bool b = false) const { + return GetIntNumber(b); + } + + TStringBuf GetString(TStringBuf s = TStringBuf()) const { + return IsString() ? String : s; + } + + const TArray& GetArray() const { + return IsArray() ? Array : TValue::DefaultArray(); + } + + TArray& GetArrayMutable() { + SetArray(); + return Array; + } + + TDict& GetDictMutable() { + SetDict(); + return Dict; + } + + const TDict& GetDict() const { + return IsDict() ? Dict : TValue::DefaultDict(); + } + + static void DoPush(TPoolPtr& p, TArray& a) { + a.push_back(TValue(p)); + a.back().CopyOnWrite = false; + } + + TValue& Push() { + SetArray(); + DoPush(Pool, Array); + return Array.back(); + } + + TValue Pop() { + if (!IsArray() || Array.empty()) { + return TValue::DefaultValue(); + } + + TValue v = Array.back(); + Array.pop_back(); + return v; + } + + const TValue& Get(size_t key) const { + return IsArray() && Array.size() > key ? Array[key] : TValue::DefaultValue(); + } + + TValue* GetNoAdd(size_t key) { + return IsArray() && Array.size() > key ? &Array[key] : nullptr; + } + + TValue& GetOrAdd(size_t key) { + SetArray(); + for (size_t i = Array.size(); i <= key; ++i) { + DoPush(Pool, Array); + } + + return Array[key]; + } + + TValue& Back() { + SetArray(); + + if (Array.empty()) { + DoPush(Pool, Array); + } + + return Array.back(); + } + + TValue& Insert(size_t key) { + SetArray(); + + if (Array.size() <= key) { + return GetOrAdd(key); + } else { + Array.insert(Array.begin() + key, TValue(Pool)); + Array[key].CopyOnWrite = false; + return Array[key]; + } + } + + TValue Delete(size_t key) { + if (!IsArray() || Array.size() <= key) { + return TValue::DefaultValue(); + } + + TValue v = Array[key]; + Array.erase(Array.begin() + key); + return v; + } + + const TValue& Get(TStringBuf key) const { + if (!IsDict()) { + return TValue::DefaultValue(); + } + + TDict::const_iterator it = Dict.find(key); + return it != Dict.end() ? it->second : TValue::DefaultValue(); + } + + TValue* GetNoAdd(TStringBuf key) { + if (!IsDict()) { + return nullptr; + } + + return Dict.FindPtr(key); + } + + TValue& Add(TStringBuf key) { + SetDict(); + TDict::iterator it = Dict.insert(std::make_pair(Pool->AppendBuf(key), TValue(Pool))).first; + it->second.CopyOnWrite = false; + return it->second; + } + + TValue& GetOrAdd(TStringBuf key) { + SetDict(); + TDict::insert_ctx ctx; + TDict::iterator it = Dict.find(key, ctx); + + if (it == Dict.end()) { + it = Dict.insert_direct(std::make_pair(Pool->AppendBuf(key), TValue(Pool)), ctx); + it->second.CopyOnWrite = false; + } + + return it->second; + } + + TValue Delete(TStringBuf key) { + if (!IsDict()) { + return TValue::DefaultValue(); + } + + TDict::iterator it = Dict.find(key); + + if (it == Dict.end()) { + return TValue::DefaultValue(); + } + + TValue v = it->second; + Dict.erase(key); + return v; + } + }; + + TValue::TScCore* TValue::NewCore(TPoolPtr& p) { + return new (p->Pool.Allocate<TScCore>()) TScCore(p); + } + + TValue::TValue() { + auto p = TPoolPtr(new NDefinitions::TPool); + TheCore = NewCore(p); + } + + TValue::TValue(double t) + : TValue() + { + SetNumber(t); + } + + TValue::TValue(unsigned long long t) + : TValue() + { + SetIntNumber(t); + } + + TValue::TValue(unsigned long t) + : TValue() + { + SetIntNumber(t); + } + + TValue::TValue(unsigned t) + : TValue() + { + SetIntNumber(t); + } + + TValue::TValue(long long t) + : TValue() + { + SetIntNumber(t); + } + + TValue::TValue(long t) + : TValue() + { + SetIntNumber(t); + } + + TValue::TValue(int t) + : TValue() + { + SetIntNumber(t); + } + + //TValue::TValue(bool t) + // : TValue() + //{ + // SetBool(t); + //} + + TValue::TValue(TStringBuf t) + : TValue() + { + SetString(t); + } + + TValue::TValue(const char* t) + : TValue() + { + SetString(t); + } + + TValue::TValue(TValue& v) + : TheCore(v.TheCore) + , CopyOnWrite(v.CopyOnWrite) + { + } + + TValue::TValue(const TValue& v) + : TheCore(v.TheCore) + , CopyOnWrite(true) + { + } + + TValue::TValue(TValue&& v) noexcept + : TheCore(std::move(v.TheCore)) + , CopyOnWrite(v.CopyOnWrite) + {} + + TValue::operator double() const { + return GetNumber(); + } + + TValue::operator float() const { + return GetNumber(); + } + + TValue::operator long long() const { + return GetIntNumber(); + } + + TValue::operator long() const { + return GetIntNumber(); + } + + TValue::operator int() const { + return GetIntNumber(); + } + + TValue::operator short() const { + return GetIntNumber(); + } + + TValue::operator char() const { + return GetIntNumber(); + } + + TValue::operator unsigned long long() const { + return GetIntNumber(); + } + + TValue::operator unsigned long() const { + return GetIntNumber(); + } + + TValue::operator unsigned() const { + return GetIntNumber(); + } + + TValue::operator unsigned short() const { + return GetIntNumber(); + } + + TValue::operator unsigned char() const { + return GetIntNumber(); + } + + TValue::operator signed char() const { + return GetIntNumber(); + } + + TValue::operator TStringBuf() const { + return GetString(); + } + + TValue::operator const ::NSc::TArray&() const { + return GetArray(); + } + + TValue::operator const ::NSc::TDict&() const { + return GetDict(); + } + + TValue& TValue::operator=(double t) { + return SetNumber(t); + } + + TValue& TValue::operator=(unsigned long long t) { + return SetIntNumber(t); + } + + TValue& TValue::operator=(unsigned long t) { + return SetIntNumber(t); + } + + TValue& TValue::operator=(unsigned t) { + return SetIntNumber(t); + } + + TValue& TValue::operator=(long long t) { + return SetIntNumber(t); + } + + TValue& TValue::operator=(long t) { + return SetIntNumber(t); + } + + TValue& TValue::operator=(int t) { + return SetIntNumber(t); + } + + //TValue& TValue::operator=(bool t) { + // return SetBool(t); + //} + + TValue& TValue::operator=(TStringBuf t) { + return SetString(t); + } + + TValue& TValue::operator=(const char* t) { + return SetString(t); + } + + TValue& TValue::operator=(TValue& v) & { + if (!Same(*this, v)) { + //Extend TheCore lifetime not to trigger possible v deletion via parent-child chain + auto tmpCore = TheCore; + TheCore = v.TheCore; + CopyOnWrite = v.CopyOnWrite; + } + return *this; + } + + TValue& TValue::operator=(const TValue& v) & { + if (!Same(*this, v)) { + //Extend TheCore lifetime not to trigger possible v deletion via parent-child chain + auto tmpCore = TheCore; + TheCore = v.TheCore; + CopyOnWrite = true; + } + return *this; + } + + TValue& TValue::operator=(TValue&& v) & noexcept { + if (!Same(*this, v)) { + //Extend TheCore lifetime not to trigger possible v deletion via parent-child chain + auto tmpCore = TheCore; + TheCore = std::move(v.TheCore); + CopyOnWrite = v.CopyOnWrite; + } + return *this; + } + + bool TValue::Has(size_t idx) const { + return IsArray() && GetArray().size() > idx; + } + + bool TValue::Has(TStringBuf s) const { + return GetDict().contains(s); + } + + TValue& TValue::GetOrAddUnsafe(size_t idx) { + return CoreMutable().GetOrAdd(idx); + } + + TValue& TValue::GetOrAdd(TStringBuf idx) { + return CoreMutable().GetOrAdd(idx); + } + + const TValue& TValue::Get(size_t idx) const { + return Core().Get(idx); + } + + TValue* TValue::GetNoAdd(size_t idx) { + return CoreMutable().GetNoAdd(idx); + } + + const TValue& TValue::Get(TStringBuf idx) const { + return Core().Get(idx); + } + + TValue* TValue::GetNoAdd(TStringBuf key) { + return CoreMutable().GetNoAdd(key); + } + + TValue& TValue::Back() { + return CoreMutable().Back(); + } + + const TValue& TValue::Back() const { + const TArray& arr = GetArray(); + return arr.empty() ? DefaultValue() : arr.back(); + } + + TValue TValue::Delete(size_t idx) { + return CoreMutable().Delete(idx); + } + + TValue TValue::Delete(TStringBuf idx) { + return CoreMutable().Delete(idx); + } + + TValue& TValue::AddAll(std::initializer_list<std::pair<TStringBuf, TValue>> t) { + for (const auto& el : t) { + Add(el.first) = el.second; + } + return *this; + } + + TValue& TValue::InsertUnsafe(size_t idx) { + return CoreMutable().Insert(idx); + } + + template <class TIt> + TValue& TValue::AppendAll(TIt begin, TIt end) { + GetArrayMutable().AppendAll(begin, end); + return *this; + } + + template <class TColl> + TValue& TValue::AppendAll(TColl&& coll) { + return AppendAll(std::begin(coll), std::end(coll)); + } + + TValue& TValue::AppendAll(std::initializer_list<TValue> coll) { + return AppendAll(coll.begin(), coll.end()); + } + + TValue& TValue::Push() { + return CoreMutable().Push(); + } + + TValue TValue::Pop() { + return CoreMutable().Pop(); + } + + TValue::EType TValue::GetType() const { + return Core().ValueType; + } + + bool TValue::IsNull() const { + return Core().IsNull(); + } + + bool TValue::IsNumber() const { + return Core().IsNumber(); + } + + bool TValue::IsIntNumber() const { + return Core().IsIntNumber(); + } + + bool TValue::IsBool() const { + return Core().IsBool(); + } + + bool TValue::IsString() const { + return Core().IsString(); + } + + bool TValue::IsArray() const { + return Core().IsArray(); + } + + bool TValue::IsDict() const { + return Core().IsDict(); + } + + TValue& TValue::SetNumber(double i) { + CoreMutableForSet().SetNumber(i); + return *this; + } + + TValue& TValue::SetIntNumber(i64 n) { + CoreMutableForSet().SetIntNumber(n); + return *this; + } + + TValue& TValue::SetBool(bool val) { + CoreMutableForSet().SetBool(val); + return *this; + } + + TValue& TValue::SetString(TStringBuf s) { + CoreMutableForSet().SetString(s); + return *this; + } + + double TValue::GetNumber(double d) const { + return Core().GetNumber(d); + } + + i64 TValue::GetIntNumber(i64 n) const { + return Core().GetIntNumber(n); + } + + bool TValue::GetBool(bool b) const { + return Core().GetBool(b); + } + + double& TValue::GetNumberMutable(double defaultval) { + return CoreMutable().GetNumberMutable(defaultval); + } + + i64& TValue::GetIntNumberMutable(i64 defaultval) { + return CoreMutable().GetIntNumberMutable(defaultval); + } + + TStringBuf TValue::GetString(TStringBuf d) const { + return Core().GetString(d); + } + + TValue& TValue::SetArray() { + CoreMutable().SetArray(); + return *this; + } + + TValue& TValue::ClearArray() { + CoreMutable().ClearArray(); + return *this; + } + + TValue& TValue::SetDict() { + CoreMutable().SetDict(); + return *this; + } + + TValue& TValue::ClearDict() { + CoreMutable().ClearDict(); + return *this; + } + + const TArray& TValue::GetArray() const { + return Core().GetArray(); + } + + TArray& TValue::GetArrayMutable() { + return CoreMutable().GetArrayMutable(); + } + + const TDict& TValue::GetDict() const { + return Core().GetDict(); + } + + TDict& TValue::GetDictMutable() { + return CoreMutable().GetDictMutable(); + } + + size_t TValue::StringSize() const { + return GetString().size(); + } + + size_t TValue::ArraySize() const { + return GetArray().size(); + } + + size_t TValue::DictSize() const { + return GetDict().size(); + } + + bool TValue::StringEmpty() const { + return GetString().empty(); + } + + bool TValue::ArrayEmpty() const { + return GetArray().empty(); + } + + bool TValue::DictEmpty() const { + return GetDict().empty(); + } + + TValue::TValue(TPoolPtr& p) + : TheCore(NewCore(p)) + { + } + + TValue::TScCore& TValue::CoreMutable() { + if (Y_UNLIKELY(!TheCore)) { + *this = TValue(); + } else if (Y_UNLIKELY(CopyOnWrite) && Y_UNLIKELY(TheCore->RefCount() > 1)) { + *this = Clone(); + } + + CopyOnWrite = false; + + return *TheCore; + } + + TValue::TScCore& TValue::CoreMutableForSet() { + if (Y_UNLIKELY(!TheCore) || Y_UNLIKELY(CopyOnWrite) && Y_UNLIKELY(TheCore->RefCount() > 1)) { + *this = TValue(); + } + + CopyOnWrite = false; + + return *TheCore; + } + + const TValue::TScCore& TValue::Core() const { + return TheCore ? *TheCore : DefaultCore(); + } + + TValue& TValue::SetNull() { + CoreMutableForSet().SetNull(); + return *this; + } + + namespace NPrivate { + int CompareStr(const NSc::TValue& a, TStringBuf b); + + int CompareInt(const NSc::TValue& a, i64 r); + + int CompareFloat(const NSc::TValue& a, double r); + } + + bool operator==(const TValue& a, const TValue& b); + + bool operator!=(const TValue& a, const TValue& b); + + bool operator<=(const TValue&, const TValue&) = delete; + bool operator>=(const TValue&, const TValue&) = delete; + bool operator<(const TValue&, const TValue&) = delete; + bool operator>(const TValue&, const TValue&) = delete; + +#define LIBRARY_SCHEME_DECLARE_TVALUE_OPS(T, Impl) \ + bool operator==(const NSc::TValue& a, T b); \ + bool operator==(T b, const NSc::TValue& a); \ + bool operator!=(const NSc::TValue& a, T b); \ + bool operator!=(T b, const NSc::TValue& a); \ + bool operator<=(const NSc::TValue& a, T b); \ + bool operator<=(T b, const NSc::TValue& a); \ + bool operator>=(const NSc::TValue& a, T b); \ + bool operator>=(T b, const NSc::TValue& a); \ + bool operator<(const NSc::TValue& a, T b); \ + bool operator<(T b, const NSc::TValue& a); \ + bool operator>(const NSc::TValue& a, T b); \ + bool operator>(T b, const NSc::TValue& a); + +#define LIBRARY_SCHEME_DECLARE_TVALUE_INT_OPS(T) \ + LIBRARY_SCHEME_DECLARE_TVALUE_OPS(signed T, CompareInt) \ + LIBRARY_SCHEME_DECLARE_TVALUE_OPS(unsigned T, CompareInt) + + //LIBRARY_SCHEME_DECLARE_TVALUE_OPS(bool, CompareInt) + LIBRARY_SCHEME_DECLARE_TVALUE_OPS(char, CompareInt) + LIBRARY_SCHEME_DECLARE_TVALUE_INT_OPS(char) + LIBRARY_SCHEME_DECLARE_TVALUE_INT_OPS(short) + LIBRARY_SCHEME_DECLARE_TVALUE_INT_OPS(int) + LIBRARY_SCHEME_DECLARE_TVALUE_INT_OPS(long) + LIBRARY_SCHEME_DECLARE_TVALUE_INT_OPS(long long) + + LIBRARY_SCHEME_DECLARE_TVALUE_OPS(float, CompareFloat) + LIBRARY_SCHEME_DECLARE_TVALUE_OPS(double, CompareFloat) + + LIBRARY_SCHEME_DECLARE_TVALUE_OPS(TStringBuf, CompareStr) + LIBRARY_SCHEME_DECLARE_TVALUE_OPS(const TString&, CompareStr) + LIBRARY_SCHEME_DECLARE_TVALUE_OPS(const char* const, CompareStr) + +#undef LIBRARY_SCHEME_DECLARE_TVALUE_OPS +#undef LIBRARY_SCHEME_DECLARE_TVALUE_INT_OPS + +} |