BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Multiset.h
Go to the documentation of this file.
00001 // Copyright (c) 2005  Tel-Aviv University (Israel).  All rights reserved.
00002 //
00003 // This file is part of CGAL (www.cgal.org); you can redistribute it and/or
00004 // modify it under the terms of the GNU Lesser General Public License as
00005 // published by the Free Software Foundation; version 2.1 of the License.
00006 // See the file LICENSE.LGPL distributed with CGAL.
00007 //
00008 // Licensees holding a valid commercial license may use this file in
00009 // accordance with the commercial license agreement provided with the software.
00010 //
00011 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00012 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00013 //
00014 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/STL_Extension/include/CGAL/Multiset.h $
00015 // $Id: Multiset.h 41420 2008-01-03 15:04:30Z spion $
00016 // 
00017 //
00018 // Author(s)     : Ron Wein <wein@post.tau.ac.il>
00019 
00020 #ifndef CGAL_MULTISET_H
00021 #define CGAL_MULTISET_H
00022 
00023 #include <CGAL/config.h>
00024 #include <CGAL/assertions.h>
00025 #include <CGAL/multiset_assertions.h>
00026 #include <CGAL/enum.h>
00027 #include <CGAL/memory.h>
00028 #include <iterator>
00029 
00030 CGAL_BEGIN_NAMESPACE
00031 
00058 template <typename Type_, 
00059           class Compare_ = CGAL::Compare<Type_>,
00060           class Allocator_ = CGAL_ALLOCATOR(int)>
00061 class Multiset
00062 {
00063 public:
00064 
00065   // General type definitions:
00066   typedef Type_                                     Type;
00067   typedef Compare_                                  Compare;
00068   typedef Allocator_                                Allocator;
00069   typedef Multiset<Type, Compare, Allocator>        Self;
00070   
00071   // Type definitions for STL compatibility.
00072   typedef Type                                      value_type;
00073   typedef Type                                      key_type;
00074   typedef value_type&                               reference;
00075   typedef const value_type&                         const_reference;
00076   typedef Compare                                   key_compare;
00077   typedef Compare                                   value_compare;
00078   typedef size_t                                    size_type;
00079   typedef std::ptrdiff_t                  difference_type;
00080 
00081 protected:
00082 
00086   struct Node
00087   {
00088 
00089     enum Color
00090     {
00091       RED,                        // Regular red node in the tree.
00092       BLACK,                      // Regular black node in the tree.
00093       DUMMY_BEGIN,                // The dummy before-the-begin tree node.
00094       DUMMY_END                   // The dummy past-the-end tree node.
00095     };
00096 
00097     typedef char Node_color;
00098 
00099     Type         object;           // The stored object.
00100     Node_color   color;            // The color of the node.
00101     Node        *parentP;          // Points on the parent node.
00102     Node        *rightP;           // Points on the right child of the node.
00103     Node        *leftP;            // Points on the left child of the node.
00104 
00106     Node() :
00107       parentP(NULL),
00108       rightP(NULL),
00109       leftP(NULL)
00110     {}
00111 
00117     Node (const Type& _object,  Node_color _color) :
00118       object(_object),
00119       color(_color),
00120       parentP(NULL),
00121       rightP(NULL),
00122       leftP(NULL)
00123     {}
00124 
00130     void init (const Type& _object, Node_color _color)
00131     {
00132       object = _object;
00133       color = _color;
00134     }
00135 
00137     ~Node ()
00138     {}
00139 
00143     inline bool is_valid () const
00144     {
00145       return (color == BLACK || color == RED);
00146     }
00147 
00151     inline bool is_red () const
00152     {
00153       return (color == RED);
00154     }
00155 
00160     inline bool is_black () const
00161     {
00162       return (color != RED);
00163     }
00164 
00168     Node* predecessor () const
00169     {
00170       // The DUMMY_BEGIN node has no predecessor.
00171       CGAL_multiset_assertion (color != DUMMY_BEGIN);
00172 
00173       Node        *predP;
00174 
00175       if (leftP != NULL)
00176       {
00177         // If there is a left child, the predecessor is the maximal object in
00178         // the sub-tree spanned by this child.
00179         predP = leftP;
00180         while (predP->rightP != NULL)
00181           predP = predP->rightP;
00182       }
00183       else
00184       {
00185         // Otherwise, go up the tree until reaching the parent from the right
00186         // direction (this also covers the case of the DUMMY_END node).
00187         const Node    *prevP = this;
00188 
00189         predP = parentP;
00190         while (predP != NULL && prevP == predP->leftP)
00191         {
00192           prevP = predP;
00193           predP = predP->parentP;
00194         }
00195       }
00196 
00197       return (predP);
00198     }
00199 
00203     Node* successor () const
00204     {
00205       // The DUMMY_END node has no successor.
00206       CGAL_multiset_assertion (color != DUMMY_END);
00207 
00208       Node        *succP;
00209 
00210       if (rightP != NULL)
00211       {
00212         // If there is a right child, the successor is the minimal object in
00213         // the sub-tree spanned by this child.
00214         succP = rightP;
00215         while (succP->leftP != NULL)
00216           succP = succP->leftP;
00217       }
00218       else
00219       {
00220         // Otherwise, go up the tree until reaching the parent from the left
00221         // direction (this also covers the case of the DUMMY_BEGIN node).
00222         const Node    *prevP = this;
00223 
00224         succP = parentP;
00225         while (succP != NULL && prevP == succP->rightP)
00226         {
00227           prevP = succP;
00228           succP = succP->parentP;
00229         }
00230       }
00231       
00232       return (succP);
00233     }
00234   };
00235 
00236   // Rebind the allocator to the Node type:
00237   typedef typename Allocator::template rebind <Node>  Node_alloc_rebind;
00238   typedef typename Node_alloc_rebind::other           Node_allocator;
00239 
00240 public:
00241 
00242   // Forward decleration:
00243   class const_iterator;
00244 
00249   class iterator
00250   {
00251     // Give the red-black tree class template access to the iterator's members.
00252     friend class Multiset<Type, Compare, Allocator>;
00253     friend class const_iterator;
00254 
00255   public:
00256 
00257     // Type definitions:
00258     typedef std::bidirectional_iterator_tag  iterator_category;
00259     typedef Type                             value_type;
00260     typedef std::ptrdiff_t         difference_type;
00261     typedef size_t                           size_type;
00262     typedef value_type&                      reference;
00263     typedef value_type*                      pointer;
00264 
00265   private:
00266 
00267     Node    *nodeP;              // Points to a tree node.
00268 
00270     iterator (Node *_nodeP) :
00271       nodeP (_nodeP)
00272     {}
00273 
00274   public:
00275 
00277     iterator () :
00278       nodeP (NULL)
00279     {}
00280 
00282     bool operator== (const iterator& iter) const
00283     {
00284       return (nodeP == iter.nodeP);
00285     }
00286 
00288     bool operator!= (const iterator& iter) const
00289     {
00290       return (nodeP != iter.nodeP);
00291     }
00292 
00294     iterator& operator++ ()
00295     {
00296       CGAL_multiset_precondition (nodeP != NULL);
00297 
00298       nodeP = nodeP->successor();
00299       return (*this);
00300     }
00301 
00303     iterator operator++ (int )
00304     {
00305       CGAL_multiset_precondition (nodeP != NULL);
00306 
00307       iterator temp = *this;
00308 
00309       nodeP = nodeP->successor();
00310       return (temp);
00311     }
00312 
00314     iterator& operator-- ()
00315     {
00316       CGAL_multiset_precondition (nodeP != NULL);
00317 
00318       nodeP = nodeP->predecessor();
00319       return (*this);
00320     }
00321 
00323     iterator operator-- (int )
00324     {
00325       CGAL_multiset_precondition (nodeP != NULL);
00326 
00327       iterator temp = *this;
00328 
00329       nodeP = nodeP->predecessor();
00330       return (temp);
00331     }
00332 
00336     reference operator* () const
00337     {
00338       CGAL_multiset_precondition (nodeP != NULL && nodeP->is_valid());
00339 
00340       return (nodeP->object);
00341     }
00342 
00346     pointer operator-> () const
00347     {
00348       CGAL_multiset_precondition (nodeP != NULL && nodeP->is_valid());
00349 
00350       return (&(nodeP->object));
00351     }
00352 
00353   };
00354   friend class iterator;
00355 
00360   class const_iterator
00361   {
00362     // Give the red-black tree class template access to the iterator's members.
00363     friend class Multiset<Type, Compare, Allocator>;
00364 
00365   public:
00366 
00367     // Type definitions:
00368     typedef std::bidirectional_iterator_tag  iterator_category;
00369     typedef Type                             value_type;
00370     typedef std::ptrdiff_t         difference_type;
00371     typedef size_t                           size_type;
00372     typedef const value_type&                reference;
00373     typedef const value_type*                pointer;
00374 
00375   private:
00376 
00377     const Node    *nodeP;     // Points to a tree node.
00378 
00380     const_iterator (const Node *_nodeP) :
00381       nodeP (_nodeP)
00382     {}
00383 
00384   public:
00385 
00387     const_iterator () :
00388       nodeP (NULL)
00389     {}
00390 
00392     const_iterator (const iterator& iter) :
00393       nodeP (iter.nodeP)
00394     {}
00395 
00397     bool operator== (const const_iterator& iter) const
00398     {
00399       return (nodeP == iter.nodeP);
00400     }
00401 
00403     bool operator!= (const const_iterator& iter) const
00404     {
00405       return (nodeP != iter.nodeP);
00406     }
00407 
00409     const_iterator& operator++ ()
00410     {
00411       CGAL_multiset_precondition (nodeP != NULL);
00412 
00413       nodeP = nodeP->successor();
00414       return (*this);
00415     }
00416 
00418     const_iterator operator++ (int )
00419     {
00420       CGAL_multiset_precondition (nodeP != NULL);
00421 
00422       const_iterator temp = *this;
00423 
00424       nodeP = nodeP->successor();
00425       return (temp);
00426     }
00427 
00429     const_iterator& operator-- ()
00430     {
00431       CGAL_multiset_precondition (nodeP != NULL);
00432 
00433       nodeP = nodeP->predecessor();
00434       return (*this);
00435     }
00436 
00438     const_iterator operator-- (int )
00439     {
00440       CGAL_multiset_precondition (nodeP != NULL);
00441 
00442       const_iterator temp = *this;
00443 
00444       nodeP = nodeP->predecessor();
00445       return (temp);
00446     }
00447 
00451     reference operator* () const
00452     {
00453       CGAL_multiset_precondition (nodeP != NULL && nodeP->is_valid());
00454 
00455       return (nodeP->object);
00456     }
00457 
00461     pointer operator-> () const
00462     {
00463       CGAL_multiset_precondition (nodeP != NULL && nodeP->is_valid());
00464 
00465       return (&(nodeP->object));
00466     }
00467 
00468   };
00469   friend class const_iterator;
00470 
00471   // Define the reverse iterators:
00472   typedef std::reverse_iterator<iterator>         reverse_iterator;
00473   typedef std::reverse_iterator<const_iterator>   const_reverse_iterator;
00474 
00475 protected:
00476 
00477   // Data members:
00478   Node            *rootP;        // Pointer to the tree root.
00479   size_t           iSize;        // Number of objects stored in the tree.
00480   size_t           iBlackHeight; // The black-height of the tree (the number
00481                                  // of black nodes from the root to each leaf).
00482   Compare          comp_f;       // A comparison functor.
00483   Node_allocator   node_alloc;   // Allocator for the tree nodes.
00484   Node             beginNode;    // A fictitious before-the-minimum node.
00485                                  // Its parent is the leftmost tree node.
00486   Node             endNode;      // A fictitious past-the-maximum node.
00487                                  // Its parent is the rightmost tree node.
00488 
00489 public:
00490 
00492 
00493 
00497   Multiset ();
00498 
00503   Multiset (const Compare& comp);
00504 
00509   Multiset (const Self& tree);
00510 
00517   template <class InputIterator>
00518   Multiset (InputIterator first, InputIterator last,
00519             const Compare& comp = Compare()) :
00520     rootP (NULL),
00521     iSize (0),
00522     iBlackHeight (0),
00523     comp_f (comp)
00524   {
00525     // Mark the two fictitious nodes as dummies.
00526     beginNode.color = Node::DUMMY_BEGIN;
00527     endNode.color = Node::DUMMY_END;
00528 
00529     // Insert all objects to the tree.
00530     while (first != last)
00531     {
00532       insert (*first);
00533       ++first;
00534     }
00535   }
00536 
00540   virtual ~Multiset ();
00541 
00546   Self& operator= (const Self& tree);
00547 
00552   void swap (Self& tree);
00554 
00556 
00557   
00562   bool operator== (const Self& tree) const;
00563 
00568   bool operator< (const Self& tree) const;
00570 
00572 
00573 
00577   inline Compare& key_comp ()
00578   {
00579     return (comp_f);
00580   }
00581 
00585   inline Compare& value_comp ()
00586   {
00587     return (comp_f);
00588   }
00589 
00590 
00594   inline const Compare& key_comp () const
00595   {
00596     return (comp_f);
00597   }
00598 
00602   inline const Compare& value_comp () const
00603   {
00604     return (comp_f);
00605   }
00606 
00610   inline iterator begin ();
00611 
00615   inline iterator end ();
00616 
00620   inline const_iterator begin () const;
00621 
00625   inline const_iterator end () const;
00626 
00631   inline reverse_iterator rbegin ();
00632 
00637   inline reverse_iterator rend ();
00638 
00642   inline const_reverse_iterator rbegin () const;
00643 
00647   inline const_reverse_iterator rend () const;
00648 
00652   inline bool empty () const
00653   {
00654     return (rootP == NULL);
00655   }
00656 
00662   size_t size () const;
00663 
00667   size_t max_size () const
00668   {
00669     return (size());
00670   }
00672 
00674 
00680   iterator insert (const Type& object);
00681 
00687   template <class InputIterator>
00688   void insert (InputIterator first, InputIterator last)
00689   {
00690     // Insert all objects to the tree.
00691     while (first != last)
00692     {
00693       insert (*first);
00694       ++first;
00695     }
00696 
00697     return;
00698   }
00699 
00707   iterator insert (iterator position,
00708                    const Type& object);
00709 
00720   iterator insert_after (iterator position,
00721                          const Type& object);
00722 
00733   iterator insert_before (iterator position,
00734                           const Type& object);
00736 
00738 
00739 
00746   size_t erase (const Type& object);
00747 
00755   void erase (iterator position);
00756 
00760   void clear ();
00761   
00763 
00765 
00766 
00775   iterator find (const Type& object)
00776   {
00777     return (find (object, comp_f));
00778   }
00779 
00780   template <class Key, class CompareKey>
00781   iterator find (const Key& key,
00782                  const CompareKey& comp_key)
00783   {
00784     bool    is_equal;
00785     Node   *nodeP = _bound (LOWER_BOUND, key, comp_key, is_equal);
00786 
00787     if (_is_valid(nodeP) && is_equal)
00788       return (iterator (nodeP));
00789     else
00790       return (iterator (&endNode));
00791   }
00792 
00801   const_iterator find (const Type& object) const
00802   {
00803     return (find (object, comp_f));
00804   }
00805 
00806   template <class Key, class CompareKey>
00807   const_iterator find (const Key& key,
00808                        const CompareKey& comp_key) const
00809   {
00810     bool          is_equal;
00811     const Node   *nodeP = _bound (LOWER_BOUND, key, comp_key, is_equal);
00812 
00813     if (_is_valid (nodeP) && is_equal)
00814       return (const_iterator (nodeP));
00815     else
00816       return (const_iterator (&endNode));
00817   }
00818 
00826   size_type count (const Type& object) const
00827   {
00828     return (count (object, comp_f));
00829   }
00830 
00831   template <class Key, class CompareKey>
00832   size_type count (const Key& key,
00833                    const CompareKey& comp_key) const
00834   {
00835     // Get the first equivalent object (if any).
00836     size_t      n_objects = 0;
00837     bool        is_equal;
00838     const Node *nodeP = _bound (LOWER_BOUND, key, comp_key, is_equal);
00839 
00840     if (! is_equal)
00841       return (0);
00842 
00843     while (_is_valid (nodeP) &&
00844            comp_key (key, nodeP->object) == EQUAL)
00845     {
00846       n_objects++;
00847 
00848       // Proceed to the successor.
00849       nodeP = nodeP->successor();
00850     }
00851 
00852     return (n_objects);
00853   }
00854 
00863   iterator lower_bound (const Type& object)
00864   {
00865     return (lower_bound (object, comp_f));
00866   }
00867 
00868   template <class Key, class CompareKey>
00869   iterator lower_bound (const Key& key,
00870                         const CompareKey& comp_key)
00871   {
00872     bool    is_equal;
00873     Node   *nodeP = _bound (LOWER_BOUND, key, comp_key, is_equal);
00874 
00875     if (_is_valid (nodeP))
00876       return (iterator (nodeP));
00877     else
00878       return (iterator (&endNode));
00879   }
00880 
00889   std::pair<iterator, bool> find_lower (const Type& object)
00890   {
00891     return (find_lower (object, comp_f));
00892   }
00893 
00894   template <class Key, class CompareKey>
00895   std::pair<iterator, bool> find_lower (const Key& key,
00896                                         const CompareKey& comp_key)
00897   {
00898     bool    is_equal;
00899     Node   *nodeP = _bound (LOWER_BOUND, key, comp_key, is_equal);
00900 
00901     if (_is_valid (nodeP))
00902       return (std::make_pair (iterator (nodeP), is_equal));
00903     else
00904       return (std::make_pair (iterator (&endNode), false));
00905   }
00906 
00915   iterator upper_bound (const Type& object)
00916   {
00917     return (upper_bound (object, comp_f));
00918   }
00919 
00920   template <class Key, class CompareKey>
00921   iterator upper_bound (const Key& key,
00922                         const CompareKey& comp_key)
00923   {
00924     bool    is_equal;
00925     Node   *nodeP = _bound (UPPER_BOUND, key, comp_key, is_equal);
00926 
00927     if (_is_valid (nodeP))
00928       return (iterator (nodeP));
00929     else
00930       return (iterator (&endNode));
00931   }
00932 
00941   const_iterator lower_bound (const Type& object) const
00942   {
00943     return (lower_bound (object, comp_f));
00944   }
00945 
00946   template <class Key, class CompareKey>
00947   const_iterator lower_bound (const Key& key,
00948                               const CompareKey& comp_key) const
00949   {
00950     bool          is_equal;
00951     const Node   *nodeP = _bound (LOWER_BOUND, key, comp_key, is_equal);
00952 
00953     if (_is_valid (nodeP))
00954       return (const_iterator (nodeP));
00955     else
00956       return (const_iterator (&endNode));
00957   }
00958 
00967   std::pair<const_iterator, bool> find_lower (const Type& object) const
00968   {
00969     return (find_lower (object, comp_f));
00970   }
00971 
00972   template <class Key, class CompareKey>
00973   std::pair<const_iterator, bool> find_lower (const Key& key,
00974                                               const CompareKey& comp_key) const
00975   {
00976     bool          is_equal;
00977     const Node   *nodeP = _bound (LOWER_BOUND, key, comp_key, is_equal);
00978 
00979     if (_is_valid (nodeP))
00980       return (std::make_pair (const_iterator (nodeP), is_equal));
00981     else
00982       return (std::make_pair (const_iterator (&endNode), false));
00983   }
00984 
00992   const_iterator upper_bound (const Type& object) const
00993   {
00994     return (upper_bound (object, comp_f));
00995   }
00996 
00997   template <class Key, class CompareKey>
00998   const_iterator upper_bound (const Key& key,
00999                               const CompareKey& comp_key) const
01000   {
01001     bool          is_equal;
01002     const Node   *nodeP = _bound (UPPER_BOUND, key, comp_key, is_equal);
01003 
01004     if (_is_valid (nodeP))
01005       return (const_iterator (nodeP));
01006     else
01007       return (const_iterator (&endNode));
01008   }
01009 
01017   std::pair<iterator, iterator> equal_range (const Type& object)
01018   {
01019     return (equal_range (object, comp_f));
01020   }
01021 
01022   template <class Key, class CompareKey>
01023   std::pair<iterator, iterator>
01024   equal_range (const Key& key,
01025                const CompareKey& comp_key)
01026   {
01027     // Get the first equivalent object (if any).
01028     const size_t   max_steps = static_cast<size_t> (1.5 * iBlackHeight);
01029     bool           is_equal;
01030     Node          *lowerP = _bound (LOWER_BOUND, key, comp_key, is_equal);
01031     Node          *upperP = lowerP;
01032     size_t         n_objects = 0;
01033 
01034     if (is_equal)
01035     {
01036       while (_is_valid (upperP) &&
01037              comp_key (key, upperP->object) == EQUAL)
01038       {
01039         n_objects++;
01040         if (n_objects >= max_steps)
01041         {
01042           // If we have more than log(n) objects in the range, locate the
01043           // upper bound directly.
01044           upperP = _bound (UPPER_BOUND, key, comp_key, is_equal);
01045           break;
01046         }
01047 
01048         // Proceed to the successor.
01049         upperP = upperP->successor();
01050       }
01051     }
01052 
01053     return (std::pair<iterator, iterator>
01054       ((_is_valid (lowerP)) ? iterator (lowerP) : iterator (&endNode),
01055        (_is_valid (upperP)) ? iterator (upperP) : iterator (&endNode)));
01056   }
01057 
01065   std::pair<const_iterator, const_iterator>
01066   equal_range (const Type& object) const
01067   {
01068     return (equal_range (object, comp_f));
01069   }
01070 
01071   template <class Key, class CompareKey>
01072   std::pair<const_iterator, const_iterator>
01073   equal_range (const Key& key,
01074                const CompareKey& comp_key) const
01075   {
01076     // Get the first equivalent object (if any).
01077     const size_t   max_steps = static_cast<size_t> (1.5 * iBlackHeight);
01078     bool           is_equal;
01079     const Node    *lowerP = _bound (LOWER_BOUND, key, comp_key, is_equal);
01080     const Node    *upperP = lowerP;
01081     size_t         n_objects = 0;
01082 
01083     if (is_equal)
01084     {
01085       while (_is_valid (upperP) &&
01086              comp_key (key, upperP->object) == EQUAL)
01087       {
01088         n_objects++;
01089         if (n_objects >= max_steps)
01090         {
01091           // If we have more than log(n) objects in the range, locate the
01092           // upper bound directly.
01093           upperP = _bound (UPPER_BOUND, key, comp_key, is_equal);
01094           break;
01095         }
01096 
01097         // Proceed to the successor.
01098         upperP = upperP->successor();
01099       }
01100     }
01101 
01102     return (std::pair<const_iterator, const_iterator>
01103       ((_is_valid (lowerP)) ? const_iterator(lowerP) :
01104                               const_iterator(&endNode),
01105        (_is_valid (upperP)) ? const_iterator(upperP) :
01106                               const_iterator(&endNode)));
01107   }
01109 
01111 
01112 
01121   void replace (iterator position,
01122                 const Type& object);
01123 
01132   void swap (iterator pos1, iterator pos2);
01133 
01143   void catenate (Self& tree);
01144 
01155   void split (const Type& object, Self& tree)
01156   {
01157     split (object, comp_f, tree);
01158     return;
01159   }
01160 
01161   template <class Key, class CompareKey>
01162   void split (const Key& key, const CompareKey& comp_key,
01163               Self& tree)
01164   {
01165     split (lower_bound (key, comp_key), tree);
01166     return;
01167   }
01168 
01177   void split (iterator position, Self& tree);
01178 
01180 
01182 
01183 
01189   bool is_valid() const;
01190 
01195   size_t height () const;
01196 
01201   inline size_t black_height () const
01202   {
01203     return (iBlackHeight);
01204   }
01206 
01207 protected:
01208 
01210 
01211 
01213   inline bool _is_valid (const Node *nodeP) const
01214   {
01215     return (nodeP != NULL && nodeP->is_valid());
01216   }
01217 
01219   inline bool _is_red (const Node *nodeP) const
01220   {
01221     return (nodeP != NULL && nodeP->color == Node::RED);
01222   }
01223 
01225   inline bool _is_black (const Node *nodeP) const
01226   {
01227     // Note that invalid nodes are considered ro be black as well.
01228     return (nodeP == NULL || nodeP->color != Node::RED);
01229   }
01231 
01233 
01234 
01240   void _shallow_assign (Self& tree);
01241 
01246   void _shallow_clear ();
01247 
01262   enum Bound_type {LOWER_BOUND, UPPER_BOUND};
01263 
01264   template <class Key, class CompareKey>
01265   Node* _bound (Bound_type type,
01266                 const Key& key,
01267                 const CompareKey& comp_key,
01268                 bool& is_equal) const
01269   {
01270     // Initially mark that the key is not found in the tree.
01271     is_equal = false;
01272 
01273     if (rootP == NULL)
01274       // The tree is empty:
01275       return (NULL);
01276 
01277     Node                      *currentP = rootP;
01278     Node                      *prevP = currentP;
01279     Comparison_result          comp_res = EQUAL;
01280 
01281     while (_is_valid (currentP))
01282     {
01283       comp_res = comp_key (key, currentP->object);
01284 
01285       if (comp_res == EQUAL)
01286       {
01287         // The key is found in the tree:
01288         if (type == LOWER_BOUND)
01289         {
01290           is_equal = true;
01291 
01292           // Lower bound computation:
01293           // Go backward as long as we find equivalent objects.
01294           prevP = currentP->predecessor();
01295           while (_is_valid (prevP))
01296           {
01297             if (comp_key (key, prevP->object) != EQUAL)
01298               break;
01299             currentP = prevP;
01300             prevP = currentP->predecessor();
01301           }
01302         }
01303         else
01304         {
01305           // Upper bound computation:
01306           // Go backward until we encounter a non-equivalent objects.
01307           do
01308           {
01309             currentP = currentP->successor();
01310           } while (_is_valid (currentP) &&
01311                    comp_key (key, currentP->object) == EQUAL);
01312         }
01313 
01314         return (currentP);
01315       }
01316       else if (comp_res == SMALLER)
01317       {
01318         prevP = currentP;
01319 
01320         // Go down to the left child.
01321         currentP = currentP->leftP;
01322       }
01323       else // comp_res == LARGER
01324       {
01325         prevP = currentP;
01326 
01327         // Go down to the right child.
01328         currentP = currentP->rightP;
01329       }
01330     }
01331 
01332     // If we reached here, the object is not found in the tree. We check if the
01333     // last node we visited (given by prevP) contains an object greater than
01334     // the query object. If not, we return its successor.
01335     if (comp_res == SMALLER)
01336       return (prevP);
01337     else
01338       return (prevP->successor());
01339   }
01340 
01345   void _remove_at (Node* nodeP);
01346 
01352   void _swap (Node* node1_P, Node* node2_P);
01353 
01360   void _swap_siblings (Node* node1_P, Node* node2_P);
01361 
01367   size_t _sub_height (const Node* nodeP) const;
01368 
01375   bool _sub_is_valid (const Node* nodeP,
01376                       size_t& sub_size,
01377                       size_t& sub_bh) const;
01378 
01384   Node* _sub_minimum (Node* nodeP) const;
01385 
01391   Node* _sub_maximum (Node* nodeP) const;
01392 
01397   void _rotate_left (Node* nodeP);
01398 
01403   void _rotate_right (Node* nodeP);
01404 
01410   Node* _duplicate (const Node* nodeP);
01411 
01416   void _destroy (Node* nodeP);
01417 
01422   void _insert_fixup (Node* nodeP);
01423 
01431   void _remove_fixup (Node* nodeP, Node* parentP);
01432 
01439   Node* _allocate_node (const Type& object,
01440                         typename Node::Node_color color)
01441 #ifdef CGAL_CFG_OUTOFLINE_MEMBER_DEFINITION_BUG
01442   {
01443       CGAL_multiset_assertion (color != Node::DUMMY_BEGIN && 
01444               color != Node::DUMMY_END);
01445 
01446       Node* new_node = node_alloc.allocate(1);
01447 
01448       node_alloc.construct(new_node, beginNode);
01449       new_node->init(object, color);
01450       return (new_node);
01451   }
01452 #else
01453   ;
01454 #endif
01455 
01460   void _deallocate_node (Node* nodeP);
01462 };
01463 
01464 //---------------------------------------------------------
01465 // Default constructor.
01466 //
01467 template <class Type, class Compare, typename Allocator>
01468 Multiset<Type, Compare, Allocator>::Multiset () :
01469   rootP (NULL),
01470   iSize (0),
01471   iBlackHeight (0),
01472   comp_f ()
01473 {
01474   // Mark the two fictitious nodes as dummies.
01475   beginNode.color = Node::DUMMY_BEGIN;
01476   endNode.color = Node::DUMMY_END;
01477 }
01478 
01479 //---------------------------------------------------------
01480 // Constructor with a pointer to comparison object.
01481 //
01482 template <class Type, class Compare, typename Allocator>
01483 Multiset<Type, Compare, Allocator>::Multiset (const Compare& comp) :
01484   rootP (NULL),
01485   iSize (0),
01486   iBlackHeight (0),
01487   comp_f (comp)
01488 {
01489   // Mark the two fictitious nodes as dummies.
01490   beginNode.color = Node::DUMMY_BEGIN;
01491   endNode.color = Node::DUMMY_END;
01492 }
01493 
01494 //---------------------------------------------------------
01495 // Copy constructor.
01496 //
01497 template <class Type, class Compare, typename Allocator>
01498 Multiset<Type, Compare, Allocator>::Multiset (const Self& tree) :
01499   rootP (NULL),
01500   iSize (tree.iSize),
01501   iBlackHeight (tree.iBlackHeight),
01502   comp_f (tree.comp_f)
01503 {
01504   // Mark the two fictitious nodes as dummies.
01505   beginNode.color = Node::DUMMY_BEGIN;
01506   endNode.color = Node::DUMMY_END;
01507 
01508   // Copy all the copied tree's nodes recursively.
01509   if (tree.rootP != NULL)
01510   {
01511     rootP = _duplicate (tree.rootP);
01512 
01513     // Set the dummy nodes.
01514     beginNode.parentP = _sub_minimum (rootP);
01515     beginNode.parentP->leftP = &beginNode;
01516     endNode.parentP = _sub_maximum (rootP);
01517     endNode.parentP->rightP = &endNode;
01518   }
01519   else
01520   {
01521     beginNode.parentP = NULL;
01522     endNode.parentP = NULL;
01523   }
01524 }
01525 
01526 //---------------------------------------------------------
01527 // Destructor.
01528 //
01529 template <class Type, class Compare, typename Allocator>
01530 Multiset<Type, Compare, Allocator>::~Multiset ()
01531 {
01532   // Delete the entire tree recursively.
01533   if (rootP != NULL)
01534     _destroy (rootP);
01535 
01536   rootP = NULL;
01537   beginNode.parentP = NULL;
01538   endNode.parentP = NULL;
01539 }
01540 
01541 //---------------------------------------------------------
01542 // Assignment operator.
01543 //
01544 template <class Type, class Compare, typename Allocator>
01545 Multiset<Type, Compare, Allocator>&
01546 Multiset<Type, Compare, Allocator>::operator= (const Self& tree)
01547 {
01548   // Avoid self-assignment.
01549   if (this == &tree)
01550     return (*this);
01551   
01552   // Free all objects currently stored in the tree.
01553   clear();
01554 
01555   // Update the number of objects stored in the tree.
01556   iSize = tree.iSize;
01557   iBlackHeight = tree.iBlackHeight;
01558 
01559   // Copy all the copied tree's nodes recursively.
01560   if (tree.rootP != NULL)
01561   {
01562     rootP = _duplicate (tree.rootP);
01563 
01564     // Set the dummy nodes.
01565     beginNode.parentP = _sub_minimum (rootP);
01566     beginNode.parentP->leftP = &beginNode;
01567     endNode.parentP = _sub_maximum (rootP);
01568     endNode.parentP->rightP = &endNode;
01569   }
01570   else
01571   {
01572     beginNode.parentP = NULL;
01573     endNode.parentP = NULL;
01574   }
01575 
01576   return (*this);
01577 }
01578 
01579 //---------------------------------------------------------
01580 // Swap two trees (replace their contents).
01581 //
01582 template <class Type, class Compare, typename Allocator>
01583 void Multiset<Type, Compare, Allocator>::swap (Self& tree)
01584 {
01585   // Avoid self-swapping.
01586   if (this == &tree)
01587     return;
01588 
01589   // Replace the contents of the trees.
01590   Node            *tempP = rootP; 
01591   rootP = tree.rootP;
01592   tree.rootP = tempP;
01593 
01594   size_t           iTemp = iSize;
01595   iSize = tree.iSize;
01596   tree.iSize = iTemp;
01597 
01598   iTemp = iBlackHeight;
01599   iBlackHeight = tree.iBlackHeight;
01600   tree.iBlackHeight = iTemp;
01601   
01602   // Update the fictitious begin and end nodes.
01603   tempP = beginNode.parentP;
01604   beginNode.parentP = tree.beginNode.parentP;
01605   if (beginNode.parentP != NULL)
01606     beginNode.parentP->leftP = &beginNode;
01607   tree.beginNode.parentP = tempP;
01608   if (tree.beginNode.parentP != NULL)
01609     tree.beginNode.parentP->leftP = &(tree.beginNode);
01610 
01611   tempP = endNode.parentP;
01612   endNode.parentP = tree.endNode.parentP;
01613   if (endNode.parentP != NULL)
01614     endNode.parentP->rightP = &endNode;
01615   tree.endNode.parentP = tempP;
01616   if (tree.endNode.parentP != NULL)
01617     tree.endNode.parentP->rightP = &(tree.endNode);
01618 
01619   return;
01620 }
01621 
01622 //---------------------------------------------------------
01623 // Test two trees for equality.
01624 //
01625 template <class Type, class Compare, typename Allocator>
01626 bool Multiset<Type,Compare,Allocator>::operator== (const Self& tree) const
01627 {
01628   // The sizes of the two trees must be the same.
01629   if (size() != tree.size())
01630     return (false);
01631 
01632   // Go over all elements in both tree and compare them pairwise.
01633   const_iterator   it1 = this->begin();
01634   const_iterator   it2 = tree.begin();
01635 
01636   while (it1 != this->end() && it2 != tree.end())
01637   {
01638     if (comp_f (*it1, *it2) != EQUAL)
01639       return (false);
01640 
01641     ++it1;
01642     ++it2;
01643   }
01644 
01645   // If we reached here, the two trees are equal.
01646   return (true);
01647 }
01648 
01649 //---------------------------------------------------------
01650 // Check if our tree is lexicographically smaller that a given tree.
01651 //
01652 template <class Type, class Compare, typename Allocator>
01653 bool Multiset<Type,Compare,Allocator>::operator< (const Self& tree) const
01654 {
01655   // Go over all elements in both tree and compare them pairwise.
01656   const_iterator   it1 = this->begin();
01657   const_iterator   it2 = tree.begin();
01658 
01659   while (it1 != this->end() && it2 != tree.end())
01660   {
01661     const Comparison_result   res = comp_f (*it1, *it2);
01662 
01663     if (res == SMALLER)
01664       return (true);
01665     if (res == LARGER)
01666       return (false);
01667 
01668     ++it1;
01669     ++it2;
01670   }
01671 
01672   // If we reached here, one tree is the prefix of the other tree. We now
01673   // check which tree contains more elements.
01674   if (it1 != this->end())
01675   {
01676     // Our tree contains the other tree as a prefix, so it is not smaller.
01677     return (false);
01678   }
01679   else if (it2 != tree.end())
01680   {
01681     // The other tree contains our tree as a prefix, so our tree is smaller.
01682     return (true);
01683   }
01684 
01685   // The two trees are equal:
01686   return (false);
01687 }
01688 
01689 //---------------------------------------------------------
01690 // Get an iterator for the minimum object in the tree (non-const version).
01691 //
01692 template <class Type, class Compare, typename Allocator>
01693 inline typename Multiset<Type,Compare,Allocator>::iterator 
01694 Multiset<Type, Compare, Allocator>::begin ()
01695 {
01696   if (beginNode.parentP != NULL)
01697     return (iterator (beginNode.parentP));
01698   else
01699     return (iterator (&endNode));
01700 }
01701 
01702 //---------------------------------------------------------
01703 // Get a past-the-end iterator for the tree objects (non-const version).
01704 //
01705 template <class Type, class Compare, typename Allocator>
01706 inline typename Multiset<Type, Compare,Allocator>::iterator 
01707 Multiset<Type, Compare, Allocator>::end ()
01708 {
01709   return (iterator (&endNode));
01710 }
01711 
01712 //---------------------------------------------------------
01713 // Get an iterator for the minimum object in the tree (const version).
01714 //
01715 template <class Type, class Compare, typename Allocator>
01716 inline typename Multiset<Type,Compare,Allocator>::const_iterator
01717 Multiset<Type, Compare, Allocator>::begin () const
01718 {
01719   if (beginNode.parentP != NULL)
01720     return (const_iterator (beginNode.parentP));
01721   else
01722     return (const_iterator (&endNode));
01723 }
01724 
01725 //---------------------------------------------------------
01726 // Get a past-the-end iterator for the tree objects (const version).
01727 //
01728 template <class Type, class Compare, typename Allocator>
01729 inline typename Multiset<Type,Compare,Allocator>::const_iterator
01730 Multiset<Type, Compare, Allocator>::end () const
01731 {
01732   return (const_iterator (&endNode));
01733 }
01734 
01735 //---------------------------------------------------------
01736 // Get a reverse iterator for the maxnimum object in the tree
01737 // (non-const version).
01738 //
01739 template <class Type, class Compare, typename Allocator>
01740 inline typename Multiset<Type,Compare,Allocator>::reverse_iterator
01741 Multiset<Type, Compare, Allocator>::rbegin ()
01742 {
01743   return (reverse_iterator (end()));
01744 }
01745 
01746 //---------------------------------------------------------
01747 // Get a pre-the-begin reverse iterator for the tree objects
01748 // (non-const version).
01749 //
01750 template <class Type, class Compare, typename Allocator>
01751 inline typename Multiset<Type,Compare,Allocator>::reverse_iterator
01752 Multiset<Type, Compare, Allocator>::rend ()
01753 {
01754   return (reverse_iterator (begin()));
01755 }
01756 
01757 //---------------------------------------------------------
01758 // Get a reverse iterator for the maximum object in the tree (const version).
01759 //
01760 template <class Type, class Compare, typename Allocator>
01761 inline typename Multiset<Type,Compare,Allocator>::const_reverse_iterator
01762 Multiset<Type, Compare, Allocator>::rbegin () const
01763 {
01764   return (const_reverse_iterator (end()));
01765 }
01766 
01767 //---------------------------------------------------------
01768 // Get a pre-the-begin reverse iterator for the tree objects (const version).
01769 //
01770 template <class Type, class Compare, typename Allocator>
01771 inline typename Multiset<Type,Compare,Allocator>::const_reverse_iterator
01772 Multiset<Type, Compare, Allocator>::rend () const
01773 {
01774   return (const_reverse_iterator (begin()));
01775 }
01776 
01777 //---------------------------------------------------------
01778 // Get the size of the tree.
01779 //
01780 template <class Type, class Compare, typename Allocator>
01781 size_t Multiset<Type, Compare, Allocator>::size () const
01782 {
01783   if (rootP == NULL)
01784     // The tree is empty:
01785     return (0);
01786   else if (iSize > 0)
01787     return (iSize);
01788 
01789   // If we reached here, the tree is the result of a split operation and its
01790   // size is not known - compute it now.
01791   const Node    *nodeP = beginNode.parentP;
01792   size_t         iComputedSize = 0;
01793 
01794   while (nodeP != &endNode)
01795   {
01796     nodeP = nodeP->successor();
01797     iComputedSize++;
01798   }
01799 
01800   // Assign the computed size.
01801   Self  *myThis = const_cast<Self*> (this);
01802   myThis->iSize = iComputedSize;
01803 
01804   return (iComputedSize);
01805 }
01806 
01807 //---------------------------------------------------------
01808 // Insert a new object to the tree.
01809 //
01810 template <class Type, class Compare, typename Allocator>
01811 typename Multiset<Type, Compare, Allocator>::iterator
01812 Multiset<Type, Compare, Allocator>::insert (const Type& object)
01813 {
01814   if (rootP == NULL)
01815   {
01816     // In case the tree is empty, assign a new rootP.
01817     // Notice that the root is always black.
01818     rootP = _allocate_node (object, Node::BLACK);
01819     
01820     iSize = 1;
01821     iBlackHeight = 1;
01822 
01823     // As the tree now contains a single node, it is both the tree
01824     // maximum and minimum.
01825     beginNode.parentP = rootP;
01826     rootP->leftP = &beginNode;
01827     endNode.parentP = rootP;
01828     rootP->rightP = &endNode;
01829 
01830     return (iterator (rootP));
01831   }
01832 
01833   // Find a place for the new object, and insert it as a red leaf.
01834   Node                      *currentP = rootP;
01835   Node                      *newNodeP = _allocate_node (object, Node::RED);
01836 
01837   Comparison_result         comp_res;
01838   bool                      is_leftmost = true;
01839   bool                      is_rightmost = true;
01840 
01841   while (_is_valid (currentP))
01842   {
01843     // Compare the inserted object with the object stored in the current node.
01844     comp_res = comp_f (object, currentP->object);
01845 
01846     if (comp_res == SMALLER)
01847     {
01848       is_rightmost = false;
01849 
01850       if (! _is_valid (currentP->leftP))
01851       {
01852         // Insert the new leaf as the left child of the current node.
01853         currentP->leftP = newNodeP;
01854         newNodeP->parentP = currentP;
01855         currentP = NULL;        // In order to terminate the while loop.
01856 
01857         if (is_leftmost)
01858         {
01859           // Assign a new tree minimum.
01860           beginNode.parentP = newNodeP;
01861           newNodeP->leftP = &beginNode;
01862         }
01863       }
01864       else
01865       {
01866         // Go to the left sub-tree.
01867         currentP = currentP->leftP;
01868       }
01869     }
01870     else
01871     {
01872       is_leftmost = false;
01873 
01874       if (! _is_valid (currentP->rightP))
01875       {
01876         // Insert the new leaf as the right child of the current node.
01877         currentP->rightP = newNodeP;
01878         newNodeP->parentP = currentP;
01879         currentP = NULL;        // In order to terminate the while loop.
01880 
01881         if (is_rightmost)
01882         {
01883           // Assign a new tree maximum.
01884           endNode.parentP = newNodeP;
01885           newNodeP->rightP = &endNode;
01886         }
01887       }
01888       else
01889       {
01890         // Go to the right sub-tree.
01891         currentP = currentP->rightP;
01892       }
01893     }
01894   }
01895 
01896   // Mark that a new node was added.
01897   if (iSize > 0)
01898     iSize++;
01899 
01900   // Fix up the tree properties.
01901   _insert_fixup (newNodeP);
01902 
01903   return (iterator(newNodeP));
01904 }
01905 
01906 //---------------------------------------------------------
01907 // Insert an object to the tree, with a given hint to its position.
01908 //
01909 template <class Type, class Compare, typename Allocator>
01910 typename Multiset<Type, Compare, Allocator>::iterator
01911 Multiset<Type, Compare, Allocator>::insert (iterator position,
01912                                             const Type& object)
01913 {
01914   Node  *nodeP = position.nodeP;
01915 
01916   CGAL_multiset_precondition (_is_valid (nodeP));
01917 
01918   // Compare the object to the one stored at the given node in order to decide
01919   // in which direction to proceed.
01920   const size_t       max_steps = static_cast<size_t> (1.5 * iBlackHeight);
01921   Comparison_result  res = comp_f(object, nodeP->object);
01922   bool               found_pos = true;
01923   size_t             k = 0;
01924 
01925   if (res == EQUAL)
01926     return (insert_after (position, object));
01927 
01928   if (res == SMALLER)
01929   {
01930     // Go back until locating an object not greater than the inserted one.
01931     Node  *predP = nodeP->predecessor();
01932 
01933     while (_is_valid (predP) &&
01934            comp_f (object, predP->object) == SMALLER)
01935     {
01936       k++;
01937       if (k > max_steps)
01938       {
01939         // In case the given position is too far away (more than log(n) steps)
01940         // from the true poisition of the object, break the loop.
01941         found_pos = false;
01942         break;
01943       }
01944 
01945       nodeP = predP;
01946       predP = nodeP->predecessor();
01947     }
01948 
01949     if (found_pos)
01950       return (insert_before (iterator (nodeP), object));
01951   }
01952   else
01953   {
01954     // Go forward until locating an object not less than the inserted one.
01955     Node  *succP = nodeP->successor();
01956 
01957     while (_is_valid (succP) &&
01958            comp_f (object, succP->object) == LARGER)
01959     {
01960       k++;
01961       if (k > max_steps)
01962       {
01963         // In case the given position is too far away (more than log(n) steps)
01964         // from the true poisition of the object, break the loop.
01965         found_pos = false;
01966         break;
01967       }
01968 
01969       nodeP = succP;
01970       succP = nodeP->successor();
01971     }
01972 
01973     if (found_pos)
01974       return (insert_after (iterator (nodeP), object));
01975   }
01976 
01977   // If the hint was too far than the actual position, perform a normal
01978   // insertion:
01979   return (insert (object));
01980 }
01981 
01982 //---------------------------------------------------------
01983 // Insert a new object to the tree as the a successor of a given node.
01984 //
01985 template <class Type, class Compare, typename Allocator>
01986 typename Multiset<Type, Compare, Allocator>::iterator
01987 Multiset<Type, Compare, Allocator>::insert_after (iterator position,
01988                                                   const Type& object)
01989 {
01990   Node  *nodeP = position.nodeP;
01991 
01992   // In case we are given a NULL node, object should be the tree minimum.
01993   CGAL_multiset_assertion (nodeP != &endNode);
01994 
01995   if (nodeP == &beginNode)
01996     nodeP = NULL;
01997 
01998   if (rootP == NULL)
01999   {
02000     // In case the tree is empty, make sure that we did not recieve a valid
02001     // iterator.
02002     CGAL_multiset_precondition (nodeP == NULL);
02003 
02004     // Assign a new root node. Notice that the root is always black.
02005     rootP = _allocate_node (object, Node::BLACK);
02006 
02007     iSize = 1;
02008     iBlackHeight = 1;
02009     
02010     // As the tree now contains a single node, it is both the tree
02011     // maximum and minimum:
02012     beginNode.parentP = rootP;
02013     rootP->leftP = &beginNode;
02014     endNode.parentP = rootP;
02015     rootP->rightP = &endNode;
02016 
02017     return (iterator (rootP));
02018   }
02019 
02020   // Insert the new object as a red leaf, being the successor of nodeP.
02021   Node        *parentP;
02022   Node        *newNodeP = _allocate_node (object, Node::RED);
02023 
02024   if (nodeP == NULL)
02025   {
02026     // The new node should become the tree minimum: Place is as the left
02027     // child of the current minimal leaf.
02028     parentP = beginNode.parentP;
02029 
02030     CGAL_multiset_precondition (comp_f(object, parentP->object) != LARGER);
02031 
02032     parentP->leftP = newNodeP;
02033 
02034     // As we inserted a new tree minimum:
02035     beginNode.parentP = newNodeP;
02036     newNodeP->leftP = &beginNode;
02037   }
02038   else
02039   {
02040     // Make sure the insertion does not violate the tree order.
02041     CGAL_multiset_precondition_code (Node *_succP = nodeP->successor());
02042     CGAL_multiset_precondition (comp_f(object, nodeP->object) != SMALLER);
02043     CGAL_multiset_precondition (! _succP->is_valid() ||
02044                                 comp_f(object, _succP->object) != LARGER);
02045 
02046     // In case given node has no right child, place the new node as its 
02047     // right child. Otherwise, place it at the leftmost position at the
02048     // sub-tree rooted at its right side.
02049     if (! _is_valid (nodeP->rightP))
02050     {
02051       parentP = nodeP;
02052       parentP->rightP = newNodeP;
02053     }
02054     else
02055     {
02056       parentP = _sub_minimum (nodeP->rightP);
02057       parentP->leftP = newNodeP;
02058     }
02059 
02060     if (nodeP == endNode.parentP)
02061     {
02062       // As we inserted a new tree maximum:
02063       endNode.parentP = newNodeP;
02064       newNodeP->rightP = &endNode;
02065     }
02066   }
02067 
02068   newNodeP->parentP = parentP;
02069 
02070   // Mark that a new node was added.
02071   if (iSize > 0)
02072     iSize++;
02073 
02074   // Fix up the tree properties.
02075   _insert_fixup (newNodeP);  
02076 
02077   return (iterator (newNodeP));
02078 }
02079 
02080 //---------------------------------------------------------
02081 // Insert a new object to the tree as the a predecessor of a given node.
02082 //
02083 template <class Type, class Compare, typename Allocator>
02084 typename Multiset<Type, Compare, Allocator>::iterator
02085 Multiset<Type, Compare, Allocator>::insert_before (iterator position,
02086                                                    const Type& object)
02087 {
02088   Node  *nodeP = position.nodeP;
02089 
02090   // In case we are given a NULL node, object should be the tree maximum.
02091   CGAL_multiset_assertion (nodeP != &beginNode);
02092 
02093   if (nodeP == &endNode)
02094     nodeP = NULL;
02095 
02096   if (rootP == NULL)
02097   {
02098     // In case the tree is empty, make sure that we did not recieve a valid
02099     // iterator.
02100     CGAL_multiset_precondition (nodeP == NULL);
02101 
02102     // Assign a new root node. Notice that the root is always black.
02103     rootP = _allocate_node(object, Node::BLACK);
02104 
02105     iSize = 1;
02106     iBlackHeight = 1;
02107     
02108     // As the tree now contains a single node, it is both the tree
02109     // maximum and minimum:
02110     beginNode.parentP = rootP;
02111     rootP->leftP = &beginNode;
02112     endNode.parentP = rootP;
02113     rootP->rightP = &endNode;
02114 
02115     return (iterator (rootP));
02116   }
02117 
02118   // Insert the new object as a red leaf, being the predecessor of nodeP.
02119   Node        *parentP;
02120   Node        *newNodeP = _allocate_node (object, Node::RED);
02121 
02122   if (nodeP == NULL)
02123   {
02124     // The new node should become the tree maximum: Place is as the right
02125     // child of the current maximal leaf.
02126     parentP = endNode.parentP;
02127 
02128     CGAL_multiset_precondition (comp_f(object, parentP->object) != SMALLER);
02129 
02130     parentP->rightP = newNodeP;
02131 
02132     // As we inserted a new tree maximum:
02133     endNode.parentP = newNodeP;
02134     newNodeP->rightP = &endNode;
02135   }
02136   else
02137   {
02138     // Make sure the insertion does not violate the tree order.
02139     CGAL_multiset_precondition_code (Node *_predP = nodeP->predecessor());
02140     CGAL_multiset_precondition (comp_f(object, nodeP->object) != LARGER);
02141     CGAL_multiset_precondition (! _predP->is_valid() ||
02142                                 comp_f(object, _predP->object) != SMALLER);
02143 
02144     // In case given node has no left child, place the new node as its
02145     // left child. Otherwise, place it at the rightmost position at the
02146     // sub-tree rooted at its left side.
02147     if (! _is_valid (nodeP->leftP))
02148     {
02149       parentP = nodeP;
02150       parentP->leftP = newNodeP;
02151     }
02152     else
02153     {
02154       parentP = _sub_maximum (nodeP->leftP);
02155       parentP->rightP = newNodeP;
02156     }
02157 
02158     if (nodeP == beginNode.parentP)
02159     {
02160       // As we inserted a new tree minimum:
02161       beginNode.parentP = newNodeP;
02162       newNodeP->leftP = &beginNode;
02163     }
02164   }
02165 
02166   newNodeP->parentP = parentP;
02167 
02168   // Mark that a new node was added.
02169   if (iSize > 0)
02170     iSize++;
02171 
02172   // Fix up the tree properties.
02173   _insert_fixup (newNodeP);  
02174 
02175   return (iterator (newNodeP));
02176 }
02177 
02178 //---------------------------------------------------------
02179 // Remove an object from the tree.
02180 //
02181 template <class Type, class Compare, typename Allocator>
02182 size_t Multiset<Type, Compare, Allocator>::erase (const Type& object)
02183 {
02184   // Find the first node containing an object not less than the object to
02185   // be erased and from there look for objects equivalent to the given object.
02186   size_t      n_removed = 0;
02187   bool        is_equal;
02188   Node       *nodeP = _bound (LOWER_BOUND, object, comp_f, is_equal);
02189   Node       *succP;
02190 
02191   if (! is_equal)
02192     return (n_removed);
02193     
02194   while (_is_valid (nodeP) && comp_f (object, nodeP->object) == EQUAL)
02195   {
02196     // Keep a pointer to the successor node.
02197     succP = nodeP->successor();
02198 
02199     // Remove the current node.
02200     _remove_at (nodeP);
02201     n_removed++;
02202 
02203     // Proceed to the successor.
02204     nodeP = succP;
02205   }
02206 
02207   return (n_removed);
02208 }
02209 
02210 //---------------------------------------------------------
02211 // Remove the object pointed by the given iterator.
02212 //
02213 template <class Type, class Compare, typename Allocator>
02214 void Multiset<Type, Compare, Allocator>::erase (iterator position)
02215 {
02216   Node  *nodeP = position.nodeP;
02217 
02218   CGAL_multiset_precondition (_is_valid (nodeP));
02219 
02220   _remove_at (nodeP);
02221   return;
02222 }
02223 
02224 //---------------------------------------------------------
02225 // Remove all objects from the tree.
02226 //
02227 template <class Type, class Compare, typename Allocator>
02228 void Multiset<Type, Compare, Allocator>::clear ()
02229 {
02230   // Delete all the tree nodes recursively.
02231   if (rootP != NULL)
02232     _destroy (rootP);
02233 
02234   rootP = NULL;
02235   beginNode.parentP = NULL;
02236   endNode.parentP = NULL;
02237 
02238   // Mark that there are no more objects in the tree.
02239   iSize = 0;
02240   iBlackHeight = 0;
02241   
02242   return;
02243 }
02244 
02245 //---------------------------------------------------------
02246 // Replace the object pointed by a given iterator with another object.
02247 //
02248 template <class Type, class Compare, typename Allocator>
02249 void Multiset<Type, Compare, Allocator>::replace (iterator position,
02250                                                   const Type& object)
02251 {
02252   Node  *nodeP = position.nodeP;
02253 
02254   CGAL_multiset_precondition (_is_valid (nodeP));
02255 
02256   // Make sure the replacement does not violate the tree order.
02257   CGAL_multiset_precondition_code (Node *_succP = nodeP->successor());
02258   CGAL_multiset_precondition (_succP == NULL || 
02259                               _succP->color == Node::DUMMY_END ||
02260                               comp_f(object, _succP->object) != LARGER);
02261 
02262   CGAL_multiset_precondition_code (Node *_predP = nodeP->predecessor());
02263   CGAL_multiset_precondition (_predP == NULL || 
02264                               _predP->color == Node::DUMMY_BEGIN ||
02265                               comp_f(object, _predP->object) != SMALLER);
02266   
02267   // Replace the object at nodeP.
02268   nodeP->object = object;
02269 
02270   return;
02271 }
02272      
02273 //---------------------------------------------------------
02274 // Swap the location two objects in the tree, given by their positions.
02275 //
02276 template <class Type, class Compare, typename Allocator>
02277 void Multiset<Type, Compare, Allocator>::swap (iterator pos1,
02278                                                iterator pos2)
02279 {
02280   Node        *node1_P = pos1.nodeP;
02281   Node        *node2_P = pos2.nodeP;
02282 
02283   CGAL_multiset_precondition (_is_valid (node1_P));
02284   CGAL_multiset_precondition (_is_valid (node2_P));
02285 
02286   if (node1_P == node2_P)
02287     return;
02288 
02289   // Make sure the swap does not violate the tree order.
02290   CGAL_multiset_precondition_code (Node *_succ1_P = node1_P->successor());
02291   CGAL_multiset_precondition (! _is_valid (_succ1_P) ||
02292                               comp_f (node2_P->object, 
02293                                       _succ1_P->object) != LARGER);
02294 
02295   CGAL_multiset_precondition_code (Node *_pred1_P = node1_P->predecessor());
02296   CGAL_multiset_precondition (! _is_valid (_pred1_P) ||
02297                               comp_f (node2_P->object, 
02298                                       _pred1_P->object) != SMALLER);
02299 
02300   CGAL_multiset_precondition_code (Node *_succ2_P = node2_P->successor());
02301   CGAL_multiset_precondition (! _is_valid (_succ2_P) ||
02302                               comp_f (node1_P->object, 
02303                                       _succ2_P->object) != LARGER);
02304 
02305   CGAL_multiset_precondition_code (Node *_pred2_P = node2_P->predecessor());
02306   CGAL_multiset_precondition (! _is_valid (_pred2_P) ||
02307                               comp_f (node1_P->object, 
02308                                       _pred2_P->object) != SMALLER);
02309 
02310   // Perform the swap.
02311   if (node1_P->parentP == node2_P->parentP)
02312     _swap_siblings (node1_P, node2_P);
02313   else
02314     _swap (node1_P, node2_P);
02315 
02316   return;
02317 }
02318 
02319 //---------------------------------------------------------
02320 // Check if the tree is a valid one.
02321 //
02322 template <class Type, class Compare, typename Allocator>
02323 bool Multiset<Type, Compare, Allocator>::is_valid () const
02324 {
02325   if (rootP == NULL)
02326   {
02327     // If there is no root, make sure that the tree is empty.
02328     if (iSize != 0 || iBlackHeight != 0)
02329       return (false);
02330 
02331     if (beginNode.parentP != NULL || endNode.parentP != NULL)
02332       return (false);
02333 
02334     return (true);
02335   }
02336 
02337   // Check the validity of the fictitious nodes.
02338   if (beginNode.parentP == NULL || beginNode.parentP->leftP != &beginNode)
02339     return (false);
02340 
02341   if (endNode.parentP == NULL || endNode.parentP->rightP != &endNode)
02342     return (false);
02343 
02344   // Check recursively whether the tree is valid.
02345   size_t           iComputedSize;
02346   size_t           iComputedBHeight;
02347 
02348   if (! _sub_is_valid (rootP, iComputedSize, iComputedBHeight))
02349     return (false);
02350 
02351   // Make sure the tree properties are correct.
02352   if (iSize != 0)
02353   {
02354     if (iSize != iComputedSize)
02355       return (false);
02356   }
02357   else
02358   {
02359     // Assign the computed size.
02360     Self  *myThis = const_cast<Self*> (this);
02361     myThis->iSize = iComputedSize;
02362   }
02363 
02364   if (iBlackHeight != iComputedBHeight)
02365     return (false);
02366 
02367   // If we reached here, the entire tree is valid.
02368   return (true);
02369 }
02370 
02371 //---------------------------------------------------------
02372 // Get the height of the tree.
02373 //
02374 template <class Type, class Compare, typename Allocator>
02375 size_t Multiset<Type, Compare, Allocator>::height () const
02376 {
02377   if (rootP == NULL)
02378     // Empty tree.
02379     return (0);
02380 
02381   // Return the height of the root's sub-tree (the entire tree).
02382   return (_sub_height (rootP));
02383 }
02384 
02385 //---------------------------------------------------------
02386 // Catenate the tree with another given tree.
02387 //
02388 template <class Type, class Compare, typename Allocator>
02389 void Multiset<Type, Compare, Allocator>::catenate (Self& tree)
02390 {
02391   // Get the maximal node in our tree and the minimal node in the other tree.
02392   Node    *max1_P = endNode.parentP;
02393   Node    *min2_P = tree.beginNode.parentP;
02394 
02395   if (min2_P == NULL)
02396   {
02397     // The other tree is empty - nothing to do.
02398     CGAL_multiset_assertion (tree.rootP == NULL);
02399     return;
02400   }
02401   else if (max1_P == NULL)
02402   {
02403     // Our tree is empty: Copy all other tree properties to our tree.
02404     CGAL_multiset_assertion (rootP == NULL);
02405 
02406     _shallow_assign (tree);
02407     return;
02408   }
02409 
02410   // Make sure that the minimal object in the other tree is not less than the
02411   // maximal object in our tree.
02412   CGAL_multiset_precondition (comp_f (max1_P->object, 
02413                                       min2_P->object) != LARGER);
02414 
02415   // Make sure both tree roots black.
02416   CGAL_multiset_assertion (_is_black (rootP));
02417   CGAL_multiset_assertion (_is_black (tree.rootP));
02418 
02419   // Splice max1_P (or min2_P) from its tree, but without deleting it.
02420   Node*   auxP = NULL;
02421 
02422   if (max1_P != rootP)
02423   {
02424     // Splice max1_P from its current poisition in our tree.
02425     // We know it is has no right child, so we just have to connect its
02426     // left child with its parent.
02427     max1_P->parentP->rightP = max1_P->leftP;
02428 
02429     if (_is_valid (max1_P->leftP))
02430       max1_P->leftP->parentP = max1_P->parentP;
02431 
02432     // If max1_P is a black node, we have to fixup our tree.
02433     if (max1_P->color == Node::BLACK)
02434       _remove_fixup (max1_P->leftP, max1_P->parentP);
02435 
02436     auxP = max1_P;
02437   }
02438   else if (min2_P != tree.rootP)
02439   {
02440     // Splice min2_P from its current poisition in the other tree.
02441     // We know it is has no left child, so we just have to connect its
02442     // right child with its parent.
02443     if (min2_P->parentP != NULL)
02444     {
02445       min2_P->parentP->leftP = min2_P->rightP;
02446 
02447       if (_is_valid (min2_P->rightP))
02448         min2_P->rightP->parentP = min2_P->parentP;
02449 
02450       // If min2_P is a black node, we have to fixup the other tree.
02451       if (min2_P->color == Node::BLACK)
02452         tree._remove_fixup (min2_P->rightP, min2_P->parentP);
02453     }
02454 
02455     auxP = min2_P;
02456   }
02457   else
02458   {
02459     // Both nodes are root nodes: Assign min2_P as the right child of the
02460     // root and color it red.
02461     rootP->rightP = min2_P;
02462     min2_P->parentP = rootP;
02463     min2_P->color = Node::RED;
02464     min2_P->leftP = NULL;
02465 
02466     if (! _is_valid (min2_P->rightP))
02467     {
02468       // The other tree is of size 1 - set min2_P as the tree maximum.
02469       min2_P->rightP = &endNode;
02470       endNode.parentP = min2_P;
02471     }
02472     else
02473     {
02474       // The other tree is of size 2 - fixup from min2_P's right child and set
02475       // it as the tree maximum.
02476       _insert_fixup (min2_P->rightP);
02477       min2_P->rightP->rightP = &endNode;
02478       endNode.parentP = min2_P->rightP;
02479     }
02480 
02481     if (iSize > 0 && tree.iSize > 0)
02482       iSize += tree.iSize;
02483     else
02484       iSize = 0;
02485 
02486     // Clear the other tree (without actually deallocating the nodes).
02487     tree._shallow_clear();
02488 
02489     return;
02490   }
02491 
02492   // Mark that the maximal node in our tree is no longer the maximum.
02493   if (endNode.parentP != NULL)
02494     endNode.parentP->rightP = NULL;
02495 
02496   // Mark that the minimal node in the other tree is no longer the minimum.
02497   if (tree.beginNode.parentP != NULL)
02498     tree.beginNode.parentP->leftP = NULL;
02499 
02500   // Locate node1_P along the rightmost path in our tree and node2_P along the
02501   // leftmost path in the other tree, both having the same black-height.
02502   Node    *node1_P = rootP;
02503   Node    *node2_P = tree.rootP;
02504   size_t   iCurrBHeight;
02505 
02506   if (iBlackHeight <= tree.iBlackHeight)
02507   {
02508     // The other tree is taller (or both trees have the same height):
02509     // Go down the leftmost path of the other tree and locate node2_P.
02510     node2_P = tree.rootP;
02511     iCurrBHeight = tree.iBlackHeight;
02512     while (iCurrBHeight > iBlackHeight)
02513     {
02514       if (node2_P->color == Node::BLACK)
02515         iCurrBHeight--;
02516       node2_P = node2_P->leftP;
02517     }
02518 
02519     if (_is_red (node2_P))
02520       node2_P = node2_P->leftP;
02521     CGAL_multiset_assertion (_is_valid (node2_P));
02522   }
02523   else
02524   {
02525     // Our tree is taller:
02526     // Go down the rightmost path of our tree and locate node1_P.
02527     node1_P = rootP;
02528     iCurrBHeight = iBlackHeight;
02529     while (iCurrBHeight > tree.iBlackHeight)
02530     {
02531       if (node1_P->color == Node::BLACK)
02532         iCurrBHeight--;
02533       node1_P = node1_P->rightP;
02534     }
02535 
02536     if (_is_red (node1_P))
02537       node1_P = node1_P->rightP;
02538     CGAL_multiset_assertion (_is_valid (node2_P));
02539   }
02540 
02541   // Check which one of the tree roots have we reached.
02542   Node    *newRootP = NULL;
02543   Node    *parentP;
02544 
02545   if (node1_P == rootP)
02546   {
02547     // We know that node2_P has the same number of black roots from it to
02548     // the minimal tree node as the number of black nodes from our tree root
02549     // to any of its leaves. We make rootP and node2_P siblings by moving
02550     // auxP to be their parent.
02551     parentP = node2_P->parentP;
02552 
02553     if (parentP == NULL)
02554     {
02555       // Make auxP the root of the catenated tree.
02556       newRootP = auxP;
02557     }
02558     else
02559     {
02560       // The catenated tree will be rooted at the other tree's root.
02561       newRootP = tree.rootP;
02562 
02563       // Move auxP as the left child of parentP.
02564       parentP->leftP = auxP;
02565     }
02566   }
02567   else
02568   {
02569     // We know that node1_P has the same number of black roots from it to
02570     // the maximal tree node as the number of black nodes from the other tree
02571     // root to any of its leaves. We make tree.rootP and node1_P siblings by
02572     // moving auxP to be their parent.
02573     parentP = node1_P->parentP;
02574 
02575     CGAL_multiset_assertion (parentP != NULL);
02576 
02577     // The catenated tree will be rooted at the current root of our tree.
02578     newRootP = rootP;
02579 
02580     // Move auxP as the right child of parentP.
02581     parentP->rightP = auxP;
02582   }
02583 
02584   // Move node1_P to be the left child of auxP, and node2_P to be its
02585   // right child. We also color this node red.
02586   auxP->parentP = parentP;
02587   auxP->color = Node::RED;
02588   auxP->leftP = node1_P;
02589   auxP->rightP = node2_P;
02590 
02591   node1_P->parentP = auxP;
02592   node2_P->parentP = auxP;
02593 
02594   // Set the catenated tree properties.
02595   if (rootP != newRootP)
02596   {
02597     // Take the black-height of the other tree.
02598     iBlackHeight = tree.iBlackHeight;
02599     rootP = newRootP;
02600   }
02601 
02602   if (iSize > 0 && tree.iSize > 0)
02603     iSize += tree.iSize;
02604   else
02605     iSize = 0;
02606 
02607   // Set the new maximal node in the tree (the minimal node remains unchanged).
02608   endNode.parentP = tree.endNode.parentP;
02609   endNode.parentP->rightP = &endNode;
02610 
02611   // Clear the other tree (without actually deallocating the nodes).
02612   tree._shallow_clear();
02613 
02614   // Perform a fixup of the tree invariants. This fixup will also take care
02615   // of updating the black-height of our catenated tree.
02616   _insert_fixup (auxP);
02617 
02618   return;
02619 }
02620 
02621 //---------------------------------------------------------
02622 // Split the tree at a given position, such that it contains all objects
02623 // in the range [begin, position) and all objects in the range
02624 // [position, end) form a new output tree.
02625 //
02626 template <class Type, class Compare, typename Allocator>
02627 void Multiset<Type, Compare, Allocator>::split (iterator position,
02628                                                 Self& tree)
02629 {
02630   CGAL_multiset_precondition (tree.empty());
02631 
02632   // Check the extremal cases.
02633   if (position == begin())
02634   {
02635     // The tree should be copied to the output tree.
02636     tree._shallow_assign (*this);
02637     return;
02638   }
02639   else if (position == end())
02640   {
02641     // Nothing to do - all objects should remain in our tree.
02642     return;
02643   }
02644 
02645   // Prepare a vector describing the path from the given node to the tree
02646   // root (where SMALLER designates a left turn and LARGER designates a
02647   // right turn). Note that the length of this path (the depth of nodeP)
02648   // is at most twice the black-height of the tree.
02649   Node    *nodeP = position.nodeP;
02650 
02651   CGAL_multiset_precondition (_is_valid (nodeP));
02652 
02653   Node              *currP = nodeP;
02654   Comparison_result *path = new Comparison_result [2 * iBlackHeight];
02655   int                depth = 0;
02656 
02657   path[depth] = EQUAL;
02658   while (currP->parentP != NULL)
02659   {
02660     depth++;
02661     if (currP == currP->parentP->leftP)
02662       path[depth] = SMALLER;
02663     else
02664       path[depth] = LARGER;
02665 
02666     currP = currP->parentP;
02667   }
02668   CGAL_multiset_assertion (currP == rootP);
02669 
02670   // Now go down the path and split the tree accordingly. We also keep
02671   // track of the black-height of the current node.
02672   size_t  iCurrBHeight = iBlackHeight;
02673   Self    leftTree;
02674   size_t  iLeftBHeight = 0;
02675   Node   *spineLeftP = NULL;
02676   Node   *auxLeftP = NULL;
02677   Self    rightTree;
02678   size_t  iRightBHeight = 0;
02679   Node   *spineRightP = NULL;
02680   Node   *auxRightP = NULL;
02681   Node   *childP = NULL;
02682   Node   *nextP = NULL;
02683 
02684   while (depth >= 0)
02685   {
02686     CGAL_multiset_assertion (_is_valid (currP));
02687 
02688     // If we encounter a black node, the black-height of both its left and
02689     // right subtrees is decremented.
02690     if (_is_black (currP))
02691       iCurrBHeight--;
02692 
02693     // Check in which direction we have to go.
02694     if (path[depth] != LARGER)
02695     {
02696       // We go left, so currP and its entire right sub-tree (T_r) should be
02697       // included in the right split tree.
02698       //
02699       //              (.) currP           .
02700       //              / \                 .
02701       //             /   \                .
02702       //           (.)    T_r             .
02703       //
02704       // This also covers that case where currP is the split node (nodeP).
02705       childP = currP->rightP;
02706       nextP = currP->leftP;
02707 
02708       if (_is_valid (childP) && rightTree.rootP == NULL)
02709       {
02710         // Assing T_r to rightTree.
02711         rightTree.rootP = childP;
02712         rightTree.iBlackHeight = iCurrBHeight;
02713 
02714         // Make sure the root of rightTree is black.
02715         rightTree.rootP->parentP = NULL;
02716         if (_is_red (rightTree.rootP))
02717         {
02718           rightTree.rootP->color = Node::BLACK;
02719           rightTree.iBlackHeight++;
02720         }
02721 
02722         // We store a black node along the leftmost spine of rightTree whose
02723         // black-hieght is exactly iRightBHeight.
02724         iRightBHeight = rightTree.iBlackHeight;
02725         spineRightP = rightTree.rootP;
02726       }
02727       else if (_is_valid (childP))
02728       {
02729         // Catenate T_r with the current rightTree.
02730         CGAL_multiset_assertion (_is_valid (spineRightP) && 
02731                                  _is_valid(auxRightP));
02732 
02733         // Make sure the root of T_r is black.
02734         size_t    iCurrRightBHeight = iCurrBHeight;
02735 
02736         if (_is_red (childP))
02737         {
02738           childP->color = Node::BLACK;
02739           iCurrRightBHeight++;
02740         }
02741 
02742         // Go down the leftmost path of rightTree until locating a black
02743         // node whose black height is exactly iCurrRightBHeight.
02744         CGAL_multiset_assertion (iRightBHeight >= iCurrRightBHeight);
02745 
02746         while (iRightBHeight > iCurrRightBHeight)
02747         {
02748           if (spineRightP->color == Node::BLACK)
02749             iRightBHeight--;
02750           spineRightP = spineRightP->leftP;
02751         }
02752 
02753         if (_is_red (spineRightP))
02754           spineRightP = spineRightP->leftP;
02755         CGAL_multiset_assertion (_is_valid (spineRightP));
02756 
02757         // Use the auxiliary node and make it the parent of T_r (which
02758         // becomes its left sub-tree) and spineRightP (which becomes its
02759         // right child). We color the auxiliary node red, as both its
02760         // children are black.
02761         auxRightP->parentP = spineRightP->parentP;
02762         auxRightP->color = Node::RED;
02763         auxRightP->leftP = childP;
02764         auxRightP->rightP = spineRightP;
02765 
02766         if (auxRightP->parentP != NULL)
02767           auxRightP->parentP->leftP = auxRightP;
02768         else
02769           rightTree.rootP = auxRightP;
02770 
02771         childP->parentP = auxRightP;
02772         spineRightP->parentP = auxRightP;
02773 
02774         // Perform a fixup on the right tree.
02775         rightTree._insert_fixup (auxRightP);
02776         auxRightP = NULL;
02777 
02778         // Note that childP is now located on the leftmost spine of
02779         // rightTree and its black-height is exactly iCurrRightBHeight.
02780         iRightBHeight = iCurrRightBHeight;
02781         spineRightP = childP;
02782       }
02783 
02784       // In case we have an auxiliary right node that has not been inserted
02785       // into the right tree, insert it now.
02786       if (auxRightP != NULL)
02787       {
02788         if (rightTree.rootP != NULL)
02789         {
02790           // The right tree is not empty. Traverse its leftmost spine to
02791           // locate the parent of auxRightP.
02792           while (_is_valid (spineRightP->leftP))
02793             spineRightP = spineRightP->leftP;
02794 
02795           auxRightP->parentP = spineRightP;
02796           auxRightP->color = Node::RED;
02797           auxRightP->rightP = NULL;
02798           auxRightP->leftP = NULL;
02799 
02800           spineRightP->leftP = auxRightP;
02801 
02802           // Perform a fixup on the right tree, following the insertion of
02803           // the auxiliary right node.
02804           rightTree._insert_fixup (auxRightP);
02805         }
02806         else
02807         {
02808           // auxRightP is the only node in the current right tree.
02809           rightTree.rootP = auxRightP;
02810           rightTree.iBlackHeight = 1;
02811 
02812           auxRightP->parentP = NULL;
02813           auxRightP->color = Node::BLACK;
02814           auxRightP->rightP = NULL;
02815           auxRightP->leftP = NULL;
02816         }
02817 
02818         // Assign spineRightP to be the auxiliary node.
02819         spineRightP = auxRightP;
02820         iRightBHeight = (_is_black (spineRightP)) ? 1 : 0;
02821         auxRightP = NULL;
02822       }
02823 
02824       // Mark currP as the auxiliary right node.
02825       auxRightP = currP;
02826     }
02827     
02828     if (path[depth] != SMALLER)
02829     {
02830       // We go right, so currP and its entire left sub-tree (T_l) should be
02831       // included in the left split tree.
02832       //
02833       //              (.) currP           .
02834       //              / \                 .
02835       //             /   \                .
02836       //          T_l    (.)              .
02837       //
02838       // An exception to this rule is when currP is the split node (nodeP),
02839       // so it should not be included in the left tree.
02840       childP = currP->leftP;
02841       nextP = currP->rightP;
02842 
02843       if (_is_valid (childP) && leftTree.rootP == NULL)
02844       {
02845         // Assing T_l to leftTree.
02846         leftTree.rootP = childP;
02847         leftTree.iBlackHeight = iCurrBHeight;
02848 
02849         // Make sure the root of leftTree is black.
02850         leftTree.rootP->parentP = NULL;
02851         if (_is_red (leftTree.rootP))
02852         {
02853           leftTree.rootP->color = Node::BLACK;
02854           leftTree.iBlackHeight++;
02855         }
02856 
02857         // We store a black node along the rightmost spine of leftTree whose
02858         // black-hieght is exactly iLeftBHeight.
02859         iLeftBHeight = leftTree.iBlackHeight;
02860         spineLeftP = leftTree.rootP;
02861       }
02862       else if (_is_valid (childP))
02863       {
02864         // Catenate T_l with the current leftTree.
02865         CGAL_multiset_assertion (_is_valid (spineLeftP) && 
02866                                  _is_valid(auxLeftP));
02867 
02868         // Make sure the root of T_l is black.
02869         size_t    iCurrLeftBHeight = iCurrBHeight;
02870 
02871         if (_is_red (childP))
02872         {
02873           childP->color = Node::BLACK;
02874           iCurrLeftBHeight++;
02875         }
02876 
02877         // Go down the rightmost path of leftTree until locating a black
02878         // node whose black height is exactly iCurrLeftBHeight.
02879         CGAL_multiset_assertion (iLeftBHeight >= iCurrLeftBHeight);
02880 
02881         while (iLeftBHeight > iCurrLeftBHeight)
02882         {
02883           if (spineLeftP->color == Node::BLACK)
02884             iLeftBHeight--;
02885           spineLeftP = spineLeftP->rightP;
02886         }
02887 
02888         if (_is_red (spineLeftP))
02889           spineLeftP = spineLeftP->rightP;
02890         CGAL_multiset_assertion (_is_valid (spineLeftP));
02891 
02892         // Use the auxiliary node and make it the parent of T_l (which
02893         // becomes its right sub-tree) and spineLeftP (which becomes its
02894         // left child). We color the auxiliary node red, as both its
02895         // children are black.
02896         auxLeftP->parentP = spineLeftP->parentP;
02897         auxLeftP->color = Node::RED;
02898         auxLeftP->leftP = spineLeftP;
02899         auxLeftP->rightP = childP;
02900 
02901         if (auxLeftP->parentP != NULL)
02902           auxLeftP->parentP->rightP = auxLeftP;
02903         else
02904           leftTree.rootP = auxLeftP;
02905 
02906         childP->parentP = auxLeftP;
02907         spineLeftP->parentP = auxLeftP;
02908 
02909         // Perform a fixup on the left tree.
02910         leftTree._insert_fixup (auxLeftP);
02911         auxLeftP = NULL;
02912 
02913         // Note that childP is now located on the rightmost spine of
02914         // leftTree and its black-height is exactly iCurrLeftBHeight.
02915         iLeftBHeight = iCurrLeftBHeight;
02916         spineLeftP = childP;
02917       }
02918 
02919       // In case we have an auxiliary left node that has not been inserted
02920       // into the left tree, insert it now.
02921       if (auxLeftP != NULL)
02922       {
02923         if (leftTree.rootP != NULL)
02924         {
02925           // The left tree is not empty. Traverse its rightmost spine to
02926           // locate the parent of auxLeftP.
02927           while (_is_valid (spineLeftP->rightP))
02928             spineLeftP = spineLeftP->rightP;
02929 
02930           auxLeftP->parentP = spineLeftP;
02931           auxLeftP->color = Node::RED;
02932           auxLeftP->rightP = NULL;
02933           auxLeftP->leftP = NULL;
02934 
02935           spineLeftP->rightP = auxLeftP;
02936 
02937           // Perform a fixup on the left tree, following the insertion of
02938           // the auxiliary left node.
02939           leftTree._insert_fixup (auxLeftP);
02940         }
02941         else
02942         {
02943           // auxLeftP is the only node in the left tree.
02944           leftTree.rootP = auxLeftP;
02945           leftTree.iBlackHeight = 1;
02946 
02947           auxLeftP->parentP = NULL;
02948           auxLeftP->color = Node::BLACK;
02949           auxLeftP->rightP = NULL;
02950           auxLeftP->leftP = NULL;
02951         }
02952 
02953         // Assign spineLeftP to be the auxiliary node.
02954         spineLeftP = auxLeftP;
02955         iLeftBHeight = (_is_black (spineLeftP)) ? 1 : 0;
02956         auxLeftP = NULL;
02957       }
02958 
02959       // Mark currP as the auxiliary right node.
02960       if (depth > 0)
02961         auxLeftP = currP;
02962     }
02963 
02964     // Proceed to the next step in the path.
02965     currP = nextP;
02966     depth--;
02967   }
02968 
02969   // It is now possible to free the path.
02970   delete[] path;
02971 
02972   CGAL_multiset_assertion (auxLeftP == NULL && auxRightP == nodeP);
02973 
02974   // Fix the properties of the left tree: We know its minimal node is the
02975   // same as the current minimum.
02976   leftTree.beginNode.parentP = beginNode.parentP;
02977   leftTree.beginNode.parentP->leftP = &(leftTree.beginNode);
02978 
02979   // Traverse the rightmost path of the left tree to find the its maximum.
02980   CGAL_multiset_assertion (_is_valid (spineLeftP));
02981 
02982   while (_is_valid (spineLeftP->rightP))
02983     spineLeftP = spineLeftP->rightP;
02984 
02985   leftTree.endNode.parentP = spineLeftP;
02986   spineLeftP->rightP = &(leftTree.endNode);
02987 
02988   // Fix the properties of the right tree: We know its maximal node is the
02989   // same as the current maximum.
02990   rightTree.endNode.parentP = endNode.parentP;
02991   rightTree.endNode.parentP->rightP = &(rightTree.endNode);
02992 
02993   // We still have to insert the split node as the minimum node of the right
02994   // tree (we can traverse its leftmost path to find its parent).
02995   if (rightTree.rootP != NULL)
02996   {
02997     while (_is_valid (spineRightP->leftP))
02998       spineRightP = spineRightP->leftP;
02999 
03000     nodeP->parentP = spineRightP;
03001     nodeP->color = Node::RED;
03002     nodeP->rightP = NULL;
03003     nodeP->leftP = NULL;
03004 
03005     spineRightP->leftP = nodeP;
03006 
03007     // Perform a fixup on the right tree, following the insertion of the
03008     // leftmost node.
03009     rightTree._insert_fixup (nodeP);
03010   }
03011   else
03012   {
03013     // nodeP is the only node in the right tree.
03014     rightTree.rootP = nodeP;
03015     rightTree.iBlackHeight = 1;
03016 
03017     nodeP->parentP = NULL;
03018     nodeP->color = Node::BLACK;
03019     nodeP->rightP = NULL;
03020     nodeP->leftP = NULL;
03021 
03022     // In this case we also know the tree sizes:
03023     leftTree.iSize = iSize - 1;
03024     rightTree.iSize = 1;
03025   }
03026 
03027   // Set nodeP as the minimal node is the right tree.
03028   rightTree.beginNode.parentP = nodeP;
03029   nodeP->leftP = &(rightTree.beginNode);
03030 
03031   // Assign leftTree to (*this) and rightTree to the output tree.
03032   _shallow_assign (leftTree);
03033 
03034   tree.clear();
03035   tree._shallow_assign (rightTree);
03036 
03037   return;
03038 }
03039 
03040 //---------------------------------------------------------
03041 // Move the contents of one tree to another without actually duplicating
03042 // the nodes. This operation also clears the copied tree.
03043 //
03044 template <class Type, class Compare, typename Allocator>
03045 void Multiset<Type, Compare, Allocator>::_shallow_assign (Self& tree)
03046 {
03047   // Copy the assigned tree properties.
03048   rootP = tree.rootP;
03049   iSize = tree.iSize;
03050   iBlackHeight = tree.iBlackHeight;
03051 
03052   // Properly mark the minimal and maximal tree nodes.
03053   beginNode.parentP = tree.beginNode.parentP;
03054   
03055   if (beginNode.parentP != NULL)
03056     beginNode.parentP->leftP = &beginNode;
03057     
03058   endNode.parentP = tree.endNode.parentP;
03059   
03060   if (endNode.parentP != NULL)
03061     endNode.parentP->rightP = &endNode;
03062 
03063   // Clear the other tree (without actually deallocating the nodes).
03064   tree._shallow_clear();
03065 
03066   return;
03067 }
03068 
03069 //---------------------------------------------------------
03070 // Clear the properties of the tree, without actually deallocating its nodes.
03071 //
03072 template <class Type, class Compare, typename Allocator>
03073 void Multiset<Type, Compare, Allocator>::_shallow_clear ()
03074 {
03075   rootP = NULL;
03076   iSize = 0;
03077   iBlackHeight = 0;
03078   beginNode.parentP = NULL;
03079   endNode.parentP = NULL;
03080 
03081   return;
03082 }
03083 
03084 //---------------------------------------------------------
03085 // Remove the given tree node.
03086 //
03087 template <class Type, class Compare, typename Allocator>
03088 void Multiset<Type, Compare, Allocator>::_remove_at (Node* nodeP)
03089 {
03090   CGAL_multiset_precondition (_is_valid (nodeP));
03091 
03092   if (nodeP == rootP && 
03093       ! _is_valid (rootP->leftP) && ! _is_valid (rootP->rightP))
03094   {
03095     // In case of deleting the single object stored in the tree, free the root,
03096     // thus emptying the tree.
03097     _deallocate_node (rootP);
03098 
03099     rootP = NULL;
03100     beginNode.parentP = NULL;
03101     endNode.parentP = NULL;
03102     iSize = 0;
03103     iBlackHeight = 0;
03104     
03105     return;
03106   }
03107 
03108   // Remove the given node from the tree.
03109   if (_is_valid (nodeP->leftP) && _is_valid (nodeP->rightP))
03110   {
03111     // If the node we want to remove has two children, find its successor,
03112     // which is the leftmost child in its right sub-tree and has at most
03113     // one child (it may have a right child).
03114     Node    *succP = _sub_minimum (nodeP->rightP);
03115     CGAL_multiset_assertion (_is_valid (succP));
03116 
03117     // Now physically swap nodeP and its successor. Notice this may temporarily
03118     // violate the tree properties, but we are going to remove nodeP anyway.
03119     // This way we have moved nodeP to a position were it is more convinient
03120     // to delete it.
03121     _swap (nodeP, succP);
03122   }
03123 
03124   // At this stage, the node we are going to remove has at most one child.
03125   Node        *childP = NULL;
03126 
03127   if (_is_valid (nodeP->leftP))
03128   {
03129     CGAL_multiset_assertion (! _is_valid (nodeP->rightP));
03130     childP = nodeP->leftP;
03131   }
03132   else
03133   {
03134     childP = nodeP->rightP;
03135   }
03136 
03137   // Splice out the node to be removed, by linking its parent straight to the
03138   // removed node's single child.
03139   if (_is_valid (childP))
03140     childP->parentP = nodeP->parentP;
03141 
03142   if (nodeP->parentP == NULL)
03143   {
03144     // If we are deleting the root, make the child the new tree node.
03145     rootP = childP;
03146 
03147     // If the deleted root is black, decrement the black height of the tree.
03148     if (nodeP->color == Node::BLACK)
03149       iBlackHeight--;
03150   }
03151   else
03152   {
03153     // Link the removed node parent to its child.
03154     if (nodeP == nodeP->parentP->leftP)
03155     {
03156       nodeP->parentP->leftP = childP;
03157     }
03158     else
03159     {
03160       nodeP->parentP->rightP = childP;
03161     }
03162   }
03163 
03164   // Fix-up the red-black properties that may have been damaged: If we have
03165   // just removed a black node, the black-height property is no longer valid.
03166   if (nodeP->color == Node::BLACK)
03167     _remove_fixup (childP, nodeP->parentP);
03168 
03169   // In case we delete the tree minimum of maximum, update the relevant
03170   // pointers.
03171   if (nodeP == beginNode.parentP)
03172   {
03173     beginNode.parentP = nodeP->successor();
03174 
03175     if (_is_valid (beginNode.parentP))
03176       beginNode.parentP->leftP = &beginNode;
03177     else
03178       beginNode.parentP = NULL;
03179   }
03180   else if (nodeP == endNode.parentP)
03181   {
03182     endNode.parentP = nodeP->predecessor();
03183 
03184     if (_is_valid (endNode.parentP))
03185       endNode.parentP->rightP = &endNode;
03186     else
03187       endNode.parentP = NULL;
03188   }
03189 
03190   // Delete the unnecessary node.
03191   _deallocate_node (nodeP);
03192 
03193   // Decrement the number of objects in the tree.
03194   if (iSize > 0)
03195     iSize--;
03196 
03197   return;
03198 }
03199 
03200 //---------------------------------------------------------
03201 // Swap the location two nodes in the tree.
03202 //
03203 template <class Type, class Compare, typename Allocator>
03204 void Multiset<Type, Compare, Allocator>::_swap (Node* node1_P,
03205                                                 Node* node2_P)
03206 {
03207   CGAL_multiset_assertion (_is_valid (node1_P));
03208   CGAL_multiset_assertion (_is_valid (node2_P));
03209 
03210   // Store the properties of the first node.
03211   typename Node::Node_color   color1 = node1_P->color;
03212   Node        *parent1_P = node1_P->parentP;
03213   Node        *right1_P = node1_P->rightP;
03214   Node        *left1_P = node1_P->leftP;
03215   
03216   // Copy the properties of the second node to the first node.
03217   node1_P->color = node2_P->color;
03218 
03219   if (node1_P != node2_P->parentP)
03220   {
03221     if (node2_P->parentP == NULL)
03222     {
03223       rootP = node1_P;
03224     }
03225     else
03226     {
03227       if (node2_P->parentP->leftP == node2_P)
03228         node2_P->parentP->leftP = node1_P;
03229       else
03230         node2_P->parentP->rightP = node1_P;
03231     }
03232 
03233     node1_P->parentP = node2_P->parentP;
03234   }
03235   else
03236   {
03237     node1_P->parentP = node2_P;
03238   }
03239 
03240   if (node1_P != node2_P->rightP)
03241   {
03242     if (_is_valid (node2_P->rightP))
03243       node2_P->rightP->parentP = node1_P;
03244 
03245     node1_P->rightP = node2_P->rightP;
03246   }
03247   else
03248   {
03249     node1_P->rightP = node2_P;
03250   }
03251 
03252   if (node1_P != node2_P->leftP)
03253   {
03254     if (_is_valid (node2_P->leftP))
03255       node2_P->leftP->parentP = node1_P;
03256 
03257     node1_P->leftP = node2_P->leftP;
03258   }
03259   else
03260   {
03261     node1_P->leftP = node2_P;
03262   }
03263 
03264   // Copy the stored properties of the first node to the second node.
03265   node2_P->color = color1;
03266 
03267   if (node2_P != parent1_P)
03268   {
03269     if (parent1_P == NULL)
03270     {
03271       rootP = node2_P;
03272     }
03273     else
03274     {
03275       if (parent1_P->leftP == node1_P)
03276         parent1_P->leftP = node2_P;
03277       else
03278         parent1_P->rightP = node2_P;
03279     }
03280 
03281     node2_P->parentP = parent1_P;
03282   }
03283   else
03284   {
03285     node2_P->parentP = node1_P;
03286   }
03287 
03288   if (node2_P != right1_P)
03289   {
03290     if (_is_valid (right1_P))
03291       right1_P->parentP = node2_P;
03292 
03293     node2_P->rightP = right1_P;
03294   }
03295   else
03296   {
03297     node2_P->rightP = node1_P;
03298   }
03299 
03300   if (node2_P != left1_P)
03301   {
03302     if (_is_valid (left1_P))
03303       left1_P->parentP = node2_P;
03304 
03305     node2_P->leftP = left1_P;
03306   }
03307   else
03308   {
03309     node2_P->leftP = node1_P;
03310   }
03311 
03312   // If one of the swapped nodes used to be the tree minimum, update
03313   // the properties of the fictitious before-the-begin node.
03314   if (beginNode.parentP == node1_P)
03315   {
03316     beginNode.parentP = node2_P;
03317     node2_P->leftP = &beginNode;
03318   }
03319   else if (beginNode.parentP == node2_P)
03320   {
03321     beginNode.parentP = node1_P;
03322     node1_P->leftP = &beginNode;
03323   }
03324 
03325   // If one of the swapped nodes used to be the tree maximum, update
03326   // the properties of the fictitious past-the-end node.
03327   if (endNode.parentP == node1_P)
03328   {
03329     endNode.parentP = node2_P;
03330     node2_P->rightP = &endNode;
03331   }
03332   else if (endNode.parentP == node2_P)
03333   {
03334     endNode.parentP = node1_P;
03335     node1_P->rightP = &endNode;
03336   }
03337 
03338   return;
03339 }
03340 
03341 //---------------------------------------------------------
03342 // Swap the location two sibling nodes in the tree.
03343 //
03344 template <class Type, class Compare, typename Allocator>
03345 void Multiset<Type, Compare, Allocator>::_swap_siblings (Node* node1_P,
03346                                                          Node* node2_P)
03347 {
03348   CGAL_multiset_assertion (_is_valid (node1_P));
03349   CGAL_multiset_assertion (_is_valid (node2_P));
03350 
03351   // Store the properties of the first node.
03352   typename Node::Node_color   color1 = node1_P->color;
03353   Node        *right1_P = node1_P->rightP;
03354   Node        *left1_P = node1_P->leftP;
03355   
03356   // Copy the properties of the second node to the first node.
03357   node1_P->color = node2_P->color;
03358 
03359   node1_P->rightP = node2_P->rightP;
03360   if (_is_valid (node1_P->rightP))
03361     node1_P->rightP->parentP = node1_P;
03362 
03363   node1_P->leftP = node2_P->leftP;
03364   if (_is_valid (node1_P->leftP))
03365     node1_P->leftP->parentP = node1_P;
03366 
03367   // Copy the stored properties of the first node to the second node.
03368   node2_P->color = color1;
03369 
03370   node2_P->rightP = right1_P;
03371   if (_is_valid (node2_P->rightP))
03372     node2_P->rightP->parentP = node2_P;
03373 
03374   node2_P->leftP = left1_P;
03375   if (_is_valid (node2_P->leftP))
03376     node2_P->leftP->parentP = node2_P;
03377 
03378   // Swap the children of the common parent node.
03379   Node        *parent_P = node1_P->parentP;
03380   Node        *temp;
03381 
03382   CGAL_multiset_assertion (parent_P == node2_P->parentP);
03383 
03384   temp = parent_P->leftP;
03385   parent_P->leftP = parent_P->rightP;
03386   parent_P->rightP = temp;
03387 
03388   // If one of the swapped nodes used to be the tree minimum, update
03389   // the properties of the fictitious before-the-begin node.
03390   if (beginNode.parentP == node1_P)
03391   {
03392     beginNode.parentP = node2_P;
03393     node2_P->leftP = &beginNode;
03394   }
03395   else if (beginNode.parentP == node2_P)
03396   {
03397     beginNode.parentP = node1_P;
03398     node1_P->leftP = &beginNode;
03399   }
03400 
03401   // If one of the swapped nodes used to be the tree maximum, update
03402   // the properties of the fictitious past-the-end node.
03403   if (endNode.parentP == node1_P)
03404   {
03405     endNode.parentP = node2_P;
03406     node2_P->rightP = &endNode;
03407   }
03408   else if (endNode.parentP == node2_P)
03409   {
03410     endNode.parentP = node1_P;
03411     node1_P->rightP = &endNode;
03412   }
03413 
03414   return;
03415 }
03416 
03417 //---------------------------------------------------------
03418 // Calculate the height of the subtree spanned by a given node.
03419 //
03420 template <class Type, class Compare, typename Allocator>
03421 size_t Multiset<Type, Compare, Allocator>::_sub_height
03422     (const Node* nodeP) const
03423 {
03424   CGAL_multiset_assertion (_is_valid (nodeP));
03425 
03426   // Recursively calculate the heights of the left and right sub-trees.
03427   size_t   iRightHeight = 0;
03428   size_t   iLeftHeight = 0;
03429 
03430   if (_is_valid (nodeP->rightP))
03431     iRightHeight = _sub_height (nodeP->rightP);
03432 
03433   if (_is_valid (nodeP->leftP))
03434     iLeftHeight = _sub_height (nodeP->leftP);
03435 
03436   // Return the maximal child sub-height + 1 (the current node).
03437   return ((iRightHeight > iLeftHeight) ? (iRightHeight + 1) :
03438                                          (iLeftHeight + 1));
03439 }
03440 
03441 //---------------------------------------------------------
03442 // Calculate the height of the subtree spanned by a given node.
03443 //
03444 template <class Type, class Compare, typename Allocator>
03445 bool Multiset<Type, Compare, Allocator>::_sub_is_valid
03446     (const Node* nodeP,
03447      size_t& sub_size,
03448      size_t& sub_bh) const
03449 {
03450   // Make sure that the node is valid.
03451   if (! _is_valid (nodeP))
03452     return (false);
03453 
03454   // If the node is red, make sure that both it children are black (note that
03455   // NULL nodes are also considered to be black).
03456   if (_is_red (nodeP) &&
03457       (! _is_black (nodeP->rightP) || ! _is_black (nodeP->leftP)))
03458   {
03459     return (false);
03460   }
03461 
03462   // Recursively calculate the black heights of the left and right sub-trees.
03463   size_t   iBlack = ((nodeP->color == Node::BLACK) ? 1 : 0);
03464   size_t   iLeftSize = 0;
03465   size_t   iLeftBHeight = 0;
03466   size_t   iRightSize = 0;
03467   size_t   iRightBHeight = 0;
03468 
03469   if (_is_valid (nodeP->leftP))
03470   {
03471     // Make sure that the object stored at nodeP is not smaller than the one
03472     // stored at its left child.
03473     if (comp_f (nodeP->object, nodeP->leftP->object) == SMALLER)
03474       return (false);
03475 
03476     // Recursively check that the left sub-tree is valid.
03477     if (! _sub_is_valid (nodeP->leftP, iLeftSize, iLeftBHeight))
03478       return (false);
03479   }
03480 
03481   if (_is_valid (nodeP->rightP))
03482   {
03483     // Make sure that the object stored at nodeP is not larger than the one
03484     // stored at its right child.
03485     if (comp_f (nodeP->object, nodeP->rightP->object) == LARGER)
03486       return (false);
03487 
03488     // Recursively check that the right sub-tree is valid.
03489     if (! _sub_is_valid (nodeP->rightP, iRightSize, iRightBHeight))
03490       return (false);
03491   }
03492 
03493   // Compute the size of the entire sub-tree.
03494   sub_size = iRightSize + iLeftSize + 1;
03495 
03496   // Make sure that the black heights of both sub-trees are equal.
03497   if (iRightBHeight != iLeftBHeight)
03498     return (false);
03499   sub_bh = iRightBHeight + iBlack;
03500 
03501   // If we reached here, the subtree is valid.
03502   return (true);
03503 }
03504 
03505 //---------------------------------------------------------
03506 // Get the leftmost node in the sub-tree spanned by the given node.
03507 //
03508 template <class Type, class Compare, typename Allocator>
03509 typename Multiset<Type, Compare, Allocator>::Node* 
03510 Multiset<Type, Compare, Allocator>::_sub_minimum (Node* nodeP) const
03511 {
03512   CGAL_multiset_assertion (_is_valid (nodeP));
03513 
03514   Node    *minP = nodeP;
03515 
03516   while (_is_valid (minP->leftP))
03517     minP = minP->leftP;
03518   return (minP);
03519 }
03520 
03521 //---------------------------------------------------------
03522 // Get the rightmost node in the sub-tree spanned by the given node.
03523 //
03524 template <class Type, class Compare, typename Allocator>
03525 typename Multiset<Type, Compare, Allocator>::Node*
03526 Multiset<Type, Compare, Allocator>::_sub_maximum (Node* nodeP) const
03527 {
03528   CGAL_multiset_assertion (_is_valid (nodeP));
03529 
03530   Node    *maxP = nodeP;
03531 
03532   while (_is_valid (maxP->rightP))
03533     maxP = maxP->rightP;
03534   return (maxP);
03535 }
03536 
03537 //---------------------------------------------------------
03538 // Left-rotate the sub-tree spanned by the given node:
03539 //
03540 //          |          RoateRight(y)            |
03541 //          y         -------------->           x
03542 //        /   \                               /   \       .
03543 //       x     T3       RoatateLeft(x)       T1    y      .
03544 //     /   \          <--------------            /   \    .
03545 //    T1    T2                                  T2    T3
03546 //
03547 template <class Type, class Compare, typename Allocator>
03548 void Multiset<Type, Compare, Allocator>::_rotate_left (Node* xNodeP)
03549 {
03550   // Get the right child of the node.
03551   Node        *yNodeP = xNodeP->rightP;
03552 
03553   CGAL_multiset_assertion (_is_valid (yNodeP));
03554 
03555   // Change its left subtree (T2) to x's right subtree.
03556   xNodeP->rightP = yNodeP->leftP;
03557 
03558   // Link T2 to its new parent x.
03559   if (_is_valid (yNodeP->leftP))
03560     yNodeP->leftP->parentP = xNodeP;
03561     
03562   // Assign x's parent to be y's parent.
03563   yNodeP->parentP = xNodeP->parentP;
03564 
03565   if (xNodeP->parentP == NULL)
03566   {
03567     // Make y the new tree root.
03568     rootP = yNodeP;
03569   }
03570   else 
03571   {
03572     // Assign a pointer to y from x's parent.
03573     if (xNodeP == xNodeP->parentP->leftP)
03574     {
03575       xNodeP->parentP->leftP = yNodeP;
03576     }
03577     else
03578     {
03579       xNodeP->parentP->rightP = yNodeP;
03580     }
03581   }
03582 
03583   // Assign x to be y's left child.
03584   yNodeP->leftP = xNodeP;
03585   xNodeP->parentP = yNodeP;
03586 
03587   return;
03588 }
03589 
03590 //---------------------------------------------------------
03591 // Right-rotate the sub-tree spanned by the given node.
03592 //
03593 template <class Type, class Compare, typename Allocator>
03594 void Multiset<Type, Compare, Allocator>::_rotate_right (Node* yNodeP)
03595 {
03596   // Get the left child of the node.
03597   Node        *xNodeP = yNodeP->leftP;
03598 
03599   CGAL_multiset_assertion (_is_valid (xNodeP));
03600 
03601   // Change its right subtree (T2) to y's left subtree.
03602   yNodeP->leftP = xNodeP->rightP;
03603 
03604   // Link T2 to its new parent y.
03605   if (_is_valid (xNodeP->rightP))
03606     xNodeP->rightP->parentP = yNodeP;
03607     
03608   // Assign y's parent to be x's parent.
03609   xNodeP->parentP = yNodeP->parentP;
03610 
03611   if (yNodeP->parentP == NULL)
03612   {
03613     // Make x the new tree root.
03614     rootP = xNodeP;
03615   }
03616   else 
03617   {
03618     // Assign a pointer to x from y's parent.
03619     if (yNodeP == yNodeP->parentP->leftP)
03620     {
03621       yNodeP->parentP->leftP = xNodeP;
03622     }
03623     else
03624     {
03625       yNodeP->parentP->rightP = xNodeP;
03626     }
03627   }
03628 
03629   // Assign y to be x's right child.
03630   xNodeP->rightP = yNodeP;
03631   yNodeP->parentP = xNodeP;
03632 
03633   return;
03634 }
03635 
03636 //---------------------------------------------------------
03637 // Duplicate the entire sub-tree rooted at the given node.
03638 //
03639 template <class Type, class Compare, typename Allocator>
03640 typename Multiset<Type, Compare, Allocator>::Node* 
03641 Multiset<Type, Compare, Allocator>::_duplicate (const Node* nodeP)
03642 {
03643   CGAL_multiset_assertion (_is_valid (nodeP));
03644 
03645   // Create a node of the same color, containing the same object.
03646   Node   *dupNodeP = _allocate_node(nodeP->object, nodeP->color);
03647     
03648   // Duplicate the children recursively.
03649   if (_is_valid (nodeP->rightP))
03650   {
03651     dupNodeP->rightP = _duplicate (nodeP->rightP);
03652     dupNodeP->rightP->parentP = dupNodeP;
03653   }
03654 
03655   if (_is_valid (nodeP->leftP))
03656   {
03657     dupNodeP->leftP = _duplicate (nodeP->leftP);
03658     dupNodeP->leftP->parentP = dupNodeP;
03659   }
03660 
03661   // Return the duplicated node.
03662   return (dupNodeP);
03663 }
03664 
03665 //---------------------------------------------------------
03666 // Destroy the entire sub-tree rooted at the given node.
03667 //
03668 template <class Type, class Compare, typename Allocator>
03669 void Multiset<Type, Compare, Allocator>::_destroy (Node* nodeP)
03670 {
03671   CGAL_multiset_assertion (_is_valid (nodeP));
03672   
03673   // Destroy the children recursively.
03674   if (_is_valid (nodeP->rightP))
03675     _destroy (nodeP->rightP);
03676   nodeP->rightP = NULL;
03677 
03678   if (_is_valid (nodeP->leftP))
03679     _destroy (nodeP->leftP);
03680   nodeP->leftP = NULL;
03681 
03682   // Free the subtree root node.
03683   _deallocate_node (nodeP);
03684 
03685   return;
03686 }
03687 
03688 //---------------------------------------------------------
03689 // Fix-up the tree so it maintains the red-black properties after insertion.
03690 //
03691 template <class Type, class Compare, typename Allocator>
03692 void Multiset<Type, Compare, Allocator>::_insert_fixup (Node* nodeP)
03693 {
03694   CGAL_multiset_precondition (_is_red (nodeP));
03695   
03696   // Fix the red-black propreties: we may have inserted a red leaf as the 
03697   // child of a red parent - so we have to fix the coloring of the parent 
03698   // recursively.
03699   Node        *currP = nodeP;
03700   Node        *grandparentP;
03701   Node        *uncleP;
03702 
03703   while (currP != rootP && _is_red (currP->parentP))
03704   {
03705     // Get a pointer to the current node's grandparent (notice the root is 
03706     // always black, so the red parent must have a parent).
03707     grandparentP = currP->parentP->parentP;
03708     CGAL_multiset_precondition (grandparentP != NULL);
03709 
03710     if (currP->parentP == grandparentP->leftP)
03711     {
03712       // If the red parent is a left child, the uncle is the right child of
03713       // the grandparent.
03714       uncleP = grandparentP->rightP;
03715 
03716       if (_is_red (uncleP))
03717       {
03718         // If both parent and uncle are red, color them black and color the
03719         // grandparent red.
03720         // In case of a NULL uncle, we treat it as a black node.
03721         currP->parentP->color = Node::BLACK;
03722         uncleP->color = Node::BLACK;
03723         grandparentP->color = Node::RED;
03724 
03725         // Move to the grandparent.
03726         currP = grandparentP;
03727       }
03728       else
03729       {
03730         // Make sure the current node is a left child. If not, left-rotate
03731         // the parent's sub-tree so the parent becomes the left child of the
03732         // current node (see _rotate_left).
03733         if (currP == currP->parentP->rightP)
03734         {
03735           currP = currP->parentP;
03736           _rotate_left (currP);
03737         }
03738 
03739         // Color the parent black and the grandparent red.
03740         currP->parentP->color = Node::BLACK;
03741         CGAL_multiset_assertion (grandparentP == currP->parentP->parentP);
03742         grandparentP->color = Node::RED;
03743 
03744         // Right-rotate the grandparent's sub-tree
03745         _rotate_right (grandparentP);
03746       }
03747     }
03748     else
03749     {
03750       // If the red parent is a right child, the uncle is the left child of
03751       // the grandparent.
03752       uncleP = grandparentP->leftP;
03753 
03754       if (_is_red (uncleP))
03755       {
03756         // If both parent and uncle are red, color them black and color the 
03757         // grandparent red.
03758         // In case of a NULL uncle, we treat it as a black node.
03759         currP->parentP->color = Node::BLACK;
03760         uncleP->color = Node::BLACK;
03761         grandparentP->color = Node::RED;
03762 
03763         // Move to the grandparent.
03764         currP = grandparentP;
03765       }
03766       else
03767       {
03768         // Make sure the current node is a right child. If not, right-rotate 
03769         // the parent's sub-tree so the parent becomes the right child of the 
03770         // current node.
03771         if (currP == currP->parentP->leftP)
03772         {
03773           currP = currP->parentP;
03774           _rotate_right (currP);
03775         }
03776 
03777         // Color the parent black and the grandparent red.
03778         currP->parentP->color = Node::BLACK;
03779         CGAL_multiset_assertion(grandparentP == currP->parentP->parentP);
03780         grandparentP->color = Node::RED;
03781 
03782         // Left-rotate the grandparent's sub-tree
03783         _rotate_left (grandparentP);
03784       }
03785     }
03786   }
03787 
03788   // Make sure that the root is black.
03789   if (_is_red (rootP))
03790   {
03791     // In case we color a red root black, we should increment the black
03792     // height of the tree.
03793     rootP->color = Node::BLACK;
03794     iBlackHeight++;
03795   }
03796   
03797   return;
03798 }
03799 
03800 //---------------------------------------------------------
03801 // Fix-up the tree so it maintains the red-black properties after removal.
03802 //
03803 template <class Type, class Compare, typename Allocator>
03804 void Multiset<Type, Compare, Allocator>::_remove_fixup (Node* nodeP,
03805                                                         Node* parentP)
03806 {
03807   Node        *currP = nodeP;
03808   Node        *currParentP = parentP;
03809   Node        *siblingP;
03810 
03811   while (currP != rootP && _is_black (currP))
03812   {
03813     // Get a pointer to the current node's sibling (notice that the node's
03814     // parent must exist, since the node is not the rootP).
03815     if (currP == currParentP->leftP)
03816     {
03817       // If the current node is a left child, its sibling is the right
03818       // child of the parent.
03819       siblingP = currParentP->rightP;
03820 
03821       // Check the sibling's color. Notice that NULL nodes are treated
03822       // as if they are colored black.
03823       if (_is_red (siblingP))
03824       {
03825         // In case the sibling is red, color it black and rotate.
03826         // Then color the parent red (and the grandparent is now black).
03827         siblingP->color = Node::BLACK;
03828         currParentP->color = Node::RED;
03829         _rotate_left (currParentP);
03830         siblingP = currParentP->rightP;
03831       }
03832 
03833       CGAL_multiset_assertion (_is_valid (siblingP));
03834 
03835       if (_is_black (siblingP->leftP) && _is_black (siblingP->rightP))
03836       {
03837         // If the sibling has two black children, color it red.
03838         siblingP->color = Node::RED;
03839 
03840         // The black-height of the entire sub-tree rooted at the parent is
03841         // now too small - fix it up recursively.
03842         currP = currParentP;
03843         currParentP = currParentP->parentP;
03844 
03845         // In case the current node is the tree root, we have just decreased
03846         // the black height of the entire tree.
03847         if (currP == rootP)
03848         {
03849           CGAL_multiset_assertion (currParentP == NULL);
03850           iBlackHeight--;
03851         }
03852       }
03853       else
03854       {
03855         // In this case, at least one of the sibling's children is red.
03856         // It is therfore obvious that the sibling itself is black.
03857         if (_is_black (siblingP->rightP))
03858         {
03859           // The left child is red: Color it black, and color the sibling red.
03860           siblingP->leftP->color = Node::BLACK;
03861           siblingP->color = Node::RED;
03862 
03863           _rotate_right (siblingP);
03864           siblingP = currParentP->rightP;
03865         }
03866 
03867         // Color the parent black (it is now safe to color the sibling with
03868         // the same color the parent used to have) and rotate left around it.
03869         siblingP->color = currParentP->color;
03870         currParentP->color = Node::BLACK;
03871         if (_is_valid (siblingP->rightP))
03872           siblingP->rightP->color = Node::BLACK;
03873         _rotate_left (currParentP);
03874 
03875         // We set currP to be the root node in order to terminate the loop.
03876         currP = rootP;
03877       }
03878     }
03879     else
03880     {
03881       // If the current node is a right child, its sibling is the left
03882       // child of the parent.
03883       siblingP = currParentP->leftP;
03884 
03885       // Check the sibling's color. Notice that NULL nodes are treated
03886       // as if they are colored black.
03887       if (_is_red (siblingP))
03888       {
03889         // In case the sibling is red, color it black and rotate.
03890         // Then color the parent red (and the grandparent is now black).
03891         siblingP->color = Node::BLACK;
03892         currParentP->color = Node::RED;
03893         _rotate_right (currParentP);
03894 
03895         siblingP = currParentP->leftP;
03896       }
03897 
03898       CGAL_multiset_assertion (_is_valid (siblingP));
03899 
03900       if (_is_black (siblingP->leftP) && _is_black (siblingP->rightP))
03901       {
03902         // If the sibling has two black children, color it red.
03903         siblingP->color = Node::RED;
03904 
03905         // The black-height of the entire sub-tree rooted at the parent is
03906         // now too small - fix it up recursively.
03907         currP = currParentP;
03908         currParentP = currParentP->parentP;
03909 
03910         // In case the current node is the tree root, we have just decreased
03911         // the black height of the entire tree.
03912         if (currP == rootP)
03913         {
03914           CGAL_multiset_assertion (currParentP == NULL);
03915           iBlackHeight--;
03916         }
03917       }
03918       else
03919       {
03920         // In this case, at least one of the sibling's children is red.
03921         // It is therfore obvious that the sibling itself is black.
03922         if (_is_black (siblingP->leftP))
03923         {
03924           // The right child is red: Color it black, and color the sibling red.
03925           siblingP->rightP->color = Node::BLACK;
03926           siblingP->color = Node::RED;
03927 
03928           _rotate_left (siblingP);
03929           siblingP = currParentP->leftP;
03930         }
03931 
03932         // Color the parent black (it is now safe to color the sibling with
03933         // the same color the parent used to have) and rotate right around it.
03934         siblingP->color = currParentP->color;
03935         currParentP->color = Node::BLACK;
03936         if (_is_valid (siblingP->leftP))
03937           siblingP->leftP->color = Node::BLACK;
03938         _rotate_right (currParentP);
03939 
03940         // We set currP to be the root node in order to terminate the loop.
03941         currP = rootP;
03942       }
03943     }
03944   }
03945 
03946   // Make sure the current node is black.
03947   if (_is_red (currP))
03948   {
03949     currP->color = Node::BLACK;
03950 
03951     if (currP == rootP)    
03952     {
03953       // In case we color a red root black, we should increment the black
03954       // height of the tree.
03955       iBlackHeight++;
03956     }
03957   }
03958 
03959   return;
03960 }
03961 
03962 //---------------------------------------------------------
03963 // Allocate and initialize new tree node.
03964 //
03965 #ifndef CGAL_CFG_OUTOFLINE_MEMBER_DEFINITION_BUG
03966 template <class Type, class Compare, typename Allocator>
03967 typename Multiset<Type, Compare, Allocator>::Node*
03968 Multiset<Type, Compare, Allocator>::_allocate_node
03969         (const Type& object,
03970          typename Node::Node_color color)
03971 {
03972   CGAL_multiset_assertion (color != Node::DUMMY_BEGIN && 
03973                            color != Node::DUMMY_END);
03974 
03975   Node* new_node = node_alloc.allocate(1);
03976   
03977   node_alloc.construct(new_node, beginNode);
03978   new_node->init(object, color);
03979   return (new_node);
03980 }
03981 #endif
03982 
03983 //---------------------------------------------------------
03984 // De-allocate a tree node.
03985 //
03986 template <class Type, class Compare, typename Allocator>
03987 void Multiset<Type, Compare, Allocator>::_deallocate_node (Node* nodeP)
03988 {
03989   node_alloc.destroy (nodeP); 
03990   node_alloc.deallocate (nodeP, 1);
03991 
03992   return;
03993 }
03994 
03995 CGAL_END_NAMESPACE
03996 
03997 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines