diff --git a/except.hpp b/except.hpp index acfbf06..562356f 100644 --- a/except.hpp +++ b/except.hpp @@ -84,6 +84,17 @@ namespace cruft::vk { } + ///-------------------------------------------------------------------- + /// returns a container of values obtained from FuncT + /// + /// FuncT must take arguments of the form: + /// ... FuncT (..., uint32_t *length, ResultT *values) + /// and must return the expected length when values is null. + /// + /// the return type will be checked by try_code if it is a VkResult. + /// + /// the container will dynamically size so that it can contain all + /// available values. template < template class ContainerT = std::vector, typename FuncT, @@ -92,9 +103,12 @@ namespace cruft::vk { static auto try_array (FuncT &&func, Args &&...args) { + // extract the number of elements available uint32_t expected = 0; try_func (func, args..., &expected, nullptr); + // find the type of the last argument, ie. the values we're + // requesting using ValueT = std::remove_pointer_t< std::tuple_element_t< sizeof...(Args) + 1, @@ -102,11 +116,17 @@ namespace cruft::vk { > >; + // return the values on the stack temporarily as we may need to + // convert them to a seperate result type. + // + // TODO: remove this intermediate step where we don't actually + // have a conversion to do, ie ResultT == ValueT. ValueT values[expected]; uint32_t found = expected; try_func (func, args..., &found, &values[0]); CHECK_EQ (expected, found); + // convert to the requested type return ContainerT { &values[0], &values[found] @@ -115,6 +135,7 @@ namespace cruft::vk { }; + //------------------------------------------------------------------------- class invalid_argument : public error { public: invalid_argument (const char *_what) noexcept: @@ -132,6 +153,7 @@ namespace cruft::vk { }; + //------------------------------------------------------------------------- template class error_code : public error { public: