mirror of
https://github.com/boostorg/unordered.git
synced 2025-06-25 11:51:33 +02:00
Compare commits
12 Commits
svn-trunk
...
boost-1.37
Author | SHA1 | Date | |
---|---|---|---|
20c13e346e | |||
89ab17cce5 | |||
517e39fc23 | |||
93141c26b9 | |||
dd2a994874 | |||
6571648bac | |||
f20f72bade | |||
4e4f99d51f | |||
56b9e0da1a | |||
4f27a146ef | |||
c8d0cb88ad | |||
5a898f2419 |
@ -1,3 +1,8 @@
|
||||
<!--
|
||||
Copyright Daniel James 2008
|
||||
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)
|
||||
-->
|
||||
<section id="unordered.bibliography">
|
||||
<title>Bibliography</title>
|
||||
<bibliography>
|
||||
|
@ -10,7 +10,7 @@
|
||||
Initial review version, for the review conducted from 7th December 2007 to
|
||||
16th December 2007.
|
||||
|
||||
[h2 1.35.0 Add-on - 31st Match 2008]
|
||||
[h2 1.35.0 Add-on - 31st March 2008]
|
||||
|
||||
Unofficial release uploaded to vault, to be used with Boost 1.35.0. Incorporated
|
||||
many of the suggestions from the review.
|
||||
@ -31,7 +31,15 @@ First official release.
|
||||
* Emplace support when rvalue references and variadic template are available.
|
||||
* More efficient node allocation when rvalue references and variadic template
|
||||
are available.
|
||||
* Added equality operators and hash functions
|
||||
([@http://svn.boost.org/trac/boost/ticket/1557 Ticket 1557]).
|
||||
* Added equality operators.
|
||||
|
||||
[h2 Boost 1.37.0]
|
||||
|
||||
* Rename overload of `emplace` with hint, to `emplace_hint` as specified in
|
||||
[@http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2691.pdf n2691].
|
||||
* Provide forwarding headers at `<boost/unordered/unordered_map_fwd.hpp>` and
|
||||
`<boost/unordered/unordered_set_fwd.hpp>`.
|
||||
* Move all the implementation inside `boost/unordered`, to assist
|
||||
modularization and hopefully make it easier to track changes in subversion.
|
||||
|
||||
[endsect]
|
||||
|
@ -72,7 +72,7 @@
|
||||
[
|
||||
[Can be compared using the `==`, `!=`, `<`, `<=`, `>`, `>=` operators.]
|
||||
[No comparison operators are defined in the standard, although
|
||||
[link unordered.rationale.equality_operator
|
||||
[link unordered.rationale.equality_operators
|
||||
implementations might extend the containers to support `==` and
|
||||
`!=`].]
|
||||
]
|
||||
|
@ -23,8 +23,8 @@ but not the equality predicate. For example, if you wanted to use the
|
||||
[import src_code/dictionary.cpp]
|
||||
[case_sensitive_dictionary_fnv]
|
||||
|
||||
An example implementation of FNV-1, and some other hash functions are supplied
|
||||
in the examples directory.
|
||||
There is an [@../../libs/unordered/examples/fnv1.hpp implementation
|
||||
of FNV-1] in the examples directory.
|
||||
|
||||
If you wish to use a different equality function,
|
||||
you will also need to use a matching hash function. For
|
||||
|
@ -9,7 +9,7 @@
|
||||
[@http://www.boost.org/doc/html/boost_tr1.html
|
||||
Boost.TR1]]
|
||||
[def __draft__
|
||||
[@http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2007/n2461.pdf
|
||||
[@http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2691.pdf
|
||||
Working Draft of the C++ Standard]]
|
||||
[def __hash-table__ [@http://en.wikipedia.org/wiki/Hash_table
|
||||
hash table]]
|
||||
@ -36,9 +36,7 @@ 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__, (it doesn't support `emplace` yet, see the [link
|
||||
unordered.rationale.future_developments Implementation Rationale] section for more
|
||||
details). If accepted the containers should also be added to __boost-tr1__.
|
||||
the __draft__.
|
||||
|
||||
`unordered_set` and `unordered_multiset` are defined in the header
|
||||
<[headerref boost/unordered_set.hpp]>
|
||||
|
@ -96,6 +96,15 @@ efficiency advantage of power of 2 hash tables.
|
||||
|
||||
So, this implementation uses a prime number for the hash table size.
|
||||
|
||||
[h2 Equality operators]
|
||||
|
||||
`operator==` and `operator!=` are not included in the standard, but I've
|
||||
added them as I think they could be useful and can be efficiently
|
||||
implemented. They are specified
|
||||
differently to the standard associative containers, comparing keys
|
||||
using the equality predicate rather than `operator==`. This is inconsistent
|
||||
with the other containers but it is probably closer to user's expectations.
|
||||
|
||||
[h2 Active Issues and Proposals]
|
||||
|
||||
[h3 Removing unused allocator functions]
|
||||
@ -181,32 +190,14 @@ It is not specified if `unordered_multiset` and `unordered_multimap` preserve th
|
||||
of elements with equivalent keys (i.e. if they're stable under `insert` and `erase`).
|
||||
This is [@http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#518 issue 581].
|
||||
The current proposal is that insert, erase and rehash are stable - so they are here.
|
||||
(Update: during the release of this version, this requirement was added to
|
||||
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2691.pdf
|
||||
the lastest working draft]).
|
||||
|
||||
[h3 const_local_iterator cbegin, cend missing from TR1]
|
||||
|
||||
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2482.html#691
|
||||
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2684.html#691
|
||||
Issue 691] is that `cbegin` and `cend` are missing for local iterators.
|
||||
The current resolution is that they'll be added, so I've added them.
|
||||
|
||||
[h2 Future Developments]
|
||||
|
||||
[h3 Support for `emplace`]
|
||||
|
||||
In __n2369__ a new member function, `emplace` was added to the containers to
|
||||
allow placement insert, as described in __n2345__. To fully implement this
|
||||
`std::forward` is required, along with new functions in `std::allocator` and
|
||||
new constructors in `std::pair`. But partial support is possible - especially
|
||||
if I don't use the `construct` member of allocators.
|
||||
|
||||
[h3 Equality operator]
|
||||
|
||||
While `operator==` and `operator!=` are not included in the standard, it's
|
||||
possible to implement them for all the containers - this is helped by having
|
||||
stable order of elements with equivalent keys. They will need to be specified
|
||||
differently to the standard associative containers, probably comparing keys
|
||||
using the equality predicate rather than `operator==`. This is inconsistent
|
||||
with the other containers but it is probably closer to user's expectations.
|
||||
|
||||
If these are added then a `hash_value` free function should also be added.
|
||||
|
||||
[endsect]
|
||||
|
138
doc/ref.xml
138
doc/ref.xml
@ -24,7 +24,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</purpose>
|
||||
<description>
|
||||
<para>For the normative reference see chapter 23 of
|
||||
<ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2461.pdf">the working draft of the C++ standard [n2461].</ulink></para>
|
||||
<ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2691.pdf">the working draft of the C++ standard [n2691].</ulink></para>
|
||||
<para><emphasis role="bold">Template Parameters</emphasis>
|
||||
<informaltable>
|
||||
<tgroup cols="2">
|
||||
@ -181,7 +181,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<para>The copy constructor. Copies the contained elements, hash function, predicate, maximum load factor and allocator.</para>
|
||||
</description>
|
||||
</constructor>
|
||||
<constructor>
|
||||
<constructor specifiers="explicit">
|
||||
<parameter name="a">
|
||||
<paramtype>Allocator const&</paramtype>
|
||||
</parameter>
|
||||
@ -284,9 +284,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<notes>
|
||||
<para>Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.</para>
|
||||
<para>Pointers and references to elements are never invalidated.</para>
|
||||
<para>Only available on compilers with support for variadic template arguments and rvalue references.</para>
|
||||
</notes>
|
||||
</method>
|
||||
<method name="emplace">
|
||||
<method name="emplace_hint">
|
||||
<template>
|
||||
<template-type-parameter name="Args" pack="1">
|
||||
</template-type-parameter>
|
||||
@ -312,6 +313,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<para>The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same value. </para>
|
||||
<para>Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.</para>
|
||||
<para>Pointers and references to elements are never invalidated.</para>
|
||||
<para>Only available on compilers with support for variadic template arguments and rvalue references.</para>
|
||||
</notes>
|
||||
</method>
|
||||
<method name="insert">
|
||||
@ -636,10 +638,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<parameter name="z">
|
||||
<paramtype>float</paramtype>
|
||||
</parameter>
|
||||
<type>float</type>
|
||||
<returns>
|
||||
<type>void</type>
|
||||
<effects>
|
||||
<para>Changes the container's maximum load factor, using <code>z</code> as a hint.</para>
|
||||
</returns>
|
||||
</effects>
|
||||
</method>
|
||||
<method name="rehash">
|
||||
<parameter name="n">
|
||||
@ -700,25 +702,6 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<para>This is a boost extension.</para>
|
||||
</notes>
|
||||
</function>
|
||||
<function name="hash_value">
|
||||
<template>
|
||||
<template-type-parameter name="Value">
|
||||
</template-type-parameter>
|
||||
<template-type-parameter name="Hash">
|
||||
</template-type-parameter>
|
||||
<template-type-parameter name="Pred">
|
||||
</template-type-parameter>
|
||||
<template-type-parameter name="Alloc">
|
||||
</template-type-parameter>
|
||||
</template>
|
||||
<parameter name="x">
|
||||
<paramtype>unordered_set<Value, Hash, Pred, Alloc> const&</paramtype>
|
||||
</parameter>
|
||||
<type>std::size_t</type>
|
||||
<notes>
|
||||
<para>This is a boost extension.</para>
|
||||
</notes>
|
||||
</function>
|
||||
</free-function-group>
|
||||
<free-function-group name="swap">
|
||||
<function name="swap">
|
||||
@ -771,7 +754,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</purpose>
|
||||
<description>
|
||||
<para>For the normative reference see chapter 23 of
|
||||
<ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2461.pdf">the working draft of the C++ standard [n2461].</ulink></para>
|
||||
<ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2691.pdf">the working draft of the C++ standard [n2691].</ulink></para>
|
||||
<para><emphasis role="bold">Template Parameters</emphasis>
|
||||
<informaltable>
|
||||
<tgroup cols="2">
|
||||
@ -928,7 +911,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<para>The copy constructor. Copies the contained elements, hash function, predicate, maximum load factor and allocator.</para>
|
||||
</description>
|
||||
</constructor>
|
||||
<constructor>
|
||||
<constructor specifiers="explicit">
|
||||
<parameter name="a">
|
||||
<paramtype>Allocator const&</paramtype>
|
||||
</parameter>
|
||||
@ -1030,9 +1013,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<notes>
|
||||
<para>Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.</para>
|
||||
<para>Pointers and references to elements are never invalidated.</para>
|
||||
<para>Only available on compilers with support for variadic template arguments and rvalue references.</para>
|
||||
</notes>
|
||||
</method>
|
||||
<method name="emplace">
|
||||
<method name="emplace_hint">
|
||||
<template>
|
||||
<template-type-parameter name="Args" pack="1">
|
||||
</template-type-parameter>
|
||||
@ -1058,6 +1042,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<para>The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same value. </para>
|
||||
<para>Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.</para>
|
||||
<para>Pointers and references to elements are never invalidated.</para>
|
||||
<para>Only available on compilers with support for variadic template arguments and rvalue references.</para>
|
||||
</notes>
|
||||
</method>
|
||||
<method name="insert">
|
||||
@ -1381,10 +1366,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<parameter name="z">
|
||||
<paramtype>float</paramtype>
|
||||
</parameter>
|
||||
<type>float</type>
|
||||
<returns>
|
||||
<type>void</type>
|
||||
<effects>
|
||||
<para>Changes the container's maximum load factor, using <code>z</code> as a hint.</para>
|
||||
</returns>
|
||||
</effects>
|
||||
</method>
|
||||
<method name="rehash">
|
||||
<parameter name="n">
|
||||
@ -1445,25 +1430,6 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<para>This is a boost extension.</para>
|
||||
</notes>
|
||||
</function>
|
||||
<function name="hash_value">
|
||||
<template>
|
||||
<template-type-parameter name="Value">
|
||||
</template-type-parameter>
|
||||
<template-type-parameter name="Hash">
|
||||
</template-type-parameter>
|
||||
<template-type-parameter name="Pred">
|
||||
</template-type-parameter>
|
||||
<template-type-parameter name="Alloc">
|
||||
</template-type-parameter>
|
||||
</template>
|
||||
<parameter name="x">
|
||||
<paramtype>unordered_multiset<Value, Hash, Pred, Alloc> const&</paramtype>
|
||||
</parameter>
|
||||
<type>std::size_t</type>
|
||||
<notes>
|
||||
<para>This is a boost extension.</para>
|
||||
</notes>
|
||||
</function>
|
||||
</free-function-group>
|
||||
<free-function-group name="swap">
|
||||
<function name="swap">
|
||||
@ -1522,7 +1488,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</purpose>
|
||||
<description>
|
||||
<para>For the normative reference see chapter 23 of
|
||||
<ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2461.pdf">the working draft of the C++ standard [n2461].</ulink></para>
|
||||
<ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2691.pdf">the working draft of the C++ standard [n2691].</ulink></para>
|
||||
<para><emphasis role="bold">Template Parameters</emphasis>
|
||||
<informaltable>
|
||||
<tgroup cols="2">
|
||||
@ -1685,7 +1651,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<para>The copy constructor. Copies the contained elements, hash function, predicate, maximum load factor and allocator.</para>
|
||||
</description>
|
||||
</constructor>
|
||||
<constructor>
|
||||
<constructor specifiers="explicit">
|
||||
<parameter name="a">
|
||||
<paramtype>Allocator const&</paramtype>
|
||||
</parameter>
|
||||
@ -1788,9 +1754,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<notes>
|
||||
<para>Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.</para>
|
||||
<para>Pointers and references to elements are never invalidated.</para>
|
||||
<para>Only available on compilers with support for variadic template arguments and rvalue references.</para>
|
||||
</notes>
|
||||
</method>
|
||||
<method name="emplace">
|
||||
<method name="emplace_hint">
|
||||
<template>
|
||||
<template-type-parameter name="Args" pack="1">
|
||||
</template-type-parameter>
|
||||
@ -1816,6 +1783,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<para>The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. </para>
|
||||
<para>Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.</para>
|
||||
<para>Pointers and references to elements are never invalidated.</para>
|
||||
<para>Only available on compilers with support for variadic template arguments and rvalue references.</para>
|
||||
</notes>
|
||||
</method>
|
||||
<method name="insert">
|
||||
@ -2175,10 +2143,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<parameter name="z">
|
||||
<paramtype>float</paramtype>
|
||||
</parameter>
|
||||
<type>float</type>
|
||||
<returns>
|
||||
<type>void</type>
|
||||
<effects>
|
||||
<para>Changes the container's maximum load factor, using <code>z</code> as a hint.</para>
|
||||
</returns>
|
||||
</effects>
|
||||
</method>
|
||||
<method name="rehash">
|
||||
<parameter name="n">
|
||||
@ -2243,27 +2211,6 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<para>This is a boost extension.</para>
|
||||
</notes>
|
||||
</function>
|
||||
<function name="hash_value">
|
||||
<template>
|
||||
<template-type-parameter name="Key">
|
||||
</template-type-parameter>
|
||||
<template-type-parameter name="Mapped">
|
||||
</template-type-parameter>
|
||||
<template-type-parameter name="Hash">
|
||||
</template-type-parameter>
|
||||
<template-type-parameter name="Pred">
|
||||
</template-type-parameter>
|
||||
<template-type-parameter name="Alloc">
|
||||
</template-type-parameter>
|
||||
</template>
|
||||
<parameter name="x">
|
||||
<paramtype>unordered_map<Key, Mapped, Hash, Pred, Alloc> const&</paramtype>
|
||||
</parameter>
|
||||
<type>std::size_t</type>
|
||||
<notes>
|
||||
<para>This is a boost extension.</para>
|
||||
</notes>
|
||||
</function>
|
||||
</free-function-group>
|
||||
<free-function-group name="swap">
|
||||
<function name="swap">
|
||||
@ -2320,7 +2267,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</purpose>
|
||||
<description>
|
||||
<para>For the normative reference see chapter 23 of
|
||||
<ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2461.pdf">the working draft of the C++ standard [n2461].</ulink></para>
|
||||
<ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2691.pdf">the working draft of the C++ standard [n2691].</ulink></para>
|
||||
<para><emphasis role="bold">Template Parameters</emphasis>
|
||||
<informaltable>
|
||||
<tgroup cols="2">
|
||||
@ -2483,7 +2430,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<para>The copy constructor. Copies the contained elements, hash function, predicate, maximum load factor and allocator.</para>
|
||||
</description>
|
||||
</constructor>
|
||||
<constructor>
|
||||
<constructor specifiers="explicit">
|
||||
<parameter name="a">
|
||||
<paramtype>Allocator const&</paramtype>
|
||||
</parameter>
|
||||
@ -2585,9 +2532,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<notes>
|
||||
<para>Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.</para>
|
||||
<para>Pointers and references to elements are never invalidated.</para>
|
||||
<para>Only available on compilers with support for variadic template arguments and rvalue references.</para>
|
||||
</notes>
|
||||
</method>
|
||||
<method name="emplace">
|
||||
<method name="emplace_hint">
|
||||
<template>
|
||||
<template-type-parameter name="Args" pack="1">
|
||||
</template-type-parameter>
|
||||
@ -2613,6 +2561,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<para>The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. </para>
|
||||
<para>Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.</para>
|
||||
<para>Pointers and references to elements are never invalidated.</para>
|
||||
<para>Only available on compilers with support for variadic template arguments and rvalue references.</para>
|
||||
</notes>
|
||||
</method>
|
||||
<method name="insert">
|
||||
@ -2936,10 +2885,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<parameter name="z">
|
||||
<paramtype>float</paramtype>
|
||||
</parameter>
|
||||
<type>float</type>
|
||||
<returns>
|
||||
<type>void</type>
|
||||
<effects>
|
||||
<para>Changes the container's maximum load factor, using <code>z</code> as a hint.</para>
|
||||
</returns>
|
||||
</effects>
|
||||
</method>
|
||||
<method name="rehash">
|
||||
<parameter name="n">
|
||||
@ -3004,27 +2953,6 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<para>This is a boost extension.</para>
|
||||
</notes>
|
||||
</function>
|
||||
<function name="hash_value">
|
||||
<template>
|
||||
<template-type-parameter name="Key">
|
||||
</template-type-parameter>
|
||||
<template-type-parameter name="Mapped">
|
||||
</template-type-parameter>
|
||||
<template-type-parameter name="Hash">
|
||||
</template-type-parameter>
|
||||
<template-type-parameter name="Pred">
|
||||
</template-type-parameter>
|
||||
<template-type-parameter name="Alloc">
|
||||
</template-type-parameter>
|
||||
</template>
|
||||
<parameter name="x">
|
||||
<paramtype>unordered_multimap<Key, Mapped, Hash, Pred, Alloc> const&</paramtype>
|
||||
</parameter>
|
||||
<type>std::size_t</type>
|
||||
<notes>
|
||||
<para>This is a boost extension.</para>
|
||||
</notes>
|
||||
</function>
|
||||
</free-function-group>
|
||||
<free-function-group name="swap">
|
||||
<function name="swap">
|
||||
@ -3062,4 +2990,4 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</class>
|
||||
</namespace>
|
||||
</header>
|
||||
</library-reference>
|
||||
</library-reference>
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include "../../examples/hash_functions/fnv-1.hpp"
|
||||
#include "../../examples/fnv1.hpp"
|
||||
|
||||
//[case_insensitive_functions
|
||||
struct iequal_to
|
||||
|
66
examples/fnv1.hpp
Normal file
66
examples/fnv1.hpp
Normal file
@ -0,0 +1,66 @@
|
||||
|
||||
// Copyright 2008 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)
|
||||
|
||||
// This code is also released into the public domain.
|
||||
|
||||
// Algorithm from: http://www.isthe.com/chongo/tech/comp/fnv/
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace hash
|
||||
{
|
||||
template <std::size_t FnvPrime, std::size_t OffsetBasis>
|
||||
struct basic_fnv_1
|
||||
{
|
||||
std::size_t operator()(std::string const& text) const
|
||||
{
|
||||
std::size_t hash = OffsetBasis;
|
||||
for(std::string::const_iterator it = text.begin(), end = text.end();
|
||||
it != end; ++it)
|
||||
{
|
||||
hash *= FnvPrime;
|
||||
hash ^= *it;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
};
|
||||
|
||||
template <std::size_t FnvPrime, std::size_t OffsetBasis>
|
||||
struct basic_fnv_1a
|
||||
{
|
||||
std::size_t operator()(std::string const& text) const
|
||||
{
|
||||
std::size_t hash = OffsetBasis;
|
||||
for(std::string::const_iterator it = text.begin(), end = text.end();
|
||||
it != end; ++it)
|
||||
{
|
||||
hash ^= *it;
|
||||
hash *= FnvPrime;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
};
|
||||
|
||||
// For 32 bit machines:
|
||||
const std::size_t fnv_prime = 16777619u;
|
||||
const std::size_t fnv_offset_basis = 2166136261u;
|
||||
|
||||
// For 64 bit machines:
|
||||
// const std::size_t fnv_prime = 1099511628211u;
|
||||
// const std::size_t fnv_offset_basis = 14695981039346656037u;
|
||||
|
||||
// For 128 bit machines:
|
||||
// const std::size_t fnv_prime = 309485009821345068724781401u;
|
||||
// const std::size_t fnv_offset_basis = 275519064689413815358837431229664493455u;
|
||||
|
||||
// For 256 bit machines:
|
||||
// const std::size_t fnv_prime = 374144419156711147060143317175368453031918731002211u;
|
||||
// const std::size_t fnv_offset_basis = 100029257958052580907070968620625704837092796014241193945225284501741471925557u;
|
||||
|
||||
typedef basic_fnv_1<fnv_prime, fnv_offset_basis> fnv_1;
|
||||
typedef basic_fnv_1a<fnv_prime, fnv_offset_basis> fnv_1a;
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
// See: http://www.isthe.com/chongo/tech/comp/fnv/
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace hash
|
||||
{
|
||||
template <std::size_t FnvPrime, std::size_t OffsetBias>
|
||||
struct basic_fnv_1
|
||||
{
|
||||
std::size_t operator()(std::string const& text) const
|
||||
{
|
||||
std::size_t hash = OffsetBias;
|
||||
for(std::string::const_iterator it = text.begin(), end = text.end();
|
||||
it != end; ++it)
|
||||
{
|
||||
hash *= FnvPrime;
|
||||
hash ^= *it;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
};
|
||||
|
||||
template <std::size_t FnvPrime, std::size_t OffsetBias>
|
||||
struct basic_fnv_1a
|
||||
{
|
||||
std::size_t operator()(std::string const& text) const
|
||||
{
|
||||
std::size_t hash = OffsetBias;
|
||||
for(std::string::const_iterator it = text.begin(), end = text.end();
|
||||
it != end; ++it)
|
||||
{
|
||||
hash ^= *it;
|
||||
hash *= FnvPrime;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: Select Bias & Prime base on the size of std::size_t.
|
||||
//
|
||||
// 32 bit FNV_prime = 16777619
|
||||
// 64 bit FNV_prime = 1099511628211
|
||||
// 128 bit FNV_prime = 309485009821345068724781401
|
||||
// 256 bit FNV_prime = 374144419156711147060143317175368453031918731002211
|
||||
//
|
||||
// 32 bit offset_basis = 2166136261
|
||||
// 64 bit offset_basis = 14695981039346656037
|
||||
// 128 bit offset_basis = 275519064689413815358837431229664493455
|
||||
// 256 bit offset_basis = 100029257958052580907070968620625704837092796014241193945225284501741471925557
|
||||
|
||||
const std::size_t fnv_prime = 16777619;
|
||||
// 64 bit FNV_prime = 1099511628211
|
||||
// 128 bit FNV_prime = 309485009821345068724781401
|
||||
// 256 bit FNV_prime = 374144419156711147060143317175368453031918731002211
|
||||
|
||||
const std::size_t fnv_offset_bias = 2166136261u;
|
||||
// 64 bit offset_basis = 14695981039346656037
|
||||
// 128 bit offset_basis = 275519064689413815358837431229664493455
|
||||
// 256 bit offset_basis = 100029257958052580907070968620625704837092796014241193945225284501741471925557
|
||||
|
||||
typedef basic_fnv_1<fnv_prime, fnv_offset_bias> fnv_1;
|
||||
typedef basic_fnv_1a<fnv_prime, fnv_offset_bias> fnv_1a;
|
||||
|
||||
}
|
@ -14,7 +14,7 @@
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cmath>
|
||||
#include <boost/config/no_tr1/cmath.hpp>
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
#include <stdexcept>
|
||||
|
@ -1493,8 +1493,6 @@ namespace boost {
|
||||
/ static_cast<float>(data_.bucket_manager_.bucket_count());
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// key extractors
|
||||
|
||||
// no throw
|
||||
@ -2127,100 +2125,6 @@ namespace boost {
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// equals
|
||||
//
|
||||
|
||||
private:
|
||||
#if BOOST_UNORDERED_EQUIVALENT_KEYS
|
||||
static inline bool group_equals(link_ptr it1, link_ptr it2,
|
||||
type_wrapper<key_type>*)
|
||||
{
|
||||
return data::group_count(it1) == data::group_count(it2);
|
||||
}
|
||||
|
||||
static inline bool group_equals(link_ptr it1, link_ptr it2, void*)
|
||||
{
|
||||
link_ptr end1 = data::next_group(it1);
|
||||
link_ptr end2 = data::next_group(it2);
|
||||
do {
|
||||
if(data::get_value(it1).second != data::get_value(it2).second) return false;
|
||||
it1 = it1->next_;
|
||||
it2 = it2->next_;
|
||||
} while(it1 != end1 && it2 != end2);
|
||||
return it1 == end1 && it2 == end2;
|
||||
}
|
||||
#else
|
||||
static inline bool group_equals(link_ptr, link_ptr,
|
||||
type_wrapper<key_type>*)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool group_equals(link_ptr it1, link_ptr it2, void*)
|
||||
{
|
||||
return data::get_value(it1).second == data::get_value(it2).second;
|
||||
}
|
||||
#endif
|
||||
|
||||
public:
|
||||
bool equals(BOOST_UNORDERED_TABLE const& other) const
|
||||
{
|
||||
if(size() != other.size()) return false;
|
||||
|
||||
for(bucket_ptr i = data_.cached_begin_bucket_,
|
||||
j = data_.buckets_end(); i != j; ++i)
|
||||
{
|
||||
for(link_ptr it(i->next_); BOOST_UNORDERED_BORLAND_BOOL(it); it = data::next_group(it))
|
||||
{
|
||||
link_ptr other_pos = other.find_iterator(other.extract_key(data::get_value(it)));
|
||||
if(!BOOST_UNORDERED_BORLAND_BOOL(other_pos) ||
|
||||
!group_equals(it, other_pos, (type_wrapper<value_type>*)0))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline std::size_t group_hash(link_ptr it, type_wrapper<key_type>*) const
|
||||
{
|
||||
std::size_t seed = data::group_count(it);
|
||||
std::size_t hashed_key = hash_function()(data::get_value(it));
|
||||
boost::hash_combine(seed, hashed_key);
|
||||
return seed;
|
||||
}
|
||||
|
||||
inline std::size_t group_hash(link_ptr it, void*) const
|
||||
{
|
||||
std::size_t seed = hash_function()(data::get_value(it).first);
|
||||
|
||||
link_ptr end = data::next_group(it);
|
||||
|
||||
do {
|
||||
boost::hash_combine(seed, data::get_value(it).second);
|
||||
it = it->next_;
|
||||
} while(it != end);
|
||||
|
||||
return seed;
|
||||
}
|
||||
|
||||
std::size_t hash_value() const
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
|
||||
for(bucket_ptr i = data_.cached_begin_bucket_,
|
||||
j = data_.buckets_end(); i != j; ++i)
|
||||
{
|
||||
for(link_ptr it(i->next_); BOOST_UNORDERED_BORLAND_BOOL(it); it = data::next_group(it))
|
||||
seed ^= group_hash(it, (type_wrapper<value_type>*)0);
|
||||
}
|
||||
|
||||
return seed;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// strong exception safety, no side effects
|
||||
bool equal(key_type const& k, value_type const& v) const
|
||||
{
|
||||
@ -2255,6 +2159,92 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Equals - unordered container equality comparison.
|
||||
//
|
||||
|
||||
#if BOOST_UNORDERED_EQUIVALENT_KEYS
|
||||
template <typename A, typename KeyType>
|
||||
inline bool group_equals(
|
||||
BOOST_UNORDERED_TABLE_DATA<A>*,
|
||||
typename BOOST_UNORDERED_TABLE_DATA<A>::link_ptr it1,
|
||||
typename BOOST_UNORDERED_TABLE_DATA<A>::link_ptr it2,
|
||||
KeyType*,
|
||||
type_wrapper<KeyType>*)
|
||||
{
|
||||
typedef BOOST_UNORDERED_TABLE_DATA<A> data;
|
||||
return data::group_count(it1) == data::group_count(it2);
|
||||
}
|
||||
|
||||
template <typename A, typename KeyType>
|
||||
inline bool group_equals(
|
||||
BOOST_UNORDERED_TABLE_DATA<A>*,
|
||||
typename BOOST_UNORDERED_TABLE_DATA<A>::link_ptr it1,
|
||||
typename BOOST_UNORDERED_TABLE_DATA<A>::link_ptr it2,
|
||||
KeyType*,
|
||||
void*)
|
||||
{
|
||||
typedef BOOST_UNORDERED_TABLE_DATA<A> data;
|
||||
typename BOOST_UNORDERED_TABLE_DATA<A>::link_ptr end1 = data::next_group(it1);
|
||||
typename BOOST_UNORDERED_TABLE_DATA<A>::link_ptr end2 = data::next_group(it2);
|
||||
|
||||
do {
|
||||
if(data::get_value(it1).second != data::get_value(it2).second) return false;
|
||||
it1 = it1->next_;
|
||||
it2 = it2->next_;
|
||||
} while(it1 != end1 && it2 != end2);
|
||||
return it1 == end1 && it2 == end2;
|
||||
}
|
||||
#else
|
||||
template <typename A, typename KeyType>
|
||||
inline bool group_equals(
|
||||
BOOST_UNORDERED_TABLE_DATA<A>*,
|
||||
typename BOOST_UNORDERED_TABLE_DATA<A>::link_ptr,
|
||||
typename BOOST_UNORDERED_TABLE_DATA<A>::link_ptr,
|
||||
KeyType*,
|
||||
type_wrapper<KeyType>*)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename A, typename KeyType>
|
||||
inline bool group_equals(
|
||||
BOOST_UNORDERED_TABLE_DATA<A>*,
|
||||
typename BOOST_UNORDERED_TABLE_DATA<A>::link_ptr it1,
|
||||
typename BOOST_UNORDERED_TABLE_DATA<A>::link_ptr it2,
|
||||
KeyType*,
|
||||
void*)
|
||||
{
|
||||
typedef BOOST_UNORDERED_TABLE_DATA<A> data;
|
||||
return data::get_value(it1).second == data::get_value(it2).second;
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename V, typename K, typename H, typename P, typename A>
|
||||
bool equals(BOOST_UNORDERED_TABLE<V, K, H, P, A> const& t1,
|
||||
BOOST_UNORDERED_TABLE<V, K, H, P, A> const& t2)
|
||||
{
|
||||
typedef BOOST_UNORDERED_TABLE_DATA<A> data;
|
||||
typedef typename data::bucket_ptr bucket_ptr;
|
||||
typedef typename data::link_ptr link_ptr;
|
||||
|
||||
if(t1.size() != t2.size()) return false;
|
||||
|
||||
for(bucket_ptr i = t1.data_.cached_begin_bucket_,
|
||||
j = t1.data_.buckets_end(); i != j; ++i)
|
||||
{
|
||||
for(link_ptr it(i->next_); BOOST_UNORDERED_BORLAND_BOOL(it); it = data::next_group(it))
|
||||
{
|
||||
link_ptr other_pos = t2.find_iterator(t2.extract_key(data::get_value(it)));
|
||||
if(!BOOST_UNORDERED_BORLAND_BOOL(other_pos) ||
|
||||
!group_equals((data*)0, it, other_pos, (K*)0, (type_wrapper<V>*)0))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Iterators
|
||||
|
||||
template <typename Alloc> class BOOST_UNORDERED_ITERATOR;
|
||||
|
788
include/boost/unordered/unordered_map.hpp
Normal file
788
include/boost/unordered/unordered_map.hpp
Normal file
@ -0,0 +1,788 @@
|
||||
|
||||
// Copyright (C) 2003-2004 Jeremy B. Maitin-Shepard.
|
||||
// Copyright (C) 2005-2008 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)
|
||||
|
||||
// See http://www.boost.org/libs/unordered for documentation
|
||||
|
||||
#ifndef BOOST_UNORDERED_UNORDERED_MAP_HPP_INCLUDED
|
||||
#define BOOST_UNORDERED_UNORDERED_MAP_HPP_INCLUDED
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/unordered/unordered_map_fwd.hpp>
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/unordered/detail/hash_table.hpp>
|
||||
|
||||
#if !defined(BOOST_HAS_RVALUE_REFS)
|
||||
#include <boost/unordered/detail/move.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template <class Key, class T, class Hash, class Pred, class Alloc>
|
||||
class unordered_map
|
||||
{
|
||||
typedef boost::unordered_detail::hash_types_unique_keys<
|
||||
std::pair<const Key, T>, Key, Hash, Pred, Alloc
|
||||
> implementation;
|
||||
|
||||
BOOST_DEDUCED_TYPENAME implementation::hash_table base;
|
||||
|
||||
public:
|
||||
|
||||
// types
|
||||
|
||||
typedef Key key_type;
|
||||
typedef std::pair<const Key, T> value_type;
|
||||
typedef T mapped_type;
|
||||
typedef Hash hasher;
|
||||
typedef Pred key_equal;
|
||||
|
||||
typedef Alloc allocator_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_type::pointer pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_type::const_pointer const_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_type::reference reference;
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_type::const_reference const_reference;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::size_type size_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::difference_type difference_type;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::iterator iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::const_iterator const_iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::local_iterator local_iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::const_local_iterator const_local_iterator;
|
||||
|
||||
// construct/destroy/copy
|
||||
|
||||
explicit unordered_map(
|
||||
size_type n = boost::unordered_detail::default_initial_bucket_count,
|
||||
const hasher &hf = hasher(),
|
||||
const key_equal &eql = key_equal(),
|
||||
const allocator_type &a = allocator_type())
|
||||
: base(n, hf, eql, a)
|
||||
{
|
||||
}
|
||||
|
||||
explicit unordered_map(allocator_type const& a)
|
||||
: base(boost::unordered_detail::default_initial_bucket_count,
|
||||
hasher(), key_equal(), a)
|
||||
{
|
||||
}
|
||||
|
||||
unordered_map(unordered_map const& other, allocator_type const& a)
|
||||
: base(other.base, a)
|
||||
{
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
unordered_map(InputIterator f, InputIterator l)
|
||||
: base(f, l, boost::unordered_detail::default_initial_bucket_count,
|
||||
hasher(), key_equal(), allocator_type())
|
||||
{
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
unordered_map(InputIterator f, InputIterator l,
|
||||
size_type n,
|
||||
const hasher &hf = hasher(),
|
||||
const key_equal &eql = key_equal(),
|
||||
const allocator_type &a = allocator_type())
|
||||
: base(f, l, n, hf, eql, a)
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(BOOST_HAS_RVALUE_REFS)
|
||||
unordered_map(unordered_map&& other)
|
||||
: base(other.base, boost::unordered_detail::move_tag())
|
||||
{
|
||||
}
|
||||
|
||||
unordered_map(unordered_map&& other, allocator_type const& a)
|
||||
: base(other.base, a, boost::unordered_detail::move_tag())
|
||||
{
|
||||
}
|
||||
|
||||
unordered_map& operator=(unordered_map&& x)
|
||||
{
|
||||
base.move(x.base);
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
unordered_map(boost::unordered_detail::move_from<unordered_map<Key, T, Hash, Pred, Alloc> > other)
|
||||
: base(other.source.base, boost::unordered_detail::move_tag())
|
||||
{
|
||||
}
|
||||
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, < 0x0593)
|
||||
unordered_map& operator=(unordered_map x)
|
||||
{
|
||||
base.move(x.base);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
BOOST_DEDUCED_TYPENAME implementation::iterator_base const&
|
||||
get(const_iterator const& it)
|
||||
{
|
||||
return boost::unordered_detail::iterator_access::get(it);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
allocator_type get_allocator() const
|
||||
{
|
||||
return base.get_allocator();
|
||||
}
|
||||
|
||||
// size and capacity
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return base.empty();
|
||||
}
|
||||
|
||||
size_type size() const
|
||||
{
|
||||
return base.size();
|
||||
}
|
||||
|
||||
size_type max_size() const
|
||||
{
|
||||
return base.max_size();
|
||||
}
|
||||
|
||||
// iterators
|
||||
|
||||
iterator begin()
|
||||
{
|
||||
return iterator(base.data_.begin());
|
||||
}
|
||||
|
||||
const_iterator begin() const
|
||||
{
|
||||
return const_iterator(base.data_.begin());
|
||||
}
|
||||
|
||||
iterator end()
|
||||
{
|
||||
return iterator(base.data_.end());
|
||||
}
|
||||
|
||||
const_iterator end() const
|
||||
{
|
||||
return const_iterator(base.data_.end());
|
||||
}
|
||||
|
||||
const_iterator cbegin() const
|
||||
{
|
||||
return const_iterator(base.data_.begin());
|
||||
}
|
||||
|
||||
const_iterator cend() const
|
||||
{
|
||||
return const_iterator(base.data_.end());
|
||||
}
|
||||
|
||||
// modifiers
|
||||
|
||||
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
||||
template <class... Args>
|
||||
std::pair<iterator, bool> emplace(Args&&... args)
|
||||
{
|
||||
return boost::unordered_detail::pair_cast<iterator, bool>(
|
||||
base.insert(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
iterator emplace_hint(const_iterator hint, Args&&... args)
|
||||
{
|
||||
return iterator(base.insert_hint(get(hint), std::forward<Args>(args)...));
|
||||
}
|
||||
#endif
|
||||
|
||||
std::pair<iterator, bool> insert(const value_type& obj)
|
||||
{
|
||||
return boost::unordered_detail::pair_cast<iterator, bool>(
|
||||
base.insert(obj));
|
||||
}
|
||||
|
||||
iterator insert(const_iterator hint, const value_type& obj)
|
||||
{
|
||||
return iterator(base.insert_hint(get(hint), obj));
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
void insert(InputIterator first, InputIterator last)
|
||||
{
|
||||
base.insert_range(first, last);
|
||||
}
|
||||
|
||||
iterator erase(const_iterator position)
|
||||
{
|
||||
return iterator(base.data_.erase(get(position)));
|
||||
}
|
||||
|
||||
size_type erase(const key_type& k)
|
||||
{
|
||||
return base.erase_key(k);
|
||||
}
|
||||
|
||||
iterator erase(const_iterator first, const_iterator last)
|
||||
{
|
||||
return iterator(base.data_.erase_range(get(first), get(last)));
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
base.data_.clear();
|
||||
}
|
||||
|
||||
void swap(unordered_map& other)
|
||||
{
|
||||
base.swap(other.base);
|
||||
}
|
||||
|
||||
// observers
|
||||
|
||||
hasher hash_function() const
|
||||
{
|
||||
return base.hash_function();
|
||||
}
|
||||
|
||||
key_equal key_eq() const
|
||||
{
|
||||
return base.key_eq();
|
||||
}
|
||||
|
||||
mapped_type& operator[](const key_type &k)
|
||||
{
|
||||
return base[k].second;
|
||||
}
|
||||
|
||||
mapped_type& at(const key_type& k)
|
||||
{
|
||||
return base.at(k).second;
|
||||
}
|
||||
|
||||
mapped_type const& at(const key_type& k) const
|
||||
{
|
||||
return base.at(k).second;
|
||||
}
|
||||
|
||||
// lookup
|
||||
|
||||
iterator find(const key_type& k)
|
||||
{
|
||||
return iterator(base.find(k));
|
||||
}
|
||||
|
||||
const_iterator find(const key_type& k) const
|
||||
{
|
||||
return const_iterator(base.find(k));
|
||||
}
|
||||
|
||||
size_type count(const key_type& k) const
|
||||
{
|
||||
return base.count(k);
|
||||
}
|
||||
|
||||
std::pair<iterator, iterator>
|
||||
equal_range(const key_type& k)
|
||||
{
|
||||
return boost::unordered_detail::pair_cast<iterator, iterator>(
|
||||
base.equal_range(k));
|
||||
}
|
||||
|
||||
std::pair<const_iterator, const_iterator>
|
||||
equal_range(const key_type& k) const
|
||||
{
|
||||
return boost::unordered_detail::pair_cast<const_iterator, const_iterator>(
|
||||
base.equal_range(k));
|
||||
}
|
||||
|
||||
// bucket interface
|
||||
|
||||
size_type bucket_count() const
|
||||
{
|
||||
return base.bucket_count();
|
||||
}
|
||||
|
||||
size_type max_bucket_count() const
|
||||
{
|
||||
return base.max_bucket_count();
|
||||
}
|
||||
|
||||
size_type bucket_size(size_type n) const
|
||||
{
|
||||
return base.data_.bucket_size(n);
|
||||
}
|
||||
|
||||
size_type bucket(const key_type& k) const
|
||||
{
|
||||
return base.bucket(k);
|
||||
}
|
||||
|
||||
local_iterator begin(size_type n)
|
||||
{
|
||||
return local_iterator(base.data_.begin(n));
|
||||
}
|
||||
|
||||
const_local_iterator begin(size_type n) const
|
||||
{
|
||||
return const_local_iterator(base.data_.begin(n));
|
||||
}
|
||||
|
||||
local_iterator end(size_type n)
|
||||
{
|
||||
return local_iterator(base.data_.end(n));
|
||||
}
|
||||
|
||||
const_local_iterator end(size_type n) const
|
||||
{
|
||||
return const_local_iterator(base.data_.end(n));
|
||||
}
|
||||
|
||||
const_local_iterator cbegin(size_type n) const
|
||||
{
|
||||
return const_local_iterator(base.data_.begin(n));
|
||||
}
|
||||
|
||||
const_local_iterator cend(size_type n) const
|
||||
{
|
||||
return const_local_iterator(base.data_.end(n));
|
||||
}
|
||||
|
||||
// hash policy
|
||||
|
||||
float load_factor() const
|
||||
{
|
||||
return base.load_factor();
|
||||
}
|
||||
|
||||
float max_load_factor() const
|
||||
{
|
||||
return base.max_load_factor();
|
||||
}
|
||||
|
||||
void max_load_factor(float m)
|
||||
{
|
||||
base.max_load_factor(m);
|
||||
}
|
||||
|
||||
void rehash(size_type n)
|
||||
{
|
||||
base.rehash(n);
|
||||
}
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
friend bool operator==(unordered_map const&, unordered_map const&);
|
||||
friend bool operator!=(unordered_map const&, unordered_map const&);
|
||||
#else
|
||||
friend bool operator==<>(unordered_map const&, unordered_map const&);
|
||||
friend bool operator!=<>(unordered_map const&, unordered_map const&);
|
||||
#endif
|
||||
}; // class template unordered_map
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
inline bool operator==(unordered_map<K, T, H, P, A> const& m1,
|
||||
unordered_map<K, T, H, P, A> const& m2)
|
||||
{
|
||||
return boost::unordered_detail::equals(m1.base, m2.base);
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
inline bool operator!=(unordered_map<K, T, H, P, A> const& m1,
|
||||
unordered_map<K, T, H, P, A> const& m2)
|
||||
{
|
||||
return !boost::unordered_detail::equals(m1.base, m2.base);
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
inline void swap(unordered_map<K, T, H, P, A> &m1,
|
||||
unordered_map<K, T, H, P, A> &m2)
|
||||
{
|
||||
m1.swap(m2);
|
||||
}
|
||||
|
||||
template <class Key, class T, class Hash, class Pred, class Alloc>
|
||||
class unordered_multimap
|
||||
{
|
||||
typedef boost::unordered_detail::hash_types_equivalent_keys<
|
||||
std::pair<const Key, T>, Key, Hash, Pred, Alloc
|
||||
> implementation;
|
||||
|
||||
BOOST_DEDUCED_TYPENAME implementation::hash_table base;
|
||||
|
||||
public:
|
||||
|
||||
// types
|
||||
|
||||
typedef Key key_type;
|
||||
typedef std::pair<const Key, T> value_type;
|
||||
typedef T mapped_type;
|
||||
typedef Hash hasher;
|
||||
typedef Pred key_equal;
|
||||
|
||||
typedef Alloc allocator_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_type::pointer pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_type::const_pointer const_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_type::reference reference;
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_type::const_reference const_reference;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::size_type size_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::difference_type difference_type;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::iterator iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::const_iterator const_iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::local_iterator local_iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::const_local_iterator const_local_iterator;
|
||||
|
||||
// construct/destroy/copy
|
||||
|
||||
explicit unordered_multimap(
|
||||
size_type n = boost::unordered_detail::default_initial_bucket_count,
|
||||
const hasher &hf = hasher(),
|
||||
const key_equal &eql = key_equal(),
|
||||
const allocator_type &a = allocator_type())
|
||||
: base(n, hf, eql, a)
|
||||
{
|
||||
}
|
||||
|
||||
explicit unordered_multimap(allocator_type const& a)
|
||||
: base(boost::unordered_detail::default_initial_bucket_count,
|
||||
hasher(), key_equal(), a)
|
||||
{
|
||||
}
|
||||
|
||||
unordered_multimap(unordered_multimap const& other, allocator_type const& a)
|
||||
: base(other.base, a)
|
||||
{
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
unordered_multimap(InputIterator f, InputIterator l)
|
||||
: base(f, l, boost::unordered_detail::default_initial_bucket_count,
|
||||
hasher(), key_equal(), allocator_type())
|
||||
{
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
unordered_multimap(InputIterator f, InputIterator l,
|
||||
size_type n,
|
||||
const hasher &hf = hasher(),
|
||||
const key_equal &eql = key_equal(),
|
||||
const allocator_type &a = allocator_type())
|
||||
: base(f, l, n, hf, eql, a)
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(BOOST_HAS_RVALUE_REFS)
|
||||
unordered_multimap(unordered_multimap&& other)
|
||||
: base(other.base, boost::unordered_detail::move_tag())
|
||||
{
|
||||
}
|
||||
|
||||
unordered_multimap(unordered_multimap&& other, allocator_type const& a)
|
||||
: base(other.base, a, boost::unordered_detail::move_tag())
|
||||
{
|
||||
}
|
||||
|
||||
unordered_multimap& operator=(unordered_multimap&& x)
|
||||
{
|
||||
base.move(x.base);
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
unordered_multimap(boost::unordered_detail::move_from<unordered_multimap<Key, T, Hash, Pred, Alloc> > other)
|
||||
: base(other.source.base, boost::unordered_detail::move_tag())
|
||||
{
|
||||
}
|
||||
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, < 0x0593)
|
||||
unordered_multimap& operator=(unordered_multimap x)
|
||||
{
|
||||
base.move(x.base);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
private:
|
||||
|
||||
BOOST_DEDUCED_TYPENAME implementation::iterator_base const&
|
||||
get(const_iterator const& it)
|
||||
{
|
||||
return boost::unordered_detail::iterator_access::get(it);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
allocator_type get_allocator() const
|
||||
{
|
||||
return base.get_allocator();
|
||||
}
|
||||
|
||||
// size and capacity
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return base.empty();
|
||||
}
|
||||
|
||||
size_type size() const
|
||||
{
|
||||
return base.size();
|
||||
}
|
||||
|
||||
size_type max_size() const
|
||||
{
|
||||
return base.max_size();
|
||||
}
|
||||
|
||||
// iterators
|
||||
|
||||
iterator begin()
|
||||
{
|
||||
return iterator(base.data_.begin());
|
||||
}
|
||||
|
||||
const_iterator begin() const
|
||||
{
|
||||
return const_iterator(base.data_.begin());
|
||||
}
|
||||
|
||||
iterator end()
|
||||
{
|
||||
return iterator(base.data_.end());
|
||||
}
|
||||
|
||||
const_iterator end() const
|
||||
{
|
||||
return const_iterator(base.data_.end());
|
||||
}
|
||||
|
||||
const_iterator cbegin() const
|
||||
{
|
||||
return const_iterator(base.data_.begin());
|
||||
}
|
||||
|
||||
const_iterator cend() const
|
||||
{
|
||||
return const_iterator(base.data_.end());
|
||||
}
|
||||
|
||||
// modifiers
|
||||
|
||||
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
||||
template <class... Args>
|
||||
iterator emplace(Args&&... args)
|
||||
{
|
||||
return iterator(base.insert(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
iterator emplace_hint(const_iterator hint, Args&&... args)
|
||||
{
|
||||
return iterator(base.insert_hint(get(hint), std::forward<Args>(args)...));
|
||||
}
|
||||
#endif
|
||||
|
||||
iterator insert(const value_type& obj)
|
||||
{
|
||||
return iterator(base.insert(obj));
|
||||
}
|
||||
|
||||
iterator insert(const_iterator hint, const value_type& obj)
|
||||
{
|
||||
return iterator(base.insert_hint(get(hint), obj));
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
void insert(InputIterator first, InputIterator last)
|
||||
{
|
||||
base.insert_range(first, last);
|
||||
}
|
||||
|
||||
iterator erase(const_iterator position)
|
||||
{
|
||||
return iterator(base.data_.erase(get(position)));
|
||||
}
|
||||
|
||||
size_type erase(const key_type& k)
|
||||
{
|
||||
return base.erase_key(k);
|
||||
}
|
||||
|
||||
iterator erase(const_iterator first, const_iterator last)
|
||||
{
|
||||
return iterator(base.data_.erase_range(get(first), get(last)));
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
base.data_.clear();
|
||||
}
|
||||
|
||||
void swap(unordered_multimap& other)
|
||||
{
|
||||
base.swap(other.base);
|
||||
}
|
||||
|
||||
// observers
|
||||
|
||||
hasher hash_function() const
|
||||
{
|
||||
return base.hash_function();
|
||||
}
|
||||
|
||||
key_equal key_eq() const
|
||||
{
|
||||
return base.key_eq();
|
||||
}
|
||||
|
||||
// lookup
|
||||
|
||||
iterator find(const key_type& k)
|
||||
{
|
||||
return iterator(base.find(k));
|
||||
}
|
||||
|
||||
const_iterator find(const key_type& k) const
|
||||
{
|
||||
return const_iterator(base.find(k));
|
||||
}
|
||||
|
||||
size_type count(const key_type& k) const
|
||||
{
|
||||
return base.count(k);
|
||||
}
|
||||
|
||||
std::pair<iterator, iterator>
|
||||
equal_range(const key_type& k)
|
||||
{
|
||||
return boost::unordered_detail::pair_cast<iterator, iterator>(
|
||||
base.equal_range(k));
|
||||
}
|
||||
|
||||
std::pair<const_iterator, const_iterator>
|
||||
equal_range(const key_type& k) const
|
||||
{
|
||||
return boost::unordered_detail::pair_cast<const_iterator, const_iterator>(
|
||||
base.equal_range(k));
|
||||
}
|
||||
|
||||
// bucket interface
|
||||
|
||||
size_type bucket_count() const
|
||||
{
|
||||
return base.bucket_count();
|
||||
}
|
||||
|
||||
size_type max_bucket_count() const
|
||||
{
|
||||
return base.max_bucket_count();
|
||||
}
|
||||
|
||||
size_type bucket_size(size_type n) const
|
||||
{
|
||||
return base.data_.bucket_size(n);
|
||||
}
|
||||
|
||||
size_type bucket(const key_type& k) const
|
||||
{
|
||||
return base.bucket(k);
|
||||
}
|
||||
|
||||
local_iterator begin(size_type n)
|
||||
{
|
||||
return local_iterator(base.data_.begin(n));
|
||||
}
|
||||
|
||||
const_local_iterator begin(size_type n) const
|
||||
{
|
||||
return const_local_iterator(base.data_.begin(n));
|
||||
}
|
||||
|
||||
local_iterator end(size_type n)
|
||||
{
|
||||
return local_iterator(base.data_.end(n));
|
||||
}
|
||||
|
||||
const_local_iterator end(size_type n) const
|
||||
{
|
||||
return const_local_iterator(base.data_.end(n));
|
||||
}
|
||||
|
||||
const_local_iterator cbegin(size_type n) const
|
||||
{
|
||||
return const_local_iterator(base.data_.begin(n));
|
||||
}
|
||||
|
||||
const_local_iterator cend(size_type n) const
|
||||
{
|
||||
return const_local_iterator(base.data_.end(n));
|
||||
}
|
||||
|
||||
// hash policy
|
||||
|
||||
float load_factor() const
|
||||
{
|
||||
return base.load_factor();
|
||||
}
|
||||
|
||||
float max_load_factor() const
|
||||
{
|
||||
return base.max_load_factor();
|
||||
}
|
||||
|
||||
void max_load_factor(float m)
|
||||
{
|
||||
base.max_load_factor(m);
|
||||
}
|
||||
|
||||
void rehash(size_type n)
|
||||
{
|
||||
base.rehash(n);
|
||||
}
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
friend bool operator==(unordered_multimap const&, unordered_multimap const&);
|
||||
friend bool operator!=(unordered_multimap const&, unordered_multimap const&);
|
||||
#else
|
||||
friend bool operator==<>(unordered_multimap const&, unordered_multimap const&);
|
||||
friend bool operator!=<>(unordered_multimap const&, unordered_multimap const&);
|
||||
#endif
|
||||
}; // class template unordered_multimap
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
inline bool operator==(unordered_multimap<K, T, H, P, A> const& m1,
|
||||
unordered_multimap<K, T, H, P, A> const& m2)
|
||||
{
|
||||
return boost::unordered_detail::equals(m1.base, m2.base);
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
inline bool operator!=(unordered_multimap<K, T, H, P, A> const& m1,
|
||||
unordered_multimap<K, T, H, P, A> const& m2)
|
||||
{
|
||||
return !boost::unordered_detail::equals(m1.base, m2.base);
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
inline void swap(unordered_multimap<K, T, H, P, A> &m1,
|
||||
unordered_multimap<K, T, H, P, A> &m2)
|
||||
{
|
||||
m1.swap(m2);
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_UNORDERED_UNORDERED_MAP_HPP_INCLUDED
|
53
include/boost/unordered/unordered_map_fwd.hpp
Normal file
53
include/boost/unordered/unordered_map_fwd.hpp
Normal file
@ -0,0 +1,53 @@
|
||||
|
||||
// Copyright (C) 2008 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)
|
||||
|
||||
#ifndef BOOST_UNORDERED_MAP_FWD_HPP_INCLUDED
|
||||
#define BOOST_UNORDERED_MAP_FWD_HPP_INCLUDED
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <boost/functional/hash_fwd.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template <class Key,
|
||||
class T,
|
||||
class Hash = hash<Key>,
|
||||
class Pred = std::equal_to<Key>,
|
||||
class Alloc = std::allocator<std::pair<const Key, T> > >
|
||||
class unordered_map;
|
||||
template <class K, class T, class H, class P, class A>
|
||||
bool operator==(unordered_map<K, T, H, P, A> const&,
|
||||
unordered_map<K, T, H, P, A> const&);
|
||||
template <class K, class T, class H, class P, class A>
|
||||
bool operator!=(unordered_map<K, T, H, P, A> const&,
|
||||
unordered_map<K, T, H, P, A> const&);
|
||||
template <class K, class T, class H, class P, class A>
|
||||
void swap(unordered_map<K, T, H, P, A>&,
|
||||
unordered_map<K, T, H, P, A>&);
|
||||
|
||||
template <class Key,
|
||||
class T,
|
||||
class Hash = hash<Key>,
|
||||
class Pred = std::equal_to<Key>,
|
||||
class Alloc = std::allocator<std::pair<const Key, T> > >
|
||||
class unordered_multimap;
|
||||
template <class K, class T, class H, class P, class A>
|
||||
bool operator==(unordered_multimap<K, T, H, P, A> const&,
|
||||
unordered_multimap<K, T, H, P, A> const&);
|
||||
template <class K, class T, class H, class P, class A>
|
||||
bool operator!=(unordered_multimap<K, T, H, P, A> const&,
|
||||
unordered_multimap<K, T, H, P, A> const&);
|
||||
template <class K, class T, class H, class P, class A>
|
||||
void swap(unordered_multimap<K, T, H, P, A>&,
|
||||
unordered_multimap<K, T, H, P, A>&);
|
||||
}
|
||||
|
||||
#endif
|
745
include/boost/unordered/unordered_set.hpp
Normal file
745
include/boost/unordered/unordered_set.hpp
Normal file
@ -0,0 +1,745 @@
|
||||
|
||||
// Copyright (C) 2003-2004 Jeremy B. Maitin-Shepard.
|
||||
// Copyright (C) 2005-2008 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)
|
||||
|
||||
// See http://www.boost.org/libs/unordered for documentation
|
||||
|
||||
#ifndef BOOST_UNORDERED_UNORDERED_SET_HPP_INCLUDED
|
||||
#define BOOST_UNORDERED_UNORDERED_SET_HPP_INCLUDED
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/unordered/unordered_set_fwd.hpp>
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/unordered/detail/hash_table.hpp>
|
||||
|
||||
#if !defined(BOOST_HAS_RVALUE_REFS)
|
||||
#include <boost/unordered/detail/move.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template <class Value, class Hash, class Pred, class Alloc>
|
||||
class unordered_set
|
||||
{
|
||||
typedef boost::unordered_detail::hash_types_unique_keys<
|
||||
Value, Value, Hash, Pred, Alloc
|
||||
> implementation;
|
||||
|
||||
BOOST_DEDUCED_TYPENAME implementation::hash_table base;
|
||||
|
||||
public:
|
||||
|
||||
// types
|
||||
|
||||
typedef Value key_type;
|
||||
typedef Value value_type;
|
||||
typedef Hash hasher;
|
||||
typedef Pred key_equal;
|
||||
|
||||
typedef Alloc allocator_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_type::pointer pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_type::const_pointer const_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_type::reference reference;
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_type::const_reference const_reference;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::size_type size_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::difference_type difference_type;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::const_iterator iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::const_iterator const_iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::const_local_iterator local_iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::const_local_iterator const_local_iterator;
|
||||
|
||||
// construct/destroy/copy
|
||||
|
||||
explicit unordered_set(
|
||||
size_type n = boost::unordered_detail::default_initial_bucket_count,
|
||||
const hasher &hf = hasher(),
|
||||
const key_equal &eql = key_equal(),
|
||||
const allocator_type &a = allocator_type())
|
||||
: base(n, hf, eql, a)
|
||||
{
|
||||
}
|
||||
|
||||
explicit unordered_set(allocator_type const& a)
|
||||
: base(boost::unordered_detail::default_initial_bucket_count,
|
||||
hasher(), key_equal(), a)
|
||||
{
|
||||
}
|
||||
|
||||
unordered_set(unordered_set const& other, allocator_type const& a)
|
||||
: base(other.base, a)
|
||||
{
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
unordered_set(InputIterator f, InputIterator l)
|
||||
: base(f, l, boost::unordered_detail::default_initial_bucket_count,
|
||||
hasher(), key_equal(), allocator_type())
|
||||
{
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
unordered_set(InputIterator f, InputIterator l, size_type n,
|
||||
const hasher &hf = hasher(),
|
||||
const key_equal &eql = key_equal(),
|
||||
const allocator_type &a = allocator_type())
|
||||
: base(f, l, n, hf, eql, a)
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(BOOST_HAS_RVALUE_REFS)
|
||||
unordered_set(unordered_set&& other)
|
||||
: base(other.base, boost::unordered_detail::move_tag())
|
||||
{
|
||||
}
|
||||
|
||||
unordered_set(unordered_set&& other, allocator_type const& a)
|
||||
: base(other.base, a, boost::unordered_detail::move_tag())
|
||||
{
|
||||
}
|
||||
|
||||
unordered_set& operator=(unordered_set&& x)
|
||||
{
|
||||
base.move(x.base);
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
unordered_set(boost::unordered_detail::move_from<unordered_set<Value, Hash, Pred, Alloc> > other)
|
||||
: base(other.source.base, boost::unordered_detail::move_tag())
|
||||
{
|
||||
}
|
||||
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, < 0x0593)
|
||||
unordered_set& operator=(unordered_set x)
|
||||
{
|
||||
base.move(x.base);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
BOOST_DEDUCED_TYPENAME implementation::iterator_base const&
|
||||
get(const_iterator const& it)
|
||||
{
|
||||
return boost::unordered_detail::iterator_access::get(it);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
allocator_type get_allocator() const
|
||||
{
|
||||
return base.get_allocator();
|
||||
}
|
||||
|
||||
// size and capacity
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return base.empty();
|
||||
}
|
||||
|
||||
size_type size() const
|
||||
{
|
||||
return base.size();
|
||||
}
|
||||
|
||||
size_type max_size() const
|
||||
{
|
||||
return base.max_size();
|
||||
}
|
||||
|
||||
// iterators
|
||||
|
||||
iterator begin()
|
||||
{
|
||||
return iterator(base.data_.begin());
|
||||
}
|
||||
|
||||
const_iterator begin() const
|
||||
{
|
||||
return const_iterator(base.data_.begin());
|
||||
}
|
||||
|
||||
iterator end()
|
||||
{
|
||||
return iterator(base.data_.end());
|
||||
}
|
||||
|
||||
const_iterator end() const
|
||||
{
|
||||
return const_iterator(base.data_.end());
|
||||
}
|
||||
|
||||
const_iterator cbegin() const
|
||||
{
|
||||
return const_iterator(base.data_.begin());
|
||||
}
|
||||
|
||||
const_iterator cend() const
|
||||
{
|
||||
return const_iterator(base.data_.end());
|
||||
}
|
||||
|
||||
// modifiers
|
||||
|
||||
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
||||
template <class... Args>
|
||||
std::pair<iterator, bool> emplace(Args&&... args)
|
||||
{
|
||||
return boost::unordered_detail::pair_cast<iterator, bool>(
|
||||
base.insert(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
iterator emplace_hint(const_iterator hint, Args&&... args)
|
||||
{
|
||||
return iterator(
|
||||
base.insert_hint(get(hint), std::forward<Args>(args)...));
|
||||
}
|
||||
#endif
|
||||
|
||||
std::pair<iterator, bool> insert(const value_type& obj)
|
||||
{
|
||||
return boost::unordered_detail::pair_cast<iterator, bool>(
|
||||
base.insert(obj));
|
||||
}
|
||||
|
||||
iterator insert(const_iterator hint, const value_type& obj)
|
||||
{
|
||||
return iterator(base.insert_hint(get(hint), obj));
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
void insert(InputIterator first, InputIterator last)
|
||||
{
|
||||
base.insert_range(first, last);
|
||||
}
|
||||
|
||||
iterator erase(const_iterator position)
|
||||
{
|
||||
return iterator(base.data_.erase(get(position)));
|
||||
}
|
||||
|
||||
size_type erase(const key_type& k)
|
||||
{
|
||||
return base.erase_key(k);
|
||||
}
|
||||
|
||||
iterator erase(const_iterator first, const_iterator last)
|
||||
{
|
||||
return iterator(base.data_.erase_range(get(first), get(last)));
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
base.data_.clear();
|
||||
}
|
||||
|
||||
void swap(unordered_set& other)
|
||||
{
|
||||
base.swap(other.base);
|
||||
}
|
||||
|
||||
// observers
|
||||
|
||||
hasher hash_function() const
|
||||
{
|
||||
return base.hash_function();
|
||||
}
|
||||
|
||||
key_equal key_eq() const
|
||||
{
|
||||
return base.key_eq();
|
||||
}
|
||||
|
||||
// lookup
|
||||
|
||||
const_iterator find(const key_type& k) const
|
||||
{
|
||||
return const_iterator(base.find(k));
|
||||
}
|
||||
|
||||
size_type count(const key_type& k) const
|
||||
{
|
||||
return base.count(k);
|
||||
}
|
||||
|
||||
std::pair<const_iterator, const_iterator>
|
||||
equal_range(const key_type& k) const
|
||||
{
|
||||
return boost::unordered_detail::pair_cast<const_iterator, const_iterator>(
|
||||
base.equal_range(k));
|
||||
}
|
||||
|
||||
// bucket interface
|
||||
|
||||
size_type bucket_count() const
|
||||
{
|
||||
return base.bucket_count();
|
||||
}
|
||||
|
||||
size_type max_bucket_count() const
|
||||
{
|
||||
return base.max_bucket_count();
|
||||
}
|
||||
|
||||
size_type bucket_size(size_type n) const
|
||||
{
|
||||
return base.data_.bucket_size(n);
|
||||
}
|
||||
|
||||
size_type bucket(const key_type& k) const
|
||||
{
|
||||
return base.bucket(k);
|
||||
}
|
||||
|
||||
local_iterator begin(size_type n)
|
||||
{
|
||||
return local_iterator(base.data_.begin(n));
|
||||
}
|
||||
|
||||
const_local_iterator begin(size_type n) const
|
||||
{
|
||||
return const_local_iterator(base.data_.begin(n));
|
||||
}
|
||||
|
||||
local_iterator end(size_type n)
|
||||
{
|
||||
return local_iterator(base.data_.end(n));
|
||||
}
|
||||
|
||||
const_local_iterator end(size_type n) const
|
||||
{
|
||||
return const_local_iterator(base.data_.end(n));
|
||||
}
|
||||
|
||||
const_local_iterator cbegin(size_type n) const
|
||||
{
|
||||
return const_local_iterator(base.data_.begin(n));
|
||||
}
|
||||
|
||||
const_local_iterator cend(size_type n) const
|
||||
{
|
||||
return const_local_iterator(base.data_.end(n));
|
||||
}
|
||||
|
||||
// hash policy
|
||||
|
||||
float load_factor() const
|
||||
{
|
||||
return base.load_factor();
|
||||
}
|
||||
|
||||
float max_load_factor() const
|
||||
{
|
||||
return base.max_load_factor();
|
||||
}
|
||||
|
||||
void max_load_factor(float m)
|
||||
{
|
||||
base.max_load_factor(m);
|
||||
}
|
||||
|
||||
void rehash(size_type n)
|
||||
{
|
||||
base.rehash(n);
|
||||
}
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
friend bool operator==(unordered_set const&, unordered_set const&);
|
||||
friend bool operator!=(unordered_set const&, unordered_set const&);
|
||||
#else
|
||||
friend bool operator==<>(unordered_set const&, unordered_set const&);
|
||||
friend bool operator!=<>(unordered_set const&, unordered_set const&);
|
||||
#endif
|
||||
}; // class template unordered_set
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
inline bool operator==(unordered_set<T, H, P, A> const& m1,
|
||||
unordered_set<T, H, P, A> const& m2)
|
||||
{
|
||||
return boost::unordered_detail::equals(m1.base, m2.base);
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
inline bool operator!=(unordered_set<T, H, P, A> const& m1,
|
||||
unordered_set<T, H, P, A> const& m2)
|
||||
{
|
||||
return !boost::unordered_detail::equals(m1.base, m2.base);
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
inline void swap(unordered_set<T, H, P, A> &m1,
|
||||
unordered_set<T, H, P, A> &m2)
|
||||
{
|
||||
m1.swap(m2);
|
||||
}
|
||||
|
||||
template <class Value, class Hash, class Pred, class Alloc>
|
||||
class unordered_multiset
|
||||
{
|
||||
typedef boost::unordered_detail::hash_types_equivalent_keys<
|
||||
Value, Value, Hash, Pred, Alloc
|
||||
> implementation;
|
||||
|
||||
BOOST_DEDUCED_TYPENAME implementation::hash_table base;
|
||||
|
||||
public:
|
||||
|
||||
//types
|
||||
|
||||
typedef Value key_type;
|
||||
typedef Value value_type;
|
||||
typedef Hash hasher;
|
||||
typedef Pred key_equal;
|
||||
|
||||
typedef Alloc allocator_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_type::pointer pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_type::const_pointer const_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_type::reference reference;
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_type::const_reference const_reference;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::size_type size_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::difference_type difference_type;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::const_iterator iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::const_iterator const_iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::const_local_iterator local_iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::const_local_iterator const_local_iterator;
|
||||
|
||||
// construct/destroy/copy
|
||||
|
||||
explicit unordered_multiset(
|
||||
size_type n = boost::unordered_detail::default_initial_bucket_count,
|
||||
const hasher &hf = hasher(),
|
||||
const key_equal &eql = key_equal(),
|
||||
const allocator_type &a = allocator_type())
|
||||
: base(n, hf, eql, a)
|
||||
{
|
||||
}
|
||||
|
||||
explicit unordered_multiset(allocator_type const& a)
|
||||
: base(boost::unordered_detail::default_initial_bucket_count,
|
||||
hasher(), key_equal(), a)
|
||||
{
|
||||
}
|
||||
|
||||
unordered_multiset(unordered_multiset const& other, allocator_type const& a)
|
||||
: base(other.base, a)
|
||||
{
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
unordered_multiset(InputIterator f, InputIterator l)
|
||||
: base(f, l, boost::unordered_detail::default_initial_bucket_count,
|
||||
hasher(), key_equal(), allocator_type())
|
||||
{
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
unordered_multiset(InputIterator f, InputIterator l, size_type n,
|
||||
const hasher &hf = hasher(),
|
||||
const key_equal &eql = key_equal(),
|
||||
const allocator_type &a = allocator_type())
|
||||
: base(f, l, n, hf, eql, a)
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(BOOST_HAS_RVALUE_REFS)
|
||||
unordered_multiset(unordered_multiset&& other)
|
||||
: base(other.base, boost::unordered_detail::move_tag())
|
||||
{
|
||||
}
|
||||
|
||||
unordered_multiset(unordered_multiset&& other, allocator_type const& a)
|
||||
: base(other.base, a, boost::unordered_detail::move_tag())
|
||||
{
|
||||
}
|
||||
|
||||
unordered_multiset& operator=(unordered_multiset&& x)
|
||||
{
|
||||
base.move(x.base);
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
unordered_multiset(boost::unordered_detail::move_from<unordered_multiset<Value, Hash, Pred, Alloc> > other)
|
||||
: base(other.source.base, boost::unordered_detail::move_tag())
|
||||
{
|
||||
}
|
||||
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, < 0x0593)
|
||||
unordered_multiset& operator=(unordered_multiset x)
|
||||
{
|
||||
base.move(x.base);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
BOOST_DEDUCED_TYPENAME implementation::iterator_base const&
|
||||
get(const_iterator const& it)
|
||||
{
|
||||
return boost::unordered_detail::iterator_access::get(it);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
allocator_type get_allocator() const
|
||||
{
|
||||
return base.get_allocator();
|
||||
}
|
||||
|
||||
// size and capacity
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return base.empty();
|
||||
}
|
||||
|
||||
size_type size() const
|
||||
{
|
||||
return base.size();
|
||||
}
|
||||
|
||||
size_type max_size() const
|
||||
{
|
||||
return base.max_size();
|
||||
}
|
||||
|
||||
// iterators
|
||||
|
||||
iterator begin()
|
||||
{
|
||||
return iterator(base.data_.begin());
|
||||
}
|
||||
|
||||
const_iterator begin() const
|
||||
{
|
||||
return const_iterator(base.data_.begin());
|
||||
}
|
||||
|
||||
iterator end()
|
||||
{
|
||||
return iterator(base.data_.end());
|
||||
}
|
||||
|
||||
const_iterator end() const
|
||||
{
|
||||
return const_iterator(base.data_.end());
|
||||
}
|
||||
|
||||
const_iterator cbegin() const
|
||||
{
|
||||
return const_iterator(base.data_.begin());
|
||||
}
|
||||
|
||||
const_iterator cend() const
|
||||
{
|
||||
return const_iterator(base.data_.end());
|
||||
}
|
||||
|
||||
// modifiers
|
||||
|
||||
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
||||
template <class... Args>
|
||||
iterator emplace(Args&&... args)
|
||||
{
|
||||
return iterator(base.insert(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
iterator emplace_hint(const_iterator hint, Args&&... args)
|
||||
{
|
||||
return iterator(base.insert_hint(get(hint), std::forward<Args>(args)...));
|
||||
}
|
||||
#endif
|
||||
|
||||
iterator insert(const value_type& obj)
|
||||
{
|
||||
return iterator(base.insert(obj));
|
||||
}
|
||||
|
||||
iterator insert(const_iterator hint, const value_type& obj)
|
||||
{
|
||||
return iterator(base.insert_hint(get(hint), obj));
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
void insert(InputIterator first, InputIterator last)
|
||||
{
|
||||
base.insert_range(first, last);
|
||||
}
|
||||
|
||||
iterator erase(const_iterator position)
|
||||
{
|
||||
return iterator(base.data_.erase(get(position)));
|
||||
}
|
||||
|
||||
size_type erase(const key_type& k)
|
||||
{
|
||||
return base.erase_key(k);
|
||||
}
|
||||
|
||||
iterator erase(const_iterator first, const_iterator last)
|
||||
{
|
||||
return iterator(base.data_.erase_range(get(first), get(last)));
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
base.data_.clear();
|
||||
}
|
||||
|
||||
void swap(unordered_multiset& other)
|
||||
{
|
||||
base.swap(other.base);
|
||||
}
|
||||
|
||||
// observers
|
||||
|
||||
hasher hash_function() const
|
||||
{
|
||||
return base.hash_function();
|
||||
}
|
||||
|
||||
key_equal key_eq() const
|
||||
{
|
||||
return base.key_eq();
|
||||
}
|
||||
|
||||
// lookup
|
||||
|
||||
const_iterator find(const key_type& k) const
|
||||
{
|
||||
return const_iterator(base.find(k));
|
||||
}
|
||||
|
||||
size_type count(const key_type& k) const
|
||||
{
|
||||
return base.count(k);
|
||||
}
|
||||
|
||||
std::pair<const_iterator, const_iterator>
|
||||
equal_range(const key_type& k) const
|
||||
{
|
||||
return boost::unordered_detail::pair_cast<const_iterator, const_iterator>(
|
||||
base.equal_range(k));
|
||||
}
|
||||
|
||||
// bucket interface
|
||||
|
||||
size_type bucket_count() const
|
||||
{
|
||||
return base.bucket_count();
|
||||
}
|
||||
|
||||
size_type max_bucket_count() const
|
||||
{
|
||||
return base.max_bucket_count();
|
||||
}
|
||||
|
||||
size_type bucket_size(size_type n) const
|
||||
{
|
||||
return base.data_.bucket_size(n);
|
||||
}
|
||||
|
||||
size_type bucket(const key_type& k) const
|
||||
{
|
||||
return base.bucket(k);
|
||||
}
|
||||
|
||||
local_iterator begin(size_type n)
|
||||
{
|
||||
return local_iterator(base.data_.begin(n));
|
||||
}
|
||||
|
||||
const_local_iterator begin(size_type n) const
|
||||
{
|
||||
return const_local_iterator(base.data_.begin(n));
|
||||
}
|
||||
|
||||
local_iterator end(size_type n)
|
||||
{
|
||||
return local_iterator(base.data_.end(n));
|
||||
}
|
||||
|
||||
const_local_iterator end(size_type n) const
|
||||
{
|
||||
return const_local_iterator(base.data_.end(n));
|
||||
}
|
||||
|
||||
const_local_iterator cbegin(size_type n) const
|
||||
{
|
||||
return const_local_iterator(base.data_.begin(n));
|
||||
}
|
||||
|
||||
const_local_iterator cend(size_type n) const
|
||||
{
|
||||
return const_local_iterator(base.data_.end(n));
|
||||
}
|
||||
|
||||
// hash policy
|
||||
|
||||
float load_factor() const
|
||||
{
|
||||
return base.load_factor();
|
||||
}
|
||||
|
||||
float max_load_factor() const
|
||||
{
|
||||
return base.max_load_factor();
|
||||
}
|
||||
|
||||
void max_load_factor(float m)
|
||||
{
|
||||
base.max_load_factor(m);
|
||||
}
|
||||
|
||||
void rehash(size_type n)
|
||||
{
|
||||
base.rehash(n);
|
||||
}
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
friend bool operator==(unordered_multiset const&, unordered_multiset const&);
|
||||
friend bool operator!=(unordered_multiset const&, unordered_multiset const&);
|
||||
#else
|
||||
friend bool operator==<>(unordered_multiset const&, unordered_multiset const&);
|
||||
friend bool operator!=<>(unordered_multiset const&, unordered_multiset const&);
|
||||
#endif
|
||||
}; // class template unordered_multiset
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
inline bool operator==(unordered_multiset<T, H, P, A> const& m1,
|
||||
unordered_multiset<T, H, P, A> const& m2)
|
||||
{
|
||||
return boost::unordered_detail::equals(m1.base, m2.base);
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
inline bool operator!=(unordered_multiset<T, H, P, A> const& m1,
|
||||
unordered_multiset<T, H, P, A> const& m2)
|
||||
{
|
||||
return !boost::unordered_detail::equals(m1.base, m2.base);
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
inline void swap(unordered_multiset<T, H, P, A> &m1,
|
||||
unordered_multiset<T, H, P, A> &m2)
|
||||
{
|
||||
m1.swap(m2);
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_UNORDERED_UNORDERED_SET_HPP_INCLUDED
|
51
include/boost/unordered/unordered_set_fwd.hpp
Normal file
51
include/boost/unordered/unordered_set_fwd.hpp
Normal file
@ -0,0 +1,51 @@
|
||||
|
||||
// Copyright (C) 2008 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)
|
||||
|
||||
#ifndef BOOST_UNORDERED_SET_FWD_HPP_INCLUDED
|
||||
#define BOOST_UNORDERED_SET_FWD_HPP_INCLUDED
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <boost/functional/hash_fwd.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template <class Value,
|
||||
class Hash = hash<Value>,
|
||||
class Pred = std::equal_to<Value>,
|
||||
class Alloc = std::allocator<Value> >
|
||||
class unordered_set;
|
||||
template <class T, class H, class P, class A>
|
||||
bool operator==(unordered_set<T, H, P, A> const&,
|
||||
unordered_set<T, H, P, A> const&);
|
||||
template <class T, class H, class P, class A>
|
||||
bool operator!=(unordered_set<T, H, P, A> const&,
|
||||
unordered_set<T, H, P, A> const&);
|
||||
template <class T, class H, class P, class A>
|
||||
void swap(unordered_set<T, H, P, A> &m1,
|
||||
unordered_set<T, H, P, A> &m2);
|
||||
|
||||
template <class Value,
|
||||
class Hash = hash<Value>,
|
||||
class Pred = std::equal_to<Value>,
|
||||
class Alloc = std::allocator<Value> >
|
||||
class unordered_multiset;
|
||||
template <class T, class H, class P, class A>
|
||||
bool operator==(unordered_multiset<T, H, P, A> const&,
|
||||
unordered_multiset<T, H, P, A> const&);
|
||||
template <class T, class H, class P, class A>
|
||||
bool operator!=(unordered_multiset<T, H, P, A> const&,
|
||||
unordered_multiset<T, H, P, A> const&);
|
||||
template <class T, class H, class P, class A>
|
||||
void swap(unordered_multiset<T, H, P, A> &m1,
|
||||
unordered_multiset<T, H, P, A> &m2);
|
||||
}
|
||||
|
||||
#endif
|
@ -13,775 +13,6 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/unordered/detail/hash_table.hpp>
|
||||
|
||||
#if !defined(BOOST_HAS_RVALUE_REFS)
|
||||
#include <boost/unordered/detail/move.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template <class Key,
|
||||
class T,
|
||||
class Hash = hash<Key>,
|
||||
class Pred = std::equal_to<Key>,
|
||||
class Alloc = std::allocator<std::pair<const Key, T> > >
|
||||
class unordered_map
|
||||
{
|
||||
typedef boost::unordered_detail::hash_types_unique_keys<
|
||||
std::pair<const Key, T>, Key, Hash, Pred, Alloc
|
||||
> implementation;
|
||||
|
||||
BOOST_DEDUCED_TYPENAME implementation::hash_table base;
|
||||
|
||||
public:
|
||||
|
||||
// types
|
||||
|
||||
typedef Key key_type;
|
||||
typedef std::pair<const Key, T> value_type;
|
||||
typedef T mapped_type;
|
||||
typedef Hash hasher;
|
||||
typedef Pred key_equal;
|
||||
|
||||
typedef Alloc allocator_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_type::pointer pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_type::const_pointer const_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_type::reference reference;
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_type::const_reference const_reference;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::size_type size_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::difference_type difference_type;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::iterator iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::const_iterator const_iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::local_iterator local_iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::const_local_iterator const_local_iterator;
|
||||
|
||||
// construct/destroy/copy
|
||||
|
||||
explicit unordered_map(
|
||||
size_type n = boost::unordered_detail::default_initial_bucket_count,
|
||||
const hasher &hf = hasher(),
|
||||
const key_equal &eql = key_equal(),
|
||||
const allocator_type &a = allocator_type())
|
||||
: base(n, hf, eql, a)
|
||||
{
|
||||
}
|
||||
|
||||
// TODO: Should this be explicit?
|
||||
unordered_map(allocator_type const& a)
|
||||
: base(boost::unordered_detail::default_initial_bucket_count,
|
||||
hasher(), key_equal(), a)
|
||||
{
|
||||
}
|
||||
|
||||
unordered_map(unordered_map const& other, allocator_type const& a)
|
||||
: base(other.base, a)
|
||||
{
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
unordered_map(InputIterator f, InputIterator l)
|
||||
: base(f, l, boost::unordered_detail::default_initial_bucket_count,
|
||||
hasher(), key_equal(), allocator_type())
|
||||
{
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
unordered_map(InputIterator f, InputIterator l,
|
||||
size_type n,
|
||||
const hasher &hf = hasher(),
|
||||
const key_equal &eql = key_equal(),
|
||||
const allocator_type &a = allocator_type())
|
||||
: base(f, l, n, hf, eql, a)
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(BOOST_HAS_RVALUE_REFS)
|
||||
unordered_map(unordered_map&& other)
|
||||
: base(other.base, boost::unordered_detail::move_tag())
|
||||
{
|
||||
}
|
||||
|
||||
unordered_map(unordered_map&& other, allocator_type const& a)
|
||||
: base(other.base, a, boost::unordered_detail::move_tag())
|
||||
{
|
||||
}
|
||||
|
||||
unordered_map& operator=(unordered_map&& x)
|
||||
{
|
||||
base.move(x.base);
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
unordered_map(boost::unordered_detail::move_from<unordered_map<Key, T, Hash, Pred, Alloc> > other)
|
||||
: base(other.base, boost::unordered_detail::move_tag())
|
||||
{
|
||||
}
|
||||
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, < 0x0593)
|
||||
unordered_map& operator=(unordered_map x)
|
||||
{
|
||||
base.move(x.base);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
BOOST_DEDUCED_TYPENAME implementation::iterator_base const&
|
||||
get(const_iterator const& it)
|
||||
{
|
||||
return boost::unordered_detail::iterator_access::get(it);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
allocator_type get_allocator() const
|
||||
{
|
||||
return base.get_allocator();
|
||||
}
|
||||
|
||||
// size and capacity
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return base.empty();
|
||||
}
|
||||
|
||||
size_type size() const
|
||||
{
|
||||
return base.size();
|
||||
}
|
||||
|
||||
size_type max_size() const
|
||||
{
|
||||
return base.max_size();
|
||||
}
|
||||
|
||||
// iterators
|
||||
|
||||
iterator begin()
|
||||
{
|
||||
return iterator(base.data_.begin());
|
||||
}
|
||||
|
||||
const_iterator begin() const
|
||||
{
|
||||
return const_iterator(base.data_.begin());
|
||||
}
|
||||
|
||||
iterator end()
|
||||
{
|
||||
return iterator(base.data_.end());
|
||||
}
|
||||
|
||||
const_iterator end() const
|
||||
{
|
||||
return const_iterator(base.data_.end());
|
||||
}
|
||||
|
||||
const_iterator cbegin() const
|
||||
{
|
||||
return const_iterator(base.data_.begin());
|
||||
}
|
||||
|
||||
const_iterator cend() const
|
||||
{
|
||||
return const_iterator(base.data_.end());
|
||||
}
|
||||
|
||||
// modifiers
|
||||
|
||||
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
||||
template <class... Args>
|
||||
std::pair<iterator, bool> emplace(Args&&... args)
|
||||
{
|
||||
return boost::unordered_detail::pair_cast<iterator, bool>(
|
||||
base.insert(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
iterator emplace(const_iterator hint, Args&&... args)
|
||||
{
|
||||
return iterator(base.insert_hint(get(hint), std::forward<Args>(args)...));
|
||||
}
|
||||
#endif
|
||||
|
||||
std::pair<iterator, bool> insert(const value_type& obj)
|
||||
{
|
||||
return boost::unordered_detail::pair_cast<iterator, bool>(
|
||||
base.insert(obj));
|
||||
}
|
||||
|
||||
iterator insert(const_iterator hint, const value_type& obj)
|
||||
{
|
||||
return iterator(base.insert_hint(get(hint), obj));
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
void insert(InputIterator first, InputIterator last)
|
||||
{
|
||||
base.insert_range(first, last);
|
||||
}
|
||||
|
||||
iterator erase(const_iterator position)
|
||||
{
|
||||
return iterator(base.data_.erase(get(position)));
|
||||
}
|
||||
|
||||
size_type erase(const key_type& k)
|
||||
{
|
||||
return base.erase_key(k);
|
||||
}
|
||||
|
||||
iterator erase(const_iterator first, const_iterator last)
|
||||
{
|
||||
return iterator(base.data_.erase_range(get(first), get(last)));
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
base.data_.clear();
|
||||
}
|
||||
|
||||
void swap(unordered_map& other)
|
||||
{
|
||||
base.swap(other.base);
|
||||
}
|
||||
|
||||
// observers
|
||||
|
||||
hasher hash_function() const
|
||||
{
|
||||
return base.hash_function();
|
||||
}
|
||||
|
||||
key_equal key_eq() const
|
||||
{
|
||||
return base.key_eq();
|
||||
}
|
||||
|
||||
mapped_type& operator[](const key_type &k)
|
||||
{
|
||||
return base[k].second;
|
||||
}
|
||||
|
||||
mapped_type& at(const key_type& k)
|
||||
{
|
||||
return base.at(k).second;
|
||||
}
|
||||
|
||||
mapped_type const& at(const key_type& k) const
|
||||
{
|
||||
return base.at(k).second;
|
||||
}
|
||||
|
||||
// lookup
|
||||
|
||||
iterator find(const key_type& k)
|
||||
{
|
||||
return iterator(base.find(k));
|
||||
}
|
||||
|
||||
const_iterator find(const key_type& k) const
|
||||
{
|
||||
return const_iterator(base.find(k));
|
||||
}
|
||||
|
||||
size_type count(const key_type& k) const
|
||||
{
|
||||
return base.count(k);
|
||||
}
|
||||
|
||||
std::pair<iterator, iterator>
|
||||
equal_range(const key_type& k)
|
||||
{
|
||||
return boost::unordered_detail::pair_cast<iterator, iterator>(
|
||||
base.equal_range(k));
|
||||
}
|
||||
|
||||
std::pair<const_iterator, const_iterator>
|
||||
equal_range(const key_type& k) const
|
||||
{
|
||||
return boost::unordered_detail::pair_cast<const_iterator, const_iterator>(
|
||||
base.equal_range(k));
|
||||
}
|
||||
|
||||
// bucket interface
|
||||
|
||||
size_type bucket_count() const
|
||||
{
|
||||
return base.bucket_count();
|
||||
}
|
||||
|
||||
size_type max_bucket_count() const
|
||||
{
|
||||
return base.max_bucket_count();
|
||||
}
|
||||
|
||||
size_type bucket_size(size_type n) const
|
||||
{
|
||||
return base.data_.bucket_size(n);
|
||||
}
|
||||
|
||||
size_type bucket(const key_type& k) const
|
||||
{
|
||||
return base.bucket(k);
|
||||
}
|
||||
|
||||
local_iterator begin(size_type n)
|
||||
{
|
||||
return local_iterator(base.data_.begin(n));
|
||||
}
|
||||
|
||||
const_local_iterator begin(size_type n) const
|
||||
{
|
||||
return const_local_iterator(base.data_.begin(n));
|
||||
}
|
||||
|
||||
local_iterator end(size_type n)
|
||||
{
|
||||
return local_iterator(base.data_.end(n));
|
||||
}
|
||||
|
||||
const_local_iterator end(size_type n) const
|
||||
{
|
||||
return const_local_iterator(base.data_.end(n));
|
||||
}
|
||||
|
||||
const_local_iterator cbegin(size_type n) const
|
||||
{
|
||||
return const_local_iterator(base.data_.begin(n));
|
||||
}
|
||||
|
||||
const_local_iterator cend(size_type n) const
|
||||
{
|
||||
return const_local_iterator(base.data_.end(n));
|
||||
}
|
||||
|
||||
// hash policy
|
||||
|
||||
float load_factor() const
|
||||
{
|
||||
return base.load_factor();
|
||||
}
|
||||
|
||||
float max_load_factor() const
|
||||
{
|
||||
return base.max_load_factor();
|
||||
}
|
||||
|
||||
void max_load_factor(float m)
|
||||
{
|
||||
base.max_load_factor(m);
|
||||
}
|
||||
|
||||
void rehash(size_type n)
|
||||
{
|
||||
base.rehash(n);
|
||||
}
|
||||
|
||||
friend bool operator==(unordered_map const& m1, unordered_map const& m2)
|
||||
{
|
||||
return m1.base.equals(m2.base);
|
||||
}
|
||||
|
||||
friend bool operator!=(unordered_map const& m1, unordered_map const& m2)
|
||||
{
|
||||
return !m1.base.equals(m2.base);
|
||||
}
|
||||
|
||||
friend std::size_t hash_value(unordered_map const& m)
|
||||
{
|
||||
return m.base.hash_value();
|
||||
}
|
||||
}; // class template unordered_map
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
void swap(unordered_map<K, T, H, P, A> &m1,
|
||||
unordered_map<K, T, H, P, A> &m2)
|
||||
{
|
||||
m1.swap(m2);
|
||||
}
|
||||
|
||||
template <class Key,
|
||||
class T,
|
||||
class Hash = hash<Key>,
|
||||
class Pred = std::equal_to<Key>,
|
||||
class Alloc = std::allocator<std::pair<const Key, T> > >
|
||||
class unordered_multimap
|
||||
{
|
||||
typedef boost::unordered_detail::hash_types_equivalent_keys<
|
||||
std::pair<const Key, T>, Key, Hash, Pred, Alloc
|
||||
> implementation;
|
||||
|
||||
BOOST_DEDUCED_TYPENAME implementation::hash_table base;
|
||||
|
||||
public:
|
||||
|
||||
// types
|
||||
|
||||
typedef Key key_type;
|
||||
typedef std::pair<const Key, T> value_type;
|
||||
typedef T mapped_type;
|
||||
typedef Hash hasher;
|
||||
typedef Pred key_equal;
|
||||
|
||||
typedef Alloc allocator_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_type::pointer pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_type::const_pointer const_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_type::reference reference;
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_type::const_reference const_reference;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::size_type size_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::difference_type difference_type;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::iterator iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::const_iterator const_iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::local_iterator local_iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::const_local_iterator const_local_iterator;
|
||||
|
||||
// construct/destroy/copy
|
||||
|
||||
explicit unordered_multimap(
|
||||
size_type n = boost::unordered_detail::default_initial_bucket_count,
|
||||
const hasher &hf = hasher(),
|
||||
const key_equal &eql = key_equal(),
|
||||
const allocator_type &a = allocator_type())
|
||||
: base(n, hf, eql, a)
|
||||
{
|
||||
}
|
||||
|
||||
unordered_multimap(allocator_type const& a)
|
||||
: base(boost::unordered_detail::default_initial_bucket_count,
|
||||
hasher(), key_equal(), a)
|
||||
{
|
||||
}
|
||||
|
||||
unordered_multimap(unordered_multimap const& other, allocator_type const& a)
|
||||
: base(other.base, a)
|
||||
{
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
unordered_multimap(InputIterator f, InputIterator l)
|
||||
: base(f, l, boost::unordered_detail::default_initial_bucket_count,
|
||||
hasher(), key_equal(), allocator_type())
|
||||
{
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
unordered_multimap(InputIterator f, InputIterator l,
|
||||
size_type n,
|
||||
const hasher &hf = hasher(),
|
||||
const key_equal &eql = key_equal(),
|
||||
const allocator_type &a = allocator_type())
|
||||
: base(f, l, n, hf, eql, a)
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(BOOST_HAS_RVALUE_REFS)
|
||||
unordered_multimap(unordered_multimap&& other)
|
||||
: base(other.base, boost::unordered_detail::move_tag())
|
||||
{
|
||||
}
|
||||
|
||||
unordered_multimap(unordered_multimap&& other, allocator_type const& a)
|
||||
: base(other.base, a, boost::unordered_detail::move_tag())
|
||||
{
|
||||
}
|
||||
|
||||
unordered_multimap& operator=(unordered_multimap&& x)
|
||||
{
|
||||
base.move(x.base);
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
unordered_multimap(boost::unordered_detail::move_from<unordered_multimap<Key, T, Hash, Pred, Alloc> > other)
|
||||
: base(other.base, boost::unordered_detail::move_tag())
|
||||
{
|
||||
}
|
||||
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, < 0x0593)
|
||||
unordered_multimap& operator=(unordered_multimap x)
|
||||
{
|
||||
base.move(x.base);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
private:
|
||||
|
||||
BOOST_DEDUCED_TYPENAME implementation::iterator_base const&
|
||||
get(const_iterator const& it)
|
||||
{
|
||||
return boost::unordered_detail::iterator_access::get(it);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
allocator_type get_allocator() const
|
||||
{
|
||||
return base.get_allocator();
|
||||
}
|
||||
|
||||
// size and capacity
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return base.empty();
|
||||
}
|
||||
|
||||
size_type size() const
|
||||
{
|
||||
return base.size();
|
||||
}
|
||||
|
||||
size_type max_size() const
|
||||
{
|
||||
return base.max_size();
|
||||
}
|
||||
|
||||
// iterators
|
||||
|
||||
iterator begin()
|
||||
{
|
||||
return iterator(base.data_.begin());
|
||||
}
|
||||
|
||||
const_iterator begin() const
|
||||
{
|
||||
return const_iterator(base.data_.begin());
|
||||
}
|
||||
|
||||
iterator end()
|
||||
{
|
||||
return iterator(base.data_.end());
|
||||
}
|
||||
|
||||
const_iterator end() const
|
||||
{
|
||||
return const_iterator(base.data_.end());
|
||||
}
|
||||
|
||||
const_iterator cbegin() const
|
||||
{
|
||||
return const_iterator(base.data_.begin());
|
||||
}
|
||||
|
||||
const_iterator cend() const
|
||||
{
|
||||
return const_iterator(base.data_.end());
|
||||
}
|
||||
|
||||
// modifiers
|
||||
|
||||
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
||||
template <class... Args>
|
||||
iterator emplace(Args&&... args)
|
||||
{
|
||||
return iterator(base.insert(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
iterator emplace(const_iterator hint, Args&&... args)
|
||||
{
|
||||
return iterator(base.insert_hint(get(hint), std::forward<Args>(args)...));
|
||||
}
|
||||
#endif
|
||||
|
||||
iterator insert(const value_type& obj)
|
||||
{
|
||||
return iterator(base.insert(obj));
|
||||
}
|
||||
|
||||
iterator insert(const_iterator hint, const value_type& obj)
|
||||
{
|
||||
return iterator(base.insert_hint(get(hint), obj));
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
void insert(InputIterator first, InputIterator last)
|
||||
{
|
||||
base.insert_range(first, last);
|
||||
}
|
||||
|
||||
iterator erase(const_iterator position)
|
||||
{
|
||||
return iterator(base.data_.erase(get(position)));
|
||||
}
|
||||
|
||||
size_type erase(const key_type& k)
|
||||
{
|
||||
return base.erase_key(k);
|
||||
}
|
||||
|
||||
iterator erase(const_iterator first, const_iterator last)
|
||||
{
|
||||
return iterator(base.data_.erase_range(get(first), get(last)));
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
base.data_.clear();
|
||||
}
|
||||
|
||||
void swap(unordered_multimap& other)
|
||||
{
|
||||
base.swap(other.base);
|
||||
}
|
||||
|
||||
// observers
|
||||
|
||||
hasher hash_function() const
|
||||
{
|
||||
return base.hash_function();
|
||||
}
|
||||
|
||||
key_equal key_eq() const
|
||||
{
|
||||
return base.key_eq();
|
||||
}
|
||||
|
||||
// lookup
|
||||
|
||||
iterator find(const key_type& k)
|
||||
{
|
||||
return iterator(base.find(k));
|
||||
}
|
||||
|
||||
const_iterator find(const key_type& k) const
|
||||
{
|
||||
return const_iterator(base.find(k));
|
||||
}
|
||||
|
||||
size_type count(const key_type& k) const
|
||||
{
|
||||
return base.count(k);
|
||||
}
|
||||
|
||||
std::pair<iterator, iterator>
|
||||
equal_range(const key_type& k)
|
||||
{
|
||||
return boost::unordered_detail::pair_cast<iterator, iterator>(
|
||||
base.equal_range(k));
|
||||
}
|
||||
|
||||
std::pair<const_iterator, const_iterator>
|
||||
equal_range(const key_type& k) const
|
||||
{
|
||||
return boost::unordered_detail::pair_cast<const_iterator, const_iterator>(
|
||||
base.equal_range(k));
|
||||
}
|
||||
|
||||
// bucket interface
|
||||
|
||||
size_type bucket_count() const
|
||||
{
|
||||
return base.bucket_count();
|
||||
}
|
||||
|
||||
size_type max_bucket_count() const
|
||||
{
|
||||
return base.max_bucket_count();
|
||||
}
|
||||
|
||||
size_type bucket_size(size_type n) const
|
||||
{
|
||||
return base.data_.bucket_size(n);
|
||||
}
|
||||
|
||||
size_type bucket(const key_type& k) const
|
||||
{
|
||||
return base.bucket(k);
|
||||
}
|
||||
|
||||
local_iterator begin(size_type n)
|
||||
{
|
||||
return local_iterator(base.data_.begin(n));
|
||||
}
|
||||
|
||||
const_local_iterator begin(size_type n) const
|
||||
{
|
||||
return const_local_iterator(base.data_.begin(n));
|
||||
}
|
||||
|
||||
local_iterator end(size_type n)
|
||||
{
|
||||
return local_iterator(base.data_.end(n));
|
||||
}
|
||||
|
||||
const_local_iterator end(size_type n) const
|
||||
{
|
||||
return const_local_iterator(base.data_.end(n));
|
||||
}
|
||||
|
||||
const_local_iterator cbegin(size_type n) const
|
||||
{
|
||||
return const_local_iterator(base.data_.begin(n));
|
||||
}
|
||||
|
||||
const_local_iterator cend(size_type n) const
|
||||
{
|
||||
return const_local_iterator(base.data_.end(n));
|
||||
}
|
||||
|
||||
// hash policy
|
||||
|
||||
float load_factor() const
|
||||
{
|
||||
return base.load_factor();
|
||||
}
|
||||
|
||||
float max_load_factor() const
|
||||
{
|
||||
return base.max_load_factor();
|
||||
}
|
||||
|
||||
void max_load_factor(float m)
|
||||
{
|
||||
base.max_load_factor(m);
|
||||
}
|
||||
|
||||
void rehash(size_type n)
|
||||
{
|
||||
base.rehash(n);
|
||||
}
|
||||
|
||||
friend bool operator==(unordered_multimap const& m1, unordered_multimap const& m2)
|
||||
{
|
||||
return m1.base.equals(m2.base);
|
||||
}
|
||||
|
||||
friend bool operator!=(unordered_multimap const& m1, unordered_multimap const& m2)
|
||||
{
|
||||
return !m1.base.equals(m2.base);
|
||||
}
|
||||
|
||||
friend std::size_t hash_value(unordered_multimap const& m)
|
||||
{
|
||||
return m.base.hash_value();
|
||||
}
|
||||
}; // class template unordered_multimap
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
void swap(unordered_multimap<K, T, H, P, A> &m1,
|
||||
unordered_multimap<K, T, H, P, A> &m2)
|
||||
{
|
||||
m1.swap(m2);
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
#include <boost/unordered/unordered_map.hpp>
|
||||
|
||||
#endif // BOOST_UNORDERED_MAP_HPP_INCLUDED
|
||||
|
@ -13,731 +13,6 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/unordered/detail/hash_table.hpp>
|
||||
|
||||
#if !defined(BOOST_HAS_RVALUE_REFS)
|
||||
#include <boost/unordered/detail/move.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template <class Value,
|
||||
class Hash = hash<Value>,
|
||||
class Pred = std::equal_to<Value>,
|
||||
class Alloc = std::allocator<Value> >
|
||||
class unordered_set
|
||||
{
|
||||
typedef boost::unordered_detail::hash_types_unique_keys<
|
||||
Value, Value, Hash, Pred, Alloc
|
||||
> implementation;
|
||||
|
||||
BOOST_DEDUCED_TYPENAME implementation::hash_table base;
|
||||
|
||||
public:
|
||||
|
||||
// types
|
||||
|
||||
typedef Value key_type;
|
||||
typedef Value value_type;
|
||||
typedef Hash hasher;
|
||||
typedef Pred key_equal;
|
||||
|
||||
typedef Alloc allocator_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_type::pointer pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_type::const_pointer const_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_type::reference reference;
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_type::const_reference const_reference;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::size_type size_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::difference_type difference_type;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::const_iterator iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::const_iterator const_iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::const_local_iterator local_iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::const_local_iterator const_local_iterator;
|
||||
|
||||
// construct/destroy/copy
|
||||
|
||||
explicit unordered_set(
|
||||
size_type n = boost::unordered_detail::default_initial_bucket_count,
|
||||
const hasher &hf = hasher(),
|
||||
const key_equal &eql = key_equal(),
|
||||
const allocator_type &a = allocator_type())
|
||||
: base(n, hf, eql, a)
|
||||
{
|
||||
}
|
||||
|
||||
// TODO: Should this be explicit?
|
||||
unordered_set(allocator_type const& a)
|
||||
: base(boost::unordered_detail::default_initial_bucket_count,
|
||||
hasher(), key_equal(), a)
|
||||
{
|
||||
}
|
||||
|
||||
unordered_set(unordered_set const& other, allocator_type const& a)
|
||||
: base(other.base, a)
|
||||
{
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
unordered_set(InputIterator f, InputIterator l)
|
||||
: base(f, l, boost::unordered_detail::default_initial_bucket_count,
|
||||
hasher(), key_equal(), allocator_type())
|
||||
{
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
unordered_set(InputIterator f, InputIterator l, size_type n,
|
||||
const hasher &hf = hasher(),
|
||||
const key_equal &eql = key_equal(),
|
||||
const allocator_type &a = allocator_type())
|
||||
: base(f, l, n, hf, eql, a)
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(BOOST_HAS_RVALUE_REFS)
|
||||
unordered_set(unordered_set&& other)
|
||||
: base(other.base, boost::unordered_detail::move_tag())
|
||||
{
|
||||
}
|
||||
|
||||
unordered_set(unordered_set&& other, allocator_type const& a)
|
||||
: base(other.base, a, boost::unordered_detail::move_tag())
|
||||
{
|
||||
}
|
||||
|
||||
unordered_set& operator=(unordered_set&& x)
|
||||
{
|
||||
base.move(x.base);
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
unordered_set(boost::unordered_detail::move_from<unordered_set<Value, Hash, Pred, Alloc> > other)
|
||||
: base(other.base, boost::unordered_detail::move_tag())
|
||||
{
|
||||
}
|
||||
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, < 0x0593)
|
||||
unordered_set& operator=(unordered_set x)
|
||||
{
|
||||
base.move(x.base);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
BOOST_DEDUCED_TYPENAME implementation::iterator_base const&
|
||||
get(const_iterator const& it)
|
||||
{
|
||||
return boost::unordered_detail::iterator_access::get(it);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
allocator_type get_allocator() const
|
||||
{
|
||||
return base.get_allocator();
|
||||
}
|
||||
|
||||
// size and capacity
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return base.empty();
|
||||
}
|
||||
|
||||
size_type size() const
|
||||
{
|
||||
return base.size();
|
||||
}
|
||||
|
||||
size_type max_size() const
|
||||
{
|
||||
return base.max_size();
|
||||
}
|
||||
|
||||
// iterators
|
||||
|
||||
iterator begin()
|
||||
{
|
||||
return iterator(base.data_.begin());
|
||||
}
|
||||
|
||||
const_iterator begin() const
|
||||
{
|
||||
return const_iterator(base.data_.begin());
|
||||
}
|
||||
|
||||
iterator end()
|
||||
{
|
||||
return iterator(base.data_.end());
|
||||
}
|
||||
|
||||
const_iterator end() const
|
||||
{
|
||||
return const_iterator(base.data_.end());
|
||||
}
|
||||
|
||||
const_iterator cbegin() const
|
||||
{
|
||||
return const_iterator(base.data_.begin());
|
||||
}
|
||||
|
||||
const_iterator cend() const
|
||||
{
|
||||
return const_iterator(base.data_.end());
|
||||
}
|
||||
|
||||
// modifiers
|
||||
|
||||
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
||||
template <class... Args>
|
||||
std::pair<iterator, bool> emplace(Args&&... args)
|
||||
{
|
||||
return boost::unordered_detail::pair_cast<iterator, bool>(
|
||||
base.insert(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
iterator emplace(const_iterator hint, Args&&... args)
|
||||
{
|
||||
return iterator(
|
||||
base.insert_hint(get(hint), std::forward<Args>(args)...));
|
||||
}
|
||||
#endif
|
||||
|
||||
std::pair<iterator, bool> insert(const value_type& obj)
|
||||
{
|
||||
return boost::unordered_detail::pair_cast<iterator, bool>(
|
||||
base.insert(obj));
|
||||
}
|
||||
|
||||
iterator insert(const_iterator hint, const value_type& obj)
|
||||
{
|
||||
return iterator(base.insert_hint(get(hint), obj));
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
void insert(InputIterator first, InputIterator last)
|
||||
{
|
||||
base.insert_range(first, last);
|
||||
}
|
||||
|
||||
iterator erase(const_iterator position)
|
||||
{
|
||||
return iterator(base.data_.erase(get(position)));
|
||||
}
|
||||
|
||||
size_type erase(const key_type& k)
|
||||
{
|
||||
return base.erase_key(k);
|
||||
}
|
||||
|
||||
iterator erase(const_iterator first, const_iterator last)
|
||||
{
|
||||
return iterator(base.data_.erase_range(get(first), get(last)));
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
base.data_.clear();
|
||||
}
|
||||
|
||||
void swap(unordered_set& other)
|
||||
{
|
||||
base.swap(other.base);
|
||||
}
|
||||
|
||||
// observers
|
||||
|
||||
hasher hash_function() const
|
||||
{
|
||||
return base.hash_function();
|
||||
}
|
||||
|
||||
key_equal key_eq() const
|
||||
{
|
||||
return base.key_eq();
|
||||
}
|
||||
|
||||
// lookup
|
||||
|
||||
const_iterator find(const key_type& k) const
|
||||
{
|
||||
return const_iterator(base.find(k));
|
||||
}
|
||||
|
||||
size_type count(const key_type& k) const
|
||||
{
|
||||
return base.count(k);
|
||||
}
|
||||
|
||||
std::pair<const_iterator, const_iterator>
|
||||
equal_range(const key_type& k) const
|
||||
{
|
||||
return boost::unordered_detail::pair_cast<const_iterator, const_iterator>(
|
||||
base.equal_range(k));
|
||||
}
|
||||
|
||||
// bucket interface
|
||||
|
||||
size_type bucket_count() const
|
||||
{
|
||||
return base.bucket_count();
|
||||
}
|
||||
|
||||
size_type max_bucket_count() const
|
||||
{
|
||||
return base.max_bucket_count();
|
||||
}
|
||||
|
||||
size_type bucket_size(size_type n) const
|
||||
{
|
||||
return base.data_.bucket_size(n);
|
||||
}
|
||||
|
||||
size_type bucket(const key_type& k) const
|
||||
{
|
||||
return base.bucket(k);
|
||||
}
|
||||
|
||||
local_iterator begin(size_type n)
|
||||
{
|
||||
return local_iterator(base.data_.begin(n));
|
||||
}
|
||||
|
||||
const_local_iterator begin(size_type n) const
|
||||
{
|
||||
return const_local_iterator(base.data_.begin(n));
|
||||
}
|
||||
|
||||
local_iterator end(size_type n)
|
||||
{
|
||||
return local_iterator(base.data_.end(n));
|
||||
}
|
||||
|
||||
const_local_iterator end(size_type n) const
|
||||
{
|
||||
return const_local_iterator(base.data_.end(n));
|
||||
}
|
||||
|
||||
const_local_iterator cbegin(size_type n) const
|
||||
{
|
||||
return const_local_iterator(base.data_.begin(n));
|
||||
}
|
||||
|
||||
const_local_iterator cend(size_type n) const
|
||||
{
|
||||
return const_local_iterator(base.data_.end(n));
|
||||
}
|
||||
|
||||
// hash policy
|
||||
|
||||
float load_factor() const
|
||||
{
|
||||
return base.load_factor();
|
||||
}
|
||||
|
||||
float max_load_factor() const
|
||||
{
|
||||
return base.max_load_factor();
|
||||
}
|
||||
|
||||
void max_load_factor(float m)
|
||||
{
|
||||
base.max_load_factor(m);
|
||||
}
|
||||
|
||||
void rehash(size_type n)
|
||||
{
|
||||
base.rehash(n);
|
||||
}
|
||||
|
||||
friend bool operator==(unordered_set const& m1, unordered_set const& m2)
|
||||
{
|
||||
return m1.base.equals(m2.base);
|
||||
}
|
||||
|
||||
friend bool operator!=(unordered_set const& m1, unordered_set const& m2)
|
||||
{
|
||||
return !m1.base.equals(m2.base);
|
||||
}
|
||||
|
||||
friend std::size_t hash_value(unordered_set const& m)
|
||||
{
|
||||
return m.base.hash_value();
|
||||
}
|
||||
}; // class template unordered_set
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
void swap(unordered_set<T, H, P, A> &m1,
|
||||
unordered_set<T, H, P, A> &m2)
|
||||
{
|
||||
m1.swap(m2);
|
||||
}
|
||||
|
||||
template <class Value,
|
||||
class Hash = hash<Value>,
|
||||
class Pred = std::equal_to<Value>,
|
||||
class Alloc = std::allocator<Value> >
|
||||
class unordered_multiset
|
||||
{
|
||||
typedef boost::unordered_detail::hash_types_equivalent_keys<
|
||||
Value, Value, Hash, Pred, Alloc
|
||||
> implementation;
|
||||
|
||||
BOOST_DEDUCED_TYPENAME implementation::hash_table base;
|
||||
|
||||
public:
|
||||
|
||||
//types
|
||||
|
||||
typedef Value key_type;
|
||||
typedef Value value_type;
|
||||
typedef Hash hasher;
|
||||
typedef Pred key_equal;
|
||||
|
||||
typedef Alloc allocator_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_type::pointer pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_type::const_pointer const_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_type::reference reference;
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_type::const_reference const_reference;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::size_type size_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::difference_type difference_type;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::const_iterator iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::const_iterator const_iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::const_local_iterator local_iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME implementation::const_local_iterator const_local_iterator;
|
||||
|
||||
// construct/destroy/copy
|
||||
|
||||
explicit unordered_multiset(
|
||||
size_type n = boost::unordered_detail::default_initial_bucket_count,
|
||||
const hasher &hf = hasher(),
|
||||
const key_equal &eql = key_equal(),
|
||||
const allocator_type &a = allocator_type())
|
||||
: base(n, hf, eql, a)
|
||||
{
|
||||
}
|
||||
|
||||
// TODO: Should this be explicit?
|
||||
unordered_multiset(allocator_type const& a)
|
||||
: base(boost::unordered_detail::default_initial_bucket_count,
|
||||
hasher(), key_equal(), a)
|
||||
{
|
||||
}
|
||||
|
||||
unordered_multiset(unordered_multiset const& other, allocator_type const& a)
|
||||
: base(other.base, a)
|
||||
{
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
unordered_multiset(InputIterator f, InputIterator l)
|
||||
: base(f, l, boost::unordered_detail::default_initial_bucket_count,
|
||||
hasher(), key_equal(), allocator_type())
|
||||
{
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
unordered_multiset(InputIterator f, InputIterator l, size_type n,
|
||||
const hasher &hf = hasher(),
|
||||
const key_equal &eql = key_equal(),
|
||||
const allocator_type &a = allocator_type())
|
||||
: base(f, l, n, hf, eql, a)
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(BOOST_HAS_RVALUE_REFS)
|
||||
unordered_multiset(unordered_multiset&& other)
|
||||
: base(other.base, boost::unordered_detail::move_tag())
|
||||
{
|
||||
}
|
||||
|
||||
unordered_multiset(unordered_multiset&& other, allocator_type const& a)
|
||||
: base(other.base, a, boost::unordered_detail::move_tag())
|
||||
{
|
||||
}
|
||||
|
||||
unordered_multiset& operator=(unordered_multiset&& x)
|
||||
{
|
||||
base.move(x.base);
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
unordered_multiset(boost::unordered_detail::move_from<unordered_multiset<Value, Hash, Pred, Alloc> > other)
|
||||
: base(other.base, boost::unordered_detail::move_tag())
|
||||
{
|
||||
}
|
||||
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, < 0x0593)
|
||||
unordered_multiset& operator=(unordered_multiset x)
|
||||
{
|
||||
base.move(x.base);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
BOOST_DEDUCED_TYPENAME implementation::iterator_base const&
|
||||
get(const_iterator const& it)
|
||||
{
|
||||
return boost::unordered_detail::iterator_access::get(it);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
allocator_type get_allocator() const
|
||||
{
|
||||
return base.get_allocator();
|
||||
}
|
||||
|
||||
// size and capacity
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return base.empty();
|
||||
}
|
||||
|
||||
size_type size() const
|
||||
{
|
||||
return base.size();
|
||||
}
|
||||
|
||||
size_type max_size() const
|
||||
{
|
||||
return base.max_size();
|
||||
}
|
||||
|
||||
// iterators
|
||||
|
||||
iterator begin()
|
||||
{
|
||||
return iterator(base.data_.begin());
|
||||
}
|
||||
|
||||
const_iterator begin() const
|
||||
{
|
||||
return const_iterator(base.data_.begin());
|
||||
}
|
||||
|
||||
iterator end()
|
||||
{
|
||||
return iterator(base.data_.end());
|
||||
}
|
||||
|
||||
const_iterator end() const
|
||||
{
|
||||
return const_iterator(base.data_.end());
|
||||
}
|
||||
|
||||
const_iterator cbegin() const
|
||||
{
|
||||
return const_iterator(base.data_.begin());
|
||||
}
|
||||
|
||||
const_iterator cend() const
|
||||
{
|
||||
return const_iterator(base.data_.end());
|
||||
}
|
||||
|
||||
// modifiers
|
||||
|
||||
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
||||
template <class... Args>
|
||||
iterator emplace(Args&&... args)
|
||||
{
|
||||
return iterator(base.insert(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
iterator emplace(const_iterator hint, Args&&... args)
|
||||
{
|
||||
return iterator(base.insert_hint(get(hint), std::forward<Args>(args)...));
|
||||
}
|
||||
#endif
|
||||
|
||||
iterator insert(const value_type& obj)
|
||||
{
|
||||
return iterator(base.insert(obj));
|
||||
}
|
||||
|
||||
iterator insert(const_iterator hint, const value_type& obj)
|
||||
{
|
||||
return iterator(base.insert_hint(get(hint), obj));
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
void insert(InputIterator first, InputIterator last)
|
||||
{
|
||||
base.insert_range(first, last);
|
||||
}
|
||||
|
||||
iterator erase(const_iterator position)
|
||||
{
|
||||
return iterator(base.data_.erase(get(position)));
|
||||
}
|
||||
|
||||
size_type erase(const key_type& k)
|
||||
{
|
||||
return base.erase_key(k);
|
||||
}
|
||||
|
||||
iterator erase(const_iterator first, const_iterator last)
|
||||
{
|
||||
return iterator(base.data_.erase_range(get(first), get(last)));
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
base.data_.clear();
|
||||
}
|
||||
|
||||
void swap(unordered_multiset& other)
|
||||
{
|
||||
base.swap(other.base);
|
||||
}
|
||||
|
||||
// observers
|
||||
|
||||
hasher hash_function() const
|
||||
{
|
||||
return base.hash_function();
|
||||
}
|
||||
|
||||
key_equal key_eq() const
|
||||
{
|
||||
return base.key_eq();
|
||||
}
|
||||
|
||||
// lookup
|
||||
|
||||
const_iterator find(const key_type& k) const
|
||||
{
|
||||
return const_iterator(base.find(k));
|
||||
}
|
||||
|
||||
size_type count(const key_type& k) const
|
||||
{
|
||||
return base.count(k);
|
||||
}
|
||||
|
||||
std::pair<const_iterator, const_iterator>
|
||||
equal_range(const key_type& k) const
|
||||
{
|
||||
return boost::unordered_detail::pair_cast<const_iterator, const_iterator>(
|
||||
base.equal_range(k));
|
||||
}
|
||||
|
||||
// bucket interface
|
||||
|
||||
size_type bucket_count() const
|
||||
{
|
||||
return base.bucket_count();
|
||||
}
|
||||
|
||||
size_type max_bucket_count() const
|
||||
{
|
||||
return base.max_bucket_count();
|
||||
}
|
||||
|
||||
size_type bucket_size(size_type n) const
|
||||
{
|
||||
return base.data_.bucket_size(n);
|
||||
}
|
||||
|
||||
size_type bucket(const key_type& k) const
|
||||
{
|
||||
return base.bucket(k);
|
||||
}
|
||||
|
||||
local_iterator begin(size_type n)
|
||||
{
|
||||
return local_iterator(base.data_.begin(n));
|
||||
}
|
||||
|
||||
const_local_iterator begin(size_type n) const
|
||||
{
|
||||
return const_local_iterator(base.data_.begin(n));
|
||||
}
|
||||
|
||||
local_iterator end(size_type n)
|
||||
{
|
||||
return local_iterator(base.data_.end(n));
|
||||
}
|
||||
|
||||
const_local_iterator end(size_type n) const
|
||||
{
|
||||
return const_local_iterator(base.data_.end(n));
|
||||
}
|
||||
|
||||
const_local_iterator cbegin(size_type n) const
|
||||
{
|
||||
return const_local_iterator(base.data_.begin(n));
|
||||
}
|
||||
|
||||
const_local_iterator cend(size_type n) const
|
||||
{
|
||||
return const_local_iterator(base.data_.end(n));
|
||||
}
|
||||
|
||||
// hash policy
|
||||
|
||||
float load_factor() const
|
||||
{
|
||||
return base.load_factor();
|
||||
}
|
||||
|
||||
float max_load_factor() const
|
||||
{
|
||||
return base.max_load_factor();
|
||||
}
|
||||
|
||||
void max_load_factor(float m)
|
||||
{
|
||||
base.max_load_factor(m);
|
||||
}
|
||||
|
||||
void rehash(size_type n)
|
||||
{
|
||||
base.rehash(n);
|
||||
}
|
||||
|
||||
friend bool operator==(unordered_multiset const& m1, unordered_multiset const& m2)
|
||||
{
|
||||
return m1.base.equals(m2.base);
|
||||
}
|
||||
|
||||
friend bool operator!=(unordered_multiset const& m1, unordered_multiset const& m2)
|
||||
{
|
||||
return !m1.base.equals(m2.base);
|
||||
}
|
||||
|
||||
friend std::size_t hash_value(unordered_multiset const& m)
|
||||
{
|
||||
return m.base.hash_value();
|
||||
}
|
||||
}; // class template unordered_multiset
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
void swap(unordered_multiset<T, H, P, A> &m1,
|
||||
unordered_multiset<T, H, P, A> &m2)
|
||||
{
|
||||
m1.swap(m2);
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
#include <boost/unordered/unordered_set.hpp>
|
||||
|
||||
#endif // BOOST_UNORDERED_SET_HPP_INCLUDED
|
||||
|
@ -53,6 +53,11 @@ namespace test {
|
||||
struct globally_counted_object
|
||||
: counted_object<globally_counted_object> {};
|
||||
|
||||
// This won't be a problem as I'm only using a single compile unit
|
||||
// in each test (this is actually require by the minimal test
|
||||
// framework).
|
||||
//
|
||||
// boostinspect:nounnamed
|
||||
namespace {
|
||||
object_count& global_object_count = globally_counted_object::count_;
|
||||
}
|
||||
|
@ -44,6 +44,11 @@ namespace test
|
||||
}
|
||||
};
|
||||
|
||||
// This won't be a problem as I'm only using a single compile unit
|
||||
// in each test (this is actually require by the minimal test
|
||||
// framework).
|
||||
//
|
||||
// boostinspect:nounnamed
|
||||
namespace {
|
||||
equivalent_type equivalent;
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include <new>
|
||||
#include "../helpers/fwd.hpp"
|
||||
#include "../helpers/allocator.hpp"
|
||||
#include "./memory.hpp"
|
||||
#include "../helpers/memory.hpp"
|
||||
|
||||
namespace test
|
||||
{
|
||||
|
@ -240,7 +240,7 @@ namespace minimal
|
||||
size_type max_size() const { return 1000; }
|
||||
|
||||
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) || \
|
||||
BOOST_WORKAROUND(MSVC, <= 1300)
|
||||
BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
public: allocator& operator=(allocator const&) { return *this;}
|
||||
#else
|
||||
private: allocator& operator=(allocator const&);
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include <iostream>
|
||||
#include "../helpers/fwd.hpp"
|
||||
#include "../helpers/count.hpp"
|
||||
#include "./memory.hpp"
|
||||
#include "../helpers/memory.hpp"
|
||||
#include <map>
|
||||
|
||||
namespace test
|
||||
@ -156,6 +156,11 @@ namespace test
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// This won't be a problem as I'm only using a single compile unit
|
||||
// in each test (this is actually require by the minimal test
|
||||
// framework).
|
||||
//
|
||||
// boostinspect:nounnamed
|
||||
namespace {
|
||||
test::detail::memory_tracker<std::allocator<int> > tracker;
|
||||
}
|
||||
|
@ -14,6 +14,8 @@ project unordered-test/unordered
|
||||
|
||||
test-suite unordered
|
||||
:
|
||||
[ run fwd_set_test.cpp ]
|
||||
[ run fwd_map_test.cpp ]
|
||||
[ run compile_set.cpp ]
|
||||
[ run compile_map.cpp ]
|
||||
[ run link_test_1.cpp link_test_2.cpp ]
|
||||
|
@ -13,6 +13,21 @@
|
||||
#include "../objects/minimal.hpp"
|
||||
#include "./compile_tests.hpp"
|
||||
|
||||
// Explicit instantiation to catch compile-time errors
|
||||
|
||||
template class boost::unordered_map<
|
||||
test::minimal::assignable,
|
||||
test::minimal::default_copy_constructible,
|
||||
test::minimal::hash<test::minimal::assignable>,
|
||||
test::minimal::equal_to<test::minimal::assignable>,
|
||||
test::minimal::allocator<test::minimal::assignable> >;
|
||||
template class boost::unordered_multimap<
|
||||
test::minimal::assignable,
|
||||
test::minimal::copy_constructible,
|
||||
test::minimal::hash<test::minimal::assignable>,
|
||||
test::minimal::equal_to<test::minimal::assignable>,
|
||||
test::minimal::allocator<test::minimal::assignable> >;
|
||||
|
||||
UNORDERED_AUTO_TEST(test0)
|
||||
{
|
||||
typedef std::pair<test::minimal::assignable const,
|
||||
|
@ -13,6 +13,19 @@
|
||||
#include "../objects/minimal.hpp"
|
||||
#include "./compile_tests.hpp"
|
||||
|
||||
// Explicit instantiation to catch compile-time errors
|
||||
|
||||
template class boost::unordered_set<
|
||||
test::minimal::assignable,
|
||||
test::minimal::hash<test::minimal::assignable>,
|
||||
test::minimal::equal_to<test::minimal::assignable>,
|
||||
test::minimal::allocator<test::minimal::assignable> >;
|
||||
template class boost::unordered_multiset<
|
||||
test::minimal::assignable,
|
||||
test::minimal::hash<test::minimal::assignable>,
|
||||
test::minimal::equal_to<test::minimal::assignable>,
|
||||
test::minimal::allocator<test::minimal::assignable> >;
|
||||
|
||||
UNORDERED_AUTO_TEST(test0)
|
||||
{
|
||||
test::minimal::assignable assignable = test::minimal::assignable::create();
|
||||
|
@ -168,11 +168,6 @@ void equality_test(X& r)
|
||||
|
||||
test::check_return_type<bool>::equals(a == b);
|
||||
test::check_return_type<bool>::equals(a != b);
|
||||
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
||||
test::check_return_type<std::size_t>::equals(boost::hash_value(a));
|
||||
#else
|
||||
test::check_return_type<std::size_t>::equals(hash_value(a));
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class X, class T>
|
||||
@ -295,7 +290,7 @@ void unordered_test(X&, Key& k, T& t, Hash& hf, Pred& eq)
|
||||
const_iterator q = a.cbegin();
|
||||
test::check_return_type<iterator>::equals(a.insert(q, t));
|
||||
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
||||
test::check_return_type<iterator>::equals(a.emplace(q, t));
|
||||
test::check_return_type<iterator>::equals(a.emplace_hint(q, t));
|
||||
#endif
|
||||
|
||||
a.insert(i, j);
|
||||
|
@ -25,118 +25,118 @@ namespace equality_tests
|
||||
};
|
||||
|
||||
#define UNORDERED_EQUALITY_SET_TEST(seq1, op, seq2) \
|
||||
do { \
|
||||
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_CHECK(set1 op set2); \
|
||||
} while(false)
|
||||
do { \
|
||||
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_CHECK(set1 op set2); \
|
||||
} while(false)
|
||||
|
||||
#define UNORDERED_EQUALITY_MULTISET_TEST(seq1, op, seq2) \
|
||||
do { \
|
||||
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_CHECK(set1 op set2); \
|
||||
} while(false)
|
||||
do { \
|
||||
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_CHECK(set1 op set2); \
|
||||
} while(false)
|
||||
|
||||
#define UNORDERED_EQUALITY_MAP_TEST(seq1, op, seq2) \
|
||||
do { \
|
||||
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_CHECK(map1 op map2); \
|
||||
} while(false)
|
||||
do { \
|
||||
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_CHECK(map1 op map2); \
|
||||
} while(false)
|
||||
|
||||
#define UNORDERED_EQUALITY_MULTIMAP_TEST(seq1, op, seq2) \
|
||||
do { \
|
||||
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_CHECK(map1 op map2); \
|
||||
} while(false)
|
||||
do { \
|
||||
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_CHECK(map1 op map2); \
|
||||
} while(false)
|
||||
|
||||
#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));
|
||||
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_CHECK(x1 == x2);
|
||||
BOOST_CHECK(!(x1 != x2));
|
||||
UNORDERED_AUTO_TEST(equality_size_tests)
|
||||
{
|
||||
boost::unordered_set<int> x1, x2;
|
||||
BOOST_CHECK(x1 == x2);
|
||||
BOOST_CHECK(!(x1 != x2));
|
||||
|
||||
x1.insert(1);
|
||||
BOOST_CHECK(x1 != x2);
|
||||
BOOST_CHECK(!(x1 == x2));
|
||||
BOOST_CHECK(x2 != x1);
|
||||
BOOST_CHECK(!(x2 == x1));
|
||||
|
||||
x2.insert(1);
|
||||
BOOST_CHECK(x1 == x2);
|
||||
BOOST_CHECK(!(x1 != x2));
|
||||
|
||||
x2.insert(2);
|
||||
BOOST_CHECK(x1 != x2);
|
||||
BOOST_CHECK(!(x1 == x2));
|
||||
BOOST_CHECK(x2 != x1);
|
||||
BOOST_CHECK(!(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)));
|
||||
}
|
||||
|
||||
x1.insert(1);
|
||||
BOOST_CHECK(x1 != x2);
|
||||
BOOST_CHECK(!(x1 == x2));
|
||||
BOOST_CHECK(x2 != x1);
|
||||
BOOST_CHECK(!(x2 == x1));
|
||||
|
||||
x2.insert(1);
|
||||
BOOST_CHECK(x1 == x2);
|
||||
BOOST_CHECK(!(x1 != x2));
|
||||
|
||||
x2.insert(2);
|
||||
BOOST_CHECK(x1 != x2);
|
||||
BOOST_CHECK(!(x1 == x2));
|
||||
BOOST_CHECK(x2 != x1);
|
||||
BOOST_CHECK(!(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_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_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_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)));
|
||||
}
|
||||
UNORDERED_EQUALITY_SET_TEST(
|
||||
(1), ==, (1001));
|
||||
UNORDERED_EQUALITY_MAP_TEST(
|
||||
((1)(2))((1001)(1)), ==, ((1001)(2))((1)(1)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
62
test/unordered/fwd_map_test.cpp
Normal file
62
test/unordered/fwd_map_test.cpp
Normal file
@ -0,0 +1,62 @@
|
||||
|
||||
// Copyright 2008 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/unordered_map_fwd.hpp>
|
||||
|
||||
typedef boost::unordered_map<int, int> int_map;
|
||||
|
||||
void call_swap(int_map& x, int_map& y) {
|
||||
swap(x,y);
|
||||
}
|
||||
|
||||
bool call_equals(int_map& x, int_map& y) {
|
||||
return x == y;
|
||||
}
|
||||
|
||||
bool call_not_equals(int_map& x, int_map& y) {
|
||||
return x != y;
|
||||
}
|
||||
|
||||
typedef boost::unordered_multimap<int, int> int_multimap;
|
||||
|
||||
void call_swap(int_multimap& x, int_multimap& y) {
|
||||
swap(x,y);
|
||||
}
|
||||
|
||||
bool call_equals(int_multimap& x, int_multimap& y) {
|
||||
return x == y;
|
||||
}
|
||||
|
||||
bool call_not_equals(int_multimap& x, int_multimap& y) {
|
||||
return x != y;
|
||||
}
|
||||
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/test.hpp"
|
||||
|
||||
UNORDERED_AUTO_TEST(use_map_fwd_declared_function) {
|
||||
int_map x, y;
|
||||
x[1] = 2;
|
||||
y[2] = 1;
|
||||
call_swap(x, y);
|
||||
|
||||
BOOST_CHECK(y.find(1) != y.end() && y.find(1)->second == 2);
|
||||
BOOST_CHECK(y.find(2) == y.end());
|
||||
|
||||
BOOST_CHECK(x.find(1) == x.end());
|
||||
BOOST_CHECK(x.find(2) != x.end() && x.find(2)->second == 1);
|
||||
|
||||
BOOST_CHECK(!call_equals(x, y));
|
||||
BOOST_CHECK(call_not_equals(x, y));
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(use_multimap_fwd_declared_function) {
|
||||
int_multimap x, y;
|
||||
call_swap(x, y);
|
||||
BOOST_CHECK(call_equals(x, y));
|
||||
BOOST_CHECK(!call_not_equals(x, y));
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
84
test/unordered/fwd_set_test.cpp
Normal file
84
test/unordered/fwd_set_test.cpp
Normal file
@ -0,0 +1,84 @@
|
||||
|
||||
// Copyright 2008 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/unordered_set_fwd.hpp>
|
||||
|
||||
struct true_type { char x[100]; };
|
||||
struct false_type { char x; };
|
||||
|
||||
false_type is_unordered_set_impl(void*);
|
||||
|
||||
template <class Value, class Hash, class Pred, class Alloc>
|
||||
true_type is_unordered_set_impl(
|
||||
boost::unordered_set<Value, Hash, Pred, Alloc>*);
|
||||
|
||||
typedef boost::unordered_set<int> int_set;
|
||||
|
||||
void call_swap(int_set& x, int_set& y) {
|
||||
swap(x,y);
|
||||
}
|
||||
|
||||
bool call_equals(int_set& x, int_set& y) {
|
||||
return x == y;
|
||||
}
|
||||
|
||||
bool call_not_equals(int_set& x, int_set& y) {
|
||||
return x != y;
|
||||
}
|
||||
|
||||
typedef boost::unordered_multiset<int> int_multiset;
|
||||
|
||||
void call_swap(int_multiset& x, int_multiset& y) {
|
||||
swap(x,y);
|
||||
}
|
||||
|
||||
bool call_equals(int_multiset& x, int_multiset& y) {
|
||||
return x == y;
|
||||
}
|
||||
|
||||
bool call_not_equals(int_multiset& x, int_multiset& y) {
|
||||
return x != y;
|
||||
}
|
||||
|
||||
#include "../helpers/test.hpp"
|
||||
|
||||
UNORDERED_AUTO_TEST(use_fwd_declared_trait_without_definition) {
|
||||
BOOST_CHECK(sizeof(is_unordered_set_impl((int_set*) 0)) == sizeof(true_type));
|
||||
}
|
||||
|
||||
#include <boost/unordered_set.hpp>
|
||||
|
||||
UNORDERED_AUTO_TEST(use_fwd_declared_trait) {
|
||||
boost::unordered_set<int> x;
|
||||
BOOST_CHECK(sizeof(is_unordered_set_impl(&x)) == sizeof(true_type));
|
||||
|
||||
int dummy;
|
||||
BOOST_CHECK(sizeof(is_unordered_set_impl(&dummy)) == sizeof(false_type));
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(use_set_fwd_declared_function) {
|
||||
int_set x, y;
|
||||
x.insert(1);
|
||||
y.insert(2);
|
||||
call_swap(x, y);
|
||||
|
||||
BOOST_CHECK(y.find(1) != y.end());
|
||||
BOOST_CHECK(y.find(2) == y.end());
|
||||
|
||||
BOOST_CHECK(x.find(1) == x.end());
|
||||
BOOST_CHECK(x.find(2) != x.end());
|
||||
|
||||
BOOST_CHECK(!call_equals(x, y));
|
||||
BOOST_CHECK(call_not_equals(x, y));
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(use_multiset_fwd_declared_function) {
|
||||
int_multiset x, y;
|
||||
call_swap(x, y);
|
||||
BOOST_CHECK(call_equals(x, y));
|
||||
BOOST_CHECK(!call_not_equals(x, y));
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
@ -84,12 +84,11 @@ namespace unnecessary_copy_tests
|
||||
template <class T>
|
||||
void unnecessary_copy_insert_test(T*)
|
||||
{
|
||||
reset();
|
||||
T x;
|
||||
BOOST_DEDUCED_TYPENAME T::value_type a;
|
||||
COPY_COUNT(1);
|
||||
reset();
|
||||
x.insert(a);
|
||||
COPY_COUNT(2);
|
||||
COPY_COUNT(1);
|
||||
}
|
||||
|
||||
boost::unordered_set<count_copies>* set;
|
||||
|
Reference in New Issue
Block a user