Lumiera  0.pre.03
»edit your freedom«
hash-standard.hpp
Go to the documentation of this file.
1 /*
2  HASH-STANDARD.hpp - allow use both of std and boost hasher implementations
3 
4  Copyright (C)
5  2014, Hermann Vosseler <Ichthyostega@web.de>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 */
13 
14 
57 #ifndef LIB_HASH_STANDARD_H
58 #define LIB_HASH_STANDARD_H
59 #ifdef _FUNCTIONAL_HASH_H
60 #error "unable to hijack std::hash, since <bits/functional_hash.hpp> has already been included. \
61  Please ensure that lib/hash_standard.hpp is included first, before including <string> or <functional>"
62 #endif
63 
64 
65 #include "lib/hash-value.h"
66 
67 #include <cstddef>
68 #include <utility>
69 
70 
71 namespace lib {
72 namespace meta {
73 
74  struct NoUsableHashDefinition { size_t more_than_one[2]; };
75  typedef size_t HasUsableHashDefinition;
76 
78 
79 
84  template<typename TY>
86  {
87  TY const& unusedDummy = *(TY*)nullptr;
88 
89  public:
90  enum{ value = (sizeof(HasUsableHashDefinition) == sizeof(hash_value(unusedDummy))) };
91  };
92 
93 }}
94 
95 
96 
97 namespace std {
98 
99  template<typename Result, typename Arg>
100  struct __hash_base;
101 
102 
103  template<typename TY, typename TOGGLE = void>
105  : public __hash_base<size_t, TY>
106  {
107  static_assert (sizeof(TY) < 0, "No hash implementation found. "
108  "Either specialise std::hash or provide a boost-style hash_value via ADL.");
109 
110  // the default provides *no* hash implementation
111  // and adds a marker type for metaprogramming
112  typedef int NotHashable;
113  };
114 
118  template<typename TY>
119  struct _HashImplementationSelector<TY, std::enable_if_t< lib::meta::provides_BoostHashFunction<TY>::value >>
120  : public __hash_base<size_t, TY>
121  {
122  size_t
123  operator() (TY const& elm) const noexcept
124  {
125  return hash_value(elm);
126  }
127  };
128 
129 
138  template<typename TY>
139  struct hash
140  : public _HashImplementationSelector<TY>
141  { };
142 
143 }
144 
145 
146 
147 
148 /* ==== Evil Evil ==== */
149 
150 #define hash hash_HIDDEN
151 #define _Hash_impl _Hash_impl_HIDDEN
152 #include <bits/c++config.h>
153 #include <bits/functional_hash.h>
154 #undef hash
155 #undef _Hash_impl
156 
157 
158 namespace std {
159 
160  /* after the manipulation is performed now,
161  * we have to do some clean-up: it might happen that
162  * other parts of the standard library call directly into the
163  * standard Hash implementation (in fact, the hashers for strings,
164  * floats and doubles do this). Thus we have to amend this standard
165  * implementation, and re-wire it to the original definition.
166  */
167 
168  struct _Hash_impl
169  : public std::_Hash_impl_HIDDEN
170  {
171  template<typename ... ARGS>
172  static auto
173  hash (ARGS&&... args) -> decltype(hash_HIDDEN (std::forward<ARGS>(args)...))
174  {
175  return hash_HIDDEN (std::forward<ARGS>(args)...);
176  }
177  };
178 
179  /* and likewise, we have to re-wire all the
180  * default hash implementations to the original implementation.
181  * This is just a defensive approach; we change a function name,
182  * yet we avoid changing any actual library code.
183  */
184 #define STD_HASH_IMPL(_TY_) \
185  template<> struct hash<_TY_> : public hash_HIDDEN<_TY_> { };
186 
187  STD_HASH_IMPL (bool)
188  STD_HASH_IMPL (char)
189  STD_HASH_IMPL (signed char)
190  STD_HASH_IMPL (unsigned char)
191  STD_HASH_IMPL (wchar_t)
192  STD_HASH_IMPL (char16_t)
193  STD_HASH_IMPL (char32_t)
194  STD_HASH_IMPL (short)
195  STD_HASH_IMPL (int)
196  STD_HASH_IMPL (long)
197  STD_HASH_IMPL (long long)
198  STD_HASH_IMPL (unsigned short)
199  STD_HASH_IMPL (unsigned int)
200  STD_HASH_IMPL (unsigned long)
201  STD_HASH_IMPL (unsigned long long)
202  STD_HASH_IMPL (float)
203  STD_HASH_IMPL (double)
204  STD_HASH_IMPL (long double)
205 
206 #undef STD_HASH_IMPL
207 }
208 
209 #endif /*LIB_HASH_STANDARD_H*/
STL namespace.
Primary class template for std::hash.
Implementation namespace for support and library code.
HashVal hash_value(QueryText const &entry)
support using queries in hashtables.
Definition: query-text.cpp:52
Hash value types and utilities.
trait template to detect if some custom type TY provides a boost compliant hash function through ADL ...