Skip to content

Commit 6910198

Browse files
committed
Simplify ast_node by inheriting parse_tree::basic_node
1 parent c4f4e12 commit 6910198

File tree

2 files changed

+23
-82
lines changed

2 files changed

+23
-82
lines changed

include/graphqlservice/internal/SyntaxTree.h

Lines changed: 16 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#define TAO_PEGTL_NAMESPACE tao::graphqlpeg
1212

1313
#include <tao/pegtl.hpp>
14+
#include <tao/pegtl/contrib/parse_tree.hpp>
1415

1516
#include <string>
1617
#include <string_view>
@@ -22,27 +23,9 @@ namespace graphql::peg {
2223
using namespace tao::graphqlpeg;
2324
namespace peginternal = tao::graphqlpeg::internal;
2425

25-
class [[nodiscard]] ast_node
26+
class [[nodiscard]] ast_node : public parse_tree::basic_node<ast_node>
2627
{
2728
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;
4629
GRAPHQLPEG_EXPORT void remove_content() noexcept;
4730

4831
GRAPHQLPEG_EXPORT void unescaped_view(std::string_view unescaped) noexcept;
@@ -55,31 +38,21 @@ class [[nodiscard]] ast_node
5538

5639
// The pointer comparison doesn't work with shared libraries where the parse tree is
5740
// 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));
6246
}
6347

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>;
7149

72-
// ...and later a call to success() when the match succeeded...
7350
template <typename Rule, typename ParseInput>
7451
void success(const ParseInput& in)
7552
{
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>();
7955
_type_hash = type_hash<Rule>();
80-
_source = in.source();
81-
_content = { _begin.data, static_cast<size_t>(end - _begin.data) };
82-
_unescaped.reset();
8356
}
8457

8558
using children_t = std::vector<std::unique_ptr<ast_node>>;
@@ -91,7 +64,9 @@ class [[nodiscard]] ast_node
9164
[[nodiscard]] static std::string_view type_name() noexcept
9265
{
9366
// 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.
9570
static const std::string_view name { tao::graphqlpeg::demangle<U>() };
9671

9772
return name;
@@ -102,20 +77,17 @@ class [[nodiscard]] ast_node
10277
{
10378
// This is cached in a static local variable per-specialization, but each module may have
10479
// 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>());
10681

10782
return hash;
10883
}
10984

110-
std::string_view _source;
111-
peginternal::iterator _begin;
112-
std::string_view _type;
85+
std::string_view _type_name;
11386
size_t _type_hash = 0;
114-
std::string_view _content;
11587

11688
using unescaped_t = std::variant<std::string_view, std::string>;
11789

118-
std::unique_ptr<unescaped_t> _unescaped;
90+
mutable std::unique_ptr<unescaped_t> _unescaped;
11991
};
12092

12193
template <class ParseInput>

src/SyntaxTree.cpp

Lines changed: 7 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
#include "graphqlservice/internal/Grammar.h"
77
#include "graphqlservice/internal/SyntaxTree.h"
88

9-
#include <tao/pegtl/contrib/parse_tree.hpp>
109
#include <tao/pegtl/contrib/unescape.hpp>
1110

1211
#include <functional>
@@ -22,26 +21,6 @@ using namespace std::literals;
2221
namespace graphql {
2322
namespace peg {
2423

25-
bool ast_node::is_root() const noexcept
26-
{
27-
return _type.empty();
28-
}
29-
30-
position ast_node::begin() const noexcept
31-
{
32-
return { _begin, _source };
33-
}
34-
35-
std::string_view ast_node::string_view() const noexcept
36-
{
37-
return _content;
38-
}
39-
40-
std::string ast_node::string() const noexcept
41-
{
42-
return std::string { string_view() };
43-
}
44-
4524
void ast_node::unescaped_view(std::string_view unescaped) noexcept
4625
{
4726
_unescaped = std::make_unique<unescaped_t>(unescaped);
@@ -131,8 +110,7 @@ std::string_view ast_node::unescaped_view() const
131110
}
132111
}
133112

134-
const_cast<ast_node*>(this)->_unescaped =
135-
std::make_unique<unescaped_t>(std::move(joined));
113+
_unescaped = std::make_unique<unescaped_t>(std::move(joined));
136114
}
137115
else if (children.size() > 1)
138116
{
@@ -150,13 +128,11 @@ std::string_view ast_node::unescaped_view() const
150128
joined.append(child->string_view());
151129
}
152130

153-
const_cast<ast_node*>(this)->_unescaped =
154-
std::make_unique<unescaped_t>(std::move(joined));
131+
_unescaped = std::make_unique<unescaped_t>(std::move(joined));
155132
}
156133
else if (!children.empty())
157134
{
158-
const_cast<ast_node*>(this)->_unescaped =
159-
std::make_unique<unescaped_t>(children.front()->string_view());
135+
_unescaped = std::make_unique<unescaped_t>(children.front()->string_view());
160136
}
161137
else if (has_content() && is_type<escaped_unicode>())
162138
{
@@ -167,13 +143,11 @@ std::string_view ast_node::unescaped_view() const
167143
utf8.reserve((content.size() + 1) / 2);
168144
unescape::unescape_j::apply(in, utf8);
169145

170-
const_cast<ast_node*>(this)->_unescaped =
171-
std::make_unique<unescaped_t>(std::move(utf8));
146+
_unescaped = std::make_unique<unescaped_t>(std::move(utf8));
172147
}
173148
else
174149
{
175-
const_cast<ast_node*>(this)->_unescaped =
176-
std::make_unique<unescaped_t>(std::string_view {});
150+
_unescaped = std::make_unique<unescaped_t>(std::string_view {});
177151
}
178152
}
179153

@@ -184,14 +158,9 @@ std::string_view ast_node::unescaped_view() const
184158
*_unescaped);
185159
}
186160

187-
bool ast_node::has_content() const noexcept
188-
{
189-
return !string_view().empty();
190-
}
191-
192161
void ast_node::remove_content() noexcept
193162
{
194-
_content = {};
163+
basic_node_t::remove_content();
195164
_unescaped.reset();
196165
}
197166

@@ -960,7 +929,7 @@ struct make_control<Selector>::state_handler<Rule, true, B> : ast_control<Rule>
960929
static void start(const ParseInput& in, ast_state& state)
961930
{
962931
state.emplace_back();
963-
state.back()->start(in);
932+
state.back()->template start<Rule>(in);
964933
}
965934

966935
template <typename ParseInput>

0 commit comments

Comments
 (0)