rapidyaml 0.14.0
parse and emit YAML, and do it fast
Loading...
Searching...
No Matches
event_handler_stack.hpp
Go to the documentation of this file.
1#ifndef _C4_YML_EVENT_HANDLER_STACK_HPP_
2#define _C4_YML_EVENT_HANDLER_STACK_HPP_
3
4#ifndef _C4_YML_DETAIL_STACK_HPP_
5#include "c4/yml/detail/stack.hpp"
6#endif
7
8#ifndef _C4_YML_NODE_TYPE_HPP_
10#endif
11
12#ifndef _C4_YML_DETAIL_DBGPRINT_HPP_
13#include "c4/yml/detail/dbgprint.hpp"
14#endif
15
16#ifndef _C4_YML_PARSER_STATE_HPP_
18#endif
19
20#ifdef RYML_DBG
21#ifndef _C4_YML_DETAIL_PRINT_HPP_
22#include "c4/yml/detail/print.hpp"
23#endif
24#endif
25
26// NOLINTBEGIN(hicpp-signed-bitwise)
27
28namespace c4 {
29namespace yml {
30
31/** @addtogroup doc_event_handlers
32 * @{ */
33
34/** Use this class a base of implementations of event handler to
35 * simplify the stack logic. */
36template<class HandlerImpl, class HandlerState>
38{
39 static_assert(std::is_base_of<ParserState, HandlerState>::value,
40 "ParserState must be a base of HandlerState");
41
42 using state = HandlerState;
43
44public:
45
46 detail::stack<state> m_stack;
47 state *C4_RESTRICT m_curr; ///< current stack level: top of the stack. cached here for easier access.
48 state *C4_RESTRICT m_parent; ///< parent of the current stack level.
50
51protected:
52
53 EventHandlerStack() : m_stack(), m_curr(), m_parent(), m_src() {} // NOLINT
54 EventHandlerStack(Callbacks const& cb) : m_stack(cb), m_curr(), m_parent(), m_src() {} // NOLINT
55
56protected:
57
58 void _stack_start_parse(const char *filename, substr ymlsrc)
59 {
60 _RYML_ASSERT_BASIC_(m_stack.m_callbacks, m_curr != nullptr);
61 m_curr->start_parse(filename, m_curr->node_id);
62 m_src = ymlsrc;
63 }
64
66 {
67 }
68
69protected:
70
72 {
73 m_stack.clear();
74 m_stack.push({});
75 m_parent = nullptr;
76 m_curr = &m_stack.top();
77 }
78
80 {
81 m_stack.clear();
82 m_stack.push({}); // parent
83 m_stack.push({}); // node
84 m_parent = &m_stack.top(1);
85 m_curr = &m_stack.top();
86 }
87
89 {
90 m_stack.push_top();
91 m_parent = &m_stack.top(1); // don't use m_curr. watch out for relocations inside the prev push
92 m_curr = &m_stack.top();
93 m_curr->reset_after_push();
94 }
95
97 {
98 _RYML_ASSERT_BASIC_(m_stack.m_callbacks, m_parent);
99 _RYML_ASSERT_BASIC_(m_stack.m_callbacks, m_stack.size() > 1);
100 m_parent->reset_before_pop(*m_curr);
101 m_stack.pop();
102 m_parent = m_stack.size() > 1 ? &m_stack.top(1) : nullptr;
103 m_curr = &m_stack.top();
104 #ifdef RYML_DBG
105 if(m_parent)
106 _c4dbgpf("popped! top is now node={} (parent={})", m_curr->node_id, m_parent->node_id);
107 else
108 _c4dbgpf("popped! top is now node={} @ ROOT", m_curr->node_id);
109 #endif
110 }
111
112protected:
113
114 // undefined below
115 #define _has_any_(bits) (static_cast<HandlerImpl const* C4_RESTRICT>(this)->template _has_any__<bits>())
116
117 // FIXME. Not happy about where these functions are. They should
118 // be defined and called by the parser, passing the bool result to
119 // begin_doc()/end_doc() as well as begin_doc_expl()/end_doc_expl().
120
122 {
123 const bool is_root = (m_stack.size() == 1u);
124 return is_root && (m_curr->has_children || _has_any_(DOC|VAL|MAP|SEQ));
125 }
126
128 {
129 const bool is_root = (m_stack.size() == 1u);
130 return !is_root && _has_any_(DOC);
131 }
132
133 #undef _has_any_
134
135};
136
137/** @} */
138
139} // namespace yml
140} // namespace c4
141
142// NOLINTEND(hicpp-signed-bitwise)
143
144#endif /* _C4_YML_EVENT_HANDLER_STACK_HPP_ */
#define _has_any_(bits)
@ MAP
a map: a parent of KEYVAL/KEYSEQ/KEYMAP nodes
Definition node_type.hpp:39
@ VAL
a scalar: has a scalar (ie string) value, possibly empty. must be a leaf node, and cannot be MAP or S...
Definition node_type.hpp:38
@ SEQ
a seq: a parent of VAL/SEQ/MAP nodes
Definition node_type.hpp:40
@ DOC
a document
Definition node_type.hpp:41
basic_substring< char > substr
a mutable string view
Definition substr.hpp:2356
(Undefined by default) Use shorter error message from checks/asserts: do not show the check condition...
Definition common.cpp:14
A c-style callbacks class to customize behavior on errors or allocation.
Definition common.hpp:546
state * m_curr
current stack level: top of the stack. cached here for easier access.
EventHandlerStack(Callbacks const &cb)
void _stack_start_parse(const char *filename, substr ymlsrc)
detail::stack< state > m_stack
state * m_parent
parent of the current stack level.