blob: 77f61e6bc492f722bb434fa83bb22428bbfebf37 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
#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;
};
}
}
|