diff --git a/VulkanHppGenerator.cpp b/VulkanHppGenerator.cpp index 9608f52..5693707 100644 --- a/VulkanHppGenerator.cpp +++ b/VulkanHppGenerator.cpp @@ -372,8 +372,34 @@ const std::string arrayProxyHeader = R"( )"; const std::string structureChainHeader = R"( + template struct isStructureChainValid { enum { value = false }; }; + template + struct TypeList + { + using list = P; + using last = T; + }; + + template + struct extendCheck + { + static const bool valid = isStructureChainValid::value || extendCheck::valid; + }; + + template + struct extendCheck,X> + { + static const bool valid = isStructureChainValid::value; + }; + + template + struct extendCheck + { + static const bool valid = true; + }; + template class StructureChainElement { @@ -390,75 +416,78 @@ const std::string structureChainHeader = R"( public: StructureChain() { - link(); + link(); } StructureChain(StructureChain const &rhs) { - linkAndCopy(rhs); + linkAndCopy(rhs); } StructureChain(StructureElements const &... elems) { - linkAndCopyElements(elems...); + linkAndCopyElements(elems...); } StructureChain& operator=(StructureChain const &rhs) { - linkAndCopy(rhs); + linkAndCopy(rhs); return *this; } template ClassType& get() { return static_cast(*this);} private: - template + template void link() { + static_assert(extendCheck::valid, "The structure chain is not valid!"); } - template + template void link() { - static_assert(isStructureChainValid::value, "The structure chain is not valid!"); + static_assert(extendCheck::valid, "The structure chain is not valid!"); X& x = static_cast(*this); Y& y = static_cast(*this); x.pNext = &y; - link(); + link, Y, Z...>(); } - template + template void linkAndCopy(StructureChain const &rhs) { + static_assert(extendCheck::valid, "The structure chain is not valid!"); static_cast(*this) = static_cast(rhs); } - template + template void linkAndCopy(StructureChain const &rhs) { - static_assert(isStructureChainValid::value, "The structure chain is not valid!"); + static_assert(extendCheck::valid, "The structure chain is not valid!"); X& x = static_cast(*this); Y& y = static_cast(*this); x = static_cast(rhs); x.pNext = &y; - linkAndCopy(rhs); + linkAndCopy, Y, Z...>(rhs); } - template + template void linkAndCopyElements(X const &xelem) { + static_assert(extendCheck::valid, "The structure chain is not valid!"); static_cast(*this) = xelem; } - template + template void linkAndCopyElements(X const &xelem, Y const &yelem, Z const &... zelem) { - static_assert(isStructureChainValid::value, "The structure chain is not valid!"); + static_assert(extendCheck::valid, "The structure chain is not valid!"); X& x = static_cast(*this); Y& y = static_cast(*this); x = xelem; x.pNext = &y; - linkAndCopyElements(yelem, zelem...); + linkAndCopyElements, Y, Z...>(yelem, zelem...); } }; diff --git a/tests/StructureChain/StructureChain.cpp b/tests/StructureChain/StructureChain.cpp index dcbd32f..ea87383 100644 --- a/tests/StructureChain/StructureChain.cpp +++ b/tests/StructureChain/StructureChain.cpp @@ -37,14 +37,28 @@ int main(int /*argc*/, char * /*argv[]*/) vk::UniqueInstance instance = vk::createInstanceUnique(vk::InstanceCreateInfo({}, &appInfo)); std::vector physicalDevices = instance->enumeratePhysicalDevices(); + // some valid StructureChains + vk::StructureChain sc0; + vk::StructureChain sc1; + vk::StructureChain sc2; + vk::StructureChain sc3; + vk::StructureChain sc4; + vk::StructureChain sc6; + vk::StructureChain sc7; + + // some not valid StructureChains + //vk::StructureChain x; + //vk::StructureChain x; + //vk::StructureChain x; + //vk::StructureChain x; + //vk::StructureChain x; + vk::PhysicalDevice & pd = physicalDevices[0]; // simple call, passing structures in vk::PhysicalDeviceFeatures2 pdf; pd.getFeatures2(&pdf); - vk::StructureChain z; - // simple calls, getting structure back vk::PhysicalDeviceFeatures2 a = pd.getFeatures2(); vk::PhysicalDeviceFeatures2 b = pd.getFeatures2(vk::DispatchLoaderStatic()); diff --git a/vulkan/vulkan.hpp b/vulkan/vulkan.hpp index 218499c..4869315 100644 --- a/vulkan/vulkan.hpp +++ b/vulkan/vulkan.hpp @@ -479,8 +479,34 @@ namespace VULKAN_HPP_NAMESPACE #endif + template struct isStructureChainValid { enum { value = false }; }; + template + struct TypeList + { + using list = P; + using last = T; + }; + + template + struct extendCheck + { + static const bool valid = isStructureChainValid::value || extendCheck::valid; + }; + + template + struct extendCheck,X> + { + static const bool valid = isStructureChainValid::value; + }; + + template + struct extendCheck + { + static const bool valid = true; + }; + template class StructureChainElement { @@ -497,75 +523,78 @@ namespace VULKAN_HPP_NAMESPACE public: StructureChain() { - link(); + link(); } StructureChain(StructureChain const &rhs) { - linkAndCopy(rhs); + linkAndCopy(rhs); } StructureChain(StructureElements const &... elems) { - linkAndCopyElements(elems...); + linkAndCopyElements(elems...); } StructureChain& operator=(StructureChain const &rhs) { - linkAndCopy(rhs); + linkAndCopy(rhs); return *this; } template ClassType& get() { return static_cast(*this);} private: - template + template void link() { + static_assert(extendCheck::valid, "The structure chain is not valid!"); } - template + template void link() { - static_assert(isStructureChainValid::value, "The structure chain is not valid!"); + static_assert(extendCheck::valid, "The structure chain is not valid!"); X& x = static_cast(*this); Y& y = static_cast(*this); x.pNext = &y; - link(); + link, Y, Z...>(); } - template + template void linkAndCopy(StructureChain const &rhs) { + static_assert(extendCheck::valid, "The structure chain is not valid!"); static_cast(*this) = static_cast(rhs); } - template + template void linkAndCopy(StructureChain const &rhs) { - static_assert(isStructureChainValid::value, "The structure chain is not valid!"); + static_assert(extendCheck::valid, "The structure chain is not valid!"); X& x = static_cast(*this); Y& y = static_cast(*this); x = static_cast(rhs); x.pNext = &y; - linkAndCopy(rhs); + linkAndCopy, Y, Z...>(rhs); } - template + template void linkAndCopyElements(X const &xelem) { + static_assert(extendCheck::valid, "The structure chain is not valid!"); static_cast(*this) = xelem; } - template + template void linkAndCopyElements(X const &xelem, Y const &yelem, Z const &... zelem) { - static_assert(isStructureChainValid::value, "The structure chain is not valid!"); + static_assert(extendCheck::valid, "The structure chain is not valid!"); X& x = static_cast(*this); Y& y = static_cast(*this); x = xelem; x.pNext = &y; - linkAndCopyElements(yelem, zelem...); + linkAndCopyElements, Y, Z...>(yelem, zelem...); } };