3 #ifndef CDSLIB_OPT_HASH_H
4 #define CDSLIB_OPT_HASH_H
8 #include <cds/opt/options.h>
10 namespace cds { namespace opt {
12 /// [type-option] Option setter for a hash function
14 This option setter specifies hash functor used in unordered containers.
16 The default value of template argument \p Functor is \p cds::opt::v::hash
17 that is synonym for <tt>std::hash</tt> implementation of standard library.
19 template <typename Functor>
22 template <typename Base> struct pack: public Base
33 /// Metafunction selecting default hash implementation
35 The metafunction selects appropriate hash functor implementation.
36 If \p Hash is not equal to opt::none, then result of metafunction is \p Hash.
37 Otherwise, the result is <tt> std::hash<Q> </tt>.
39 Note that default hash function like <tt> std::hash<Q> </tt>
40 is generally not suitable for complex type \p Q and its derivatives.
41 You should manually provide particular hash functor for such types.
43 template <typename Hash>
46 typedef Hash type; ///< resulting implementation of hash functor
50 struct hash_selector<opt::none>
54 size_t operator()( Q const& key ) const
56 return std::hash<Q>()( key );
65 template <class> struct hash_list;
66 template <typename... Functors>
67 struct hash_list< std::tuple<Functors...> >
69 static size_t const size = sizeof...(Functors);
70 typedef size_t values[size];
71 typedef std::tuple<Functors...> hash_tuple_type;
73 hash_tuple_type hash_tuple;
78 hash_list( hash_tuple_type const& t)
81 hash_list( hash_tuple_type&& t)
82 : hash_tuple( std::forward<hash_tuple_type>(t) )
85 template <size_t I, typename T>
86 typename std::enable_if< (I == sizeof...(Functors)) >::type apply( size_t * /*dest*/, T const& /*v*/ ) const
89 template <size_t I, typename T>
90 typename std::enable_if< (I < sizeof...(Functors)) >::type apply( size_t * dest, T const& v ) const
92 dest[I] = std::get<I>( hash_tuple )( v );
93 apply<I+1>( dest, v );
97 void operator()( size_t * dest, T const& v ) const
102 } // namespace details
105 /// Declare tuple for hash functors \p Functors
106 template <typename... Functors>
107 using hash_tuple = details::hash_list< std::tuple< Functors... >>;
110 // At least, two functors must be provided. Single functor is not supported
111 template <typename Functor> struct hash< std::tuple<Functor> >;
114 /// Multi-functor hash option setter - specialization for std::tuple
115 template <typename... Functors>
116 struct hash< std::tuple<Functors...> >
119 template <typename Base> struct pack: public Base
121 typedef details::hash_list< std::tuple<Functors...> > hash;
130 template <class HashList, typename WrappedType, typename Wrapper>
131 struct hash_list_wrapper {
132 typedef HashList hash_list;
133 typedef WrappedType wrapped_type;
134 typedef Wrapper wrapper_type;
136 typedef typename hash_list::hash_tuple_type hash_tuple_type;
137 static size_t const size = hash_list::size;
139 hash_list m_wrappedList;
143 hash_list_wrapper( hash_tuple_type const& t)
146 hash_list_wrapper( hash_tuple_type&& t)
147 : m_wrappedList( std::forward<hash_tuple_type>(t) )
150 void operator()( size_t * dest, wrapped_type const& what ) const
152 m_wrappedList( dest, wrapper_type()( what ));
155 template <typename Q>
156 void operator()( size_t * dest, Q const& what) const
158 m_wrappedList( dest, what );
162 } // namespace details
165 }} // namespace cds::opt
167 #endif // #ifndef CDSLIB_OPT_HASH_H