00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00046 #ifndef RANGED_HASH_FN_HPP
00047 #define RANGED_HASH_FN_HPP
00048 
00049 #include <utility>
00050 
00051 namespace pb_assoc
00052 {
00053 
00054   namespace detail
00055   {
00056 
00057 #ifdef PB_ASSOC_RANGED_HASH_FN_DEBUG
00058 #define PB_ASSOC_DBG_ASSERT(X) assert(X)
00059 #define PB_ASSOC_DBG_VERIFY(X) assert(X)
00060 #define PB_ASSOC_DBG_ONLY(X) X
00061 #else // #ifdef PB_ASSOC_RANGED_HASH_FN_DEBUG
00062 #define PB_ASSOC_DBG_ASSERT(X)
00063 #define PB_ASSOC_DBG_VERIFY(X) {if((X)==0);}
00064 #define PB_ASSOC_DBG_ONLY(X) ;
00065 #endif // #ifdef PB_ASSOC_RANGED_HASH_FN_DEBUG
00066 
00067     template<typename Key,
00068          class Hash_Fn,
00069          class Allocator,
00070          class Comb_Hash_Fn,
00071          bool Store_Hash>
00072     class ranged_hash_fn;
00073 
00074 #define PB_ASSOC_CLASS_T_DEC \
00075     template< \
00076         typename Key, \
00077         class Hash_Fn, \
00078         class Allocator, \
00079         class Comb_Hash_Fn>
00080 
00081 #define PB_ASSOC_CLASS_C_DEC \
00082     ranged_hash_fn< \
00083         Key, \
00084         Hash_Fn, \
00085         Allocator, \
00086         Comb_Hash_Fn, \
00087         false>
00088 
00093     template<typename Key,
00094          class Hash_Fn,
00095          class Allocator,
00096          class Comb_Hash_Fn>
00097     class ranged_hash_fn<Key, Hash_Fn, Allocator, Comb_Hash_Fn, false> : public Hash_Fn,
00098                                      public Comb_Hash_Fn
00099     {
00100     protected:
00101       typedef typename Allocator::size_type size_type;
00102 
00103       typedef Hash_Fn my_hash_fn_base;
00104 
00105       typedef Comb_Hash_Fn my_comb_hash_fn_base;
00106 
00107       typedef typename Allocator::template rebind<Key>::other key_allocator;
00108 
00109       typedef typename key_allocator::const_reference const_key_reference;
00110 
00111     protected:
00112       ranged_hash_fn(size_type size);
00113 
00114       ranged_hash_fn(size_type size, const Hash_Fn& r_hash_fn);
00115 
00116       ranged_hash_fn(size_type size, const Hash_Fn& r_hash_fn, const Comb_Hash_Fn& r_comb_hash_fn);
00117 
00118       void
00119       swap(PB_ASSOC_CLASS_C_DEC& r_other);
00120 
00121       void
00122       notify_resized(size_type size);
00123 
00124       inline size_type
00125       operator()(const_key_reference r_key) const;
00126     };
00127 
00128     PB_ASSOC_CLASS_T_DEC
00129     PB_ASSOC_CLASS_C_DEC::
00130     ranged_hash_fn(size_type size)
00131     {
00132       Comb_Hash_Fn::notify_resized(size);
00133     }
00134 
00135     PB_ASSOC_CLASS_T_DEC
00136     PB_ASSOC_CLASS_C_DEC::
00137     ranged_hash_fn(size_type size, const Hash_Fn& r_hash_fn) :
00138       Hash_Fn(r_hash_fn)
00139     {
00140       Comb_Hash_Fn::notify_resized(size);
00141     }
00142 
00143     PB_ASSOC_CLASS_T_DEC
00144     PB_ASSOC_CLASS_C_DEC::
00145     ranged_hash_fn(size_type size, const Hash_Fn& r_hash_fn, const Comb_Hash_Fn& r_comb_hash_fn) :
00146       Hash_Fn(r_hash_fn),
00147       Comb_Hash_Fn(r_comb_hash_fn)
00148     {
00149       my_comb_hash_fn_base::notify_resized(size);
00150     }
00151 
00152     PB_ASSOC_CLASS_T_DEC
00153     void
00154     PB_ASSOC_CLASS_C_DEC::
00155     swap(PB_ASSOC_CLASS_C_DEC& r_other)
00156     {
00157       my_comb_hash_fn_base::swap(r_other);
00158 
00159       std::swap((Hash_Fn& )(*this), (Hash_Fn& )r_other);
00160     }
00161 
00162     PB_ASSOC_CLASS_T_DEC
00163     void
00164     PB_ASSOC_CLASS_C_DEC::
00165     notify_resized(size_type size)
00166     {
00167       my_comb_hash_fn_base::notify_resized(size);
00168     }
00169 
00170     PB_ASSOC_CLASS_T_DEC
00171     inline typename PB_ASSOC_CLASS_C_DEC::size_type
00172     PB_ASSOC_CLASS_C_DEC::
00173     operator()(const_key_reference r_key) const
00174     {
00175       return (my_comb_hash_fn_base::operator()(
00176                            my_hash_fn_base::operator()(r_key)));
00177     }
00178 
00179 #undef PB_ASSOC_CLASS_T_DEC
00180 #undef PB_ASSOC_CLASS_C_DEC
00181 
00182 #define PB_ASSOC_CLASS_T_DEC \
00183     template< \
00184         typename Key, \
00185         class Hash_Fn, \
00186         class Allocator, \
00187         class Comb_Hash_Fn>
00188 
00189 #define PB_ASSOC_CLASS_C_DEC \
00190     ranged_hash_fn< \
00191         Key, \
00192         Hash_Fn, \
00193         Allocator, \
00194         Comb_Hash_Fn, \
00195         true>
00196 
00201     template<typename Key,
00202          class Hash_Fn,
00203          class Allocator,
00204          class Comb_Hash_Fn>
00205     class ranged_hash_fn<Key, Hash_Fn, Allocator, Comb_Hash_Fn, true> :
00206       public Hash_Fn,
00207       public Comb_Hash_Fn
00208     {
00209     protected:
00210       typedef typename Allocator::size_type size_type;
00211 
00212       typedef std::pair<size_type, size_type> comp_hash;
00213 
00214       typedef Hash_Fn my_hash_fn_base;
00215 
00216       typedef Comb_Hash_Fn my_comb_hash_fn_base;
00217 
00218       typedef typename Allocator::template rebind<Key>::other key_allocator;
00219 
00220       typedef typename key_allocator::const_reference const_key_reference;
00221 
00222     protected:
00223       ranged_hash_fn(size_type size);
00224 
00225       ranged_hash_fn(size_type size, const Hash_Fn& r_hash_fn);
00226 
00227       ranged_hash_fn(size_type size, const Hash_Fn& r_hash_fn, const Comb_Hash_Fn& r_comb_hash_fn);
00228 
00229       void
00230       swap(PB_ASSOC_CLASS_C_DEC& r_other);
00231 
00232       void
00233       notify_resized(size_type size);
00234 
00235       inline comp_hash
00236       operator()(const_key_reference r_key) const;
00237 
00238       inline comp_hash
00239       operator()(const_key_reference r_key, size_type hash) const;
00240     };
00241 
00242     PB_ASSOC_CLASS_T_DEC
00243     PB_ASSOC_CLASS_C_DEC::
00244     ranged_hash_fn(size_type size)
00245     {
00246       Comb_Hash_Fn::notify_resized(size);
00247     }
00248 
00249     PB_ASSOC_CLASS_T_DEC
00250     PB_ASSOC_CLASS_C_DEC::
00251     ranged_hash_fn(size_type size, const Hash_Fn& r_hash_fn) :
00252       Hash_Fn(r_hash_fn)
00253     {
00254       Comb_Hash_Fn::notify_resized(size);
00255     }
00256 
00257     PB_ASSOC_CLASS_T_DEC
00258     PB_ASSOC_CLASS_C_DEC::
00259     ranged_hash_fn(size_type size, const Hash_Fn& r_hash_fn, const Comb_Hash_Fn& r_comb_hash_fn) :
00260       Hash_Fn(r_hash_fn),
00261       Comb_Hash_Fn(r_comb_hash_fn)
00262     {
00263       my_comb_hash_fn_base::notify_resized(size);
00264     }
00265 
00266     PB_ASSOC_CLASS_T_DEC
00267     void
00268     PB_ASSOC_CLASS_C_DEC::
00269     swap(PB_ASSOC_CLASS_C_DEC& r_other)
00270     {
00271       my_comb_hash_fn_base::swap(r_other);
00272 
00273       std::swap((Hash_Fn& )(*this), (Hash_Fn& )r_other);
00274     }
00275 
00276     PB_ASSOC_CLASS_T_DEC
00277     void
00278     PB_ASSOC_CLASS_C_DEC::
00279     notify_resized(size_type size)
00280     {
00281       my_comb_hash_fn_base::notify_resized(size);
00282     }
00283 
00284     PB_ASSOC_CLASS_T_DEC
00285     inline typename PB_ASSOC_CLASS_C_DEC::comp_hash
00286     PB_ASSOC_CLASS_C_DEC::
00287     operator()(const_key_reference r_key) const
00288     {
00289       const size_type hash = my_hash_fn_base::operator()(r_key);
00290 
00291       return (std::make_pair(my_comb_hash_fn_base::operator()(hash), hash));
00292     }
00293 
00294     PB_ASSOC_CLASS_T_DEC
00295     inline typename PB_ASSOC_CLASS_C_DEC::comp_hash
00296     PB_ASSOC_CLASS_C_DEC::
00297     operator()
00298 #ifdef PB_ASSOC_RANGED_HASH_FN_DEBUG
00299       (const_key_reference r_key, size_type hash) const
00300 #else 
00301       (const_key_reference , size_type hash) const
00302 #endif // #ifdef PB_ASSOC_RANGED_HASH_FN_DEBUG
00303     {
00304       PB_ASSOC_DBG_ASSERT(hash == my_hash_fn_base::operator()(r_key));
00305 
00306       return (std::make_pair(my_comb_hash_fn_base::operator()(hash), hash));
00307     }
00308 
00309 #undef PB_ASSOC_CLASS_T_DEC
00310 #undef PB_ASSOC_CLASS_C_DEC
00311 
00312 #define PB_ASSOC_CLASS_T_DEC \
00313     template<typename Key, class Allocator, class Comb_Hash_Fn>
00314 
00315 #define PB_ASSOC_CLASS_C_DEC \
00316     ranged_hash_fn< \
00317         Key, \
00318         null_hash_fn, \
00319         Allocator, \
00320         Comb_Hash_Fn, \
00321         false>
00322 
00329     template<typename Key, class Allocator, class Comb_Hash_Fn>
00330     class ranged_hash_fn<Key, null_hash_fn, Allocator,
00331              Comb_Hash_Fn, false> :
00332       public null_hash_fn,
00333       public Comb_Hash_Fn
00334     {
00335     protected:
00336 
00337       typedef typename Allocator::size_type size_type;
00338 
00339       typedef Comb_Hash_Fn my_comb_hash_fn_base;
00340 
00341     protected:
00342       ranged_hash_fn(size_type size);
00343 
00344       ranged_hash_fn(size_type size, const Comb_Hash_Fn& r_comb_hash_fn);
00345 
00346       ranged_hash_fn(size_type size, const null_hash_fn&r_null_hash_fn, const Comb_Hash_Fn& r_comb_hash_fn);
00347 
00348       void
00349       swap(PB_ASSOC_CLASS_C_DEC& r_other);
00350     };
00351 
00352     PB_ASSOC_CLASS_T_DEC
00353     PB_ASSOC_CLASS_C_DEC::
00354     ranged_hash_fn(size_type size)
00355     {
00356       Comb_Hash_Fn::notify_resized(size);
00357     }
00358 
00359     PB_ASSOC_CLASS_T_DEC
00360     PB_ASSOC_CLASS_C_DEC::
00361     ranged_hash_fn(size_type size, const Comb_Hash_Fn& r_comb_hash_fn) :
00362       Comb_Hash_Fn(r_comb_hash_fn)
00363     { }
00364 
00365     PB_ASSOC_CLASS_T_DEC
00366     PB_ASSOC_CLASS_C_DEC::
00367     ranged_hash_fn(size_type size, const null_hash_fn& r_null_hash_fn, const Comb_Hash_Fn& r_comb_hash_fn) :
00368       Comb_Hash_Fn(r_comb_hash_fn)
00369     { }
00370 
00371     PB_ASSOC_CLASS_T_DEC
00372     void
00373     PB_ASSOC_CLASS_C_DEC::
00374     swap(PB_ASSOC_CLASS_C_DEC& r_other)
00375     {
00376       my_comb_hash_fn_base::swap(r_other);
00377     }
00378 
00379 #undef PB_ASSOC_CLASS_T_DEC
00380 #undef PB_ASSOC_CLASS_C_DEC
00381 
00382 #define PB_ASSOC_CLASS_T_DEC \
00383     template<typename Key, class Allocator, class Comb_Hash_Fn>
00384 
00385 #define PB_ASSOC_CLASS_C_DEC \
00386     ranged_hash_fn< \
00387         Key, \
00388         null_hash_fn, \
00389         Allocator, \
00390         Comb_Hash_Fn, \
00391         true>
00392 
00399     template<typename Key, class Allocator, class Comb_Hash_Fn>
00400     class ranged_hash_fn<Key, null_hash_fn, Allocator,
00401              Comb_Hash_Fn, true> :
00402       public null_hash_fn,
00403       public Comb_Hash_Fn
00404     {
00405     protected:
00406       typedef typename Allocator::size_type size_type;
00407 
00408       typedef Comb_Hash_Fn my_comb_hash_fn_base;
00409 
00410     protected:
00411       ranged_hash_fn(size_type size);
00412 
00413       ranged_hash_fn(size_type size, const Comb_Hash_Fn& r_comb_hash_fn);
00414 
00415       ranged_hash_fn(size_type size, const null_hash_fn&r_null_hash_fn, const Comb_Hash_Fn& r_comb_hash_fn);
00416 
00417       void
00418       swap(PB_ASSOC_CLASS_C_DEC& r_other);
00419     };
00420 
00421     PB_ASSOC_CLASS_T_DEC
00422     PB_ASSOC_CLASS_C_DEC::
00423     ranged_hash_fn(size_type size)
00424     {
00425       Comb_Hash_Fn::notify_resized(size);
00426     }
00427 
00428     PB_ASSOC_CLASS_T_DEC
00429     PB_ASSOC_CLASS_C_DEC::
00430     ranged_hash_fn(size_type size, const Comb_Hash_Fn& r_comb_hash_fn) :
00431       Comb_Hash_Fn(r_comb_hash_fn)
00432     { }
00433 
00434     PB_ASSOC_CLASS_T_DEC
00435     PB_ASSOC_CLASS_C_DEC::
00436     ranged_hash_fn(size_type size, const null_hash_fn&r_null_hash_fn, const Comb_Hash_Fn& r_comb_hash_fn) :
00437       Comb_Hash_Fn(r_comb_hash_fn)
00438     { }
00439 
00440     PB_ASSOC_CLASS_T_DEC
00441     void
00442     PB_ASSOC_CLASS_C_DEC::
00443     swap(PB_ASSOC_CLASS_C_DEC& r_other)
00444     {
00445       my_comb_hash_fn_base::swap(r_other);
00446     }
00447 
00448 #undef PB_ASSOC_CLASS_T_DEC
00449 #undef PB_ASSOC_CLASS_C_DEC
00450 
00451 #undef PB_ASSOC_DBG_ASSERT
00452 #undef PB_ASSOC_DBG_VERIFY
00453 #undef PB_ASSOC_DBG_ONLY
00454 
00455   } 
00456 
00457 } 
00458 
00459 #endif // #ifndef RANGED_HASH_FN_HPP