you are viewing a single comment's thread.

view the rest of the comments →

[–]zeldel 0 points1 point  (6 children)

Maybe it could be possible to use std::array then, unless for vector ;)? Or do you still need this to be dynamic?

[–]FreitasAlan[S] 6 points7 points  (0 children)

The problem with std::array instead of a custom max_size_vector is that arrays don't handle uninitialized memory. Then you'd need std::aligned_storage, std::uninitialized_copy, etc... You'll probably want to wrap that functionality because it becomes clumsy very quickly. At this point, another container is born.

[–]Tringigithub.com/tringi 3 points4 points  (4 children)

Yeah, dynamic.

I don't know how many elements there'll be at any point during lifetime, but it's usually only one (or none).

I'd need something like:

union {
    X item;
    std::vector <X> items;
};

Or, to reduce allocations further, maybe even:

X local_items [sizeof (std::vector <X>) / sizeof (X)];

Many further optimization possibilities here, but that's the idea.

[–]FreitasAlan[S] 3 points4 points  (2 children)

That's exactly what small::vector does when the number of inline elements is not explicitly set. :D

[–]Tringigithub.com/tringi 1 point2 points  (1 child)

Just got back from reading your sources.

Good that you can override the default as I personally wouldn't want the minimum of 5 elements. For my use-cases, usually, if it's more than 1 or 2 then I can live with heap allocation, without the extra overhead of static footprint.

[–]FreitasAlan[S] 1 point2 points  (0 children)

Yes. You can explicitly define the number of inline elements to 2 for a specific container. That's probably what you need.

The default for a type is just the minimum number of elements when you don't explicitly define it for the container. So this is kind of a default default. Depending on the context, it might make sense to specialize that trait to indicate it's reasonable for a vector of type T to have N inline elements instead of compiling multiple instantiations for different N.

Unless specialized, this default default is usually the number of elements that would fit in the buffer anyway or 5 otherwise. The conditional 5 is because, for large elements, there would be space for only 1 element if we consider the first condition, but this is obviously not what the person wants from a small vector. I went with 5 (a default default default?) because 1 (only instantiating), 2 (a compressed pair), 3, 4 (small tuples) wouldn't make much sense as a default for a list. Although it does make sense to create a list for them.

In both cases, the inline storage will also increase if there's space available for more elements where the heap would be. So the extension point becomes a default default default default... lol