Compare commits

...

35 Commits

Author SHA1 Message Date
ca39084331 Release 1.40.0
[SVN r55802]
2009-08-27 16:24:59 +00:00
df1dad5cb6 Merge an unordered documentation change that I missed before.
Merged revisions 54914 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r54914 | danieljames | 2009-07-12 19:03:35 +0100 (Sun, 12 Jul 2009) | 1 line
  
  Add constructors to the methods for controlling bucket size in unordered containers.
........


[SVN r55211]
2009-07-27 20:46:40 +00:00
1bc3ae3d9d Merge unordered changes, including fixes for Boost.TR1.
Merged revisions 55099-55100,55132,55138,55184-55185 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r55099 | danieljames | 2009-07-22 23:37:52 +0100 (Wed, 22 Jul 2009) | 1 line
  
  Fix the insert tests when there is a small number of buckets.
........
  r55100 | danieljames | 2009-07-22 23:38:08 +0100 (Wed, 22 Jul 2009) | 1 line
  
  Adjust the unordered defaults so that emplace takes more parameters and less buckets are created by default.
........
  r55132 | danieljames | 2009-07-23 18:53:59 +0100 (Thu, 23 Jul 2009) | 1 line
  
  Remove the emulation of single argument C++0x std::pair constructor.
........
  r55138 | danieljames | 2009-07-23 23:17:20 +0100 (Thu, 23 Jul 2009) | 1 line
  
  Try to work around an odd Visual C++ 8 bug.
........
  r55184 | danieljames | 2009-07-26 19:59:33 +0100 (Sun, 26 Jul 2009) | 1 line
  
  Some extra changelog notes.
........
  r55185 | danieljames | 2009-07-26 20:00:40 +0100 (Sun, 26 Jul 2009) | 1 line
  
  Update the reference documentation to mention that emplace is now emulated.
........


[SVN r55189]
2009-07-26 20:22:48 +00:00
60ecf12779 Add basic copyright/license to keep cmake out of the inspection report
[SVN r55095]
2009-07-22 21:51:01 +00:00
241316e0d9 Misc. unordered changes. Fixes #3082, #3119.
Merged revisions 53505-53506,53525,53550,53552,53614 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r53505 | danieljames | 2009-05-31 16:50:56 +0100 (Sun, 31 May 2009) | 1 line
  
  Disable incorrect Visual C++ 64-bit warnings. Ref #3082.
........
  r53506 | danieljames | 2009-05-31 16:53:09 +0100 (Sun, 31 May 2009) | 1 line
  
  Remove misplaced visual C++ warning pragma.
........
  r53525 | danieljames | 2009-06-01 07:50:37 +0100 (Mon, 01 Jun 2009) | 1 line
  
  Fix tests for when the library has support for initializer lists but the compiler doesn't.
........
  r53550 | danieljames | 2009-06-01 20:17:49 +0100 (Mon, 01 Jun 2009) | 1 line
  
  Get the type of the initializer_list right.
........
  r53552 | danieljames | 2009-06-01 20:22:27 +0100 (Mon, 01 Jun 2009) | 1 line
  
  Fix the unordered_map declaration in the tutorial. Fixes #3119.
........
  r53614 | danieljames | 2009-06-03 23:48:49 +0100 (Wed, 03 Jun 2009) | 1 line
  
  The move tests pass on 64 bit visual c++.
........


[SVN r53687]
2009-06-06 14:05:54 +00:00
9c43533655 A couple more minor unordered changes.
Merged revisions 53312,53367 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r53312 | danieljames | 2009-05-27 18:43:22 +0100 (Wed, 27 May 2009) | 1 line
  
  Remove obsolete comment.
........
  r53367 | danieljames | 2009-05-28 23:06:42 +0100 (Thu, 28 May 2009) | 1 line
  
  Remove a couple of old uses of BOOST_NO_INITIALIZER_LISTS.
........


[SVN r53466]
2009-05-30 17:41:05 +00:00
ae09b0dd24 Merge latest changes for unordered. Improved compatability and a few tweaks.
Merged revisions 53127,53253,53256,53311,53314,53316-53318 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r53127 | danieljames | 2009-05-20 07:43:38 +0100 (Wed, 20 May 2009) | 1 line
  
  Better configuration for boost.unordered.
........
  r53253 | danieljames | 2009-05-25 20:14:07 +0100 (Mon, 25 May 2009) | 3 lines
  
  Add explicit destructors to the unordered containers. Refs #2908.
  
  Isn't really needed but it doesn't hurt.
........
  r53256 | danieljames | 2009-05-25 20:45:23 +0100 (Mon, 25 May 2009) | 1 line
  
  Unordered change log for explicit destructors.
........
  r53311 | danieljames | 2009-05-27 18:42:01 +0100 (Wed, 27 May 2009) | 1 line
  
  Missing changelog entry.
........
  r53314 | danieljames | 2009-05-27 18:44:09 +0100 (Wed, 27 May 2009) | 1 line
  
  Use lightweight_test for unordered.
........
  r53316 | danieljames | 2009-05-27 19:19:32 +0100 (Wed, 27 May 2009) | 1 line
  
  Some workarounds for old versions of Borland.
........
  r53317 | danieljames | 2009-05-27 19:32:22 +0100 (Wed, 27 May 2009) | 1 line
  
  Fix a change accidentally included in the last commit.
........
  r53318 | danieljames | 2009-05-27 19:32:38 +0100 (Wed, 27 May 2009) | 1 line
  
  Remove an unused function.
........


[SVN r53465]
2009-05-30 17:34:12 +00:00
b018f8b173 Second try at merging emplace support.
Note that the previously rolled back commit was [53257], not [52357].

Merged revisions 52393-52394,52397,52884-52885,53255 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r52393 | danieljames | 2009-04-14 18:23:37 +0100 (Tue, 14 Apr 2009) | 2 lines
  
  Implement full extract_key for compilers without SFINAE and variadic
  templates.
........
  r52394 | danieljames | 2009-04-14 18:23:51 +0100 (Tue, 14 Apr 2009) | 1 line
  
  Use emplace instead of insert in the backend as it's more appropriate.
........
  r52397 | danieljames | 2009-04-14 18:51:34 +0100 (Tue, 14 Apr 2009) | 1 line
  
  Add stream output to the count test helper for unordered.
........
  r52884 | danieljames | 2009-05-10 22:24:41 +0100 (Sun, 10 May 2009) | 19 lines
  
  Cherrypick some unordered container changes from sandbox. Not including
  anything which depends on the new move library.
  
  ------------------------------------------------------------------------
  r52746 | danieljames | 2009-05-03 11:12:30 +0100 (Sun, 03 May 2009) | 1 line
  
  Merge latest unordered container changes.
  ------------------------------------------------------------------------
  r52747 | danieljames | 2009-05-03 11:15:35 +0100 (Sun, 03 May 2009) | 4 lines
  
  Put the C++0x emplace implementations before the non-C++0x versions.
  
  I'm going to change the non-C++0x to be macro heavy emulations of the
  C++0x versions, so this will put the readable version first.
  ------------------------------------------------------------------------
  r52748 | danieljames | 2009-05-03 11:15:44 +0100 (Sun, 03 May 2009) | 1 line
  
  Refactor the unordered implementation a tad, to make implementing emplace less painful.
  ------------------------------------------------------------------------
........
  r52885 | danieljames | 2009-05-10 22:25:09 +0100 (Sun, 10 May 2009) | 1 line
  
  Merge emplace support for sandbox - but without move support.
........
  r53255 | danieljames | 2009-05-25 20:45:06 +0100 (Mon, 25 May 2009) | 1 line
  
  Unordered change log.
........


[SVN r53328]
2009-05-27 21:31:08 +00:00
0b4241833d Rollback [52357] as it depends on macros that aren't in release.
Rolled back revisions 52393-52394,52397,52884-52885,53127,53255 via svnmerge from 
https://svn.boost.org/svn/boost/trunk


[SVN r53277]
2009-05-26 09:56:59 +00:00
e911a8011b Merge unordered changes:
* Support emplace for all compilers.
 * Better configuration of C++0x features for when the appropriate headers
   aren't available.

Merged revisions 52393-52394,52397,52884-52885,53127,53255 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r52393 | danieljames | 2009-04-14 18:23:37 +0100 (Tue, 14 Apr 2009) | 2 lines
  
  Implement full extract_key for compilers without SFINAE and variadic
  templates.
........
  r52394 | danieljames | 2009-04-14 18:23:51 +0100 (Tue, 14 Apr 2009) | 1 line
  
  Use emplace instead of insert in the backend as it's more appropriate.
........
  r52397 | danieljames | 2009-04-14 18:51:34 +0100 (Tue, 14 Apr 2009) | 1 line
  
  Add stream output to the count test helper for unordered.
........
  r52884 | danieljames | 2009-05-10 22:24:41 +0100 (Sun, 10 May 2009) | 19 lines
  
  Cherrypick some unordered container changes from sandbox. Not including
  anything which depends on the new move library.
  
  ------------------------------------------------------------------------
  r52746 | danieljames | 2009-05-03 11:12:30 +0100 (Sun, 03 May 2009) | 1 line
  
  Merge latest unordered container changes.
  ------------------------------------------------------------------------
  r52747 | danieljames | 2009-05-03 11:15:35 +0100 (Sun, 03 May 2009) | 4 lines
  
  Put the C++0x emplace implementations before the non-C++0x versions.
  
  I'm going to change the non-C++0x to be macro heavy emulations of the
  C++0x versions, so this will put the readable version first.
  ------------------------------------------------------------------------
  r52748 | danieljames | 2009-05-03 11:15:44 +0100 (Sun, 03 May 2009) | 1 line
  
  Refactor the unordered implementation a tad, to make implementing emplace less painful.
  ------------------------------------------------------------------------
........
  r52885 | danieljames | 2009-05-10 22:25:09 +0100 (Sun, 10 May 2009) | 1 line
  
  Merge emplace support for sandbox - but without move support.
........
  r53127 | danieljames | 2009-05-20 07:43:38 +0100 (Wed, 20 May 2009) | 1 line
  
  Better configuration for boost.unordered.
........
  r53255 | danieljames | 2009-05-25 20:45:06 +0100 (Mon, 25 May 2009) | 1 line
  
  Unordered change log.
........


[SVN r53257]
2009-05-25 19:57:04 +00:00
f02cc7775d Long term fix for the incorrect length of prime list.
Merged revisions 52658,52669,52673,52711 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r52658 | danieljames | 2009-04-29 11:05:17 +0100 (Wed, 29 Apr 2009) | 1 line
  
  Fix the length of the prime number list.
........
  r52669 | danieljames | 2009-04-29 22:43:41 +0100 (Wed, 29 Apr 2009) | 3 lines
  
  Don't test prime_list::length on Visual C++.
  
  Checking the array size doesn't seem to work on it.
........
  r52673 | danieljames | 2009-04-30 06:08:40 +0100 (Thu, 30 Apr 2009) | 1 line
  
  Revert changes to unordered, as the test fails on most compilers.
........
  r52711 | danieljames | 2009-05-01 21:50:32 +0100 (Fri, 01 May 2009) | 5 lines
  
  Use a preprocessor sequence for the primes.
  
  This feels like overkill but it seems to be the most reliable way to ensure
  that the length is correct. I obviously can't be trusted to get it right, and
  the template hack seems to prevent Boost.Range from working.
........


[SVN r53043]
2009-05-16 13:38:37 +00:00
4e6b5de196 tuning up cmakefiles for unordered, utility
[SVN r53008]
2009-05-15 00:21:14 +00:00
fb71e0618d Last minute merge, remove google analytics script tags and fixes #2975.
Merged revisions 52665,52674 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r52665 | danieljames | 2009-04-29 22:16:10 +0100 (Wed, 29 Apr 2009) | 1 line
  
  Remove google analytics script tags.
........
  r52674 | danieljames | 2009-04-30 06:10:57 +0100 (Thu, 30 Apr 2009) | 1 line
  
  Fix the prime number list length in unordered.
........


[SVN r52707]
2009-05-01 19:00:57 +00:00
694398f0e1 Some small documentation fixes for the release.
Merged revisions 52348-52350 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r52348 | danieljames | 2009-04-12 11:50:31 +0100 (Sun, 12 Apr 2009) | 1 line
  
  Use a test file that's actually valid C++.
........
  r52349 | danieljames | 2009-04-12 11:50:43 +0100 (Sun, 12 Apr 2009) | 3 lines
  
  Revert support for static mutable variables.
  
  Of course there's no such thing.
........
  r52350 | danieljames | 2009-04-12 11:50:57 +0100 (Sun, 12 Apr 2009) | 1 line
  
  Note change to operator[] in the unordered release notes.
........


[SVN r52351]
2009-04-12 10:54:44 +00:00
ab62d33495 Merged revisions 52224 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r52224 | danieljames | 2009-04-06 23:51:36 +0100 (Mon, 06 Apr 2009) | 1 line
  
  Avoid an unnecessary copy in 'operator[]'
........


[SVN r52346]
2009-04-12 10:25:38 +00:00
b475ba05c0 Merge quickbook and hash changelogs. Tweak gcc detection in container_fwd.hpp
Merged revisions 52084,52245-52246,52304,52320,52323 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r52084 | danieljames | 2009-03-31 20:43:58 +0100 (Tue, 31 Mar 2009) | 1 line
  
  Changelog for unordered and hash.
........
  r52245 | danieljames | 2009-04-08 06:51:31 +0100 (Wed, 08 Apr 2009) | 5 lines
  
  Detect gcc stdlib for gcc 4.0.1.
  
  For some reason the normal macros aren't defined for the standard
  library that comes with gcc 4.0.1 (although maybe just on BSDs?). So try
  to detect the library for that compiler.
........
  r52246 | danieljames | 2009-04-08 11:56:22 +0100 (Wed, 08 Apr 2009) | 7 lines
  
  Include <utility> for some versions of gcc's library.
  
  Sometimes gcc's <cstddef> doesn't define the C++ macros, so check for it
  and include <utility> in that case. Also remove a workaround from
  container_fwd.hpp
  
  Fixes #2924.
........
  r52304 | danieljames | 2009-04-10 20:25:32 +0100 (Fri, 10 Apr 2009) | 4 lines
  
  Don't use debug containers on darwin.
  
  I'm getting errors from the darwin 4.2 debug containers which appear to
  a problem with its implementation.
........
  r52320 | danieljames | 2009-04-11 08:53:59 +0100 (Sat, 11 Apr 2009) | 1 line
  
  Don't need to include utility now that select_stdlib has been fixed.
........
  r52323 | danieljames | 2009-04-11 09:26:20 +0100 (Sat, 11 Apr 2009) | 1 line
  
  Also don't need to check for _GLIBCXX_CSTDDEF.
........


[SVN r52324]
2009-04-11 08:49:33 +00:00
60e3e96b48 Tweak unordered for some compilers.
Fixes #2756.

Merged revisions 51982-51983,51995 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r51982 | danieljames | 2009-03-26 07:00:21 +0000 (Thu, 26 Mar 2009) | 3 lines
  
  Revert [51409]
  
  It isn't working on Borland.
........
  r51983 | danieljames | 2009-03-26 07:00:46 +0000 (Thu, 26 Mar 2009) | 1 line
  
  Try to destruct values in a way that all compilers might like.
........
  r51995 | danieljames | 2009-03-26 21:09:51 +0000 (Thu, 26 Mar 2009) | 1 line
  
  Give up and use another macro to destruct values.
........


[SVN r52065]
2009-03-30 17:54:49 +00:00
c0e472755e Merge misc. changes from trunk, mostly minor documentation fixes.
Merged revisions 48412,50921,51042,51369,51386-51387,51506-51507,51668,51802,51804,51881 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r48412 | danieljames | 2008-08-28 11:23:33 +0100 (Thu, 28 Aug 2008) | 1 line
  
  Fix a typo. Thanks to Jon Biggar.
........
  r50921 | danieljames | 2009-01-31 09:36:38 +0000 (Sat, 31 Jan 2009) | 1 line
  
  Remove executable flag from preprocess.cmd. It was a mistake to add it.
........
  r51042 | danieljames | 2009-02-06 00:04:44 +0000 (Fri, 06 Feb 2009) | 1 line
  
  Ignore some version control files in inspect.
........
  r51369 | danieljames | 2009-02-21 18:49:48 +0000 (Sat, 21 Feb 2009) | 1 line
  
  Minor markup fix in concept check documentation.
........
  r51386 | danieljames | 2009-02-22 11:53:28 +0000 (Sun, 22 Feb 2009) | 1 line
  
  Add index.html file for compose, as our server setup doesn't support index.htm files.
