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 HASH_EQ_FN_HPP
00047 #define HASH_EQ_FN_HPP
00048 
00049 #include <utility>
00050 
00051 namespace pb_assoc
00052 {
00053 
00054   namespace detail
00055   {
00056 
00057 #ifdef PB_ASSOC_HASH_EQ_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_HASH_EQ_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_HASH_EQ_FN_DEBUG
00066 
00067     template<typename Key, class Eq_Fn, class Allocator, bool Store_Hash>
00068     struct hash_eq_fn;
00069 
00070 #define PB_ASSOC_CLASS_T_DEC \
00071     template<typename Key, class Eq_Fn, class Allocator>
00072 
00073 #define PB_ASSOC_CLASS_C_DEC \
00074     hash_eq_fn< \
00075         Key, \
00076         Eq_Fn, \
00077         Allocator, \
00078         false>
00079 
00083     template<typename Key, class Eq_Fn, class Allocator>
00084     struct hash_eq_fn<Key, Eq_Fn, Allocator, false> : public Eq_Fn
00085     {
00086       typedef Eq_Fn my_eq_fn_base;
00087 
00088       typedef typename Allocator::template rebind<Key>::other key_allocator;
00089 
00090       typedef typename key_allocator::const_reference const_key_reference;
00091 
00092       hash_eq_fn();
00093 
00094       hash_eq_fn(const Eq_Fn& r_eq_fn);
00095 
00096       inline bool
00097       operator()(const_key_reference r_lhs_key, const_key_reference r_rhs_key) const;
00098 
00099       inline void
00100       swap(const PB_ASSOC_CLASS_C_DEC& r_other);
00101     };
00102 
00103     PB_ASSOC_CLASS_T_DEC
00104     PB_ASSOC_CLASS_C_DEC::
00105     hash_eq_fn()
00106     { }
00107 
00108     PB_ASSOC_CLASS_T_DEC
00109     inline void
00110     PB_ASSOC_CLASS_C_DEC::
00111     swap(const PB_ASSOC_CLASS_C_DEC& r_other)
00112     {
00113       std::swap((Eq_Fn& )(*this), (Eq_Fn& )r_other);
00114     }
00115 
00116     PB_ASSOC_CLASS_T_DEC
00117     PB_ASSOC_CLASS_C_DEC::
00118     hash_eq_fn(const Eq_Fn& r_eq_fn) :
00119       Eq_Fn(r_eq_fn)
00120     { }
00121 
00122     PB_ASSOC_CLASS_T_DEC
00123     inline bool
00124     PB_ASSOC_CLASS_C_DEC::
00125     operator()(const_key_reference r_lhs_key, const_key_reference r_rhs_key) const
00126     {
00127       return (my_eq_fn_base::operator()(r_lhs_key, r_rhs_key));
00128     }
00129 
00130 #undef PB_ASSOC_CLASS_T_DEC
00131 #undef PB_ASSOC_CLASS_C_DEC
00132 
00133 #define PB_ASSOC_CLASS_T_DEC \
00134     template<typename Key, class Eq_Fn, class Allocator>
00135 
00136 #define PB_ASSOC_CLASS_C_DEC \
00137     hash_eq_fn< \
00138         Key, \
00139         Eq_Fn, \
00140         Allocator, \
00141         true>
00142 
00146     template<typename Key, class Eq_Fn, class Allocator>
00147     struct hash_eq_fn<Key, Eq_Fn, Allocator, true> :
00148       public Eq_Fn
00149     {
00150       typedef typename Allocator::size_type size_type;
00151 
00152       typedef Eq_Fn my_eq_fn_base;
00153 
00154       typedef typename Allocator::template rebind<Key>::other key_allocator;
00155 
00156       typedef typename key_allocator::const_reference const_key_reference;
00157 
00158       hash_eq_fn();
00159 
00160       hash_eq_fn(const Eq_Fn& r_eq_fn);
00161 
00162       inline bool
00163       operator()(const_key_reference r_lhs_key, size_type lhs_hash, const_key_reference r_rhs_key, size_type rhs_hash) const;
00164 
00165       inline void
00166       swap(const PB_ASSOC_CLASS_C_DEC& r_other);
00167     };
00168 
00169     PB_ASSOC_CLASS_T_DEC
00170     PB_ASSOC_CLASS_C_DEC::
00171     hash_eq_fn()
00172     { }
00173 
00174     PB_ASSOC_CLASS_T_DEC
00175     PB_ASSOC_CLASS_C_DEC::
00176     hash_eq_fn(const Eq_Fn& r_eq_fn) :
00177       Eq_Fn(r_eq_fn)
00178     { }
00179 
00180     PB_ASSOC_CLASS_T_DEC
00181     inline bool
00182     PB_ASSOC_CLASS_C_DEC::
00183     operator()(const_key_reference r_lhs_key, size_type lhs_hash, const_key_reference r_rhs_key, size_type rhs_hash) const
00184     {
00185       PB_ASSOC_DBG_ASSERT(!my_eq_fn_base::operator()(r_lhs_key, r_rhs_key) ||
00186               lhs_hash == rhs_hash);
00187 
00188       return (lhs_hash == rhs_hash&& 
00189           my_eq_fn_base::operator()(r_lhs_key, r_rhs_key));
00190     }
00191 
00192     PB_ASSOC_CLASS_T_DEC
00193     inline void
00194     PB_ASSOC_CLASS_C_DEC::
00195     swap(const PB_ASSOC_CLASS_C_DEC& r_other)
00196     {
00197       std::swap((Eq_Fn& )(*this), (Eq_Fn& )(r_other));
00198     }
00199 
00200 #undef PB_ASSOC_CLASS_T_DEC
00201 #undef PB_ASSOC_CLASS_C_DEC
00202 
00203 #undef PB_ASSOC_DBG_ASSERT
00204 #undef PB_ASSOC_DBG_VERIFY
00205 #undef PB_ASSOC_DBG_ONLY
00206 
00207   } 
00208 
00209 } 
00210 
00211 #endif // #ifndef HASH_EQ_FN_HPP