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