mirror of https://gitee.com/bigwinds/arangodb
113 lines
4.5 KiB
Plaintext
113 lines
4.5 KiB
Plaintext
[/ Copyright 2011 Daniel James.
|
|
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ]
|
|
|
|
[section:compliance C++11 Compliance]
|
|
|
|
[section:move Move emulation]
|
|
|
|
Support for move semantics is implemented using Boost.Move. If rvalue
|
|
references are available it will use them, but if not it uses a close,
|
|
but imperfect emulation. On such compilers:
|
|
|
|
* Non-copyable objects can be stored in the containers.
|
|
They can be constructed in place using `emplace`, or if they support
|
|
Boost.Move, moved into place.
|
|
* The containers themselves are not movable.
|
|
* Argument forwarding is not perfect.
|
|
|
|
[endsect]
|
|
|
|
[section:allocator_compliance Use of allocators]
|
|
|
|
C++11 introduced a new allocator system. It's backwards compatible due to
|
|
the lax requirements for allocators in the old standard, but might need
|
|
some changes for allocators which worked with the old versions of the
|
|
unordered containers.
|
|
It uses a traits class, `allocator_traits` to handle the allocator
|
|
adding extra functionality, and making some methods and types optional.
|
|
During development a stable release of
|
|
`allocator_traits` wasn't available so an internal partial implementation
|
|
is always used in this version. Hopefully a future version will use the
|
|
standard implementation where available.
|
|
|
|
The member functions `construct`, `destroy` and `max_size` are now
|
|
optional, if they're not available a fallback is used.
|
|
A full implementation of `allocator_traits` requires sophisticated
|
|
member function detection so that the fallback is used whenever the
|
|
member function call is not well formed.
|
|
This requires support for SFINAE expressions, which are available on
|
|
GCC from version 4.4 and Clang.
|
|
|
|
On other compilers, there's just a test to see if the allocator has
|
|
a member, but no check that it can be called. So rather than using a
|
|
fallback there will just be a compile error.
|
|
|
|
`propagate_on_container_copy_assignment`,
|
|
`propagate_on_container_move_assignment`,
|
|
`propagate_on_container_swap` and
|
|
`select_on_container_copy_construction` are also supported.
|
|
Due to imperfect move emulation, some assignments might check
|
|
`propagate_on_container_copy_assignment` on some compilers and
|
|
`propagate_on_container_move_assignment` on others.
|
|
|
|
The use of the allocator's construct and destruct methods might be a bit
|
|
surprising.
|
|
Nodes are constructed and destructed using the allocator, but the elements
|
|
are stored in aligned space within the node and constructed and destructed
|
|
by calling the constructor and destructor directly.
|
|
|
|
In C++11 the allocator's construct function has the signature:
|
|
|
|
template <class U, class... Args>
|
|
void construct(U* p, Args&&... args);
|
|
|
|
which supports calling `construct` for the contained object, but
|
|
most existing allocators don't support this. If member function detection
|
|
was good enough then with old allocators it would fall back to calling
|
|
the element's constructor directly but in general, detection isn't good
|
|
enough to do this which is why Boost.Unordered just calls the constructor
|
|
directly every time. In most cases this will work okay.
|
|
|
|
`pointer_traits` aren't used. Instead, pointer types are obtained from
|
|
rebound allocators, this can cause problems if the allocator can't be
|
|
used with incomplete types. If `const_pointer` is not defined in the
|
|
allocator, `boost::pointer_to_other<pointer, const value_type>::type`
|
|
is used to obtain a const pointer.
|
|
|
|
[endsect]
|
|
|
|
[section:pairs Pairs]
|
|
|
|
Since the containers use `std::pair` they're limited to the version
|
|
from the current standard library. But since C++11 `std::pair`'s
|
|
`piecewise_construct` based constructor is very useful, `emplace`
|
|
emulates it with a `piecewise_construct` in the `boost::unordered`
|
|
namespace. So for example, the following will work:
|
|
|
|
boost::unordered_multimap<std::string, std::complex> x;
|
|
|
|
x.emplace(
|
|
boost::unordered::piecewise_construct,
|
|
boost::make_tuple("key"), boost::make_tuple(1, 2));
|
|
|
|
Older drafts of the standard also supported variadic constructors
|
|
for `std::pair`, where the first argument would be used for the
|
|
first part of the pair, and the remaining for the second part.
|
|
|
|
[endsect]
|
|
|
|
[section:misc Miscellaneous]
|
|
|
|
When swapping, `Pred` and `Hash` are not currently swapped by calling
|
|
`swap`, their copy constructors are used. As a consequence when swapping
|
|
an exception may be throw from their copy constructor.
|
|
|
|
Variadic constructor arguments for `emplace` are only used when both
|
|
rvalue references and variadic template parameters are available.
|
|
Otherwise `emplace` can only take up to 10 constructors arguments.
|
|
|
|
[endsect]
|
|
|
|
[endsect]
|