From ab1f43c996b512ae35639dbd02e6aaa86c01bc18 Mon Sep 17 00:00:00 2001
From: Christian Engwer <christi@dune-project.org>
Date: Sun, 25 Nov 2012 10:23:22 +0000
Subject: [PATCH] [hash] Add support for boost::hash
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This patch adds boost::hash as a fallback option for Dune::hash
if neither std::hash nor std::tr1::hash can be found. We only
have to include the appropriate header and import the name into
the Dune namespace, as the built-in extension mechanism of boost::hash
will automatically pick up the global hash_value() functions.

To test whether the mechanism actually works, the patch also adds
boost::hash to the list of hash implementations tested in
bigunsignedinttest.

Kudos to Steffen Müthing, see FS#1192

[[Imported from SVN: r7067]]
---
 dune/common/hash.hh                    | 43 +++++++++++++++++++++++++-
 dune/common/test/Makefile.am           |  1 +
 dune/common/test/bigunsignedinttest.cc | 11 +++++++
 m4/dune_common.m4                      |  1 +
 4 files changed, 55 insertions(+), 1 deletion(-)

diff --git a/dune/common/hash.hh b/dune/common/hash.hh
index 9346a4526..5a512cfa0 100644
--- a/dune/common/hash.hh
+++ b/dune/common/hash.hh
@@ -11,6 +11,23 @@
 #include <tr1/functional>
 #endif
 
+#if HAVE_BOOST
+
+#include <boost/version.hpp>
+
+// Boost 1.34.0 seems to be the first usable version of boost::functional::hash
+#if BOOST_VERSION >= 103400
+#define HAVE_BOOST_HASH 1
+
+// only pull in boost if really necessary
+#if !HAVE_STD_HASH && !HAVE_TR1_HASH
+
+#include <boost/functional/hash.hpp>
+
+#endif // !HAVE_STD_HASH && !HAVE_TR1_HASH
+#endif // BOOST_VERSION >= 103400
+#endif // HAVE_BOOST
+
 /**
  * \file
  * \brief Support for calculating hash values of objects.
@@ -37,7 +54,7 @@ namespace Dune {
    * boost::hash, so it is possible to use Dune::hash in associative containers from
    * those libraries.
    *
-   * The current implementation piggybacks on top of C++11 or TR1, in that order.
+   * The current implementation piggybacks on top of C++11, TR1 or Boost, in that order.
    * As there is no local fallback implementation, hashing will not work without at least
    * one of those dependencies installed.
    */
@@ -270,9 +287,33 @@ namespace Dune {
 #endif // HAVE_STD_HASH || HAVE_TR1_HASH
 
 
+
+// ********************************************************************************
+// Boost support
+// ********************************************************************************
+
+#if !HAVE_DUNE_HASH && HAVE_BOOST_HASH
+// We haven't found a hash implementation yet and Boost is available
+
+// Announce that we provide Dune::hash
+#define HAVE_DUNE_HASH 1
+
+// import boost::hash into Dune namespace
+namespace Dune {
+
+  using boost::hash;
+
+}
+
+// We no not need to register our types with boost::hash, as its extension
+// mechanism will automatically pick up the global hash_value() functions.
+
+#endif // !HAVE_DUNE_HASH && HAVE_BOOST_HASH
+
 #endif // DOXYGEN
 
 
+
 // ********************************************************************************
 // Some utility functions for combining hashes of member variables.
 // ********************************************************************************
diff --git a/dune/common/test/Makefile.am b/dune/common/test/Makefile.am
index f6a7e38f1..f75aa909b 100644
--- a/dune/common/test/Makefile.am
+++ b/dune/common/test/Makefile.am
@@ -123,6 +123,7 @@ static_assert_test_fail_SOURCES = static_assert_test_fail.cc
 fassigntest_SOURCES = fassigntest.cc
 
 bigunsignedinttest_SOURCES=bigunsignedinttest.cc
+bigunsignedinttest_CPPFLAGS = $(AM_CPPFLAGS) $(BOOST_CPPFLAGS)
 
 lrutest_SOURCES = lrutest.cc
 
diff --git a/dune/common/test/bigunsignedinttest.cc b/dune/common/test/bigunsignedinttest.cc
index 5eb6f3b33..4f1177e30 100644
--- a/dune/common/test/bigunsignedinttest.cc
+++ b/dune/common/test/bigunsignedinttest.cc
@@ -8,6 +8,10 @@
 #include <limits>
 #include <iostream>
 
+#if HAVE_BOOST_HASH
+#include <boost/functional/hash.hpp>
+#endif
+
 int main()
 {
 
@@ -85,6 +89,13 @@ int main()
     }
 #endif
 
+#if HAVE_BOOST_HASH
+    {
+      boost::hash<Dune::bigunsignedint<100> > hasher;
+      std::cout << "boost::hash:    " << hasher(a) << std::endl;
+    }
+#endif
+
 #endif // HAVE_DUNE_HASH
 
   }
diff --git a/m4/dune_common.m4 b/m4/dune_common.m4
index 3729daf68..ffd70f01f 100644
--- a/m4/dune_common.m4
+++ b/m4/dune_common.m4
@@ -22,6 +22,7 @@ AC_DEFUN([DUNE_COMMON_CHECKS],
   AC_REQUIRE([STATIC_ASSERT_CHECK])
   AC_REQUIRE([NULLPTR_CHECK])
   AC_REQUIRE([SHARED_PTR])
+  AC_REQUIRE([DUNE_BOOST_BASE])
   AC_REQUIRE([MAKE_SHARED])
   AC_REQUIRE([DUNE_LINKCXX])
   AC_REQUIRE([DUNE_CHECKDEPRECATED])
-- 
GitLab