1[/ Copyright 2011 Daniel James. 2 / Distributed under the Boost Software License, Version 1.0. (See accompanying 3 / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ] 4 5[section:compliance Standard Compliance] 6 7The intent of Boost.Unordered is to implement a close (but imperfect) 8implementation of the C++17 standard, that will work with C++98 upwards. 9The wide compatibility does mean some comprimises have to be made. 10With a compiler and library that fully support C++11, the differences should 11be minor. 12 13[section:move Move emulation] 14 15Support for move semantics is implemented using Boost.Move. If rvalue 16references are available it will use them, but if not it uses a close, 17but imperfect emulation. On such compilers: 18 19* Non-copyable objects can be stored in the containers. 20 They can be constructed in place using `emplace`, or if they support 21 Boost.Move, moved into place. 22* The containers themselves are not movable. 23* Argument forwarding is not perfect. 24 25[endsect] 26 27[section:allocator_compliance Use of allocators] 28 29C++11 introduced a new allocator system. It's backwards compatible due to 30the lax requirements for allocators in the old standard, but might need 31some changes for allocators which worked with the old versions of the 32unordered containers. 33It uses a traits class, `allocator_traits` to handle the allocator 34adding extra functionality, and making some methods and types optional. 35During development a stable release of 36`allocator_traits` wasn't available so an internal partial implementation 37is always used in this version. Hopefully a future version will use the 38standard implementation where available. 39 40The member functions `construct`, `destroy` and `max_size` are now 41optional, if they're not available a fallback is used. 42A full implementation of `allocator_traits` requires sophisticated 43member function detection so that the fallback is used whenever the 44member function call is not well formed. 45This requires support for SFINAE expressions, which are available on 46GCC from version 4.4 and Clang. 47 48On other compilers, there's just a test to see if the allocator has 49a member, but no check that it can be called. So rather than using a 50fallback there will just be a compile error. 51 52`propagate_on_container_copy_assignment`, 53`propagate_on_container_move_assignment`, 54`propagate_on_container_swap` and 55`select_on_container_copy_construction` are also supported. 56Due to imperfect move emulation, some assignments might check 57`propagate_on_container_copy_assignment` on some compilers and 58`propagate_on_container_move_assignment` on others. 59 60[endsect] 61 62[section:construction Construction/Destruction using allocators] 63 64The following support is required for full use of C++11 style 65construction/destruction: 66 67* Variadic templates. 68* Piecewise construction of `std::pair`. 69* Either `std::allocator_traits` or expression SFINAE. 70 71This is detected using Boost.Config. The macro 72`BOOST_UNORDERED_CXX11_CONSTRUCTION` will be set to 1 if it is found, or 0 73otherwise. 74 75When this is the case `allocator_traits::construct` and 76`allocator_traits::destroy` will always be used, apart from when piecewise 77constructing a `std::pair` using `boost::tuple` (see [link 78unordered.compliance.pairs below]), but that should be easily avoided. 79 80When support is not available `allocator_traits::construct` and 81`allocator_traits::destroy` are never called. 82 83[endsect] 84 85[section:pointer_traits Pointer Traits] 86 87`pointer_traits` aren't used. Instead, pointer types are obtained from 88rebound allocators, this can cause problems if the allocator can't be 89used with incomplete types. If `const_pointer` is not defined in the 90allocator, `boost::pointer_to_other<pointer, const value_type>::type` 91is used to obtain a const pointer. 92 93[endsect] 94 95[#unordered.compliance.pairs] 96[section:pairs Pairs] 97 98Since the containers use `std::pair` they're limited to the version 99from the current standard library. But since C++11 `std::pair`'s 100`piecewise_construct` based constructor is very useful, `emplace` 101emulates it with a `piecewise_construct` in the `boost::unordered` 102namespace. So for example, the following will work: 103 104 boost::unordered_multimap<std::string, std::complex> x; 105 106 x.emplace( 107 boost::unordered::piecewise_construct, 108 boost::make_tuple("key"), boost::make_tuple(1, 2)); 109 110Older drafts of the standard also supported variadic constructors 111for `std::pair`, where the first argument would be used for the 112first part of the pair, and the remaining for the second part. 113 114[endsect] 115 116[section:misc Miscellaneous] 117 118When swapping, `Pred` and `Hash` are not currently swapped by calling 119`swap`, their copy constructors are used. As a consequence when swapping 120an exception may be thrown from their copy constructor. 121 122Variadic constructor arguments for `emplace` are only used when both 123rvalue references and variadic template parameters are available. 124Otherwise `emplace` can only take up to 10 constructors arguments. 125 126[endsect] 127 128[endsect] 129