11
11
#define TAO_PEGTL_NAMESPACE tao::graphqlpeg
12
12
13
13
#include < tao/pegtl.hpp>
14
+ #include < tao/pegtl/contrib/parse_tree.hpp>
14
15
15
16
#include < string>
16
17
#include < string_view>
@@ -22,27 +23,9 @@ namespace graphql::peg {
22
23
using namespace tao ::graphqlpeg;
23
24
namespace peginternal = tao::graphqlpeg::internal;
24
25
25
- class [[nodiscard]] ast_node
26
+ class [[nodiscard]] ast_node : public parse_tree::basic_node<ast_node>
26
27
{
27
28
public:
28
- // Must be default constructible
29
- ast_node () = default ;
30
-
31
- // Nodes are always owned/handled by a std::unique_ptr
32
- // and never copied or assigned...
33
- ast_node (const ast_node&) = delete ;
34
- ast_node (ast_node&&) = delete ;
35
- ast_node& operator =(const ast_node&) = delete ;
36
- ast_node& operator =(ast_node&&) = delete ;
37
-
38
- // Must be destructible
39
- ~ast_node () = default ;
40
-
41
- [[nodiscard]] GRAPHQLPEG_EXPORT bool is_root () const noexcept ;
42
- [[nodiscard]] GRAPHQLPEG_EXPORT position begin () const noexcept ;
43
- [[nodiscard]] GRAPHQLPEG_EXPORT std::string_view string_view () const noexcept ;
44
- [[nodiscard]] GRAPHQLPEG_EXPORT std::string string () const noexcept ;
45
- [[nodiscard]] GRAPHQLPEG_EXPORT bool has_content () const noexcept ;
46
29
GRAPHQLPEG_EXPORT void remove_content () noexcept ;
47
30
48
31
GRAPHQLPEG_EXPORT void unescaped_view (std::string_view unescaped) noexcept ;
@@ -55,31 +38,21 @@ class [[nodiscard]] ast_node
55
38
56
39
// The pointer comparison doesn't work with shared libraries where the parse tree is
57
40
// constructed in one module and consumed in another. So to optimize this comparison, check
58
- // the size first, then the hash (cached in a static local variable per specialization of
59
- // type_hash<U>()), then the pointer comparison with a full string compare as fallback.
60
- return _type.size () == u.size () && _type_hash == type_hash<U>()
61
- && (_type.data () == u.data () || _type == u);
41
+ // the size first, then the pointer (cached in a static local variable per specialization of
42
+ // type_name<U>()), then the hash (cached in a static local variable per specialization of
43
+ // type_hash<U>()) and a full string compare as fallback.
44
+ return _type_name.size () == u.size ()
45
+ && (_type_name.data () == u.data () || (_type_hash == type_hash<U>() && _type_name == u));
62
46
}
63
47
64
- // All non-root nodes receive a call to start() when
65
- // a match is attempted for Rule in a parsing run...
66
- template <typename ParseInput>
67
- void start (const ParseInput& in)
68
- {
69
- _begin = in.iterator ();
70
- }
48
+ using basic_node_t = parse_tree::basic_node<ast_node>;
71
49
72
- // ...and later a call to success() when the match succeeded...
73
50
template <typename Rule, typename ParseInput>
74
51
void success (const ParseInput& in)
75
52
{
76
- const char * end = in.iterator ().data ;
77
-
78
- _type = type_name<Rule>();
53
+ basic_node_t ::template success<Rule>(in);
54
+ _type_name = type_name<Rule>();
79
55
_type_hash = type_hash<Rule>();
80
- _source = in.source ();
81
- _content = { _begin.data , static_cast <size_t >(end - _begin.data ) };
82
- _unescaped.reset ();
83
56
}
84
57
85
58
using children_t = std::vector<std::unique_ptr<ast_node>>;
@@ -91,7 +64,9 @@ class [[nodiscard]] ast_node
91
64
[[nodiscard]] static std::string_view type_name () noexcept
92
65
{
93
66
// This is cached in a static local variable per-specialization, but each module may have
94
- // its own instance of the specialization and the local variable.
67
+ // its own instance of the specialization and the local variable. Within a single module,
68
+ // the pointer returned from std::string_view::data() should always be equal, which speeds
69
+ // up the string comparison in is_type.
95
70
static const std::string_view name { tao::graphqlpeg::demangle<U>() };
96
71
97
72
return name;
@@ -102,20 +77,17 @@ class [[nodiscard]] ast_node
102
77
{
103
78
// This is cached in a static local variable per-specialization, but each module may have
104
79
// its own instance of the specialization and the local variable.
105
- static const size_t hash = std::hash<std::string_view>() (type_name<U>());
80
+ static const size_t hash = std::hash<std::string_view> {} (type_name<U>());
106
81
107
82
return hash;
108
83
}
109
84
110
- std::string_view _source;
111
- peginternal::iterator _begin;
112
- std::string_view _type;
85
+ std::string_view _type_name;
113
86
size_t _type_hash = 0 ;
114
- std::string_view _content;
115
87
116
88
using unescaped_t = std::variant<std::string_view, std::string>;
117
89
118
- std::unique_ptr<unescaped_t > _unescaped;
90
+ mutable std::unique_ptr<unescaped_t > _unescaped;
119
91
};
120
92
121
93
template <class ParseInput >
0 commit comments