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) Lumiera.org
5  2014, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 */
22 
23 
66 #ifndef LIB_HASH_STANDARD_H
67 #define LIB_HASH_STANDARD_H
68 #ifdef _FUNCTIONAL_HASH_H
69 #error "unable to hijack std::hash, since <bits/functional_hash.hpp> has already been included. \
70  Please ensure that lib/hash_standard.hpp is included first, before including <string> or <functional>"
71 #endif
72 
73 
74 #include "lib/hash-value.h"
75 
76 #include <cstddef>
77 #include <utility>
78 
79 
80 namespace lib {
81 namespace meta {
82 
83  struct NoUsableHashDefinition { size_t more_than_one[2]; };
84  typedef size_t HasUsableHashDefinition;
85 
87 
88 
93  template<typename TY>
95  {
96  TY const& unusedDummy = *(TY*)nullptr;
97 
98  public:
99  enum{ value = (sizeof(HasUsableHashDefinition) == sizeof(hash_value(unusedDummy))) };
100  };
101 
102 }}
103 
104 
105 
106 namespace std {
107 
108  template<typename Result, typename Arg>
109  struct __hash_base;
110 
111 
112  template<typename TY, typename TOGGLE = void>
114  : public __hash_base<size_t, TY>
115  {
116  static_assert (sizeof(TY) < 0, "No hash implementation found. "
117  "Either specialise std::hash or provide a boost-style hash_value via ADL.");
118 
119  // the default provides *no* hash implementation
120  // and adds a marker type for metaprogramming
121  typedef int NotHashable;
122  };
123 
127  template<typename TY>
128  struct _HashImplementationSelector<TY, std::enable_if_t< lib::meta::provides_BoostHashFunction<TY>::value >>
129  : public __hash_base<size_t, TY>
130  {
131  size_t
132  operator() (TY const& elm) const noexcept
133  {
134  return hash_value(elm);
135  }
136  };
137 
138 
147  template<typename TY>
148  struct hash
149  : public _HashImplementationSelector<TY>
150  { };
151 
152 }
153 
154 
155 
156 
157 /* ==== Evil Evil ==== */
158 
159 #define hash hash_HIDDEN
160 #define _Hash_impl _Hash_impl_HIDDEN
161 #include <bits/c++config.h>
162 #include <bits/functional_hash.h>
163 #undef hash
164 #undef _Hash_impl
165 
166 
167 namespace std {
168 
169  /* after the manipulation is performed now,
170  * we have to do some clean-up: it might happen that
171  * other parts of the standard library call directly into the
172  * standard Hash implementation (in fact, the hashers for strings,
173  * floats and doubles do this). Thus we have to amend this standard
174  * implementation, and re-wire it to the original definition.
175  */
176 
177  struct _Hash_impl
178  : public std::_Hash_impl_HIDDEN
179  {
180  template<typename ... ARGS>
181  static auto
182  hash (ARGS&&... args) -> decltype(hash_HIDDEN (std::forward<ARGS>(args)...))
183  {
184  return hash_HIDDEN (std::forward<ARGS>(args)...);
185  }
186  };
187 
188  /* and likewise, we have to re-wire all the
189  * default hash implementations to the original implementation.
190  * This is just a defensive approach; we change a function name,
191  * yet we avoid changing any actual library code.
192  */
193 #define STD_HASH_IMPL(_TY_) \
194  template<> struct hash<_TY_> : public hash_HIDDEN<_TY_> { };
195 
196  STD_HASH_IMPL (bool)
197  STD_HASH_IMPL (char)
198  STD_HASH_IMPL (signed char)
199  STD_HASH_IMPL (unsigned char)
200  STD_HASH_IMPL (wchar_t)
201  STD_HASH_IMPL (char16_t)
202  STD_HASH_IMPL (char32_t)
203  STD_HASH_IMPL (short)
204  STD_HASH_IMPL (int)
205  STD_HASH_IMPL (long)
206  STD_HASH_IMPL (long long)
207  STD_HASH_IMPL (unsigned short)
208  STD_HASH_IMPL (unsigned int)
209  STD_HASH_IMPL (unsigned long)
210  STD_HASH_IMPL (unsigned long long)
211  STD_HASH_IMPL (float)
212  STD_HASH_IMPL (double)
213  STD_HASH_IMPL (long double)
214 
215 #undef STD_HASH_IMPL
216 }
217 
218 #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:61
Hash value types and utilities.
trait template to detect if some custom type TY provides a boost compliant hash function through ADL ...