........
  r51387 | danieljames | 2009-02-22 11:53:48 +0000 (Sun, 22 Feb 2009) | 5 lines
  
  Add missing index.html file for MPI and GIL.
  
  All the top level libraries now have index.html files but
  several sub-libraries don't. I'm not sure it's worth adding them as many
  of them don't have appropriate subdirectories anyway.
........
  r51506 | danieljames | 2009-03-01 14:16:00 +0000 (Sun, 01 Mar 2009) | 1 line
  
  Update links to command line invocation.
........
  r51507 | danieljames | 2009-03-01 14:16:24 +0000 (Sun, 01 Mar 2009) | 1 line
  
  Use xpointer attributes in the boost build documentation.
........
  r51668 | danieljames | 2009-03-09 20:56:51 +0000 (Mon, 09 Mar 2009) | 1 line
  
  Redirect to the Trac wiki instead of the old one.
........
  r51802 | danieljames | 2009-03-16 20:21:05 +0000 (Mon, 16 Mar 2009) | 1 line
  
  Use paragraphs inside purpose tags.
........
  r51804 | danieljames | 2009-03-16 20:21:46 +0000 (Mon, 16 Mar 2009) | 1 line
  
  Give the variablelist a margin.
........
  r51881 | danieljames | 2009-03-21 15:35:35 +0000 (Sat, 21 Mar 2009) | 1 line
  
  Fix html.
........


[SVN r51897]
2009-03-22 10:42:48 +00:00
6f45d36d97 Merge hash and unordered changes.
Remove deprecated headers, move hash_fwd.hpp into hash subdirectory. And
several minor internal changes.
Mostly minor internal details.

Merged revisions 51262-51263,51407-51409,51504-51505,51644-51646,51667 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r51262 | danieljames | 2009-02-15 19:32:04 +0000 (Sun, 15 Feb 2009) | 1 line
  
  Use the new 'boost:' links for the hash, unordered and quickbook documentation.
........
  r51263 | danieljames | 2009-02-15 19:32:19 +0000 (Sun, 15 Feb 2009) | 2 lines
  
  Don't copy images for the standalone hash and unordered documentation, was only
  really required before the libraries were integrated into boost.
........
  r51407 | danieljames | 2009-02-22 23:49:51 +0000 (Sun, 22 Feb 2009) | 1 line
  
  Fix the hash dirname.
........
  r51408 | danieljames | 2009-02-22 23:50:04 +0000 (Sun, 22 Feb 2009) | 1 line
  
  Make copy_buckets and move_buckets member functions - so that calling them is a bit simpler.
........
  r51409 | danieljames | 2009-02-22 23:50:20 +0000 (Sun, 22 Feb 2009) | 1 line
  
  Move some of the data structure classes out of hash table data.
........
  r51504 | danieljames | 2009-03-01 14:15:09 +0000 (Sun, 01 Mar 2009) | 1 line
  
  Add missing return for operator=.
........
  r51505 | danieljames | 2009-03-01 14:15:39 +0000 (Sun, 01 Mar 2009) | 3 lines
  
  Make the sort stable.
  
  Doesn't really matter, but it might as well be.
........
  r51644 | danieljames | 2009-03-08 09:44:51 +0000 (Sun, 08 Mar 2009) | 1 line
  
  Detab.
........
  r51645 | danieljames | 2009-03-08 09:45:11 +0000 (Sun, 08 Mar 2009) | 4 lines
  
  Move hash_fwd into the hash subdirectory.
  
  I should have done this in the last release. But now all of the hash
  implementation is in the hash subdirectory.
........
  r51646 | danieljames | 2009-03-08 09:45:30 +0000 (Sun, 08 Mar 2009) | 3 lines
  
  Remove deprecated headers.
  
  Fixes #2412.
........
  r51667 | danieljames | 2009-03-09 20:56:23 +0000 (Mon, 09 Mar 2009) | 1 line
  
  Update copyright dates in hash and unordered.
........


[SVN r51729]
2009-03-11 22:51:09 +00:00
2e9cf20cd0 Merge PDF build changes from Trunk.
[SVN r51417]
2009-02-23 18:39:32 +00:00
f7c664a359 merge of cmake build files from trunk per beman
[SVN r50756]
2009-01-24 18:57:20 +00:00
0921f8076d Remove a tab.
Merged revisions 50452 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r50452 | danieljames | 2009-01-03 23:26:00 +0000 (Sat, 03 Jan 2009) | 1 line
  
  Remove a tab.
........


[SVN r50506]
2009-01-07 21:50:23 +00:00
b8e8ffa242 Merge latest hash and unordered developments, and add support for initialiser
lists to config.

Merged revisions 49338,49924-49927,49955,50029,50118 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r49338 | danieljames | 2008-10-15 10:44:41 +0100 (Wed, 15 Oct 2008) | 2 lines
  
  Revert [49229], it fixes the same problem as [48674].
........
  r49924 | danieljames | 2008-11-24 22:55:14 +0000 (Mon, 24 Nov 2008) | 1 line
  
  Extra tests for equality with different hash functions.
........
  r49925 | danieljames | 2008-11-24 22:55:47 +0000 (Mon, 24 Nov 2008) | 1 line
  
  Document operator==/operator!= as undefined if the equality predicates aren't equivalent.
........
  r49926 | danieljames | 2008-11-24 22:56:04 +0000 (Mon, 24 Nov 2008) | 1 line
  
  Use a larger prime number list.
........
  r49927 | danieljames | 2008-11-24 23:15:55 +0000 (Mon, 24 Nov 2008) | 1 line
  
  Use aligned storage for the value.
........
  r49955 | danieljames | 2008-11-27 11:42:13 +0000 (Thu, 27 Nov 2008) | 1 line
  
  Wild stab at getting destruction working on more compilers.
........
  r50029 | danieljames | 2008-11-29 21:47:55 +0000 (Sat, 29 Nov 2008) | 1 line
  
  Workaround another in-place destruction.
........
  r50118 | danieljames | 2008-12-04 21:30:19 +0000 (Thu, 04 Dec 2008) | 1 line
  
  Add support for initializer lists to config and the unordered containers.
........


[SVN r50451]
2009-01-03 23:18:33 +00:00
07e715fceb Merged revisions 49661-49662,49666,49669,49735,49756,49770,49811 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r49661 | danieljames | 2008-11-09 12:03:45 +0000 (Sun, 09 Nov 2008) | 1 line
  
  Move hash detail headers out of boost/functional/detail.
........
  r49662 | danieljames | 2008-11-09 12:11:50 +0000 (Sun, 09 Nov 2008) | 1 line
  
  Add a forwarding header for container_fwd.hpp
........
  r49666 | danieljames | 2008-11-09 19:12:05 +0000 (Sun, 09 Nov 2008) | 1 line
  
  Avoid comparing default initialised iterators in position_iterator.
........
  r49669 | danieljames | 2008-11-09 21:57:38 +0000 (Sun, 09 Nov 2008) | 2 lines
  
  Add link to the header to the synopsis in reference documentation.
  Refs #2214
........
  r49735 | danieljames | 2008-11-14 12:51:00 +0000 (Fri, 14 Nov 2008) | 1 line
  
  Explicitly specify the template parameters in the unordered container friend, in order to avoid some warnings.
........
  r49756 | danieljames | 2008-11-14 16:11:16 +0000 (Fri, 14 Nov 2008) | 1 line
  
  Use pragmas to suppress a Visual C++ warning.
........
  r49770 | danieljames | 2008-11-15 13:07:29 +0000 (Sat, 15 Nov 2008) | 1 line
  
  Use the new swap library.
........
  r49811 | danieljames | 2008-11-16 23:10:00 +0000 (Sun, 16 Nov 2008) | 1 line
  
  Fix a typo.
........


[SVN r49855]
2008-11-20 22:53:20 +00:00
89ab17cce5 Merge fixes from Trunk.
Fixes #2392.

Change includes of <cmath> to <boost/config/no_tr1/config.hpp>.

Previously if Boost.TR1 was in the include path then including <cmath> pulls in all the new TR1 math functions, which in turn also requires linking to an external library. With auto-linking support this requires that library to have been built and be present in the library search path, even if the actual library under use is header only. 

[SVN r49314]
2008-10-13 09:00:03 +00:00
517e39fc23 Merged revisions 48081-48082,48791,48802-48803,48853 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r48081 | danieljames | 2008-08-11 08:52:37 +0100 (Mon, 11 Aug 2008) | 2 lines
  
  Rename 'emplace' with hint to 'emplace_hint'.
........
  r48082 | danieljames | 2008-08-11 08:53:05 +0100 (Mon, 11 Aug 2008) | 2 lines
  
  More recent version of the working draft.
........
  r48791 | danieljames | 2008-09-15 22:48:46 +0100 (Mon, 15 Sep 2008) | 1 line
  
  Fix a workaround macro.
........
  r48802 | danieljames | 2008-09-16 22:45:53 +0100 (Tue, 16 Sep 2008) | 1 line
  
  Forward headers for the unordered containers.
........
  r48803 | danieljames | 2008-09-16 22:49:41 +0100 (Tue, 16 Sep 2008) | 1 line
  
  Move the unordered headers into the unordered directory.
........
  r48853 | danieljames | 2008-09-18 12:23:12 +0100 (Thu, 18 Sep 2008) | 1 line
  
  Update unordered changelog.
........


[SVN r48854]
2008-09-18 11:30:59 +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
87 changed files with 3722 additions and 2680 deletions

29
CMakeLists.txt Normal file
View File

@ -0,0 +1,29 @@
#
# Copyright Troy D. Straszheim
#
# Distributed under the Boost Software License, Version 1.0.
# See http://www.boost.org/LICENSE_1_0.txt
#
#----------------------------------------------------------------------------
# This file was automatically generated from the original CMakeLists.txt file
# Add a variable to hold the headers for the library
set (lib_headers
unordered_map.hpp
unordered_set.hpp
unordered
)
# Add a library target to the build system
boost_library_project(
unordered
# SRCDIRS
TESTDIRS test
HEADERS ${lib_headers}
# DOCDIRS
# DESCRIPTION
MODULARIZED
# AUTHORS
# MAINTAINERS
)

View File

