From e355e7a6538e4ba9f643805819840397e66de9b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20M=C3=BCller?= Date: Fri, 23 Jun 2017 07:34:22 +0200 Subject: [PATCH] Fix empty arguments to template instantiation --- include/cppast/code_generator.hpp | 5 ++-- include/cppast/cpp_template.hpp | 7 +++-- src/code_generator.cpp | 49 +++++++++++++++++-------------- test/cpp_type_alias.cpp | 16 ++++++---- 4 files changed, 45 insertions(+), 32 deletions(-) diff --git a/include/cppast/code_generator.hpp b/include/cppast/code_generator.hpp index ccf29d4..85abd35 100644 --- a/include/cppast/code_generator.hpp +++ b/include/cppast/code_generator.hpp @@ -482,8 +482,9 @@ namespace cppast /// \exclude namespace detail { - void write_template_arguments(code_generator::output& output, - type_safe::array_ref arguments); + void write_template_arguments( + code_generator::output& output, + type_safe::optional> arguments); } // namespace detail } // namespace cppast diff --git a/include/cppast/cpp_template.hpp b/include/cppast/cpp_template.hpp index c5155d6..31d5943 100644 --- a/include/cppast/cpp_template.hpp +++ b/include/cppast/cpp_template.hpp @@ -140,12 +140,15 @@ namespace cppast type_safe::variant_type>{}); } - /// \returns An iteratable object iterating over the [cppast::cpp_template_argument]()s. + /// \returns An array ref to the [cppast::cpp_template_argument](), if there are any. /// \requires The arguments are exposed, i.e. `arguments_exposed()` returns `true`. - type_safe::array_ref arguments() const noexcept + type_safe::optional> arguments() const + noexcept { auto& vec = arguments_.value(type_safe::variant_type>{}); + if (vec.empty()) + return type_safe::nullopt; return type_safe::ref(vec.data(), vec.size()); } diff --git a/src/code_generator.cpp b/src/code_generator.cpp index 91d36ad..6079194 100644 --- a/src/code_generator.cpp +++ b/src/code_generator.cpp @@ -1035,29 +1035,34 @@ bool cppast::generate_code(code_generator& generator, const cpp_entity& e) return false; } -void detail::write_template_arguments(code_generator::output& output, - type_safe::array_ref arguments) +void detail::write_template_arguments( + code_generator::output& output, + type_safe::optional> arguments) { - if (arguments.size() == 0u) - return; - - output << punctuation("<") << bracket_ws; - auto need_sep = false; - for (auto& arg : arguments) + if (!arguments) { - if (need_sep) - output << comma; - else - need_sep = true; - - if (auto type = arg.type()) - detail::write_type(output, type.value(), ""); - else if (auto expr = arg.expression()) - detail::write_expression(output, expr.value()); - else if (auto templ = arg.template_ref()) - output << templ.value(); - else - DEBUG_UNREACHABLE(detail::assert_handler{}); + output << punctuation("<") << punctuation(">"); + } + else + { + output << punctuation("<") << bracket_ws; + auto need_sep = false; + for (auto& arg : arguments.value()) + { + if (need_sep) + output << comma; + else + need_sep = true; + + if (auto type = arg.type()) + detail::write_type(output, type.value(), ""); + else if (auto expr = arg.expression()) + detail::write_expression(output, expr.value()); + else if (auto templ = arg.template_ref()) + output << templ.value(); + else + DEBUG_UNREACHABLE(detail::assert_handler{}); + } + output << bracket_ws << punctuation(">"); } - output << bracket_ws << punctuation(">"); } diff --git a/test/cpp_type_alias.cpp b/test/cpp_type_alias.cpp index 754a2cc..13d9b1b 100644 --- a/test/cpp_type_alias.cpp +++ b/test/cpp_type_alias.cpp @@ -149,11 +149,15 @@ bool equal_types(const cpp_entity_index& idx, const cpp_type& parsed, const cpp_ return false; else if (!inst_parsed.arguments_exposed()) return inst_parsed.unexposed_arguments() == inst_synthesized.unexposed_arguments(); + else if (inst_parsed.arguments().has_value() != inst_synthesized.arguments().has_value()) + return false; + else if (!inst_parsed.arguments().has_value()) + return true; - auto iter_a = inst_parsed.arguments().begin(); - auto iter_b = inst_synthesized.arguments().begin(); - while (iter_a != inst_parsed.arguments().end() - && iter_b != inst_synthesized.arguments().end()) + auto iter_a = inst_parsed.arguments().value().begin(); + auto iter_b = inst_synthesized.arguments().value().begin(); + while (iter_a != inst_parsed.arguments().value().end() + && iter_b != inst_synthesized.arguments().value().end()) { if (iter_a->type().has_value() && iter_b->type().has_value()) { @@ -175,8 +179,8 @@ bool equal_types(const cpp_entity_index& idx, const cpp_type& parsed, const cpp_ ++iter_a; ++iter_b; } - return iter_a == inst_parsed.arguments().end() - && iter_b == inst_synthesized.arguments().end(); + return iter_a == inst_parsed.arguments().value().end() + && iter_b == inst_synthesized.arguments().value().end(); } case cpp_type_kind::dependent_t: {