Personally my first choice would be a struct of vectors instead of vector of variants. No problems with alignment, minimal storage, and minimal complexity(unless there are additional constraints like keeping the "variants" ordered, but that can be solved with just an additional indirection)
To avoid alignment issues, I think that we can store different types inside different vectors. I am not sure which operation will be more complex in comparison to proposed approach, but maybe something to look into..
great talk! quick question though: how exactly does vv::vector::visit figure out the type of the thing it's looking at? You're storing the type metadata in an array on the heap, so you can't use those runtime values to index into a type list or call the std::in_place_index_t constructor of std::variant. How do you map the runtime index to an actual type?
For the type/offset storage, I think it could be combined together, since you're already using bitfields for your type indices, i.e. store the type information in the LSB of an unsigned integer and store the offset in the MSB.
I have another idea: Store an tuple of std::vectors in the vv type alongside a similar type/offset storage that index into the tuple of vectors. This will bloat the stack size of the actual vv type significantly but it solves all the problems w.r.t. alignment or insertions, since you can just manipulate the underlying normal std::vector of the corresponding type. The heap memory usage of this approach will be the same as that of your proposed implementation.
the operator [] could return const variant, thus making assigning a compiler error. however, this could lead to unintended copies where people spell out the actual type instead of auto.
Wonder if the idea was considered to have one vector for each type. The type array would then give which array to look at. And the index instead of bytes would store the index in that specific array. That would make the internal implementation quite a bit simpler, while adding a bit more stack space. Heap storage and performance characteristics should be similar.
Why not store each of the possible types in the variant in separate vectors of each type? So a vector
Personally my first choice would be a struct of vectors instead of vector of variants. No problems with alignment, minimal storage, and minimal complexity(unless there are additional constraints like keeping the "variants" ordered, but that can be solved with just an additional indirection)
To avoid alignment issues, I think that we can store different types inside different vectors. I am not sure which operation will be more complex in comparison to proposed approach, but maybe something to look into..
great talk!
quick question though: how exactly does vv::vector::visit figure out the type of the thing it's looking at? You're storing the type metadata in an array on the heap, so you can't use those runtime values to index into a type list or call the std::in_place_index_t constructor of std::variant. How do you map the runtime index to an actual type?
got a basic version working with some magic fold expressions ✌thanks again for the cool talk 😄
For the type/offset storage, I think it could be combined together, since you're already using bitfields for your type indices, i.e. store the type information in the LSB of an unsigned integer and store the offset in the MSB.
I have another idea: Store an tuple of std::vectors in the vv type alongside a similar type/offset storage that index into the tuple of vectors. This will bloat the stack size of the actual vv type significantly but it solves all the problems w.r.t. alignment or insertions, since you can just manipulate the underlying normal std::vector of the corresponding type. The heap memory usage of this approach will be the same as that of your proposed implementation.
the operator [] could return const variant, thus making assigning a compiler error. however, this could lead to unintended copies where people spell out the actual type instead of auto.
Wonder if the idea was considered to have one vector for each type. The type array would then give which array to look at. And the index instead of bytes would store the index in that specific array. That would make the internal implementation quite a bit simpler, while adding a bit more stack space. Heap storage and performance characteristics should be similar.
Great talk. Learned a lot. Though, so many “umm”s..
stop teaching me more C++ I'm already fully insane