Lumiera
0.pre.03
»edit your freedom«
|
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>
Classes | |
struct | __hash_base< Result, Arg > |
struct | _Hash_impl |
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 | NoUsableHashDefinition |
class | provides_BoostHashFunction< TY > |
trait template to detect if some custom type TY provides a boost compliant hash function through ADL More... | |
Typedefs | |
typedef size_t | HasUsableHashDefinition |
Macros | |
#define | _Hash_impl _Hash_impl_HIDDEN |
#define | hash hash_HIDDEN |
#define | STD_HASH_IMPL(_TY_) template<> struct hash<_TY_> : public hash_HIDDEN<_TY_> { }; |
Variables | |
NoUsableHashDefinition | hash_value (...) |
declared for metaprogramming only, never defined | |
Namespaces | |
lib | |
Implementation namespace for support and library code. | |