From 75cb7d14f1610b2f6c41a041679a8056c2f0f027 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20S=C3=BC=C3=9Fenbach?= Date: Thu, 1 Feb 2018 14:45:30 +0100 Subject: [PATCH] Correct usage of Allocator in functions returning a vector of UniqueObjects (#178) --- VulkanHppGenerator.cpp | 233 ++++++++++++++++++++++++----------------- VulkanHppGenerator.hpp | 3 +- vulkan/vulkan.hpp | 93 ++++++++-------- 3 files changed, 185 insertions(+), 144 deletions(-) diff --git a/VulkanHppGenerator.cpp b/VulkanHppGenerator.cpp index 23fc0ae..7bad7e2 100644 --- a/VulkanHppGenerator.cpp +++ b/VulkanHppGenerator.cpp @@ -541,7 +541,7 @@ const std::string createResultValueHeader = R"( { throwResultException( result, message ); } - return data; + return std::move( data ); #endif } @@ -2741,6 +2741,46 @@ void VulkanHppGenerator::sortDependencies() m_dependencies.swap(sortedDependencies); } +void VulkanHppGenerator::writeArguments(std::ostream & os, CommandData const& commandData, bool firstCall, bool singular, size_t from, size_t to) +{ + assert(from <= to); + + // get the parameter indices of the counter for vector parameters + std::map countIndices; + for (std::map::const_iterator it = commandData.vectorParams.begin(); it != commandData.vectorParams.end(); ++it) + { + countIndices.insert(std::make_pair(it->second, it->first)); + } + + bool encounteredArgument = false; + for (size_t i = from; i < to; i++) + { + if (encounteredArgument) + { + os << ", "; + } + + std::map::const_iterator it = countIndices.find(i); + if (it != countIndices.end()) + { + writeCallCountParameter(os, commandData, singular, it); + } + else if ((it = commandData.vectorParams.find(i)) != commandData.vectorParams.end()) + { + writeCallVectorParameter(os, commandData, firstCall, singular, it); + } + else if (m_vkTypes.find(commandData.params[i].pureType) != m_vkTypes.end()) + { + writeCallVulkanTypeParameter(os, commandData.params[i]); + } + else + { + writeCallPlainTypeParameter(os, commandData.params[i]); + } + encounteredArgument = true; + } +} + void VulkanHppGenerator::writeBitmaskToString(std::ostream & os, std::string const& bitmaskName, EnumData const &enumData) { // the helper functions to make strings out of flag values @@ -2772,13 +2812,6 @@ void VulkanHppGenerator::writeBitmaskToString(std::ostream & os, std::string con void VulkanHppGenerator::writeCall(std::ostream & os, CommandData const& commandData, bool firstCall, bool singular) { - // get the parameter indices of the counter for vector parameters - std::map countIndices; - for (std::map::const_iterator it = commandData.vectorParams.begin(); it != commandData.vectorParams.end(); ++it) - { - countIndices.insert(std::make_pair(it->second, it->first)); - } - // the original function call os << "d.vk" << startUpperCase(commandData.fullName) << "( "; @@ -2786,33 +2819,13 @@ void VulkanHppGenerator::writeCall(std::ostream & os, CommandData const& command { // if it's member of a class -> add the first parameter with "m_" as prefix os << "m_" << commandData.params[0].name; - } - - for (size_t i = commandData.className.empty() ? 0 : 1; i < commandData.params.size(); i++) - { - if (0 < i) + if (1 < commandData.params.size()) { os << ", "; } - - std::map::const_iterator it = countIndices.find(i); - if (it != countIndices.end()) - { - writeCallCountParameter(os, commandData, singular, it); - } - else if ((it = commandData.vectorParams.find(i)) != commandData.vectorParams.end()) - { - writeCallVectorParameter(os, commandData, firstCall, singular, it); - } - else if (m_vkTypes.find(commandData.params[i].pureType) != m_vkTypes.end()) - { - writeCallVulkanTypeParameter(os, commandData.params[i]); - } - else - { - writeCallPlainTypeParameter(os, commandData.params[i]); - } } + + writeArguments(os, commandData, firstCall, singular, commandData.className.empty() ? 0 : 1, commandData.params.size()); os << " )"; } @@ -3204,7 +3217,7 @@ void VulkanHppGenerator::writeExceptionsForEnum(std::ostream & os, EnumData cons void VulkanHppGenerator::writeFunction(std::ostream & os, std::string const& indentation, CommandData const& commandData, bool definition, bool enhanced, bool singular, bool unique, bool isStructureChain) { - writeFunctionHeaderTemplate(os, indentation, commandData, enhanced, !definition, isStructureChain); + writeFunctionHeaderTemplate(os, indentation, commandData, enhanced, unique, !definition, isStructureChain); os << indentation << (definition ? "VULKAN_HPP_INLINE " : ""); writeFunctionHeaderReturnType(os, indentation, commandData, enhanced, singular, unique, isStructureChain); @@ -3234,63 +3247,106 @@ void VulkanHppGenerator::writeFunction(std::ostream & os, std::string const& ind void VulkanHppGenerator::writeFunctionBodyEnhanced(std::ostream & os, std::string const& indentation, CommandData const& commandData, bool singular, bool unique, bool isStructureChain) { - if (1 < commandData.vectorParams.size()) + if (unique && !singular && (commandData.vectorParams.find(commandData.returnParam) != commandData.vectorParams.end())) // returns a vector of UniqueStuff { - writeFunctionBodyEnhancedMultiVectorSizeCheck(os, indentation, commandData); - } + std::string const stringTemplate = +R"(${i} static_assert( sizeof( ${type} ) <= sizeof( Unique${type} ), "${type} is greater than Unique${type}!" ); +${i} std::vector ${typeVariable}s; +${i} ${typeVariable}s.reserve( ${vectorSize} ); +${i} ${type}* buffer = reinterpret_cast<${type}*>( reinterpret_cast( ${typeVariable}s.data() ) + ${vectorSize} * ( sizeof( Unique${type} ) - sizeof( ${type} ) ) ); +${i} Result result = static_cast(d.vk${command}( m_device, ${arguments}, reinterpret_cast( buffer ) ) ); - std::string returnName; - if (commandData.returnParam != ~0) - { - returnName = writeFunctionBodyEnhancedLocalReturnVariable(os, indentation, commandData, singular, isStructureChain); - } +${i} ${type}Deleter deleter( *this, ${deleterArg} ); +${i} for ( size_t i=0 ; i<${vectorSize} ; i++ ) +${i} { +${i} ${typeVariable}s.push_back( Unique${type}( buffer[i], deleter ) ); +${i} } - if (commandData.twoStep) - { - assert(!singular); - writeFunctionBodyEnhancedLocalCountVariable(os, indentation, commandData); +${i} return createResultValue( result, ${typeVariable}s, "VULKAN_HPP_NAMESPACE::${class}::${function}Unique" ); +)"; - // we now might have to check the result, resize the returned vector accordingly, and call the function again - std::map::const_iterator returnit = commandData.vectorParams.find(commandData.returnParam); - assert(returnit != commandData.vectorParams.end() && (returnit->second != ~0)); - std::string sizeName = startLowerCase(strip(commandData.params[returnit->second].name, "p")); + std::string type = (commandData.returnParam != ~0) ? commandData.params[commandData.returnParam].pureType : ""; + std::string typeVariable = startLowerCase(type); + std::ostringstream arguments; + writeArguments(arguments, commandData, true, singular, 1, commandData.params.size() - 1); - if (commandData.returnType == "Result") + std::map::const_iterator ddit = m_deleters.find(type); + assert(ddit != m_deleters.end()); + + bool isCreateFunction = (commandData.fullName.substr(0, 6) == "create"); + os << replaceWithMap(stringTemplate, std::map { - if (1 < commandData.successCodes.size()) - { - writeFunctionBodyEnhancedCallTwoStepIterate(os, indentation, returnName, sizeName, commandData); - } - else - { - writeFunctionBodyEnhancedCallTwoStepChecked(os, indentation, returnName, sizeName, commandData); - } - } - else - { - writeFunctionBodyEnhancedCallTwoStep(os, indentation, returnName, sizeName, commandData); - } + { "i", indentation }, + { "type", type }, + { "typeVariable", typeVariable }, + { "vectorSize", isCreateFunction ? "createInfos.size()" : "allocateInfo." + typeVariable + "Count" }, + { "command", startUpperCase(commandData.fullName) }, + { "arguments", arguments.str() }, + { "deleterArg", ddit->second.pool.empty() ? "allocator" : "allocateInfo." + startLowerCase(ddit->second.pool) }, + { "class", commandData.className }, + { "function", commandData.reducedName } + }); } else { - if (commandData.returnType == "Result") + if (1 < commandData.vectorParams.size()) { - writeFunctionBodyEnhancedCallResult(os, indentation, commandData, singular); + writeFunctionBodyEnhancedMultiVectorSizeCheck(os, indentation, commandData); + } + + std::string returnName; + if (commandData.returnParam != ~0) + { + returnName = writeFunctionBodyEnhancedLocalReturnVariable(os, indentation, commandData, singular, isStructureChain); + } + + if (commandData.twoStep) + { + assert(!singular); + writeFunctionBodyEnhancedLocalCountVariable(os, indentation, commandData); + + // we now might have to check the result, resize the returned vector accordingly, and call the function again + std::map::const_iterator returnit = commandData.vectorParams.find(commandData.returnParam); + assert(returnit != commandData.vectorParams.end() && (returnit->second != ~0)); + std::string sizeName = startLowerCase(strip(commandData.params[returnit->second].name, "p")); + + if (commandData.returnType == "Result") + { + if (1 < commandData.successCodes.size()) + { + writeFunctionBodyEnhancedCallTwoStepIterate(os, indentation, returnName, sizeName, commandData); + } + else + { + writeFunctionBodyEnhancedCallTwoStepChecked(os, indentation, returnName, sizeName, commandData); + } + } + else + { + writeFunctionBodyEnhancedCallTwoStep(os, indentation, returnName, sizeName, commandData); + } } else { - writeFunctionBodyEnhancedCall(os, indentation, commandData, singular); + if (commandData.returnType == "Result") + { + writeFunctionBodyEnhancedCallResult(os, indentation, commandData, singular); + } + else + { + writeFunctionBodyEnhancedCall(os, indentation, commandData, singular); + } } - } - if ((commandData.returnType == "Result") || !commandData.successCodes.empty()) - { - writeFunctionBodyEnhancedReturnResultValue(os, indentation, returnName, commandData, singular, unique); - } - else if ((commandData.returnParam != ~0) && (commandData.returnType != commandData.enhancedReturnType)) - { - // for the other returning cases, when the return type is somhow enhanced, just return the local returnVariable - os << indentation << " return " << returnName << ";" << std::endl; + if ((commandData.returnType == "Result") || !commandData.successCodes.empty()) + { + writeFunctionBodyEnhancedReturnResultValue(os, indentation, returnName, commandData, singular, unique); + } + else if ((commandData.returnParam != ~0) && (commandData.returnType != commandData.enhancedReturnType)) + { + // for the other returning cases, when the return type is somhow enhanced, just return the local returnVariable + os << indentation << " return " << returnName << ";" << std::endl; + } } } @@ -3539,33 +3595,12 @@ void VulkanHppGenerator::writeFunctionBodyEnhancedReturnResultValue(std::ostream os << " );" << std::endl; } - bool returnUniqueVector = unique && !singular && (commandData.vectorParams.find(commandData.returnParam) != commandData.vectorParams.end()); - if (returnUniqueVector) - { - std::string const stringTemplate = -R"(${i} std::vector unique${returnVectorName}s; -${i} unique${returnVectorName}s.reserve( ${localName}s.size() ); -${i} for ( auto const& ${localName} : ${localName}s ) -${i} { -${i} unique${returnVectorName}s.push_back( Unique${type}( ${localName}, deleter ) ); -${i} } - -)"; - - os << replaceWithMap(stringTemplate, std::map{ - { "i", indentation }, - { "type", type }, - { "returnVectorName", returnVectorName }, - { "localName", startLowerCase(returnVectorName) } - }); - } - // if the return type is "Result" or there is at least one success code, create the Result/Value construct to return os << indentation << " return createResultValue( result, "; if (commandData.returnParam != ~0) { // if there's a return parameter, list it in the Result/Value constructor - os << (returnUniqueVector ? "unique" + returnVectorName + "s" : returnName) << ", "; + os << returnName << ", "; } // now the function name (with full namespace) as a string @@ -3582,7 +3617,7 @@ ${i} } os << " }"; } - if (unique && !returnUniqueVector) + if (unique) { os << ", deleter"; } @@ -3934,7 +3969,7 @@ void VulkanHppGenerator::writeFunctionHeaderReturnType(std::ostream & os, std::s os << replaceWithMap(templateString, { { "returnType", returnType } }); } -void VulkanHppGenerator::writeFunctionHeaderTemplate(std::ostream & os, std::string const& indentation, CommandData const& commandData, bool enhanced, bool withDefault, bool isStructureChain) +void VulkanHppGenerator::writeFunctionHeaderTemplate(std::ostream & os, std::string const& indentation, CommandData const& commandData, bool enhanced, bool unique, bool withDefault, bool isStructureChain) { std::string dispatch = withDefault ? std::string("typename Dispatch = DispatchLoaderStatic") : std::string("typename Dispatch"); if (enhanced && isStructureChain) @@ -3955,7 +3990,7 @@ void VulkanHppGenerator::writeFunctionHeaderTemplate(std::ostream & os, std::str if (withDefault) { // for the default type get the type from the enhancedReturnType, which is of the form 'std::vector' - os << " = std::allocator<" << commandData.enhancedReturnType.substr(12, commandData.enhancedReturnType.find(',') - 12) << ">"; + os << " = std::allocator<" << (unique ? "Unique" : "") << commandData.enhancedReturnType.substr(12, commandData.enhancedReturnType.find(',') - 12) << ">"; } os << ", " << dispatch; os << "> " << std::endl; diff --git a/VulkanHppGenerator.hpp b/VulkanHppGenerator.hpp index 477d2e6..1d98add 100644 --- a/VulkanHppGenerator.hpp +++ b/VulkanHppGenerator.hpp @@ -238,6 +238,7 @@ class VulkanHppGenerator void readTypeStructMember(tinyxml2::XMLElement const* element, StructData & structData); void registerDeleter(CommandData const& commandData); void setDefault(std::string const& name, std::map & defaultValues, EnumData const& enumData); + void writeArguments(std::ostream & os, CommandData const& commandData, bool firstCall, bool singular, size_t from, size_t to); void writeBitmaskToString(std::ostream & os, std::string const& flagsName, EnumData const &enumData); void writeCall(std::ostream & os, CommandData const& commandData, bool firstCall, bool singular); void writeCallCountParameter(std::ostream & os, CommandData const& commandData, bool singular, std::map::const_iterator it); @@ -266,7 +267,7 @@ class VulkanHppGenerator void writeFunctionHeaderArgumentsEnhanced(std::ostream & os, CommandData const& commandData, bool singular, bool withDefaults); void writeFunctionHeaderArgumentsStandard(std::ostream & os, CommandData const& commandData, bool withDefaults); void writeFunctionHeaderReturnType(std::ostream & os, std::string const& indentation, CommandData const& commandData, bool enhanced, bool singular, bool unique, bool isStructureChain); - void writeFunctionHeaderTemplate(std::ostream & os, std::string const& indentation, CommandData const& commandData, bool enhanced, bool withDefault, bool isStructureChain); + void writeFunctionHeaderTemplate(std::ostream & os, std::string const& indentation, CommandData const& commandData, bool enhanced, bool unique, bool withDefault, bool isStructureChain); void writeStructConstructor(std::ostream & os, std::string const& name, StructData const& structData, std::map const& defaultValues); void writeStructSetter(std::ostream & os, std::string const& structureName, MemberData const& memberData); void writeStructureChainValidation(std::ostream & os, DependencyData const& dependencyData); diff --git a/vulkan/vulkan.hpp b/vulkan/vulkan.hpp index 2f5320d..d4b558f 100644 --- a/vulkan/vulkan.hpp +++ b/vulkan/vulkan.hpp @@ -924,7 +924,7 @@ namespace VULKAN_HPP_NAMESPACE { throwResultException( result, message ); } - return data; + return std::move( data ); #endif } @@ -28699,9 +28699,9 @@ public: template , typename Dispatch = DispatchLoaderStatic> ResultValueType::type createGraphicsPipeline( PipelineCache pipelineCache, const GraphicsPipelineCreateInfo & createInfo, Optional allocator = nullptr, Dispatch const &d = Dispatch() ) const; #ifndef VULKAN_HPP_NO_SMART_HANDLE - template , typename Dispatch = DispatchLoaderStatic> + template , typename Dispatch = DispatchLoaderStatic> typename ResultValueType>::type createGraphicsPipelinesUnique( PipelineCache pipelineCache, ArrayProxy createInfos, Optional allocator = nullptr, Dispatch const &d = Dispatch() ) const; - template , typename Dispatch = DispatchLoaderStatic> + template , typename Dispatch = DispatchLoaderStatic> ResultValueType::type createGraphicsPipelineUnique( PipelineCache pipelineCache, const GraphicsPipelineCreateInfo & createInfo, Optional allocator = nullptr, Dispatch const &d = Dispatch() ) const; #endif /*VULKAN_HPP_NO_SMART_HANDLE*/ #endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/ @@ -28714,9 +28714,9 @@ public: template , typename Dispatch = DispatchLoaderStatic> ResultValueType::type createComputePipeline( PipelineCache pipelineCache, const ComputePipelineCreateInfo & createInfo, Optional allocator = nullptr, Dispatch const &d = Dispatch() ) const; #ifndef VULKAN_HPP_NO_SMART_HANDLE - template , typename Dispatch = DispatchLoaderStatic> + template , typename Dispatch = DispatchLoaderStatic> typename ResultValueType>::type createComputePipelinesUnique( PipelineCache pipelineCache, ArrayProxy createInfos, Optional allocator = nullptr, Dispatch const &d = Dispatch() ) const; - template , typename Dispatch = DispatchLoaderStatic> + template , typename Dispatch = DispatchLoaderStatic> ResultValueType::type createComputePipelineUnique( PipelineCache pipelineCache, const ComputePipelineCreateInfo & createInfo, Optional allocator = nullptr, Dispatch const &d = Dispatch() ) const; #endif /*VULKAN_HPP_NO_SMART_HANDLE*/ #endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/ @@ -28814,7 +28814,7 @@ public: template , typename Dispatch = DispatchLoaderStatic> typename ResultValueType>::type allocateDescriptorSets( const DescriptorSetAllocateInfo & allocateInfo, Dispatch const &d = Dispatch() ) const; #ifndef VULKAN_HPP_NO_SMART_HANDLE - template , typename Dispatch = DispatchLoaderStatic> + template , typename Dispatch = DispatchLoaderStatic> typename ResultValueType>::type allocateDescriptorSetsUnique( const DescriptorSetAllocateInfo & allocateInfo, Dispatch const &d = Dispatch() ) const; #endif /*VULKAN_HPP_NO_SMART_HANDLE*/ #endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/ @@ -28908,7 +28908,7 @@ public: template , typename Dispatch = DispatchLoaderStatic> typename ResultValueType>::type allocateCommandBuffers( const CommandBufferAllocateInfo & allocateInfo, Dispatch const &d = Dispatch() ) const; #ifndef VULKAN_HPP_NO_SMART_HANDLE - template , typename Dispatch = DispatchLoaderStatic> + template , typename Dispatch = DispatchLoaderStatic> typename ResultValueType>::type allocateCommandBuffersUnique( const CommandBufferAllocateInfo & allocateInfo, Dispatch const &d = Dispatch() ) const; #endif /*VULKAN_HPP_NO_SMART_HANDLE*/ #endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/ @@ -28928,9 +28928,9 @@ public: template , typename Dispatch = DispatchLoaderStatic> ResultValueType::type createSharedSwapchainKHR( const SwapchainCreateInfoKHR & createInfo, Optional allocator = nullptr, Dispatch const &d = Dispatch() ) const; #ifndef VULKAN_HPP_NO_SMART_HANDLE - template , typename Dispatch = DispatchLoaderStatic> + template , typename Dispatch = DispatchLoaderStatic> typename ResultValueType>::type createSharedSwapchainsKHRUnique( ArrayProxy createInfos, Optional allocator = nullptr, Dispatch const &d = Dispatch() ) const; - template , typename Dispatch = DispatchLoaderStatic> + template , typename Dispatch = DispatchLoaderStatic> ResultValueType::type createSharedSwapchainKHRUnique( const SwapchainCreateInfoKHR & createInfo, Optional allocator = nullptr, Dispatch const &d = Dispatch() ) const; #endif /*VULKAN_HPP_NO_SMART_HANDLE*/ #endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/ @@ -30779,18 +30779,19 @@ public: template VULKAN_HPP_INLINE typename ResultValueType>::type Device::createGraphicsPipelinesUnique( PipelineCache pipelineCache, ArrayProxy createInfos, Optional allocator, Dispatch const &d ) const { - std::vector pipelines( createInfos.size() ); - Result result = static_cast( d.vkCreateGraphicsPipelines( m_device, static_cast( pipelineCache ), createInfos.size() , reinterpret_cast( createInfos.data() ), reinterpret_cast( static_cast( allocator ) ), reinterpret_cast( pipelines.data() ) ) ); + static_assert( sizeof( Pipeline ) <= sizeof( UniquePipeline ), "Pipeline is greater than UniquePipeline!" ); + std::vector pipelines; + pipelines.reserve( createInfos.size() ); + Pipeline* buffer = reinterpret_cast( reinterpret_cast( pipelines.data() ) + createInfos.size() * ( sizeof( UniquePipeline ) - sizeof( Pipeline ) ) ); + Result result = static_cast(d.vkCreateGraphicsPipelines( m_device, static_cast( pipelineCache ), createInfos.size() , reinterpret_cast( createInfos.data() ), reinterpret_cast( static_cast( allocator ) ), reinterpret_cast( buffer ) ) ); PipelineDeleter deleter( *this, allocator ); - std::vector uniquePipelines; - uniquePipelines.reserve( pipelines.size() ); - for ( auto const& pipeline : pipelines ) + for ( size_t i=0 ; i VULKAN_HPP_INLINE ResultValueType::type Device::createGraphicsPipelineUnique( PipelineCache pipelineCache, const GraphicsPipelineCreateInfo & createInfo, Optional allocator, Dispatch const &d ) const @@ -30828,18 +30829,19 @@ public: template VULKAN_HPP_INLINE typename ResultValueType>::type Device::createComputePipelinesUnique( PipelineCache pipelineCache, ArrayProxy createInfos, Optional allocator, Dispatch const &d ) const { - std::vector pipelines( createInfos.size() ); - Result result = static_cast( d.vkCreateComputePipelines( m_device, static_cast( pipelineCache ), createInfos.size() , reinterpret_cast( createInfos.data() ), reinterpret_cast( static_cast( allocator ) ), reinterpret_cast( pipelines.data() ) ) ); + static_assert( sizeof( Pipeline ) <= sizeof( UniquePipeline ), "Pipeline is greater than UniquePipeline!" ); + std::vector pipelines; + pipelines.reserve( createInfos.size() ); + Pipeline* buffer = reinterpret_cast( reinterpret_cast( pipelines.data() ) + createInfos.size() * ( sizeof( UniquePipeline ) - sizeof( Pipeline ) ) ); + Result result = static_cast(d.vkCreateComputePipelines( m_device, static_cast( pipelineCache ), createInfos.size() , reinterpret_cast( createInfos.data() ), reinterpret_cast( static_cast( allocator ) ), reinterpret_cast( buffer ) ) ); PipelineDeleter deleter( *this, allocator ); - std::vector uniquePipelines; - uniquePipelines.reserve( pipelines.size() ); - for ( auto const& pipeline : pipelines ) + for ( size_t i=0 ; i VULKAN_HPP_INLINE ResultValueType::type Device::createComputePipelineUnique( PipelineCache pipelineCache, const ComputePipelineCreateInfo & createInfo, Optional allocator, Dispatch const &d ) const @@ -31054,18 +31056,19 @@ public: template VULKAN_HPP_INLINE typename ResultValueType>::type Device::allocateDescriptorSetsUnique( const DescriptorSetAllocateInfo & allocateInfo, Dispatch const &d ) const { - std::vector descriptorSets( allocateInfo.descriptorSetCount ); - Result result = static_cast( d.vkAllocateDescriptorSets( m_device, reinterpret_cast( &allocateInfo ), reinterpret_cast( descriptorSets.data() ) ) ); + static_assert( sizeof( DescriptorSet ) <= sizeof( UniqueDescriptorSet ), "DescriptorSet is greater than UniqueDescriptorSet!" ); + std::vector descriptorSets; + descriptorSets.reserve( allocateInfo.descriptorSetCount ); + DescriptorSet* buffer = reinterpret_cast( reinterpret_cast( descriptorSets.data() ) + allocateInfo.descriptorSetCount * ( sizeof( UniqueDescriptorSet ) - sizeof( DescriptorSet ) ) ); + Result result = static_cast(d.vkAllocateDescriptorSets( m_device, reinterpret_cast( &allocateInfo ), reinterpret_cast( buffer ) ) ); DescriptorSetDeleter deleter( *this, allocateInfo.descriptorPool ); - std::vector uniqueDescriptorSets; - uniqueDescriptorSets.reserve( descriptorSets.size() ); - for ( auto const& descriptorSet : descriptorSets ) + for ( size_t i=0 ; i VULKAN_HPP_INLINE typename ResultValueType>::type Device::allocateCommandBuffersUnique( const CommandBufferAllocateInfo & allocateInfo, Dispatch const &d ) const { - std::vector commandBuffers( allocateInfo.commandBufferCount ); - Result result = static_cast( d.vkAllocateCommandBuffers( m_device, reinterpret_cast( &allocateInfo ), reinterpret_cast( commandBuffers.data() ) ) ); + static_assert( sizeof( CommandBuffer ) <= sizeof( UniqueCommandBuffer ), "CommandBuffer is greater than UniqueCommandBuffer!" ); + std::vector commandBuffers; + commandBuffers.reserve( allocateInfo.commandBufferCount ); + CommandBuffer* buffer = reinterpret_cast( reinterpret_cast( commandBuffers.data() ) + allocateInfo.commandBufferCount * ( sizeof( UniqueCommandBuffer ) - sizeof( CommandBuffer ) ) ); + Result result = static_cast(d.vkAllocateCommandBuffers( m_device, reinterpret_cast( &allocateInfo ), reinterpret_cast( buffer ) ) ); CommandBufferDeleter deleter( *this, allocateInfo.commandPool ); - std::vector uniqueCommandBuffers; - uniqueCommandBuffers.reserve( commandBuffers.size() ); - for ( auto const& commandBuffer : commandBuffers ) + for ( size_t i=0 ; i VULKAN_HPP_INLINE typename ResultValueType>::type Device::createSharedSwapchainsKHRUnique( ArrayProxy createInfos, Optional allocator, Dispatch const &d ) const { - std::vector swapchains( createInfos.size() ); - Result result = static_cast( d.vkCreateSharedSwapchainsKHR( m_device, createInfos.size() , reinterpret_cast( createInfos.data() ), reinterpret_cast( static_cast( allocator ) ), reinterpret_cast( swapchains.data() ) ) ); + static_assert( sizeof( SwapchainKHR ) <= sizeof( UniqueSwapchainKHR ), "SwapchainKHR is greater than UniqueSwapchainKHR!" ); + std::vector swapchainKHRs; + swapchainKHRs.reserve( createInfos.size() ); + SwapchainKHR* buffer = reinterpret_cast( reinterpret_cast( swapchainKHRs.data() ) + createInfos.size() * ( sizeof( UniqueSwapchainKHR ) - sizeof( SwapchainKHR ) ) ); + Result result = static_cast(d.vkCreateSharedSwapchainsKHR( m_device, createInfos.size() , reinterpret_cast( createInfos.data() ), reinterpret_cast( static_cast( allocator ) ), reinterpret_cast( buffer ) ) ); SwapchainKHRDeleter deleter( *this, allocator ); - std::vector uniqueSwapchains; - uniqueSwapchains.reserve( swapchains.size() ); - for ( auto const& swapchain : swapchains ) + for ( size_t i=0 ; i VULKAN_HPP_INLINE ResultValueType::type Device::createSharedSwapchainKHRUnique( const SwapchainCreateInfoKHR & createInfo, Optional allocator, Dispatch const &d ) const