mirror of
https://github.com/boostorg/container_hash.git
synced 2026-04-28 18:02:14 +02:00
Compare commits
148 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 42f5aeb552 | |||
| 524335a091 | |||
| 4c24efeadf | |||
| bf7e1328c4 | |||
| 946d693768 | |||
| aa9670ad2f | |||
| c8845a10fb | |||
| b81d239dbb | |||
| f0176013b7 | |||
| 292d7a7ae5 | |||
| 8eb8ad993a | |||
| 3b947c29de | |||
| fb20d59aa8 | |||
| 9dd1099e28 | |||
| 81e3119c51 | |||
| 86eae42d6f | |||
| 58033a375f | |||
| 77ac0f4198 | |||
| e1c1fc681d | |||
| e592b7f057 | |||
| da8405cb69 | |||
| 39570c232c | |||
| 7770a516fe | |||
| 49a87ce365 | |||
| 8e8f7a8d11 | |||
| 60d6f2fabd | |||
| 22a2c49db9 | |||
| 3ce1a740b7 | |||
| d11d2dd17a | |||
| 17d5f71c35 | |||
| a332300682 | |||
| fa8ce5ac40 | |||
| bbb8d4f19f | |||
| 59ee910b2e | |||
| bf0ea56eac | |||
| 5fdfe5d328 | |||
| 3788bb9e75 | |||
| b36cac82c3 | |||
| 4baf5e8517 | |||
| 946d1b9cc3 | |||
| 0a1800f9f8 | |||
| 7ec1fbe694 | |||
| 4bee159a10 | |||
| 514757c312 | |||
| 1cf74208aa | |||
| 1d5bfbcc9c | |||
| 5a5bbbf403 | |||
| 50011103a4 | |||
| 19564252b4 | |||
| b2be632311 | |||
| 003ec473b6 | |||
| c6f5970551 | |||
| a7d8c36057 | |||
| e09e3f1e06 | |||
| 691437839e | |||
| d8328a403c | |||
| 946a362d56 | |||
| 81483cc533 | |||
| b922722090 | |||
| da55a4fcca | |||
| e78d662c7a | |||
| 1f2c6bfaba | |||
| 79b5aa7a2e | |||
| ed548575d4 | |||
| af88f13aca | |||
| 1ff1366c5e | |||
| a5d18ba409 | |||
| f9a050b68e | |||
| a9144ed80b | |||
| 4ed4e4760b | |||
| 332201e5c8 | |||
| e225ed8f14 | |||
| 11170a916b | |||
| 26f4b6cd55 | |||
| 6f61ab5b0b | |||
| 1ec297d8d4 | |||
| 906b14102d | |||
| 803b01c8c8 | |||
| 016766fdec | |||
| b70f0b3aab | |||
| bb16ae385a | |||
| f5cbe3661c | |||
| 9158f88562 | |||
| eb20117301 | |||
| 379105280f | |||
| 1df9014b94 | |||
| 30bc59df59 | |||
| b2c5ed9adf | |||
| 9a63dd6667 | |||
| 5e713acaef | |||
| bc9ab80b9f | |||
| dedb3ba27b | |||
| 1cea89464b | |||
| 74ec71fe8d | |||
| 8090093f06 | |||
| 16b4e4b261 | |||
| bbf337598b | |||
| 386d46aff0 | |||
| 8b483e7d86 | |||
| 177884e8a3 | |||
| 7e6b470009 | |||
| f2a59837b0 | |||
| 78b6d8731e | |||
| 7c2f3b6bf5 | |||
| dd93c7c9a4 | |||
| 7092068156 | |||
| 572ec155db | |||
| 9a96585cb9 | |||
| dbcb234320 | |||
| 412ec29987 | |||
| d8eb578ae5 | |||
| 1cf16e51b9 | |||
| 91dfc92b0e | |||
| f2afc2a08d | |||
| 7223c8da60 | |||
| 0fae4b4f65 | |||
| 72cd8cdaa1 | |||
| 43e79383ae | |||
| dbed5ebafa | |||
| 976683836e | |||
| 9cd9c5780f | |||
| be1be0d1fe | |||
| 557e8e7ff9 | |||
| 0a43718366 | |||
| 8c8baeedd8 | |||
| 763e59741a | |||
| 8b08528611 | |||
| 18b3a53699 | |||
| a267ab6a2c | |||
| 477004a45d | |||
| 15d97d95e7 | |||
| 1d10a0f323 | |||
| 5e9f0e4c8e | |||
| 896e07cca7 | |||
| e24a93d8c6 | |||
| 50e6bad2fd | |||
| d252ee760d | |||
| 2d91127422 | |||
| a65dc47fcb | |||
| 3d0a7a34dd | |||
| d305aad29d | |||
| 52750a193d | |||
| f3d016cf6d | |||
| 733ded8185 | |||
| 0aff6fe1a8 | |||
| 27d6247dac | |||
| 8bfc36b94d | |||
| 2b375867f5 |
@@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
# Copyright Daniel James 2005. Use, modification, and distribution are
|
||||||
|
# subject to 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 quickbook ;
|
||||||
|
|
||||||
|
xml hash : hash.qbk ;
|
||||||
|
boostbook standalone : hash ;
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
|
||||||
|
[/ Copyright 2005-2006 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:changes Change Log]
|
||||||
|
|
||||||
|
[h2 Boost 1.33.0]
|
||||||
|
|
||||||
|
* Initial Release
|
||||||
|
|
||||||
|
[h2 Changes in Boost 1.33.1]
|
||||||
|
|
||||||
|
* Fixed the points example, as pointed out by 沈慧峰.
|
||||||
|
|
||||||
|
[h2 Changes in Boost 1.34.0]
|
||||||
|
|
||||||
|
* Use declarations for standard classes, so that the library
|
||||||
|
doesn't need to include all of their headers
|
||||||
|
* Deprecated the `<boost/functional/hash/*.hpp>` headers. Now a single header,
|
||||||
|
<[headerref boost/functional/hash.hpp]> is used.
|
||||||
|
* Add support for the `BOOST_HASH_NO_EXTENSIONS` macro, which
|
||||||
|
disables the extensions to TR1
|
||||||
|
* Minor improvements to the hash functions for floating point numbers.
|
||||||
|
|
||||||
|
[h2 Future Developments]
|
||||||
|
|
||||||
|
* A more portable hash function, as described by Daniel Krügler in
|
||||||
|
[@http://lists.boost.org/boost-users/2005/08/13418.php a post to the boost users list].
|
||||||
|
* Implement `hash_value` for more classes, including `std::complex`.
|
||||||
|
|
||||||
|
[endsect]
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
|
||||||
|
[/ Copyright 2005-2006 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:disable Disabling The Extensions]
|
||||||
|
|
||||||
|
While [classref boost::hash]'s extensions are generally useful, you might want
|
||||||
|
to turn them of in order to check that your code will work with other
|
||||||
|
implementations of TR1. To do this define the macro `BOOST_HASH_NO_EXTENSIONS`.
|
||||||
|
When this macro is defined, only the specialisations detailed
|
||||||
|
in TR1 will be declared. But, if you later undefine the macro and include
|
||||||
|
<[headerref boost/functional/hash.hpp]> then the non-specialised form will be defined
|
||||||
|
- activating the extensions.
|
||||||
|
|
||||||
|
It is strongly recommended that you never undefine the macro - and only define
|
||||||
|
it so that it applies to the complete translation unit, either by defining it
|
||||||
|
at the beginning of the main source file or, preferably, by using a compiler
|
||||||
|
switch or preference. And you really should never define it in header files.
|
||||||
|
|
||||||
|
If you are writing a library which has code in the header which requires the
|
||||||
|
extensions, then the best action is to tell users not to define the macro.
|
||||||
|
Their code won't ['require] the macro.
|
||||||
|
|
||||||
|
Translation units that are compiled with the macro defined will link with units
|
||||||
|
that were compiled without it. This feature has been designed to avoid ODR
|
||||||
|
violations.
|
||||||
|
|
||||||
|
[endsect]
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
[library Boost.Functional/Hash
|
||||||
|
[quickbook 1.3]
|
||||||
|
[authors [James, Daniel]]
|
||||||
|
[copyright 2005 2006 Daniel James]
|
||||||
|
[purpose A TR1 hash function object that can be extended to hash user
|
||||||
|
defined types]
|
||||||
|
[category higher-order]
|
||||||
|
[id hash]
|
||||||
|
[dirname hash]
|
||||||
|
[license
|
||||||
|
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:hash intro.qbk]
|
||||||
|
[include:hash tutorial.qbk]
|
||||||
|
[include:hash portability.qbk]
|
||||||
|
[include:hash disable.qbk]
|
||||||
|
[include:hash changes.qbk]
|
||||||
|
[xinclude ref.xml]
|
||||||
|
[include:hash links.qbk]
|
||||||
|
[include:hash thanks.qbk]
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
|
||||||
|
[/ Copyright 2005-2006 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:intro Introduction]
|
||||||
|
|
||||||
|
[def __tr1-full__
|
||||||
|
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf
|
||||||
|
Draft Technical Report on C++ Library Extensions]]
|
||||||
|
[def __tr1__
|
||||||
|
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf
|
||||||
|
TR1]]
|
||||||
|
[def __multi-index__ [@../../libs/multi_index/doc/index.html
|
||||||
|
Boost Multi-Index Containers Library]]
|
||||||
|
[def __multi-index-short__ [@../../libs/multi_index/doc/index.html
|
||||||
|
Boost.MultiIndex]]
|
||||||
|
[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]]
|
||||||
|
|
||||||
|
[classref boost::hash] is an implementation of the __hash-function__ object
|
||||||
|
specified by the __tr1-full__ (TR1). It is intended for use as the default hash function
|
||||||
|
for unordered associative containers, and the __multi-index__'s hash indexes.
|
||||||
|
|
||||||
|
As it is compliant with __tr1__, it will work with:
|
||||||
|
|
||||||
|
* integers
|
||||||
|
* floats
|
||||||
|
* pointers
|
||||||
|
* strings
|
||||||
|
|
||||||
|
It also implements the extension proposed by Peter Dimov in issue 6.18 of the
|
||||||
|
__issues__ (page 63), this adds support for:
|
||||||
|
|
||||||
|
* arrays
|
||||||
|
* `std::pair`
|
||||||
|
* the standard containers.
|
||||||
|
* extending [classref boost::hash] for custom types.
|
||||||
|
|
||||||
|
[endsect]
|
||||||
|
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
[/ Copyright 2005-2006 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:links Links]
|
||||||
|
|
||||||
|
[*A Proposal to Add Hash Tables to the Standard Library]\n
|
||||||
|
[@http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1456.html]\n
|
||||||
|
The hash table proposal explains much of the design. The hash function object
|
||||||
|
is discussed in Section D.
|
||||||
|
|
||||||
|
[*The C++ Standard Library Technical Report.]\n
|
||||||
|
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf]\n
|
||||||
|
Contains the hash function specification in section 6.3.2.
|
||||||
|
|
||||||
|
[*Library Extension Technical Report Issues List.]\n
|
||||||
|
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf]\n
|
||||||
|
The library implements the extension described in Issue 6.18, pages 63-67.
|
||||||
|
|
||||||
|
[*Methods for Identifying Versioned and Plagiarised Documents]\n
|
||||||
|
Timothy C. Hoad, Justin Zobel\n
|
||||||
|
[@http://www.cs.rmit.edu.au/~jz/fulltext/jasist-tch.pdf]\n
|
||||||
|
Contains the hash function that [funcref boost::hash_combine] is based on.
|
||||||
|
|
||||||
|
[endsect]
|
||||||
|
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
|
||||||
|
[/ Copyright 2005-2006 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:portability Portability]
|
||||||
|
|
||||||
|
[def __boost_hash__ [classref boost::hash]]
|
||||||
|
|
||||||
|
__boost_hash__ is written to be as portable as possible, but unfortunately, several
|
||||||
|
older compilers don't support argument dependent lookup (ADL) - the mechanism
|
||||||
|
used for customisation. On those compilers custom overloads for `hash_value`
|
||||||
|
need to be declared in the boost namespace.
|
||||||
|
|
||||||
|
On a strictly standards compliant compiler, an overload defined in the
|
||||||
|
boost namespace won't be found when __boost_hash__ is instantiated,
|
||||||
|
so for these compilers the overload should only be declared in the same
|
||||||
|
namespace as the class.
|
||||||
|
|
||||||
|
Let's say we have a simple custom type:
|
||||||
|
|
||||||
|
namespace foo
|
||||||
|
{
|
||||||
|
template <class T>
|
||||||
|
class custom_type
|
||||||
|
{
|
||||||
|
T value;
|
||||||
|
public:
|
||||||
|
custom_type(T x) : value(x) {}
|
||||||
|
|
||||||
|
friend std::size_t hash_value(custom_type x)
|
||||||
|
{
|
||||||
|
__boost_hash__<int> hasher;
|
||||||
|
return hasher(x.value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
On a compliant compiler, when `hash_value` is called for this type,
|
||||||
|
it will look at the namespace inside the type and find `hash_value`
|
||||||
|
but on a compiler which doesn't support ADL `hash_value` won't be found.
|
||||||
|
To make things worse, some compilers which do support ADL won't find
|
||||||
|
a friend class defined inside the class.
|
||||||
|
|
||||||
|
So first move the member function out of the class:
|
||||||
|
|
||||||
|
namespace foo
|
||||||
|
{
|
||||||
|
template <class T>
|
||||||
|
class custom_type
|
||||||
|
{
|
||||||
|
T value;
|
||||||
|
public:
|
||||||
|
custom_type(T x) : value(x) {}
|
||||||
|
|
||||||
|
std::size_t hash(custom_type x)
|
||||||
|
{
|
||||||
|
__boost_hash__<T> hasher;
|
||||||
|
return hasher(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline std::size_t hash_value(custom_type<T> x)
|
||||||
|
{
|
||||||
|
return x.hash();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Unfortunately, I couldn't declare hash_value as a friend, as some compilers
|
||||||
|
don't support template friends, so instead I declared a member function to
|
||||||
|
calculate the hash, and called it from hash_value.
|
||||||
|
|
||||||
|
For compilers which don't support ADL, hash_value needs to be defined in the
|
||||||
|
boost namespace:
|
||||||
|
|
||||||
|
#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
|
||||||
|
namespace boost
|
||||||
|
#else
|
||||||
|
namespace foo
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
template <class T>
|
||||||
|
std::size_t hash_value(foo::custom_type<T> x)
|
||||||
|
{
|
||||||
|
return x.hash();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Full code for this example is at
|
||||||
|
[@../../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]
|
||||||
+699
@@ -0,0 +1,699 @@
|
|||||||
|
<!--
|
||||||
|
Copyright 2005-2006 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)
|
||||||
|
-->
|
||||||
|
|
||||||
|
<library-reference>
|
||||||
|
<section id="hash.reference.specification">
|
||||||
|
<para>For the full specification, see section 6.3 of the
|
||||||
|
<ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf">C++ Standard Library Technical Report</ulink>
|
||||||
|
and issue 6.18 of the
|
||||||
|
<ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf">Library Extension Technical Report Issues List</ulink> (page 63).
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
<header name="boost/functional/hash.hpp">
|
||||||
|
<para>
|
||||||
|
Defines <code><classname>boost::hash</classname></code>,
|
||||||
|
and helper functions.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<namespace name="boost">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
boost::hash
|
||||||
|
-->
|
||||||
|
|
||||||
|
<struct name="hash">
|
||||||
|
<template>
|
||||||
|
<template-type-parameter name="T"/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<inherit access="public">
|
||||||
|
<classname>std::unary_function<T, std::size_t></classname>
|
||||||
|
</inherit>
|
||||||
|
|
||||||
|
<purpose>A <ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf">TR1</ulink> compliant hash function object.</purpose>
|
||||||
|
|
||||||
|
<method name="operator()" cv="const">
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val">
|
||||||
|
<paramtype>T const&</paramtype>
|
||||||
|
</parameter>
|
||||||
|
<returns><para>
|
||||||
|
<programlisting><functionname>hash_value</functionname>(val)</programlisting>
|
||||||
|
</para></returns>
|
||||||
|
<notes>
|
||||||
|
<para>
|
||||||
|
The call to <code><functionname>hash_value</functionname></code>
|
||||||
|
is unqualified, so that custom overloads can be
|
||||||
|
found via argument dependent lookup.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
This is not defined when the macro <code>BOOST_HASH_NO_EXTENSIONS</code>
|
||||||
|
is defined. The specializations are still defined, so only the specializations
|
||||||
|
required by TR1 are defined.
|
||||||
|
</para>
|
||||||
|
</notes>
|
||||||
|
<throws><para>
|
||||||
|
Only throws if
|
||||||
|
<code><functionname>hash_value</functionname>(T)</code> throws.
|
||||||
|
</para></throws>
|
||||||
|
</method>
|
||||||
|
</struct>
|
||||||
|
|
||||||
|
<struct-specialization name="hash">
|
||||||
|
<template></template>
|
||||||
|
<specialization>
|
||||||
|
<template-arg>bool</template-arg>
|
||||||
|
</specialization>
|
||||||
|
<method name="operator()" cv="const">
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val">
|
||||||
|
<paramtype>bool</paramtype>
|
||||||
|
</parameter>
|
||||||
|
<returns>
|
||||||
|
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
|
||||||
|
<para><functionname>hash_value</functionname>(val) in Boost.</para>
|
||||||
|
</returns>
|
||||||
|
<throws><para>Doesn't throw</para></throws>
|
||||||
|
</method>
|
||||||
|
</struct-specialization>
|
||||||
|
|
||||||
|
<struct-specialization name="hash">
|
||||||
|
<template></template>
|
||||||
|
<specialization>
|
||||||
|
<template-arg>char</template-arg>
|
||||||
|
</specialization>
|
||||||
|
<method name="operator()" cv="const">
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val">
|
||||||
|
<paramtype>char</paramtype>
|
||||||
|
</parameter>
|
||||||
|
<returns>
|
||||||
|
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
|
||||||
|
<para><functionname>hash_value</functionname>(val) in Boost.</para>
|
||||||
|
</returns>
|
||||||
|
<throws><para>Doesn't throw</para></throws>
|
||||||
|
</method>
|
||||||
|
</struct-specialization>
|
||||||
|
|
||||||
|
<struct-specialization name="hash">
|
||||||
|
<template></template>
|
||||||
|
<specialization>
|
||||||
|
<template-arg>signed char</template-arg>
|
||||||
|
</specialization>
|
||||||
|
<method name="operator()" cv="const">
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val">
|
||||||
|
<paramtype>signed char</paramtype>
|
||||||
|
</parameter>
|
||||||
|
<returns>
|
||||||
|
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
|
||||||
|
<para><functionname>hash_value</functionname>(val) in Boost.</para>
|
||||||
|
</returns>
|
||||||
|
<throws><para>Doesn't throw</para></throws>
|
||||||
|
</method>
|
||||||
|
</struct-specialization>
|
||||||
|
|
||||||
|
<struct-specialization name="hash">
|
||||||
|
<template></template>
|
||||||
|
<specialization>
|
||||||
|
<template-arg>unsigned char</template-arg>
|
||||||
|
</specialization>
|
||||||
|
<method name="operator()" cv="const">
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val">
|
||||||
|
<paramtype>unsigned char</paramtype>
|
||||||
|
</parameter>
|
||||||
|
<returns>
|
||||||
|
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
|
||||||
|
<para><functionname>hash_value</functionname>(val) in Boost.</para>
|
||||||
|
</returns>
|
||||||
|
<throws><para>Doesn't throw</para></throws>
|
||||||
|
</method>
|
||||||
|
</struct-specialization>
|
||||||
|
|
||||||
|
<struct-specialization name="hash">
|
||||||
|
<template></template>
|
||||||
|
<specialization>
|
||||||
|
<template-arg>wchar_t</template-arg>
|
||||||
|
</specialization>
|
||||||
|
<method name="operator()" cv="const">
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val">
|
||||||
|
<paramtype>wchar_t</paramtype>
|
||||||
|
</parameter>
|
||||||
|
<returns>
|
||||||
|
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
|
||||||
|
<para><functionname>hash_value</functionname>(val) in Boost.</para>
|
||||||
|
</returns>
|
||||||
|
<throws><para>Doesn't throw</para></throws>
|
||||||
|
</method>
|
||||||
|
</struct-specialization>
|
||||||
|
|
||||||
|
<struct-specialization name="hash">
|
||||||
|
<template></template>
|
||||||
|
<specialization>
|
||||||
|
<template-arg>short</template-arg>
|
||||||
|
</specialization>
|
||||||
|
<method name="operator()" cv="const">
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val">
|
||||||
|
<paramtype>short</paramtype>
|
||||||
|
</parameter>
|
||||||
|
<returns>
|
||||||
|
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
|
||||||
|
<para><functionname>hash_value</functionname>(val) in Boost.</para>
|
||||||
|
</returns>
|
||||||
|
<throws><para>Doesn't throw</para></throws>
|
||||||
|
</method>
|
||||||
|
</struct-specialization>
|
||||||
|
|
||||||
|
<struct-specialization name="hash">
|
||||||
|
<template></template>
|
||||||
|
<specialization>
|
||||||
|
<template-arg>unsigned short</template-arg>
|
||||||
|
</specialization>
|
||||||
|
<method name="operator()" cv="const">
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val">
|
||||||
|
<paramtype>unsigned short</paramtype>
|
||||||
|
</parameter>
|
||||||
|
<returns>
|
||||||
|
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
|
||||||
|
<para><functionname>hash_value</functionname>(val) in Boost.</para>
|
||||||
|
</returns>
|
||||||
|
<throws><para>Doesn't throw</para></throws>
|
||||||
|
</method>
|
||||||
|
</struct-specialization>
|
||||||
|
|
||||||
|
<struct-specialization name="hash">
|
||||||
|
<template></template>
|
||||||
|
<specialization>
|
||||||
|
<template-arg>int</template-arg>
|
||||||
|
</specialization>
|
||||||
|
<method name="operator()" cv="const">
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val">
|
||||||
|
<paramtype>int</paramtype>
|
||||||
|
</parameter>
|
||||||
|
<returns>
|
||||||
|
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
|
||||||
|
<para><functionname>hash_value</functionname>(val) in Boost.</para>
|
||||||
|
</returns>
|
||||||
|
<throws><para>Doesn't throw</para></throws>
|
||||||
|
</method>
|
||||||
|
</struct-specialization>
|
||||||
|
|
||||||
|
<struct-specialization name="hash">
|
||||||
|
<template></template>
|
||||||
|
<specialization>
|
||||||
|
<template-arg>unsigned int</template-arg>
|
||||||
|
</specialization>
|
||||||
|
<method name="operator()" cv="const">
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val">
|
||||||
|
<paramtype>unsigned int</paramtype>
|
||||||
|
</parameter>
|
||||||
|
<returns>
|
||||||
|
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
|
||||||
|
<para><functionname>hash_value</functionname>(val) in Boost.</para>
|
||||||
|
</returns>
|
||||||
|
<throws><para>Doesn't throw</para></throws>
|
||||||
|
</method>
|
||||||
|
</struct-specialization>
|
||||||
|
|
||||||
|
<struct-specialization name="hash">
|
||||||
|
<template></template>
|
||||||
|
<specialization>
|
||||||
|
<template-arg>long</template-arg>
|
||||||
|
</specialization>
|
||||||
|
<method name="operator()" cv="const">
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val">
|
||||||
|
<paramtype>long</paramtype>
|
||||||
|
</parameter>
|
||||||
|
<returns>
|
||||||
|
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
|
||||||
|
<para><functionname>hash_value</functionname>(val) in Boost.</para>
|
||||||
|
</returns>
|
||||||
|
<throws><para>Doesn't throw</para></throws>
|
||||||
|
</method>
|
||||||
|
</struct-specialization>
|
||||||
|
|
||||||
|
<struct-specialization name="hash">
|
||||||
|
<template></template>
|
||||||
|
<specialization>
|
||||||
|
<template-arg>unsigned long</template-arg>
|
||||||
|
</specialization>
|
||||||
|
<method name="operator()" cv="const">
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val">
|
||||||
|
<paramtype>unsigned long</paramtype>
|
||||||
|
</parameter>
|
||||||
|
<returns>
|
||||||
|
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
|
||||||
|
<para><functionname>hash_value</functionname>(val) in Boost.</para>
|
||||||
|
</returns>
|
||||||
|
<throws><para>Doesn't throw</para></throws>
|
||||||
|
</method>
|
||||||
|
</struct-specialization>
|
||||||
|
|
||||||
|
<struct-specialization name="hash">
|
||||||
|
<template></template>
|
||||||
|
<specialization>
|
||||||
|
<template-arg>float</template-arg>
|
||||||
|
</specialization>
|
||||||
|
<method name="operator()" cv="const">
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val">
|
||||||
|
<paramtype>float</paramtype>
|
||||||
|
</parameter>
|
||||||
|
<returns>
|
||||||
|
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
|
||||||
|
<para><functionname>hash_value</functionname>(val) in Boost.</para>
|
||||||
|
</returns>
|
||||||
|
<throws><para>Doesn't throw</para></throws>
|
||||||
|
</method>
|
||||||
|
</struct-specialization>
|
||||||
|
|
||||||
|
<struct-specialization name="hash">
|
||||||
|
<template></template>
|
||||||
|
<specialization>
|
||||||
|
<template-arg>double</template-arg>
|
||||||
|
</specialization>
|
||||||
|
<method name="operator()" cv="const">
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val">
|
||||||
|
<paramtype>double</paramtype>
|
||||||
|
</parameter>
|
||||||
|
<returns>
|
||||||
|
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
|
||||||
|
<para><functionname>hash_value</functionname>(val) in Boost.</para>
|
||||||
|
</returns>
|
||||||
|
<throws><para>Doesn't throw</para></throws>
|
||||||
|
</method>
|
||||||
|
</struct-specialization>
|
||||||
|
|
||||||
|
<struct-specialization name="hash">
|
||||||
|
<template></template>
|
||||||
|
<specialization>
|
||||||
|
<template-arg>long double</template-arg>
|
||||||
|
</specialization>
|
||||||
|
<method name="operator()" cv="const">
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val">
|
||||||
|
<paramtype>long double</paramtype>
|
||||||
|
</parameter>
|
||||||
|
<returns>
|
||||||
|
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
|
||||||
|
<para><functionname>hash_value</functionname>(val) in Boost.</para>
|
||||||
|
</returns>
|
||||||
|
<throws><para>Doesn't throw</para></throws>
|
||||||
|
</method>
|
||||||
|
</struct-specialization>
|
||||||
|
|
||||||
|
<struct-specialization name="hash">
|
||||||
|
<template></template>
|
||||||
|
<specialization>
|
||||||
|
<template-arg>std::string</template-arg>
|
||||||
|
</specialization>
|
||||||
|
<method name="operator()" cv="const">
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val">
|
||||||
|
<paramtype>std::string const&</paramtype>
|
||||||
|
</parameter>
|
||||||
|
<returns>
|
||||||
|
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
|
||||||
|
<para><functionname>hash_value</functionname>(val) in Boost.</para>
|
||||||
|
</returns>
|
||||||
|
<throws><para>Doesn't throw</para></throws>
|
||||||
|
</method>
|
||||||
|
</struct-specialization>
|
||||||
|
|
||||||
|
<struct-specialization name="hash">
|
||||||
|
<template></template>
|
||||||
|
<specialization>
|
||||||
|
<template-arg>std::wstring</template-arg>
|
||||||
|
</specialization>
|
||||||
|
<method name="operator()" cv="const">
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val">
|
||||||
|
<paramtype>std::wstring const&</paramtype>
|
||||||
|
</parameter>
|
||||||
|
<returns>
|
||||||
|
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
|
||||||
|
<para><functionname>hash_value</functionname>(val) in Boost.</para>
|
||||||
|
</returns>
|
||||||
|
<throws><para>Doesn't throw</para></throws>
|
||||||
|
</method>
|
||||||
|
</struct-specialization>
|
||||||
|
|
||||||
|
<struct-specialization name="hash">
|
||||||
|
<template>
|
||||||
|
<template-type-parameter name="T"/>
|
||||||
|
</template>
|
||||||
|
<specialization>
|
||||||
|
<template-arg>T*</template-arg>
|
||||||
|
</specialization>
|
||||||
|
<method name="operator()" cv="const">
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val">
|
||||||
|
<paramtype>T*</paramtype>
|
||||||
|
</parameter>
|
||||||
|
<returns>
|
||||||
|
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
|
||||||
|
</returns>
|
||||||
|
<throws><para>Doesn't throw</para></throws>
|
||||||
|
</method>
|
||||||
|
</struct-specialization>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
boost::hash_combine
|
||||||
|
-->
|
||||||
|
|
||||||
|
<function name="hash_combine">
|
||||||
|
<template>
|
||||||
|
<template-type-parameter name="T"/>
|
||||||
|
</template>
|
||||||
|
<type>void</type>
|
||||||
|
<parameter name="seed"><paramtype>size_t &</paramtype></parameter>
|
||||||
|
<parameter name="v"><paramtype>T const&</paramtype></parameter>
|
||||||
|
<purpose>
|
||||||
|
Called repeatedly to incrementally create a hash value from
|
||||||
|
several variables.
|
||||||
|
</purpose>
|
||||||
|
<effects><programlisting>seed ^= <functionname>hash_value</functionname>(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);</programlisting></effects>
|
||||||
|
<notes>
|
||||||
|
<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>
|
||||||
|
</notes>
|
||||||
|
<throws>
|
||||||
|
Only throws if <functionname>hash_value</functionname>(T) throws.
|
||||||
|
Strong exception safety, as long as <functionname>hash_value</functionname>(T)
|
||||||
|
also has strong exception safety.
|
||||||
|
</throws>
|
||||||
|
</function>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
boost::hash_range
|
||||||
|
-->
|
||||||
|
|
||||||
|
<overloaded-function name="hash_range">
|
||||||
|
<signature>
|
||||||
|
<template>
|
||||||
|
<template-type-parameter name="It"/>
|
||||||
|
</template>
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="first"><paramtype>It</paramtype></parameter>
|
||||||
|
<parameter name="last"><paramtype>It</paramtype></parameter>
|
||||||
|
</signature>
|
||||||
|
|
||||||
|
<signature>
|
||||||
|
<template>
|
||||||
|
<template-type-parameter name="It"/>
|
||||||
|
</template>
|
||||||
|
<type>void</type>
|
||||||
|
<parameter name="seed"><paramtype>std::size_t&</paramtype></parameter>
|
||||||
|
<parameter name="first"><paramtype>It</paramtype></parameter>
|
||||||
|
<parameter name="last"><paramtype>It</paramtype></parameter>
|
||||||
|
</signature>
|
||||||
|
|
||||||
|
<purpose>
|
||||||
|
Calculate the combined hash value of the elements of an iterator
|
||||||
|
range.
|
||||||
|
</purpose>
|
||||||
|
<effects>
|
||||||
|
<para>For the two argument overload:
|
||||||
|
<programlisting>
|
||||||
|
size_t seed = 0;
|
||||||
|
|
||||||
|
for(; first != last; ++first)
|
||||||
|
{
|
||||||
|
<functionname>hash_combine</functionname>(seed, *first);
|
||||||
|
}
|
||||||
|
|
||||||
|
return seed;
|
||||||
|
</programlisting>
|
||||||
|
</para>For the three arguments overload:
|
||||||
|
<programlisting>
|
||||||
|
for(; first != last; ++first)
|
||||||
|
{
|
||||||
|
<functionname>hash_combine</functionname>(seed, *first);
|
||||||
|
}
|
||||||
|
</programlisting>
|
||||||
|
<para>
|
||||||
|
</para>
|
||||||
|
</effects>
|
||||||
|
<notes>
|
||||||
|
<para>
|
||||||
|
<code>hash_range</code> is sensitive to the order of the elements
|
||||||
|
so it wouldn't be appropriate to use this with an unordered
|
||||||
|
container.
|
||||||
|
</para>
|
||||||
|
<para>This is an extension to TR1</para>
|
||||||
|
</notes>
|
||||||
|
<throws><para>
|
||||||
|
Only throws if <code><functionname>hash_value</functionname>(std::iterator_traits<It>::value_type)</code>
|
||||||
|
throws. <code>hash_range(std::size_t&, It, It)</code> has basic exception safety as long as
|
||||||
|
<code><functionname>hash_value</functionname>(std::iterator_traits<It>::value_type)</code>
|
||||||
|
has basic exception safety.
|
||||||
|
</para></throws>
|
||||||
|
</overloaded-function>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
boost::hash_value - integers
|
||||||
|
-->
|
||||||
|
|
||||||
|
<overloaded-function name="hash_value">
|
||||||
|
<purpose>
|
||||||
|
Implementation of the hash function.
|
||||||
|
</purpose>
|
||||||
|
|
||||||
|
<signature>
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val"><paramtype>int</paramtype></parameter>
|
||||||
|
</signature>
|
||||||
|
|
||||||
|
<signature>
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val"><paramtype>unsigned int</paramtype></parameter>
|
||||||
|
</signature>
|
||||||
|
|
||||||
|
<signature>
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val"><paramtype>long</paramtype></parameter>
|
||||||
|
</signature>
|
||||||
|
|
||||||
|
<signature>
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val"><paramtype>unsigned long</paramtype></parameter>
|
||||||
|
</signature>
|
||||||
|
|
||||||
|
<signature>
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val"><paramtype>float</paramtype></parameter>
|
||||||
|
</signature>
|
||||||
|
|
||||||
|
<signature>
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val"><paramtype>double</paramtype></parameter>
|
||||||
|
</signature>
|
||||||
|
|
||||||
|
<signature>
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val"><paramtype>long double</paramtype></parameter>
|
||||||
|
</signature>
|
||||||
|
|
||||||
|
<signature>
|
||||||
|
<template><template-type-parameter name="T"/></template>
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val"><paramtype>T* const&</paramtype></parameter>
|
||||||
|
</signature>
|
||||||
|
|
||||||
|
<signature>
|
||||||
|
<template>
|
||||||
|
<template-type-parameter name="T"/>
|
||||||
|
<template-nontype-parameter name="N"><type>unsigned</type></template-nontype-parameter>
|
||||||
|
</template>
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter><paramtype>T (&val)[N]</paramtype></parameter>
|
||||||
|
</signature>
|
||||||
|
|
||||||
|
<signature>
|
||||||
|
<template>
|
||||||
|
<template-type-parameter name="T"/>
|
||||||
|
<template-nontype-parameter name="N"><type>unsigned</type></template-nontype-parameter>
|
||||||
|
</template>
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter><paramtype>const T (&val)[N]</paramtype></parameter>
|
||||||
|
</signature>
|
||||||
|
|
||||||
|
<signature>
|
||||||
|
<template>
|
||||||
|
<template-type-parameter name="Ch"/>
|
||||||
|
<template-type-parameter name="A"/>
|
||||||
|
</template>
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val">
|
||||||
|
<paramtype>std::basic_string<Ch, std::char_traits<Ch>, A> const&</paramtype>
|
||||||
|
</parameter>
|
||||||
|
</signature>
|
||||||
|
|
||||||
|
<signature>
|
||||||
|
<template>
|
||||||
|
<template-type-parameter name="A"/>
|
||||||
|
<template-type-parameter name="B"/>
|
||||||
|
</template>
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val"><paramtype>std::pair<A, B> const&</paramtype></parameter>
|
||||||
|
</signature>
|
||||||
|
|
||||||
|
<signature>
|
||||||
|
<template>
|
||||||
|
<template-type-parameter name="T"/>
|
||||||
|
<template-type-parameter name="A"/>
|
||||||
|
</template>
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val"><paramtype>std::vector<T, A> const&</paramtype></parameter>
|
||||||
|
</signature>
|
||||||
|
|
||||||
|
<signature>
|
||||||
|
<template>
|
||||||
|
<template-type-parameter name="T"/>
|
||||||
|
<template-type-parameter name="A"/>
|
||||||
|
</template>
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val"><paramtype>std::list<T, A> const&</paramtype></parameter>
|
||||||
|
</signature>
|
||||||
|
|
||||||
|
<signature>
|
||||||
|
<template>
|
||||||
|
<template-type-parameter name="T"/>
|
||||||
|
<template-type-parameter name="A"/>
|
||||||
|
</template>
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val"><paramtype>std::deque<T, A> const&</paramtype></parameter>
|
||||||
|
</signature>
|
||||||
|
|
||||||
|
<signature>
|
||||||
|
<template>
|
||||||
|
<template-type-parameter name="K"/>
|
||||||
|
<template-type-parameter name="C"/>
|
||||||
|
<template-type-parameter name="A"/>
|
||||||
|
</template>
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val"><paramtype>std::set<K, C, A> const&</paramtype></parameter>
|
||||||
|
</signature>
|
||||||
|
|
||||||
|
<signature>
|
||||||
|
<template>
|
||||||
|
<template-type-parameter name="K"/>
|
||||||
|
<template-type-parameter name="C"/>
|
||||||
|
<template-type-parameter name="A"/>
|
||||||
|
</template>
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val"><paramtype>std::multiset<K, C, A> const&</paramtype></parameter>
|
||||||
|
</signature>
|
||||||
|
|
||||||
|
<signature>
|
||||||
|
<template>
|
||||||
|
<template-type-parameter name="K"/>
|
||||||
|
<template-type-parameter name="T"/>
|
||||||
|
<template-type-parameter name="C"/>
|
||||||
|
<template-type-parameter name="A"/>
|
||||||
|
</template>
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val"><paramtype>std::map<K, T, C, A> const&</paramtype></parameter>
|
||||||
|
</signature>
|
||||||
|
|
||||||
|
<signature>
|
||||||
|
<template>
|
||||||
|
<template-type-parameter name="K"/>
|
||||||
|
<template-type-parameter name="T"/>
|
||||||
|
<template-type-parameter name="C"/>
|
||||||
|
<template-type-parameter name="A"/>
|
||||||
|
</template>
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val"><paramtype>std::multimap<K, T, C, A> const&</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>
|
||||||
|
or <functionname>boost::hash_combine</functionname> which
|
||||||
|
call <code>hash_value</code> without namespace qualification so that overloads
|
||||||
|
for custom types are found via ADL.
|
||||||
|
</para></description>
|
||||||
|
|
||||||
|
<notes>
|
||||||
|
<para>This is an extension to TR1</para>
|
||||||
|
</notes>
|
||||||
|
|
||||||
|
<throws>
|
||||||
|
Only throws if a user supplied version of
|
||||||
|
<code><functionname>hash_value</functionname></code>
|
||||||
|
throws for an element of a container, or
|
||||||
|
one of the types stored in a pair.
|
||||||
|
</throws>
|
||||||
|
|
||||||
|
<returns>
|
||||||
|
<informaltable>
|
||||||
|
<tgroup cols="2">
|
||||||
|
<thead>
|
||||||
|
<row>
|
||||||
|
<entry>Types</entry>
|
||||||
|
<entry>Returns</entry>
|
||||||
|
</row>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<row>
|
||||||
|
<entry><code>int</code>, <code>unsigned int</code>, <code>long</code>, <code>unsigned long</code></entry>
|
||||||
|
<entry><code>val</code></entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry><code>float</code>, <code>double</code>, <code>long double</code></entry>
|
||||||
|
<entry>An unspecified value, except that equal arguments shall yield the same result.</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry><code>T*</code></entry>
|
||||||
|
<entry>An unspecified value, except that equal arguments shall yield the same result.</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry>
|
||||||
|
<code>T val[N]</code>,
|
||||||
|
<code>const T val[N]</code>
|
||||||
|
</entry>
|
||||||
|
<entry><code>hash_range(val, val+N)</code></entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry>
|
||||||
|
<code>std:basic_string<Ch, std::char_traits<Ch>, A></code>,
|
||||||
|
<code>std::vector<T, A></code>,
|
||||||
|
<code>std::list<T, A></code>,
|
||||||
|
<code>std::deque<T, A></code>,
|
||||||
|
<code>std::set<K, C, A></code>,
|
||||||
|
<code>std::multiset<K, C, A></code>,
|
||||||
|
<code>std::map<K, T, C, A></code>,
|
||||||
|
<code>std::multimap<K, T, C, A></code>
|
||||||
|
</entry>
|
||||||
|
<entry><code>hash_range(val.begin(), val.end())</code></entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry><code>std::pair<A, B></code></entry>
|
||||||
|
<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>
|
||||||
|
</tbody>
|
||||||
|
</tgroup>
|
||||||
|
</informaltable>
|
||||||
|
</returns>
|
||||||
|
</overloaded-function>
|
||||||
|
</namespace>
|
||||||
|
</header>
|
||||||
|
</library-reference>
|
||||||
|
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
|
||||||
|
[/ Copyright 2005-2006 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:acknowledgements Acknowledgements]
|
||||||
|
|
||||||
|
This library is based on the design by Peter Dimov's original design.
|
||||||
|
|
||||||
|
During the initial development Joaquín M López Muñoz made many useful
|
||||||
|
suggestions, contributed fixes.
|
||||||
|
|
||||||
|
The formal review was managed by Thorsten Ottosen, and the library reviewed by:
|
||||||
|
David Abrahams, Alberto Barbati, Topher Cooper, Caleb Epstein, Dave Harris,
|
||||||
|
Chris Jefferson, Bronek Kozicki, John Maddock, Tobias Swinger, Jaap Suter, Rob
|
||||||
|
Stewart and Pavel Vozenilek. Since then, there have been further contributions
|
||||||
|
from Daniel Krügler, Alexander Nasonov, 沈慧峰 and John Maddock.
|
||||||
|
|
||||||
|
The implementation of the hash function for pointers is based on suggestions
|
||||||
|
made by Alberto Barbati and Dave Harris. Dave Harris also suggested an
|
||||||
|
important improvement to [funcref boost::hash_combine] that was taken up.
|
||||||
|
|
||||||
|
Some useful improvements to the floating point hash algorithm were suggested
|
||||||
|
by Daniel Krügler.
|
||||||
|
|
||||||
|
The original implementation came from Jeremy B. Maitin-Shepard's hash table
|
||||||
|
library, although this is a complete rewrite.
|
||||||
|
|
||||||
|
[endsect]
|
||||||
@@ -0,0 +1,202 @@
|
|||||||
|
|
||||||
|
[/ Copyright 2005-2006 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) ]
|
||||||
|
|
||||||
|
[def __multi-index-short__ [@../../libs/multi_index/doc/index.html
|
||||||
|
Boost.MultiIndex]]
|
||||||
|
|
||||||
|
[section:tutorial Tutorial]
|
||||||
|
|
||||||
|
When using a hash index with __multi-index-short__, you don't need to do
|
||||||
|
anything to use [classref boost::hash] as it uses it by default.
|
||||||
|
To find out how to use a user-defined type, read the
|
||||||
|
[link hash.custom section on extending boost::hash for a custom data type].
|
||||||
|
|
||||||
|
If your standard library supplies its own implementation of the unordered
|
||||||
|
associative containers and you wish to use
|
||||||
|
[classref boost::hash], just use an extra template parameter:
|
||||||
|
|
||||||
|
std::unordered_multiset<int, ``[classref boost::hash]``<int> >
|
||||||
|
set_of_ints;
|
||||||
|
|
||||||
|
std::unordered_set<std::pair<int, int>, ``[classref boost::hash]``<std::pair<int, int> >
|
||||||
|
set_of_pairs;
|
||||||
|
|
||||||
|
std::unordered_map<int, std::string, ``[classref boost::hash]``<int> > map_int_to_string;
|
||||||
|
|
||||||
|
To use [classref boost::hash] directly, create an instance and call it as a function:
|
||||||
|
|
||||||
|
#include <``[headerref boost/functional/hash.hpp]``>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
``[classref boost::hash]``<std::string> string_hash;
|
||||||
|
|
||||||
|
std::size_t h = string_hash("Hash me");
|
||||||
|
}
|
||||||
|
|
||||||
|
For an example of generic use, here is a function to generate a vector
|
||||||
|
containing the hashes of the elements of a container:
|
||||||
|
|
||||||
|
template <class Container>
|
||||||
|
std::vector<std::size_t> get_hashes(Container const& x)
|
||||||
|
{
|
||||||
|
std::vector<std::size_t> hashes;
|
||||||
|
std::transform(x.begin(), x.end(), std::insert_iterator(hashes),
|
||||||
|
``[classref boost::hash]``<typename Container::value_type>());
|
||||||
|
|
||||||
|
return hashes;
|
||||||
|
}
|
||||||
|
|
||||||
|
[endsect]
|
||||||
|
|
||||||
|
[section:custom Extending boost::hash for a custom data type]
|
||||||
|
|
||||||
|
[classref boost::hash] is implemented by calling the function
|
||||||
|
[funcref boost::hash_value hash_value].
|
||||||
|
The namespace isn't specified so that it can detect overloads via argument
|
||||||
|
dependant lookup. So if there is a free function `hash_value` in the same
|
||||||
|
namespace as a custom type, it will get called.
|
||||||
|
|
||||||
|
If you have a structure `library::book`, where each `book` is uniquely
|
||||||
|
defined by it's member `id`:
|
||||||
|
|
||||||
|
namespace library
|
||||||
|
{
|
||||||
|
struct book
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
std::string author;
|
||||||
|
std::string title;
|
||||||
|
|
||||||
|
// ....
|
||||||
|
};
|
||||||
|
|
||||||
|
bool operator==(book const& a, book const& b)
|
||||||
|
{
|
||||||
|
return a.id == b.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Then all you would need to do is write the function `library::hash_value`:
|
||||||
|
|
||||||
|
namespace library
|
||||||
|
{
|
||||||
|
std::size_t hash_value(book const& b)
|
||||||
|
{
|
||||||
|
``[classref boost::hash]``<int> hasher;
|
||||||
|
return hasher(b.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
And you can now use [classref boost::hash] with book:
|
||||||
|
|
||||||
|
library::book knife(3458, "Zane Grey", "The Hash Knife Outfit");
|
||||||
|
library::book dandelion(1354, "Paul J. Shanley",
|
||||||
|
"Hash & Dandelion Greens");
|
||||||
|
|
||||||
|
``[classref boost::hash]``<library::book> book_hasher;
|
||||||
|
std::size_t knife_hash_value = book_hasher(knife);
|
||||||
|
|
||||||
|
// If std::unordered_set is available:
|
||||||
|
std::unordered_set<library::book, ``[classref boost::hash]``<library::book> > books;
|
||||||
|
books.insert(knife);
|
||||||
|
books.insert(library::book(2443, "Lindgren, Torgny", "Hash"));
|
||||||
|
books.insert(library::book(1953, "Snyder, Bernadette M.",
|
||||||
|
"Heavenly Hash: A Tasty Mix of a Mother's Meditations"));
|
||||||
|
|
||||||
|
assert(books.find(knife) != books.end());
|
||||||
|
assert(books.find(dandelion) == books.end());
|
||||||
|
|
||||||
|
The full example can be found in:
|
||||||
|
[@../../libs/functional/hash/examples/books.cpp /libs/functional/hash/examples/books.hpp]
|
||||||
|
and
|
||||||
|
[@../../libs/functional/hash/examples/books.cpp /libs/functional/hash/examples/books.cpp].
|
||||||
|
|
||||||
|
[tip
|
||||||
|
When writing a hash function, first look at how the equality function works.
|
||||||
|
Objects that are equal must generate the same hash value.
|
||||||
|
When objects are not equal they should generate different hash values.
|
||||||
|
In this object equality was based just on the id so the hash function
|
||||||
|
only hash the id. If it was based on the objects name and author
|
||||||
|
then the hash function should take them into account
|
||||||
|
(how to do this is discussed in the next section).
|
||||||
|
]
|
||||||
|
|
||||||
|
[endsect]
|
||||||
|
|
||||||
|
[section:combine Combining hash values]
|
||||||
|
|
||||||
|
Say you have a point class, representing a two dimensional location:
|
||||||
|
|
||||||
|
class point
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
public:
|
||||||
|
point() : x(0), y(0) {}
|
||||||
|
point(int x, int y) : x(x), y(y) {}
|
||||||
|
|
||||||
|
bool operator==(point const& other) const
|
||||||
|
{
|
||||||
|
return x == other.x && y == other.y;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
and you wish to use it as the key for an `unordered_map`. You need to
|
||||||
|
customise the hash for this structure. To do this we need to combine
|
||||||
|
the hash values for `x` and `y`. The function
|
||||||
|
[funcref boost::hash_combine] is supplied for this purpose:
|
||||||
|
|
||||||
|
class point
|
||||||
|
{
|
||||||
|
...
|
||||||
|
|
||||||
|
friend std::size_t hash_value(point const& p)
|
||||||
|
{
|
||||||
|
std::size_t seed = 0;
|
||||||
|
``[funcref boost::hash_combine]``(seed, p.x);
|
||||||
|
``[funcref boost::hash_combine]``(seed, p.y);
|
||||||
|
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
...
|
||||||
|
};
|
||||||
|
|
||||||
|
Calls to hash_combine incrementally build the hash from the different members
|
||||||
|
of point, it can be repeatedly called for any number of elements. It calls
|
||||||
|
[funcref boost::hash_value hash_value] on the supplied element, and combines it with the seed.
|
||||||
|
|
||||||
|
Full code for this example is at
|
||||||
|
[@../../libs/functional/hash/examples/point.cpp /libs/functional/hash/examples/point.cpp].
|
||||||
|
|
||||||
|
[note
|
||||||
|
When using [funcref boost::hash_combine] the order of the
|
||||||
|
calls matters.
|
||||||
|
'''
|
||||||
|
<programlisting>
|
||||||
|
std::size_t seed = 0;
|
||||||
|
boost::hash_combine(seed, 1);
|
||||||
|
boost::hash_combine(seed, 2);
|
||||||
|
</programlisting>
|
||||||
|
results in a different seed to:
|
||||||
|
<programlisting>
|
||||||
|
std::size_t seed = 0;
|
||||||
|
boost::hash_combine(seed, 2);
|
||||||
|
boost::hash_combine(seed, 1);
|
||||||
|
</programlisting>
|
||||||
|
'''
|
||||||
|
If you are calculating a hash value for data where the order of the data
|
||||||
|
doesn't matter in comparisons (e.g. a set) you will have to ensure that the
|
||||||
|
data is always supplied in the same order.
|
||||||
|
]
|
||||||
|
|
||||||
|
To calculate the hash of an iterator range you can use [funcref boost::hash_range]:
|
||||||
|
|
||||||
|
std::vector<std::string> some_strings;
|
||||||
|
std::size_t hash = ``[funcref boost::hash_range]``(some_strings.begin(), some_strings.end());
|
||||||
|
|
||||||
|
[endsect]
|
||||||
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
# Copyright Daniel James 2005. Use, modification, and distribution are
|
||||||
|
# subject to 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)
|
||||||
|
|
||||||
|
run books.cpp ;
|
||||||
|
run point.cpp ;
|
||||||
|
run portable.cpp ;
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||||
|
// subject to 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 "./books.hpp"
|
||||||
|
#include <boost/functional/hash.hpp>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
// If std::unordered_set was available:
|
||||||
|
//#include <unordered_set>
|
||||||
|
|
||||||
|
// This example illustrates how to use boost::hash with a custom hash function.
|
||||||
|
// For full details, see the tutorial.
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
library::book knife(3458, "Zane Grey", "The Hash Knife Outfit");
|
||||||
|
library::book dandelion(1354, "Paul J. Shanley", "Hash & Dandelion Greens");
|
||||||
|
|
||||||
|
boost::hash<library::book> book_hasher;
|
||||||
|
std::size_t knife_hash_value = book_hasher(knife);
|
||||||
|
|
||||||
|
// If std::unordered_set was available:
|
||||||
|
//
|
||||||
|
//std::unordered_set<library::book, boost::hash<library::book> > books;
|
||||||
|
//books.insert(knife);
|
||||||
|
//books.insert(library::book(2443, "Lindgren, Torgny", "Hash"));
|
||||||
|
//books.insert(library::book(1953, "Snyder, Bernadette M.",
|
||||||
|
// "Heavenly Hash: A Tasty Mix of a Mother's Meditations"));
|
||||||
|
|
||||||
|
//assert(books.find(knife) != books.end());
|
||||||
|
//assert(books.find(dandelion) == books.end());
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace library
|
||||||
|
{
|
||||||
|
bool operator==(book const& a, book const& b)
|
||||||
|
{
|
||||||
|
return a.id == b.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t hash_value(book const& b)
|
||||||
|
{
|
||||||
|
boost::hash<int> hasher;
|
||||||
|
return hasher(b.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||||
|
// subject to 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 example illustrates how to use boost::hash with a custom hash function.
|
||||||
|
// The implementation is contained in books.cpp
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace library
|
||||||
|
{
|
||||||
|
struct book
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
std::string author;
|
||||||
|
std::string title;
|
||||||
|
|
||||||
|
book(int i, std::string const& a, std::string const& t)
|
||||||
|
: id(i), author(a), title(t) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
bool operator==(book const&, book const&);
|
||||||
|
std::size_t hash_value(book const&);
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2005. Use, modification, and distribution are
|
||||||
|
// subject to 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>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
// This example illustrates how to use boost::hash_combine to generate a hash
|
||||||
|
// value from the different members of a class. For full details see the hash
|
||||||
|
// tutorial.
|
||||||
|
|
||||||
|
class point
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
public:
|
||||||
|
point() : x(0), y(0) {}
|
||||||
|
point(int x, int y) : x(x), y(y) {}
|
||||||
|
|
||||||
|
bool operator==(point const& other) const
|
||||||
|
{
|
||||||
|
return x == other.x && y == other.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend std::size_t hash_value(point const& p)
|
||||||
|
{
|
||||||
|
std::size_t seed = 0;
|
||||||
|
boost::hash_combine(seed, p.x);
|
||||||
|
boost::hash_combine(seed, p.y);
|
||||||
|
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
boost::hash<point> point_hasher;
|
||||||
|
|
||||||
|
point p1(0, 0);
|
||||||
|
point p2(1, 2);
|
||||||
|
point p3(4, 1);
|
||||||
|
point p4 = p1;
|
||||||
|
|
||||||
|
assert(point_hasher(p1) == point_hasher(p4));
|
||||||
|
|
||||||
|
// These tests could legally fail, but if they did it'd be a pretty bad
|
||||||
|
// hash function.
|
||||||
|
assert(point_hasher(p1) != point_hasher(p2));
|
||||||
|
assert(point_hasher(p1) != point_hasher(p3));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||||
|
// subject to 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>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
// This example illustrates how to customise boost::hash portably, so that
|
||||||
|
// it'll work on both compilers that don't implement argument dependent lookup
|
||||||
|
// and compilers that implement strict two-phase template instantiation.
|
||||||
|
|
||||||
|
namespace foo
|
||||||
|
{
|
||||||
|
template <class T>
|
||||||
|
class custom_type
|
||||||
|
{
|
||||||
|
T value;
|
||||||
|
public:
|
||||||
|
custom_type(T x) : value(x) {}
|
||||||
|
|
||||||
|
std::size_t hash() const
|
||||||
|
{
|
||||||
|
boost::hash<T> hasher;
|
||||||
|
return hasher(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
|
||||||
|
namespace boost
|
||||||
|
#else
|
||||||
|
namespace foo
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
template <class T>
|
||||||
|
std::size_t hash_value(foo::custom_type<T> x)
|
||||||
|
{
|
||||||
|
return x.hash();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
foo::custom_type<int> x(1), y(2), z(1);
|
||||||
|
|
||||||
|
boost::hash<foo::custom_type<int> > hasher;
|
||||||
|
|
||||||
|
assert(hasher(x) == hasher(x));
|
||||||
|
assert(hasher(x) != hasher(y));
|
||||||
|
assert(hasher(x) == hasher(z));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||||
|
// subject to 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_HPP)
|
||||||
|
#define BOOST_DETAIL_CONTAINER_FWD_HPP
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/detail/workaround.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
|
||||||
|
|
||||||
|
#if (defined(__GLIBCXX__) && defined(_GLIBCXX_DEBUG)) \
|
||||||
|
|| BOOST_WORKAROUND(__BORLANDC__, > 0x551) \
|
||||||
|
|| BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x842)) \
|
||||||
|
|| (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION))
|
||||||
|
|
||||||
|
#include <deque>
|
||||||
|
#include <list>
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
#include <bitset>
|
||||||
|
#include <string>
|
||||||
|
#include <complex>
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
#if !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) && \
|
||||||
|
defined(__STL_CONFIG_H)
|
||||||
|
|
||||||
|
#define BOOST_CONTAINER_FWD_BAD_BITSET
|
||||||
|
|
||||||
|
#if !defined(__STL_NON_TYPE_TMPL_PARAM_BUG)
|
||||||
|
#define BOOST_CONTAINER_FWD_BAD_DEQUE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(BOOST_CONTAINER_FWD_BAD_DEQUE)
|
||||||
|
#include <deque>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(BOOST_CONTAINER_FWD_BAD_BITSET)
|
||||||
|
#include <bitset>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(BOOST_MSVC)
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable:4099) // struct/class mismatch in fwd declarations
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
template <class T> class allocator;
|
||||||
|
template <class charT, class traits, class Allocator> class basic_string;
|
||||||
|
template <class charT> struct BOOST_HASH_CHAR_TRAITS;
|
||||||
|
template <class T> class complex;
|
||||||
|
}
|
||||||
|
|
||||||
|
// gcc 3.4 and greater
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
#if !defined(BOOST_CONTAINER_FWD_BAD_DEQUE)
|
||||||
|
template <class T, class Allocator> class deque;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <class T, class Allocator> class list;
|
||||||
|
template <class T, class Allocator> class vector;
|
||||||
|
template <class Key, class T, class Compare, class Allocator> class map;
|
||||||
|
template <class Key, class T, class Compare, class Allocator>
|
||||||
|
class multimap;
|
||||||
|
template <class Key, class Compare, class Allocator> class set;
|
||||||
|
template <class Key, class Compare, class Allocator> class multiset;
|
||||||
|
|
||||||
|
#if !defined(BOOST_CONTAINER_FWD_BAD_BITSET)
|
||||||
|
template <size_t N> class bitset;
|
||||||
|
#endif
|
||||||
|
template <class T1, class T2> struct pair;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(BOOST_MSVC)
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,154 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||||
|
// subject to 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_FUNCTIONAL_DETAIL_FLOAT_FUNCTIONS_HPP)
|
||||||
|
#define BOOST_FUNCTIONAL_DETAIL_FLOAT_FUNCTIONS_HPP
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// The C++ standard requires that the C float functions are overloarded
|
||||||
|
// for float, double and long double in the std namespace, but some of the older
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
// Roguewave:
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
|
||||||
|
// libstdc++ (gcc 3.0 onwards, I think)
|
||||||
|
#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
|
||||||
|
# define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
// Dinkumware.
|
||||||
|
#elif (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER)
|
||||||
|
// Overloaded float functions were probably introduced in an earlier version
|
||||||
|
// than this.
|
||||||
|
# if defined(_CPPLIB_VER) && (_CPPLIB_VER >= 402)
|
||||||
|
# define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS
|
||||||
|
# else
|
||||||
|
# define BOOST_HASH_USE_C99_FLOAT_FUNCS
|
||||||
|
# endif
|
||||||
|
|
||||||
|
// Digital Mars
|
||||||
|
#elif defined(__DMC__)
|
||||||
|
# define BOOST_HASH_USE_C99_FLOAT_FUNCS
|
||||||
|
|
||||||
|
// Use overloaded float functions by default.
|
||||||
|
#else
|
||||||
|
# define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace hash_detail
|
||||||
|
{
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double call_ldexp(double v, int exp)
|
||||||
|
{
|
||||||
|
using namespace std;
|
||||||
|
return ldexp(v, exp);
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#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
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||||
|
// subject to 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)
|
||||||
|
|
||||||
|
// Based on Peter Dimov's proposal
|
||||||
|
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
|
||||||
|
// issue 6.18.
|
||||||
|
|
||||||
|
#if !defined(BOOST_FUNCTIONAL_DETAIL_HASH_FLOAT_HEADER)
|
||||||
|
#define BOOST_FUNCTIONAL_DETAIL_HASH_FLOAT_HEADER
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/functional/detail/float_functions.hpp>
|
||||||
|
#include <boost/limits.hpp>
|
||||||
|
#include <boost/assert.hpp>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
// Don't use fpclassify or _fpclass for stlport.
|
||||||
|
#if !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
|
||||||
|
# if defined(__GLIBCPP__) || defined(__GLIBCXX__)
|
||||||
|
// GNU libstdc++ 3
|
||||||
|
# if (defined(__USE_ISOC99) || defined(_GLIBCXX_USE_C99_MATH)) && \
|
||||||
|
!(defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__))
|
||||||
|
# define BOOST_HASH_USE_FPCLASSIFY
|
||||||
|
# endif
|
||||||
|
# elif (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER)
|
||||||
|
// Dinkumware Library, on Visual C++
|
||||||
|
# if defined(BOOST_MSVC)
|
||||||
|
# define BOOST_HASH_USE_FPCLASS
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace hash_detail
|
||||||
|
{
|
||||||
|
inline void hash_float_combine(std::size_t& seed, std::size_t value)
|
||||||
|
{
|
||||||
|
seed ^= value + (seed<<6) + (seed>>2);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline std::size_t float_hash_impl(T v)
|
||||||
|
{
|
||||||
|
int exp = 0;
|
||||||
|
errno = 0;
|
||||||
|
v = boost::hash_detail::call_frexp(v, &exp);
|
||||||
|
if(errno) return 0;
|
||||||
|
|
||||||
|
std::size_t seed = 0;
|
||||||
|
|
||||||
|
std::size_t const length
|
||||||
|
= (std::numeric_limits<T>::digits +
|
||||||
|
std::numeric_limits<int>::digits - 1)
|
||||||
|
/ std::numeric_limits<int>::digits;
|
||||||
|
|
||||||
|
for(std::size_t i = 0; i < length; ++i)
|
||||||
|
{
|
||||||
|
v = boost::hash_detail::call_ldexp(v, std::numeric_limits<int>::digits);
|
||||||
|
int const part = static_cast<int>(v);
|
||||||
|
v -= part;
|
||||||
|
hash_float_combine(seed, part);
|
||||||
|
}
|
||||||
|
|
||||||
|
hash_float_combine(seed, exp);
|
||||||
|
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
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:
|
||||||
|
return 0;
|
||||||
|
case FP_INFINITE:
|
||||||
|
return (std::size_t)(v > 0 ? -1 : -2);
|
||||||
|
case FP_NAN:
|
||||||
|
return (std::size_t)(-3);
|
||||||
|
case FP_NORMAL:
|
||||||
|
case FP_SUBNORMAL:
|
||||||
|
return float_hash_impl(v);
|
||||||
|
default:
|
||||||
|
BOOST_ASSERT(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#elif defined(BOOST_HASH_USE_FPCLASS)
|
||||||
|
switch(_fpclass(v)) {
|
||||||
|
case _FPCLASS_NZ:
|
||||||
|
case _FPCLASS_PZ:
|
||||||
|
return 0;
|
||||||
|
case _FPCLASS_PINF:
|
||||||
|
return (std::size_t)(-1);
|
||||||
|
case _FPCLASS_NINF:
|
||||||
|
return (std::size_t)(-2);
|
||||||
|
case _FPCLASS_SNAN:
|
||||||
|
case _FPCLASS_QNAN:
|
||||||
|
return (std::size_t)(-3);
|
||||||
|
case _FPCLASS_NN:
|
||||||
|
case _FPCLASS_ND:
|
||||||
|
return float_hash_impl(v);
|
||||||
|
case _FPCLASS_PD:
|
||||||
|
case _FPCLASS_PN:
|
||||||
|
return float_hash_impl(v);
|
||||||
|
default:
|
||||||
|
BOOST_ASSERT(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
return float_hash_impl(v);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||||
|
// subject to 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)
|
||||||
|
|
||||||
|
// Based on Peter Dimov's proposal
|
||||||
|
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
|
||||||
|
// issue 6.18.
|
||||||
|
|
||||||
|
#include <boost/functional/hash/hash.hpp>
|
||||||
@@ -0,0 +1,592 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||||
|
// subject to 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)
|
||||||
|
|
||||||
|
// Based on Peter Dimov's proposal
|
||||||
|
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
|
||||||
|
// issue 6.18.
|
||||||
|
|
||||||
|
#if !defined(BOOST_FUNCTIONAL_HASH_HASH_HPP)
|
||||||
|
#define BOOST_FUNCTIONAL_HASH_HASH_HPP
|
||||||
|
|
||||||
|
#include <boost/functional/hash_fwd.hpp>
|
||||||
|
#include <functional>
|
||||||
|
#include <boost/functional/detail/hash_float.hpp>
|
||||||
|
#include <boost/functional/detail/container_fwd.hpp>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#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>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||||
|
#include <boost/type_traits/is_const.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||||
|
// Borland complains about an ambiguous function overload
|
||||||
|
// when compiling boost::hash<bool>.
|
||||||
|
std::size_t hash_value(bool);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
#if defined(BOOST_MSVC) && defined(_WIN64)
|
||||||
|
// On 64-bit windows std::size_t is a typedef for unsigned long long, which
|
||||||
|
// isn't due to be supported until Boost 1.35. So add support here.
|
||||||
|
// (Technically, Boost.Hash isn't actually documented as supporting
|
||||||
|
// std::size_t. But it would be pretty silly not to).
|
||||||
|
std::size_t hash_value(std::size_t);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !BOOST_WORKAROUND(__DMC__, <= 0x848)
|
||||||
|
template <class T> std::size_t hash_value(T* const&);
|
||||||
|
#else
|
||||||
|
template <class T> std::size_t hash_value(T*);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
|
||||||
|
template< class T, unsigned N >
|
||||||
|
std::size_t hash_value(const T (&array)[N]);
|
||||||
|
|
||||||
|
template< class T, unsigned N >
|
||||||
|
std::size_t hash_value(T (&array)[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&);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
// Implementation
|
||||||
|
|
||||||
|
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||||
|
inline std::size_t hash_value(bool v)
|
||||||
|
{
|
||||||
|
return static_cast<std::size_t>(v);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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(_M_X64) && defined(_WIN64)
|
||||||
|
inline std::size_t hash_value(long long v)
|
||||||
|
{
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::size_t hash_value(unsigned long long v)
|
||||||
|
{
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Implementation by Alberto Barbati and Dave Harris.
|
||||||
|
#if !BOOST_WORKAROUND(__DMC__, <= 0x848)
|
||||||
|
template <class T> std::size_t hash_value(T* const& v)
|
||||||
|
#else
|
||||||
|
template <class T> std::size_t hash_value(T* v)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
std::size_t x = static_cast<std::size_t>(
|
||||||
|
reinterpret_cast<std::ptrdiff_t>(v));
|
||||||
|
return x + (x >> 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||||
|
template <class T>
|
||||||
|
inline void hash_combine(std::size_t& seed, T& v)
|
||||||
|
#else
|
||||||
|
template <class T>
|
||||||
|
inline void hash_combine(std::size_t& seed, T const& v)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
boost::hash<T> hasher;
|
||||||
|
seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class It>
|
||||||
|
inline std::size_t hash_range(It first, It last)
|
||||||
|
{
|
||||||
|
std::size_t seed = 0;
|
||||||
|
|
||||||
|
for(; first != last; ++first)
|
||||||
|
{
|
||||||
|
hash_combine(seed, *first);
|
||||||
|
}
|
||||||
|
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class It>
|
||||||
|
inline void hash_range(std::size_t& seed, It first, It last)
|
||||||
|
{
|
||||||
|
for(; first != last; ++first)
|
||||||
|
{
|
||||||
|
hash_combine(seed, *first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||||
|
template <class T>
|
||||||
|
inline std::size_t hash_range(T* first, T* last)
|
||||||
|
{
|
||||||
|
std::size_t seed = 0;
|
||||||
|
|
||||||
|
for(; first != last; ++first)
|
||||||
|
{
|
||||||
|
boost::hash<T> hasher;
|
||||||
|
seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline void hash_range(std::size_t& seed, T* first, T* last)
|
||||||
|
{
|
||||||
|
for(; first != last; ++first)
|
||||||
|
{
|
||||||
|
boost::hash<T> hasher;
|
||||||
|
seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
|
||||||
|
template< class T, unsigned N >
|
||||||
|
inline std::size_t hash_value(const T (&array)[N])
|
||||||
|
{
|
||||||
|
return hash_range(array, array + N);
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class T, unsigned N >
|
||||||
|
inline std::size_t hash_value(T (&array)[N])
|
||||||
|
{
|
||||||
|
return hash_range(array, array + N);
|
||||||
|
}
|
||||||
|
#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)
|
||||||
|
{
|
||||||
|
return hash_range(v.begin(), v.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::size_t hash_value(float v)
|
||||||
|
{
|
||||||
|
return boost::hash_detail::float_hash_value(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::size_t hash_value(double 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());
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// boost::hash
|
||||||
|
//
|
||||||
|
|
||||||
|
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||||
|
#define BOOST_HASH_SPECIALIZE(type) \
|
||||||
|
template <> struct hash<type> \
|
||||||
|
: public std::unary_function<type, std::size_t> \
|
||||||
|
{ \
|
||||||
|
std::size_t operator()(type v) const \
|
||||||
|
{ \
|
||||||
|
return boost::hash_value(v); \
|
||||||
|
} \
|
||||||
|
};
|
||||||
|
|
||||||
|
#define BOOST_HASH_SPECIALIZE_REF(type) \
|
||||||
|
template <> struct hash<type> \
|
||||||
|
: public std::unary_function<type, std::size_t> \
|
||||||
|
{ \
|
||||||
|
std::size_t operator()(type const& v) const \
|
||||||
|
{ \
|
||||||
|
return boost::hash_value(v); \
|
||||||
|
} \
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
#define BOOST_HASH_SPECIALIZE(type) \
|
||||||
|
template <> struct hash<type> \
|
||||||
|
: public std::unary_function<type, std::size_t> \
|
||||||
|
{ \
|
||||||
|
std::size_t operator()(type v) const \
|
||||||
|
{ \
|
||||||
|
return boost::hash_value(v); \
|
||||||
|
} \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
template <> struct hash<const type> \
|
||||||
|
: public std::unary_function<const type, std::size_t> \
|
||||||
|
{ \
|
||||||
|
std::size_t operator()(const type v) const \
|
||||||
|
{ \
|
||||||
|
return boost::hash_value(v); \
|
||||||
|
} \
|
||||||
|
};
|
||||||
|
|
||||||
|
#define BOOST_HASH_SPECIALIZE_REF(type) \
|
||||||
|
template <> struct hash<type> \
|
||||||
|
: public std::unary_function<type, std::size_t> \
|
||||||
|
{ \
|
||||||
|
std::size_t operator()(type const& v) const \
|
||||||
|
{ \
|
||||||
|
return boost::hash_value(v); \
|
||||||
|
} \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
template <> struct hash<const type> \
|
||||||
|
: public std::unary_function<const type, std::size_t> \
|
||||||
|
{ \
|
||||||
|
std::size_t operator()(type const& v) const \
|
||||||
|
{ \
|
||||||
|
return boost::hash_value(v); \
|
||||||
|
} \
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
BOOST_HASH_SPECIALIZE(bool)
|
||||||
|
BOOST_HASH_SPECIALIZE(char)
|
||||||
|
BOOST_HASH_SPECIALIZE(signed char)
|
||||||
|
BOOST_HASH_SPECIALIZE(unsigned char)
|
||||||
|
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
|
||||||
|
BOOST_HASH_SPECIALIZE(wchar_t)
|
||||||
|
#endif
|
||||||
|
BOOST_HASH_SPECIALIZE(short)
|
||||||
|
BOOST_HASH_SPECIALIZE(unsigned short)
|
||||||
|
BOOST_HASH_SPECIALIZE(int)
|
||||||
|
BOOST_HASH_SPECIALIZE(unsigned int)
|
||||||
|
BOOST_HASH_SPECIALIZE(long)
|
||||||
|
BOOST_HASH_SPECIALIZE(unsigned long)
|
||||||
|
|
||||||
|
BOOST_HASH_SPECIALIZE(float)
|
||||||
|
BOOST_HASH_SPECIALIZE(double)
|
||||||
|
BOOST_HASH_SPECIALIZE(long double)
|
||||||
|
|
||||||
|
BOOST_HASH_SPECIALIZE_REF(std::string)
|
||||||
|
#if !defined(BOOST_NO_STD_WSTRING)
|
||||||
|
BOOST_HASH_SPECIALIZE_REF(std::wstring)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef BOOST_HASH_SPECIALIZE
|
||||||
|
#undef BOOST_HASH_SPECIALIZE_REF
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||||
|
template <class T>
|
||||||
|
struct hash<T*>
|
||||||
|
: public std::unary_function<T*, std::size_t>
|
||||||
|
{
|
||||||
|
std::size_t operator()(T* v) const \
|
||||||
|
{ \
|
||||||
|
return boost::hash_value(v); \
|
||||||
|
} \
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
namespace hash_detail
|
||||||
|
{
|
||||||
|
template <bool IsPointer>
|
||||||
|
struct hash_impl;
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct hash_impl<true>
|
||||||
|
{
|
||||||
|
template <class T>
|
||||||
|
struct inner
|
||||||
|
: public std::unary_function<T, std::size_t>
|
||||||
|
{
|
||||||
|
std::size_t operator()(T val) const
|
||||||
|
{
|
||||||
|
return boost::hash_value(val);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T> struct hash
|
||||||
|
: public boost::hash_detail::hash_impl<boost::is_pointer<T>::value>
|
||||||
|
::BOOST_NESTED_TEMPLATE inner<T>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // BOOST_FUNCTIONAL_HASH_HASH_HPP
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#if !defined(BOOST_HASH_NO_EXTENSIONS) \
|
||||||
|
&& !defined(BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP)
|
||||||
|
#define BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
|
||||||
|
namespace hash_detail
|
||||||
|
{
|
||||||
|
template <bool IsArray>
|
||||||
|
struct call_hash_impl
|
||||||
|
{
|
||||||
|
template <class T>
|
||||||
|
struct inner
|
||||||
|
{
|
||||||
|
static std::size_t call(T const& v)
|
||||||
|
{
|
||||||
|
using namespace boost;
|
||||||
|
return hash_value(v);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct call_hash_impl<true>
|
||||||
|
{
|
||||||
|
template <class Array>
|
||||||
|
struct inner
|
||||||
|
{
|
||||||
|
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||||
|
static std::size_t call(Array const& v)
|
||||||
|
#else
|
||||||
|
static std::size_t call(Array& v)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
const int size = sizeof(v) / sizeof(*v);
|
||||||
|
return boost::hash_range(v, v + size);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct call_hash
|
||||||
|
: public call_hash_impl<boost::is_array<T>::value>
|
||||||
|
::BOOST_NESTED_TEMPLATE inner<T>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||||
|
|
||||||
|
template <class T> struct hash
|
||||||
|
: std::unary_function<T, std::size_t>
|
||||||
|
{
|
||||||
|
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
|
||||||
|
std::size_t operator()(T const& val) const
|
||||||
|
{
|
||||||
|
return hash_value(val);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
std::size_t operator()(T const& val) const
|
||||||
|
{
|
||||||
|
return hash_detail::call_hash<T>::call(val);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#if BOOST_WORKAROUND(__DMC__, <= 0x848)
|
||||||
|
template <class T, unsigned int n> struct hash<T[n]>
|
||||||
|
: std::unary_function<T[n], std::size_t>
|
||||||
|
{
|
||||||
|
std::size_t operator()(const T* val) const
|
||||||
|
{
|
||||||
|
return boost::hash_range(val, val+n);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
namespace hash_detail
|
||||||
|
{
|
||||||
|
template <bool IsPointer>
|
||||||
|
struct hash_impl;
|
||||||
|
|
||||||
|
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct hash_impl<false>
|
||||||
|
{
|
||||||
|
template <class T>
|
||||||
|
struct inner
|
||||||
|
: std::unary_function<T, std::size_t>
|
||||||
|
{
|
||||||
|
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
|
||||||
|
std::size_t operator()(T const& val) const
|
||||||
|
{
|
||||||
|
return hash_value(val);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
std::size_t operator()(T const& val) const
|
||||||
|
{
|
||||||
|
return hash_detail::call_hash<T>::call(val);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#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.
|
||||||
|
|
||||||
|
template <bool IsConst>
|
||||||
|
struct hash_impl_msvc
|
||||||
|
{
|
||||||
|
template <class T>
|
||||||
|
struct inner
|
||||||
|
: public std::unary_function<T, std::size_t>
|
||||||
|
{
|
||||||
|
std::size_t operator()(T const& val) const
|
||||||
|
{
|
||||||
|
return hash_detail::call_hash<T const>::call(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t operator()(T& val) const
|
||||||
|
{
|
||||||
|
return hash_detail::call_hash<T>::call(val);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct hash_impl_msvc<true>
|
||||||
|
{
|
||||||
|
template <class T>
|
||||||
|
struct inner
|
||||||
|
: public std::unary_function<T, std::size_t>
|
||||||
|
{
|
||||||
|
std::size_t operator()(T& val) const
|
||||||
|
{
|
||||||
|
return hash_detail::call_hash<T>::call(val);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct hash_impl_msvc2
|
||||||
|
: public hash_impl_msvc<boost::is_const<T>::value>
|
||||||
|
::BOOST_NESTED_TEMPLATE inner<T> {};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct hash_impl<false>
|
||||||
|
{
|
||||||
|
template <class T>
|
||||||
|
struct inner : public hash_impl_msvc2<T> {};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // Visual C++ 6.5
|
||||||
|
}
|
||||||
|
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||||
|
// subject to 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)
|
||||||
|
|
||||||
|
// Based on Peter Dimov's proposal
|
||||||
|
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
|
||||||
|
// issue 6.18.
|
||||||
|
|
||||||
|
#if !defined(BOOST_FUNCTIONAL_HASH_FWD_HPP)
|
||||||
|
#define BOOST_FUNCTIONAL_HASH_FWD_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <boost/detail/workaround.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
template <class T> struct hash;
|
||||||
|
|
||||||
|
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||||
|
template <class T> void hash_combine(std::size_t& seed, T& v);
|
||||||
|
#else
|
||||||
|
template <class T> void hash_combine(std::size_t& seed, T const& v);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <class It> std::size_t hash_range(It, It);
|
||||||
|
template <class It> void hash_range(std::size_t&, It, It);
|
||||||
|
|
||||||
|
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||||
|
template <class T> inline std::size_t hash_range(T*, T*);
|
||||||
|
template <class T> inline void hash_range(std::size_t&, T*, T*);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
<!--
|
||||||
|
Copyright 2005-2006 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)
|
||||||
|
-->
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="refresh" content="0; URL=../../doc/html/hash.html">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
Automatic redirection failed, please go to
|
||||||
|
<a href="../../doc/html/hash.html">../../doc/html/hash.html</a>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
|
||||||
|
# Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||||
|
# subject to 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)
|
||||||
|
|
||||||
|
import testing ;
|
||||||
|
|
||||||
|
project hash-tests
|
||||||
|
: requirements
|
||||||
|
<toolset>gcc:<define>_GLIBCXX_DEBUG
|
||||||
|
;
|
||||||
|
|
||||||
|
test-suite functional/hash
|
||||||
|
:
|
||||||
|
[ run hash_fwd_test_1.cpp ]
|
||||||
|
[ run hash_fwd_test_2.cpp ]
|
||||||
|
[ run hash_number_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_string_test.cpp ]
|
||||||
|
[ run hash_range_test.cpp ]
|
||||||
|
[ run hash_custom_test.cpp ]
|
||||||
|
[ run hash_global_namespace_test.cpp ]
|
||||||
|
[ run hash_friend_test.cpp ]
|
||||||
|
[ run hash_built_in_array_test.cpp ]
|
||||||
|
[ run hash_value_array_test.cpp ]
|
||||||
|
[ run hash_vector_test.cpp ]
|
||||||
|
[ run hash_list_test.cpp ]
|
||||||
|
[ run hash_deque_test.cpp ]
|
||||||
|
[ run hash_set_test.cpp ]
|
||||||
|
[ run hash_map_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 ]
|
||||||
|
[ compile-fail hash_no_ext_fail_test.cpp ]
|
||||||
|
[ run hash_no_ext_macro_1.cpp ]
|
||||||
|
[ run hash_no_ext_macro_2.cpp ]
|
||||||
|
;
|
||||||
|
|
||||||
|
build-project ../examples ;
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||||
|
// subject to 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/config.hpp>
|
||||||
|
#include <boost/static_assert.hpp>
|
||||||
|
#include <boost/type_traits/is_base_and_derived.hpp>
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void compile_time_tests(T*)
|
||||||
|
{
|
||||||
|
BOOST_STATIC_ASSERT((boost::is_base_and_derived<
|
||||||
|
std::unary_function<T, std::size_t>, HASH_NAMESPACE::hash<T> >::value));
|
||||||
|
};
|
||||||
|
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||||
|
// subject to 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(TEST_STD)
|
||||||
|
# define TEST_STD_INCLUDES
|
||||||
|
# define HASH_NAMESPACE std::tr1
|
||||||
|
#else
|
||||||
|
# define HASH_NAMESPACE boost
|
||||||
|
# if !defined(BOOST_HASH_NO_EXTENSIONS)
|
||||||
|
# define TEST_EXTENSIONS
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||||
|
// subject to 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;
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||||
|
// subject to 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/detail/lightweight_test.hpp>
|
||||||
|
|
||||||
|
#ifdef TEST_EXTENSIONS
|
||||||
|
|
||||||
|
void array_int_test()
|
||||||
|
{
|
||||||
|
const int length1 = 25;
|
||||||
|
int array1[25] = {
|
||||||
|
26, -43, 32, 65, 45,
|
||||||
|
12, 67, 32, 12, 23,
|
||||||
|
0, 0, 0, 0, 0,
|
||||||
|
8, -12, 23, 65, 45,
|
||||||
|
-1, 93, -54, 987, 3
|
||||||
|
};
|
||||||
|
HASH_NAMESPACE::hash<int[25]> hasher1;
|
||||||
|
|
||||||
|
const int length2 = 1;
|
||||||
|
int array2[1] = {3};
|
||||||
|
HASH_NAMESPACE::hash<int[1]> hasher2;
|
||||||
|
|
||||||
|
const int length3 = 2;
|
||||||
|
int array3[2] = {2, 3};
|
||||||
|
HASH_NAMESPACE::hash<int[2]> hasher3;
|
||||||
|
|
||||||
|
BOOST_TEST(hasher1(array1)
|
||||||
|
== HASH_NAMESPACE::hash_range(array1, array1 + length1));
|
||||||
|
BOOST_TEST(hasher2(array2)
|
||||||
|
== HASH_NAMESPACE::hash_range(array2, array2 + length2));
|
||||||
|
BOOST_TEST(hasher3(array3)
|
||||||
|
== HASH_NAMESPACE::hash_range(array3, array3 + length3));
|
||||||
|
}
|
||||||
|
|
||||||
|
void two_dimensional_array_test()
|
||||||
|
{
|
||||||
|
int array[3][2] = {{-5, 6}, {7, -3}, {26, 1}};
|
||||||
|
HASH_NAMESPACE::hash<int[3][2]> hasher;
|
||||||
|
|
||||||
|
std::size_t seed1 = 0;
|
||||||
|
for(int i = 0; i < 3; ++i)
|
||||||
|
{
|
||||||
|
std::size_t seed2 = 0;
|
||||||
|
for(int j = 0; j < 2; ++j)
|
||||||
|
HASH_NAMESPACE::hash_combine(seed2, array[i][j]);
|
||||||
|
HASH_NAMESPACE::hash_combine(seed1, seed2);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_TEST(hasher(array) == seed1);
|
||||||
|
BOOST_TEST(hasher(array) == HASH_NAMESPACE::hash_range(array, array + 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // TEST_EXTENSIONS
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
#ifdef TEST_EXTENSIONS
|
||||||
|
array_int_test();
|
||||||
|
two_dimensional_array_test();
|
||||||
|
#endif
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||||
|
// subject to 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/config.hpp>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
namespace test
|
||||||
|
{
|
||||||
|
struct custom
|
||||||
|
{
|
||||||
|
int value_;
|
||||||
|
|
||||||
|
std::size_t hash() const
|
||||||
|
{
|
||||||
|
return value_ * 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
||||||
|
friend std::size_t hash_value(custom const& x )
|
||||||
|
{
|
||||||
|
return x.hash();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
custom(int x) : value_(x) {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
std::size_t hash_value(test::custom x)
|
||||||
|
{
|
||||||
|
return x.hash();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "./config.hpp"
|
||||||
|
|
||||||
|
#ifdef TEST_EXTENSIONS
|
||||||
|
# ifdef TEST_STD_INCLUDES
|
||||||
|
# include <functional>
|
||||||
|
# else
|
||||||
|
# include <boost/functional/hash.hpp>
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
|
|
||||||
|
#ifdef TEST_EXTENSIONS
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <cctype>
|
||||||
|
|
||||||
|
void custom_tests()
|
||||||
|
{
|
||||||
|
HASH_NAMESPACE::hash<test::custom> custom_hasher;
|
||||||
|
BOOST_TEST(custom_hasher(10) == 100u);
|
||||||
|
test::custom x(55);
|
||||||
|
BOOST_TEST(custom_hasher(x) == 550u);
|
||||||
|
|
||||||
|
{
|
||||||
|
using namespace HASH_NAMESPACE;
|
||||||
|
BOOST_TEST(custom_hasher(x) == hash_value(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<test::custom> custom_vector;
|
||||||
|
custom_vector.push_back(5);
|
||||||
|
custom_vector.push_back(25);
|
||||||
|
custom_vector.push_back(35);
|
||||||
|
|
||||||
|
std::size_t seed = 0;
|
||||||
|
HASH_NAMESPACE::hash_combine(seed, test::custom(5));
|
||||||
|
HASH_NAMESPACE::hash_combine(seed, test::custom(25));
|
||||||
|
HASH_NAMESPACE::hash_combine(seed, test::custom(35));
|
||||||
|
|
||||||
|
std::size_t seed2 = 0;
|
||||||
|
HASH_NAMESPACE::hash_combine(seed2, 50u);
|
||||||
|
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 == seed2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // TEST_EXTENSIONS
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
#ifdef TEST_EXTENSIONS
|
||||||
|
custom_tests();
|
||||||
|
#endif
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||||
|
// subject to 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/detail/lightweight_test.hpp>
|
||||||
|
|
||||||
|
#ifdef TEST_EXTENSIONS
|
||||||
|
|
||||||
|
#include <deque>
|
||||||
|
|
||||||
|
using std::deque;
|
||||||
|
#define CONTAINER_TYPE deque
|
||||||
|
#include "./hash_sequence_test.hpp"
|
||||||
|
|
||||||
|
#endif // TEST_EXTENSIONS
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
#ifdef TEST_EXTENSIONS
|
||||||
|
deque_tests::deque_hash_integer_tests();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
@@ -0,0 +1,228 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||||
|
// subject to 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 <cmath>
|
||||||
|
#include <boost/limits.hpp>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void float_tests(char const* name, T* = 0)
|
||||||
|
{
|
||||||
|
std::cerr<<"\n"
|
||||||
|
<<"Testing " BOOST_STRINGIZE(HASH_NAMESPACE) "::hash<"<<name<<">\n"
|
||||||
|
<<"\n"
|
||||||
|
<<"std::numeric_limits<T>::digits = "
|
||||||
|
<<std::numeric_limits<T>::digits<<"\n"
|
||||||
|
<<"std::numeric_limits<int>::digits = "
|
||||||
|
<<std::numeric_limits<int>::digits<<"\n"
|
||||||
|
<<"std::numeric_limits<std::size_t>::digits = "
|
||||||
|
<<std::numeric_limits<std::size_t>::digits<<"\n"
|
||||||
|
<<"\n"
|
||||||
|
;
|
||||||
|
|
||||||
|
HASH_NAMESPACE::hash<T> x1;
|
||||||
|
|
||||||
|
T zero = 0;
|
||||||
|
T minus_zero = (T) -1 * zero;
|
||||||
|
|
||||||
|
BOOST_TEST(zero == minus_zero);
|
||||||
|
BOOST_TEST(x1(zero) == x1(minus_zero));
|
||||||
|
|
||||||
|
BOOST_TEST(x1(zero) == HASH_NAMESPACE::hash_value(zero));
|
||||||
|
BOOST_TEST(x1(minus_zero) == HASH_NAMESPACE::hash_value(minus_zero));
|
||||||
|
|
||||||
|
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";
|
||||||
|
#else
|
||||||
|
if(std::numeric_limits<T>::has_infinity) {
|
||||||
|
T infinity = -log(zero);
|
||||||
|
T infinity2 = (T) 1. / zero;
|
||||||
|
T infinity3 = (T) -1. / minus_zero;
|
||||||
|
T infinity4 = std::numeric_limits<T>::infinity();
|
||||||
|
|
||||||
|
T minus_infinity = log(zero);
|
||||||
|
T minus_infinity2 = (T) -1. / zero;
|
||||||
|
T minus_infinity3 = (T) 1. / minus_zero;
|
||||||
|
|
||||||
|
BOOST_TEST(x1(infinity) == HASH_NAMESPACE::hash_value(infinity));
|
||||||
|
BOOST_TEST(x1(minus_infinity)
|
||||||
|
== HASH_NAMESPACE::hash_value(minus_infinity));
|
||||||
|
|
||||||
|
if(infinity == infinity2)
|
||||||
|
BOOST_TEST(x1(infinity) == x1(infinity2));
|
||||||
|
if(infinity == infinity3);
|
||||||
|
BOOST_TEST(x1(infinity) == x1(infinity3));
|
||||||
|
if(infinity == infinity4)
|
||||||
|
BOOST_TEST(x1(infinity) == x1(infinity4));
|
||||||
|
|
||||||
|
if(minus_infinity == minus_infinity2)
|
||||||
|
BOOST_TEST(x1(minus_infinity) == x1(minus_infinity2));
|
||||||
|
if(minus_infinity == minus_infinity3)
|
||||||
|
BOOST_TEST(x1(minus_infinity) == x1(minus_infinity3));
|
||||||
|
|
||||||
|
BOOST_TEST(infinity != minus_infinity);
|
||||||
|
|
||||||
|
if(x1(infinity) == x1(minus_infinity)) {
|
||||||
|
std::cerr<<"x1(infinity) == x1(-infinity) == "<<x1(infinity)<<"\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// This should really be 'has_denorm == denorm_present' but some
|
||||||
|
// compilers don't have 'denorm_present'. See also a later use.
|
||||||
|
if(std::numeric_limits<T>::has_denorm) {
|
||||||
|
if(x1(std::numeric_limits<T>::denorm_min()) == x1(infinity)) {
|
||||||
|
std::cerr<<"x1(denorm_min) == x1(infinity) == "<<x1(infinity)<<"\n";
|
||||||
|
}
|
||||||
|
if(x1(std::numeric_limits<T>::denorm_min()) == x1(minus_infinity)) {
|
||||||
|
std::cerr<<"x1(denorm_min) == x1(-infinity) == "<<x1(minus_infinity)<<"\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(std::numeric_limits<T>::has_quiet_NaN) {
|
||||||
|
if(x1(std::numeric_limits<T>::quiet_NaN()) == x1(infinity)) {
|
||||||
|
std::cerr<<"x1(quiet_NaN) == x1(infinity) == "<<x1(infinity)<<"\n";
|
||||||
|
}
|
||||||
|
if(x1(std::numeric_limits<T>::quiet_NaN()) == x1(minus_infinity)) {
|
||||||
|
std::cerr<<"x1(quiet_NaN) == x1(-infinity) == "<<x1(minus_infinity)<<"\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
T max = (std::numeric_limits<T>::max)();
|
||||||
|
T half_max = max / 2;
|
||||||
|
T quarter_max = max / 4;
|
||||||
|
T three_quarter_max = max - quarter_max;
|
||||||
|
|
||||||
|
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));
|
||||||
|
|
||||||
|
// 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));
|
||||||
|
BOOST_TEST(x1(max) != x1(three_quarter_max));
|
||||||
|
BOOST_TEST(x1(quarter_max) == x1(quarter_max));
|
||||||
|
BOOST_TEST(x1(quarter_max) != x1(half_max));
|
||||||
|
BOOST_TEST(x1(quarter_max) != x1(three_quarter_max));
|
||||||
|
BOOST_TEST(x1(half_max) == x1(half_max));
|
||||||
|
BOOST_TEST(x1(half_max) != x1(three_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)) && \
|
||||||
|
(defined(__GLIBCPP__) || defined(__GLIBCXX__)))
|
||||||
|
T v1 = asin((T) 1);
|
||||||
|
T v2 = acos((T) 0);
|
||||||
|
if(v1 == v2)
|
||||||
|
BOOST_TEST(x1(v1) == x1(v2));
|
||||||
|
BOOST_TEST(x1(v1) == HASH_NAMESPACE::hash_value(v1));
|
||||||
|
BOOST_TEST(x1(v2) == HASH_NAMESPACE::hash_value(v2));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
BOOST_TEST(x1(std::numeric_limits<T>::epsilon()) ==
|
||||||
|
HASH_NAMESPACE::hash_value(std::numeric_limits<T>::epsilon()));
|
||||||
|
|
||||||
|
BOOST_TEST(std::numeric_limits<T>::epsilon() != (T) 0);
|
||||||
|
if(x1(std::numeric_limits<T>::epsilon()) == x1((T) 0))
|
||||||
|
std::cerr<<"x1(epsilon) == x1(0) == "<<x1((T) 0)<<"\n";
|
||||||
|
|
||||||
|
BOOST_TEST(-std::numeric_limits<T>::epsilon() != (T) 0);
|
||||||
|
if(x1(-std::numeric_limits<T>::epsilon()) == x1((T) 0))
|
||||||
|
std::cerr<<"x1(-epsilon) == x1(0) == "<<x1((T) 0)<<"\n";
|
||||||
|
|
||||||
|
BOOST_TEST((T) 1 + std::numeric_limits<T>::epsilon() != (T) 1);
|
||||||
|
if(x1((T) 1 + std::numeric_limits<T>::epsilon()) == x1((T) 1))
|
||||||
|
std::cerr<<"x1(1 + epsilon) == x1(1) == "<<x1((T) 1)<<"\n";
|
||||||
|
|
||||||
|
BOOST_TEST((T) 1 - std::numeric_limits<T>::epsilon() != (T) 1);
|
||||||
|
if(x1((T) 1 - std::numeric_limits<T>::epsilon()) == x1((T) 1))
|
||||||
|
std::cerr<<"x1(1 - epsilon) == x1(1) == "<<x1((T) 1)<<"\n";
|
||||||
|
|
||||||
|
BOOST_TEST((T) -1 + std::numeric_limits<T>::epsilon() != (T) -1);
|
||||||
|
if(x1((T) -1 + std::numeric_limits<T>::epsilon()) == x1((T) -1))
|
||||||
|
std::cerr<<"x1(-1 + epsilon) == x1(-1) == "<<x1((T) -1)<<"\n";
|
||||||
|
|
||||||
|
BOOST_TEST((T) -1 - std::numeric_limits<T>::epsilon() != (T) -1);
|
||||||
|
if(x1((T) -1 - std::numeric_limits<T>::epsilon()) == x1((T) -1))
|
||||||
|
std::cerr<<"x1(-1 - epsilon) == x1(-1) == "<<x1((T) -1)<<"\n";
|
||||||
|
|
||||||
|
// As before.
|
||||||
|
if(std::numeric_limits<T>::has_denorm) {
|
||||||
|
if(x1(std::numeric_limits<T>::denorm_min()) == x1(zero)) {
|
||||||
|
std::cerr<<"x1(denorm_min) == x1(zero) == "<<x1(zero)<<"\n";
|
||||||
|
}
|
||||||
|
#if !BOOST_WORKAROUND(__DECCXX_VER,<70190006)
|
||||||
|
// The Tru64/CXX standard library prior to 7.1 contains a bug in the
|
||||||
|
// specialization of std::numeric_limits::denorm_min() for long
|
||||||
|
// doubles which causes this test to fail.
|
||||||
|
if(x1(std::numeric_limits<T>::denorm_min()) !=
|
||||||
|
HASH_NAMESPACE::hash_value(std::numeric_limits<T>::denorm_min()))
|
||||||
|
{
|
||||||
|
std::cerr<<"x1(std::numeric_limits<T>::denorm_min()) = "
|
||||||
|
<< x1(std::numeric_limits<T>::denorm_min())
|
||||||
|
<< "\nhash_value(std::numeric_limits<T>::denorm_min()) = "
|
||||||
|
<< HASH_NAMESPACE::hash_value(
|
||||||
|
std::numeric_limits<T>::denorm_min())
|
||||||
|
<< "\nx1(0) = "<<x1(0)<<"\n";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// NaN also causes borland to crash.
|
||||||
|
#if !defined(__BORLANDC__)
|
||||||
|
if(std::numeric_limits<T>::has_quiet_NaN) {
|
||||||
|
if(x1(std::numeric_limits<T>::quiet_NaN()) == x1(1.0)) {
|
||||||
|
std::cerr<<"x1(quiet_NaN) == x1(1.0) == "<<x1(1.0)<<"\n";
|
||||||
|
}
|
||||||
|
BOOST_TEST(x1(std::numeric_limits<T>::quiet_NaN()) ==
|
||||||
|
HASH_NAMESPACE::hash_value(std::numeric_limits<T>::quiet_NaN()));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void hash_float_tests()
|
||||||
|
{
|
||||||
|
std::cerr<<"Compiler: "<<BOOST_COMPILER<<"\n";
|
||||||
|
std::cerr<<"Platform: "<<BOOST_PLATFORM<<"\n";
|
||||||
|
std::cerr<<"Library: "<<BOOST_STDLIB<<"\n\n";
|
||||||
|
|
||||||
|
float_tests("float", (float*) 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hash_double_tests()
|
||||||
|
{
|
||||||
|
float_tests("double", (double*) 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hash_long_double_tests()
|
||||||
|
{
|
||||||
|
float_tests("long double", (long double*) 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
hash_float_tests();
|
||||||
|
hash_double_tests();
|
||||||
|
hash_long_double_tests();
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2006. Use, modification, and distribution are
|
||||||
|
// subject to 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/config.hpp>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
namespace test
|
||||||
|
{
|
||||||
|
template <class T>
|
||||||
|
struct custom
|
||||||
|
{
|
||||||
|
int value_;
|
||||||
|
|
||||||
|
std::size_t hash() const
|
||||||
|
{
|
||||||
|
return value_ * 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
||||||
|
friend std::size_t hash_value(custom const& x)
|
||||||
|
{
|
||||||
|
return x.hash();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
custom(int x) : value_(x) {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
template <class T>
|
||||||
|
std::size_t hash_value(test::custom<T> x)
|
||||||
|
{
|
||||||
|
return x.hash();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "./config.hpp"
|
||||||
|
|
||||||
|
#ifdef TEST_EXTENSIONS
|
||||||
|
# ifdef TEST_STD_INCLUDES
|
||||||
|
# include <functional>
|
||||||
|
# else
|
||||||
|
# include <boost/functional/hash.hpp>
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
|
|
||||||
|
#ifdef TEST_EXTENSIONS
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <cctype>
|
||||||
|
|
||||||
|
void custom_tests()
|
||||||
|
{
|
||||||
|
HASH_NAMESPACE::hash<test::custom<int> > custom_hasher;
|
||||||
|
BOOST_TEST(custom_hasher(10) == 100u);
|
||||||
|
test::custom<int> x(55);
|
||||||
|
BOOST_TEST(custom_hasher(x) == 550u);
|
||||||
|
|
||||||
|
{
|
||||||
|
using namespace HASH_NAMESPACE;
|
||||||
|
BOOST_TEST(custom_hasher(x) == hash_value(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<test::custom<int> > custom_vector;
|
||||||
|
custom_vector.push_back(5);
|
||||||
|
custom_vector.push_back(25);
|
||||||
|
custom_vector.push_back(35);
|
||||||
|
|
||||||
|
std::size_t seed = 0;
|
||||||
|
HASH_NAMESPACE::hash_combine(seed, test::custom<int>(5));
|
||||||
|
HASH_NAMESPACE::hash_combine(seed, test::custom<int>(25));
|
||||||
|
HASH_NAMESPACE::hash_combine(seed, test::custom<int>(35));
|
||||||
|
|
||||||
|
std::size_t seed2 = 0;
|
||||||
|
HASH_NAMESPACE::hash_combine(seed2, 50u);
|
||||||
|
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 == seed2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // TEST_EXTENSIONS
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
#ifdef TEST_EXTENSIONS
|
||||||
|
custom_tests();
|
||||||
|
#endif
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||||
|
// subject to 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 <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; }
|
||||||
|
void void_func2() { static int x = 2; --x; }
|
||||||
|
int int_func1(int) { return 0; }
|
||||||
|
int int_func2(int) { return 1; }
|
||||||
|
|
||||||
|
void function_pointer_tests()
|
||||||
|
{
|
||||||
|
compile_time_tests((void(**)()) 0);
|
||||||
|
compile_time_tests((int(**)(int)) 0);
|
||||||
|
|
||||||
|
HASH_NAMESPACE::hash<void(*)()> hasher_void;
|
||||||
|
HASH_NAMESPACE::hash<int(*)(int)> hasher_int;
|
||||||
|
|
||||||
|
BOOST_TEST(&void_func1 != &void_func2);
|
||||||
|
BOOST_TEST(&int_func1 != &int_func2);
|
||||||
|
|
||||||
|
BOOST_TEST(hasher_void(0) == hasher_void(0));
|
||||||
|
BOOST_TEST(hasher_void(&void_func1) == hasher_void(&void_func1));
|
||||||
|
BOOST_TEST(hasher_void(&void_func1) != hasher_void(&void_func2));
|
||||||
|
BOOST_TEST(hasher_void(&void_func1) != hasher_void(0));
|
||||||
|
BOOST_TEST(hasher_int(0) == hasher_int(0));
|
||||||
|
BOOST_TEST(hasher_int(&int_func1) == hasher_int(&int_func1));
|
||||||
|
BOOST_TEST(hasher_int(&int_func1) != hasher_int(&int_func2));
|
||||||
|
BOOST_TEST(hasher_int(&int_func1) != hasher_int(0));
|
||||||
|
#if defined(TEST_EXTENSIONS)
|
||||||
|
BOOST_TEST(hasher_void(&void_func1)
|
||||||
|
== HASH_NAMESPACE::hash_value(&void_func1));
|
||||||
|
BOOST_TEST(hasher_int(&int_func1)
|
||||||
|
== HASH_NAMESPACE::hash_value(&int_func1));
|
||||||
|
|
||||||
|
// This isn't specified in Peter's proposal:
|
||||||
|
BOOST_TEST(hasher_void(0) == 0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
function_pointer_tests();
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2006. Use, modification, and distribution are
|
||||||
|
// subject to 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"
|
||||||
|
|
||||||
|
#if defined(TEST_EXTENSIONS) && !defined(TEST_STD_INCLUDES)
|
||||||
|
#include <boost/functional/hash_fwd.hpp>
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace test {
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct test_type1
|
||||||
|
{
|
||||||
|
T value;
|
||||||
|
test_type1(T const& x) : value(x) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
||||||
|
template <class T>
|
||||||
|
std::size_t hash_value(test_type1<T> const& x)
|
||||||
|
{
|
||||||
|
HASH_NAMESPACE::hash<T> hasher;
|
||||||
|
return hasher(x.value);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct test_type2
|
||||||
|
{
|
||||||
|
T value1, value2;
|
||||||
|
test_type2(T const& x, T const& y) : value1(x), value2(y) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
||||||
|
template <class T>
|
||||||
|
std::size_t hash_value(test_type2<T> const& x)
|
||||||
|
{
|
||||||
|
std::size_t seed = 0;
|
||||||
|
HASH_NAMESPACE::hash_combine(seed, x.value1);
|
||||||
|
HASH_NAMESPACE::hash_combine(seed, x.value2);
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct test_type3
|
||||||
|
{
|
||||||
|
std::vector<T> values;
|
||||||
|
test_type3(typename std::vector<T>::iterator x,
|
||||||
|
typename std::vector<T>::iterator y) : values(x, y) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
||||||
|
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());
|
||||||
|
HASH_NAMESPACE::hash_range(seed, x.values.begin(), x.values.end());
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
template <class T>
|
||||||
|
std::size_t hash_value(test::test_type1<T> const& x)
|
||||||
|
{
|
||||||
|
HASH_NAMESPACE::hash<T> hasher;
|
||||||
|
return hasher(x.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
std::size_t hash_value(test::test_type2<T> const& x)
|
||||||
|
{
|
||||||
|
std::size_t seed = 0;
|
||||||
|
HASH_NAMESPACE::hash_combine(seed, x.value1);
|
||||||
|
HASH_NAMESPACE::hash_combine(seed, x.value2);
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
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());
|
||||||
|
HASH_NAMESPACE::hash_range(seed, x.values.begin(), x.values.end());
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2006. Use, modification, and distribution are
|
||||||
|
// subject to 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 checks that template code implemented using hash_fwd will work.
|
||||||
|
|
||||||
|
#include "./hash_fwd_test.hpp"
|
||||||
|
|
||||||
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
|
|
||||||
|
#if defined(TEST_EXTENSIONS) && !defined(TEST_STD_INCLUDES)
|
||||||
|
|
||||||
|
#include <boost/functional/hash.hpp>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
void fwd_test1()
|
||||||
|
{
|
||||||
|
test::test_type1<int> x(5);
|
||||||
|
test::test_type1<std::string> y("Test");
|
||||||
|
|
||||||
|
HASH_NAMESPACE::hash<int> hasher_int;
|
||||||
|
HASH_NAMESPACE::hash<std::string> hasher_string;
|
||||||
|
HASH_NAMESPACE::hash<test::test_type1<int> > hasher_test_int;
|
||||||
|
HASH_NAMESPACE::hash<test::test_type1<std::string> > hasher_test_string;
|
||||||
|
|
||||||
|
BOOST_TEST(hasher_int(5) == hasher_test_int(x));
|
||||||
|
BOOST_TEST(hasher_string("Test") == hasher_test_string(y));
|
||||||
|
}
|
||||||
|
|
||||||
|
void fwd_test2()
|
||||||
|
{
|
||||||
|
test::test_type2<int> x(5, 10);
|
||||||
|
test::test_type2<std::string> y("Test1", "Test2");
|
||||||
|
|
||||||
|
std::size_t seed1 = 0;
|
||||||
|
HASH_NAMESPACE::hash_combine(seed1, 5);
|
||||||
|
HASH_NAMESPACE::hash_combine(seed1, 10);
|
||||||
|
|
||||||
|
std::size_t seed2 = 0;
|
||||||
|
HASH_NAMESPACE::hash_combine(seed2, std::string("Test1"));
|
||||||
|
HASH_NAMESPACE::hash_combine(seed2, std::string("Test2"));
|
||||||
|
|
||||||
|
HASH_NAMESPACE::hash<test::test_type2<int> > hasher_test_int;
|
||||||
|
HASH_NAMESPACE::hash<test::test_type2<std::string> > hasher_test_string;
|
||||||
|
|
||||||
|
BOOST_TEST(seed1 == hasher_test_int(x));
|
||||||
|
BOOST_TEST(seed2 == hasher_test_string(y));
|
||||||
|
}
|
||||||
|
|
||||||
|
void fwd_test3()
|
||||||
|
{
|
||||||
|
std::vector<int> values1;
|
||||||
|
values1.push_back(10);
|
||||||
|
values1.push_back(15);
|
||||||
|
values1.push_back(20);
|
||||||
|
values1.push_back(3);
|
||||||
|
|
||||||
|
std::vector<std::string> values2;
|
||||||
|
values2.push_back("Chico");
|
||||||
|
values2.push_back("Groucho");
|
||||||
|
values2.push_back("Harpo");
|
||||||
|
values2.push_back("Gummo");
|
||||||
|
values2.push_back("Zeppo");
|
||||||
|
|
||||||
|
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());
|
||||||
|
HASH_NAMESPACE::hash_range(seed1, values1.begin(), values1.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;
|
||||||
|
HASH_NAMESPACE::hash<test::test_type3<std::string> > hasher_test_string;
|
||||||
|
|
||||||
|
BOOST_TEST(seed1 == hasher_test_int(x));
|
||||||
|
BOOST_TEST(seed2 == hasher_test_string(y));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
#ifdef TEST_EXTENSIONS
|
||||||
|
fwd_test1();
|
||||||
|
fwd_test2();
|
||||||
|
fwd_test3();
|
||||||
|
#endif
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2006. Use, modification, and distribution are
|
||||||
|
// subject to 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 test just makes sure a header which uses hash_fwd can compile without
|
||||||
|
// the main hash headers.
|
||||||
|
|
||||||
|
#include "./hash_fwd_test.hpp"
|
||||||
|
|
||||||
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
|
|
||||||
|
template <class T> void unused(T const&) {}
|
||||||
|
|
||||||
|
void fwd_test()
|
||||||
|
{
|
||||||
|
test::test_type1<int> x1(3);
|
||||||
|
test::test_type1<std::string> y1("Black");
|
||||||
|
test::test_type2<int> x2(25, 16);
|
||||||
|
test::test_type2<std::string> y2("White", "Green");
|
||||||
|
|
||||||
|
std::vector<int> empty;
|
||||||
|
std::vector<std::string> empty2;
|
||||||
|
|
||||||
|
test::test_type3<int> x3(empty.begin(), empty.end());
|
||||||
|
test::test_type3<std::string> y3(empty2.begin(), empty2.end());
|
||||||
|
|
||||||
|
// Prevent gcc warnings:
|
||||||
|
unused(x1); unused(x2); unused(x3);
|
||||||
|
unused(y1); unused(y2); unused(y3);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
fwd_test();
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2006. Use, modification, and distribution are
|
||||||
|
// subject to 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 test demonstrates an ADL bug in Borland 5.5 where ADL isn't performed
|
||||||
|
// in the global namespace.
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
struct custom
|
||||||
|
{
|
||||||
|
int value_;
|
||||||
|
|
||||||
|
std::size_t hash() const
|
||||||
|
{
|
||||||
|
return value_ * 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
||||||
|
friend std::size_t hash_value(custom const& x )
|
||||||
|
{
|
||||||
|
return x.hash();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
custom(int x) : value_(x) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
std::size_t hash_value(custom x)
|
||||||
|
{
|
||||||
|
return x.hash();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "./config.hpp"
|
||||||
|
|
||||||
|
#ifdef TEST_EXTENSIONS
|
||||||
|
# ifdef TEST_STD_INCLUDES
|
||||||
|
# include <functional>
|
||||||
|
# else
|
||||||
|
# include <boost/functional/hash/hash.hpp>
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
|
|
||||||
|
#ifdef TEST_EXTENSIONS
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <cctype>
|
||||||
|
|
||||||
|
void custom_tests()
|
||||||
|
{
|
||||||
|
HASH_NAMESPACE::hash<custom> custom_hasher;
|
||||||
|
BOOST_TEST(custom_hasher(10) == 100u);
|
||||||
|
custom x(55);
|
||||||
|
BOOST_TEST(custom_hasher(x) == 550u);
|
||||||
|
|
||||||
|
{
|
||||||
|
using namespace HASH_NAMESPACE;
|
||||||
|
BOOST_TEST(custom_hasher(x) == hash_value(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<custom> custom_vector;
|
||||||
|
custom_vector.push_back(5);
|
||||||
|
custom_vector.push_back(25);
|
||||||
|
custom_vector.push_back(35);
|
||||||
|
|
||||||
|
std::size_t seed = 0;
|
||||||
|
HASH_NAMESPACE::hash_combine(seed, custom(5));
|
||||||
|
HASH_NAMESPACE::hash_combine(seed, custom(25));
|
||||||
|
HASH_NAMESPACE::hash_combine(seed, custom(35));
|
||||||
|
|
||||||
|
std::size_t seed2 = 0;
|
||||||
|
HASH_NAMESPACE::hash_combine(seed2, 50u);
|
||||||
|
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 == seed2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // TEST_EXTENSIONS
|
||||||
|
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
#ifdef TEST_EXTENSIONS
|
||||||
|
custom_tests();
|
||||||
|
#endif
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||||
|
// subject to 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/detail/lightweight_test.hpp>
|
||||||
|
|
||||||
|
#ifdef TEST_EXTENSIONS
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
using std::list;
|
||||||
|
#define CONTAINER_TYPE list
|
||||||
|
#include "./hash_sequence_test.hpp"
|
||||||
|
|
||||||
|
#endif // TEST_EXTENSIONS
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
#ifdef TEST_EXTENSIONS
|
||||||
|
list_tests::list_hash_integer_tests();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||||
|
// subject to 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/detail/lightweight_test.hpp>
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#ifdef TEST_EXTENSIONS
|
||||||
|
|
||||||
|
using std::map;
|
||||||
|
#define CONTAINER_TYPE map
|
||||||
|
#include "./hash_map_test.hpp"
|
||||||
|
|
||||||
|
using std::multimap;
|
||||||
|
#define CONTAINER_TYPE multimap
|
||||||
|
#include "./hash_map_test.hpp"
|
||||||
|
|
||||||
|
#endif // TEST_EXTENSTIONS
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
#ifdef TEST_EXTENSIONS
|
||||||
|
map_tests::map_hash_integer_tests();
|
||||||
|
multimap_tests::multimap_hash_integer_tests();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||||
|
// subject to 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(CONTAINER_TYPE)
|
||||||
|
#error "CONTAINER_TYPE not defined"
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <boost/preprocessor/cat.hpp>
|
||||||
|
|
||||||
|
namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
|
||||||
|
{
|
||||||
|
template <class T>
|
||||||
|
void integer_tests(T* = 0)
|
||||||
|
{
|
||||||
|
const int number_of_containers = 10;
|
||||||
|
T containers[number_of_containers];
|
||||||
|
typedef typename T::value_type pair;
|
||||||
|
|
||||||
|
for(int i = 0; i < 5; ++i) {
|
||||||
|
for(int j = 0; j < i; ++j)
|
||||||
|
containers[i].insert(pair(0, 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));
|
||||||
|
|
||||||
|
HASH_NAMESPACE::hash<T> hasher;
|
||||||
|
|
||||||
|
for(int i2 = 0; i2 < number_of_containers; ++i2) {
|
||||||
|
BOOST_TEST(hasher(containers[i2]) == hasher(containers[i2]));
|
||||||
|
|
||||||
|
BOOST_TEST(hasher(containers[i2]) ==
|
||||||
|
HASH_NAMESPACE::hash_value(containers[i2]));
|
||||||
|
|
||||||
|
BOOST_TEST(hasher(containers[i2])
|
||||||
|
== HASH_NAMESPACE::hash_range(
|
||||||
|
containers[i2].begin(), containers[i2].end()));
|
||||||
|
|
||||||
|
for(int j2 = i2 + 1; j2 < number_of_containers; ++j2) {
|
||||||
|
BOOST_TEST(
|
||||||
|
(containers[i2] == containers[j2]) ==
|
||||||
|
(hasher(containers[i2]) == hasher(containers[j2]))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BOOST_PP_CAT(CONTAINER_TYPE, _hash_integer_tests())
|
||||||
|
{
|
||||||
|
integer_tests((CONTAINER_TYPE<char, unsigned char>*) 0);
|
||||||
|
integer_tests((CONTAINER_TYPE<int, float>*) 0);
|
||||||
|
integer_tests((CONTAINER_TYPE<unsigned long, unsigned long>*) 0);
|
||||||
|
integer_tests((CONTAINER_TYPE<double, short>*) 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef CONTAINER_TYPE
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2006. Use, modification, and distribution are
|
||||||
|
// subject to 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
|
||||||
|
|
||||||
|
// Simple test to make sure BOOST_HASH_NO_EXTENSIONS does disable extensions
|
||||||
|
// (or at least one of them).
|
||||||
|
#define BOOST_HASH_NO_EXTENSIONS
|
||||||
|
|
||||||
|
#include <boost/functional/hash.hpp>
|
||||||
|
#include <boost/functional/hash.hpp>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
HASH_NAMESPACE::hash< int[10] > hasher;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2006. Use, modification, and distribution are
|
||||||
|
// subject to 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 <boost/detail/lightweight_test.hpp>
|
||||||
|
#include <deque>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
std::deque<int> x;
|
||||||
|
|
||||||
|
x.push_back(1);
|
||||||
|
x.push_back(2);
|
||||||
|
|
||||||
|
HASH_NAMESPACE::hash<std::deque<int> > hasher;
|
||||||
|
BOOST_TEST(hasher(x) == HASH_NAMESPACE::hash_value(x));
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2006. Use, modification, and distribution are
|
||||||
|
// subject to 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 <boost/detail/lightweight_test.hpp>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
std::map<int, int> x;
|
||||||
|
|
||||||
|
x.insert(std::map<int, int>::value_type(53, -42));
|
||||||
|
x.insert(std::map<int, int>::value_type(14, -75));
|
||||||
|
|
||||||
|
HASH_NAMESPACE::hash<std::map<int, int> > hasher;
|
||||||
|
BOOST_TEST(hasher(x) == HASH_NAMESPACE::hash_value(x));
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||||
|
// subject to 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 <iostream>
|
||||||
|
#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 "./compile_time.hpp"
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void numeric_test(T*)
|
||||||
|
{
|
||||||
|
typedef std::numeric_limits<T> limits;
|
||||||
|
|
||||||
|
compile_time_tests((T*) 0);
|
||||||
|
|
||||||
|
HASH_NAMESPACE::hash<T> x1;
|
||||||
|
HASH_NAMESPACE::hash<T> x2;
|
||||||
|
|
||||||
|
T v1 = -5;
|
||||||
|
BOOST_TEST(x1(v1) == x2(v1));
|
||||||
|
BOOST_TEST(x1(T(-5)) == x2(T(-5)));
|
||||||
|
BOOST_TEST(x1(T(0)) == x2(T(0)));
|
||||||
|
BOOST_TEST(x1(T(10)) == x2(T(10)));
|
||||||
|
BOOST_TEST(x1(T(25)) == x2(T(25)));
|
||||||
|
BOOST_TEST(x1(T(5) - T(5)) == x2(T(0)));
|
||||||
|
BOOST_TEST(x1(T(6) + T(4)) == x2(T(10)));
|
||||||
|
|
||||||
|
#if defined(TEST_EXTENSIONS)
|
||||||
|
BOOST_TEST(x1(T(-5)) == HASH_NAMESPACE::hash_value(T(-5)));
|
||||||
|
BOOST_TEST(x1(T(0)) == HASH_NAMESPACE::hash_value(T(0)));
|
||||||
|
BOOST_TEST(x1(T(10)) == HASH_NAMESPACE::hash_value(T(10)));
|
||||||
|
BOOST_TEST(x1(T(25)) == HASH_NAMESPACE::hash_value(T(25)));
|
||||||
|
|
||||||
|
if (limits::is_integer)
|
||||||
|
{
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void limits_test(T*)
|
||||||
|
{
|
||||||
|
typedef std::numeric_limits<T> limits;
|
||||||
|
|
||||||
|
if(limits::is_specialized)
|
||||||
|
{
|
||||||
|
HASH_NAMESPACE::hash<T> x1;
|
||||||
|
HASH_NAMESPACE::hash<T> x2;
|
||||||
|
|
||||||
|
T min_value = (limits::min)();
|
||||||
|
T max_value = (limits::max)();
|
||||||
|
|
||||||
|
BOOST_TEST(x1(min_value) == x2((limits::min)()));
|
||||||
|
BOOST_TEST(x1(max_value) == x2((limits::max)()));
|
||||||
|
|
||||||
|
#if defined(TEST_EXTENSIONS)
|
||||||
|
BOOST_TEST(x1(min_value) == HASH_NAMESPACE::hash_value(min_value));
|
||||||
|
BOOST_TEST(x1(max_value) == HASH_NAMESPACE::hash_value(max_value));
|
||||||
|
|
||||||
|
if (limits::is_integer)
|
||||||
|
{
|
||||||
|
BOOST_TEST(HASH_NAMESPACE::hash_value(min_value)
|
||||||
|
== std::size_t(min_value));
|
||||||
|
BOOST_TEST(HASH_NAMESPACE::hash_value(max_value)
|
||||||
|
== std::size_t(max_value));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void poor_quality_tests(T*)
|
||||||
|
{
|
||||||
|
typedef std::numeric_limits<T> limits;
|
||||||
|
|
||||||
|
HASH_NAMESPACE::hash<T> x1;
|
||||||
|
HASH_NAMESPACE::hash<T> x2;
|
||||||
|
|
||||||
|
// A hash function can legally fail these tests, but it'll not be a good
|
||||||
|
// sign.
|
||||||
|
if(T(1) != T(-1))
|
||||||
|
BOOST_TEST(x1(T(1)) != x2(T(-1)));
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define NUMERIC_TEST(type, name) \
|
||||||
|
std::cerr<<"Testing: " BOOST_STRINGIZE(name) "\n"; \
|
||||||
|
numeric_test((type*) 0); \
|
||||||
|
limits_test((type*) 0); \
|
||||||
|
poor_quality_tests((type*) 0);
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
NUMERIC_TEST(bool, bool)
|
||||||
|
NUMERIC_TEST(char, char)
|
||||||
|
NUMERIC_TEST(signed char, schar)
|
||||||
|
NUMERIC_TEST(unsigned char, uchar)
|
||||||
|
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
|
||||||
|
NUMERIC_TEST(wchar_t, wchar)
|
||||||
|
#endif
|
||||||
|
NUMERIC_TEST(short, short)
|
||||||
|
NUMERIC_TEST(unsigned short, ushort)
|
||||||
|
NUMERIC_TEST(int, int)
|
||||||
|
NUMERIC_TEST(unsigned int, uint)
|
||||||
|
NUMERIC_TEST(long, hash_long)
|
||||||
|
NUMERIC_TEST(unsigned long, ulong)
|
||||||
|
|
||||||
|
NUMERIC_TEST(float, float)
|
||||||
|
NUMERIC_TEST(double, double)
|
||||||
|
NUMERIC_TEST(long double, ldouble)
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||||
|
// subject to 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 <boost/limits.hpp>
|
||||||
|
#include <boost/mpl/assert.hpp>
|
||||||
|
#include <boost/type_traits/is_base_and_derived.hpp>
|
||||||
|
|
||||||
|
#include "./compile_time.hpp"
|
||||||
|
|
||||||
|
void pointer_tests()
|
||||||
|
{
|
||||||
|
compile_time_tests((int**) 0);
|
||||||
|
compile_time_tests((void**) 0);
|
||||||
|
|
||||||
|
HASH_NAMESPACE::hash<int*> x1;
|
||||||
|
HASH_NAMESPACE::hash<int*> x2;
|
||||||
|
|
||||||
|
int int1;
|
||||||
|
int int2;
|
||||||
|
|
||||||
|
BOOST_TEST(x1(0) == x2(0));
|
||||||
|
BOOST_TEST(x1(&int1) == x2(&int1));
|
||||||
|
BOOST_TEST(x1(&int2) == x2(&int2));
|
||||||
|
#if defined(TEST_EXTENSIONS)
|
||||||
|
BOOST_TEST(x1(&int1) == HASH_NAMESPACE::hash_value(&int1));
|
||||||
|
BOOST_TEST(x1(&int2) == HASH_NAMESPACE::hash_value(&int2));
|
||||||
|
|
||||||
|
// This isn't specified in Peter's proposal:
|
||||||
|
BOOST_TEST(x1(0) == 0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
pointer_tests();
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||||
|
// subject to 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/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()
|
||||||
|
{
|
||||||
|
std::vector<int> empty, values1, values2, values3, values4, values5;
|
||||||
|
values1.push_back(0);
|
||||||
|
values2.push_back(10);
|
||||||
|
values3.push_back(10);
|
||||||
|
values3.push_back(20);
|
||||||
|
values4.push_back(15);
|
||||||
|
values4.push_back(75);
|
||||||
|
values5.push_back(10);
|
||||||
|
values5.push_back(20);
|
||||||
|
values5.push_back(15);
|
||||||
|
values5.push_back(75);
|
||||||
|
values5.push_back(10);
|
||||||
|
values5.push_back(20);
|
||||||
|
|
||||||
|
std::vector<int> x;
|
||||||
|
|
||||||
|
std::size_t x_seed = 0;
|
||||||
|
BOOST_TEST(x_seed == HASH_NAMESPACE::hash_range(x.begin(), x.end()));
|
||||||
|
|
||||||
|
BOOST_TEST(HASH_NAMESPACE::hash_range(empty.begin(), empty.end())
|
||||||
|
== HASH_NAMESPACE::hash_range(x.begin(), x.end()));
|
||||||
|
BOOST_TEST(HASH_NAMESPACE::hash_range(empty.begin(), empty.end())
|
||||||
|
!= HASH_NAMESPACE::hash_range(values1.begin(), values1.end()));
|
||||||
|
|
||||||
|
x.push_back(10);
|
||||||
|
HASH_NAMESPACE::hash_combine(x_seed, 10);
|
||||||
|
BOOST_TEST(x_seed == HASH_NAMESPACE::hash_range(x.begin(), x.end()));
|
||||||
|
|
||||||
|
BOOST_TEST(HASH_NAMESPACE::hash_range(empty.begin(), empty.end())
|
||||||
|
!= HASH_NAMESPACE::hash_range(x.begin(), x.end()));
|
||||||
|
BOOST_TEST(HASH_NAMESPACE::hash_range(values2.begin(), values2.end())
|
||||||
|
== HASH_NAMESPACE::hash_range(x.begin(), x.end()));
|
||||||
|
|
||||||
|
x.push_back(20);
|
||||||
|
HASH_NAMESPACE::hash_combine(x_seed, 20);
|
||||||
|
BOOST_TEST(x_seed == HASH_NAMESPACE::hash_range(x.begin(), x.end()));
|
||||||
|
|
||||||
|
BOOST_TEST(HASH_NAMESPACE::hash_range(empty.begin(), empty.end())
|
||||||
|
!= HASH_NAMESPACE::hash_range(x.begin(), x.end()));
|
||||||
|
BOOST_TEST(HASH_NAMESPACE::hash_range(values2.begin(), values2.end())
|
||||||
|
!= HASH_NAMESPACE::hash_range(x.begin(), x.end()));
|
||||||
|
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());
|
||||||
|
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()));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
hash_range_tests();
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||||
|
// subject to 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(CONTAINER_TYPE)
|
||||||
|
#error "CONTAINER_TYPE not defined"
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <boost/preprocessor/cat.hpp>
|
||||||
|
|
||||||
|
namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
|
||||||
|
{
|
||||||
|
template <class T>
|
||||||
|
void integer_tests(T* = 0)
|
||||||
|
{
|
||||||
|
const int number_of_containers = 11;
|
||||||
|
T containers[number_of_containers];
|
||||||
|
|
||||||
|
for(int i = 0; i < 5; ++i) {
|
||||||
|
for(int j = 0; j < i; ++j)
|
||||||
|
containers[i].push_back(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
containers[5].push_back(1);
|
||||||
|
containers[6].push_back(1);
|
||||||
|
containers[6].push_back(1);
|
||||||
|
containers[7].push_back(-1);
|
||||||
|
containers[8].push_back(-1);
|
||||||
|
containers[8].push_back(-1);
|
||||||
|
containers[9].push_back(1);
|
||||||
|
containers[9].push_back(-1);
|
||||||
|
containers[10].push_back(-1);
|
||||||
|
containers[10].push_back(1);
|
||||||
|
|
||||||
|
HASH_NAMESPACE::hash<T> hasher;
|
||||||
|
|
||||||
|
for(int i2 = 0; i2 < number_of_containers; ++i2) {
|
||||||
|
BOOST_TEST(hasher(containers[i2]) == hasher(containers[i2]));
|
||||||
|
|
||||||
|
BOOST_TEST(hasher(containers[i2]) ==
|
||||||
|
HASH_NAMESPACE::hash_value(containers[i2]));
|
||||||
|
|
||||||
|
BOOST_TEST(hasher(containers[i2])
|
||||||
|
== HASH_NAMESPACE::hash_range(
|
||||||
|
containers[i2].begin(), containers[i2].end()));
|
||||||
|
|
||||||
|
for(int j2 = i2 + 1; j2 < number_of_containers; ++j2) {
|
||||||
|
BOOST_TEST(
|
||||||
|
(containers[i2] == containers[j2]) ==
|
||||||
|
(hasher(containers[i2]) == hasher(containers[j2]))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BOOST_PP_CAT(CONTAINER_TYPE, _hash_integer_tests())
|
||||||
|
{
|
||||||
|
integer_tests((CONTAINER_TYPE<char>*) 0);
|
||||||
|
integer_tests((CONTAINER_TYPE<int>*) 0);
|
||||||
|
integer_tests((CONTAINER_TYPE<unsigned long>*) 0);
|
||||||
|
integer_tests((CONTAINER_TYPE<double>*) 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef CONTAINER_TYPE
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||||
|
// subject to 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/detail/lightweight_test.hpp>
|
||||||
|
|
||||||
|
#ifdef TEST_EXTENSIONS
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
using std::set;
|
||||||
|
#define CONTAINER_TYPE set
|
||||||
|
#include "./hash_set_test.hpp"
|
||||||
|
|
||||||
|
using std::multiset;
|
||||||
|
#define CONTAINER_TYPE multiset
|
||||||
|
#include "./hash_set_test.hpp"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
#ifdef TEST_EXTENSIONS
|
||||||
|
set_tests::set_hash_integer_tests();
|
||||||
|
multiset_tests::multiset_hash_integer_tests();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||||
|
// subject to 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(CONTAINER_TYPE)
|
||||||
|
#error "CONTAINER_TYPE not defined"
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <boost/preprocessor/cat.hpp>
|
||||||
|
|
||||||
|
namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
|
||||||
|
{
|
||||||
|
template <class T>
|
||||||
|
void integer_tests(T* = 0)
|
||||||
|
{
|
||||||
|
const int number_of_containers = 11;
|
||||||
|
T containers[number_of_containers];
|
||||||
|
|
||||||
|
for(int i = 0; i < 5; ++i) {
|
||||||
|
for(int j = 0; j < i; ++j)
|
||||||
|
containers[i].insert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
containers[6].insert(1);
|
||||||
|
containers[7].insert(1);
|
||||||
|
containers[7].insert(1);
|
||||||
|
containers[8].insert(-1);
|
||||||
|
containers[9].insert(-1);
|
||||||
|
containers[9].insert(-1);
|
||||||
|
containers[10].insert(-1);
|
||||||
|
containers[10].insert(1);
|
||||||
|
|
||||||
|
HASH_NAMESPACE::hash<T> hasher;
|
||||||
|
|
||||||
|
for(int i2 = 0; i2 < number_of_containers; ++i2) {
|
||||||
|
BOOST_TEST(hasher(containers[i2]) == hasher(containers[i2]));
|
||||||
|
|
||||||
|
BOOST_TEST(hasher(containers[i2]) ==
|
||||||
|
HASH_NAMESPACE::hash_value(containers[i2]));
|
||||||
|
|
||||||
|
BOOST_TEST(hasher(containers[i2])
|
||||||
|
== HASH_NAMESPACE::hash_range(
|
||||||
|
containers[i2].begin(), containers[i2].end()));
|
||||||
|
|
||||||
|
for(int j2 = i2 + 1; j2 < number_of_containers; ++j2) {
|
||||||
|
BOOST_TEST(
|
||||||
|
(containers[i2] == containers[j2]) ==
|
||||||
|
(hasher(containers[i2]) == hasher(containers[j2]))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BOOST_PP_CAT(CONTAINER_TYPE, _hash_integer_tests())
|
||||||
|
{
|
||||||
|
integer_tests((CONTAINER_TYPE<char>*) 0);
|
||||||
|
integer_tests((CONTAINER_TYPE<int>*) 0);
|
||||||
|
integer_tests((CONTAINER_TYPE<unsigned long>*) 0);
|
||||||
|
integer_tests((CONTAINER_TYPE<double>*) 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef CONTAINER_TYPE
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||||
|
// subject to 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 <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()
|
||||||
|
{
|
||||||
|
compile_time_tests((std::string*) 0);
|
||||||
|
|
||||||
|
HASH_NAMESPACE::hash<std::string> x1;
|
||||||
|
HASH_NAMESPACE::hash<std::string> x2;
|
||||||
|
|
||||||
|
BOOST_TEST(x1("Hello") == x2(std::string("Hel") + "lo"));
|
||||||
|
BOOST_TEST(x1("") == x2(std::string()));
|
||||||
|
|
||||||
|
#if defined(TEST_EXTENSIONS)
|
||||||
|
std::string value1;
|
||||||
|
std::string value2("Hello");
|
||||||
|
|
||||||
|
BOOST_TEST(x1(value1) == HASH_NAMESPACE::hash_value(value1));
|
||||||
|
BOOST_TEST(x1(value2) == HASH_NAMESPACE::hash_value(value2));
|
||||||
|
BOOST_TEST(HASH_NAMESPACE::hash_value(value1) ==
|
||||||
|
HASH_NAMESPACE::hash_range(value1.begin(), value1.end()));
|
||||||
|
BOOST_TEST(HASH_NAMESPACE::hash_value(value2) ==
|
||||||
|
HASH_NAMESPACE::hash_range(value2.begin(), value2.end()));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_STD_WSTRING)
|
||||||
|
void wstring_tests()
|
||||||
|
{
|
||||||
|
compile_time_tests((std::wstring*) 0);
|
||||||
|
|
||||||
|
HASH_NAMESPACE::hash<std::wstring> x1;
|
||||||
|
HASH_NAMESPACE::hash<std::wstring> x2;
|
||||||
|
|
||||||
|
BOOST_TEST(x1(L"Hello") == x2(std::wstring(L"Hel") + L"lo"));
|
||||||
|
BOOST_TEST(x1(L"") == x2(std::wstring()));
|
||||||
|
|
||||||
|
#if defined(TEST_EXTENSIONS)
|
||||||
|
std::wstring value1;
|
||||||
|
std::wstring value2(L"Hello");
|
||||||
|
|
||||||
|
BOOST_TEST(x1(value1) == HASH_NAMESPACE::hash_value(value1));
|
||||||
|
BOOST_TEST(x1(value2) == HASH_NAMESPACE::hash_value(value2));
|
||||||
|
BOOST_TEST(HASH_NAMESPACE::hash_value(value1) ==
|
||||||
|
HASH_NAMESPACE::hash_range(value1.begin(), value1.end()));
|
||||||
|
BOOST_TEST(HASH_NAMESPACE::hash_value(value2) ==
|
||||||
|
HASH_NAMESPACE::hash_range(value2.begin(), value2.end()));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
string_tests();
|
||||||
|
#if !defined(BOOST_NO_STD_WSTRING)
|
||||||
|
wstring_tests();
|
||||||
|
#endif
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||||
|
// subject to 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 compilers hash_value isn't available for arrays, so I test it
|
||||||
|
// separately from the main array tests.
|
||||||
|
|
||||||
|
#include "./config.hpp"
|
||||||
|
|
||||||
|
#ifdef TEST_EXTENSIONS
|
||||||
|
# ifdef TEST_STD_INCLUDES
|
||||||
|
# include <functional>
|
||||||
|
# else
|
||||||
|
# include <boost/functional/hash.hpp>
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
|
|
||||||
|
#ifdef TEST_EXTENSIONS
|
||||||
|
|
||||||
|
void array_int_test()
|
||||||
|
{
|
||||||
|
const int array1[25] = {
|
||||||
|
26, -43, 32, 65, 45,
|
||||||
|
12, 67, 32, 12, 23,
|
||||||
|
0, 0, 0, 0, 0,
|
||||||
|
8, -12, 23, 65, 45,
|
||||||
|
-1, 93, -54, 987, 3
|
||||||
|
};
|
||||||
|
HASH_NAMESPACE::hash<int[25]> hasher1;
|
||||||
|
|
||||||
|
int array2[1] = {3};
|
||||||
|
HASH_NAMESPACE::hash<int[1]> hasher2;
|
||||||
|
|
||||||
|
int array3[2] = {2, 3};
|
||||||
|
HASH_NAMESPACE::hash<int[2]> hasher3;
|
||||||
|
|
||||||
|
BOOST_TEST(hasher1(array1) == HASH_NAMESPACE::hash_value(array1));
|
||||||
|
BOOST_TEST(hasher2(array2) == HASH_NAMESPACE::hash_value(array2));
|
||||||
|
BOOST_TEST(hasher3(array3) == HASH_NAMESPACE::hash_value(array3));
|
||||||
|
}
|
||||||
|
|
||||||
|
void two_dimensional_array_test()
|
||||||
|
{
|
||||||
|
int array[3][2] = {{-5, 6}, {7, -3}, {26, 1}};
|
||||||
|
HASH_NAMESPACE::hash<int[3][2]> hasher;
|
||||||
|
|
||||||
|
BOOST_TEST(hasher(array) == HASH_NAMESPACE::hash_value(array));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
#ifdef TEST_EXTENSIONS
|
||||||
|
array_int_test();
|
||||||
|
two_dimensional_array_test();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||||
|
// subject to 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/detail/lightweight_test.hpp>
|
||||||
|
|
||||||
|
#ifdef TEST_EXTENSIONS
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
using std::vector;
|
||||||
|
#define CONTAINER_TYPE vector
|
||||||
|
#include "./hash_sequence_test.hpp"
|
||||||
|
|
||||||
|
#endif // TEST_EXTENSIONS
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
#ifdef TEST_EXTENSIONS
|
||||||
|
vector_tests::vector_hash_integer_tests();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2006. Use, modification, and distribution are
|
||||||
|
// subject to 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>
|
||||||
|
#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));
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||||
|
// subject to 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>
|
||||||
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
|
|
||||||
|
extern int f(std::size_t, int*);
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
HASH_NAMESPACE::hash<int*> ptr_hasher;
|
||||||
|
int x = 55;
|
||||||
|
BOOST_TEST(!f(ptr_hasher(&x), &x));
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||||
|
// subject to 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>
|
||||||
|
|
||||||
|
extern int f();
|
||||||
|
int main() { return f(); }
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||||
|
// subject to 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>
|
||||||
|
|
||||||
|
int f() { return 0; }
|
||||||
Reference in New Issue
Block a user