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 
00040 
00041 
00042 
00043 
00044 
00045 #ifndef ORDER_STATISTICS_IMP_HPP
00046 #define ORDER_STATISTICS_IMP_HPP
00047 
00048 #define PB_ASSOC_CLASS_T_DEC \
00049     template<class Key, class Allocator>
00050 
00051 #define PB_ASSOC_CLASS_C_DEC \
00052     order_statistics_key< \
00053         Key, \
00054         Allocator>
00055 
00056 PB_ASSOC_CLASS_T_DEC
00057 inline
00058 PB_ASSOC_CLASS_C_DEC::
00059 order_statistics_key(const_key_reference r_key) :
00060   m_key(r_key),
00061   m_rank(1)
00062 { }
00063 
00064 PB_ASSOC_CLASS_T_DEC
00065 inline
00066 PB_ASSOC_CLASS_C_DEC::
00067 operator typename PB_ASSOC_CLASS_C_DEC::key_reference()
00068 {
00069   return (m_key);
00070 }
00071 
00072 PB_ASSOC_CLASS_T_DEC
00073 inline
00074 PB_ASSOC_CLASS_C_DEC::
00075 operator typename PB_ASSOC_CLASS_C_DEC::key_type() const
00076 {
00077   return (m_key);
00078 }
00079 
00080 #undef PB_ASSOC_CLASS_T_DEC
00081 
00082 #undef PB_ASSOC_CLASS_C_DEC
00083 
00084 #define PB_ASSOC_CLASS_T_DEC \
00085     template<class Cmp_Fn, class Allocator>
00086 
00087 #define PB_ASSOC_CLASS_C_DEC \
00088     order_statistics_key_cmp< \
00089         Cmp_Fn, \
00090         Allocator>
00091 
00092 PB_ASSOC_CLASS_T_DEC
00093 inline
00094 PB_ASSOC_CLASS_C_DEC::
00095 order_statistics_key_cmp()
00096 { }
00097 
00098 PB_ASSOC_CLASS_T_DEC
00099 inline
00100 PB_ASSOC_CLASS_C_DEC::
00101 order_statistics_key_cmp(const Cmp_Fn& r_cmp_fn) :
00102   Cmp_Fn(r_cmp_fn)
00103 { }
00104 
00105 PB_ASSOC_CLASS_T_DEC
00106 inline bool
00107 PB_ASSOC_CLASS_C_DEC::
00108 operator()(const_key_reference r_lhs_key, const_key_reference r_rhs_key) const
00109 {
00110   return Cmp_Fn::operator()((key_type)r_lhs_key, (key_type)r_rhs_key);
00111 }
00112 
00113 PB_ASSOC_CLASS_T_DEC
00114 inline typename PB_ASSOC_CLASS_C_DEC::cmp_fn& 
00115 PB_ASSOC_CLASS_C_DEC::
00116 get_cmp_fn()
00117 {
00118   return (*this);
00119 }
00120 
00121 PB_ASSOC_CLASS_T_DEC
00122 inline const typename PB_ASSOC_CLASS_C_DEC::cmp_fn& 
00123 PB_ASSOC_CLASS_C_DEC::
00124 get_cmp_fn() const
00125 {
00126   return (*this);
00127 }
00128 
00129 #undef PB_ASSOC_CLASS_T_DEC
00130 
00131 #undef PB_ASSOC_CLASS_C_DEC
00132 
00133 #define PB_ASSOC_CLASS_T_DEC \
00134     template<class Key, class Allocator>
00135 
00136 #define PB_ASSOC_CLASS_C_DEC \
00137     order_statistics_node_updator< \
00138         Key, \
00139         Allocator>
00140 
00141 PB_ASSOC_CLASS_T_DEC
00142 inline void
00143 PB_ASSOC_CLASS_C_DEC::
00144 operator()(const_key_pointer p_key, const_key_pointer p_l_child_key, const_key_pointer p_r_child_key)
00145 {
00146   
00147 
00148 
00149 
00150   const size_type l_rank =(p_l_child_key == NULL)? 0 : p_l_child_key->m_rank;
00151 
00152   
00153 
00154 
00155 
00156   const size_type r_rank =(p_r_child_key == NULL)? 0 : p_r_child_key->m_rank;
00157 
00158   
00159 
00160 
00161 
00162   p_key->m_rank = 1 + l_rank + r_rank;
00163 }
00164 
00165 PB_ASSOC_CLASS_T_DEC
00166 inline void
00167 PB_ASSOC_CLASS_C_DEC::
00168 swap(PB_ASSOC_CLASS_C_DEC& )
00169 { }
00170 
00171 #undef PB_ASSOC_CLASS_T_DEC
00172 
00173 #undef PB_ASSOC_CLASS_C_DEC
00174 
00175 #define PB_ASSOC_CLASS_T_DEC \
00176     template<class Cntnr>
00177 
00178 #define PB_ASSOC_CLASS_C_DEC \
00179     find_by_order< \
00180         Cntnr>
00181 
00182 PB_ASSOC_CLASS_T_DEC
00183 inline typename PB_ASSOC_CLASS_C_DEC::iterator
00184 PB_ASSOC_CLASS_C_DEC::
00185 operator()(Cntnr& r_c, size_type order) const
00186 {
00187   return find(r_c, order);
00188 }
00189 
00190 PB_ASSOC_CLASS_T_DEC
00191 inline typename PB_ASSOC_CLASS_C_DEC::const_iterator
00192 PB_ASSOC_CLASS_C_DEC::
00193 operator()(const Cntnr& r_c, size_type order) const
00194 {
00195   return find(r_c, order);
00196 }
00197 
00198 PB_ASSOC_CLASS_T_DEC
00199 inline typename PB_ASSOC_CLASS_C_DEC::const_iterator
00200 PB_ASSOC_CLASS_C_DEC::
00201 find(const Cntnr& r_c, size_type order)
00202 {
00203   if (order > r_c.size())
00204     return (r_c.end());
00205 
00206   
00207 
00208 
00209   typename Cntnr::const_node_iterator it = r_c.node_begin();
00210 
00211   
00212 
00213 
00214   while (it != r_c.node_end())
00215     {
00216       typename Cntnr::const_node_iterator l_it = it.l_child();
00217 
00218       
00219 
00220 
00221 
00222       const size_type o = (l_it == r_c.node_end())?
00223     0 :(*l_it)->m_rank;
00224 
00225       
00226 
00227 
00228 
00229       if (order == o)
00230     return (*it);
00231       
00232 
00233 
00234 
00235       else if (order < o)
00236     it = l_it;
00237       
00238 
00239 
00240       else
00241     {
00242       order -= o + 1;
00243 
00244       it = it.r_child();
00245     }
00246     }
00247 
00248   return (r_c.end());
00249 }
00250 
00251 PB_ASSOC_CLASS_T_DEC
00252 inline typename PB_ASSOC_CLASS_C_DEC::iterator
00253 PB_ASSOC_CLASS_C_DEC::
00254 find(Cntnr& r_c, size_type order)
00255 {
00256   if (order > r_c.size())
00257     return (r_c.end());
00258 
00259   
00260 
00261 
00262   typename Cntnr::node_iterator it = r_c.node_begin();
00263 
00264   
00265 
00266 
00267   while (it != r_c.node_end())
00268     {
00269       typename Cntnr::node_iterator l_it = it.l_child();
00270 
00271       
00272 
00273 
00274 
00275       const size_type o = (l_it == r_c.node_end())?
00276     0 :
00277     r_c.extract_key(*(*l_it)).m_rank;
00278 
00279       
00280 
00281 
00282 
00283       if (order == o)
00284     return (*it);
00285       
00286 
00287 
00288 
00289       else if (order < o)
00290     it = l_it;
00291       
00292 
00293 
00294       else
00295     {
00296       order -= o + 1;
00297 
00298       it = it.r_child();
00299     }
00300     }
00301 
00302   return (r_c.end());
00303 }
00304 
00305 #undef PB_ASSOC_CLASS_T_DEC
00306 
00307 #undef PB_ASSOC_CLASS_C_DEC
00308 
00309 #define PB_ASSOC_CLASS_T_DEC \
00310     template<class Cntnr>
00311 
00312 #define PB_ASSOC_CLASS_C_DEC \
00313     order_by_key< \
00314         Cntnr>
00315 
00316 PB_ASSOC_CLASS_T_DEC
00317 inline typename PB_ASSOC_CLASS_C_DEC::size_type
00318 PB_ASSOC_CLASS_C_DEC::
00319 operator()(const Cntnr& r_c, const underlying_key_type& r_key) const
00320 {
00321   
00322 
00323 
00324 
00325   typename Cntnr::const_node_iterator it = r_c.node_begin();
00326 
00327   size_type ord = 0;
00328 
00329   while (it != r_c.node_end())
00330     {
00331       typename Cntnr::const_node_iterator l_it = it.l_child();
00332 
00333       if (r_c.get_cmp_fn().get_cmp_fn()(
00334                     r_key,
00335                     r_c.extract_key(*(*it)).m_key))
00336     it = l_it;
00337       else if (r_c.get_cmp_fn().get_cmp_fn()(
00338                          r_c.extract_key(*(*it)).m_key,
00339                          r_key))
00340     {
00341 
00342       ord += (l_it == r_c.node_end())?
00343         1 :
00344         1 + r_c.extract_key(*(*l_it)).m_rank;
00345 
00346       it = it.r_child();
00347     }
00348       else
00349     {
00350       ord += (l_it == r_c.node_end())?
00351         0 :
00352         r_c.extract_key(*(*l_it)).m_rank;
00353 
00354       it = r_c.node_end();
00355     }
00356     }
00357 
00358   return (ord);
00359 }
00360 
00361 #undef PB_ASSOC_CLASS_T_DEC
00362 
00363 #undef PB_ASSOC_CLASS_C_DEC
00364 
00365 #define PB_ASSOC_CLASS_T_DEC \
00366     template<class Cntnr, class Allocator>
00367 
00368 #define PB_ASSOC_CLASS_C_DEC \
00369     order_statistics_key_verifier< \
00370         Cntnr, \
00371         Allocator>
00372 
00373 template<class Cntnr, class Allocator = std::allocator<char> >
00374 class order_statistics_key_verifier
00375 {
00376 public:
00377   typedef Cntnr map;
00378 
00379   typedef Allocator allocator;
00380 
00381   typedef typename allocator::size_type size_type;
00382 
00383   typedef
00384   typename allocator::template rebind<map>::other::const_reference
00385   const_map_reference;
00386 
00387 public:
00388   bool
00389   operator()(const Cntnr& r_c) const;
00390 
00391 private:
00392   typedef typename Cntnr::const_node_iterator const_node_iterator;
00393 
00394   typedef typename Cntnr::const_iterator cntnr_const_it;
00395 
00396   typedef std::pair<bool, size_type> stat;
00397 
00398 private:
00399   static stat
00400   verify_imp(const_node_iterator it, const_node_iterator end_it)
00401   {
00402     if (it == end_it)
00403       return (std::make_pair(true, 0));
00404 
00405     const stat l_ret =
00406       verify_imp(it.l_child(), end_it);
00407 
00408     const stat r_ret =
00409       verify_imp(it.r_child(), end_it);
00410 
00411     if (!l_ret.first || !r_ret.first)
00412       return (std::make_pair(false, 0));
00413 
00414     if ((*it)->m_rank != 1 + l_ret.second + r_ret.second)
00415       return (std::make_pair(false, 0));
00416 
00417     return (std::make_pair(true, (*it)->m_rank));
00418   }
00419 };
00420 
00421 PB_ASSOC_CLASS_T_DEC
00422 bool
00423 PB_ASSOC_CLASS_C_DEC::
00424 operator()(const Cntnr& r_c) const
00425 {
00426   const stat top_stat =
00427     verify_imp(r_c.node_begin(), r_c.node_end());
00428 
00429   return (top_stat.first);
00430 }
00431 
00432 #undef PB_ASSOC_CLASS_T_DEC
00433 
00434 #undef PB_ASSOC_CLASS_C_DEC
00435 
00436 #endif // #ifndef ORDER_STATISTICS_IMP_HPP