Compare commits

...

10 Commits

Author SHA1 Message Date
81d2bd284c 1.36.0
[SVN r48100]
2008-08-12 12:44:50 +00:00
93141c26b9 Merge a couple of simple documentation fixes.
Merged revisions 47881-47882 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r47881 | danieljames | 2008-07-30 10:44:26 +0100 (Wed, 30 Jul 2008) | 1 line
  
  Fix a link and a header.
........
  r47882 | danieljames | 2008-07-30 11:46:27 +0100 (Wed, 30 Jul 2008) | 1 line
  
  Use the correct library page for the asio documentation.
........


[SVN r47900]
2008-07-30 22:29:27 +00:00
dd2a994874 Merge in some small documentation fixes.
Merged revisions 47054,47750,47766,47800,47807,47811-47813 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r47750 | danieljames | 2008-07-24 11:14:15 +0100 (Thu, 24 Jul 2008) | 2 lines
  
  Remove some old information that's no longer true.
........
  r47766 | danieljames | 2008-07-24 19:16:09 +0100 (Thu, 24 Jul 2008) | 1 line
  
  Link to Igor Zlatkovic's xsltproc packages.
........
  r47800 | danieljames | 2008-07-25 11:24:50 +0100 (Fri, 25 Jul 2008) | 1 line
  
  Fix a link.
........
  r47807 | danieljames | 2008-07-25 18:52:11 +0100 (Fri, 25 Jul 2008) | 1 line
  
  Convert a few 'unacceptable' characters to underscores in generated documentation filenames.
........
  r47811 | danieljames | 2008-07-25 22:13:27 +0100 (Fri, 25 Jul 2008) | 1 line
  
  Avoid some more unacceptable characters.
........
  r47812 | danieljames | 2008-07-25 22:15:39 +0100 (Fri, 25 Jul 2008) | 1 line
  
  Merge asio details from the release branch.
........
  r47813 | danieljames | 2008-07-25 22:25:58 +0100 (Fri, 25 Jul 2008) | 1 line
  
  Fix a typo.
........


[SVN r47819]
2008-07-25 22:47:41 +00:00
6571648bac Remove hash_value for unordered containers.
Merged revisions 47463,47465,47522 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r47463 | danieljames | 2008-07-15 22:26:54 +0100 (Tue, 15 Jul 2008) | 1 line
  
  Better hash function for unordered containers. Still a bit rubbish.
........
  r47465 | danieljames | 2008-07-15 23:03:15 +0100 (Tue, 15 Jul 2008) | 4 lines
  
  On second thoughts, I'll just completely remove hash_value for ordered
  containers. It's low quality and not very generic (it uses boost::hash for
  mapped values). Should be a painless change.
........
  r47522 | danieljames | 2008-07-18 00:08:32 +0100 (Fri, 18 Jul 2008) | 1 line
  
  Remove a mention of the hash functions which I missed before.
........


[SVN r47523]
2008-07-17 23:33:51 +00:00
f20f72bade Merge some documentation updates and fixes from trunk.
Merged revisions 47364,47402-47403 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r47364 | danieljames | 2008-07-12 20:32:15 +0100 (Sat, 12 Jul 2008) | 1 line
  
  Fix a PDF link that I missed before. (in static assert)
........
  r47402 | danieljames | 2008-07-13 20:42:56 +0100 (Sun, 13 Jul 2008) | 2 lines
  
  Note that emplace is only available on a few compilers.
........
  r47403 | danieljames | 2008-07-13 21:07:45 +0100 (Sun, 13 Jul 2008) | 2 lines
  
  Update the implementation details.
........


[SVN r47405]
2008-07-13 21:08:33 +00:00
4e4f99d51f Make the unordered constructors from allocators explicit.
And clean of the FNV-1 example & documentation a little.

Merged revisions 47085,47132,47143-47146 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r47085 | danieljames | 2008-07-04 23:57:20 +0100 (Fri, 04 Jul 2008) | 4 lines
  
  Require explicit conversion from allocators.
  
  (Not what it says in the draft standard, but I think that might be a defect).
........
  r47132 | danieljames | 2008-07-06 13:41:09 +0100 (Sun, 06 Jul 2008) | 2 lines
  
  'Bias' should be 'basis'.
........
  r47143 | danieljames | 2008-07-06 22:06:52 +0100 (Sun, 06 Jul 2008) | 1 line
  
  Clean up the FNV-1 comments.
........
  r47144 | danieljames | 2008-07-06 22:07:31 +0100 (Sun, 06 Jul 2008) | 1 line
  
  I've only got one hash function for release, so no need for its own directory.
........
  r47145 | danieljames | 2008-07-06 22:08:11 +0100 (Sun, 06 Jul 2008) | 1 line
  
  Remove the hash_functions directory (for now).
........
  r47146 | danieljames | 2008-07-06 22:29:47 +0100 (Sun, 06 Jul 2008) | 1 line
  
  Update the docs for the new location of FNV-1.
........


