22
22
#include < memory>
23
23
#include < variant>
24
24
#include < iostream>
25
+ #include < optional>
25
26
26
27
27
28
namespace cpp2 {
@@ -682,18 +683,21 @@ struct unqualified_id_node
682
683
std::unique_ptr<type_id_node>
683
684
> arg;
684
685
};
685
- std::vector<term> template_args;
686
+ std::optional<std:: vector<term> > template_args;
686
687
687
688
auto template_args_count ()
688
689
-> int
689
690
{
690
- return std::ssize (template_args);
691
+ if (template_args.has_value ())
692
+ return std::ssize (template_args.value ());
693
+ // else
694
+ return 0 ;
691
695
}
692
696
693
697
auto get_token () const
694
698
-> token const *
695
699
{
696
- if (template_args.empty ()) {
700
+ if (! template_args.has_value ()) {
697
701
assert (identifier);
698
702
return identifier;
699
703
}
@@ -718,13 +722,14 @@ struct unqualified_id_node
718
722
assert (identifier);
719
723
v.start (*identifier, depth+1 );
720
724
721
- if (! template_args.empty ()) {
725
+ if (template_args.has_value ()) {
722
726
// Inform the visitor that this is a template args list
723
727
v.start (template_args_tag{}, depth);
724
728
assert (open_angle != source_position{});
725
729
assert (close_angle != source_position{});
726
- assert (template_args.front ().comma == source_position{});
727
- for (auto & a : template_args) {
730
+ assert (template_args.value ().empty ()
731
+ || template_args.value ().front ().comma == source_position{});
732
+ for (auto & a : template_args.value ()) {
728
733
try_visit<expression>(a.arg , v, depth+1 );
729
734
try_visit<type_id >(a.arg , v, depth+1 );
730
735
}
@@ -925,9 +930,9 @@ auto unqualified_id_node::to_string() const
925
930
{
926
931
assert (identifier);
927
932
auto ret = identifier->to_string (true );
928
- if (! template_args.empty ()) {
933
+ if (template_args.has_value ()) {
929
934
auto separator = std::string{" <" };
930
- for (auto & t : template_args) {
935
+ for (auto & t : template_args. value () ) {
931
936
ret += separator;
932
937
assert (t.arg .index () != empty);
933
938
if (t.arg .index () == expression) {
@@ -4454,18 +4459,10 @@ class parser
4454
4459
// Remember current position, in case this < is isn't a template argument list
4455
4460
auto start_pos = pos;
4456
4461
4457
- // And since we'll do this in two places, factor it into a local function
4458
- auto back_out_template_arg_list = [&]{
4459
- // Aha, this wasn't a template argument list after all,
4460
- // so back out just that part and return the identifier
4461
- n->open_angle = source_position{};
4462
- n->template_args .clear ();
4463
- pos = start_pos;
4464
- };
4465
-
4466
4462
n->open_angle = curr ().position ();
4467
4463
next ();
4468
-
4464
+
4465
+ n->template_args .emplace ();
4469
4466
auto term = unqualified_id_node::term{};
4470
4467
4471
4468
do {
@@ -4477,10 +4474,9 @@ class parser
4477
4474
term.arg = std::move (i);
4478
4475
}
4479
4476
else {
4480
- back_out_template_arg_list ();
4481
- return n;
4477
+ break ;
4482
4478
}
4483
- n->template_args .push_back ( std::move (term) );
4479
+ n->template_args .value (). push_back ( std::move (term) );
4484
4480
}
4485
4481
// Use the lambda trick to jam in a "next" clause
4486
4482
while (
@@ -4492,7 +4488,11 @@ class parser
4492
4488
// next term.comma = curr().position();
4493
4489
4494
4490
if (curr ().type () != lexeme::Greater) {
4495
- back_out_template_arg_list ();
4491
+ // Aha, this wasn't a template argument list after all,
4492
+ // so back out just that part and return the identifier
4493
+ n->open_angle = source_position{};
4494
+ n->template_args .reset ();
4495
+ pos = start_pos;
4496
4496
return n;
4497
4497
}
4498
4498
n->close_angle = curr ().position ();
0 commit comments