Lumiera 0.pre.04~rc.1
»edit your freedom«
Loading...
Searching...
No Matches
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
71namespace lib {
72namespace meta {
73
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
97namespace std {
98
99 template<typename Result, typename Arg>
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
158namespace 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
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*/
trait template to detect if some custom type TY provides a boost compliant hash function through ADL
#define STD_HASH_IMPL(_TY_)
Hash value types and utilities.
enable_if_c< Cond::value, T >::type enable_if
SFINAE helper to control the visibility of specialisations and overloads.
Definition meta/util.hpp:87
NoUsableHashDefinition hash_value(...)
declared for metaprogramming only, never defined
size_t HasUsableHashDefinition
Implementation namespace for support and library code.
STL namespace.
static auto hash(ARGS &&... args) -> decltype(hash_HIDDEN(std::forward< ARGS >(args)...))
Primary class template for std::hash.