BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/In_place_list.h
Go to the documentation of this file.
00001 // Copyright (c) 2003  Utrecht University (The Netherlands),
00002 // ETH Zurich (Switzerland), Freie Universitaet Berlin (Germany),
00003 // INRIA Sophia-Antipolis (France), Martin-Luther-University Halle-Wittenberg
00004 // (Germany), Max-Planck-Institute Saarbruecken (Germany), RISC Linz (Austria),
00005 // and Tel-Aviv University (Israel).  All rights reserved.
00006 //
00007 // This file is part of CGAL (www.cgal.org); you can redistribute it and/or
00008 // modify it under the terms of the GNU Lesser General Public License as
00009 // published by the Free Software Foundation; version 2.1 of the License.
00010 // See the file LICENSE.LGPL distributed with CGAL.
00011 //
00012 // Licensees holding a valid commercial license may use this file in
00013 // accordance with the commercial license agreement provided with the software.
00014 //
00015 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00016 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00017 //
00018 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/STL_Extension/include/CGAL/In_place_list.h $
00019 // $Id: In_place_list.h 46206 2008-10-11 20:21:08Z spion $
00020 // 
00021 //
00022 // Author(s)     : Michael Hoffmann <hoffmann@inf.ethz.ch>
00023 //                 Lutz Kettner <kettner@mpi-sb.mpg.de>
00024 //                 Sylvain Pion
00025 
00026 #ifndef CGAL_IN_PLACE_LIST_H
00027 #define CGAL_IN_PLACE_LIST_H 1
00028 
00029 #include <CGAL/basic.h>
00030 #include <cstddef>
00031 #include <iterator>
00032 #include <functional>
00033 #include <algorithm>
00034 #include <CGAL/circulator_impl.h>
00035 #include <CGAL/circulator.h>
00036 #include <CGAL/memory.h>
00037 
00038 CGAL_BEGIN_NAMESPACE
00039 
00040 // Forward declarations
00041 namespace CGALi {
00042   template <class T, class Alloc> class In_place_list_iterator;
00043   template <class T, class Alloc> class In_place_list_const_iterator;
00044 }
00045 
00046 template <class T, bool managed, class Alloc = CGAL_ALLOCATOR(T)>
00047 class In_place_list;
00048 
00049 template < class T >
00050 class In_place_sl_list_base {
00051 public:
00052   T* next_link;        // forward pointer
00053 };
00054 
00055 template < class T >
00056 class In_place_list_base {
00057 public:
00058   T* next_link;        // forward pointer
00059   T* prev_link;        // backwards pointer
00060   //friend  class CGALi::In_place_list_iterator<T, Alloc>;
00061   //friend  class CGALi::In_place_list_const_iterator<T, Alloc>;
00062   //friend  class In_place_list<T,false, Alloc>;
00063   //friend  class In_place_list<T,true, Alloc>;
00064 };
00065 
00066 
00067 namespace CGALi {
00068   template <class T, class Alloc>
00069   class In_place_list_iterator {
00070   protected:
00071     T* node;
00072   public:
00073     friend  class In_place_list<T,false, Alloc>;
00074     friend  class In_place_list<T,true, Alloc>;
00075 
00076     typedef In_place_list_iterator<T, Alloc>  Self;
00077     typedef In_place_list_base<T>      Base;
00078 
00079     typedef T               value_type;
00080     typedef T*              pointer;
00081     typedef T&              reference;
00082     typedef std::size_t     size_type;
00083     typedef std::ptrdiff_t  difference_type;
00084     typedef std::bidirectional_iterator_tag   iterator_category;
00085 
00086     In_place_list_iterator() : node(0) {}
00087     In_place_list_iterator(T* x) : node(x) {}
00088 
00089     bool  operator==( const Self& x) const { return node == x.node; }
00090     bool  operator!=( const Self& x) const { return node != x.node; }
00091     T&    operator*()  const { return *node; }
00092     T*    operator->() const { return  node; }
00093     Self& operator++() {
00094       node = ((Base*)(node))->next_link;
00095       return *this;
00096     }
00097     Self  operator++(int) {
00098       Self tmp = *this;
00099       ++*this;
00100       return tmp;
00101     }
00102     Self& operator--() {
00103       node = ((Base*)(node))->prev_link;
00104       return *this;
00105     }
00106     Self  operator--(int) {
00107       Self tmp = *this;
00108       --*this;
00109       return tmp;
00110     }
00111   };
00112 }
00113 
00114 namespace CGALi {
00115   template <class T, class Alloc>
00116   class In_place_list_const_iterator {
00117   protected:
00118     const T* node;  // It's not Ptr. Otherwise traversal won't work.
00119   public:
00120     friend  class In_place_list<T,false, Alloc>;
00121     friend  class In_place_list<T,true, Alloc>;
00122 
00123     typedef In_place_list_const_iterator<T, Alloc> Self;
00124     typedef In_place_list_iterator<T, Alloc>       Iterator;
00125     typedef In_place_list_base<T>           Base;
00126 
00127     typedef T               value_type;
00128     typedef const T*        pointer;
00129     typedef const T&        reference;
00130     typedef std::size_t     size_type;
00131     typedef std::ptrdiff_t  difference_type;
00132     typedef std::bidirectional_iterator_tag   iterator_category;
00133 
00134     In_place_list_const_iterator() : node(0) {}
00135     In_place_list_const_iterator( Iterator i) : node(&*i) {}
00136     In_place_list_const_iterator(const T* x) : node(x) {}
00137 
00138     bool     operator==( const Self& x) const { return node == x.node; }
00139     bool     operator!=( const Self& x) const { return node != x.node; }
00140     const T& operator*()  const { return *node; }
00141     const T* operator->() const { return  node; }
00142     Self& operator++() {
00143       node = ((const Base*)(node))->next_link;
00144       return *this;
00145     }
00146     Self  operator++(int) {
00147       Self tmp = *this;
00148       ++*this;
00149       return tmp;
00150     }
00151     Self& operator--() {
00152       node = ((const Base*)(node))->prev_link;
00153       return *this;
00154     }
00155     Self  operator--(int) {
00156       Self tmp = *this;
00157       --*this;
00158       return tmp;
00159     }
00160   };
00161 }
00162 
00163 
00164 template <class T, bool managed, class Alloc>
00165 class In_place_list {
00166 
00167   // Bidirectional List Managing Objects in Place
00168   // --------------------------------------------
00169   //
00170   // DEFINITION An object of the class In_place_list<T,bool> is a
00171   // sequence that supports bidirectional iterators and allows constant time
00172   // insert and erase operations anywhere within the sequence. The
00173   // functionality is similar to the `list<T>' in the STL.
00174   //
00175   // The In_place_list<T,bool> manages element items in place. Two
00176   // pointers `T*' are expected in the class. For example the base class
00177   // `In_place_list_base<T>' can be used.
00178   //
00179   // The In_place_list<T,bool> does not copy element items during
00180   // insertion (unless otherwise stated for a function). On removal or
00181   // destruction of the list the element items are not deleted by default.
00182   // The second template parameter `bool' has to be set to `false' in this
00183   // case. If the In_place_list<T,bool> should take the responsibility
00184   // for the stored objects the `bool' parameter could be set to `true', in
00185   // which case the list will delete removed items and will delete all
00186   // remaining items on destruction. In any case, the `destroy()' member
00187   // function deletes all elements.
00188   //
00189   // On purpose, these two possible versions of In_place_list<T,bool>
00190   // are not assignment compatible to avoid confusions between the different
00191   // storage responsibilities.
00192   //
00193   // PARAMETERS
00194   //
00195   // The full classname is `In_place_list<T,bool managed = false, Alloc
00196   // = CGAL_ALLOCATOR(T)>'.
00197   //
00198   // TYPES
00199 
00200 public:
00201   typedef Alloc           Allocator;
00202   typedef Alloc           allocator_type; // STL compliant
00203 
00204   // Note: the standard requires the following types to be equivalent
00205   // to T, T*, const T*, T&, const T&, size_t, and ptrdiff_t, respectively.
00206   // So we don't pass these types to the iterators explicitly.
00207   typedef typename Allocator::value_type          value_type;
00208   typedef typename Allocator::pointer             pointer;
00209   typedef typename Allocator::const_pointer       const_pointer;
00210   typedef typename Allocator::reference           reference;
00211   typedef typename Allocator::const_reference     const_reference;
00212   typedef typename Allocator::size_type           size_type;
00213   typedef typename Allocator::difference_type     difference_type;
00214 
00215   typedef CGALi::In_place_list_iterator<T, Alloc> iterator;
00216   typedef CGALi::In_place_list_const_iterator<T, Alloc> const_iterator;
00217 
00218   typedef std::reverse_iterator<iterator>         reverse_iterator;
00219   typedef std::reverse_iterator<const_iterator>   const_reverse_iterator;
00220 
00221   typedef In_place_list<T,managed,Alloc>          Self;
00222 
00223 protected:
00224   Allocator allocator;
00225 
00226   pointer      node;
00227   size_type    length;
00228 
00229   // These are the only places where the allocator gets called.
00230   pointer get_node() {
00231     pointer p = allocator.allocate(1);
00232 #ifdef CGAL_USE_ALLOCATOR_CONSTRUCT_DESTROY
00233     allocator.construct(p, value_type());
00234 #else
00235     new (p) value_type;
00236 #endif
00237     return p;
00238   }
00239   pointer get_node( const T& t) {
00240     pointer p = allocator.allocate(1);
00241 #ifdef CGAL_USE_ALLOCATOR_CONSTRUCT_DESTROY
00242     allocator.construct(p, t);
00243 #else
00244     new (p) value_type(t);
00245 #endif
00246     return p;
00247   }
00248   void put_node( pointer p) {
00249 #ifdef CGAL_USE_ALLOCATOR_CONSTRUCT_DESTROY  
00250     allocator.destroy( p);
00251 #else 
00252    p->~value_type();
00253 #endif
00254     allocator.deallocate( p, 1);
00255   }
00256 
00257 public:
00258   // CREATION
00259   //
00260   // New creation variable is: `l'
00261 
00262   explicit In_place_list() : length(0) {
00263     // introduces an empty list.
00264     node = get_node();
00265     (*node).next_link = node;
00266     (*node).prev_link = node;
00267   }
00268   void swap(Self& x) {
00269     std::swap(node, x.node);
00270     std::swap(length, x.length);
00271   }
00272 
00273   // ACCESS MEMBER FUNCTIONS
00274 
00275   allocator_type get_allocator() const { return allocator; }
00276 
00277   iterator       begin() { return (*node).next_link; }
00278   const_iterator begin() const { return (*node).next_link; }
00279   iterator       end() { return node; }
00280   const_iterator end() const { return node; }
00281 
00282   reverse_iterator       rbegin() { return reverse_iterator(end()); }
00283   const_reverse_iterator rbegin() const {
00284     return const_reverse_iterator(end());
00285   }
00286   reverse_iterator       rend() { return reverse_iterator(begin()); }
00287   const_reverse_iterator rend() const {
00288     return const_reverse_iterator(begin());
00289   }
00290 
00291   bool            empty() const    { return length == 0; }
00292   size_type       size() const     { return length; }
00293   size_type       max_size() const { return size_type(-1); }
00294 
00295   reference       front()          { return *begin(); }
00296   const_reference front() const    { return *begin(); }
00297   reference       back()           { return *(--end()); }
00298   const_reference back() const     { return *(--end()); }
00299 
00300   // INSERTION
00301 
00302   iterator insert(iterator position, T& x) {
00303     // inserts `t' in front of iterator `pos'. The return value points
00304     // to the inserted item.
00305     x.next_link = position.node;
00306     x.prev_link = (*position.node).prev_link;
00307     (*((*position.node).prev_link)).next_link = &x;
00308     (*position.node).prev_link = &x;
00309     ++length;
00310     return &x;
00311   }
00312   iterator insert(T* pos, T& x) {
00313     return insert( iterator(pos), x);
00314   }
00315   void push_front(T& x) { insert(begin(), x); }
00316   // inserts an item in front of list `l'.
00317 
00318   void push_back(T& x)  { insert(end(), x); }
00319   // inserts an item at the back of list `l'.
00320 
00321   void insert(iterator position, size_type n);
00322   // inserts n copies of `T()' in front of iterator `pos'.
00323 
00324   void insert(iterator position, size_type n, const T& x);
00325   // inserts n copies of `t' in front of iterator `pos'.
00326 
00327   void insert( T* pos, size_type n) { insert( iterator(pos), n); }
00328   void insert( T* pos, size_type n, const T& x) {
00329     insert( iterator(pos), n, x);
00330   }
00331 
00332   template <class InputIterator>
00333   void insert(iterator pos, InputIterator first, InputIterator last) {
00334     // inserts the range [`first, last') in front of iterator `pos'.
00335     while (first != last)
00336       insert(pos, *get_node(*first++));
00337   }
00338 
00339   template <class InputIterator>
00340   void insert(T* pos, InputIterator first, InputIterator last) {
00341     // inserts the range [`first, last') in front of iterator `pos'.
00342     while (first != last)
00343       insert(pos, *get_node(*first++));
00344   }
00345 
00346   void insert(T* pos, const T* first, const T* last) {
00347     insert( iterator(pos), const_iterator(first),
00348             const_iterator(last));
00349   }
00350 
00351 
00352   // REMOVAL
00353 
00354   void erase(iterator i) {
00355     // removes the item from list `l', where `pos' refers to.
00356     CGAL_assertion( length > 0);
00357     (*((*i.node).prev_link)).next_link = (*i.node).next_link;
00358     (*((*i.node).next_link)).prev_link = (*i.node).prev_link;
00359     if (managed)
00360       put_node(i.node);
00361     --length;
00362   }
00363   void erase(T* pos)  { erase( iterator( pos)); }
00364 
00365   void pop_front() { erase(begin()); }
00366   // removes the first item from list `l'.
00367 
00368   void pop_back() {
00369     // removes the last item from list `l'.
00370     iterator tmp = end();
00371     erase(--tmp);
00372   }
00373 
00374   void erase(iterator first, iterator last);
00375   // removes the items in the range [`first, last') from list `l'.
00376 
00377   void erase(T* first, T* last) {
00378     erase( iterator(first), iterator(last));
00379   }
00380 
00381   void clear() { erase( begin(), end()); }
00382 
00383   // CREATION (Continued)
00384 
00385   explicit In_place_list(size_type n, const T& value = T()) : length(0) {
00386     // introduces a list with n items, all initialized with copies of
00387     // value.
00388     node = get_node();
00389     (*node).next_link = node;
00390     (*node).prev_link = node;
00391     insert(begin(), n, value);
00392   }
00393 
00394   template <class InputIterator>
00395   In_place_list( InputIterator first, InputIterator last) : length(0) {
00396     // a list with copies from the range [`first,last').
00397     node = get_node();
00398     (*node).next_link = node;
00399     (*node).prev_link = node;
00400     insert( begin(), first, last);
00401   }
00402 
00403   In_place_list(const T* first, const T* last) : length(0) {
00404     // a list with copies from the range [`first,last').
00405     node = get_node();
00406     (*node).next_link = node;
00407     (*node).prev_link = node;
00408     insert(begin(), first, last);
00409   }
00410   In_place_list(const Self& x) : length(0) {
00411     // copy constructor. Each item in `l1' is copied.
00412     node = get_node();
00413     (*node).next_link = node;
00414     (*node).prev_link = node;
00415     insert(begin(), x.begin(), x.end());
00416   }
00417   ~In_place_list() {
00418     erase(begin(), end());
00419     put_node(node);
00420   }
00421 
00422   Self& operator=(const Self& x);
00423 
00424   void destroy();
00425 
00426   template <class InputIterator>
00427   void assign( InputIterator first, InputIterator last) {
00428     erase( begin(), end());
00429     insert( begin(), first, last);
00430   }
00431 
00432   void assign( size_type n, const T& t) {
00433     erase( begin(), end());
00434     insert( begin(), n, t);
00435   }
00436 
00437   void resize( size_type sz, const T& c = T()) {
00438     if ( sz > size())
00439       insert( end(), sz - size(), c);
00440     else if ( sz < size()) {
00441       iterator i = begin();
00442       while ( sz-- > 0)
00443         ++i;
00444       erase( i, end());
00445     }  // else do nothing
00446   }
00447 
00448   // COMPARISON OPERATIONS
00449 
00450   bool operator==( const Self& y) const {
00451     return size() == y.size() && std::equal(begin(), end(), y.begin());
00452   }
00453 
00454   bool operator!=( const Self& y) const {
00455     return size() != y.size() || ! std::equal(begin(),end(),y.begin());
00456   }
00457 
00458   bool operator<(const Self& y) const {
00459     return std::lexicographical_compare( begin(),end(),
00460                                          y.begin(),y.end());
00461   }
00462   bool operator> ( const Self& i) const { return i < *this; }
00463   bool operator<=( const Self& i) const { return !(i < *this); }
00464   bool operator>=( const Self& i) const { return !(*this < i); }
00465 
00466   // SPECIAL LIST OPERATIONS
00467 
00468 protected:
00469   void transfer(iterator position, iterator first, iterator last) {
00470     // move the range [`first, last') before the position.
00471     (*((*last.node).prev_link)).next_link = position.node;
00472     (*((*first.node).prev_link)).next_link = last.node;
00473     (*((*position.node).prev_link)).next_link = first.node;
00474     T* tmp = (*position.node).prev_link;
00475     (*position.node).prev_link = (*last.node).prev_link;
00476     (*last.node).prev_link = (*first.node).prev_link;
00477     (*first.node).prev_link = tmp;
00478   }
00479 
00480 public:
00481   void splice(iterator position, Self& x) {
00482     // inserts the list x before position `pos' and x becomes empty.
00483     // It takes constant time. Precondition: `&l != &x'.
00484     if (!x.empty()) {
00485       transfer(position, x.begin(), x.end());
00486       length += x.length;
00487       x.length = 0;
00488     }
00489   }
00490   void splice(T* position, Self& x) {
00491     splice( iterator(position), x);
00492   }
00493   void splice( iterator position, Self& x, iterator i) {
00494     // inserts an element pointed to by i from list x before position
00495     // `pos' and removes the element from x. It takes constant time. i
00496     // is a valid dereferenceable iterator of x. The result is
00497     // unchanged if `pos == i' or `pos == ++i'.
00498     iterator j = i;
00499     if (position == i || position == ++j) return;
00500     transfer(position, i, j);
00501     ++length;
00502     --x.length;
00503   }
00504   void splice(T* position, Self& x, T* i) {
00505     splice( iterator(position), x, iterator(i));
00506   }
00507   void splice(iterator pos, Self& x, iterator first, iterator last) {
00508     // inserts elements in the range [`first, last') before position
00509     // `pos' and removes the elements from x. It takes constant time
00510     // if `&x == $l'; otherwise, it takes linear time. [`first,
00511     // last') is a valid range in x. Precondition: `pos' is not in the
00512     // range [`first, last').
00513     if (first != last) {
00514       if (&x != this) {
00515         difference_type n = std::distance(first, last);
00516         x.length -= n;
00517         length += n;
00518       }
00519       transfer(pos, first, last);
00520     }
00521   }
00522   void splice(T* p, Self& x, T* first, T* last) {
00523     splice( iterator(p), x, iterator(first), iterator(last));
00524   }
00525 
00526   void remove(const T& value);
00527   // erases all elements e in the list l for which `e == value'.
00528   // It is stable. Precondition: a suitable `operator==' for the
00529   // type T.
00530 
00531   void reverse();
00532   // reverses the order of the elements in `l' in linear time.
00533 
00534   void unique();
00535   // erases all but the first element from every consecutive group
00536   // of equal elements in the list `l'. Precondition: a suitable
00537   // `operator==' for the type T.
00538 
00539   void merge(Self& x);
00540   // merges the list x into the list `l' and x becomes empty. It is
00541   // stable. Precondition: Both lists are increasingly sorted. A
00542   // suitable `operator<' for the type T.
00543 
00544   template < class StrictWeakOrdering >
00545   void merge(Self& x, StrictWeakOrdering ord)
00546   // merges the list x into the list `l' and x becomes empty.
00547   // It is stable.
00548   // Precondition: Both lists are increasingly sorted wrt. ord.
00549   {
00550     iterator first1 = begin();
00551     iterator last1 = end();
00552     iterator first2 = x.begin();
00553     iterator last2 = x.end();
00554     while (first1 != last1 && first2 != last2)
00555       if (ord(*first2, *first1)) {
00556         iterator next = first2;
00557         transfer(first1, first2, ++next);
00558         first2 = next;
00559       } else
00560         ++first1;
00561     if (first2 != last2)
00562       transfer(last1, first2, last2);
00563     length += x.length;
00564     x.length= 0;
00565   }
00566 
00567   void sort();
00568   // sorts the list `l' according to the `operator<' in time O(n
00569   // log n) where `n = size()'. It is stable. Precondition: a
00570   // suitable `operator<' for the type T.
00571 
00572   template < class StrictWeakOrdering >
00573   void sort(StrictWeakOrdering ord)
00574   // sorts the list `l' according to ord in time O(n log n)
00575   // where `n = size()'. It is stable.
00576   {
00577     if (size() < 2) return;
00578     In_place_list<T,managed,Alloc> carry;
00579     In_place_list<T,managed,Alloc> counter[64];
00580     int fill = 0;
00581     while (!empty()) {
00582       carry.splice(carry.begin(), *this, begin());
00583       int i = 0;
00584       while(i < fill && !counter[i].empty()) {
00585         counter[i].merge(carry, ord);
00586         carry.swap(counter[i++]);
00587       }
00588       carry.swap(counter[i]);
00589       if (i == fill)
00590         ++fill;
00591     }
00592     for (int i = 1; i < fill; ++i)
00593       counter[i].merge(counter[i-1], ord);
00594     swap(counter[fill-1]);
00595   }
00596 
00597 };
00598 
00599 template <class T, bool managed, class Alloc>
00600 void In_place_list<T,managed,Alloc>::
00601 insert(CGALi::In_place_list_iterator<T, Alloc> position, size_type n) {
00602   while (n--)
00603     insert(position, *get_node());
00604 }
00605 
00606 template <class T, bool managed, class Alloc>
00607 void In_place_list<T,managed,Alloc>::
00608 insert(CGALi::In_place_list_iterator<T, Alloc> position, size_type n, const T& x) {
00609   while (n--)
00610     insert(position, *get_node(x));
00611 }
00612 
00613 template <class T, bool managed, class Alloc>
00614 void In_place_list<T,managed,Alloc>::
00615 erase(CGALi::In_place_list_iterator<T, Alloc> first,
00616       CGALi::In_place_list_iterator<T, Alloc> last)
00617 {
00618   while (first != last)
00619     erase(first++);
00620 }
00621 
00622 template <class T, bool managed, class Alloc>
00623 In_place_list<T,managed,Alloc>&
00624 In_place_list<T,managed,Alloc>::
00625 operator=(const In_place_list<T,managed,Alloc>& x) {
00626   if (this != &x) {
00627     iterator first1 = begin();
00628     iterator last1  = end();
00629     const_iterator first2 = x.begin();
00630     const_iterator last2  = x.end();
00631     while (first1 != last1 && first2 != last2) {
00632       // Save the pointer values before assignment.
00633       // Assignment avoids unneccassary delete's and new's.
00634       T* tmp1 = (*first1).next_link;
00635       T* tmp2 = (*first1).prev_link;
00636       *first1 = *first2++;
00637       (*first1).next_link = tmp1;
00638       (*first1).prev_link = tmp2;
00639       ++first1;
00640     }
00641     if (first2 == last2)
00642       erase(first1, last1);
00643     else
00644       insert(last1, first2, last2);
00645   }
00646   return *this;
00647 }
00648 
00649 template <class T, bool managed, class Alloc>
00650 void In_place_list<T,managed,Alloc>::
00651 destroy() {
00652   iterator first = begin();
00653   iterator last  = end();
00654   while( first != last) {
00655     iterator i = first++;
00656     put_node(i.node);
00657   }
00658   length = 0;
00659   (*node).next_link = node;
00660   (*node).prev_link = node;
00661 }
00662 
00663 template <class T, bool managed, class Alloc>
00664 void In_place_list<T,managed,Alloc>::remove(const T& value) {
00665   iterator first = begin();
00666   iterator last = end();
00667   while (first != last) {
00668     iterator next = first;
00669     ++next;
00670     if (*first == value)
00671       erase(first);
00672     first = next;
00673   }
00674 }
00675 
00676 template <class T, bool managed, class Alloc>
00677 void In_place_list<T,managed,Alloc>::reverse() {
00678   if (size() < 2) return;
00679   for (iterator first = ++begin(); first != end();) {
00680     iterator old = first++;
00681     transfer(begin(), old, first);
00682   }
00683 }
00684 
00685 template <class T, bool managed, class Alloc>
00686 void In_place_list<T,managed,Alloc>::unique() {
00687   iterator first = begin();
00688   iterator last = end();
00689   if (first == last) return;
00690   iterator next = first;
00691   while (++next != last) {
00692     if (*first == *next)
00693       erase(next);
00694     else
00695       first = next;
00696     next = first;
00697   }
00698 }
00699 
00700 template <class T, bool managed, class Alloc>
00701 void In_place_list<T,managed,Alloc>::merge(In_place_list<T,managed,Alloc>& x) {
00702   iterator first1 = begin();
00703   iterator last1 = end();
00704   iterator first2 = x.begin();
00705   iterator last2 = x.end();
00706   while (first1 != last1 && first2 != last2)
00707     if (*first2 < *first1) {
00708       iterator next = first2;
00709       transfer(first1, first2, ++next);
00710       first2 = next;
00711     } else
00712       ++first1;
00713   if (first2 != last2)
00714     transfer(last1, first2, last2);
00715   length += x.length;
00716   x.length= 0;
00717 }
00718 
00719 template <class T, bool managed, class Alloc>
00720 void In_place_list<T,managed,Alloc>::sort() {
00721   if (size() < 2) return;
00722   In_place_list<T,managed,Alloc> carry;
00723   In_place_list<T,managed,Alloc> counter[64];
00724   int fill = 0;
00725   while (!empty()) {
00726     carry.splice(carry.begin(), *this, begin());
00727     int i = 0;
00728     while(i < fill && !counter[i].empty()) {
00729       counter[i].merge(carry);
00730       carry.swap(counter[i++]);
00731     }
00732     carry.swap(counter[i]);
00733     if (i == fill)
00734       ++fill;
00735   }
00736   for (int i = 1; i < fill; ++i)
00737     counter[i].merge(counter[i-1]);
00738   swap(counter[fill-1]);
00739 }
00740 
00741 CGAL_END_NAMESPACE
00742 
00743 #endif // CGAL_IN_PLACE_LIST_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines