File indexing completed on 2025-01-30 09:44:16
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef BOOST_INTRUSIVE_AVLTREE_ALGORITHMS_HPP
0015 #define BOOST_INTRUSIVE_AVLTREE_ALGORITHMS_HPP
0016
0017 #include <boost/intrusive/detail/config_begin.hpp>
0018 #include <boost/intrusive/intrusive_fwd.hpp>
0019
0020 #include <cstddef>
0021
0022 #include <boost/intrusive/detail/assert.hpp>
0023 #include <boost/intrusive/detail/algo_type.hpp>
0024 #include <boost/intrusive/detail/ebo_functor_holder.hpp>
0025 #include <boost/intrusive/bstree_algorithms.hpp>
0026
0027 #if defined(BOOST_HAS_PRAGMA_ONCE)
0028 # pragma once
0029 #endif
0030
0031
0032 namespace boost {
0033 namespace intrusive {
0034
0035
0036
0037 template<class NodeTraits, class F>
0038 struct avltree_node_cloner
0039
0040 : public detail::ebo_functor_holder<F>
0041 {
0042 typedef typename NodeTraits::node_ptr node_ptr;
0043 typedef detail::ebo_functor_holder<F> base_t;
0044
0045 BOOST_INTRUSIVE_FORCEINLINE avltree_node_cloner(F f)
0046 : base_t(f)
0047 {}
0048
0049 node_ptr operator()(node_ptr p)
0050 {
0051 node_ptr n = base_t::get()(p);
0052 NodeTraits::set_balance(n, NodeTraits::get_balance(p));
0053 return n;
0054 }
0055
0056 node_ptr operator()(node_ptr p) const
0057 {
0058 node_ptr n = base_t::get()(p);
0059 NodeTraits::set_balance(n, NodeTraits::get_balance(p));
0060 return n;
0061 }
0062 };
0063
0064 namespace detail {
0065
0066 template<class ValueTraits, class NodePtrCompare, class ExtraChecker>
0067 struct avltree_node_checker
0068 : public bstree_node_checker<ValueTraits, NodePtrCompare, ExtraChecker>
0069 {
0070 typedef bstree_node_checker<ValueTraits, NodePtrCompare, ExtraChecker> base_checker_t;
0071 typedef ValueTraits value_traits;
0072 typedef typename value_traits::node_traits node_traits;
0073 typedef typename node_traits::const_node_ptr const_node_ptr;
0074
0075 struct return_type
0076 : public base_checker_t::return_type
0077 {
0078 return_type() : height(0) {}
0079 int height;
0080 };
0081
0082 avltree_node_checker(const NodePtrCompare& comp, ExtraChecker extra_checker)
0083 : base_checker_t(comp, extra_checker)
0084 {}
0085
0086 void operator () (const_node_ptr p,
0087 const return_type& check_return_left, const return_type& check_return_right,
0088 return_type& check_return)
0089 {
0090 const int height_diff = check_return_right.height - check_return_left.height; (void)height_diff;
0091 BOOST_INTRUSIVE_INVARIANT_ASSERT(
0092 (height_diff == -1 && node_traits::get_balance(p) == node_traits::negative()) ||
0093 (height_diff == 0 && node_traits::get_balance(p) == node_traits::zero()) ||
0094 (height_diff == 1 && node_traits::get_balance(p) == node_traits::positive())
0095 );
0096 check_return.height = 1 +
0097 (check_return_left.height > check_return_right.height ? check_return_left.height : check_return_right.height);
0098 base_checker_t::operator()(p, check_return_left, check_return_right, check_return);
0099 }
0100 };
0101
0102 }
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143 template<class NodeTraits>
0144 class avltree_algorithms
0145 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0146 : public bstree_algorithms<NodeTraits>
0147 #endif
0148 {
0149 public:
0150 typedef typename NodeTraits::node node;
0151 typedef NodeTraits node_traits;
0152 typedef typename NodeTraits::node_ptr node_ptr;
0153 typedef typename NodeTraits::const_node_ptr const_node_ptr;
0154 typedef typename NodeTraits::balance balance;
0155
0156
0157 private:
0158 typedef bstree_algorithms<NodeTraits> bstree_algo;
0159
0160
0161
0162 public:
0163
0164
0165 typedef typename bstree_algo::insert_commit_data insert_commit_data;
0166
0167 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0168
0169
0170 static node_ptr get_header(const_node_ptr n) BOOST_NOEXCEPT;
0171
0172
0173 static node_ptr begin_node(const_node_ptr header) BOOST_NOEXCEPT;
0174
0175
0176 static node_ptr end_node(const_node_ptr header) BOOST_NOEXCEPT;
0177
0178
0179 static void swap_tree(node_ptr header1, node_ptr header2) BOOST_NOEXCEPT;
0180
0181 #endif
0182
0183
0184 static void swap_nodes(node_ptr node1, node_ptr node2) BOOST_NOEXCEPT
0185 {
0186 if(node1 == node2)
0187 return;
0188
0189 node_ptr header1(bstree_algo::get_header(node1)), header2(bstree_algo::get_header(node2));
0190 swap_nodes(node1, header1, node2, header2);
0191 }
0192
0193
0194 static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2) BOOST_NOEXCEPT
0195 {
0196 if(node1 == node2) return;
0197
0198 bstree_algo::swap_nodes(node1, header1, node2, header2);
0199
0200 balance c = NodeTraits::get_balance(node1);
0201 NodeTraits::set_balance(node1, NodeTraits::get_balance(node2));
0202 NodeTraits::set_balance(node2, c);
0203 }
0204
0205
0206 static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node) BOOST_NOEXCEPT
0207 {
0208 if(node_to_be_replaced == new_node)
0209 return;
0210 replace_node(node_to_be_replaced, bstree_algo::get_header(node_to_be_replaced), new_node);
0211 }
0212
0213
0214 static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node) BOOST_NOEXCEPT
0215 {
0216 bstree_algo::replace_node(node_to_be_replaced, header, new_node);
0217 NodeTraits::set_balance(new_node, NodeTraits::get_balance(node_to_be_replaced));
0218 }
0219
0220
0221 static void unlink(node_ptr n) BOOST_NOEXCEPT
0222 {
0223 node_ptr x = NodeTraits::get_parent(n);
0224 if(x){
0225 while(!is_header(x))
0226 x = NodeTraits::get_parent(x);
0227 erase(x, n);
0228 }
0229 }
0230
0231 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0232
0233 static node_ptr unlink_leftmost_without_rebalance(node_ptr header) BOOST_NOEXCEPT;
0234
0235
0236 static bool unique(const_node_ptr n) BOOST_NOEXCEPT;
0237
0238
0239 static std::size_t size(const_node_ptr header) BOOST_NOEXCEPT;
0240
0241
0242 static node_ptr next_node(node_ptr n) BOOST_NOEXCEPT;
0243
0244
0245 static node_ptr prev_node(node_ptr n) BOOST_NOEXCEPT;
0246
0247
0248 static void init(node_ptr n) BOOST_NOEXCEPT;
0249 #endif
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261 static void init_header(node_ptr header) BOOST_NOEXCEPT
0262 {
0263 bstree_algo::init_header(header);
0264 NodeTraits::set_balance(header, NodeTraits::zero());
0265 }
0266
0267
0268 static node_ptr erase(node_ptr header, node_ptr z) BOOST_NOEXCEPT
0269 {
0270 typename bstree_algo::data_for_rebalance info;
0271 bstree_algo::erase(header, z, info);
0272 rebalance_after_erasure(header, z, info);
0273 return z;
0274 }
0275
0276
0277 template<class NodePtrCompare>
0278 static bool transfer_unique
0279 (node_ptr header1, NodePtrCompare comp, node_ptr header2, node_ptr z)
0280 {
0281 typename bstree_algo::data_for_rebalance info;
0282 bool const transferred = bstree_algo::transfer_unique(header1, comp, header2, z, info);
0283 if(transferred){
0284 rebalance_after_erasure(header2, z, info);
0285 rebalance_after_insertion(header1, z);
0286 }
0287 return transferred;
0288 }
0289
0290
0291 template<class NodePtrCompare>
0292 static void transfer_equal
0293 (node_ptr header1, NodePtrCompare comp, node_ptr header2, node_ptr z)
0294 {
0295 typename bstree_algo::data_for_rebalance info;
0296 bstree_algo::transfer_equal(header1, comp, header2, z, info);
0297 rebalance_after_erasure(header2, z, info);
0298 rebalance_after_insertion(header1, z);
0299 }
0300
0301
0302 template <class Cloner, class Disposer>
0303 static void clone
0304 (const_node_ptr source_header, node_ptr target_header, Cloner cloner, Disposer disposer)
0305 {
0306 avltree_node_cloner<NodeTraits, Cloner> new_cloner(cloner);
0307 bstree_algo::clone(source_header, target_header, new_cloner, disposer);
0308 }
0309
0310 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0311
0312 template<class Disposer>
0313 static void clear_and_dispose(node_ptr header, Disposer disposer) BOOST_NOEXCEPT;
0314
0315
0316 template<class KeyType, class KeyNodePtrCompare>
0317 static node_ptr lower_bound
0318 (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
0319
0320
0321 template<class KeyType, class KeyNodePtrCompare>
0322 static node_ptr upper_bound
0323 (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
0324
0325
0326 template<class KeyType, class KeyNodePtrCompare>
0327 static node_ptr find
0328 (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
0329
0330
0331 template<class KeyType, class KeyNodePtrCompare>
0332 static std::pair<node_ptr, node_ptr> equal_range
0333 (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
0334
0335
0336 template<class KeyType, class KeyNodePtrCompare>
0337 static std::pair<node_ptr, node_ptr> bounded_range
0338 (const_node_ptr header, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp
0339 , bool left_closed, bool right_closed);
0340
0341
0342 template<class KeyType, class KeyNodePtrCompare>
0343 static std::size_t count(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
0344
0345 #endif
0346
0347
0348 template<class NodePtrCompare>
0349 static node_ptr insert_equal_upper_bound
0350 (node_ptr h, node_ptr new_node, NodePtrCompare comp)
0351 {
0352 bstree_algo::insert_equal_upper_bound(h, new_node, comp);
0353 rebalance_after_insertion(h, new_node);
0354 return new_node;
0355 }
0356
0357
0358 template<class NodePtrCompare>
0359 static node_ptr insert_equal_lower_bound
0360 (node_ptr h, node_ptr new_node, NodePtrCompare comp)
0361 {
0362 bstree_algo::insert_equal_lower_bound(h, new_node, comp);
0363 rebalance_after_insertion(h, new_node);
0364 return new_node;
0365 }
0366
0367
0368 template<class NodePtrCompare>
0369 static node_ptr insert_equal
0370 (node_ptr header, node_ptr hint, node_ptr new_node, NodePtrCompare comp)
0371 {
0372 bstree_algo::insert_equal(header, hint, new_node, comp);
0373 rebalance_after_insertion(header, new_node);
0374 return new_node;
0375 }
0376
0377
0378 static node_ptr insert_before
0379 (node_ptr header, node_ptr pos, node_ptr new_node) BOOST_NOEXCEPT
0380 {
0381 bstree_algo::insert_before(header, pos, new_node);
0382 rebalance_after_insertion(header, new_node);
0383 return new_node;
0384 }
0385
0386
0387 static void push_back(node_ptr header, node_ptr new_node) BOOST_NOEXCEPT
0388 {
0389 bstree_algo::push_back(header, new_node);
0390 rebalance_after_insertion(header, new_node);
0391 }
0392
0393
0394 static void push_front(node_ptr header, node_ptr new_node) BOOST_NOEXCEPT
0395 {
0396 bstree_algo::push_front(header, new_node);
0397 rebalance_after_insertion(header, new_node);
0398 }
0399
0400 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0401
0402 template<class KeyType, class KeyNodePtrCompare>
0403 static std::pair<node_ptr, bool> insert_unique_check
0404 (const_node_ptr header, const KeyType &key
0405 ,KeyNodePtrCompare comp, insert_commit_data &commit_data);
0406
0407
0408 template<class KeyType, class KeyNodePtrCompare>
0409 static std::pair<node_ptr, bool> insert_unique_check
0410 (const_node_ptr header, node_ptr hint, const KeyType &key
0411 ,KeyNodePtrCompare comp, insert_commit_data &commit_data);
0412 #endif
0413
0414
0415 static void insert_unique_commit
0416 (node_ptr header, node_ptr new_value, const insert_commit_data &commit_data) BOOST_NOEXCEPT
0417 {
0418 bstree_algo::insert_unique_commit(header, new_value, commit_data);
0419 rebalance_after_insertion(header, new_value);
0420 }
0421
0422
0423 static bool is_header(const_node_ptr p) BOOST_NOEXCEPT
0424 { return NodeTraits::get_balance(p) == NodeTraits::zero() && bstree_algo::is_header(p); }
0425
0426
0427
0428 static bool verify(node_ptr header)
0429 {
0430 std::size_t height;
0431 std::size_t count;
0432 return verify_recursion(NodeTraits::get_parent(header), count, height);
0433 }
0434
0435 private:
0436
0437 static bool verify_recursion(node_ptr n, std::size_t &count, std::size_t &height)
0438 {
0439 if (!n){
0440 count = 0;
0441 height = 0;
0442 return true;
0443 }
0444 std::size_t leftcount, rightcount;
0445 std::size_t leftheight, rightheight;
0446 if(!verify_recursion(NodeTraits::get_left (n), leftcount, leftheight) ||
0447 !verify_recursion(NodeTraits::get_right(n), rightcount, rightheight) ){
0448 return false;
0449 }
0450 count = 1u + leftcount + rightcount;
0451 height = 1u + (leftheight > rightheight ? leftheight : rightheight);
0452
0453
0454 if(rightheight == leftheight){
0455 if(NodeTraits::get_balance(n) != NodeTraits::zero()){
0456 BOOST_ASSERT(0);
0457 return false;
0458 }
0459 }
0460
0461 else if(rightheight > leftheight){
0462 if(rightheight - leftheight > 1 ){
0463 BOOST_ASSERT(0);
0464 return false;
0465 }
0466 else if(NodeTraits::get_balance(n) != NodeTraits::positive()){
0467 BOOST_ASSERT(0);
0468 return false;
0469 }
0470 }
0471
0472 else{
0473 if(leftheight - rightheight > 1 ){
0474 BOOST_ASSERT(0);
0475 return false;
0476 }
0477 else if(NodeTraits::get_balance(n) != NodeTraits::negative()){
0478 BOOST_ASSERT(0);
0479 return false;
0480 }
0481 }
0482 return true;
0483 }
0484
0485 static void rebalance_after_erasure
0486 ( node_ptr header, node_ptr z, const typename bstree_algo::data_for_rebalance &info) BOOST_NOEXCEPT
0487 {
0488 if(info.y != z){
0489 NodeTraits::set_balance(info.y, NodeTraits::get_balance(z));
0490 }
0491
0492 rebalance_after_erasure_restore_invariants(header, info.x, info.x_parent);
0493 }
0494
0495 static void rebalance_after_erasure_restore_invariants(node_ptr header, node_ptr x, node_ptr x_parent) BOOST_NOEXCEPT
0496 {
0497 for ( node_ptr root = NodeTraits::get_parent(header)
0498 ; x != root
0499 ; root = NodeTraits::get_parent(header), x_parent = NodeTraits::get_parent(x)) {
0500 const balance x_parent_balance = NodeTraits::get_balance(x_parent);
0501
0502
0503 const node_ptr x_parent_left (NodeTraits::get_left(x_parent));
0504 const node_ptr x_parent_right(NodeTraits::get_right(x_parent));
0505
0506 if(x_parent_balance == NodeTraits::zero()){
0507 NodeTraits::set_balance( x_parent, x == x_parent_right ? NodeTraits::negative() : NodeTraits::positive() );
0508 break;
0509 }
0510 else if(x_parent_balance == NodeTraits::negative()){
0511 if (x == x_parent_left) {
0512 NodeTraits::set_balance(x_parent, NodeTraits::zero());
0513 x = x_parent;
0514 }
0515 else {
0516
0517 BOOST_INTRUSIVE_INVARIANT_ASSERT(x_parent_left);
0518 if (NodeTraits::get_balance(x_parent_left) == NodeTraits::positive()) {
0519
0520 BOOST_INTRUSIVE_INVARIANT_ASSERT(NodeTraits::get_right(x_parent_left));
0521 x = avl_rotate_left_right(x_parent, x_parent_left, header);
0522 }
0523 else {
0524 avl_rotate_right(x_parent, x_parent_left, header);
0525 x = x_parent_left;
0526 }
0527
0528
0529 if (NodeTraits::get_balance(x) == NodeTraits::positive()){
0530 break;
0531 }
0532 }
0533 }
0534 else if(x_parent_balance == NodeTraits::positive()){
0535 if (x == x_parent_right) {
0536 NodeTraits::set_balance(x_parent, NodeTraits::zero());
0537 x = x_parent;
0538 }
0539 else {
0540
0541 BOOST_INTRUSIVE_INVARIANT_ASSERT(x_parent_right);
0542 if (NodeTraits::get_balance(x_parent_right) == NodeTraits::negative()) {
0543
0544 BOOST_INTRUSIVE_INVARIANT_ASSERT(NodeTraits::get_left(x_parent_right));
0545 x = avl_rotate_right_left(x_parent, x_parent_right, header);
0546 }
0547 else {
0548 avl_rotate_left(x_parent, x_parent_right, header);
0549 x = x_parent_right;
0550 }
0551
0552 if (NodeTraits::get_balance(x) == NodeTraits::negative()){
0553 break;
0554 }
0555 }
0556 }
0557 else{
0558 BOOST_INTRUSIVE_INVARIANT_ASSERT(false);
0559 }
0560 }
0561 }
0562
0563 static void rebalance_after_insertion(node_ptr header, node_ptr x) BOOST_NOEXCEPT
0564 {
0565 NodeTraits::set_balance(x, NodeTraits::zero());
0566
0567 for(node_ptr root = NodeTraits::get_parent(header); x != root; root = NodeTraits::get_parent(header)){
0568 node_ptr const x_parent(NodeTraits::get_parent(x));
0569 node_ptr const x_parent_left(NodeTraits::get_left(x_parent));
0570 const balance x_parent_balance = NodeTraits::get_balance(x_parent);
0571 const bool x_is_leftchild(x == x_parent_left);
0572 if(x_parent_balance == NodeTraits::zero()){
0573
0574
0575 NodeTraits::set_balance( x_parent, x_is_leftchild ? NodeTraits::negative() : NodeTraits::positive() );
0576 x = x_parent;
0577 }
0578 else if(x_parent_balance == NodeTraits::positive()){
0579
0580 if (x_is_leftchild)
0581 NodeTraits::set_balance(x_parent, NodeTraits::zero());
0582 else{
0583 if (NodeTraits::get_balance(x) == NodeTraits::negative())
0584 avl_rotate_right_left(x_parent, x, header);
0585 else
0586 avl_rotate_left(x_parent, x, header);
0587 }
0588 break;
0589 }
0590 else if(x_parent_balance == NodeTraits::negative()){
0591
0592 if (x_is_leftchild) {
0593 if (NodeTraits::get_balance(x) == NodeTraits::positive())
0594 avl_rotate_left_right(x_parent, x, header);
0595 else
0596 avl_rotate_right(x_parent, x, header);
0597 }
0598 else
0599 NodeTraits::set_balance(x_parent, NodeTraits::zero());
0600 break;
0601 }
0602 else{
0603 BOOST_INTRUSIVE_INVARIANT_ASSERT(false);
0604 }
0605 }
0606 }
0607
0608 static void left_right_balancing(node_ptr a, node_ptr b, node_ptr c) BOOST_NOEXCEPT
0609 {
0610
0611 const balance c_balance = NodeTraits::get_balance(c);
0612 const balance zero_balance = NodeTraits::zero();
0613 const balance posi_balance = NodeTraits::positive();
0614 const balance nega_balance = NodeTraits::negative();
0615 NodeTraits::set_balance(c, zero_balance);
0616 if(c_balance == nega_balance){
0617 NodeTraits::set_balance(a, posi_balance);
0618 NodeTraits::set_balance(b, zero_balance);
0619 }
0620 else if(c_balance == zero_balance){
0621 NodeTraits::set_balance(a, zero_balance);
0622 NodeTraits::set_balance(b, zero_balance);
0623 }
0624 else if(c_balance == posi_balance){
0625 NodeTraits::set_balance(a, zero_balance);
0626 NodeTraits::set_balance(b, nega_balance);
0627 }
0628 else{
0629 BOOST_INTRUSIVE_INVARIANT_ASSERT(false);
0630 }
0631 }
0632
0633 static node_ptr avl_rotate_left_right(const node_ptr a, const node_ptr a_oldleft, node_ptr hdr) BOOST_NOEXCEPT
0634 {
0635
0636
0637
0638
0639
0640
0641
0642
0643
0644 const node_ptr c = NodeTraits::get_right(a_oldleft);
0645 bstree_algo::rotate_left_no_parent_fix(a_oldleft, c);
0646
0647
0648 bstree_algo::rotate_right(a, c, NodeTraits::get_parent(a), hdr);
0649 left_right_balancing(a, a_oldleft, c);
0650 return c;
0651 }
0652
0653 static node_ptr avl_rotate_right_left(const node_ptr a, const node_ptr a_oldright, node_ptr hdr) BOOST_NOEXCEPT
0654 {
0655
0656
0657
0658
0659
0660
0661
0662
0663
0664 const node_ptr c (NodeTraits::get_left(a_oldright));
0665 bstree_algo::rotate_right_no_parent_fix(a_oldright, c);
0666
0667
0668 bstree_algo::rotate_left(a, c, NodeTraits::get_parent(a), hdr);
0669 left_right_balancing(a_oldright, a, c);
0670 return c;
0671 }
0672
0673 static void avl_rotate_left(node_ptr x, node_ptr x_oldright, node_ptr hdr) BOOST_NOEXCEPT
0674 {
0675 bstree_algo::rotate_left(x, x_oldright, NodeTraits::get_parent(x), hdr);
0676
0677
0678 if (NodeTraits::get_balance(x_oldright) == NodeTraits::positive()) {
0679 NodeTraits::set_balance(x, NodeTraits::zero());
0680 NodeTraits::set_balance(x_oldright, NodeTraits::zero());
0681 }
0682 else {
0683 NodeTraits::set_balance(x, NodeTraits::positive());
0684 NodeTraits::set_balance(x_oldright, NodeTraits::negative());
0685 }
0686 }
0687
0688 static void avl_rotate_right(node_ptr x, node_ptr x_oldleft, node_ptr hdr) BOOST_NOEXCEPT
0689 {
0690 bstree_algo::rotate_right(x, x_oldleft, NodeTraits::get_parent(x), hdr);
0691
0692
0693 if (NodeTraits::get_balance(x_oldleft) == NodeTraits::negative()) {
0694 NodeTraits::set_balance(x, NodeTraits::zero());
0695 NodeTraits::set_balance(x_oldleft, NodeTraits::zero());
0696 }
0697 else {
0698 NodeTraits::set_balance(x, NodeTraits::negative());
0699 NodeTraits::set_balance(x_oldleft, NodeTraits::positive());
0700 }
0701 }
0702
0703
0704 };
0705
0706
0707
0708 template<class NodeTraits>
0709 struct get_algo<AvlTreeAlgorithms, NodeTraits>
0710 {
0711 typedef avltree_algorithms<NodeTraits> type;
0712 };
0713
0714 template <class ValueTraits, class NodePtrCompare, class ExtraChecker>
0715 struct get_node_checker<AvlTreeAlgorithms, ValueTraits, NodePtrCompare, ExtraChecker>
0716 {
0717 typedef detail::avltree_node_checker<ValueTraits, NodePtrCompare, ExtraChecker> type;
0718 };
0719
0720
0721
0722 }
0723 }
0724
0725 #include <boost/intrusive/detail/config_end.hpp>
0726
0727 #endif