Skip to content

Commit c557f18

Browse files
authored
Merge pull request #29 from wravery/ast_by_value
Define move semantics for peg::ast<> and return by value
2 parents ee264a6 + 5a0134c commit c557f18

File tree

7 files changed

+65
-43
lines changed

7 files changed

+65
-43
lines changed

GraphQLService.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1317,7 +1317,7 @@ void OperationDefinitionVisitor::visit(const peg::ast_node& operationDefinition)
13171317
}
13181318

13191319
SubscriptionData::SubscriptionData(std::shared_ptr<OperationData>&& data, std::unordered_map<SubscriptionName, std::vector<response::Value>>&& fieldNamesAndArgs,
1320-
std::unique_ptr<peg::ast<std::string>>&& query, std::string&& operationName, SubscriptionCallback&& callback,
1320+
peg::ast<std::string>&& query, std::string&& operationName, SubscriptionCallback&& callback,
13211321
const peg::ast_node& selection)
13221322
: data(std::move(data))
13231323
, fieldNamesAndArgs(std::move(fieldNamesAndArgs))
@@ -1363,7 +1363,7 @@ SubscriptionDefinitionVisitor::SubscriptionDefinitionVisitor(SubscriptionParams&
13631363

13641364
const peg::ast_node& SubscriptionDefinitionVisitor::getRoot() const
13651365
{
1366-
return *_params.query->root;
1366+
return *_params.query.root;
13671367
}
13681368

13691369
std::shared_ptr<SubscriptionData> SubscriptionDefinitionVisitor::getRegistration()
@@ -1645,7 +1645,7 @@ SubscriptionKey Request::subscribe(SubscriptionParams&& params, SubscriptionCall
16451645

16461646
FragmentDefinitionVisitor fragmentVisitor(params.variables);
16471647

1648-
peg::for_each_child<peg::fragment_definition>(*params.query->root,
1648+
peg::for_each_child<peg::fragment_definition>(*params.query.root,
16491649
[&fragmentVisitor](const peg::ast_node& child)
16501650
{
16511651
fragmentVisitor.visit(child);

GraphQLTree.cpp

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -561,38 +561,54 @@ struct ast_selector<input_object_type_extension>
561561
{
562562
};
563563

564-
std::unique_ptr<ast<std::string>> parseString(std::string&& input)
564+
template <>
565+
ast<std::string>::~ast()
565566
{
566-
std::unique_ptr<ast<std::string>> result(new ast<std::string> { std::move(input), nullptr });
567-
memory_input<> in(result->input.c_str(), result->input.size(), "GraphQL");
567+
// The default destructor gets inlined and may use a different allocator to free ast<>'s member
568+
// variables than the graphqlservice module used to allocate them. So even though this could be
569+
// omitted, declare it explicitly and define it in graphqlservice.
570+
}
568571

569-
result->root = parse_tree::parse<document, ast_node, ast_selector>(std::move(in));
572+
template <>
573+
ast<std::unique_ptr<file_input<>>>::~ast()
574+
{
575+
// The default destructor gets inlined and may use a different allocator to free ast<>'s member
576+
// variables than the graphqlservice module used to allocate them. So even though this could be
577+
// omitted, declare it explicitly and define it in graphqlservice.
578+
}
570579

571-
return result;
580+
template <>
581+
ast<const char*>::~ast()
582+
{
583+
// The default destructor gets inlined and may use a different allocator to free ast<>'s member
584+
// variables than the graphqlservice module used to allocate them. So even though this could be
585+
// omitted, declare it explicitly and define it in graphqlservice.
572586
}
573587

574-
std::unique_ptr<ast<std::unique_ptr<file_input<>>>> parseFile(const char* filename)
588+
ast<std::string> parseString(std::string&& input)
575589
{
576-
std::unique_ptr<ast<std::unique_ptr<file_input<>>>> result(new ast<std::unique_ptr<file_input<>>> {
577-
std::unique_ptr<file_input<>>(new file_input<>(std::string(filename))),
578-
nullptr
579-
});
590+
memory_input<> in(input.c_str(), input.size(), "GraphQL");
591+
592+
return { std::move(input), parse_tree::parse<document, ast_node, ast_selector>(std::move(in)) };
593+
}
580594

581-
result->root = parse_tree::parse<document, ast_node, ast_selector>(std::move(*result->input));
595+
ast<std::unique_ptr<file_input<>>> parseFile(const char* filename)
596+
{
597+
std::unique_ptr<file_input<>> in(new file_input<>(std::string(filename)));
598+
ast<std::unique_ptr<file_input<>>> result { std::move(in), nullptr };
599+
600+
result.root = parse_tree::parse<document, ast_node, ast_selector>(std::move(*result.input));
582601

583602
return result;
584603
}
585604

586605
} /* namespace peg */
587606

588-
std::unique_ptr<peg::ast<const char*>> operator "" _graphql(const char* text, size_t size)
607+
peg::ast<const char*> operator "" _graphql(const char* text, size_t size)
589608
{
590-
std::unique_ptr<peg::ast<const char*>> result(new peg::ast<const char*> { text, nullptr });
591609
peg::memory_input<> in(text, size, "GraphQL");
592610

593-
result->root = peg::parse_tree::parse<peg::document, peg::ast_node, peg::ast_selector>(std::move(in));
594-
595-
return result;
611+
return { text, peg::parse_tree::parse<peg::document, peg::ast_node, peg::ast_selector>(std::move(in)) };
596612
}
597613

598614
} /* namespace graphql */

SchemaGenerator.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -135,12 +135,12 @@ Generator::Generator()
135135
INPUT_FIELD_DEFINITION
136136
})"_graphql;
137137

138-
if (!ast)
138+
if (!ast.root)
139139
{
140140
throw std::logic_error("Unable to parse the introspection schema, but there was no error message from the parser!");
141141
}
142142

143-
for (const auto& child : ast->root->children)
143+
for (const auto& child : ast.root->children)
144144
{
145145
visitDefinition(*child);
146146
}
@@ -158,12 +158,12 @@ Generator::Generator(std::string schemaFileName, std::string filenamePrefix, std
158158
{
159159
auto ast = peg::parseFile(schemaFileName.c_str());
160160

161-
if (!ast)
161+
if (!ast.root)
162162
{
163163
throw std::logic_error("Unable to parse the service schema, but there was no error message from the parser!");
164164
}
165165

166-
for (const auto& child : ast->root->children)
166+
for (const auto& child : ast.root->children)
167167
{
168168
visitDefinition(*child);
169169
}

include/graphqlservice/GraphQLService.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,7 @@ using TypeMap = std::unordered_map<std::string, std::shared_ptr<Object>>;
498498
struct SubscriptionParams
499499
{
500500
std::shared_ptr<RequestState> state;
501-
std::unique_ptr<peg::ast<std::string>> query;
501+
peg::ast<std::string> query;
502502
std::string operationName;
503503
response::Value variables;
504504
};
@@ -534,12 +534,12 @@ using SubscriptionName = std::string;
534534
struct SubscriptionData : std::enable_shared_from_this<SubscriptionData>
535535
{
536536
explicit SubscriptionData(std::shared_ptr<OperationData>&& data, std::unordered_map<SubscriptionName, std::vector<response::Value>>&& fieldNamesAndArgs,
537-
std::unique_ptr<peg::ast<std::string>>&& query, std::string&& operationName, SubscriptionCallback&& callback,
537+
peg::ast<std::string>&& query, std::string&& operationName, SubscriptionCallback&& callback,
538538
const peg::ast_node& selection);
539539

540540
std::shared_ptr<OperationData> data;
541541
std::unordered_map<SubscriptionName, std::vector<response::Value>> fieldNamesAndArgs;
542-
std::unique_ptr<peg::ast<std::string>> query;
542+
peg::ast<std::string> query;
543543
std::string operationName;
544544
SubscriptionCallback callback;
545545
const peg::ast_node& selection;

include/graphqlservice/GraphQLTree.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,22 @@ struct ast_node
2626
template <typename _Input>
2727
struct ast
2828
{
29+
ast() = default;
30+
ast(ast&& other) = default;
31+
~ast();
32+
33+
ast& operator=(ast&& other) = default;
34+
2935
_Input input;
3036
std::unique_ptr<ast_node> root;
3137
};
3238

33-
std::unique_ptr<ast<std::string>> parseString(std::string&& input);
34-
std::unique_ptr<ast<std::unique_ptr<file_input<>>>> parseFile(const char* filename);
39+
ast<std::string> parseString(std::string&& input);
40+
ast<std::unique_ptr<file_input<>>> parseFile(const char* filename);
3541

3642
} /* namespace peg */
3743

38-
std::unique_ptr<peg::ast<const char*>> operator "" _graphql(const char* text, size_t size);
44+
peg::ast<const char*> operator "" _graphql(const char* text, size_t size);
3945

4046
} /* namespace graphql */
4147
} /* namespace facebook */

test_today.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,13 @@ int main(int argc, char** argv)
5959
try
6060
{
6161
const peg::ast_node* ast = nullptr;
62-
std::unique_ptr<peg::ast<std::string>> ast_input;
63-
std::unique_ptr<peg::ast<std::unique_ptr<peg::file_input<>>>> ast_file;
62+
peg::ast<std::string> ast_input;
63+
peg::ast<std::unique_ptr<peg::file_input<>>> ast_file;
6464

6565
if (argc > 1)
6666
{
6767
ast_file = peg::parseFile(argv[1]);
68-
ast = ast_file->root.get();
68+
ast = ast_file.root.get();
6969
}
7070
else
7171
{
@@ -78,7 +78,7 @@ int main(int argc, char** argv)
7878
}
7979

8080
ast_input = peg::parseString(std::move(input));
81-
ast = ast_input->root.get();
81+
ast = ast_input.root.get();
8282
}
8383

8484
if (!ast)

tests.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ TEST_F(TodayServiceCase, QueryEverything)
126126
})"_graphql;
127127
response::Value variables(response::Type::Map);
128128
auto state = std::make_shared<today::RequestState>(1);
129-
auto result = _service->resolve(state, *ast->root, "Everything", std::move(variables)).get();
129+
auto result = _service->resolve(state, *ast.root, "Everything", std::move(variables)).get();
130130
EXPECT_EQ(size_t(1), _getAppointmentsCount) << "today service lazy loads the appointments and caches the result";
131131
EXPECT_EQ(size_t(1), _getTasksCount) << "today service lazy loads the tasks and caches the result";
132132
EXPECT_EQ(size_t(1), _getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result";
@@ -198,7 +198,7 @@ TEST_F(TodayServiceCase, QueryAppointments)
198198
})"_graphql;
199199
response::Value variables(response::Type::Map);
200200
auto state = std::make_shared<today::RequestState>(2);
201-
auto result = _service->resolve(state, *ast->root, "", std::move(variables)).get();
201+
auto result = _service->resolve(state, *ast.root, "", std::move(variables)).get();
202202
EXPECT_EQ(size_t(1), _getAppointmentsCount) << "today service lazy loads the appointments and caches the result";
203203
EXPECT_GE(size_t(1), _getTasksCount) << "today service lazy loads the tasks and caches the result";
204204
EXPECT_GE(size_t(1), _getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result";
@@ -250,7 +250,7 @@ TEST_F(TodayServiceCase, QueryTasks)
250250
})gql"_graphql;
251251
response::Value variables(response::Type::Map);
252252
auto state = std::make_shared<today::RequestState>(3);
253-
auto result = _service->resolve(state, *ast->root, "", std::move(variables)).get();
253+
auto result = _service->resolve(state, *ast.root, "", std::move(variables)).get();
254254
EXPECT_GE(size_t(1), _getAppointmentsCount) << "today service lazy loads the appointments and caches the result";
255255
EXPECT_EQ(size_t(1), _getTasksCount) << "today service lazy loads the tasks and caches the result";
256256
EXPECT_GE(size_t(1), _getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result";
@@ -301,7 +301,7 @@ TEST_F(TodayServiceCase, QueryUnreadCounts)
301301
})"_graphql;
302302
response::Value variables(response::Type::Map);
303303
auto state = std::make_shared<today::RequestState>(4);
304-
auto result = _service->resolve(state, *ast->root, "", std::move(variables)).get();
304+
auto result = _service->resolve(state, *ast.root, "", std::move(variables)).get();
305305
EXPECT_GE(size_t(1), _getAppointmentsCount) << "today service lazy loads the appointments and caches the result";
306306
EXPECT_GE(size_t(1), _getTasksCount) << "today service lazy loads the tasks and caches the result";
307307
EXPECT_EQ(size_t(1), _getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result";
@@ -351,7 +351,7 @@ TEST_F(TodayServiceCase, MutateCompleteTask)
351351
})"_graphql;
352352
response::Value variables(response::Type::Map);
353353
auto state = std::make_shared<today::RequestState>(5);
354-
auto result = _service->resolve(state, *ast->root, "", std::move(variables)).get();
354+
auto result = _service->resolve(state, *ast.root, "", std::move(variables)).get();
355355

