Merge pull request #82 from asuessenbach/issue81

Fix issue #81, support Optional<string> for functions where strings are not required. Also remove static null() function in each struct. Use nullptr instead.
This commit is contained in:
Markus Tavenrath 2016-03-23 16:19:37 +01:00
commit 900744a8ca
3 changed files with 370 additions and 977 deletions

View File

@ -106,8 +106,8 @@ vk::ImageCreateInfo ci(
# String conversions # String conversions
At development time it can be quite handy to have a utility function that can convert an enum or flags to a string for debugging purposes. To achieve this, At development time it can be quite handy to have a utility function that can convert an enum or flags to a string for debugging purposes. To achieve this,
we have implemented ```getString(type)``` functions for all enums and flags. Calling ```getString(vk::SharingMode::eExclusive)``` will return 'Exclusive' and calling we have implemented ```to_string(type)``` functions for all enums and flags. Calling ```to_string(vk::SharingMode::eExclusive)``` will return 'Exclusive' and calling
```getString(vk::QueueFlagBits::eGraphics | vk::QueueFlagBits::eCompute)``` will return the concatenated string 'Graphics | Compute'. ```to_string(vk::QueueFlagBits::eGraphics | vk::QueueFlagBits::eCompute)``` will return the concatenated string 'Graphics | Compute'.
# Alternative Initialization of Structs # Alternative Initialization of Structs
@ -141,7 +141,7 @@ parameter matches the handle. In addition to this we made a few changes to the s
* ```const char *``` has been replaced by ```std::string ``` * ```const char *``` has been replaced by ```std::string ```
* ```T const*``` has been replaced by ```T const &``` to allow temporary objects. This is useful to pass small structures like ```vk::ClearColorValue``` or ```vk::Extent*``` * ```T const*``` has been replaced by ```T const &``` to allow temporary objects. This is useful to pass small structures like ```vk::ClearColorValue``` or ```vk::Extent*```
```commandBuffer.clearColorImage(image, layout, std::array<float, 4>{1.0f, 1.0f, 1.0f, 1.0f}, {...});``` ```commandBuffer.clearColorImage(image, layout, std::array<float, 4>{1.0f, 1.0f, 1.0f, 1.0f}, {...});```
Optional parameters are being replaced by ```Optional<T> const &``` which accept a type of ```T const&```. To tell the wrapper that a nullptr should be passed use ```T::null()```. Optional parameters are being replaced by ```Optional<T> const &``` which accept a type of ```T const&```. ```nullptr``` can be used to initialize an empty ```Optional<T>```.
* The wrapper will throw a ```std::system_error``` if a ```vk::Result``` return value is not an success code. If there's only a single success code it's not returned at all. In this case functions with a single output value do return this output value instead. * The wrapper will throw a ```std::system_error``` if a ```vk::Result``` return value is not an success code. If there's only a single success code it's not returned at all. In this case functions with a single output value do return this output value instead.
Here are a few code examples: Here are a few code examples:
@ -168,8 +168,8 @@ Here are a few code examples:
// Accept std::vector as source for updateBuffer // Accept std::vector as source for updateBuffer
commandBuffer.updateBuffer(buffer, 0, {some values}); // update buffer with std::vector commandBuffer.updateBuffer(buffer, 0, {some values}); // update buffer with std::vector
// Sometimes it's necessary to pass a nullptr to a struct. For this case we've added Optional<T> T::null() to all structs T as replacement for the nullptr. // Sometimes it's necessary to pass a nullptr to a struct. For this case we've added Optional<T>(std::nullptr_t).
device.allocateMemory(allocateInfo, vk::AllocationCallbacks::null()); device.allocateMemory(allocateInfo, nullptr);
} }
catch (std::system_error e) catch (std::system_error e)

View File

