From 2d23e7e0566792d0781aa725c0bef8b0ba0381b0 Mon Sep 17 00:00:00 2001 From: Christian Mazakas Date: Wed, 2 Feb 2022 10:44:02 -0800 Subject: [PATCH 01/23] Update Jamfile to produce AsciiDoc and add corresponding file stubs --- doc/Jamfile.v2 | 29 +++++++++++++---------------- doc/hash.adoc | 23 +++++++++++++++++++++++ doc/hash/changes.adoc | 4 ++++ doc/hash/combine.adoc | 4 ++++ doc/hash/copyright.adoc | 4 ++++ doc/hash/custom.adoc | 4 ++++ doc/hash/disable.adoc | 4 ++++ doc/hash/intro.adoc | 4 ++++ doc/hash/links.adoc | 4 ++++ doc/hash/portability.adoc | 4 ++++ doc/hash/rationale.adoc | 4 ++++ doc/hash/ref.adoc | 4 ++++ doc/hash/thanks.adoc | 4 ++++ doc/hash/tutorial.adoc | 4 ++++ 14 files changed, 84 insertions(+), 16 deletions(-) create mode 100644 doc/hash.adoc create mode 100644 doc/hash/changes.adoc create mode 100644 doc/hash/combine.adoc create mode 100644 doc/hash/copyright.adoc create mode 100644 doc/hash/custom.adoc create mode 100644 doc/hash/disable.adoc create mode 100644 doc/hash/intro.adoc create mode 100644 doc/hash/links.adoc create mode 100644 doc/hash/portability.adoc create mode 100644 doc/hash/rationale.adoc create mode 100644 doc/hash/ref.adoc create mode 100644 doc/hash/thanks.adoc create mode 100644 doc/hash/tutorial.adoc diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 index 86f889a..006fe8b 100644 --- a/doc/Jamfile.v2 +++ b/doc/Jamfile.v2 @@ -3,23 +3,20 @@ # Distributed under the Boost Software License, Version 1.0. (See accompanying # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -using boostbook ; -using quickbook ; +import asciidoctor ; -xml hash : hash.qbk ; -boostbook standalone : hash : - boost.root=../../../.. +html hash.html : hash.adoc ; - chunk.first.sections=1 - chunk.section.depth=2 - generate.section.toc.level=2 - toc.section.depth=1 - toc.max.depth=1 - pdf:boost.url.prefix=http://www.boost.org/doc/libs/release/libs/container_hash/doc/html - ; +install html_ : hash.html : html ; + +pdf hash.pdf : hash.adoc ; +explicit hash.pdf ; + +install pdf_ : hash.pdf : pdf ; +explicit pdf_ ; ############################################################################### - alias boostdoc : hash ; - explicit boostdoc ; - alias boostrelease ; - explicit boostrelease ; +alias boostdoc ; +explicit boostdoc ; +alias boostrelease : html_ ; +explicit boostrelease ; diff --git a/doc/hash.adoc b/doc/hash.adoc new file mode 100644 index 0000000..7362e61 --- /dev/null +++ b/doc/hash.adoc @@ -0,0 +1,23 @@ += Boost.ContainerHash +:toc: left +:toclevels: 2 +:idprefix: +:docinfo: private-footer +:source-highlighter: rouge +:nofooter: +:sectlinks: + +:leveloffset: +1 + +include::hash/intro.adoc[] +include::hash/tutorial.adoc[] +include::hash/custom.adoc[] +include::hash/combine.adoc[] +include::hash/portability.adoc[] +include::hash/disable.adoc[] +include::hash/changes.adoc[] +include::hash/rationale.adoc[] +include::hash/ref.adoc[] +include::hash/links.adoc[] +include::hash/thanks.adoc[] +include::hash/copyright.adoc[] \ No newline at end of file diff --git a/doc/hash/changes.adoc b/doc/hash/changes.adoc new file mode 100644 index 0000000..2eff44f --- /dev/null +++ b/doc/hash/changes.adoc @@ -0,0 +1,4 @@ +[#changes] += Change Log + +:idprefix: changes_ \ No newline at end of file diff --git a/doc/hash/combine.adoc b/doc/hash/combine.adoc new file mode 100644 index 0000000..3bd3575 --- /dev/null +++ b/doc/hash/combine.adoc @@ -0,0 +1,4 @@ +[#combine] += Combining hash values + +:idprefix: combine_ diff --git a/doc/hash/copyright.adoc b/doc/hash/copyright.adoc new file mode 100644 index 0000000..94fc43f --- /dev/null +++ b/doc/hash/copyright.adoc @@ -0,0 +1,4 @@ +[#copyright] += Copyright + +:idprefix: copyright_ diff --git a/doc/hash/custom.adoc b/doc/hash/custom.adoc new file mode 100644 index 0000000..f4a3f52 --- /dev/null +++ b/doc/hash/custom.adoc @@ -0,0 +1,4 @@ +[#custom] += Extending boost::hash for a custom data type + +:idprefix: custom_ diff --git a/doc/hash/disable.adoc b/doc/hash/disable.adoc new file mode 100644 index 0000000..9885242 --- /dev/null +++ b/doc/hash/disable.adoc @@ -0,0 +1,4 @@ +[#disable] += Disabling The Extensions + +:idprefix: disable_ diff --git a/doc/hash/intro.adoc b/doc/hash/intro.adoc new file mode 100644 index 0000000..8a9d0cb --- /dev/null +++ b/doc/hash/intro.adoc @@ -0,0 +1,4 @@ +[#intro] += Introduction + +:idprefix: intro_ diff --git a/doc/hash/links.adoc b/doc/hash/links.adoc new file mode 100644 index 0000000..e99c705 --- /dev/null +++ b/doc/hash/links.adoc @@ -0,0 +1,4 @@ +[#links] += Links + +:idprefix: links_ diff --git a/doc/hash/portability.adoc b/doc/hash/portability.adoc new file mode 100644 index 0000000..0f86e87 --- /dev/null +++ b/doc/hash/portability.adoc @@ -0,0 +1,4 @@ +[#portability] += Portability + +:idprefix: portability_ diff --git a/doc/hash/rationale.adoc b/doc/hash/rationale.adoc new file mode 100644 index 0000000..75522fd --- /dev/null +++ b/doc/hash/rationale.adoc @@ -0,0 +1,4 @@ +[#rationale] += Rationale + +:idprefix: rationale_ diff --git a/doc/hash/ref.adoc b/doc/hash/ref.adoc new file mode 100644 index 0000000..15a3169 --- /dev/null +++ b/doc/hash/ref.adoc @@ -0,0 +1,4 @@ +[#ref] += Reference + +:idprefix: ref_ diff --git a/doc/hash/thanks.adoc b/doc/hash/thanks.adoc new file mode 100644 index 0000000..0f6ab59 --- /dev/null +++ b/doc/hash/thanks.adoc @@ -0,0 +1,4 @@ +[#thanks] += Acknowledgements + +:idprefix: thanks_ \ No newline at end of file diff --git a/doc/hash/tutorial.adoc b/doc/hash/tutorial.adoc new file mode 100644 index 0000000..04841fd --- /dev/null +++ b/doc/hash/tutorial.adoc @@ -0,0 +1,4 @@ +[#tutorial] += Tutorial + +:idprefix: tutorial_ From a67e350fd9176e8fe20b00928bb04891aa6a4180 Mon Sep 17 00:00:00 2001 From: Christian Mazakas Date: Wed, 2 Feb 2022 11:07:50 -0800 Subject: [PATCH 02/23] Add Introduction section to AsciiDoc --- doc/hash/intro.adoc | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/doc/hash/intro.adoc b/doc/hash/intro.adoc index 8a9d0cb..60c731e 100644 --- a/doc/hash/intro.adoc +++ b/doc/hash/intro.adoc @@ -2,3 +2,21 @@ = Introduction :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`. + +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: + +* arrays +* `std::pair` +* the standard containers. +* extending xref:#ref_hash[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 <>. From 301c76646cde41faa7d932ef66394c3d62bc4268 Mon Sep 17 00:00:00 2001 From: Christian Mazakas Date: Wed, 2 Feb 2022 11:14:05 -0800 Subject: [PATCH 03/23] Add Tutorial section to AsciiDoc --- doc/hash/tutorial.adoc | 44 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/doc/hash/tutorial.adoc b/doc/hash/tutorial.adoc index 04841fd..aa165d6 100644 --- a/doc/hash/tutorial.adoc +++ b/doc/hash/tutorial.adoc @@ -2,3 +2,47 @@ = Tutorial :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 <>. + +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: + +[listing,subs="+quotes,+macros"] +---- +std::unordered_multiset > + set_of_ints; + +std::unordered_set, xref:#ref_hash[boost::hash] > > + set_of_pairs; + +std::unordered_map > map_int_to_string; +---- + +To use xref:#ref_hash[boost::hash] directly, create an instance and call it as a function: + +[listing,subs="+quotes,+macros"] +---- +xref:#ref_header_boostcontainer_hashhash_hpp[++#include ++] + +int main() +{ + xref:#ref_hash[boost::hash] 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: + +[listing,subs="+quotes,+macros"] +---- +template +std::vector get_hashes(Container const& x) +{ + std::vector hashes; + std::transform(x.begin(), x.end(), std::back_inserter(hashes), + xref:#ref_hash[boost::hash]()); + + return hashes; +} +---- From 37f3e6fcb762b46805f200a87fe253ac925f2ebf Mon Sep 17 00:00:00 2001 From: Christian Mazakas Date: Wed, 2 Feb 2022 11:26:40 -0800 Subject: [PATCH 04/23] Add Extending boost::hash section to AsciiDoc --- doc/hash/custom.adoc | 64 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/doc/hash/custom.adoc b/doc/hash/custom.adoc index f4a3f52..5e0a650 100644 --- a/doc/hash/custom.adoc +++ b/doc/hash/custom.adoc @@ -2,3 +2,67 @@ = Extending boost::hash for a custom data type :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. + +If you have a structure `library::book`, where each book is uniquely defined by its member `id`: + +[listing] +---- +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`: + +[listing,subs="+quotes,+macros"] +---- +namespace library +{ + std::size_t hash_value(book const& b) + { + xref:#ref_hash[boost::hash] hasher; + return hasher(b.id); + } +} +---- + +And you can now use xref:#ref_hash[boost::hash] with book: + +[listing,subs="+quotes,+macros"] +---- +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] book_hasher; +std::size_t knife_hash_value = book_hasher(knife); + +// If std::unordered_set is available: +std::unordered_set > 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: 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). From 74f9abe52c797a9a5976720865a12d3665c132c7 Mon Sep 17 00:00:00 2001 From: Christian Mazakas Date: Wed, 2 Feb 2022 12:45:24 -0800 Subject: [PATCH 05/23] Add Combining Hashes section to AsciiDoc --- doc/hash/combine.adoc | 76 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/doc/hash/combine.adoc b/doc/hash/combine.adoc index 3bd3575..ac49a86 100644 --- a/doc/hash/combine.adoc +++ b/doc/hash/combine.adoc @@ -2,3 +2,79 @@ = Combining hash values :idprefix: combine_ + +Say you have a point class, representing a two dimensional location: + +[listing] +---- +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 xref:#ref_hash_combine[boost::hash_combine] is supplied for this purpose: + +[listing,subs="+quotes,+macros"] +---- +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); + + 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 xref:#ref_hash_value[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^]. + +[NOTE] +==== +When using xref:#ref_hash_combine[boost::hash_combine] the order of the calls matters. +[listing,subs="+quotes,+macros"] +---- +std::size_t seed = 0; +boost::hash_combine(seed, 1); +boost::hash_combine(seed, 2); +---- +results in a different seed to: + +[listing,subs="+quotes,+macros"] +---- +std::size_t seed = 0; +boost::hash_combine(seed, 2); +boost::hash_combine(seed, 1); +---- + +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 xref:#ref_hash_range[boost::hash_range]: + +[listing,subs="+quotes,+macros"] +---- +std::vector some_strings; +std::size_t hash = xref:#ref_hash_range[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 `` 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^]. From 21dbdb9b47ae01957f2e8bb7fc460e3624acf35a Mon Sep 17 00:00:00 2001 From: Christian Mazakas Date: Wed, 2 Feb 2022 13:14:51 -0800 Subject: [PATCH 06/23] Add Portability section to AsciiDoc --- doc/hash/portability.adoc | 78 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/doc/hash/portability.adoc b/doc/hash/portability.adoc index 0f86e87..a552b8e 100644 --- a/doc/hash/portability.adoc +++ b/doc/hash/portability.adoc @@ -2,3 +2,81 @@ = Portability :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. + +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. + +Let's say we have a simple custom type: + +[list,subs="+quotes,+macros"] +---- +namespace foo +{ + template + class custom_type + { + T value; + public: + custom_type(T x) : value(x) {} + + friend std::size_t hash_value(custom_type x) + { + xref:#ref_hash[boost::hash] 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: + +[listing,subs="+quotes,+macros"] +---- +namespace foo +{ + template + class custom_type + { + T value; + public: + custom_type(T x) : value(x) {} + + std::size_t hash(custom_type x) + { + xref:#ref_hash[boost::hash] hasher; + return hasher(value); + } + }; + + template + inline std::size_t hash_value(custom_type 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: + +[listing] +---- +#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP +namespace boost +#else +namespace foo +#endif +{ + template + std::size_t hash_value(foo::custom_type x) + { + return x.hash(); + } +} +---- + +Full code for this example is at link:../../examples/portable.cpp[/libs/container_hash/examples/portable.cpp^]. From 334eac8166012627a2dfde24642a46bc147e1030 Mon Sep 17 00:00:00 2001 From: Christian Mazakas Date: Wed, 2 Feb 2022 13:20:23 -0800 Subject: [PATCH 07/23] Add Disabling section to AsciiDoc --- doc/hash/disable.adoc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/hash/disable.adoc b/doc/hash/disable.adoc index 9885242..eeba618 100644 --- a/doc/hash/disable.adoc +++ b/doc/hash/disable.adoc @@ -2,3 +2,11 @@ = Disabling The Extensions :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[] 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. From c95e02fe854b4894fd8ccc27a68fa7fc9a20d31b Mon Sep 17 00:00:00 2001 From: Christian Mazakas Date: Wed, 2 Feb 2022 15:00:32 -0800 Subject: [PATCH 08/23] Add Change List to AsciiDoc --- doc/hash/changes.adoc | 130 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 129 insertions(+), 1 deletion(-) diff --git a/doc/hash/changes.adoc b/doc/hash/changes.adoc index 2eff44f..51e09d9 100644 --- a/doc/hash/changes.adoc +++ b/doc/hash/changes.adoc @@ -1,4 +1,132 @@ [#changes] = Change Log -:idprefix: changes_ \ No newline at end of file +:cpp: C++ +:int128: __int128 + +:idprefix: changes_ + +== Boost 1.67.0 +* Moved library into its own module, `container_hash`. +* Moved headers for new module name, now at: ``, ``, ``. +* Added forwarding headers to support the old headers locations. +* 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^]). +* Quick fix for hashing `vector` when using lib{cpp}. Will try to introduce a more general fix in the next release. + +== Boost 1.66.0 +* Avoid float comparison warning when using Clang - this workaround was already in place for GCC, and was used when Clang pretends to be GCC, but the warning was appearing when running Clang in other contexts. + +== Boost 1.65.0 +* 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^]). + +== 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^]). + +== Boost 1.58.0 +* 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^]). + +== Boost 1.54.0 +* 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. +* On platforms that are known to have the standard floating point functions, don't use automatic detection - which can break if there are ambiguous overloads. +* Fix undefined behaviour when using the binary `float` hash (Thomas Heller). + +== Boost 1.52.0 +* Restore `enum` support, which was accidentally removed in the last version. +* New floating point hasher - will hash the binary representation on more platforms, which should be faster. + +== Boost 1.51.0 +* Support the standard smart pointers. +* `hash_value` now implemented using SFINAE to avoid implicit casts to built in types when calling it. +* Updated to use the new config macros. + +== 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. +* Add deprecation warning to the long deprecated `boost/container_hash/detail/container_fwd.hpp`. + +== Boost 1.46.0 +* Avoid warning due with gcc's `-Wconversion` flag. + +== Boost 1.44.0 +* Add option to prevent implicit conversions when calling `hash_value` by defining `BOOST_HASH_NO_IMPLICIT_CASTS`. When using `boost::hash` for a type that does not have `hash_value` declared but does have an implicit conversion to a type that does, it would use that implicit conversion to hash it. Which can sometimes go very wrong, e.g. using a conversion to `bool` and only hashing to 2 possible values. Since fixing this is a breaking change and was only approached quite late in the release cycle with little discussion it's opt-in for now. This, or something like it, will become the default in a future version. + +== Boost 1.43.0 +* https://svn.boost.org/trac/boost/ticket/3866[Ticket 3866^]: Don't foward declare containers when using gcc's parallel library, allow user to stop forward declaration by defining the `BOOST_DETAIL_NO_CONTAINER_FWD` macro. +* https://svn.boost.org/trac/boost/ticket/4038[Ticket 4038^]: Avoid hashing `0.5` and `0` to the same number. +* Stop using deprecated `BOOST_HAS_*` macros. + +== Boost 1.42.0 +* Reduce the number of warnings for Visual {cpp} warning level 4. +* Some code formatting changes to fit lines into 80 characters. +* Rename an internal namespace. + +== Boost 1.40.0 +* Automatically configure the `float` functions using template metaprogramming instead of trying to configure every possibility manually. +* Workaround for when STLport doesn't support long double. + +== 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. + +== 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. + +== Boost 1.36.0 +* Stop using OpenBSD's dodgy `std::numeric_limits`. +* Using the boost typedefs for `long long` and `unsigned long long`. +* Move the extensions into their own header. + +== 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^]. +** 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. +* 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. +** 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}. + +== Boost 1.34.0 +* Use declarations for standard classes, so that the library doesn't need to include all of their headers +* Deprecated the `` headers. Now a single header, `` 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. +* Update the portable example to hopefully be more generally portable. + +== Boost 1.33.1 +* Fixed the points example, as pointed out by 沈慧峰. + +== Boost 1.33.0 +* Initial Release + From 6600a264605af9d01e3df59485cc0fd670b16ee1 Mon Sep 17 00:00:00 2001 From: Christian Mazakas Date: Wed, 2 Feb 2022 15:28:09 -0800 Subject: [PATCH 09/23] Add Rationale to AsciiDoc --- doc/hash/rationale.adoc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/doc/hash/rationale.adoc b/doc/hash/rationale.adoc index 75522fd..18f2a47 100644 --- a/doc/hash/rationale.adoc +++ b/doc/hash/rationale.adoc @@ -2,3 +2,15 @@ = Rationale :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)]. + +== Quality of the hash function + +Many hash functions strive to have little correlation between the input and output values. They attempt to uniformally distribute the output values for very similar inputs. This hash function makes no such attempt. In fact, for integers, the result of the hash function is often just the input value. So similar but different input values will often result in similar but different output values. This means that it is not appropriate as a general hash function. For example, a hash table may discard bits from the hash function resulting in likely collisions, or might have poor collision resolution when hash values are clustered together. In such cases this hash function will preform poorly. + +But the standard has no such requirement for the hash function, it just requires that the hashes of two different values are unlikely to collide. Containers or algorithms designed to work with the standard hash function will have to be implemented to work well when the hash function's output is correlated to its input. Since they are paying that cost a higher quality hash function would be wasteful. + +For other use cases, if you do need a higher quality hash function, then neither the standard hash function or `boost::hash` are appropriate. There are several options available. One is to use a second hash on the output of this hash function, such as http://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). From b2222c2755c4ac87bac925c0258e610b218e1c64 Mon Sep 17 00:00:00 2001 From: Christian Mazakas Date: Thu, 3 Feb 2022 08:48:33 -0800 Subject: [PATCH 10/23] Add Links section to AsciiDoc --- doc/hash/links.adoc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/hash/links.adoc b/doc/hash/links.adoc index e99c705..3ed3d1b 100644 --- a/doc/hash/links.adoc +++ b/doc/hash/links.adoc @@ -2,3 +2,11 @@ = Links :idprefix: links_ + +*A Proposal to Add Hash Tables to the Standard Library* http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1456.html The hash table proposal explains much of the design. The hash function object is discussed in Section D. + +*The C++ Standard Library Technical Report.* http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf Contains the hash function specification in section 6.3.2. + +*Library Extension Technical Report Issues List.* http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf The library implements the extension described in Issue 6.18, pages 63-67. + +*Methods for Identifying Versioned and Plagiarised Documents* Timothy C. Hoad, Justin Zobel http://www.cs.rmit.edu.au/~jz/fulltext/jasist-tch.pdf Contains the hash function that `boost::hash_combine` is based on. From 5906cba1a0b301a8e8dbb507114c0e9459a1f539 Mon Sep 17 00:00:00 2001 From: Christian Mazakas Date: Thu, 3 Feb 2022 08:51:40 -0800 Subject: [PATCH 11/23] Add Acknowledgements section --- doc/hash/thanks.adoc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/doc/hash/thanks.adoc b/doc/hash/thanks.adoc index 0f6ab59..d46c249 100644 --- a/doc/hash/thanks.adoc +++ b/doc/hash/thanks.adoc @@ -1,4 +1,14 @@ [#thanks] = Acknowledgements -:idprefix: thanks_ \ No newline at end of file +:idprefix: thanks_ + +This library is based on the design by Peter Dimov. During the initial development Joaquín M López Muñoz made many useful suggestions and 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, further constructive criticism has been made by Daniel Krügler, Alexander Nasonov and 沈慧峰. + +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 `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. From 06db43a56ac9ff605013e7c50f7c62d335c7fa61 Mon Sep 17 00:00:00 2001 From: Christian Mazakas Date: Thu, 3 Feb 2022 08:57:45 -0800 Subject: [PATCH 12/23] Add Copyright section to AsciiDoc --- doc/hash/copyright.adoc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/doc/hash/copyright.adoc b/doc/hash/copyright.adoc index 94fc43f..1551b0b 100644 --- a/doc/hash/copyright.adoc +++ b/doc/hash/copyright.adoc @@ -1,4 +1,10 @@ [#copyright] -= Copyright += Copyright and License :idprefix: copyright_ + +*Daniel James* + +Copyright (C) 2005-2008 Daniel James + +Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) From 773307fe1cc70b254b3534e2f9af89b5d708b558 Mon Sep 17 00:00:00 2001 From: Christian Mazakas Date: Thu, 3 Feb 2022 15:32:05 -0800 Subject: [PATCH 13/23] Add Reference section to AsciiDoc --- doc/hash/ref.adoc | 382 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 382 insertions(+) diff --git a/doc/hash/ref.adoc b/doc/hash/ref.adoc index 15a3169..ec3719a 100644 --- a/doc/hash/ref.adoc +++ b/doc/hash/ref.adoc @@ -2,3 +2,385 @@ = Reference :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). + +== Header + +Defines xref:#ref_hash[boost::hash], and helper functions. + +[listing,subs="+quotes,+macros"] +---- +namespace boost { + template struct xref:#ref_hash[hash]; + + template<> struct xref:#ref_specializations[hash]; + template<> struct xref:#ref_specializations[hash]; + template<> struct xref:#ref_specializations[hash]; + template<> struct xref:#ref_specializations[hash]; + template<> struct xref:#ref_specializations[hash]; + template<> struct xref:#ref_specializations[hash]; + template<> struct xref:#ref_specializations[hash]; + template<> struct xref:#ref_specializations[hash]; + template<> struct xref:#ref_specializations[hash]; + template<> struct xref:#ref_specializations[hash]; + template<> struct xref:#ref_specializations[hash]; + template<> struct xref:#ref_specializations[hash]; + template<> struct xref:#ref_specializations[hash]; + template<> struct xref:#ref_specializations[hash]; + template<> struct xref:#ref_specializations[hash]; + template<> struct xref:#ref_specializations[hash]; + template<> struct xref:#ref_specializations[hash]; + template<> struct xref:#ref_specializations[hash]; + template<> struct xref:#ref_specializations[hash]; + template<> struct xref:#ref_specializations[hash]; + template<> struct xref:#ref_specializations[hash]; + template<> struct xref:#ref_specializations[hash]; + template<> struct xref:#ref_specializations[hash]; + + template struct xref:#ref_specializations[hash]; + + // xref:#ref_support_functions_boost_extension[Support functions (Boost extension).] + template + void xref:#ref_hash_combine[hash_combine](size_t &, T const&); + + template + std::size_t xref:#ref_hash_range[hash_range](It, It); + + template + void xref:#ref_hash_range[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); + + template + std::size_t xref:#ref_hash_value[hash_value](T* const&); + + template + std::size_t xref:#ref_hash_value[hash_value](T (&val)[N]); + + template + std::size_t xref:#ref_hash_value[hash_value](const T (&val)[N]); + + template + std::size_t xref:#ref_hash_value[hash_value](std::basic_string, A> const&); + + template + std::size_t xref:#ref_hash_value[hash_value](std::pair const&); + + template + std::size_t xref:#ref_hash_value[hash_value](std::vector const&); + + template + std::size_t xref:#ref_hash_value[hash_value](std::list const&); + + template + std::size_t xref:#ref_hash_value[hash_value](std::deque const&); + + template + std::size_t xref:#ref_hash_value[hash_value](std::set const&); + + template + std::size_t xref:#ref_hash_value[hash_value](std::multiset const&); + + template + std::size_t xref:#ref_hash_value[hash_value](std::map const&); + + template + std::size_t xref:#ref_hash_value[hash_value](std::multimap const&); + + template std::size_t xref:#ref_hash_value[hash_value](std::complex const&); + std::size_t xref:#ref_hash_value[hash_value](std::type_index); + + template + std::size_t xref:#ref_hash_value[hash_value](std::array const&); + + template + std::size_t xref:#ref_hash_value[hash_value](std::tuple); +} +---- + +== Struct template hash + +=== hash + +`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"] +---- +// xref:#ref_header_boostcontainer_hashhash_hpp[#include ] + +template +struct hash : public std::unary_function { + std::size_t operator()(T const&) const; +}; +---- + +==== Description + +[listing] +---- +std::size_t operator()(T const& val) const; +---- + +[horizontal] +Returns:: xref:#ref_hash_value[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. ++ +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. ++ +Forward declared in `` ++ +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. + +== Specializations + +`boost::hash` + +=== Synopsis + +[listing] +---- +// #include + +struct hash { + std::size_t operator()(T const&) const; +}; +---- + +=== Description + +[listing] +---- +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. + +[horizontal] +Throws:: Doesn't throw + +== Support functions (Boost extension). + +=== hash_combine + +[listing] +---- +template +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. + +[horizontal] +Notes:: xref:#ref_hash_value[hash_value] is called without qualification, so that overloads can be found via ADL. + ++ +This is an extension to TR1 + ++ +Forward declared in `` + ++ +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. + +=== hash_range + +[listing] +---- +template +std::size_t hash_range(It, It); + +template +void hash_range(std::size_t&, It, It); +---- + +Calculate the combined hash value of the elements of an iterator range. + +[horizontal] +Effects:: For the two argument overload: ++ +[listing,subs="+quotes,+macros"] +---- +size_t seed = 0; + +for(; first != last; ++first) +{ + xref:#ref_hash_combine[hash_combine](seed, *first); +} +return seed; +---- ++ +For the three arguments overload: ++ +[listing,subs="+quotes,+macros"] +---- +for(; first != last; ++first) +{ + xref:#ref_hash_combine[hash_combine](seed, *first); +} +---- + +[horizontal] +Notes:: `hash_range` is sensitive to the order of the elements so it wouldn't be appropriate to use this with an unordered container. ++ +This is an extension to TR1 ++ +Forward declared in `` ++ +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::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::value_type)` has basic exception safety. + +== Overloadable hash implementation (Boost extension). + +=== hash_value + +[listing] +---- +std::size_t hash_value(bool val); +std::size_t hash_value(char val); +std::size_t hash_value(signed char val); +std::size_t hash_value(unsigned char val); +std::size_t hash_value(wchar_t val); +std::size_t hash_value(char16_t val); +std::size_t hash_value(char32_t val); +std::size_t hash_value(short val); +std::size_t hash_value(unsigned short val); +std::size_t hash_value(int val); +std::size_t hash_value(unsigned int val); +std::size_t hash_value(long val); +std::size_t hash_value(unsigned long val); +std::size_t hash_value(long long val); +std::size_t hash_value(unsigned long long val); +std::size_t hash_value(float val); +std::size_t hash_value(double val); +std::size_t hash_value(long double val); + +template std::size_t hash_value(T* const& val); + +template std::size_t hash_value(T (&val)[N]); +template std::size_t hash_value(const T (&val)[N]); + +template + std::size_t hash_value(std::basic_string, A> const& val); +template + std::size_t hash_value(std::pair const& val); +template + std::size_t hash_value(std::vector const& val); +template + std::size_t hash_value(std::list const& val); +template + std::size_t hash_value(std::deque const& val); +template + std::size_t hash_value(std::set const& val); +template + std::size_t hash_value(std::multiset const& val); +template + std::size_t hash_value(std::map const& val); +template + std::size_t hash_value(std::multimap const& val); +template std::size_t hash_value(std::complex const& val); +std::size_t hash_value(std::type_index val); +template + std::size_t hash_value(std::array const& val); +template + std::size_t hash_value(std::tuple val); +---- + +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. + +[horizontal] +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. + +[vertical] +Returns:: ++ +[cols="1,1", frame=all, grid=rows] +|=== +|Types |Returns + +|`bool`, `char`, `signed char`, `unsigned char`, `wchar_t`, `char16_t`, `char32_t`, `short`, `unsigned short`, `int`, `unsigned int`, `long`, `unsigned long` +|val + +|`long long`, `unsigned long long` +|val when `abs(val) \<= std::numeric_limits::max()`. + +|`float`, `double`, `long double` +|An unspecified value, except that equal arguments shall yield the same result. + +|`T*` +|An unspecified value, except that equal arguments shall yield the same result. + +|`T val[N]`, `const T val[N]` +|`hash_range(val, val+N)` + +|`std:basic_string, A>`, `std::vector`, `std::list`, `std::deque`, `std::set`, `std::multiset`, `std::map`, `std::multimap`, `std::array` +|`hash_range(val.begin(), val.end())` + +|`std::pair` +a| + +[listing] +---- +size_t seed = 0; +hash_combine(seed, val.first); +hash_combine(seed, val.second); +return seed; +---- + +|`std::tuple` +a| + +[listing] +---- +size_t seed = 0; +hash_combine(seed, get<0>(val)); +hash_combine(seed, get<1>(val)); +// .... +return seed; +---- + +|`std::complex` +|When T is a built in type and `val.imag() == 0`, the result is equal to `hash_value(val.real())`. Otherwise an unspecified value, except that equal arguments shall yield the same result. + +|`std::type_index` +|`val.hash_code()` + +|=== From 4ab431f12f20a819040062f14400006e777163a7 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 5 Feb 2022 02:12:27 +0200 Subject: [PATCH 14/23] Update index.html --- index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index 4b26a41..409b989 100644 --- a/index.html +++ b/index.html @@ -7,10 +7,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - + Automatic redirection failed, please go to -../../doc/html/hash.html +doc/html/hash.html From 143a55ea3bc17200122325df7c320703a519b282 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 5 Feb 2022 02:13:07 +0200 Subject: [PATCH 15/23] Add doc/.gitignore --- doc/.gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 doc/.gitignore diff --git a/doc/.gitignore b/doc/.gitignore new file mode 100644 index 0000000..0972e2d --- /dev/null +++ b/doc/.gitignore @@ -0,0 +1,2 @@ +/html/ +/pdf/ From dee871f45c23274a03a8512407bd844ecae90a08 Mon Sep 17 00:00:00 2001 From: Christian Mazakas Date: Mon, 7 Feb 2022 13:11:32 -0800 Subject: [PATCH 16/23] Remove unneeded QuickBook and sample files from docs --- doc/changes.qbk | 222 --------- doc/disable.qbk | 29 -- doc/hash.qbk | 29 -- doc/intro.qbk | 52 -- doc/links.qbk | 27 -- doc/portability.qbk | 93 ---- doc/rationale.qbk | 50 -- doc/ref.xml | 994 --------------------------------------- doc/samples/tutorial.cpp | 27 -- doc/thanks.qbk | 28 -- doc/tutorial.qbk | 207 -------- 11 files changed, 1758 deletions(-) delete mode 100644 doc/changes.qbk delete mode 100644 doc/disable.qbk delete mode 100644 doc/hash.qbk delete mode 100644 doc/intro.qbk delete mode 100644 doc/links.qbk delete mode 100644 doc/portability.qbk delete mode 100644 doc/rationale.qbk delete mode 100644 doc/ref.xml delete mode 100644 doc/samples/tutorial.cpp delete mode 100644 doc/thanks.qbk delete mode 100644 doc/tutorial.qbk diff --git a/doc/changes.qbk b/doc/changes.qbk deleted file mode 100644 index 459a15d..0000000 --- a/doc/changes.qbk +++ /dev/null @@ -1,222 +0,0 @@ - -[/ Copyright 2005-2008 Daniel James. - / Distributed under the Boost Software License, Version 1.0. (See accompanying - / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ] - -[template ticket[number]''''''#[number]''''''] - -[section:changes Change Log] - -[h2 Boost 1.33.0] - -* Initial Release - -[h2 Boost 1.33.1] - -* Fixed the points example, as pointed out by 沈慧峰. - -[h2 Boost 1.34.0] - -* Use declarations for standard classes, so that the library - doesn't need to include all of their headers -* Deprecated the `` 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. -* Update the portable example to hopefully be more generally portable. - -[h2 Boost 1.34.1] - -* [@http://svn.boost.org/trac/boost/ticket/952 Ticket 952]: - Suppress incorrect 64-bit warning on Visual C++. - -[h2 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]. - * 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`. -* 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 C++ warning. - * Some workarounds for the Sun compilers. - -[h2 Boost 1.36.0] - -* Stop using OpenBSD's dodgy `std::numeric_limits`. -* Using the boost typedefs for `long long` and `unsigned long long`. -* Move the extensions into their own header. - -[h2 Boost 1.37.0] - -* [@http://svn.boost.org/trac/boost/ticket/2264 Ticket 2264]: - In Visual C++, always use C99 float functions for `long double` and `float` as - the C++ overloads aren't always availables. - -[h2 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`. - -[h2 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. - -[h2 Boost 1.40.0] - -* Automatically configure the float functions using template metaprogramming - instead of trying to configure every possibility manually. -* Workaround for when STLport doesn't support long double. - -[h2 Boost 1.42.0] - -* Reduce the number of warnings for Visual C++ warning level 4. -* Some code formatting changes to fit lines into 80 characters. -* Rename an internal namespace. - -[h2 Boost 1.43.0] - -* [@https://svn.boost.org/trac/boost/ticket/3866 Ticket 3866]: - Don't foward declare containers when using gcc's parallel library, - allow user to stop forward declaration by defining the - `BOOST_DETAIL_NO_CONTAINER_FWD` macro. -* [@https://svn.boost.org/trac/boost/ticket/4038 Ticket 4038]: - Avoid hashing 0.5 and 0 to the same number. -* Stop using deprecated `BOOST_HAS_*` macros. - -[h2 Boost 1.44.0] - -* Add option to prevent implicit conversions when calling `hash_value` by - defining `BOOST_HASH_NO_IMPLICIT_CASTS`. When using `boost::hash` - for a type that does not have `hash_value` declared but does have - an implicit conversion to a type that does, it would use that - implicit conversion to hash it. Which can sometimes go very wrong, - e.g. using a conversion to bool and only hashing to 2 possible - values. Since fixing this is a breaking change and was only - approached quite late in the release cycle with little discussion - it's opt-in for now. This, or something like it, will become the - default in a future version. - -[h2 Boost 1.46.0] - -* Avoid warning due with gcc's `-Wconversion` flag. - -[h2 Boost 1.50.0] - -* [@http://svn.boost.org/trac/boost/ticket/6771 Ticket 6771]: - Avoid gcc's `-Wfloat-equal` warning. -* [@http://svn.boost.org/trac/boost/ticket/6806 Ticket 6806]: - Support `std::array` and `std::tuple` when available. -* Add deprecation warning to the long deprecated - `boost/container_hash/detail/container_fwd.hpp`. - -[h2 Boost 1.51.0] - -* Support the standard smart pointers. -* `hash_value` now implemented using SFINAE to avoid implicit casts to built - in types when calling it. -* Updated to use the new config macros. - -[h2 Boost 1.52.0] - -* Restore `enum` support, which was accidentally removed in the last version. -* New floating point hasher - will hash the binary representation on more - platforms, which should be faster. - -[h2 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. -* On platforms that are known to have the standard floating point functions, - don't use automatic detection - which can break if there are ambiguous - overloads. -* Fix undefined behaviour when using the binary float hash (Thomas Heller). - -[h2 Boost 1.54.0] - -* [@https://svn.boost.org/trac/boost/ticket/7957 Ticket 7957]: - Fixed a typo. - -[h2 Boost 1.55.0] - -* Simplify a SFINAE check so that it will hopefully work on Sun 5.9 - ([ticket 8822]). -* Suppress Visual C++ infinite loop warning ([ticket 8568]). - -[h2 Boost 1.56.0] - -* Removed some Visual C++ 6 workarounds. -* Ongoing work on improving `hash_combine`. This changes the combine function - which was previously defined in the reference documentation. - -[h2 Boost 1.58.0] - -* Fixed strict aliasing violation - ([@https://github.com/boostorg/container_hash/pull/3 GitHub #3]). - -[h2 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 ([ticket 8552]). - -[h2 Boost 1.64.0] - -* Fix for recent versions of Visual C++ which have removed `std::unary_function` - and `std::binary_function` ([ticket 12353]). - -[h2 Boost 1.65.0] - -* Support for `char16_t`, `char32_t`, `u16string`, `u32string` - -[h2 Boost 1.66.0] - -* Avoid float comparison warning when using Clang - this workaround was - already in place for GCC, and was used when Clang pretends to be GCC, - but the warning was appearing when running Clang in other contexts. - -[h2 Boost 1.67.0] - -* Moved library into its own module, `container_hash`. -* Moved headers for new module name, now at: - ``, - ``, - ``. -* Added forwarding headers to support the old headers locations. -* 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 ([ticket 11017]). -* Quick fix for hashing `vector` when using libc++. Will try to introduce - a more general fix in the next release. - -[endsect] diff --git a/doc/disable.qbk b/doc/disable.qbk deleted file mode 100644 index 5373b42..0000000 --- a/doc/disable.qbk +++ /dev/null @@ -1,29 +0,0 @@ - -[/ Copyright 2005-2008 Daniel James. - / Distributed under the Boost Software License, Version 1.0. (See accompanying - / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ] - -[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/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. - -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] diff --git a/doc/hash.qbk b/doc/hash.qbk deleted file mode 100644 index 3bcc80e..0000000 --- a/doc/hash.qbk +++ /dev/null @@ -1,29 +0,0 @@ -[library Boost.ContainerHash - [quickbook 1.5] - [authors [James, Daniel]] - [copyright 2005 2006 2007 2008 Daniel James] - [purpose A TR1 hash function object that can be extended to hash user - defined types] - [category higher-order] - [id hash] - [dirname container_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]) - ] -] - -[def __issues__ - [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf - Library Extension Technical Report Issues List]] - -[include:hash intro.qbk] -[include:hash tutorial.qbk] -[include:hash portability.qbk] -[include:hash disable.qbk] -[include:hash changes.qbk] -[include:hash rationale.qbk] -[xinclude ref.xml] -[include:hash links.qbk] -[include:hash thanks.qbk] diff --git a/doc/intro.qbk b/doc/intro.qbk deleted file mode 100644 index 076e997..0000000 --- a/doc/intro.qbk +++ /dev/null @@ -1,52 +0,0 @@ - -[/ Copyright 2005-2008 Daniel James. - / Distributed under the Boost Software License, Version 1.0. (See accompanying - / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ] - -[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 __unordered__ [link unordered Boost.Unordered]] -[def __intrusive__ [link intrusive.unordered_set_unordered_multiset Boost.Intrusive]] -[def __multi-index__ [@boost:/libs/multi_index/doc/index.html - Boost Multi-Index Containers Library]] -[def __multi-index-short__ [@boost:/libs/multi_index/doc/index.html - Boost.MultiIndex]] -[def __bimap__ [@boost:/libs/bimap/index.html Boost.Bimap]] -[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 the default hash function for -__unordered__, __intrusive__'s unordered associative containers, and -__multi-index-short__'s hash indicies and __bimap__'s `unordered_set_of`. - -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. - -[note -This hash function is designed to be used in containers based on -the STL and is not suitable as a general purpose hash function. -For more details see the [link hash.rationale rationale]. -] - - -[endsect] - diff --git a/doc/links.qbk b/doc/links.qbk deleted file mode 100644 index 405536e..0000000 --- a/doc/links.qbk +++ /dev/null @@ -1,27 +0,0 @@ - -[/ Copyright 2005-2008 Daniel James. - / Distributed under the Boost Software License, Version 1.0. (See accompanying - / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ] - -[section:links Links] - -[*A Proposal to Add Hash Tables to the Standard Library] -[@http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1456.html] -The hash table proposal explains much of the design. The hash function object -is discussed in Section D. - -[*The C++ Standard Library Technical Report.] -[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf] -Contains the hash function specification in section 6.3.2. - -[*Library Extension Technical Report Issues List.] -[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf] -The library implements the extension described in Issue 6.18, pages 63-67. - -[*Methods for Identifying Versioned and Plagiarised Documents] -Timothy C. Hoad, Justin Zobel -[@http://www.cs.rmit.edu.au/~jz/fulltext/jasist-tch.pdf] -Contains the hash function that [funcref boost::hash_combine] is based on. - -[endsect] - diff --git a/doc/portability.qbk b/doc/portability.qbk deleted file mode 100644 index d667b89..0000000 --- a/doc/portability.qbk +++ /dev/null @@ -1,93 +0,0 @@ - -[/ Copyright 2005-2008 Daniel James. - / Distributed under the Boost Software License, Version 1.0. (See accompanying - / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ] - -[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` -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 __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 custom_type - { - T value; - public: - custom_type(T x) : value(x) {} - - friend std::size_t hash_value(custom_type x) - { - __boost_hash__ 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 custom_type - { - T value; - public: - custom_type(T x) : value(x) {} - - std::size_t hash(custom_type x) - { - __boost_hash__ hasher; - return hasher(value); - } - }; - - template - inline std::size_t hash_value(custom_type 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 - std::size_t hash_value(foo::custom_type x) - { - return x.hash(); - } - } - -Full code for this example is at -[@boost:/libs/container_hash/examples/portable.cpp /libs/container_hash/examples/portable.cpp]. - -[endsect] diff --git a/doc/rationale.qbk b/doc/rationale.qbk deleted file mode 100644 index 76ff6d1..0000000 --- a/doc/rationale.qbk +++ /dev/null @@ -1,50 +0,0 @@ - -[/ Copyright 2011 Daniel James. - / Distributed under the Boost Software License, Version 1.0. (See accompanying - / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ] - -[section:rationale Rationale] - -The rationale can be found in the original design -[footnote issue 6.18 of the __issues__ (page 63)]. - -[heading Quality of the hash function] - -Many hash functions strive to have little correlation between the input -and output values. They attempt to uniformally distribute the output -values for very similar inputs. This hash function makes no such -attempt. In fact, for integers, the result of the hash function is often -just the input value. So similar but different input values will often -result in similar but different output values. -This means that it is not appropriate as a general hash function. For -example, a hash table may discard bits from the hash function resulting -in likely collisions, or might have poor collision resolution when hash -values are clustered together. In such cases this hash function will -preform poorly. - -But the standard has no such requirement for the hash function, -it just requires that the hashes of two different values are unlikely -to collide. Containers or algorithms -designed to work with the standard hash function will have to be -implemented to work well when the hash function's output is correlated -to its input. Since they are paying that cost a higher quality hash function -would be wasteful. - -For other use cases, if you do need a higher quality hash function, -then neither the standard hash function or `boost::hash` are appropriate. -There are several options -available. One is to use a second hash on the output of this hash -function, such as [@http://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). - -[endsect] diff --git a/doc/ref.xml b/doc/ref.xml deleted file mode 100644 index 1c8bca9..0000000 --- a/doc/ref.xml +++ /dev/null @@ -1,994 +0,0 @@ - - - - -
- For the full specification, see section 6.3 of the - C++ Standard Library Technical Report - and issue 6.18 of the - Library Extension Technical Report Issues List (page 63). - -
-
- - Defines boost::hash, - and helper functions. - - - - - - - - - - - std::unary_function<T, std::size_t> - - - A TR1 compliant hash function object. - - - std::size_t - - T const& - - - hash_value(val) - - - - 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. - - - 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. - - - - Only throws if - hash_value(T) throws. - - - - - - - - bool - - - std::size_t - - bool - - - Unspecified in TR1, except that equal arguments yield the same result. - hash_value(val) in Boost. - - Doesn't throw - - - - - - - char - - - std::size_t - - char - - - Unspecified in TR1, except that equal arguments yield the same result. - hash_value(val) in Boost. - - Doesn't throw - - - - - - - signed char - - - std::size_t - - signed char - - - Unspecified in TR1, except that equal arguments yield the same result. - hash_value(val) in Boost. - - Doesn't throw - - - - - - - unsigned char - - - std::size_t - - unsigned char - - - Unspecified in TR1, except that equal arguments yield the same result. - hash_value(val) in Boost. - - Doesn't throw - - - - - - - wchar_t - - - std::size_t - - wchar_t - - - Unspecified in TR1, except that equal arguments yield the same result. - hash_value(val) in Boost. - - Doesn't throw - - - - - - - char16_t - - - std::size_t - - char16_t - - - Unspecified in TR1, except that equal arguments yield the same result. - hash_value(val) in Boost. - - Doesn't throw - - - - - - - char32_t - - - std::size_t - - char32_t - - - Unspecified in TR1, except that equal arguments yield the same result. - hash_value(val) in Boost. - - Doesn't throw - - - - - - - short - - - std::size_t - - short - - - Unspecified in TR1, except that equal arguments yield the same result. - hash_value(val) in Boost. - - Doesn't throw - - - - - - - unsigned short - - - std::size_t - - unsigned short - - - Unspecified in TR1, except that equal arguments yield the same result. - hash_value(val) in Boost. - - Doesn't throw - - - - - - - int - - - std::size_t - - int - - - Unspecified in TR1, except that equal arguments yield the same result. - hash_value(val) in Boost. - - Doesn't throw - - - - - - - unsigned int - - - std::size_t - - unsigned int - - - Unspecified in TR1, except that equal arguments yield the same result. - hash_value(val) in Boost. - - Doesn't throw - - - - - - - long - - - std::size_t - - long - - - Unspecified in TR1, except that equal arguments yield the same result. - hash_value(val) in Boost. - - Doesn't throw - - - - - - - unsigned long - - - std::size_t - - unsigned long - - - Unspecified in TR1, except that equal arguments yield the same result. - hash_value(val) in Boost. - - Doesn't throw - - - - - - - long long - - - std::size_t - - long long - - - Unspecified in TR1, except that equal arguments yield the same result. - hash_value(val) in Boost. - - Doesn't throw - - - - - - - unsigned long long - - - std::size_t - - unsigned long long - - - Unspecified in TR1, except that equal arguments yield the same result. - hash_value(val) in Boost. - - Doesn't throw - - - - - - - float - - - std::size_t - - float - - - Unspecified in TR1, except that equal arguments yield the same result. - hash_value(val) in Boost. - - Doesn't throw - - - - - - - double - - - std::size_t - - double - - - Unspecified in TR1, except that equal arguments yield the same result. - hash_value(val) in Boost. - - Doesn't throw - - - - - - - long double - - - std::size_t - - long double - - - Unspecified in TR1, except that equal arguments yield the same result. - hash_value(val) in Boost. - - Doesn't throw - - - - - - - std::string - - - std::size_t - - std::string const& - - - Unspecified in TR1, except that equal arguments yield the same result. - hash_value(val) in Boost. - - Doesn't throw - - - - - - - std::wstring - - - std::size_t - - std::wstring const& - - - Unspecified in TR1, except that equal arguments yield the same result. - hash_value(val) in Boost. - - Doesn't throw - - - - - - - std::u16string - - - std::size_t - - std::u16string const& - - - Unspecified in TR1, except that equal arguments yield the same result. - hash_value(val) in Boost. - - Doesn't throw - - - - - - - std::u32string - - - std::size_t - - std::u32string const& - - - Unspecified in TR1, except that equal arguments yield the same result. - hash_value(val) in Boost. - - Doesn't throw - - - - - - - T* - - - std::size_t - - T* - - - Unspecified in TR1, except that equal arguments yield the same result. - - Doesn't throw - - - - - - - std::type_index - - - std::size_t - - std::type_index - - - val.hash_code() - - Doesn't throw - - - - Only available if it's in your standard library and Boost.Config - is aware of it. - - - - - - - - - - - void - size_t & - T const& - - Called repeatedly to incrementally create a hash value from - several variables. - - - 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. - - - hash_value is called without - qualification, so that overloads can be found via ADL. - This is an extension to TR1 - - 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. - - - - Only throws if hash_value(T) throws. - Strong exception safety, as long as hash_value(T) - also has strong exception safety. - - - - - - - - - std::size_t - It - It - - - - - void - std::size_t& - It - It - - - - Calculate the combined hash value of the elements of an iterator - range. - - - For the two argument overload: - -size_t seed = 0; - -for(; first != last; ++first) -{ - hash_combine(seed, *first); -} - -return seed; - - - For the three arguments overload: - -for(; first != last; ++first) -{ - hash_combine(seed, *first); -} - - - - - hash_range is sensitive to the order of the elements - so it wouldn't be appropriate to use this with an unordered - container. - - This is an extension to TR1 - - 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. - - - - 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. - - - - - - - - - - - - Implementation of the hash function. - - - - std::size_t - bool - - - - std::size_t - char - - - - std::size_t - signed char - - - - std::size_t - unsigned char - - - - std::size_t - wchar_t - - - - std::size_t - char16_t - - - - std::size_t - char32_t - - - - std::size_t - short - - - - std::size_t - unsigned short - - - - std::size_t - int - - - - std::size_t - unsigned int - - - - std::size_t - long - - - - std::size_t - unsigned long - - - - std::size_t - long long - - - - std::size_t - unsigned long long - - - - std::size_t - float - - - - std::size_t - double - - - - std::size_t - long double - - - - - std::size_t - T* const& - - - - - std::size_t - T (&val)[N] - - - - - std::size_t - const T (&val)[N] - - - - - std::size_t - - std::basic_string<Ch, std::char_traits<Ch>, A> const& - - - - - - std::size_t - std::pair<A, B> const& - - - - - std::size_t - std::vector<T, A> const& - - - - - std::size_t - std::list<T, A> const& - - - - - std::size_t - std::deque<T, A> const& - - - - - std::size_t - std::set<K, C, A> const& - - - - - std::size_t - std::multiset<K, C, A> const& - - - - - std::size_t - std::map<K, T, C, A> const& - - - - - std::size_t - std::multimap<K, T, C, A> const& - - - - - std::size_t - std::complex<T> const& - - - - std::size_t - std::type_index - - - - - std::size_t - std::array<T, N> const& - - - - - std::size_t - std::tuple<T...> - - - - 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. - - - - 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. - - - - - 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. - - - - - - - - Types - Returns - - - - - bool, - char, signed char, unsigned char, - wchar_t, char16_t, char32_t, - short, unsigned short, - int, unsigned int, long, unsigned long - - val - - - long long, unsigned long long - val when abs(val) <= std::numeric_limits<std::size_t>::max(). - - - float, double, long double - An unspecified value, except that equal arguments shall yield the same result. - - - T* - An unspecified value, except that equal arguments shall yield the same result. - - - - T val[N], - const T val[N] - - hash_range(val, val+N) - - - - std:basic_string<Ch, std::char_traits<Ch>, A>, - std::vector<T, A>, - std::list<T, A>, - std::deque<T, A>, - std::set<K, C, A>, - std::multiset<K, C, A>, - std::map<K, T, C, A>, - std::multimap<K, T, C, A>, - std::array<T, N> - - hash_range(val.begin(), val.end()) - - - std::pair<A, B> - size_t seed = 0; -hash_combine(seed, val.first); -hash_combine(seed, val.second); -return seed; - - - std::tuple<T...> - size_t seed = 0; -hash_combine(seed, get<0>(val)); -hash_combine(seed, get<1>(val)); -// .... -return seed; - - - - std::complex<T> - - When T is a built in type and val.imag() == 0, the result is equal to hash_value(val.real()). Otherwise an unspecified value, except that equal arguments shall yield the same result. - - - - std::type_index - - val.hash_code() - - - - - - - - -
-
- diff --git a/doc/samples/tutorial.cpp b/doc/samples/tutorial.cpp deleted file mode 100644 index b11609b..0000000 --- a/doc/samples/tutorial.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include -#include -#include -#include - -//[ get_hashes -template -std::vector get_hashes(Container const& x) -{ - std::vector hashes; - std::transform(x.begin(), x.end(), std::back_inserter(hashes), - boost::hash()); - - return hashes; -} -//] - -int main() { - std::vector values; - values.push_back(10); - values.push_back(20); - - std::vector hashes = get_hashes(values); - assert(hashes[0] = boost::hash()(values[0])); - assert(hashes[1] = boost::hash()(values[1])); -} diff --git a/doc/thanks.qbk b/doc/thanks.qbk deleted file mode 100644 index fcc5108..0000000 --- a/doc/thanks.qbk +++ /dev/null @@ -1,28 +0,0 @@ - -[/ Copyright 2005-2008 Daniel James. - / Distributed under the Boost Software License, Version 1.0. (See accompanying - / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ] - -[section:acknowledgements Acknowledgements] - -This library is based on the design by Peter Dimov. During the initial -development -Joaquín M López Muñoz made many useful suggestions and 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, further constructive criticism has -been made by Daniel Krügler, Alexander Nasonov and 沈慧峰. - -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] diff --git a/doc/tutorial.qbk b/doc/tutorial.qbk deleted file mode 100644 index 234b759..0000000 --- a/doc/tutorial.qbk +++ /dev/null @@ -1,207 +0,0 @@ - -[/ Copyright 2005-2008 Daniel James. - / Distributed under the Boost Software License, Version 1.0. (See accompanying - / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ] - -[quickbook 1.7] -[import samples/tutorial.cpp] - -[def __multi-index-short__ [@boost:/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 > - set_of_ints; - - std::unordered_set, ``[classref boost::hash]`` > - set_of_pairs; - - std::unordered_map > map_int_to_string; - -To use [classref boost::hash] directly, create an instance and call it as a function: - - #include <``[headerref boost/container_hash/hash.hpp]``> - - int main() - { - ``[classref boost::hash]`` 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: - -[get_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]`` 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]`` book_hasher; - std::size_t knife_hash_value = book_hasher(knife); - - // If std::unordered_set is available: - std::unordered_set > 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: -[@boost:/libs/container_hash/examples/books.hpp /libs/container_hash/examples/books.hpp] -and -[@boost:/libs/container_hash/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). -] - -[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 -[@boost:/libs/container_hash/examples/point.cpp /libs/container_hash/examples/point.cpp]. - -[note -When using [funcref boost::hash_combine] the order of the -calls matters. -''' - - std::size_t seed = 0; - boost::hash_combine(seed, 1); - boost::hash_combine(seed, 2); - -results in a different seed to: - - std::size_t seed = 0; - boost::hash_combine(seed, 2); - boost::hash_combine(seed, 1); - -''' -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 some_strings; - std::size_t hash = ``[funcref 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 `` -header which forward declares [classref boost::hash], -[funcref boost::hash_range] and [funcref boost::hash_combine]. You'll need to -include the main header before instantiating [classref boost::hash]. When using -a container that uses [classref boost::hash] it should do that for you, so your -type will work fine with the boost hash containers. There's an example of this -in [@boost:/libs/container_hash/examples/template.hpp template.hpp] and -[@boost:/libs/container_hash/examples/template.cpp template.cpp]. - -[endsect] From 8d820ee7d0bad0875bcbc3502a8a0386e28389fc Mon Sep 17 00:00:00 2001 From: Christian Mazakas Date: Tue, 8 Feb 2022 11:53:30 -0800 Subject: [PATCH 17/23] Remove unnecessary cross-references --- doc/hash/combine.adoc | 16 ++-- doc/hash/custom.adoc | 8 +- doc/hash/disable.adoc | 2 +- doc/hash/intro.adoc | 4 +- doc/hash/portability.adoc | 8 +- doc/hash/ref.adoc | 156 +++++++++++++++++++------------------- doc/hash/tutorial.adoc | 18 ++--- 7 files changed, 106 insertions(+), 106 deletions(-) diff --git a/doc/hash/combine.adoc b/doc/hash/combine.adoc index ac49a86..a77b1fd 100644 --- a/doc/hash/combine.adoc +++ b/doc/hash/combine.adoc @@ -22,7 +22,7 @@ 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"] ---- @@ -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,13 +43,13 @@ 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^]. [NOTE] ==== -When using xref:#ref_hash_combine[boost::hash_combine] the order of the calls matters. +When using `boost::hash_combine` the order of the calls matters. [listing,subs="+quotes,+macros"] ---- std::size_t seed = 0; @@ -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"] ---- std::vector 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 `` 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 `` 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^]. diff --git a/doc/hash/custom.adoc b/doc/hash/custom.adoc index 5e0a650..fdbdf5c 100644 --- a/doc/hash/custom.adoc +++ b/doc/hash/custom.adoc @@ -3,7 +3,7 @@ :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`: @@ -35,13 +35,13 @@ namespace library { std::size_t hash_value(book const& b) { - xref:#ref_hash[boost::hash] hasher; + boost::hash 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"] ---- @@ -49,7 +49,7 @@ 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] book_hasher; +boost::hash book_hasher; std::size_t knife_hash_value = book_hasher(knife); // If std::unordered_set is available: diff --git a/doc/hash/disable.adoc b/doc/hash/disable.adoc index eeba618..3c9b205 100644 --- a/doc/hash/disable.adoc +++ b/doc/hash/disable.adoc @@ -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[] 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 `` 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. diff --git a/doc/hash/intro.adoc b/doc/hash/intro.adoc index 60c731e..8140895 100644 --- a/doc/hash/intro.adoc +++ b/doc/hash/intro.adoc @@ -3,7 +3,7 @@ :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: @@ -17,6 +17,6 @@ It also implements the extension proposed by Peter Dimov in issue 6.18 of the ht * 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 <>. diff --git a/doc/hash/portability.adoc b/doc/hash/portability.adoc index a552b8e..b427a38 100644 --- a/doc/hash/portability.adoc +++ b/doc/hash/portability.adoc @@ -3,9 +3,9 @@ :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: @@ -22,7 +22,7 @@ namespace foo friend std::size_t hash_value(custom_type x) { - xref:#ref_hash[boost::hash] hasher; + boost::hash hasher; return hasher(x.value); } }; @@ -46,7 +46,7 @@ namespace foo std::size_t hash(custom_type x) { - xref:#ref_hash[boost::hash] hasher; + boost::hash hasher; return hasher(value); } }; diff --git a/doc/hash/ref.adoc b/doc/hash/ref.adoc index ec3719a..e759291 100644 --- a/doc/hash/ref.adoc +++ b/doc/hash/ref.adoc @@ -7,113 +7,113 @@ For the full specification, see section 6.3 of the http://www.open-std.org/jtc1/ == Header -Defines xref:#ref_hash[boost::hash], and helper functions. +Defines `boost::hash`, and helper functions. [listing,subs="+quotes,+macros"] ---- namespace boost { - template struct xref:#ref_hash[hash]; + template struct hash; - template<> struct xref:#ref_specializations[hash]; - template<> struct xref:#ref_specializations[hash]; - template<> struct xref:#ref_specializations[hash]; - template<> struct xref:#ref_specializations[hash]; - template<> struct xref:#ref_specializations[hash]; - template<> struct xref:#ref_specializations[hash]; - template<> struct xref:#ref_specializations[hash]; - template<> struct xref:#ref_specializations[hash]; - template<> struct xref:#ref_specializations[hash]; - template<> struct xref:#ref_specializations[hash]; - template<> struct xref:#ref_specializations[hash]; - template<> struct xref:#ref_specializations[hash]; - template<> struct xref:#ref_specializations[hash]; - template<> struct xref:#ref_specializations[hash]; - template<> struct xref:#ref_specializations[hash]; - template<> struct xref:#ref_specializations[hash]; - template<> struct xref:#ref_specializations[hash]; - template<> struct xref:#ref_specializations[hash]; - template<> struct xref:#ref_specializations[hash]; - template<> struct xref:#ref_specializations[hash]; - template<> struct xref:#ref_specializations[hash]; - template<> struct xref:#ref_specializations[hash]; - template<> struct xref:#ref_specializations[hash]; + template<> struct hash; + template<> struct hash; + template<> struct hash; + template<> struct hash; + template<> struct hash; + template<> struct hash; + template<> struct hash; + template<> struct hash; + template<> struct hash; + template<> struct hash; + template<> struct hash; + template<> struct hash; + template<> struct hash; + template<> struct hash; + template<> struct hash; + template<> struct hash; + template<> struct hash; + template<> struct hash; + template<> struct hash; + template<> struct hash; + template<> struct hash; + template<> struct hash; + template<> struct hash; - template struct xref:#ref_specializations[hash]; + template struct hash; - // xref:#ref_support_functions_boost_extension[Support functions (Boost extension).] + // Support functions (Boost extension). template - void xref:#ref_hash_combine[hash_combine](size_t &, T const&); + void hash_combine(size_t &, T const&); template - std::size_t xref:#ref_hash_range[hash_range](It, It); + std::size_t hash_range(It, It); template - 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 - std::size_t xref:#ref_hash_value[hash_value](T* const&); + std::size_t hash_value(T* const&); template - std::size_t xref:#ref_hash_value[hash_value](T (&val)[N]); + std::size_t hash_value(T (&val)[N]); template - std::size_t xref:#ref_hash_value[hash_value](const T (&val)[N]); + std::size_t hash_value(const T (&val)[N]); template - std::size_t xref:#ref_hash_value[hash_value](std::basic_string, A> const&); + std::size_t hash_value(std::basic_string, A> const&); template - std::size_t xref:#ref_hash_value[hash_value](std::pair const&); + std::size_t hash_value(std::pair const&); template - std::size_t xref:#ref_hash_value[hash_value](std::vector const&); + std::size_t hash_value(std::vector const&); template - std::size_t xref:#ref_hash_value[hash_value](std::list const&); + std::size_t hash_value(std::list const&); template - std::size_t xref:#ref_hash_value[hash_value](std::deque const&); + std::size_t hash_value(std::deque const&); template - std::size_t xref:#ref_hash_value[hash_value](std::set const&); + std::size_t hash_value(std::set const&); template - std::size_t xref:#ref_hash_value[hash_value](std::multiset const&); + std::size_t hash_value(std::multiset const&); template - std::size_t xref:#ref_hash_value[hash_value](std::map const&); + std::size_t hash_value(std::map const&); template - std::size_t xref:#ref_hash_value[hash_value](std::multimap const&); + std::size_t hash_value(std::multimap const&); - template std::size_t xref:#ref_hash_value[hash_value](std::complex const&); - std::size_t xref:#ref_hash_value[hash_value](std::type_index); + template std::size_t hash_value(std::complex const&); + std::size_t hash_value(std::type_index); template - std::size_t xref:#ref_hash_value[hash_value](std::array const&); + std::size_t hash_value(std::array const&); template - std::size_t xref:#ref_hash_value[hash_value](std::tuple); + std::size_t hash_value(std::tuple); } ---- @@ -127,7 +127,7 @@ namespace boost { [listing,subs="+quotes,+macros"] ---- -// xref:#ref_header_boostcontainer_hashhash_hpp[#include ] +// #include template struct hash : public std::unary_function { @@ -143,9 +143,9 @@ 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 `` + 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 @@ -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 @@ -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,7 +210,7 @@ Forward declared in `` + 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 @@ -234,7 +234,7 @@ size_t seed = 0; for(; first != last; ++first) { - xref:#ref_hash_combine[hash_combine](seed, *first); + hash_combine(seed, *first); } return seed; ---- @@ -245,7 +245,7 @@ For the three arguments overload: ---- for(; first != last; ++first) { - xref:#ref_hash_combine[hash_combine](seed, *first); + hash_combine(seed, *first); } ---- @@ -259,7 +259,7 @@ Forward declared in `` 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::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::value_type)` has basic exception safety. +Throws:: Only throws if `hash_value(std::iterator_traits::value_type)` throws. `hash_range(std::size_t&, It, It)` has basic exception safety as long as `hash_value(std::iterator_traits::value_type)` has basic exception safety. == Overloadable hash implementation (Boost extension). @@ -319,7 +319,7 @@ template 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:: diff --git a/doc/hash/tutorial.adoc b/doc/hash/tutorial.adoc index aa165d6..43f5cbd 100644 --- a/doc/hash/tutorial.adoc +++ b/doc/hash/tutorial.adoc @@ -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 <>. +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 <>. -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"] ---- -std::unordered_multiset > +std::unordered_multiset > set_of_ints; -std::unordered_set, xref:#ref_hash[boost::hash] > > +std::unordered_set, boost::hash > > set_of_pairs; -std::unordered_map > map_int_to_string; +std::unordered_map > 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"] ---- -xref:#ref_header_boostcontainer_hashhash_hpp[++#include ++] +#include int main() { - xref:#ref_hash[boost::hash] string_hash; + boost::hash string_hash; std::size_t h = string_hash("Hash me"); } @@ -41,7 +41,7 @@ std::vector get_hashes(Container const& x) { std::vector hashes; std::transform(x.begin(), x.end(), std::back_inserter(hashes), - xref:#ref_hash[boost::hash]()); + boost::hash()); return hashes; } From cb233af7185734108d2eb6a91f567dc49e6341ba Mon Sep 17 00:00:00 2001 From: Christian Mazakas Date: Tue, 8 Feb 2022 12:00:47 -0800 Subject: [PATCH 18/23] Update `[listing]`s to become proper source code blocks --- doc/hash.adoc | 1 + doc/hash/combine.adoc | 10 +++++----- doc/hash/custom.adoc | 6 +++--- doc/hash/portability.adoc | 6 +++--- doc/hash/ref.adoc | 24 ++++++++++++------------ doc/hash/tutorial.adoc | 6 +++--- 6 files changed, 27 insertions(+), 26 deletions(-) diff --git a/doc/hash.adoc b/doc/hash.adoc index 7362e61..9fda14b 100644 --- a/doc/hash.adoc +++ b/doc/hash.adoc @@ -6,6 +6,7 @@ :source-highlighter: rouge :nofooter: :sectlinks: +:source-language: c++ :leveloffset: +1 diff --git a/doc/hash/combine.adoc b/doc/hash/combine.adoc index a77b1fd..f1cd2b2 100644 --- a/doc/hash/combine.adoc +++ b/doc/hash/combine.adoc @@ -5,7 +5,7 @@ Say you have a point class, representing a two dimensional location: -[listing] +[source] ---- class point { @@ -24,7 +24,7 @@ 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 `boost::hash_combine` is supplied for this purpose: -[listing,subs="+quotes,+macros"] +[source] ---- class point { @@ -50,7 +50,7 @@ Full code for this example is at link:../../examples/point.cpp[/libs/container_h [NOTE] ==== When using `boost::hash_combine` the order of the calls matters. -[listing,subs="+quotes,+macros"] +[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); @@ -71,7 +71,7 @@ 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 `boost::hash_range`: -[listing,subs="+quotes,+macros"] +[source] ---- std::vector some_strings; std::size_t hash = boost::hash_range(some_strings.begin(), some_strings.end()); diff --git a/doc/hash/custom.adoc b/doc/hash/custom.adoc index fdbdf5c..7d5c908 100644 --- a/doc/hash/custom.adoc +++ b/doc/hash/custom.adoc @@ -7,7 +7,7 @@ If you have a structure `library::book`, where each book is uniquely defined by its member `id`: -[listing] +[source] ---- namespace library { @@ -29,7 +29,7 @@ namespace library Then all you would need to do is write the function `library::hash_value`: -[listing,subs="+quotes,+macros"] +[source] ---- namespace library { @@ -43,7 +43,7 @@ namespace library 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", diff --git a/doc/hash/portability.adoc b/doc/hash/portability.adoc index b427a38..53ff2e3 100644 --- a/doc/hash/portability.adoc +++ b/doc/hash/portability.adoc @@ -9,7 +9,7 @@ On a strictly standards compliant compiler, an overload defined in the `boost` n Let's say we have a simple custom type: -[list,subs="+quotes,+macros"] +[source] ---- namespace foo { @@ -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 { @@ -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 diff --git a/doc/hash/ref.adoc b/doc/hash/ref.adoc index e759291..89f637a 100644 --- a/doc/hash/ref.adoc +++ b/doc/hash/ref.adoc @@ -9,7 +9,7 @@ For the full specification, see section 6.3 of the http://www.open-std.org/jtc1/ Defines `boost::hash`, and helper functions. -[listing,subs="+quotes,+macros"] +[source] ---- namespace boost { template struct hash; @@ -125,7 +125,7 @@ namespace boost { ==== Synopsis -[listing,subs="+quotes,+macros"] +[source] ---- // #include @@ -137,7 +137,7 @@ struct hash : public std::unary_function { ==== Description -[listing] +[source] ---- std::size_t operator()(T const& val) const; ---- @@ -161,7 +161,7 @@ Throws:: Only throws if `hash_value(T)` throws. === Synopsis -[listing] +[source] ---- // #include @@ -172,7 +172,7 @@ struct hash { === Description -[listing] +[source] ---- std::size_t operator()(T const val) const; ---- @@ -189,7 +189,7 @@ Throws:: Doesn't throw === hash_combine -[listing] +[source] ---- template void hash_combine(size_t &, T const&); @@ -214,7 +214,7 @@ Throws:: Only throws if `hash_value(T)` throws. Strong exception safety, as long === hash_range -[listing] +[source] ---- template std::size_t hash_range(It, It); @@ -228,7 +228,7 @@ 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; @@ -241,7 +241,7 @@ return seed; + For the three arguments overload: + -[listing,subs="+quotes,+macros"] +[source] ---- for(; first != last; ++first) { @@ -265,7 +265,7 @@ Throws:: Only throws if `hash_value(std::iterator_traits::value_type)` throw === hash_value -[listing] +[source] ---- std::size_t hash_value(bool val); std::size_t hash_value(char val); @@ -357,7 +357,7 @@ Returns:: |`std::pair` a| -[listing] +[source] ---- size_t seed = 0; hash_combine(seed, val.first); @@ -368,7 +368,7 @@ return seed; |`std::tuple` a| -[listing] +[source] ---- size_t seed = 0; hash_combine(seed, get<0>(val)); diff --git a/doc/hash/tutorial.adoc b/doc/hash/tutorial.adoc index 43f5cbd..8a4a9a7 100644 --- a/doc/hash/tutorial.adoc +++ b/doc/hash/tutorial.adoc @@ -7,7 +7,7 @@ When using a hash index with link:../../../multi_index/index.html[Boost.MultiInd 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 > set_of_ints; @@ -20,7 +20,7 @@ std::unordered_map > map_int_to_string; To use `boost::hash` directly, create an instance and call it as a function: -[listing,subs="+quotes,+macros"] +[source] ---- #include @@ -34,7 +34,7 @@ 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 std::vector get_hashes(Container const& x) From fc11122353542014a053bab67c0eb725a67ca461 Mon Sep 17 00:00:00 2001 From: Christian Mazakas Date: Tue, 8 Feb 2022 12:02:15 -0800 Subject: [PATCH 19/23] Refactor links to no longer open up a new tab --- doc/hash/changes.adoc | 36 ++++++++++++++++++------------------ doc/hash/combine.adoc | 4 ++-- doc/hash/custom.adoc | 2 +- doc/hash/intro.adoc | 6 +++--- doc/hash/portability.adoc | 2 +- doc/hash/rationale.adoc | 6 +++--- doc/hash/ref.adoc | 4 ++-- doc/hash/tutorial.adoc | 2 +- 8 files changed, 31 insertions(+), 31 deletions(-) diff --git a/doc/hash/changes.adoc b/doc/hash/changes.adoc index 51e09d9..1f47dcf 100644 --- a/doc/hash/changes.adoc +++ b/doc/hash/changes.adoc @@ -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` 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 diff --git a/doc/hash/combine.adoc b/doc/hash/combine.adoc index f1cd2b2..b3261b0 100644 --- a/doc/hash/combine.adoc +++ b/doc/hash/combine.adoc @@ -45,7 +45,7 @@ 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 `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] ==== @@ -77,4 +77,4 @@ std::vector some_strings; 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 `` 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^]. +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 `` 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]. diff --git a/doc/hash/custom.adoc b/doc/hash/custom.adoc index 7d5c908..3bd0913 100644 --- a/doc/hash/custom.adoc +++ b/doc/hash/custom.adoc @@ -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). diff --git a/doc/hash/intro.adoc b/doc/hash/intro.adoc index 8140895..8b7607d 100644 --- a/doc/hash/intro.adoc +++ b/doc/hash/intro.adoc @@ -3,16 +3,16 @@ :idprefix: intro_ -`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` diff --git a/doc/hash/portability.adoc b/doc/hash/portability.adoc index 53ff2e3..08e9e1c 100644 --- a/doc/hash/portability.adoc +++ b/doc/hash/portability.adoc @@ -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]. diff --git a/doc/hash/rationale.adoc b/doc/hash/rationale.adoc index 18f2a47..0379e51 100644 --- a/doc/hash/rationale.adoc +++ b/doc/hash/rationale.adoc @@ -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). diff --git a/doc/hash/ref.adoc b/doc/hash/ref.adoc index 89f637a..9431329 100644 --- a/doc/hash/ref.adoc +++ b/doc/hash/ref.adoc @@ -3,7 +3,7 @@ :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 @@ -121,7 +121,7 @@ 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 diff --git a/doc/hash/tutorial.adoc b/doc/hash/tutorial.adoc index 8a4a9a7..6062b79 100644 --- a/doc/hash/tutorial.adoc +++ b/doc/hash/tutorial.adoc @@ -3,7 +3,7 @@ :idprefix: tutorial_ -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 <>. +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 <>. 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: From 355603c0c2a56013d7e44f3a0952004f4f280b39 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 9 Mar 2022 16:36:40 +0200 Subject: [PATCH 20/23] Update ci.yml --- .github/workflows/ci.yml | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5bd9858..a0a449a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -156,14 +156,22 @@ jobs: fail-fast: false matrix: include: - - toolset: msvc-14.1 - cxxstd: "14,17,latest" - addrmd: 32,64 - os: windows-2016 - - toolset: msvc-14.2 - cxxstd: "14,17,latest" + - toolset: msvc-14.0 + cxxstd: 14,latest addrmd: 32,64 os: windows-2019 + - toolset: msvc-14.2 + cxxstd: "14,17,20,latest" + addrmd: 32,64 + os: windows-2019 + - toolset: msvc-14.3 + cxxstd: "14,17,20,latest" + addrmd: 32,64 + os: windows-2022 + - toolset: clang-win + cxxstd: "14,17,latest" + addrmd: 32,64 + os: windows-2022 - toolset: gcc cxxstd: "03,11,14,17,2a" addrmd: 64 @@ -200,5 +208,5 @@ jobs: shell: cmd run: | cd ../boost-root - b2 -j3 --verbose-test libs/%LIBRARY%/test//hash_info toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release - b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release + b2 -j3 --verbose-test libs/%LIBRARY%/test//hash_info toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release embed-manifest-via=linker + b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release embed-manifest-via=linker From 000276988f21e05191cca87d3a010506b477d274 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Thu, 28 Apr 2022 21:13:23 +0300 Subject: [PATCH 21/23] Add hash_string_test2 --- test/Jamfile.v2 | 1 + test/hash_string_test2.cpp | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 test/hash_string_test2.cpp diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index c46e8ff..a5175e1 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -86,3 +86,4 @@ explicit container_hash/hash_no_generic_float ; build-project ../examples ; run hash_reference_values.cpp ; +run hash_string_test2.cpp ; diff --git a/test/hash_string_test2.cpp b/test/hash_string_test2.cpp new file mode 100644 index 0000000..abca666 --- /dev/null +++ b/test/hash_string_test2.cpp @@ -0,0 +1,34 @@ +// Copyright 2022 Peter Dimov. +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include +#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) +#include +#endif + +// Test whether the hash values of a string and a +// string_view that refers to it match. This is +// important for unordered heterogeneous lookups. + +template std::size_t hv( T const& t ) +{ + return boost::hash()( t ); +} + +int main() +{ + std::string s( "Test." ); + + BOOST_TEST_EQ( hv( s ), hv( boost::string_view( s ) ) ); + +#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) + BOOST_TEST_EQ( hv( s ), hv( std::string_view( s ) ) ); +#endif + + return boost::report_errors(); +} From d2986d9a64c2bb74513dad8874136064d262423b Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Fri, 29 Apr 2022 02:01:46 +0300 Subject: [PATCH 22/23] Test boost::core::string_view in hash_string_test2 --- test/hash_string_test2.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/hash_string_test2.cpp b/test/hash_string_test2.cpp index abca666..4dc67d9 100644 --- a/test/hash_string_test2.cpp +++ b/test/hash_string_test2.cpp @@ -2,8 +2,9 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt -#include #include +#include +#include #include #include #include @@ -25,6 +26,7 @@ int main() std::string s( "Test." ); BOOST_TEST_EQ( hv( s ), hv( boost::string_view( s ) ) ); + BOOST_TEST_EQ( hv( s ), hv( boost::core::string_view( s ) ) ); #if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) BOOST_TEST_EQ( hv( s ), hv( std::string_view( s ) ) ); From b3e424b6503709f4d86a91b78017ecce53747f02 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 11 May 2022 21:48:23 +0300 Subject: [PATCH 23/23] Add gcc-12, clang-13, clang-14 to GHA --- .github/workflows/ci.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a0a449a..06f7c5d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -57,6 +57,11 @@ jobs: os: ubuntu-20.04 install: g++-11-multilib address-model: 32,64 + - toolset: gcc-12 + cxxstd: "03,11,14,17,20" + os: ubuntu-22.04 + install: g++-12-multilib + address-model: 32,64 - toolset: clang compiler: clang++-3.9 cxxstd: "03,11,14" @@ -104,6 +109,16 @@ jobs: compiler: clang++-12 cxxstd: "03,11,14,17,20" os: ubuntu-20.04 + - toolset: clang + compiler: clang++-13 + cxxstd: "03,11,14,17,20" + os: ubuntu-22.04 + install: clang-13 + - toolset: clang + compiler: clang++-14 + cxxstd: "03,11,14,17,20" + os: ubuntu-22.04 + install: clang-14 - toolset: clang cxxstd: "03,11,14,17,2a" os: macos-10.15