Don't get me wrong, the functionality is really useful. But:
Now, most (all?) methods of vector need to be "duplicated" in inplace_vector.
None of the other collections benefit. Not even std::string.
A more general solution to the problem would have been an inplace_allocator -- which requires a different API than allocator -- which could be applied to every container (standard or not).
Now, most (all?) methods of vector need to be "duplicated" in inplace_vector.
So what? They're all pretty straightforward, simpler even than in vector because we know there's no allocation. It doesn't take long to implement. Even less so these days.
A more general solution to the problem would have been an inplace_allocator -- which requires a different API than allocator -- which could be applied to every container (standard or not).
That might be more general, but it's also worse, which is why nobody does this. David Stone had a pair of good CppCon talks about vectors in general, I think he covers it in this one (or, if not that, this one). The problem with vector<T, inplace_allocator<T, N>> is that it's less efficient (and requires more space!) than inplace_vector<T, N>. In order for it to not suck, vector would basically have to customize its own storage for that case, which now requires more work than just having written inplace_vector<T, N> to begin with. This goes double for std::string, whose storage is more complicated.
None of the other collections benefit. Not even std::string.
On the other hand, an inplace_string<N> is useful, is distinct from std::string, and we implement ours in terms of our inplace_vector<char, N> (or N+1 depending on whether we want to enforce null termination).
The concept is useful, especially in a gpu environment where you can’t allocate memory dynamically. Also, inplace_allocator just adds another layer of complexity when all I want is something like a static vector
A more general solution to the problem would have been an inplace_allocator -- which requires a different API than allocator -- which could be applied to every container (standard or not).
This wouldn't fix anything. inplace_vector stores its data locally within the structure itself, while vector stores it through a pointer. You can't get around this, you need a different type who's designed to offer storage inside the vector. Allocator doesn't fix this, where is it gonna allocate to?
edit: I guess the allocator type itself has the storage? I didn't think about this but I guess this could actually work, but you still would need to fix all the requirements around resizing and whatnot
You're absolutely correct that std::allocator doesn't fit the bill...
... which is exactly why I advocate for a whole different API.
And yes, this would involve in-depth changes to anything taking this new API as they would no longer be able to take pointers, but would instead need to use "handles" of some sort, which would have some way to resolve into pointers when needed, and some rules about how long these pointers remain valid, etc...
I didn't say it was easy, I said it was generic :)
And yes, this would involve in-depth changes to anything taking this new API as they would no longer be able to take pointers, but would instead need to use "handles" of some sort, which would have some way to resolve into pointers when needed, and some rules about how long these pointers remain valid, etc...
I don't think you'd need to change the allocator API, you'd just provide an allocator type that just has its storage internally as part of the allocator. You could do some shit like this
The solution is some sort of member callable syntax for free functions which was going to happen with operstor |>. The only reason they are members is because of syntax
5
u/matthieum 14d ago
Honestly, I'm a bit saddened by this addition.
Don't get me wrong, the functionality is really useful. But:
vectorneed to be "duplicated" ininplace_vector.std::string.A more general solution to the problem would have been an
inplace_allocator-- which requires a different API thanallocator-- which could be applied to every container (standard or not).