356356
try
357357
{
@@ -509,7 +509,7 @@ TEST_F(TodayServiceCase, Introspection)
509509
})"_graphql;
510510
response::Value variables(response::Type::Map);
511511
auto state = std::make_shared<today::RequestState>(8);
512-
auto result = _service->resolve(state, *ast->root, "", std::move(variables)).get();
512+
auto result = _service->resolve(state, *ast.root, "", std::move(variables)).get();
513513

514514
try
515515
{
@@ -571,7 +571,7 @@ TEST_F(TodayServiceCase, SkipDirective)
571571
})"_graphql;
572572
response::Value variables(response::Type::Map);
573573
auto state = std::make_shared<today::RequestState>(9);
574-
auto result = _service->resolve(state, *ast->root, "", std::move(variables)).get();
574+
auto result = _service->resolve(state, *ast.root, "", std::move(variables)).get();
575575

576576
try
577577
{
@@ -633,7 +633,7 @@ TEST_F(TodayServiceCase, IncludeDirective)
633633
})"_graphql;
634634
response::Value variables(response::Type::Map);
635635
auto state = std::make_shared<today::RequestState>(10);
636-
auto result = _service->resolve(state, *ast->root, "", std::move(variables)).get();
636+
auto result = _service->resolve(state, *ast.root, "", std::move(variables)).get();
637637

638638
try
639639
{
@@ -690,7 +690,7 @@ TEST_F(TodayServiceCase, NestedFragmentDirectives)
690690
})"_graphql;
691691
response::Value variables(response::Type::Map);
692692
auto state = std::make_shared<today::RequestState>(11);
693-
auto result = _service->resolve(state, *ast->root, "", std::move(variables)).get();
693+
auto result = _service->resolve(state, *ast.root, "", std::move(variables)).get();
694694

695695
try
696696
{
@@ -798,7 +798,7 @@ TEST_F(TodayServiceCase, QueryAppointmentsById)
798798
response::Value variables(response::Type::Map);
799799
variables.emplace_back("appointmentId", response::Value(std::string("ZmFrZUFwcG9pbnRtZW50SWQ=")));
800800
auto state = std::make_shared<today::RequestState>(12);
801-
auto result = _service->resolve(state, *ast->root, "", std::move(variables)).get();
801+
auto result = _service->resolve(state, *ast.root, "", std::move(variables)).get();
802802
EXPECT_EQ(size_t(1), _getAppointmentsCount) << "today service lazy loads the appointments and caches the result";
803803
EXPECT_GE(size_t(1), _getTasksCount) << "today service lazy loads the tasks and caches the result";
804804
EXPECT_GE(size_t(1), _getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result";

0 commit comments

Comments
 (0)