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
namespace detail
{
void write_template_arguments(code_generator::output& output,
type_safe::array_ref<const cpp_template_argument> arguments);
void write_template_arguments(
code_generator::output& output,
type_safe::optional<type_safe::array_ref<const cpp_template_argument>> arguments);
} // namespace detail
} // namespace cppast

View file

@ -140,12 +140,15 @@ namespace cppast
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`.
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 =
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());
}

View file

@ -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<const cpp_template_argument> arguments)
void detail::write_template_arguments(
code_generator::output& output,
type_safe::optional<type_safe::array_ref<const cpp_template_argument>> 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(">");
}

View file

@ -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:
{