From 65bade2cb21347a56382423fac18b27102d31aa6 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Mon, 7 May 2012 10:58:55 +0000 Subject: [PATCH] Hash: Add some notes about forwarding header. Refs #6849. [SVN r78366] --- hash/doc/ref.xml | 17 ++++++++++++++--- hash/doc/tutorial.qbk | 12 +++++++++++- hash/examples/Jamfile.v2 | 1 + hash/examples/template.cpp | 18 ++++++++++++++++++ hash/examples/template.hpp | 36 ++++++++++++++++++++++++++++++++++++ 5 files changed, 80 insertions(+), 4 deletions(-) create mode 100644 hash/examples/template.cpp create mode 100644 hash/examples/template.hpp diff --git a/hash/doc/ref.xml b/hash/doc/ref.xml index fa29fcd..d7c427c 100644 --- a/hash/doc/ref.xml +++ b/hash/doc/ref.xml @@ -55,6 +55,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) is defined. The specializations are still defined, so only the specializations required by TR1 are defined. + + Forward declared in + <boost/functional/hash_fwd.hpp> + Only throws if @@ -451,6 +455,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) hash_value is called without qualification, so that overloads can be found via ADL. This is an extension to TR1 + + Forward declared in + <boost/functional/hash_fwd.hpp> + Only throws if hash_value(T) throws. @@ -499,15 +507,14 @@ for(; first != last; ++first) return seed; - For the three arguments overload: + + For the three arguments overload: for(; first != last; ++first) { hash_combine(seed, *first); } - - @@ -516,6 +523,10 @@ for(; first != last; ++first) container. This is an extension to TR1 + + Forward declared in + <boost/functional/hash_fwd.hpp> + Only throws if hash_value(std::iterator_traits<It>::value_type) diff --git a/hash/doc/tutorial.qbk b/hash/doc/tutorial.qbk index 81c1b15..916ab93 100644 --- a/hash/doc/tutorial.qbk +++ b/hash/doc/tutorial.qbk @@ -198,5 +198,15 @@ To calculate the hash of an iterator range you can use [funcref boost::hash_rang std::vector some_strings; std::size_t hash = ``[funcref boost::hash_range]``(some_strings.begin(), some_strings.end()); -[endsect] +Note that when writing template classes, you might not want to include the main +hash header as it's quite an expensive include that brings in a lot of other +headers, so instead you can include the `` +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/unordered/examples/template.hpp template.hpp] and +[@boost:/libs/unordered/examples/template.cpp template.cpp]. +[endsect] diff --git a/hash/examples/Jamfile.v2 b/hash/examples/Jamfile.v2 index dc5bdce..6291621 100644 --- a/hash/examples/Jamfile.v2 +++ b/hash/examples/Jamfile.v2 @@ -6,3 +6,4 @@ run books.cpp ; run point.cpp ; run portable.cpp ; +run template.cpp ; diff --git a/hash/examples/template.cpp b/hash/examples/template.cpp new file mode 100644 index 0000000..d74f0a9 --- /dev/null +++ b/hash/examples/template.cpp @@ -0,0 +1,18 @@ + +// Copyright 2012 Daniel James. +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include "template.hpp" +#include +#include + +int main() +{ + typedef my_pair pair; + boost::unordered_set pair_set; + pair_set.emplace(10, 0.5f); + + assert(pair_set.find(pair(10, 0.5f)) != pair_set.end()); + assert(pair_set.find(pair(10, 0.6f)) == pair_set.end()); +} diff --git a/hash/examples/template.hpp b/hash/examples/template.hpp new file mode 100644 index 0000000..b630704 --- /dev/null +++ b/hash/examples/template.hpp @@ -0,0 +1,36 @@ + +// Copyright 2012 Daniel James. +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// This is an example of how to write a hash function for a template +// class. + +#include + +template +class my_pair +{ + A value1; + B value2; +public: + my_pair(A const& v1, B const& v2) + : value1(v1), value2(v2) + {} + + bool operator==(my_pair const& other) const + { + return value1 == other.value1 && + value2 == other.value2; + } + + friend std::size_t hash_value(my_pair const& p) + { + std::size_t seed = 0; + boost::hash_combine(seed, p.value1); + boost::hash_combine(seed, p.value2); + + return seed; + } +}; +