Unify type traits handling of Handles, Structures, and IndexTypes.

This commit is contained in:
asuessenbach 2020-04-21 14:26:32 +02:00 committed by Markus Tavenrath
parent ac272a10ff
commit c7c375eb98
3 changed files with 4139 additions and 133 deletions

View File

@ -1807,6 +1807,14 @@ void VulkanHppGenerator::appendEnums( std::string & str ) const
appendPlatformEnter( str, !e.second.alias.empty(), e.second.platform ); appendPlatformEnter( str, !e.second.alias.empty(), e.second.platform );
appendEnum( str, e ); appendEnum( str, e );
appendEnumToString( str, e ); appendEnumToString( str, e );
if ( e.first == "VkObjectType" )
{
str += R"(
template<ObjectType value>
struct [[deprecated("vk::cpp_type is deprecated. Use vk::CppType instead.")]] cpp_type
{};
)";
}
if ( e.second.alias.empty() ) // enums with an alias are not protected anymore ! if ( e.second.alias.empty() ) // enums with an alias are not protected anymore !
{ {
appendPlatformLeave( str, !e.second.alias.empty(), e.second.platform ); appendPlatformLeave( str, !e.second.alias.empty(), e.second.platform );
@ -3259,10 +3267,16 @@ ${commands}
static_assert( sizeof( ${className} ) == sizeof( Vk${className} ), "handle and wrapper have different size!" ); static_assert( sizeof( ${className} ) == sizeof( Vk${className} ), "handle and wrapper have different size!" );
template <> template <>
struct cpp_type<ObjectType::e${className}> struct [[deprecated("vk::cpp_type is deprecated. Use vk::CppType instead.")]] cpp_type<ObjectType::e${className}>
{ {
using type = ${className}; using type = ${className};
}; };
template <>
struct CppType<ObjectType, ObjectType::e${className}>
{
using Type = ${className};
};
)"; )";
std::string enter, leave; std::string enter, leave;
@ -3610,10 +3624,11 @@ void VulkanHppGenerator::appendStructCopyConstructors( std::string & str, std::s
str += replaceWithMap( templateString, { { "name", name } } ); str += replaceWithMap( templateString, { { "name", name } } );
} }
void VulkanHppGenerator::appendStructMembers( std::string & str, std::string VulkanHppGenerator::appendStructMembers( std::string & str,
std::pair<std::string, StructureData> const & structData, std::pair<std::string, StructureData> const & structData,
std::string const & prefix ) const std::string const & prefix ) const
{ {
std::string sTypeValue;
for ( auto const & member : structData.second.members ) for ( auto const & member : structData.second.members )
{ {
str += prefix; str += prefix;
@ -3651,7 +3666,8 @@ void VulkanHppGenerator::appendStructMembers( std::string &
enumIt->second.values.end(), enumIt->second.values.end(),
[&member]( EnumValueData const & evd ) { return member.values == evd.vulkanValue; } ); [&member]( EnumValueData const & evd ) { return member.values == evd.vulkanValue; } );
assert( nameIt != enumIt->second.values.end() ); assert( nameIt != enumIt->second.values.end() );
str += " = StructureType::" + nameIt->vkValue; sTypeValue = nameIt->vkValue;
str += " = StructureType::" + sTypeValue;
} }
else else
{ {
@ -3684,6 +3700,7 @@ void VulkanHppGenerator::appendStructMembers( std::string &
} }
str += ";\n"; str += ";\n";
} }
return sTypeValue;
} }
void VulkanHppGenerator::appendStructs( std::string & str ) const void VulkanHppGenerator::appendStructs( std::string & str ) const
@ -3695,7 +3712,10 @@ void VulkanHppGenerator::appendStructs( std::string & str ) const
} }
} }
void VulkanHppGenerator::appendStructSetter(std::string & str, std::string const& structureName, bool isUnion, MemberData const& memberData) const void VulkanHppGenerator::appendStructSetter( std::string & str,
std::string const & structureName,
bool isUnion,
MemberData const & memberData ) const
{ {
if ( memberData.type.type != "VkStructureType" ) // filter out StructureType, which is supposed to be immutable ! if ( memberData.type.type != "VkStructureType" ) // filter out StructureType, which is supposed to be immutable !
{ {
@ -3707,13 +3727,16 @@ void VulkanHppGenerator::appendStructSetter(std::string & str, std::string const
} }
)"; )";
std::string memberType = memberData.arraySizes.empty() ? memberData.type.compose() : constructStandardArray(memberData.type.compose(), memberData.arraySizes); std::string memberType = memberData.arraySizes.empty()
? memberData.type.compose()
: constructStandardArray( memberData.type.compose(), memberData.arraySizes );
std::string assignment; std::string assignment;
if ( !memberData.bitCount.empty() && beginsWith( memberData.type.type, "Vk" ) ) if ( !memberData.bitCount.empty() && beginsWith( memberData.type.type, "Vk" ) )
{ {
assignment = memberData.name + " = " + "*reinterpret_cast<" + memberData.type.type + "*>(&" + memberData.name + "_)"; assignment =
memberData.name + " = " + "*reinterpret_cast<" + memberData.type.type + "*>(&" + memberData.name + "_)";
} }
else if (isUnion && holdsSType(memberData.type.type) ) else if ( isUnion && holdsSType( memberData.type.type ) )
{ {
assignment = "memcpy( &" + memberData.name + ", &" + memberData.name + "_, sizeof(" + memberType + "))"; assignment = "memcpy( &" + memberData.name + ", &" + memberData.name + "_, sizeof(" + memberType + "))";
} }
@ -3722,15 +3745,17 @@ void VulkanHppGenerator::appendStructSetter(std::string & str, std::string const
assignment = memberData.name + " = " + memberData.name + "_"; assignment = memberData.name + " = " + memberData.name + "_";
} }
str += replaceWithMap(templateString, str += replaceWithMap(
{ templateString,
{ "assignment", assignment }, { { "assignment", assignment },
{ "memberName", memberData.name }, { "memberName", memberData.name },
{ "MemberName", startUpperCase(memberData.name) }, { "MemberName", startUpperCase( memberData.name ) },
{ "memberType", memberType }, { "memberType", memberType },
{ "reference", (memberData.type.postfix.empty() && (m_structures.find(memberData.type.type) != m_structures.end())) ? "const & " : "" }, { "reference",
{ "structureName", structureName } ( memberData.type.postfix.empty() && ( m_structures.find( memberData.type.type ) != m_structures.end() ) )
}); ? "const & "
: "" },
{ "structureName", structureName } } );
} }
} }
@ -3793,7 +3818,7 @@ void VulkanHppGenerator::appendStructure( std::string &
// only structs that are not returnedOnly get setters! // only structs that are not returnedOnly get setters!
for ( auto const & member : structure.second.members ) for ( auto const & member : structure.second.members )
{ {
appendStructSetter(constructorAndSetters, stripPrefix(structure.first, "Vk"), false, member); appendStructSetter( constructorAndSetters, stripPrefix( structure.first, "Vk" ), false, member );
} }
} }
@ -3806,11 +3831,12 @@ void VulkanHppGenerator::appendStructure( std::string &
} }
// the member variables // the member variables
std::string members = "\n public:\n"; std::string members = "\n public:\n";
appendStructMembers( members, structure, " " ); std::string sTypeValue = appendStructMembers( members, structure, " " );
static const std::string structureTemplate = R"( struct ${name} static const std::string structureTemplate = R"( struct ${structureName}
{ {
${structureType}
${constructorAndSetters} ${constructorAndSetters}
operator ${vkName} const&() const VULKAN_HPP_NOEXCEPT operator ${vkName} const&() const VULKAN_HPP_NOEXCEPT
@ -3827,16 +3853,37 @@ ${compareOperators}
${members} ${members}
}; };
static_assert( sizeof( ${name} ) == sizeof( ${vkName} ), "struct and wrapper have different size!" ); static_assert( sizeof( ${structureName} ) == sizeof( ${vkName} ), "struct and wrapper have different size!" );
static_assert( std::is_standard_layout<${name}>::value, "struct wrapper is not a standard layout!" ); static_assert( std::is_standard_layout<${structureName}>::value, "struct wrapper is not a standard layout!" );
)"; )";
std::string structureName = stripPrefix( structure.first, "Vk" );
std::string structureType;
if ( !sTypeValue.empty() )
{
structureType =
" static VULKAN_HPP_CONST_OR_CONSTEXPR StructureType structureType = StructureType::" + sTypeValue + ";\n";
}
str += replaceWithMap( structureTemplate, str += replaceWithMap( structureTemplate,
{ { "name", stripPrefix( structure.first, "Vk" ) }, { { "structureName", structureName },
{ "structureType", structureType },
{ "constructorAndSetters", constructorAndSetters }, { "constructorAndSetters", constructorAndSetters },
{ "vkName", structure.first }, { "vkName", structure.first },
{ "compareOperators", compareOperators }, { "compareOperators", compareOperators },
{ "members", members } } ); { "members", members } } );
if ( !sTypeValue.empty() )
{
std::string cppTypeTemplate = R"(
template <>
struct CppType<StructureType, StructureType::${sTypeValue}>
{
using Type = ${structureName};
};
)";
str += replaceWithMap( cppTypeTemplate, { { "sTypeValue", sTypeValue }, { "structureName", structureName } } );
}
appendPlatformLeave( str, !structure.second.aliases.empty(), structure.second.platform ); appendPlatformLeave( str, !structure.second.aliases.empty(), structure.second.platform );
} }
@ -3961,21 +4008,22 @@ void VulkanHppGenerator::appendUnion( std::string & str, std::pair<std::string,
{} {}
)"; )";
std::string memberType = (member.arraySizes.empty()) ? member.type.compose() : ("const " + constructStandardArray(member.type.compose(), member.arraySizes) + "&"); std::string memberType =
str += replaceWithMap(constructorTemplate, ( member.arraySizes.empty() )
{ ? member.type.compose()
{ "defaultAssignment", firstMember ? " = {}" : "" }, : ( "const " + constructStandardArray( member.type.compose(), member.arraySizes ) + "&" );
{ "memberName", member.name }, str += replaceWithMap( constructorTemplate,
{ "memberType", memberType }, { { "defaultAssignment", firstMember ? " = {}" : "" },
{ "unionName", stripPrefix(structure.first, "Vk") } { "memberName", member.name },
}); { "memberType", memberType },
{ "unionName", stripPrefix( structure.first, "Vk" ) } } );
firstMember = false; firstMember = false;
} }
// one setter per union element // one setter per union element
for ( auto const & member : structure.second.members ) for ( auto const & member : structure.second.members )
{ {
appendStructSetter(str, stripPrefix(structure.first, "Vk"), true, member); appendStructSetter( str, stripPrefix( structure.first, "Vk" ), true, member );
} }
// assignment operator // assignment operator
@ -4488,6 +4536,77 @@ std::map<size_t, size_t> VulkanHppGenerator::determineVectorParamIndices( std::v
return vectorParamIndices; return vectorParamIndices;
} }
void VulkanHppGenerator::appendIndexTypeTraits( std::string & str ) const
{
auto indexType = m_enums.find( "VkIndexType" );
assert( indexType != m_enums.end() );
str += R"(
template<typename T>
struct IndexTypeValue
{};
)";
std::set<std::string> seenCppTypes;
for ( auto const & value : indexType->second.values )
{
std::string cppType;
if ( beginsWith( value.vkValue, "eUint8" ) )
{
cppType = "uint8_t";
}
else if ( beginsWith( value.vkValue, "eUint16" ) )
{
cppType = "uint16_t";
}
else if ( beginsWith( value.vkValue, "eUint32" ) )
{
cppType = "uint32_t";
}
else if ( beginsWith( value.vkValue, "eUint64" ) )
{
cppType = "uint64_t"; // No extension for this currently
}
else
{
assert( value.vkValue == "eNoneKHR" );
}
if ( !cppType.empty() )
{
if ( seenCppTypes.insert( cppType ).second )
{
// IndexType traits aren't necessarily invertible.
// The Type -> Enum translation will only occur for the first prefixed enum value.
// A hypothetical extension to this enum with a conflicting prefix will use the core spec value.
str +=
"\n"
" template <>\n"
" struct IndexTypeValue<" +
cppType +
">\n"
" {\n"
" static VULKAN_HPP_CONST_OR_CONSTEXPR IndexType value = IndexType::" +
value.vkValue +
";\n"
" };\n";
}
// Enum -> Type translations are always able to occur.
str +=
"\n"
" template <>\n"
" struct CppType<IndexType, IndexType::" +
value.vkValue +
">\n"
" {\n"
" using Type = " +
cppType +
";\n"
" };\n";
}
}
}
std::string const & VulkanHppGenerator::getTypesafeCheck() const std::string const & VulkanHppGenerator::getTypesafeCheck() const
{ {
return m_typesafeCheck; return m_typesafeCheck;
@ -4503,18 +4622,18 @@ std::string const & VulkanHppGenerator::getVulkanLicenseHeader() const
return m_vulkanLicenseHeader; return m_vulkanLicenseHeader;
} }
bool VulkanHppGenerator::holdsSType(std::string const& type) const bool VulkanHppGenerator::holdsSType( std::string const & type ) const
{ {
auto it = m_structures.find(type); auto it = m_structures.find( type );
if (it != m_structures.end()) if ( it != m_structures.end() )
{ {
assert(!it->second.members.empty()); assert( !it->second.members.empty() );
return (it->second.members.front().name == "sType"); return ( it->second.members.front().name == "sType" );
} }
return false; return false;
} }
bool VulkanHppGenerator::isTwoStepAlgorithm(std::vector<ParamData> const& params) const bool VulkanHppGenerator::isTwoStepAlgorithm( std::vector<ParamData> const & params ) const
{ {
// we generate a two-step algorithm for functions returning a vector of stuff, where the length is specified as a // we generate a two-step algorithm for functions returning a vector of stuff, where the length is specified as a
// pointer as well for those functions, the size can be queried first, and then used // pointer as well for those functions, the size can be queried first, and then used
@ -7823,10 +7942,9 @@ namespace std
)"; )";
static const std::string typeTraits = R"( static const std::string typeTraits = R"(
template<ObjectType value> template <typename EnumType, EnumType value>
struct cpp_type struct CppType
{ {};
};
)"; )";
try try
@ -7859,8 +7977,9 @@ namespace std
generator.appendDispatchLoaderDefault( str ); generator.appendDispatchLoaderDefault( str );
str += classObjectDestroy + classObjectFree + classPoolFree + "\n"; str += classObjectDestroy + classObjectFree + classPoolFree + "\n";
generator.appendBaseTypes( str ); generator.appendBaseTypes( str );
generator.appendEnums( str );
str += typeTraits; str += typeTraits;
generator.appendEnums( str );
generator.appendIndexTypeTraits( str );
generator.appendBitmasks( str ); generator.appendBitmasks( str );
str += "} // namespace VULKAN_HPP_NAMESPACE\n" + is_error_code_enum + "\n" + "namespace VULKAN_HPP_NAMESPACE\n" + str += "} // namespace VULKAN_HPP_NAMESPACE\n" + is_error_code_enum + "\n" + "namespace VULKAN_HPP_NAMESPACE\n" +
"{\n" + "#ifndef VULKAN_HPP_NO_EXCEPTIONS" + exceptions; "{\n" + "#ifndef VULKAN_HPP_NO_EXCEPTIONS" + exceptions;

View File

@ -40,6 +40,7 @@ public:
void appendStructs( std::string & str ) const; void appendStructs( std::string & str ) const;
void appendStructureChainValidation( std::string & str ); void appendStructureChainValidation( std::string & str );
void appendThrowExceptions( std::string & str ) const; void appendThrowExceptions( std::string & str ) const;
void appendIndexTypeTraits( std::string & str ) const;
std::string const & getTypesafeCheck() const; std::string const & getTypesafeCheck() const;
std::string const & getVersion() const; std::string const & getVersion() const;
std::string const & getVulkanLicenseHeader() const; std::string const & getVulkanLicenseHeader() const;
@ -461,39 +462,39 @@ private:
std::string const & indentation, std::string const & indentation,
MemberData const & memberData ) const; MemberData const & memberData ) const;
void appendStructCopyConstructors( std::string & str, std::string const & vkName ) const; void appendStructCopyConstructors( std::string & str, std::string const & vkName ) const;
void appendStructMembers( std::string & str, std::string appendStructMembers( std::string & str,
std::pair<std::string, StructureData> const & structData,
std::string const & prefix ) const;
void appendStructSetter( std::string & str,
std::string const & structureName,
bool isUnion,
MemberData const & memberData ) const;
void appendStructSubConstructor( std::string & str,
std::pair<std::string, StructureData> const & structData, std::pair<std::string, StructureData> const & structData,
std::string const & prefix ) const; std::string const & prefix ) const;
void appendStructure( std::string & str, std::pair<std::string, StructureData> const & structure ) const; void appendStructSetter( std::string & str,
void appendUnion( std::string & str, std::pair<std::string, StructureData> const & structure ) const; std::string const & structureName,
void appendUniqueTypes( std::string & str, bool isUnion,
std::string const & parentType, MemberData const & memberData ) const;
std::set<std::string> const & childrenTypes ) const; void appendStructSubConstructor( std::string & str,
std::string constructConstexprString( std::pair<std::string, StructureData> const & structData ) const; std::pair<std::string, StructureData> const & structData,
void checkCorrectness(); std::string const & prefix ) const;
bool checkLenAttribute( std::string const & len, std::vector<ParamData> const & params ); void appendStructure( std::string & str, std::pair<std::string, StructureData> const & structure ) const;
bool containsArray( std::string const & type ) const; void appendUnion( std::string & str, std::pair<std::string, StructureData> const & structure ) const;
bool containsUnion( std::string const & type ) const; void appendUniqueTypes( std::string & str,
std::string determineEnhancedReturnType( CommandData const & commandData, std::string const & parentType,
size_t returnParamIndex, std::set<std::string> const & childrenTypes ) const;
std::map<size_t, size_t> const & vectorParamIndices, std::string constructConstexprString( std::pair<std::string, StructureData> const & structData ) const;
bool isStructureChain ) const; void checkCorrectness();
size_t determineReturnParamIndex( CommandData const & commandData, bool checkLenAttribute( std::string const & len, std::vector<ParamData> const & params );
std::map<size_t, size_t> const & vectorParamIndices, bool containsArray( std::string const & type ) const;
bool twoStep ) const; bool containsUnion( std::string const & type ) const;
std::string determineSubStruct( std::pair<std::string, StructureData> const & structure ) const; std::string determineEnhancedReturnType( CommandData const & commandData,
size_t determineTemplateParamIndex( std::vector<ParamData> const & params, size_t returnParamIndex,
std::map<size_t, size_t> const & vectorParamIndices ) const; std::map<size_t, size_t> const & vectorParamIndices,
bool isStructureChain ) const;
size_t determineReturnParamIndex( CommandData const & commandData,
std::map<size_t, size_t> const & vectorParamIndices,
bool twoStep ) const;
std::string determineSubStruct( std::pair<std::string, StructureData> const & structure ) const;
size_t determineTemplateParamIndex( std::vector<ParamData> const & params,
std::map<size_t, size_t> const & vectorParamIndices ) const;
std::map<size_t, size_t> determineVectorParamIndices( std::vector<ParamData> const & params ) const; std::map<size_t, size_t> determineVectorParamIndices( std::vector<ParamData> const & params ) const;
bool holdsSType( std::string const & type ) const; bool holdsSType( std::string const & type ) const;
bool isTwoStepAlgorithm( std::vector<ParamData> const & params ) const; bool isTwoStepAlgorithm( std::vector<ParamData> const & params ) const;
void linkCommandToHandle( int line, std::string const & name, CommandData const & commandData ); void linkCommandToHandle( int line, std::string const & name, CommandData const & commandData );
void readBaseType( tinyxml2::XMLElement const * element, std::map<std::string, std::string> const & attributes ); void readBaseType( tinyxml2::XMLElement const * element, std::map<std::string, std::string> const & attributes );
void readBitmask( tinyxml2::XMLElement const * element, std::map<std::string, std::string> const & attributes ); void readBitmask( tinyxml2::XMLElement const * element, std::map<std::string, std::string> const & attributes );
@ -575,27 +576,27 @@ private:
void setVulkanLicenseHeader( int line, std::string const & comment ); void setVulkanLicenseHeader( int line, std::string const & comment );
std::string toString( TypeCategory category ); std::string toString( TypeCategory category );
private: private:
std::map<std::string, BaseTypeData> m_baseTypes; std::map<std::string, BaseTypeData> m_baseTypes;
std::map<std::string, BitmaskData> m_bitmasks; std::map<std::string, BitmaskData> m_bitmasks;
std::map<std::string, std::string> m_commandToHandle; std::map<std::string, std::string> m_commandToHandle;
std::set<std::string> m_constants; std::set<std::string> m_constants;
std::set<std::string> m_defines; std::set<std::string> m_defines;
std::map<std::string, EnumData> m_enums; std::map<std::string, EnumData> m_enums;
std::set<std::string> m_extendedStructs; // structs which are referenced by the structextends tag std::set<std::string> m_extendedStructs; // structs which are referenced by the structextends tag
std::map<std::string, ExtensionData> m_extensions; std::map<std::string, ExtensionData> m_extensions;
std::map<std::string, std::string> m_features; std::map<std::string, std::string> m_features;
std::map<std::string, FuncPointerData> m_funcPointers; std::map<std::string, FuncPointerData> m_funcPointers;
std::map<std::string, HandleData> m_handles; std::map<std::string, HandleData> m_handles;
std::set<std::string> m_includes; std::set<std::string> m_includes;
std::map<std::string, std::string> m_platforms; std::map<std::string, std::string> m_platforms;
std::map<std::string, std::string> m_structureAliases; std::map<std::string, std::string> m_structureAliases;
std::map<std::string, StructureData> m_structures; std::map<std::string, StructureData> m_structures;
std::set<std::string> m_tags; std::set<std::string> m_tags;
std::map<std::string, TypeCategory> m_types; std::map<std::string, TypeCategory> m_types;
std::string m_typesafeCheck; std::string m_typesafeCheck;
std::string m_version; std::string m_version;
std::string m_vulkanLicenseHeader; std::string m_vulkanLicenseHeader;
}; };
const size_t INVALID_INDEX = (size_t)~0; const size_t INVALID_INDEX = (size_t)~0;

File diff suppressed because it is too large Load Diff