diff --git a/doc/changes.qbk b/doc/changes.qbk index 9254011d..9c4d040e 100644 --- a/doc/changes.qbk +++ b/doc/changes.qbk @@ -134,16 +134,23 @@ First official release. * Fix a bug when inserting into an `unordered_map` or `unordered_set` using iterators which returns `value_type` by copy. -[h2 Boost 1.48.0] +[h2 Boost 1.48.0 - Major update] This is major change which has been converted to use Boost.Move's move -emulation, and be more compliant with the C++11 standard. This has resulted -in some breaking changes: +emulation, and be more compliant with the C++11 standard. See the +[link unordered.compliance compliance section] for details. + +The container now meets C++11's complexity requirements, but to do so +uses a little more memory. This means that `quick_erase` and +`erase_return_void` are no longer required, they'll be removed in a +future version. + +C++11 support has resulted in some breaking changes: * Equality comparison has been changed to the C++11 specification. In a container with equivalent keys, elements in a group with equal keys used to have to be in the same order to be considered equal, - now they can be a permutation of each other. To keep the old + now they can be a permutation of each other. To use the old behavior define the macro `BOOST_UNORDERED_DEPRECATED_EQUALITY`. * The behaviour of swap is different when the two containers to be diff --git a/doc/compliance.qbk b/doc/compliance.qbk index 322483fd..622b053f 100644 --- a/doc/compliance.qbk +++ b/doc/compliance.qbk @@ -4,59 +4,80 @@ [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. +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 you'll need to use Boost.Move +to take advantage of using movable container elements, also note that: * 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: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. They aren't supported by +Visual C++ 2008/2010, but with a bit of hacking it's possible to support +certain use cases. + +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 + 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::type` +is used to obtain a const pointer. + +[endsect] + [section:pairs Pairs] Since the containers use `std::pair` they're limited to the version @@ -74,22 +95,19 @@ namespace. So for example, the following will work: 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] +[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] diff --git a/doc/ref.php b/doc/ref.php index 1070c6cf..cc871be5 100644 --- a/doc/ref.php +++ b/doc/ref.php @@ -116,16 +116,28 @@ EOL; typename allocator_type::pointer + + + value_type* if + allocator_type::pointer is not defined. + + typename allocator_type::const_pointer + + + boost::pointer_to_other<pointer, value_type>::type + if allocator_type::const_pointer is not defined. + + - typename allocator_type::reference + value_type& lvalue of value_type. - typename allocator_type::const_reference + value_type const& const lvalue of value_type. @@ -320,7 +332,8 @@ EOL; On compilers without rvalue references, this is emulated using - Boost.Move. + Boost.Move. Note that on some compilers the copy assignment + operator may be used in some circumstances. diff --git a/doc/ref.xml b/doc/ref.xml index 5afa1f4f..aecfd0af 100644 --- a/doc/ref.xml +++ b/doc/ref.xml @@ -61,16 +61,28 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) typename allocator_type::pointer + + + value_type* if + allocator_type::pointer is not defined. + + typename allocator_type::const_pointer + + + boost::pointer_to_other<pointer, value_type>::type + if allocator_type::const_pointer is not defined. + + - typename allocator_type::reference + value_type& lvalue of value_type. - typename allocator_type::const_reference + value_type const& const lvalue of value_type. @@ -265,7 +277,8 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) On compilers without rvalue references, this is emulated using - Boost.Move. + Boost.Move. Note that on some compilers the copy assignment + operator may be used in some circumstances. @@ -1001,16 +1014,28 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) typename allocator_type::pointer + + + value_type* if + allocator_type::pointer is not defined. + + typename allocator_type::const_pointer + + + boost::pointer_to_other<pointer, value_type>::type + if allocator_type::const_pointer is not defined. + + - typename allocator_type::reference + value_type& lvalue of value_type. - typename allocator_type::const_reference + value_type const& const lvalue of value_type. @@ -1205,7 +1230,8 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) On compilers without rvalue references, this is emulated using - Boost.Move. + Boost.Move. Note that on some compilers the copy assignment + operator may be used in some circumstances. @@ -1951,16 +1977,28 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) typename allocator_type::pointer + + + value_type* if + allocator_type::pointer is not defined. + + typename allocator_type::const_pointer + + + boost::pointer_to_other<pointer, value_type>::type + if allocator_type::const_pointer is not defined. + + - typename allocator_type::reference + value_type& lvalue of value_type. - typename allocator_type::const_reference + value_type const& const lvalue of value_type. @@ -2155,7 +2193,8 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) On compilers without rvalue references, this is emulated using - Boost.Move. + Boost.Move. Note that on some compilers the copy assignment + operator may be used in some circumstances. @@ -2936,16 +2975,28 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) typename allocator_type::pointer + + + value_type* if + allocator_type::pointer is not defined. + + typename allocator_type::const_pointer + + + boost::pointer_to_other<pointer, value_type>::type + if allocator_type::const_pointer is not defined. + + - typename allocator_type::reference + value_type& lvalue of value_type. - typename allocator_type::const_reference + value_type const& const lvalue of value_type. @@ -3140,7 +3191,8 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) On compilers without rvalue references, this is emulated using - Boost.Move. + Boost.Move. Note that on some compilers the copy assignment + operator may be used in some circumstances.