#pragma once #include "scheme.h" #include namespace NSc { namespace NImpl { template static inline TContext& GetTlsInstance() { return *FastTlsSingleton(); } template class TContextGuard : TNonCopyable { using TElement = typename TContext::TElement; using TTarget = typename TContext::TTarget; using TVectorType = TVector; public: TContextGuard(TContext& ctx, TTarget& target) : Ctx(ctx) , Active(TContext::Needed(target)) { if (Active) { Begin = Ctx.Vector.size(); Ok = Ctx.Process(target); End = Ctx.Vector.size(); } } ~TContextGuard() noexcept { if (Active) { Ctx.Vector.resize(Begin); } } const TVectorType& GetVector() const { return Ctx.Vector; } using const_iterator = size_t; size_t begin() const { return Begin; } size_t end() const { return End; } bool Ok = true; private: TContext& Ctx; size_t Begin = 0; size_t End = 0; bool Active = false; }; template class TBasicContext { public: using TElement = TElem; using TTarget = TTgt; TBasicContext() { Vector.reserve(64); } TVector Vector; }; class TKeySortContext: public TBasicContext { public: using TGuard = TContextGuard; bool Process(const TDict& self); static bool Needed(const TDict& self) { return self.size(); } }; class TSelfOverrideContext: public TBasicContext { public: using TGuard = TContextGuard; bool Process(TValue::TScCore& self); static bool Needed(const TValue::TScCore& self) { return self.HasChildren(); } }; class TSelfLoopContext: public TBasicContext { public: enum class EMode { Assert, Throw, Abort, Stderr }; using TGuard = TContextGuard; bool Process(const TValue::TScCore& self); static bool Needed(const TValue::TScCore& self) { return self.HasChildren(); } public: EMode ReportingMode = EMode::Assert; }; } }