[SVN r47150]
2008-07-06 22:00:18 +00:00
56b9e0da1a Merge some small fixes from trunk.
Merged revisions 46740,46742,47002,47040 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r46740 | danieljames | 2008-06-26 20:20:56 +0100 (Thu, 26 Jun 2008) | 1 line
  
  Fix a character encoding error.
........
  r46742 | danieljames | 2008-06-26 20:25:38 +0100 (Thu, 26 Jun 2008) | 6 lines
  
  Give the asio documentation its own target.
  
  The asio documentation is built with the rest of the combined documentation but
  is really separate. So give it its own target so that separate parts can be
  built separately.
........
  r47040 | danieljames | 2008-07-03 15:34:56 +0100 (Thu, 03 Jul 2008) | 1 line
  
  Workaround for some template syntax not supported in old versions of Visual C++ 6.5
........


[SVN r47078]
2008-07-04 17:04:47 +00:00
4f27a146ef Merge from trunk. Fix some inspect errors, try to avoid instantiating the
equality operators when not required, and some bookkeeping.

................
  r42539 | danieljames | 2008-01-06 17:48:11 +0000 (Sun, 06 Jan 2008) | 2 lines
  
  Add the unordered library to the maintainers list.
................
  r46579 | danieljames | 2008-06-21 16:32:11 +0100 (Sat, 21 Jun 2008) | 10 lines
  
  Define unordered containers' friend functions outside of the class.
  
  On some compilers, friend functions are being instantiated when the main class
  is explicitly instantiated. This is slightly problematic because the equality
  functions (which are an extension) put extra requirements on the types used. So
  I'm going to try defining the functions outside of the class, in the hope that
  they won't get instantiated. If someone wants non-member functions to be
  instantiated, I think it's reasonable to expect them to explicitly instantiate
  them, especially as compilers don't seem to be consistent about this.
................
  r46587 | danieljames | 2008-06-21 20:58:39 +0100 (Sat, 21 Jun 2008) | 8 lines
  
  Get the test to pass when pair's default constructor creates two instances of
  the member classes.
  
  With some standard libraries I was getting two copies of the object after
  creating a default pair, probably because it was creating an instance for its
  default parameter. So only test after creating the pair object - since it isn't
  our concern how many instances that creates.
................
  r46588 | danieljames | 2008-06-21 21:11:26 +0100 (Sat, 21 Jun 2008) | 1 line
  
  Markup an expected failure for unordered.
................
  r46594 | danieljames | 2008-06-21 23:02:15 +0100 (Sat, 21 Jun 2008) | 19 lines
  
  Merge inspect fixes for the unordered library.
  
  Merged revisions 46470-46592 via svnmerge from 
  https://svn.boost.org/svn/boost/branches/unordered/trunk
  
  ................
    r46589 | danieljames | 2008-06-21 21:37:42 +0100 (Sat, 21 Jun 2008) | 2 lines
    
    Fix some inspect errors (tabs and missing copyright/license).
  ................
    r46591 | danieljames | 2008-06-21 21:47:51 +0100 (Sat, 21 Jun 2008) | 1 line
    
    Move memory.hpp into the helpers subdirectory.
  ................
    r46592 | danieljames | 2008-06-21 22:08:53 +0100 (Sat, 21 Jun 2008) | 1 line
    
    Prevent inspect errors for unnamed namespaces in some of the test header files.
  ................
................
  r46607 | danieljames | 2008-06-22 14:54:45 +0100 (Sun, 22 Jun 2008) | 9 lines
  
  Extract the hash and equality functions from hash_table_data_*.
  
  As these are extensions and add extra requirements to the container elements,
  they shouldn't be part of hash_table_data_* so that they won't get instantiated
  if an unordered container is explicitly instantiated.
  
  Merged revisions 46594-46604 via svnmerge from 
  https://svn.boost.org/svn/boost/branches/unordered/trunk
................
  r46608 | danieljames | 2008-06-22 16:00:02 +0100 (Sun, 22 Jun 2008) | 5 lines
  
  Remove the svnmerge integration information for the unordered branch.
  
  Now that the unordered library is moving towards release, the main development
  version is in trunk. New features will be developed on a new branch.
................


[SVN r46629]
2008-06-23 17:44:53 +00:00
c8d0cb88ad Merge unordered 'move_from' fix from trunk [46410].
[SVN r46413]
2008-06-15 19:21:12 +00:00
5a898f2419 Add Boost.Unordered to release branch.
[SVN r46342]
2008-06-12 00:26:08 +00:00
23 changed files with 492 additions and 471 deletions

View File

@ -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>

View File

@ -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,6 @@ 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.
[endsect]

View File

@ -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
`!=`].]
]

View File

@ -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

View File

@ -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]>

View File

@ -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]

View File

