mirror of
https://github.com/KhronosGroup/Vulkan-Hpp.git
synced 2024-10-14 16:32:17 +00:00
Introduce simple reflection function on vk-structs
Used that to simplify comparison operators.
This commit is contained in:
parent
4d82f64e66
commit
ce3eb55ada
@ -11693,56 +11693,6 @@ std::string VulkanHppGenerator::generateStructAssignmentOperators(
|
||||
return replaceWithMap( assignmentFromVulkanType, { { "structName", stripPrefix( structData.first, "Vk" ) } } );
|
||||
}
|
||||
|
||||
std::string
|
||||
VulkanHppGenerator::generateStructCompareOperators( std::pair<std::string, StructureData> const & structData ) const
|
||||
{
|
||||
static const std::set<std::string> simpleTypes = { "char", "double", "DWORD", "float", "HANDLE",
|
||||
"HINSTANCE", "HMONITOR", "HWND", "int", "int8_t",
|
||||
"int16_t", "int32_t", "int64_t", "LPCWSTR", "size_t",
|
||||
"uint8_t", "uint16_t", "uint32_t", "uint64_t" };
|
||||
// two structs are compared by comparing each of the elements
|
||||
std::string compareMembers;
|
||||
std::string intro = "";
|
||||
for ( size_t i = 0; i < structData.second.members.size(); i++ )
|
||||
{
|
||||
MemberData const & member = structData.second.members[i];
|
||||
auto typeIt = m_types.find( member.type.type );
|
||||
assert( typeIt != m_types.end() );
|
||||
if ( ( typeIt->second.category == TypeCategory::Requires ) && member.type.postfix.empty() &&
|
||||
( simpleTypes.find( member.type.type ) == simpleTypes.end() ) )
|
||||
{
|
||||
// this type might support operator==()... that is, use memcmp
|
||||
compareMembers +=
|
||||
intro + "( memcmp( &" + member.name + ", &rhs." + member.name + ", sizeof( " + member.type.type + " ) ) == 0 )";
|
||||
}
|
||||
else
|
||||
{
|
||||
// for all others, we use the operator== of that type
|
||||
compareMembers += intro + "( " + member.name + " == rhs." + member.name + " )";
|
||||
}
|
||||
intro = "\n && ";
|
||||
}
|
||||
|
||||
static const std::string compareTemplate = R"(
|
||||
#if defined(VULKAN_HPP_HAS_SPACESHIP_OPERATOR)
|
||||
auto operator<=>( ${name} const & ) const = default;
|
||||
#else
|
||||
bool operator==( ${name} const & rhs ) const VULKAN_HPP_NOEXCEPT
|
||||
{
|
||||
return ${compareMembers};
|
||||
}
|
||||
|
||||
bool operator!=( ${name} const & rhs ) const VULKAN_HPP_NOEXCEPT
|
||||
{
|
||||
return !operator==( rhs );
|
||||
}
|
||||
#endif
|
||||
)";
|
||||
|
||||
return replaceWithMap( compareTemplate,
|
||||
{ { "name", stripPrefix( structData.first, "Vk" ) }, { "compareMembers", compareMembers } } );
|
||||
}
|
||||
|
||||
std::string
|
||||
VulkanHppGenerator::generateStructConstructors( std::pair<std::string, StructureData> const & structData ) const
|
||||
{
|
||||
@ -11993,15 +11943,13 @@ std::string VulkanHppGenerator::generateStructHashSum( std::string const &
|
||||
hashSum += " {\n";
|
||||
if ( member.arraySizes.size() == 1 )
|
||||
{
|
||||
hashSum +=
|
||||
" VULKAN_HPP_HASH_COMBINE( seed, " + structName + "." + member.name + "[i] );\n";
|
||||
hashSum += " VULKAN_HPP_HASH_COMBINE( seed, " + structName + "." + member.name + "[i] );\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
hashSum += " for ( size_t j=0; j < " + member.arraySizes[1] + "; ++j )\n";
|
||||
hashSum += " {\n";
|
||||
hashSum += " VULKAN_HPP_HASH_COMBINE( seed, " + structName + "." + member.name +
|
||||
"[i][j] );\n";
|
||||
hashSum += " VULKAN_HPP_HASH_COMBINE( seed, " + structName + "." + member.name + "[i][j] );\n";
|
||||
hashSum += " }\n";
|
||||
}
|
||||
hashSum += " }\n";
|
||||
@ -12040,17 +11988,52 @@ std::string VulkanHppGenerator::generateStructure( std::pair<std::string, Struct
|
||||
constructorAndSetters += "#endif /*VULKAN_HPP_NO_STRUCT_SETTERS*/\n";
|
||||
}
|
||||
|
||||
std::string structureType = stripPrefix( structure.first, "Vk" );
|
||||
// the member variables
|
||||
std::string members, memberNames, memberTypes, sTypeValue;
|
||||
std::tie( members, memberNames, memberTypes, sTypeValue ) = generateStructMembers( structure );
|
||||
|
||||
// reflect is meaningfull for structs only, filter out unions
|
||||
std::string reflect;
|
||||
if ( !structure.second.isUnion )
|
||||
{
|
||||
static const std::string reflectTemplate = R"(
|
||||
#if 14 <= VULKAN_HPP_CPP_VERSION
|
||||
auto
|
||||
#else
|
||||
std::tuple<${memberTypes}>
|
||||
#endif
|
||||
reflect() const VULKAN_HPP_NOEXCEPT
|
||||
{
|
||||
return std::tie( ${memberNames} );
|
||||
}
|
||||
)";
|
||||
|
||||
reflect = replaceWithMap( reflectTemplate, { { "memberNames", memberNames }, { "memberTypes", memberTypes } } );
|
||||
}
|
||||
|
||||
// operator==() and operator!=()
|
||||
// only structs without a union as a member can have a meaningfull == and != operation; we filter them out
|
||||
std::string compareOperators;
|
||||
if ( !containsUnion( structure.first ) )
|
||||
{
|
||||
compareOperators += generateStructCompareOperators( structure );
|
||||
}
|
||||
static const std::string compareOperatorsTemplate = R"(
|
||||
#if defined(VULKAN_HPP_HAS_SPACESHIP_OPERATOR)
|
||||
auto operator<=>( ${structureType} const & ) const = default;
|
||||
#else
|
||||
bool operator==( ${structureType} const & rhs ) const VULKAN_HPP_NOEXCEPT
|
||||
{
|
||||
return this->reflect() == rhs.reflect();
|
||||
}
|
||||
|
||||
// the member variables
|
||||
std::string members, sTypeValue;
|
||||
std::tie( members, sTypeValue ) = generateStructMembers( structure, " " );
|
||||
bool operator!=( ${structureType} const & rhs ) const VULKAN_HPP_NOEXCEPT
|
||||
{
|
||||
return this->reflect() != rhs.reflect();
|
||||
}
|
||||
#endif
|
||||
)";
|
||||
compareOperators = replaceWithMap( compareOperatorsTemplate, { { "structureType", structureType } } );
|
||||
}
|
||||
|
||||
static const std::string structureTemplate = R"( struct ${structureType}
|
||||
{
|
||||
@ -12069,9 +12052,8 @@ ${constructorAndSetters}
|
||||
{
|
||||
return *reinterpret_cast<Vk${structureType}*>( this );
|
||||
}
|
||||
|
||||
${reflect}
|
||||
${compareOperators}
|
||||
|
||||
public:
|
||||
${members}
|
||||
};
|
||||
@ -12080,7 +12062,6 @@ ${members}
|
||||
VULKAN_HPP_STATIC_ASSERT( std::is_nothrow_move_constructible<VULKAN_HPP_NAMESPACE::${structureType}>::value, "${structureType} is not nothrow_move_constructible!" );
|
||||
)";
|
||||
|
||||
std::string structureType = stripPrefix( structure.first, "Vk" );
|
||||
std::string allowDuplicate, typeValue;
|
||||
if ( !sTypeValue.empty() )
|
||||
{
|
||||
@ -12094,6 +12075,7 @@ ${members}
|
||||
{ "constructorAndSetters", constructorAndSetters },
|
||||
{ "compareOperators", compareOperators },
|
||||
{ "members", members },
|
||||
{ "reflect", reflect },
|
||||
{ "structureType", structureType },
|
||||
{ "typeValue", typeValue } } );
|
||||
|
||||
@ -12203,36 +12185,36 @@ std::string VulkanHppGenerator::generateStructForwardDeclarations( std::vector<R
|
||||
return addTitleAndProtection( title, str );
|
||||
}
|
||||
|
||||
std::pair<std::string, std::string>
|
||||
VulkanHppGenerator::generateStructMembers( std::pair<std::string, StructureData> const & structData,
|
||||
std::string const & prefix ) const
|
||||
std::tuple<std::string, std::string, std::string, std::string>
|
||||
VulkanHppGenerator::generateStructMembers( std::pair<std::string, StructureData> const & structData ) const
|
||||
{
|
||||
std::string str, sTypeValue;
|
||||
std::string members, memberNames, memberTypes, sTypeValue;
|
||||
for ( auto const & member : structData.second.members )
|
||||
{
|
||||
str += prefix;
|
||||
members += " ";
|
||||
std::string type;
|
||||
if ( !member.bitCount.empty() && beginsWith( member.type.type, "Vk" ) )
|
||||
{
|
||||
assert( member.type.prefix.empty() && member.type.postfix.empty() ); // never encounterd a different case
|
||||
str += member.type.type;
|
||||
type = member.type.type;
|
||||
}
|
||||
else if ( member.arraySizes.empty() )
|
||||
{
|
||||
str += member.type.compose( "VULKAN_HPP_NAMESPACE" );
|
||||
type = member.type.compose( "VULKAN_HPP_NAMESPACE" );
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( member.type.prefix.empty() && member.type.postfix.empty() );
|
||||
str += generateStandardArrayWrapper( member.type.compose( "VULKAN_HPP_NAMESPACE" ), member.arraySizes );
|
||||
type = generateStandardArrayWrapper( member.type.compose( "VULKAN_HPP_NAMESPACE" ), member.arraySizes );
|
||||
}
|
||||
str += " " + member.name;
|
||||
members += type + " " + member.name;
|
||||
if ( !member.value.empty() )
|
||||
{
|
||||
// special handling for members with legal value: use it as the default
|
||||
str += " = ";
|
||||
members += " = ";
|
||||
if ( member.type.type == "uint32_t" )
|
||||
{
|
||||
str += member.value;
|
||||
members += member.value;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -12244,7 +12226,7 @@ std::pair<std::string, std::string>
|
||||
[&enumValue]( EnumValueData const & evd ) { return enumValue == evd.name; } );
|
||||
assert( valueIt != enumIt->second.values.end() );
|
||||
std::string valueName = generateEnumValueName( enumIt->first, valueIt->name, enumIt->second.isBitmask, m_tags );
|
||||
str += stripPrefix( member.type.type, "Vk" ) + "::" + valueName;
|
||||
members += stripPrefix( member.type.type, "Vk" ) + "::" + valueName;
|
||||
if ( member.name == "sType" )
|
||||
{
|
||||
sTypeValue = valueName;
|
||||
@ -12257,27 +12239,30 @@ std::pair<std::string, std::string>
|
||||
assert( member.arraySizes.empty() || member.bitCount.empty() );
|
||||
if ( !member.bitCount.empty() )
|
||||
{
|
||||
str += " : " + member.bitCount; // except for bitfield members, where no default member initializatin is
|
||||
// supported (up to C++20)
|
||||
members += " : " + member.bitCount; // except for bitfield members, where no default member initializatin is
|
||||
// supported (up to C++20)
|
||||
}
|
||||
else
|
||||
{
|
||||
str += " = ";
|
||||
members += " = ";
|
||||
auto enumIt = m_enums.find( member.type.type );
|
||||
if ( member.arraySizes.empty() && ( enumIt != m_enums.end() ) && member.type.postfix.empty() )
|
||||
{
|
||||
str +=
|
||||
members +=
|
||||
generateEnumInitializer( member.type, member.arraySizes, enumIt->second.values, enumIt->second.isBitmask );
|
||||
}
|
||||
else
|
||||
{
|
||||
str += "{}";
|
||||
members += "{}";
|
||||
}
|
||||
}
|
||||
}
|
||||
str += ";\n";
|
||||
members += ";\n";
|
||||
|
||||
memberNames += member.name + ", ";
|
||||
memberTypes += type + " const &, ";
|
||||
}
|
||||
return std::make_pair( str, sTypeValue );
|
||||
return std::make_tuple( members, stripPostfix( memberNames, ", " ), stripPostfix( memberTypes, ", " ), sTypeValue );
|
||||
}
|
||||
|
||||
std::string VulkanHppGenerator::generateStructSetter( std::string const & structureName,
|
||||
|
@ -1214,13 +1214,12 @@ private:
|
||||
std::string generateStruct( std::pair<std::string, StructureData> const & structure,
|
||||
std::set<std::string> & listedStructs ) const;
|
||||
std::string generateStructAssignmentOperators( std::pair<std::string, StructureData> const & structure ) const;
|
||||
std::string generateStructCompareOperators( std::pair<std::string, StructureData> const & structure ) const;
|
||||
std::string generateStructConstructors( std::pair<std::string, StructureData> const & structData ) const;
|
||||
std::string generateStructConstructorsEnhanced( std::pair<std::string, StructureData> const & structData ) const;
|
||||
std::string
|
||||
generateStructConstructorArgument( bool listedArgument, MemberData const & memberData, bool withDefault ) const;
|
||||
std::string generateStructHashStructure( std::pair<std::string, StructureData> const & structure,
|
||||
std::set<std::string> & listedStructs ) const;
|
||||
std::set<std::string> & listedStructs ) const;
|
||||
std::string generateStructHashSum( std::string const & structName, std::vector<MemberData> const & members ) const;
|
||||
std::string generateStructure( std::pair<std::string, StructureData> const & structure ) const;
|
||||
std::string generateStructExtendsStructs( std::vector<RequireData> const & requireData,
|
||||
@ -1228,11 +1227,11 @@ private:
|
||||
std::string const & title ) const;
|
||||
std::string generateStructForwardDeclarations( std::vector<RequireData> const & requireData,
|
||||
std::string const & title ) const;
|
||||
std::pair<std::string, std::string> generateStructMembers( std::pair<std::string, StructureData> const & structData,
|
||||
std::string const & prefix ) const;
|
||||
std::string generateStructSetter( std::string const & structureName,
|
||||
std::vector<MemberData> const & memberData,
|
||||
size_t index ) const;
|
||||
std::tuple<std::string, std::string, std::string, std::string>
|
||||
generateStructMembers( std::pair<std::string, StructureData> const & structData ) const;
|
||||
std::string generateStructSetter( std::string const & structureName,
|
||||
std::vector<MemberData> const & memberData,
|
||||
size_t index ) const;
|
||||
std::string generateStructSubConstructor( std::pair<std::string, StructureData> const & structData ) const;
|
||||
std::string generateSuccessCheck( std::vector<std::string> const & successCodes ) const;
|
||||
std::string generateSuccessCodeList( std::vector<std::string> const & successCodes ) const;
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user