123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858 |
- #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
- }
|