Fix empty arguments to template instantiation

This commit is contained in:
Jonathan Müller 2017-06-23 07:34:22 +02:00
commit e355e7a653
4 changed files with 45 additions and 32 deletions

View file

@ -482,8 +482,9 @@ namespace cppast
/// \exclude /// \exclude
namespace detail namespace detail
{ {
void write_template_arguments(code_generator::output& output, void write_template_arguments(
type_safe::array_ref<const cpp_template_argument> arguments); code_generator::output& output,
type_safe::optional<type_safe::array_ref<const cpp_template_argument>> arguments);
} // namespace detail } // namespace detail
} // namespace cppast } // namespace cppast

View file

@ -140,12 +140,15 @@ namespace cppast
type_safe::variant_type<std::vector<cpp_template_argument>>{}); type_safe::variant_type<std::vector<cpp_template_argument>>{});
} }
/// \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`. /// \requires The arguments are exposed, i.e. `arguments_exposed()` returns `true`.
type_safe::array_ref<const cpp_template_argument> arguments() const noexcept type_safe::optional<type_safe::array_ref<const cpp_template_argument>> arguments() const
noexcept
{ {
auto& vec = auto& vec =
arguments_.value(type_safe::variant_type<std::vector<cpp_template_argument>>{}); arguments_.value(type_safe::variant_type<std::vector<cpp_template_argument>>{});
if (vec.empty())
return type_safe::nullopt;
return type_safe::ref(vec.data(), vec.size()); return type_safe::ref(vec.data(), vec.size());
} }

View file

@ -1035,29 +1035,34 @@ bool cppast::generate_code(code_generator& generator, const cpp_entity& e)
return false; return false;
} }
void detail::write_template_arguments(code_generator::output& output, void detail::write_template_arguments(
type_safe::array_ref<const cpp_template_argument> arguments) code_generator::output& output,
type_safe::optional<type_safe::array_ref<const cpp_template_argument>> arguments)
{ {
if (arguments.size() == 0u) if (!arguments)
return;
output << punctuation("<") << bracket_ws;
auto need_sep = false;
for (auto& arg : arguments)
{ {
if (need_sep) output << punctuation("<") << punctuation(">");
output << comma; }
else else
need_sep = true; {
output << punctuation("<") << bracket_ws;
if (auto type = arg.type()) auto need_sep = false;
detail::write_type(output, type.value(), ""); for (auto& arg : arguments.value())
else if (auto expr = arg.expression()) {
detail::write_expression(output, expr.value()); if (need_sep)
else if (auto templ = arg.template_ref()) output << comma;
output << templ.value(); else
else need_sep = true;
DEBUG_UNREACHABLE(detail::assert_handler{});
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(">");
} }

View file

@ -149,11 +149,15 @@ bool equal_types(const cpp_entity_index& idx, const cpp_type& parsed, const cpp_
return false; return false;
else if (!inst_parsed.arguments_exposed()) else if (!inst_parsed.arguments_exposed())
return inst_parsed.unexposed_arguments() == inst_synthesized.unexposed_arguments(); 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_a = inst_parsed.arguments().value().begin();
auto iter_b = inst_synthesized.arguments().begin(); auto iter_b = inst_synthesized.arguments().value().begin();
while (iter_a != inst_parsed.arguments().end() while (iter_a != inst_parsed.arguments().value().end()
&& iter_b != inst_synthesized.arguments().end()) && iter_b != inst_synthesized.arguments().value().end())
{ {
if (iter_a->type().has_value() && iter_b->type().has_value()) 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_a;
++iter_b; ++iter_b;
} }
return iter_a == inst_parsed.arguments().end() return iter_a == inst_parsed.arguments().value().end()
&& iter_b == inst_synthesized.arguments().end(); && iter_b == inst_synthesized.arguments().value().end();
} }
case cpp_type_kind::dependent_t: case cpp_type_kind::dependent_t:
{ {