Unordered: Merge from trunk.

Remove some workarounds for old compilers, some documentation updates and tweak
some tests for problem compilers.


[SVN r74469]
This commit is contained in:
Daniel James
2011-09-19 18:22:18 +00:00
parent 0618d01f86
commit 17ba6c9916
7 changed files with 325 additions and 153 deletions

View File

@ -143,7 +143,8 @@ 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.
now they can be a permutation of each other. To keep the old
behavior define the macro `BOOST_UNORDERED_DEPRECATED_EQUALITY`.
* The behaviour of swap is different when the two containers to be
swapped has unequal allocators. It used to allocate new nodes using
@ -154,4 +155,12 @@ in some breaking changes:
* Allocator's `construct` and `destroy` functions are called with raw
pointers, rather than the allocator's `pointer` type.
* `emplace` used to emulate the variadic pair constructors that
appeared in early C++0x drafts. Since they were removed it no
longer does so. It does emulate the new `piecewise_construct`
pair constructors - only you need to use
`boost::piecewise_construct`. To use the old emulation of
the variadic consturctors define
`BOOST_UNORDERED_DEPRECATED_PAIR_CONSTRUCT`.
[endsect]

View File

@ -44,6 +44,8 @@ bucket but there are a some serious problems with this:
So chained addressing is used.
[/ (Removing for now as this is out of date)
For containers with unique keys I store the buckets in a single-linked list.
There are other possible data structures (such as a double-linked list)
that allow for some operations to be faster (such as erasing and iteration)
@ -63,6 +65,17 @@ nodes in reverse order. This allows quick navigation to the end of a group (sinc
the first element points to the last) and can be quickly updated when elements
are inserted or erased. The main disadvantage of this approach is some hairy code
for erasing elements.
]
[/ (Starting to write up new structure, might not be ready in time)
The node used to be stored in a linked list for each bucket but that
didn't meet the complexity requirements for C++11, so now the nodes
are stored in one long single linked list. But there needs a way to get
the bucket from the node, to do that a copy of the key's hash value is
stored in the node. Another possibility would be to store a pointer to
the bucket, or the bucket's index, but storing the hash value allows
some operations to be faster.
]
[h2 Number of Buckets]
@ -90,58 +103,4 @@ efficiency advantage of power of 2 hash tables.
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
containers, comparing keys using the equality predicate rather than
`operator==`.
It's also different to the proposal
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2944.pdf n2944].
which uses the equality operators for the whole of `value_type`. This
implementation just uses the key equality function for the key,
and `mapped_type`'s equality operator in `unordered_map` and
`unordered_multimap` for the mapped part of the element.
Also, in `unordered_multimap`, the mapped values for a group of elements with
equivalent keys are only considered equal if they are in the same order,
in n2944 they just need to be a permutation of each other. Since the
order of elements with equal keys is now defined to be stable, it seems to me
that their order can be considered part of the container's value.
[h2 Active Issues and Proposals]
[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]
attempts to respecify them without concepts. I'll try to implement this (or
an appropriate later version) in a future version of boost, possibly changed
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
Issue 431: Swapping containers with unequal allocators]. This has been resolved
with the new allocator specification, so this should be fixed when
support is added.
[h3 Are insert and erase stable for unordered_multiset and unordered_multimap?]
It wan't specified if `unordered_multiset` and `unordered_multimap` preserve the order
of elements with equivalent keys (i.e. if they're stable under `insert` and `erase`).
Since [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2691.pdf
n2691] it's been specified that they do and this implementation follows that.
[endsect]

View File

@ -412,10 +412,13 @@ 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
<para>Since existing <code>std::pair</code> implementations don't support
<code>std::piecewise_construct</code> this emulates it,
but using <code>boost::unordered::piecewise_construct</code>.
</para>
but using <code>boost::unordered::piecewise_construct</code>.</para>
<para>In version of Boost before 1.48 this emulated the variadic pair
constructor from older C++0x drafts. For backwards compatability
this can be enabled by defining the macro
<code>BOOST_UNORDERED_DEPRECATED_PAIR_CONSTRUCT</code>.
</notes>
</method>
<method name="emplace_hint">
@ -454,9 +457,13 @@ 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
<para>Since existing <code>std::pair</code> implementations don't support
<code>std::piecewise_construct</code> this emulates it,
but using <code>boost::unordered::piecewise_construct</code>.
<para>In version of Boost before 1.48 this emulated the variadic pair
constructor from older C++0x drafts. For backwards compatability
this can be enabled by defining the macro
<code>BOOST_UNORDERED_DEPRECATED_PAIR_CONSTRUCT</code>.
</para>
</notes>
</method>
@ -658,13 +665,19 @@ EOL;
<paramtype><?php echo $name; ?>&amp;</paramtype>
</parameter>
<type>void</type>
<description>
<para>Swaps the contents of the container with the parameter.</para>
<para>If <code>Allocator::propagate_on_container_swap</code> is declared and
<code>Allocator::propagate_on_container_swap::value</code> is true then the
containers' allocators are swapped. Otherwise, swapping with unequal allocators
results in undefined behavior.</para>
</description>
<throws>
<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>
<para>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>
<para>The exception specifications aren't quite the same as the C++11 standard, as
the equality predieate and hash function are swapped using their copy constructors.</para>
</notes>
</method>
</method-group>
@ -961,9 +974,28 @@ EOL;
<paramtype><?php echo $full_type; ?> const&amp;</paramtype>
</parameter>
<type>bool</type>
<description>
<?php if($equivalent_keys): ?>
<para>Return <code>true</code> if <code>x.size() ==
y.size</code> and for every equivalent key group in
<code>x</code>, there is a group in <code>y</code>
for the same key, which is a permutation (using
<code>operator==</code> to compare the value types).
</para>
<?php else: ?>
<para>Return <code>true</code> if <code>x.size() ==
y.size</code> and for every element in <code>x</code>,
there is an element in <code>y</code> with the same
for the same key, with an equal value (using
<code>operator==</code> to compare the value types).
</para>
<?php endif; ?>
</description>
<notes>
<para><emphasis>TODO</emphasis>: Documentation outdated.</para>
<para>This is a boost extension.</para>
<para>The behavior of this function was changed to match
the C++11 standard in Boost 1.48. If you wish to use
the old behaviour, define the macro
<code>BOOST_UNORDERED_DEPRECATED_EQUALITY</code>.</para>
<para>Behavior is undefined if the two containers don't have
equivalent equality predicates.</para>
</notes>
@ -985,9 +1017,28 @@ EOL;
<paramtype><?php echo $full_type; ?> const&amp;</paramtype>
</parameter>
<type>bool</type>
<description>
<?php if($equivalent_keys): ?>
<para>Return <code>false</code> if <code>x.size() ==
y.size</code> and for every equivalent key group in
<code>x</code>, there is a group in <code>y</code>
for the same key, which is a permutation (using
<code>operator==</code> to compare the value types).
</para>
<?php else: ?>
<para>Return <code>false</code> if <code>x.size() ==
y.size</code> and for every element in <code>x</code>,
there is an element in <code>y</code> with the same
for the same key, with an equal value (using
<code>operator==</code> to compare the value types).
</para>
<?php endif; ?>
</description>
<notes>
<para><emphasis>TODO</emphasis>: Documentation outdated.</para>
<para>This is a boost extension.</para>
<para>The behavior of this function was changed to match
the C++11 standard in Boost 1.48. If you wish to use
the old behaviour, define the macro
<code>BOOST_UNORDERED_DEPRECATED_EQUALITY</code>.</para>
<para>Behavior is undefined if the two containers don't have
equivalent equality predicates.</para>
</notes>
@ -1014,13 +1065,19 @@ EOL;
<effects>
<para><code>x.swap(y)</code></para>
</effects>
<description>
<para>Swaps the contents of <code>x</code> and <code>y</code>.</para>
<para>If <code>Allocator::propagate_on_container_swap</code> is declared and
<code>Allocator::propagate_on_container_swap::value</code> is true then the
containers' allocators are swapped. Otherwise, swapping with unequal allocators
results in undefined behavior.</para>
</description>
<throws>
<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>
<para>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>
<para>The exception specifications aren't quite the same as the C++11 standard, as
the equality predieate and hash function are swapped using their copy constructors.</para>
</notes>
</function>
</free-function-group>

View File

@ -350,10 +350,13 @@ 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
<para>Since existing <code>std::pair</code> implementations don't support
<code>std::piecewise_construct</code> this emulates it,
but using <code>boost::unordered::piecewise_construct</code>.
</para>
but using <code>boost::unordered::piecewise_construct</code>.</para>
<para>In version of Boost before 1.48 this emulated the variadic pair
constructor from older C++0x drafts. For backwards compatability
this can be enabled by defining the macro
<code>BOOST_UNORDERED_DEPRECATED_PAIR_CONSTRUCT</code>.
</notes>
</method>
<method name="emplace_hint">
@ -385,9 +388,13 @@ 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
<para>Since existing <code>std::pair</code> implementations don't support
<code>std::piecewise_construct</code> this emulates it,
but using <code>boost::unordered::piecewise_construct</code>.
<para>In version of Boost before 1.48 this emulated the variadic pair
constructor from older C++0x drafts. For backwards compatability
this can be enabled by defining the macro
<code>BOOST_UNORDERED_DEPRECATED_PAIR_CONSTRUCT</code>.
</para>
</notes>
</method>
@ -574,13 +581,19 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<paramtype>unordered_set&amp;</paramtype>
</parameter>
<type>void</type>
<description>
<para>Swaps the contents of the container with the parameter.</para>
<para>If <code>Allocator::propagate_on_container_swap</code> is declared and
<code>Allocator::propagate_on_container_swap::value</code> is true then the
containers' allocators are swapped. Otherwise, swapping with unequal allocators
results in undefined behavior.</para>
</description>
<throws>
<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>
<para>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>
<para>The exception specifications aren't quite the same as the C++11 standard, as
the equality predieate and hash function are swapped using their copy constructors.</para>
</notes>
</method>
</method-group>
@ -841,9 +854,19 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<paramtype>unordered_set&lt;Value, Hash, Pred, Alloc&gt; const&amp;</paramtype>
</parameter>
<type>bool</type>
<description>
<para>Return <code>true</code> if <code>x.size() ==
y.size</code> and for every element in <code>x</code>,
there is an element in <code>y</code> with the same
for the same key, with an equal value (using
<code>operator==</code> to compare the value types).
</para>
</description>
<notes>
<para><emphasis>TODO</emphasis>: Documentation outdated.</para>
<para>This is a boost extension.</para>
<para>The behavior of this function was changed to match
the C++11 standard in Boost 1.48. If you wish to use
the old behaviour, define the macro
<code>BOOST_UNORDERED_DEPRECATED_EQUALITY</code>.</para>
<para>Behavior is undefined if the two containers don't have
equivalent equality predicates.</para>
</notes>
@ -866,9 +889,19 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<paramtype>unordered_set&lt;Value, Hash, Pred, Alloc&gt; const&amp;</paramtype>
</parameter>
<type>bool</type>
<description>
<para>Return <code>false</code> if <code>x.size() ==
y.size</code> and for every element in <code>x</code>,
there is an element in <code>y</code> with the same
for the same key, with an equal value (using
<code>operator==</code> to compare the value types).
</para>
</description>
<notes>
<para><emphasis>TODO</emphasis>: Documentation outdated.</para>
<para>This is a boost extension.</para>
<para>The behavior of this function was changed to match
the C++11 standard in Boost 1.48. If you wish to use
the old behaviour, define the macro
<code>BOOST_UNORDERED_DEPRECATED_EQUALITY</code>.</para>
<para>Behavior is undefined if the two containers don't have
equivalent equality predicates.</para>
</notes>
@ -896,13 +929,19 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<effects>
<para><code>x.swap(y)</code></para>
</effects>
<description>
<para>Swaps the contents of <code>x</code> and <code>y</code>.</para>
<para>If <code>Allocator::propagate_on_container_swap</code> is declared and
<code>Allocator::propagate_on_container_swap::value</code> is true then the
containers' allocators are swapped. Otherwise, swapping with unequal allocators
results in undefined behavior.</para>
</description>
<throws>
<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>
<para>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>
<para>The exception specifications aren't quite the same as the C++11 standard, as
the equality predieate and hash function are swapped using their copy constructors.</para>
</notes>
</function>
</free-function-group>
@ -1251,10 +1290,13 @@ 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
<para>Since existing <code>std::pair</code> implementations don't support
<code>std::piecewise_construct</code> this emulates it,
but using <code>boost::unordered::piecewise_construct</code>.
</para>
but using <code>boost::unordered::piecewise_construct</code>.</para>
<para>In version of Boost before 1.48 this emulated the variadic pair
constructor from older C++0x drafts. For backwards compatability
this can be enabled by defining the macro
<code>BOOST_UNORDERED_DEPRECATED_PAIR_CONSTRUCT</code>.
</notes>
</method>
<method name="emplace_hint">
@ -1286,9 +1328,13 @@ 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
<para>Since existing <code>std::pair</code> implementations don't support
<code>std::piecewise_construct</code> this emulates it,
but using <code>boost::unordered::piecewise_construct</code>.
<para>In version of Boost before 1.48 this emulated the variadic pair
constructor from older C++0x drafts. For backwards compatability
this can be enabled by defining the macro
<code>BOOST_UNORDERED_DEPRECATED_PAIR_CONSTRUCT</code>.
</para>
</notes>
</method>
@ -1474,13 +1520,19 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<paramtype>unordered_multiset&amp;</paramtype>
</parameter>
<type>void</type>
<description>
<para>Swaps the contents of the container with the parameter.</para>
<para>If <code>Allocator::propagate_on_container_swap</code> is declared and
<code>Allocator::propagate_on_container_swap::value</code> is true then the
containers' allocators are swapped. Otherwise, swapping with unequal allocators
results in undefined behavior.</para>
</description>
<throws>
<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>
<para>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>
<para>The exception specifications aren't quite the same as the C++11 standard, as
the equality predieate and hash function are swapped using their copy constructors.</para>
</notes>
</method>
</method-group>
@ -1741,9 +1793,19 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<paramtype>unordered_multiset&lt;Value, Hash, Pred, Alloc&gt; const&amp;</paramtype>
</parameter>
<type>bool</type>
<description>
<para>Return <code>true</code> if <code>x.size() ==
y.size</code> and for every equivalent key group in
<code>x</code>, there is a group in <code>y</code>
for the same key, which is a permutation (using
<code>operator==</code> to compare the value types).
</para>
</description>
<notes>
<para><emphasis>TODO</emphasis>: Documentation outdated.</para>
<para>This is a boost extension.</para>
<para>The behavior of this function was changed to match
the C++11 standard in Boost 1.48. If you wish to use
the old behaviour, define the macro
<code>BOOST_UNORDERED_DEPRECATED_EQUALITY</code>.</para>
<para>Behavior is undefined if the two containers don't have
equivalent equality predicates.</para>
</notes>
@ -1766,9 +1828,19 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<paramtype>unordered_multiset&lt;Value, Hash, Pred, Alloc&gt; const&amp;</paramtype>
</parameter>
<type>bool</type>
<description>
<para>Return <code>false</code> if <code>x.size() ==
y.size</code> and for every equivalent key group in
<code>x</code>, there is a group in <code>y</code>
for the same key, which is a permutation (using
<code>operator==</code> to compare the value types).
</para>
</description>
<notes>
<para><emphasis>TODO</emphasis>: Documentation outdated.</para>
<para>This is a boost extension.</para>
<para>The behavior of this function was changed to match
the C++11 standard in Boost 1.48. If you wish to use
the old behaviour, define the macro
<code>BOOST_UNORDERED_DEPRECATED_EQUALITY</code>.</para>
<para>Behavior is undefined if the two containers don't have
equivalent equality predicates.</para>
</notes>
@ -1796,13 +1868,19 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<effects>
<para><code>x.swap(y)</code></para>
</effects>
<description>
<para>Swaps the contents of <code>x</code> and <code>y</code>.</para>
<para>If <code>Allocator::propagate_on_container_swap</code> is declared and
<code>Allocator::propagate_on_container_swap::value</code> is true then the
containers' allocators are swapped. Otherwise, swapping with unequal allocators
results in undefined behavior.</para>
</description>
<throws>
<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>
<para>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>
<para>The exception specifications aren't quite the same as the C++11 standard, as
the equality predieate and hash function are swapped using their copy constructors.</para>
</notes>
</function>
</free-function-group>
@ -2164,10 +2242,13 @@ 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
<para>Since existing <code>std::pair</code> implementations don't support
<code>std::piecewise_construct</code> this emulates it,
but using <code>boost::unordered::piecewise_construct</code>.
</para>
but using <code>boost::unordered::piecewise_construct</code>.</para>
<para>In version of Boost before 1.48 this emulated the variadic pair
constructor from older C++0x drafts. For backwards compatability
this can be enabled by defining the macro
<code>BOOST_UNORDERED_DEPRECATED_PAIR_CONSTRUCT</code>.
</notes>
</method>
<method name="emplace_hint">
@ -2199,9 +2280,13 @@ 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
<para>Since existing <code>std::pair</code> implementations don't support
<code>std::piecewise_construct</code> this emulates it,
but using <code>boost::unordered::piecewise_construct</code>.
<para>In version of Boost before 1.48 this emulated the variadic pair
constructor from older C++0x drafts. For backwards compatability
this can be enabled by defining the macro
<code>BOOST_UNORDERED_DEPRECATED_PAIR_CONSTRUCT</code>.
</para>
</notes>
</method>
@ -2388,13 +2473,19 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<paramtype>unordered_map&amp;</paramtype>
</parameter>
<type>void</type>
<description>
<para>Swaps the contents of the container with the parameter.</para>
<para>If <code>Allocator::propagate_on_container_swap</code> is declared and
<code>Allocator::propagate_on_container_swap::value</code> is true then the
containers' allocators are swapped. Otherwise, swapping with unequal allocators
results in undefined behavior.</para>
</description>
<throws>
<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>
<para>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>
<para>The exception specifications aren't quite the same as the C++11 standard, as
the equality predieate and hash function are swapped using their copy constructors.</para>
</notes>
</method>
</method-group>
@ -2692,9 +2783,19 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<paramtype>unordered_map&lt;Key, Mapped, Hash, Pred, Alloc&gt; const&amp;</paramtype>
</parameter>
<type>bool</type>
<description>
<para>Return <code>true</code> if <code>x.size() ==
y.size</code> and for every element in <code>x</code>,
there is an element in <code>y</code> with the same
for the same key, with an equal value (using
<code>operator==</code> to compare the value types).
</para>
</description>
<notes>
<para><emphasis>TODO</emphasis>: Documentation outdated.</para>
<para>This is a boost extension.</para>
<para>The behavior of this function was changed to match
the C++11 standard in Boost 1.48. If you wish to use
the old behaviour, define the macro
<code>BOOST_UNORDERED_DEPRECATED_EQUALITY</code>.</para>
<para>Behavior is undefined if the two containers don't have
equivalent equality predicates.</para>
</notes>
@ -2719,9 +2820,19 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<paramtype>unordered_map&lt;Key, Mapped, Hash, Pred, Alloc&gt; const&amp;</paramtype>
</parameter>
<type>bool</type>
<description>
<para>Return <code>false</code> if <code>x.size() ==
y.size</code> and for every element in <code>x</code>,
there is an element in <code>y</code> with the same
for the same key, with an equal value (using
<code>operator==</code> to compare the value types).
</para>
</description>
<notes>
<para><emphasis>TODO</emphasis>: Documentation outdated.</para>
<para>This is a boost extension.</para>
<para>The behavior of this function was changed to match
the C++11 standard in Boost 1.48. If you wish to use
the old behaviour, define the macro
<code>BOOST_UNORDERED_DEPRECATED_EQUALITY</code>.</para>
<para>Behavior is undefined if the two containers don't have
equivalent equality predicates.</para>
</notes>
@ -2751,13 +2862,19 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<effects>
<para><code>x.swap(y)</code></para>
</effects>
<description>
<para>Swaps the contents of <code>x</code> and <code>y</code>.</para>
<para>If <code>Allocator::propagate_on_container_swap</code> is declared and
<code>Allocator::propagate_on_container_swap::value</code> is true then the
containers' allocators are swapped. Otherwise, swapping with unequal allocators
results in undefined behavior.</para>
</description>
<throws>
<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>
<para>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>
<para>The exception specifications aren't quite the same as the C++11 standard, as
the equality predieate and hash function are swapped using their copy constructors.</para>
</notes>
</function>
</free-function-group>
@ -3114,10 +3231,13 @@ 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
<para>Since existing <code>std::pair</code> implementations don't support
<code>std::piecewise_construct</code> this emulates it,
but using <code>boost::unordered::piecewise_construct</code>.
</para>
but using <code>boost::unordered::piecewise_construct</code>.</para>
<para>In version of Boost before 1.48 this emulated the variadic pair
constructor from older C++0x drafts. For backwards compatability
this can be enabled by defining the macro
<code>BOOST_UNORDERED_DEPRECATED_PAIR_CONSTRUCT</code>.
</notes>
</method>
<method name="emplace_hint">
@ -3149,9 +3269,13 @@ 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
<para>Since existing <code>std::pair</code> implementations don't support
<code>std::piecewise_construct</code> this emulates it,
but using <code>boost::unordered::piecewise_construct</code>.
<para>In version of Boost before 1.48 this emulated the variadic pair
constructor from older C++0x drafts. For backwards compatability
this can be enabled by defining the macro
<code>BOOST_UNORDERED_DEPRECATED_PAIR_CONSTRUCT</code>.
</para>
</notes>
</method>
@ -3337,13 +3461,19 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<paramtype>unordered_multimap&amp;</paramtype>
</parameter>
<type>void</type>
<description>
<para>Swaps the contents of the container with the parameter.</para>
<para>If <code>Allocator::propagate_on_container_swap</code> is declared and
<code>Allocator::propagate_on_container_swap::value</code> is true then the
containers' allocators are swapped. Otherwise, swapping with unequal allocators
results in undefined behavior.</para>
</description>
<throws>
<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>
<para>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>
<para>The exception specifications aren't quite the same as the C++11 standard, as
the equality predieate and hash function are swapped using their copy constructors.</para>
</notes>
</method>
</method-group>
@ -3606,9 +3736,19 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<paramtype>unordered_multimap&lt;Key, Mapped, Hash, Pred, Alloc&gt; const&amp;</paramtype>
</parameter>
<type>bool</type>
<description>
<para>Return <code>true</code> if <code>x.size() ==
y.size</code> and for every equivalent key group in
<code>x</code>, there is a group in <code>y</code>
for the same key, which is a permutation (using
<code>operator==</code> to compare the value types).
</para>
</description>
<notes>
<para><emphasis>TODO</emphasis>: Documentation outdated.</para>
<para>This is a boost extension.</para>
<para>The behavior of this function was changed to match
the C++11 standard in Boost 1.48. If you wish to use
the old behaviour, define the macro
<code>BOOST_UNORDERED_DEPRECATED_EQUALITY</code>.</para>
<para>Behavior is undefined if the two containers don't have
equivalent equality predicates.</para>
</notes>
@ -3633,9 +3773,19 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<paramtype>unordered_multimap&lt;Key, Mapped, Hash, Pred, Alloc&gt; const&amp;</paramtype>
</parameter>
<type>bool</type>
<description>
<para>Return <code>false</code> if <code>x.size() ==
y.size</code> and for every equivalent key group in
<code>x</code>, there is a group in <code>y</code>
for the same key, which is a permutation (using
<code>operator==</code> to compare the value types).
</para>
</description>
<notes>
<para><emphasis>TODO</emphasis>: Documentation outdated.</para>
<para>This is a boost extension.</para>
<para>The behavior of this function was changed to match
the C++11 standard in Boost 1.48. If you wish to use
the old behaviour, define the macro
<code>BOOST_UNORDERED_DEPRECATED_EQUALITY</code>.</para>
<para>Behavior is undefined if the two containers don't have
equivalent equality predicates.</para>
</notes>
@ -3665,13 +3815,19 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<effects>
<para><code>x.swap(y)</code></para>
</effects>
<description>
<para>Swaps the contents of <code>x</code> and <code>y</code>.</para>
<para>If <code>Allocator::propagate_on_container_swap</code> is declared and
<code>Allocator::propagate_on_container_swap::value</code> is true then the
containers' allocators are swapped. Otherwise, swapping with unequal allocators
results in undefined behavior.</para>
</description>
<throws>
<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>
<para>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>
<para>The exception specifications aren't quite the same as the C++11 standard, as
the equality predieate and hash function are swapped using their copy constructors.</para>
</notes>
</function>
</free-function-group>

View File

@ -22,15 +22,6 @@
#include <boost/limits.hpp>
#include <boost/type_traits/add_lvalue_reference.hpp>
#if (defined(BOOST_NO_STD_ALLOCATOR) || defined(BOOST_DINKUMWARE_STDLIB)) \
&& !defined(__BORLANDC__)
# define BOOST_UNORDERED_USE_ALLOCATOR_UTILITIES
#endif
#if defined(BOOST_UNORDERED_USE_ALLOCATOR_UTILITIES)
# include <boost/detail/allocator_utilities.hpp>
#endif
#if BOOST_UNORDERED_USE_ALLOCATOR_TRAITS
# include <memory>
#endif
@ -87,17 +78,12 @@ namespace boost { namespace unordered { namespace detail {
// Rebind allocators. For some problematic libraries, use rebind_to
// from <boost/detail/allocator_utilities.hpp>.
# if defined(BOOST_UNORDERED_USE_ALLOCATOR_UTILITIES)
template <typename Alloc, typename T>
struct rebind_wrap : ::boost::detail::allocator::rebind_to<Alloc, T> {};
# else
template <typename Alloc, typename T>
struct rebind_wrap
{
typedef typename Alloc::BOOST_NESTED_TEMPLATE rebind<T>::other
type;
};
# endif
template <typename T> typename boost::add_lvalue_reference<T>::type make();
struct choice9 { typedef char (&type)[9]; };
@ -474,8 +460,4 @@ namespace boost { namespace unordered { namespace detail {
};
}}}
#if defined(BOOST_UNORDERED_USE_ALLOCATOR_UTILITIES)
# undef BOOST_UNORDERED_USE_ALLOCATOR_UTILITIES
#endif
#endif

View File

@ -541,9 +541,11 @@ UNORDERED_AUTO_TEST(map_emplace_test)
{
boost::unordered_map<int, overloaded_constructor> x;
#if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100))
x.emplace();
BOOST_TEST(x.find(0) != x.end() &&
x.find(0)->second == overloaded_constructor());
#endif
x.emplace(2, 3);
BOOST_TEST(x.find(2) != x.end() &&
@ -569,8 +571,10 @@ UNORDERED_AUTO_TEST(set_emplace_test)
boost::unordered_set<overloaded_constructor> x;
overloaded_constructor check;
#if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100))
x.emplace();
BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check);
#endif
x.clear();
x.emplace(1);

View File

@ -203,6 +203,7 @@ namespace unnecessary_copy_tests
{
reset();
T x;
COPY_COUNT(0); MOVE_COUNT(0);
BOOST_DEDUCED_TYPENAME T::value_type a;
COPY_COUNT(1); MOVE_COUNT(0);
x.emplace(boost::move(a));
@ -237,6 +238,7 @@ namespace unnecessary_copy_tests
// 0 arguments
//
#if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100))
// The container will have to create a copy in order to compare with
// the existing element.
reset();
@ -246,6 +248,7 @@ namespace unnecessary_copy_tests
#else
// source_cost doesn't make much sense here, but it seems to fit.
COPY_COUNT(1); MOVE_COUNT(source_cost);
#endif
#endif
//
@ -322,10 +325,12 @@ namespace unnecessary_copy_tests
// 0 arguments
//
#if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100))
// COPY_COUNT(1) would be okay here.
reset();
x.emplace();
COPY_COUNT(2); MOVE_COUNT(0);
#endif
reset();
x.emplace(boost::unordered::piecewise_construct,