Unordered: Merge from trunk

- Remove use of BOOST_DEDUCED_TYPENAME and BOOST_UNORDERED_PAIR_CAST, it's
  unlikely that the compilers which require them will be able to cope with the
  new version of unordered.
- Use the old equality algorithm if BOOST_UNORDERED_DEPRECATED_EQUALITY is
  defined.
- Use SFINAE to control which overloads of `construct_impl` are available.
  Fixes problems with differing overload resolution on different compilers.
- Support for piecewise pair construction.
- Only support the old variadic pair construction when
  BOOST_UNORDERED_DEPRECATED_PAIR_CONSTRUCT is defined (also fixed some bugs).
- Avoid instantiating BOOST_RV_REF for non-classes.
- Support optional allocator member functions for compilers with SFINAE
  expressions and Visual C++ 9.0/10.0
- Follow boost macro naming conventions.
- Improved portability for `allocator_traits` emulation.

Current compiler support:

- Full support for GCC 4.4+, Visual C++ 9.0+, Clang.
- All other compilers odn't support optional allocator members.
- No other errors for GCC 3.4.6+, Visual C++ 8.0, Intel, Pathscale.
- Visual Age has a compile error if `select_on_container_copy_construction`
  isn't `const` (it should ignore it).
- `select_on_container_copy_construction` detection doesn't work on Sun.
- `unnecessary_copy_tests` is failling for vacpp on AIX, but not on linux.
- Warnings causing failures for Visual C++ with STLport and WM5.


[SVN r74234]
This commit is contained in:
Daniel James committed 2011-09-04 19:37:45 +00:00
1 parent f6f19aaaaa
commit 5867994b8c
27 files changed
+1465 -719

No files matched your search

