aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/scheme/scimpl_private.cpp
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 /library/cpp/scheme/scimpl_private.cpp
downloadydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/scheme/scimpl_private.cpp')
-rw-r--r--library/cpp/scheme/scimpl_private.cpp74
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;
+ }
+ }
+}