| 10482 | } |
| 10483 | |
| 10484 | std::string VulkanHppGenerator::generateStructCompareOperators( std::pair<std::string, StructData> const & structData ) const |
| 10485 | { |
| 10486 | static std::set<std::string> const simpleTypes = { "char", "double", "DWORD", "float", "HANDLE", "HINSTANCE", "HMONITOR", |
| 10487 | "HWND", "int", "int8_t", "int16_t", "int32_t", "int64_t", "LPCWSTR", |
| 10488 | "size_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t" }; |
| 10489 | // two structs are compared by comparing each of the elements |
| 10490 | std::string compareMembers, spaceshipMembers; |
| 10491 | std::string intro = ""; |
| 10492 | bool nonDefaultCompare = false; |
| 10493 | std::string spaceshipOrdering = containsFloatingPoints( structData.second.members ) ? "std::partial_ordering" : "std::strong_ordering"; |
| 10494 | for ( size_t i = 0; i < structData.second.members.size(); i++ ) |
| 10495 | { |
| 10496 | MemberData const & member = structData.second.members[i]; |
| 10497 | if ( member.deprecated.empty() ) |
| 10498 | { |
| 10499 | auto typeIt = m_types.find( member.type.name ); |
| 10500 | assert( typeIt != m_types.end() ); |
| 10501 | if ( ( typeIt->second.category == TypeCategory::ExternalType ) && member.type.postfix.empty() && !simpleTypes.contains( member.type.name ) ) |
| 10502 | { |
| 10503 | nonDefaultCompare = true; |
| 10504 | // this type might support operator==() or operator<=>()... that is, use memcmp |
| 10505 | compareMembers += intro + "( memcmp( &" + member.name + ", &rhs." + member.name + ", sizeof( " + member.type.name + " ) ) == 0 )"; |
| 10506 | |
| 10507 | static std::string const spaceshipMemberTemplate = |
| 10508 | R"( if ( auto cmp = memcmp( &${name}, &rhs.${name}, sizeof( ${type} ) ); cmp != 0 ) |
| 10509 | return ( cmp < 0 ) ? ${ordering}::less : ${ordering}::greater; |
| 10510 | )"; |
| 10511 | spaceshipMembers += |
| 10512 | replaceWithMap( spaceshipMemberTemplate, { { "name", member.name }, { "ordering", spaceshipOrdering }, { "type", member.type.name } } ); |
| 10513 | } |
| 10514 | else if ( member.type.name == "char" && !member.lenExpressions.empty() ) |
| 10515 | { |
| 10516 | // compare null-terminated strings |
| 10517 | nonDefaultCompare = true; |
| 10518 | assert( member.lenExpressions.size() < 3 ); |
| 10519 | if ( member.lenExpressions.size() == 1 ) |
| 10520 | { |
| 10521 | assert( member.lenExpressions[0] == "null-terminated" ); |
| 10522 | if ( member.arraySizes.empty() ) |
| 10523 | { |
| 10524 | compareMembers += |
| 10525 | intro + "( ( " + member.name + " == rhs." + member.name + " ) || ( strcmp( " + member.name + ", rhs." + member.name + " ) == 0 ) )"; |
| 10526 | |
| 10527 | static std::string const spaceshipMemberTemplate = |
| 10528 | R"( if ( ${name} != rhs.${name} ) |
| 10529 | if ( auto cmp = strcmp( ${name}, rhs.${name} ); cmp != 0 ) |
| 10530 | return ( cmp < 0 ) ? ${ordering}::less : ${ordering}::greater; |
| 10531 | )"; |
| 10532 | spaceshipMembers += replaceWithMap( spaceshipMemberTemplate, { { "name", member.name }, { "ordering", spaceshipOrdering } } ); |
| 10533 | } |
| 10534 | else |
| 10535 | { |
| 10536 | assert( member.arraySizes.size() == 1 ); |
| 10537 | compareMembers += intro + "( strcmp( " + member.name + ", rhs." + member.name + " ) == 0 )"; |
| 10538 | |
| 10539 | static std::string const spaceshipMemberTemplate = |
| 10540 | R"( if ( auto cmp = strcmp( ${name}, rhs.${name} ); cmp != 0 ) |
| 10541 | return ( cmp < 0 ) ? ${ordering}::less : ${ordering}::greater; |
nothing calls this directly
no test coverage detected