blob: b92badabde14c9d8c8f9aa53e8c00e52d241e631 (
plain) (
tree)
|
|
#pragma once
#include "scheme.h"
#include <util/thread/singleton.h>
namespace NSc {
namespace NImpl {
template <typename TContext>
static inline TContext& GetTlsInstance() {
return *FastTlsSingleton<TContext>();
}
template <typename TContext>
class TContextGuard : TNonCopyable {
using TElement = typename TContext::TElement;
using TTarget = typename TContext::TTarget;
using TVectorType = TVector<TElement>;
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 <typename TElem, typename TTgt>
class TBasicContext {
public:
using TElement = TElem;
using TTarget = TTgt;
TBasicContext() {
Vector.reserve(64);
}
TVector<TElement> Vector;
};
class TKeySortContext: public TBasicContext<TStringBuf, const TDict> {
public:
using TGuard = TContextGuard<TKeySortContext>;
bool Process(const TDict& self);
static bool Needed(const TDict& self) {
return self.size();
}
};
class TSelfOverrideContext: public TBasicContext<TValue, TValue::TScCore> {
public:
using TGuard = TContextGuard<TSelfOverrideContext>;
bool Process(TValue::TScCore& self);
static bool Needed(const TValue::TScCore& self) {
return self.HasChildren();
}
};
class TSelfLoopContext: public TBasicContext<const void*, const TValue::TScCore> {
public:
enum class EMode {
Assert, Throw, Abort, Stderr
};
using TGuard = TContextGuard<TSelfLoopContext>;
bool Process(const TValue::TScCore& self);
static bool Needed(const TValue::TScCore& self) {
return self.HasChildren();
}
public:
EMode ReportingMode = EMode::Assert;
};
}
}
|