]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 C++11 Compliance] | |
6 | ||
7 | [section:move Move emulation] | |
8 | ||
9 | Support for move semantics is implemented using Boost.Move. If rvalue | |
10 | references are available it will use them, but if not it uses a close, | |
11 | but imperfect emulation. On such compilers: | |
12 | ||
13 | * Non-copyable objects can be stored in the containers. | |
14 | They can be constructed in place using `emplace`, or if they support | |
15 | Boost.Move, moved into place. | |
16 | * The containers themselves are not movable. | |
17 | * Argument forwarding is not perfect. | |
18 | ||
19 | [endsect] | |
20 | ||
21 | [section:allocator_compliance Use of allocators] | |
22 | ||
23 | C++11 introduced a new allocator system. It's backwards compatible due to | |
24 | the lax requirements for allocators in the old standard, but might need | |
25 | some changes for allocators which worked with the old versions of the | |
26 | unordered containers. | |
27 | It uses a traits class, `allocator_traits` to handle the allocator | |
28 | adding extra functionality, and making some methods and types optional. | |
29 | During development a stable release of | |
30 | `allocator_traits` wasn't available so an internal partial implementation | |
31 | is always used in this version. Hopefully a future version will use the | |
32 | standard implementation where available. | |
33 | ||
34 | The member functions `construct`, `destroy` and `max_size` are now | |
35 | optional, if they're not available a fallback is used. | |
36 | A full implementation of `allocator_traits` requires sophisticated | |
37 | member function detection so that the fallback is used whenever the | |
38 | member function call is not well formed. | |
39 | This requires support for SFINAE expressions, which are available on | |
40 | GCC from version 4.4 and Clang. | |
41 | ||
42 | On other compilers, there's just a test to see if the allocator has | |
43 | a member, but no check that it can be called. So rather than using a | |
44 | fallback there will just be a compile error. | |
45 | ||
46 | `propagate_on_container_copy_assignment`, | |
47 | `propagate_on_container_move_assignment`, | |
48 | `propagate_on_container_swap` and | |
49 | `select_on_container_copy_construction` are also supported. | |
50 | Due to imperfect move emulation, some assignments might check | |
51 | `propagate_on_container_copy_assignment` on some compilers and | |
52 | `propagate_on_container_move_assignment` on others. | |
53 | ||
54 | The use of the allocator's construct and destruct methods might be a bit | |
55 | surprising. | |
56 | Nodes are constructed and destructed using the allocator, but the elements | |
57 | are stored in aligned space within the node and constructed and destructed | |
58 | by calling the constructor and destructor directly. | |
59 | ||
60 | In C++11 the allocator's construct function has the signature: | |
61 | ||
62 | template <class U, class... Args> | |
63 | void construct(U* p, Args&&... args); | |
64 | ||
65 | which supports calling `construct` for the contained object, but | |
66 | most existing allocators don't support this. If member function detection | |
67 | was good enough then with old allocators it would fall back to calling | |
68 | the element's constructor directly but in general, detection isn't good | |
69 | enough to do this which is why Boost.Unordered just calls the constructor | |
70 | directly every time. In most cases this will work okay. | |
71 | ||
72 | `pointer_traits` aren't used. Instead, pointer types are obtained from | |
73 | rebound allocators, this can cause problems if the allocator can't be | |
74 | used with incomplete types. If `const_pointer` is not defined in the | |
75 | allocator, `boost::pointer_to_other<pointer, const value_type>::type` | |
76 | is used to obtain a const pointer. | |
77 | ||
78 | [endsect] | |
79 | ||
80 | [section:pairs Pairs] | |
81 | ||
82 | Since the containers use `std::pair` they're limited to the version | |
83 | from the current standard library. But since C++11 `std::pair`'s | |
84 | `piecewise_construct` based constructor is very useful, `emplace` | |
85 | emulates it with a `piecewise_construct` in the `boost::unordered` | |
86 | namespace. So for example, the following will work: | |
87 | ||
88 | boost::unordered_multimap<std::string, std::complex> x; | |
89 | ||
90 | x.emplace( | |
91 | boost::unordered::piecewise_construct, | |
92 | boost::make_tuple("key"), boost::make_tuple(1, 2)); | |
93 | ||
94 | Older drafts of the standard also supported variadic constructors | |
95 | for `std::pair`, where the first argument would be used for the | |
96 | first part of the pair, and the remaining for the second part. | |
97 | ||
98 | [endsect] | |
99 | ||
100 | [section:misc Miscellaneous] | |
101 | ||
102 | When swapping, `Pred` and `Hash` are not currently swapped by calling | |
103 | `swap`, their copy constructors are used. As a consequence when swapping | |
104 | an exception may be throw from their copy constructor. | |
105 | ||
106 | Variadic constructor arguments for `emplace` are only used when both | |
107 | rvalue references and variadic template parameters are available. | |
108 | Otherwise `emplace` can only take up to 10 constructors arguments. | |
109 | ||
110 | [endsect] | |
111 | ||
112 | [endsect] |