mirror of
https://github.com/KhronosGroup/Vulkan-Hpp.git
synced 2024-10-14 16:32:17 +00:00
Add/Reshape copy constructors for structs and unions.
Allows usage of constexpr on those constructors. Resolves #493
This commit is contained in:
parent
837aac5499
commit
7feffc1b9d
@ -2615,6 +2615,24 @@ void VulkanHppGenerator::appendStruct(std::string & str, std::pair<std::string,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VulkanHppGenerator::appendStructAssignmentOperator(std::string &str, std::pair<std::string, StructureData> const& structData, std::string const& prefix) const
|
||||||
|
{
|
||||||
|
// we need an assignment operator if there is constant sType in this struct
|
||||||
|
if ((nonConstSTypeStructs.find(structData.first) == nonConstSTypeStructs.end()) && !structData.second.members.empty() && (structData.second.members.front().name == "sType"))
|
||||||
|
{
|
||||||
|
assert((2 <= structData.second.members.size()) && (structData.second.members[1].name == "pNext"));
|
||||||
|
|
||||||
|
static const std::string stringTemplate = R"(
|
||||||
|
${prefix}${structName} & operator=( ${structName} const & rhs ) VULKAN_HPP_NOEXCEPT
|
||||||
|
${prefix}{
|
||||||
|
${prefix} memcpy( &pNext, &rhs.pNext, sizeof( ${structName} ) - offsetof( ${structName}, pNext ) );
|
||||||
|
${prefix} return *this;
|
||||||
|
${prefix}}
|
||||||
|
)";
|
||||||
|
str += replaceWithMap(stringTemplate, { {"prefix", prefix }, { "structName", stripPrefix(structData.first, "Vk") } });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void VulkanHppGenerator::appendStructCompareOperators(std::string & str, std::pair<std::string, StructureData> const& structData) const
|
void VulkanHppGenerator::appendStructCompareOperators(std::string & str, std::pair<std::string, StructureData> const& structData) const
|
||||||
{
|
{
|
||||||
// two structs are compared by comparing each of the elements
|
// two structs are compared by comparing each of the elements
|
||||||
@ -2656,12 +2674,17 @@ void VulkanHppGenerator::appendStructCompareOperators(std::string & str, std::pa
|
|||||||
str += replaceWithMap(compareTemplate, { { "name", stripPrefix(structData.first, "Vk") }, { "compareMembers", compareMembers } });
|
str += replaceWithMap(compareTemplate, { { "name", stripPrefix(structData.first, "Vk") }, { "compareMembers", compareMembers } });
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string VulkanHppGenerator::appendStructConstructor(std::pair<std::string, StructureData> const& structData, std::string const& prefix) const
|
std::string VulkanHppGenerator::constructConstexprString(std::pair<std::string, StructureData> const& structData) const
|
||||||
|
{
|
||||||
|
// structs with a union (and VkBaseInStructure and VkBaseOutStructure) can't be a constexpr!
|
||||||
|
bool isConstExpression = !containsUnion(structData.first) && (structData.first != "VkBaseInStructure") && (structData.first != "VkBaseOutStructure");
|
||||||
|
return isConstExpression ? (std::string("VULKAN_HPP_CONSTEXPR") + (containsArray(structData.first) ? "_14 " : " ")) : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void VulkanHppGenerator::appendStructConstructor(std::string &str, std::pair<std::string, StructureData> const& structData, std::string const& prefix) const
|
||||||
{
|
{
|
||||||
// the constructor with all the elements as arguments, with defaults
|
// the constructor with all the elements as arguments, with defaults
|
||||||
// returnedOnly structs and structs with a union (and VkBaseInStructure and VkBaseOutStructure) can't be a constexpr!
|
std::string constexprString = constructConstexprString(structData);
|
||||||
bool isConstExpression = !structData.second.returnedOnly && !containsUnion(structData.first) && (structData.first != "VkBaseInStructure") && (structData.first != "VkBaseOutStructure");
|
|
||||||
std::string constexprString = isConstExpression ? (std::string("VULKAN_HPP_CONSTEXPR") + (containsArray(structData.first) ? "_14 " : " ")) : "";
|
|
||||||
std::string ctorOpening = prefix + constexprString + stripPrefix(structData.first, "Vk");
|
std::string ctorOpening = prefix + constexprString + stripPrefix(structData.first, "Vk");
|
||||||
std::string indentation(ctorOpening.size() + 2, ' ');
|
std::string indentation(ctorOpening.size() + 2, ' ');
|
||||||
|
|
||||||
@ -2699,67 +2722,70 @@ std::string VulkanHppGenerator::appendStructConstructor(std::pair<std::string, S
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string structConstructor = ctorOpening + (arguments.empty() ? "()" : std::string("( " + arguments + " )")) + " VULKAN_HPP_NOEXCEPT\n";
|
str += ctorOpening + (arguments.empty() ? "()" : std::string("( " + arguments + " )")) + " VULKAN_HPP_NOEXCEPT\n" + initializers;
|
||||||
structConstructor += initializers;
|
|
||||||
if (copyOps.empty())
|
if (copyOps.empty())
|
||||||
{
|
{
|
||||||
structConstructor += prefix + "{}\n";
|
str += prefix + "{}\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
structConstructor += prefix + "{\n" + copyOps + prefix + "}\n";
|
str += prefix + "{\n" + copyOps + prefix + "}\n";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!structData.second.subStruct.empty())
|
void VulkanHppGenerator::appendStructCopyConstructor(std::string &str, std::pair<std::string, StructureData> const& structData, std::string const& prefix) const
|
||||||
|
{
|
||||||
|
// the constructor with all the elements as arguments, with defaults
|
||||||
|
std::string constexprString = constructConstexprString(structData);
|
||||||
|
std::string ctorOpening = prefix + constexprString + stripPrefix(structData.first, "Vk");
|
||||||
|
std::string indentation(ctorOpening.size() + 2, ' ');
|
||||||
|
|
||||||
|
std::string initializers, copyOps;
|
||||||
|
bool firstArgument = true;
|
||||||
|
for (auto const& member : structData.second.members)
|
||||||
{
|
{
|
||||||
auto const& subStruct = m_structures.find(structData.second.subStruct);
|
if (member.name == "pNext")
|
||||||
assert(subStruct != m_structures.end());
|
|
||||||
|
|
||||||
std::string subStructArgumentName = startLowerCase(stripPrefix(subStruct->first, "Vk"));
|
|
||||||
ctorOpening = prefix + "explicit " + stripPrefix(structData.first, "Vk") + "( ";
|
|
||||||
indentation = std::string(ctorOpening.size(), ' ');
|
|
||||||
|
|
||||||
std::string subCopies;
|
|
||||||
firstArgument = true;
|
|
||||||
for (size_t i = 0; i < subStruct->second.members.size(); i++)
|
|
||||||
{
|
{
|
||||||
assert(structData.second.members[i].arraySizes.empty());
|
assert(firstArgument);
|
||||||
subCopies += prefix + " " + (firstArgument ? ":" : ",") + " " + structData.second.members[i].name + "( " + subStructArgumentName + "." + subStruct->second.members[i].name + " )\n";
|
initializers += prefix + " : pNext( rhs.pNext )\n";
|
||||||
firstArgument = false;
|
firstArgument = false;
|
||||||
}
|
}
|
||||||
|
else if (member.name != "sType")
|
||||||
std::string subArguments;
|
|
||||||
listedArgument = true;
|
|
||||||
for (size_t i = subStruct->second.members.size(); i < structData.second.members.size(); i++)
|
|
||||||
{
|
{
|
||||||
listedArgument = appendStructConstructorArgument(subArguments, listedArgument, indentation, structData.second.members[i]);
|
// gather the initializers; skip member 'sType', which is directly set by initializer
|
||||||
|
if (member.arraySizes.empty())
|
||||||
|
{
|
||||||
|
// here, we can only handle non-array arguments
|
||||||
|
initializers += prefix + " " + (firstArgument ? ":" : ",") + " " + member.name + "( rhs." + member.name + " )\n";
|
||||||
|
firstArgument = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// here we can handle the arrays, copying over from argument (with trailing '_') to member
|
||||||
|
initializers += prefix + " " + (firstArgument ? ":" : ",") + " " + member.name + "{}\n"; // need to initialize the array
|
||||||
|
firstArgument = false;
|
||||||
|
|
||||||
assert(structData.second.members[i].arraySizes.empty());
|
std::string type = (member.type.type.substr(0, 2) == "Vk") ? ("VULKAN_HPP_NAMESPACE::" + stripPrefix(member.type.type, "Vk")) : member.type.type;
|
||||||
subCopies += prefix + " , " + structData.second.members[i].name + "( " + structData.second.members[i].name + "_ )\n";
|
std::string arraySizes;
|
||||||
|
for (auto const& as : member.arraySizes)
|
||||||
|
{
|
||||||
|
arraySizes += "," + as;
|
||||||
|
}
|
||||||
|
copyOps += "\n" + prefix + " VULKAN_HPP_NAMESPACE::ConstExpression" + std::to_string(member.arraySizes.size()) + "DArrayCopy<" + type + arraySizes + arraySizes + ">::copy( " + member.name + ", rhs." + member.name + " );";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!copyOps.empty())
|
||||||
|
{
|
||||||
|
copyOps += "\n" + prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
structConstructor += "\n"
|
static std::string constructorTemplate = R"(
|
||||||
" explicit " + stripPrefix(structData.first, "Vk") + "( " + stripPrefix(subStruct->first, "Vk") + " const& " + subStructArgumentName + subArguments + " )\n"
|
${prefix}${constexpr}${structName}( ${structName} const& rhs ) VULKAN_HPP_NOEXCEPT
|
||||||
+ subCopies +
|
${initializers}${prefix}{${copyOps}}
|
||||||
" {}\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// we need a copy constructor if there is constant sType in this struct
|
|
||||||
if ((nonConstSTypeStructs.find(structData.first) == nonConstSTypeStructs.end()) && !structData.second.members.empty() && (structData.second.members.front().name == "sType"))
|
|
||||||
{
|
|
||||||
assert((2 <= structData.second.members.size()) && (structData.second.members[1].name == "pNext"));
|
|
||||||
|
|
||||||
static const std::string stringTemplate = R"(
|
|
||||||
${prefix}VULKAN_HPP_NAMESPACE::${structName} & operator=( VULKAN_HPP_NAMESPACE::${structName} const & rhs ) VULKAN_HPP_NOEXCEPT
|
|
||||||
${prefix}{
|
|
||||||
${prefix} memcpy( &pNext, &rhs.pNext, sizeof( VULKAN_HPP_NAMESPACE::${structName} ) - offsetof( ${structName}, pNext ) );
|
|
||||||
${prefix} return *this;
|
|
||||||
${prefix}}
|
|
||||||
)";
|
)";
|
||||||
structConstructor += replaceWithMap(stringTemplate, { {"prefix", prefix }, { "structName", stripPrefix(structData.first, "Vk") } });
|
|
||||||
}
|
|
||||||
|
|
||||||
return structConstructor;
|
str += replaceWithMap(constructorTemplate, { { "prefix", prefix }, { "constexpr", constexprString }, { "structName", stripPrefix(structData.first, "Vk") }, { "initializers", initializers }, { "copyOps", copyOps } });
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VulkanHppGenerator::appendStructConstructorArgument(std::string & str, bool listedArgument, std::string const& indentation, MemberData const& memberData) const
|
bool VulkanHppGenerator::appendStructConstructorArgument(std::string & str, bool listedArgument, std::string const& indentation, MemberData const& memberData) const
|
||||||
@ -2925,12 +2951,53 @@ void VulkanHppGenerator::appendStructSetter(std::string & str, std::string const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VulkanHppGenerator::appendStructSubConstructor(std::string &str, std::pair<std::string, StructureData> const& structData, std::string const& prefix) const
|
||||||
|
{
|
||||||
|
if (!structData.second.subStruct.empty())
|
||||||
|
{
|
||||||
|
auto const& subStruct = m_structures.find(structData.second.subStruct);
|
||||||
|
assert(subStruct != m_structures.end());
|
||||||
|
|
||||||
|
std::string subStructArgumentName = startLowerCase(stripPrefix(subStruct->first, "Vk"));
|
||||||
|
std::string ctorOpening = prefix + "explicit " + stripPrefix(structData.first, "Vk") + "( ";
|
||||||
|
std::string indentation = std::string(ctorOpening.size(), ' ');
|
||||||
|
|
||||||
|
std::string subCopies;
|
||||||
|
bool firstArgument = true;
|
||||||
|
for (size_t i = 0; i < subStruct->second.members.size(); i++)
|
||||||
|
{
|
||||||
|
assert(structData.second.members[i].arraySizes.empty());
|
||||||
|
subCopies += prefix + " " + (firstArgument ? ":" : ",") + " " + structData.second.members[i].name + "( " + subStructArgumentName + "." + subStruct->second.members[i].name + " )\n";
|
||||||
|
firstArgument = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string subArguments;
|
||||||
|
bool listedArgument = true;
|
||||||
|
for (size_t i = subStruct->second.members.size(); i < structData.second.members.size(); i++)
|
||||||
|
{
|
||||||
|
listedArgument = appendStructConstructorArgument(subArguments, listedArgument, indentation, structData.second.members[i]);
|
||||||
|
|
||||||
|
assert(structData.second.members[i].arraySizes.empty());
|
||||||
|
subCopies += prefix + " , " + structData.second.members[i].name + "( " + structData.second.members[i].name + "_ )\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
str += "\n"
|
||||||
|
" explicit " + stripPrefix(structData.first, "Vk") + "( " + stripPrefix(subStruct->first, "Vk") + " const& " + subStructArgumentName + subArguments + " )\n"
|
||||||
|
+ subCopies +
|
||||||
|
" {}\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void VulkanHppGenerator::appendStructure(std::string & str, std::pair<std::string, StructureData> const& structure) const
|
void VulkanHppGenerator::appendStructure(std::string & str, std::pair<std::string, StructureData> const& structure) const
|
||||||
{
|
{
|
||||||
str += "\n";
|
str += "\n";
|
||||||
appendPlatformEnter(str, structure.second.platform);
|
appendPlatformEnter(str, structure.second.platform);
|
||||||
|
|
||||||
std::string constructorAndSetters = appendStructConstructor(structure, " ");
|
std::string constructorAndSetters;
|
||||||
|
appendStructConstructor(constructorAndSetters, structure, " ");
|
||||||
|
appendStructCopyConstructor(constructorAndSetters, structure, " ");
|
||||||
|
appendStructSubConstructor(constructorAndSetters, structure, " ");
|
||||||
|
appendStructAssignmentOperator(constructorAndSetters, structure, " ");
|
||||||
appendStructCopyConstructors(constructorAndSetters, stripPrefix(structure.first, "Vk"));
|
appendStructCopyConstructors(constructorAndSetters, stripPrefix(structure.first, "Vk"));
|
||||||
if (!structure.second.returnedOnly)
|
if (!structure.second.returnedOnly)
|
||||||
{
|
{
|
||||||
@ -3053,12 +3120,15 @@ void VulkanHppGenerator::appendThrowExceptions(std::string & str) const
|
|||||||
|
|
||||||
void VulkanHppGenerator::appendUnion(std::string & str, std::pair<std::string, StructureData> const& structure) const
|
void VulkanHppGenerator::appendUnion(std::string & str, std::pair<std::string, StructureData> const& structure) const
|
||||||
{
|
{
|
||||||
|
std::string unionName = stripPrefix(structure.first, "Vk");
|
||||||
str += "\n"
|
str += "\n"
|
||||||
" union " + stripPrefix(structure.first, "Vk") + "\n"
|
" union " + unionName + "\n"
|
||||||
" {\n";
|
" {\n"
|
||||||
|
" " + unionName + "( VULKAN_HPP_NAMESPACE::" + unionName + " const& rhs ) VULKAN_HPP_NOEXCEPT\n"
|
||||||
|
" {\n"
|
||||||
|
" memcpy( this, &rhs, sizeof( VULKAN_HPP_NAMESPACE::" + unionName + " ) );\n"
|
||||||
|
" }\n";
|
||||||
|
|
||||||
if (!structure.second.returnedOnly)
|
|
||||||
{
|
|
||||||
bool firstMember = true;
|
bool firstMember = true;
|
||||||
for (auto const& member : structure.second.members)
|
for (auto const& member : structure.second.members)
|
||||||
{
|
{
|
||||||
@ -3106,7 +3176,6 @@ void VulkanHppGenerator::appendUnion(std::string & str, std::pair<std::string, S
|
|||||||
{
|
{
|
||||||
appendStructSetter(str, stripPrefix(structure.first, "Vk"), member);
|
appendStructSetter(str, stripPrefix(structure.first, "Vk"), member);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// assignment operator
|
// assignment operator
|
||||||
static const std::string operatorsTemplate = R"(
|
static const std::string operatorsTemplate = R"(
|
||||||
@ -3210,7 +3279,7 @@ bool VulkanHppGenerator::containsArray(std::string const& type) const
|
|||||||
{
|
{
|
||||||
for (auto memberIt = structureIt->second.members.begin(); memberIt != structureIt->second.members.end() && !found; ++memberIt)
|
for (auto memberIt = structureIt->second.members.begin(); memberIt != structureIt->second.members.end() && !found; ++memberIt)
|
||||||
{
|
{
|
||||||
found = !memberIt->arraySizes.empty();
|
found = !memberIt->arraySizes.empty() || containsArray(memberIt->type.type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return found;
|
return found;
|
||||||
@ -5331,6 +5400,12 @@ static const std::string constExpressionArrayCopy = R"(
|
|||||||
dst[I-1] = src[I-1];
|
dst[I-1] = src[I-1];
|
||||||
ConstExpression1DArrayCopy<T, N, I - 1>::copy(dst, src);
|
ConstExpression1DArrayCopy<T, N, I - 1>::copy(dst, src);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VULKAN_HPP_CONSTEXPR_14 static void copy(T dst[N], const T src[N]) VULKAN_HPP_NOEXCEPT
|
||||||
|
{
|
||||||
|
dst[I - 1] = src[I - 1];
|
||||||
|
ConstExpression1DArrayCopy<T, N, I - 1>::copy(dst, src);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, size_t N>
|
template <typename T, size_t N>
|
||||||
@ -5338,6 +5413,7 @@ static const std::string constExpressionArrayCopy = R"(
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
VULKAN_HPP_CONSTEXPR_14 static void copy(T /*dst*/[N], std::array<T,N> const& /*src*/) VULKAN_HPP_NOEXCEPT {}
|
VULKAN_HPP_CONSTEXPR_14 static void copy(T /*dst*/[N], std::array<T,N> const& /*src*/) VULKAN_HPP_NOEXCEPT {}
|
||||||
|
VULKAN_HPP_CONSTEXPR_14 static void copy(T /*dst*/[N], const T /*src*/[N]) VULKAN_HPP_NOEXCEPT {}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, size_t N, size_t M, size_t I, size_t J>
|
template <typename T, size_t N, size_t M, size_t I, size_t J>
|
||||||
|
@ -215,15 +215,19 @@ class VulkanHppGenerator
|
|||||||
void appendPlatformEnter(std::string & str, std::string const& platform) const;
|
void appendPlatformEnter(std::string & str, std::string const& platform) const;
|
||||||
void appendPlatformLeave(std::string & str, std::string const& platform) const;
|
void appendPlatformLeave(std::string & str, std::string const& platform) const;
|
||||||
void appendStruct(std::string & str, std::pair<std::string, StructureData> const& structure, std::set<std::string> & listedStructures) const;
|
void appendStruct(std::string & str, std::pair<std::string, StructureData> const& structure, std::set<std::string> & listedStructures) const;
|
||||||
|
void appendStructAssignmentOperator(std::string &str, std::pair<std::string, StructureData> const& structure, std::string const& prefix) const;
|
||||||
void appendStructCompareOperators(std::string & str, std::pair<std::string, StructureData> const& structure) const;
|
void appendStructCompareOperators(std::string & str, std::pair<std::string, StructureData> const& structure) const;
|
||||||
std::string appendStructConstructor(std::pair<std::string, StructureData> const& structData, std::string const& prefix) const;
|
void appendStructConstructor(std::string &str, std::pair<std::string, StructureData> const& structData, std::string const& prefix) const;
|
||||||
bool appendStructConstructorArgument(std::string & str, bool listedArgument, std::string const& indentation, MemberData const& memberData) const;
|
bool appendStructConstructorArgument(std::string & str, bool listedArgument, std::string const& indentation, MemberData const& memberData) const;
|
||||||
|
void appendStructCopyConstructor(std::string &str, std::pair<std::string, StructureData> const& structData, std::string const& prefix) const;
|
||||||
void appendStructCopyConstructors(std::string & str, std::string const& vkName) const;
|
void appendStructCopyConstructors(std::string & str, std::string const& vkName) const;
|
||||||
void appendStructMembers(std::string & str, std::pair<std::string,StructureData> const& structData, std::string const& prefix) const;
|
void appendStructMembers(std::string & str, std::pair<std::string,StructureData> const& structData, std::string const& prefix) const;
|
||||||
void appendStructSetter(std::string & str, std::string const& structureName, MemberData const& memberData) const;
|
void appendStructSetter(std::string & str, std::string const& structureName, MemberData const& memberData) const;
|
||||||
|
void appendStructSubConstructor(std::string &str, std::pair<std::string, StructureData> const& structData, std::string const& prefix) const;
|
||||||
void appendStructure(std::string & str, std::pair<std::string, StructureData> const& structure) const;
|
void appendStructure(std::string & str, std::pair<std::string, StructureData> const& structure) const;
|
||||||
void appendUnion(std::string & str, std::pair<std::string, StructureData> const& structure) const;
|
void appendUnion(std::string & str, std::pair<std::string, StructureData> const& structure) const;
|
||||||
void appendUniqueTypes(std::string &str, std::string const& parentType, std::set<std::string> const& childrenTypes) const;
|
void appendUniqueTypes(std::string &str, std::string const& parentType, std::set<std::string> const& childrenTypes) const;
|
||||||
|
std::string constructConstexprString(std::pair<std::string, StructureData> const& structData) const;
|
||||||
bool containsArray(std::string const& type) const;
|
bool containsArray(std::string const& type) const;
|
||||||
bool containsUnion(std::string const& type) const;
|
bool containsUnion(std::string const& type) const;
|
||||||
std::string determineEnhancedReturnType(CommandData const& commandData, size_t returnParamIndex, std::map<size_t, size_t> const& vectorParamIndices, bool twoStep, bool isStructureChain) const;
|
std::string determineEnhancedReturnType(CommandData const& commandData, size_t returnParamIndex, std::map<size_t, size_t> const& vectorParamIndices, bool twoStep, bool isStructureChain) const;
|
||||||
|
5588
vulkan/vulkan.hpp
5588
vulkan/vulkan.hpp
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user