forked from boostorg/unordered
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:
@ -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]]
|
||||
|
||||
[
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
||||
|
@ -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]]
|
||||
|
||||
[
|
||||
|
@ -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]>
|
||||
|
@ -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
|
||||
|
81
doc/ref.php
81
doc/ref.php
@ -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; ?>&</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; ?>&</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>
|
||||
|
324
doc/ref.xml
324
doc/ref.xml
@ -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&</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&</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&</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&</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&</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&</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&</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&</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>
|
||||
|
@ -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]
|
||||
|
@ -19,6 +19,8 @@
|
||||
#include <boost/detail/select_type.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/type_traits/add_lvalue_reference.hpp>
|
||||
|
||||
#if (defined(BOOST_NO_STD_ALLOCATOR) || defined(BOOST_DINKUMWARE_STDLIB)) \
|
||||
&& !defined(__BORLANDC__)
|
||||
@ -76,13 +78,12 @@ namespace boost { namespace unordered { namespace detail {
|
||||
template <typename Alloc, typename T>
|
||||
struct rebind_wrap
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
Alloc::BOOST_NESTED_TEMPLATE rebind<T>::other
|
||||
typedef typename Alloc::BOOST_NESTED_TEMPLATE rebind<T>::other
|
||||
type;
|
||||
};
|
||||
# endif
|
||||
|
||||
template <typename T> T& make();
|
||||
template <typename T> typename boost::add_lvalue_reference<T>::type make();
|
||||
struct choice9 { typedef char (&type)[9]; };
|
||||
struct choice8 : choice9 { typedef char (&type)[8]; };
|
||||
struct choice7 : choice8 { typedef char (&type)[7]; };
|
||||
@ -94,13 +95,14 @@ namespace boost { namespace unordered { namespace detail {
|
||||
struct choice1 : choice2 { typedef char (&type)[1]; };
|
||||
choice1 choose();
|
||||
|
||||
#define BOOST_DEFAULT_TYPE_TMPLT(tname) \
|
||||
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1400
|
||||
|
||||
#define BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(tname) \
|
||||
template <typename Tp, typename Default> \
|
||||
struct default_type_ ## tname { \
|
||||
\
|
||||
template <typename X> \
|
||||
static choice1::type test(choice1, \
|
||||
BOOST_DEDUCED_TYPENAME X::tname* = 0); \
|
||||
static choice1::type test(choice1, typename X::tname* = 0); \
|
||||
\
|
||||
template <typename X> \
|
||||
static choice2::type test(choice2, void* = 0); \
|
||||
@ -109,24 +111,50 @@ namespace boost { namespace unordered { namespace detail {
|
||||
\
|
||||
enum { value = (1 == sizeof(test<Tp>(choose()))) }; \
|
||||
\
|
||||
typedef BOOST_DEDUCED_TYPENAME \
|
||||
boost::detail::if_true<value>:: \
|
||||
typedef typename boost::detail::if_true<value>:: \
|
||||
BOOST_NESTED_TEMPLATE then<Tp, DefaultWrap> \
|
||||
::type::tname type; \
|
||||
}
|
||||
|
||||
#define BOOST_DEFAULT_TYPE(T,tname, arg) \
|
||||
BOOST_DEDUCED_TYPENAME default_type_ ## tname<T, arg>::type
|
||||
#else
|
||||
|
||||
BOOST_DEFAULT_TYPE_TMPLT(pointer);
|
||||
BOOST_DEFAULT_TYPE_TMPLT(const_pointer);
|
||||
BOOST_DEFAULT_TYPE_TMPLT(void_pointer);
|
||||
BOOST_DEFAULT_TYPE_TMPLT(const_void_pointer);
|
||||
BOOST_DEFAULT_TYPE_TMPLT(difference_type);
|
||||
BOOST_DEFAULT_TYPE_TMPLT(size_type);
|
||||
BOOST_DEFAULT_TYPE_TMPLT(propagate_on_container_copy_assignment);
|
||||
BOOST_DEFAULT_TYPE_TMPLT(propagate_on_container_move_assignment);
|
||||
BOOST_DEFAULT_TYPE_TMPLT(propagate_on_container_swap);
|
||||
template <typename T, typename T2>
|
||||
struct sfinae : T2 {};
|
||||
|
||||
#define BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(tname) \
|
||||
template <typename Tp, typename Default> \
|
||||
struct default_type_ ## tname { \
|
||||
\
|
||||
template <typename X> \
|
||||
static typename sfinae<typename X::tname, choice1>::type \
|
||||
test(choice1); \
|
||||
\
|
||||
template <typename X> \
|
||||
static choice2::type test(choice2); \
|
||||
\
|
||||
struct DefaultWrap { typedef Default tname; }; \
|
||||
\
|
||||
enum { value = (1 == sizeof(test<Tp>(choose()))) }; \
|
||||
\
|
||||
typedef typename boost::detail::if_true<value>:: \
|
||||
BOOST_NESTED_TEMPLATE then<Tp, DefaultWrap> \
|
||||
::type::tname type; \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#define BOOST_UNORDERED_DEFAULT_TYPE(T,tname, arg) \
|
||||
typename default_type_ ## tname<T, arg>::type
|
||||
|
||||
BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(pointer);
|
||||
BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(const_pointer);
|
||||
BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(void_pointer);
|
||||
BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(const_void_pointer);
|
||||
BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(difference_type);
|
||||
BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(size_type);
|
||||
BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(propagate_on_container_copy_assignment);
|
||||
BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(propagate_on_container_move_assignment);
|
||||
BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(propagate_on_container_swap);
|
||||
|
||||
#if !defined(BOOST_NO_SFINAE_EXPR) || BOOST_WORKAROUND(BOOST_MSVC, >= 1500)
|
||||
|
||||
@ -146,14 +174,40 @@ namespace boost { namespace unordered { namespace detail {
|
||||
static BOOST_PP_CAT(choice, result)::type test( \
|
||||
BOOST_PP_CAT(choice, count))
|
||||
|
||||
#define BOOST_UNORDERED_HAS_EXPRESSION(name, expression) \
|
||||
struct BOOST_PP_CAT(has_, name) \
|
||||
{ \
|
||||
BOOST_UNORDERED_CHECK_EXPRESSION(1, 1, expression); \
|
||||
BOOST_UNORDERED_DEFAULT_EXPRESSION(2, 2); \
|
||||
\
|
||||
enum { value = sizeof(test<T>(choose())) == sizeof(choice1::type) };\
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct has_select_on_container_copy_construction
|
||||
{
|
||||
BOOST_UNORDERED_CHECK_EXPRESSION(1, 1, make<U const>().select_on_container_copy_construction());
|
||||
BOOST_UNORDERED_DEFAULT_EXPRESSION(2, 2);
|
||||
|
||||
enum { value = sizeof(test<T>(choose())) == sizeof(choice1::type) };
|
||||
};
|
||||
BOOST_UNORDERED_HAS_EXPRESSION(
|
||||
select_on_container_copy_construction,
|
||||
make<U const>().select_on_container_copy_construction()
|
||||
);
|
||||
|
||||
// Only supporting the basic copy constructor for now.
|
||||
|
||||
template <typename T, typename ValueType>
|
||||
BOOST_UNORDERED_HAS_EXPRESSION(
|
||||
construct,
|
||||
make<U>().construct(make<ValueType*>(), make<ValueType const>())
|
||||
);
|
||||
|
||||
template <typename T, typename ValueType>
|
||||
BOOST_UNORDERED_HAS_EXPRESSION(
|
||||
destroy,
|
||||
make<U>().destroy(make<ValueType*>())
|
||||
);
|
||||
|
||||
template <typename T>
|
||||
BOOST_UNORDERED_HAS_EXPRESSION(
|
||||
max_size,
|
||||
make<U const>().max_size()
|
||||
);
|
||||
|
||||
#else
|
||||
|
||||
@ -165,32 +219,43 @@ namespace boost { namespace unordered { namespace detail {
|
||||
\
|
||||
template <BOOST_PP_CAT(check, count) e> \
|
||||
struct BOOST_PP_CAT(test, count) { \
|
||||
typedef void* type; \
|
||||
typedef BOOST_PP_CAT(choice, result) type; \
|
||||
}; \
|
||||
\
|
||||
template <class U> static BOOST_PP_CAT(choice, result)::type \
|
||||
test(BOOST_PP_CAT(choice, count), \
|
||||
typename BOOST_PP_CAT(test, count)< \
|
||||
&U::name>::type = 0)
|
||||
template <class U> static typename \
|
||||
BOOST_PP_CAT(test, count)<&U::name>::type \
|
||||
test(BOOST_PP_CAT(choice, count))
|
||||
|
||||
#define BOOST_UNORDERED_DEFAULT_MEMBER(count, result) \
|
||||
template <class U> static BOOST_PP_CAT(choice, result)::type \
|
||||
test(BOOST_PP_CAT(choice, count), void* = 0)
|
||||
test(BOOST_PP_CAT(choice, count))
|
||||
|
||||
|
||||
template <typename T>
|
||||
struct has_select_on_container_copy_construction
|
||||
{
|
||||
BOOST_UNORDERED_CHECK_MEMBER(1, 1, select_on_container_copy_construction, T (T::*)() const);
|
||||
BOOST_UNORDERED_CHECK_MEMBER(1, 1,
|
||||
select_on_container_copy_construction,
|
||||
T (T::*)() const);
|
||||
BOOST_UNORDERED_DEFAULT_MEMBER(2, 2);
|
||||
|
||||
enum { value = sizeof(test<T>(choose())) == sizeof(choice1::type) };
|
||||
};
|
||||
|
||||
// Detection isn't reliable enough, so just assume that we have these
|
||||
// functions.
|
||||
|
||||
template <typename Alloc, typename value_type>
|
||||
struct has_construct : true_type {};
|
||||
template <typename Alloc, typename value_type>
|
||||
struct has_destroy : true_type {};
|
||||
template <typename Alloc>
|
||||
struct has_max_size : true_type {};
|
||||
|
||||
#endif
|
||||
|
||||
template <typename Alloc>
|
||||
inline BOOST_DEDUCED_TYPENAME boost::enable_if<
|
||||
inline typename boost::enable_if<
|
||||
has_select_on_container_copy_construction<Alloc>, Alloc
|
||||
>::type call_select_on_container_copy_construction(const Alloc& rhs)
|
||||
{
|
||||
@ -198,48 +263,62 @@ namespace boost { namespace unordered { namespace detail {
|
||||
}
|
||||
|
||||
template <typename Alloc>
|
||||
inline BOOST_DEDUCED_TYPENAME boost::disable_if<
|
||||
inline typename boost::disable_if<
|
||||
has_select_on_container_copy_construction<Alloc>, Alloc
|
||||
>::type call_select_on_container_copy_construction(const Alloc& rhs)
|
||||
{
|
||||
return rhs;
|
||||
}
|
||||
|
||||
template <typename SizeType, typename Alloc>
|
||||
SizeType call_max_size(const Alloc& a,
|
||||
typename boost::enable_if<has_max_size<Alloc>, void*>::type = 0)
|
||||
{
|
||||
return a.max_size();
|
||||
}
|
||||
|
||||
template <typename SizeType, typename Alloc>
|
||||
SizeType call_max_size(const Alloc&,
|
||||
typename boost::disable_if<has_max_size<Alloc>, void*>::type = 0)
|
||||
{
|
||||
return std::numeric_limits<SizeType>::max();
|
||||
}
|
||||
|
||||
template <typename Alloc>
|
||||
struct allocator_traits
|
||||
{
|
||||
typedef Alloc allocator_type;
|
||||
typedef typename Alloc::value_type value_type;
|
||||
|
||||
typedef BOOST_DEFAULT_TYPE(Alloc, pointer, value_type*)
|
||||
typedef BOOST_UNORDERED_DEFAULT_TYPE(Alloc, pointer, value_type*)
|
||||
pointer;
|
||||
|
||||
// For now always use the allocator's const_pointer.
|
||||
|
||||
//typedef BOOST_DEFAULT_TYPE(Alloc, const_pointer,
|
||||
// BOOST_DEDUCED_TYPENAME pointer_traits<pointer>::
|
||||
//typedef BOOST_UNORDERED_DEFAULT_TYPE(Alloc, const_pointer,
|
||||
// typename pointer_traits<pointer>::
|
||||
// BOOST_NESTED_TEMPLATE rebind<const value_type>::other)
|
||||
// const_pointer;
|
||||
|
||||
typedef BOOST_DEFAULT_TYPE(Alloc, const_pointer, value_type const*)
|
||||
const_pointer;
|
||||
typedef BOOST_UNORDERED_DEFAULT_TYPE(Alloc, const_pointer,
|
||||
value_type const*) const_pointer;
|
||||
|
||||
// I'm not using void pointers for now.
|
||||
|
||||
//typedef BOOST_DEFAULT_TYPE(Alloc, void_pointer,
|
||||
//typedef BOOST_UNORDERED_DEFAULT_TYPE(Alloc, void_pointer,
|
||||
// BOOST_NESTED_TEMPLATE pointer_traits<pointer>::
|
||||
// BOOST_NESTED_TEMPLATE rebind<void>::other)
|
||||
// void_pointer;
|
||||
|
||||
//typedef BOOST_DEFAULT_TYPE(Alloc, const_void_pointer,
|
||||
// BOOST_DEDUCED_TYPENAME pointer_traits<pointer>::
|
||||
//typedef BOOST_UNORDERED_DEFAULT_TYPE(Alloc, const_void_pointer,
|
||||
// typename pointer_traits<pointer>::
|
||||
// BOOST_NESTED_TEMPLATE rebind<const void>::other)
|
||||
// const_void_pointer;
|
||||
|
||||
typedef BOOST_DEFAULT_TYPE(Alloc, difference_type, std::ptrdiff_t)
|
||||
difference_type;
|
||||
typedef BOOST_UNORDERED_DEFAULT_TYPE(Alloc, difference_type,
|
||||
std::ptrdiff_t) difference_type;
|
||||
|
||||
typedef BOOST_DEFAULT_TYPE(Alloc, size_type, std::size_t)
|
||||
typedef BOOST_UNORDERED_DEFAULT_TYPE(Alloc, size_type, std::size_t)
|
||||
size_type;
|
||||
|
||||
// TODO: rebind_alloc and rebind_traits
|
||||
@ -249,32 +328,49 @@ namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
// I never use this, so I'll just comment it out for now.
|
||||
//
|
||||
//static pointer allocate(Alloc& a, size_type n, const_void_pointer hint)
|
||||
//static pointer allocate(Alloc& a, size_type n,
|
||||
// const_void_pointer hint)
|
||||
// { return DEFAULT_FUNC(allocate, pointer)(a, n, hint); }
|
||||
|
||||
static void deallocate(Alloc& a, pointer p, size_type n)
|
||||
{ a.deallocate(p, n); }
|
||||
|
||||
// Only support the basic copy constructor
|
||||
public:
|
||||
|
||||
// template <typename T, typename... Args>
|
||||
// static void construct(Alloc& a, T* p, Args&&... args) {
|
||||
// DEFAULT_FUNC(construct,void)(a, p, std::forward<Args>(args)...);
|
||||
// }
|
||||
// Only supporting the basic copy constructor for now.
|
||||
|
||||
template <typename T>
|
||||
static void construct(Alloc& a, T* p, T const& x) {
|
||||
static void construct(Alloc& a, T* p, T const& x, typename
|
||||
boost::enable_if<has_construct<Alloc, T>, void*>::type = 0)
|
||||
{
|
||||
a.construct(p, x);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void destroy(Alloc& a, T* p) {
|
||||
// DEFAULT_FUNC(destroy,void)(a, p);
|
||||
static void construct(Alloc&, T* p, T const& x, typename
|
||||
boost::disable_if<has_construct<Alloc, T>, void*>::type = 0)
|
||||
{
|
||||
new ((void*) p) T(x);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void destroy(Alloc& a, T* p, typename
|
||||
boost::enable_if<has_destroy<Alloc, T>, void*>::type = 0)
|
||||
{
|
||||
a.destroy(p);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void destroy(Alloc&, T* p, typename
|
||||
boost::disable_if<has_destroy<Alloc, T>, void*>::type = 0)
|
||||
{
|
||||
p->~T();
|
||||
}
|
||||
|
||||
static size_type max_size(const Alloc& a)
|
||||
{ return a.max_size(); }
|
||||
{
|
||||
return boost::unordered::detail::call_max_size<size_type>(a);
|
||||
}
|
||||
|
||||
// Allocator propagation on construction
|
||||
|
||||
@ -286,13 +382,13 @@ namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
// Allocator propagation on assignment and swap.
|
||||
// Return true if lhs is modified.
|
||||
typedef BOOST_DEFAULT_TYPE(
|
||||
typedef BOOST_UNORDERED_DEFAULT_TYPE(
|
||||
Alloc, propagate_on_container_copy_assignment, false_type)
|
||||
propagate_on_container_copy_assignment;
|
||||
typedef BOOST_DEFAULT_TYPE(
|
||||
typedef BOOST_UNORDERED_DEFAULT_TYPE(
|
||||
Alloc,propagate_on_container_move_assignment, false_type)
|
||||
propagate_on_container_move_assignment;
|
||||
typedef BOOST_DEFAULT_TYPE(
|
||||
typedef BOOST_UNORDERED_DEFAULT_TYPE(
|
||||
Alloc,propagate_on_container_swap,false_type)
|
||||
propagate_on_container_swap;
|
||||
};
|
||||
@ -307,7 +403,7 @@ namespace boost { namespace unordered { namespace detail {
|
||||
template <typename Allocator>
|
||||
struct allocator_array_constructor
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_traits<Allocator>::pointer
|
||||
typedef typename allocator_traits<Allocator>::pointer
|
||||
pointer;
|
||||
|
||||
Allocator& alloc_;
|
||||
|
@ -41,7 +41,7 @@ namespace boost { namespace unordered { namespace detail {
|
||||
public:
|
||||
// Types
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME ::boost::detail::if_true<Unique>::
|
||||
typedef typename ::boost::detail::if_true<Unique>::
|
||||
BOOST_NESTED_TEMPLATE then<
|
||||
::boost::unordered::detail::ungrouped_node<A>,
|
||||
::boost::unordered::detail::grouped_node<A>
|
||||
@ -49,16 +49,15 @@ namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
typedef A value_allocator;
|
||||
typedef ::boost::unordered::detail::bucket<A> bucket;
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_traits<A>::value_type value_type;
|
||||
typedef typename allocator_traits<A>::value_type value_type;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME bucket::bucket_allocator
|
||||
bucket_allocator;
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_traits<bucket_allocator>::pointer bucket_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME bucket::node_ptr node_ptr;
|
||||
typedef typename bucket::bucket_allocator bucket_allocator;
|
||||
typedef typename allocator_traits<bucket_allocator>::pointer bucket_ptr;
|
||||
typedef typename bucket::node_ptr node_ptr;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME rebind_wrap<value_allocator, node>::type
|
||||
typedef typename rebind_wrap<value_allocator, node>::type
|
||||
node_allocator;
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_traits<node_allocator>::pointer real_node_ptr;
|
||||
typedef typename allocator_traits<node_allocator>::pointer real_node_ptr;
|
||||
|
||||
// Members
|
||||
|
||||
@ -423,7 +422,7 @@ namespace boost { namespace unordered { namespace detail {
|
||||
functions& operator=(functions const&);
|
||||
|
||||
typedef compressed_pair<H, P> function_pair;
|
||||
typedef BOOST_DEDUCED_TYPENAME ::boost::aligned_storage<
|
||||
typedef typename ::boost::aligned_storage<
|
||||
sizeof(function_pair),
|
||||
::boost::alignment_of<function_pair>::value>::type aligned_function;
|
||||
|
||||
@ -515,28 +514,130 @@ namespace boost { namespace unordered { namespace detail {
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Node Constructors
|
||||
//
|
||||
// Value Construction
|
||||
|
||||
template <typename T, typename Arg1 = void>
|
||||
struct emulated_pair_constructor
|
||||
{
|
||||
enum { value = false };
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
struct emulated_pair_constructor<std::pair<A, B>, void>
|
||||
{
|
||||
enum { value = true };
|
||||
};
|
||||
|
||||
template <typename A, typename B, typename Value>
|
||||
struct emulated_pair_constructor<std::pair<A, B>, Value>
|
||||
{
|
||||
#define BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(n, namespace_) \
|
||||
template<typename T> \
|
||||
void construct_from_tuple(T* ptr, namespace_::tuple<>) \
|
||||
{ \
|
||||
new ((void*) ptr) T(); \
|
||||
} \
|
||||
\
|
||||
BOOST_PP_REPEAT_FROM_TO(1, n, \
|
||||
BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE_IMPL, namespace_)
|
||||
|
||||
#define BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE_IMPL(z, n, namespace_) \
|
||||
template<typename T BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, typename Arg)>\
|
||||
void construct_from_tuple(T* ptr, \
|
||||
namespace_::tuple<BOOST_PP_ENUM_PARAMS_Z(z, n, Arg)> const& x) \
|
||||
{ \
|
||||
new ((void*) ptr) T( \
|
||||
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_GET_TUPLE_ARG, namespace_) \
|
||||
); \
|
||||
}
|
||||
|
||||
#define BOOST_UNORDERED_GET_TUPLE_ARG(z, n, namespace_) \
|
||||
namespace_::get<n>(x)
|
||||
|
||||
BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, boost)
|
||||
|
||||
#if !defined(BOOST_NO_0X_HDR_TUPLE)
|
||||
BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, std)
|
||||
#elif defined(BOOST_HAS_TR1_TUPLE)
|
||||
BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, std::tr1)
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_UNORDERED_DEPRECATED_PAIR_CONSTRUCT)
|
||||
template <typename A, typename B, typename Arg1>
|
||||
struct emulation1 {
|
||||
static choice1::type check(choice1, std::pair<A, B> const&);
|
||||
static choice2::type check(choice2, A const&);
|
||||
|
||||
enum { value = sizeof(check(choose(), make<Value>())) - 1 };
|
||||
|
||||
enum { value = sizeof(check(choose(), make<Arg1>())) == sizeof(choice2::type) };
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_UNORDERED_DEPRECATED_PAIR_CONSTRUCT)
|
||||
template <typename A, typename B, typename Arg1>
|
||||
struct check3_base {
|
||||
static choice1::type check(choice1, boost::unordered::piecewise_construct_t);
|
||||
static choice2::type check(choice2, A const&);
|
||||
static choice3::type check(choice3, ...);
|
||||
};
|
||||
#else
|
||||
template <typename A, typename B, typename Arg1>
|
||||
struct check3_base {
|
||||
static choice1::type check(choice1, boost::unordered::piecewise_construct_t);
|
||||
static choice3::type check(choice3, ...);
|
||||
};
|
||||
#endif
|
||||
|
||||
template <typename A, typename B, typename Arg1>
|
||||
struct piecewise3 {
|
||||
enum { value =
|
||||
sizeof(check3_base<A,B,Arg1>::check(choose(), make<Arg1>())) ==
|
||||
sizeof(choice1::type) };
|
||||
};
|
||||
|
||||
template <typename A, typename B, typename Arg1>
|
||||
struct emulation3 {
|
||||
enum { value =
|
||||
sizeof(check3_base<A,B,Arg1>::check(choose(), make<Arg1>())) ==
|
||||
sizeof(choice2::type) };
|
||||
};
|
||||
|
||||
template <typename A, typename B, typename Arg1>
|
||||
struct normal3 {
|
||||
enum { value =
|
||||
sizeof(check3_base<A,B,Arg1>::check(choose(), make<Arg1>())) ==
|
||||
sizeof(choice3::type) };
|
||||
};
|
||||
|
||||
template <typename T, typename Arg1>
|
||||
struct pair_construct1 {};
|
||||
template <typename T, typename Arg1>
|
||||
struct normal_construct1 { typedef void type; };
|
||||
|
||||
#if defined(BOOST_UNORDERED_DEPRECATED_PAIR_CONSTRUCT)
|
||||
template <typename A, typename B, typename Arg1>
|
||||
struct pair_construct1<std::pair<A, B>, Arg1>
|
||||
: enable_if<emulation1<A, B, Arg1>, void> {};
|
||||
|
||||
template <typename A, typename B, typename Arg1>
|
||||
struct normal_construct1<std::pair<A, B>, Arg1>
|
||||
: disable_if<emulation1<A, B, Arg1>, void> {};
|
||||
#endif
|
||||
|
||||
template <typename T, typename Arg1>
|
||||
struct piecewise_construct3 {};
|
||||
template <typename A, typename B, typename Arg1>
|
||||
struct piecewise_construct3<std::pair<A, B>, Arg1>
|
||||
: enable_if<piecewise3<A, B, Arg1>, void> {};
|
||||
|
||||
template <typename T, typename Arg1>
|
||||
struct pair_construct3 {};
|
||||
template <typename A, typename B, typename Arg1>
|
||||
struct pair_construct3<std::pair<A, B>, Arg1>
|
||||
: enable_if<emulation3<A, B, Arg1>, void> {};
|
||||
|
||||
template <typename T, typename Arg1>
|
||||
struct normal_construct3 { typedef void type; };
|
||||
template <typename A, typename B, typename Arg1>
|
||||
struct normal_construct3<std::pair<A, B>, Arg1>
|
||||
: enable_if<normal3<A, B, Arg1>, void> {};
|
||||
|
||||
template <typename T>
|
||||
struct pair_construct_n {};
|
||||
template <typename T>
|
||||
struct normal_construct_n { typedef void type; };
|
||||
|
||||
#if defined(BOOST_UNORDERED_DEPRECATED_PAIR_CONSTRUCT)
|
||||
template <typename A, typename B>
|
||||
struct pair_construct_n<std::pair<A, B> > { typedef void type; };
|
||||
template <typename A, typename B>
|
||||
struct normal_construct_n<std::pair<A, B> > {};
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
inline void construct_impl(void* address)
|
||||
@ -544,110 +645,135 @@ namespace boost { namespace unordered { namespace detail {
|
||||
new(address) T();
|
||||
}
|
||||
|
||||
#if defined(BOOST_UNORDERED_STD_FORWARD_MOVE)
|
||||
|
||||
template <class T, class Arg1>
|
||||
inline void construct_impl(
|
||||
typename boost::disable_if<emulated_pair_constructor<T, Arg1>,
|
||||
void*>::type address,
|
||||
Arg1&& a1)
|
||||
inline typename normal_construct1<T, Arg1>::type
|
||||
construct_impl(void* address, BOOST_FWD_REF(Arg1) arg1)
|
||||
{
|
||||
new(address) T(std::forward<Arg1>(a1));
|
||||
new(address) T(
|
||||
boost::forward<Arg1>(arg1)
|
||||
);
|
||||
}
|
||||
|
||||
template <class T, class Arg1>
|
||||
inline void construct_impl(
|
||||
typename boost::enable_if<emulated_pair_constructor<T, Arg1>,
|
||||
void*>::type address,
|
||||
Arg1&& a1)
|
||||
inline typename pair_construct1<T, Arg1>::type
|
||||
construct_impl(void* address, BOOST_FWD_REF(Arg1) arg1)
|
||||
{
|
||||
new(address) T(std::forward<Arg1>(a1), typename T::second_type());
|
||||
}
|
||||
new((void*)(&static_cast<T*>(address)->first))
|
||||
typename T::first_type(
|
||||
boost::forward<Arg1>(arg1));
|
||||
new((void*)(&static_cast<T*>(address)->second))
|
||||
typename T::second_type();
|
||||
}
|
||||
|
||||
template <class T, class Arg1, class Arg2>
|
||||
inline void construct_impl(void* address, Arg1&& a1, Arg2&& a2)
|
||||
inline void construct_impl(void* address, BOOST_FWD_REF(Arg1) arg1,
|
||||
BOOST_FWD_REF(Arg2) arg2)
|
||||
{
|
||||
new(address) T(std::forward<Arg1>(a1), std::forward<Arg2>(a2));
|
||||
new(address) T(
|
||||
boost::forward<Arg1>(arg1),
|
||||
boost::forward<Arg2>(arg2));
|
||||
}
|
||||
|
||||
template <class T, class Arg1, class Arg2, class... Args>
|
||||
inline typename boost::disable_if<emulated_pair_constructor<T>, void>::type
|
||||
construct_impl(void* address, Arg1&& arg1, Arg2&& arg2, Args&&... args)
|
||||
template <class T, class Arg1, class Arg2, class Arg3>
|
||||
inline typename piecewise_construct3<T, Arg1>::type
|
||||
construct_impl(void* address, BOOST_FWD_REF(Arg1),
|
||||
BOOST_FWD_REF(Arg2) arg2, BOOST_FWD_REF(Arg3) arg3)
|
||||
{
|
||||
new(address) T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2),
|
||||
construct_from_tuple(&static_cast<T*>(address)->first, arg2);
|
||||
construct_from_tuple(&static_cast<T*>(address)->second, arg3);
|
||||
}
|
||||
|
||||
template <class T, class Arg1, class Arg2, class Arg3>
|
||||
inline typename pair_construct3<T, Arg1>::type
|
||||
construct_impl(void* address, BOOST_FWD_REF(Arg1) arg1,
|
||||
BOOST_FWD_REF(Arg2) arg2, BOOST_FWD_REF(Arg3) arg3)
|
||||
{
|
||||
new((void*)(&static_cast<T*>(address)->first))
|
||||
typename T::first_type(
|
||||
boost::forward<Arg1>(arg1));
|
||||
new((void*)(&static_cast<T*>(address)->second))
|
||||
typename T::second_type(
|
||||
boost::forward<Arg2>(arg2),
|
||||
boost::forward<Arg3>(arg3));
|
||||
}
|
||||
|
||||
template <class T, class Arg1, class Arg2, class Arg3>
|
||||
inline typename normal_construct3<T, Arg1>::type
|
||||
construct_impl(void* address, BOOST_FWD_REF(Arg1) arg1,
|
||||
BOOST_FWD_REF(Arg2) arg2, BOOST_FWD_REF(Arg3) arg3)
|
||||
{
|
||||
new(address) T(
|
||||
boost::forward<Arg1>(arg1),
|
||||
boost::forward<Arg2>(arg2),
|
||||
boost::forward<Arg3>(arg3));
|
||||
}
|
||||
|
||||
#if defined(BOOST_UNORDERED_STD_FORWARD_MOVE)
|
||||
|
||||
template <class T, class Arg1, class Arg2, class Arg3, class Arg4, class... Args>
|
||||
inline typename normal_construct_n<T>::type
|
||||
construct_impl(void* address, Arg1&& arg1, Arg2&& arg2, Arg3&& arg3,
|
||||
Arg4&& arg4, Args&&... args)
|
||||
{
|
||||
new(address) T(
|
||||
std::forward<Arg1>(arg1),
|
||||
std::forward<Arg2>(arg2),
|
||||
std::forward<Arg3>(arg3),
|
||||
std::forward<Arg4>(arg4),
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <class T, class Arg1, class Arg2, class... Args>
|
||||
inline typename boost::enable_if<emulated_pair_constructor<T>, void>::type
|
||||
construct_impl(void* address, Arg1&& arg1, Arg2&& arg2, Args&&... args)
|
||||
template <class T, class Arg1, class Arg2, class Arg3, class Arg4, class... Args>
|
||||
inline typename pair_construct_n<T>::type
|
||||
construct_impl(void* address, Arg1&& arg1, Arg2&& arg2, Arg3&& arg3,
|
||||
Arg4&& arg4, Args&&... args)
|
||||
{
|
||||
new(address) T(std::forward<Arg1>(arg1),
|
||||
typename T::second_type(
|
||||
std::forward<Arg2>(arg2), std::forward<Args>(args)...));
|
||||
new((void*)(&static_cast<T*>(address)->first))
|
||||
typename T::first_type(
|
||||
std::forward<Arg1>(arg1));
|
||||
new((void*)(&static_cast<T*>(address)->second))
|
||||
typename T::second_type(
|
||||
std::forward<Arg2>(arg2),
|
||||
std::forward<Arg3>(arg3),
|
||||
std::forward<Arg4>(arg4),
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template <class T, class Arg1>
|
||||
inline BOOST_DEDUCED_TYPENAME boost::disable_if<emulated_pair_constructor<T, Arg1>, void>::type
|
||||
construct_impl(void* address, BOOST_FWD_REF(Arg1) a1)
|
||||
{
|
||||
new(address) T(boost::forward<Arg1>(a1));
|
||||
}
|
||||
|
||||
template <class T, class Arg1>
|
||||
inline BOOST_DEDUCED_TYPENAME boost::enable_if<emulated_pair_constructor<T, Arg1>, void>::type
|
||||
construct_impl(void* address, BOOST_FWD_REF(Arg1) a1)
|
||||
{
|
||||
new(address) T(
|
||||
boost::forward<Arg1>(a1),
|
||||
BOOST_DEDUCED_TYPENAME T::second_type()
|
||||
);
|
||||
}
|
||||
|
||||
template <class T, class Arg1, class Arg2>
|
||||
inline void construct_impl(void* address,
|
||||
BOOST_FWD_REF(Arg1) a1, BOOST_FWD_REF(Arg2) a2)
|
||||
{
|
||||
new(address) T(boost::forward<Arg1>(a1), boost::forward<Arg2>(a2));
|
||||
}
|
||||
|
||||
#define BOOST_UNORDERED_CONSTRUCT_IMPL(z, num_params, _) \
|
||||
template < \
|
||||
class T, \
|
||||
BOOST_UNORDERED_TEMPLATE_ARGS(z, num_params) \
|
||||
> \
|
||||
inline void construct_impl( \
|
||||
BOOST_DEDUCED_TYPENAME \
|
||||
boost::disable_if<emulated_pair_constructor<T>, void*>::type \
|
||||
address, \
|
||||
BOOST_UNORDERED_FUNCTION_PARAMS(z, num_params) \
|
||||
) \
|
||||
inline typename normal_construct_n<T>::type \
|
||||
construct_impl(void* address, \
|
||||
BOOST_UNORDERED_FUNCTION_PARAMS(z, num_params)) \
|
||||
{ \
|
||||
new(address) T( \
|
||||
BOOST_UNORDERED_CALL_PARAMS(z, num_params)); \
|
||||
}
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(3, BOOST_UNORDERED_EMPLACE_LIMIT,
|
||||
BOOST_PP_REPEAT_FROM_TO(4, BOOST_UNORDERED_EMPLACE_LIMIT,
|
||||
BOOST_UNORDERED_CONSTRUCT_IMPL, _)
|
||||
|
||||
#define BOOST_UNORDERED_CONSTRUCT_PAIR_IMPL(z, num_params, _) \
|
||||
template <class T, class Key, \
|
||||
BOOST_UNORDERED_TEMPLATE_ARGS(z, num_params) \
|
||||
> \
|
||||
inline void construct_impl( \
|
||||
BOOST_DEDUCED_TYPENAME \
|
||||
boost::enable_if<emulated_pair_constructor<T>, void*>::type \
|
||||
address, \
|
||||
Key const& k, BOOST_UNORDERED_FUNCTION_PARAMS(z, num_params)) \
|
||||
inline typename pair_construct_n<T>::type \
|
||||
construct_impl(void* address, BOOST_FWD_REF(Key) key, \
|
||||
BOOST_UNORDERED_FUNCTION_PARAMS(z, num_params)) \
|
||||
{ \
|
||||
new(address) T(k, \
|
||||
BOOST_DEDUCED_TYPENAME \
|
||||
T::second_type(BOOST_UNORDERED_CALL_PARAMS(z, num_params))); \
|
||||
new((void*)(&static_cast<T*>(address)->first)) \
|
||||
typename T::first_type( \
|
||||
boost::forward<Key>(key)); \
|
||||
new((void*)(&static_cast<T*>(address)->second)) \
|
||||
typename T::second_type( \
|
||||
BOOST_UNORDERED_CALL_PARAMS(z, num_params)); \
|
||||
}
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(2, BOOST_UNORDERED_EMPLACE_LIMIT,
|
||||
BOOST_PP_REPEAT_FROM_TO(3, BOOST_UNORDERED_EMPLACE_LIMIT,
|
||||
BOOST_UNORDERED_CONSTRUCT_PAIR_IMPL, _)
|
||||
|
||||
#undef BOOST_UNORDERED_CONSTRUCT_IMPL
|
||||
@ -661,10 +787,10 @@ namespace boost { namespace unordered { namespace detail {
|
||||
class node_constructor
|
||||
{
|
||||
typedef ::boost::unordered::detail::buckets<Alloc, Unique> buckets;
|
||||
typedef BOOST_DEDUCED_TYPENAME buckets::node node;
|
||||
typedef BOOST_DEDUCED_TYPENAME buckets::real_node_ptr real_node_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME buckets::value_type value_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME buckets::node_allocator node_allocator;
|
||||
typedef typename buckets::node node;
|
||||
typedef typename buckets::real_node_ptr real_node_ptr;
|
||||
typedef typename buckets::value_type value_type;
|
||||
typedef typename buckets::node_allocator node_allocator;
|
||||
|
||||
buckets& buckets_;
|
||||
real_node_ptr node_;
|
||||
@ -731,7 +857,7 @@ namespace boost { namespace unordered { namespace detail {
|
||||
}
|
||||
|
||||
// no throw
|
||||
BOOST_DEDUCED_TYPENAME buckets::node_ptr release()
|
||||
typename buckets::node_ptr release()
|
||||
{
|
||||
real_node_ptr p = node_;
|
||||
node_ = real_node_ptr();
|
||||
|
@ -15,19 +15,19 @@ namespace boost { namespace unordered { namespace detail {
|
||||
class equivalent_table : public T::table_base
|
||||
{
|
||||
public:
|
||||
typedef BOOST_DEDUCED_TYPENAME T::hasher hasher;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::key_equal key_equal;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::value_allocator value_allocator;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::key_type key_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::value_type value_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::table_base table_base;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::node_constructor node_constructor;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::node_allocator node_allocator;
|
||||
typedef typename T::hasher hasher;
|
||||
typedef typename T::key_equal key_equal;
|
||||
typedef typename T::value_allocator value_allocator;
|
||||
typedef typename T::key_type key_type;
|
||||
typedef typename T::value_type value_type;
|
||||
typedef typename T::table_base table_base;
|
||||
typedef typename T::node_constructor node_constructor;
|
||||
typedef typename T::node_allocator node_allocator;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME T::node node;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::node_ptr node_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::bucket_ptr bucket_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::extractor extractor;
|
||||
typedef typename T::node node;
|
||||
typedef typename T::node_ptr node_ptr;
|
||||
typedef typename T::bucket_ptr bucket_ptr;
|
||||
typedef typename T::extractor extractor;
|
||||
|
||||
// Constructors
|
||||
|
||||
@ -67,7 +67,9 @@ namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#if !defined(BOOST_UNORDERED_DEPRECATED_EQUALITY)
|
||||
|
||||
static bool group_equals(node_ptr n1, node_ptr end1,
|
||||
node_ptr n2, node_ptr end2)
|
||||
{
|
||||
@ -108,7 +110,28 @@ namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
static bool group_equals(node_ptr n1, node_ptr end1,
|
||||
node_ptr n2, node_ptr end2)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
if(!extractor::compare_mapped(
|
||||
node::get_value(n1), node::get_value(n2)))
|
||||
return false;
|
||||
|
||||
n1 = n1->next_;
|
||||
n2 = n2->next_;
|
||||
|
||||
if (n1 == end1) return n2 == end2;
|
||||
if (n2 == end2) return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static bool find(node_ptr n, node_ptr end, value_type const& v)
|
||||
{
|
||||
for(;n != end; n = n->next_)
|
||||
@ -203,6 +226,14 @@ namespace boost { namespace unordered { namespace detail {
|
||||
this->find_node(bucket_index, hash, k));
|
||||
}
|
||||
|
||||
#if defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
node_ptr emplace(please_ignore_this_overload const&)
|
||||
{
|
||||
BOOST_ASSERT(false);
|
||||
return this->begin();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_UNORDERED_STD_FORWARD_MOVE)
|
||||
|
||||
template <class... Args>
|
||||
@ -273,19 +304,18 @@ namespace boost { namespace unordered { namespace detail {
|
||||
template <class I>
|
||||
void insert_range(I i, I j)
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME ::boost::iterator_traversal<I>::type
|
||||
iterator_traversal_tag;
|
||||
insert_for_range(i, j, iterator_traversal_tag);
|
||||
insert_for_range(i, j,
|
||||
BOOST_DEDUCED_TYPENAME ::boost::iterator_traversal<I>::type());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <class H, class P, class A>
|
||||
struct multiset : public types<
|
||||
BOOST_DEDUCED_TYPENAME allocator_traits<A>::value_type,
|
||||
BOOST_DEDUCED_TYPENAME allocator_traits<A>::value_type,
|
||||
typename allocator_traits<A>::value_type,
|
||||
typename allocator_traits<A>::value_type,
|
||||
H, P, A,
|
||||
set_extractor<BOOST_DEDUCED_TYPENAME allocator_traits<A>::value_type>,
|
||||
set_extractor<typename allocator_traits<A>::value_type>,
|
||||
false>
|
||||
{
|
||||
typedef equivalent_table<multiset<H, P, A> > impl;
|
||||
@ -294,9 +324,9 @@ namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
template <class K, class H, class P, class A>
|
||||
struct multimap : public types<
|
||||
K, BOOST_DEDUCED_TYPENAME allocator_traits<A>::value_type,
|
||||
K, typename allocator_traits<A>::value_type,
|
||||
H, P, A,
|
||||
map_extractor<K, BOOST_DEDUCED_TYPENAME allocator_traits<A>::value_type>,
|
||||
map_extractor<K, typename allocator_traits<A>::value_type>,
|
||||
false>
|
||||
{
|
||||
typedef equivalent_table<multimap<K, H, P, A> > impl;
|
||||
|
@ -27,6 +27,18 @@ namespace detail {
|
||||
template <class T> no_key(T const&) {}
|
||||
};
|
||||
|
||||
template <typename Key, typename T>
|
||||
struct is_key {
|
||||
template <typename T2>
|
||||
static choice1::type test(T2 const&);
|
||||
static choice2::type test(Key const&);
|
||||
|
||||
enum { value = sizeof(test(make<T>())) == sizeof(choice2::type) };
|
||||
|
||||
typedef typename boost::detail::if_true<value>::
|
||||
BOOST_NESTED_TEMPLATE then<Key const&, no_key>::type type;
|
||||
};
|
||||
|
||||
template <class ValueType>
|
||||
struct set_extractor
|
||||
{
|
||||
@ -64,8 +76,8 @@ namespace detail {
|
||||
return no_key();
|
||||
}
|
||||
|
||||
template <class Arg>
|
||||
static no_key extract(Arg const&, Arg const&)
|
||||
template <class Arg1, class Arg2>
|
||||
static no_key extract(Arg1 const&, Arg2 const&)
|
||||
{
|
||||
return no_key();
|
||||
}
|
||||
@ -81,7 +93,7 @@ namespace detail {
|
||||
struct map_extractor
|
||||
{
|
||||
typedef ValueType value_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME ::boost::remove_const<Key>::type key_type;
|
||||
typedef typename ::boost::remove_const<Key>::type key_type;
|
||||
|
||||
static key_type const& extract(value_type const& v)
|
||||
{
|
||||
@ -127,6 +139,7 @@ namespace detail {
|
||||
return no_key();
|
||||
}
|
||||
#else
|
||||
|
||||
template <class Arg1>
|
||||
static key_type const& extract(key_type const& k, Arg1 const&)
|
||||
{
|
||||
@ -151,6 +164,54 @@ namespace detail {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_UNORDERED_STD_FORWARD_MOVE)
|
||||
|
||||
#define BOOST_UNORDERED_KEY_FROM_TUPLE(namespace_) \
|
||||
template <typename T2> \
|
||||
static no_key extract(boost::unordered::piecewise_construct_t, \
|
||||
namespace_::tuple<> const&, T2&&) \
|
||||
{ \
|
||||
return no_key(); \
|
||||
} \
|
||||
\
|
||||
template <typename T, typename T2> \
|
||||
static typename is_key<key_type, T>::type \
|
||||
extract(boost::unordered::piecewise_construct_t, \
|
||||
namespace_::tuple<T> const& k, T2&&) \
|
||||
{ \
|
||||
return typename is_key<key_type, T>::type( \
|
||||
namespace_::get<0>(k)); \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_UNORDERED_KEY_FROM_TUPLE(namespace_) \
|
||||
static no_key extract(boost::unordered::piecewise_construct_t, \
|
||||
namespace_::tuple<> const&) \
|
||||
{ \
|
||||
return no_key(); \
|
||||
} \
|
||||
\
|
||||
template <typename T> \
|
||||
static typename is_key<key_type, T>::type \
|
||||
extract(boost::unordered::piecewise_construct_t, \
|
||||
namespace_::tuple<T> const& k) \
|
||||
{ \
|
||||
return typename is_key<key_type, T>::type( \
|
||||
namespace_::get<0>(k)); \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
BOOST_UNORDERED_KEY_FROM_TUPLE(boost)
|
||||
|
||||
#if !defined(BOOST_NO_0X_HDR_TUPLE)
|
||||
BOOST_UNORDERED_KEY_FROM_TUPLE(std)
|
||||
#elif defined(BOOST_HAS_TR1_TUPLE)
|
||||
BOOST_UNORDERED_KEY_FROM_TUPLE(std::tr1)
|
||||
#endif
|
||||
|
||||
|
||||
static bool compare_mapped(value_type const& x, value_type const& y)
|
||||
{
|
||||
return x.second == y.second;
|
||||
|
@ -44,6 +44,9 @@ namespace unordered
|
||||
class P = std::equal_to<T>,
|
||||
class A = std::allocator<T> >
|
||||
class unordered_multiset;
|
||||
|
||||
struct piecewise_construct_t {};
|
||||
const piecewise_construct_t piecewise_construct = piecewise_construct_t();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,11 +59,9 @@ namespace boost { namespace unordered { namespace detail {
|
||||
{
|
||||
bucket& operator=(bucket const&);
|
||||
public:
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
::boost::unordered::detail::rebind_wrap<A, bucket>::type
|
||||
typedef typename ::boost::unordered::detail::rebind_wrap<A, bucket>::type
|
||||
bucket_allocator;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
allocator_traits<bucket_allocator>::pointer bucket_ptr;
|
||||
typedef typename allocator_traits<bucket_allocator>::pointer bucket_ptr;
|
||||
typedef bucket_ptr node_ptr;
|
||||
|
||||
node_ptr next_;
|
||||
@ -77,7 +75,7 @@ namespace boost { namespace unordered { namespace detail {
|
||||
struct value_base
|
||||
{
|
||||
typedef ValueType value_type;
|
||||
BOOST_DEDUCED_TYPENAME ::boost::aligned_storage<
|
||||
typename ::boost::aligned_storage<
|
||||
sizeof(value_type),
|
||||
::boost::alignment_of<value_type>::value>::type data_;
|
||||
|
||||
@ -107,12 +105,12 @@ namespace boost { namespace unordered { namespace detail {
|
||||
template <class A>
|
||||
struct ungrouped_node
|
||||
: ::boost::unordered::detail::bucket<A>,
|
||||
value_base<BOOST_DEDUCED_TYPENAME allocator_traits<A>::value_type>
|
||||
value_base<typename allocator_traits<A>::value_type>
|
||||
{
|
||||
typedef ::boost::unordered::detail::bucket<A> bucket;
|
||||
typedef BOOST_DEDUCED_TYPENAME bucket::bucket_ptr bucket_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME bucket::node_ptr node_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_traits<A>::value_type value_type;
|
||||
typedef typename bucket::bucket_ptr bucket_ptr;
|
||||
typedef typename bucket::node_ptr node_ptr;
|
||||
typedef typename allocator_traits<A>::value_type value_type;
|
||||
|
||||
std::size_t hash_;
|
||||
|
||||
@ -182,12 +180,12 @@ namespace boost { namespace unordered { namespace detail {
|
||||
template <class A>
|
||||
struct grouped_node
|
||||
: ::boost::unordered::detail::bucket<A>,
|
||||
value_base<BOOST_DEDUCED_TYPENAME allocator_traits<A>::value_type>
|
||||
value_base<typename allocator_traits<A>::value_type>
|
||||
{
|
||||
typedef ::boost::unordered::detail::bucket<A> bucket;
|
||||
typedef BOOST_DEDUCED_TYPENAME bucket::bucket_ptr bucket_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME bucket::node_ptr node_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_traits<A>::value_type value_type;
|
||||
typedef typename bucket::bucket_ptr bucket_ptr;
|
||||
typedef typename bucket::node_ptr node_ptr;
|
||||
typedef typename allocator_traits<A>::value_type value_type;
|
||||
|
||||
std::size_t hash_;
|
||||
node_ptr group_prev_;
|
||||
|
@ -23,22 +23,22 @@ namespace boost { namespace unordered { namespace detail {
|
||||
table(table const&);
|
||||
table& operator=(table const&);
|
||||
public:
|
||||
typedef BOOST_DEDUCED_TYPENAME T::hasher hasher;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::key_equal key_equal;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::value_allocator value_allocator;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::key_type key_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::value_type value_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::functions functions;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::buckets buckets;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::extractor extractor;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::node_constructor node_constructor;
|
||||
typedef typename T::hasher hasher;
|
||||
typedef typename T::key_equal key_equal;
|
||||
typedef typename T::value_allocator value_allocator;
|
||||
typedef typename T::key_type key_type;
|
||||
typedef typename T::value_type value_type;
|
||||
typedef typename T::functions functions;
|
||||
typedef typename T::buckets buckets;
|
||||
typedef typename T::extractor extractor;
|
||||
typedef typename T::node_constructor node_constructor;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME T::node node;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::bucket bucket;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::node_ptr node_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::bucket_ptr bucket_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::node_allocator node_allocator;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::iterator_pair iterator_pair;
|
||||
typedef typename T::node node;
|
||||
typedef typename T::bucket bucket;
|
||||
typedef typename T::node_ptr node_ptr;
|
||||
typedef typename T::bucket_ptr bucket_ptr;
|
||||
typedef typename T::node_allocator node_allocator;
|
||||
typedef typename T::iterator_pair iterator_pair;
|
||||
|
||||
// Members
|
||||
|
||||
@ -485,11 +485,11 @@ namespace boost { namespace unordered { namespace detail {
|
||||
typedef ::boost::unordered::detail::buckets<value_allocator, Unique> buckets;
|
||||
typedef ::boost::unordered::detail::functions<hasher, key_equal> functions;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME buckets::node node;
|
||||
typedef BOOST_DEDUCED_TYPENAME buckets::bucket bucket;
|
||||
typedef BOOST_DEDUCED_TYPENAME buckets::node_ptr node_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME buckets::bucket_ptr bucket_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME buckets::node_allocator node_allocator;
|
||||
typedef typename buckets::node node;
|
||||
typedef typename buckets::bucket bucket;
|
||||
typedef typename buckets::node_ptr node_ptr;
|
||||
typedef typename buckets::bucket_ptr bucket_ptr;
|
||||
typedef typename buckets::node_allocator node_allocator;
|
||||
|
||||
typedef std::pair<node_ptr, node_ptr> iterator_pair;
|
||||
};
|
||||
@ -514,18 +514,18 @@ namespace boost { namespace unordered { namespace iterator_detail {
|
||||
class l_iterator
|
||||
: public ::boost::iterator <
|
||||
std::forward_iterator_tag,
|
||||
BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::value_type,
|
||||
typename boost::unordered::detail::allocator_traits<A>::value_type,
|
||||
std::ptrdiff_t,
|
||||
BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::pointer,
|
||||
BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::value_type&>
|
||||
typename boost::unordered::detail::allocator_traits<A>::pointer,
|
||||
typename boost::unordered::detail::allocator_traits<A>::value_type&>
|
||||
{
|
||||
public:
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::value_type value_type;
|
||||
typedef typename boost::unordered::detail::allocator_traits<A>::value_type value_type;
|
||||
|
||||
private:
|
||||
typedef ::boost::unordered::detail::buckets<A, Unique> buckets;
|
||||
typedef BOOST_DEDUCED_TYPENAME buckets::node_ptr node_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME buckets::node node;
|
||||
typedef typename buckets::node_ptr node_ptr;
|
||||
typedef typename buckets::node node;
|
||||
typedef cl_iterator<A, Unique> const_local_iterator;
|
||||
|
||||
friend class cl_iterator<A, Unique>;
|
||||
@ -538,7 +538,7 @@ namespace boost { namespace unordered { namespace iterator_detail {
|
||||
l_iterator() : ptr_() {}
|
||||
l_iterator(node_ptr x, std::size_t b, std::size_t c)
|
||||
: ptr_(x), bucket_(b), bucket_count_(c) {}
|
||||
BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::value_type& operator*() const {
|
||||
typename boost::unordered::detail::allocator_traits<A>::value_type& operator*() const {
|
||||
return node::get_value(ptr_);
|
||||
}
|
||||
value_type* operator->() const {
|
||||
@ -575,18 +575,18 @@ namespace boost { namespace unordered { namespace iterator_detail {
|
||||
class cl_iterator
|
||||
: public ::boost::iterator <
|
||||
std::forward_iterator_tag,
|
||||
BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::value_type,
|
||||
typename boost::unordered::detail::allocator_traits<A>::value_type,
|
||||
std::ptrdiff_t,
|
||||
BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::const_pointer,
|
||||
BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::value_type const& >
|
||||
typename boost::unordered::detail::allocator_traits<A>::const_pointer,
|
||||
typename boost::unordered::detail::allocator_traits<A>::value_type const& >
|
||||
{
|
||||
public:
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::value_type value_type;
|
||||
typedef typename boost::unordered::detail::allocator_traits<A>::value_type value_type;
|
||||
|
||||
private:
|
||||
typedef ::boost::unordered::detail::buckets<A, Unique> buckets;
|
||||
typedef BOOST_DEDUCED_TYPENAME buckets::node_ptr node_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME buckets::node node;
|
||||
typedef typename buckets::node_ptr node_ptr;
|
||||
typedef typename buckets::node node;
|
||||
typedef l_iterator<A, Unique> local_iterator;
|
||||
|
||||
friend class l_iterator<A, Unique>;
|
||||
@ -602,7 +602,7 @@ namespace boost { namespace unordered { namespace iterator_detail {
|
||||
cl_iterator(local_iterator x)
|
||||
: ptr_(x.ptr_), bucket_(x.bucket_), bucket_count_(x.bucket_count_)
|
||||
{}
|
||||
BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::value_type const&
|
||||
typename boost::unordered::detail::allocator_traits<A>::value_type const&
|
||||
operator*() const {
|
||||
return node::get_value(ptr_);
|
||||
}
|
||||
@ -640,18 +640,18 @@ namespace boost { namespace unordered { namespace iterator_detail {
|
||||
class iterator
|
||||
: public ::boost::iterator <
|
||||
std::forward_iterator_tag,
|
||||
BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::value_type,
|
||||
typename boost::unordered::detail::allocator_traits<A>::value_type,
|
||||
std::ptrdiff_t,
|
||||
BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::pointer,
|
||||
BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::value_type& >
|
||||
typename boost::unordered::detail::allocator_traits<A>::pointer,
|
||||
typename boost::unordered::detail::allocator_traits<A>::value_type& >
|
||||
{
|
||||
public:
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::value_type value_type;
|
||||
typedef typename boost::unordered::detail::allocator_traits<A>::value_type value_type;
|
||||
|
||||
private:
|
||||
typedef ::boost::unordered::detail::buckets<A, Unique> buckets;
|
||||
typedef BOOST_DEDUCED_TYPENAME buckets::node node;
|
||||
typedef BOOST_DEDUCED_TYPENAME buckets::node_ptr node_ptr;
|
||||
typedef typename buckets::node node;
|
||||
typedef typename buckets::node_ptr node_ptr;
|
||||
typedef c_iterator<A, Unique> const_iterator;
|
||||
friend class c_iterator<A, Unique>;
|
||||
node_ptr node_;
|
||||
@ -660,7 +660,7 @@ namespace boost { namespace unordered { namespace iterator_detail {
|
||||
|
||||
iterator() : node_() {}
|
||||
explicit iterator(node_ptr const& x) : node_(x) {}
|
||||
BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::value_type& operator*() const {
|
||||
typename boost::unordered::detail::allocator_traits<A>::value_type& operator*() const {
|
||||
return node::get_value(node_);
|
||||
}
|
||||
value_type* operator->() const {
|
||||
@ -690,18 +690,18 @@ namespace boost { namespace unordered { namespace iterator_detail {
|
||||
class c_iterator
|
||||
: public ::boost::iterator <
|
||||
std::forward_iterator_tag,
|
||||
BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::value_type,
|
||||
typename boost::unordered::detail::allocator_traits<A>::value_type,
|
||||
std::ptrdiff_t,
|
||||
BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::const_pointer,
|
||||
BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::value_type const& >
|
||||
typename boost::unordered::detail::allocator_traits<A>::const_pointer,
|
||||
typename boost::unordered::detail::allocator_traits<A>::value_type const& >
|
||||
{
|
||||
public:
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::value_type value_type;
|
||||
typedef typename boost::unordered::detail::allocator_traits<A>::value_type value_type;
|
||||
|
||||
private:
|
||||
typedef ::boost::unordered::detail::buckets<A, Unique> buckets;
|
||||
typedef BOOST_DEDUCED_TYPENAME buckets::node node;
|
||||
typedef BOOST_DEDUCED_TYPENAME buckets::node_ptr node_ptr;
|
||||
typedef typename buckets::node node;
|
||||
typedef typename buckets::node_ptr node_ptr;
|
||||
typedef ::boost::unordered::iterator_detail::iterator<A, Unique>
|
||||
iterator;
|
||||
friend class ::boost::unordered::iterator_detail::iterator<A, Unique>;
|
||||
@ -726,7 +726,7 @@ namespace boost { namespace unordered { namespace iterator_detail {
|
||||
c_iterator() : node_() {}
|
||||
explicit c_iterator(node_ptr const& x) : node_(x) {}
|
||||
c_iterator(iterator const& x) : node_(x.node_) {}
|
||||
BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::value_type const& operator*() const {
|
||||
typename boost::unordered::detail::allocator_traits<A>::value_type const& operator*() const {
|
||||
return node::get_value(node_);
|
||||
}
|
||||
value_type const* operator->() const {
|
||||
|
@ -15,19 +15,19 @@ namespace boost { namespace unordered { namespace detail {
|
||||
class unique_table : public T::table_base
|
||||
{
|
||||
public:
|
||||
typedef BOOST_DEDUCED_TYPENAME T::hasher hasher;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::key_equal key_equal;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::value_allocator value_allocator;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::key_type key_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::value_type value_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::table_base table_base;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::node_constructor node_constructor;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::node_allocator node_allocator;
|
||||
typedef typename T::hasher hasher;
|
||||
typedef typename T::key_equal key_equal;
|
||||
typedef typename T::value_allocator value_allocator;
|
||||
typedef typename T::key_type key_type;
|
||||
typedef typename T::value_type value_type;
|
||||
typedef typename T::table_base table_base;
|
||||
typedef typename T::node_constructor node_constructor;
|
||||
typedef typename T::node_allocator node_allocator;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME T::node node;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::node_ptr node_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::bucket_ptr bucket_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::extractor extractor;
|
||||
typedef typename T::node node;
|
||||
typedef typename T::node_ptr node_ptr;
|
||||
typedef typename T::bucket_ptr bucket_ptr;
|
||||
typedef typename T::extractor extractor;
|
||||
|
||||
typedef std::pair<node_ptr, bool> emplace_return;
|
||||
|
||||
@ -60,8 +60,15 @@ namespace boost { namespace unordered { namespace detail {
|
||||
n1; n1 = n1->next_)
|
||||
{
|
||||
node_ptr n2 = other.find_matching_node(n1);
|
||||
|
||||
#if !defined(BOOST_UNORDERED_DEPRECATED_EQUALITY)
|
||||
if(!n2 || node::get_value(n1) != node::get_value(n2))
|
||||
return false;
|
||||
#else
|
||||
if(!n2 || !extractor::compare_mapped(
|
||||
node::get_value(n1), node::get_value(n2)))
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -111,7 +118,7 @@ namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
value_type& operator[](key_type const& k)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME value_type::second_type mapped_type;
|
||||
typedef typename value_type::second_type mapped_type;
|
||||
|
||||
std::size_t hash = this->hash_function()(k);
|
||||
std::size_t bucket_index = hash % this->bucket_count_;
|
||||
@ -189,6 +196,14 @@ namespace boost { namespace unordered { namespace detail {
|
||||
}
|
||||
|
||||
|
||||
#if defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
emplace_return emplace(please_ignore_this_overload const&)
|
||||
{
|
||||
BOOST_ASSERT(false);
|
||||
return emplace_return(this->begin(), false);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_UNORDERED_STD_FORWARD_MOVE)
|
||||
|
||||
template<class... Args>
|
||||
@ -392,10 +407,10 @@ namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
template <class H, class P, class A>
|
||||
struct set : public types<
|
||||
BOOST_DEDUCED_TYPENAME allocator_traits<A>::value_type,
|
||||
BOOST_DEDUCED_TYPENAME allocator_traits<A>::value_type,
|
||||
typename allocator_traits<A>::value_type,
|
||||
typename allocator_traits<A>::value_type,
|
||||
H, P, A,
|
||||
set_extractor<BOOST_DEDUCED_TYPENAME allocator_traits<A>::value_type>,
|
||||
set_extractor<typename allocator_traits<A>::value_type>,
|
||||
true>
|
||||
{
|
||||
typedef ::boost::unordered::detail::unique_table<set<H, P, A> > impl;
|
||||
@ -404,9 +419,9 @@ namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
template <class K, class H, class P, class A>
|
||||
struct map : public types<
|
||||
K, BOOST_DEDUCED_TYPENAME allocator_traits<A>::value_type,
|
||||
K, typename allocator_traits<A>::value_type,
|
||||
H, P, A,
|
||||
map_extractor<K, BOOST_DEDUCED_TYPENAME allocator_traits<A>::value_type>,
|
||||
map_extractor<K, typename allocator_traits<A>::value_type>,
|
||||
true>
|
||||
{
|
||||
typedef ::boost::unordered::detail::unique_table<map<K, H, P, A> > impl;
|
||||
|
@ -23,13 +23,23 @@
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/type_traits/is_empty.hpp>
|
||||
#if defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
#include <boost/type_traits/is_class.hpp>
|
||||
#endif
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/unordered/detail/allocator_helpers.hpp>
|
||||
#include <boost/preprocessor/seq/size.hpp>
|
||||
#include <boost/preprocessor/seq/enum.hpp>
|
||||
#include <boost/preprocessor/repetition/enum.hpp>
|
||||
#include <boost/move/move.hpp>
|
||||
#include <boost/swap.hpp>
|
||||
#include <boost/preprocessor/seq/size.hpp>
|
||||
#include <boost/preprocessor/seq/enum.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
|
||||
#include <boost/preprocessor/repetition/enum.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#if !defined(BOOST_NO_0X_HDR_TUPLE) || defined(BOOST_HAS_TR1_TUPLE)
|
||||
#include <tuple>
|
||||
#endif
|
||||
#include <boost/unordered/detail/allocator_helpers.hpp>
|
||||
|
||||
// Template parameters:
|
||||
//
|
||||
@ -121,6 +131,36 @@ namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
|
||||
#define BOOST_UNORDERED_RV_REF(T) BOOST_RV_REF(T)
|
||||
|
||||
#else
|
||||
|
||||
struct please_ignore_this_overload {
|
||||
typedef please_ignore_this_overload type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct rv_ref_impl {
|
||||
typedef BOOST_RV_REF(T) type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct rv_ref :
|
||||
boost::detail::if_true<
|
||||
boost::is_class<T>::value
|
||||
>::BOOST_NESTED_TEMPLATE then <
|
||||
rv_ref_impl<T>,
|
||||
please_ignore_this_overload
|
||||
>::type
|
||||
{};
|
||||
|
||||
#define BOOST_UNORDERED_RV_REF(T) \
|
||||
typename ::boost::unordered::detail::rv_ref<T>::type
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
@ -197,22 +237,6 @@ namespace boost { namespace unordered { namespace detail {
|
||||
return *bound;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// pair_cast - because some libraries don't have the full pair constructors.
|
||||
|
||||
#if 0
|
||||
template <class Dst1, class Dst2, class Src1, class Src2>
|
||||
inline std::pair<Dst1, Dst2> pair_cast(std::pair<Src1, Src2> const& x)
|
||||
{
|
||||
return std::pair<Dst1, Dst2>(Dst1(x.first), Dst2(x.second));
|
||||
}
|
||||
|
||||
#define BOOST_UNORDERED_PAIR_CAST(First, Last, Argument) \
|
||||
::boost::unordered::detail::pair_cast<First, Last>(Argument)
|
||||
#else
|
||||
#define BOOST_UNORDERED_PAIR_CAST(First, Last, Argument) \
|
||||
Argument
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// insert_size/initial_size
|
||||
|
||||
@ -242,9 +266,8 @@ namespace boost { namespace unordered { namespace detail {
|
||||
template <class I>
|
||||
inline std::size_t insert_size(I i, I j)
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME ::boost::iterator_traversal<I>::type
|
||||
iterator_traversal_tag;
|
||||
return insert_size(i, j, iterator_traversal_tag);
|
||||
return insert_size(i, j,
|
||||
typename ::boost::iterator_traversal<I>::type());
|
||||
}
|
||||
|
||||
template <class I>
|
||||
@ -295,8 +318,8 @@ namespace boost { namespace unordered { namespace detail {
|
||||
: private generate_base<T1, 1>::type,
|
||||
private generate_base<T2, 2>::type
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME generate_base<T1, 1>::type base1;
|
||||
typedef BOOST_DEDUCED_TYPENAME generate_base<T2, 2>::type base2;
|
||||
typedef typename generate_base<T1, 1>::type base1;
|
||||
typedef typename generate_base<T2, 2>::type base2;
|
||||
|
||||
typedef T1 first_type;
|
||||
typedef T2 second_type;
|
||||
|
@ -52,24 +52,21 @@ namespace unordered
|
||||
private:
|
||||
#endif
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
::boost::unordered::detail::rebind_wrap<
|
||||
typedef typename ::boost::unordered::detail::rebind_wrap<
|
||||
allocator_type, value_type>::type
|
||||
value_allocator;
|
||||
typedef ::boost::unordered::detail::allocator_traits<value_allocator> allocator_traits;
|
||||
|
||||
typedef ::boost::unordered::detail::map<K, H, P,
|
||||
value_allocator> types;
|
||||
typedef BOOST_DEDUCED_TYPENAME types::impl table;
|
||||
typedef typename types::impl table;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME types::node_ptr node_ptr;
|
||||
typedef typename types::node_ptr node_ptr;
|
||||
|
||||
public:
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
allocator_traits::pointer pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
allocator_traits::const_pointer const_pointer;
|
||||
typedef typename allocator_traits::pointer pointer;
|
||||
typedef typename allocator_traits::const_pointer const_pointer;
|
||||
|
||||
typedef value_type& reference;
|
||||
typedef value_type const& const_reference;
|
||||
@ -135,9 +132,7 @@ namespace unordered
|
||||
|
||||
unordered_map(unordered_map const&);
|
||||
|
||||
#if BOOST_UNORDERED_USE_RV_REF
|
||||
unordered_map& operator=(
|
||||
BOOST_RV_REF(unordered_map) x)
|
||||
unordered_map& operator=(BOOST_RV_REF(unordered_map) x)
|
||||
{
|
||||
table_.move_assign(x.table_);
|
||||
return *this;
|
||||
@ -147,7 +142,6 @@ namespace unordered
|
||||
: table_(other.table_, ::boost::unordered::detail::move_tag())
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
unordered_map(unordered_map&&, allocator_type const&);
|
||||
@ -260,11 +254,10 @@ namespace unordered
|
||||
#endif
|
||||
|
||||
std::pair<iterator, bool> insert(value_type const&);
|
||||
iterator insert(const_iterator, value_type const&);
|
||||
#if BOOST_UNORDERED_USE_RV_REF
|
||||
std::pair<iterator, bool> insert(BOOST_RV_REF(value_type));
|
||||
iterator insert(const_iterator, value_type const&);
|
||||
iterator insert(const_iterator, BOOST_RV_REF(value_type));
|
||||
#endif
|
||||
|
||||
template <class InputIt> void insert(InputIt, InputIt);
|
||||
|
||||
#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST)
|
||||
@ -403,8 +396,7 @@ namespace unordered
|
||||
private:
|
||||
#endif
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
::boost::unordered::detail::rebind_wrap<
|
||||
typedef typename ::boost::unordered::detail::rebind_wrap<
|
||||
allocator_type, value_type>::type
|
||||
value_allocator;
|
||||
typedef ::boost::unordered::detail::allocator_traits<value_allocator>
|
||||
@ -412,16 +404,14 @@ namespace unordered
|
||||
|
||||
typedef ::boost::unordered::detail::multimap<K, H, P,
|
||||
value_allocator> types;
|
||||
typedef BOOST_DEDUCED_TYPENAME types::impl table;
|
||||
typedef typename types::impl table;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME types::node_ptr node_ptr;
|
||||
typedef typename types::node_ptr node_ptr;
|
||||
|
||||
public:
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
allocator_traits::pointer pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
allocator_traits::const_pointer const_pointer;
|
||||
typedef typename allocator_traits::pointer pointer;
|
||||
typedef typename allocator_traits::const_pointer const_pointer;
|
||||
|
||||
typedef value_type& reference;
|
||||
typedef value_type const& const_reference;
|
||||
@ -487,9 +477,7 @@ namespace unordered
|
||||
|
||||
unordered_multimap(unordered_multimap const&);
|
||||
|
||||
#if BOOST_UNORDERED_USE_RV_REF
|
||||
unordered_multimap& operator=(
|
||||
BOOST_RV_REF(unordered_multimap) x)
|
||||
unordered_multimap& operator=(BOOST_RV_REF(unordered_multimap) x)
|
||||
{
|
||||
table_.move_assign(x.table_);
|
||||
return *this;
|
||||
@ -499,7 +487,6 @@ namespace unordered
|
||||
: table_(other.table_, ::boost::unordered::detail::move_tag())
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
unordered_multimap(unordered_multimap&&, allocator_type const&);
|
||||
@ -612,11 +599,10 @@ namespace unordered
|
||||
#endif
|
||||
|
||||
iterator insert(value_type const&);
|
||||
iterator insert(const_iterator, value_type const&);
|
||||
#if BOOST_UNORDERED_USE_RV_REF
|
||||
iterator insert(BOOST_RV_REF(value_type));
|
||||
iterator insert(const_iterator, value_type const&);
|
||||
iterator insert(const_iterator, BOOST_RV_REF(value_type));
|
||||
#endif
|
||||
|
||||
template <class InputIt> void insert(InputIt, InputIt);
|
||||
|
||||
#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST)
|
||||
@ -851,16 +837,15 @@ namespace unordered
|
||||
#if defined(BOOST_UNORDERED_STD_FORWARD_MOVE)
|
||||
template <class K, class T, class H, class P, class A>
|
||||
template <class... Args>
|
||||
std::pair<BOOST_DEDUCED_TYPENAME unordered_map<K,T,H,P,A>::iterator, bool>
|
||||
std::pair<typename unordered_map<K,T,H,P,A>::iterator, bool>
|
||||
unordered_map<K,T,H,P,A>::emplace(Args&&... args)
|
||||
{
|
||||
return BOOST_UNORDERED_PAIR_CAST(iterator, bool,
|
||||
table_.emplace(std::forward<Args>(args)...));
|
||||
return table_.emplace(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
template <class... Args>
|
||||
BOOST_DEDUCED_TYPENAME unordered_map<K,T,H,P,A>::iterator
|
||||
typename unordered_map<K,T,H,P,A>::iterator
|
||||
unordered_map<K,T,H,P,A>::emplace_hint(const_iterator, Args&&... args)
|
||||
{
|
||||
return iterator(table_.emplace(std::forward<Args>(args)...).first);
|
||||
@ -869,18 +854,17 @@ namespace unordered
|
||||
|
||||
#if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100))
|
||||
template <class K, class T, class H, class P, class A>
|
||||
std::pair<BOOST_DEDUCED_TYPENAME unordered_map<K,T,H,P,A>::iterator, bool>
|
||||
std::pair<typename unordered_map<K,T,H,P,A>::iterator, bool>
|
||||
unordered_map<K,T,H,P,A>::emplace(
|
||||
boost::unordered::detail::empty_emplace,
|
||||
value_type v
|
||||
)
|
||||
{
|
||||
return BOOST_UNORDERED_PAIR_CAST(iterator, bool,
|
||||
table_.emplace(boost::move(v)));
|
||||
return table_.emplace(boost::move(v));
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_map<K,T,H,P,A>::iterator
|
||||
typename unordered_map<K,T,H,P,A>::iterator
|
||||
unordered_map<K,T,H,P,A>::emplace_hint(const_iterator,
|
||||
boost::unordered::detail::empty_emplace,
|
||||
value_type v
|
||||
@ -895,23 +879,18 @@ namespace unordered
|
||||
template < \
|
||||
BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
|
||||
> \
|
||||
std::pair< \
|
||||
BOOST_DEDUCED_TYPENAME unordered_map<K,T,H,P,A>::iterator, \
|
||||
bool> \
|
||||
std::pair<typename unordered_map<K,T,H,P,A>::iterator, bool> \
|
||||
unordered_map<K,T,H,P,A>::emplace( \
|
||||
BOOST_UNORDERED_FUNCTION_PARAMS(z, n)) \
|
||||
{ \
|
||||
return \
|
||||
BOOST_UNORDERED_PAIR_CAST(iterator, bool, \
|
||||
table_.emplace( \
|
||||
BOOST_UNORDERED_CALL_PARAMS(z, n))); \
|
||||
return table_.emplace(BOOST_UNORDERED_CALL_PARAMS(z, n)); \
|
||||
} \
|
||||
\
|
||||
template <class K, class T, class H, class P, class A> \
|
||||
template < \
|
||||
BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
|
||||
> \
|
||||
BOOST_DEDUCED_TYPENAME unordered_map<K,T,H,P,A>::iterator \
|
||||
typename unordered_map<K,T,H,P,A>::iterator \
|
||||
unordered_map<K,T,H,P,A>::emplace_hint( \
|
||||
const_iterator, \
|
||||
BOOST_UNORDERED_FUNCTION_PARAMS(z, n) \
|
||||
@ -929,38 +908,34 @@ namespace unordered
|
||||
#endif
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
std::pair<BOOST_DEDUCED_TYPENAME unordered_map<K,T,H,P,A>::iterator, bool>
|
||||
std::pair<typename unordered_map<K,T,H,P,A>::iterator, bool>
|
||||
unordered_map<K,T,H,P,A>::insert(value_type const& obj)
|
||||
{
|
||||
return BOOST_UNORDERED_PAIR_CAST(iterator, bool,
|
||||
table_.emplace(obj));
|
||||
return table_.emplace(obj);
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_map<K,T,H,P,A>::iterator
|
||||
typename unordered_map<K,T,H,P,A>::iterator
|
||||
unordered_map<K,T,H,P,A>::insert(const_iterator,
|
||||
value_type const& obj)
|
||||
{
|
||||
return iterator(table_.emplace(obj).first);
|
||||
}
|
||||
|
||||
#if BOOST_UNORDERED_USE_RV_REF
|
||||
template <class K, class T, class H, class P, class A>
|
||||
std::pair<BOOST_DEDUCED_TYPENAME unordered_map<K,T,H,P,A>::iterator, bool>
|
||||
std::pair<typename unordered_map<K,T,H,P,A>::iterator, bool>
|
||||
unordered_map<K,T,H,P,A>::insert(BOOST_RV_REF(value_type) obj)
|
||||
{
|
||||
return BOOST_UNORDERED_PAIR_CAST(iterator, bool,
|
||||
table_.emplace(boost::move(obj)));
|
||||
return table_.emplace(boost::move(obj));
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_map<K,T,H,P,A>::iterator
|
||||
typename unordered_map<K,T,H,P,A>::iterator
|
||||
unordered_map<K,T,H,P,A>::insert(const_iterator,
|
||||
BOOST_RV_REF(value_type) obj)
|
||||
{
|
||||
return iterator(table_.emplace(boost::move(obj)).first);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
template <class InputIt>
|
||||
@ -979,21 +954,21 @@ namespace unordered
|
||||
#endif
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_map<K,T,H,P,A>::iterator
|
||||
typename unordered_map<K,T,H,P,A>::iterator
|
||||
unordered_map<K,T,H,P,A>::erase(const_iterator position)
|
||||
{
|
||||
return iterator(table_.erase(position.node_));
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_map<K,T,H,P,A>::size_type
|
||||
typename unordered_map<K,T,H,P,A>::size_type
|
||||
unordered_map<K,T,H,P,A>::erase(const key_type& k)
|
||||
{
|
||||
return table_.erase_key(k);
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_map<K,T,H,P,A>::iterator
|
||||
typename unordered_map<K,T,H,P,A>::iterator
|
||||
unordered_map<K,T,H,P,A>::erase(
|
||||
const_iterator first, const_iterator last)
|
||||
{
|
||||
@ -1015,35 +990,35 @@ namespace unordered
|
||||
// observers
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_map<K,T,H,P,A>::hasher
|
||||
typename unordered_map<K,T,H,P,A>::hasher
|
||||
unordered_map<K,T,H,P,A>::hash_function() const
|
||||
{
|
||||
return table_.hash_function();
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_map<K,T,H,P,A>::key_equal
|
||||
typename unordered_map<K,T,H,P,A>::key_equal
|
||||
unordered_map<K,T,H,P,A>::key_eq() const
|
||||
{
|
||||
return table_.key_eq();
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_map<K,T,H,P,A>::mapped_type&
|
||||
typename unordered_map<K,T,H,P,A>::mapped_type&
|
||||
unordered_map<K,T,H,P,A>::operator[](const key_type &k)
|
||||
{
|
||||
return table_[k].second;
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_map<K,T,H,P,A>::mapped_type&
|
||||
typename unordered_map<K,T,H,P,A>::mapped_type&
|
||||
unordered_map<K,T,H,P,A>::at(const key_type& k)
|
||||
{
|
||||
return table_.at(k).second;
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_map<K,T,H,P,A>::mapped_type const&
|
||||
typename unordered_map<K,T,H,P,A>::mapped_type const&
|
||||
unordered_map<K,T,H,P,A>::at(const key_type& k) const
|
||||
{
|
||||
return table_.at(k).second;
|
||||
@ -1052,14 +1027,14 @@ namespace unordered
|
||||
// lookup
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_map<K,T,H,P,A>::iterator
|
||||
typename unordered_map<K,T,H,P,A>::iterator
|
||||
unordered_map<K,T,H,P,A>::find(const key_type& k)
|
||||
{
|
||||
return iterator(table_.find_node(k));
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_map<K,T,H,P,A>::const_iterator
|
||||
typename unordered_map<K,T,H,P,A>::const_iterator
|
||||
unordered_map<K,T,H,P,A>::find(const key_type& k) const
|
||||
{
|
||||
return const_iterator(table_.find_node(k));
|
||||
@ -1068,7 +1043,7 @@ namespace unordered
|
||||
template <class K, class T, class H, class P, class A>
|
||||
template <class CompatibleKey, class CompatibleHash,
|
||||
class CompatiblePredicate>
|
||||
BOOST_DEDUCED_TYPENAME unordered_map<K,T,H,P,A>::iterator
|
||||
typename unordered_map<K,T,H,P,A>::iterator
|
||||
unordered_map<K,T,H,P,A>::find(
|
||||
CompatibleKey const& k,
|
||||
CompatibleHash const& hash,
|
||||
@ -1080,7 +1055,7 @@ namespace unordered
|
||||
template <class K, class T, class H, class P, class A>
|
||||
template <class CompatibleKey, class CompatibleHash,
|
||||
class CompatiblePredicate>
|
||||
BOOST_DEDUCED_TYPENAME unordered_map<K,T,H,P,A>::const_iterator
|
||||
typename unordered_map<K,T,H,P,A>::const_iterator
|
||||
unordered_map<K,T,H,P,A>::find(
|
||||
CompatibleKey const& k,
|
||||
CompatibleHash const& hash,
|
||||
@ -1090,7 +1065,7 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_map<K,T,H,P,A>::size_type
|
||||
typename unordered_map<K,T,H,P,A>::size_type
|
||||
unordered_map<K,T,H,P,A>::count(const key_type& k) const
|
||||
{
|
||||
return table_.count(k);
|
||||
@ -1098,26 +1073,24 @@ namespace unordered
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
std::pair<
|
||||
BOOST_DEDUCED_TYPENAME unordered_map<K,T,H,P,A>::iterator,
|
||||
BOOST_DEDUCED_TYPENAME unordered_map<K,T,H,P,A>::iterator>
|
||||
typename unordered_map<K,T,H,P,A>::iterator,
|
||||
typename unordered_map<K,T,H,P,A>::iterator>
|
||||
unordered_map<K,T,H,P,A>::equal_range(const key_type& k)
|
||||
{
|
||||
return BOOST_UNORDERED_PAIR_CAST(iterator, iterator,
|
||||
table_.equal_range(k));
|
||||
return table_.equal_range(k);
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
std::pair<
|
||||
BOOST_DEDUCED_TYPENAME unordered_map<K,T,H,P,A>::const_iterator,
|
||||
BOOST_DEDUCED_TYPENAME unordered_map<K,T,H,P,A>::const_iterator>
|
||||
typename unordered_map<K,T,H,P,A>::const_iterator,
|
||||
typename unordered_map<K,T,H,P,A>::const_iterator>
|
||||
unordered_map<K,T,H,P,A>::equal_range(const key_type& k) const
|
||||
{
|
||||
return BOOST_UNORDERED_PAIR_CAST(const_iterator, const_iterator,
|
||||
table_.equal_range(k));
|
||||
return table_.equal_range(k);
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_map<K,T,H,P,A>::size_type
|
||||
typename unordered_map<K,T,H,P,A>::size_type
|
||||
unordered_map<K,T,H,P,A>::bucket_size(size_type n) const
|
||||
{
|
||||
return table_.bucket_size(n);
|
||||
@ -1293,7 +1266,7 @@ namespace unordered
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
template <class... Args>
|
||||
BOOST_DEDUCED_TYPENAME unordered_multimap<K,T,H,P,A>::iterator
|
||||
typename unordered_multimap<K,T,H,P,A>::iterator
|
||||
unordered_multimap<K,T,H,P,A>::emplace(Args&&... args)
|
||||
{
|
||||
return iterator(table_.emplace(std::forward<Args>(args)...));
|
||||
@ -1301,7 +1274,7 @@ namespace unordered
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
template <class... Args>
|
||||
BOOST_DEDUCED_TYPENAME unordered_multimap<K,T,H,P,A>::iterator
|
||||
typename unordered_multimap<K,T,H,P,A>::iterator
|
||||
unordered_multimap<K,T,H,P,A>::emplace_hint(
|
||||
const_iterator, Args&&... args)
|
||||
{
|
||||
@ -1312,7 +1285,7 @@ namespace unordered
|
||||
|
||||
#if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100))
|
||||
template <class K, class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_multimap<K,T,H,P,A>::iterator
|
||||
typename unordered_multimap<K,T,H,P,A>::iterator
|
||||
unordered_multimap<K,T,H,P,A>::emplace(
|
||||
boost::unordered::detail::empty_emplace,
|
||||
value_type v
|
||||
@ -1322,7 +1295,7 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_multimap<K,T,H,P,A>::iterator
|
||||
typename unordered_multimap<K,T,H,P,A>::iterator
|
||||
unordered_multimap<K,T,H,P,A>::emplace_hint(const_iterator,
|
||||
boost::unordered::detail::empty_emplace,
|
||||
value_type v
|
||||
@ -1337,7 +1310,7 @@ namespace unordered
|
||||
template < \
|
||||
BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
|
||||
> \
|
||||
BOOST_DEDUCED_TYPENAME unordered_multimap<K,T,H,P,A>::iterator \
|
||||
typename unordered_multimap<K,T,H,P,A>::iterator \
|
||||
unordered_multimap<K,T,H,P,A>::emplace( \
|
||||
BOOST_UNORDERED_FUNCTION_PARAMS(z, n)) \
|
||||
{ \
|
||||
@ -1349,7 +1322,7 @@ namespace unordered
|
||||
template < \
|
||||
BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
|
||||
> \
|
||||
BOOST_DEDUCED_TYPENAME unordered_multimap<K,T,H,P,A>::iterator \
|
||||
typename unordered_multimap<K,T,H,P,A>::iterator \
|
||||
unordered_multimap<K,T,H,P,A>::emplace_hint( \
|
||||
const_iterator, \
|
||||
BOOST_UNORDERED_FUNCTION_PARAMS(z, n)) \
|
||||
@ -1366,36 +1339,34 @@ namespace unordered
|
||||
#endif
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_multimap<K,T,H,P,A>::iterator
|
||||
typename unordered_multimap<K,T,H,P,A>::iterator
|
||||
unordered_multimap<K,T,H,P,A>::insert(value_type const& obj)
|
||||
{
|
||||
return iterator(table_.emplace(obj));
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_multimap<K,T,H,P,A>::iterator
|
||||
typename unordered_multimap<K,T,H,P,A>::iterator
|
||||
unordered_multimap<K,T,H,P,A>::insert(
|
||||
const_iterator, value_type const& obj)
|
||||
{
|
||||
return iterator(table_.emplace(obj));
|
||||
}
|
||||
|
||||
#if BOOST_UNORDERED_USE_RV_REF
|
||||
template <class K, class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_multimap<K,T,H,P,A>::iterator
|
||||
typename unordered_multimap<K,T,H,P,A>::iterator
|
||||
unordered_multimap<K,T,H,P,A>::insert(BOOST_RV_REF(value_type) obj)
|
||||
{
|
||||
return iterator(table_.emplace(boost::move(obj)));
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_multimap<K,T,H,P,A>::iterator
|
||||
typename unordered_multimap<K,T,H,P,A>::iterator
|
||||
unordered_multimap<K,T,H,P,A>::insert(
|
||||
const_iterator, BOOST_RV_REF(value_type) obj)
|
||||
{
|
||||
return iterator(table_.emplace(boost::move(obj)));
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
template <class InputIt>
|
||||
@ -1414,21 +1385,21 @@ namespace unordered
|
||||
#endif
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_multimap<K,T,H,P,A>::iterator
|
||||
typename unordered_multimap<K,T,H,P,A>::iterator
|
||||
unordered_multimap<K,T,H,P,A>::erase(const_iterator position)
|
||||
{
|
||||
return iterator(table_.erase(position.node_));
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_multimap<K,T,H,P,A>::size_type
|
||||
typename unordered_multimap<K,T,H,P,A>::size_type
|
||||
unordered_multimap<K,T,H,P,A>::erase(const key_type& k)
|
||||
{
|
||||
return table_.erase_key(k);
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_multimap<K,T,H,P,A>::iterator
|
||||
typename unordered_multimap<K,T,H,P,A>::iterator
|
||||
unordered_multimap<K,T,H,P,A>::erase(
|
||||
const_iterator first, const_iterator last)
|
||||
{
|
||||
@ -1450,14 +1421,14 @@ namespace unordered
|
||||
// observers
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_multimap<K,T,H,P,A>::hasher
|
||||
typename unordered_multimap<K,T,H,P,A>::hasher
|
||||
unordered_multimap<K,T,H,P,A>::hash_function() const
|
||||
{
|
||||
return table_.hash_function();
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_multimap<K,T,H,P,A>::key_equal
|
||||
typename unordered_multimap<K,T,H,P,A>::key_equal
|
||||
unordered_multimap<K,T,H,P,A>::key_eq() const
|
||||
{
|
||||
return table_.key_eq();
|
||||
@ -1466,14 +1437,14 @@ namespace unordered
|
||||
// lookup
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_multimap<K,T,H,P,A>::iterator
|
||||
typename unordered_multimap<K,T,H,P,A>::iterator
|
||||
unordered_multimap<K,T,H,P,A>::find(const key_type& k)
|
||||
{
|
||||
return iterator(table_.find_node(k));
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_multimap<K,T,H,P,A>::const_iterator
|
||||
typename unordered_multimap<K,T,H,P,A>::const_iterator
|
||||
unordered_multimap<K,T,H,P,A>::find(const key_type& k) const
|
||||
{
|
||||
return const_iterator(table_.find_node(k));
|
||||
@ -1482,7 +1453,7 @@ namespace unordered
|
||||
template <class K, class T, class H, class P, class A>
|
||||
template <class CompatibleKey, class CompatibleHash,
|
||||
class CompatiblePredicate>
|
||||
BOOST_DEDUCED_TYPENAME unordered_multimap<K,T,H,P,A>::iterator
|
||||
typename unordered_multimap<K,T,H,P,A>::iterator
|
||||
unordered_multimap<K,T,H,P,A>::find(
|
||||
CompatibleKey const& k,
|
||||
CompatibleHash const& hash,
|
||||
@ -1494,7 +1465,7 @@ namespace unordered
|
||||
template <class K, class T, class H, class P, class A>
|
||||
template <class CompatibleKey, class CompatibleHash,
|
||||
class CompatiblePredicate>
|
||||
BOOST_DEDUCED_TYPENAME unordered_multimap<K,T,H,P,A>::const_iterator
|
||||
typename unordered_multimap<K,T,H,P,A>::const_iterator
|
||||
unordered_multimap<K,T,H,P,A>::find(
|
||||
CompatibleKey const& k,
|
||||
CompatibleHash const& hash,
|
||||
@ -1504,7 +1475,7 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_multimap<K,T,H,P,A>::size_type
|
||||
typename unordered_multimap<K,T,H,P,A>::size_type
|
||||
unordered_multimap<K,T,H,P,A>::count(const key_type& k) const
|
||||
{
|
||||
return table_.count(k);
|
||||
@ -1512,26 +1483,24 @@ namespace unordered
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
std::pair<
|
||||
BOOST_DEDUCED_TYPENAME unordered_multimap<K,T,H,P,A>::iterator,
|
||||
BOOST_DEDUCED_TYPENAME unordered_multimap<K,T,H,P,A>::iterator>
|
||||
typename unordered_multimap<K,T,H,P,A>::iterator,
|
||||
typename unordered_multimap<K,T,H,P,A>::iterator>
|
||||
unordered_multimap<K,T,H,P,A>::equal_range(const key_type& k)
|
||||
{
|
||||
return BOOST_UNORDERED_PAIR_CAST(iterator, iterator,
|
||||
table_.equal_range(k));
|
||||
return table_.equal_range(k);
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
std::pair<
|
||||
BOOST_DEDUCED_TYPENAME unordered_multimap<K,T,H,P,A>::const_iterator,
|
||||
BOOST_DEDUCED_TYPENAME unordered_multimap<K,T,H,P,A>::const_iterator>
|
||||
typename unordered_multimap<K,T,H,P,A>::const_iterator,
|
||||
typename unordered_multimap<K,T,H,P,A>::const_iterator>
|
||||
unordered_multimap<K,T,H,P,A>::equal_range(const key_type& k) const
|
||||
{
|
||||
return BOOST_UNORDERED_PAIR_CAST(const_iterator, const_iterator,
|
||||
table_.equal_range(k));
|
||||
return table_.equal_range(k);
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_multimap<K,T,H,P,A>::size_type
|
||||
typename unordered_multimap<K,T,H,P,A>::size_type
|
||||
unordered_multimap<K,T,H,P,A>::bucket_size(size_type n) const
|
||||
{
|
||||
return table_.bucket_size(n);
|
||||
|
@ -52,8 +52,7 @@ namespace unordered
|
||||
private:
|
||||
#endif
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
::boost::unordered::detail::rebind_wrap<
|
||||
typedef typename ::boost::unordered::detail::rebind_wrap<
|
||||
allocator_type, value_type>::type
|
||||
value_allocator;
|
||||
typedef ::boost::unordered::detail::allocator_traits<value_allocator>
|
||||
@ -61,16 +60,14 @@ namespace unordered
|
||||
|
||||
typedef ::boost::unordered::detail::set<H, P,
|
||||
value_allocator> types;
|
||||
typedef BOOST_DEDUCED_TYPENAME types::impl table;
|
||||
typedef typename types::impl table;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME types::node_ptr node_ptr;
|
||||
typedef typename types::node_ptr node_ptr;
|
||||
|
||||
public:
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
allocator_traits::pointer pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
allocator_traits::const_pointer const_pointer;
|
||||
typedef typename allocator_traits::pointer pointer;
|
||||
typedef typename allocator_traits::const_pointer const_pointer;
|
||||
|
||||
typedef value_type& reference;
|
||||
typedef value_type const& const_reference;
|
||||
@ -134,9 +131,7 @@ namespace unordered
|
||||
|
||||
unordered_set(unordered_set const&);
|
||||
|
||||
#if BOOST_UNORDERED_USE_RV_REF
|
||||
unordered_set& operator=(
|
||||
BOOST_RV_REF(unordered_set) x)
|
||||
unordered_set& operator=(BOOST_RV_REF(unordered_set) x)
|
||||
{
|
||||
table_.move_assign(x.table_);
|
||||
return *this;
|
||||
@ -146,7 +141,6 @@ namespace unordered
|
||||
: table_(other.table_, ::boost::unordered::detail::move_tag())
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
unordered_set(unordered_set&&, allocator_type const&);
|
||||
@ -257,11 +251,9 @@ namespace unordered
|
||||
#endif
|
||||
|
||||
std::pair<iterator, bool> insert(value_type const&);
|
||||
std::pair<iterator, bool> insert(BOOST_UNORDERED_RV_REF(value_type));
|
||||
iterator insert(const_iterator, value_type const&);
|
||||
#if BOOST_UNORDERED_USE_RV_REF
|
||||
std::pair<iterator, bool> insert(BOOST_RV_REF(value_type));
|
||||
iterator insert(const_iterator, BOOST_RV_REF(value_type));
|
||||
#endif
|
||||
iterator insert(const_iterator, BOOST_UNORDERED_RV_REF(value_type));
|
||||
template <class InputIt> void insert(InputIt, InputIt);
|
||||
|
||||
#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST)
|
||||
@ -384,8 +376,7 @@ namespace unordered
|
||||
private:
|
||||
#endif
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
::boost::unordered::detail::rebind_wrap<
|
||||
typedef typename ::boost::unordered::detail::rebind_wrap<
|
||||
allocator_type, value_type>::type
|
||||
value_allocator;
|
||||
typedef ::boost::unordered::detail::allocator_traits<value_allocator>
|
||||
@ -393,16 +384,14 @@ namespace unordered
|
||||
|
||||
typedef ::boost::unordered::detail::multiset<H, P,
|
||||
value_allocator> types;
|
||||
typedef BOOST_DEDUCED_TYPENAME types::impl table;
|
||||
typedef typename types::impl table;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME types::node_ptr node_ptr;
|
||||
typedef typename types::node_ptr node_ptr;
|
||||
|
||||
public:
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
allocator_traits::pointer pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
allocator_traits::const_pointer const_pointer;
|
||||
typedef typename allocator_traits::pointer pointer;
|
||||
typedef typename allocator_traits::const_pointer const_pointer;
|
||||
|
||||
typedef value_type& reference;
|
||||
typedef value_type const& const_reference;
|
||||
@ -466,9 +455,7 @@ namespace unordered
|
||||
|
||||
unordered_multiset(unordered_multiset const&);
|
||||
|
||||
#if BOOST_UNORDERED_USE_RV_REF
|
||||
unordered_multiset& operator=(
|
||||
BOOST_RV_REF(unordered_multiset) x)
|
||||
unordered_multiset& operator=(BOOST_RV_REF(unordered_multiset) x)
|
||||
{
|
||||
table_.move_assign(x.table_);
|
||||
return *this;
|
||||
@ -478,7 +465,6 @@ namespace unordered
|
||||
: table_(other.table_, ::boost::unordered::detail::move_tag())
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
unordered_multiset(unordered_multiset&&, allocator_type const&);
|
||||
@ -589,11 +575,10 @@ namespace unordered
|
||||
#endif
|
||||
|
||||
iterator insert(value_type const&);
|
||||
iterator insert(BOOST_UNORDERED_RV_REF(value_type));
|
||||
iterator insert(const_iterator, value_type const&);
|
||||
#if BOOST_UNORDERED_USE_RV_REF
|
||||
iterator insert(BOOST_RV_REF(value_type));
|
||||
iterator insert(const_iterator, BOOST_RV_REF(value_type));
|
||||
#endif
|
||||
iterator insert(const_iterator, BOOST_UNORDERED_RV_REF(value_type));
|
||||
|
||||
template <class InputIt>
|
||||
void insert(InputIt, InputIt);
|
||||
|
||||
@ -818,16 +803,15 @@ namespace unordered
|
||||
#if defined(BOOST_UNORDERED_STD_FORWARD_MOVE)
|
||||
template <class T, class H, class P, class A>
|
||||
template <class... Args>
|
||||
std::pair<BOOST_DEDUCED_TYPENAME unordered_set<T,H,P,A>::iterator, bool>
|
||||
std::pair<typename unordered_set<T,H,P,A>::iterator, bool>
|
||||
unordered_set<T,H,P,A>::emplace(Args&&... args)
|
||||
{
|
||||
return BOOST_UNORDERED_PAIR_CAST(iterator, bool,
|
||||
table_.emplace(std::forward<Args>(args)...));
|
||||
return table_.emplace(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
template <class... Args>
|
||||
BOOST_DEDUCED_TYPENAME unordered_set<T,H,P,A>::iterator
|
||||
typename unordered_set<T,H,P,A>::iterator
|
||||
unordered_set<T,H,P,A>::emplace_hint(const_iterator, Args&&... args)
|
||||
{
|
||||
return iterator(table_.emplace(std::forward<Args>(args)...).first);
|
||||
@ -835,18 +819,17 @@ namespace unordered
|
||||
#else
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
std::pair<BOOST_DEDUCED_TYPENAME unordered_set<T,H,P,A>::iterator, bool>
|
||||
std::pair<typename unordered_set<T,H,P,A>::iterator, bool>
|
||||
unordered_set<T,H,P,A>::emplace(
|
||||
boost::unordered::detail::empty_emplace,
|
||||
value_type v
|
||||
)
|
||||
{
|
||||
return BOOST_UNORDERED_PAIR_CAST(iterator, bool,
|
||||
table_.emplace(boost::move(v)));
|
||||
return table_.emplace(boost::move(v));
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_set<T,H,P,A>::iterator
|
||||
typename unordered_set<T,H,P,A>::iterator
|
||||
unordered_set<T,H,P,A>::emplace_hint(const_iterator,
|
||||
boost::unordered::detail::empty_emplace,
|
||||
value_type v
|
||||
@ -860,23 +843,18 @@ namespace unordered
|
||||
template < \
|
||||
BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
|
||||
> \
|
||||
std::pair< \
|
||||
BOOST_DEDUCED_TYPENAME unordered_set<T,H,P,A>::iterator, \
|
||||
bool> \
|
||||
std::pair<typename unordered_set<T,H,P,A>::iterator, bool> \
|
||||
unordered_set<T,H,P,A>::emplace( \
|
||||
BOOST_UNORDERED_FUNCTION_PARAMS(z, n)) \
|
||||
{ \
|
||||
return \
|
||||
BOOST_UNORDERED_PAIR_CAST(iterator, bool, \
|
||||
table_.emplace( \
|
||||
BOOST_UNORDERED_CALL_PARAMS(z, n))); \
|
||||
return table_.emplace(BOOST_UNORDERED_CALL_PARAMS(z, n)); \
|
||||
} \
|
||||
\
|
||||
template <class T, class H, class P, class A> \
|
||||
template < \
|
||||
BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
|
||||
> \
|
||||
BOOST_DEDUCED_TYPENAME unordered_set<T,H,P,A>::iterator \
|
||||
typename unordered_set<T,H,P,A>::iterator \
|
||||
unordered_set<T,H,P,A>::emplace_hint( \
|
||||
const_iterator, \
|
||||
BOOST_UNORDERED_FUNCTION_PARAMS(z, n) \
|
||||
@ -894,38 +872,34 @@ namespace unordered
|
||||
#endif
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
std::pair<BOOST_DEDUCED_TYPENAME unordered_set<T,H,P,A>::iterator, bool>
|
||||
std::pair<typename unordered_set<T,H,P,A>::iterator, bool>
|
||||
unordered_set<T,H,P,A>::insert(value_type const& obj)
|
||||
{
|
||||
return BOOST_UNORDERED_PAIR_CAST(iterator, bool,
|
||||
table_.emplace(obj));
|
||||
return table_.emplace(obj);
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_set<T,H,P,A>::iterator
|
||||
typename unordered_set<T,H,P,A>::iterator
|
||||
unordered_set<T,H,P,A>::insert(const_iterator,
|
||||
value_type const& obj)
|
||||
{
|
||||
return iterator(table_.emplace(obj).first);
|
||||
}
|
||||
|
||||
#if BOOST_UNORDERED_USE_RV_REF
|
||||
template <class T, class H, class P, class A>
|
||||
std::pair<BOOST_DEDUCED_TYPENAME unordered_set<T,H,P,A>::iterator, bool>
|
||||
unordered_set<T,H,P,A>::insert(BOOST_RV_REF(value_type) obj)
|
||||
std::pair<typename unordered_set<T,H,P,A>::iterator, bool>
|
||||
unordered_set<T,H,P,A>::insert(BOOST_UNORDERED_RV_REF(value_type) obj)
|
||||
{
|
||||
return BOOST_UNORDERED_PAIR_CAST(iterator, bool,
|
||||
table_.emplace(boost::move(obj)));
|
||||
return table_.emplace(boost::move(obj));
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_set<T,H,P,A>::iterator
|
||||
typename unordered_set<T,H,P,A>::iterator
|
||||
unordered_set<T,H,P,A>::insert(const_iterator,
|
||||
BOOST_RV_REF(value_type) obj)
|
||||
BOOST_UNORDERED_RV_REF(value_type) obj)
|
||||
{
|
||||
return iterator(table_.emplace(boost::move(obj)).first);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
template <class InputIt>
|
||||
@ -943,21 +917,21 @@ namespace unordered
|
||||
#endif
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_set<T,H,P,A>::iterator
|
||||
typename unordered_set<T,H,P,A>::iterator
|
||||
unordered_set<T,H,P,A>::erase(const_iterator position)
|
||||
{
|
||||
return iterator(table_.erase(position.node_));
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_set<T,H,P,A>::size_type
|
||||
typename unordered_set<T,H,P,A>::size_type
|
||||
unordered_set<T,H,P,A>::erase(const key_type& k)
|
||||
{
|
||||
return table_.erase_key(k);
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_set<T,H,P,A>::iterator
|
||||
typename unordered_set<T,H,P,A>::iterator
|
||||
unordered_set<T,H,P,A>::erase(const_iterator first, const_iterator last)
|
||||
{
|
||||
return iterator(table_.erase_range(first.node_, last.node_));
|
||||
@ -978,14 +952,14 @@ namespace unordered
|
||||
// observers
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_set<T,H,P,A>::hasher
|
||||
typename unordered_set<T,H,P,A>::hasher
|
||||
unordered_set<T,H,P,A>::hash_function() const
|
||||
{
|
||||
return table_.hash_function();
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_set<T,H,P,A>::key_equal
|
||||
typename unordered_set<T,H,P,A>::key_equal
|
||||
unordered_set<T,H,P,A>::key_eq() const
|
||||
{
|
||||
return table_.key_eq();
|
||||
@ -994,7 +968,7 @@ namespace unordered
|
||||
// lookup
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_set<T,H,P,A>::const_iterator
|
||||
typename unordered_set<T,H,P,A>::const_iterator
|
||||
unordered_set<T,H,P,A>::find(const key_type& k) const
|
||||
{
|
||||
return const_iterator(table_.find_node(k));
|
||||
@ -1003,7 +977,7 @@ namespace unordered
|
||||
template <class T, class H, class P, class A>
|
||||
template <class CompatibleKey, class CompatibleHash,
|
||||
class CompatiblePredicate>
|
||||
BOOST_DEDUCED_TYPENAME unordered_set<T,H,P,A>::const_iterator
|
||||
typename unordered_set<T,H,P,A>::const_iterator
|
||||
unordered_set<T,H,P,A>::find(
|
||||
CompatibleKey const& k,
|
||||
CompatibleHash const& hash,
|
||||
@ -1013,7 +987,7 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_set<T,H,P,A>::size_type
|
||||
typename unordered_set<T,H,P,A>::size_type
|
||||
unordered_set<T,H,P,A>::count(const key_type& k) const
|
||||
{
|
||||
return table_.count(k);
|
||||
@ -1021,16 +995,15 @@ namespace unordered
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
std::pair<
|
||||
BOOST_DEDUCED_TYPENAME unordered_set<T,H,P,A>::const_iterator,
|
||||
BOOST_DEDUCED_TYPENAME unordered_set<T,H,P,A>::const_iterator>
|
||||
typename unordered_set<T,H,P,A>::const_iterator,
|
||||
typename unordered_set<T,H,P,A>::const_iterator>
|
||||
unordered_set<T,H,P,A>::equal_range(const key_type& k) const
|
||||
{
|
||||
return BOOST_UNORDERED_PAIR_CAST(const_iterator, const_iterator,
|
||||
table_.equal_range(k));
|
||||
return table_.equal_range(k);
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_set<T,H,P,A>::size_type
|
||||
typename unordered_set<T,H,P,A>::size_type
|
||||
unordered_set<T,H,P,A>::bucket_size(size_type n) const
|
||||
{
|
||||
return table_.bucket_size(n);
|
||||
@ -1206,7 +1179,7 @@ namespace unordered
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
template <class... Args>
|
||||
BOOST_DEDUCED_TYPENAME unordered_multiset<T,H,P,A>::iterator
|
||||
typename unordered_multiset<T,H,P,A>::iterator
|
||||
unordered_multiset<T,H,P,A>::emplace(Args&&... args)
|
||||
{
|
||||
return iterator(table_.emplace(std::forward<Args>(args)...));
|
||||
@ -1214,7 +1187,7 @@ namespace unordered
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
template <class... Args>
|
||||
BOOST_DEDUCED_TYPENAME unordered_multiset<T,H,P,A>::iterator
|
||||
typename unordered_multiset<T,H,P,A>::iterator
|
||||
unordered_multiset<T,H,P,A>::emplace_hint(
|
||||
const_iterator, Args&&... args)
|
||||
{
|
||||
@ -1224,7 +1197,7 @@ namespace unordered
|
||||
#else
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_multiset<T,H,P,A>::iterator
|
||||
typename unordered_multiset<T,H,P,A>::iterator
|
||||
unordered_multiset<T,H,P,A>::emplace(
|
||||
boost::unordered::detail::empty_emplace,
|
||||
value_type v
|
||||
@ -1234,7 +1207,7 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_multiset<T,H,P,A>::iterator
|
||||
typename unordered_multiset<T,H,P,A>::iterator
|
||||
unordered_multiset<T,H,P,A>::emplace_hint(const_iterator,
|
||||
boost::unordered::detail::empty_emplace,
|
||||
value_type v
|
||||
@ -1248,7 +1221,7 @@ namespace unordered
|
||||
template < \
|
||||
BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
|
||||
> \
|
||||
BOOST_DEDUCED_TYPENAME unordered_multiset<T,H,P,A>::iterator \
|
||||
typename unordered_multiset<T,H,P,A>::iterator \
|
||||
unordered_multiset<T,H,P,A>::emplace( \
|
||||
BOOST_UNORDERED_FUNCTION_PARAMS(z, n)) \
|
||||
{ \
|
||||
@ -1260,7 +1233,7 @@ namespace unordered
|
||||
template < \
|
||||
BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
|
||||
> \
|
||||
BOOST_DEDUCED_TYPENAME unordered_multiset<T,H,P,A>::iterator \
|
||||
typename unordered_multiset<T,H,P,A>::iterator \
|
||||
unordered_multiset<T,H,P,A>::emplace_hint( \
|
||||
const_iterator, \
|
||||
BOOST_UNORDERED_FUNCTION_PARAMS(z, n)) \
|
||||
@ -1277,36 +1250,34 @@ namespace unordered
|
||||
#endif
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_multiset<T,H,P,A>::iterator
|
||||
typename unordered_multiset<T,H,P,A>::iterator
|
||||
unordered_multiset<T,H,P,A>::insert(value_type const& obj)
|
||||
{
|
||||
return iterator(table_.emplace(obj));
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_multiset<T,H,P,A>::iterator
|
||||
typename unordered_multiset<T,H,P,A>::iterator
|
||||
unordered_multiset<T,H,P,A>::insert(const_iterator,
|
||||
value_type const& obj)
|
||||
{
|
||||
return iterator(table_.emplace(obj));
|
||||
}
|
||||
|
||||
#if BOOST_UNORDERED_USE_RV_REF
|
||||
template <class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_multiset<T,H,P,A>::iterator
|
||||
unordered_multiset<T,H,P,A>::insert(BOOST_RV_REF(value_type) obj)
|
||||
typename unordered_multiset<T,H,P,A>::iterator
|
||||
unordered_multiset<T,H,P,A>::insert(BOOST_UNORDERED_RV_REF(value_type) obj)
|
||||
{
|
||||
return iterator(table_.emplace(boost::move(obj)));
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_multiset<T,H,P,A>::iterator
|
||||
typename unordered_multiset<T,H,P,A>::iterator
|
||||
unordered_multiset<T,H,P,A>::insert(const_iterator,
|
||||
BOOST_RV_REF(value_type) obj)
|
||||
BOOST_UNORDERED_RV_REF(value_type) obj)
|
||||
{
|
||||
return iterator(table_.emplace(boost::move(obj)));
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
template <class InputIt>
|
||||
@ -1324,21 +1295,21 @@ namespace unordered
|
||||
#endif
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_multiset<T,H,P,A>::iterator
|
||||
typename unordered_multiset<T,H,P,A>::iterator
|
||||
unordered_multiset<T,H,P,A>::erase(const_iterator position)
|
||||
{
|
||||
return iterator(table_.erase(position.node_));
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_multiset<T,H,P,A>::size_type
|
||||
typename unordered_multiset<T,H,P,A>::size_type
|
||||
unordered_multiset<T,H,P,A>::erase(const key_type& k)
|
||||
{
|
||||
return table_.erase_key(k);
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_multiset<T,H,P,A>::iterator
|
||||
typename unordered_multiset<T,H,P,A>::iterator
|
||||
unordered_multiset<T,H,P,A>::erase(const_iterator first, const_iterator last)
|
||||
{
|
||||
return iterator(table_.erase_range(first.node_, last.node_));
|
||||
@ -1359,14 +1330,14 @@ namespace unordered
|
||||
// observers
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_multiset<T,H,P,A>::hasher
|
||||
typename unordered_multiset<T,H,P,A>::hasher
|
||||
unordered_multiset<T,H,P,A>::hash_function() const
|
||||
{
|
||||
return table_.hash_function();
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_multiset<T,H,P,A>::key_equal
|
||||
typename unordered_multiset<T,H,P,A>::key_equal
|
||||
unordered_multiset<T,H,P,A>::key_eq() const
|
||||
{
|
||||
return table_.key_eq();
|
||||
@ -1375,7 +1346,7 @@ namespace unordered
|
||||
// lookup
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_multiset<T,H,P,A>::const_iterator
|
||||
typename unordered_multiset<T,H,P,A>::const_iterator
|
||||
unordered_multiset<T,H,P,A>::find(const key_type& k) const
|
||||
{
|
||||
return const_iterator(table_.find_node(k));
|
||||
@ -1384,7 +1355,7 @@ namespace unordered
|
||||
template <class T, class H, class P, class A>
|
||||
template <class CompatibleKey, class CompatibleHash,
|
||||
class CompatiblePredicate>
|
||||
BOOST_DEDUCED_TYPENAME unordered_multiset<T,H,P,A>::const_iterator
|
||||
typename unordered_multiset<T,H,P,A>::const_iterator
|
||||
unordered_multiset<T,H,P,A>::find(
|
||||
CompatibleKey const& k,
|
||||
CompatibleHash const& hash,
|
||||
@ -1394,7 +1365,7 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_multiset<T,H,P,A>::size_type
|
||||
typename unordered_multiset<T,H,P,A>::size_type
|
||||
unordered_multiset<T,H,P,A>::count(const key_type& k) const
|
||||
{
|
||||
return table_.count(k);
|
||||
@ -1402,16 +1373,15 @@ namespace unordered
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
std::pair<
|
||||
BOOST_DEDUCED_TYPENAME unordered_multiset<T,H,P,A>::const_iterator,
|
||||
BOOST_DEDUCED_TYPENAME unordered_multiset<T,H,P,A>::const_iterator>
|
||||
typename unordered_multiset<T,H,P,A>::const_iterator,
|
||||
typename unordered_multiset<T,H,P,A>::const_iterator>
|
||||
unordered_multiset<T,H,P,A>::equal_range(const key_type& k) const
|
||||
{
|
||||
return BOOST_UNORDERED_PAIR_CAST(const_iterator, const_iterator,
|
||||
table_.equal_range(k));
|
||||
return table_.equal_range(k);
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
BOOST_DEDUCED_TYPENAME unordered_multiset<T,H,P,A>::size_type
|
||||
typename unordered_multiset<T,H,P,A>::size_type
|
||||
unordered_multiset<T,H,P,A>::bucket_size(size_type n) const
|
||||
{
|
||||
return table_.bucket_size(n);
|
||||
|
@ -23,6 +23,7 @@ test-suite unordered
|
||||
[ run fwd_set_test.cpp ]
|
||||
[ run fwd_map_test.cpp ]
|
||||
[ run allocator_traits.cpp ]
|
||||
[ run minimal_allocator.cpp ]
|
||||
[ run compile_set.cpp ]
|
||||
[ run compile_map.cpp ]
|
||||
[ run link_test_1.cpp link_test_2.cpp ]
|
||||
@ -34,6 +35,9 @@ test-suite unordered
|
||||
[ run move_tests.cpp ]
|
||||
[ run assign_tests.cpp ]
|
||||
[ run insert_tests.cpp ]
|
||||
[ run insert_tests.cpp : :
|
||||
: <define>BOOST_UNORDERED_DEPRECATED_PAIR_CONSTRUCT
|
||||
: insert_deprecated ]
|
||||
[ run insert_stable_tests.cpp ]
|
||||
[ run unnecessary_copy_tests.cpp ]
|
||||
[ run erase_tests.cpp ]
|
||||
@ -44,5 +48,6 @@ test-suite unordered
|
||||
[ run load_factor_tests.cpp ]
|
||||
[ run rehash_tests.cpp ]
|
||||
[ run equality_tests.cpp ]
|
||||
[ run equality_deprecated.cpp ]
|
||||
[ run swap_tests.cpp ]
|
||||
;
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include "./compile_tests.hpp"
|
||||
|
||||
// Explicit instantiation to catch compile-time errors
|
||||
/*
|
||||
|
||||
template class boost::unordered_set<
|
||||
int,
|
||||
boost::hash<int>,
|
||||
@ -27,7 +27,7 @@ template class boost::unordered_multiset<
|
||||
boost::hash<int>,
|
||||
std::equal_to<int>,
|
||||
test::minimal::allocator<int> >;
|
||||
*/
|
||||
|
||||
template class boost::unordered_set<
|
||||
test::minimal::assignable,
|
||||
test::minimal::hash<test::minimal::assignable>,
|
||||
|
173
test/unordered/equality_deprecated.cpp
Normal file
173
test/unordered/equality_deprecated.cpp
Normal file
@ -0,0 +1,173 @@
|
||||
|
||||
// Copyright 2008-2009 Daniel James.
|
||||
// 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)
|
||||
|
||||
#define BOOST_UNORDERED_DEPRECATED_EQUALITY
|
||||
|
||||
#include "../helpers/prefix.hpp"
|
||||
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include <boost/preprocessor/seq.hpp>
|
||||
#include <list>
|
||||
#include "../helpers/test.hpp"
|
||||
|
||||
namespace equality_tests
|
||||
{
|
||||
struct mod_compare
|
||||
{
|
||||
bool alt_hash_;
|
||||
|
||||
explicit mod_compare(bool alt_hash = false) : alt_hash_(alt_hash) {}
|
||||
|
||||
bool operator()(int x, int y) const
|
||||
{
|
||||
return x % 1000 == y % 1000;
|
||||
}
|
||||
|
||||
int operator()(int x) const
|
||||
{
|
||||
return alt_hash_ ? x % 250 : (x + 5) % 250;
|
||||
}
|
||||
};
|
||||
|
||||
#define UNORDERED_EQUALITY_SET_TEST(seq1, op, seq2) \
|
||||
{ \
|
||||
boost::unordered_set<int, mod_compare, mod_compare> set1, set2; \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set1, seq1) \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set2, seq2) \
|
||||
BOOST_TEST(set1 op set2); \
|
||||
}
|
||||
|
||||
#define UNORDERED_EQUALITY_MULTISET_TEST(seq1, op, seq2) \
|
||||
{ \
|
||||
boost::unordered_multiset<int, mod_compare, mod_compare> \
|
||||
set1, set2; \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set1, seq1) \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set2, seq2) \
|
||||
BOOST_TEST(set1 op set2); \
|
||||
}
|
||||
|
||||
#define UNORDERED_EQUALITY_MAP_TEST(seq1, op, seq2) \
|
||||
{ \
|
||||
boost::unordered_map<int, int, mod_compare, mod_compare> \
|
||||
map1, map2; \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map1, seq1) \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map2, seq2) \
|
||||
BOOST_TEST(map1 op map2); \
|
||||
}
|
||||
|
||||
#define UNORDERED_EQUALITY_MULTIMAP_TEST(seq1, op, seq2) \
|
||||
{ \
|
||||
boost::unordered_multimap<int, int, mod_compare, mod_compare> \
|
||||
map1, map2; \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map1, seq1) \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map2, seq2) \
|
||||
BOOST_TEST(map1 op map2); \
|
||||
}
|
||||
|
||||
#define UNORDERED_SET_INSERT(r, set, item) set.insert(item);
|
||||
#define UNORDERED_MAP_INSERT(r, map, item) \
|
||||
map.insert(std::pair<int const, int> BOOST_PP_SEQ_TO_TUPLE(item));
|
||||
|
||||
UNORDERED_AUTO_TEST(equality_size_tests)
|
||||
{
|
||||
boost::unordered_set<int> x1, x2;
|
||||
BOOST_TEST(x1 == x2);
|
||||
BOOST_TEST(!(x1 != x2));
|
||||
|
||||
x1.insert(1);
|
||||
BOOST_TEST(x1 != x2);
|
||||
BOOST_TEST(!(x1 == x2));
|
||||
BOOST_TEST(x2 != x1);
|
||||
BOOST_TEST(!(x2 == x1));
|
||||
|
||||
x2.insert(1);
|
||||
BOOST_TEST(x1 == x2);
|
||||
BOOST_TEST(!(x1 != x2));
|
||||
|
||||
x2.insert(2);
|
||||
BOOST_TEST(x1 != x2);
|
||||
BOOST_TEST(!(x1 == x2));
|
||||
BOOST_TEST(x2 != x1);
|
||||
BOOST_TEST(!(x2 == x1));
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(equality_key_value_tests)
|
||||
{
|
||||
UNORDERED_EQUALITY_MULTISET_TEST((1), !=, (2))
|
||||
UNORDERED_EQUALITY_SET_TEST((2), ==, (2))
|
||||
UNORDERED_EQUALITY_MAP_TEST(((1)(1))((2)(1)), !=, ((1)(1))((3)(1)))
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(equality_collision_test)
|
||||
{
|
||||
UNORDERED_EQUALITY_MULTISET_TEST(
|
||||
(1), !=, (501))
|
||||
UNORDERED_EQUALITY_MULTISET_TEST(
|
||||
(1)(251), !=, (1)(501))
|
||||
UNORDERED_EQUALITY_MULTIMAP_TEST(
|
||||
((251)(1))((1)(1)), !=, ((501)(1))((1)(1)))
|
||||
UNORDERED_EQUALITY_MULTISET_TEST(
|
||||
(1)(501), ==, (1)(501))
|
||||
UNORDERED_EQUALITY_SET_TEST(
|
||||
(1)(501), ==, (501)(1))
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(equality_group_size_test)
|
||||
{
|
||||
UNORDERED_EQUALITY_MULTISET_TEST(
|
||||
(10)(20)(20), !=, (10)(10)(20))
|
||||
UNORDERED_EQUALITY_MULTIMAP_TEST(
|
||||
((10)(1))((20)(1))((20)(1)), !=,
|
||||
((10)(1))((20)(1))((10)(1)))
|
||||
UNORDERED_EQUALITY_MULTIMAP_TEST(
|
||||
((20)(1))((10)(1))((10)(1)), ==,
|
||||
((10)(1))((20)(1))((10)(1)))
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(equality_map_value_test)
|
||||
{
|
||||
UNORDERED_EQUALITY_MAP_TEST(
|
||||
((1)(1)), !=, ((1)(2)))
|
||||
UNORDERED_EQUALITY_MAP_TEST(
|
||||
((1)(1)), ==, ((1)(1)))
|
||||
UNORDERED_EQUALITY_MULTIMAP_TEST(
|
||||
((1)(1)), !=, ((1)(2)))
|
||||
UNORDERED_EQUALITY_MULTIMAP_TEST(
|
||||
((1)(1))((1)(1)), !=, ((1)(1))((1)(2)))
|
||||
UNORDERED_EQUALITY_MULTIMAP_TEST(
|
||||
((1)(2))((1)(1)), !=, ((1)(1))((1)(2)))
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(equality_predicate_test)
|
||||
{
|
||||
UNORDERED_EQUALITY_SET_TEST(
|
||||
(1), ==, (1001))
|
||||
UNORDERED_EQUALITY_MAP_TEST(
|
||||
((1)(2))((1001)(1)), ==, ((1001)(2))((1)(1)))
|
||||
}
|
||||
|
||||
// Test that equality still works when the two containers have
|
||||
// different hash functions but the same equality predicate.
|
||||
|
||||
UNORDERED_AUTO_TEST(equality_different_hash_test)
|
||||
{
|
||||
typedef boost::unordered_set<int, mod_compare, mod_compare> set;
|
||||
set set1(0, mod_compare(false), mod_compare(false));
|
||||
set set2(0, mod_compare(true), mod_compare(true));
|
||||
BOOST_TEST(set1 == set2);
|
||||
set1.insert(1); set2.insert(2);
|
||||
BOOST_TEST(set1 != set2);
|
||||
set1.insert(2); set2.insert(1);
|
||||
BOOST_TEST(set1 == set2);
|
||||
set1.insert(10); set2.insert(20);
|
||||
BOOST_TEST(set1 != set2);
|
||||
set1.insert(20); set2.insert(10);
|
||||
BOOST_TEST(set1 == set2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
@ -537,8 +537,6 @@ struct overloaded_constructor
|
||||
}
|
||||
};
|
||||
|
||||
// This will actually be deprecated pretty soon.
|
||||
|
||||
UNORDERED_AUTO_TEST(map_emplace_test)
|
||||
{
|
||||
boost::unordered_map<int, overloaded_constructor> x;
|
||||
@ -547,14 +545,15 @@ UNORDERED_AUTO_TEST(map_emplace_test)
|
||||
BOOST_TEST(x.find(0) != x.end() &&
|
||||
x.find(0)->second == overloaded_constructor());
|
||||
|
||||
x.emplace(1);
|
||||
BOOST_TEST(x.find(1) != x.end() &&
|
||||
x.find(1)->second == overloaded_constructor());
|
||||
|
||||
x.emplace(2, 3);
|
||||
BOOST_TEST(x.find(2) != x.end() &&
|
||||
x.find(2)->second == overloaded_constructor(3));
|
||||
|
||||
#if defined (BOOST_UNORDERED_DEPRECATED_PAIR_CONSTRUCT)
|
||||
x.emplace(1);
|
||||
BOOST_TEST(x.find(1) != x.end() &&
|
||||
x.find(1)->second == overloaded_constructor());
|
||||
|
||||
x.emplace(4, 5, 6);
|
||||
BOOST_TEST(x.find(4) != x.end() &&
|
||||
x.find(4)->second == overloaded_constructor(5, 6));
|
||||
@ -562,6 +561,7 @@ UNORDERED_AUTO_TEST(map_emplace_test)
|
||||
x.emplace(7, 8, 9, 10);
|
||||
BOOST_TEST(x.find(7) != x.end() &&
|
||||
x.find(7)->second == overloaded_constructor(8, 9, 10));
|
||||
#endif
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(set_emplace_test)
|
||||
@ -593,6 +593,37 @@ UNORDERED_AUTO_TEST(set_emplace_test)
|
||||
BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check);
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(map_emplace_test2)
|
||||
{
|
||||
boost::unordered_map<overloaded_constructor, overloaded_constructor> x;
|
||||
|
||||
x.emplace(boost::unordered::piecewise_construct, boost::make_tuple(), boost::make_tuple());
|
||||
BOOST_TEST(x.find(overloaded_constructor()) != x.end() &&
|
||||
x.find(overloaded_constructor())->second == overloaded_constructor());
|
||||
|
||||
x.emplace(boost::unordered::piecewise_construct, boost::make_tuple(1), boost::make_tuple());
|
||||
BOOST_TEST(x.find(overloaded_constructor(1)) != x.end() &&
|
||||
x.find(overloaded_constructor(1))->second == overloaded_constructor());
|
||||
|
||||
x.emplace(boost::unordered::piecewise_construct, boost::make_tuple(2,3), boost::make_tuple(4,5,6));
|
||||
BOOST_TEST(x.find(overloaded_constructor(2,3)) != x.end() &&
|
||||
x.find(overloaded_constructor(2,3))->second == overloaded_constructor(4,5,6));
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(set_emplace_test2)
|
||||
{
|
||||
boost::unordered_set<std::pair<overloaded_constructor, overloaded_constructor> > x;
|
||||
std::pair<overloaded_constructor, overloaded_constructor> check;
|
||||
|
||||
x.emplace(boost::unordered::piecewise_construct, boost::make_tuple(), boost::make_tuple());
|
||||
BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check);
|
||||
|
||||
x.clear();
|
||||
x.emplace(boost::unordered::piecewise_construct, boost::make_tuple(1), boost::make_tuple(2,3));
|
||||
check = std::make_pair(overloaded_constructor(1), overloaded_constructor(2, 3));;
|
||||
BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
|
89
test/unordered/minimal_allocator.cpp
Normal file
89
test/unordered/minimal_allocator.cpp
Normal file
@ -0,0 +1,89 @@
|
||||
|
||||
// Copyright 2011 Daniel James.
|
||||
// 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)
|
||||
|
||||
#include <boost/unordered/detail/allocator_helpers.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include "../objects/test.hpp"
|
||||
|
||||
template <class Tp>
|
||||
struct SimpleAllocator
|
||||
{
|
||||
typedef Tp value_type;
|
||||
|
||||
SimpleAllocator()
|
||||
{
|
||||
}
|
||||
|
||||
template <class T> SimpleAllocator(const SimpleAllocator<T>& other)
|
||||
{
|
||||
}
|
||||
|
||||
Tp *allocate(std::size_t n)
|
||||
{
|
||||
return static_cast<Tp*>(::operator new(n * sizeof(Tp)));
|
||||
}
|
||||
|
||||
void deallocate(Tp* p, std::size_t)
|
||||
{
|
||||
::operator delete((void*) p);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void test_simple_allocator()
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
typedef boost::unordered::detail::allocator_traits<
|
||||
SimpleAllocator<T> > traits;
|
||||
|
||||
BOOST_MPL_ASSERT((boost::is_same<typename traits::allocator_type, SimpleAllocator<T> >));
|
||||
|
||||
BOOST_MPL_ASSERT((boost::is_same<typename traits::value_type, T>));
|
||||
|
||||
BOOST_MPL_ASSERT((boost::is_same<typename traits::pointer, T* >));
|
||||
BOOST_MPL_ASSERT((boost::is_same<typename traits::const_pointer, T const*>));
|
||||
//BOOST_MPL_ASSERT((boost::is_same<typename traits::void_pointer, void* >));
|
||||
//BOOST_MPL_ASSERT((boost::is_same<typename traits::const_void_pointer, void const*>));
|
||||
|
||||
BOOST_MPL_ASSERT((boost::is_same<typename traits::difference_type, std::ptrdiff_t>));
|
||||
BOOST_MPL_ASSERT((boost::is_same<typename traits::size_type, std::size_t>));
|
||||
|
||||
BOOST_TEST(!traits::propagate_on_container_copy_assignment::value);
|
||||
BOOST_TEST(!traits::propagate_on_container_move_assignment::value);
|
||||
BOOST_TEST(!traits::propagate_on_container_swap::value);
|
||||
|
||||
// rebind_alloc
|
||||
// rebind_traits
|
||||
|
||||
SimpleAllocator<T> a;
|
||||
|
||||
T* ptr1 = traits::allocate(a, 1);
|
||||
//T* ptr2 = traits::allocate(a, 1, static_cast<void const*>(ptr1));
|
||||
|
||||
traits::construct(a, ptr1, T(10));
|
||||
//traits::construct(a, ptr2, T(30), ptr1);
|
||||
|
||||
BOOST_TEST(*ptr1 == T(10));
|
||||
//BOOST_TEST(*ptr2 == T(30));
|
||||
|
||||
traits::destroy(a, ptr1);
|
||||
//traits::destroy(a, ptr2);
|
||||
|
||||
//traits::deallocate(a, ptr2, 1);
|
||||
traits::deallocate(a, ptr1, 1);
|
||||
|
||||
traits::max_size(a);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_simple_allocator<int>();
|
||||
test_simple_allocator<test::object>();
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
|
||||
#include <iostream>
|
||||
// Copyright 2006-2009 Daniel James.
|
||||
// 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)
|
||||
@ -327,6 +327,13 @@ namespace unnecessary_copy_tests
|
||||
x.emplace();
|
||||
COPY_COUNT(2); MOVE_COUNT(0);
|
||||
|
||||
reset();
|
||||
x.emplace(boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(),
|
||||
boost::make_tuple());
|
||||
COPY_COUNT(2); MOVE_COUNT(0);
|
||||
|
||||
|
||||
//
|
||||
// 1 argument
|
||||
//
|
||||
@ -345,19 +352,23 @@ namespace unnecessary_copy_tests
|
||||
(defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ > 2) || \
|
||||
(defined(BOOST_MSVC) && BOOST_MSVC >= 1600 ) || \
|
||||
(!defined(__GNUC__) && !defined(BOOST_MSVC))
|
||||
|
||||
count_copies part;
|
||||
reset();
|
||||
std::pair<count_copies const&, count_copies const&> a_ref(part, part);
|
||||
x.emplace(a_ref);
|
||||
COPY_COUNT(2); MOVE_COUNT(0);
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_UNORDERED_STD_FORWARD_MOVE)
|
||||
|
||||
// No move should take place.
|
||||
// (since a is already in the container)
|
||||
reset();
|
||||
x.emplace(std::move(a));
|
||||
COPY_COUNT(0); MOVE_COUNT(0);
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
@ -382,6 +393,47 @@ namespace unnecessary_copy_tests
|
||||
reset();
|
||||
x.emplace(count_copies(b.first.tag_), count_copies(b.second.tag_));
|
||||
COPY_COUNT(2); MOVE_COUNT(0);
|
||||
|
||||
reset();
|
||||
x.emplace(boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(boost::ref(b.first)),
|
||||
boost::make_tuple(boost::ref(b.second)));
|
||||
COPY_COUNT(0); MOVE_COUNT(0);
|
||||
|
||||
#if !defined(BOOST_NO_0X_HDR_TUPLE) || defined(BOOST_HAS_TR1_TUPLE)
|
||||
|
||||
reset();
|
||||
x.emplace(boost::unordered::piecewise_construct,
|
||||
std::make_tuple(std::ref(b.first)),
|
||||
std::make_tuple(std::ref(b.second)));
|
||||
COPY_COUNT(0); MOVE_COUNT(0);
|
||||
|
||||
std::pair<count_copies const, count_copies> move_source_trial;
|
||||
reset();
|
||||
std::make_tuple(std::move(move_source_trial.first));
|
||||
std::make_tuple(std::move(move_source_trial.second));
|
||||
int tuple_move_cost = ::unnecessary_copy_tests::count_copies::moves;
|
||||
int tuple_copy_cost = ::unnecessary_copy_tests::count_copies::copies;
|
||||
|
||||
std::pair<count_copies const, count_copies> move_source;
|
||||
reset();
|
||||
x.emplace(boost::unordered::piecewise_construct,
|
||||
std::make_tuple(std::move(move_source.first)),
|
||||
std::make_tuple(std::move(move_source.second)));
|
||||
COPY_COUNT(tuple_copy_cost);
|
||||
MOVE_COUNT(tuple_move_cost);
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ > 4 || \
|
||||
defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ >= 6
|
||||
reset();
|
||||
x.emplace(boost::unordered::piecewise_construct,
|
||||
std::forward_as_tuple(b.first),
|
||||
std::forward_as_tuple(b.second));
|
||||
COPY_COUNT(0); MOVE_COUNT(0);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user