From 10e69621b6e1b8f53fa9facc2af8fb32ab493b9a Mon Sep 17 00:00:00 2001
From: Christian Engwer <christi@dune-project.org>
Date: Sun, 25 Nov 2012 10:23:16 +0000
Subject: [PATCH] [hash] Make bigunsignedint hashable using Dune::hash
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This patch adds the required hooks to enable hashing of bigunsignedint
and makes sure the hasher can be invoked in bigunsignedinttest.

Making bigunsignedint hashable also makes it possible to use hash-based
containers for EntityIDs with YaspGrid and SGrid, as those grids implement
the EntityID as a plain bigunsignedint.

The patch also adds a little test to bigunsignedinttest, trying to hash
a bigunsignedint with Dune::hash as well as any of the detected backends
(std::hash and std::tr1::hash).

Kudos to Steffen Müthing, see FS#1192

[[Imported from SVN: r7066]]
---
 dune/common/bigunsignedint.hh          | 12 ++++++++++++
 dune/common/test/bigunsignedinttest.cc | 24 ++++++++++++++++++++++++
 2 files changed, 36 insertions(+)

diff --git a/dune/common/bigunsignedint.hh b/dune/common/bigunsignedint.hh
index fb697e8a3..e3f4b1b8f 100644
--- a/dune/common/bigunsignedint.hh
+++ b/dune/common/bigunsignedint.hh
@@ -9,6 +9,7 @@
 #include <limits>
 #include <cstdlib>
 #include <dune/common/exceptions.hh>
+#include <dune/common/hash.hh>
 
 /**
  * @file
@@ -133,6 +134,15 @@ namespace Dune
     friend class bigunsignedint<k/2>;
     friend struct std::numeric_limits< bigunsignedint<k> >;
 
+#if HAVE_DUNE_HASH
+
+    inline friend std::size_t hash_value(const bigunsignedint& arg)
+    {
+      return hash_range(arg.digit,arg.digit + arg.n);
+    }
+
+#endif // HAVE_DUNE_HASH
+
   private:
     unsigned short digit[n];
 #if HAVE_MPI
@@ -628,4 +638,6 @@ namespace std
 
 }
 
+DUNE_DEFINE_HASH(DUNE_HASH_TEMPLATE_ARGS(int k),DUNE_HASH_TYPE(Dune::bigunsignedint<k>))
+
 #endif
diff --git a/dune/common/test/bigunsignedinttest.cc b/dune/common/test/bigunsignedinttest.cc
index 80e3451d4..5eb6f3b33 100644
--- a/dune/common/test/bigunsignedinttest.cc
+++ b/dune/common/test/bigunsignedinttest.cc
@@ -63,6 +63,30 @@ int main()
     b=a;
     a=a*b*b;
     std::cout<<a.todouble()<<std::endl;
+
+#if HAVE_DUNE_HASH
+
+    {
+      Dune::hash<Dune::bigunsignedint<100> > hasher;
+      std::cout << "Dune::hash:     " << hasher(a) << std::endl;
+    }
+
+#if HAVE_STD_HASH
+    {
+      std::hash<Dune::bigunsignedint<100> > hasher;
+      std::cout << "std::hash:      " << hasher(a) << std::endl;
+    }
+#endif
+
+#if HAVE_TR1_HASH
+    {
+      std::tr1::hash<Dune::bigunsignedint<100> > hasher;
+      std::cout << "std::tr1::hash: " << hasher(a) << std::endl;
+    }
+#endif
+
+#endif // HAVE_DUNE_HASH
+
   }
   catch(Dune::MathError e) {
     std::cout<<e<<std::endl;
-- 
GitLab