Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
stenzek
GitHub Repository: stenzek/duckstation
Path: blob/master/dep/rapidyaml/include/c4/yml/detail/checks.hpp
4270 views
1
#ifndef C4_YML_DETAIL_CHECKS_HPP_
2
#define C4_YML_DETAIL_CHECKS_HPP_
3
4
#include "c4/yml/tree.hpp"
5
6
#ifdef __clang__
7
# pragma clang diagnostic push
8
#elif defined(__GNUC__)
9
# pragma GCC diagnostic push
10
# pragma GCC diagnostic ignored "-Wtype-limits" // error: comparison of unsigned expression >= 0 is always true
11
#elif defined(_MSC_VER)
12
# pragma warning(push)
13
# pragma warning(disable: 4296/*expression is always 'boolean_value'*/)
14
#endif
15
16
namespace c4 {
17
namespace yml {
18
19
20
void check_invariants(Tree const& t, size_t node=NONE);
21
void check_free_list(Tree const& t);
22
void check_arena(Tree const& t);
23
24
25
//-----------------------------------------------------------------------------
26
//-----------------------------------------------------------------------------
27
//-----------------------------------------------------------------------------
28
29
inline void check_invariants(Tree const& t, size_t node)
30
{
31
if(node == NONE)
32
{
33
if(t.size() == 0) return;
34
node = t.root_id();
35
}
36
37
auto const& n = *t._p(node);
38
#ifdef RYML_DBG
39
if(n.m_first_child != NONE || n.m_last_child != NONE)
40
{
41
printf("check(%zu): fc=%zu lc=%zu\n", node, n.m_first_child, n.m_last_child);
42
}
43
else
44
{
45
printf("check(%zu)\n", node);
46
}
47
#endif
48
49
C4_CHECK(n.m_parent != node);
50
if(n.m_parent == NONE)
51
{
52
C4_CHECK(t.is_root(node));
53
}
54
else //if(n.m_parent != NONE)
55
{
56
C4_CHECK(t.has_child(n.m_parent, node));
57
58
auto const& p = *t._p(n.m_parent);
59
if(n.m_prev_sibling == NONE)
60
{
61
C4_CHECK(p.m_first_child == node);
62
C4_CHECK(t.first_sibling(node) == node);
63
}
64
else
65
{
66
C4_CHECK(p.m_first_child != node);
67
C4_CHECK(t.first_sibling(node) != node);
68
}
69
70
if(n.m_next_sibling == NONE)
71
{
72
C4_CHECK(p.m_last_child == node);
73
C4_CHECK(t.last_sibling(node) == node);
74
}
75
else
76
{
77
C4_CHECK(p.m_last_child != node);
78
C4_CHECK(t.last_sibling(node) != node);
79
}
80
}
81
82
C4_CHECK(n.m_first_child != node);
83
C4_CHECK(n.m_last_child != node);
84
if(n.m_first_child != NONE || n.m_last_child != NONE)
85
{
86
C4_CHECK(n.m_first_child != NONE);
87
C4_CHECK(n.m_last_child != NONE);
88
}
89
90
C4_CHECK(n.m_prev_sibling != node);
91
C4_CHECK(n.m_next_sibling != node);
92
if(n.m_prev_sibling != NONE)
93
{
94
C4_CHECK(t._p(n.m_prev_sibling)->m_next_sibling == node);
95
C4_CHECK(t._p(n.m_prev_sibling)->m_prev_sibling != node);
96
}
97
if(n.m_next_sibling != NONE)
98
{
99
C4_CHECK(t._p(n.m_next_sibling)->m_prev_sibling == node);
100
C4_CHECK(t._p(n.m_next_sibling)->m_next_sibling != node);
101
}
102
103
size_t count = 0;
104
for(size_t i = n.m_first_child; i != NONE; i = t.next_sibling(i))
105
{
106
#ifdef RYML_DBG
107
printf("check(%zu): descend to child[%zu]=%zu\n", node, count, i);
108
#endif
109
auto const& ch = *t._p(i);
110
C4_CHECK(ch.m_parent == node);
111
C4_CHECK(ch.m_next_sibling != i);
112
++count;
113
}
114
C4_CHECK(count == t.num_children(node));
115
116
if(n.m_prev_sibling == NONE && n.m_next_sibling == NONE)
117
{
118
if(n.m_parent != NONE)
119
{
120
C4_CHECK(t.num_children(n.m_parent) == 1);
121
C4_CHECK(t.num_siblings(node) == 1);
122
}
123
}
124
125
if(node == t.root_id())
126
{
127
C4_CHECK(t.size() == t.m_size);
128
C4_CHECK(t.capacity() == t.m_cap);
129
C4_CHECK(t.m_cap == t.m_size + t.slack());
130
check_free_list(t);
131
check_arena(t);
132
}
133
134
for(size_t i = t.first_child(node); i != NONE; i = t.next_sibling(i))
135
{
136
check_invariants(t, i);
137
}
138
}
139
140
141
//-----------------------------------------------------------------------------
142
//-----------------------------------------------------------------------------
143
//-----------------------------------------------------------------------------
144
145
inline void check_free_list(Tree const& t)
146
{
147
if(t.m_free_head == NONE)
148
{
149
C4_CHECK(t.m_free_tail == t.m_free_head);
150
return;
151
}
152
153
C4_CHECK(t.m_free_head >= 0 && t.m_free_head < t.m_cap);
154
C4_CHECK(t.m_free_tail >= 0 && t.m_free_tail < t.m_cap);
155
156
auto const& head = *t._p(t.m_free_head);
157
//auto const& tail = *t._p(t.m_free_tail);
158
159
//C4_CHECK(head.m_prev_sibling == NONE);
160
//C4_CHECK(tail.m_next_sibling == NONE);
161
162
size_t count = 0;
163
for(size_t i = t.m_free_head, prev = NONE; i != NONE; i = t._p(i)->m_next_sibling)
164
{
165
auto const& elm = *t._p(i);
166
if(&elm != &head)
167
{
168
C4_CHECK(elm.m_prev_sibling == prev);
169
}
170
prev = i;
171
++count;
172
}
173
C4_CHECK(count == t.slack());
174
}
175
176
177
//-----------------------------------------------------------------------------
178
//-----------------------------------------------------------------------------
179
//-----------------------------------------------------------------------------
180
181
inline void check_arena(Tree const& t)
182
{
183
C4_CHECK(t.m_arena.len == 0 || (t.m_arena_pos >= 0 && t.m_arena_pos <= t.m_arena.len));
184
C4_CHECK(t.arena_size() == t.m_arena_pos);
185
C4_CHECK(t.arena_slack() + t.m_arena_pos == t.m_arena.len);
186
}
187
188
189
} /* namespace yml */
190
} /* namespace c4 */
191
192
#ifdef __clang__
193
# pragma clang diagnostic pop
194
#elif defined(__GNUC__)
195
# pragma GCC diagnostic pop
196
#elif defined(_MSC_VER)
197
# pragma warning(pop)
198
#endif
199
200
#endif /* C4_YML_DETAIL_CHECKS_HPP_ */
201
202