@ -8,11 +8,11 @@ path-constant admonishment_location : ../../../../doc/src/images ;
xml unordered : unordered.qbk ;
boostbook standalone : unordered :
<xsl:param>admon.graphics.path=images/
<xsl:param>navig.graphics.path=images/
<xsl:param>html.stylesheet=boostbook.css
<xsl:param>html.stylesheet=../../../../doc/html/boostbook.css
<xsl:param>boost.root=../../../..
<xsl:param>boost.libraries=../../../libraries.htm
<xsl:param>navig.graphics=1
<xsl:param>chunk.first.sections=1
<xsl:param>chunk.section.depth=2
<xsl:param>generate.section.toc.level=2
@ -23,9 +23,6 @@ boostbook standalone : unordered :
<xsl:param>boost.compact.function=0
<xsl:param>boost.compact.enum=0
<dependency>css
<dependency>images
# PDF Options:
# TOC Generation: this is needed for FOP-0.9 and later:
<xsl:param>fop1.extensions=0
@ -51,11 +48,6 @@ boostbook standalone : unordered :
<format>pdf:<xsl:param>img.src.path=$(images_location)/
#<format>pdf:<xsl:param>admon.graphics.path=$(admonishment_location)
<format>pdf:<xsl:param>draft.mode="no"
<format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/libs/unordered/doc/html
;
install css : [ glob $(BOOST_ROOT)/doc/src/*.css ]
: <location>html ;
install images : [ glob $(BOOST_ROOT)/doc/src/images/*.png ]
: <location>html/images ;
explicit css ;
explicit images ;

View File

@ -1,3 +1,8 @@
<!--
Copyright Daniel James 2008-2009
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

@ -115,6 +115,15 @@ or close to the hint - unless your hint is unreasonably small or large.
[table Methods for Controlling Bucket Size
[[Method] [Description]]
[
[`X(size_type n)`]
[Construct an empty container with at least `n` buckets (`X` is the container type).]
]
[
[`X(InputIterator i, InputIterator j, size_type n)`]
[Construct an empty container with at least `n` buckets and insert elements
from the range \[`i`, `j`) (`X` is the container type).]
]
[
[`float load_factor() const`]
[The average number of elements per bucket.]

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,61 @@ 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.
[h2 Boost 1.38.0]
* Use [@boost:/libs/utility/swap.html `boost::swap`].
* [@https://svn.boost.org/trac/boost/ticket/2237 Ticket 2237]:
Document that the equality and inequality operators are undefined for two
objects if their equality predicates aren't equivalent. Thanks to Daniel
Krügler.
* [@https://svn.boost.org/trac/boost/ticket/1710 Ticket 1710]:
Use a larger prime number list. Thanks to Thorsten Ottosen and Hervé
Brönnimann.
* Use
[@boost:/libs/type_traits/doc/html/boost_typetraits/category/alignment.html
aligned storage] to store the types. This changes the way the allocator is
used to construct nodes. It used to construct the node with two calls to
the allocator's `construct` method - once for the pointers and once for the
value. It now constructs the node with a single call to construct and
then constructs the value using in place construction.
* Add support for C++0x initializer lists where they're available (currently
only g++ 4.4 in C++0x mode).
[h2 Boost 1.39.0]
* [@https://svn.boost.org/trac/boost/ticket/2756 Ticket 2756]: Avoid a warning
on Visual C++ 2009.
* Some other minor internal changes to the implementation, tests and
documentation.
* Avoid an unnecessary copy in `operator[]`.
* [@https://svn.boost.org/trac/boost/ticket/2975 Ticket 2975]: Fix length of
prime number list.
[h2 Boost 1.40.0]
* [@https://svn.boost.org/trac/boost/ticket/2975 Ticket 2975]:
Store the prime list as a preprocessor sequence - so that it will always get
the length right if it changes again in the future.
* [@https://svn.boost.org/trac/boost/ticket/1978 Ticket 1978]:
Implement `emplace` for all compilers.
* [@https://svn.boost.org/trac/boost/ticket/2908 Ticket 2908],
[@https://svn.boost.org/trac/boost/ticket/3096 Ticket 3096]:
Some workarounds for old versions of borland, including adding explicit
destructors to all containers.
* [@https://svn.boost.org/trac/boost/ticket/3082 Ticket 3082]:
Disable incorrect Visual C++ warnings.
* Better configuration for C++0x features when the headers aren't available.
* Create less buckets by default.
[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

@ -13,7 +13,7 @@ is declared as:
class Key, class Mapped,
class Hash = ``[classref boost::hash]``<Key>,
class Pred = std::equal_to<Key>,
class Alloc = std::allocator<Key> >
class Alloc = std::allocator<std::pair<Key const, Mapped> > >
class ``[classref boost::unordered_map unordered_map]``;
The hash function comes first as you might want to change the hash function
@ -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 [@boost:/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
@ -38,9 +38,19 @@ Which you can then use in a case insensitive dictionary:
[case_insensitive_dictionary]
This is a simplified version of the example at
[@../../libs/unordered/examples/case_insensitive.hpp /libs/unordered/examples/case_insensitive.hpp]
[@boost:/libs/unordered/examples/case_insensitive.hpp /libs/unordered/examples/case_insensitive.hpp]
which supports other locales and string types.
[caution
Be careful when using the equality (`==`) operator with custom equality
predicates, especially if you're using a function pointer. If you compare two
containers with different equality predicates then the result is undefined.
For most stateless function objects this is impossible - since you can only
compare objects with the same equality predicate you know the equality
predicates must be equal. But if you're using function pointers or a stateful
equality predicate (e.g. boost::function) then you can get into trouble.
]
[h2 Custom Types]
Similarly, a custom hash function can be used for custom types:

View File

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

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

@ -1,5 +1,5 @@
<!--
Copyright Daniel James 2006-2008
Copyright Daniel James 2006-2009
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)
--><library-reference>
@ -19,12 +19,12 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<default><type>std::allocator&lt;Value&gt;</type></default>
</template-type-parameter>
</template>
<purpose>
<purpose><simpara>
An unordered associative container that stores unique values.
</purpose>
</simpara></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-2009/n2691.pdf">the working draft of the C++ standard [n2691].</ulink></para>
<para><emphasis role="bold">Template Parameters</emphasis>
<informaltable>
<tgroup cols="2">
@ -69,11 +69,11 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</typedef>
<typedef name="reference">
<type>typename allocator_type::reference</type>
<purpose>lvalue of <type>value_type</type>.</purpose>
<purpose><simpara>lvalue of <type>value_type</type>.</simpara></purpose>
</typedef>
<typedef name="const_reference">
<type>typename allocator_type::const_reference</type>
<purpose>const lvalue of <type>value_type</type>.</purpose>
<purpose><simpara>const lvalue of <type>value_type</type>.</simpara></purpose>
</typedef>
<typedef name="size_type">
<type><emphasis>implementation-defined</emphasis></type>
@ -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,9 +284,12 @@ 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>If the compiler doesn't support variadic template arguments or rvalue
references, this is emulated for up to 10 arguments, with no support
for rvalue references or move semantics.</para>
</notes>
</method>
<method name="emplace">
<method name="emplace_hint">
<template>
<template-type-parameter name="Args" pack="1">
</template-type-parameter>
@ -312,6 +315,9 @@ 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>If the compiler doesn't support variadic template arguments or rvalue
references, this is emulated for up to 10 arguments, with no support
for rvalue references or move semantics.</para>
</notes>
</method>
<method name="insert">
@ -636,10 +642,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">
@ -676,6 +682,8 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<type>bool</type>
<notes>
<para>This is a boost extension.</para>
<para>Behavior is undefined if the two containers don't have
equivalent equality predicates.</para>
</notes>
</function>
<function name="operator!=">
@ -698,25 +706,8 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<type>bool</type>
<notes>
<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>
<para>Behavior is undefined if the two containers don't have
equivalent equality predicates.</para>
</notes>
</function>
</free-function-group>
@ -766,12 +757,12 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<default><type>std::allocator&lt;Value&gt;</type></default>
</template-type-parameter>
</template>
<purpose>
<purpose><simpara>
An unordered associative container that stores values. The same key can be stored multiple times.
</purpose>
</simpara></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-2009/n2691.pdf">the working draft of the C++ standard [n2691].</ulink></para>
<para><emphasis role="bold">Template Parameters</emphasis>
<informaltable>
<tgroup cols="2">
@ -816,11 +807,11 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</typedef>
<typedef name="reference">
<type>typename allocator_type::reference</type>
<purpose>lvalue of <type>value_type</type>.</purpose>
<purpose><simpara>lvalue of <type>value_type</type>.</simpara></purpose>
</typedef>
<typedef name="const_reference">
<type>typename allocator_type::const_reference</type>
<purpose>const lvalue of <type>value_type</type>.</purpose>
<purpose><simpara>const lvalue of <type>value_type</type>.</simpara></purpose>
</typedef>
<typedef name="size_type">
<type><emphasis>implementation-defined</emphasis></type>
@ -928,7 +919,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,9 +1021,12 @@ 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>If the compiler doesn't support variadic template arguments or rvalue
references, this is emulated for up to 10 arguments, with no support
for rvalue references or move semantics.</para>
</notes>
</method>
<method name="emplace">
<method name="emplace_hint">
<template>
<template-type-parameter name="Args" pack="1">
</template-type-parameter>
@ -1058,6 +1052,9 @@ 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>If the compiler doesn't support variadic template arguments or rvalue
references, this is emulated for up to 10 arguments, with no support
for rvalue references or move semantics.</para>
</notes>
</method>
<method name="insert">
@ -1381,10 +1378,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">
@ -1421,6 +1418,8 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<type>bool</type>
<notes>
<para>This is a boost extension.</para>
<para>Behavior is undefined if the two containers don't have
equivalent equality predicates.</para>
</notes>
</function>
<function name="operator!=">
@ -1443,25 +1442,8 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<type>bool</type>
<notes>
<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>
<para>Behavior is undefined if the two containers don't have
equivalent equality predicates.</para>
</notes>
</function>
</free-function-group>
@ -1517,12 +1499,12 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<default><type>std::allocator&lt;std::pair&lt;Key const, Mapped&gt; &gt;</type></default>
</template-type-parameter>
</template>
<purpose>
<purpose><simpara>
An unordered associative container that associates unique keys with another value.
</purpose>
</simpara></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-2009/n2691.pdf">the working draft of the C++ standard [n2691].</ulink></para>
<para><emphasis role="bold">Template Parameters</emphasis>
<informaltable>
<tgroup cols="2">
@ -1573,11 +1555,11 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</typedef>
<typedef name="reference">
<type>typename allocator_type::reference</type>
<purpose>lvalue of <type>value_type</type>.</purpose>
<purpose><simpara>lvalue of <type>value_type</type>.</simpara></purpose>
</typedef>
<typedef name="const_reference">
<type>typename allocator_type::const_reference</type>
<purpose>const lvalue of <type>value_type</type>.</purpose>
<purpose><simpara>const lvalue of <type>value_type</type>.</simpara></purpose>
</typedef>
<typedef name="size_type">
<type><emphasis>implementation-defined</emphasis></type>
@ -1685,7 +1667,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,9 +1770,12 @@ 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>If the compiler doesn't support variadic template arguments or rvalue
references, this is emulated for up to 10 arguments, with no support
for rvalue references or move semantics.</para>
</notes>
</method>
<method name="emplace">
<method name="emplace_hint">
<template>
<template-type-parameter name="Args" pack="1">
</template-type-parameter>
@ -1816,6 +1801,9 @@ 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>If the compiler doesn't support variadic template arguments or rvalue
references, this is emulated for up to 10 arguments, with no support
for rvalue references or move semantics.</para>
</notes>
</method>
<method name="insert">
@ -2175,10 +2163,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">
@ -2217,6 +2205,8 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<type>bool</type>
<notes>
<para>This is a boost extension.</para>
<para>Behavior is undefined if the two containers don't have
equivalent equality predicates.</para>
</notes>
</function>
<function name="operator!=">
@ -2241,27 +2231,8 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<type>bool</type>
<notes>
<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>
<para>Behavior is undefined if the two containers don't have
equivalent equality predicates.</para>
</notes>
</function>
</free-function-group>
@ -2315,12 +2286,12 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<default><type>std::allocator&lt;std::pair&lt;Key const, Mapped&gt; &gt;</type></default>
</template-type-parameter>
</template>
<purpose>
<purpose><simpara>
An unordered associative container that associates keys with another value. The same key can be stored multiple times.
</purpose>
</simpara></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-2009/n2691.pdf">the working draft of the C++ standard [n2691].</ulink></para>
<para><emphasis role="bold">Template Parameters</emphasis>
<informaltable>
<tgroup cols="2">
@ -2371,11 +2342,11 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</typedef>
<typedef name="reference">
<type>typename allocator_type::reference</type>
<purpose>lvalue of <type>value_type</type>.</purpose>
<purpose><simpara>lvalue of <type>value_type</type>.</simpara></purpose>
</typedef>
<typedef name="const_reference">
<type>typename allocator_type::const_reference</type>
<purpose>const lvalue of <type>value_type</type>.</purpose>
<purpose><simpara>const lvalue of <type>value_type</type>.</simpara></purpose>
</typedef>
<typedef name="size_type">
<type><emphasis>implementation-defined</emphasis></type>
@ -2483,7 +2454,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,9 +2556,12 @@ 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>If the compiler doesn't support variadic template arguments or rvalue
references, this is emulated for up to 10 arguments, with no support
for rvalue references or move semantics.</para>
</notes>
</method>
<method name="emplace">
<method name="emplace_hint">
<template>
<template-type-parameter name="Args" pack="1">
</template-type-parameter>
@ -2613,6 +2587,9 @@ 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>If the compiler doesn't support variadic template arguments or rvalue
references, this is emulated for up to 10 arguments, with no support
for rvalue references or move semantics.</para>
</notes>
</method>
<method name="insert">
@ -2936,10 +2913,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">
@ -2978,6 +2955,8 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<type>bool</type>
<notes>
<para>This is a boost extension.</para>
<para>Behavior is undefined if the two containers don't have
equivalent equality predicates.</para>
</notes>
</function>
<function name="operator!=">
@ -3002,27 +2981,8 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<type>bool</type>
<notes>
<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>
<para>Behavior is undefined if the two containers don't have
equivalent equality predicates.</para>
</notes>
</function>
</free-function-group>
@ -3062,4 +3022,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

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

66
examples/fnv1.hpp Normal file
View File

@ -0,0 +1,66 @@
// Copyright 2008-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// 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

@ -1,5 +1,5 @@
// Copyright 2005-2008 Daniel James.
// Copyright 2005-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -1,5 +1,5 @@
// Copyright 2008 Daniel James.
// Copyright 2008-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -19,4 +19,12 @@
# define BOOST_UNORDERED_NO_HAS_MOVE_ASSIGN
#endif
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
# if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
// STLport doesn't have std::forward.
# else
# define BOOST_UNORDERED_STD_FORWARD
# endif
#endif
#endif

View File

@ -1,6 +1,6 @@
// Copyright (C) 2003-2004 Jeremy B. Maitin-Shepard.
// Copyright (C) 2005-2008 Daniel James
// Copyright (C) 2005-2009 Daniel James
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -12,9 +12,14 @@
#endif
#include <boost/config.hpp>
#include <boost/unordered/detail/config.hpp>
#if !defined(BOOST_UNORDERED_EMPLACE_LIMIT)
#define BOOST_UNORDERED_EMPLACE_LIMIT 10
#endif
#include <cstddef>
#include <cmath>
#include <boost/config/no_tr1/cmath.hpp>
#include <algorithm>
#include <utility>
#include <stdexcept>
@ -26,17 +31,42 @@
#include <boost/static_assert.hpp>
#include <boost/unordered/detail/allocator_helpers.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/aligned_storage.hpp>
#include <boost/type_traits/alignment_of.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/not.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/utility/swap.hpp>
#include <boost/preprocessor/seq/size.hpp>
#include <boost/preprocessor/seq/enum.hpp>
#include <boost/mpl/aux_/config/eti.hpp>
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/mpl/not.hpp>
#if !(defined(BOOST_UNORDERED_STD_FORWARD))
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#define BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
BOOST_PP_ENUM_PARAMS_Z(z, n, typename Arg)
#define BOOST_UNORDERED_FUNCTION_PARAMS(z, n) \
BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, Arg, const& arg)
#define BOOST_UNORDERED_CALL_PARAMS(z, n) \
BOOST_PP_ENUM_PARAMS_Z(z, n, arg)
#endif
#if defined(BOOST_MSVC)
#pragma warning(push)
#if BOOST_MSVC >= 1400
#pragma warning(disable:4267) // conversion from 'size_t' to 'unsigned int',
// possible loss of data.
#endif
#endif
#if BOOST_WORKAROUND(__BORLANDC__, <= 0x0582)
@ -55,20 +85,9 @@ namespace boost {
namespace unordered_detail {
template <class T> struct type_wrapper {};
static const std::size_t default_initial_bucket_count = 50;
static const std::size_t default_initial_bucket_count = 11;
static const float minimum_max_load_factor = 1e-3f;
template <class T>
inline void hash_swap(T& x, T& y)
{
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
std::swap(x,y);
#else
using std::swap;
swap(x, y);
#endif
}
inline std::size_t double_to_size_t(double f)
{
return f >= static_cast<double>((std::numeric_limits<std::size_t>::max)()) ?
@ -84,17 +103,25 @@ namespace boost {
static std::ptrdiff_t const length;
};
template<typename T>
std::size_t const prime_list_template<T>::value[] = {
53ul, 97ul, 193ul, 389ul, 769ul,
1543ul, 3079ul, 6151ul, 12289ul, 24593ul,
49157ul, 98317ul, 196613ul, 393241ul, 786433ul,
1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul,
50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,
1610612741ul, 3221225473ul, 4294967291ul };
#define BOOST_UNORDERED_PRIMES \
(5ul)(11ul)(17ul)(29ul)(37ul)(53ul)(67ul)(79ul) \
(97ul)(131ul)(193ul)(257ul)(389ul)(521ul)(769ul) \
(1031ul)(1543ul)(2053ul)(3079ul)(6151ul)(12289ul)(24593ul) \
(49157ul)(98317ul)(196613ul)(393241ul)(786433ul) \
(1572869ul)(3145739ul)(6291469ul)(12582917ul)(25165843ul) \
(50331653ul)(100663319ul)(201326611ul)(402653189ul)(805306457ul) \
(1610612741ul)(3221225473ul)(4294967291ul)
template<typename T>
std::ptrdiff_t const prime_list_template<T>::length = 28;
std::size_t const prime_list_template<T>::value[] = {
BOOST_PP_SEQ_ENUM(BOOST_UNORDERED_PRIMES)
};
template<typename T>
std::ptrdiff_t const prime_list_template<T>::length
= BOOST_PP_SEQ_SIZE(BOOST_UNORDERED_PRIMES);
#undef BOOST_UNORDERED_PRIMES
typedef prime_list_template<std::size_t> prime_list;
@ -230,7 +257,16 @@ namespace boost {
functions func2_;
functions_ptr func_; // The currently active functions.
};
#if defined(BOOST_MSVC)
# define BOOST_UNORDERED_DESTRUCT(x, type) (x)->~type();
#else
# define BOOST_UNORDERED_DESTRUCT(x, type) boost::unordered_detail::destroy(x)
template <typename T>
void destroy(T* x) {
x->~T();
}
#endif
}
}
@ -304,4 +340,8 @@ namespace boost {
#undef BOOST_UNORDERED_BORLAND_BOOL
#undef BOOST_UNORDERED_MSVC_RESET_PTR
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
#endif // BOOST_UNORDERED_DETAIL_HASH_TABLE_HPP_INCLUDED

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,957 @@
// Copyright (C) 2003-2004 Jeremy B. Maitin-Shepard.
// Copyright (C) 2005-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// 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
#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST)
#include <initializer_list>
#endif
#if defined(BOOST_MSVC)
#pragma warning(push)
#if BOOST_MSVC >= 1400
#pragma warning(disable:4396) //the inline specifier cannot be used when a
// friend declaration refers to a specialization
// of a function template
#endif
#endif
namespace boost
{
template <class Key, class T, class Hash, class Pred, class Alloc>
class unordered_map
{
#if BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
public:
#endif
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())
: base(f, l, n, hf, eql, allocator_type())
{
}
template <class InputIterator>
unordered_map(InputIterator f, InputIterator l,
size_type n,
const hasher &hf,
const key_equal &eql,
const allocator_type &a)
: base(f, l, n, hf, eql, a)
{
}
~unordered_map() {}
#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
#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST)
unordered_map(std::initializer_list<value_type> list,
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(list.begin(), list.end(), n, hf, eql, a)
{
}
unordered_map& operator=(std::initializer_list<value_type> list)
{
base.data_.clear();
base.insert_range(list.begin(), list.end());
return *this;
}
#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_UNORDERED_STD_FORWARD)
template <class... Args>
std::pair<iterator, bool> emplace(Args&&... args)
{
return boost::unordered_detail::pair_cast<iterator, bool>(
base.emplace(std::forward<Args>(args)...));
}
template <class... Args>
iterator emplace_hint(const_iterator hint, Args&&... args)
{
return iterator(base.emplace_hint(get(hint), std::forward<Args>(args)...));
}
#else
std::pair<iterator, bool> emplace(value_type const& v = value_type())
{
return boost::unordered_detail::pair_cast<iterator, bool>(
base.emplace(v));
}
iterator emplace_hint(const_iterator hint, value_type const& v = value_type())
{
return iterator(base.emplace_hint(get(hint), v));
}
#define BOOST_UNORDERED_EMPLACE(z, n, _) \
template < \
BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
> \
std::pair<iterator, bool> emplace( \
BOOST_UNORDERED_FUNCTION_PARAMS(z, n) \
) \
{ \
return boost::unordered_detail::pair_cast<iterator, bool>( \
base.emplace( \
BOOST_UNORDERED_CALL_PARAMS(z, n) \
)); \
} \
\
template < \
BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
> \
iterator emplace_hint(const_iterator hint, \
BOOST_UNORDERED_FUNCTION_PARAMS(z, n) \
) \
{ \
return iterator(base.emplace_hint(get(hint), \
BOOST_UNORDERED_CALL_PARAMS(z, n) \
)); \
}
BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT,
BOOST_UNORDERED_EMPLACE, _)
#undef BOOST_UNORDERED_EMPLACE
#endif
std::pair<iterator, bool> insert(const value_type& obj)
{
return boost::unordered_detail::pair_cast<iterator, bool>(
base.emplace(obj));
}
iterator insert(const_iterator hint, const value_type& obj)
{
return iterator(base.emplace_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&);
#elif !BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
friend bool operator==<Key, T, Hash, Pred, Alloc>(unordered_map const&, unordered_map const&);
friend bool operator!=<Key, T, Hash, Pred, Alloc>(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
{
#if BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
public:
#endif
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())
: base(f, l, n, hf, eql, allocator_type())
{
}
template <class InputIterator>
unordered_multimap(InputIterator f, InputIterator l,
size_type n,
const hasher &hf,
const key_equal &eql,
const allocator_type &a)
: base(f, l, n, hf, eql, a)
{
}
~unordered_multimap() {}
#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
#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST)
unordered_multimap(std::initializer_list<value_type> list,
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(list.begin(), list.end(), n, hf, eql, a)
{
}
unordered_multimap& operator=(std::initializer_list<value_type> list)
{
base.data_.clear();
base.insert_range(list.begin(), list.end());
return *this;
}
#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_UNORDERED_STD_FORWARD)
template <class... Args>
iterator emplace(Args&&... args)
{
return iterator(base.emplace(std::forward<Args>(args)...));
}
template <class... Args>
iterator emplace_hint(const_iterator hint, Args&&... args)
{
return iterator(base.emplace_hint(get(hint), std::forward<Args>(args)...));
}
#else
iterator emplace(value_type const& v = value_type())
{
return iterator(base.emplace(v));
}
iterator emplace_hint(const_iterator hint, value_type const& v = value_type())
{
return iterator(base.emplace_hint(get(hint), v));
}
#define BOOST_UNORDERED_EMPLACE(z, n, _) \
template < \
BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
> \
iterator emplace( \
BOOST_UNORDERED_FUNCTION_PARAMS(z, n) \
) \
{ \
return iterator( \
base.emplace( \
BOOST_UNORDERED_CALL_PARAMS(z, n) \
)); \
} \
\
template < \
BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
> \
iterator emplace_hint(const_iterator hint, \
BOOST_UNORDERED_FUNCTION_PARAMS(z, n) \
) \
{ \
return iterator(base.emplace_hint(get(hint), \
BOOST_UNORDERED_CALL_PARAMS(z, n) \
)); \
}
BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT,
BOOST_UNORDERED_EMPLACE, _)
#undef BOOST_UNORDERED_EMPLACE
#endif
iterator insert(const value_type& obj)
{
return iterator(base.emplace(obj));
}
iterator insert(const_iterator hint, const value_type& obj)
{
return iterator(base.emplace_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&);
#elif !BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
friend bool operator==<Key, T, Hash, Pred, Alloc>(unordered_multimap const&, unordered_multimap const&);
friend bool operator!=<Key, T, Hash, Pred, Alloc>(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
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
#endif // BOOST_UNORDERED_UNORDERED_MAP_HPP_INCLUDED

View File

@ -0,0 +1,53 @@
// Copyright (C) 2008-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#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

View File

@ -0,0 +1,911 @@
// Copyright (C) 2003-2004 Jeremy B. Maitin-Shepard.
// Copyright (C) 2005-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// 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
#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST)
#include <initializer_list>
#endif
#if defined(BOOST_MSVC)
#pragma warning(push)
#if BOOST_MSVC >= 1400
#pragma warning(disable:4396) //the inline specifier cannot be used when a
// friend declaration refers to a specialization
// of a function template
#endif
#endif
namespace boost
{
template <class Value, class Hash, class Pred, class Alloc>
class unordered_set
{
#if BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
public:
#endif
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())
: base(f, l, n, hf, eql, allocator_type())
{
}
template <class InputIterator>
unordered_set(InputIterator f, InputIterator l, size_type n,
const hasher &hf,
const key_equal &eql,
const allocator_type &a)
: base(f, l, n, hf, eql, a)
{
}
~unordered_set() {}
#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
#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST)
unordered_set(std::initializer_list<value_type> list,
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(list.begin(), list.end(), n, hf, eql, a)
{
}
unordered_set& operator=(std::initializer_list<value_type> list)
{
base.data_.clear();
base.insert_range(list.begin(), list.end());
return *this;
}
#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_UNORDERED_STD_FORWARD)
template <class... Args>
std::pair<iterator, bool> emplace(Args&&... args)
{
return boost::unordered_detail::pair_cast<iterator, bool>(
base.emplace(std::forward<Args>(args)...));
}
template <class... Args>
iterator emplace_hint(const_iterator hint, Args&&... args)
{
return iterator(
base.emplace_hint(get(hint), std::forward<Args>(args)...));
}
#else
std::pair<iterator, bool> emplace(value_type const& v = value_type())
{
return boost::unordered_detail::pair_cast<iterator, bool>(
base.emplace(v));
}
iterator emplace_hint(const_iterator hint, value_type const& v = value_type())
{
return iterator(base.emplace_hint(get(hint), v));
}
#define BOOST_UNORDERED_EMPLACE(z, n, _) \
template < \
BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
> \
std::pair<iterator, bool> emplace( \
BOOST_UNORDERED_FUNCTION_PARAMS(z, n) \
) \
{ \
return boost::unordered_detail::pair_cast<iterator, bool>( \
base.emplace( \
BOOST_UNORDERED_CALL_PARAMS(z, n) \
)); \
} \
\
template < \
BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
> \
iterator emplace_hint(const_iterator hint, \
BOOST_UNORDERED_FUNCTION_PARAMS(z, n) \
) \
{ \
return iterator(base.emplace_hint(get(hint), \
BOOST_UNORDERED_CALL_PARAMS(z, n) \
)); \
}
BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT,
BOOST_UNORDERED_EMPLACE, _)
#undef BOOST_UNORDERED_EMPLACE
#endif
std::pair<iterator, bool> insert(const value_type& obj)
{
return boost::unordered_detail::pair_cast<iterator, bool>(
base.emplace(obj));
}
iterator insert(const_iterator hint, const value_type& obj)
{
return iterator(base.emplace_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&);
#elif !BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
friend bool operator==<Value, Hash, Pred, Alloc>(unordered_set const&, unordered_set const&);
friend bool operator!=<Value, Hash, Pred, Alloc>(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
{
#if BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
public:
#endif
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())
: base(f, l, n, hf, eql, allocator_type())
{
}
template <class InputIterator>
unordered_multiset(InputIterator f, InputIterator l, size_type n,
const hasher &hf,
const key_equal &eql,
const allocator_type &a)
: base(f, l, n, hf, eql, a)
{
}
~unordered_multiset() {}
#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
#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST)
unordered_multiset(std::initializer_list<value_type> list,
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(list.begin(), list.end(), n, hf, eql, a)
{
}
unordered_multiset& operator=(std::initializer_list<value_type> list)
{
base.data_.clear();
base.insert_range(list.begin(), list.end());
return *this;
}
#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_UNORDERED_STD_FORWARD)
template <class... Args>
iterator emplace(Args&&... args)
{
return iterator(base.emplace(std::forward<Args>(args)...));
}
template <class... Args>
iterator emplace_hint(const_iterator hint, Args&&... args)
{
return iterator(base.emplace_hint(get(hint), std::forward<Args>(args)...));
}
#else
iterator emplace(value_type const& v = value_type())
{
return iterator(base.emplace(v));
}
iterator emplace_hint(const_iterator hint, value_type const& v = value_type())
{
return iterator(base.emplace_hint(get(hint), v));
}
#define BOOST_UNORDERED_EMPLACE(z, n, _) \
template < \
BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
> \
iterator emplace( \
BOOST_UNORDERED_FUNCTION_PARAMS(z, n) \
) \
{ \
return iterator( \
base.emplace( \
BOOST_UNORDERED_CALL_PARAMS(z, n) \
)); \
} \
\
template < \
BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
> \
iterator emplace_hint(const_iterator hint, \
BOOST_UNORDERED_FUNCTION_PARAMS(z, n) \
) \
{ \
return iterator(base.emplace_hint(get(hint), \
BOOST_UNORDERED_CALL_PARAMS(z, n) \
)); \
}
BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT,
BOOST_UNORDERED_EMPLACE, _)
#undef BOOST_UNORDERED_EMPLACE
#endif
iterator insert(const value_type& obj)
{
return iterator(base.emplace(obj));
}
iterator insert(const_iterator hint, const value_type& obj)
{
return iterator(base.emplace_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&);
#elif !BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
friend bool operator==<Value, Hash, Pred, Alloc>(unordered_multiset const&, unordered_multiset const&);
friend bool operator!=<Value, Hash, Pred, Alloc>(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
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
#endif // BOOST_UNORDERED_UNORDERED_SET_HPP_INCLUDED

View File

@ -0,0 +1,51 @@
// Copyright (C) 2008-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#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

View File

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

View File

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

1
module.cmake Normal file
View File

@ -0,0 +1 @@
boost_module(unordered DEPENDS config functional)

24
test/CMakeLists.txt Normal file
View File

@ -0,0 +1,24 @@
#
# Copyright Troy D. Straszheim
#
# Distributed under the Boost Software License, Version 1.0.
# See http://www.boost.org/LICENSE_1_0.txt
#
boost_additional_test_dependencies(unordered BOOST_DEPENDS test)
# GCC Compilers
IF(CMAKE_COMPILER_IS_GNUCC)
SET(test_compile_flags "-Wsign-promo -Wunused-parameter")
ENDIF(CMAKE_COMPILER_IS_GNUCC)
# Intel Compiler flags
IF( ${CMAKE_CXX_COMPILER} MATCHES "icpc" )
SET(test_compile_flags "${test_compile_flags} -strict_ansi -cxxlib-icc")
ENDIF( ${CMAKE_CXX_COMPILER} MATCHES "icpc" )
set (swap_compile_flags "${test_compile_flags} -DBOOST_UNORDERED_SWAP_METHOD=2")
add_subdirectory(exception)
add_subdirectory(unordered)

View File

@ -0,0 +1,25 @@
#
# Copyright Troy D. Straszheim
#
# Distributed under the Boost Software License, Version 1.0.
# See http://www.boost.org/LICENSE_1_0.txt
#
foreach(test
constructor_exception_tests
copy_exception_tests
assign_exception_tests
insert_exception_tests
erase_exception_tests
rehash_exception_tests
)
boost_test_run(${test}
COMPILE_FLAGS ${test_compile_flags}
DEPENDS boost_unit_test_framework)
endforeach(test ${unordered_tests})
#-- run the swap test
boost_test_run(swap_exception_tests
COMPILE_FLAGS ${swap_compile_flags}
DEPENDS boost_unit_test_framework)

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -25,7 +25,7 @@ struct erase_test_base : public test::exception_base
void check(T const& x) const {
std::string scope(test::scope);
BOOST_CHECK(scope.find("hash::") != std::string::npos ||
BOOST_TEST(scope.find("hash::") != std::string::npos ||
scope.find("equal_to::") != std::string::npos ||
scope == "operator==(object, object)");

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -128,10 +128,10 @@ struct insert_test_rehash1 : public insert_test_base<T>
size_type bucket_count = x.bucket_count();
size_type initial_elements = static_cast<size_type>(
ceil(bucket_count * (double) x.max_load_factor()) - 1);
BOOST_REQUIRE(initial_elements < this->values.size());
BOOST_TEST(initial_elements < this->values.size());
x.insert(this->values.begin(),
boost::next(this->values.begin(), initial_elements));
BOOST_REQUIRE(bucket_count == x.bucket_count());
BOOST_TEST(bucket_count == x.bucket_count());
return x;
}
@ -150,7 +150,7 @@ struct insert_test_rehash1 : public insert_test_base<T>
// This isn't actually a failure, but it means the test isn't doing its
// job.
BOOST_REQUIRE(x.bucket_count() != bucket_count);
BOOST_TEST(x.bucket_count() != bucket_count);
}
};
@ -173,7 +173,7 @@ struct insert_test_rehash2 : public insert_test_rehash1<T>
// This isn't actually a failure, but it means the test isn't doing its
// job.
BOOST_REQUIRE(x.bucket_count() != bucket_count);
BOOST_TEST(x.bucket_count() != bucket_count);
}
};
@ -195,12 +195,12 @@ struct insert_test_rehash3 : public insert_test_base<T>
rehash_bucket_count = static_cast<size_type>(
ceil(original_bucket_count * (double) x.max_load_factor())) - 1;
size_type initial_elements = rehash_bucket_count - 5;
size_type initial_elements = rehash_bucket_count > 5 ? rehash_bucket_count - 5 : 1;
BOOST_REQUIRE(initial_elements < this->values.size());
BOOST_TEST(initial_elements < this->values.size());
x.insert(this->values.begin(),
boost::next(this->values.begin(), initial_elements));
BOOST_REQUIRE(original_bucket_count == x.bucket_count());
BOOST_TEST(original_bucket_count == x.bucket_count());
return x;
}
@ -212,12 +212,12 @@ struct insert_test_rehash3 : public insert_test_base<T>
// This isn't actually a failure, but it means the test isn't doing its
// job.
BOOST_REQUIRE(x.bucket_count() != bucket_count);
BOOST_TEST(x.bucket_count() != bucket_count);
}
void check(T const& x) const {
if(x.size() < rehash_bucket_count) {
//BOOST_CHECK(x.bucket_count() == original_bucket_count);
//BOOST_TEST(x.bucket_count() == original_bucket_count);
}
test::check_equivalent_keys(x);
}

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -22,7 +22,7 @@ struct self_swap_base : public test::exception_base
std::string scope(test::scope);
#if BOOST_UNORDERED_SWAP_METHOD != 2
BOOST_CHECK(
BOOST_TEST(
scope == "hash::operator(hash)" ||
scope == "hash::operator=(hash)" ||
scope == "equal_to::operator(equal_to)" ||
@ -77,7 +77,7 @@ struct swap_base : public test::exception_base
std::string scope(test::scope);
#if BOOST_UNORDERED_SWAP_METHOD != 2
BOOST_CHECK(
BOOST_TEST(
scope == "hash::operator(hash)" ||
scope == "hash::operator=(hash)" ||
scope == "equal_to::operator(equal_to)" ||

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -1,5 +1,5 @@
// Copyright 2005-2008 Daniel James.
// Copyright 2005-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -1,11 +1,13 @@
// Copyright 2008 Daniel James.
// Copyright 2008-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or move at http://www.boost.org/LICENSE_1_0.txt)
#if !defined(BOOST_UNORDERED_TEST_HELPERS_COUNT_HEAD)
#define BOOST_UNORDERED_TEST_HELPERS_COUNT_HEAD
#include <iostream>
namespace test {
struct object_count {
int instances;
@ -36,6 +38,11 @@ namespace test {
bool operator!=(object_count const& x) const {
return !(*this == x);
}
friend std::ostream& operator<<(std::ostream& out, object_count const& c) {
out<<"[instances: "<<c.instances<<", constructions: "<<c.constructions<<"]";
return out;
}
};
template <class T>
@ -53,6 +60,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

@ -1,5 +1,5 @@
// Copyright 2005-2008 Daniel James.
// Copyright 2005-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -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

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -8,25 +8,10 @@
#include "./test.hpp"
#if defined(BOOST_UNORDERED_FULL_TEST)
# define BOOST_TEST_MAIN
# include <boost/test/exception_safety.hpp>
# include <boost/test/unit_test.hpp>
#endif
#include <boost/preprocessor/seq/for_each_product.hpp>
#include <boost/preprocessor/seq/elem.hpp>
#include <boost/preprocessor/cat.hpp>
#if defined(BOOST_UNORDERED_FULL_TEST)
# define UNORDERED_EXCEPTION_TEST_CASE(name, test_func, type) \
UNORDERED_AUTO_TEST(name) \
{ \
test_func< type > fixture; \
::test::exception_safety(fixture, BOOST_STRINGIZE(test_func<type>)); \
}
# define UNORDERED_EPOINT_IMPL BOOST_ITEST_EPOINT
#else
# define UNORDERED_EXCEPTION_TEST_CASE(name, test_func, type) \
UNORDERED_AUTO_TEST(name) \
{ \
@ -34,7 +19,6 @@
::test::lightweight::exception_safety(fixture, BOOST_STRINGIZE(test_func<type>)); \
}
# define UNORDERED_EPOINT_IMPL ::test::lightweight::epoint
#endif
#define UNORDERED_EXCEPTION_TEST_POSTFIX RUN_TESTS()
@ -178,16 +162,7 @@ namespace test {
}
}
};
#if defined(BOOST_UNORDERED_FULL_TEST)
template <class Test>
void exception_safety(Test const& f, char const* name) {
test_runner<Test> runner(f);
::boost::itest::exception_safety(runner, name);
}
#else
// Quick exception testing based on lightweight test
namespace lightweight {
@ -237,7 +212,6 @@ namespace test {
} while(!success);
}
}
#endif
}
#endif

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -1,5 +1,5 @@
// Copyright 2005-2008 Daniel James.
// Copyright 2005-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -1,24 +1,39 @@
// Copyright 2005-2008 Daniel James.
// Copyright 2005-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#if !defined(BOOST_UNORDERED_TEST_HELPERS_INPUT_ITERATOR_HEADER)
#define BOOST_UNORDERED_TEST_HELPERS_INPUT_ITERATOR_HEADER
#include <boost/config.hpp>
#include <boost/iterator_adaptors.hpp>
namespace test
{
template <class Iterator>
struct proxy
{
typedef BOOST_DEDUCED_TYPENAME Iterator::value_type value_type;
proxy(value_type const& v) : v_(v) {}
proxy(proxy const& x) : v_(x.v_) {}
operator value_type const&() const { return v_; }
value_type v_;
};
template <class Iterator>
struct input_iterator_adaptor
: boost::iterator_adaptor<
input_iterator_adaptor<Iterator>, Iterator,
boost::use_default, std::input_iterator_tag>
boost::use_default, std::input_iterator_tag,
proxy<Iterator> >
{
typedef boost::iterator_adaptor<
input_iterator_adaptor<Iterator>, Iterator,
boost::use_default, std::input_iterator_tag> base;
boost::use_default, std::input_iterator_tag,
proxy<Iterator> > base;
explicit input_iterator_adaptor(Iterator it = Iterator())
: base(it) {}

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -1,5 +1,5 @@
// Copyright 2008 Daniel James.
// Copyright 2008-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -81,7 +81,7 @@ namespace test
T* operator->() const { return &ptr_->value_; }
list_iterator& operator++() {
ptr_ = ptr_->next_; return *this; }
list_iterator& operator++(int) {
list_iterator operator++(int) {
list_iterator tmp = *this; ptr_ = ptr_->next_; return tmp; }
bool operator==(const_iterator y) const { return ptr_ == y.ptr_; }
bool operator!=(const_iterator y) const { return ptr_ != y.ptr_; }
@ -108,7 +108,7 @@ namespace test
T const* operator->() const { return &ptr_->value_; }
list_const_iterator& operator++() {
ptr_ = ptr_->next_; return *this; }
list_const_iterator& operator++(int) {
list_const_iterator operator++(int) {
list_const_iterator tmp = *this; ptr_ = ptr_->next_; return tmp; }
bool operator==(const_iterator y) const { return ptr_ == y.ptr_; }
bool operator!=(const_iterator y) const { return ptr_ != y.ptr_; }
@ -144,6 +144,7 @@ namespace test
list& operator=(list const& other) {
clear();
insert(other.begin(), other.end());
return *this;
}
iterator begin() { return iterator(data_.first_); }
@ -242,14 +243,28 @@ namespace test
node** merge_adjacent_ranges(node** first, node** second,
node** third, Less less)
{
while(first != second) {
if(less((*second)->value_, (*first)->value_)) {
swap_adjacent_ranges(first, second, third);
std::swap(second, third);
while(true) {
while(true) {
if(first == second) return third;
if(less((*second)->value_, (*first)->value_)) break;
first = &(*first)->next_;
}
swap_adjacent_ranges(first, second, third);
first = &(*first)->next_;
// Since the two ranges we just swapped, the order is now:
// first...third...second
while(true) {
if(first == third) return second;
if(!less((*first)->value_, (*third)->value_)) break;
first = &(*first)->next_;
}
swap_adjacent_ranges(first, third, second);
first = &(*first)->next_;
}
return third;
}
void swap_adjacent_ranges(node** first, node** second, node** third)

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -18,11 +18,6 @@ namespace test
{
namespace detail
{
// This annoymous namespace won't cause ODR violations as I won't
// be linking multiple translation units together. I'll probably
// move this into a cpp file before a full release, but for now it's
// the most convenient way.
struct memory_area {
void const* start;
void const* end;
@ -103,7 +98,7 @@ namespace test
void allocator_unref()
{
BOOST_CHECK(count_allocators > 0);
BOOST_TEST(count_allocators > 0);
if(count_allocators > 0) {
--count_allocators;
if(count_allocators == 0) {
@ -116,9 +111,9 @@ namespace test
count_constructions = 0;
allocated_memory.clear();
BOOST_CHECK(no_allocations_left);
BOOST_CHECK(no_constructions_left);
BOOST_CHECK(allocated_memory_empty);
BOOST_TEST(no_allocations_left);
BOOST_TEST(no_constructions_left);
BOOST_TEST(allocated_memory_empty);
}
}
}
@ -144,12 +139,12 @@ namespace test
if(pos == allocated_memory.end()) {
BOOST_ERROR("Deallocating unknown pointer.");
} else {
BOOST_CHECK(pos->first.start == ptr);
BOOST_CHECK(pos->first.end == (char*) ptr + n * size);
BOOST_CHECK(pos->second.tag_ == tag);
BOOST_TEST(pos->first.start == ptr);
BOOST_TEST(pos->first.end == (char*) ptr + n * size);
BOOST_TEST(pos->second.tag_ == tag);
allocated_memory.erase(pos);
}
BOOST_CHECK(count_allocations > 0);
BOOST_TEST(count_allocations > 0);
if(count_allocations > 0) --count_allocations;
}
@ -160,7 +155,7 @@ namespace test
void track_destroy(void* /*ptr*/, std::size_t /*size*/, int /*tag*/)
{
BOOST_CHECK(count_constructions > 0);
BOOST_TEST(count_constructions > 0);
if(count_constructions > 0) --count_constructions;
}
};

