Boost logo

Boost :

Subject: Re: [boost] [container] static_vector: fixed capacity vector update
From: Andrew Hundt (athundt_at_[hidden])
Date: 2013-01-20 15:59:26


On Fri, Jan 18, 2013 at 4:17 PM, Jeffrey Lee Hellrung, Jr.
<jeffrey.hellrung_at_[hidden]> wrote:
>
> This is encouraging!

Thanks!

> Great, seems almost simple enough. I say "almost" because, IMHO, we
> shouldn't try *too* hard to make static_vector a drop-in replacement for
> vector. Make the interface common where it makes sense, but reserve and
> shrink_to_fit shouldn't be part of the interface. It would just confuse me
> if I saw a reserve or shrink_to_fit method call on a static_vector in real
> code.

This may make sense to do. It could alternately be #ifdef'd out in some
BOOST_CONTAINER_VECTOR_COMPATIBILITY mode that enables shrink_to_fit()
for those that are clients of template code they cant change, but could
specify the container type. Perhaps that isn't worthwhile either and
users should just remove their shrink_to_fit calls if they want to use
static_vector.

> > Changes:
> > - C++11 support
>
> Please elaborate.

It supports all the C++11 member functions, such as move semantics and
emplace() that boost::container::vector supports. Allocators are the
obvious exception in addition to some runtime performance degradation
in cases such as swap() because a simple pointer swap is not possible.

In case you were concerned, everything is also set up for C++03.

> The documentation is not the prettiest right now, which is fine

I agree that the documentation wording, formatting, and examples still
need improvement.

> one key omission is a Strategy concept specification (at least, I didn't
see
> one).

The Strategy concept is defined in the code using Boost.concept_check.
Adding it to the documentation depends on how the discussion
immediately below and in Q4 of my Q&A goes since it wouldn't make
sense to document the strategy if it is not part of the public API.

> Also, I'm not 100% sold on the Strategy template parameter. I think
there's
> something to be said for simplicity, and the simplest implementation would
> have just 2 template parameters and assert on any bounds violations; if
you
> want to throw, use, say, a free function push_back_and_throw_on_error. At
> least, that's what I'd say is an alternative design.

I concur, while I'm fairly happy with the current code I too am not
100% sold on the Strategy. I wrote more detail in Q4 of the Q&A
section of my original post. The proposed alternative is putting the
current version into the detail namespace and defining one or more
publicly available interfaces using partial specializations in which
the strategy is fully defined.

> > - bounds checks are asserts by default but can be switched to
exceptions
>
> Is this true for static_vector::at as well, or does that throw regardless
> as with std::vector?

static_vector::at() throws in the same manner as
boost::container::vector::at() by default. It is also possible to
disable exceptions so in that case there is an assert() when indexed
out of bounds. Perhaps the case where exceptions are disabled should
use BOOST_VERIFY so it triggers in release mode too for at()?

> > - memory is uninitialized until objects are inserted
>
> Hmmm...this is a change?! I would think this is a correctness requirement
:/

The original version was boost::array with size so the behavior was
much more understandable. I agree that the new behavior is much better
and that's why it has been changed. :-)

> > - internal size is currently the same as Strategy::size_type
> > - expanded documentation and unit tests
> > - optimizations based on type traits
>
> Please elaborate.

This is related to Q5 of the Q&A in my original post. People on the
list expressed the desire to make the value tracking the vector size
configurable, so if the capacity was 20 you could use uint8_t, or if
it was 20000 you could use uint16_t instead of the default, which is
std::size_t. This configuration can be accomplished by modifying the
strategy.

The type traits optimizations are the same ones provided by
boost::container::vector, such as using memcpy/memmove for POD types
where appropriate, and selecting algorithms based on traits indicating
if an iterator is a RandomAccessIterator, ForwardIterator, etc.

> > - boost::interprocess support
>
> Please elaborate.

Since the pointer type is configurable you can initialize
static_vector in shared memory with the specialized pointers
interprocess provides. There is also some example code that uses a
static_vector with boost::interprocess here: http://goo.gl/oUyj7

Cheers!

Cheers!
Andrew Hundt


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk