| 
									
										
										
										
											2011-08-16 22:18:09 +00:00
										 |  |  | [/ 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) ] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-18 10:14:26 +01:00
										 |  |  | [section:compliance Standard Compliance] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-07 22:56:54 +01:00
										 |  |  | The intent of Boost.Unordered is to implement a close (but imperfect) | 
					
						
							| 
									
										
										
										
											2017-04-18 10:14:26 +01:00
										 |  |  | implementation of the C++17 standard, that will work with C++98 upwards. | 
					
						
							|  |  |  | The wide compatibility does mean some comprimises have to be made. | 
					
						
							|  |  |  | With a compiler and library that fully support C++11, the differences should | 
					
						
							|  |  |  | be minor. | 
					
						
							| 
									
										
										
										
											2011-08-16 22:18:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-16 10:31:25 +00:00
										 |  |  | [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, | 
					
						
							| 
									
										
										
										
											2013-07-08 22:11:54 +00:00
										 |  |  | but imperfect emulation. On such compilers: | 
					
						
							| 
									
										
										
										
											2011-10-16 10:31:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-08 22:11:54 +00:00
										 |  |  | * 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. | 
					
						
							| 
									
										
										
										
											2011-10-16 10:31:25 +00:00
										 |  |  | * Argument forwarding is not perfect. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [endsect] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-16 22:18:09 +00:00
										 |  |  | [section:allocator_compliance Use of allocators] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-16 10:31:25 +00:00
										 |  |  | 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 | 
					
						
							| 
									
										
										
										
											2011-08-29 15:20:27 +00:00
										 |  |  | adding extra functionality, and making some methods and types optional. | 
					
						
							| 
									
										
										
										
											2011-10-16 10:31:25 +00:00
										 |  |  | 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. | 
					
						
							| 
									
										
										
										
											2011-08-29 15:20:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-16 10:31:25 +00:00
										 |  |  | The member functions `construct`, `destroy` and `max_size` are now | 
					
						
							|  |  |  | optional, if they're not available a fallback is used. | 
					
						
							| 
									
										
										
										
											2011-08-29 15:20:27 +00:00
										 |  |  | A full implementation of `allocator_traits` requires sophisticated | 
					
						
							| 
									
										
										
										
											2011-10-16 10:31:25 +00:00
										 |  |  | 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 | 
					
						
							| 
									
										
										
										
											2011-10-29 16:31:40 +00:00
										 |  |  | GCC from version 4.4 and Clang. | 
					
						
							| 
									
										
										
										
											2011-08-29 15:20:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-16 10:31:25 +00:00
										 |  |  | 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. | 
					
						
							| 
									
										
										
										
											2011-08-29 15:20:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | `propagate_on_container_copy_assignment`, | 
					
						
							| 
									
										
										
										
											2011-10-16 10:31:25 +00:00
										 |  |  | `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. | 
					
						
							| 
									
										
										
										
											2011-08-29 15:20:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-18 10:14:26 +01:00
										 |  |  | [endsect] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [section:construction Construction/Destruction using allocators] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The following support is required for full use of C++11 style | 
					
						
							|  |  |  | construction/destruction: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-25 21:14:11 +01:00
										 |  |  | * Variadic templates. | 
					
						
							|  |  |  | * Piecewise construction of `std::pair`. | 
					
						
							|  |  |  | * Either `std::allocator_traits` or expression SFINAE. | 
					
						
							| 
									
										
										
										
											2011-08-16 22:18:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-18 10:14:26 +01:00
										 |  |  | This is detected using Boost.Config. The macro | 
					
						
							|  |  |  | `BOOST_UNORDERED_CXX11_CONSTRUCTION` will be set to 1 if it is found, or 0 | 
					
						
							|  |  |  | otherwise. | 
					
						
							| 
									
										
										
										
											2011-08-16 22:18:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-18 10:14:26 +01:00
										 |  |  | When this is the case `allocator_traits::construct` and | 
					
						
							|  |  |  | `allocator_traits::destroy` will always be used, apart from when piecewise | 
					
						
							|  |  |  | constructing a `std::pair` using `boost::tuple` (see [link | 
					
						
							|  |  |  | unordered.compliance.pairs below]), but that should be easily avoided. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | When support is not available `allocator_traits::construct` and | 
					
						
							|  |  |  | `allocator_traits::destroy` are never called. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [endsect] | 
					
						
							| 
									
										
										
										
											2011-08-16 22:18:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-18 10:14:26 +01:00
										 |  |  | [section:pointer_traits Pointer Traits] | 
					
						
							| 
									
										
										
										
											2011-08-16 22:18:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-16 10:31:25 +00:00
										 |  |  | `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. | 
					
						
							| 
									
										
										
										
											2011-08-16 22:18:09 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | [endsect] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-18 10:14:26 +01:00
										 |  |  | [#unordered.compliance.pairs] | 
					
						
							| 
									
										
										
										
											2011-08-29 15:20:27 +00:00
										 |  |  | [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] | 
					
						
							| 
									
										
										
										
											2011-08-16 22:18:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-16 10:31:25 +00:00
										 |  |  | [section:misc Miscellaneous] | 
					
						
							| 
									
										
										
										
											2011-08-16 22:18:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-29 15:20:27 +00:00
										 |  |  | When swapping, `Pred` and `Hash` are not currently swapped by calling | 
					
						
							|  |  |  | `swap`, their copy constructors are used. As a consequence when swapping | 
					
						
							| 
									
										
										
										
											2017-09-07 22:56:54 +01:00
										 |  |  | an exception may be thrown from their copy constructor. | 
					
						
							| 
									
										
										
										
											2011-08-16 22:18:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-16 10:31:25 +00:00
										 |  |  | 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. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-16 22:18:09 +00:00
										 |  |  | [endsect] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 19:29:22 +00:00
										 |  |  | [endsect] |