forked from boostorg/unordered
		
	
		
			
				
	
	
		
			96 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			96 lines
		
	
	
		
			3.6 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:allocator_compliance Use of allocators]
 | 
						|
 | 
						|
C++11 introduced a new, mostly backwards compatible, allocator system.
 | 
						|
This uses a traits class, `allocator_traits` to handle the allocator
 | 
						|
adding extra functionality, and making some methods and types optional.
 | 
						|
At the time of writing there isn't a stable release of a standard library
 | 
						|
with `allocator_traits` (libc++ has `allocator_traits` but it hasn't been
 | 
						|
released yet) so a partial implementation is always used.
 | 
						|
 | 
						|
A full implementation of `allocator_traits` requires sophisticated
 | 
						|
member function detection which requires support for SFINAE expressions,
 | 
						|
or something close. This is available on GCC from version 4.4, Clang and
 | 
						|
Visual C++ 2008 (with a little hacking) or later.
 | 
						|
 | 
						|
On these compilers, the `construct`, `destroy` and `max_size` member functions
 | 
						|
are optional, as per C++11. On other compilers they are still required.
 | 
						|
 | 
						|
`propagate_on_container_copy_assignment`,
 | 
						|
`propagate_on_container_move_assignment` and
 | 
						|
`propagate_on_container_swap` are supported on most compilers
 | 
						|
(/TODO/: which ones don't support them?).
 | 
						|
`select_on_container_copy_construction` is also supported, but on
 | 
						|
compilers without full member function detection it must have exactly
 | 
						|
the right function signature, and can't be declared in a base class
 | 
						|
in order for it to be detected.
 | 
						|
 | 
						|
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 objects
 | 
						|
contained in the node are stored in aligned space within the node
 | 
						|
and constructed and destructed by calling the constructor and destructor
 | 
						|
directly. So `construct` and `destroy` are called for the node, but not for
 | 
						|
the object.
 | 
						|
 | 
						|
`pointer_traits` aren't used. Instead, pointer types are obtained from
 | 
						|
rebound allocators.
 | 
						|
 | 
						|
[endsect]
 | 
						|
 | 
						|
[section:move Move emulation]
 | 
						|
 | 
						|
Move emulation is implemented using Boost.Move. If rvalue references are
 | 
						|
available it will use them, but if not it uses a close, but imperfect emulation
 | 
						|
and to get the advantage of using movable container elements, you'll need to
 | 
						|
use Boost.Move.
 | 
						|
 | 
						|
* Non-copyable objects can be stored in the containers, but without support
 | 
						|
  for rvalue references the container will not be movable.
 | 
						|
* The number of arguments used in `emplace` is limited to /TODO/.
 | 
						|
* Argument forwarding is not perfect.
 | 
						|
 | 
						|
[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.
 | 
						|
For the same example:
 | 
						|
 | 
						|
    x.emplace("key", 1, 2);
 | 
						|
 | 
						|
This is emulated in Boost.Unordered, but will be deprecated soon.
 | 
						|
While it is a lot more compact, it lead to ambiguities so it was
 | 
						|
removed.
 | 
						|
 | 
						|
[endsect]
 | 
						|
 | 
						|
[section:swap Swapping]
 | 
						|
 | 
						|
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.
 | 
						|
 | 
						|
[endsect]
 | 
						|
 | 
						|
[endsect]
 |