+1 -1
View File
@@ -112,7 +112,7 @@ load factor is /required/ to be less than the maximum is following a call to
below the max load factor, and set the maximum load factor to be the same as
or close to the hint - unless your hint is unreasonably small or large.
[table Methods for Controlling Bucket Size
[table:bucket_size Methods for Controlling Bucket Size
[[Method] [Description]]
[
+3
View File
@@ -151,4 +151,7 @@ in some breaking changes:
the allocator has a member structure `propagate_on_container_swap`,
such that `propagate_on_container_swap::value` is true.
* Allocator's `construct` and `destroy` functions are called with raw
pointers, rather than the allocator's `pointer` type.
[endsect]
+2 -2
View File
@@ -4,7 +4,7 @@
[section:comparison Comparison with Associative Containers]
[table Interface differences.
[table:interface_differences Interface differences.
[[Associative Containers] [Unordered Associative Containers]]
[
@@ -88,7 +88,7 @@
]
]
[table Complexity Guarantees
[table:complexity_guarantees Complexity Guarantees
[[Operation] [Associative Containers] [Unordered Associative Containers]]
[
[Construction of empty container]
+65 -24
View File
@@ -4,25 +4,42 @@
[section:compliance C++11 Compliance]
/TODO/: Look into C++11's `std::pair`.
[section:allocator_compliance Use of allocators]
* Objects are not constructed using the allocator. The node containing them
is constructed using the allocator's `construct` function, but then the
object is constructed in a buffer in that node by calling the constructor
directly.
* Similarly the object is destructed by calling its destructor directly, and
then the allocator's `destroy` method is used to destruct the node.
* For most compilers `select_on_container_copy` is only detected for an
exact signature match in the allocator itself - not in a base. There is full
detection for g++ 4.4 or laster, Visual C++ 2008 or later, Clang and maybe
other compilers which support SFINAE for expressions.
* `pointer_traits` aren't used. Instead, pointer types are obtained from
rebound allocators.
* /TODO/: Any other defficiences of `allocator_traits` emulation.
* Pointers of base types are used to store the location of a derived type.
(/TODO/: I'm not sure if that isn't compliant).
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]
@@ -35,19 +52,43 @@ 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/.
* The number of arguments used in `emplace` is limited to /TODO/.
* Argument forwarding is not perfect.
* /TODO/: Constructor call for pairs.
[endsect]
[section:other Other]
[section:pairs Pairs]
* 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.
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]
+3 -2
View File
@@ -67,9 +67,10 @@ so that the hash function doesn't need to be explicitly given:
See the [link hash.custom Boost.Hash documentation] for more detail on how to
do this. Remember that it relies on extensions to the draft standard - so it
won't work on other implementations of the unordered associative containers.
won't work for other implementations of the unordered associative containers,
you'll need to explicitly use Boost.Hash.
[table Methods for accessing the hash and equality functions.
[table:access_methods Methods for accessing the hash and equality functions.
[[Method] [Description]]
[
+4 -15
View File
@@ -2,15 +2,6 @@
/ 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) ]
[def __tr1__
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf
C++ Standard Library Technical Report]]
[def __boost-tr1__
[@http://www.boost.org/doc/html/boost_tr1.html
Boost.TR1]]
[def __draft__
[@http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2960.pdf
Working Draft of the C++ Standard]]
[def __hash-table__ [@http://en.wikipedia.org/wiki/Hash_table
hash table]]
[def __hash-function__ [@http://en.wikipedia.org/wiki/Hash_function
@@ -31,12 +22,10 @@ to order their elements. For some data types this is impossible to implement
or isn't practical. In contrast, a hash table only needs an equality function
and a hash function for the key.
With this in mind, the __tr1__ introduced the unordered associative containers,
which are implemented using hash tables, and they have now been added to the
__draft__.
This library supplies an almost complete implementation of the specification in
the __draft__.
With this in mind, unordered associative containers were added to the C++
standard. This is an implementation of the containers described in C++11,
with some [link unordered.compliance deviations from the standard] in
order to work with non-C++11 compilers and libraries.
`unordered_set` and `unordered_multiset` are defined in the header
<[headerref boost/unordered_set.hpp]>
+6
View File
@@ -92,6 +92,8 @@ So, this implementation uses a prime number for the hash table size.
[h2 Equality operators]
/TODO/: This is out of date.
`operator==` and `operator!=` are not included in the standard, but I've
added them as I think they could be useful and can be implemented
fairly efficiently. They are specified differently to the other standard
@@ -115,6 +117,8 @@ that their order can be considered part of the container's value.
[h3 C++0x allocators]
/TODO/: This is out of date.
Recent drafts have included an overhaul of the allocators, but this was
dependent on concepts which are no longer in the standard.
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2946.pdf n2946]
@@ -124,6 +128,8 @@ a little to accomodate non-C++0x compilers.
[h3 Swapping containers with unequal allocators]
/TODO/: This is out of date.
It isn't clear how to swap containers when their allocators aren't equal.
This is
[@http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#431
+47 -34
View File
@@ -60,10 +60,6 @@ EOL;
</simpara></purpose>
<description>
<para>Based on chapter 23 of
<ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2960.pdf">the working draft of the C++ standard [n2960]</ulink>.
But without the updated rules for allocators.
</para>
<para><emphasis role="bold">Template Parameters</emphasis>
<informaltable>
<tgroup cols="2">
@@ -236,6 +232,9 @@ EOL;
</parameter>
<description>
<para>The copy constructor. Copies the contained elements, hash function, predicate, maximum load factor and allocator.</para>
<para>If <code>Allocator::select_on_container_copy_construction</code>
exists and has the right signature, the allocator will be
constructed from its result.</para>
</description>
<requires>
<para><code>value_type</code> is copy constructible</para>
@@ -249,12 +248,18 @@ EOL;
<para>The move constructor.</para>
</description>
<notes>
<para>This is emulated on compilers without rvalue references.</para>
<para>This is implemented using Boost.Move.</para>
</notes>
<requires>
<para>
<code>value_type</code> is move constructible.
(TODO: This is not actually required in this implementation).
</para>
<para>
On compilers without rvalue reference support the
emulation does not support moving without calling
<code>boost::move</code> if <code>value_type</code> is
not copyable. So, for example, you can't return the
container from a function.
</para>
</requires>
</constructor>
@@ -289,14 +294,12 @@ EOL;
<type><?php echo $name; ?>&amp;</type>
<description>
<para>The assignment operator. Copies the contained elements, hash function, predicate and maximum load factor but not the allocator.</para>
<para>If <code>Alloc::propagate_on_container_copy_assignment</code>
exists and <code>Alloc::propagate_on_container_copy_assignment::value
</code> is true, the allocator is overwritten, if not the
copied elements are created using the existing
allocator.</para>
</description>
<notes>
<para>
On compilers without rvalue references, there is a single assignment
operator with the signature <code>operator=(<?php echo $name; ?>)</code>
in order to emulate move semantics.
</para>
</notes>
<requires>
<para><code>value_type</code> is copy constructible</para>
</requires>
@@ -308,18 +311,21 @@ EOL;
<type><?php echo $name; ?>&amp;</type>
<description>
<para>The move assignment operator.</para>
<para>If <code>Alloc::propagate_on_container_move_assignment</code>
exists and <code>Alloc::propagate_on_container_move_assignment::value
</code> is true, the allocator is overwritten, if not the
moved elements are created using the existing
allocator.</para>
</description>
<notes>
<para>
On compilers without rvalue references, there is a single assignment
operator with the signature <code>operator=(<?php echo $name; ?>)</code>
in order to emulate move semantics.
On compilers without rvalue references, this is emulated using
Boost.Move.
</para>
</notes>
<requires>
<para>
<code>value_type</code> is move constructible.
(TODO: This is not actually required in this implementation).
</para>
</requires>
</method>
@@ -406,6 +412,10 @@ EOL;
<para>If the compiler doesn't support variadic template arguments or rvalue
references, this is emulated for up to 10 arguments, with no support
for rvalue references or move semantics.</para>
<para>Since existing `std::pair` implementations don't support
<code>std::piecewise_construct</code> this emulates it,
but using <code>boost::unordered::piecewise_construct</code>.
</para>
</notes>
</method>
<method name="emplace_hint">
@@ -444,6 +454,10 @@ EOL;
<para>If the compiler doesn't support variadic template arguments or rvalue
references, this is emulated for up to 10 arguments, with no support
for rvalue references or move semantics.</para>
<para>Since existing `std::pair` implementations don't support
<code>std::piecewise_construct</code> this emulates it,
but using <code>boost::unordered::piecewise_construct</code>.
</para>
</notes>
</method>
<method name="insert">
@@ -541,15 +555,13 @@ EOL;
</returns>
<throws>
<para>Only throws an exception if it is thrown by <code>hasher</code> or <code>key_equal</code>.</para>
<para>In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations.</para>
</throws>
<notes>
<para>
When the number of elements is a lot smaller than the number of buckets
this function can be very inefficient as it has to search through empty
buckets for the next element, in order to return the iterator.
The method <methodname>quick_erase</methodname> is faster, but has yet
to be standardized.
In older versions this could be inefficient because it had to search
through several buckets to find the position of the returned iterator.
The data structure has been changed so that this is no longer the case,
and the alternative erase methods have been deprecated.
</para>
</notes>
</method>
@@ -601,13 +613,10 @@ EOL;
</throws>
<notes>
<para>
This method is faster than <methodname>erase</methodname> as
it doesn't have to find the next element in the container -
a potentially costly operation.
</para>
<para>
As it hasn't been standardized, it's likely that this may
change in the future.
This method was implemented because returning an iterator to
the next element from <code>erase</code> was expensive, but
the container has been redesigned so that is no longer the
case. So this method is now deprecated.
</para>
</notes>
</method>
@@ -625,10 +634,10 @@ EOL;
</throws>
<notes>
<para>
This method is now deprecated, use
<methodname>quick_return</methodname> instead. Although be
warned that as that isn't standardized yet, it could also
change.
This method was implemented because returning an iterator to
the next element from <code>erase</code> was expensive, but
the container has been redesigned so that is no longer the
case. So this method is now deprecated.
</para>
</notes>
</method>
@@ -653,6 +662,7 @@ EOL;
<para>If the allocators are equal, doesn't throw an exception unless it is thrown by the copy constructor or copy assignment operator of <code>key_equal</code> or <code>hasher</code>.</para>
</throws>
<notes>
<para><emphasis>TODO</emphasis>: Update swap documentation, no longer correct.</para>
<para>For a discussion of the behavior when allocators aren't equal see
<link linkend="unordered.rationale.swapping_containers_with_unequal_allocators">the implementation details</link>.</para>
</notes>
@@ -952,6 +962,7 @@ EOL;
</parameter>
<type>bool</type>
<notes>
<para><emphasis>TODO</emphasis>: Documentation outdated.</para>
<para>This is a boost extension.</para>
<para>Behavior is undefined if the two containers don't have
equivalent equality predicates.</para>
@@ -975,6 +986,7 @@ EOL;
</parameter>
<type>bool</type>
<notes>
<para><emphasis>TODO</emphasis>: Documentation outdated.</para>
<para>This is a boost extension.</para>
<para>Behavior is undefined if the two containers don't have
equivalent equality predicates.</para>
@@ -1006,6 +1018,7 @@ EOL;
<para>If the allocators are equal, doesn't throw an exception unless it is thrown by the copy constructor or copy assignment operator of <code>Hash</code> or <code>Pred</code>.</para>
</throws>
<notes>
<para><emphasis>TODO</emphasis>: Update swap documentation, no longer correct.</para>
<para>For a discussion of the behavior when allocators aren't equal see
<link linkend="unordered.rationale.swapping_containers_with_unequal_allocators">the implementation details</link>.</para>
</notes>
+188 -136
View File
@@ -23,10 +23,6 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
An unordered associative container that stores unique values.
</simpara></purpose>
<description>
<para>Based on chapter 23 of
<ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2960.pdf">the working draft of the C++ standard [n2960]</ulink>.
But without the updated rules for allocators.
</para>
<para><emphasis role="bold">Template Parameters</emphasis>
<informaltable>
<tgroup cols="2">
@@ -181,6 +177,9 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</parameter>
<description>
<para>The copy constructor. Copies the contained elements, hash function, predicate, maximum load factor and allocator.</para>
<para>If <code>Allocator::select_on_container_copy_construction</code>
exists and has the right signature, the allocator will be
constructed from its result.</para>
</description>
<requires>
<para><code>value_type</code> is copy constructible</para>
@@ -194,12 +193,18 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<para>The move constructor.</para>
</description>
<notes>
<para>This is emulated on compilers without rvalue references.</para>
<para>This is implemented using Boost.Move.</para>
</notes>
<requires>
<para>
<code>value_type</code> is move constructible.
(TODO: This is not actually required in this implementation).
</para>
<para>
On compilers without rvalue reference support the
emulation does not support moving without calling
<code>boost::move</code> if <code>value_type</code> is
not copyable. So, for example, you can't return the
container from a function.
</para>
</requires>
</constructor>
@@ -234,14 +239,12 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<type>unordered_set&amp;</type>
<description>
<para>The assignment operator. Copies the contained elements, hash function, predicate and maximum load factor but not the allocator.</para>
<para>If <code>Alloc::propagate_on_container_copy_assignment</code>
exists and <code>Alloc::propagate_on_container_copy_assignment::value
</code> is true, the allocator is overwritten, if not the
copied elements are created using the existing
allocator.</para>
</description>
<notes>
<para>
On compilers without rvalue references, there is a single assignment
operator with the signature <code>operator=(unordered_set)</code>
in order to emulate move semantics.
</para>
</notes>
<requires>
<para><code>value_type</code> is copy constructible</para>
</requires>
@@ -253,18 +256,21 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<type>unordered_set&amp;</type>
<description>
<para>The move assignment operator.</para>
<para>If <code>Alloc::propagate_on_container_move_assignment</code>
exists and <code>Alloc::propagate_on_container_move_assignment::value
</code> is true, the allocator is overwritten, if not the
moved elements are created using the existing
allocator.</para>
</description>
<notes>
<para>
On compilers without rvalue references, there is a single assignment
operator with the signature <code>operator=(unordered_set)</code>
in order to emulate move semantics.
On compilers without rvalue references, this is emulated using
Boost.Move.
</para>
</notes>
<requires>
<para>
<code>value_type</code> is move constructible.
(TODO: This is not actually required in this implementation).
</para>
</requires>
</method>
@@ -344,6 +350,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<para>If the compiler doesn't support variadic template arguments or rvalue
references, this is emulated for up to 10 arguments, with no support
for rvalue references or move semantics.</para>
<para>Since existing `std::pair` implementations don't support
<code>std::piecewise_construct</code> this emulates it,
but using <code>boost::unordered::piecewise_construct</code>.
</para>
</notes>
</method>
<method name="emplace_hint">
@@ -375,6 +385,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<para>If the compiler doesn't support variadic template arguments or rvalue
references, this is emulated for up to 10 arguments, with no support
for rvalue references or move semantics.</para>
<para>Since existing `std::pair` implementations don't support
<code>std::piecewise_construct</code> this emulates it,
but using <code>boost::unordered::piecewise_construct</code>.
</para>
</notes>
</method>
<method name="insert">
@@ -457,15 +471,13 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</returns>
<throws>
<para>Only throws an exception if it is thrown by <code>hasher</code> or <code>key_equal</code>.</para>
<para>In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations.</para>
</throws>
<notes>
<para>
When the number of elements is a lot smaller than the number of buckets
this function can be very inefficient as it has to search through empty
buckets for the next element, in order to return the iterator.
The method <methodname>quick_erase</methodname> is faster, but has yet
to be standardized.
In older versions this could be inefficient because it had to search
through several buckets to find the position of the returned iterator.
The data structure has been changed so that this is no longer the case,
and the alternative erase methods have been deprecated.
</para>
</notes>
</method>
@@ -517,13 +529,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</throws>
<notes>
<para>
This method is faster than <methodname>erase</methodname> as
it doesn't have to find the next element in the container -
a potentially costly operation.
</para>
<para>
As it hasn't been standardized, it's likely that this may
change in the future.
This method was implemented because returning an iterator to
the next element from <code>erase</code> was expensive, but
the container has been redesigned so that is no longer the
case. So this method is now deprecated.
</para>
</notes>
</method>
@@ -541,10 +550,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</throws>
<notes>
<para>
This method is now deprecated, use
<methodname>quick_return</methodname> instead. Although be
warned that as that isn't standardized yet, it could also
change.
This method was implemented because returning an iterator to
the next element from <code>erase</code> was expensive, but
the container has been redesigned so that is no longer the
case. So this method is now deprecated.
</para>
</notes>
</method>
@@ -569,6 +578,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<para>If the allocators are equal, doesn't throw an exception unless it is thrown by the copy constructor or copy assignment operator of <code>key_equal</code> or <code>hasher</code>.</para>
</throws>
<notes>
<para><emphasis>TODO</emphasis>: Update swap documentation, no longer correct.</para>
<para>For a discussion of the behavior when allocators aren't equal see
<link linkend="unordered.rationale.swapping_containers_with_unequal_allocators">the implementation details</link>.</para>
</notes>
@@ -832,6 +842,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</parameter>
<type>bool</type>
<notes>
<para><emphasis>TODO</emphasis>: Documentation outdated.</para>
<para>This is a boost extension.</para>
<para>Behavior is undefined if the two containers don't have
equivalent equality predicates.</para>
@@ -856,6 +867,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</parameter>
<type>bool</type>
<notes>
<para><emphasis>TODO</emphasis>: Documentation outdated.</para>
<para>This is a boost extension.</para>
<para>Behavior is undefined if the two containers don't have
equivalent equality predicates.</para>
@@ -888,6 +900,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<para>If the allocators are equal, doesn't throw an exception unless it is thrown by the copy constructor or copy assignment operator of <code>Hash</code> or <code>Pred</code>.</para>
</throws>
<notes>
<para><emphasis>TODO</emphasis>: Update swap documentation, no longer correct.</para>
<para>For a discussion of the behavior when allocators aren't equal see
<link linkend="unordered.rationale.swapping_containers_with_unequal_allocators">the implementation details</link>.</para>
</notes>
@@ -912,10 +925,6 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
An unordered associative container that stores values. The same key can be stored multiple times.
</simpara></purpose>
<description>
<para>Based on chapter 23 of
<ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2960.pdf">the working draft of the C++ standard [n2960]</ulink>.
But without the updated rules for allocators.
</para>
<para><emphasis role="bold">Template Parameters</emphasis>
<informaltable>
<tgroup cols="2">
@@ -1070,6 +1079,9 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</parameter>
<description>
<para>The copy constructor. Copies the contained elements, hash function, predicate, maximum load factor and allocator.</para>
<para>If <code>Allocator::select_on_container_copy_construction</code>
exists and has the right signature, the allocator will be
constructed from its result.</para>
</description>
<requires>
<para><code>value_type</code> is copy constructible</para>
@@ -1083,12 +1095,18 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<para>The move constructor.</para>
</description>
<notes>
<para>This is emulated on compilers without rvalue references.</para>
<para>This is implemented using Boost.Move.</para>
</notes>
<requires>
<para>
<code>value_type</code> is move constructible.
(TODO: This is not actually required in this implementation).
</para>
<para>
On compilers without rvalue reference support the
emulation does not support moving without calling
<code>boost::move</code> if <code>value_type</code> is
not copyable. So, for example, you can't return the
container from a function.
</para>
</requires>
</constructor>
@@ -1123,14 +1141,12 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<type>unordered_multiset&amp;</type>
<description>
<para>The assignment operator. Copies the contained elements, hash function, predicate and maximum load factor but not the allocator.</para>
<para>If <code>Alloc::propagate_on_container_copy_assignment</code>
exists and <code>Alloc::propagate_on_container_copy_assignment::value
</code> is true, the allocator is overwritten, if not the
copied elements are created using the existing
allocator.</para>
</description>
<notes>
<para>
On compilers without rvalue references, there is a single assignment
operator with the signature <code>operator=(unordered_multiset)</code>
in order to emulate move semantics.
</para>
</notes>
<requires>
<para><code>value_type</code> is copy constructible</para>
</requires>
@@ -1142,18 +1158,21 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<type>unordered_multiset&amp;</type>
<description>
<para>The move assignment operator.</para>
<para>If <code>Alloc::propagate_on_container_move_assignment</code>
exists and <code>Alloc::propagate_on_container_move_assignment::value
</code> is true, the allocator is overwritten, if not the
moved elements are created using the existing
allocator.</para>
</description>
<notes>
<para>
On compilers without rvalue references, there is a single assignment
operator with the signature <code>operator=(unordered_multiset)</code>
in order to emulate move semantics.
On compilers without rvalue references, this is emulated using
Boost.Move.
</para>
</notes>
<requires>
<para>
<code>value_type</code> is move constructible.
(TODO: This is not actually required in this implementation).
</para>
</requires>
</method>
@@ -1232,6 +1251,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<para>If the compiler doesn't support variadic template arguments or rvalue
references, this is emulated for up to 10 arguments, with no support
for rvalue references or move semantics.</para>
<para>Since existing `std::pair` implementations don't support
<code>std::piecewise_construct</code> this emulates it,
but using <code>boost::unordered::piecewise_construct</code>.
</para>
</notes>
</method>
<method name="emplace_hint">
@@ -1263,6 +1286,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<para>If the compiler doesn't support variadic template arguments or rvalue
references, this is emulated for up to 10 arguments, with no support
for rvalue references or move semantics.</para>
<para>Since existing `std::pair` implementations don't support
<code>std::piecewise_construct</code> this emulates it,
but using <code>boost::unordered::piecewise_construct</code>.
</para>
</notes>
</method>
<method name="insert">
@@ -1344,15 +1371,13 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</returns>
<throws>
<para>Only throws an exception if it is thrown by <code>hasher</code> or <code>key_equal</code>.</para>
<para>In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations.</para>
</throws>
<notes>
<para>
When the number of elements is a lot smaller than the number of buckets
this function can be very inefficient as it has to search through empty
buckets for the next element, in order to return the iterator.
The method <methodname>quick_erase</methodname> is faster, but has yet
to be standardized.
In older versions this could be inefficient because it had to search
through several buckets to find the position of the returned iterator.
The data structure has been changed so that this is no longer the case,
and the alternative erase methods have been deprecated.
</para>
</notes>
</method>
@@ -1404,13 +1429,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</throws>
<notes>
<para>
This method is faster than <methodname>erase</methodname> as
it doesn't have to find the next element in the container -
a potentially costly operation.
</para>
<para>
As it hasn't been standardized, it's likely that this may
change in the future.
This method was implemented because returning an iterator to
the next element from <code>erase</code> was expensive, but
the container has been redesigned so that is no longer the
case. So this method is now deprecated.
</para>
</notes>
</method>
@@ -1428,10 +1450,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</throws>
<notes>
<para>
This method is now deprecated, use
<methodname>quick_return</methodname> instead. Although be
warned that as that isn't standardized yet, it could also
change.
This method was implemented because returning an iterator to
the next element from <code>erase</code> was expensive, but
the container has been redesigned so that is no longer the
case. So this method is now deprecated.
</para>
</notes>
</method>
@@ -1456,6 +1478,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<para>If the allocators are equal, doesn't throw an exception unless it is thrown by the copy constructor or copy assignment operator of <code>key_equal</code> or <code>hasher</code>.</para>
</throws>
<notes>
<para><emphasis>TODO</emphasis>: Update swap documentation, no longer correct.</para>
<para>For a discussion of the behavior when allocators aren't equal see
<link linkend="unordered.rationale.swapping_containers_with_unequal_allocators">the implementation details</link>.</para>
</notes>
@@ -1719,6 +1742,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</parameter>
<type>bool</type>
<notes>
<para><emphasis>TODO</emphasis>: Documentation outdated.</para>
<para>This is a boost extension.</para>
<para>Behavior is undefined if the two containers don't have
equivalent equality predicates.</para>
@@ -1743,6 +1767,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</parameter>
<type>bool</type>
<notes>
<para><emphasis>TODO</emphasis>: Documentation outdated.</para>
<para>This is a boost extension.</para>
<para>Behavior is undefined if the two containers don't have
equivalent equality predicates.</para>
@@ -1775,6 +1800,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<para>If the allocators are equal, doesn't throw an exception unless it is thrown by the copy constructor or copy assignment operator of <code>Hash</code> or <code>Pred</code>.</para>
</throws>
<notes>
<para><emphasis>TODO</emphasis>: Update swap documentation, no longer correct.</para>
<para>For a discussion of the behavior when allocators aren't equal see
<link linkend="unordered.rationale.swapping_containers_with_unequal_allocators">the implementation details</link>.</para>
</notes>
@@ -1805,10 +1831,6 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
An unordered associative container that associates unique keys with another value.
</simpara></purpose>
<description>
<para>Based on chapter 23 of
<ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2960.pdf">the working draft of the C++ standard [n2960]</ulink>.
But without the updated rules for allocators.
</para>
<para><emphasis role="bold">Template Parameters</emphasis>
<informaltable>
<tgroup cols="2">
@@ -1969,6 +1991,9 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</parameter>
<description>
<para>The copy constructor. Copies the contained elements, hash function, predicate, maximum load factor and allocator.</para>
<para>If <code>Allocator::select_on_container_copy_construction</code>
exists and has the right signature, the allocator will be
constructed from its result.</para>
</description>
<requires>
<para><code>value_type</code> is copy constructible</para>
@@ -1982,12 +2007,18 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<para>The move constructor.</para>
</description>
<notes>
<para>This is emulated on compilers without rvalue references.</para>
<para>This is implemented using Boost.Move.</para>
</notes>
<requires>
<para>
<code>value_type</code> is move constructible.
(TODO: This is not actually required in this implementation).
</para>
<para>
On compilers without rvalue reference support the
emulation does not support moving without calling
<code>boost::move</code> if <code>value_type</code> is
not copyable. So, for example, you can't return the
container from a function.
</para>
</requires>
</constructor>
@@ -2022,14 +2053,12 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<type>unordered_map&amp;</type>
<description>
<para>The assignment operator. Copies the contained elements, hash function, predicate and maximum load factor but not the allocator.</para>
<para>If <code>Alloc::propagate_on_container_copy_assignment</code>
exists and <code>Alloc::propagate_on_container_copy_assignment::value
</code> is true, the allocator is overwritten, if not the
copied elements are created using the existing
allocator.</para>
</description>
<notes>
<para>
On compilers without rvalue references, there is a single assignment
operator with the signature <code>operator=(unordered_map)</code>
in order to emulate move semantics.
</para>
</notes>
<requires>
<para><code>value_type</code> is copy constructible</para>
</requires>
@@ -2041,18 +2070,21 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<type>unordered_map&amp;</type>
<description>
<para>The move assignment operator.</para>
<para>If <code>Alloc::propagate_on_container_move_assignment</code>
exists and <code>Alloc::propagate_on_container_move_assignment::value
</code> is true, the allocator is overwritten, if not the
moved elements are created using the existing
allocator.</para>
</description>
<notes>
<para>
On compilers without rvalue references, there is a single assignment
operator with the signature <code>operator=(unordered_map)</code>
in order to emulate move semantics.
On compilers without rvalue references, this is emulated using
Boost.Move.
</para>
</notes>
<requires>
<para>
<code>value_type</code> is move constructible.
(TODO: This is not actually required in this implementation).
</para>
</requires>
</method>
@@ -2132,6 +2164,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<para>If the compiler doesn't support variadic template arguments or rvalue
references, this is emulated for up to 10 arguments, with no support
for rvalue references or move semantics.</para>
<para>Since existing `std::pair` implementations don't support
<code>std::piecewise_construct</code> this emulates it,
but using <code>boost::unordered::piecewise_construct</code>.
</para>
</notes>
</method>
<method name="emplace_hint">
@@ -2163,6 +2199,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<para>If the compiler doesn't support variadic template arguments or rvalue
references, this is emulated for up to 10 arguments, with no support
for rvalue references or move semantics.</para>
<para>Since existing `std::pair` implementations don't support
<code>std::piecewise_construct</code> this emulates it,
but using <code>boost::unordered::piecewise_construct</code>.
</para>
</notes>
</method>
<method name="insert">
@@ -2245,15 +2285,13 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</returns>
<throws>
<para>Only throws an exception if it is thrown by <code>hasher</code> or <code>key_equal</code>.</para>
<para>In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations.</para>
</throws>
<notes>
<para>
When the number of elements is a lot smaller than the number of buckets
this function can be very inefficient as it has to search through empty
buckets for the next element, in order to return the iterator.
The method <methodname>quick_erase</methodname> is faster, but has yet
to be standardized.
In older versions this could be inefficient because it had to search
through several buckets to find the position of the returned iterator.
The data structure has been changed so that this is no longer the case,
and the alternative erase methods have been deprecated.
</para>
</notes>
</method>
@@ -2305,13 +2343,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</throws>
<notes>
<para>
This method is faster than <methodname>erase</methodname> as
it doesn't have to find the next element in the container -
a potentially costly operation.
</para>
<para>
As it hasn't been standardized, it's likely that this may
change in the future.
This method was implemented because returning an iterator to
the next element from <code>erase</code> was expensive, but
the container has been redesigned so that is no longer the
case. So this method is now deprecated.
</para>
</notes>
</method>
@@ -2329,10 +2364,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</throws>
<notes>
<para>
This method is now deprecated, use
<methodname>quick_return</methodname> instead. Although be
warned that as that isn't standardized yet, it could also
change.
This method was implemented because returning an iterator to
the next element from <code>erase</code> was expensive, but
the container has been redesigned so that is no longer the
case. So this method is now deprecated.
</para>
</notes>
</method>
@@ -2357,6 +2392,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<para>If the allocators are equal, doesn't throw an exception unless it is thrown by the copy constructor or copy assignment operator of <code>key_equal</code> or <code>hasher</code>.</para>
</throws>
<notes>
<para><emphasis>TODO</emphasis>: Update swap documentation, no longer correct.</para>
<para>For a discussion of the behavior when allocators aren't equal see
<link linkend="unordered.rationale.swapping_containers_with_unequal_allocators">the implementation details</link>.</para>
</notes>
@@ -2657,6 +2693,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</parameter>
<type>bool</type>
<notes>
<para><emphasis>TODO</emphasis>: Documentation outdated.</para>
<para>This is a boost extension.</para>
<para>Behavior is undefined if the two containers don't have
equivalent equality predicates.</para>
@@ -2683,6 +2720,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</parameter>
<type>bool</type>
<notes>
<para><emphasis>TODO</emphasis>: Documentation outdated.</para>
<para>This is a boost extension.</para>
<para>Behavior is undefined if the two containers don't have
equivalent equality predicates.</para>
@@ -2717,6 +2755,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<para>If the allocators are equal, doesn't throw an exception unless it is thrown by the copy constructor or copy assignment operator of <code>Hash</code> or <code>Pred</code>.</para>
</throws>
<notes>
<para><emphasis>TODO</emphasis>: Update swap documentation, no longer correct.</para>
<para>For a discussion of the behavior when allocators aren't equal see
<link linkend="unordered.rationale.swapping_containers_with_unequal_allocators">the implementation details</link>.</para>
</notes>
@@ -2743,10 +2782,6 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
An unordered associative container that associates keys with another value. The same key can be stored multiple times.
</simpara></purpose>
<description>
<para>Based on chapter 23 of
<ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2960.pdf">the working draft of the C++ standard [n2960]</ulink>.
But without the updated rules for allocators.
</para>
<para><emphasis role="bold">Template Parameters</emphasis>
<informaltable>
<tgroup cols="2">
@@ -2907,6 +2942,9 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</parameter>
<description>
<para>The copy constructor. Copies the contained elements, hash function, predicate, maximum load factor and allocator.</para>
<para>If <code>Allocator::select_on_container_copy_construction</code>
exists and has the right signature, the allocator will be
constructed from its result.</para>
</description>
<requires>
<para><code>value_type</code> is copy constructible</para>
@@ -2920,12 +2958,18 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<para>The move constructor.</para>
</description>
<notes>
<para>This is emulated on compilers without rvalue references.</para>
<para>This is implemented using Boost.Move.</para>
</notes>
<requires>
<para>
<code>value_type</code> is move constructible.
(TODO: This is not actually required in this implementation).
</para>
<para>
On compilers without rvalue reference support the
emulation does not support moving without calling
<code>boost::move</code> if <code>value_type</code> is
not copyable. So, for example, you can't return the
container from a function.
</para>
</requires>
</constructor>
@@ -2960,14 +3004,12 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<type>unordered_multimap&amp;</type>
<description>
<para>The assignment operator. Copies the contained elements, hash function, predicate and maximum load factor but not the allocator.</para>
<para>If <code>Alloc::propagate_on_container_copy_assignment</code>
exists and <code>Alloc::propagate_on_container_copy_assignment::value
</code> is true, the allocator is overwritten, if not the
copied elements are created using the existing
allocator.</para>
</description>
<notes>
<para>
On compilers without rvalue references, there is a single assignment
operator with the signature <code>operator=(unordered_multimap)</code>
in order to emulate move semantics.
</para>
</notes>
<requires>
<para><code>value_type</code> is copy constructible</para>
</requires>
@@ -2979,18 +3021,21 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<type>unordered_multimap&amp;</type>
<description>
<para>The move assignment operator.</para>
<para>If <code>Alloc::propagate_on_container_move_assignment</code>
exists and <code>Alloc::propagate_on_container_move_assignment::value
</code> is true, the allocator is overwritten, if not the
moved elements are created using the existing
allocator.</para>
</description>
<notes>
<para>
On compilers without rvalue references, there is a single assignment
operator with the signature <code>operator=(unordered_multimap)</code>
in order to emulate move semantics.
On compilers without rvalue references, this is emulated using
Boost.Move.
</para>
</notes>
<requires>
<para>
<code>value_type</code> is move constructible.
(TODO: This is not actually required in this implementation).
</para>
</requires>
</method>
@@ -3069,6 +3114,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<para>If the compiler doesn't support variadic template arguments or rvalue
references, this is emulated for up to 10 arguments, with no support
for rvalue references or move semantics.</para>
<para>Since existing `std::pair` implementations don't support
<code>std::piecewise_construct</code> this emulates it,
but using <code>boost::unordered::piecewise_construct</code>.
</para>
</notes>
</method>
<method name="emplace_hint">
@@ -3100,6 +3149,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<para>If the compiler doesn't support variadic template arguments or rvalue
references, this is emulated for up to 10 arguments, with no support
for rvalue references or move semantics.</para>
<para>Since existing `std::pair` implementations don't support
<code>std::piecewise_construct</code> this emulates it,
but using <code>boost::unordered::piecewise_construct</code>.
</para>
</notes>
</method>
<method name="insert">
@@ -3181,15 +3234,13 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</returns>
<throws>
<para>Only throws an exception if it is thrown by <code>hasher</code> or <code>key_equal</code>.</para>
<para>In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations.</para>
</throws>
<notes>
<para>
When the number of elements is a lot smaller than the number of buckets
this function can be very inefficient as it has to search through empty
buckets for the next element, in order to return the iterator.
The method <methodname>quick_erase</methodname> is faster, but has yet
to be standardized.
In older versions this could be inefficient because it had to search
through several buckets to find the position of the returned iterator.
The data structure has been changed so that this is no longer the case,
and the alternative erase methods have been deprecated.
</para>
</notes>
</method>
@@ -3241,13 +3292,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</throws>
<notes>
<para>
This method is faster than <methodname>erase</methodname> as
it doesn't have to find the next element in the container -
a potentially costly operation.
</para>
<para>
As it hasn't been standardized, it's likely that this may
change in the future.
This method was implemented because returning an iterator to
the next element from <code>erase</code> was expensive, but
the container has been redesigned so that is no longer the
case. So this method is now deprecated.
</para>
</notes>
</method>
@@ -3265,10 +3313,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</throws>
<notes>
<para>
This method is now deprecated, use
<methodname>quick_return</methodname> instead. Although be
warned that as that isn't standardized yet, it could also
change.
This method was implemented because returning an iterator to
the next element from <code>erase</code> was expensive, but
the container has been redesigned so that is no longer the
case. So this method is now deprecated.
</para>
</notes>
</method>
@@ -3293,6 +3341,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<para>If the allocators are equal, doesn't throw an exception unless it is thrown by the copy constructor or copy assignment operator of <code>key_equal</code> or <code>hasher</code>.</para>
</throws>
<notes>
<para><emphasis>TODO</emphasis>: Update swap documentation, no longer correct.</para>
<para>For a discussion of the behavior when allocators aren't equal see
<link linkend="unordered.rationale.swapping_containers_with_unequal_allocators">the implementation details</link>.</para>
</notes>
@@ -3558,6 +3607,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</parameter>
<type>bool</type>
<notes>
<para><emphasis>TODO</emphasis>: Documentation outdated.</para>
<para>This is a boost extension.</para>
<para>Behavior is undefined if the two containers don't have
equivalent equality predicates.</para>
@@ -3584,6 +3634,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</parameter>
<type>bool</type>
<notes>
<para><emphasis>TODO</emphasis>: Documentation outdated.</para>
<para>This is a boost extension.</para>
<para>Behavior is undefined if the two containers don't have
equivalent equality predicates.</para>
@@ -3618,6 +3669,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<para>If the allocators are equal, doesn't throw an exception unless it is thrown by the copy constructor or copy assignment operator of <code>Hash</code> or <code>Pred</code>.</para>
</throws>
<notes>
<para><emphasis>TODO</emphasis>: Update swap documentation, no longer correct.</para>
<para>For a discussion of the behavior when allocators aren't equal see
<link linkend="unordered.rationale.swapping_containers_with_unequal_allocators">the implementation details</link>.</para>
</notes>
+1 -1
View File
@@ -3,7 +3,7 @@
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ]
[library Boost.Unordered
[quickbook 1.4]
[quickbook 1.5]
[authors [James, Daniel]]
[copyright 2003 2004 Jeremy B. Maitin-Shepard]
[copyright 2005 2006 2007 2008 Daniel James]