Merge pull request #106 from asuessenbach/DirectAccess

Changed struct/union wrappers from class to struct/union, directly containing the members of the native struct/union

*no accessor functions to those members any more, but just direct access to them available;
*modified "named parameter idiom" to use setter-functions with the prefix "set", continuing with an uppercase letter;
*If the C++11 feature "unrestricted unions" is not supported, unions may hold the native vulkan datatypes, instead of those from the vk-namespace (in fact, it's just the vk::ClearValue that needs handling here). For clang, gcc, and MSVC compiler, the support of/version supporting this feature is checked; for other compilers, you need to check on your own and define VK_CPP_HAS_UNRESTRICTED_UNIONS if appropriate.
This commit is contained in:
Markus Tavenrath 2016-05-10 16:14:33 +02:00
commit 9c55803341
3 changed files with 3960 additions and 11330 deletions

View File

@ -40,7 +40,6 @@ errors into compile errors. Following is a list of features and conventions intr
* defines all symbols within the 'vk' namespace and to avoid redundancy the vk/Vk/VK_ prefixes have been removed from all symbols, i.e. ```vk::ImageCreateInfo``` for VkImageCreateInfo. * defines all symbols within the 'vk' namespace and to avoid redundancy the vk/Vk/VK_ prefixes have been removed from all symbols, i.e. ```vk::ImageCreateInfo``` for VkImageCreateInfo.
* camel case syntax with an 'e' prefix has been introduced for all enums, i.e. ```vk::ImageType::e2D``` (the prefix was a compromise, more about that later) removes the 'BIT' suffix from all flag related enums, i.e. ```vk::ImageUsage::eColorAttachment```. * camel case syntax with an 'e' prefix has been introduced for all enums, i.e. ```vk::ImageType::e2D``` (the prefix was a compromise, more about that later) removes the 'BIT' suffix from all flag related enums, i.e. ```vk::ImageUsage::eColorAttachment```.
* introduces constructors for all structs, which by default set the appropriate ```sType``` and all other values to zero. * introduces constructors for all structs, which by default set the appropriate ```sType``` and all other values to zero.
* encapsulates member variables of the structs with getter and setter functions, i.e. ```ci.imageType()``` to get a value and ```ci.imageType(vk::ImageType::e2D)``` to set a value.
* introduces wrapper classes around the vulkan handles, i.e. ```vk::CommandBuffer``` for VkCommandBuffer * introduces wrapper classes around the vulkan handles, i.e. ```vk::CommandBuffer``` for VkCommandBuffer
* introduces member functions of those wrapper classes, that map to vulkan functions getting the corresponding vulkan handle as its first argument. The type of that handle is stripped from the function name, i.e. ```vk::Device::getProcAddr``` for vkGetDeviceProcAddr. Note the special handling for the class CommandBuffer, where most of the vulkan functions would just include "Cmd", instead of "CommandBuffer", i.e. ```vk::CommandBuffer::bindPipeline``` for vkCmdBindPipeline. * introduces member functions of those wrapper classes, that map to vulkan functions getting the corresponding vulkan handle as its first argument. The type of that handle is stripped from the function name, i.e. ```vk::Device::getProcAddr``` for vkGetDeviceProcAddr. Note the special handling for the class CommandBuffer, where most of the vulkan functions would just include "Cmd", instead of "CommandBuffer", i.e. ```vk::CommandBuffer::bindPipeline``` for vkCmdBindPipeline.
With those changes applied, the updated code snippet looks like this: With those changes applied, the updated code snippet looks like this:
@ -48,19 +47,19 @@ With those changes applied, the updated code snippet looks like this:
```c++ ```c++
vk::ImageCreateInfo ci; vk::ImageCreateInfo ci;
ci.flags(...some flags...); ci.flags = ...some flags...;
ci.imageType(vk::ImageType::e2D); ci.imageType = vk::ImageType::e2D;
ci.format(vk::Format::eR8G8B8A8Unorm); ci.format = vk::Format::eR8G8B8A8Unorm;
ci.extent(vk::Extent3D { width, height, 1 }); ci.extent = vk::Extent3D { width, height, 1 };
ci.mipLevels(1); ci.mipLevels = 1;
ci.arrayLayers(1); ci.arrayLayers = 1;
ci.samples(1); ci.samples = 1;
ci.tiling(vk::ImageTiling::eOptimal); ci.tiling = vk::ImageTiling::eOptimal;
ci.usage(vk::ImageUsage::eColorAttachment); ci.usage = vk::ImageUsage::eColorAttachment;
ci.sharingMode(vk::SharingMode::eExclusive); ci.sharingMode = vk::SharingMode::eExclusive;
// ci.queueFamilyIndexCount(0) // no need to set, already initialized // ci.queueFamilyIndexCount = 0 // no need to set, already initialized
// ci.pQueueFamilyIndices(0) // no need to set, already initialized // ci.pQueueFamilyIndices = 0 // no need to set, already initialized
ci.initialLayout(vk::ImageLayout::eUndefined); ci.initialLayout = vk::ImageLayout::eUndefined;
device.createImage(&ci, allocator, &image); device.createImage(&ci, allocator, &image);
``` ```
@ -113,23 +112,23 @@ we have implemented ```to_string(type)``` functions for all enums and flags. Cal
Another nice feature of those constructors is that sType is being initialized internally and thus is always correct. Another nice feature of those constructors is that sType is being initialized internally and thus is always correct.
Finally, we have added a default constructor to each struct which initializes all values to 0 to allow setting the values with the named parameter idiom which is similar to the designated initializer list of C99. Finally, we have added a default constructor to each struct which initializes all values to 0 to allow setting the values with a variant of the named parameter idiom which is similar to the designated initializer list of C99.
```c++ ```c++
vk::ImageCreateInfo ci = vk::ImageCreateInfo() vk::ImageCreateInfo ci = vk::ImageCreateInfo()
.flags(...some flags...) .setFlags(...some flags...)
.imageType(vk::ImageType::e2D) .setImageType(vk::ImageType::e2D)
.format(vk::Format::eR8G8B8A8Unorm) .setFormat(vk::Format::eR8G8B8A8Unorm)
.extent(vk::Extent3D { width, height, 1 }) .setExtent(vk::Extent3D { width, height, 1 })
.mipLevels(1) .setMipLevels(1)
.arrayLayers(1) .setArrayLayers(1)
.samples(1) .setSamples(1)
.tiling(vk::ImageTiling::eOptimal) .setTiling(vk::ImageTiling::eOptimal)
.usage(vk::ImageUsage::eColorAttachment) .setUsage(vk::ImageUsage::eColorAttachment)
.sharingMode(vk::SharingMode::eExclusive) .setSharingMode(vk::SharingMode::eExclusive)
// .queueFamilyIndexCount(0) // no need to set, already initialized // .setQueueFamilyIndexCount(0) // no need to set, already initialized
// .pQueueFamilyIndices(0) // no need to set, already initialized // .setPQueueFamilyIndices(0) // no need to set, already initialized
.initialLayout(vk::ImageLayout::eUndefined); .setInitialLayout(vk::ImageLayout::eUndefined);
device.createImage(&ci, allocator, &image); device.createImage(&ci, allocator, &image);
``` ```

View File

@ -294,6 +294,26 @@ std::string const arrayProxyHeader = (
"\n" "\n"
); );
std::string const versionCheckHeader = (
"#if !defined(VK_CPP_HAS_UNRESTRICTED_UNIONS)\n"
"# if defined(__clang__)\n"
"# if __has_feature(cxx_unrestricted_unions)\n"
"# define VK_CPP_HAS_UNRESTRICTED_UNIONS\n"
"# endif\n"
"# elif defined(__GNUC__)\n"
"# define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)\n"
"# if 40600 <= GCC_VERSION\n"
"# define VK_CPP_HAS_UNRESTRICTED_UNIONS\n"
"# endif\n"
"# elif defined(_MSC_VER)\n"
"# if 1900 <= _MSC_VER\n"
"# define VK_CPP_HAS_UNRESTRICTED_UNIONS\n"
"# endif\n"
"# endif\n"
"#endif\n"
"\n"
);
// trim from end // trim from end
std::string trimEnd(std::string const& input) std::string trimEnd(std::string const& input)
{ {
@ -458,9 +478,8 @@ void writeExceptionCheck(std::ofstream & ofs, std::string const& indentation, st
void writeFunctionBody(std::ofstream & ofs, std::string const& indentation, std::string const& className, std::string const& functionName, std::string const& returnType, size_t templateIndex, DependencyData const& dependencyData, CommandData const& commandData, std::set<std::string> const& vkTypes, size_t returnIndex, std::map<size_t, size_t> const& vectorParameters); void writeFunctionBody(std::ofstream & ofs, std::string const& indentation, std::string const& className, std::string const& functionName, std::string const& returnType, size_t templateIndex, DependencyData const& dependencyData, CommandData const& commandData, std::set<std::string> const& vkTypes, size_t returnIndex, std::map<size_t, size_t> const& vectorParameters);
void writeFunctionHeader(std::ofstream & ofs, std::string const& indentation, std::string const& returnType, std::string const& name, CommandData const& commandData, size_t returnIndex, size_t templateIndex, std::map<size_t, size_t> const& vectorParameters); void writeFunctionHeader(std::ofstream & ofs, std::string const& indentation, std::string const& returnType, std::string const& name, CommandData const& commandData, size_t returnIndex, size_t templateIndex, std::map<size_t, size_t> const& vectorParameters);
void writeMemberData(std::ofstream & ofs, MemberData const& memberData, std::set<std::string> const& vkTypes); void writeMemberData(std::ofstream & ofs, MemberData const& memberData, std::set<std::string> const& vkTypes);
void writeStructConstructor( std::ofstream & ofs, std::string const& name, std::string const& memberName, StructData const& structData, std::set<std::string> const& vkTypes, std::map<std::string,std::string> const& defaultValues ); void writeStructConstructor( std::ofstream & ofs, std::string const& name, StructData const& structData, std::set<std::string> const& vkTypes, std::map<std::string,std::string> const& defaultValues );
void writeStructGetter( std::ofstream & ofs, MemberData const& memberData, std::string const& memberName, std::set<std::string> const& vkTypes, bool constVersion ); void writeStructSetter( std::ofstream & ofs, std::string const& name, MemberData const& memberData, std::set<std::string> const& vkTypes, std::map<std::string,StructData> const& structs );
void writeStructSetter( std::ofstream & ofs, std::string const& name, MemberData const& memberData, std::string const& memberName, std::set<std::string> const& vkTypes, std::map<std::string,StructData> const& structs );
void writeTypeCommand( std::ofstream & ofs, DependencyData const& dependencyData, CommandData const& commandData, std::set<std::string> const& vkTypes ); void writeTypeCommand( std::ofstream & ofs, DependencyData const& dependencyData, CommandData const& commandData, std::set<std::string> const& vkTypes );
void writeTypeCommandEnhanced(std::ofstream & ofs, std::string const& indentation, std::string const& className, std::string const& functionName, DependencyData const& dependencyData, CommandData const& commandData, std::set<std::string> const& vkTypes); void writeTypeCommandEnhanced(std::ofstream & ofs, std::string const& indentation, std::string const& className, std::string const& functionName, DependencyData const& dependencyData, CommandData const& commandData, std::set<std::string> const& vkTypes);
void writeTypeCommandStandard(std::ofstream & ofs, std::string const& indentation, std::string const& functionName, DependencyData const& dependencyData, CommandData const& commandData, std::set<std::string> const& vkTypes); void writeTypeCommandStandard(std::ofstream & ofs, std::string const& indentation, std::string const& functionName, DependencyData const& dependencyData, CommandData const& commandData, std::set<std::string> const& vkTypes);
@ -1828,7 +1847,6 @@ void writeFunctionBody(std::ofstream & ofs, std::string const& indentation, std:
size_t pos = size.find("->"); size_t pos = size.find("->");
assert(pos != std::string::npos); assert(pos != std::string::npos);
size.replace(pos, 2, "."); size.replace(pos, 2, ".");
size += "()";
} }
else else
{ {
@ -2093,7 +2111,7 @@ void writeMemberData(std::ofstream & ofs, MemberData const& memberData, std::set
} }
} }
void writeStructConstructor( std::ofstream & ofs, std::string const& name, std::string const& memberName, StructData const& structData, std::set<std::string> const& vkTypes, std::map<std::string,std::string> const& defaultValues ) void writeStructConstructor( std::ofstream & ofs, std::string const& name, StructData const& structData, std::set<std::string> const& vkTypes, std::map<std::string,std::string> const& defaultValues )
{ {
// check if there is a member element with no default available // check if there is a member element with no default available
bool noDefault = false; bool noDefault = false;
@ -2158,47 +2176,39 @@ void writeStructConstructor( std::ofstream & ofs, std::string const& name, std::
{ {
if (structData.members[i].arraySize.empty()) if (structData.members[i].arraySize.empty())
{ {
ofs << structData.members[i].type + " " + structData.members[i].name; ofs << structData.members[i].type + " " + structData.members[i].name << "_";
} }
else else
{ {
ofs << "std::array<" + structData.members[i].type + "," + structData.members[i].arraySize + "> const& " + structData.members[i].name; ofs << "std::array<" + structData.members[i].type + "," + structData.members[i].arraySize + "> const& " + structData.members[i].name << "_";
} }
listedArgument = true; listedArgument = true;
} }
} }
ofs << " )" << std::endl; ofs << " )" << std::endl;
// now the body of the constructor, copying over data from argument list into wrapped struct // the body of the constructor, copying over data from argument list into wrapped struct
ofs << " {" << std::endl; ofs << " {" << std::endl;
for ( size_t i=0 ; i<structData.members.size() ; i++ ) for ( size_t i=0 ; i<structData.members.size() ; i++ )
{ {
if ( !structData.members[i].arraySize.empty() ) if ( !structData.members[i].arraySize.empty() )
{ {
ofs << " memcpy( &" << memberName << "." << structData.members[i].name << ", " << structData.members[i].name << ".data(), " << structData.members[i].arraySize << " * sizeof( " << structData.members[i].type << " ) )"; ofs << " memcpy( &" << structData.members[i].name << ", " << structData.members[i].name << "_.data(), " << structData.members[i].arraySize << " * sizeof( " << structData.members[i].type << " ) )";
} }
else else
{ {
ofs << " " << memberName << "." << structData.members[i].name << " = "; ofs << " " << structData.members[i].name << " = ";
if ( structData.members[i].name == "pNext" ) if ( structData.members[i].name == "pNext" )
{ {
ofs << "nullptr"; ofs << "nullptr";
} }
else if ( structData.members[i].name == "sType" ) else if ( structData.members[i].name == "sType" )
{ {
// HACK: we need to read <enum extends="VkStructureType"> here for the correct name. In this case the 'generic' rule to create the enums doesn't work ofs << "StructureType::e" << name;
if (name == "DebugReportCallbackCreateInfoEXT")
{
ofs << "VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT";
} }
else else
{ {
ofs << "VK_STRUCTURE_TYPE" << toUpperCase(name); ofs << structData.members[i].name << "_";
}
}
else
{
writeMemberData( ofs, structData.members[i], vkTypes );
} }
} }
ofs << ";" << std::endl; ofs << ";" << std::endl;
@ -2206,90 +2216,25 @@ void writeStructConstructor( std::ofstream & ofs, std::string const& name, std::
ofs << " }" << std::endl ofs << " }" << std::endl
<< std::endl; << std::endl;
// now write the copy constructor // the copy constructor from a native struct (Vk...)
ofs << " " << name << "( Vk" << name << " const & rhs )" << std::endl ofs << " " << name << "( Vk" << name << " const & rhs )" << std::endl
<< " : " << memberName << "(rhs)" << std::endl
<< " {" << std::endl << " {" << std::endl
<< " memcpy( this, &rhs, sizeof(" << name << ") );" << std::endl
<< " }" << std::endl << " }" << std::endl
<< std::endl; << std::endl;
// now write the assignment operator // the assignment operator from a native sturct (Vk...)
ofs << " " << name << "& operator=( Vk" << name << " const & rhs )" << std::endl ofs << " " << name << "& operator=( Vk" << name << " const & rhs )" << std::endl
<< " {" << std::endl << " {" << std::endl
<< " " << memberName << " = rhs;" << std::endl << " memcpy( this, &rhs, sizeof(" << name << ") );" << std::endl
<< " return *this;" << std::endl << " return *this;" << std::endl
<< " }" << std::endl << " }" << std::endl
<< std::endl; << std::endl;
} }
void writeStructGetter( std::ofstream & ofs, MemberData const& memberData, std::string const& memberName, std::set<std::string> const& vkTypes, bool constVersion ) void writeStructSetter( std::ofstream & ofs, std::string const& name, MemberData const& memberData, std::set<std::string> const& vkTypes )
{ {
ofs << " "; ofs << " " << name << "& set" << static_cast<char>(toupper(memberData.name[0])) << memberData.name.substr(1) << "( ";
if ( memberData.type.back() == '*' )
{
if ( constVersion && ( memberData.type.find( "const" ) != 0 ) )
{
ofs << "const ";
}
ofs << memberData.type;
}
else
{
if (constVersion)
{
ofs << "const ";
}
ofs << memberData.type << ( memberData.arraySize.empty() ? '&' : '*' );
}
ofs << " " << memberData.name << "()";
if (constVersion)
{
ofs << " const";
}
ofs << std::endl
<< " {" << std::endl
<< " return ";
if ( ! memberData.arraySize.empty() )
{
ofs << "reinterpret_cast<";
if (constVersion)
{
ofs << "const ";
}
ofs << memberData.type << "*>( " << memberName << "." << memberData.name << " )";
}
else if ( memberData.type.back() == '*' )
{
ofs << "reinterpret_cast<";
if (constVersion && (memberData.type.find("const") != 0))
{
ofs << "const ";
}
ofs << memberData.type << ">( " << memberName << "." << memberData.name << " )";
}
else if ( vkTypes.find( memberData.pureType ) != vkTypes.end() )
{
ofs << "reinterpret_cast<";
if (constVersion)
{
ofs << "const ";
}
ofs << memberData.pureType << "&>( " << memberName << "." << memberData.name << " )";
}
else
{
ofs << memberName << "." << memberData.name;
}
ofs << ";" << std::endl
<< " }" << std::endl
<< std::endl;
}
void writeStructSetter( std::ofstream & ofs, std::string const& name, MemberData const& memberData, std::string const& memberName, std::set<std::string> const& vkTypes )
{
ofs << " " << name << "& " << memberData.name << "( ";
if ( memberData.arraySize.empty() ) if ( memberData.arraySize.empty() )
{ {
ofs << memberData.type << " "; ofs << memberData.type << " ";
@ -2298,16 +2243,15 @@ void writeStructSetter( std::ofstream & ofs, std::string const& name, MemberData
{ {
ofs << "std::array<" << memberData.type << "," << memberData.arraySize << "> "; ofs << "std::array<" << memberData.type << "," << memberData.arraySize << "> ";
} }
ofs << memberData.name << " )" << std::endl ofs << memberData.name << "_ )" << std::endl
<< " {" << std::endl; << " {" << std::endl;
if ( !memberData.arraySize.empty() ) if ( !memberData.arraySize.empty() )
{ {
ofs << " memcpy( &" << memberName << "." << memberData.name << ", " << memberData.name << ".data(), " << memberData.arraySize << " * sizeof( " << memberData.type << " ) )"; ofs << " memcpy( &" << memberData.name << ", " << memberData.name << "_.data(), " << memberData.arraySize << " * sizeof( " << memberData.type << " ) )";
} }
else else
{ {
ofs << " " << memberName << "." << memberData.name << " = "; ofs << " " << memberData.name << " = " << memberData.name << "_";
writeMemberData( ofs, memberData, vkTypes );
} }
ofs << ";" << std::endl ofs << ";" << std::endl
<< " return *this;" << std::endl << " return *this;" << std::endl
@ -2617,41 +2561,42 @@ void writeTypeStruct( std::ofstream & ofs, VkData const& vkData, DependencyData
assert( it != vkData.structs.end() ); assert( it != vkData.structs.end() );
enterProtect(ofs, it->second.protect); enterProtect(ofs, it->second.protect);
ofs << " class " << dependencyData.name << std::endl ofs << " struct " << dependencyData.name << std::endl
<< " {" << std::endl << " {" << std::endl;
<< " public:" << std::endl;
std::string memberName( dependencyData.name );
assert( isupper( memberName[0] ) );
memberName[0] = tolower( memberName[0] );
memberName = "m_" + memberName;
// only structs that are not returnedOnly get a constructor! // only structs that are not returnedOnly get a constructor!
if ( !it->second.returnedOnly ) if ( !it->second.returnedOnly )
{ {
writeStructConstructor( ofs, dependencyData.name, memberName, it->second, vkData.vkTypes, defaultValues ); writeStructConstructor( ofs, dependencyData.name, it->second, vkData.vkTypes, defaultValues );
} }
// create the getters and setters // create the setters
for ( size_t i=0 ; i<it->second.members.size() ; i++ )
{
writeStructGetter(ofs, it->second.members[i], memberName, vkData.vkTypes, true);
if (!it->second.returnedOnly) if (!it->second.returnedOnly)
{ {
writeStructGetter(ofs, it->second.members[i], memberName, vkData.vkTypes, false); for (size_t i = 0; i<it->second.members.size(); i++)
writeStructSetter( ofs, dependencyData.name, it->second.members[i], memberName, vkData.vkTypes ); {
writeStructSetter( ofs, dependencyData.name, it->second.members[i], vkData.vkTypes );
} }
} }
// the cast-operator to the wrapped struct, and the struct itself as a private member variable // the cast-operator to the wrapped struct
ofs << " operator const Vk" << dependencyData.name << "&() const" << std::endl ofs << " operator const Vk" << dependencyData.name << "&() const" << std::endl
<< " {" << std::endl << " {" << std::endl
<< " return " << memberName << ";" << std::endl << " return *reinterpret_cast<const Vk" << dependencyData.name << "*>(this);" << std::endl
<< " }" << std::endl << " }" << std::endl
<< std::endl << std::endl;
<< " private:" << std::endl
<< " Vk" << dependencyData.name << " " << memberName << ";" << std::endl // the member variables
<< " };" << std::endl; for (size_t i = 0; i < it->second.members.size(); i++)
{
ofs << " " << it->second.members[i].type << " " << it->second.members[i].name;
if (!it->second.members[i].arraySize.empty())
{
ofs << "[" << it->second.members[i].arraySize << "]";
}
ofs << ";" << std::endl;
}
ofs << " };" << std::endl;
#if 1 #if 1
ofs << " static_assert( sizeof( " << dependencyData.name << " ) == sizeof( Vk" << dependencyData.name << " ), \"struct and wrapper have different size!\" );" << std::endl; ofs << " static_assert( sizeof( " << dependencyData.name << " ) == sizeof( Vk" << dependencyData.name << " ), \"struct and wrapper have different size!\" );" << std::endl;
#endif #endif
@ -2662,14 +2607,8 @@ void writeTypeStruct( std::ofstream & ofs, VkData const& vkData, DependencyData
void writeTypeUnion( std::ofstream & ofs, VkData const& vkData, DependencyData const& dependencyData, StructData const& unionData, std::map<std::string,std::string> const& defaultValues ) void writeTypeUnion( std::ofstream & ofs, VkData const& vkData, DependencyData const& dependencyData, StructData const& unionData, std::map<std::string,std::string> const& defaultValues )
{ {
std::ostringstream oss; std::ostringstream oss;
ofs << " class " << dependencyData.name << std::endl ofs << " union " << dependencyData.name << std::endl
<< " {" << std::endl << " {" << std::endl;
<< " public:" << std::endl;
std::string memberName( dependencyData.name );
assert( isupper( memberName[0] ) );
memberName[0] = tolower( memberName[0] );
memberName = "m_" + memberName;
for ( size_t i=0 ; i<unionData.members.size() ; i++ ) for ( size_t i=0 ; i<unionData.members.size() ; i++ )
{ {
@ -2683,7 +2622,7 @@ void writeTypeUnion( std::ofstream & ofs, VkData const& vkData, DependencyData c
{ {
ofs << "const std::array<" << unionData.members[i].type << "," << unionData.members[i].arraySize << ">& "; ofs << "const std::array<" << unionData.members[i].type << "," << unionData.members[i].arraySize << ">& ";
} }
ofs << unionData.members[i].name; ofs << unionData.members[i].name << "_";
// just the very first constructor gets default arguments // just the very first constructor gets default arguments
if ( i == 0 ) if ( i == 0 )
@ -2704,31 +2643,71 @@ void writeTypeUnion( std::ofstream & ofs, VkData const& vkData, DependencyData c
<< " "; << " ";
if ( unionData.members[i].arraySize.empty() ) if ( unionData.members[i].arraySize.empty() )
{ {
ofs << memberName << "." << unionData.members[i].name << " = " << unionData.members[i].name; ofs << unionData.members[i].name << " = " << unionData.members[i].name << "_";
} }
else else
{ {
ofs << "memcpy( &" << memberName << "." << unionData.members[i].name << ", " << unionData.members[i].name << ".data(), " << unionData.members[i].arraySize << " * sizeof( " << unionData.members[i].type << " ) )"; ofs << "memcpy( &" << unionData.members[i].name << ", " << unionData.members[i].name << "_.data(), " << unionData.members[i].arraySize << " * sizeof( " << unionData.members[i].type << " ) )";
} }
ofs << ";" << std::endl ofs << ";" << std::endl
<< " }" << std::endl << " }" << std::endl
<< std::endl; << std::endl;
// one getter/setter per union element
writeStructGetter(ofs, unionData.members[i], memberName, vkData.vkTypes, true);
assert(!unionData.returnedOnly);
writeStructGetter(ofs, unionData.members[i], memberName, vkData.vkTypes, false);
writeStructSetter(ofs, dependencyData.name, unionData.members[i], memberName, vkData.vkTypes);
} }
for (size_t i = 0; i<unionData.members.size(); i++)
{
// one setter per union element
assert(!unionData.returnedOnly);
writeStructSetter(ofs, dependencyData.name, unionData.members[i], vkData.vkTypes);
}
// the implicit cast operator to the native type
ofs << " operator Vk" << dependencyData.name << " const& () const" << std::endl ofs << " operator Vk" << dependencyData.name << " const& () const" << std::endl
<< " {" << std::endl << " {" << std::endl
<< " return " << memberName << ";" << std::endl << " return *reinterpret_cast<const Vk" << dependencyData.name << "*>(this);" << std::endl
<< " }" << std::endl << " }" << std::endl
<< std::endl << std::endl;
<< " private:" << std::endl
<< " Vk" << dependencyData.name << " " << memberName << ";" << std::endl // the union member variables
<< " };" << std::endl // if there's at least one Vk... type in this union, check for unrestricted unions support
bool needsUnrestrictedUnions = false;
for (size_t i = 0; i < unionData.members.size() && !needsUnrestrictedUnions; i++)
{
needsUnrestrictedUnions = (vkData.vkTypes.find(unionData.members[i].type) != vkData.vkTypes.end());
}
if (needsUnrestrictedUnions)
{
ofs << "#ifdef VK_CPP_HAS_UNRESTRICTED_UNIONS" << std::endl;
for (size_t i = 0; i < unionData.members.size(); i++)
{
ofs << " " << unionData.members[i].type << " " << unionData.members[i].name;
if (!unionData.members[i].arraySize.empty())
{
ofs << "[" << unionData.members[i].arraySize << "]";
}
ofs << ";" << std::endl;
}
ofs << "#else" << std::endl;
}
for (size_t i = 0; i < unionData.members.size(); i++)
{
ofs << " ";
if (vkData.vkTypes.find(unionData.members[i].type) != vkData.vkTypes.end())
{
ofs << "Vk";
}
ofs << unionData.members[i].type << " " << unionData.members[i].name;
if (!unionData.members[i].arraySize.empty())
{
ofs << "[" << unionData.members[i].arraySize << "]";
}
ofs << ";" << std::endl;
}
if (needsUnrestrictedUnions)
{
ofs << "#endif // VK_CPP_HAS_UNRESTRICTED_UNIONS" << std::endl;
}
ofs << " };" << std::endl
<< std::endl; << std::endl;
} }
@ -2875,7 +2854,8 @@ int main( int argc, char **argv )
writeVersionCheck(ofs, vkData.version); writeVersionCheck(ofs, vkData.version);
writeTypesafeCheck(ofs, vkData.typesafeCheck); writeTypesafeCheck(ofs, vkData.typesafeCheck);
ofs << "namespace vk" << std::endl ofs << versionCheckHeader
<< "namespace vk" << std::endl
<< "{" << std::endl << "{" << std::endl
<< flagsHeader << flagsHeader
<< optionalClassHeader << optionalClassHeader

File diff suppressed because it is too large Load Diff