Vulkan-Hpp: Add RAII support with VULKAN_HPP_NO_EXCEPTIONS
Google / Android does not use exceptions (see here). However, the RAII classes are very useful!
Could we update the RAII generator to guard the throwing constructors for handle types using:
#ifndef VULKAN_HPP_NO_EXCEPTIONS
Image(...)
{
...
if (result != success)
{
throwResultException(...);
}
}
#endif
guard the throwResultException() function definition, and introduce static “create” functions that return a std::expected<HandleType, vk::Result> using:
static std::expected<Image, VULKAN_HPP_NAMESPACE::Result> create(...)
{
...
if (result != success)
{
return std::unexpected(result);
}
return Image(...);
}
Bonus points if we can use custom defines such as VULKAN_HPP_RAII_EXPECTED_CLASS /VULKAN_HPP_RAII_UNEXPECTED_CLASS to use custom “expected” implementations when compiling for C++ version < 23 (for example, android::base::expected). If these VULKAN_HPP_RAII_EXPECTED_CLASS /VULKAN_HPP_RAII_UNEXPECTED_CLASS defines are not defined, potentially need to guard the create() functions based on the version.
See https://android-review.googlesource.com/c/device/google/cuttlefish/+/2404731 for a quick attempt at this.
About this issue
- Original URL
- State: closed
- Created a year ago
- Comments: 26 (21 by maintainers)
Yep, that’s the way to go!
I might have a go at implementing it and see if I get something workable.
vk::ResultValuealready exists, so we might need name itvk::Expected.I figure keep it out of the
vk::raiinamespace because it’s not really an RAII object, and maybe we can eventually backport it to Vulkan.hpp as a configurable replacement forResultValue.I did some experiments on top of @jmacnak’s code (see my WIP branch is here. No guarantee it actually runs)
With a careful choice of defines, it’s possible to make the it work with both the
std::expectedinterface and something more basic like astd::tupleHowever, I spent some time porting my codebase over using tuples for error returns, and it’s less than ideal. Very tempting to use
std::tie, which made it very easy for thenullptrconstructed RAII objects to escape into the rest of application’s codebase. Feels unclean and I’m very tempted to just borrow android’s implementation ofstd::expected.But an alternative proposal for supporting older versions of C++ What if RAII provided it’s own
vk::ValueResult(or whatever it’s named) that implements a usable subset of thestd::expectedinterface. Make it hard-coded tovk::Resultand supply the basic accessors. Then when the headers are compiled with a c++23 compiler (or a supplied alternative implementation ofstd::expected) they can implementvk::ValueResultas just a type alias and the user will get the full functionality ofstd::expected, without breaking old code.My understanding is that this is fairly common in library code. Macros are the most straightforward way to provide similar functionality across various C++ versions. They also make generated code easier to deal with, from what I’ve seen.
Templated types can potentially explode compile times, and Vulkan-Hpp is already huge as it is (I’ve literally never seen a larger header file, we are approaching 100K lines).
We actually do have constexpr functions, but these are for the users to use.