Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. // RB tree utilities implementation -*- C++ -*-
  2.  
  3. // Copyright (C) 2003-2013 Free Software Foundation, Inc.
  4. //
  5. // This file is part of the GNU ISO C++ Library.  This library is free
  6. // software; you can redistribute it and/or modify it under the
  7. // terms of the GNU General Public License as published by the
  8. // Free Software Foundation; either version 3, or (at your option)
  9. // any later version.
  10.  
  11. // This library is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. // GNU General Public License for more details.
  15.  
  16. // Under Section 7 of GPL version 3, you are granted additional
  17. // permissions described in the GCC Runtime Library Exception, version
  18. // 3.1, as published by the Free Software Foundation.
  19.  
  20. // You should have received a copy of the GNU General Public License and
  21. // a copy of the GCC Runtime Library Exception along with this program;
  22. // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
  23. // <http://www.gnu.org/licenses/>.
  24.  
  25. /*
  26.  *
  27.  * Copyright (c) 1996,1997
  28.  * Silicon Graphics Computer Systems, Inc.
  29.  *
  30.  * Permission to use, copy, modify, distribute and sell this software
  31.  * and its documentation for any purpose is hereby granted without fee,
  32.  * provided that the above copyright notice appear in all copies and
  33.  * that both that copyright notice and this permission notice appear
  34.  * in supporting documentation.  Silicon Graphics makes no
  35.  * representations about the suitability of this software for any
  36.  * purpose.  It is provided "as is" without express or implied warranty.
  37.  *
  38.  *
  39.  * Copyright (c) 1994
  40.  * Hewlett-Packard Company
  41.  *
  42.  * Permission to use, copy, modify, distribute and sell this software
  43.  * and its documentation for any purpose is hereby granted without fee,
  44.  * provided that the above copyright notice appear in all copies and
  45.  * that both that copyright notice and this permission notice appear
  46.  * in supporting documentation.  Hewlett-Packard Company makes no
  47.  * representations about the suitability of this software for any
  48.  * purpose.  It is provided "as is" without express or implied warranty.
  49.  *
  50.  *
  51.  */
  52.  
  53. #include <bits/stl_tree.h>
  54.  
  55. namespace std _GLIBCXX_VISIBILITY(default)
  56. {
  57. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  58.  
  59.   static _Rb_tree_node_base*
  60.   local_Rb_tree_increment(_Rb_tree_node_base* __x) throw ()
  61.   {
  62.     if (__x->_M_right != 0)
  63.       {
  64.         __x = __x->_M_right;
  65.         while (__x->_M_left != 0)
  66.           __x = __x->_M_left;
  67.       }
  68.     else
  69.       {
  70.         _Rb_tree_node_base* __y = __x->_M_parent;
  71.         while (__x == __y->_M_right)
  72.           {
  73.             __x = __y;
  74.             __y = __y->_M_parent;
  75.           }
  76.         if (__x->_M_right != __y)
  77.           __x = __y;
  78.       }
  79.     return __x;
  80.   }
  81.  
  82.   _Rb_tree_node_base*
  83.   _Rb_tree_increment(_Rb_tree_node_base* __x) throw ()
  84.   {
  85.     return local_Rb_tree_increment(__x);
  86.   }
  87.  
  88.   const _Rb_tree_node_base*
  89.   _Rb_tree_increment(const _Rb_tree_node_base* __x) throw ()
  90.   {
  91.     return local_Rb_tree_increment(const_cast<_Rb_tree_node_base*>(__x));
  92.   }
  93.  
  94.   static _Rb_tree_node_base*
  95.   local_Rb_tree_decrement(_Rb_tree_node_base* __x) throw ()
  96.   {
  97.     if (__x->_M_color == _S_red
  98.         && __x->_M_parent->_M_parent == __x)
  99.       __x = __x->_M_right;
  100.     else if (__x->_M_left != 0)
  101.       {
  102.         _Rb_tree_node_base* __y = __x->_M_left;
  103.         while (__y->_M_right != 0)
  104.           __y = __y->_M_right;
  105.         __x = __y;
  106.       }
  107.     else
  108.       {
  109.         _Rb_tree_node_base* __y = __x->_M_parent;
  110.         while (__x == __y->_M_left)
  111.           {
  112.             __x = __y;
  113.             __y = __y->_M_parent;
  114.           }
  115.         __x = __y;
  116.       }
  117.     return __x;
  118.   }
  119.  
  120.   _Rb_tree_node_base*
  121.   _Rb_tree_decrement(_Rb_tree_node_base* __x) throw ()
  122.   {
  123.     return local_Rb_tree_decrement(__x);
  124.   }
  125.  
  126.   const _Rb_tree_node_base*
  127.   _Rb_tree_decrement(const _Rb_tree_node_base* __x) throw ()
  128.   {
  129.     return local_Rb_tree_decrement(const_cast<_Rb_tree_node_base*>(__x));
  130.   }
  131.  
  132.   static void
  133.   local_Rb_tree_rotate_left(_Rb_tree_node_base* const __x,
  134.                              _Rb_tree_node_base*& __root)
  135.   {
  136.     _Rb_tree_node_base* const __y = __x->_M_right;
  137.  
  138.     __x->_M_right = __y->_M_left;
  139.     if (__y->_M_left !=0)
  140.       __y->_M_left->_M_parent = __x;
  141.     __y->_M_parent = __x->_M_parent;
  142.    
  143.     if (__x == __root)
  144.       __root = __y;
  145.     else if (__x == __x->_M_parent->_M_left)
  146.       __x->_M_parent->_M_left = __y;
  147.     else
  148.       __x->_M_parent->_M_right = __y;
  149.     __y->_M_left = __x;
  150.     __x->_M_parent = __y;
  151.   }
  152.  
  153.   /* Static keyword was missing on _Rb_tree_rotate_left.
  154.      Export the symbol for backward compatibility until
  155.      next ABI change.  */
  156.   void
  157.   _Rb_tree_rotate_left(_Rb_tree_node_base* const __x,
  158.                        _Rb_tree_node_base*& __root)
  159.   {
  160.     local_Rb_tree_rotate_left (__x, __root);
  161.   }
  162.  
  163.   static void
  164.   local_Rb_tree_rotate_right(_Rb_tree_node_base* const __x,
  165.                              _Rb_tree_node_base*& __root)
  166.   {
  167.     _Rb_tree_node_base* const __y = __x->_M_left;
  168.  
  169.     __x->_M_left = __y->_M_right;
  170.     if (__y->_M_right != 0)
  171.       __y->_M_right->_M_parent = __x;
  172.     __y->_M_parent = __x->_M_parent;
  173.  
  174.     if (__x == __root)
  175.       __root = __y;
  176.     else if (__x == __x->_M_parent->_M_right)
  177.       __x->_M_parent->_M_right = __y;
  178.     else
  179.       __x->_M_parent->_M_left = __y;
  180.     __y->_M_right = __x;
  181.     __x->_M_parent = __y;
  182.   }
  183.  
  184.   /* Static keyword was missing on _Rb_tree_rotate_right
  185.      Export the symbol for backward compatibility until
  186.      next ABI change.  */
  187.   void
  188.   _Rb_tree_rotate_right(_Rb_tree_node_base* const __x,
  189.                         _Rb_tree_node_base*& __root)
  190.   {
  191.     local_Rb_tree_rotate_right (__x, __root);
  192.   }
  193.  
  194.   void
  195.   _Rb_tree_insert_and_rebalance(const bool          __insert_left,
  196.                                 _Rb_tree_node_base* __x,
  197.                                 _Rb_tree_node_base* __p,
  198.                                 _Rb_tree_node_base& __header) throw ()
  199.   {
  200.     _Rb_tree_node_base *& __root = __header._M_parent;
  201.  
  202.     // Initialize fields in new node to insert.
  203.     __x->_M_parent = __p;
  204.     __x->_M_left = 0;
  205.     __x->_M_right = 0;
  206.     __x->_M_color = _S_red;
  207.  
  208.     // Insert.
  209.     // Make new node child of parent and maintain root, leftmost and
  210.     // rightmost nodes.
  211.     // N.B. First node is always inserted left.
  212.     if (__insert_left)
  213.       {
  214.         __p->_M_left = __x; // also makes leftmost = __x when __p == &__header
  215.  
  216.         if (__p == &__header)
  217.         {
  218.             __header._M_parent = __x;
  219.             __header._M_right = __x;
  220.         }
  221.         else if (__p == __header._M_left)
  222.           __header._M_left = __x; // maintain leftmost pointing to min node
  223.       }
  224.     else
  225.       {
  226.         __p->_M_right = __x;
  227.  
  228.         if (__p == __header._M_right)
  229.           __header._M_right = __x; // maintain rightmost pointing to max node
  230.       }
  231.     // Rebalance.
  232.     while (__x != __root
  233.            && __x->_M_parent->_M_color == _S_red)
  234.       {
  235.         _Rb_tree_node_base* const __xpp = __x->_M_parent->_M_parent;
  236.  
  237.         if (__x->_M_parent == __xpp->_M_left)
  238.           {
  239.             _Rb_tree_node_base* const __y = __xpp->_M_right;
  240.             if (__y && __y->_M_color == _S_red)
  241.               {
  242.                 __x->_M_parent->_M_color = _S_black;
  243.                 __y->_M_color = _S_black;
  244.                 __xpp->_M_color = _S_red;
  245.                 __x = __xpp;
  246.               }
  247.             else
  248.               {
  249.                 if (__x == __x->_M_parent->_M_right)
  250.                   {
  251.                     __x = __x->_M_parent;
  252.                     local_Rb_tree_rotate_left(__x, __root);
  253.                   }
  254.                 __x->_M_parent->_M_color = _S_black;
  255.                 __xpp->_M_color = _S_red;
  256.                 local_Rb_tree_rotate_right(__xpp, __root);
  257.               }
  258.           }
  259.         else
  260.           {
  261.             _Rb_tree_node_base* const __y = __xpp->_M_left;
  262.             if (__y && __y->_M_color == _S_red)
  263.               {
  264.                 __x->_M_parent->_M_color = _S_black;
  265.                 __y->_M_color = _S_black;
  266.                 __xpp->_M_color = _S_red;
  267.                 __x = __xpp;
  268.               }
  269.             else
  270.               {
  271.                 if (__x == __x->_M_parent->_M_left)
  272.                   {
  273.                     __x = __x->_M_parent;
  274.                     local_Rb_tree_rotate_right(__x, __root);
  275.                   }
  276.                 __x->_M_parent->_M_color = _S_black;
  277.                 __xpp->_M_color = _S_red;
  278.                 local_Rb_tree_rotate_left(__xpp, __root);
  279.               }
  280.           }
  281.       }
  282.     __root->_M_color = _S_black;
  283.   }
  284.  
  285.   _Rb_tree_node_base*
  286.   _Rb_tree_rebalance_for_erase(_Rb_tree_node_base* const __z,
  287.                                _Rb_tree_node_base& __header) throw ()
  288.   {
  289.     _Rb_tree_node_base *& __root = __header._M_parent;
  290.     _Rb_tree_node_base *& __leftmost = __header._M_left;
  291.     _Rb_tree_node_base *& __rightmost = __header._M_right;
  292.     _Rb_tree_node_base* __y = __z;
  293.     _Rb_tree_node_base* __x = 0;
  294.     _Rb_tree_node_base* __x_parent = 0;
  295.  
  296.     if (__y->_M_left == 0)     // __z has at most one non-null child. y == z.
  297.       __x = __y->_M_right;     // __x might be null.
  298.     else
  299.       if (__y->_M_right == 0)  // __z has exactly one non-null child. y == z.
  300.         __x = __y->_M_left;    // __x is not null.
  301.       else
  302.         {
  303.           // __z has two non-null children.  Set __y to
  304.           __y = __y->_M_right;   //   __z's successor.  __x might be null.
  305.           while (__y->_M_left != 0)
  306.             __y = __y->_M_left;
  307.           __x = __y->_M_right;
  308.         }
  309.     if (__y != __z)
  310.       {
  311.         // relink y in place of z.  y is z's successor
  312.         __z->_M_left->_M_parent = __y;
  313.         __y->_M_left = __z->_M_left;
  314.         if (__y != __z->_M_right)
  315.           {
  316.             __x_parent = __y->_M_parent;
  317.             if (__x) __x->_M_parent = __y->_M_parent;
  318.             __y->_M_parent->_M_left = __x;   // __y must be a child of _M_left
  319.             __y->_M_right = __z->_M_right;
  320.             __z->_M_right->_M_parent = __y;
  321.           }
  322.         else
  323.           __x_parent = __y;  
  324.         if (__root == __z)
  325.           __root = __y;
  326.         else if (__z->_M_parent->_M_left == __z)
  327.           __z->_M_parent->_M_left = __y;
  328.         else
  329.           __z->_M_parent->_M_right = __y;
  330.         __y->_M_parent = __z->_M_parent;
  331.         std::swap(__y->_M_color, __z->_M_color);
  332.         __y = __z;
  333.         // __y now points to node to be actually deleted
  334.       }
  335.     else
  336.       {                        // __y == __z
  337.         __x_parent = __y->_M_parent;
  338.         if (__x)
  339.           __x->_M_parent = __y->_M_parent;  
  340.         if (__root == __z)
  341.           __root = __x;
  342.         else
  343.           if (__z->_M_parent->_M_left == __z)
  344.             __z->_M_parent->_M_left = __x;
  345.           else
  346.             __z->_M_parent->_M_right = __x;
  347.         if (__leftmost == __z)
  348.           {
  349.             if (__z->_M_right == 0)        // __z->_M_left must be null also
  350.               __leftmost = __z->_M_parent;
  351.             // makes __leftmost == _M_header if __z == __root
  352.             else
  353.               __leftmost = _Rb_tree_node_base::_S_minimum(__x);
  354.           }
  355.         if (__rightmost == __z)  
  356.           {
  357.             if (__z->_M_left == 0)         // __z->_M_right must be null also
  358.               __rightmost = __z->_M_parent;  
  359.             // makes __rightmost == _M_header if __z == __root
  360.             else                      // __x == __z->_M_left
  361.               __rightmost = _Rb_tree_node_base::_S_maximum(__x);
  362.           }
  363.       }
  364.     if (__y->_M_color != _S_red)
  365.       {
  366.         while (__x != __root && (__x == 0 || __x->_M_color == _S_black))
  367.           if (__x == __x_parent->_M_left)
  368.             {
  369.               _Rb_tree_node_base* __w = __x_parent->_M_right;
  370.               if (__w->_M_color == _S_red)
  371.                 {
  372.                   __w->_M_color = _S_black;
  373.                   __x_parent->_M_color = _S_red;
  374.                   local_Rb_tree_rotate_left(__x_parent, __root);
  375.                   __w = __x_parent->_M_right;
  376.                 }
  377.               if ((__w->_M_left == 0 ||
  378.                    __w->_M_left->_M_color == _S_black) &&
  379.                   (__w->_M_right == 0 ||
  380.                    __w->_M_right->_M_color == _S_black))
  381.                 {
  382.                   __w->_M_color = _S_red;
  383.                   __x = __x_parent;
  384.                   __x_parent = __x_parent->_M_parent;
  385.                 }
  386.               else
  387.                 {
  388.                   if (__w->_M_right == 0
  389.                       || __w->_M_right->_M_color == _S_black)
  390.                     {
  391.                       __w->_M_left->_M_color = _S_black;
  392.                       __w->_M_color = _S_red;
  393.                       local_Rb_tree_rotate_right(__w, __root);
  394.                       __w = __x_parent->_M_right;
  395.                     }
  396.                   __w->_M_color = __x_parent->_M_color;
  397.                   __x_parent->_M_color = _S_black;
  398.                   if (__w->_M_right)
  399.                     __w->_M_right->_M_color = _S_black;
  400.                   local_Rb_tree_rotate_left(__x_parent, __root);
  401.                   break;
  402.                 }
  403.             }
  404.           else
  405.             {  
  406.               // same as above, with _M_right <-> _M_left.
  407.               _Rb_tree_node_base* __w = __x_parent->_M_left;
  408.               if (__w->_M_color == _S_red)
  409.                 {
  410.                   __w->_M_color = _S_black;
  411.                   __x_parent->_M_color = _S_red;
  412.                   local_Rb_tree_rotate_right(__x_parent, __root);
  413.                   __w = __x_parent->_M_left;
  414.                 }
  415.               if ((__w->_M_right == 0 ||
  416.                    __w->_M_right->_M_color == _S_black) &&
  417.                   (__w->_M_left == 0 ||
  418.                    __w->_M_left->_M_color == _S_black))
  419.                 {
  420.                   __w->_M_color = _S_red;
  421.                   __x = __x_parent;
  422.                   __x_parent = __x_parent->_M_parent;
  423.                 }
  424.               else
  425.                 {
  426.                   if (__w->_M_left == 0 || __w->_M_left->_M_color == _S_black)
  427.                     {
  428.                       __w->_M_right->_M_color = _S_black;
  429.                       __w->_M_color = _S_red;
  430.                       local_Rb_tree_rotate_left(__w, __root);
  431.                       __w = __x_parent->_M_left;
  432.                     }
  433.                   __w->_M_color = __x_parent->_M_color;
  434.                   __x_parent->_M_color = _S_black;
  435.                   if (__w->_M_left)
  436.                     __w->_M_left->_M_color = _S_black;
  437.                   local_Rb_tree_rotate_right(__x_parent, __root);
  438.                   break;
  439.                 }
  440.             }
  441.         if (__x) __x->_M_color = _S_black;
  442.       }
  443.     return __y;
  444.   }
  445.  
  446.   unsigned int
  447.   _Rb_tree_black_count(const _Rb_tree_node_base* __node,
  448.                        const _Rb_tree_node_base* __root) throw ()
  449.   {
  450.     if (__node == 0)
  451.       return 0;
  452.     unsigned int __sum = 0;
  453.     do
  454.       {
  455.         if (__node->_M_color == _S_black)
  456.           ++__sum;
  457.         if (__node == __root)
  458.           break;
  459.         __node = __node->_M_parent;
  460.       }
  461.     while (1);
  462.     return __sum;
  463.   }
  464.  
  465. _GLIBCXX_END_NAMESPACE_VERSION
  466. } // namespace
  467.