diff --git a/VulkanHppGenerator.cpp b/VulkanHppGenerator.cpp index cb43aca..e098e7b 100644 --- a/VulkanHppGenerator.cpp +++ b/VulkanHppGenerator.cpp @@ -18,30 +18,29 @@ #include #include -void appendTypesafeStuff( std::string & str, std::string const & typesafeCheck ); -void appendVersionCheck( std::string & str, std::string const & version ); -bool beginsWith( std::string const & text, std::string const & prefix ); -bool endsWith( std::string const & text, std::string const & postfix ); -void check( bool condition, int line, std::string const & message ); -void checkAttributes( int line, - std::map const & attributes, - std::map> const & required, - std::map> const & optional ); -void checkElements( int line, - std::vector const & elements, - std::map const & required, - std::set const & optional = {} ); -std::string constructStandardArray( std::string const & type, std::vector const & sizes ); -std::string createEnumValueName( std::string const & name, - std::string const & prefix, - std::string const & postfix, - bool bitmask, - std::string const & tag ); -std::string createSuccessCode( std::string const & code, std::set const & tags ); -std::string determineCommandName( std::string const & vulkanCommandName, - std::string const & argumentType, - std::set const & tags ); -std::string determineNoDiscard( bool multiSuccessCodes, bool multiErrorCodes ); +void appendVersionCheck( std::string & str, std::string const & version ); +bool beginsWith( std::string const & text, std::string const & prefix ); +bool endsWith( std::string const & text, std::string const & postfix ); +void check( bool condition, int line, std::string const & message ); +void checkAttributes( int line, + std::map const & attributes, + std::map> const & required, + std::map> const & optional ); +void checkElements( int line, + std::vector const & elements, + std::map const & required, + std::set const & optional = {} ); +std::string constructStandardArray( std::string const & type, std::vector const & sizes ); +std::string createEnumValueName( std::string const & name, + std::string const & prefix, + std::string const & postfix, + bool bitmask, + std::string const & tag ); +std::string createSuccessCode( std::string const & code, std::set const & tags ); +std::string determineCommandName( std::string const & vulkanCommandName, + std::string const & argumentType, + std::set const & tags ); +std::string determineNoDiscard( bool multiSuccessCodes, bool multiErrorCodes ); std::set determineSingularParams( size_t returnParamIndex, std::map const & vectorParamIndices ); std::set determineSkippedParams( size_t returnParamIndex, std::map const & vectorParamIndices ); @@ -85,19 +84,6 @@ const std::set specialPointerTypes = { "Display", "IDirectFB", "wl_display", "xcb_connection_t", "_screen_window" }; -void appendTypesafeStuff( std::string & str, std::string const & typesafeCheck ) -{ - str += - "// 32-bit vulkan is not typesafe for handles, so don't allow copy constructors on this platform by default.\n" - "// To enable this feature on 32-bit platforms please define VULKAN_HPP_TYPESAFE_CONVERSION\n" + - typesafeCheck + - "\n" - "# if !defined( VULKAN_HPP_TYPESAFE_CONVERSION )\n" - "# define VULKAN_HPP_TYPESAFE_CONVERSION\n" - "# endif\n" - "#endif\n"; -} - void appendVersionCheck( std::string & str, std::string const & version ) { str += "static_assert( VK_HEADER_VERSION == " + version + @@ -912,11 +898,11 @@ void VulkanHppGenerator::appendBitmasks( std::string & str ) const str += "\n //=== " + feature.first + " ===\n"; for ( auto const & type : feature.second.types ) { - auto bitmaskIt = m_bitmasks.find( type ); + auto bitmaskIt = m_bitmasks.find( type.first ); if ( bitmaskIt != m_bitmasks.end() ) { - assert( listedBitmasks.find( type ) == listedBitmasks.end() ); - listedBitmasks.insert( type ); + assert( listedBitmasks.find( type.first ) == listedBitmasks.end() ); + listedBitmasks.insert( type.first ); appendBitmask( str, bitmaskIt ); } } @@ -2711,11 +2697,11 @@ void VulkanHppGenerator::appendEnums( std::string & str ) const str += "\n //=== " + feature.first + " ===\n"; for ( auto const & type : feature.second.types ) { - auto enumIt = m_enums.find( type ); + auto enumIt = m_enums.find( type.first ); if ( enumIt != m_enums.end() ) { - assert( listedEnums.find( type ) == listedEnums.end() ); - listedEnums.insert( type ); + assert( listedEnums.find( type.first ) == listedEnums.end() ); + listedEnums.insert( type.first ); str += "\n"; appendEnum( str, *enumIt ); @@ -13332,7 +13318,17 @@ void VulkanHppGenerator::readFeatureRequireType( tinyxml2::XMLElement const * std::map attributes = getAttributes( element ); checkAttributes( line, attributes, {}, { { "comment", {} }, { "name", {} } } ); checkElements( line, getChildElements( element ), {} ); - std::string name = attributes.find( "name" )->second; + + std::string name = attributes.find( "name" )->second; + auto featureTypeIt = std::find_if( featureIt->second.types.begin(), + featureIt->second.types.end(), + [&name]( std::pair const & typeLine ) + { return ( typeLine.first == name ) && ( typeLine.second != 0 ); } ); + check( featureTypeIt == featureIt->second.types.end(), + line, + "type <" + name + "> already listed for this feature on line " + + ( ( featureTypeIt == featureIt->second.types.end() ) ? "" : std::to_string( featureTypeIt->second ) ) + + " !" ); // some types are in fact includes (like vk_platform) or defines (like VK_API_VERSION) if ( ( m_defines.find( name ) == m_defines.end() ) && ( m_includes.find( name ) == m_includes.end() ) ) @@ -13349,13 +13345,16 @@ void VulkanHppGenerator::readFeatureRequireType( tinyxml2::XMLElement const * { assert( !featureIt->second.types.empty() ); std::string flagBits = name.substr( 0, name.length() - 5 ) + "FlagBits"; - if ( featureIt->second.types.back() != flagBits ) + if ( featureIt->second.types.back().first != flagBits ) { - assert( std::find( featureIt->second.types.begin(), featureIt->second.types.end(), flagBits ) == - featureIt->second.types.end() ); - featureIt->second.types.push_back( flagBits ); + assert( std::find_if( featureIt->second.types.begin(), + featureIt->second.types.end(), + [&flagBits]( std::pair const & typeLine ) + { return ( typeLine.first == flagBits ); } ) == featureIt->second.types.end() ); + featureIt->second.types.push_back( std::make_pair( flagBits, 0 ) ); } } + // filter out FlagBits that are listed after their Flags! // (and therefore have been added right before that Flags, above) bool skipIt = false; @@ -13363,18 +13362,28 @@ void VulkanHppGenerator::readFeatureRequireType( tinyxml2::XMLElement const * { assert( !featureIt->second.types.empty() ); std::string flags = name.substr( 0, name.length() - 4 ) + "s"; - if ( featureIt->second.types.back() == flags ) + if ( featureIt->second.types.back().first == flags ) { - assert( std::find( featureIt->second.types.begin(), featureIt->second.types.end(), flags ) != - featureIt->second.types.end() ); - skipIt = true; + skipIt = true; + auto flagBitsIt = std::find_if( featureIt->second.types.begin(), + featureIt->second.types.end(), + [&name]( std::pair const & typeLine ) + { return ( typeLine.first == name ); } ); + assert( flagBitsIt != featureIt->second.types.end() ); + assert( flagBitsIt->second == 0 ); + flagBitsIt->second = line; + } + else + { + assert( std::find_if( featureIt->second.types.begin(), + featureIt->second.types.end(), + [&flags]( std::pair const & typeLine ) + { return ( typeLine.first == flags ); } ) == featureIt->second.types.end() ); } } if ( !skipIt ) { - assert( std::find( featureIt->second.types.begin(), featureIt->second.types.end(), name ) == - featureIt->second.types.end() ); - featureIt->second.types.push_back( name ); + featureIt->second.types.push_back( std::make_pair( name, line ) ); } } } @@ -16589,7 +16598,15 @@ namespace std str.reserve( estimatedLength ); str += generator.getVulkanLicenseHeader() + includes + "\n"; appendVersionCheck( str, generator.getVersion() ); - appendTypesafeStuff( str, generator.getTypesafeCheck() ); + str += + "// 32-bit vulkan is not typesafe for handles, so don't allow copy constructors on this platform by default.\n" + "// To enable this feature on 32-bit platforms please define VULKAN_HPP_TYPESAFE_CONVERSION\n" + + generator.getTypesafeCheck() + + "\n" + "# if !defined( VULKAN_HPP_TYPESAFE_CONVERSION )\n" + "# define VULKAN_HPP_TYPESAFE_CONVERSION\n" + "# endif\n" + "#endif\n"; str += defines + "\n" + "namespace VULKAN_HPP_NAMESPACE\n" + "{" + classArrayProxy + classArrayWrapper + classFlags + classOptional + classStructureChain + classUniqueHandle; generator.appendDispatchLoaderStatic( str ); diff --git a/VulkanHppGenerator.hpp b/VulkanHppGenerator.hpp index 2fb6407..d546f86 100644 --- a/VulkanHppGenerator.hpp +++ b/VulkanHppGenerator.hpp @@ -177,9 +177,9 @@ private: { FeatureData( std::string const & number_ ) : number( number_ ) {} - std::vector commands; - std::string number; - std::vector types; + std::vector commands; + std::string number; + std::vector> types; }; struct ExtensionData