@ -215,20 +215,21 @@ const std::string flagsHeader(
); );
std::string const optionalClassHeader = ( std::string const optionalClassHeader = (
" template <typename RefType>\n" " template <typename RefType>\n"
" class Optional\n" " class Optional\n"
" {\n" " {\n"
" public:\n" " public:\n"
" Optional(RefType & reference) { m_ptr = &reference; }\n" " Optional(RefType & reference) { m_ptr = &reference; }\n"
"\n" " Optional(std::nullptr_t) { m_ptr = nullptr; }\n"
" operator RefType*() const { return m_ptr; }\n" "\n"
"\n" " operator RefType*() const { return m_ptr; }\n"
" private:\n" " RefType const* operator->() const { return m_ptr; }\n"
" Optional(std::nullptr_t) { m_ptr = nullptr; }\n" " explicit operator bool() const { return !m_ptr; }\n"
" friend RefType;\n" "\n"
" RefType *m_ptr;\n" " private:\n"
" };\n" " RefType *m_ptr;\n"
"\n" " };\n"
"\n"
); );
// trim from end // trim from end
@ -1603,7 +1604,15 @@ void writeCall(std::ofstream & ofs, std::string const& name, size_t templateInde
} }
else if (commandData.arguments[it->first].pureType == "char") else if (commandData.arguments[it->first].pureType == "char")
{ {
ofs << reduceName(commandData.arguments[it->first].name) << ".c_str()"; ofs << reduceName(commandData.arguments[it->first].name);
if (commandData.arguments[it->first].optional)
{
ofs << " ? " << reduceName(commandData.arguments[it->first].name) << "->c_str() : nullptr";
}
else
{
ofs << ".c_str()";
}
} }
else else
{ {
@ -1626,11 +1635,11 @@ void writeCall(std::ofstream & ofs, std::string const& name, size_t templateInde
{ {
ofs << "&"; ofs << "&";
} }
ofs << reduceName(commandData.arguments[i].name) ofs << reduceName(commandData.arguments[i].name) << (commandData.arguments[i].optional ? "))" : " )");
<< (commandData.arguments[i].optional ? "))" : " )");
} }
else else
{ {
assert(!commandData.arguments[i].optional);
ofs << "reinterpret_cast<Vk" << commandData.arguments[i].pureType << "*>( &" << reduceName(commandData.arguments[i].name) << " )"; ofs << "reinterpret_cast<Vk" << commandData.arguments[i].pureType << "*>( &" << reduceName(commandData.arguments[i].name) << " )";
} }
} }
@ -1646,7 +1655,15 @@ void writeCall(std::ofstream & ofs, std::string const& name, size_t templateInde
if (commandData.arguments[i].type.find("const") != std::string::npos) if (commandData.arguments[i].type.find("const") != std::string::npos)
{ {
assert(commandData.arguments[i].type.find("char") != std::string::npos); assert(commandData.arguments[i].type.find("char") != std::string::npos);
ofs << reduceName(commandData.arguments[i].name) << ".c_str()"; ofs << reduceName(commandData.arguments[i].name);
if (commandData.arguments[i].optional)
{
ofs << " ? " << reduceName(commandData.arguments[i].name) << "->c_str() : nullptr";
}
else
{
ofs << ".c_str()";
}
} }
else else
{ {
@ -1864,10 +1881,10 @@ void writeFunctionHeader(std::ofstream & ofs, std::string const& indentation, st
{ {
ofs << ", "; ofs << ", ";
} }
if (vectorParameters.find(i) == vectorParameters.end())
{ std::map<size_t,size_t>::const_iterator it = vectorParameters.find(i);
size_t pos = commandData.arguments[i].type.find('*'); size_t pos = commandData.arguments[i].type.find('*');
if (pos == std::string::npos) if ((it == vectorParameters.end()) && (pos == std::string::npos))
{ {
ofs << commandData.arguments[i].type << " " << commandData.arguments[i].name; ofs << commandData.arguments[i].type << " " << commandData.arguments[i].name;
if (!commandData.arguments[i].arraySize.empty()) if (!commandData.arguments[i].arraySize.empty())
@ -1877,50 +1894,52 @@ void writeFunctionHeader(std::ofstream & ofs, std::string const& indentation, st
} }
else else
{ {
std::string type = commandData.arguments[i].type; bool optional = commandData.arguments[i].optional && ((it == vectorParameters.end()) || (it->second == ~0));
if (type.find("char") != std::string::npos) if (optional)
{ {
type = "std::string const&"; ofs << "vk::Optional<";
}
if (vectorParameters.find(i) == vectorParameters.end())
{
assert(pos != std::string::npos);
if (commandData.arguments[i].type.find("char") != std::string::npos)
{
ofs << "std::string const";
} }
else else
{ {
assert(type[pos] == '*'); assert(commandData.arguments[i].type[pos] == '*');
if (commandData.arguments[i].optional) ofs << trimEnd(commandData.arguments[i].type.substr(0, pos));
{
type[pos] = ' ';
type = "vk::Optional<" + trimEnd(type) + "> const &";
}
else
{
type[pos] = '&';
}
}
ofs << type << " " << reduceName(commandData.arguments[i].name);
} }
} }
else else
{ {
if (templateIndex == i) if (templateIndex == i)
{ {
ofs << "std::vector<T> "; ofs << "std::vector<T>";
} }
else if (commandData.arguments[i].pureType == "char") else if (commandData.arguments[i].pureType == "char")
{ {
ofs << "std::string "; ofs << "std::string";
} }
else if (commandData.arguments[i].pureType == "void") else if (commandData.arguments[i].pureType == "void")
{ {
ofs << "std::vector<uint8_t> "; ofs << "std::vector<uint8_t>";
} }
else else
{ {
ofs << "std::vector<" << commandData.arguments[i].pureType << "> "; ofs << "std::vector<" << commandData.arguments[i].pureType << ">";
} }
if (commandData.arguments[i].type.find("const") != std::string::npos) if (commandData.arguments[i].type.find("const") != std::string::npos)
{ {
ofs << "const"; ofs << " const";
} }
ofs << "& " << reduceName(commandData.arguments[i].name); }
if (optional)
{
ofs << "> const";
}
ofs << " & " << reduceName(commandData.arguments[i].name);
} }
argEncountered = true; argEncountered = true;
} }
@ -2506,13 +2525,6 @@ void writeTypeStruct( std::ofstream & ofs, VkData const& vkData, DependencyData
} }
} }
// null handle
ofs << " static Optional<const " << dependencyData.name << "> null()" << std::endl
<< " {" << std::endl
<< " return Optional<const " << dependencyData.name << ">(nullptr);" << std::endl
<< " }" << std::endl
<< std::endl;
// the cast-operator to the wrapped struct, and the struct itself as a private member variable // the cast-operator to the wrapped struct, and the struct itself as a private member variable
ofs << " operator const Vk" << dependencyData.name << "&() const" << std::endl ofs << " operator const Vk" << dependencyData.name << "&() const" << std::endl
<< " {" << std::endl << " {" << std::endl

File diff suppressed because it is too large Load Diff