@ -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&amp;</paramtype>
</parameter>
@ -284,6 +284,7 @@ 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">
@ -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&lt;Value, Hash, Pred, Alloc&gt; const&amp;</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">
@ -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&amp;</paramtype>
</parameter>
@ -1030,6 +1013,7 @@ 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">
@ -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&lt;Value, Hash, Pred, Alloc&gt; const&amp;</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">
@ -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&amp;</paramtype>
</parameter>
@ -1788,6 +1754,7 @@ 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">
@ -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&lt;Key, Mapped, Hash, Pred, Alloc&gt; const&amp;</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">
@ -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&amp;</paramtype>
</parameter>
@ -2585,6 +2532,7 @@ 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">
@ -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&lt;Key, Mapped, Hash, Pred, Alloc&gt; const&amp;</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>

View File

@ -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
View 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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -32,6 +32,34 @@ namespace boost
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>&);
template <class Key, class T, class Hash, class Pred, class Alloc>
class unordered_map
{
typedef boost::unordered_detail::hash_types_unique_keys<
@ -75,8 +103,7 @@ namespace boost
{
}
// TODO: Should this be explicit?
unordered_map(allocator_type const& a)
explicit unordered_map(allocator_type const& a)
: base(boost::unordered_detail::default_initial_bucket_count,
hasher(), key_equal(), a)
{
@ -122,7 +149,7 @@ namespace boost
}
#else
unordered_map(boost::unordered_detail::move_from<unordered_map<Key, T, Hash, Pred, Alloc> > other)
: base(other.base, boost::unordered_detail::move_tag())
: base(other.source.base, boost::unordered_detail::move_tag())
{
}
@ -390,34 +417,37 @@ namespace boost
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();
}
#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>
void swap(unordered_map<K, T, H, P, A> &m1,
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 = hash<Key>,
class Pred = std::equal_to<Key>,
class Alloc = std::allocator<std::pair<const Key, T> > >
template <class Key, class T, class Hash, class Pred, class Alloc>
class unordered_multimap
{
typedef boost::unordered_detail::hash_types_equivalent_keys<
@ -461,7 +491,7 @@ namespace boost
{
}
unordered_multimap(allocator_type const& a)
explicit unordered_multimap(allocator_type const& a)
: base(boost::unordered_detail::default_initial_bucket_count,
hasher(), key_equal(), a)
{
@ -507,7 +537,7 @@ namespace boost
}
#else
unordered_multimap(boost::unordered_detail::move_from<unordered_multimap<Key, T, Hash, Pred, Alloc> > other)
: base(other.base, boost::unordered_detail::move_tag())
: base(other.source.base, boost::unordered_detail::move_tag())
{
}
@ -759,24 +789,31 @@ namespace boost
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();
}
#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>
void swap(unordered_multimap<K, T, H, P, A> &m1,
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);

View File

@ -31,6 +31,33 @@ namespace boost
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);
template <class Value, class Hash, class Pred, class Alloc>
class unordered_set
{
typedef boost::unordered_detail::hash_types_unique_keys<
@ -73,8 +100,7 @@ namespace boost
{
}
// TODO: Should this be explicit?
unordered_set(allocator_type const& a)
explicit unordered_set(allocator_type const& a)
: base(boost::unordered_detail::default_initial_bucket_count,
hasher(), key_equal(), a)
{
@ -119,7 +145,7 @@ namespace boost
}
#else
unordered_set(boost::unordered_detail::move_from<unordered_set<Value, Hash, Pred, Alloc> > other)
: base(other.base, boost::unordered_detail::move_tag())
: base(other.source.base, boost::unordered_detail::move_tag())
{
}
@ -361,33 +387,37 @@ namespace boost
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();
}
#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>
void swap(unordered_set<T, H, P, A> &m1,
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 = hash<Value>,
class Pred = std::equal_to<Value>,
class Alloc = std::allocator<Value> >
template <class Value, class Hash, class Pred, class Alloc>
class unordered_multiset
{
typedef boost::unordered_detail::hash_types_equivalent_keys<
@ -430,8 +460,7 @@ namespace boost
{
}
// TODO: Should this be explicit?
unordered_multiset(allocator_type const& a)
explicit unordered_multiset(allocator_type const& a)
: base(boost::unordered_detail::default_initial_bucket_count,
hasher(), key_equal(), a)
{
@ -476,7 +505,7 @@ namespace boost
}
#else
unordered_multiset(boost::unordered_detail::move_from<unordered_multiset<Value, Hash, Pred, Alloc> > other)
: base(other.base, boost::unordered_detail::move_tag())
: base(other.source.base, boost::unordered_detail::move_tag())
{
}
@ -715,24 +744,31 @@ namespace boost
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();
}
#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>
void swap(unordered_multiset<T, H, P, A> &m1,
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);

View File

@ -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_;
}

View File

@ -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;
}

View File

@ -14,7 +14,7 @@
#include <new>
#include "../helpers/fwd.hpp"
#include "../helpers/allocator.hpp"
#include "./memory.hpp"
#include "../helpers/memory.hpp"
namespace test
{

View File

@ -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;
}

View File

@ -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,

View File

@ -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();

View File

@ -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>

View File

@ -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)));
}
}

View File

@ -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;