Compare commits

..

140 Commits

Author SHA1 Message Date
Daniel James
9c37cd46b1 Unordered/Hash: Merge change log.
[SVN r80778]
2012-09-30 11:58:06 +00:00
Daniel James
b856e6308d Hash: Merge new floating point hasher.
Uses a binary hash for more platforms.


[SVN r80293]
2012-08-28 21:50:57 +00:00
Daniel James
b4b4a559e0 Hash: merge enum support + cleanup some tests.
[SVN r80292]
2012-08-28 21:48:16 +00:00
Daniel James
043571dabf Merge #error for deperectaed boost/functional/detail/container_fwd.hpp
[SVN r80286]
2012-08-28 17:38:30 +00:00
Daniel James
34a6eebf7e Hash: Merge C++11 forward declaration fix.
[SVN r80054]
2012-08-15 23:04:49 +00:00
Daniel James
12f49f7c53 Merge some link fixes.
[SVN r79869]
2012-08-05 08:36:49 +00:00
Daniel James
73b507c728 Hash: Merge support for smart pointers.
[SVN r79548]
2012-07-16 00:18:30 +00:00
Daniel James
330040aea9 Hash: Merge update c++11 header macros.
[SVN r79544]
2012-07-15 23:28:30 +00:00
Daniel James
75bcfdeb36 Hash: Merge using SFINAE to avoid implicit casts.
[SVN r79394]
2012-07-09 20:53:36 +00:00
Daniel James
dfe0ad3a60 Hash: Merge test fix.
[SVN r78854]
2012-06-07 19:50:10 +00:00
Daniel James
c409903f5e Hash: Merge deprecated header warning + some documentation.
[SVN r78697]
2012-05-27 21:13:49 +00:00
Lorenzo Caminiti
033ef4b507 Merged ScopeExit (improved), LocalFunction (new), Functional/OverloadedFunction (new), and Utility/IdentityType (new) from trunk into release branch.
[SVN r78564]
2012-05-24 01:35:04 +00:00
Daniel James
18b143cad1 Unordered: Merge unordered from trunk.
- Activate `std::allocator_traits` for gcc 4.7 and Visual C++ 11.
- Implement variadic construct in `boost::unordered::detail::allocator_traits`
  when variadics, rvalue references and SFINAE expression are available.
- Use variadic construct from `allocator_traits`, or when not available move
  the logic for constructing `value_type` to a lower level, so the container
  code is a bit simpler.
- Avoid `-Wshadow` warnings. Fixes #6190.
- Implement `reserve`. Fixes #6857.


[SVN r78432]
2012-05-12 08:14:05 +00:00
Daniel James
346e62f53f Unordered/Hash: Merge from trunk.
[SVN r78319]
2012-05-03 22:05:21 +00:00
Daniel James
9a38ebf8c3 Hash: Merge documentation fix.
[SVN r76955]
2012-02-09 09:26:00 +00:00
Daniel James
a6f8c51afb Hash: Fix 1.6 quickbook in 1.5 document.
[SVN r76703]
2012-01-26 08:17:11 +00:00
Daniel James
903b1e409e Hash: Merge documentation changes.
[SVN r76533]
2012-01-15 20:49:40 +00:00
Daniel James
eb040cb89b Hash: Improve rationale slightly.
[SVN r75542]
2011-11-18 09:03:29 +00:00
Daniel James
d92209d725 Hash: Use quickbook 1.5
[SVN r75541]
2011-11-18 09:02:47 +00:00
Daniel James
58e42260d5 Merge unordered+hash documentation updates.
[SVN r75015]
2011-10-17 20:23:27 +00:00
Daniel James
56293f4313 Hash: A few edits to the new rationale.
[SVN r74963]
2011-10-16 10:32:12 +00:00
Daniel James
335930c652 Hash: Remove info for compilers that are no longer supported.
[SVN r74857]
2011-10-09 18:22:11 +00:00
Daniel James
da096ddf8c Hash: Note about the quality of the hash function.
In response to the thread starting at:

http://lists.boost.org/Archives/boost/2011/10/186476.php

[SVN r74856]
2011-10-09 18:14:50 +00:00
Daniel James
15bc3339e2 Hash: merge updated tests.
- Remove shared_ptr_fail_test, since shared_ptr now has a hash function.
- Run several tests with and without implicit casts.


[SVN r70445]
2011-03-23 00:10:03 +00:00
Daniel James
8c0e9a2b09 Run some tests without BOOST_HASH_NO_IMPLICIT_CASTS.
[SVN r69854]
2011-03-11 18:19:23 +00:00
Daniel James
664522596f Remove shared_ptr fail test since it now supports Boost.Hash
[SVN r69853]
2011-03-11 18:17:48 +00:00
Daniel James
cc0710b8a2 Merge typeindex support for hash. Fixes #4756.
[SVN r68199]
2011-01-17 04:15:00 +00:00
Daniel James
ce885af9b0 Fix copy and paste typo. Refs #4756.
[SVN r68182]
2011-01-16 11:06:00 +00:00
Daniel James
9e641187c6 Oops, make new hash_value overload inline.
[SVN r68147]
2011-01-14 03:36:39 +00:00
Daniel James
7dc95d044d Support typeindex in hash. Refs #4756.
[SVN r68145]
2011-01-14 03:13:39 +00:00
Daniel James
ad614b3d5f Move tests for container_fwd.hpp into detail.
[SVN r67667]
2011-01-04 23:30:22 +00:00
Daniel James
fc7eb28826 Merge hash from trunk.
- Avoid `-Wconversion` warnings.


[SVN r67664]
2011-01-04 23:06:53 +00:00
Daniel James
ed598f865e Fix tabs and files without copyright.
[SVN r67612]
2011-01-03 12:43:34 +00:00
Daniel James
482f038837 Avoid -Wconversion warnings in unordered & hash.
[SVN r67170]
2010-12-11 14:43:00 +00:00
Daniel James
a2e947588d Import boostbook/quickbook in unordered and hash docs.
[SVN r67091]
2010-12-07 20:45:08 +00:00
Daniel James
982b350d71 Remove some 'always_show_run_output' flags.
[SVN r66566]
2010-11-14 11:42:58 +00:00
Daniel James
80b88f24c1 Merge OpenVMS 64 bit patch for hash. Fixes #4477.
[SVN r64869]
2010-08-17 20:00:17 +00:00
Daniel James
577054de93 Fix hashing pointers on 64-bit OpenVMS.
Patch by Artyom. Refs #4477

[SVN r64397]
2010-07-27 19:18:53 +00:00
Daniel James
a98b37d12f Merge hash, opt-in to breaking change rather than opt-out.
[SVN r64031]
2010-07-15 01:12:23 +00:00
Daniel James
fc3b3863b4 Only include static_assert when necessary.
[SVN r64009]
2010-07-14 08:28:04 +00:00
Daniel James
906f632706 Actually, make the change to hash opt-in, rather than opt-out. It's a bit late to introduce a breaking change.
[SVN r64007]
2010-07-14 08:17:48 +00:00
Daniel James
afc4d6664f Merge iostreams, hash.
Including disallowing implicit casts to `hash_value`.


[SVN r63812]
2010-07-10 14:20:45 +00:00
Daniel James
bbfb6fd32c Release notes for hash.
[SVN r63810]
2010-07-10 13:47:47 +00:00
Daniel James
38d131c158 Fix inspect issues.
[SVN r63762]
2010-07-08 20:48:30 +00:00
Daniel James
2553a5fbdc Try preventing static casts when calling hash_value.
[SVN r63716]
2010-07-06 23:32:37 +00:00
Tobias Schwinger
55fac118e9 adds Functional/Factory
[SVN r61596]
2010-04-26 23:20:27 +00:00
Daniel James
5ce1a71c84 Merge some link fixes and release notes.
[SVN r61474]
2010-04-21 23:00:35 +00:00
Daniel James
425de7d1dd Unordered/hash release notes.
[SVN r61356]
2010-04-18 13:20:45 +00:00
Daniel James
a60758dec2 Disable warnings as errors for hash.
[SVN r61207]
2010-04-11 20:24:04 +00:00
Daniel James
f544265741 Give up on warnings-as-errors for gcc for now.
[SVN r61113]
2010-04-06 20:14:12 +00:00
Daniel James
7af7c59420 Merge from trunk.
- Add `quick_erase` for unordered. `erase_return_void` is now deprecated.
   Fixes #3966
 - Avoid collision between 0 and 0.5. Fixes #4038


[SVN r60980]
2010-03-31 21:39:07 +00:00
Daniel James
733422d1b9 Remove optimization which causes 0.5 to hash to 0. Refs #4038.
I have an internal requirement the 0 hashes to 0, a better solution
might be to remove that, put the optimization back and hash 0 to another
value. Or alternatively, use the main combine function instead.

[SVN r60805]
2010-03-24 08:49:00 +00:00
Daniel James
f3072d2023 Merge hash and unordered from trunk.
- Replace uses of deprecated C++0x macros
 - Set length of primes inside template on Sun C++. Fixes #3854
 - Missing newline at end of file.



[SVN r59911]
2010-02-25 19:05:01 +00:00
Daniel James
77f856e3cf Remove deprecated macros for hash and unordered's tests.
[SVN r59708]
2010-02-16 22:33:10 +00:00
Daniel James
6544b32920 Take advantage of the simplified parameters.
[SVN r59707]
2010-02-16 22:32:49 +00:00
Daniel James
538b8fb95a Stop using the deprecated BOOST_HAS_ macros in unordered and hash.
[SVN r59697]
2010-02-15 23:01:06 +00:00
Daniel James
fdc0995489 Merge some detail changes.
- [53670] Avoid C style casts.
 - [55604] Fix #3346 boost/detail/scoped_enum_emulation.hpp enum_t conflict
   with Unix rpc/types.h
 - Don't foward declare containers when using gcc's parallel library and add a
   macro to disable forward declaration. Fixes #3866.


[SVN r59679]
2010-02-14 16:31:21 +00:00
Daniel James
e042170fb9 Missing newline.
[SVN r59365]
2010-01-30 09:30:04 +00:00
Daniel James
316b1aa9f0 Don't foward declare containers when using gcc's parallel library and
add a macro to disable forward declaration. Fixes #3866.

[SVN r59282]
2010-01-27 19:32:39 +00:00
Daniel James
692d65d0e4 Merge link fix.
[SVN r59013]
2010-01-15 00:56:07 +00:00
Daniel James
0ba3e9b282 Fix link to example file. Fixes #3836.
Thanks for reporting this.

[SVN r58951]
2010-01-12 18:52:43 +00:00
Daniel James
98f0f11423 Turn warnings as errors back on.
[SVN r58949]
2010-01-12 18:51:59 +00:00
Daniel James
e67ee6032a Merge unordered documentation.
[SVN r58844]
2010-01-09 17:17:53 +00:00
Daniel James
6e37c616db Update changelogs and slightly improved reference documentation for new release.
[SVN r58805]
2010-01-08 06:43:57 +00:00
Daniel James
5860602e5c Merge hash changes.
[SVN r58801]
2010-01-08 05:38:39 +00:00
Daniel James
5f10c2bb7e Explicitly cast values to avoid warning on Visual C++ 10
[SVN r58745]
2010-01-06 08:43:47 +00:00
Daniel James
6d7a55a4f7 Formatting changes, mostly to fit within 80 characters.
Also, some C casts converted to static_cast.

[SVN r58692]
2010-01-04 22:49:39 +00:00
Daniel James
0ed492ba18 Rename namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS to lower case for consistency.
[SVN r58632]
2010-01-02 11:12:23 +00:00
Daniel James
2734e22b50 Only use _GLIBCXX_DEBUG on gcc/darwin.
It looks like pathscale also uses the gcc library but debug mode doesn't
work on it.

[SVN r58567]
2009-12-29 18:06:41 +00:00
Daniel James
9938fad017 Only use gcc debug containers on the container_fwd_test.
[SVN r58395]
2009-12-15 13:16:50 +00:00
Daniel James
4787563f96 Turn off warnings as errors on gcc/darwin because the integer library currently causes some warnings.
[SVN r58394]
2009-12-15 13:16:32 +00:00
Daniel James
01630b4053 Merge unordered and hash.
Improved Codegear support in unordered.
Another warning suppression in hash.


[SVN r58223]
2009-12-07 19:26:26 +00:00
Daniel James
78eeabaeb2 Suppress another warning.
[SVN r58078]
2009-12-01 08:52:10 +00:00
Daniel James
d45d471e34 Merge hash warning fixes from trunk.
[SVN r58032]
2009-11-29 16:14:10 +00:00
Daniel James
3882189584 Try to suppress some more Visual C++ warnings.
[SVN r57976]
2009-11-27 19:43:26 +00:00
Daniel James
079f8025b3 Suppress a warning that's in the windows mobile system headers.
[SVN r57963]
2009-11-26 23:15:30 +00:00
Daniel James
b43c9fa145 Fix some hash /W4 warnings. Fixes #3648
[SVN r57839]
2009-11-21 19:40:54 +00:00
Daniel James
b0ceeca154 Turn on warnings as errors for the hash tests.
[SVN r57720]
2009-11-16 23:56:56 +00:00
Daniel James
d8bfb81914 Remove 'warnings-as-errors' flag that was breaking the build.
[SVN r57564]
2009-11-11 14:03:44 +00:00
Daniel James
9958072d2a Stricter warnings for unordered and hash.
There are still warnings in hash_complex_test.

[SVN r57537]
2009-11-10 08:15:55 +00:00
Troy D. Straszheim
99c6e89390 rm cmake from trunk. I'm not entirely sure this is necessary to satisfy the inspect script, but I'm not taking any chances, and it is easy to put back
[SVN r56942]
2009-10-17 02:07:38 +00:00
Troy D. Straszheim
84e1b951f5 rm cmake from the release branch before it goes out broken. Policy dictates that you never commit to release, you commit to trunk and merge to release.
[SVN r56941]
2009-10-17 01:10:45 +00:00
Daniel James
3ee9d7d507 Copy the unordered and hash CMake files from release.
[SVN r56704]
2009-10-10 15:09:02 +00:00
Daniel James
1d792ecb45 Merge some documentation changes and inspect fixes.
Merged revisions 55370,55729,56440,56570-56571,56603,56697-56699 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r55370 | danieljames | 2009-08-02 19:18:14 +0100 (Sun, 02 Aug 2009) | 1 line
  
  Pass through more elements in doxygen2boostbook. Refs #3309.
........
  r55729 | danieljames | 2009-08-23 11:07:25 +0100 (Sun, 23 Aug 2009) | 3 lines
  
  Add depencies on doxygen documentation to standalone documentation targets.
  
  This seems to be needed for building pdfs.
........
  r56440 | danieljames | 2009-09-27 20:11:39 +0100 (Sun, 27 Sep 2009) | 1 line
  
  Fix silly error in doxygen test file.
........
  r56570 | danieljames | 2009-10-04 11:37:36 +0100 (Sun, 04 Oct 2009) | 1 line
  
  Clean up some unordered TODOs.
........
  r56571 | danieljames | 2009-10-04 11:37:56 +0100 (Sun, 04 Oct 2009) | 1 line
  
  Detab.
........
  r56603 | danieljames | 2009-10-05 22:29:39 +0100 (Mon, 05 Oct 2009) | 1 line
  
  Various inspect fixes.
........
  r56697 | danieljames | 2009-10-10 14:00:28 +0100 (Sat, 10 Oct 2009) | 1 line
  
  Add forwarding html file for accumulators.
........
  r56698 | danieljames | 2009-10-10 14:01:14 +0100 (Sat, 10 Oct 2009) | 1 line
  
  Missing newline.
........
  r56699 | danieljames | 2009-10-10 14:01:30 +0100 (Sat, 10 Oct 2009) | 1 line
  
  Add copyright to boostbook reference xml.
........


[SVN r56702]
2009-10-10 14:53:46 +00:00
Daniel James
e75f94f71d Various inspect fixes.
[SVN r56603]
2009-10-05 21:29:39 +00:00
Troy D. Straszheim
5db98a2dda Copyrights on CMakeLists.txt to keep them from clogging up the inspect
reports.  This is essentially the same commit as r55095 on the release
branch.



[SVN r55159]
2009-07-26 00:49:56 +00:00
Troy D. Straszheim
58eab40c2a Add basic copyright/license to keep cmake out of the inspection report
[SVN r55095]
2009-07-22 21:51:01 +00:00
Daniel James
f9669b6218 Fix gcc -pedantic warning: remove extra ";".
Merged revisions 54146 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r54146 | jhunold | 2009-06-21 15:38:19 +0100 (Sun, 21 Jun 2009) | 2 lines
  
  Fix gcc -pedantic warning: remove extra ";".
........


