Boost.Container aims for full C++11 conformance except reasoned deviations, backporting as much as possible for C++03. Obviously, this conformance is a work in progress so this section explains what C++11 features are implemented and which of them have been backported to C++03 compilers.
For compilers with rvalue references and for those C++03 types that use
Boost.Move rvalue reference
emulation Boost.Container supports all C++11
features related to move semantics: containers are movable, requirements
value_type are those
specified for C++11 containers.
For compilers with variadic templates, Boost.Container
supports placement insertion (
...) functions from C++11. For those compilers without variadic templates
support Boost.Container uses the preprocessor
to create a set of overloads up to a finite (10) number of parameters.
C++03 was not stateful-allocator friendly. For compactness of container objects and for simplicity, it did not require containers to support allocators with state: Allocator objects need not be stored in container objects. It was not possible to store an allocator with state, say an allocator that holds a pointer to an arena from which to allocate. C++03 allowed implementors to suppose two allocators of the same type always compare equal (that means that memory allocated by one allocator object could be deallocated by another instance of the same type) and allocators were not swapped when the container was swapped.
C++11 further improves stateful allocator support through
std::allocator_traits is the protocol between
a container and an allocator, and an allocator writer can customize its behaviour
(should the container propagate it in move constructor, swap, etc.?) following
Boost.Container not only supports this model
with C++11 but also backports it to C++03
This class offers some workarounds for C++03 compilers to achieve the same
allocator guarantees as
In [Boost.Container] containers, if possible, a single allocator is hold
If the container needs an auxiliary allocator (e.g. an array allocator used
stable_vector), that allocator is also
stored in the container and initialized from the user-supplied allocator
when the container is constructed (i.e. it's not constructed on the fly when
auxiliary memory is needed).
C++11 improves stateful allocators with the introduction of
is instantiated with one outer allocator and zero or more inner allocators.
A scoped allocator is a mechanism to automatically propagate the state of
the allocator to the subobjects of a container in a controlled way. If instantiated
with only one allocator type, the inner allocator becomes the
scoped_allocator_adaptor itself, thus using
the same allocator resource for the container and every element within the
container and, if the elements themselves are containers, each of their elements
recursively. If instantiated with more than one allocator, the first allocator
is the outer allocator for use by the container, the second allocator is
passed to the constructors of the container's elements, and, if the elements
themselves are containers, the third allocator is passed to the elements'
elements, and so on.
Boost.Container implements its own
scoped_allocator_adaptor class and backports this feature also to C++03 compilers. Due
to C++03 limitations, in those compilers the allocator propagation implemented
functions will be based on traits (
proposed in N2554:
The Scoped Allocator Model (Rev 2) proposal. In conforming C++11
compilers or compilers supporting SFINAE expressions (when
BOOST_NO_SFINAE_EXPR is NOT defined), traits
are ignored and C++11 rules (
Args...>::value) will be used to detect if the allocator
must be propagated with suffix or prefix allocator arguments.
Boost.Container does not support initializer lists when constructing or assigning containers but it will support it for compilers with initialized-list support. This feature won't be backported to C++03 compilers.
Boost.Container does not offer C++11
forward_list container yet, but it will
be available in future versions.
vector does not support
the strong exception guarantees given by
in functions like
shrink_to_fit for either
copyable or no-throw moveable classes. In C++11 move_if_noexcept
is used to maintain C++03 exception safety guarantees combined with C++11
move semantics. This strong exception guarantee degrades the insertion performance
of copyable and throwing-moveable types, degrading moves to copies when such
types are inserted in the vector using the aforementioned members.
This strong exception guarantee also precludes the possibility of using some
type of in-place reallocations that can further improve the insertion performance
vector See Extended
Allocators to know more about these optimizations.
vector always uses
move constructors/assignments to rearrange elements in the vector and uses
memory expansion mechanisms if the allocator supports them, while offering
only basic safety guarantees. It trades off exception guarantees for an improved
has been quite problematic, and there have been several unsuccessful tries
to deprecate or remove it from the standard. Boost.Container
does not implement it as there is a superior Boost.DynamicBitset
solution. For issues with
see the following papers:
vector<bool>is not a container and
vector<bool>::iteratoris not a random-access iterator (or even a forward or bidirectional iterator either, for that matter). This has already broken user code in the field in mysterious ways.”
vector<bool>forces a specific (and potentially bad) optimization choice on all users by enshrining it in the standard. The optimization is premature; different users have different requirements. This too has already hurt users who have been forced to implement workarounds to disable the 'optimization' (e.g., by using a vector<char> and manually casting to/from bool).”
boost::container::vector<bool>::iterator returns real
references and works as a fully compliant container. If you need a memory
optimized version of
please use Boost.DynamicBitset.
with a zero value to initialize some types as in most platforms this initialization
yields to the desired value initialization with improved performance.
Following the C11 standard, Boost.Container
assumes that for any integer type, the object representation where
all the bits are zero shall be a representation of the value zero in that
char32_t are also integer types in C, it considers
all C++ integral types as initializable via
By default, Boost.Container also considers
floating point types to be initializable using
Most platforms are compatible with this initialization, but in case this
initialization is not desirable the user can
before including library headers.
By default, it also considers pointer types (pointer and pointer to function
types, excluding member object and member function pointers) to be initializable
std::memset. Most platforms are compatible with
this initialization, but in case this initialization is not desired the user
before including library headers.
is defined Boost.Container also considers
POD types to be value initializable via
with value zero.