in cppwinrt/code_writers.h [1602:1711]
static void write_produce_cleanup_param(writer& w, T const& param_signature, std::string_view const& param_name, bool out)
{
TypeSig const& signature = param_signature.Type();
bool clear{};
bool optional{};
bool zero{};
call(signature.Type(),
[&](ElementType type)
{
if (out && type == ElementType::Object)
{
optional = true;
}
else if (type == ElementType::String || type == ElementType::Object)
{
clear = true;
}
},
[&](coded_index<TypeDefOrRef> const& index)
{
assert(index.type() == TypeDefOrRef::TypeDef || index.type() == TypeDefOrRef::TypeRef);
TypeDef type;
if (index.type() == TypeDefOrRef::TypeDef)
{
type = index.TypeDef();
}
else if (index.type() == TypeDefOrRef::TypeRef)
{
type = find(index.TypeRef());
}
if (type)
{
auto category = get_category(type);
clear = category == category::class_type || category == category::interface_type || category == category::delegate_type;
zero = category == category::struct_type;
}
},
[&](GenericTypeIndex const&)
{
clear = true;
},
[](GenericMethodTypeIndex)
{
throw_invalid("Generic methods not supported.");
},
[&](GenericTypeInstSig const&)
{
clear = true;
});
if (signature.is_szarray())
{
if constexpr (std::is_same_v<RetTypeSig, T>)
{
clear = true;
}
else if (param_signature.ByRef())
{
clear = true;
}
else if (optional || clear)
{
clear = false;
zero = true;
}
}
if (clear)
{
auto format = R"( clear_abi(%);
)";
w.write(format, param_name);
}
else if (zero)
{
if (signature.is_szarray())
{
auto format = R"( zero_abi<%>(%, __%Size);
)";
w.write(format,
signature.Type(),
param_name,
param_name);
}
else
{
auto format = R"( zero_abi<%>(%);
)";
w.write(format,
signature.Type(),
param_name);
}
}
else if (optional)
{
auto format = R"( if (%) *% = nullptr;
winrt::Windows::Foundation::IInspectable winrt_impl_%;
)";
w.write(format, param_name, param_name, param_name);
}
}