[SVN r54826]
2009-07-09 00:11:16 +00:00
Daniel James
2b3bc8c3f4 Merge latest hash developments:
* Avoid float to int warning.
 * Work around 'using namespace' bug in Visual C++.
 * Make `<boost/functional/hash/extensions.hpp> self contained.
 * Move some of the extension implementation from the main hash header
   into the exensions header.
 * Remove BOOST_HASH_CHAR_TRAITS from `container_fwd.hpp`.
 * Other minor changes.

Merged revisions 53828,53924,54024-54025,54033-54034,54139-54145,54399 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r53828 | danieljames | 2009-06-12 19:24:47 +0100 (Fri, 12 Jun 2009) | 1 line
  
  Try to avoid float to int warning when a float function doesn't exist.
........
  r53924 | danieljames | 2009-06-15 08:37:42 +0100 (Mon, 15 Jun 2009) | 4 lines
  
  Remove hash_complex_test's dependency on Boost.Random.
  
  Only test for a few values, but that should be okay as there isn't much
  to test.
........
  r54024 | danieljames | 2009-06-17 22:22:49 +0100 (Wed, 17 Jun 2009) | 1 line
  
  Put the minimum amount of implementation in the same namespace as the 'using namespace' directives in order to avoid Visual C++ 8 bug.
........
  r54025 | danieljames | 2009-06-17 22:23:42 +0100 (Wed, 17 Jun 2009) | 1 line
  
  Try to avoid using special macro handling code.
........
  r54033 | danieljames | 2009-06-18 00:24:28 +0100 (Thu, 18 Jun 2009) | 1 line
  
  Add copyright to namespace_fail_test.cpp
........
  r54034 | danieljames | 2009-06-18 00:25:12 +0100 (Thu, 18 Jun 2009) | 1 line
  
  A couple of missing newlines.
........
  r54139 | danieljames | 2009-06-21 10:41:11 +0100 (Sun, 21 Jun 2009) | 1 line
  
  A few more comments in boost::hash.
........
  r54140 | danieljames | 2009-06-21 10:41:30 +0100 (Sun, 21 Jun 2009) | 1 line
  
  Move includes to the header which they're used in.
........
  r54141 | danieljames | 2009-06-21 10:41:46 +0100 (Sun, 21 Jun 2009) | 1 line
  
  Revert [54025] "Try to avoid using special macro handling code."
........
  r54142 | danieljames | 2009-06-21 10:42:05 +0100 (Sun, 21 Jun 2009) | 1 line
  
  Get <boost/functional/hash/extensions.hpp> to work.
........
  r54143 | danieljames | 2009-06-21 10:42:20 +0100 (Sun, 21 Jun 2009) | 1 line
  
  Move BOOST_HASH_CHAR_TRAITS from container_fwd into the hash headers, and undefine it.
........
  r54144 | danieljames | 2009-06-21 10:42:40 +0100 (Sun, 21 Jun 2009) | 1 line
  
  Move the support for hashing containers into the extension header, and improve the standard tests.
........
  r54145 | danieljames | 2009-06-21 10:51:59 +0100 (Sun, 21 Jun 2009) | 1 line
  
  I didn't mean to comment this out.
........
  r54399 | danieljames | 2009-06-27 08:39:12 +0100 (Sat, 27 Jun 2009) | 1 line
  
  Add am implementation note about the Visual C++ problems.
........


[SVN r54402]
2009-06-27 08:12:20 +00:00
Daniel James
07b565143f Add am implementation note about the Visual C++ problems.
[SVN r54399]
2009-06-27 07:39:12 +00:00
Jürgen Hunold
d8980c3f09 Fix gcc -pedantic warning: remove extra ";".
[SVN r54146]
2009-06-21 14:38:19 +00:00
Daniel James
83b052b784 I didn't mean to comment this out.
[SVN r54145]
2009-06-21 09:51:59 +00:00
Daniel James
c51bebf8a4 Move the support for hashing containers into the extension header, and improve the standard tests.
[SVN r54144]
2009-06-21 09:42:40 +00:00
Daniel James
8b98036bb8 Move BOOST_HASH_CHAR_TRAITS from container_fwd into the hash headers, and undefine it.
[SVN r54143]
2009-06-21 09:42:20 +00:00
Daniel James
4774d24966 Get <boost/functional/hash/extensions.hpp> to work.
[SVN r54142]
2009-06-21 09:42:05 +00:00
Daniel James
13f44653b5 Revert [54025] "Try to avoid using special macro handling code."
[SVN r54141]
2009-06-21 09:41:46 +00:00
Daniel James
e20c872440 Move includes to the header which they're used in.
[SVN r54140]
2009-06-21 09:41:30 +00:00
Daniel James
600740e2ae A few more comments in boost::hash.
[SVN r54139]
2009-06-21 09:41:11 +00:00
Daniel James
52a964ae91 Add copyright to namespace_fail_test.cpp
[SVN r54033]
2009-06-17 23:24:28 +00:00
Daniel James
3d79c2f1e4 Try to avoid using special macro handling code.
[SVN r54025]
2009-06-17 21:23:42 +00:00
Daniel James
3cf1a67771 Put the minimum amount of implementation in the same namespace as the 'using namespace' directives in order to avoid Visual C++ 8 bug.
[SVN r54024]
2009-06-17 21:22:49 +00:00
Daniel James
9cc8c20413 Remove hash_complex_test's dependency on Boost.Random.
Only test for a few values, but that should be okay as there isn't much
to test.

[SVN r53924]
2009-06-15 07:37:42 +00:00
Daniel James
9f4a6a966e Try to avoid float to int warning when a float function doesn't exist. Refs #3171.
[SVN r53828]
2009-06-12 18:24:47 +00:00
Daniel James
786af5df98 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
Daniel James
6a2d96428b Minor hash test changes.
Merged revisions 53522-53523 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r53522 | danieljames | 2009-06-01 07:49:45 +0100 (Mon, 01 Jun 2009) | 1 line
  
  Test the hash functions for a couple of typedefs.
........
  r53523 | danieljames | 2009-06-01 07:50:14 +0100 (Mon, 01 Jun 2009) | 2 lines
  
  Recent versions of borland haven't fixed some of their namespace bugs, so mark
  up their hash failures for all versions.
........


[SVN r53686]
2009-06-06 13:53:19 +00:00
Daniel James
15d4153c37 Test the hash functions for a couple of typedefs.
[SVN r53522]
2009-06-01 06:49:45 +00:00
Daniel James
326a338add Remove misplaced visual C++ warning pragma.
[SVN r53506]
2009-05-31 15:53:09 +00:00
Daniel James
f6e0d26ffc Fix gcc -pedantic error:extra extra ';'
Merged revisions 53203 via svnmerge from 
https://svn.boost.org/svn/boost/trunk


[SVN r53467]
2009-05-30 17:45:06 +00:00
Daniel James
e624b55a5c Automatically detect what float functions the compiler/library supports
in hash and seperate out some of the detail headers.

Merged revisions 53159-53161,53167-53169,53175,53185,53205,53247-53248,53254 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r53159 | danieljames | 2009-05-21 22:21:11 +0100 (Thu, 21 May 2009) | 1 line
  
  Move the hash limits workaround into its own file.
........
  r53160 | danieljames | 2009-05-21 22:21:44 +0100 (Thu, 21 May 2009) | 1 line
  
  Move the two different hash float implementation into their own header.
........
  r53161 | danieljames | 2009-05-21 22:22:04 +0100 (Thu, 21 May 2009) | 1 line
  
  Try to automatically detect which float functions are available.
........
  r53167 | danieljames | 2009-05-22 07:00:56 +0100 (Fri, 22 May 2009) | 1 line
  
  Fix a typo.
........
  r53168 | danieljames | 2009-05-22 07:01:19 +0100 (Fri, 22 May 2009) | 3 lines
  
  Spell out exactly which functions can be used with which types.
  
  I was hitting some ambiguity errors when the function was for the wrong type.
........
  r53169 | danieljames | 2009-05-22 07:01:35 +0100 (Fri, 22 May 2009) | 1 line
  
  Some STLport fixes for hash.
........
  r53175 | danieljames | 2009-05-22 14:35:56 +0100 (Fri, 22 May 2009) | 2 lines
  
  Rename struct to avoid using 'type::'type' which confuses some
  compilers.
........
  r53185 | danieljames | 2009-05-22 20:00:35 +0100 (Fri, 22 May 2009) | 1 line
  
  Explicitly qualify 'none' to avoid confusion with boost::none.
........
  r53205 | danieljames | 2009-05-23 16:21:38 +0100 (Sat, 23 May 2009) | 4 lines
  
  Try to deal with macros for frexpl and ldexpl.
  
  The error message for msvc-9.0~wm5~stlport5.2 suggests that frexpl and ldexpl
  are macros.
........
  r53247 | danieljames | 2009-05-25 14:45:16 +0100 (Mon, 25 May 2009) | 4 lines
  
  Check for float functions with less templates.
  
  The only template mechanism now used is full specialization, so this should
  hopefully be more portable to compilers we don't test.
........
  r53248 | danieljames | 2009-05-25 15:27:00 +0100 (Mon, 25 May 2009) | 1 line
  
  Fix a couple of clumsy errors in the last commit.
........
  r53254 | danieljames | 2009-05-25 20:44:52 +0100 (Mon, 25 May 2009) | 1 line
  
  Hash change log.
........


[SVN r53361]
2009-05-28 20:42:55 +00:00
Daniel James
b0459a20da Hash change log.
[SVN r53254]
2009-05-25 19:44:52 +00:00
Daniel James
909d0c9547 Fix a couple of clumsy errors in the last commit.
[SVN r53248]
2009-05-25 14:27:00 +00:00
Daniel James
912aed0b57 Check for float functions with less templates.
The only template mechanism now used is full specialization, so this should
hopefully be more portable to compilers we don't test.

[SVN r53247]
2009-05-25 13:45:16 +00:00
Daniel James
e5d343faea Try to deal with macros for frexpl and ldexpl.
The error message for msvc-9.0~wm5~stlport5.2 suggests that frexpl and ldexpl
are macros.

[SVN r53205]
2009-05-23 15:21:38 +00:00
Jürgen Hunold
3e320b7ae5 Fix gcc -pedantic error:extra extra ';'
[SVN r53203]
2009-05-23 13:03:25 +00:00
Daniel James
8bc6175fa0 Explicitly qualify 'none' to avoid confusion with boost::none.
[SVN r53185]
2009-05-22 19:00:35 +00:00
Daniel James
6751e9cf47 Rename struct to avoid using 'type::'type' which confuses some
compilers.

[SVN r53175]
2009-05-22 13:35:56 +00:00
Daniel James
004e4df2a2 Some STLport fixes for hash.
[SVN r53169]
2009-05-22 06:01:35 +00:00
Daniel James
411f559730 Spell out exactly which functions can be used with which types.
I was hitting some ambiguity errors when the function was for the wrong type.

[SVN r53168]
2009-05-22 06:01:19 +00:00
Daniel James
8a6aba46c7 Fix a typo.
[SVN r53167]
2009-05-22 06:00:56 +00:00
Daniel James
65b103e812 Try to automatically detect which float functions are available.
[SVN r53161]
2009-05-21 21:22:04 +00:00
Daniel James
c160428eff Move the two different hash float implementation into their own header.
[SVN r53160]
2009-05-21 21:21:44 +00:00
Daniel James
dda32a279a Move the hash limits workaround into its own file.
[SVN r53159]
2009-05-21 21:21:11 +00:00
Troy D. Straszheim
ff7008e031 undoing bad commit to functional's cmakelists
[SVN r53002]
2009-05-14 20:55:39 +00:00
Troy D. Straszheim
8fd93d38bb more cmakefile tweaks
[SVN r52999]
2009-05-14 19:58:42 +00:00
Troy D. Straszheim
bc87281ed6 sync with jamfile
[SVN r52998]
2009-05-14 18:10:23 +00:00
Daniel James
f1a8a0fde8 Add a missing entry to the changelog.
[SVN r52552]
2009-04-22 21:12:49 +00:00
Daniel James
814476afa2 Fix float support on vxWorks.
Thanks to Dustin Spicuzza. Refs #2957

[SVN r52481]
2009-04-19 09:17:18 +00:00
Daniel James
9ef99e556a 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.

[SVN r52304]
2009-04-10 19:25:32 +00:00
Daniel James
2aff9855bb 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.

[SVN r52245]
2009-04-08 05:51:31 +00:00
Daniel James
72cb0e7788 Changelog for unordered and hash.
[SVN r52084]
2009-03-31 19:43:58 +00:00
Daniel James
220c3a4e62 Use paragraphs inside purpose tags.
[SVN r51802]
2009-03-16 20:21:05 +00:00
Daniel James
b0b7f17984 Update copyright dates in hash and unordered.
[SVN r51667]
2009-03-09 20:56:23 +00:00
Daniel James
342284f4cf Remove deprecated headers.
Fixes #2412.

[SVN r51646]
2009-03-08 09:45:30 +00:00
Daniel James
fe6449fea6 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.

[SVN r51645]
2009-03-08 09:45:11 +00:00
Daniel James
a3e434ec47 Fix the hash dirname.
[SVN r51407]
2009-02-22 23:49:51 +00:00
John Maddock
7c72c09288 Add PDF generation options to fix external links to point to the web site.
Added a few more Boostbook based libs that were missed first time around.
Fixed PDF naming issues.

[SVN r51284]
2009-02-17 10:05:58 +00:00
Daniel James
45dfe7d9c5 Don't copy images for the standalone hash and unordered documentation, was only
really required before the libraries were integrated into boost.

[SVN r51263]
2009-02-15 19:32:19 +00:00
Daniel James
2560590a2b Use the new 'boost:' links for the hash, unordered and quickbook documentation.
[SVN r51262]
2009-02-15 19:32:04 +00:00
John Maddock
c984bbb5f0 Add Jamfile to build PDF versions of all the docs.
Tweaked some existing Jamfiles so that PDF build finds all the necessary image files etc.
Tweaked fo.xsl to provide more options by default, and improve formatting.

[SVN r51104]
2009-02-08 16:59:14 +00:00
Daniel James
0480bcf503 Rename parameter to avoid Visual C++ warning about clash with boost::array.
Fixes #2643

[SVN r50514]
2009-01-08 13:37:33 +00:00
56 changed files with 1881 additions and 753 deletions

View File

@@ -1,2 +0,0 @@
message(STATUS "functional/hash docs need love")

View File

@@ -3,12 +3,12 @@
# 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)
using boostbook ;
using quickbook ;
xml hash : hash.qbk ;
boostbook standalone : hash :
<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

View File

@@ -84,4 +84,65 @@
* [@https://svn.boost.org/trac/boost/ticket/2957 Ticket 2957]: Fix configuration
for vxworks.
[h2 Boost 1.40.0]
* Automatically configure the float functions using template metaprogramming
instead of trying to configure every possibility manually.
* Workaround for when STLport doesn't support long double.
[h2 Boost 1.42.0]
* Reduce the number of warnings for Visual C++ warning level 4.
* Some code formatting changes to fit lines into 80 characters.
* Rename an internal namespace.
[h2 Boost 1.43.0]
* [@https://svn.boost.org/trac/boost/ticket/3866 Ticket 3866]:
Don't foward declare containers when using gcc's parallel library,
allow user to stop forward declaration by defining the
`BOOST_DETAIL_NO_CONTAINER_FWD` macro.
* [@https://svn.boost.org/trac/boost/ticket/4038 Ticket 4038]:
Avoid hashing 0.5 and 0 to the same number.
* Stop using deprecated `BOOST_HAS_*` macros.
[h2 Boost 1.44.0]
* Add option to prevent implicit conversions when calling `hash_value` by
defining `BOOST_HASH_NO_IMPLICIT_CASTS`. When using `boost::hash`
for a type that does not have `hash_value` declared but does have
an implicit conversion to a type that does, it would use that
implicit conversion to hash it. Which can sometimes go very wrong,
e.g. using a conversion to bool and only hashing to 2 possible
values. Since fixing this is a breaking change and was only
approached quite late in the release cycle with little discussion
it's opt-in for now. This, or something like it, will become the
default in a future version.
[h2 Boost 1.46.0]
* Avoid warning due with gcc's `-Wconversion` flag.
[h2 Boost 1.50.0]
* [@http://svn.boost.org/trac/boost/ticket/6771 Ticket 6771]:
Avoid gcc's `-Wfloat-equal` warning.
* [@http://svn.boost.org/trac/boost/ticket/6806 Ticket 6806]:
Support `std::array` and `std::tuple` when available.
* Add deprecation warning to the long deprecated
`boost/functional/detail/container_fwd.hpp`.
[h2 Boost 1.51.0]
* Support the standard smart pointers.
* `hash_value` now implemented using SFINAE to avoid implicit casts to built
in types when calling it.
* Updated to use the new config macros.
[h2 Boost 1.52.0]
* Restore `enum` support, which was accidentally removed in the last version.
* New floating point hasher - will hash the binary representation on more
platforms, which should be faster.
[endsect]

View File

@@ -1,5 +1,5 @@
[library Boost.Functional/Hash
[quickbook 1.4]
[quickbook 1.5]
[authors [James, Daniel]]
[copyright 2005 2006 2007 2008 Daniel James]
[purpose A TR1 hash function object that can be extended to hash user
@@ -14,11 +14,16 @@
]
]
[def __issues__
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf
Library Extension Technical Report Issues List]]
[include:hash intro.qbk]
[include:hash tutorial.qbk]
[include:hash portability.qbk]
[include:hash disable.qbk]
[include:hash changes.qbk]
[include:hash rationale.qbk]
[xinclude ref.xml]
[include:hash links.qbk]
[include:hash thanks.qbk]

View File

@@ -18,9 +18,6 @@
[def __multi-index-short__ [@boost:/libs/multi_index/doc/index.html
Boost.MultiIndex]]
[def __bimap__ [@boost:/libs/bimap/index.html Boost.Bimap]]
[def __issues__
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf
Library Extension Technical Report Issues List]]
[def __hash-function__ [@http://en.wikipedia.org/wiki/Hash_function hash function]]
[def __hash-table__ [@http://en.wikipedia.org/wiki/Hash_table hash table]]
@@ -44,5 +41,12 @@ __issues__ (page 63), this adds support for:
* the standard containers.
* extending [classref boost::hash] for custom types.
[note
This hash function is designed to be used in containers based on
the STL and is not suitable as a general purpose hash function.
For more details see the [link hash.rationale rationale].
]
[endsect]

View File

@@ -90,16 +90,4 @@ boost namespace:
Full code for this example is at
[@boost:/libs/functional/hash/examples/portable.cpp /libs/functional/hash/examples/portable.cpp].
[h2 Other Issues]
On Visual C++ versions 6.5 and 7.0, `hash_value` isn't overloaded for built in
arrays. __boost_hash__, [funcref boost::hash_combine] and [funcref boost::hash_range] all use a workaround to
support built in arrays so this shouldn't be a problem in most cases.
On Visual C++ versions 6.5 and 7.0, function pointers aren't currently supported.
When using GCC on Solaris, `boost::hash_value(long double)` treats
`long double`s as `double`s - so the hash function doesn't take into account the
full range of values.
[endsect]

50
doc/rationale.qbk Normal file
View File

@@ -0,0 +1,50 @@
[/ Copyright 2011 Daniel James.
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ]
[section:rationale Rationale]
The rationale can be found in the original design
[footnote issue 6.18 of the __issues__ (page 63)].
[heading Quality of the hash function]
Many hash functions strive to have little correlation between the input
and output values. They attempt to uniformally distribute the output
values for very similar inputs. This hash function makes no such
attempt. In fact, for integers, the result of the hash function is often
just the input value. So similar but different input values will often
result in similar but different output values.
This means that it is not appropriate as a general hash function. For
example, a hash table may discard bits from the hash function resulting
in likely collisions, or might have poor collision resolution when hash
values are clustered together. In such cases this hash function will
preform poorly.
But the standard has no such requirement for the hash function,
it just requires that the hashes of two different values are unlikely
to collide. Containers or algorithms
designed to work with the standard hash function will have to be
implemented to work well when the hash function's output is correlated
to its input. Since they are paying that cost a higher quality hash function
would be wasteful.
For other use cases, if you do need a higher quality hash function,
then neither the standard hash function or `boost::hash` are appropriate.
There are several options
available. One is to use a second hash on the output of this hash
function, such as [@http://www.concentric.net/~ttwang/tech/inthash.htm
Thomas Wang's hash function]. This this may not work as
well as a hash algorithm tailored for the input.
For strings that are several fast, high quality hash functions
available (for example [@http://code.google.com/p/smhasher/ MurmurHash3]
and [@http://code.google.com/p/cityhash/ Google's CityHash]),
although they tend to be more machine specific.
These may also be appropriate for hashing a binary representation of
your data - providing that all equal values have an equal
representation, which is not always the case (e.g. for floating point
values).
[endsect]

View File

@@ -55,6 +55,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
is defined. The specializations are still defined, so only the specializations
required by TR1 are defined.
</para>
<para>
Forward declared in
<code>&lt;boost/functional/hash_fwd.hpp&gt;</code>
</para>
</notes>
<throws><para>
Only throws if
@@ -406,6 +410,29 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</method>
</struct-specialization>
<struct-specialization name="hash">
<template></template>
<specialization>
<template-arg>std::type_index</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>std::type_index</paramtype>
</parameter>
<returns>
<para><code>val.hash_code()</code></para>
</returns>
<throws><para>Doesn't throw</para></throws>
</method>
<notes>
<para>
Only available if it's in your standard library and Boost.Config
is aware of it.
</para>
</notes>
</struct-specialization>
<free-function-group name="Support functions (Boost extension).">
<!--
@@ -428,6 +455,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<para><functionname>hash_value</functionname> is called without
qualification, so that overloads can be found via ADL.</para>
<para>This is an extension to TR1</para>
<para>
Forward declared in
<code>&lt;boost/functional/hash_fwd.hpp&gt;</code>
</para>
</notes>
<throws>
Only throws if <functionname>hash_value</functionname>(T) throws.
@@ -476,15 +507,14 @@ for(; first != last; ++first)
return seed;
</programlisting>
</para>For the three arguments overload:
</para>
<para>For the three arguments overload:</para>
<programlisting>
for(; first != last; ++first)
{
<functionname>hash_combine</functionname>(seed, *first);
}
</programlisting>
<para>
</para>
</effects>
<notes>
<para>
@@ -493,6 +523,10 @@ for(; first != last; ++first)
container.
</para>
<para>This is an extension to TR1</para>
<para>
Forward declared in
<code>&lt;boost/functional/hash_fwd.hpp&gt;</code>
</para>
</notes>
<throws><para>
Only throws if <code><functionname>hash_value</functionname>(std::iterator_traits&lt;It&gt;::value_type)</code>
@@ -716,6 +750,30 @@ for(; first != last; ++first)
<parameter name="val"><paramtype>std::complex&lt;T&gt; const&amp;</paramtype></parameter>
</signature>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>std::type_index</paramtype></parameter>
</signature>
<signature>
<template>
<template-type-parameter name="T"/>
<template-nontype-parameter name="N">
<type>std::size_t</type>
</template-nontype-parameter>
</template>
<type>std::size_t</type>
<parameter name="val"><paramtype>std::array&lt;T, N&gt; const&amp;</paramtype></parameter>
</signature>
<signature>
<template>
<template-type-parameter name="T" pack="1"/>
</template>
<type>std::size_t</type>
<parameter name="val"><paramtype>std::tuple&lt;T...&gt;</paramtype></parameter>
</signature>
<description><para>
Generally shouldn't be called directly by users, instead they should use
<classname>boost::hash</classname>, <functionname>boost::hash_range</functionname>
@@ -781,7 +839,8 @@ for(; first != last; ++first)
<code>std::set&lt;K,&#160;C,&#160;A&gt;</code>,
<code>std::multiset&lt;K,&#160;C,&#160;A&gt;</code>,
<code>std::map&lt;K,&#160;T,&#160;C,&#160;A&gt;</code>,
<code>std::multimap&lt;K,&#160;T,&#160;C,&#160;A&gt;</code>
<code>std::multimap&lt;K,&#160;T,&#160;C,&#160;A&gt;</code>,
<code>std::array&lt;T,&#160;N&gt;</code>
</entry>
<entry><code>hash_range(val.begin(), val.end())</code></entry>
</row>
@@ -790,6 +849,14 @@ for(; first != last; ++first)
<entry><programlisting>size_t seed = 0;
<functionname>hash_combine</functionname>(seed, val.first);
<functionname>hash_combine</functionname>(seed, val.second);
return seed;</programlisting></entry>
</row>
<row>
<entry><code>std::tuple&lt;T...&gt;</code></entry>
<entry><programlisting>size_t seed = 0;
<functionname>hash_combine</functionname>(seed, get&lt;0&gt;(val));
<functionname>hash_combine</functionname>(seed, get&lt;1&gt;(val));
// ....
return seed;</programlisting></entry>
</row>
<row>
@@ -798,6 +865,12 @@ return seed;</programlisting></entry>
</entry>
<entry>When <code>T</code> is a built in type and <code>val.imag() == 0</code>, the result is equal to <code>hash_value(val.real())</code>. Otherwise an unspecified value, except that equal arguments shall yield the same result.</entry>
</row>
<row>
<entry>
<code>std::type_index</code>
</entry>
<entry><code>val.hash_code()</code></entry>
</row>
</tbody>
</tgroup>
</informaltable>

View File

@@ -110,7 +110,7 @@ And you can now use [classref boost::hash] with book:
assert(books.find(dandelion) == books.end());
The full example can be found in:
[@boost:/libs/functional/hash/examples/books.cpp /libs/functional/hash/examples/books.hpp]
[@boost:/libs/functional/hash/examples/books.hpp /libs/functional/hash/examples/books.hpp]
and
[@boost:/libs/functional/hash/examples/books.cpp /libs/functional/hash/examples/books.cpp].
@@ -198,5 +198,15 @@ To calculate the hash of an iterator range you can use [funcref boost::hash_rang
std::vector<std::string> some_strings;
std::size_t hash = ``[funcref boost::hash_range]``(some_strings.begin(), some_strings.end());
[endsect]
Note that when writing template classes, you might not want to include the main
hash header as it's quite an expensive include that brings in a lot of other
headers, so instead you can include the `<boost/functional/hash_fwd.hpp>`
header which forward declares [classref boost::hash],
[funcref boost::hash_range] and [funcref boost::hash_combine]. You'll need to
include the main header before instantiating [classref boost::hash]. When using
a container that uses [classref boost::hash] it should do that for you, so your
type will work fine with the boost hash containers. There's an example of this
in [@boost:/libs/functional/hash/examples/template.hpp template.hpp] and
[@boost:/libs/functional/hash/examples/template.cpp template.cpp].
[endsect]

View File

@@ -1,9 +0,0 @@
#-------------------------------------------------------------------------
#-- Needed include directories for the tests
boost_additional_test_dependencies(config BOOST_DEPENDS test)
#-------------------------------------------------------------------------
boost_test_run(books)
boost_test_run(point)
boost_test_run(portable)

View File

@@ -6,3 +6,4 @@
run books.cpp ;
run point.cpp ;
run portable.cpp ;
run template.cpp ;

View File

@@ -20,6 +20,7 @@ int main()
boost::hash<library::book> book_hasher;
std::size_t knife_hash_value = book_hasher(knife);
(void)knife_hash_value; // suppress unused variable warning
// If std::unordered_set was available:
//

18
examples/template.cpp Normal file
View File

@@ -0,0 +1,18 @@
// Copyright 2012 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 "template.hpp"
#include <cassert>
#include <boost/unordered_set.hpp>
int main()
{
typedef my_pair<int, float> pair;
boost::unordered_set<pair> pair_set;
pair_set.emplace(10, 0.5f);
assert(pair_set.find(pair(10, 0.5f)) != pair_set.end());
assert(pair_set.find(pair(10, 0.6f)) == pair_set.end());
}

36
examples/template.hpp Normal file
View File

@@ -0,0 +1,36 @@
// Copyright 2012 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 is an example of how to write a hash function for a template
// class.
#include <boost/functional/hash_fwd.hpp>
template <typename A, typename B>
class my_pair
{
A value1;
B value2;
public:
my_pair(A const& v1, B const& v2)
: value1(v1), value2(v2)
{}
bool operator==(my_pair const& other) const
{
return value1 == other.value1 &&
value2 == other.value2;
}
friend std::size_t hash_value(my_pair const& p)
{
std::size_t seed = 0;
boost::hash_combine(seed, p.value1);
boost::hash_combine(seed, p.value2);
return seed;
}
};

View File

@@ -1,19 +1,10 @@
// Copyright 2005-2008 Daniel James.
// Copyright 2005-2012 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)
// Forwarding header for container_fwd.hpp's new location.
// This header is deprecated, I'll be adding a warning in a future release,
// then converting it to an error and finally removing this header completely.
// This header is deprecated, I'll change the warning to an error in a future
// release, and then later remove the header completely.
#if !defined(BOOST_FUNCTIONAL_DETAIL_CONTAINER_FWD_HPP)
#define BOOST_FUNCTIONAL_DETAIL_CONTAINER_FWD_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include <boost/detail/container_fwd.hpp>
#endif
#error "boost/functional/detail/container_fwd.hpp is deprecated, use boost/detail/container_fwd.hpp instead."

View File

@@ -0,0 +1,29 @@
// Copyright 2012 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_DETAIL_CONTAINER_FWD_0X_HPP)
#define BOOST_DETAIL_CONTAINER_FWD_0X_HPP
#include <boost/detail/container_fwd.hpp>
// std::array
#if !defined(BOOST_NO_CXX11_HDR_ARRAY)
# include <array>
#endif
// std::tuple
#if !defined(BOOST_NO_CXX11_HDR_TUPLE)
# include <tuple>
#endif
// std::shared_ptr/std::unique_ptr
#if !defined(BOOST_NO_CXX11_HDR_MEMORY)
# include <memory>
#endif
#endif

View File

@@ -6,6 +6,7 @@
#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_FLOAT_FUNCTIONS_HPP)
#define BOOST_FUNCTIONAL_HASH_DETAIL_FLOAT_FUNCTIONS_HPP
#include <boost/config.hpp>
#include <boost/config/no_tr1/cmath.hpp>
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
@@ -17,146 +18,229 @@
// library implementations don't support this. On some that don't, the C99
// float functions (frexpf, frexpl, etc.) are available.
//
// Some of this is based on guess work. If I don't know any better I assume that
// the standard C++ overloaded functions are available. If they're not then this
// means that the argument is cast to a double and back, which is inefficient
// and will give pretty bad results for long doubles - so if you know better
// let me know.
// The following tries to automatically detect which are available.
// STLport:
#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
# if (defined(__GNUC__) && __GNUC__ < 3 && (defined(linux) || defined(__linux) || defined(__linux__))) || defined(__DMC__)
# define BOOST_HASH_USE_C99_FLOAT_FUNCS
# elif defined(BOOST_MSVC) && BOOST_MSVC < 1300
# define BOOST_HASH_USE_C99_FLOAT_FUNCS
# else
# define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS
# endif
namespace boost {
namespace hash_detail {
// Roguewave:
// Returned by dummy versions of the float functions.
struct not_found {
// Implicitly convertible to float and long double in order to avoid
// a compile error when the dummy float functions are used.
inline operator float() const { return 0; }
inline operator long double() const { return 0; }
};
// A type for detecting the return type of functions.
template <typename T> struct is;
template <> struct is<float> { char x[10]; };
template <> struct is<double> { char x[20]; };
template <> struct is<long double> { char x[30]; };
template <> struct is<boost::hash_detail::not_found> { char x[40]; };
// Used to convert the return type of a function to a type for sizeof.
template <typename T> is<T> float_type(T);
// call_ldexp
//
// This will get specialized for float and long double
template <typename Float> struct call_ldexp
{
typedef double float_type;
inline double operator()(double a, int b) const
{
using namespace std;
return ldexp(a, b);
}
};
// call_frexp
//
// This will get specialized for float and long double
template <typename Float> struct call_frexp
{
typedef double float_type;
inline double operator()(double a, int* b) const
{
using namespace std;
return frexp(a, b);
}
};
}
}
// A namespace for dummy functions to detect when the actual function we want
// isn't available. ldexpl, ldexpf etc. might be added tby the macros below.
//
// On borland 5.51, with roguewave 2.1.1 the standard C++ overloads aren't
// defined, but for the same version of roguewave on sunpro they are.
#elif defined(_RWSTD_VER)
# if defined(__BORLANDC__)
# define BOOST_HASH_USE_C99_FLOAT_FUNCS
# define BOOST_HASH_C99_NO_FLOAT_FUNCS
# elif defined(__DECCXX)
# define BOOST_HASH_USE_C99_FLOAT_FUNCS
# else
# define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS
# endif
// AFAICT these have to be outside of the boost namespace, as if they're in
// the boost namespace they'll always be preferable to any other function
// (since the arguments are built in types, ADL can't be used).
// libstdc++ (gcc 3.0 onwards, I think)
#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
# define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS
namespace boost_hash_detect_float_functions {
template <class Float> boost::hash_detail::not_found ldexp(Float, int);
template <class Float> boost::hash_detail::not_found frexp(Float, int*);
}
// SGI:
#elif defined(__STL_CONFIG_H)
# if defined(linux) || defined(__linux) || defined(__linux__)
# define BOOST_HASH_USE_C99_FLOAT_FUNCS
# else
# define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS
# endif
// Macros for generating specializations of call_ldexp and call_frexp.
//
// check_cpp and check_c99 check if the C++ or C99 functions are available.
//
// Then the call_* functions select an appropriate implementation.
//
// I used c99_func in a few places just to get a unique name.
//
// Important: when using 'using namespace' at namespace level, include as
// little as possible in that namespace, as Visual C++ has an odd bug which
// can cause the namespace to be imported at the global level. This seems to
// happen mainly when there's a template in the same namesapce.
// vxWorks. It has its own math library, but uses Dinkumware STL
#elif defined(__VXWORKS__)
# define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS
#define BOOST_HASH_CALL_FLOAT_FUNC(cpp_func, c99_func, type1, type2) \
namespace boost_hash_detect_float_functions { \
template <class Float> \
boost::hash_detail::not_found c99_func(Float, type2); \
} \
\
namespace boost { \
namespace hash_detail { \
namespace c99_func##_detect { \
using namespace std; \
using namespace boost_hash_detect_float_functions; \
\
struct check { \
static type1 x; \
static type2 y; \
BOOST_STATIC_CONSTANT(bool, cpp = \
sizeof(float_type(cpp_func(x,y))) \
== sizeof(is<type1>)); \
BOOST_STATIC_CONSTANT(bool, c99 = \
sizeof(float_type(c99_func(x,y))) \
== sizeof(is<type1>)); \
}; \
} \
\
template <bool x> \
struct call_c99_##c99_func : \
boost::hash_detail::call_##cpp_func<double> {}; \
\
template <> \
struct call_c99_##c99_func<true> { \
typedef type1 float_type; \
\
template <typename T> \
inline type1 operator()(type1 a, T b) const \
{ \
using namespace std; \
return c99_func(a, b); \
} \
}; \
\
template <bool x> \
struct call_cpp_##c99_func : \
call_c99_##c99_func< \
::boost::hash_detail::c99_func##_detect::check::c99 \
> {}; \
\
template <> \
struct call_cpp_##c99_func<true> { \
typedef type1 float_type; \
\
template <typename T> \
inline type1 operator()(type1 a, T b) const \
{ \
using namespace std; \
return cpp_func(a, b); \
} \
}; \
\
template <> \
struct call_##cpp_func<type1> : \
call_cpp_##c99_func< \
::boost::hash_detail::c99_func##_detect::check::cpp \
> {}; \
} \
}
// Dinkumware.
#elif (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER)
// Some versions of Visual C++ don't seem to have the C++ overloads but they
// all seem to have the c99 float overloads
# if defined(BOOST_MSVC)
# define BOOST_HASH_USE_C99_FLOAT_FUNCS
// On other platforms the C++ overloads seem to have been introduced sometime
// before 402.
# elif defined(_CPPLIB_VER) && (_CPPLIB_VER >= 402)
# define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS
# else
# define BOOST_HASH_USE_C99_FLOAT_FUNCS
# endif
#define BOOST_HASH_CALL_FLOAT_MACRO(cpp_func, c99_func, type1, type2) \
namespace boost { \
namespace hash_detail { \
\
template <> \
struct call_##cpp_func<type1> { \
typedef type1 float_type; \
inline type1 operator()(type1 x, type2 y) const { \
return c99_func(x, y); \
} \
}; \
} \
}
// Digital Mars
#elif defined(__DMC__)
# define BOOST_HASH_USE_C99_FLOAT_FUNCS
// Use overloaded float functions by default.
#if defined(ldexpf)
BOOST_HASH_CALL_FLOAT_MACRO(ldexp, ldexpf, float, int)
#else
# define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS
BOOST_HASH_CALL_FLOAT_FUNC(ldexp, ldexpf, float, int)
#endif
#if defined(ldexpl)
BOOST_HASH_CALL_FLOAT_MACRO(ldexp, ldexpl, long double, int)
#else
BOOST_HASH_CALL_FLOAT_FUNC(ldexp, ldexpl, long double, int)
#endif
#if defined(frexpf)
BOOST_HASH_CALL_FLOAT_MACRO(frexp, frexpf, float, int*)
#else
BOOST_HASH_CALL_FLOAT_FUNC(frexp, frexpf, float, int*)
#endif
#if defined(frexpl)
BOOST_HASH_CALL_FLOAT_MACRO(frexp, frexpl, long double, int*)
#else
BOOST_HASH_CALL_FLOAT_FUNC(frexp, frexpl, long double, int*)
#endif
#undef BOOST_HASH_CALL_FLOAT_MACRO
#undef BOOST_HASH_CALL_FLOAT_FUNC
namespace boost
{
namespace hash_detail
{
template <typename Float1, typename Float2>
struct select_hash_type_impl {
typedef double type;
};
inline float call_ldexp(float v, int exp)
{
using namespace std;
#if defined(BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS) || \
defined(BOOST_HASH_C99_NO_FLOAT_FUNCS)
return ldexp(v, exp);
#else
return ldexpf(v, exp);
#endif
}
template <>
struct select_hash_type_impl<float, float> {
typedef float type;
};
inline double call_ldexp(double v, int exp)
{
using namespace std;
return ldexp(v, exp);
}
template <>
struct select_hash_type_impl<long double, long double> {
typedef long double type;
};
inline long double call_ldexp(long double v, int exp)
{
using namespace std;
#if defined(BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS)
return ldexp(v, exp);
#else
return ldexpl(v, exp);
#endif
}
inline float call_frexp(float v, int* exp)
{
using namespace std;
#if defined(BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS) || \
defined(BOOST_HASH_C99_NO_FLOAT_FUNCS)
return frexp(v, exp);
#else
return frexpf(v, exp);
#endif
}
inline double call_frexp(double v, int* exp)
{
using namespace std;
return frexp(v, exp);
}
inline long double call_frexp(long double v, int* exp)
{
using namespace std;
#if defined(BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS)
return frexp(v, exp);
#else
return frexpl(v, exp);
#endif
}
// select_hash_type
//
// If there is support for a particular floating point type, use that
// otherwise use double (there's always support for double).
template <typename Float>
struct select_hash_type : select_hash_type_impl<
BOOST_DEDUCED_TYPENAME call_ldexp<Float>::float_type,
BOOST_DEDUCED_TYPENAME call_frexp<Float>::float_type
> {};
}
}
#if defined(BOOST_HASH_USE_C99_FLOAT_FUNCS)
#undef BOOST_HASH_USE_C99_FLOAT_FUNCS
#endif
#if defined(BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS)
#undef BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS
#endif
#if defined(BOOST_HASH_C99_NO_FLOAT_FUNCS)
#undef BOOST_HASH_C99_NO_FLOAT_FUNCS
#endif
#endif

View File

@@ -1,5 +1,5 @@
// Copyright 2005-2009 Daniel James.
// Copyright 2005-2012 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)
@@ -10,151 +10,176 @@
# pragma once
#endif
#include <boost/config.hpp>
#include <boost/functional/hash/detail/float_functions.hpp>
#include <boost/functional/hash/detail/limits.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/integer/static_log2.hpp>
#include <boost/cstdint.hpp>
#include <boost/assert.hpp>
#include <boost/limits.hpp>
#include <cstring>
#if defined(BOOST_MSVC)
#pragma warning(push)
#if BOOST_MSVC >= 1400
#pragma warning(disable:6294) // Ill-defined for-loop: initial condition does
// not satisfy test. Loop body not executed
// not satisfy test. Loop body not executed
#endif
#endif
#include <boost/functional/hash/detail/float_functions.hpp>
#include <boost/integer/static_log2.hpp>
#include <boost/cstdint.hpp>
#include <boost/limits.hpp>
#include <boost/assert.hpp>
// Select implementation for the current platform.
// Cygwn
#if defined(__CYGWIN__)
# if defined(__i386__) || defined(_M_IX86)
# define BOOST_HASH_USE_x86_BINARY_HASH
# endif
// Can we use fpclassify?
// STLport
#elif defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
// fpclassify aren't good enough on STLport.
#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
#define BOOST_HASH_USE_FPCLASSIFY 0
// GNU libstdc++ 3
#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
# if (defined(__USE_ISOC99) || defined(_GLIBCXX_USE_C99_MATH)) && \
!(defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__))
# define BOOST_HASH_USE_FPCLASSIFY
# define BOOST_HASH_USE_FPCLASSIFY 1
# else
# define BOOST_HASH_USE_FPCLASSIFY 0
# endif
// Dinkumware Library, on Visual C++
#elif (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER)
// Not using _fpclass because it is only available for double.
#endif
// On OpenBSD, numeric_limits is not reliable for long doubles, but
// the macros defined in <float.h> are.
#if defined(__OpenBSD__)
#include <float.h>
// Everything else
#else
# define BOOST_HASH_USE_FPCLASSIFY 0
#endif
namespace boost
{
namespace hash_detail
{
template <class T>
struct limits : std::numeric_limits<T> {};
#if defined(__OpenBSD__)
template <>
struct limits<long double>
: std::numeric_limits<long double>
{
static long double epsilon() {
return LDBL_EPSILON;
}
static long double (max)() {
return LDBL_MAX;
}
static long double (min)() {
return LDBL_MIN;
}
BOOST_STATIC_CONSTANT(int, digits = LDBL_MANT_DIG);
BOOST_STATIC_CONSTANT(int, max_exponent = LDBL_MAX_EXP);
BOOST_STATIC_CONSTANT(int, min_exponent = LDBL_MIN_EXP);
};
#endif // __OpenBSD__
inline void hash_float_combine(std::size_t& seed, std::size_t value)
{
seed ^= value + (seed<<6) + (seed>>2);
}
// A simple, non-portable hash algorithm for x86.
#if defined(BOOST_HASH_USE_x86_BINARY_HASH)
inline std::size_t float_hash_impl(float v)
////////////////////////////////////////////////////////////////////////
// Binary hash function
//
// Only used for floats with known iec559 floats, and certain values in
// numeric_limits
inline std::size_t hash_binary(char* ptr, std::size_t length)
{
boost::uint32_t* ptr = (boost::uint32_t*)&v;
std::size_t seed = *ptr;
std::size_t seed = 0;
if (length >= sizeof(std::size_t)) {
seed = *(std::size_t*) ptr;
length -= sizeof(std::size_t);
ptr += sizeof(std::size_t);
while(length >= sizeof(std::size_t)) {
hash_float_combine(seed, *(std::size_t*) ptr);
length -= sizeof(std::size_t);
ptr += sizeof(std::size_t);
}
}
if (length > 0) {
std::size_t buffer = 0;
std::memcpy(&buffer, ptr, length);
hash_float_combine(seed, buffer);
}
return seed;
}
inline std::size_t float_hash_impl(double v)
template <typename Float>
inline std::size_t float_hash_impl(Float v,
BOOST_DEDUCED_TYPENAME boost::enable_if_c<
std::numeric_limits<Float>::is_iec559 &&
std::numeric_limits<Float>::digits == 24 &&
std::numeric_limits<Float>::radix == 2 &&
std::numeric_limits<Float>::max_exponent == 128,
int>::type
)
{
boost::uint32_t* ptr = (boost::uint32_t*)&v;
std::size_t seed = *ptr++;
hash_float_combine(seed, *ptr);
return seed;
return hash_binary((char*) &v, 4);
}
inline std::size_t float_hash_impl(long double v)
template <typename Float>
inline std::size_t float_hash_impl(Float v,
BOOST_DEDUCED_TYPENAME boost::enable_if_c<
std::numeric_limits<Float>::is_iec559 &&
std::numeric_limits<Float>::digits == 53 &&
std::numeric_limits<Float>::radix == 2 &&
std::numeric_limits<Float>::max_exponent == 1024,
int>::type
)
{
boost::uint32_t* ptr = (boost::uint32_t*)&v;
std::size_t seed = *ptr++;
hash_float_combine(seed, *ptr++);
hash_float_combine(seed, *(boost::uint16_t*)ptr);
return seed;
return hash_binary((char*) &v, 8);
}
#else
template <typename Float>
inline std::size_t float_hash_impl(Float v,
BOOST_DEDUCED_TYPENAME boost::enable_if_c<
std::numeric_limits<Float>::is_iec559 &&
std::numeric_limits<Float>::digits == 64 &&
std::numeric_limits<Float>::radix == 2 &&
std::numeric_limits<Float>::max_exponent == 16384,
int>::type
)
{
return hash_binary((char*) &v, 10);
}
template <typename Float>
inline std::size_t float_hash_impl(Float v,
BOOST_DEDUCED_TYPENAME boost::enable_if_c<
std::numeric_limits<Float>::is_iec559 &&
std::numeric_limits<Float>::digits == 113 &&
std::numeric_limits<Float>::radix == 2 &&
std::numeric_limits<Float>::max_exponent == 16384,
int>::type
)
{
return hash_binary((char*) &v, 16);
}
////////////////////////////////////////////////////////////////////////
// Portable hash function
//
// Used as a fallback when the binary hash function isn't supported.
template <class T>
inline std::size_t float_hash_impl(T v)
inline std::size_t float_hash_impl2(T v)
{
boost::hash_detail::call_frexp<T> frexp;
boost::hash_detail::call_ldexp<T> ldexp;
int exp = 0;
v = boost::hash_detail::call_frexp(v, &exp);
v = frexp(v, &exp);
// A postive value is easier to hash, so combine the
// sign with the exponent.
// sign with the exponent and use the absolute value.
if(v < 0) {
v = -v;
exp += limits<T>::max_exponent -
limits<T>::min_exponent;
}
// The result of frexp is always between 0.5 and 1, so its
// top bit will always be 1. Subtract by 0.5 to remove that.
v -= T(0.5);
v = boost::hash_detail::call_ldexp(v,
limits<std::size_t>::digits + 1);
v = ldexp(v, limits<std::size_t>::digits);
std::size_t seed = static_cast<std::size_t>(v);
v -= seed;
v -= static_cast<T>(seed);
// ceiling(digits(T) * log2(radix(T))/ digits(size_t)) - 1;
std::size_t const length
= (limits<T>::digits *
boost::static_log2<limits<T>::radix>::value - 1)
boost::static_log2<limits<T>::radix>::value
+ limits<std::size_t>::digits - 1)
/ limits<std::size_t>::digits;
for(std::size_t i = 0; i != length; ++i)
{
v = boost::hash_detail::call_ldexp(v,
limits<std::size_t>::digits);
v = ldexp(v, limits<std::size_t>::digits);
std::size_t part = static_cast<std::size_t>(v);
v -= part;
v -= static_cast<T>(part);
hash_float_combine(seed, part);
}
@@ -162,12 +187,29 @@ namespace boost
return seed;
}
#endif
#if !defined(BOOST_HASH_DETAIL_TEST_WITHOUT_GENERIC)
template <class T>
inline std::size_t float_hash_impl(T v, ...)
{
typedef BOOST_DEDUCED_TYPENAME select_hash_type<T>::type type;
return float_hash_impl2(static_cast<type>(v));
}
#endif
}
}
#if BOOST_HASH_USE_FPCLASSIFY
#include <boost/config/no_tr1/cmath.hpp>
namespace boost
{
namespace hash_detail
{
template <class T>
inline std::size_t float_hash_value(T v)
{
#if defined(BOOST_HASH_USE_FPCLASSIFY)
using namespace std;
switch (fpclassify(v)) {
case FP_ZERO:
@@ -178,18 +220,47 @@ namespace boost
return (std::size_t)(-3);
case FP_NORMAL:
case FP_SUBNORMAL:
return float_hash_impl(v);
return float_hash_impl(v, 0);
default:
BOOST_ASSERT(0);
return 0;
}
#else
return v == 0 ? 0 : float_hash_impl(v);
#endif
}
}
}
#else // !BOOST_HASH_USE_FPCLASSIFY
namespace boost
{
namespace hash_detail
{
template <class T>
inline bool is_zero(T v)
{
#if !defined(__GNUC__)
return v == 0;
#else
// GCC's '-Wfloat-equal' will complain about comparing
// v to 0, but because it disables warnings for system
// headers it won't complain if you use std::equal_to to
// compare with 0. Resulting in this silliness:
return std::equal_to<T>()(v, 0);
#endif
}
template <class T>
inline std::size_t float_hash_value(T v)
{
return boost::hash_detail::is_zero(v) ? 0 : float_hash_impl(v, 0);
}
}
}
#endif // BOOST_HASH_USE_FPCLASSIFY
#undef BOOST_HASH_USE_FPCLASSIFY
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif

View File

@@ -0,0 +1,61 @@
// 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)
//
// On some platforms std::limits gives incorrect values for long double.
// This tries to work around them.
#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER)
#define BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include <boost/limits.hpp>
// On OpenBSD, numeric_limits is not reliable for long doubles, but
// the macros defined in <float.h> are and support long double when STLport
// doesn't.
#if defined(__OpenBSD__) || defined(_STLP_NO_LONG_DOUBLE)
#include <float.h>
#endif
namespace boost
{
namespace hash_detail
{
template <class T>
struct limits : std::numeric_limits<T> {};
#if defined(__OpenBSD__) || defined(_STLP_NO_LONG_DOUBLE)
template <>
struct limits<long double>
: std::numeric_limits<long double>
{
static long double epsilon() {
return LDBL_EPSILON;
}
static long double (max)() {
return LDBL_MAX;
}
static long double (min)() {
return LDBL_MIN;
}
BOOST_STATIC_CONSTANT(int, digits = LDBL_MANT_DIG);
BOOST_STATIC_CONSTANT(int, max_exponent = LDBL_MAX_EXP);
BOOST_STATIC_CONSTANT(int, min_exponent = LDBL_MIN_EXP);
#if defined(_STLP_NO_LONG_DOUBLE)
BOOST_STATIC_CONSTANT(int, radix = FLT_RADIX);
#endif
};
#endif // __OpenBSD__
}
}
#endif

View File

@@ -7,15 +7,195 @@
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
// issue 6.18.
// This implements the extensions to the standard.
// It's undocumented, so you shouldn't use it....
#if !defined(BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP)
#define BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP
#include <boost/functional/hash/hash.hpp>
#include <boost/functional/hash/detail/container_fwd_0x.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/static_assert.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
#include <boost/type_traits/is_array.hpp>
#endif
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
#include <boost/type_traits/is_const.hpp>
#endif
namespace boost
{
template <class A, class B>
std::size_t hash_value(std::pair<A, B> const&);
template <class T, class A>
std::size_t hash_value(std::vector<T, A> const&);
template <class T, class A>
std::size_t hash_value(std::list<T, A> const& v);
template <class T, class A>
std::size_t hash_value(std::deque<T, A> const& v);
template <class K, class C, class A>
std::size_t hash_value(std::set<K, C, A> const& v);
template <class K, class C, class A>
std::size_t hash_value(std::multiset<K, C, A> const& v);
template <class K, class T, class C, class A>
std::size_t hash_value(std::map<K, T, C, A> const& v);
template <class K, class T, class C, class A>
std::size_t hash_value(std::multimap<K, T, C, A> const& v);
template <class T>
std::size_t hash_value(std::complex<T> const&);
template <class A, class B>
std::size_t hash_value(std::pair<A, B> const& v)
{
std::size_t seed = 0;
boost::hash_combine(seed, v.first);
boost::hash_combine(seed, v.second);
return seed;
}
template <class T, class A>
std::size_t hash_value(std::vector<T, A> const& v)
{
return boost::hash_range(v.begin(), v.end());
}
template <class T, class A>
std::size_t hash_value(std::list<T, A> const& v)
{
return boost::hash_range(v.begin(), v.end());
}
template <class T, class A>
std::size_t hash_value(std::deque<T, A> const& v)
{
return boost::hash_range(v.begin(), v.end());
}
template <class K, class C, class A>
std::size_t hash_value(std::set<K, C, A> const& v)
{
return boost::hash_range(v.begin(), v.end());
}
template <class K, class C, class A>
std::size_t hash_value(std::multiset<K, C, A> const& v)
{
return boost::hash_range(v.begin(), v.end());
}
template <class K, class T, class C, class A>
std::size_t hash_value(std::map<K, T, C, A> const& v)
{
return boost::hash_range(v.begin(), v.end());
}
template <class K, class T, class C, class A>
std::size_t hash_value(std::multimap<K, T, C, A> const& v)
{
return boost::hash_range(v.begin(), v.end());
}
template <class T>
std::size_t hash_value(std::complex<T> const& v)
{
boost::hash<T> hasher;
std::size_t seed = hasher(v.imag());
seed ^= hasher(v.real()) + (seed<<6) + (seed>>2);
return seed;
}
#if !defined(BOOST_NO_CXX11_HDR_ARRAY)
template <class T, std::size_t N>
std::size_t hash_value(std::array<T, N> const& v)
{
return boost::hash_range(v.begin(), v.end());
}
#endif
#if !defined(BOOST_NO_CXX11_HDR_TUPLE)
namespace hash_detail {
template <std::size_t I, typename T>
inline typename boost::enable_if_c<(I == std::tuple_size<T>::value),
void>::type
hash_combine_tuple(std::size_t&, T const&)
{
}
template <std::size_t I, typename T>
inline typename boost::enable_if_c<(I < std::tuple_size<T>::value),
void>::type
hash_combine_tuple(std::size_t& seed, T const& v)
{
boost::hash_combine(seed, std::get<I>(v));
boost::hash_detail::hash_combine_tuple<I + 1>(seed, v);
}
template <typename T>
inline std::size_t hash_tuple(T const& v)
{
std::size_t seed = 0;
boost::hash_detail::hash_combine_tuple<0>(seed, v);
return seed;
}
}
#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
template <typename... T>
inline std::size_t hash_value(std::tuple<T...> const& v)
{
return boost::hash_detail::hash_tuple(v);
}
#else
inline std::size_t hash_value(std::tuple<> const& v)
{
return boost::hash_detail::hash_tuple(v);
}
# define BOOST_HASH_TUPLE_F(z, n, _) \
template< \
BOOST_PP_ENUM_PARAMS_Z(z, n, typename A) \
> \
inline std::size_t hash_value(std::tuple< \
BOOST_PP_ENUM_PARAMS_Z(z, n, A) \
> const& v) \
{ \
return boost::hash_detail::hash_tuple(v); \
}
BOOST_PP_REPEAT_FROM_TO(1, 11, BOOST_HASH_TUPLE_F, _)
# undef BOOST_HASH_TUPLE_F
#endif
#endif
#if !defined(BOOST_NO_CXX11_SMART_PTR)
template <typename T>
inline std::size_t hash_value(std::shared_ptr<T> const& x) {
return boost::hash_value(x.get());
}
template <typename T, typename Deleter>
inline std::size_t hash_value(std::unique_ptr<T, Deleter> const& x) {
return boost::hash_value(x.get());
}
#endif
//
// call_hash_impl
//
// On compilers without function template ordering, this deals with arrays.
#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
namespace hash_detail
@@ -61,6 +241,11 @@ namespace boost
}
#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
//
// boost::hash
//
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <class T> struct hash
@@ -94,7 +279,7 @@ namespace boost
// On compilers without partial specialization, boost::hash<T>
// has already been declared to deal with pointers, so just
// need to supply the non-pointer version.
// need to supply the non-pointer version of hash_impl.
namespace hash_detail
{
@@ -126,8 +311,8 @@ namespace boost
#else // Visual C++ 6.5
// There's probably a more elegant way to Visual C++ 6.5 to work
// but I don't know what it is.
// Visual C++ 6.5 has problems with nested member functions and
// applying const to const types in templates. So we get this:
template <bool IsConst>
struct hash_impl_msvc

View File

@@ -13,43 +13,89 @@
#include <boost/functional/hash/hash_fwd.hpp>
#include <functional>
#include <boost/functional/hash/detail/hash_float.hpp>
#include <boost/detail/container_fwd.hpp>
#include <string>
#include <boost/limits.hpp>
#include <boost/type_traits/is_enum.hpp>
#include <boost/utility/enable_if.hpp>
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
#include <boost/type_traits/is_pointer.hpp>
#endif
#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
#include <boost/type_traits/is_array.hpp>
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
#include <typeindex>
#endif
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
#include <boost/type_traits/is_const.hpp>
#if BOOST_WORKAROUND(__GNUC__, < 3) \
&& !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
#define BOOST_HASH_CHAR_TRAITS string_char_traits
#else
#define BOOST_HASH_CHAR_TRAITS char_traits
#endif
namespace boost
{
std::size_t hash_value(bool);
std::size_t hash_value(char);
std::size_t hash_value(unsigned char);
std::size_t hash_value(signed char);
std::size_t hash_value(short);
std::size_t hash_value(unsigned short);
std::size_t hash_value(int);
std::size_t hash_value(unsigned int);
std::size_t hash_value(long);
std::size_t hash_value(unsigned long);
namespace hash_detail
{
struct enable_hash_value { typedef std::size_t type; };
template <typename T> struct basic_numbers {};
template <typename T> struct long_numbers {};
template <typename T> struct ulong_numbers {};
template <typename T> struct float_numbers {};
template <> struct basic_numbers<bool> :
boost::hash_detail::enable_hash_value {};
template <> struct basic_numbers<char> :
boost::hash_detail::enable_hash_value {};
template <> struct basic_numbers<unsigned char> :
boost::hash_detail::enable_hash_value {};
template <> struct basic_numbers<signed char> :
boost::hash_detail::enable_hash_value {};
template <> struct basic_numbers<short> :
boost::hash_detail::enable_hash_value {};
template <> struct basic_numbers<unsigned short> :
boost::hash_detail::enable_hash_value {};
template <> struct basic_numbers<int> :
boost::hash_detail::enable_hash_value {};
template <> struct basic_numbers<unsigned int> :
boost::hash_detail::enable_hash_value {};
template <> struct basic_numbers<long> :
boost::hash_detail::enable_hash_value {};
template <> struct basic_numbers<unsigned long> :
boost::hash_detail::enable_hash_value {};
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
std::size_t hash_value(wchar_t);
template <> struct basic_numbers<wchar_t> :
boost::hash_detail::enable_hash_value {};
#endif
#if defined(BOOST_HAS_LONG_LONG)
std::size_t hash_value(boost::long_long_type);
std::size_t hash_value(boost::ulong_long_type);
#if !defined(BOOST_NO_LONG_LONG)
template <> struct long_numbers<boost::long_long_type> :
boost::hash_detail::enable_hash_value {};
template <> struct ulong_numbers<boost::ulong_long_type> :
boost::hash_detail::enable_hash_value {};
#endif
template <> struct float_numbers<float> :
boost::hash_detail::enable_hash_value {};
template <> struct float_numbers<double> :
boost::hash_detail::enable_hash_value {};
template <> struct float_numbers<long double> :
boost::hash_detail::enable_hash_value {};
}
template <typename T>
typename boost::hash_detail::basic_numbers<T>::type hash_value(T);
template <typename T>
typename boost::hash_detail::long_numbers<T>::type hash_value(T);
template <typename T>
typename boost::hash_detail::ulong_numbers<T>::type hash_value(T);
template <typename T>
typename boost::enable_if<boost::is_enum<T>, std::size_t>::type
hash_value(T);
#if !BOOST_WORKAROUND(__DMC__, <= 0x848)
template <class T> std::size_t hash_value(T* const&);
#else
@@ -64,32 +110,16 @@ namespace boost
std::size_t hash_value(T (&x)[N]);
#endif
std::size_t hash_value(float v);
std::size_t hash_value(double v);
std::size_t hash_value(long double v);
template <class Ch, class A>
std::size_t hash_value(std::basic_string<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch>, A> const&);
std::size_t hash_value(
std::basic_string<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch>, A> const&);
template <class A, class B>
std::size_t hash_value(std::pair<A, B> const&);
template <class T, class A>
std::size_t hash_value(std::vector<T, A> const&);
template <class T, class A>
std::size_t hash_value(std::list<T, A> const& v);
template <class T, class A>
std::size_t hash_value(std::deque<T, A> const& v);
template <class K, class C, class A>
std::size_t hash_value(std::set<K, C, A> const& v);
template <class K, class C, class A>
std::size_t hash_value(std::multiset<K, C, A> const& v);
template <class K, class T, class C, class A>
std::size_t hash_value(std::map<K, T, C, A> const& v);
template <class K, class T, class C, class A>
std::size_t hash_value(std::multimap<K, T, C, A> const& v);
template <typename T>
typename boost::hash_detail::float_numbers<T>::type hash_value(T);
template <class T>
std::size_t hash_value(std::complex<T> const&);
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
std::size_t hash_value(std::type_index);
#endif
// Implementation
@@ -137,74 +167,30 @@ namespace boost
}
}
inline std::size_t hash_value(bool v)
template <typename T>
typename boost::hash_detail::basic_numbers<T>::type hash_value(T v)
{
return static_cast<std::size_t>(v);
}
inline std::size_t hash_value(char v)
{
return static_cast<std::size_t>(v);
}
inline std::size_t hash_value(unsigned char v)
{
return static_cast<std::size_t>(v);
}
inline std::size_t hash_value(signed char v)
{
return static_cast<std::size_t>(v);
}
inline std::size_t hash_value(short v)
{
return static_cast<std::size_t>(v);
}
inline std::size_t hash_value(unsigned short v)
{
return static_cast<std::size_t>(v);
}
inline std::size_t hash_value(int v)
{
return static_cast<std::size_t>(v);
}
inline std::size_t hash_value(unsigned int v)
{
return static_cast<std::size_t>(v);
}
inline std::size_t hash_value(long v)
{
return static_cast<std::size_t>(v);
}
inline std::size_t hash_value(unsigned long v)
{
return static_cast<std::size_t>(v);
}
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
inline std::size_t hash_value(wchar_t v)
{
return static_cast<std::size_t>(v);
}
#endif
#if defined(BOOST_HAS_LONG_LONG)
inline std::size_t hash_value(boost::long_long_type v)
template <typename T>
typename boost::hash_detail::long_numbers<T>::type hash_value(T v)
{
return hash_detail::hash_value_signed(v);
}
inline std::size_t hash_value(boost::ulong_long_type v)
template <typename T>
typename boost::hash_detail::ulong_numbers<T>::type hash_value(T v)
{
return hash_detail::hash_value_unsigned(v);
}
#endif
template <typename T>
typename boost::enable_if<boost::is_enum<T>, std::size_t>::type
hash_value(T v)
{
return static_cast<std::size_t>(v);
}
// Implementation by Alberto Barbati and Dave Harris.
#if !BOOST_WORKAROUND(__DMC__, <= 0x848)
@@ -213,12 +199,28 @@ namespace boost
template <class T> std::size_t hash_value(T* v)
#endif
{
#if defined(__VMS) && __INITIAL_POINTER_SIZE == 64
// for some reason ptrdiff_t on OpenVMS compiler with
// 64 bit is not 64 bit !!!
std::size_t x = static_cast<std::size_t>(
reinterpret_cast<long long int>(v));
#else
std::size_t x = static_cast<std::size_t>(
reinterpret_cast<std::ptrdiff_t>(v));
#endif
return x + (x >> 3);
}
#if defined(BOOST_MSVC)
#pragma warning(push)
#if BOOST_MSVC <= 1400
#pragma warning(disable:4267) // 'argument' : conversion from 'size_t' to
// 'unsigned int', possible loss of data
// A misguided attempt to detect 64-bit
// incompatability.
#endif
#endif
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
template <class T>
inline void hash_combine(std::size_t& seed, T& v)
@@ -231,6 +233,10 @@ namespace boost
seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
template <class It>
inline std::size_t hash_range(It first, It last)
{
@@ -294,89 +300,40 @@ namespace boost
#endif
template <class Ch, class A>
inline std::size_t hash_value(std::basic_string<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch>, A> const& v)
inline std::size_t hash_value(
std::basic_string<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch>, A> const& v)
{
return hash_range(v.begin(), v.end());
}
inline std::size_t hash_value(float v)
template <typename T>
typename boost::hash_detail::float_numbers<T>::type hash_value(T v)
{
return boost::hash_detail::float_hash_value(v);
}
inline std::size_t hash_value(double v)
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
inline std::size_t hash_value(std::type_index v)
{
return boost::hash_detail::float_hash_value(v);
}
inline std::size_t hash_value(long double v)
{
return boost::hash_detail::float_hash_value(v);
}
template <class A, class B>
std::size_t hash_value(std::pair<A, B> const& v)
{
std::size_t seed = 0;
hash_combine(seed, v.first);
hash_combine(seed, v.second);
return seed;
}
template <class T, class A>
std::size_t hash_value(std::vector<T, A> const& v)
{
return hash_range(v.begin(), v.end());
}
template <class T, class A>
std::size_t hash_value(std::list<T, A> const& v)
{
return hash_range(v.begin(), v.end());
}
template <class T, class A>
std::size_t hash_value(std::deque<T, A> const& v)
{
return hash_range(v.begin(), v.end());
}
template <class K, class C, class A>
std::size_t hash_value(std::set<K, C, A> const& v)
{
return hash_range(v.begin(), v.end());
}
template <class K, class C, class A>
std::size_t hash_value(std::multiset<K, C, A> const& v)
{
return hash_range(v.begin(), v.end());
}
template <class K, class T, class C, class A>
std::size_t hash_value(std::map<K, T, C, A> const& v)
{
return hash_range(v.begin(), v.end());
}
template <class K, class T, class C, class A>
std::size_t hash_value(std::multimap<K, T, C, A> const& v)
{
return hash_range(v.begin(), v.end());
}
template <class T>
std::size_t hash_value(std::complex<T> const& v)
{
boost::hash<T> hasher;
std::size_t seed = hasher(v.imag());
seed ^= hasher(v.real()) + (seed<<6) + (seed>>2);
return seed;
return v.hash_code();
}
#endif
//
// boost::hash
//
// Define the specializations required by the standard. The general purpose
// boost::hash is defined later in extensions.hpp if
// BOOST_HASH_NO_EXTENSIONS is not defined.
// BOOST_HASH_SPECIALIZE - define a specialization for a type which is
// passed by copy.
//
// BOOST_HASH_SPECIALIZE_REF - define a specialization for a type which is
// passed by copy.
//
// These are undefined later.
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
#define BOOST_HASH_SPECIALIZE(type) \
@@ -461,10 +418,22 @@ namespace boost
BOOST_HASH_SPECIALIZE_REF(std::wstring)
#endif
#if !defined(BOOST_NO_LONG_LONG)
BOOST_HASH_SPECIALIZE(boost::long_long_type)
BOOST_HASH_SPECIALIZE(boost::ulong_long_type)
#endif
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
BOOST_HASH_SPECIALIZE(std::type_index)
#endif
#undef BOOST_HASH_SPECIALIZE
#undef BOOST_HASH_SPECIALIZE_REF
// Specializing boost::hash for pointers.
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <class T>
struct hash<T*>
: public std::unary_function<T*, std::size_t>
@@ -481,7 +450,15 @@ namespace boost
#endif
}
};
#else
// For compilers without partial specialization, we define a
// boost::hash for all remaining types. But hash_impl is only defined
// for pointers in 'extensions.hpp' - so when BOOST_HASH_NO_EXTENSIONS
// is defined there will still be a compile error for types not supported
// in the standard.
namespace hash_detail
{
template <bool IsPointer>
@@ -514,9 +491,12 @@ namespace boost
::BOOST_NESTED_TEMPLATE inner<T>
{
};
#endif
}
#undef BOOST_HASH_CHAR_TRAITS
#endif // BOOST_FUNCTIONAL_HASH_HASH_HPP
// Include this outside of the include guards in case the file is included

View File

@@ -1,51 +0,0 @@
#project hash-tests
# : requirements
# <toolset>gcc:<define>_GLIBCXX_DEBUG
# ;
if (GCC)
ADD_DEFINITIONS(-D_GLIBCXX_DEBUG)
endif(GCC)
# [ run .cpp : : : <test-info>always_show_run_output ]
#-------------------------------------------------------------------------
#-- Needed include directories for the tests
boost_additional_test_dependencies(functional BOOST_DEPENDS test)
#-------------------------------------------------------------------------
SET(tests
hash_float_test
hash_fwd_test_1
hash_fwd_test_2
hash_number_test
hash_pointer_test
hash_function_pointer_test
hash_string_test
hash_range_test
hash_custom_test
hash_global_namespace_test
hash_friend_test
hash_built_in_array_test
hash_value_array_test
hash_vector_test
hash_list_test
hash_deque_test
hash_set_test
hash_map_test
container_fwd_test
hash_no_ext_macro_1
hash_no_ext_macro_2
)
boost_test_run(link_test link_test.cpp link_test_2.cpp)
boost_test_run(link_ext_test link_ext_test.cpp link_no_ext_test.cpp)
foreach(test ${tests})
boost_test_run(${test})
endforeach(test ${tests})
boost_test_compile_fail(hash_no_ext_fail_test)
# build-project ../examples ;

View File

@@ -1,5 +1,5 @@
# Copyright 2005-2008 Daniel James.
# Copyright 2005-2012 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)
@@ -7,9 +7,14 @@ import testing ;
project hash-tests
: requirements
<toolset>gcc:<define>_GLIBCXX_DEBUG
<toolset>gcc:<cxxflags>-Wsign-promo
#<toolset>gcc:<cxxflags>-Wextra
<warnings>all
<toolset>intel:<warnings>on
<toolset>intel:<cxxflags>-strict-ansi
<toolset>gcc:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wconversion -Wfloat-equal -Wshadow"
<toolset>darwin:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wconversion -Wfloat-equal -Wshadow"
<toolset>msvc:<warnings-as-errors>on
#<toolset>gcc:<warnings-as-errors>on
#<toolset>darwin:<warnings-as-errors>on
;
test-suite functional/hash
@@ -17,10 +22,11 @@ test-suite functional/hash
[ run hash_fwd_test_1.cpp ]
[ run hash_fwd_test_2.cpp ]
[ run hash_number_test.cpp ]
[ run hash_enum_test.cpp ]
[ run hash_pointer_test.cpp ]
[ run hash_function_pointer_test.cpp ]
[ run hash_float_test.cpp : : : <test-info>always_show_run_output ]
[ run hash_long_double_test.cpp : : : <test-info>always_show_run_output ]
[ run hash_float_test.cpp ]
[ run hash_long_double_test.cpp ]
[ run hash_string_test.cpp ]
[ run hash_range_test.cpp ]
[ run hash_custom_test.cpp ]
@@ -34,12 +40,43 @@ test-suite functional/hash
[ run hash_set_test.cpp ]
[ run hash_map_test.cpp ]
[ run hash_complex_test.cpp ]
[ run hash_type_index_test.cpp ]
[ run hash_std_array_test.cpp ]
[ run hash_std_tuple_test.cpp ]
[ run hash_std_smart_ptr_test.cpp ]
[ run link_test.cpp link_test_2.cpp ]
[ run link_ext_test.cpp link_no_ext_test.cpp ]
[ run container_fwd_test.cpp ]
[ run extensions_hpp_test.cpp ]
[ compile-fail hash_no_ext_fail_test.cpp ]
[ compile-fail namespace_fail_test.cpp ]
[ run implicit_test.cpp ]
[ run hash_no_ext_macro_1.cpp ]
[ run hash_no_ext_macro_2.cpp ]
[ compile-fail deprecated_container_fwd.cpp ]
;
test-suite functional/hash_no_ext
:
[ run hash_number_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_number_test ]
[ run hash_pointer_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_pointer_test ]
[ run hash_function_pointer_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_function_pointer_test ]
[ run hash_float_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_float_test ]
[ run hash_long_double_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_long_double_test ]
[ run hash_string_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_string_test ]
[ run link_test.cpp link_test_2.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_link_test ]
;
# Tests to see if the floating point hash is using the binary hash.
# Not run normally because on some platforms these should fail.
test-suite functional/hash_no_generic_float
:
[ run hash_float_test.cpp
: : : <define>BOOST_HASH_DETAIL_TEST_WITHOUT_GENERIC
: hash_float_test_no_generic ]
[ run hash_long_double_test.cpp
: : : <define>BOOST_HASH_DETAIL_TEST_WITHOUT_GENERIC
: hash_long_double_test_no_generic ]
;
explicit functional/hash_no_generic_float ;
build-project ../examples ;

View File

@@ -5,10 +5,17 @@
#if defined(TEST_STD)
# define TEST_STD_INCLUDES
# define HASH_NAMESPACE std::tr1
# define HASH_NAMESPACE std
#else
# define HASH_NAMESPACE boost
# if !defined(BOOST_HASH_NO_EXTENSIONS)
# define TEST_EXTENSIONS
# endif
#endif
#if defined(_WIN32_WCE)
// The standard windows mobile headers trigger this warning so I disable it
// before doing anything else.
#pragma warning(disable:4201) // nonstandard extension used :
// nameless struct/union
#endif

View File

@@ -1,109 +0,0 @@
// 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)
#include <boost/functional/detail/container_fwd.hpp>
#if BOOST_WORKAROUND(__GNUC__, < 3) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
template <class charT, class Allocator>
static void test(std::basic_string<charT, std::string_char_traits<charT>, Allocator> const&)
{
}
#else
template <class charT, class Allocator>
static void test(std::basic_string<charT, std::char_traits<charT>, Allocator> const&)
{
}
#endif
template <class T, class Allocator>
static void test(std::deque<T, Allocator> const&)
{
}
template <class T, class Allocator>
static void test(std::list<T, Allocator> const&)
{
}
template <class T, class Allocator>
static void test(std::vector<T, Allocator> const&)
{
}
template <class Key, class T, class Compare, class Allocator>
static void test(std::map<Key, T, Compare, Allocator> const&)
{
}
template <class Key, class T, class Compare, class Allocator>
static void test(std::multimap<Key, T, Compare, Allocator> const&)
{
}
template <class Key, class Compare, class Allocator>
static void test(std::set<Key, Compare, Allocator> const&)
{
}
template <class Key, class Compare, class Allocator>
static void test(std::multiset<Key, Compare, Allocator> const&)
{
}
template <std::size_t N>
static void test(std::bitset<N> const&)
{
}
template <class T>
static void test(std::complex<T> const&)
{
}
template <class X, class Y>
static void test(std::pair<X, Y> const&)
{
}
#include <deque>
#include <list>
#include <vector>
#include <map>
#include <set>
#include <bitset>
#include <string>
#include <complex>
#include <utility>
int main()
{
std::deque<int> x1;
std::list<std::string> x2;
std::vector<float> x3;
std::vector<bool> x4;
std::map<int, int> x5;
std::multimap<float, int*> x6;
std::set<std::string> x7;
std::multiset<std::vector<int> > x8;
std::bitset<10> x9;
std::string x10;
std::complex<double> x11;
std::pair<std::list<int>, char***> x12;
test(x1);
test(x2);
test(x3);
test(x4);
test(x5);
test(x6);
test(x7);
test(x8);
test(x9);
test(x10);
test(x11);
test(x12);
return 0;
}

View File

@@ -0,0 +1,6 @@
// Copyright 2012 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/functional/detail/container_fwd.hpp>

View File

@@ -0,0 +1,19 @@
// Copyright 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)
// Check that boost/functional/hash/extensions.hpp works okay.
//
// It probably should be in boost/functional/hash/detail, but since it isn't it
// should work.
#include "./config.hpp"
#include <boost/functional/hash/extensions.hpp>
int main() {
int x[2] = { 2, 3 };
boost::hash<int[2]> hf;
hf(x);
}

View File

@@ -5,37 +5,44 @@
#include "./config.hpp"
#ifdef TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/functional/hash.hpp>
# endif
#if !defined(TEST_EXTENSIONS)
int main() {}
#else
#ifdef TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/functional/hash.hpp>
#endif
#include <boost/detail/lightweight_test.hpp>
#ifdef TEST_EXTENSIONS
#if defined(BOOST_MSVC)
#pragma warning(disable:4244) // conversion from 'unsigned long' to
// 'unsigned short', possible loss of data
#pragma warning(disable:4245) // conversion from 'int' to
// 'const unsigned short',
// signed/unsigned mismatch
#pragma warning(disable:4305) // truncation from 'double' to
// 'const std::complex<float>::_Ty'
#pragma warning(disable:4309) // truncation of constant value
#pragma warning(disable:4512) // assignment operator could not be generated
#if BOOST_MSVC < 1400
#pragma warning(disable:4267) // conversion from 'size_t' to 'unsigned int',
// possible loss of data
#endif
#endif
#if defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
#include <complex>
#include <sstream>
#include <boost/limits.hpp>
#if defined(BOOST_MSVC)
#pragma warning(push)
#pragma warning(disable:4244) // conversion from 'unsigned long' to 'unsigned short', possible loss of data
#pragma warning(disable:4512) // assignment operator could not be generated
#endif
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int.hpp>
#include <boost/random/uniform_real.hpp>
#include <boost/random/variate_generator.hpp>
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
template <class T>
void generic_complex_tests(std::complex<T> v)
{
@@ -61,48 +68,43 @@ void generic_complex_tests(std::complex<T> v)
template <class Float>
void complex_float_tests(Float*)
{
boost::mt19937 rng;
boost::uniform_real<Float> uniform;
boost::variate_generator<boost::mt19937&, boost::uniform_real<Float> >
uniform_generator(rng, uniform);
for(int i = 0; i < 100; ++i)
{
std::complex<Float> v(uniform_generator(), uniform_generator());
generic_complex_tests(v);
}
typedef std::complex<Float> complex;
generic_complex_tests(complex(0,0));
generic_complex_tests(complex(0.5,0));
generic_complex_tests(complex(25,0));
generic_complex_tests(complex(25,0));
generic_complex_tests(complex(static_cast<Float>(-67.5324535),static_cast<Float>(56.23578678)));
}
template <class Integer>
void complex_integral_tests(Integer*)
{
boost::mt19937 rng;
boost::uniform_int<Integer> uniform(
(std::numeric_limits<Integer>::min)(),
(std::numeric_limits<Integer>::max)());
boost::variate_generator<boost::mt19937&, boost::uniform_int<Integer> >
uniform_generator(rng, uniform);
for(int i = 0; i < 100; ++i)
{
std::complex<Integer>v(uniform_generator(), uniform_generator());
generic_complex_tests(v);
}
typedef std::complex<Integer> complex;
generic_complex_tests(complex(0,0));
generic_complex_tests(complex(15342,124));
generic_complex_tests(complex(25,54356));
generic_complex_tests(complex(5325,2346));
generic_complex_tests(complex(-243897,-49923874));
generic_complex_tests(complex(-543,763));
}
int main()
{
// I've comments out the short and unsigned short tests
// as they cause warnings and don't really test
// anything that the other tests already deal with.
complex_float_tests((float*) 0);
complex_float_tests((double*) 0);
complex_float_tests((long double*) 0);
complex_integral_tests((short*) 0);
//complex_integral_tests((short*) 0);
complex_integral_tests((int*) 0);
complex_integral_tests((long*) 0);
complex_integral_tests((unsigned short*) 0);
//complex_integral_tests((unsigned short*) 0);
complex_integral_tests((unsigned int*) 0);
complex_integral_tests((unsigned long*) 0);
return boost::report_errors();
}
#endif
#endif // TEST_EXTENSIONS

View File

@@ -3,6 +3,7 @@
// 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 "./config.hpp"
#include <boost/config.hpp>
#include <cstddef>
@@ -83,8 +84,8 @@ void custom_tests()
HASH_NAMESPACE::hash_combine(seed2, 250u);
HASH_NAMESPACE::hash_combine(seed2, 350u);
BOOST_TEST(seed ==
HASH_NAMESPACE::hash_range(custom_vector.begin(), custom_vector.end()));
BOOST_TEST(seed == HASH_NAMESPACE::hash_range(
custom_vector.begin(), custom_vector.end()));
BOOST_TEST(seed == seed2);
}

63
test/hash_enum_test.cpp Normal file
View File

@@ -0,0 +1,63 @@
// Copyright 2012 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 "./config.hpp"
#ifdef TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/functional/hash.hpp>
#endif
#include <boost/detail/lightweight_test.hpp>
#include "./compile_time.hpp"
namespace test {
enum enum_override { enum_override1, enum_override2 };
std::size_t hash_value(enum_override) { return 896532; }
enum enum1 { enum1a };
enum enum2 { enum2a, enum2b };
enum enum3 { enum3a = 574, enum3b };
enum enum4 { enum4a = -12574, enum4b };
}
int main() {
compile_time_tests((test::enum1*) 0);
compile_time_tests((test::enum2*) 0);
compile_time_tests((test::enum3*) 0);
compile_time_tests((test::enum4*) 0);
compile_time_tests((test::enum_override*) 0);
HASH_NAMESPACE::hash<test::enum1> hash1;
HASH_NAMESPACE::hash<test::enum2> hash2;
HASH_NAMESPACE::hash<test::enum3> hash3;
HASH_NAMESPACE::hash<test::enum4> hash4;
BOOST_TEST(hash1(test::enum1a) == hash1(test::enum1a));
BOOST_TEST(hash2(test::enum2a) == hash2(test::enum2a));
BOOST_TEST(hash2(test::enum2a) != hash2(test::enum2b));
BOOST_TEST(hash2(test::enum2b) == hash2(test::enum2b));
BOOST_TEST(hash3(test::enum3a) == hash3(test::enum3a));
BOOST_TEST(hash3(test::enum3a) != hash3(test::enum3b));
BOOST_TEST(hash3(test::enum3b) == hash3(test::enum3b));
BOOST_TEST(hash4(test::enum4a) == hash4(test::enum4a));
BOOST_TEST(hash4(test::enum4a) != hash4(test::enum4b));
BOOST_TEST(hash4(test::enum4b) == hash4(test::enum4b));
HASH_NAMESPACE::hash<test::enum_override> hash_override;
BOOST_TEST(hash_override(test::enum_override1) ==
hash_override(test::enum_override1));
BOOST_TEST(hash_override(test::enum_override1) ==
hash_override(test::enum_override2));
BOOST_TEST(hash_override(test::enum_override1) ==
hash_override(test::enum_override1));
return boost::report_errors();
}

View File

@@ -14,28 +14,60 @@
#include <boost/detail/lightweight_test.hpp>
#include <cmath>
#include <boost/limits.hpp>
#include <boost/functional/hash/detail/limits.hpp>
#include <boost/functional/hash/detail/float_functions.hpp>
#include <boost/detail/workaround.hpp>
#include <iostream>
#if defined(BOOST_MSVC)
#pragma warning(push)
#pragma warning(disable:4127) // conditional expression is constant
#pragma warning(disable:4127) // conditional expression is constant
#pragma warning(disable:4723) // conditional expression is constant
#if BOOST_MSVC < 1400
#pragma warning(disable:4267) // conversion from 'size_t' to 'unsigned int',
// possible loss of data
#endif
#endif
#if defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
char const* float_type(float*) { return "float"; }
char const* float_type(double*) { return "double"; }
char const* float_type(long double*) { return "long double"; }
template <class T>
void float_tests(char const* name, T* = 0)
{
std::cerr<<"\n"
<<"Testing " BOOST_STRINGIZE(HASH_NAMESPACE) "::hash<"<<name<<">\n"
<<"\n"
<<"boost::hash_detail::limits<T>::digits = "
<<boost::hash_detail::limits<T>::digits<<"\n"
<<"boost::hash_detail::limits<int>::digits = "
<<boost::hash_detail::limits<int>::digits<<"\n"
<<"boost::hash_detail::limits<std::size_t>::digits = "
<<boost::hash_detail::limits<std::size_t>::digits<<"\n"
<<"\n"
std::cerr
<< "\n"
<< "Testing " BOOST_STRINGIZE(HASH_NAMESPACE) "::hash<"
<< name
<< ">\n"
<< "\n"
<< "boost::hash_detail::limits<T>::digits = "
<< boost::hash_detail::limits<T>::digits<< "\n"
<< "boost::hash_detail::limits<int>::digits = "
<< boost::hash_detail::limits<int>::digits<< "\n"
<< "boost::hash_detail::limits<std::size_t>::digits = "
<< boost::hash_detail::limits<std::size_t>::digits
<< "\n"
<< "\n"
<< "boost::hash_detail::call_ldexp<T>::float_type = "
<< float_type(static_cast<BOOST_DEDUCED_TYPENAME
boost::hash_detail::call_ldexp<T>::float_type*>(0))
<< "\n"
<< "boost::hash_detail::call_frexp<T>::float_type = "
<< float_type(static_cast<BOOST_DEDUCED_TYPENAME
boost::hash_detail::call_frexp<T>::float_type*>(0))
<< "\n"
<< "boost::hash_detail::select_hash_type<T>::type = "
<< float_type(static_cast<BOOST_DEDUCED_TYPENAME
boost::hash_detail::select_hash_type<T>::type*>(0))
<< "\n"
<< "\n"
;
HASH_NAMESPACE::hash<T> x1;
@@ -46,14 +78,23 @@ void float_tests(char const* name, T* = 0)
BOOST_TEST(zero == minus_zero);
BOOST_TEST(x1(zero) == x1(minus_zero));
#if defined(TEST_EXTENSIONS)
BOOST_TEST(x1(zero) == HASH_NAMESPACE::hash_value(zero));
BOOST_TEST(x1(minus_zero) == HASH_NAMESPACE::hash_value(minus_zero));
#endif
BOOST_TEST(x1(zero) != x1(0.5));
BOOST_TEST(x1(minus_zero) != x1(0.5));
BOOST_TEST(x1(0.5) != x1(-0.5));
BOOST_TEST(x1(1) != x1(-1));
using namespace std;
// Doing anything with infinity causes borland to crash.
#if defined(__BORLANDC__)
std::cerr<<"Not running infinity checks on Borland, as it causes it to crash.\n";
std::cerr
<< "Not running infinity checks on Borland, as it causes it to crash."
"\n";
#else
if(boost::hash_detail::limits<T>::has_infinity) {
T infinity = -log(zero);
@@ -65,9 +106,11 @@ void float_tests(char const* name, T* = 0)
T minus_infinity2 = (T) -1. / zero;
T minus_infinity3 = (T) 1. / minus_zero;
#if defined(TEST_EXTENSIONS)
BOOST_TEST(x1(infinity) == HASH_NAMESPACE::hash_value(infinity));
BOOST_TEST(x1(minus_infinity)
== HASH_NAMESPACE::hash_value(minus_infinity));
#endif
if(infinity == infinity2)
BOOST_TEST(x1(infinity) == x1(infinity2));
@@ -90,19 +133,40 @@ void float_tests(char const* name, T* = 0)
// This should really be 'has_denorm == denorm_present' but some
// compilers don't have 'denorm_present'. See also a later use.
if(boost::hash_detail::limits<T>::has_denorm) {
if(x1(boost::hash_detail::limits<T>::denorm_min()) == x1(infinity)) {
std::cerr<<"x1(denorm_min) == x1(infinity) == "<<x1(infinity)<<"\n";
if(x1(boost::hash_detail::limits<T>::denorm_min()) == x1(infinity))
{
std::cerr
<< "x1(denorm_min) == x1(infinity) == "
<< x1(infinity)
<< "\n";
}
if(x1(boost::hash_detail::limits<T>::denorm_min()) == x1(minus_infinity)) {
std::cerr<<"x1(denorm_min) == x1(-infinity) == "<<x1(minus_infinity)<<"\n";
if(x1(boost::hash_detail::limits<T>::denorm_min()) ==
x1(minus_infinity))
{
std::cerr
<< "x1(denorm_min) == x1(-infinity) == "
<< x1(minus_infinity)
<< "\n";
}
}
if(boost::hash_detail::limits<T>::has_quiet_NaN) {
if(x1(boost::hash_detail::limits<T>::quiet_NaN()) == x1(infinity)) {
std::cerr<<"x1(quiet_NaN) == x1(infinity) == "<<x1(infinity)<<"\n";
if(x1(boost::hash_detail::limits<T>::quiet_NaN()) == x1(infinity))
{
std::cerr
<< "x1(quiet_NaN) == x1(infinity) == "
<< x1(infinity)
<< "\n";
}
if(x1(boost::hash_detail::limits<T>::quiet_NaN()) == x1(minus_infinity)) {
std::cerr<<"x1(quiet_NaN) == x1(-infinity) == "<<x1(minus_infinity)<<"\n";
if(x1(boost::hash_detail::limits<T>::quiet_NaN()) ==
x1(minus_infinity))
{
std::cerr
<< "x1(quiet_NaN) == x1(-infinity) == "
<< x1(minus_infinity)
<< "\n";
}
}
}
@@ -112,13 +176,31 @@ void float_tests(char const* name, T* = 0)
T half_max = max / 2;
T quarter_max = max / 4;
T three_quarter_max = max - quarter_max;
// Check the limits::max is in range.
BOOST_TEST(max != half_max);
BOOST_TEST(max != quarter_max);
BOOST_TEST(max != three_quarter_max);
BOOST_TEST(half_max != quarter_max);
BOOST_TEST(half_max != three_quarter_max);
BOOST_TEST(quarter_max != three_quarter_max);
BOOST_TEST(max != -max);
BOOST_TEST(half_max != -half_max);
BOOST_TEST(quarter_max != -quarter_max);
BOOST_TEST(three_quarter_max != -three_quarter_max);
#if defined(TEST_EXTENSIONS)
BOOST_TEST(x1(max) == HASH_NAMESPACE::hash_value(max));
BOOST_TEST(x1(half_max) == HASH_NAMESPACE::hash_value(half_max));
BOOST_TEST(x1(quarter_max) == HASH_NAMESPACE::hash_value(quarter_max));
BOOST_TEST(x1(three_quarter_max) == HASH_NAMESPACE::hash_value(three_quarter_max));
BOOST_TEST(x1(three_quarter_max) ==
HASH_NAMESPACE::hash_value(three_quarter_max));
#endif
// The '!=' tests could legitimately fail, but with my hash it indicates a bug.
// The '!=' tests could legitimately fail, but with my hash it indicates a
// bug.
BOOST_TEST(x1(max) == x1(max));
BOOST_TEST(x1(max) != x1(quarter_max));
BOOST_TEST(x1(max) != x1(half_max));
@@ -130,6 +212,12 @@ void float_tests(char const* name, T* = 0)
BOOST_TEST(x1(half_max) != x1(three_quarter_max));
BOOST_TEST(x1(three_quarter_max) == x1(three_quarter_max));
BOOST_TEST(x1(max) != x1(-max));
BOOST_TEST(x1(half_max) != x1(-half_max));
BOOST_TEST(x1(quarter_max) != x1(-quarter_max));
BOOST_TEST(x1(three_quarter_max) != x1(-three_quarter_max));
// Intel with gcc stdlib sometimes segfaults on calls to asin and acos.
#if !((defined(__INTEL_COMPILER) || defined(__ICL) || \
defined(__ICC) || defined(__ECC)) && \
@@ -138,12 +226,19 @@ void float_tests(char const* name, T* = 0)
T v2 = acos((T) 0);
if(v1 == v2)
BOOST_TEST(x1(v1) == x1(v2));
#if defined(TEST_EXTENSIONS)
BOOST_TEST(x1(v1) == HASH_NAMESPACE::hash_value(v1));
BOOST_TEST(x1(v2) == HASH_NAMESPACE::hash_value(v2));
#endif
#endif
#if defined(TEST_EXTENSIONS)
BOOST_TEST(x1(boost::hash_detail::limits<T>::epsilon()) ==
HASH_NAMESPACE::hash_value(boost::hash_detail::limits<T>::epsilon()));
HASH_NAMESPACE::hash_value(
boost::hash_detail::limits<T>::epsilon()));
#endif
BOOST_TEST(boost::hash_detail::limits<T>::epsilon() != (T) 0);
if(x1(boost::hash_detail::limits<T>::epsilon()) == x1((T) 0))
@@ -174,31 +269,37 @@ void float_tests(char const* name, T* = 0)
if(x1(boost::hash_detail::limits<T>::denorm_min()) == x1(zero)) {
std::cerr<<"x1(denorm_min) == x1(zero) == "<<x1(zero)<<"\n";
}
#if !BOOST_WORKAROUND(__DECCXX_VER,<70190006)
#if !BOOST_WORKAROUND(__DECCXX_VER,<70190006) && defined(TEST_EXTENSIONS)
// The Tru64/CXX standard library prior to 7.1 contains a bug in the
// specialization of boost::hash_detail::limits::denorm_min() for long
// doubles which causes this test to fail.
if(x1(boost::hash_detail::limits<T>::denorm_min()) !=
HASH_NAMESPACE::hash_value(boost::hash_detail::limits<T>::denorm_min()))
HASH_NAMESPACE::hash_value(
boost::hash_detail::limits<T>::denorm_min()))
{
std::cerr<<"x1(boost::hash_detail::limits<T>::denorm_min()) = "
<< x1(boost::hash_detail::limits<T>::denorm_min())
<< "\nhash_value(boost::hash_detail::limits<T>::denorm_min()) = "
<< HASH_NAMESPACE::hash_value(
std::cerr
<< "x1(boost::hash_detail::limits<T>::denorm_min()) = "
<< x1(boost::hash_detail::limits<T>::denorm_min())
<< "\nhash_value(boost::hash_detail::limits<T>::denorm_min())"
" = "
<< HASH_NAMESPACE::hash_value(
boost::hash_detail::limits<T>::denorm_min())
<< "\nx1(0) = "<<x1(0)<<"\n";
<< "\nx1(0) = "
<< x1(0)
<< "\n";
}
#endif
}
// NaN also causes borland to crash.
#if !defined(__BORLANDC__)
#if !defined(__BORLANDC__) && defined(TEST_EXTENSIONS)
if(boost::hash_detail::limits<T>::has_quiet_NaN) {
if(x1(boost::hash_detail::limits<T>::quiet_NaN()) == x1(1.0)) {
std::cerr<<"x1(quiet_NaN) == x1(1.0) == "<<x1(1.0)<<"\n";
}
BOOST_TEST(x1(boost::hash_detail::limits<T>::quiet_NaN()) ==
HASH_NAMESPACE::hash_value(boost::hash_detail::limits<T>::quiet_NaN()));
HASH_NAMESPACE::hash_value(
boost::hash_detail::limits<T>::quiet_NaN()));
}
#endif
}

View File

@@ -3,6 +3,8 @@
// 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 "./config.hpp"
#include <boost/config.hpp>
#include <cstddef>
@@ -85,8 +87,8 @@ void custom_tests()
HASH_NAMESPACE::hash_combine(seed2, 250u);
HASH_NAMESPACE::hash_combine(seed2, 350u);
BOOST_TEST(seed ==
HASH_NAMESPACE::hash_range(custom_vector.begin(), custom_vector.end()));
BOOST_TEST(seed == HASH_NAMESPACE::hash_range(
custom_vector.begin(), custom_vector.end()));
BOOST_TEST(seed == seed2);
}

View File

@@ -12,11 +12,6 @@
#endif
#include <boost/detail/lightweight_test.hpp>
#include <boost/limits.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include "./compile_time.hpp"
void void_func1() { static int x = 1; ++x; }

View File

@@ -60,7 +60,8 @@ namespace test {
template <class T>
std::size_t hash_value(test_type3<T> const& x)
{
std::size_t seed = HASH_NAMESPACE::hash_range(x.values.begin(), x.values.end());
std::size_t seed =
HASH_NAMESPACE::hash_range(x.values.begin(), x.values.end());
HASH_NAMESPACE::hash_range(seed, x.values.begin(), x.values.end());
return seed;
}
@@ -91,7 +92,8 @@ namespace boost
template <class T>
std::size_t hash_value(test::test_type3<T> const& x)
{
std::size_t seed = HASH_NAMESPACE::hash_range(x.values.begin(), x.values.end());
std::size_t seed =
HASH_NAMESPACE::hash_range(x.values.begin(), x.values.end());
HASH_NAMESPACE::hash_range(seed, x.values.begin(), x.values.end());
return seed;
}

View File

@@ -5,6 +5,8 @@
// This checks that template code implemented using hash_fwd will work.
#include "./config.hpp"
#include "./hash_fwd_test.hpp"
#include <boost/detail/lightweight_test.hpp>
@@ -66,10 +68,12 @@ void fwd_test3()
test::test_type3<int> x(values1.begin(), values1.end());
test::test_type3<std::string> y(values2.begin(), values2.end());
std::size_t seed1 = HASH_NAMESPACE::hash_range(values1.begin(), values1.end());
std::size_t seed1 =
HASH_NAMESPACE::hash_range(values1.begin(), values1.end());
HASH_NAMESPACE::hash_range(seed1, values1.begin(), values1.end());
std::size_t seed2 = HASH_NAMESPACE::hash_range(values2.begin(), values2.end());
std::size_t seed2 =
HASH_NAMESPACE::hash_range(values2.begin(), values2.end());
HASH_NAMESPACE::hash_range(seed2, values2.begin(), values2.end());
HASH_NAMESPACE::hash<test::test_type3<int> > hasher_test_int;
@@ -90,4 +94,3 @@ int main()
#endif
return boost::report_errors();
}

View File

@@ -6,8 +6,15 @@
// This test just makes sure a header which uses hash_fwd can compile without
// the main hash headers.
#include "./hash_fwd_test.hpp"
#include "./config.hpp"
#if !defined(TEST_EXTENSIONS) || defined(TEST_STD_INCLUDES)
int main() {}
#else
#include "./hash_fwd_test.hpp"
#include <boost/detail/lightweight_test.hpp>
template <class T> void unused(T const&) {}
@@ -30,10 +37,11 @@ void fwd_test()
unused(y1); unused(y2); unused(y3);
}
int main()
{
fwd_test();
return boost::report_errors();
}
#endif // defined(TEST_EXTENSIONS) && !defined(TEST_STD_INCLUDES)

View File

@@ -6,6 +6,8 @@
// This test demonstrates an ADL bug in Borland 5.5 where ADL isn't performed
// in the global namespace.
#include "./config.hpp"
#include <boost/config.hpp>
#include <cstddef>
@@ -83,8 +85,8 @@ void custom_tests()
HASH_NAMESPACE::hash_combine(seed2, 250u);
HASH_NAMESPACE::hash_combine(seed2, 350u);
BOOST_TEST(seed ==
HASH_NAMESPACE::hash_range(custom_vector.begin(), custom_vector.end()));
BOOST_TEST(seed == HASH_NAMESPACE::hash_range(
custom_vector.begin(), custom_vector.end()));
BOOST_TEST(seed == seed2);
}

View File

@@ -27,7 +27,7 @@ using std::multimap;
#define CONTAINER_TYPE multimap
#include "./hash_map_test.hpp"
#endif // TEST_EXTENSTIONS
#endif // TEST_EXTENSIONS
int main()
{

View File

@@ -11,6 +11,7 @@
#if defined(BOOST_MSVC)
#pragma warning(push)
#pragma warning(disable:4244) // conversion from 'int' to 'float'
#pragma warning(disable:4245) // signed/unsigned mismatch
#endif
@@ -21,19 +22,21 @@ namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
{
const int number_of_containers = 10;
T containers[number_of_containers];
typedef typename T::value_type pair;
typedef BOOST_DEDUCED_TYPENAME T::value_type pair;
typedef BOOST_DEDUCED_TYPENAME T::key_type key;
typedef BOOST_DEDUCED_TYPENAME T::mapped_type value;
for(int i = 0; i < 5; ++i) {
for(int j = 0; j < i; ++j)
containers[i].insert(pair(0, 0));
containers[i].insert(pair(key(0), value(0)));
}
containers[6].insert(pair(1,0));
containers[7].insert(pair(1,0));
containers[7].insert(pair(1,0));
containers[8].insert(pair(-1,1));
containers[9].insert(pair(-1,3));
containers[9].insert(pair(-1,3));
containers[6].insert(pair(key(1),value(0)));
containers[7].insert(pair(key(1),value(0)));
containers[7].insert(pair(key(1),value(0)));
containers[8].insert(pair(key(-1),value(1)));
containers[9].insert(pair(key(-1),value(3)));
containers[9].insert(pair(key(-1),value(3)));
HASH_NAMESPACE::hash<T> hasher;

View File

@@ -3,17 +3,26 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#define HASH_NAMESPACE boost
#include "./config.hpp"
// Simple test to make sure BOOST_HASH_NO_EXTENSIONS does disable extensions
// (or at least one of them).
#define BOOST_HASH_NO_EXTENSIONS
#if !defined(BOOST_HASH_NO_EXTENSIONS)
# define BOOST_HASH_NO_EXTENSIONS
#endif
#include <boost/functional/hash.hpp>
#include <boost/functional/hash.hpp>
#ifdef TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/functional/hash.hpp>
#endif
template <class T> void ignore(T const&) {}
int main()
{
HASH_NAMESPACE::hash< int[10] > hasher;
ignore(hasher);
return 0;
}

View File

@@ -3,16 +3,27 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#define HASH_NAMESPACE boost
#include <boost/functional/hash.hpp>
#define BOOST_HASH_NO_EXTENSIONS
#include <boost/functional/hash.hpp>
#include "./config.hpp"
#if defined(TEST_EXTENSIONS)
// Include header without BOOST_HASH_NO_EXTENSIONS defined
# if defined(BOOST_HASH_NO_EXTENSIONS)
# undef BOOST_HASH_NO_EXTENSIONS
# endif
# include <boost/functional/hash.hpp>
// Include header with BOOST_HASH_NO_EXTENSIONS defined
# define BOOST_HASH_NO_EXTENSIONS
# include <boost/functional/hash.hpp>
#endif
#include <boost/detail/lightweight_test.hpp>
#include <deque>
#include <cassert>
int main()
{
#if defined(TEST_EXTENSIONS)
std::deque<int> x;
x.push_back(1);
@@ -20,6 +31,7 @@ int main()
HASH_NAMESPACE::hash<std::deque<int> > hasher;
BOOST_TEST(hasher(x) == HASH_NAMESPACE::hash_value(x));
#endif
return boost::report_errors();
}

View File

@@ -3,16 +3,27 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#define HASH_NAMESPACE boost
#define BOOST_HASH_NO_EXTENSIONS
#include <boost/functional/hash.hpp>
#undef BOOST_HASH_NO_EXTENSIONS
#include <boost/functional/hash.hpp>
#include "./config.hpp"
#if defined(TEST_EXTENSIONS)
// Include header with BOOST_HASH_NO_EXTENSIONS defined
# if !defined(BOOST_HASH_NO_EXTENSIONS)
# define BOOST_HASH_NO_EXTENSIONS
# endif
# include <boost/functional/hash.hpp>
// Include header without BOOST_HASH_NO_EXTENSIONS defined
# undef BOOST_HASH_NO_EXTENSIONS
# include <boost/functional/hash.hpp>
#endif
#include <boost/detail/lightweight_test.hpp>
#include <map>
int main()
{
#if defined(TEST_EXTENSIONS)
std::map<int, int> x;
x.insert(std::map<int, int>::value_type(53, -42));
@@ -20,6 +31,7 @@ int main()
HASH_NAMESPACE::hash<std::map<int, int> > hasher;
BOOST_TEST(hasher(x) == HASH_NAMESPACE::hash_value(x));
#endif
return boost::report_errors();
}

View File

@@ -15,9 +15,7 @@
#include <boost/detail/lightweight_test.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/limits.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include <boost/functional/hash/detail/limits.hpp>
#include "./compile_time.hpp"
@@ -28,6 +26,10 @@
#pragma warning(disable:4310) // cast truncates constant value
#endif
#if defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
template <class T>
void numeric_test(T*)
{
@@ -55,8 +57,11 @@ void numeric_test(T*)
if (limits::is_integer)
{
if(limits::is_signed || limits::digits <= boost::hash_detail::limits<std::size_t>::digits)
if(limits::is_signed ||
limits::digits <= boost::hash_detail::limits<std::size_t>::digits)
{
BOOST_TEST(HASH_NAMESPACE::hash_value(T(-5)) == (std::size_t)T(-5));
}
BOOST_TEST(HASH_NAMESPACE::hash_value(T(0)) == (std::size_t)T(0u));
BOOST_TEST(HASH_NAMESPACE::hash_value(T(10)) == (std::size_t)T(10u));
BOOST_TEST(HASH_NAMESPACE::hash_value(T(25)) == (std::size_t)T(25u));
@@ -110,7 +115,8 @@ void poor_quality_tests(T*)
if(T(1) != T(2))
BOOST_TEST(x1(T(1)) != x2(T(2)));
if((limits::max)() != (limits::max)() - 1)
BOOST_TEST(x1((limits::max)()) != x2((limits::max)() - 1));
BOOST_TEST(x1(static_cast<T>((limits::max)()))
!= x2(static_cast<T>((limits::max)() - 1)));
}
void bool_test()
@@ -149,7 +155,7 @@ int main()
NUMERIC_TEST(long, hash_long)
NUMERIC_TEST(unsigned long, ulong)
#if defined(BOOST_HAS_LONG_LONG)
#if !defined(BOOST_NO_LONG_LONG)
NUMERIC_TEST_NO_LIMITS(boost::long_long_type, long_long)
NUMERIC_TEST_NO_LIMITS(boost::ulong_long_type, ulong_long)
#endif
@@ -157,6 +163,9 @@ int main()
NUMERIC_TEST(float, float)
NUMERIC_TEST(double, double)
NUMERIC_TEST(std::size_t, size_t)
NUMERIC_TEST(std::ptrdiff_t, ptrdiff_t)
bool_test();
return boost::report_errors();

View File

@@ -12,11 +12,7 @@
#endif
#include <boost/detail/lightweight_test.hpp>
#include <boost/limits.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include "./compile_time.hpp"
void pointer_tests()

View File

@@ -5,21 +5,20 @@
#include "./config.hpp"
#ifdef TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/functional/hash.hpp>
# endif
#if !defined(TEST_EXTENSIONS)
int main() {}
#else
#ifdef TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/functional/hash.hpp>
#endif
#include <boost/detail/lightweight_test.hpp>
#ifdef TEST_EXTENSIONS
#include <boost/limits.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include <vector>
void hash_range_tests()
@@ -68,14 +67,14 @@ void hash_range_tests()
BOOST_TEST(HASH_NAMESPACE::hash_range(values3.begin(), values3.end())
== HASH_NAMESPACE::hash_range(x.begin(), x.end()));
std::size_t seed = HASH_NAMESPACE::hash_range(values3.begin(), values3.end());
std::size_t seed =
HASH_NAMESPACE::hash_range(values3.begin(), values3.end());
HASH_NAMESPACE::hash_range(seed, values4.begin(), values4.end());
HASH_NAMESPACE::hash_range(seed, x.begin(), x.end());
BOOST_TEST(seed == HASH_NAMESPACE::hash_range(values5.begin(), values5.end()));
BOOST_TEST(seed ==
HASH_NAMESPACE::hash_range(values5.begin(), values5.end()));
}
#endif
int main()
{
hash_range_tests();
@@ -83,3 +82,4 @@ int main()
return boost::report_errors();
}
#endif // TEST_EXTESNIONS

View File

@@ -0,0 +1,103 @@
// Copyright 2012 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 "./config.hpp"
#ifdef TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/functional/hash.hpp>
# endif
#endif
#include <boost/config.hpp>
#include <boost/detail/lightweight_test.hpp>
#if defined(TEST_EXTENSIONS) && !defined(BOOST_NO_CXX11_HDR_ARRAY)
#define TEST_ARRAY
#include <array>
#include <vector>
#endif
#ifdef TEST_ARRAY
template <typename T>
void array_tests(T const& v) {
boost::hash<typename T::value_type> hf;
for(typename T::const_iterator i = v.begin(); i != v.end(); ++i) {
for(typename T::const_iterator j = v.begin(); j != v.end(); ++j) {
if (i != j)
BOOST_TEST(hf(*i) != hf(*j));
else
BOOST_TEST(hf(*i) == hf(*j));
}
}
}
void empty_array_test() {
/*
boost::hash<std::array<int, 0> > empty_array_hash;
std::array<int, 0> empty_array;
BOOST_TEST(empty_array_hash(empty_array) == boost::hash_value(empty_array));
*/
}
void int_1_array_test()
{
std::vector<std::array<int, 1> > arrays;
std::array<int, 1> val;
val[0] = 0;
arrays.push_back(val);
val[0] = 1;
arrays.push_back(val);
val[0] = 2;
arrays.push_back(val);
array_tests(arrays);
}
void string_1_array_test()
{
std::vector<std::array<std::string, 1> > arrays;
std::array<std::string, 1> val;
arrays.push_back(val);
val[0] = "one";
arrays.push_back(val);
val[0] = "two";
arrays.push_back(val);
array_tests(arrays);
}
void string_3_array_test()
{
std::vector<std::array<std::string,3 > > arrays;
std::array<std::string, 3> val;
arrays.push_back(val);
val[0] = "one";
arrays.push_back(val);
val[0] = ""; val[1] = "one"; val[2] = "";
arrays.push_back(val);
val[0] = ""; val[1] = ""; val[2] = "one";
arrays.push_back(val);
val[0] = "one"; val[1] = "one"; val[2] = "one";
arrays.push_back(val);
val[0] = "one"; val[1] = "two"; val[2] = "three";
arrays.push_back(val);
array_tests(arrays);
}
#endif // TEST_ARRAY
int main()
{
#ifdef TEST_ARRAY
empty_array_test();
int_1_array_test();
string_1_array_test();
string_3_array_test();
#endif
return boost::report_errors();
}

View File

@@ -0,0 +1,80 @@
// Copyright 2012 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 "./config.hpp"
#ifdef TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/functional/hash.hpp>
#endif
#include <boost/detail/lightweight_test.hpp>
#include "./compile_time.hpp"
#if defined(TEST_EXTENSIONS) && !defined(BOOST_NO_CXX11_SMART_PTR)
#define TEST_SMART_PTRS
#include <memory>
#endif
#ifdef TEST_SMART_PTRS
void shared_ptr_tests()
{
std::shared_ptr<int> x;
compile_time_tests(&x);
HASH_NAMESPACE::hash<std::shared_ptr<int> > x1;
HASH_NAMESPACE::hash<std::shared_ptr<int> > x2;
std::shared_ptr<int> ptr1(new int(10));
std::shared_ptr<int> ptr2;
BOOST_TEST(x1(x) == x2(ptr2));
BOOST_TEST(x1(x) != x2(ptr1));
ptr2.reset(new int(10));
BOOST_TEST(x1(ptr1) == x2(ptr1));
BOOST_TEST(x1(ptr1) != x2(ptr2));
ptr2 = ptr1;
BOOST_TEST(x1(ptr1) == x2(ptr2));
#if defined(TEST_EXTENSIONS)
BOOST_TEST(x1(x) == HASH_NAMESPACE::hash_value(x));
BOOST_TEST(x1(ptr1) == HASH_NAMESPACE::hash_value(ptr2));
#endif
}
void unique_ptr_tests()
{
std::unique_ptr<int> x;
compile_time_tests(&x);
HASH_NAMESPACE::hash<std::unique_ptr<int> > x1;
HASH_NAMESPACE::hash<std::unique_ptr<int> > x2;
std::unique_ptr<int> ptr1(new int(10));
std::unique_ptr<int> ptr2;
BOOST_TEST(x1(x) == x2(ptr2));
BOOST_TEST(x1(x) != x2(ptr1));
ptr2.reset(new int(10));
BOOST_TEST(x1(ptr1) == x2(ptr1));
BOOST_TEST(x1(ptr1) != x2(ptr2));
#if defined(TEST_EXTENSIONS)
BOOST_TEST(x1(x) == HASH_NAMESPACE::hash_value(x));
#endif
}
#endif
int main()
{
#ifdef TEST_SMART_PTRS
shared_ptr_tests();
unique_ptr_tests();
#endif
return boost::report_errors();
}

View File

@@ -0,0 +1,77 @@
// Copyright 2012 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 "./config.hpp"
#ifdef TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/functional/hash.hpp>
# endif
#endif
#include <boost/config.hpp>
#include <boost/detail/lightweight_test.hpp>
#if defined(TEST_EXTENSIONS) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
#define TEST_TUPLE
#include <tuple>
#include <vector>
#endif
#ifdef TEST_TUPLE
template <typename T>
void tuple_tests(T const& v) {
boost::hash<typename T::value_type> hf;
for(typename T::const_iterator i = v.begin(); i != v.end(); ++i) {
for(typename T::const_iterator j = v.begin(); j != v.end(); ++j) {
if (i != j)
BOOST_TEST(hf(*i) != hf(*j));
else
BOOST_TEST(hf(*i) == hf(*j));
}
}
}
void empty_tuple_test() {
boost::hash<std::tuple<> > empty_tuple_hash;
std::tuple<> empty_tuple;
BOOST_TEST(empty_tuple_hash(empty_tuple) == boost::hash_value(empty_tuple));
}
void int_tuple_test() {
std::vector<std::tuple<int> > int_tuples;
int_tuples.push_back(std::make_tuple(0));
int_tuples.push_back(std::make_tuple(1));
int_tuples.push_back(std::make_tuple(2));
tuple_tests(int_tuples);
}
void int_string_tuple_test() {
std::vector<std::tuple<int, std::string> > int_string_tuples;
int_string_tuples.push_back(std::make_tuple(0, std::string("zero")));
int_string_tuples.push_back(std::make_tuple(1, std::string("one")));
int_string_tuples.push_back(std::make_tuple(2, std::string("two")));
int_string_tuples.push_back(std::make_tuple(0, std::string("one")));
int_string_tuples.push_back(std::make_tuple(1, std::string("zero")));
int_string_tuples.push_back(std::make_tuple(0, std::string("")));
int_string_tuples.push_back(std::make_tuple(1, std::string("")));
tuple_tests(int_string_tuples);
}
#endif // TEST_TUPLE
int main()
{
#ifdef TEST_TUPLE
empty_tuple_test();
int_tuple_test();
int_string_tuple_test();
#endif
return boost::report_errors();
}

View File

@@ -12,12 +12,7 @@
#endif
#include <boost/detail/lightweight_test.hpp>
#include <boost/limits.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include <string>
#include "./compile_time.hpp"
void string_tests()

View File

@@ -0,0 +1,53 @@
// Copyright 2011 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./config.hpp"
#ifdef TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/functional/hash.hpp>
#endif
#include <boost/config.hpp>
#include <boost/detail/lightweight_test.hpp>
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
#include <typeindex>
void test_type_index() {
HASH_NAMESPACE::hash<std::type_index> hasher;
#if defined(BOOST_NO_TYPEID)
std::cout<<"Unable to test std::type_index, as typeid isn't available"
<<std::endl;
#else
std::type_index int_index = typeid(int);
std::type_index int2_index = typeid(int);
std::type_index char_index = typeid(char);
BOOST_TEST(hasher(int_index) == int_index.hash_code());
BOOST_TEST(hasher(int_index) == int2_index.hash_code());
BOOST_TEST(hasher(char_index) == char_index.hash_code());
BOOST_TEST(HASH_NAMESPACE::hash_value(int_index) == int_index.hash_code());
BOOST_TEST(HASH_NAMESPACE::hash_value(int_index) == int2_index.hash_code());
BOOST_TEST(HASH_NAMESPACE::hash_value(char_index) == char_index.hash_code());
BOOST_TEST(hasher(int_index) == hasher(int2_index));
BOOST_TEST(hasher(int_index) != hasher(char_index));
#endif
}
#endif
int main()
{
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
test_type_index();
#else
std::cout<<"<type_index> not available."<<std::endl;
#endif
return boost::report_errors();
}

21
test/implicit_test.cpp Normal file
View File

@@ -0,0 +1,21 @@
// Copyright 2010 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/functional/hash.hpp>
namespace test
{
struct base {};
std::size_t hash_value(base const&) { return 0; }
struct converts { operator base() const { return base(); } };
}
int main() {
boost::hash<test::converts> hash;
test::converts x;
hash(x);
}

View File

@@ -3,20 +3,31 @@
// 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 "./config.hpp"
#define HASH_NAMESPACE boost
#include <boost/functional/hash.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <vector>
int f(std::size_t hash1, int* x1) {
// Check that HASH_NAMESPACE::hash<int*> works in both files.
HASH_NAMESPACE::hash<int*> ptr_hasher;
BOOST_TEST(hash1 == ptr_hasher(x1));
#if defined(TEST_EXTENSIONS)
// Check that std::vector<std::size_t> is avaiable in this file.
std::vector<std::size_t> x;
x.push_back(*x1);
HASH_NAMESPACE::hash<std::vector<std::size_t> > vector_hasher;
return vector_hasher(x) != HASH_NAMESPACE::hash_value(x);
#else
return 0;
#endif
}

View File

@@ -3,6 +3,8 @@
// 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 "./config.hpp"
#define HASH_NAMESPACE boost
#define BOOST_HASH_NO_EXTENSIONS
#include <boost/functional/hash.hpp>

View File

@@ -3,6 +3,8 @@
// 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 "./config.hpp"
#include <boost/functional/hash.hpp>
extern int f();

View File

@@ -3,6 +3,8 @@
// 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 "./config.hpp"
#include <boost/functional/hash.hpp>
int f() { return 0; }

View File

@@ -0,0 +1,16 @@
// Copyright 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)
// Check that I haven't inadvertantly pulled namespace std into the global
// namespace.
#include "./config.hpp"
#include <list>
#include <boost/functional/hash.hpp>
typedef list<int> foo;
int main() {}