View File

@ -1,5 +1,5 @@
// Copyright 2005-2008 Daniel James.
// Copyright 2005-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -1,5 +1,5 @@
// Copyright 2005-2008 Daniel James.
// Copyright 2005-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -1,5 +1,5 @@
// Copyright 2005-2008 Daniel James.
// Copyright 2005-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -1,20 +1,12 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#if !defined(BOOST_UNORDERED_TEST_TEST_HEADER)
#define BOOST_UNORDERED_TEST_TEST_HEADER
#if defined(BOOST_UNORDERED_FULL_TEST)
#include <boost/test/test_tools.hpp>
#define UNORDERED_AUTO_TEST(x) BOOST_AUTO_TEST_CASE(x)
#define RUN_TESTS()
#else
#include <boost/test/minimal.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <iostream>
@ -30,7 +22,8 @@
}; \
BOOST_PP_CAT(x, _type) x; \
void BOOST_PP_CAT(x, _type)::run()
#define RUN_TESTS() int test_main(int, char**) { ::test::test_list::run_tests(); return 0; }
#define RUN_TESTS() int main(int, char**) \
{ ::test::test_list::run_tests(); return boost::report_errors(); }
namespace test {
struct registered_test_base {
@ -74,8 +67,6 @@ namespace test {
}
}
#endif
#include <boost/preprocessor/seq/for_each_product.hpp>
#include <boost/preprocessor/seq/fold_left.hpp>
#include <boost/preprocessor/seq/to_tuple.hpp>

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -49,7 +49,7 @@ namespace test
value_list values2(x2.begin(), x2.end());
values1.sort();
values2.sort();
BOOST_CHECK(values1.size() == values2.size() &&
BOOST_TEST(values1.size() == values2.size() &&
std::equal(values1.begin(), values1.end(), values2.begin(),
test::equivalent));
}
@ -61,7 +61,7 @@ namespace test
test::list<T> values2(x2.first, x2.second);
values1.sort();
values2.sort();
BOOST_CHECK(values1.size() == values2.size() &&
BOOST_TEST(values1.size() == values2.size() &&
std::equal(values1.begin(), values1.end(), values2.begin(), test::equivalent));
}

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -14,7 +14,7 @@
#include <new>
#include "../helpers/fwd.hpp"
#include "../helpers/allocator.hpp"
#include "./memory.hpp"
#include "../helpers/memory.hpp"
namespace test
{
@ -347,7 +347,7 @@ namespace exception
detail::tracker.track_construct((void*) p, sizeof(T), tag_);
}
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
#if defined(BOOST_UNORDERED_STD_FORWARD)
template<class... Args> void construct(pointer p, Args&&... args) {
UNORDERED_SCOPE(allocator::construct(pointer, Args&&...)) {
UNORDERED_EPOINT("Mock allocator construct function.");

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -229,7 +229,7 @@ namespace minimal
void construct(pointer p, T const& t) { new((void*)p.ptr_) T(t); }
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
#if defined(BOOST_UNORDERED_STD_FORWARD)
template<class... Args> void construct(pointer p, Args&&... args) {
new((void*)p.ptr_) T(std::forward<Args>(args)...);
}
@ -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&);

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -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;
}
@ -213,7 +218,7 @@ namespace test
new(p) T(t);
}
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
#if defined(BOOST_UNORDERED_STD_FORWARD)
template<class... Args> void construct(pointer p, Args&&... args) {
detail::tracker.track_construct((void*) p, sizeof(T), tag_);
new(p) T(std::forward<Args>(args)...);

View File

@ -0,0 +1,43 @@
#
# Copyright Troy D. Straszheim
#
# Distributed under the Boost Software License, Version 1.0.
# See http://www.boost.org/LICENSE_1_0.txt
#
#-------------------------------------------------------------------------------
# Unordered Tests
foreach(test
fwd_set_test
fwd_map_test
compile_set
compile_map
simple_tests
equivalent_keys_tests
constructor_tests
copy_tests
move_tests
assign_tests
insert_tests
insert_stable_tests
unnecessary_copy_tests
erase_tests
erase_equiv_tests
find_tests
at_tests
bucket_tests
load_factor_tests
rehash_tests
equality_tests
)
boost_test_run(${test}
COMPILE_FLAGS ${test_compile_flags}
DEPENDS boost_unit_test_framework)
endforeach()
boost_test_run(link_test link_test_1.cpp link_test_2.cpp)
#-- run the swap test
boost_test_run(swap_tests
COMPILE_FLAGS ${swap_compile_flags}
DEPENDS boost_unit_test_framework)

View File

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

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -27,9 +27,9 @@ void assign_tests1(T*, test::random_generator generator = test::default_generato
{
T x;
x = x;
BOOST_CHECK(x.empty());
BOOST_CHECK(test::equivalent(x.hash_function(), hf));
BOOST_CHECK(test::equivalent(x.key_eq(), eq));
BOOST_TEST(x.empty());
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
}
std::cerr<<"assign_tests1.2\n";
@ -47,7 +47,7 @@ void assign_tests1(T*, test::random_generator generator = test::default_generato
y.max_load_factor(x.max_load_factor() / 20);
y = x;
tracker.compare(y);
BOOST_CHECK(x.max_load_factor() == y.max_load_factor());
BOOST_TEST(x.max_load_factor() == y.max_load_factor());
}
}
@ -67,8 +67,8 @@ void assign_tests2(T*, test::random_generator generator = test::default_generato
T x1(v.begin(), v.end(), 0, hf1, eq1);
T x2(0, hf2, eq2);
x2 = x1;
BOOST_CHECK(test::equivalent(x2.hash_function(), hf1));
BOOST_CHECK(test::equivalent(x2.key_eq(), eq1));
BOOST_TEST(test::equivalent(x2.hash_function(), hf1));
BOOST_TEST(test::equivalent(x2.key_eq(), eq1));
test::check_container(x2, v);
}
@ -78,9 +78,9 @@ void assign_tests2(T*, test::random_generator generator = test::default_generato
T x1(v1.begin(), v1.end(), 0, hf1, eq1, al1);
T x2(v2.begin(), v2.end(), 0, hf2, eq2, al2);
x2 = x1;
BOOST_CHECK(test::equivalent(x2.hash_function(), hf1));
BOOST_CHECK(test::equivalent(x2.key_eq(), eq1));
BOOST_CHECK(test::equivalent(x2.get_allocator(), al2));
BOOST_TEST(test::equivalent(x2.hash_function(), hf1));
BOOST_TEST(test::equivalent(x2.key_eq(), eq1));
BOOST_TEST(test::equivalent(x2.get_allocator(), al2));
test::check_container(x2, v1);
}
}
@ -103,6 +103,37 @@ UNORDERED_TEST(assign_tests2,
((default_generator)(generate_collisions))
)
#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST)
UNORDERED_AUTO_TEST(assign_default_initializer_list) {
std::cerr<<"Initializer List Tests\n";
std::initializer_list<std::pair<int const, int> > init;
boost::unordered_map<int, int> x1;
x1[25] = 3;
x1[16] = 10;
BOOST_TEST(!x1.empty());
x1 = init;
BOOST_TEST(x1.empty());
}
#endif
#if !defined(BOOST_NO_INITIALIZER_LISTS)
UNORDERED_AUTO_TEST(assign_initializer_list)
{
std::cerr<<"Initializer List Tests\n";
boost::unordered_set<int> x;
x.insert(10);
x.insert(20);
x = { 1, 2, -10 };
BOOST_TEST(x.find(10) == x.end());
BOOST_TEST(x.find(-10) != x.end());
}
#endif
}
RUN_TESTS()

View File

@ -1,5 +1,5 @@
// Copyright 2007-2008 Daniel James.
// Copyright 2007-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -16,8 +16,8 @@ UNORDERED_AUTO_TEST(at_tests) {
x["one"] = 1;
x["two"] = 2;
BOOST_CHECK(x.at("one") == 1);
BOOST_CHECK(x.at("two") == 2);
BOOST_TEST(x.at("one") == 1);
BOOST_TEST(x.at("two") == 2);
try {
x.at("three");

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -24,7 +24,7 @@ void tests(X* = 0, test::random_generator generator = test::default_generator)
X x(v.begin(), v.end());
BOOST_CHECK(x.bucket_count() < x.max_bucket_count());
BOOST_TEST(x.bucket_count() < x.max_bucket_count());
std::cerr<<x.bucket_count()<<"<"<<x.max_bucket_count()<<"\n";
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::const_iterator
@ -32,21 +32,21 @@ void tests(X* = 0, test::random_generator generator = test::default_generator)
{
size_type bucket = x.bucket(test::get_key<X>(*it));
BOOST_CHECK(bucket < x.bucket_count());
BOOST_TEST(bucket < x.bucket_count());
if(bucket < x.max_bucket_count()) {
// lit? lend?? I need a new naming scheme.
const_local_iterator lit = x.begin(bucket), lend = x.end(bucket);
while(lit != lend && test::get_key<X>(*it) != test::get_key<X>(*lit)) ++lit;
BOOST_CHECK(lit != lend);
BOOST_TEST(lit != lend);
}
}
for(size_type i = 0; i < x.bucket_count(); ++i) {
BOOST_CHECK(x.bucket_size(i) == (size_type) std::distance(x.begin(i), x.end(i)));
BOOST_CHECK(x.bucket_size(i) == (size_type) std::distance(x.cbegin(i), x.cend(i)));
BOOST_TEST(x.bucket_size(i) == (size_type) std::distance(x.begin(i), x.end(i)));
BOOST_TEST(x.bucket_size(i) == (size_type) std::distance(x.cbegin(i), x.cend(i)));
X const& x_ref = x;
BOOST_CHECK(x.bucket_size(i) == (size_type) std::distance(x_ref.begin(i), x_ref.end(i)));
BOOST_CHECK(x.bucket_size(i) == (size_type) std::distance(x_ref.cbegin(i), x_ref.cend(i)));
BOOST_TEST(x.bucket_size(i) == (size_type) std::distance(x_ref.begin(i), x_ref.end(i)));
BOOST_TEST(x.bucket_size(i) == (size_type) std::distance(x_ref.cbegin(i), x_ref.cend(i)));
}
}

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -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

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -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

@ -1,5 +1,5 @@
// Copyright 2005-2008 Daniel James.
// Copyright 2005-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -87,10 +87,10 @@ void container_test(X& r, T const&)
// I'm not sure about either of these tests...
size_type max_diff((std::numeric_limits<difference_type>::max)());
difference_type converted_diff(max_diff);
BOOST_CHECK((std::numeric_limits<difference_type>::max)()
BOOST_TEST((std::numeric_limits<difference_type>::max)()
== converted_diff);
BOOST_CHECK(
BOOST_TEST(
static_cast<comparison_type>(
(std::numeric_limits<size_type>::max)()) >
static_cast<comparison_type>(
@ -98,8 +98,8 @@ void container_test(X& r, T const&)
// I don't test the runtime post-conditions here.
X u;
BOOST_CHECK(u.size() == 0);
BOOST_CHECK(X().size() == 0);
BOOST_TEST(u.size() == 0);
BOOST_TEST(X().size() == 0);
X a,b;
@ -151,14 +151,12 @@ void unordered_map_test(X& r, Key const& k, T const& v)
r.insert(std::pair<Key const, T>(k, v));
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
Key k_lvalue(k);
T v_lvalue(v);
r.emplace(k, v);
r.emplace(k_lvalue, v_lvalue);
r.emplace(rvalue(k), rvalue(v));
#endif
}
template <class X>
@ -168,11 +166,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>
@ -180,9 +173,7 @@ void unordered_unique_test(X& r, T const& t)
{
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
test::check_return_type<std::pair<iterator, bool> >::equals(r.insert(t));
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
test::check_return_type<std::pair<iterator, bool> >::equals(r.emplace(t));
#endif
}
template <class X, class T>
@ -190,9 +181,7 @@ void unordered_equivalent_test(X& r, T const& t)
{
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
test::check_return_type<iterator>::equals(r.insert(t));
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
test::check_return_type<iterator>::equals(r.emplace(t));
#endif
}
template <class X, class Key, class T>
@ -294,14 +283,12 @@ 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));
#endif
test::check_return_type<iterator>::equals(a.emplace_hint(q, t));
a.insert(i, j);
test::check_return_type<size_type>::equals(a.erase(k));
BOOST_CHECK(a.empty());
BOOST_TEST(a.empty());
if(a.empty()) {
a.insert(t);
q = a.cbegin();

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -29,42 +29,42 @@ void constructor_tests1(T*, test::random_generator generator = test::default_gen
std::cerr<<"Construct 1\n";
{
T x(0, hf, eq);
BOOST_CHECK(x.empty());
BOOST_CHECK(test::equivalent(x.hash_function(), hf));
BOOST_CHECK(test::equivalent(x.key_eq(), eq));
BOOST_CHECK(test::equivalent(x.get_allocator(), al));
BOOST_TEST(x.empty());
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
BOOST_TEST(test::equivalent(x.get_allocator(), al));
test::check_equivalent_keys(x);
}
std::cerr<<"Construct 2\n";
{
T x(100, hf);
BOOST_CHECK(x.empty());
BOOST_CHECK(x.bucket_count() >= 100);
BOOST_CHECK(test::equivalent(x.hash_function(), hf));
BOOST_CHECK(test::equivalent(x.key_eq(), eq));
BOOST_CHECK(test::equivalent(x.get_allocator(), al));
BOOST_TEST(x.empty());
BOOST_TEST(x.bucket_count() >= 100);
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
BOOST_TEST(test::equivalent(x.get_allocator(), al));
test::check_equivalent_keys(x);
}
std::cerr<<"Construct 3\n";
{
T x(2000);
BOOST_CHECK(x.empty());
BOOST_CHECK(x.bucket_count() >= 2000);
BOOST_CHECK(test::equivalent(x.hash_function(), hf));
BOOST_CHECK(test::equivalent(x.key_eq(), eq));
BOOST_CHECK(test::equivalent(x.get_allocator(), al));
BOOST_TEST(x.empty());
BOOST_TEST(x.bucket_count() >= 2000);
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
BOOST_TEST(test::equivalent(x.get_allocator(), al));
test::check_equivalent_keys(x);
}
std::cerr<<"Construct 4\n";
{
T x;
BOOST_CHECK(x.empty());
BOOST_CHECK(test::equivalent(x.hash_function(), hf));
BOOST_CHECK(test::equivalent(x.key_eq(), eq));
BOOST_CHECK(test::equivalent(x.get_allocator(), al));
BOOST_TEST(x.empty());
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
BOOST_TEST(test::equivalent(x.get_allocator(), al));
test::check_equivalent_keys(x);
}
@ -72,10 +72,10 @@ void constructor_tests1(T*, test::random_generator generator = test::default_gen
{
test::random_values<T> v(1000, generator);
T x(v.begin(), v.end(), 10000, hf, eq);
BOOST_CHECK(x.bucket_count() >= 10000);
BOOST_CHECK(test::equivalent(x.hash_function(), hf));
BOOST_CHECK(test::equivalent(x.key_eq(), eq));
BOOST_CHECK(test::equivalent(x.get_allocator(), al));
BOOST_TEST(x.bucket_count() >= 10000);
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
BOOST_TEST(test::equivalent(x.get_allocator(), al));
test::check_container(x, v);
test::check_equivalent_keys(x);
}
@ -84,10 +84,10 @@ void constructor_tests1(T*, test::random_generator generator = test::default_gen
{
test::random_values<T> v(10, generator);
T x(v.begin(), v.end(), 10000, hf);
BOOST_CHECK(x.bucket_count() >= 10000);
BOOST_CHECK(test::equivalent(x.hash_function(), hf));
BOOST_CHECK(test::equivalent(x.key_eq(), eq));
BOOST_CHECK(test::equivalent(x.get_allocator(), al));
BOOST_TEST(x.bucket_count() >= 10000);
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
BOOST_TEST(test::equivalent(x.get_allocator(), al));
test::check_container(x, v);
test::check_equivalent_keys(x);
}
@ -96,10 +96,10 @@ void constructor_tests1(T*, test::random_generator generator = test::default_gen
{
test::random_values<T> v(100, generator);
T x(v.begin(), v.end(), 100);
BOOST_CHECK(x.bucket_count() >= 100);
BOOST_CHECK(test::equivalent(x.hash_function(), hf));
BOOST_CHECK(test::equivalent(x.key_eq(), eq));
BOOST_CHECK(test::equivalent(x.get_allocator(), al));
BOOST_TEST(x.bucket_count() >= 100);
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
BOOST_TEST(test::equivalent(x.get_allocator(), al));
test::check_container(x, v);
test::check_equivalent_keys(x);
}
@ -108,9 +108,9 @@ void constructor_tests1(T*, test::random_generator generator = test::default_gen
{
test::random_values<T> v(1, generator);
T x(v.begin(), v.end());
BOOST_CHECK(test::equivalent(x.hash_function(), hf));
BOOST_CHECK(test::equivalent(x.key_eq(), eq));
BOOST_CHECK(test::equivalent(x.get_allocator(), al));
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
BOOST_TEST(test::equivalent(x.get_allocator(), al));
test::check_container(x, v);
test::check_equivalent_keys(x);
}
@ -118,10 +118,10 @@ void constructor_tests1(T*, test::random_generator generator = test::default_gen
std::cerr<<"Construct 9\n";
{
T x(0, hf, eq, al);
BOOST_CHECK(x.empty());
BOOST_CHECK(test::equivalent(x.hash_function(), hf));
BOOST_CHECK(test::equivalent(x.key_eq(), eq));
BOOST_CHECK(test::equivalent(x.get_allocator(), al));
BOOST_TEST(x.empty());
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
BOOST_TEST(test::equivalent(x.get_allocator(), al));
test::check_equivalent_keys(x);
}
@ -129,10 +129,10 @@ void constructor_tests1(T*, test::random_generator generator = test::default_gen
{
test::random_values<T> v(1000, generator);
T x(v.begin(), v.end(), 10000, hf, eq, al);
BOOST_CHECK(x.bucket_count() >= 10000);
BOOST_CHECK(test::equivalent(x.hash_function(), hf));
BOOST_CHECK(test::equivalent(x.key_eq(), eq));
BOOST_CHECK(test::equivalent(x.get_allocator(), al));
BOOST_TEST(x.bucket_count() >= 10000);
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
BOOST_TEST(test::equivalent(x.get_allocator(), al));
test::check_container(x, v);
test::check_equivalent_keys(x);
}
@ -141,10 +141,10 @@ void constructor_tests1(T*, test::random_generator generator = test::default_gen
{
test::random_values<T> v(1000, generator);
T x(al);
BOOST_CHECK(x.empty());
BOOST_CHECK(test::equivalent(x.hash_function(), hf));
BOOST_CHECK(test::equivalent(x.key_eq(), eq));
BOOST_CHECK(test::equivalent(x.get_allocator(), al));
BOOST_TEST(x.empty());
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
BOOST_TEST(test::equivalent(x.get_allocator(), al));
test::check_equivalent_keys(x);
}
}
@ -165,21 +165,21 @@ void constructor_tests2(T*, test::random_generator const& generator = test::defa
std::cerr<<"Construct 1\n";
{
T x(10000, hf1, eq1);
BOOST_CHECK(x.bucket_count() >= 10000);
BOOST_CHECK(test::equivalent(x.hash_function(), hf1));
BOOST_CHECK(test::equivalent(x.key_eq(), eq1));
BOOST_CHECK(test::equivalent(x.get_allocator(), al));
BOOST_TEST(x.bucket_count() >= 10000);
BOOST_TEST(test::equivalent(x.hash_function(), hf1));
BOOST_TEST(test::equivalent(x.key_eq(), eq1));
BOOST_TEST(test::equivalent(x.get_allocator(), al));
test::check_equivalent_keys(x);
}
std::cerr<<"Construct 2\n";
{
T x(100, hf1);
BOOST_CHECK(x.empty());
BOOST_CHECK(x.bucket_count() >= 100);
BOOST_CHECK(test::equivalent(x.hash_function(), hf1));
BOOST_CHECK(test::equivalent(x.key_eq(), eq));
BOOST_CHECK(test::equivalent(x.get_allocator(), al));
BOOST_TEST(x.empty());
BOOST_TEST(x.bucket_count() >= 100);
BOOST_TEST(test::equivalent(x.hash_function(), hf1));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
BOOST_TEST(test::equivalent(x.get_allocator(), al));
test::check_equivalent_keys(x);
}
@ -187,9 +187,9 @@ void constructor_tests2(T*, test::random_generator const& generator = test::defa
{
test::random_values<T> v(100, generator);
T x(v.begin(), v.end(), 0, hf1, eq1);
BOOST_CHECK(test::equivalent(x.hash_function(), hf1));
BOOST_CHECK(test::equivalent(x.key_eq(), eq1));
BOOST_CHECK(test::equivalent(x.get_allocator(), al));
BOOST_TEST(test::equivalent(x.hash_function(), hf1));
BOOST_TEST(test::equivalent(x.key_eq(), eq1));
BOOST_TEST(test::equivalent(x.get_allocator(), al));
test::check_container(x, v);
test::check_equivalent_keys(x);
}
@ -198,10 +198,10 @@ void constructor_tests2(T*, test::random_generator const& generator = test::defa
{
test::random_values<T> v(5, generator);
T x(v.begin(), v.end(), 1000, hf1);
BOOST_CHECK(x.bucket_count() >= 1000);
BOOST_CHECK(test::equivalent(x.hash_function(), hf1));
BOOST_CHECK(test::equivalent(x.key_eq(), eq));
BOOST_CHECK(test::equivalent(x.get_allocator(), al));
BOOST_TEST(x.bucket_count() >= 1000);
BOOST_TEST(test::equivalent(x.hash_function(), hf1));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
BOOST_TEST(test::equivalent(x.get_allocator(), al));
test::check_container(x, v);
test::check_equivalent_keys(x);
}
@ -288,6 +288,28 @@ UNORDERED_TEST(map_constructor_test,
((test_map)(test_multimap))
)
#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST)
UNORDERED_AUTO_TEST(test_default_initializer_list) {
std::cerr<<"Initializer List Tests\n";
std::initializer_list<int> init;
boost::unordered_set<int> x1 = init;
BOOST_TEST(x1.empty());
}
#endif
#if !defined(BOOST_NO_INITIALIZER_LISTS)
UNORDERED_AUTO_TEST(test_initializer_list) {
std::cerr<<"Initializer List Tests\n";
boost::unordered_set<int> x1 = { 2, 10, 45, -5 };
BOOST_TEST(x1.find(10) != x1.end());
BOOST_TEST(x1.find(46) == x1.end());
}
#endif
}
RUN_TESTS()

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -27,11 +27,11 @@ void copy_construct_tests1(T*, test::random_generator const& generator = test::d
{
T x;
T y(x);
BOOST_CHECK(y.empty());
BOOST_CHECK(test::equivalent(y.hash_function(), hf));
BOOST_CHECK(test::equivalent(y.key_eq(), eq));
BOOST_CHECK(test::equivalent(y.get_allocator(), al));
BOOST_CHECK(x.max_load_factor() == y.max_load_factor());
BOOST_TEST(y.empty());
BOOST_TEST(test::equivalent(y.hash_function(), hf));
BOOST_TEST(test::equivalent(y.key_eq(), eq));
BOOST_TEST(test::equivalent(y.get_allocator(), al));
BOOST_TEST(x.max_load_factor() == y.max_load_factor());
test::check_equivalent_keys(y);
}
@ -57,7 +57,7 @@ void copy_construct_tests1(T*, test::random_generator const& generator = test::d
test::unordered_equivalence_tester<T> equivalent(x);
equivalent(y);
// This isn't guaranteed:
BOOST_CHECK(y.load_factor() < y.max_load_factor());
BOOST_TEST(y.load_factor() < y.max_load_factor());
test::check_equivalent_keys(y);
}
}
@ -75,22 +75,22 @@ void copy_construct_tests2(T* ptr, test::random_generator const& generator = tes
{
T x(10000, hf, eq, al);
T y(x);
BOOST_CHECK(y.empty());
BOOST_CHECK(test::equivalent(y.hash_function(), hf));
BOOST_CHECK(test::equivalent(y.key_eq(), eq));
BOOST_CHECK(test::equivalent(y.get_allocator(), al));
BOOST_CHECK(x.max_load_factor() == y.max_load_factor());
BOOST_TEST(y.empty());
BOOST_TEST(test::equivalent(y.hash_function(), hf));
BOOST_TEST(test::equivalent(y.key_eq(), eq));
BOOST_TEST(test::equivalent(y.get_allocator(), al));
BOOST_TEST(x.max_load_factor() == y.max_load_factor());
test::check_equivalent_keys(y);
}
{
T x(1000, hf, eq, al);
T y(x, al2);
BOOST_CHECK(y.empty());
BOOST_CHECK(test::equivalent(y.hash_function(), hf));
BOOST_CHECK(test::equivalent(y.key_eq(), eq));
BOOST_CHECK(test::equivalent(y.get_allocator(), al2));
BOOST_CHECK(x.max_load_factor() == y.max_load_factor());
BOOST_TEST(y.empty());
BOOST_TEST(test::equivalent(y.hash_function(), hf));
BOOST_TEST(test::equivalent(y.key_eq(), eq));
BOOST_TEST(test::equivalent(y.get_allocator(), al2));
BOOST_TEST(x.max_load_factor() == y.max_load_factor());
test::check_equivalent_keys(y);
}
@ -102,7 +102,7 @@ void copy_construct_tests2(T* ptr, test::random_generator const& generator = tes
test::unordered_equivalence_tester<T> equivalent(x);
equivalent(y);
test::check_equivalent_keys(y);
BOOST_CHECK(test::equivalent(y.get_allocator(), al));
BOOST_TEST(test::equivalent(y.get_allocator(), al));
}
{
@ -113,7 +113,7 @@ void copy_construct_tests2(T* ptr, test::random_generator const& generator = tes
test::unordered_equivalence_tester<T> equivalent(x);
equivalent(y);
test::check_equivalent_keys(y);
BOOST_CHECK(test::equivalent(y.get_allocator(), al2));
BOOST_TEST(test::equivalent(y.get_allocator(), al2));
}
}

View File

@ -1,5 +1,5 @@
// Copyright 2008 Daniel James.
// Copyright 2008-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -13,6 +13,10 @@ namespace equality_tests
{
struct mod_compare
{
bool alt_hash_;
explicit mod_compare(bool alt_hash = false) : alt_hash_(alt_hash) {}
bool operator()(int x, int y) const
{
return x % 1000 == y % 1000;
@ -20,123 +24,142 @@ namespace equality_tests
int operator()(int x) const
{
return x % 250;
return alt_hash_ ? x % 250 : (x + 5) % 250;
}
};
#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_TEST(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_TEST(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_TEST(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_TEST(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_TEST(x1 == x2);
BOOST_TEST(!(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_TEST(x1 != x2);
BOOST_TEST(!(x1 == x2));
BOOST_TEST(x2 != x1);
BOOST_TEST(!(x2 == x1));
x2.insert(1);
BOOST_TEST(x1 == x2);
BOOST_TEST(!(x1 != x2));
x2.insert(2);
BOOST_TEST(x1 != x2);
BOOST_TEST(!(x1 == x2));
BOOST_TEST(x2 != x1);
BOOST_TEST(!(x2 == x1));
}
UNORDERED_AUTO_TEST(equality_key_value_tests)
{
UNORDERED_EQUALITY_MULTISET_TEST((1), !=, (2));
UNORDERED_EQUALITY_SET_TEST((2), ==, (2));
UNORDERED_EQUALITY_MAP_TEST(((1)(1))((2)(1)), !=, ((1)(1))((3)(1)));
}
UNORDERED_AUTO_TEST(equality_collision_test)
{
UNORDERED_EQUALITY_MULTISET_TEST(
(1), !=, (501));
UNORDERED_EQUALITY_MULTISET_TEST(
(1)(251), !=, (1)(501));
UNORDERED_EQUALITY_MULTIMAP_TEST(
((251)(1))((1)(1)), !=, ((501)(1))((1)(1)));
UNORDERED_EQUALITY_MULTISET_TEST(
(1)(501), ==, (1)(501));
UNORDERED_EQUALITY_SET_TEST(
(1)(501), ==, (501)(1));
UNORDERED_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)));
}
// Test that equality still works when the two containers have
// different hash functions but the same equality predicate.
UNORDERED_AUTO_TEST(equality_different_hash_test)
{
typedef boost::unordered_set<int, mod_compare, mod_compare> set;
set set1(0, mod_compare(false), mod_compare(false));
set set2(0, mod_compare(true), mod_compare(true));
BOOST_TEST(set1 == set2);
set1.insert(1); set2.insert(2);
BOOST_TEST(set1 != set2);
set1.insert(2); set2.insert(1);
BOOST_TEST(set1 == set2);
set1.insert(10); set2.insert(20);
BOOST_TEST(set1 != set2);
set1.insert(20); set2.insert(10);
BOOST_TEST(set1 == set2);
}
}

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -67,11 +67,11 @@ UNORDERED_AUTO_TEST(single_item_tests)
collide_map x(init.begin(), init.end());
x.erase(x.begin(), x.begin());
BOOST_CHECK(x.count(1) == 1 && x.size() == 1);
BOOST_TEST(x.count(1) == 1 && x.size() == 1);
x.erase(x.end(), x.end());
BOOST_CHECK(x.count(1) == 1 && x.size() == 1);
BOOST_TEST(x.count(1) == 1 && x.size() == 1);
x.erase(x.begin(), x.end());
BOOST_CHECK(x.count(1) == 0 && x.size() == 0);
BOOST_TEST(x.count(1) == 0 && x.size() == 0);
}
UNORDERED_AUTO_TEST(two_equivalent_item_tests)
@ -83,14 +83,14 @@ UNORDERED_AUTO_TEST(two_equivalent_item_tests)
{
collide_map x(init.begin(), init.end());
x.erase(x.begin(), x.end());
BOOST_CHECK(x.count(1) == 0 && x.size() == 0);
BOOST_TEST(x.count(1) == 0 && x.size() == 0);
}
{
collide_map x(init.begin(), init.end());
int value = boost::next(x.begin())->second;
x.erase(x.begin(), boost::next(x.begin()));
BOOST_CHECK(x.count(1) == 1 && x.size() == 1 &&
BOOST_TEST(x.count(1) == 1 && x.size() == 1 &&
x.begin()->first == 1 && x.begin()->second == value);
}
@ -98,7 +98,7 @@ UNORDERED_AUTO_TEST(two_equivalent_item_tests)
collide_map x(init.begin(), init.end());
int value = x.begin()->second;
x.erase(boost::next(x.begin()), x.end());
BOOST_CHECK(x.count(1) == 1 && x.size() == 1 &&
BOOST_TEST(x.count(1) == 1 && x.size() == 1 &&
x.begin()->first == 1 && x.begin()->second == value);
}
}

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -32,10 +32,10 @@ void erase_tests1(Container*, test::random_generator generator = test::default_g
{
std::size_t count = x.count(test::get_key<Container>(*it));
std::size_t old_size = x.size();
BOOST_CHECK(count == x.erase(test::get_key<Container>(*it)));
BOOST_CHECK(x.size() == old_size - count);
BOOST_CHECK(x.count(test::get_key<Container>(*it)) == 0);
BOOST_CHECK(x.find(test::get_key<Container>(*it)) == x.end());
BOOST_TEST(count == x.erase(test::get_key<Container>(*it)));
BOOST_TEST(x.size() == old_size - count);
BOOST_TEST(x.count(test::get_key<Container>(*it)) == 0);
BOOST_TEST(x.find(test::get_key<Container>(*it)) == x.end());
}
}
@ -50,11 +50,11 @@ void erase_tests1(Container*, test::random_generator generator = test::default_g
std::size_t count = x.count(key);
BOOST_DEDUCED_TYPENAME Container::iterator pos = x.erase(x.begin());
--size;
BOOST_CHECK(pos == x.begin());
BOOST_CHECK(x.count(key) == count - 1);
BOOST_CHECK(x.size() == size);
BOOST_TEST(pos == x.begin());
BOOST_TEST(x.count(key) == count - 1);
BOOST_TEST(x.size() == size);
}
BOOST_CHECK(x.empty());
BOOST_TEST(x.empty());
}
std::cerr<<"erase(random position).\n";
@ -77,15 +77,15 @@ void erase_tests1(Container*, test::random_generator generator = test::default_g
next = boost::next(pos);
BOOST_DEDUCED_TYPENAME Container::key_type key = test::get_key<Container>(*pos);
std::size_t count = x.count(key);
BOOST_CHECK(next == x.erase(pos));
BOOST_TEST(next == x.erase(pos));
--size;
if(size > 0)
BOOST_CHECK(index == 0 ? next == x.begin() :
BOOST_TEST(index == 0 ? next == x.begin() :
next == boost::next(prev));
BOOST_CHECK(x.count(key) == count - 1);
BOOST_CHECK(x.size() == size);
BOOST_TEST(x.count(key) == count - 1);
BOOST_TEST(x.size() == size);
}
BOOST_CHECK(x.empty());
BOOST_TEST(x.empty());
}
std::cerr<<"erase(ranges).\n";
@ -99,15 +99,15 @@ void erase_tests1(Container*, test::random_generator generator = test::default_g
// returns 'the iterator immediately following the erase elements'
// and if nothing is erased, then there's nothing to follow. But I
// think this is the only sensible option...
BOOST_CHECK(x.erase(x.end(), x.end()) == x.end());
BOOST_CHECK(x.erase(x.begin(), x.begin()) == x.begin());
BOOST_CHECK(x.size() == size);
BOOST_TEST(x.erase(x.end(), x.end()) == x.end());
BOOST_TEST(x.erase(x.begin(), x.begin()) == x.begin());
BOOST_TEST(x.size() == size);
BOOST_CHECK(x.erase(x.begin(), x.end()) == x.end());
BOOST_CHECK(x.empty());
BOOST_CHECK(x.begin() == x.end());
BOOST_TEST(x.erase(x.begin(), x.end()) == x.end());
BOOST_TEST(x.empty());
BOOST_TEST(x.begin() == x.end());
BOOST_CHECK(x.erase(x.begin(), x.end()) == x.begin());
BOOST_TEST(x.erase(x.begin(), x.end()) == x.begin());
}
std::cerr<<"clear().\n";
@ -115,8 +115,8 @@ void erase_tests1(Container*, test::random_generator generator = test::default_g
test::random_values<Container> v(500, generator);
Container x(v.begin(), v.end());
x.clear();
BOOST_CHECK(x.empty());
BOOST_CHECK(x.begin() == x.end());
BOOST_TEST(x.empty());
BOOST_TEST(x.begin() == x.end());
}
std::cerr<<"\n";

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -34,12 +34,12 @@ void find_tests1(X*, test::random_generator generator = test::default_generator)
BOOST_DEDUCED_TYPENAME X::key_type key = test::get_key<X>(*it1);
iterator pos = x.find(key);
BOOST_DEDUCED_TYPENAME X::const_iterator const_pos = x_const.find(key);
BOOST_CHECK(pos != x.end() &&
BOOST_TEST(pos != x.end() &&
x.key_eq()(key, test::get_key<X>(*pos)));
BOOST_CHECK(const_pos != x_const.end() &&
BOOST_TEST(const_pos != x_const.end() &&
x_const.key_eq()(key, test::get_key<X>(*const_pos)));
BOOST_CHECK(x.count(key) == tracker.count(key));
BOOST_TEST(x.count(key) == tracker.count(key));
test::compare_pairs(x.equal_range(key),
tracker.equal_range(key),
@ -56,11 +56,11 @@ void find_tests1(X*, test::random_generator generator = test::default_generator)
BOOST_DEDUCED_TYPENAME X::key_type key = test::get_key<X>(*it2);
if(tracker.find(test::get_key<X>(key)) == tracker.end())
{
BOOST_CHECK(x.find(key) == x.end());
BOOST_CHECK(x_const.find(key) == x_const.end());
BOOST_CHECK(x.count(key) == 0);
BOOST_TEST(x.find(key) == x.end());
BOOST_TEST(x_const.find(key) == x_const.end());
BOOST_TEST(x.count(key) == 0);
std::pair<iterator, iterator> range = x.equal_range(key);
BOOST_CHECK(range.first == range.second);
BOOST_TEST(range.first == range.second);
}
}
}
@ -73,10 +73,10 @@ void find_tests1(X*, test::random_generator generator = test::default_generator)
v2.begin(); it3 != v2.end(); ++it3)
{
BOOST_DEDUCED_TYPENAME X::key_type key = test::get_key<X>(*it3);
BOOST_CHECK(x.find(key) == x.end());
BOOST_CHECK(x.count(key) == 0);
BOOST_TEST(x.find(key) == x.end());
BOOST_TEST(x.count(key) == 0);
std::pair<iterator, iterator> range = x.equal_range(key);
BOOST_CHECK(range.first == range.second);
BOOST_TEST(range.first == range.second);
}
}
}

View File

@ -0,0 +1,62 @@
// Copyright 2008-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#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_TEST(y.find(1) != y.end() && y.find(1)->second == 2);
BOOST_TEST(y.find(2) == y.end());
BOOST_TEST(x.find(1) == x.end());
BOOST_TEST(x.find(2) != x.end() && x.find(2)->second == 1);
BOOST_TEST(!call_equals(x, y));
BOOST_TEST(call_not_equals(x, y));
}
UNORDERED_AUTO_TEST(use_multimap_fwd_declared_function) {
int_multimap x, y;
call_swap(x, y);
BOOST_TEST(call_equals(x, y));
BOOST_TEST(!call_not_equals(x, y));
}
RUN_TESTS()

View File

@ -0,0 +1,84 @@
// Copyright 2008-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#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_TEST(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_TEST(sizeof(is_unordered_set_impl(&x)) == sizeof(true_type));
int dummy;
BOOST_TEST(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_TEST(y.find(1) != y.end());
BOOST_TEST(y.find(2) == y.end());
BOOST_TEST(x.find(1) == x.end());
BOOST_TEST(x.find(2) != x.end());
BOOST_TEST(!call_equals(x, y));
BOOST_TEST(call_not_equals(x, y));
}
UNORDERED_AUTO_TEST(use_multiset_fwd_declared_function) {
int_multiset x, y;
call_swap(x, y);
BOOST_TEST(call_equals(x, y));
BOOST_TEST(!call_not_equals(x, y));
}
RUN_TESTS()

View File

@ -1,5 +1,5 @@
// Copyright 2007-2008 Daniel James.
// Copyright 2007-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -47,13 +47,13 @@ UNORDERED_AUTO_TEST(stable_insert_test1) {
x.insert(insert_stable::member(1,3));
boost::unordered_multiset<insert_stable::member>::const_iterator it = x.begin(), end = x.end();
BOOST_CHECK(it != end);
if(it != end) { BOOST_CHECK(it->tag2_ == 1); ++it; }
BOOST_CHECK(it != end);
if(it != end) { BOOST_CHECK(it->tag2_ == 2); ++it; }
BOOST_CHECK(it != end);
if(it != end) { BOOST_CHECK(it->tag2_ == 3); ++it; }
BOOST_CHECK(it == end);
BOOST_TEST(it != end);
if(it != end) { BOOST_TEST(it->tag2_ == 1); ++it; }
BOOST_TEST(it != end);
if(it != end) { BOOST_TEST(it->tag2_ == 2); ++it; }
BOOST_TEST(it != end);
if(it != end) { BOOST_TEST(it->tag2_ == 3); ++it; }
BOOST_TEST(it == end);
}
UNORDERED_AUTO_TEST(stable_insert_test2) {
@ -66,13 +66,13 @@ UNORDERED_AUTO_TEST(stable_insert_test2) {
it = x.begin();
iterator end = x.end();
BOOST_CHECK(it != end);
if(it != end) { BOOST_CHECK(it->first.tag2_ == 1 && it->second == 1); ++it; }
BOOST_CHECK(it != end);
if(it != end) { BOOST_CHECK(it->first.tag2_ == 2 && it->second == 2); ++it; }
BOOST_CHECK(it != end);
if(it != end) { BOOST_CHECK(it->first.tag2_ == 3 && it->second == 3); ++it; }
BOOST_CHECK(it == end);
BOOST_TEST(it != end);
if(it != end) { BOOST_TEST(it->first.tag2_ == 1 && it->second == 1); ++it; }
BOOST_TEST(it != end);
if(it != end) { BOOST_TEST(it->first.tag2_ == 2 && it->second == 2); ++it; }
BOOST_TEST(it != end);
if(it != end) { BOOST_TEST(it->first.tag2_ == 3 && it->second == 3); ++it; }
BOOST_TEST(it == end);
}
RUN_TESTS()

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -43,13 +43,13 @@ void unique_insert_tests1(X*, test::random_generator generator = test::default_g
std::pair<iterator, bool> r1 = x.insert(*it);
std::pair<BOOST_DEDUCED_TYPENAME ordered::iterator, bool> r2 = tracker.insert(*it);
BOOST_CHECK(r1.second == r2.second);
BOOST_CHECK(*r1.first == *r2.first);
BOOST_TEST(r1.second == r2.second);
BOOST_TEST(*r1.first == *r2.first);
tracker.compare_key(x, *it);
if(x.size() < b * old_bucket_count)
BOOST_CHECK(x.bucket_count() == old_bucket_count);
BOOST_TEST(x.bucket_count() == old_bucket_count);
}
test::check_equivalent_keys(x);
@ -73,12 +73,12 @@ void equivalent_insert_tests1(X*, test::random_generator generator = test::defau
BOOST_DEDUCED_TYPENAME X::iterator r1 = x.insert(*it);
BOOST_DEDUCED_TYPENAME test::ordered<X>::iterator r2 = tracker.insert(*it);
BOOST_CHECK(*r1 == *r2);
BOOST_TEST(*r1 == *r2);
tracker.compare_key(x, *it);
if(x.size() < b * old_bucket_count)
BOOST_CHECK(x.bucket_count() == old_bucket_count);
BOOST_TEST(x.bucket_count() == old_bucket_count);
}
test::check_equivalent_keys(x);
@ -107,11 +107,11 @@ void insert_tests2(X*, test::random_generator generator = test::default_generato
iterator r1 = x.insert(x.begin(), *it);
tracker_iterator r2 = tracker.insert(tracker.begin(), *it);
BOOST_CHECK(*r1 == *r2);
BOOST_TEST(*r1 == *r2);
tracker.compare_key(x, *it);
if(x.size() < b * old_bucket_count)
BOOST_CHECK(x.bucket_count() == old_bucket_count);
BOOST_TEST(x.bucket_count() == old_bucket_count);
}
test::check_equivalent_keys(x);
@ -133,11 +133,11 @@ void insert_tests2(X*, test::random_generator generator = test::default_generato
const_iterator r1 = x.insert(x_const.end(), *it);
tracker_iterator r2 = tracker.insert(tracker.end(), *it);
BOOST_CHECK(*r1 == *r2);
BOOST_TEST(*r1 == *r2);
tracker.compare_key(x, *it);
if(x.size() < b * old_bucket_count)
BOOST_CHECK(x.bucket_count() == old_bucket_count);
BOOST_TEST(x.bucket_count() == old_bucket_count);
}
test::check_equivalent_keys(x);
@ -159,11 +159,11 @@ void insert_tests2(X*, test::random_generator generator = test::default_generato
pos = x.insert(pos, *it);
tracker_iterator r2 = tracker.insert(tracker.begin(), *it);
BOOST_CHECK(*pos == *r2);
BOOST_TEST(*pos == *r2);
tracker.compare_key(x, *it);
if(x.size() < b * old_bucket_count)
BOOST_CHECK(x.bucket_count() == old_bucket_count);
BOOST_TEST(x.bucket_count() == old_bucket_count);
}
test::check_equivalent_keys(x);
@ -187,7 +187,7 @@ void insert_tests2(X*, test::random_generator generator = test::default_generato
tracker.compare_key(x, *it);
if(x.size() < b * old_bucket_count)
BOOST_CHECK(x.bucket_count() == old_bucket_count);
BOOST_TEST(x.bucket_count() == old_bucket_count);
}
test::check_equivalent_keys(x);
@ -243,13 +243,13 @@ void unique_emplace_tests1(X*, test::random_generator generator = test::default_
std::pair<iterator, bool> r1 = x.emplace(*it);
std::pair<BOOST_DEDUCED_TYPENAME ordered::iterator, bool> r2 = tracker.insert(*it);
BOOST_CHECK(r1.second == r2.second);
BOOST_CHECK(*r1.first == *r2.first);
BOOST_TEST(r1.second == r2.second);
BOOST_TEST(*r1.first == *r2.first);
tracker.compare_key(x, *it);
if(x.size() < b * old_bucket_count)
BOOST_CHECK(x.bucket_count() == old_bucket_count);
BOOST_TEST(x.bucket_count() == old_bucket_count);
}
test::check_equivalent_keys(x);
@ -273,12 +273,12 @@ void equivalent_emplace_tests1(X*, test::random_generator generator = test::defa
BOOST_DEDUCED_TYPENAME X::iterator r1 = x.emplace(*it);
BOOST_DEDUCED_TYPENAME test::ordered<X>::iterator r2 = tracker.insert(*it);
BOOST_CHECK(*r1 == *r2);
BOOST_TEST(*r1 == *r2);
tracker.compare_key(x, *it);
if(x.size() < b * old_bucket_count)
BOOST_CHECK(x.bucket_count() == old_bucket_count);
BOOST_TEST(x.bucket_count() == old_bucket_count);
}
test::check_equivalent_keys(x);
@ -307,7 +307,7 @@ void map_tests(X*, test::random_generator generator = test::default_generator)
tracker.compare_key(x, *it);
if(x.size() < b * old_bucket_count)
BOOST_CHECK(x.bucket_count() == old_bucket_count);
BOOST_TEST(x.bucket_count() == old_bucket_count);
}
test::check_equivalent_keys(x);

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -24,13 +24,13 @@ void set_load_factor_tests(X* = 0)
{
X x;
BOOST_CHECK(x.max_load_factor() == 1.0);
BOOST_CHECK(x.load_factor() == 0);
BOOST_TEST(x.max_load_factor() == 1.0);
BOOST_TEST(x.load_factor() == 0);
// A valid implementation could fail these tests, but I think they're
// reasonable.
x.max_load_factor(2.0); BOOST_CHECK(x.max_load_factor() == 2.0);
x.max_load_factor(0.5); BOOST_CHECK(x.max_load_factor() == 0.5);
x.max_load_factor(2.0); BOOST_TEST(x.max_load_factor() == 2.0);
x.max_load_factor(0.5); BOOST_TEST(x.max_load_factor() == 0.5);
}
template <class X>
@ -49,7 +49,7 @@ void insert_test(X*, float mlf, test::random_generator generator = test::default
old_bucket_count = x.bucket_count();
x.insert(*it);
if(old_size + 1 < b * old_bucket_count)
BOOST_CHECK(x.bucket_count() == old_bucket_count);
BOOST_TEST(x.bucket_count() == old_bucket_count);
}
}

View File

@ -1,5 +1,5 @@
// Copyright 2008 Daniel James.
// Copyright 2008-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or move at http://www.boost.org/LICENSE_1_0.txt)
@ -52,11 +52,11 @@ namespace move_tests
{
T y(empty(ptr));
BOOST_CHECK(y.empty());
BOOST_CHECK(test::equivalent(y.hash_function(), hf));
BOOST_CHECK(test::equivalent(y.key_eq(), eq));
BOOST_CHECK(test::equivalent(y.get_allocator(), al));
BOOST_CHECK(y.max_load_factor() == 1.0);
BOOST_TEST(y.empty());
BOOST_TEST(test::equivalent(y.hash_function(), hf));
BOOST_TEST(test::equivalent(y.key_eq(), eq));
BOOST_TEST(test::equivalent(y.get_allocator(), al));
BOOST_TEST(y.max_load_factor() == 1.0);
test::check_equivalent_keys(y);
}
@ -64,7 +64,7 @@ namespace move_tests
test::random_values<T> v(1000, generator);
test::object_count count;
T y(create(v, count));
BOOST_CHECK(count == test::global_object_count);
BOOST_TEST(count == test::global_object_count);
test::check_container(y, v);
test::check_equivalent_keys(y);
}
@ -78,7 +78,7 @@ namespace move_tests
test::object_count count;
T y;
y = create(v, count);
BOOST_CHECK(count == test::global_object_count);
BOOST_TEST(count == test::global_object_count);
test::check_container(y, v);
test::check_equivalent_keys(y);
}
@ -98,12 +98,12 @@ namespace move_tests
{
test::random_values<T> v(500, generator);
T y(create(v, count, hf, eq, al, 0.5));
BOOST_CHECK(count == test::global_object_count);
BOOST_TEST(count == test::global_object_count);
test::check_container(y, v);
BOOST_CHECK(test::equivalent(y.hash_function(), hf));
BOOST_CHECK(test::equivalent(y.key_eq(), eq));
BOOST_CHECK(test::equivalent(y.get_allocator(), al));
BOOST_CHECK(y.max_load_factor() == 0.5); // Not necessarily required.
BOOST_TEST(test::equivalent(y.hash_function(), hf));
BOOST_TEST(test::equivalent(y.key_eq(), eq));
BOOST_TEST(test::equivalent(y.get_allocator(), al));
BOOST_TEST(y.max_load_factor() == 0.5); // Not necessarily required.
test::check_equivalent_keys(y);
}
@ -111,12 +111,12 @@ namespace move_tests
// TODO: To do this correctly requires the fancy new allocator stuff.
test::random_values<T> v(500, generator);
T y(create(v, count, hf, eq, al, 2.0), al2);
BOOST_CHECK(count != test::global_object_count);
BOOST_TEST(count != test::global_object_count);
test::check_container(y, v);
BOOST_CHECK(test::equivalent(y.hash_function(), hf));
BOOST_CHECK(test::equivalent(y.key_eq(), eq));
BOOST_CHECK(test::equivalent(y.get_allocator(), al2));
BOOST_CHECK(y.max_load_factor() == 2.0); // Not necessarily required.
BOOST_TEST(test::equivalent(y.hash_function(), hf));
BOOST_TEST(test::equivalent(y.key_eq(), eq));
BOOST_TEST(test::equivalent(y.get_allocator(), al2));
BOOST_TEST(y.max_load_factor() == 2.0); // Not necessarily required.
test::check_equivalent_keys(y);
}
@ -124,17 +124,17 @@ namespace move_tests
test::random_values<T> v(25, generator);
T y(create(v, count, hf, eq, al, 1.0), al);
#if defined(BOOST_HAS_RVALUE_REFS)
BOOST_CHECK(count == test::global_object_count);
BOOST_TEST(count == test::global_object_count);
#else
BOOST_CHECK(test::global_object_count.constructions - count.constructions <=
BOOST_TEST(test::global_object_count.constructions - count.constructions <=
(test::is_map<T>::value ? 50 : 25));
BOOST_CHECK(count.instances == test::global_object_count.instances);
BOOST_TEST(count.instances == test::global_object_count.instances);
#endif
test::check_container(y, v);
BOOST_CHECK(test::equivalent(y.hash_function(), hf));
BOOST_CHECK(test::equivalent(y.key_eq(), eq));
BOOST_CHECK(test::equivalent(y.get_allocator(), al));
BOOST_CHECK(y.max_load_factor() == 1.0); // Not necessarily required.
BOOST_TEST(test::equivalent(y.hash_function(), hf));
BOOST_TEST(test::equivalent(y.key_eq(), eq));
BOOST_TEST(test::equivalent(y.get_allocator(), al));
BOOST_TEST(y.max_load_factor() == 1.0); // Not necessarily required.
test::check_equivalent_keys(y);
}
}

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -26,10 +26,10 @@ void rehash_empty_test1(X* = 0)
X x;
x.rehash(10000);
BOOST_CHECK(postcondition(x, 10000));
BOOST_TEST(postcondition(x, 10000));
x.rehash(0);
BOOST_CHECK(postcondition(x, 0));
BOOST_TEST(postcondition(x, 0));
}
template <class X>
@ -40,18 +40,18 @@ void rehash_test1(X* = 0, test::random_generator generator = test::default_gener
tracker.insert_range(v.begin(), v.end());
X x(v.begin(), v.end());
x.rehash(0); BOOST_CHECK(postcondition(x, 0));
x.rehash(0); BOOST_TEST(postcondition(x, 0));
tracker.compare(x);
x.max_load_factor(0.25);
x.rehash(0); BOOST_CHECK(postcondition(x, 0));
x.rehash(0); BOOST_TEST(postcondition(x, 0));
tracker.compare(x);
x.max_load_factor(50.0);
x.rehash(0); BOOST_CHECK(postcondition(x, 0));
x.rehash(0); BOOST_TEST(postcondition(x, 0));
tracker.compare(x);
x.rehash(1000); BOOST_CHECK(postcondition(x, 1000));
x.rehash(1000); BOOST_TEST(postcondition(x, 1000));
tracker.compare(x);
}

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -19,67 +19,67 @@ void simple_test(X const& a)
{
X u;
BOOST_CHECK(u.size() == 0);
BOOST_CHECK(X().size() == 0);
BOOST_TEST(u.size() == 0);
BOOST_TEST(X().size() == 0);
}
{
BOOST_CHECK(equivalent(X(a)));
BOOST_TEST(equivalent(X(a)));
}
{
X u(a);
BOOST_CHECK(equivalent(u));
BOOST_TEST(equivalent(u));
}
{
X u = a;
BOOST_CHECK(equivalent(u));
BOOST_TEST(equivalent(u));
}
{
X b(a);
BOOST_CHECK(b.begin() == const_cast<X const&>(b).cbegin());
BOOST_CHECK(b.end() == const_cast<X const&>(b).cend());
BOOST_TEST(b.begin() == const_cast<X const&>(b).cbegin());
BOOST_TEST(b.end() == const_cast<X const&>(b).cend());
}
{
X b(a);
X c;
BOOST_CHECK(equivalent(b));
BOOST_CHECK(c.empty());
BOOST_TEST(equivalent(b));
BOOST_TEST(c.empty());
b.swap(c);
BOOST_CHECK(b.empty());
BOOST_CHECK(equivalent(c));
BOOST_TEST(b.empty());
BOOST_TEST(equivalent(c));
b.swap(c);
BOOST_CHECK(c.empty());
BOOST_CHECK(equivalent(b));
BOOST_TEST(c.empty());
BOOST_TEST(equivalent(b));
}
{
X u;
X& r = u;
BOOST_CHECK(&(r = r) == &r);
BOOST_CHECK(r.empty());
BOOST_CHECK(&(r = a) == &r);
BOOST_CHECK(equivalent(r));
BOOST_CHECK(&(r = r) == &r);
BOOST_CHECK(equivalent(r));
BOOST_TEST(&(r = r) == &r);
BOOST_TEST(r.empty());
BOOST_TEST(&(r = a) == &r);
BOOST_TEST(equivalent(r));
BOOST_TEST(&(r = r) == &r);
BOOST_TEST(equivalent(r));
}
{
BOOST_CHECK(a.size() ==
BOOST_TEST(a.size() ==
(BOOST_DEDUCED_TYPENAME X::size_type) std::distance(a.begin(), a.end()));
}
{
BOOST_CHECK(a.empty() == (a.size() == 0));
BOOST_TEST(a.empty() == (a.size() == 0));
}
{
BOOST_CHECK(a.empty() == (a.begin() == a.end()));
BOOST_TEST(a.empty() == (a.begin() == a.end()));
X u;
BOOST_CHECK(u.begin() == u.end());
BOOST_TEST(u.begin() == u.end());
}
}

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -1,5 +1,5 @@
// Copyright 2006-2008 Daniel James.
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -68,12 +68,22 @@ namespace unnecessary_copy_tests
#define COPY_COUNT(n) \
if(count_copies::copies != n) { \
BOOST_ERROR("Wrong number of copies."); \
std::cerr<<"Number of copies: "<<count_copies::copies<<std::endl; \
std::cerr<<"Number of copies: "<<count_copies::copies<<" expecting: "<<n<<std::endl; \
}
#define MOVE_COUNT(n) \
if(count_copies::moves != n) { \
BOOST_ERROR("Wrong number of moves."); \
std::cerr<<"Number of moves: "<<count_copies::moves<<std::endl; \
std::cerr<<"Number of moves: "<<count_copies::moves<<" expecting: "<<n<<std::endl; \
}
#define COPY_COUNT_RANGE(a, b) \
if(count_copies::copies < a || count_copies::copies > b) { \
BOOST_ERROR("Wrong number of copies."); \
std::cerr<<"Number of copies: "<<count_copies::copies<<" expecting: ["<<a<<", "<<b<<"]"<<std::endl; \
}
#define MOVE_COUNT_RANGE(a, b) \
if(count_copies::moves < a || count_copies::moves > b) { \
BOOST_ERROR("Wrong number of moves."); \
std::cerr<<"Number of moves: "<<count_copies::copies<<" expecting: ["<<a<<", "<<b<<"]"<<std::endl; \
}
namespace unnecessary_copy_tests
@ -84,12 +94,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;
@ -100,7 +109,6 @@ namespace unnecessary_copy_tests
UNORDERED_TEST(unnecessary_copy_insert_test,
((set)(multiset)(map)(multimap)))
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
template <class T>
void unnecessary_copy_emplace_test(T*)
{
@ -118,9 +126,19 @@ namespace unnecessary_copy_tests
reset();
T x;
x.emplace(source<BOOST_DEDUCED_TYPENAME T::value_type>());
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
COPY_COUNT(1);
#else
COPY_COUNT(2);
#endif
}
UNORDERED_TEST(unnecessary_copy_emplace_test,
((set)(multiset)(map)(multimap)))
UNORDERED_TEST(unnecessary_copy_emplace_rvalue_test,
((set)(multiset)(map)(multimap)))
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
template <class T>
void unnecessary_copy_emplace_move_test(T*)
{
@ -132,13 +150,11 @@ namespace unnecessary_copy_tests
COPY_COUNT(1); MOVE_COUNT(1);
}
UNORDERED_TEST(unnecessary_copy_emplace_test,
((set)(multiset)(map)(multimap)))
UNORDERED_TEST(unnecessary_copy_emplace_rvalue_test,
((set)(multiset)(map)(multimap)))
UNORDERED_TEST(unnecessary_copy_emplace_move_test,
((set)(multiset)(map)(multimap)))
#endif
UNORDERED_AUTO_TEST(unnecessary_copy_emplace_set_test)
{
reset();
@ -173,10 +189,12 @@ namespace unnecessary_copy_tests
x.emplace(source<count_copies>());
COPY_COUNT(1); MOVE_COUNT(0);
#if defined(BOOST_HAS_RVALUE_REFS)
// No move should take place.
reset();
x.emplace(std::move(a));
COPY_COUNT(0); MOVE_COUNT(0);
#endif
// Just in case a did get moved...
count_copies b;
@ -193,8 +211,12 @@ namespace unnecessary_copy_tests
// The container will have to create b copy in order to compare with
// the existing element.
//
// Note to self: If copy_count == 0 it's an error not an optimization.
// TODO: Devise a better test.
reset();
x.emplace(b, b);
COPY_COUNT(1); MOVE_COUNT(0);
}
@ -231,24 +253,22 @@ namespace unnecessary_copy_tests
x.emplace(source<std::pair<count_copies, count_copies> >());
COPY_COUNT(2); MOVE_COUNT(0);
count_copies part;
reset();
std::pair<count_copies const&, count_copies const&> a_ref(part, part);
x.emplace(a_ref);
COPY_COUNT(0); MOVE_COUNT(0);
// TODO: This doesn't work on older versions of gcc.
//count_copies part;
std::pair<count_copies const, count_copies> b;
//reset();
//std::pair<count_copies const&, count_copies const&> a_ref(part, part);
//x.emplace(a_ref);
//COPY_COUNT(0); MOVE_COUNT(0);
#if defined(BOOST_HAS_RVALUE_REFS)
// No move should take place.
// (since a is already in the container)
reset();
x.emplace(std::move(a));
COPY_COUNT(0); MOVE_COUNT(0);
#endif
// Just in case a did get moved
std::pair<count_copies const, count_copies> b;
// This test requires a C++0x std::pair. Which gcc hasn't got yet.
//reset();
//x.emplace(b.first.tag_);
//COPY_COUNT(2); MOVE_COUNT(0);
//
// 2 arguments
@ -268,10 +288,9 @@ namespace unnecessary_copy_tests
COPY_COUNT(1); MOVE_COUNT(0);
reset();
x.emplace(b.first.tag_, b.second.tag_);
COPY_COUNT(2); MOVE_COUNT(0);
x.emplace(count_copies(b.first.tag_), count_copies(b.second.tag_));
COPY_COUNT(2); MOVE_COUNT(0);
}
#endif
}
RUN_TESTS()