Filter constructors for unions with multiple elements of the same type.

This commit is contained in:
asuessenbach 2021-07-28 09:13:25 +02:00
parent 8f211dc0ca
commit 6f067eecac
2 changed files with 63 additions and 26 deletions

View File

@ -6959,7 +6959,8 @@ void VulkanHppGenerator::checkEnumCorrectness( std::vector<RequireData> const &
check( !requireTypeIt->second.referencedIn.empty(), check( !requireTypeIt->second.referencedIn.empty(),
bitmaskIt->second.xmlLine, bitmaskIt->second.xmlLine,
"bitmask <" + bitmaskIt->first + ">, listed for <" + typeIt->second.referencedIn + "bitmask <" + bitmaskIt->first + ">, listed for <" + typeIt->second.referencedIn +
">, requires <" + bitmaskIt->second.requirements + "> which is not listed for any feature or extension!" ); ">, requires <" + bitmaskIt->second.requirements +
"> which is not listed for any feature or extension!" );
} }
} }
else else
@ -11063,6 +11064,22 @@ std::string VulkanHppGenerator::generateLenInitializer(
return initializer; return initializer;
} }
std::string VulkanHppGenerator::generateName( TypeInfo const & typeInfo ) const
{
std::string name = stripPrefix( typeInfo.type, "Vk" );
assert( typeInfo.prefix.find( '*' ) == std::string::npos );
if ( typeInfo.postfix.find( '*' ) != std::string::npos )
{
assert( typeInfo.postfix.find_first_of( '*' ) == typeInfo.postfix.find_last_of( '*' ) );
name = "p" + name;
}
else
{
name = startLowerCase( name );
}
return name;
}
std::pair<std::string, std::string> VulkanHppGenerator::generateProtection( std::string const & referencedIn, std::pair<std::string, std::string> VulkanHppGenerator::generateProtection( std::string const & referencedIn,
std::string const & protect ) const std::string const & protect ) const
{ {
@ -12191,39 +12208,51 @@ std::string VulkanHppGenerator::generateUnion( std::pair<std::string, StructureD
" ) );\n" " ) );\n"
" }\n"; " }\n";
bool firstMember = true; bool firstMember = true;
for ( auto const & member : structure.second.members ) std::set<TypeInfo> listedTypes; // create just one constructor per different type !
for (auto memberIt = structure.second.members.begin(); memberIt != structure.second.members.end(); ++memberIt )
{ {
// VkBool32 is aliased to uint32_t. Don't create a VkBool32 constructor if the union also contains a uint32_t if ( listedTypes.insert( memberIt->type ).second )
// constructor.
auto compareBool32Alias = []( MemberData const & member )
{ {
return member.type.type == std::string( "uint32_t" ); // VkBool32 is aliased to uint32_t. Don't create a VkBool32 constructor if the union also contains a uint32_t
}; // constructor.
if ( member.type.type == "VkBool32" ) if ( memberIt->type.type == "VkBool32" )
{
if ( std::find_if( structure.second.members.begin(), structure.second.members.end(), compareBool32Alias ) !=
structure.second.members.end() )
{ {
continue; if ( std::find_if( structure.second.members.begin(),
structure.second.members.end(),
[]( MemberData const & member ) {
return member.type.type == std::string( "uint32_t" );
} ) !=
structure.second.members.end() )
{
continue;
}
} }
}
static const std::string constructorTemplate = R"( bool multipleType = ( std::find_if( std::next( memberIt ),
${unionName}( ${memberType} ${memberName}_${defaultAssignment} ) structure.second.members.end(),
: ${memberName}( ${memberName}_ ) [memberIt]( MemberData const & member ) {
return member.type == memberIt->type;
} ) != structure.second.members.end() );
static const std::string constructorTemplate = R"(
${unionName}( ${memberType} ${argumentName}_${defaultAssignment} )
: ${memberName}( ${argumentName}_ )
{} {}
)"; )";
std::string memberType = ( member.arraySizes.empty() ) std::string memberType =
? member.type.compose() ( memberIt->arraySizes.empty() )
: ( "const " + generateStandardArray( member.type.compose(), member.arraySizes ) + "&" ); ? memberIt->type.compose()
str += replaceWithMap( constructorTemplate, : ( "const " + generateStandardArray( memberIt->type.compose(), memberIt->arraySizes ) + "&" );
{ { "defaultAssignment", firstMember ? " = {}" : "" }, str += replaceWithMap( constructorTemplate,
{ "memberName", member.name }, { { "argumentName", multipleType ? generateName( memberIt->type ) : memberIt->name },
{ "memberType", memberType }, { "defaultAssignment", firstMember ? " = {}" : "" },
{ "unionName", stripPrefix( structure.first, "Vk" ) } } ); { "memberName", memberIt->name },
firstMember = false; { "memberType", memberType },
{ "unionName", stripPrefix( structure.first, "Vk" ) } } );
firstMember = false;
}
} }
str += "#endif /*VULKAN_HPP_NO_UNION_CONSTRUCTORS*/\n"; str += "#endif /*VULKAN_HPP_NO_UNION_CONSTRUCTORS*/\n";

View File

@ -56,6 +56,13 @@ private:
return ( prefix == rhs.prefix ) && ( type == rhs.type ) && ( postfix == rhs.postfix ); return ( prefix == rhs.prefix ) && ( type == rhs.type ) && ( postfix == rhs.postfix );
} }
bool operator<( TypeInfo const & rhs ) const
{
return ( prefix < rhs.prefix ) ||
( ( prefix == rhs.prefix ) &&
( ( type < rhs.type ) || ( ( type == rhs.type ) && ( postfix < rhs.postfix ) ) ) );
}
bool isConstPointer() const bool isConstPointer() const
{ {
return ( prefix.find( "const" ) != std::string::npos ) && ( postfix.find( '*' ) != std::string::npos ); return ( prefix.find( "const" ) != std::string::npos ) && ( postfix.find( '*' ) != std::string::npos );
@ -1058,6 +1065,7 @@ private:
std::map<std::vector<MemberData>::const_iterator, std::map<std::vector<MemberData>::const_iterator,
std::vector<std::vector<MemberData>::const_iterator>>::const_iterator litit, std::vector<std::vector<MemberData>::const_iterator>>::const_iterator litit,
bool mutualExclusiveLens ) const; bool mutualExclusiveLens ) const;
std::string generateName( TypeInfo const & typeInfo ) const;
std::pair<std::string, std::string> generateProtection( std::string const & referencedIn, std::pair<std::string, std::string> generateProtection( std::string const & referencedIn,
std::string const & protect ) const; std::string const & protect ) const;
std::pair<std::string, std::string> generateProtection( std::string const & type, bool isAliased ) const; std::pair<std::string, std::string> generateProtection( std::string const & type, bool isAliased ) const;