At many places within Auto-Vk and Gears-Vk, small std::vector
s are passed around --- meaning that only few elements are contained. A small vector type would probably be very beneficial to be used instead of std::vector
especially when passing something to arguments or returning results from functions/methods.
But not only for argument/result passing could such a type be useful, but also for holding data like, e.g., the swapchain images, etc. Especially for all the frames in flight, at many places there will be exactly #frames-in-flight (e.g., three) resources to be held. Would be a waste to have a memory redirection for each of these given that there will be only very few elements in each case.
There are a few implementations, but I think that they generally have too many dependencies:
Note: Looks like llvm::SmallVector
does not satisfy the noexcept
requirement (see below). And looks like folly:small_vector
requires Boost, which is hell of a dependency. ^^
Possible route to go:
It might even be the best idea to implement it by ourselves following a similar strategy as described here: https://easyperf.net/blog/2016/11/25/Small_size_optimization (with corresponding GitHub repository here: https://github.com/dendibakh/prep/blob/master/SmallVector.cpp), meaning that we have both, a std::array
and a std::vector
as members and if the std::array
gets too small, std::move
s are performed from the std::array
into the std::vector
.
I think, the best option would be to have a std::variant<std::array<T, N>, std::vector<T>>
and when that "fateful" move from array
->vector
has to happen, it would probably be best to: 1st move the std::array
into a std::vector<T> tmp
, and 2nd move that "back" into the std::variant
.
We define this type to serve a specific purpose, namely: To serve the purpose of passing parameters or results. That means, it shall offer convenient addition of elements (push_back
) and once constructed, convenient usage of those elements, either by turning it into a std::span
or by getting begin/end iterators. But the type does not have to pay attention to stuff like graceful handling of iterator invalidation, etc. and does not even have to support removal of elements. It shall just be a useful (rather temporarily used) container for passing around information and compared to a std::vector, it shall have the advantage that it does not perform a heap allocation for small numbers of elements.
Some required properties of the small vector type:
Definition of done: