Lumiera  0.pre.03
»edit your freedom«
hash-standard.hpp File Reference

Go to the source code of this file.

Description

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.

Note
this trick was proposed by user "enobayram" on Stackoverflow at Oct 5, 2012 http://stackoverflow.com/questions/12753997/check-if-type-is-hashable
Warning
this header includes and manipulates the standard header <functional>. Please ensure it is always included before the latter. Failing to do so will result in mysterious failures.
Todo:
4/2014 doesn't work as expected. My suspicion is that in the actual use case (PlacementIndex), the type providing the hasher is mixed in through inheritance, and the template specialisation for this base type is not considered on lookup. ///////TICKET #722
See also
HashIndexed
LUID

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.