forked from boostorg/container_hash
@@ -6,6 +6,7 @@
|
||||
:source-highlighter: rouge
|
||||
:nofooter:
|
||||
:sectlinks:
|
||||
:source-language: c++
|
||||
|
||||
:leveloffset: +1
|
||||
|
||||
|
@@ -13,7 +13,7 @@
|
||||
* Support `std::string_view`, `std::error_code`, `std::error_condition`, `std::optional`, `std::variant`, `std::monostate` where available.
|
||||
* Update include paths from other Boost libraries.
|
||||
* Manually write out tuple overloads, rather than using the preprocessor to generate them. Should improve usability, due to better error messages, and easier debugging.
|
||||
* Fix tutorial example (https://svn.boost.org/trac/boost/ticket/11017[#11017^]).
|
||||
* Fix tutorial example (https://svn.boost.org/trac/boost/ticket/11017[#11017]).
|
||||
* Quick fix for hashing `vector<bool>` when using lib{cpp}. Will try to introduce a more general fix in the next release.
|
||||
|
||||
== Boost 1.66.0
|
||||
@@ -23,25 +23,25 @@
|
||||
* Support for `char16_t`, `char32_t`, `u16string`, `u32string`
|
||||
|
||||
== Boost 1.64.0
|
||||
* Fix for recent versions of Visual {cpp} which have removed `std::unary_function` and `std::binary_function` (https://svn.boost.org/trac/boost/ticket/12353[#12353^]).
|
||||
* Fix for recent versions of Visual {cpp} which have removed `std::unary_function` and `std::binary_function` (https://svn.boost.org/trac/boost/ticket/12353[#12353]).
|
||||
|
||||
== Boost 1.63.0
|
||||
* Fixed some warnings.
|
||||
* Only define hash for `std::wstring` when we know we have a `wchar_t`. Otherwise there's a compile error as there's no overload for hashing the characters in wide strings (https://svn.boost.org/trac/boost/ticket/8552[#8552^]).
|
||||
* Only define hash for `std::wstring` when we know we have a `wchar_t`. Otherwise there's a compile error as there's no overload for hashing the characters in wide strings (https://svn.boost.org/trac/boost/ticket/8552[#8552]).
|
||||
|
||||
== Boost 1.58.0
|
||||
* Fixed strict aliasing violation (https://github.com/boostorg/container_hash/issues/3[GitHub #3^]).
|
||||
* Fixed strict aliasing violation (https://github.com/boostorg/container_hash/issues/3[GitHub #3]).
|
||||
|
||||
== Boost 1.56.0
|
||||
* Removed some Visual {cpp} 6 workarounds.
|
||||
* Ongoing work on improving `hash_combine`. This changes the combine function which was previously defined in the reference documentation.
|
||||
|
||||
== Boost 1.55.0
|
||||
* Simplify a SFINAE check so that it will hopefully work on Sun 5.9 (https://svn.boost.org/trac10/ticket/8822[#8822^]).
|
||||
* Suppress Visual {cpp} infinite loop warning (https://svn.boost.org/trac10/ticket/8568[#8568^]).
|
||||
* Simplify a SFINAE check so that it will hopefully work on Sun 5.9 (https://svn.boost.org/trac10/ticket/8822[#8822]).
|
||||
* Suppress Visual {cpp} infinite loop warning (https://svn.boost.org/trac10/ticket/8568[#8568]).
|
||||
|
||||
== Boost 1.54.0
|
||||
* https://svn.boost.org/trac/boost/ticket/7957[Ticket 7957^]: Fixed a typo.
|
||||
* https://svn.boost.org/trac/boost/ticket/7957[Ticket 7957]: Fixed a typo.
|
||||
|
||||
== Boost 1.53.0
|
||||
* Add support for `boost::int128_type` and `boost::uint128_type` where available - currently only `{int128}` and `unsigned {int128}` on some versions of gcc.
|
||||
@@ -58,8 +58,8 @@
|
||||
* Updated to use the new config macros.
|
||||
|
||||
== Boost 1.50.0
|
||||
* https://svn.boost.org/trac/boost/ticket/6771[Ticket 6771^]: Avoid gcc's `-Wfloat-equal` warning.
|
||||
* https://svn.boost.org/trac/boost/ticket/6806[Ticket 6806^]: Support `std::array` and `std::tuple` when available.
|
||||
* https://svn.boost.org/trac/boost/ticket/6771[Ticket 6771]: Avoid gcc's `-Wfloat-equal` warning.
|
||||
* https://svn.boost.org/trac/boost/ticket/6806[Ticket 6806]: Support `std::array` and `std::tuple` when available.
|
||||
* Add deprecation warning to the long deprecated `boost/container_hash/detail/container_fwd.hpp`.
|
||||
|
||||
== Boost 1.46.0
|
||||
@@ -69,8 +69,8 @@
|
||||
* Add option to prevent implicit conversions when calling `hash_value` by defining `BOOST_HASH_NO_IMPLICIT_CASTS`. When using `boost::hash` for a type that does not have `hash_value` declared but does have an implicit conversion to a type that does, it would use that implicit conversion to hash it. Which can sometimes go very wrong, e.g. using a conversion to `bool` and only hashing to 2 possible values. Since fixing this is a breaking change and was only approached quite late in the release cycle with little discussion it's opt-in for now. This, or something like it, will become the default in a future version.
|
||||
|
||||
== Boost 1.43.0
|
||||
* https://svn.boost.org/trac/boost/ticket/3866[Ticket 3866^]: Don't foward declare containers when using gcc's parallel library, allow user to stop forward declaration by defining the `BOOST_DETAIL_NO_CONTAINER_FWD` macro.
|
||||
* https://svn.boost.org/trac/boost/ticket/4038[Ticket 4038^]: Avoid hashing `0.5` and `0` to the same number.
|
||||
* https://svn.boost.org/trac/boost/ticket/3866[Ticket 3866]: Don't foward declare containers when using gcc's parallel library, allow user to stop forward declaration by defining the `BOOST_DETAIL_NO_CONTAINER_FWD` macro.
|
||||
* https://svn.boost.org/trac/boost/ticket/4038[Ticket 4038]: Avoid hashing `0.5` and `0` to the same number.
|
||||
* Stop using deprecated `BOOST_HAS_*` macros.
|
||||
|
||||
== Boost 1.42.0
|
||||
@@ -84,15 +84,15 @@
|
||||
|
||||
== Boost 1.39.0
|
||||
* Move the `hash_fwd.hpp` implementation into the hash subdirectory, leaving a forwarding header in the old location. You should still use the old location, the new location is mainly for implementation and possible modularization.
|
||||
* https://svn.boost.org/trac/boost/ticket/2412[Ticket 2412^]: Removed deprecated headers.
|
||||
* https://svn.boost.org/trac/boost/ticket/2957[Ticket 2957^]: Fix configuration for vxworks.
|
||||
* https://svn.boost.org/trac/boost/ticket/2412[Ticket 2412]: Removed deprecated headers.
|
||||
* https://svn.boost.org/trac/boost/ticket/2957[Ticket 2957]: Fix configuration for vxworks.
|
||||
|
||||
== Boost 1.38.0
|
||||
* Changed the warnings in the deprecated headers from 1.34.0 to errors. These will be removed in a future version of Boost.
|
||||
* Moved detail headers out of `boost/container_hash/detail`, since they are part of `functional/hash`, not `container_hash`. `boost/container_hash/detail/container_fwd.hpp` has been moved to `boost/detail/container_fwd.hpp` as it's used outside of this library, the others have been moved to `boost/functional/hash/detail`.
|
||||
|
||||
== Boost 1.37.0
|
||||
* http://svn.boost.org/trac/boost/ticket/2264[Ticket 2264^]: In Visual {cpp}, always use C99 float functions for long double and float as the {cpp} overloads aren't always availables.
|
||||
* http://svn.boost.org/trac/boost/ticket/2264[Ticket 2264]: In Visual {cpp}, always use C99 float functions for long double and float as the {cpp} overloads aren't always availables.
|
||||
|
||||
== Boost 1.36.0
|
||||
* Stop using OpenBSD's dodgy `std::numeric_limits`.
|
||||
@@ -102,20 +102,20 @@
|
||||
== Boost 1.35.0
|
||||
* Support for `long long`, `std::complex`.
|
||||
* Improved algorithm for hashing floating point numbers:
|
||||
** Improved portablity, as described by Daniel Krügler in http://lists.boost.org/boost-users/2005/08/13418.php[a post to the boost users list^].
|
||||
** Improved portablity, as described by Daniel Krügler in http://lists.boost.org/boost-users/2005/08/13418.php[a post to the boost users list].
|
||||
** Fits more information into each combine loop, which can reduce the the number of times combine is called and hopefully give a better quality hash function.
|
||||
** Improved the algorithm for hashing floating point numbers.
|
||||
** On Cygwin use a binary hash function for floating point numbers, as Cygwin doesn't have decent floating point functions for `long double`.
|
||||
** Never uses `fpclass` which doesn't support `long double`.
|
||||
** http://svn.boost.org/trac/boost/ticket/1064[Ticket 1064^]: Removed unnecessary use of errno.
|
||||
** http://svn.boost.org/trac/boost/ticket/1064[Ticket 1064]: Removed unnecessary use of errno.
|
||||
* Explicitly overload for more built in types.
|
||||
* Minor improvements to the documentation.
|
||||
* A few bug and warning fixes:
|
||||
** http://svn.boost.org/trac/boost/ticket/1509[Ticket 1509^]: Suppress another Visual {cpp} warning.
|
||||
** http://svn.boost.org/trac/boost/ticket/1509[Ticket 1509]: Suppress another Visual {cpp} warning.
|
||||
** Some workarounds for the Sun compilers.
|
||||
|
||||
== Boost 1.34.1
|
||||
* https://svn.boost.org/trac10/ticket/952[Ticket 952^]: Suppress incorrect 64-bit warning on Visual {cpp}.
|
||||
* https://svn.boost.org/trac10/ticket/952[Ticket 952]: Suppress incorrect 64-bit warning on Visual {cpp}.
|
||||
|
||||
== Boost 1.34.0
|
||||
* Use declarations for standard classes, so that the library doesn't need to include all of their headers
|
||||
|
@@ -5,7 +5,7 @@
|
||||
|
||||
Say you have a point class, representing a two dimensional location:
|
||||
|
||||
[listing]
|
||||
[source]
|
||||
----
|
||||
class point
|
||||
{
|
||||
@@ -22,9 +22,9 @@ public:
|
||||
};
|
||||
----
|
||||
|
||||
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 xref:#ref_hash_combine[boost::hash_combine] is supplied for this purpose:
|
||||
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 `boost::hash_combine` is supplied for this purpose:
|
||||
|
||||
[listing,subs="+quotes,+macros"]
|
||||
[source]
|
||||
----
|
||||
class point
|
||||
{
|
||||
@@ -33,8 +33,8 @@ class point
|
||||
friend std::size_t hash_value(point const& p)
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
xref:#ref_hash_combine[boost::hash_combine](seed, p.x);
|
||||
xref:#ref_hash_combine[boost::hash_combine](seed, p.y);
|
||||
boost::hash_combine(seed, p.x);
|
||||
boost::hash_combine(seed, p.y);
|
||||
|
||||
return seed;
|
||||
}
|
||||
@@ -43,14 +43,14 @@ class point
|
||||
};
|
||||
----
|
||||
|
||||
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 xref:#ref_hash_value[hash_value] on the supplied element, and combines it with the 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 `hash_value` on the supplied element, and combines it with the seed.
|
||||
|
||||
Full code for this example is at link:../../examples/point.cpp[/libs/container_hash/examples/point.cpp^].
|
||||
Full code for this example is at link:../../examples/point.cpp[/libs/container_hash/examples/point.cpp].
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
When using xref:#ref_hash_combine[boost::hash_combine] the order of the calls matters.
|
||||
[listing,subs="+quotes,+macros"]
|
||||
When using `boost::hash_combine` the order of the calls matters.
|
||||
[source]
|
||||
----
|
||||
std::size_t seed = 0;
|
||||
boost::hash_combine(seed, 1);
|
||||
@@ -58,7 +58,7 @@ boost::hash_combine(seed, 2);
|
||||
----
|
||||
results in a different seed to:
|
||||
|
||||
[listing,subs="+quotes,+macros"]
|
||||
[source]
|
||||
----
|
||||
std::size_t seed = 0;
|
||||
boost::hash_combine(seed, 2);
|
||||
@@ -69,12 +69,12 @@ If you are calculating a hash value for data where the order of the data doesn't
|
||||
|
||||
====
|
||||
|
||||
To calculate the hash of an iterator range you can use xref:#ref_hash_range[boost::hash_range]:
|
||||
To calculate the hash of an iterator range you can use `boost::hash_range`:
|
||||
|
||||
[listing,subs="+quotes,+macros"]
|
||||
[source]
|
||||
----
|
||||
std::vector<std::string> some_strings;
|
||||
std::size_t hash = xref:#ref_hash_range[boost::hash_range](some_strings.begin(), some_strings.end());
|
||||
std::size_t hash = boost::hash_range(some_strings.begin(), some_strings.end());
|
||||
----
|
||||
|
||||
Note that when writing template classes, you might not want to include the main hash header as it's quite an expensive include that brings in a lot of other headers, so instead you can include the `<boost/container_hash/hash_fwd.hpp>` header which forward declares xref:#ref_hash[boost::hash], xref:#ref_hash_range[boost::hash_range] and xref:#ref_hash_combine[boost::hash_combine]. You'll need to include the main header before instantiating xref:#ref_hash[boost::hash]. When using a container that uses xref:#ref_hash[boost::hash] it should do that for you, so your type will work fine with the boost hash containers. There's an example of this in link:../../examples/template.hpp[template.hpp^] and link:../../examples/template.cpp[template.cpp^].
|
||||
Note that when writing template classes, you might not want to include the main hash header as it's quite an expensive include that brings in a lot of other headers, so instead you can include the `<boost/container_hash/hash_fwd.hpp>` header which forward declares `boost::hash`, `boost::hash_range` and `boost::hash_combine`. You'll need to include the main header before instantiating `boost::hash`. When using a container that uses `boost::hash` it should do that for you, so your type will work fine with the boost hash containers. There's an example of this in link:../../examples/template.hpp[template.hpp] and link:../../examples/template.cpp[template.cpp].
|
||||
|
@@ -3,11 +3,11 @@
|
||||
|
||||
:idprefix: custom_
|
||||
|
||||
xref:#ref_hash[boost::hash] is implemented by calling the function xref:#ref_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.
|
||||
`boost::hash` is implemented by calling the function `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 its member `id`:
|
||||
|
||||
[listing]
|
||||
[source]
|
||||
----
|
||||
namespace library
|
||||
{
|
||||
@@ -29,27 +29,27 @@ namespace library
|
||||
|
||||
Then all you would need to do is write the function `library::hash_value`:
|
||||
|
||||
[listing,subs="+quotes,+macros"]
|
||||
[source]
|
||||
----
|
||||
namespace library
|
||||
{
|
||||
std::size_t hash_value(book const& b)
|
||||
{
|
||||
xref:#ref_hash[boost::hash]<int> hasher;
|
||||
boost::hash<int> hasher;
|
||||
return hasher(b.id);
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
And you can now use xref:#ref_hash[boost::hash] with book:
|
||||
And you can now use `boost::hash` with book:
|
||||
|
||||
[listing,subs="+quotes,+macros"]
|
||||
[source]
|
||||
----
|
||||
library::book knife(3458, "Zane Grey", "The Hash Knife Outfit");
|
||||
library::book dandelion(1354, "Paul J. Shanley",
|
||||
"Hash & Dandelion Greens");
|
||||
|
||||
xref:#ref_hash[boost::hash]<library::book> book_hasher;
|
||||
boost::hash<library::book> book_hasher;
|
||||
std::size_t knife_hash_value = book_hasher(knife);
|
||||
|
||||
// If std::unordered_set is available:
|
||||
@@ -63,6 +63,6 @@ assert(books.find(knife) != books.end());
|
||||
assert(books.find(dandelion) == books.end());
|
||||
----
|
||||
|
||||
The full example can be found in: link:../../examples/books.hpp[/libs/container_hash/examples/books.hpp^] and link:../../examples/books.cpp[/libs/container_hash/examples/books.cpp^].
|
||||
The full example can be found in: link:../../examples/books.hpp[/libs/container_hash/examples/books.hpp] and link:../../examples/books.cpp[/libs/container_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 hashes the id. If it was based on the object's name and author then the hash function should take them into account (how to do this is discussed in the next section).
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
:idprefix: disable_
|
||||
|
||||
While xref:#ref_hash[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 xref:#ref_header_boostcontainer_hashhash_hpp[<boost/container_hash/hash.hpp>] then the non-specialised form will be defined - activating the extensions.
|
||||
While ``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 `<boost/container_hash/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.
|
||||
|
||||
|
@@ -3,20 +3,20 @@
|
||||
|
||||
:idprefix: intro_
|
||||
|
||||
xref:#ref_hash[boost::hash] is an implementation of the https://en.wikipedia.org/wiki/Hash_function[hash function^] object specified by the http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf[Draft Technical Report on C++ Library Extensions^] (TR1). It is the default hash function for link:../../../unordered/index.html[Boost.Unordered^], link:../../../intrusive/index.html[Boost.Intrusive^]'s unordered associative containers, and link:../../../multi_index/index.html[Boost.MultiIndex^]'s hash indicies and link:../../../bimap/index.html[Boost.Bimap^]'s `unordered_set_of`.
|
||||
`boost::hash` is an implementation of the https://en.wikipedia.org/wiki/Hash_function[hash function] object specified by the http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf[Draft Technical Report on C++ Library Extensions] (TR1). It is the default hash function for link:../../../unordered/index.html[Boost.Unordered], link:../../../intrusive/index.html[Boost.Intrusive]'s unordered associative containers, and link:../../../multi_index/index.html[Boost.MultiIndex]'s hash indicies and link:../../../bimap/index.html[Boost.Bimap]'s `unordered_set_of`.
|
||||
|
||||
As it is compliant with http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf[TR1^], it will work with:
|
||||
As it is compliant with http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf[TR1], it will work with:
|
||||
|
||||
* integers
|
||||
* floats
|
||||
* pointers
|
||||
* strings
|
||||
|
||||
It also implements the extension proposed by Peter Dimov in issue 6.18 of the http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf[Library Extension Technical Report Issues List^] (page 63), this adds support for:
|
||||
It also implements the extension proposed by Peter Dimov in issue 6.18 of the http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf[Library Extension Technical Report Issues List] (page 63), this adds support for:
|
||||
|
||||
* arrays
|
||||
* `std::pair`
|
||||
* the standard containers.
|
||||
* extending xref:#ref_hash[boost::hash] for custom types.
|
||||
* extending `boost::hash` for custom types.
|
||||
|
||||
NOTE: This hash function is designed to be used in containers based on the STL and is not suitable as a general purpose hash function. For more details see the <<rationale,rationale>>.
|
||||
|
@@ -3,13 +3,13 @@
|
||||
|
||||
:idprefix: portability_
|
||||
|
||||
xref:#ref_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` needs to be declared in the `boost` namespace.
|
||||
`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` needs 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 xref:#ref_hash[boost::hash] is instantiated, so for these compilers the overload should only be declared in the same namespace as the class.
|
||||
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:
|
||||
|
||||
[list,subs="+quotes,+macros"]
|
||||
[source]
|
||||
----
|
||||
namespace foo
|
||||
{
|
||||
@@ -22,7 +22,7 @@ namespace foo
|
||||
|
||||
friend std::size_t hash_value(custom_type x)
|
||||
{
|
||||
xref:#ref_hash[boost::hash]<int> hasher;
|
||||
boost::hash<int> hasher;
|
||||
return hasher(x.value);
|
||||
}
|
||||
};
|
||||
@@ -33,7 +33,7 @@ On a compliant compiler, when `hash_value` is called for this type, it will look
|
||||
|
||||
So first move the member function out of the class:
|
||||
|
||||
[listing,subs="+quotes,+macros"]
|
||||
[source]
|
||||
----
|
||||
namespace foo
|
||||
{
|
||||
@@ -46,7 +46,7 @@ namespace foo
|
||||
|
||||
std::size_t hash(custom_type x)
|
||||
{
|
||||
xref:#ref_hash[boost::hash]<T> hasher;
|
||||
boost::hash<T> hasher;
|
||||
return hasher(value);
|
||||
}
|
||||
};
|
||||
@@ -63,7 +63,7 @@ Unfortunately, I couldn't declare `hash_value` as a friend, as some compilers do
|
||||
|
||||
For compilers which don't support ADL, `hash_value` needs to be defined in the `boost` namespace:
|
||||
|
||||
[listing]
|
||||
[source]
|
||||
----
|
||||
#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
|
||||
namespace boost
|
||||
@@ -79,4 +79,4 @@ namespace foo
|
||||
}
|
||||
----
|
||||
|
||||
Full code for this example is at link:../../examples/portable.cpp[/libs/container_hash/examples/portable.cpp^].
|
||||
Full code for this example is at link:../../examples/portable.cpp[/libs/container_hash/examples/portable.cpp].
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
:idprefix: rationale_
|
||||
|
||||
The rationale can be found in the original designfootnote:[issue 6.18 of the http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf[Library Extension Technical Report Issues List^] (page 63)].
|
||||
The rationale can be found in the original designfootnote:[issue 6.18 of the http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf[Library Extension Technical Report Issues List] (page 63)].
|
||||
|
||||
== Quality of the hash function
|
||||
|
||||
@@ -11,6 +11,6 @@ Many hash functions strive to have little correlation between the input and outp
|
||||
|
||||
But the standard has no such requirement for the hash function, it just requires that the hashes of two different values are unlikely to collide. Containers or algorithms designed to work with the standard hash function will have to be implemented to work well when the hash function's output is correlated to its input. Since they are paying that cost a higher quality hash function would be wasteful.
|
||||
|
||||
For other use cases, if you do need a higher quality hash function, then neither the standard hash function or `boost::hash` are appropriate. There are several options available. One is to use a second hash on the output of this hash function, such as http://web.archive.org/web/20121102023700/http://www.concentric.net/~Ttwang/tech/inthash.htm[Thomas Wang's hash function^]. This this may not work as well as a hash algorithm tailored for the input.
|
||||
For other use cases, if you do need a higher quality hash function, then neither the standard hash function or `boost::hash` are appropriate. There are several options available. One is to use a second hash on the output of this hash function, such as http://web.archive.org/web/20121102023700/http://www.concentric.net/~Ttwang/tech/inthash.htm[Thomas Wang's hash function]. This this may not work as well as a hash algorithm tailored for the input.
|
||||
|
||||
For strings there are several fast, high quality hash functions available (for example http://code.google.com/p/smhasher/[MurmurHash3^] and http://code.google.com/p/cityhash/[Google's CityHash^]), although they tend to be more machine specific. These may also be appropriate for hashing a binary representation of your data - providing that all equal values have an equal representation, which is not always the case (e.g. for floating point values).
|
||||
For strings there are several fast, high quality hash functions available (for example http://code.google.com/p/smhasher/[MurmurHash3] and http://code.google.com/p/cityhash/[Google's CityHash]), although they tend to be more machine specific. These may also be appropriate for hashing a binary representation of your data - providing that all equal values have an equal representation, which is not always the case (e.g. for floating point values).
|
||||
|
@@ -3,117 +3,117 @@
|
||||
|
||||
:idprefix: ref_
|
||||
|
||||
For the full specification, see section 6.3 of the http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf[C++ Standard Library Technical Report^] and issue 6.18 of the http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf[Library Extension Technical Report Issues List^] (page 63).
|
||||
For the full specification, see section 6.3 of the http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf[C++ Standard Library Technical Report] and issue 6.18 of the http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf[Library Extension Technical Report Issues List] (page 63).
|
||||
|
||||
== Header <boost/container_hash/hash.hpp>
|
||||
|
||||
Defines xref:#ref_hash[boost::hash], and helper functions.
|
||||
Defines `boost::hash`, and helper functions.
|
||||
|
||||
[listing,subs="+quotes,+macros"]
|
||||
[source]
|
||||
----
|
||||
namespace boost {
|
||||
template<typename T> struct xref:#ref_hash[hash];
|
||||
template<typename T> struct hash;
|
||||
|
||||
template<> struct xref:#ref_specializations[hash]<bool>;
|
||||
template<> struct xref:#ref_specializations[hash]<char>;
|
||||
template<> struct xref:#ref_specializations[hash]<signed char>;
|
||||
template<> struct xref:#ref_specializations[hash]<unsigned char>;
|
||||
template<> struct xref:#ref_specializations[hash]<wchar_t>;
|
||||
template<> struct xref:#ref_specializations[hash]<char16_t>;
|
||||
template<> struct xref:#ref_specializations[hash]<char32_t>;
|
||||
template<> struct xref:#ref_specializations[hash]<short>;
|
||||
template<> struct xref:#ref_specializations[hash]<unsigned short>;
|
||||
template<> struct xref:#ref_specializations[hash]<int>;
|
||||
template<> struct xref:#ref_specializations[hash]<unsigned int>;
|
||||
template<> struct xref:#ref_specializations[hash]<long>;
|
||||
template<> struct xref:#ref_specializations[hash]<unsigned long>;
|
||||
template<> struct xref:#ref_specializations[hash]<long long>;
|
||||
template<> struct xref:#ref_specializations[hash]<unsigned long long>;
|
||||
template<> struct xref:#ref_specializations[hash]<float>;
|
||||
template<> struct xref:#ref_specializations[hash]<double>;
|
||||
template<> struct xref:#ref_specializations[hash]<long double>;
|
||||
template<> struct xref:#ref_specializations[hash]<std::string>;
|
||||
template<> struct xref:#ref_specializations[hash]<std::wstring>;
|
||||
template<> struct xref:#ref_specializations[hash]<std::u16string>;
|
||||
template<> struct xref:#ref_specializations[hash]<std::u32string>;
|
||||
template<> struct xref:#ref_specializations[hash]<std::type_index>;
|
||||
template<> struct hash<bool>;
|
||||
template<> struct hash<char>;
|
||||
template<> struct hash<signed char>;
|
||||
template<> struct hash<unsigned char>;
|
||||
template<> struct hash<wchar_t>;
|
||||
template<> struct hash<char16_t>;
|
||||
template<> struct hash<char32_t>;
|
||||
template<> struct hash<short>;
|
||||
template<> struct hash<unsigned short>;
|
||||
template<> struct hash<int>;
|
||||
template<> struct hash<unsigned int>;
|
||||
template<> struct hash<long>;
|
||||
template<> struct hash<unsigned long>;
|
||||
template<> struct hash<long long>;
|
||||
template<> struct hash<unsigned long long>;
|
||||
template<> struct hash<float>;
|
||||
template<> struct hash<double>;
|
||||
template<> struct hash<long double>;
|
||||
template<> struct hash<std::string>;
|
||||
template<> struct hash<std::wstring>;
|
||||
template<> struct hash<std::u16string>;
|
||||
template<> struct hash<std::u32string>;
|
||||
template<> struct hash<std::type_index>;
|
||||
|
||||
template<typename T> struct xref:#ref_specializations[hash]<T*>;
|
||||
template<typename T> struct hash<T*>;
|
||||
|
||||
// xref:#ref_support_functions_boost_extension[Support functions (Boost extension).]
|
||||
// Support functions (Boost extension).
|
||||
template<typename T>
|
||||
void xref:#ref_hash_combine[hash_combine](size_t &, T const&);
|
||||
void hash_combine(size_t &, T const&);
|
||||
|
||||
template<typename It>
|
||||
std::size_t xref:#ref_hash_range[hash_range](It, It);
|
||||
std::size_t hash_range(It, It);
|
||||
|
||||
template<typename It>
|
||||
void xref:#ref_hash_range[hash_range](std::size_t&, It, It);
|
||||
void hash_range(std::size_t&, It, It);
|
||||
|
||||
// xref:#ref_overloadable_hash_implementation_boost_extension[Overloadable hash implementation (Boost extension).]
|
||||
std::size_t xref:#ref_hash_value[hash_value](bool);
|
||||
std::size_t xref:#ref_hash_value[hash_value](char);
|
||||
std::size_t xref:#ref_hash_value[hash_value](signed char);
|
||||
std::size_t xref:#ref_hash_value[hash_value](unsigned char);
|
||||
std::size_t xref:#ref_hash_value[hash_value](wchar_t);
|
||||
std::size_t xref:#ref_hash_value[hash_value](char16_t);
|
||||
std::size_t xref:#ref_hash_value[hash_value](char32_t);
|
||||
std::size_t xref:#ref_hash_value[hash_value](short);
|
||||
std::size_t xref:#ref_hash_value[hash_value](unsigned short);
|
||||
std::size_t xref:#ref_hash_value[hash_value](int);
|
||||
std::size_t xref:#ref_hash_value[hash_value](unsigned int);
|
||||
std::size_t xref:#ref_hash_value[hash_value](long);
|
||||
std::size_t xref:#ref_hash_value[hash_value](unsigned long);
|
||||
std::size_t xref:#ref_hash_value[hash_value](long long);
|
||||
std::size_t xref:#ref_hash_value[hash_value](unsigned long long);
|
||||
std::size_t xref:#ref_hash_value[hash_value](float);
|
||||
std::size_t xref:#ref_hash_value[hash_value](double);
|
||||
std::size_t xref:#ref_hash_value[hash_value](long double);
|
||||
// Overloadable hash implementation (Boost extension).
|
||||
std::size_t hash_value(bool);
|
||||
std::size_t hash_value(char);
|
||||
std::size_t hash_value(signed char);
|
||||
std::size_t hash_value(unsigned char);
|
||||
std::size_t hash_value(wchar_t);
|
||||
std::size_t hash_value(char16_t);
|
||||
std::size_t hash_value(char32_t);
|
||||
std::size_t hash_value(short);
|
||||
std::size_t hash_value(unsigned short);
|
||||
std::size_t hash_value(int);
|
||||
std::size_t hash_value(unsigned int);
|
||||
std::size_t hash_value(long);
|
||||
std::size_t hash_value(unsigned long);
|
||||
std::size_t hash_value(long long);
|
||||
std::size_t hash_value(unsigned long long);
|
||||
std::size_t hash_value(float);
|
||||
std::size_t hash_value(double);
|
||||
std::size_t hash_value(long double);
|
||||
|
||||
template<typename T>
|
||||
std::size_t xref:#ref_hash_value[hash_value](T* const&);
|
||||
std::size_t hash_value(T* const&);
|
||||
|
||||
template<typename T, unsigned N>
|
||||
std::size_t xref:#ref_hash_value[hash_value](T (&val)[N]);
|
||||
std::size_t hash_value(T (&val)[N]);
|
||||
|
||||
template<typename T, unsigned N>
|
||||
std::size_t xref:#ref_hash_value[hash_value](const T (&val)[N]);
|
||||
std::size_t hash_value(const T (&val)[N]);
|
||||
|
||||
template<typename Ch, typename A>
|
||||
std::size_t xref:#ref_hash_value[hash_value](std::basic_string<Ch, std::char_traits<Ch>, A> const&);
|
||||
std::size_t hash_value(std::basic_string<Ch, std::char_traits<Ch>, A> const&);
|
||||
|
||||
template<typename A, typename B>
|
||||
std::size_t xref:#ref_hash_value[hash_value](std::pair<A, B> const&);
|
||||
std::size_t hash_value(std::pair<A, B> const&);
|
||||
|
||||
template<typename T, typename A>
|
||||
std::size_t xref:#ref_hash_value[hash_value](std::vector<T, A> const&);
|
||||
std::size_t hash_value(std::vector<T, A> const&);
|
||||
|
||||
template<typename T, typename A>
|
||||
std::size_t xref:#ref_hash_value[hash_value](std::list<T, A> const&);
|
||||
std::size_t hash_value(std::list<T, A> const&);
|
||||
|
||||
template<typename T, typename A>
|
||||
std::size_t xref:#ref_hash_value[hash_value](std::deque<T, A> const&);
|
||||
std::size_t hash_value(std::deque<T, A> const&);
|
||||
|
||||
template<typename K, typename C, typename A>
|
||||
std::size_t xref:#ref_hash_value[hash_value](std::set<K, C, A> const&);
|
||||
std::size_t hash_value(std::set<K, C, A> const&);
|
||||
|
||||
template<typename K, typename C, typename A>
|
||||
std::size_t xref:#ref_hash_value[hash_value](std::multiset<K, C, A> const&);
|
||||
std::size_t hash_value(std::multiset<K, C, A> const&);
|
||||
|
||||
template<typename K, typename T, typename C, typename A>
|
||||
std::size_t xref:#ref_hash_value[hash_value](std::map<K, T, C, A> const&);
|
||||
std::size_t hash_value(std::map<K, T, C, A> const&);
|
||||
|
||||
template<typename K, typename T, typename C, typename A>
|
||||
std::size_t xref:#ref_hash_value[hash_value](std::multimap<K, T, C, A> const&);
|
||||
std::size_t hash_value(std::multimap<K, T, C, A> const&);
|
||||
|
||||
template<typename T> std::size_t xref:#ref_hash_value[hash_value](std::complex<T> const&);
|
||||
std::size_t xref:#ref_hash_value[hash_value](std::type_index);
|
||||
template<typename T> std::size_t hash_value(std::complex<T> const&);
|
||||
std::size_t hash_value(std::type_index);
|
||||
|
||||
template<typename T, std::size_t N>
|
||||
std::size_t xref:#ref_hash_value[hash_value](std::array<T, N> const&);
|
||||
std::size_t hash_value(std::array<T, N> const&);
|
||||
|
||||
template<typename... T>
|
||||
std::size_t xref:#ref_hash_value[hash_value](std::tuple<T...>);
|
||||
std::size_t hash_value(std::tuple<T...>);
|
||||
}
|
||||
----
|
||||
|
||||
@@ -121,13 +121,13 @@ namespace boost {
|
||||
|
||||
=== hash
|
||||
|
||||
`boost::hash` — A http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf[TR1^] compliant hash function object.
|
||||
`boost::hash` — A http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf[TR1] compliant hash function object.
|
||||
|
||||
==== Synopsis
|
||||
|
||||
[listing,subs="+quotes,+macros"]
|
||||
[source]
|
||||
----
|
||||
// xref:#ref_header_boostcontainer_hashhash_hpp[#include <boost/container_hash/hash.hpp>]
|
||||
// #include <boost/container_hash/hash.hpp>
|
||||
|
||||
template<typename T>
|
||||
struct hash : public std::unary_function<T, std::size_t> {
|
||||
@@ -137,15 +137,15 @@ struct hash : public std::unary_function<T, std::size_t> {
|
||||
|
||||
==== Description
|
||||
|
||||
[listing]
|
||||
[source]
|
||||
----
|
||||
std::size_t operator()(T const& val) const;
|
||||
----
|
||||
|
||||
[horizontal]
|
||||
Returns:: xref:#ref_hash_value[hash_value](val)
|
||||
Returns:: `hash_value(val)`
|
||||
|
||||
Notes:: The call to xref:#ref_hash_value[hash_value] is unqualified, so that custom overloads can be found via argument dependent lookup.
|
||||
Notes:: The call to `hash_value` is unqualified, so that custom overloads can be found via argument dependent lookup.
|
||||
+
|
||||
This is not defined when the macro `BOOST_HASH_NO_EXTENSIONS` is defined. The specializations are still defined, so only the specializations required by TR1 are defined.
|
||||
+
|
||||
@@ -153,7 +153,7 @@ Forward declared in `<boost/container_hash/hash_fwd.hpp>`
|
||||
+
|
||||
This hash function is not intended for general use, and isn't guaranteed to be equal during separate runs of a program - so please don't use it for any persistent storage or communication.
|
||||
|
||||
Throws:: Only throws if xref:#ref_hash_value[hash_value](T) throws.
|
||||
Throws:: Only throws if `hash_value(T)` throws.
|
||||
|
||||
== Specializations
|
||||
|
||||
@@ -161,7 +161,7 @@ Throws:: Only throws if xref:#ref_hash_value[hash_value](T) throws.
|
||||
|
||||
=== Synopsis
|
||||
|
||||
[listing]
|
||||
[source]
|
||||
----
|
||||
// #include <boost/container_hash/hash.hpp>
|
||||
|
||||
@@ -172,7 +172,7 @@ struct hash<T> {
|
||||
|
||||
=== Description
|
||||
|
||||
[listing]
|
||||
[source]
|
||||
----
|
||||
std::size_t operator()(T const val) const;
|
||||
----
|
||||
@@ -180,7 +180,7 @@ std::size_t operator()(T const val) const;
|
||||
[horizontal]
|
||||
Returns:: Unspecified in TR1, except that equal arguments yield the same result.
|
||||
+
|
||||
xref:#ref_hash_value[hash_value](val) in Boost.
|
||||
`hash_value(val)` in Boost.
|
||||
|
||||
[horizontal]
|
||||
Throws:: Doesn't throw
|
||||
@@ -189,7 +189,7 @@ Throws:: Doesn't throw
|
||||
|
||||
=== hash_combine
|
||||
|
||||
[listing]
|
||||
[source]
|
||||
----
|
||||
template<typename T>
|
||||
void hash_combine(size_t &, T const&);
|
||||
@@ -198,10 +198,10 @@ void hash_combine(size_t &, T const&);
|
||||
Called repeatedly to incrementally create a hash value from several variables.
|
||||
|
||||
[horizontal]
|
||||
Effects:: Updates seed with a new hash value generated by combining it with the result of xref:#ref_hash_value[hash_value](v). Will always produce the same result for the same combination of seed and xref:#ref_hash_value[hash_value](v) during the single run of a program.
|
||||
Effects:: Updates seed with a new hash value generated by combining it with the result of `hash_value(v)`. Will always produce the same result for the same combination of seed and `hash_value(v)` during the single run of a program.
|
||||
|
||||
[horizontal]
|
||||
Notes:: xref:#ref_hash_value[hash_value] is called without qualification, so that overloads can be found via ADL. +
|
||||
Notes:: `hash_value` is called without qualification, so that overloads can be found via ADL. +
|
||||
+
|
||||
This is an extension to TR1 +
|
||||
+
|
||||
@@ -210,11 +210,11 @@ Forward declared in `<boost/container_hash/hash_fwd.hpp>` +
|
||||
This hash function is not intended for general use, and isn't guaranteed to be equal during separate runs of a program - so please don't use it for any persistent storage or communication.
|
||||
|
||||
[horizontal]
|
||||
Throws:: Only throws if xref:#ref_hash_value[hash_value](T) throws. Strong exception safety, as long as xref:#ref_hash_value[hash_value](T) also has strong exception safety.
|
||||
Throws:: Only throws if `hash_value(T)` throws. Strong exception safety, as long as `hash_value(T)` also has strong exception safety.
|
||||
|
||||
=== hash_range
|
||||
|
||||
[listing]
|
||||
[source]
|
||||
----
|
||||
template<typename It>
|
||||
std::size_t hash_range(It, It);
|
||||
@@ -228,24 +228,24 @@ Calculate the combined hash value of the elements of an iterator range.
|
||||
[horizontal]
|
||||
Effects:: For the two argument overload:
|
||||
+
|
||||
[listing,subs="+quotes,+macros"]
|
||||
[source]
|
||||
----
|
||||
size_t seed = 0;
|
||||
|
||||
for(; first != last; ++first)
|
||||
{
|
||||
xref:#ref_hash_combine[hash_combine](seed, *first);
|
||||
hash_combine(seed, *first);
|
||||
}
|
||||
return seed;
|
||||
----
|
||||
+
|
||||
For the three arguments overload:
|
||||
+
|
||||
[listing,subs="+quotes,+macros"]
|
||||
[source]
|
||||
----
|
||||
for(; first != last; ++first)
|
||||
{
|
||||
xref:#ref_hash_combine[hash_combine](seed, *first);
|
||||
hash_combine(seed, *first);
|
||||
}
|
||||
----
|
||||
|
||||
@@ -259,13 +259,13 @@ Forward declared in `<boost/container_hash/hash_fwd.hpp>`
|
||||
This hash function is not intended for general use, and isn't guaranteed to be equal during separate runs of a program - so please don't use it for any persistent storage or communication.
|
||||
|
||||
[horizontal]
|
||||
Throws:: Only throws if xref:#ref_hash_value[hash_value]`(std::iterator_traits<It>::value_type)` throws. `hash_range(std::size_t&, It, It)` has basic exception safety as long as xref:#ref_hash_value[hash_value]`(std::iterator_traits<It>::value_type)` has basic exception safety.
|
||||
Throws:: Only throws if `hash_value(std::iterator_traits<It>::value_type)` throws. `hash_range(std::size_t&, It, It)` has basic exception safety as long as `hash_value(std::iterator_traits<It>::value_type)` has basic exception safety.
|
||||
|
||||
== Overloadable hash implementation (Boost extension).
|
||||
|
||||
=== hash_value
|
||||
|
||||
[listing]
|
||||
[source]
|
||||
----
|
||||
std::size_t hash_value(bool val);
|
||||
std::size_t hash_value(char val);
|
||||
@@ -319,7 +319,7 @@ template<typename... T>
|
||||
|
||||
Implementation of the hash function.
|
||||
|
||||
Generally shouldn't be called directly by users, instead they should use xref:#ref_hash[boost::hash], xref:#ref_hash_range[boost::hash_range] or xref:#ref_hash_combine[boost::hash_combine] which call `hash_value` without namespace qualification so that overloads for custom types are found via ADL.
|
||||
Generally shouldn't be called directly by users, instead they should use `boost::hash`, `boost::hash_range` or `boost::hash_combine` which call `hash_value` without namespace qualification so that overloads for custom types are found via ADL.
|
||||
|
||||
[horizontal]
|
||||
Notes:: This is an extension to TR1
|
||||
@@ -327,7 +327,7 @@ Notes:: This is an extension to TR1
|
||||
This hash function is not intended for general use, and isn't guaranteed to be equal during separate runs of a program - so please don't use it for any persistent storage or communication.
|
||||
|
||||
[horizontal]
|
||||
Throws:: Only throws if a user supplied version of xref:#ref_hash_value[hash_value] throws for an element of a container, or one of the types stored in a pair.
|
||||
Throws:: Only throws if a user supplied version of `hash_value` throws for an element of a container, or one of the types stored in a pair.
|
||||
|
||||
[vertical]
|
||||
Returns::
|
||||
@@ -357,7 +357,7 @@ Returns::
|
||||
|`std::pair<A, B>`
|
||||
a|
|
||||
|
||||
[listing]
|
||||
[source]
|
||||
----
|
||||
size_t seed = 0;
|
||||
hash_combine(seed, val.first);
|
||||
@@ -368,7 +368,7 @@ return seed;
|
||||
|`std::tuple<T...>`
|
||||
a|
|
||||
|
||||
[listing]
|
||||
[source]
|
||||
----
|
||||
size_t seed = 0;
|
||||
hash_combine(seed, get<0>(val));
|
||||
|
@@ -3,30 +3,30 @@
|
||||
|
||||
:idprefix: tutorial_
|
||||
|
||||
When using a hash index with link:../../../multi_index/index.html[Boost.MultiIndex^], you don't need to do anything to use xref:#ref_hash[boost::hash] as it uses it by default. To find out how to use a user-defined type, read the <<custom,section on extending boost::hash for a custom data type>>.
|
||||
When using a hash index with link:../../../multi_index/index.html[Boost.MultiIndex], you don't need to do anything to use `boost::hash` as it uses it by default. To find out how to use a user-defined type, read the <<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 xref:#ref_hash[boost::hash], just use an extra template parameter:
|
||||
If your standard library supplies its own implementation of the unordered associative containers and you wish to use `boost::hash`, just use an extra template parameter:
|
||||
|
||||
[listing,subs="+quotes,+macros"]
|
||||
[source]
|
||||
----
|
||||
std::unordered_multiset<int, xref:#ref_hash[boost::hash]<int> >
|
||||
std::unordered_multiset<int, boost::hash<int> >
|
||||
set_of_ints;
|
||||
|
||||
std::unordered_set<std::pair<int, int>, xref:#ref_hash[boost::hash]<std::pair<int, int> > >
|
||||
std::unordered_set<std::pair<int, int>, boost::hash<std::pair<int, int> > >
|
||||
set_of_pairs;
|
||||
|
||||
std::unordered_map<int, std::string, xref:#ref_hash[boost::hash]<int> > map_int_to_string;
|
||||
std::unordered_map<int, std::string, boost::hash<int> > map_int_to_string;
|
||||
----
|
||||
|
||||
To use xref:#ref_hash[boost::hash] directly, create an instance and call it as a function:
|
||||
To use `boost::hash` directly, create an instance and call it as a function:
|
||||
|
||||
[listing,subs="+quotes,+macros"]
|
||||
[source]
|
||||
----
|
||||
xref:#ref_header_boostcontainer_hashhash_hpp[++#include <boost/container_hash/hash.hpp>++]
|
||||
#include <boost/container_hash/hash.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
xref:#ref_hash[boost::hash]<std::string> string_hash;
|
||||
boost::hash<std::string> string_hash;
|
||||
|
||||
std::size_t h = string_hash("Hash me");
|
||||
}
|
||||
@@ -34,14 +34,14 @@ int main()
|
||||
|
||||
For an example of generic use, here is a function to generate a vector containing the hashes of the elements of a container:
|
||||
|
||||
[listing,subs="+quotes,+macros"]
|
||||
[source]
|
||||
----
|
||||
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::back_inserter(hashes),
|
||||
xref:#ref_hash[boost::hash]<typename Container::value_type>());
|
||||
boost::hash<typename Container::value_type>());
|
||||
|
||||
return hashes;
|
||||
}
|
||||
|
Reference in New Issue
Block a user