BWAPI
|
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