Refactored storing of enum values. (#1831)

This commit is contained in:
Andreas Süßenbach 2024-03-25 10:47:09 +01:00 committed by GitHub
parent ce84c37abf
commit 89dd8393db
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 202 additions and 167 deletions

View File

@ -26,6 +26,10 @@
namespace namespace
{ {
std::vector<std::pair<std::string, size_t>> filterNumbers( std::vector<std::string> const & names ); std::vector<std::pair<std::string, size_t>> filterNumbers( std::vector<std::string> const & names );
template <typename T>
typename std::vector<std::pair<std::string, T>>::const_iterator find( std::vector<std::pair<std::string, T>> const & values, std::string const & name );
template <typename T>
typename std::vector<std::pair<std::string, T>>::iterator find( std::vector<std::pair<std::string, T>> & values, std::string const & name );
std::string generateCArraySizes( std::vector<std::string> const & sizes ); std::string generateCArraySizes( std::vector<std::string> const & sizes );
std::string generateList( std::vector<std::string> const & elements, std::string const & prefix, std::string const & separator ); std::string generateList( std::vector<std::string> const & elements, std::string const & prefix, std::string const & separator );
std::string generateNamespacedType( std::string const & type ); std::string generateNamespacedType( std::string const & type );
@ -1120,16 +1124,16 @@ void VulkanHppGenerator::checkCommandCorrectness() const
std::set<std::string> resultCodes; std::set<std::string> resultCodes;
for ( auto rc : resultIt->second.values ) for ( auto rc : resultIt->second.values )
{ {
resultCodes.insert( rc.name ); resultCodes.insert( rc.first );
for ( auto ac : rc.aliases ) for ( auto ac : rc.second.aliases )
{ {
resultCodes.insert( ac.first ); resultCodes.insert( ac.first );
} }
} }
for ( auto rc : resultIt->second.unsupportedValues ) for ( auto rc : resultIt->second.unsupportedValues )
{ {
resultCodes.insert( rc.name ); resultCodes.insert( rc.first );
for ( auto ac : rc.aliases ) for ( auto ac : rc.second.aliases )
{ {
resultCodes.insert( ac.first ); resultCodes.insert( ac.first );
} }
@ -1215,12 +1219,12 @@ void VulkanHppGenerator::checkEnumCorrectness() const
// check that each enum value actually is specified (and not only listed as an alias) // check that each enum value actually is specified (and not only listed as an alias)
for ( auto const & evd : e.second.values ) for ( auto const & evd : e.second.values )
{ {
if ( evd.xmlLine == -1 ) if ( evd.second.xmlLine == -1 )
{ {
assert( !evd.aliases.empty() ); assert( !evd.second.aliases.empty() );
checkForError( false, checkForError( false,
evd.aliases.begin()->second, evd.second.aliases.begin()->second,
"enum alias value <" + evd.aliases.begin()->first + "> is listed as an alias of enum value <" + evd.name + "enum alias value <" + evd.second.aliases.begin()->first + "> is listed as an alias of enum value <" + evd.first +
"> but that value has never been listed" ); "> but that value has never been listed" );
} }
} }
@ -1247,10 +1251,10 @@ void VulkanHppGenerator::checkEnumCorrectness() const
{ {
auto enumIt = m_enums.find( "VkFormat" ); auto enumIt = m_enums.find( "VkFormat" );
assert( enumIt != m_enums.end() ); assert( enumIt != m_enums.end() );
assert( enumIt->second.values.front().name == "VK_FORMAT_UNDEFINED" ); assert( enumIt->second.values.front().first == "VK_FORMAT_UNDEFINED" );
for ( auto enumValueIt = std::next( enumIt->second.values.begin() ); enumValueIt != enumIt->second.values.end(); ++enumValueIt ) for ( auto enumValueIt = std::next( enumIt->second.values.begin() ); enumValueIt != enumIt->second.values.end(); ++enumValueIt )
{ {
checkForError( m_formats.contains( enumValueIt->name ), enumValueIt->xmlLine, "missing format specification for <" + enumValueIt->name + ">" ); checkForError( m_formats.contains( enumValueIt->first ), enumValueIt->second.xmlLine, "missing format specification for <" + enumValueIt->first + ">" );
} }
} }
} }
@ -1441,9 +1445,7 @@ void VulkanHppGenerator::checkHandleCorrectness() const
assert( !handle.second.objTypeEnum.empty() ); assert( !handle.second.objTypeEnum.empty() );
// only check with used handles! // only check with used handles!
checkForError( !isTypeUsed( handle.first ) || std::any_of( objectTypeIt->second.values.begin(), checkForError( !isTypeUsed( handle.first ) || contains( objectTypeIt->second.values, handle.second.objTypeEnum ),
objectTypeIt->second.values.end(),
[&handle]( EnumValueData const & evd ) { return evd.name == handle.second.objTypeEnum; } ),
handle.second.xmlLine, handle.second.xmlLine,
"handle <" + handle.first + "> specifies unknown \"objtypeenum\" <" + handle.second.objTypeEnum + ">" ); "handle <" + handle.first + "> specifies unknown \"objtypeenum\" <" + handle.second.objTypeEnum + ">" );
} }
@ -1452,14 +1454,14 @@ void VulkanHppGenerator::checkHandleCorrectness() const
// check that all specified objectType values are used with a handle type // check that all specified objectType values are used with a handle type
for ( auto const & objectTypeValue : objectTypeIt->second.values ) for ( auto const & objectTypeValue : objectTypeIt->second.values )
{ {
if ( objectTypeValue.name != "VK_OBJECT_TYPE_UNKNOWN" ) if ( objectTypeValue.first != "VK_OBJECT_TYPE_UNKNOWN" )
{ {
checkForError( std::any_of( m_handles.begin(), checkForError( std::any_of( m_handles.begin(),
m_handles.end(), m_handles.end(),
[&objectTypeValue]( std::pair<std::string, HandleData> const & hd ) [&objectTypeValue]( std::pair<std::string, HandleData> const & hd )
{ return hd.second.objTypeEnum == objectTypeValue.name; } ), { return hd.second.objTypeEnum == objectTypeValue.first; } ),
objectTypeValue.xmlLine, objectTypeValue.second.xmlLine,
"VkObjectType value <" + objectTypeValue.name + "> not specified as \"objtypeenum\" for any handle" ); "VkObjectType value <" + objectTypeValue.first + "> not specified as \"objtypeenum\" for any handle" );
} }
} }
} }
@ -1501,13 +1503,14 @@ void VulkanHppGenerator::checkStructCorrectness() const
"VK_STRUCTURE_TYPE_PRIVATE_VENDOR_INFO_PLACEHOLDER_OFFSET_0_NV" }; "VK_STRUCTURE_TYPE_PRIVATE_VENDOR_INFO_PLACEHOLDER_OFFSET_0_NV" };
for ( auto const & enumValue : structureTypeIt->second.values ) for ( auto const & enumValue : structureTypeIt->second.values )
{ {
if ( reservedValues.contains( enumValue.name ) ) if ( reservedValues.contains( enumValue.first ) )
{ {
checkForError( !sTypeValues.contains( enumValue.name ), enumValue.xmlLine, "Reserved VkStructureType enum value <" + enumValue.name + "> is used" ); checkForError(
!sTypeValues.contains( enumValue.first ), enumValue.second.xmlLine, "Reserved VkStructureType enum value <" + enumValue.first + "> is used" );
} }
else else
{ {
checkForWarning( sTypeValues.erase( enumValue.name ) == 1, enumValue.xmlLine, "VkStructureType enum value <" + enumValue.name + "> never used" ); checkForWarning( sTypeValues.erase( enumValue.first ) == 1, enumValue.second.xmlLine, "VkStructureType enum value <" + enumValue.first + "> never used" );
} }
} }
assert( sTypeValues.empty() ); assert( sTypeValues.empty() );
@ -1548,12 +1551,7 @@ void VulkanHppGenerator::checkStructMemberCorrectness( std::string const &
assert( !unionMember.selection.empty() ); assert( !unionMember.selection.empty() );
for ( auto const & selection : unionMember.selection ) for ( auto const & selection : unionMember.selection )
{ {
checkForError( std::any_of( selectorEnumIt->second.values.begin(), checkForError( contains( selectorEnumIt->second.values, selection ) || selectorEnumIt->second.unsupportedValues.contains( selection ),
selectorEnumIt->second.values.end(),
[&selection]( EnumValueData const & evd ) { return evd.name == selection; } ) ||
std::any_of( selectorEnumIt->second.unsupportedValues.begin(),
selectorEnumIt->second.unsupportedValues.end(),
[&selection]( EnumValueData const & evd ) { return evd.name == selection; } ),
unionMember.xmlLine, unionMember.xmlLine,
"union member <" + unionMember.name + "> uses selection <" + selection + "> that is not part of the selector type <" + "union member <" + unionMember.name + "> uses selection <" + selection + "> that is not part of the selector type <" +
selectorIt->type.type + ">" ); selectorIt->type.type + ">" );
@ -1585,11 +1583,10 @@ void VulkanHppGenerator::checkStructMemberCorrectness( std::string const &
// check that the value exists in the specified enum (if the struct is used at all) // check that the value exists in the specified enum (if the struct is used at all)
if ( structUsed ) if ( structUsed )
{ {
checkForError( checkForError( contains( enumIt->second.values, member.value ),
std::any_of( enumIt->second.values.begin(), enumIt->second.values.end(), [&member]( auto const & evd ) { return member.value == evd.name; } ),
member.xmlLine, member.xmlLine,
"value <" + member.value + "> for member <" + member.name + "> in structure <" + structureName + "> of enum type <" + member.type.type + "value <" + member.value + "> for member <" + member.name + "> in structure <" + structureName + "> of enum type <" +
"> not listed" ); member.type.type + "> not listed" );
// special handling for sType: no value should appear more than once // special handling for sType: no value should appear more than once
if ( member.name == "sType" ) if ( member.name == "sType" )
{ {
@ -1668,6 +1665,11 @@ std::string VulkanHppGenerator::combineDataTypes( std::map<size_t, VectorParamDa
return combinedType; return combinedType;
} }
bool VulkanHppGenerator::contains( std::vector<EnumValue> const & enumValues, std::string const & name ) const
{
return std::any_of( enumValues.begin(), enumValues.end(), [&name]( EnumValue const & ev ) { return ev.first == name; } );
}
bool VulkanHppGenerator::containsArray( std::string const & type ) const bool VulkanHppGenerator::containsArray( std::string const & type ) const
{ {
// a simple recursive check if a type is or contains an array // a simple recursive check if a type is or contains an array
@ -2179,19 +2181,18 @@ VulkanHppGenerator::EnumValueData const * VulkanHppGenerator::findEnumValueData(
std::string const & name ) const std::string const & name ) const
{ {
EnumValueData const * evdPtr = nullptr; EnumValueData const * evdPtr = nullptr;
auto evdIt = std::find_if( enumIt->second.values.begin(), enumIt->second.values.end(), [&name]( EnumValueData const & evd ) { return evd.name == name; } ); auto evIt = find( enumIt->second.values, name );
if ( evdIt == enumIt->second.values.end() ) if ( evIt == enumIt->second.values.end() )
{ {
evdIt = std::find_if( auto uvIt = enumIt->second.unsupportedValues.find( name );
enumIt->second.unsupportedValues.begin(), enumIt->second.unsupportedValues.end(), [&name]( EnumValueData const & evd ) { return evd.name == name; } ); if ( uvIt != enumIt->second.unsupportedValues.end() )
if ( evdIt != enumIt->second.unsupportedValues.end() )
{ {
evdPtr = &*evdIt; evdPtr = &uvIt->second;
} }
} }
else else
{ {
evdPtr = &*evdIt; evdPtr = &evIt->second;
} }
return evdPtr; return evdPtr;
} }
@ -2238,17 +2239,17 @@ void VulkanHppGenerator::fixEnumValueIssues()
// fix enum values that are only listed as an alias, but actually are listed as an unsupported value // fix enum values that are only listed as an alias, but actually are listed as an unsupported value
for ( auto & evd : e.second.values ) for ( auto & evd : e.second.values )
{ {
if ( evd.xmlLine == -1 ) if ( evd.second.xmlLine == -1 )
{ {
assert( !evd.aliases.empty() ); assert( !evd.second.aliases.empty() );
auto unsupportedIt = auto unsupportedIt = e.second.unsupportedValues.find( evd.first );
std::find_if( e.second.unsupportedValues.begin(), e.second.unsupportedValues.end(), [&evd]( auto const & uvd ) { return evd.name == uvd.name; } );
if ( unsupportedIt != e.second.unsupportedValues.end() ) if ( unsupportedIt != e.second.unsupportedValues.end() )
{ {
assert( unsupportedIt->second.aliases.empty() );
// "fix" this, by moving that unsupported enum over to the supported // "fix" this, by moving that unsupported enum over to the supported
auto aliases = evd.aliases; auto aliases = evd.second.aliases;
evd = *unsupportedIt; evd.second = unsupportedIt->second;
evd.aliases = aliases; evd.second.aliases = aliases;
e.second.unsupportedValues.erase( unsupportedIt ); e.second.unsupportedValues.erase( unsupportedIt );
} }
} }
@ -2566,11 +2567,11 @@ std::string VulkanHppGenerator::generateBitmask( std::map<std::string, BitmaskDa
{ {
// if the value's protect differs from the surrounding protect, generate protection code // if the value's protect differs from the surrounding protect, generate protection code
std::string enter, leave; std::string enter, leave;
if ( !value.protect.empty() && ( value.protect != surroundingProtect ) ) if ( !value.second.protect.empty() && ( value.second.protect != surroundingProtect ) )
{ {
tie( enter, leave ) = generateProtection( value.protect ); tie( enter, leave ) = generateProtection( value.second.protect );
} }
std::string valueName = generateEnumValueName( bitmaskBitsIt->first, value.name, true ); std::string valueName = generateEnumValueName( bitmaskBitsIt->first, value.first, true );
allFlags += allFlags +=
( ( previousEnter != enter ) ? ( "\n" + previousLeave + enter ) : "\n" ) + " " + ( encounteredFlag ? "| " : " " ) + enumName + "::" + valueName; ( ( previousEnter != enter ) ? ( "\n" + previousLeave + enter ) : "\n" ) + " " + ( encounteredFlag ? "| " : " " ) + enumName + "::" + valueName;
encounteredFlag = true; encounteredFlag = true;
@ -2680,15 +2681,15 @@ ${toStringChecks}
std::string previousEnter, previousLeave; std::string previousEnter, previousLeave;
for ( auto const & value : bitmaskBitsIt->second.values ) for ( auto const & value : bitmaskBitsIt->second.values )
{ {
std::string valueName = generateEnumValueName( bitmaskBitsIt->first, value.name, true ); std::string valueName = generateEnumValueName( bitmaskBitsIt->first, value.first, true );
if ( value.value == "0" ) if ( value.second.value == "0" )
{ {
assert( emptyValue == "{}" ); assert( emptyValue == "{}" );
emptyValue = valueName.substr( 1 ); emptyValue = valueName.substr( 1 );
} }
else if ( !value.bitpos.empty() ) else if ( !value.second.bitpos.empty() )
{ {
const auto [enter, leave] = generateProtection( value.protect ); const auto [enter, leave] = generateProtection( value.second.protect );
toStringChecks += ( ( previousEnter != enter ) ? ( previousLeave + enter ) : "" ) + " if ( value & " + enumName + "::" + valueName + toStringChecks += ( ( previousEnter != enter ) ? ( previousLeave + enter ) : "" ) + " if ( value & " + enumName + "::" + valueName +
" ) result += \"" + valueName.substr( 1 ) + " | \";\n"; " ) result += \"" + valueName.substr( 1 ) + " | \";\n";
previousEnter = enter; previousEnter = enter;
@ -5666,15 +5667,15 @@ std::string VulkanHppGenerator::generateCppModuleUsings() const
// result Exceptions // result Exceptions
auto resultExceptionsUsings = std::string{}; auto resultExceptionsUsings = std::string{};
auto const & [name, data] = *m_enums.find( "VkResult" ); auto const & [name, data] = *m_enums.find( "VkResult" );
for ( auto const & [aliases, bitpos, enumName, protect, value, xmlLine] : data.values ) for ( auto const & value : data.values )
{ {
if ( enumName.starts_with( "VK_ERROR" ) ) if ( value.first.starts_with( "VK_ERROR" ) )
{ {
auto [enter, leave] = generateProtection( protect ); auto [enter, leave] = generateProtection( value.second.protect );
enter = enter.empty() ? enter : "\n" + enter; enter = enter.empty() ? enter : "\n" + enter;
leave = leave.empty() ? leave : leave + "\n"; leave = leave.empty() ? leave : leave + "\n";
auto const valueName = generateEnumValueName( name, enumName, false ); auto const valueName = generateEnumValueName( name, value.first, false );
auto const className = stripPrefix( valueName, "eError" ) + "Error"; auto const className = stripPrefix( valueName, "eError" ) + "Error";
resultExceptionsUsings += enter + replaceWithMap( usingTemplate, { { "className", className } } ) + leave; resultExceptionsUsings += enter + replaceWithMap( usingTemplate, { { "className", className } } ) + leave;
@ -6248,10 +6249,7 @@ std::string VulkanHppGenerator::generateDebugReportObjectType( std::string const
debugReportObjectType = debugReportObjectType.replace( 3, 0, "DEBUG_REPORT_" ) + "_EXT"; debugReportObjectType = debugReportObjectType.replace( 3, 0, "DEBUG_REPORT_" ) + "_EXT";
auto enumIt = m_enums.find( "VkDebugReportObjectTypeEXT" ); auto enumIt = m_enums.find( "VkDebugReportObjectTypeEXT" );
assert( enumIt != m_enums.end() ); assert( enumIt != m_enums.end() );
auto valueIt = std::find_if( enumIt->second.values.begin(), return contains( enumIt->second.values, debugReportObjectType ) ? generateEnumValueName( enumIt->first, debugReportObjectType, false ) : "eUnknown";
enumIt->second.values.end(),
[&debugReportObjectType]( EnumValueData const & evd ) { return debugReportObjectType == evd.name; } );
return ( valueIt == enumIt->second.values.end() ) ? "eUnknown" : generateEnumValueName( enumIt->first, valueIt->name, false );
} }
std::string VulkanHppGenerator::generateDecoratedReturnType( std::string const & name, std::string VulkanHppGenerator::generateDecoratedReturnType( std::string const & name,
@ -6599,24 +6597,24 @@ std::string VulkanHppGenerator::generateEnum( std::pair<std::string, EnumData> c
std::map<std::string, std::string> valueToNameMap; std::map<std::string, std::string> valueToNameMap;
for ( auto const & value : enumData.second.values ) for ( auto const & value : enumData.second.values )
{ {
std::string valueName = generateEnumValueName( enumData.first, value.name, enumData.second.isBitmask ); std::string valueName = generateEnumValueName( enumData.first, value.first, enumData.second.isBitmask );
checkForError( valueToNameMap.insert( { valueName, value.name } ).second, checkForError( valueToNameMap.insert( { valueName, value.first } ).second,
value.xmlLine, value.second.xmlLine,
"generated enum value name <" + valueName + "> already listed for enum <" + enumData.first + ">" ); "generated enum value name <" + valueName + "> already listed for enum <" + enumData.first + ">" );
// if the value's protect differs from the surrounding protect, generate protection code // if the value's protect differs from the surrounding protect, generate protection code
std::string enter, leave; std::string enter, leave;
if ( !value.protect.empty() && ( value.protect != surroundingProtect ) ) if ( !value.second.protect.empty() && ( value.second.protect != surroundingProtect ) )
{ {
tie( enter, leave ) = generateProtection( value.protect ); tie( enter, leave ) = generateProtection( value.second.protect );
} }
if ( previousEnter != enter ) if ( previousEnter != enter )
{ {
enumValues += previousLeave + enter; enumValues += previousLeave + enter;
} }
enumValues += " " + valueName + " = " + value.name + ",\n"; enumValues += " " + valueName + " = " + value.first + ",\n";
for ( auto const & alias : value.aliases ) for ( auto const & alias : value.second.aliases )
{ {
std::string enumName = enumData.first; std::string enumName = enumData.first;
auto aliasIt = std::find_if( m_enumAliases.begin(), m_enumAliases.end(), [&enumData]( auto const & ad ) { return ad.second.name == enumData.first; } ); auto aliasIt = std::find_if( m_enumAliases.begin(), m_enumAliases.end(), [&enumData]( auto const & ad ) { return ad.second.name == enumData.first; } );
@ -6643,7 +6641,7 @@ std::string VulkanHppGenerator::generateEnum( std::pair<std::string, EnumData> c
{ {
// some aliases are so close to the original, that no new entry can be generated! // some aliases are so close to the original, that no new entry can be generated!
assert( mapIt->second != alias.first ); assert( mapIt->second != alias.first );
checkForError( ( mapIt->second == value.name ) || value.aliases.contains( mapIt->second ), checkForError( ( mapIt->second == value.first ) || value.second.aliases.contains( mapIt->second ),
alias.second, alias.second,
"generated enum alias value name <" + aliasName + ">, generated from <" + alias.first + "generated enum alias value name <" + aliasName + ">, generated from <" + alias.first +
"> is already generated from different enum value <" + mapIt->second + ">" ); "> is already generated from different enum value <" + mapIt->second + ">" );
@ -6786,12 +6784,12 @@ std::string VulkanHppGenerator::generateEnumsToString( std::vector<RequireData>
std::string VulkanHppGenerator::generateEnumInitializer( TypeInfo const & type, std::string VulkanHppGenerator::generateEnumInitializer( TypeInfo const & type,
std::vector<std::string> const & arraySizes, std::vector<std::string> const & arraySizes,
std::vector<EnumValueData> const & values, std::vector<EnumValue> const & values,
bool bitmask ) const bool bitmask ) const
{ {
// enum arguments might need special initialization // enum arguments might need special initialization
assert( type.prefix.empty() && !values.empty() ); assert( type.prefix.empty() && !values.empty() );
std::string valueName = generateEnumValueName( type.type, values.front().name, bitmask ); std::string valueName = generateEnumValueName( type.type, values.front().first, bitmask );
std::string value = generateNamespacedType( type.type ) + "::" + valueName; std::string value = generateNamespacedType( type.type ) + "::" + valueName;
std::string str; std::string str;
if ( arraySizes.empty() ) if ( arraySizes.empty() )
@ -6827,7 +6825,7 @@ std::string VulkanHppGenerator::generateEnumToString( std::pair<std::string, Enu
std::string cases, previousEnter, previousLeave; std::string cases, previousEnter, previousLeave;
for ( auto const & value : enumData.second.values ) for ( auto const & value : enumData.second.values )
{ {
const auto [enter, leave] = generateProtection( value.protect ); const auto [enter, leave] = generateProtection( value.second.protect );
if ( previousEnter != enter ) if ( previousEnter != enter )
{ {
cases += previousLeave + enter; cases += previousLeave + enter;
@ -6837,7 +6835,7 @@ std::string VulkanHppGenerator::generateEnumToString( std::pair<std::string, Enu
)"; )";
cases += replaceWithMap( cases += replaceWithMap(
caseTemplate, caseTemplate,
{ { "enumName", enumName }, { "valueName", generateEnumValueName( enumData.first, value.name, enumData.second.isBitmask ).substr( 1 ) } } ); { { "enumName", enumName }, { "valueName", generateEnumValueName( enumData.first, value.first, enumData.second.isBitmask ).substr( 1 ) } } );
previousEnter = enter; previousEnter = enter;
previousLeave = leave; previousLeave = leave;
@ -7323,14 +7321,14 @@ ${texelsPerBlockCases}
auto formatIt = m_enums.find( "VkFormat" ); auto formatIt = m_enums.find( "VkFormat" );
assert( formatIt != m_enums.end() ); assert( formatIt != m_enums.end() );
assert( formatIt->second.values.front().name == "VK_FORMAT_UNDEFINED" ); assert( formatIt->second.values.front().first == "VK_FORMAT_UNDEFINED" );
std::string blockSizeCases, blockExtentCases, classCases, componentBitsCases, componentCountCases, componentNameCases, componentNumericFormatCases, std::string blockSizeCases, blockExtentCases, classCases, componentBitsCases, componentCountCases, componentNameCases, componentNumericFormatCases,
componentPlaneIndexCases, componentsAreCompressedCases, compressionSchemeCases, packedCases, planeCompatibleCases, planeCountCases, planeHeightDivisorCases, componentPlaneIndexCases, componentsAreCompressedCases, compressionSchemeCases, packedCases, planeCompatibleCases, planeCountCases, planeHeightDivisorCases,
planeWidthDivisorCases, texelsPerBlockCases; planeWidthDivisorCases, texelsPerBlockCases;
for ( auto formatValuesIt = std::next( formatIt->second.values.begin() ); formatValuesIt != formatIt->second.values.end(); ++formatValuesIt ) for ( auto formatValuesIt = std::next( formatIt->second.values.begin() ); formatValuesIt != formatIt->second.values.end(); ++formatValuesIt )
{ {
auto traitIt = m_formats.find( formatValuesIt->name ); auto traitIt = m_formats.find( formatValuesIt->first );
assert( traitIt != m_formats.end() ); assert( traitIt != m_formats.end() );
std::string caseString = " case VULKAN_HPP_NAMESPACE::Format::" + generateEnumValueName( "VkFormat", traitIt->first, false ) + ":"; std::string caseString = " case VULKAN_HPP_NAMESPACE::Format::" + generateEnumValueName( "VkFormat", traitIt->first, false ) + ":";
@ -7563,10 +7561,7 @@ std::string VulkanHppGenerator::generateHandle( std::pair<std::string, HandleDat
assert( !handleData.second.objTypeEnum.empty() ); assert( !handleData.second.objTypeEnum.empty() );
auto enumIt = m_enums.find( "VkObjectType" ); auto enumIt = m_enums.find( "VkObjectType" );
assert( enumIt != m_enums.end() ); assert( enumIt != m_enums.end() );
auto valueIt = std::find_if( enumIt->second.values.begin(), assert( contains( enumIt->second.values, handleData.second.objTypeEnum ) );
enumIt->second.values.end(),
[&handleData]( EnumValueData const & evd ) { return evd.name == handleData.second.objTypeEnum; } );
assert( valueIt != enumIt->second.values.end() );
std::string usingAlias; std::string usingAlias;
auto aliasIt = findAlias( handleData.first, m_handleAliases ); auto aliasIt = findAlias( handleData.first, m_handleAliases );
@ -7676,7 +7671,7 @@ ${usingAlias}${leave})";
{ "enter", enter }, { "enter", enter },
{ "leave", leave }, { "leave", leave },
{ "memberName", startLowerCase( stripPrefix( handleData.first, "Vk" ) ) }, { "memberName", startLowerCase( stripPrefix( handleData.first, "Vk" ) ) },
{ "objTypeEnum", generateEnumValueName( enumIt->first, valueIt->name, false ) }, { "objTypeEnum", generateEnumValueName( enumIt->first, handleData.second.objTypeEnum, false ) },
{ "usingAlias", usingAlias }, { "usingAlias", usingAlias },
{ "typesafeExplicitKeyword", typesafeExplicitKeyword }, { "typesafeExplicitKeyword", typesafeExplicitKeyword },
{ "typesafeConversionConditional", typesafeConversionConditional }, { "typesafeConversionConditional", typesafeConversionConditional },
@ -7914,10 +7909,10 @@ ${indexTypeTraits}
std::string indexTypeTraits; std::string indexTypeTraits;
for ( auto const & value : indexType->second.values ) for ( auto const & value : indexType->second.values )
{ {
assert( value.name.starts_with( "VK_INDEX_TYPE_UINT" ) || value.name.starts_with( "VK_INDEX_TYPE_NONE" ) ); assert( value.first.starts_with( "VK_INDEX_TYPE_UINT" ) || value.first.starts_with( "VK_INDEX_TYPE_NONE" ) );
if ( value.name.starts_with( "VK_INDEX_TYPE_UINT" ) ) if ( value.first.starts_with( "VK_INDEX_TYPE_UINT" ) )
{ {
std::string valueName = generateEnumValueName( indexType->first, value.name, false ); std::string valueName = generateEnumValueName( indexType->first, value.first, false );
assert( valueName.starts_with( "eUint" ) ); assert( valueName.starts_with( "eUint" ) );
auto beginDigit = valueName.begin() + strlen( "eUint" ); auto beginDigit = valueName.begin() + strlen( "eUint" );
assert( isdigit( *beginDigit ) ); assert( isdigit( *beginDigit ) );
@ -8320,18 +8315,14 @@ std::string VulkanHppGenerator::generateRAIIHandle( std::pair<std::string, Handl
assert( !handle.second.objTypeEnum.empty() ); assert( !handle.second.objTypeEnum.empty() );
auto enumIt = m_enums.find( "VkObjectType" ); auto enumIt = m_enums.find( "VkObjectType" );
assert( enumIt != m_enums.end() ); assert( enumIt != m_enums.end() );
auto valueIt = std::find_if( assert( contains( enumIt->second.values, handle.second.objTypeEnum ) );
enumIt->second.values.begin(), enumIt->second.values.end(), [&handle]( EnumValueData const & evd ) { return evd.name == handle.second.objTypeEnum; } ); std::string objTypeEnum = generateEnumValueName( enumIt->first, handle.second.objTypeEnum, false );
assert( valueIt != enumIt->second.values.end() );
std::string objTypeEnum = generateEnumValueName( enumIt->first, valueIt->name, false );
enumIt = m_enums.find( "VkDebugReportObjectTypeEXT" ); enumIt = m_enums.find( "VkDebugReportObjectTypeEXT" );
assert( enumIt != m_enums.end() ); assert( enumIt != m_enums.end() );
std::string valueName = handle.second.objTypeEnum; std::string valueName = handle.second.objTypeEnum;
valueName = valueName.replace( 3, 0, "DEBUG_REPORT_" ) + "_EXT"; valueName = valueName.replace( 3, 0, "DEBUG_REPORT_" ) + "_EXT";
valueIt = std::string debugReportObjectType = contains( enumIt->second.values, valueName ) ? generateEnumValueName( enumIt->first, valueName, false ) : "eUnknown";
std::find_if( enumIt->second.values.begin(), enumIt->second.values.end(), [&valueName]( EnumValueData const & evd ) { return valueName == evd.name; } );
std::string debugReportObjectType = ( valueIt != enumIt->second.values.end() ) ? generateEnumValueName( enumIt->first, valueIt->name, false ) : "eUnknown";
std::string dispatcherType = ( ( handle.first == "VkDevice" ) || ( handle.second.constructorIts.front()->second.params.front().type.type == "VkDevice" ) ) std::string dispatcherType = ( ( handle.first == "VkDevice" ) || ( handle.second.constructorIts.front()->second.params.front().type.type == "VkDevice" ) )
? "VULKAN_HPP_NAMESPACE::VULKAN_HPP_RAII_NAMESPACE::DeviceDispatcher" ? "VULKAN_HPP_NAMESPACE::VULKAN_HPP_RAII_NAMESPACE::DeviceDispatcher"
@ -9883,10 +9874,10 @@ ${leave})";
auto enumIt = m_enums.find( "VkResult" ); auto enumIt = m_enums.find( "VkResult" );
for ( auto const & value : enumIt->second.values ) for ( auto const & value : enumIt->second.values )
{ {
if ( value.name.starts_with( "VK_ERROR" ) ) if ( value.first.starts_with( "VK_ERROR" ) )
{ {
auto [enter, leave] = generateProtection( value.protect ); auto [enter, leave] = generateProtection( value.second.protect );
std::string valueName = generateEnumValueName( enumIt->first, value.name, false ); std::string valueName = generateEnumValueName( enumIt->first, value.first, false );
str += replaceWithMap( templateString, str += replaceWithMap( templateString,
{ { "className", stripPrefix( valueName, "eError" ) + "Error" }, { { "className", stripPrefix( valueName, "eError" ) + "Error" },
{ "enter", enter }, { "enter", enter },
@ -11293,11 +11284,8 @@ std::tuple<std::string, std::string, std::string, std::string>
{ {
auto enumIt = m_enums.find( member.type.type ); auto enumIt = m_enums.find( member.type.type );
assert( enumIt != m_enums.end() ); assert( enumIt != m_enums.end() );
std::string enumValue = member.value; assert( contains( enumIt->second.values, member.value ) );
auto valueIt = std::find_if( std::string valueName = generateEnumValueName( enumIt->first, member.value, enumIt->second.isBitmask );
enumIt->second.values.begin(), enumIt->second.values.end(), [&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 );
members += stripPrefix( member.type.type, "Vk" ) + "::" + valueName; members += stripPrefix( member.type.type, "Vk" ) + "::" + valueName;
if ( member.name == "sType" ) if ( member.name == "sType" )
{ {
@ -11610,10 +11598,10 @@ std::string VulkanHppGenerator::generateThrowResultException() const
std::string cases; std::string cases;
for ( auto const & value : enumIt->second.values ) for ( auto const & value : enumIt->second.values )
{ {
if ( value.name.starts_with( "VK_ERROR" ) ) if ( value.first.starts_with( "VK_ERROR" ) )
{ {
const auto [enter, leave] = generateProtection( value.protect ); const auto [enter, leave] = generateProtection( value.second.protect );
std::string valueName = generateEnumValueName( enumIt->first, value.name, false ); std::string valueName = generateEnumValueName( enumIt->first, value.first, false );
cases += enter + " case Result::" + valueName + ": throw " + stripPrefix( valueName, "eError" ) + "Error( message );\n" + leave; cases += enter + " case Result::" + valueName + ": throw " + stripPrefix( valueName, "eError" ) + "Error( message );\n" + leave;
} }
} }
@ -12348,7 +12336,7 @@ void VulkanHppGenerator::handleRemoval( RemoveData const & removeData )
bool removed = false; bool removed = false;
for ( auto enumIt = m_enums.begin(); !removed && enumIt != m_enums.end(); ++enumIt ) for ( auto enumIt = m_enums.begin(); !removed && enumIt != m_enums.end(); ++enumIt )
{ {
auto valueIt = std::find_if( enumIt->second.values.begin(), enumIt->second.values.end(), [&e]( EnumValueData const evd ) { return evd.name == e; } ); auto valueIt = find( enumIt->second.values, e );
if ( valueIt != enumIt->second.values.end() ) if ( valueIt != enumIt->second.values.end() )
{ {
enumIt->second.values.erase( valueIt ); enumIt->second.values.erase( valueIt );
@ -13575,19 +13563,13 @@ void VulkanHppGenerator::readFormat( tinyxml2::XMLElement const * element )
auto formatIt = m_enums.find( "VkFormat" ); auto formatIt = m_enums.find( "VkFormat" );
assert( formatIt != m_enums.end() ); assert( formatIt != m_enums.end() );
auto valueIt = if ( contains( formatIt->second.values, name ) )
std::find_if( formatIt->second.values.begin(), formatIt->second.values.end(), [&name]( EnumValueData const & evd ) { return evd.name == name; } );
if ( valueIt != formatIt->second.values.end() )
{ {
checkForError( m_formats.insert( { name, format } ).second, line, "format <" + name + "> already specified" ); checkForError( m_formats.insert( { name, format } ).second, line, "format <" + name + "> already specified" );
} }
else else
{ {
checkForError( std::any_of( formatIt->second.unsupportedValues.begin(), checkForError( formatIt->second.unsupportedValues.contains( name ), line, "unknown format <" + name + ">" );
formatIt->second.unsupportedValues.end(),
[&name]( EnumValueData const & evd ) { return evd.name == name; } ),
line,
"unknown format <" + name + ">" );
} }
} }
@ -13647,11 +13629,7 @@ void VulkanHppGenerator::readFormatPlane( tinyxml2::XMLElement const * element,
plane.compatible = attribute.second; plane.compatible = attribute.second;
auto formatIt = m_enums.find( "VkFormat" ); auto formatIt = m_enums.find( "VkFormat" );
assert( formatIt != m_enums.end() ); assert( formatIt != m_enums.end() );
checkForError( std::any_of( formatIt->second.values.begin(), checkForError( contains( formatIt->second.values, plane.compatible ), line, "encountered unknown format <" + plane.compatible + ">" );
formatIt->second.values.end(),
[&plane]( EnumValueData const & evd ) { return evd.name == plane.compatible; } ),
line,
"encountered unknown format <" + plane.compatible + ">" );
} }
else if ( attribute.first == "index" ) else if ( attribute.first == "index" )
{ {
@ -14127,11 +14105,7 @@ void VulkanHppGenerator::readSPIRVCapabilityEnable( tinyxml2::XMLElement const *
const auto enumIt = m_enums.find( bitmaskIt->second.require ); const auto enumIt = m_enums.find( bitmaskIt->second.require );
checkForError( checkForError(
enumIt != m_enums.end(), line, "member <" + member + "> specified for SPIR-V capability requires an unknown enum <" + bitmaskIt->second.require + ">" ); enumIt != m_enums.end(), line, "member <" + member + "> specified for SPIR-V capability requires an unknown enum <" + bitmaskIt->second.require + ">" );
checkForError( checkForError( contains( enumIt->second.values, value ) || enumIt->second.unsupportedValues.contains( value ),
std::any_of( enumIt->second.values.begin(), enumIt->second.values.end(), [&value]( EnumValueData const & evd ) { return evd.name == value; } ) ||
std::any_of( enumIt->second.unsupportedValues.begin(),
enumIt->second.unsupportedValues.end(),
[&value]( EnumValueData const & evd ) { return evd.name == value; } ),
line, line,
"unknown attribute value <" + value + "> specified for SPIR-V capability" ); "unknown attribute value <" + value + "> specified for SPIR-V capability" );
} }
@ -14428,11 +14402,13 @@ void VulkanHppGenerator::readSyncAccess( tinyxml2::XMLElement const *
std::vector<tinyxml2::XMLElement const *> children = getChildElements( element ); std::vector<tinyxml2::XMLElement const *> children = getChildElements( element );
checkElements( line, children, {}, { "comment", "syncequivalent", "syncsupport" } ); checkElements( line, children, {}, { "comment", "syncequivalent", "syncsupport" } );
std::string aliasName;
EnumValueData const * aliasPtr = nullptr; EnumValueData const * aliasPtr = nullptr;
for ( auto const & attribute : attributes ) for ( auto const & attribute : attributes )
{ {
if ( attribute.first == "alias" ) if ( attribute.first == "alias" )
{ {
aliasName = attribute.second;
aliasPtr = findEnumValueData( accessFlagBitsIt, attribute.second ); aliasPtr = findEnumValueData( accessFlagBitsIt, attribute.second );
checkForError( aliasPtr != nullptr, line, "syncaccess alias <" + attribute.second + "> not specified as a VkAccessFlagBits value!" ); checkForError( aliasPtr != nullptr, line, "syncaccess alias <" + attribute.second + "> not specified as a VkAccessFlagBits value!" );
} }
@ -14445,7 +14421,7 @@ void VulkanHppGenerator::readSyncAccess( tinyxml2::XMLElement const *
{ {
checkForError( ( aliasPtr->value == namePtr->value ) && ( aliasPtr->bitpos == namePtr->bitpos ), checkForError( ( aliasPtr->value == namePtr->value ) && ( aliasPtr->bitpos == namePtr->bitpos ),
line, line,
"syncaccess name <" + attribute.second + "> has an alias <" + aliasPtr->name + "> with a different value or bitpos!" ); "syncaccess name <" + attribute.second + "> has an alias <" + aliasName + "> with a different value or bitpos!" );
} }
} }
} }
@ -14536,11 +14512,13 @@ void VulkanHppGenerator::readSyncStage( tinyxml2::XMLElement const *
std::vector<tinyxml2::XMLElement const *> children = getChildElements( element ); std::vector<tinyxml2::XMLElement const *> children = getChildElements( element );
checkElements( line, children, {}, { "syncequivalent", "syncsupport" } ); checkElements( line, children, {}, { "syncequivalent", "syncsupport" } );
std::string aliasName;
EnumValueData const * aliasPtr = nullptr; EnumValueData const * aliasPtr = nullptr;
for ( auto const & attribute : attributes ) for ( auto const & attribute : attributes )
{ {
if ( attribute.first == "alias" ) if ( attribute.first == "alias" )
{ {
aliasName = attribute.second;
aliasPtr = findEnumValueData( stageFlagBitsIt, attribute.second ); aliasPtr = findEnumValueData( stageFlagBitsIt, attribute.second );
checkForError( aliasPtr != nullptr, line, "syncstage alias <" + attribute.second + "> not specified as a VkPipelineStageFlagBits value!" ); checkForError( aliasPtr != nullptr, line, "syncstage alias <" + attribute.second + "> not specified as a VkPipelineStageFlagBits value!" );
} }
@ -14553,7 +14531,7 @@ void VulkanHppGenerator::readSyncStage( tinyxml2::XMLElement const *
{ {
checkForError( ( aliasPtr->value == namePtr->value ) && ( aliasPtr->bitpos == namePtr->bitpos ), checkForError( ( aliasPtr->value == namePtr->value ) && ( aliasPtr->bitpos == namePtr->bitpos ),
line, line,
"syncstate name <" + attribute.second + "> has an alias <" + aliasPtr->name + "> with a different value or bitpos!" ); "syncstate name <" + attribute.second + "> has an alias <" + aliasName + "> with a different value or bitpos!" );
} }
} }
} }
@ -15407,43 +15385,88 @@ std::string VulkanHppGenerator::toString( TypeCategory category )
void VulkanHppGenerator::EnumData::addEnumAlias( int line, std::string const & name, std::string const & alias, std::string const & protect, bool supported ) void VulkanHppGenerator::EnumData::addEnumAlias( int line, std::string const & name, std::string const & alias, std::string const & protect, bool supported )
{ {
auto & valuesRef = supported ? values : unsupportedValues; EnumValueData * valuePtr = nullptr;
auto valueIt = if ( supported )
std::find_if( valuesRef.begin(), valuesRef.end(), [&alias]( EnumValueData const & evd ) { return evd.name == alias || evd.aliases.contains( alias ); } );
if ( valueIt == valuesRef.end() )
{ {
// the alias is defined before the aliased enum!! -> insert a preliminary enum value with bitpos or value auto valueIt = find( values, alias );
addEnumValue( -1, alias, "", "", "", supported ); if ( valueIt == values.end() )
assert( valuesRef.back().name == alias ); {
valueIt = std::prev( valuesRef.end() ); valueIt = std::find_if( values.begin(), values.end(), [alias]( auto const value ) { return value.second.aliases.contains( alias ); } );
} }
checkForError( protect == valueIt->protect, if ( valueIt != values.end() )
{
valuePtr = &valueIt->second;
}
}
else
{
auto valueIt = unsupportedValues.find( alias );
if ( valueIt == unsupportedValues.end() )
{
valueIt =
std::find_if( unsupportedValues.begin(), unsupportedValues.end(), [alias]( auto const value ) { return value.second.aliases.contains( alias ); } );
}
if ( valueIt != unsupportedValues.end() )
{
valuePtr = &valueIt->second;
}
}
if ( valuePtr )
{
checkForError( protect == valuePtr->protect,
line, line,
"enum alias value <" + name + "> uses a different protection <" + protect + "> than the aliased enum value <" + alias + ">" ); "enum alias value <" + name + "> uses a different protection <" + protect + "> than the aliased enum value <" + alias + ">" );
valueIt->aliases.insert( { name, line } ); // it happens, that the very same alias is listed multiple times -> no error check here! valuePtr->aliases.insert( { name, line } ); // it happens, that the very same alias is listed multiple times -> no error check here!
}
else
{
// the alias is defined before the aliased enum!! -> insert a preliminary enum on line -1 and add this alias again
addEnumValue( -1, alias, "", "", "", supported );
addEnumAlias( line, name, alias, protect, supported );
}
} }
void VulkanHppGenerator::EnumData::addEnumValue( void VulkanHppGenerator::EnumData::addEnumValue(
int line, std::string const & name, std::string const & protect, std::string const & bitpos, std::string const & value, bool supported ) int line, std::string const & name, std::string const & protect, std::string const & bitpos, std::string const & value, bool supported )
{ {
auto & valuesRef = supported ? values : unsupportedValues; EnumValueData * valuePtr = nullptr;
auto valueIt = std::find_if( valuesRef.begin(), valuesRef.end(), [&name]( EnumValueData const & evd ) { return evd.name == name; } ); if ( supported )
if ( valueIt == valuesRef.end() )
{ {
valuesRef.push_back( { {}, bitpos, name, protect, value, line } ); auto valueIt = find( values, name );
if ( valueIt != values.end() )
{
valuePtr = &valueIt->second;
} }
else if ( valueIt->xmlLine == -1 )
{
// this enum value has been listed by an alias before!
assert( !valueIt->aliases.empty() && valueIt->bitpos.empty() && valueIt->protect.empty() && valueIt->value.empty() );
valueIt->bitpos = bitpos;
valueIt->protect = protect;
valueIt->value = value;
valueIt->xmlLine = line;
} }
else else
{ {
checkForError( ( protect == valueIt->protect ) && ( bitpos == valueIt->bitpos ) && ( value == valueIt->value ), auto valueIt = unsupportedValues.find( name );
if ( valueIt != unsupportedValues.end() )
{
valuePtr = &valueIt->second;
}
}
if ( !valuePtr )
{
if ( supported )
{
values.push_back( { name, { {}, bitpos, protect, value, line } } );
}
else
{
unsupportedValues.insert( { name, { {}, bitpos, protect, value, line } } );
}
}
else if ( valuePtr->xmlLine == -1 )
{
// this enum value has been listed by an alias before!
assert( !valuePtr->aliases.empty() && valuePtr->bitpos.empty() && valuePtr->protect.empty() && valuePtr->value.empty() );
*valuePtr = { valuePtr->aliases, bitpos, protect, value, line };
}
else
{
checkForError( ( protect == valuePtr->protect ) && ( bitpos == valuePtr->bitpos ) && ( value == valuePtr->value ),
line, line,
"enum value <" + name + "> already listed with different properties" ); "enum value <" + name + "> already listed with different properties" );
} }
@ -15468,6 +15491,18 @@ namespace
return filteredNames; return filteredNames;
} }
template <typename T>
typename std::vector<std::pair<std::string, T>>::const_iterator find( std::vector<std::pair<std::string, T>> const & values, std::string const & name )
{
return std::find_if( values.begin(), values.end(), [&name]( std::pair<std::string, T> const & value ) { return value.first == name; } );
}
template <typename T>
typename std::vector<std::pair<std::string, T>>::iterator find( std::vector<std::pair<std::string, T>> & values, std::string const & name )
{
return std::find_if( values.begin(), values.end(), [&name]( std::pair<std::string, T> const & value ) { return value.first == name; } );
}
std::string generateCArraySizes( std::vector<std::string> const & sizes ) std::string generateCArraySizes( std::vector<std::string> const & sizes )
{ {
std::string arraySizes; std::string arraySizes;

View File

@ -137,12 +137,13 @@ private:
{ {
std::map<std::string, int> aliases = {}; std::map<std::string, int> aliases = {};
std::string bitpos = {}; std::string bitpos = {};
std::string name = {};
std::string protect = {}; std::string protect = {};
std::string value = {}; std::string value = {};
int xmlLine = {}; int xmlLine = {};
}; };
using EnumValue = std::pair<std::string, EnumValueData>;
struct EnumData struct EnumData
{ {
void addEnumAlias( int line, std::string const & name, std::string const & alias, std::string const & protect, bool supported ); void addEnumAlias( int line, std::string const & name, std::string const & alias, std::string const & protect, bool supported );
@ -151,8 +152,8 @@ private:
std::string bitwidth = {}; std::string bitwidth = {};
bool isBitmask = false; bool isBitmask = false;
std::vector<EnumValueData> unsupportedValues = {}; std::map<std::string, EnumValueData> unsupportedValues = {};
std::vector<EnumValueData> values = {}; std::vector<EnumValue> values = {};
int xmlLine = {}; int xmlLine = {};
}; };
@ -428,6 +429,7 @@ private:
std::vector<std::string> const & dataTypes, std::vector<std::string> const & dataTypes,
CommandFlavourFlags flavourFlags, CommandFlavourFlags flavourFlags,
bool raii ) const; bool raii ) const;
bool contains( std::vector<EnumValue> const & enumValues, std::string const & name ) const;
bool containsArray( std::string const & type ) const; bool containsArray( std::string const & type ) const;
bool containsFuncPointer( std::string const & type ) const; bool containsFuncPointer( std::string const & type ) const;
bool containsFloatingPoints( std::vector<MemberData> const & members ) const; bool containsFloatingPoints( std::vector<MemberData> const & members ) const;
@ -700,10 +702,8 @@ private:
std::set<std::string> & listedCommands, std::set<std::string> & listedCommands,
std::string const & title ) const; std::string const & title ) const;
std::string generateEnum( std::pair<std::string, EnumData> const & enumData, std::string const & surroundingProtect ) const; std::string generateEnum( std::pair<std::string, EnumData> const & enumData, std::string const & surroundingProtect ) const;
std::string generateEnumInitializer( TypeInfo const & type, std::string
std::vector<std::string> const & arraySizes, generateEnumInitializer( TypeInfo const & type, std::vector<std::string> const & arraySizes, std::vector<EnumValue> const & values, bool bitmask ) const;
std::vector<EnumValueData> const & values,
bool bitmask ) const;
std::string generateEnums() const; std::string generateEnums() const;
std::string generateEnums( std::vector<RequireData> const & requireData, std::set<std::string> & listedEnums, std::string const & title ) const; std::string generateEnums( std::vector<RequireData> const & requireData, std::set<std::string> & listedEnums, std::string const & title ) const;
std::string generateEnumsToString() const; std::string generateEnumsToString() const;