![]() |
Lumiera 0.pre.04~rc.1
»edit your freedom«
|
Helper to use a single extension point for specialised hash functions. More...
Go to the source code of this file.
Helper to use a single extension point for specialised hash functions.
With the switch to C++11, there are now two competing quasi standard frameworks for defining individual hasher functions: the std::hash functor and <boost/functional/hash.hpp>. The standard library hasher is used by the (new) STL hashtables and requires an explicit specialisation of std::hash<TYPE>, while the boost hash automatically picks up an free function hash_value(MyType const&). Additionally, Boost ships with a large collection of predefined hash functions for various combinations of standard containers and custom types. To add to this venerable mess, the standard hash defines a default specialisation which triggers a static assertion and halts compilation, in case no custom specialisation can be found – which defeats a meta programming solution based on SFINAE.
In the Lumiera code base, the habit is to define a free function hash_value alongside with custom data types. This helper uses metaprogramming to generate a bridge from the standard hasher to use this boost-style custom hash function if applicable. To allow for such an automatic bridge, we have to work around aforementioned problem with the static assertion. Recent discussion threads indicate that the GCC and Clang developers are aware of those likely unintended side effects of a well meant hint for people to implement their own hash functions. AFAIK, the standard lib shipping with some GCC 4.8.x doesn't contain the assertion anymore; and there are plans to adopt the boost style extension mechanism and provide such a bridge in the standard library at some point in the future.
In the light of this situation, it feels justified to play a dirty trick in order to defeat that static assertion: in this header, we blatantly hijack the standard library definition of std::hash, push it aside and plant our own definition instead.
<functional>. Please ensure it is always included before the latter. Failing to do so will result in mysterious failures.Definition in file hash-standard.hpp.
#include "lib/hash-value.h"#include <cstddef>#include <utility>#include <bits/c++config.h>#include <bits/functional_hash.h>Namespaces | |
| namespace | lib |
| Implementation namespace for support and library code. | |
| namespace | lib::meta |
| namespace | std |
| STL namespace. | |
Macros | |
| #define | hash hash_HIDDEN |
| #define | _Hash_impl _Hash_impl_HIDDEN |
| #define | STD_HASH_IMPL(_TY_) template<> struct hash<_TY_> : public hash_HIDDEN<_TY_> { }; |
Typedefs | |
| typedef size_t | HasUsableHashDefinition |
Classes | |
| struct | NoUsableHashDefinition |
| class | provides_BoostHashFunction< TY > |
| trait template to detect if some custom type TY provides a boost compliant hash function through ADL More... | |
| struct | _HashImplementationSelector< TY, TOGGLE > |
| struct | _HashImplementationSelector< TY, std::enable_if_t< lib::meta::provides_BoostHashFunction< TY >::value > > |
| Specialisation: Bridge from std::hash to boost::hash. More... | |
| struct | hash< TY > |
| Primary class template for std::hash. More... | |
| struct | _Hash_impl |
Variables | |
| NoUsableHashDefinition | hash_value (...) |
| declared for metaprogramming only, never defined | |
| #define hash hash_HIDDEN |
Definition at line 150 of file hash-standard.hpp.
| #define _Hash_impl _Hash_impl_HIDDEN |
Definition at line 151 of file hash-standard.hpp.
| #define STD_HASH_IMPL | ( | _TY_ | ) | template<> struct hash<_TY_> : public hash_HIDDEN<_TY_> { }; |
Definition at line 184 of file hash-standard.hpp.