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 
00045 #ifndef MASK_BASED_RANGE_HASHING_HPP
00046 #define MASK_BASED_RANGE_HASHING_HPP
00047 
00048 namespace pb_assoc
00049 {
00050 
00051   namespace detail
00052   {
00053 
00054 #define PB_ASSOC_CLASS_T_DEC \
00055     template<typename Size_Type>
00056 
00057 #define PB_ASSOC_CLASS_C_DEC \
00058     mask_based_range_hashing< \
00059         Size_Type>
00060 
00061     template<typename Size_Type>
00062     class mask_based_range_hashing
00063     {
00064     protected:
00065       typedef Size_Type size_type;
00066 
00067     protected:
00068       void
00069       swap(PB_ASSOC_CLASS_C_DEC& r_other);
00070 
00071       void
00072       notify_resized(size_type size);
00073 
00074       inline size_type
00075       range_hash(size_type hash) const;
00076 
00077     private:
00078       size_type m_mask;
00079 
00080       const static size_type s_num_bits_in_size_type;
00081 
00082       const static size_type s_highest_bit_1;
00083     };
00084 
00085     PB_ASSOC_CLASS_T_DEC
00086     const typename PB_ASSOC_CLASS_C_DEC::size_type
00087     PB_ASSOC_CLASS_C_DEC::s_num_bits_in_size_type =
00088     sizeof(typename PB_ASSOC_CLASS_C_DEC::size_type) << 3;
00089 
00090     PB_ASSOC_CLASS_T_DEC
00091     const typename PB_ASSOC_CLASS_C_DEC::size_type
00092     PB_ASSOC_CLASS_C_DEC::s_highest_bit_1 =
00093     (typename PB_ASSOC_CLASS_C_DEC::size_type) 1
00094       << (s_num_bits_in_size_type - 1);
00095 
00096     PB_ASSOC_CLASS_T_DEC
00097     void
00098     PB_ASSOC_CLASS_C_DEC::
00099     swap(PB_ASSOC_CLASS_C_DEC& r_other)
00100     {
00101       std::swap(m_mask, r_other.m_mask);
00102     }
00103 
00104     PB_ASSOC_CLASS_T_DEC
00105     void
00106     PB_ASSOC_CLASS_C_DEC::
00107     notify_resized(size_type size)
00108     {
00109       size_type i = 0;
00110 
00111       while (size ^ s_highest_bit_1)
00112     {
00113       size <<= 1;
00114 
00115       ++i;
00116     }
00117 
00118       m_mask = 1;
00119 
00120       i += 2;
00121 
00122       while (i++ < s_num_bits_in_size_type)
00123     m_mask = (m_mask << 1) ^ 1;
00124     }
00125 
00126     PB_ASSOC_CLASS_T_DEC
00127     inline typename PB_ASSOC_CLASS_C_DEC::size_type
00128     PB_ASSOC_CLASS_C_DEC::
00129     range_hash(size_type hash) const
00130     {
00131       return (hash&  m_mask);
00132     }
00133 
00134 #undef PB_ASSOC_CLASS_T_DEC
00135 #undef PB_ASSOC_CLASS_C_DEC
00136 
00137   } 
00138 
00139 } 
00140 
00141 #endif // #ifndef MASK_BASED_RANGE_HASHING_HPP