103a78d15Sespie // List implementation (out of line) -*- C++ -*- 203a78d15Sespie 303a78d15Sespie // Copyright (C) 2001, 2002 Free Software Foundation, Inc. 403a78d15Sespie // 503a78d15Sespie // This file is part of the GNU ISO C++ Library. This library is free 603a78d15Sespie // software; you can redistribute it and/or modify it under the 703a78d15Sespie // terms of the GNU General Public License as published by the 803a78d15Sespie // Free Software Foundation; either version 2, or (at your option) 903a78d15Sespie // any later version. 1003a78d15Sespie 1103a78d15Sespie // This library is distributed in the hope that it will be useful, 1203a78d15Sespie // but WITHOUT ANY WARRANTY; without even the implied warranty of 1303a78d15Sespie // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1403a78d15Sespie // GNU General Public License for more details. 1503a78d15Sespie 1603a78d15Sespie // You should have received a copy of the GNU General Public License along 1703a78d15Sespie // with this library; see the file COPYING. If not, write to the Free 1803a78d15Sespie // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 1903a78d15Sespie // USA. 2003a78d15Sespie 2103a78d15Sespie // As a special exception, you may use this file as part of a free software 2203a78d15Sespie // library without restriction. Specifically, if other files instantiate 2303a78d15Sespie // templates or use macros or inline functions from this file, or you compile 2403a78d15Sespie // this file and link it with other files to produce an executable, this 2503a78d15Sespie // file does not by itself cause the resulting executable to be covered by 2603a78d15Sespie // the GNU General Public License. This exception does not however 2703a78d15Sespie // invalidate any other reasons why the executable file might be covered by 2803a78d15Sespie // the GNU General Public License. 2903a78d15Sespie 3003a78d15Sespie /* 3103a78d15Sespie * 3203a78d15Sespie * Copyright (c) 1994 3303a78d15Sespie * Hewlett-Packard Company 3403a78d15Sespie * 3503a78d15Sespie * Permission to use, copy, modify, distribute and sell this software 3603a78d15Sespie * and its documentation for any purpose is hereby granted without fee, 3703a78d15Sespie * provided that the above copyright notice appear in all copies and 3803a78d15Sespie * that both that copyright notice and this permission notice appear 3903a78d15Sespie * in supporting documentation. Hewlett-Packard Company makes no 4003a78d15Sespie * representations about the suitability of this software for any 4103a78d15Sespie * purpose. It is provided "as is" without express or implied warranty. 4203a78d15Sespie * 4303a78d15Sespie * 4403a78d15Sespie * Copyright (c) 1996,1997 4503a78d15Sespie * Silicon Graphics Computer Systems, Inc. 4603a78d15Sespie * 4703a78d15Sespie * Permission to use, copy, modify, distribute and sell this software 4803a78d15Sespie * and its documentation for any purpose is hereby granted without fee, 4903a78d15Sespie * provided that the above copyright notice appear in all copies and 5003a78d15Sespie * that both that copyright notice and this permission notice appear 5103a78d15Sespie * in supporting documentation. Silicon Graphics makes no 5203a78d15Sespie * representations about the suitability of this software for any 5303a78d15Sespie * purpose. It is provided "as is" without express or implied warranty. 5403a78d15Sespie */ 5503a78d15Sespie 5603a78d15Sespie /** @file list.tcc 5703a78d15Sespie * This is an internal header file, included by other library headers. 5803a78d15Sespie * You should not attempt to use it directly. 5903a78d15Sespie */ 6003a78d15Sespie 6103a78d15Sespie #ifndef __GLIBCPP_INTERNAL_LIST_TCC 6203a78d15Sespie #define __GLIBCPP_INTERNAL_LIST_TCC 6303a78d15Sespie 6403a78d15Sespie namespace std 6503a78d15Sespie { 6603a78d15Sespie template<typename _Tp, typename _Alloc> 6703a78d15Sespie void 6803a78d15Sespie _List_base<_Tp,_Alloc>:: __clear()6903a78d15Sespie __clear() 7003a78d15Sespie { 7103a78d15Sespie typedef _List_node<_Tp> _Node; 7203a78d15Sespie _Node* __cur = static_cast<_Node*>(_M_node->_M_next); 7303a78d15Sespie while (__cur != _M_node) 7403a78d15Sespie { 7503a78d15Sespie _Node* __tmp = __cur; 7603a78d15Sespie __cur = static_cast<_Node*>(__cur->_M_next); 7703a78d15Sespie _Destroy(&__tmp->_M_data); 7803a78d15Sespie _M_put_node(__tmp); 7903a78d15Sespie } 8003a78d15Sespie _M_node->_M_next = _M_node; 8103a78d15Sespie _M_node->_M_prev = _M_node; 8203a78d15Sespie } 8303a78d15Sespie 8403a78d15Sespie template<typename _Tp, typename _Alloc> 8503a78d15Sespie typename list<_Tp,_Alloc>::iterator 8603a78d15Sespie list<_Tp,_Alloc>:: insert(iterator __position,const value_type & __x)8703a78d15Sespie insert(iterator __position, const value_type& __x) 8803a78d15Sespie { 8903a78d15Sespie _Node* __tmp = _M_create_node(__x); 9003a78d15Sespie __tmp->_M_next = __position._M_node; 9103a78d15Sespie __tmp->_M_prev = __position._M_node->_M_prev; 9203a78d15Sespie __position._M_node->_M_prev->_M_next = __tmp; 9303a78d15Sespie __position._M_node->_M_prev = __tmp; 9403a78d15Sespie return __tmp; 9503a78d15Sespie } 9603a78d15Sespie 9703a78d15Sespie template<typename _Tp, typename _Alloc> 9803a78d15Sespie typename list<_Tp,_Alloc>::iterator 9903a78d15Sespie list<_Tp,_Alloc>:: erase(iterator __position)10003a78d15Sespie erase(iterator __position) 10103a78d15Sespie { 10203a78d15Sespie _List_node_base* __next_node = __position._M_node->_M_next; 10303a78d15Sespie _List_node_base* __prev_node = __position._M_node->_M_prev; 10403a78d15Sespie _Node* __n = static_cast<_Node*>(__position._M_node); 10503a78d15Sespie __prev_node->_M_next = __next_node; 10603a78d15Sespie __next_node->_M_prev = __prev_node; 10703a78d15Sespie _Destroy(&__n->_M_data); 10803a78d15Sespie _M_put_node(__n); 10903a78d15Sespie return iterator(static_cast<_Node*>(__next_node)); 11003a78d15Sespie } 11103a78d15Sespie 11203a78d15Sespie template<typename _Tp, typename _Alloc> 11303a78d15Sespie void 11403a78d15Sespie list<_Tp,_Alloc>:: resize(size_type __new_size,const value_type & __x)11503a78d15Sespie resize(size_type __new_size, const value_type& __x) 11603a78d15Sespie { 11703a78d15Sespie iterator __i = begin(); 11803a78d15Sespie size_type __len = 0; 11903a78d15Sespie for ( ; __i != end() && __len < __new_size; ++__i, ++__len) 12003a78d15Sespie ; 12103a78d15Sespie if (__len == __new_size) 12203a78d15Sespie erase(__i, end()); 12303a78d15Sespie else // __i == end() 12403a78d15Sespie insert(end(), __new_size - __len, __x); 12503a78d15Sespie } 12603a78d15Sespie 12703a78d15Sespie template<typename _Tp, typename _Alloc> 12803a78d15Sespie list<_Tp,_Alloc>& 12903a78d15Sespie list<_Tp,_Alloc>:: operator =(const list & __x)13003a78d15Sespie operator=(const list& __x) 13103a78d15Sespie { 13203a78d15Sespie if (this != &__x) 13303a78d15Sespie { 13403a78d15Sespie iterator __first1 = begin(); 13503a78d15Sespie iterator __last1 = end(); 13603a78d15Sespie const_iterator __first2 = __x.begin(); 13703a78d15Sespie const_iterator __last2 = __x.end(); 13803a78d15Sespie while (__first1 != __last1 && __first2 != __last2) 13903a78d15Sespie *__first1++ = *__first2++; 14003a78d15Sespie if (__first2 == __last2) 14103a78d15Sespie erase(__first1, __last1); 14203a78d15Sespie else 14303a78d15Sespie insert(__last1, __first2, __last2); 14403a78d15Sespie } 14503a78d15Sespie return *this; 14603a78d15Sespie } 14703a78d15Sespie 14803a78d15Sespie template<typename _Tp, typename _Alloc> 14903a78d15Sespie void 15003a78d15Sespie list<_Tp,_Alloc>:: _M_fill_assign(size_type __n,const value_type & __val)15103a78d15Sespie _M_fill_assign(size_type __n, const value_type& __val) 15203a78d15Sespie { 15303a78d15Sespie iterator __i = begin(); 15403a78d15Sespie for ( ; __i != end() && __n > 0; ++__i, --__n) 15503a78d15Sespie *__i = __val; 15603a78d15Sespie if (__n > 0) 15703a78d15Sespie insert(end(), __n, __val); 15803a78d15Sespie else 15903a78d15Sespie erase(__i, end()); 16003a78d15Sespie } 16103a78d15Sespie 16203a78d15Sespie template<typename _Tp, typename _Alloc> 16303a78d15Sespie template <typename _InputIter> 16403a78d15Sespie void 16503a78d15Sespie list<_Tp,_Alloc>:: _M_assign_dispatch(_InputIter __first2,_InputIter __last2,__false_type)16603a78d15Sespie _M_assign_dispatch(_InputIter __first2, _InputIter __last2, __false_type) 16703a78d15Sespie { 16803a78d15Sespie iterator __first1 = begin(); 16903a78d15Sespie iterator __last1 = end(); 17003a78d15Sespie for (; __first1 != __last1 && __first2 != __last2; ++__first1, ++__first2) 17103a78d15Sespie *__first1 = *__first2; 17203a78d15Sespie if (__first2 == __last2) 17303a78d15Sespie erase(__first1, __last1); 17403a78d15Sespie else 17503a78d15Sespie insert(__last1, __first2, __last2); 17603a78d15Sespie } 17703a78d15Sespie 17803a78d15Sespie template<typename _Tp, typename _Alloc> 17903a78d15Sespie void 18003a78d15Sespie list<_Tp,_Alloc>:: remove(const value_type & __value)18103a78d15Sespie remove(const value_type& __value) 18203a78d15Sespie { 18303a78d15Sespie iterator __first = begin(); 18403a78d15Sespie iterator __last = end(); 18503a78d15Sespie while (__first != __last) 18603a78d15Sespie { 18703a78d15Sespie iterator __next = __first; 18803a78d15Sespie ++__next; 18903a78d15Sespie if (*__first == __value) 19003a78d15Sespie erase(__first); 19103a78d15Sespie __first = __next; 19203a78d15Sespie } 19303a78d15Sespie } 19403a78d15Sespie 19503a78d15Sespie template<typename _Tp, typename _Alloc> 19603a78d15Sespie void 19703a78d15Sespie list<_Tp,_Alloc>:: unique()19803a78d15Sespie unique() 19903a78d15Sespie { 20003a78d15Sespie iterator __first = begin(); 20103a78d15Sespie iterator __last = end(); 20203a78d15Sespie if (__first == __last) return; 20303a78d15Sespie iterator __next = __first; 20403a78d15Sespie while (++__next != __last) 20503a78d15Sespie { 20603a78d15Sespie if (*__first == *__next) 20703a78d15Sespie erase(__next); 20803a78d15Sespie else 20903a78d15Sespie __first = __next; 21003a78d15Sespie __next = __first; 21103a78d15Sespie } 21203a78d15Sespie } 21303a78d15Sespie 21403a78d15Sespie template<typename _Tp, typename _Alloc> 21503a78d15Sespie void 21603a78d15Sespie list<_Tp,_Alloc>:: merge(list & __x)21703a78d15Sespie merge(list& __x) 21803a78d15Sespie { 219*19731d4fSespie // _GLIBCXX_RESOLVE_LIB_DEFECTS 220*19731d4fSespie // 300. list::merge() specification incomplete 221*19731d4fSespie if (this != &__x) 222*19731d4fSespie { 22303a78d15Sespie iterator __first1 = begin(); 22403a78d15Sespie iterator __last1 = end(); 22503a78d15Sespie iterator __first2 = __x.begin(); 22603a78d15Sespie iterator __last2 = __x.end(); 22703a78d15Sespie while (__first1 != __last1 && __first2 != __last2) 22803a78d15Sespie if (*__first2 < *__first1) 22903a78d15Sespie { 23003a78d15Sespie iterator __next = __first2; 23103a78d15Sespie _M_transfer(__first1, __first2, ++__next); 23203a78d15Sespie __first2 = __next; 23303a78d15Sespie } 23403a78d15Sespie else 23503a78d15Sespie ++__first1; 23603a78d15Sespie if (__first2 != __last2) 23703a78d15Sespie _M_transfer(__last1, __first2, __last2); 23803a78d15Sespie } 239*19731d4fSespie } 24003a78d15Sespie 24103a78d15Sespie // FIXME put this somewhere else 24203a78d15Sespie inline void __List_base_reverse(_List_node_base * __p)24303a78d15Sespie __List_base_reverse(_List_node_base* __p) 24403a78d15Sespie { 24503a78d15Sespie _List_node_base* __tmp = __p; 24603a78d15Sespie do { 24703a78d15Sespie std::swap(__tmp->_M_next, __tmp->_M_prev); 24803a78d15Sespie __tmp = __tmp->_M_prev; // Old next node is now prev. 24903a78d15Sespie } while (__tmp != __p); 25003a78d15Sespie } 25103a78d15Sespie 25203a78d15Sespie template<typename _Tp, typename _Alloc> 25303a78d15Sespie void 25403a78d15Sespie list<_Tp,_Alloc>:: sort()25503a78d15Sespie sort() 25603a78d15Sespie { 25703a78d15Sespie // Do nothing if the list has length 0 or 1. 25803a78d15Sespie if (_M_node->_M_next != _M_node && _M_node->_M_next->_M_next != _M_node) 25903a78d15Sespie { 26003a78d15Sespie list __carry; 26103a78d15Sespie list __counter[64]; 26203a78d15Sespie int __fill = 0; 26303a78d15Sespie while (!empty()) 26403a78d15Sespie { 26503a78d15Sespie __carry.splice(__carry.begin(), *this, begin()); 26603a78d15Sespie int __i = 0; 26703a78d15Sespie while(__i < __fill && !__counter[__i].empty()) 26803a78d15Sespie { 26903a78d15Sespie __counter[__i].merge(__carry); 27003a78d15Sespie __carry.swap(__counter[__i++]); 27103a78d15Sespie } 27203a78d15Sespie __carry.swap(__counter[__i]); 27303a78d15Sespie if (__i == __fill) ++__fill; 27403a78d15Sespie } 27503a78d15Sespie 27603a78d15Sespie for (int __i = 1; __i < __fill; ++__i) 27703a78d15Sespie __counter[__i].merge(__counter[__i-1]); 27803a78d15Sespie swap(__counter[__fill-1]); 27903a78d15Sespie } 28003a78d15Sespie } 28103a78d15Sespie 28203a78d15Sespie template<typename _Tp, typename _Alloc> 28303a78d15Sespie template <typename _Predicate> 28403a78d15Sespie void 28503a78d15Sespie list<_Tp,_Alloc>:: remove_if(_Predicate __pred)28603a78d15Sespie remove_if(_Predicate __pred) 28703a78d15Sespie { 28803a78d15Sespie iterator __first = begin(); 28903a78d15Sespie iterator __last = end(); 29003a78d15Sespie while (__first != __last) 29103a78d15Sespie { 29203a78d15Sespie iterator __next = __first; 29303a78d15Sespie ++__next; 29403a78d15Sespie if (__pred(*__first)) erase(__first); 29503a78d15Sespie __first = __next; 29603a78d15Sespie } 29703a78d15Sespie } 29803a78d15Sespie 29903a78d15Sespie template<typename _Tp, typename _Alloc> 30003a78d15Sespie template <typename _BinaryPredicate> 30103a78d15Sespie void 30203a78d15Sespie list<_Tp,_Alloc>:: unique(_BinaryPredicate __binary_pred)30303a78d15Sespie unique(_BinaryPredicate __binary_pred) 30403a78d15Sespie { 30503a78d15Sespie iterator __first = begin(); 30603a78d15Sespie iterator __last = end(); 30703a78d15Sespie if (__first == __last) return; 30803a78d15Sespie iterator __next = __first; 30903a78d15Sespie while (++__next != __last) 31003a78d15Sespie { 31103a78d15Sespie if (__binary_pred(*__first, *__next)) 31203a78d15Sespie erase(__next); 31303a78d15Sespie else 31403a78d15Sespie __first = __next; 31503a78d15Sespie __next = __first; 31603a78d15Sespie } 31703a78d15Sespie } 31803a78d15Sespie 31903a78d15Sespie template<typename _Tp, typename _Alloc> 32003a78d15Sespie template <typename _StrictWeakOrdering> 32103a78d15Sespie void 32203a78d15Sespie list<_Tp,_Alloc>:: merge(list & __x,_StrictWeakOrdering __comp)32303a78d15Sespie merge(list& __x, _StrictWeakOrdering __comp) 32403a78d15Sespie { 325*19731d4fSespie // _GLIBCXX_RESOLVE_LIB_DEFECTS 326*19731d4fSespie // 300. list::merge() specification incomplete 327*19731d4fSespie if (this != &__x) 328*19731d4fSespie { 32903a78d15Sespie iterator __first1 = begin(); 33003a78d15Sespie iterator __last1 = end(); 33103a78d15Sespie iterator __first2 = __x.begin(); 33203a78d15Sespie iterator __last2 = __x.end(); 33303a78d15Sespie while (__first1 != __last1 && __first2 != __last2) 33403a78d15Sespie if (__comp(*__first2, *__first1)) 33503a78d15Sespie { 33603a78d15Sespie iterator __next = __first2; 33703a78d15Sespie _M_transfer(__first1, __first2, ++__next); 33803a78d15Sespie __first2 = __next; 33903a78d15Sespie } 34003a78d15Sespie else 34103a78d15Sespie ++__first1; 34203a78d15Sespie if (__first2 != __last2) _M_transfer(__last1, __first2, __last2); 34303a78d15Sespie } 344*19731d4fSespie } 34503a78d15Sespie 34603a78d15Sespie template<typename _Tp, typename _Alloc> 34703a78d15Sespie template <typename _StrictWeakOrdering> 34803a78d15Sespie void 34903a78d15Sespie list<_Tp,_Alloc>:: sort(_StrictWeakOrdering __comp)35003a78d15Sespie sort(_StrictWeakOrdering __comp) 35103a78d15Sespie { 35203a78d15Sespie // Do nothing if the list has length 0 or 1. 35303a78d15Sespie if (_M_node->_M_next != _M_node && _M_node->_M_next->_M_next != _M_node) 35403a78d15Sespie { 35503a78d15Sespie list __carry; 35603a78d15Sespie list __counter[64]; 35703a78d15Sespie int __fill = 0; 35803a78d15Sespie while (!empty()) 35903a78d15Sespie { 36003a78d15Sespie __carry.splice(__carry.begin(), *this, begin()); 36103a78d15Sespie int __i = 0; 36203a78d15Sespie while(__i < __fill && !__counter[__i].empty()) 36303a78d15Sespie { 36403a78d15Sespie __counter[__i].merge(__carry, __comp); 36503a78d15Sespie __carry.swap(__counter[__i++]); 36603a78d15Sespie } 36703a78d15Sespie __carry.swap(__counter[__i]); 36803a78d15Sespie if (__i == __fill) ++__fill; 36903a78d15Sespie } 37003a78d15Sespie 37103a78d15Sespie for (int __i = 1; __i < __fill; ++__i) 37203a78d15Sespie __counter[__i].merge(__counter[__i-1], __comp); 37303a78d15Sespie swap(__counter[__fill-1]); 37403a78d15Sespie } 37503a78d15Sespie } 37603a78d15Sespie } // namespace std 37703a78d15Sespie 37803a78d15Sespie #endif /* __GLIBCPP_INTERNAL_LIST_TCC */ 379