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_private.cpp | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/scheme/scimpl_private.cpp')
-rw-r--r-- | library/cpp/scheme/scimpl_private.cpp | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/library/cpp/scheme/scimpl_private.cpp b/library/cpp/scheme/scimpl_private.cpp new file mode 100644 index 0000000000..024bf8cc3b --- /dev/null +++ b/library/cpp/scheme/scimpl_private.cpp @@ -0,0 +1,74 @@ +#include "scimpl_private.h" + +#include <util/generic/algorithm.h> +#include <utility> + +namespace NSc { + namespace NImpl { + struct TGetKey { + static inline TStringBuf Do(const TDict::value_type& v) { + return v.first; + } + }; + + struct TMoveValue { + static inline TValue&& Do(TDict::value_type& v) { + return std::move(v.second); + } + + static inline TValue&& Do(TArray::value_type& v) { + return std::move(v); + } + }; + + template <typename TAction, typename TElement, typename TColl> + static inline void PutToVector(TVector<TElement>& vector, TColl& coll) { + size_t i = vector.size(); + vector.resize(vector.size() + coll.size()); + + for (auto& item : coll) { + vector[i++] = TAction::Do(item); + } + } + + bool TKeySortContext::Process(const TDict& self) { + size_t oldSz = Vector.size(); + PutToVector<TGetKey>(Vector, self); + Sort(Vector.begin() + oldSz, Vector.end()); + return true; + } + + bool TSelfOverrideContext::Process(TValue::TScCore& self) { + if (self.GetDict().size()) { + PutToVector<TMoveValue>(Vector, self.Dict); + } else if (self.GetArray().size()) { + PutToVector<TMoveValue>(Vector, self.Array); + } + return true; + } + + bool TSelfLoopContext::Process(const TValue::TScCore& self) { + const bool ok = (Vector.end() == Find(Vector.begin(), Vector.end(), &self)); + + if (!ok) { + switch (ReportingMode) { + case EMode::Assert: + Y_ASSERT(false); // make sure the debug build sees this + break; + case EMode::Throw: + ythrow TSchemeException() << "REFERENCE LOOP DETECTED"; + case EMode::Abort: + Y_FAIL("REFERENCE LOOP DETECTED"); + break; + case EMode::Stderr: + Cerr << "REFERENCE LOOP DETECTED: " << JoinStrings(Vector.begin(), Vector.end(), ", ") + << " AND " << ToString((const void*)&self) << Endl; + break; + } + } + + Vector.push_back(&self); + return ok; + } + } +} |