Import gcc-4.7.2 to new vendor branch
[dragonfly.git] / contrib / gcc-4.7 / libstdc++-v3 / include / bits / list.tcc
1 // List implementation (out of line) -*- C++ -*-
2
3 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
4 // 2011, 2012 Free Software Foundation, Inc.
5 //
6 // This file is part of the GNU ISO C++ Library.  This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 3, or (at your option)
10 // any later version.
11
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16
17 // Under Section 7 of GPL version 3, you are granted additional
18 // permissions described in the GCC Runtime Library Exception, version
19 // 3.1, as published by the Free Software Foundation.
20
21 // You should have received a copy of the GNU General Public License and
22 // a copy of the GCC Runtime Library Exception along with this program;
23 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24 // <http://www.gnu.org/licenses/>.
25
26 /*
27  *
28  * Copyright (c) 1994
29  * Hewlett-Packard Company
30  *
31  * Permission to use, copy, modify, distribute and sell this software
32  * and its documentation for any purpose is hereby granted without fee,
33  * provided that the above copyright notice appear in all copies and
34  * that both that copyright notice and this permission notice appear
35  * in supporting documentation.  Hewlett-Packard Company makes no
36  * representations about the suitability of this software for any
37  * purpose.  It is provided "as is" without express or implied warranty.
38  *
39  *
40  * Copyright (c) 1996,1997
41  * Silicon Graphics Computer Systems, Inc.
42  *
43  * Permission to use, copy, modify, distribute and sell this software
44  * and its documentation for any purpose is hereby granted without fee,
45  * provided that the above copyright notice appear in all copies and
46  * that both that copyright notice and this permission notice appear
47  * in supporting documentation.  Silicon Graphics makes no
48  * representations about the suitability of this software for any
49  * purpose.  It is provided "as is" without express or implied warranty.
50  */
51
52 /** @file bits/list.tcc
53  *  This is an internal header file, included by other library headers.
54  *  Do not attempt to use it directly. @headername{list}
55  */
56
57 #ifndef _LIST_TCC
58 #define _LIST_TCC 1
59
60 namespace std _GLIBCXX_VISIBILITY(default)
61 {
62 _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
63
64   template<typename _Tp, typename _Alloc>
65     void
66     _List_base<_Tp, _Alloc>::
67     _M_clear()
68     {
69       typedef _List_node<_Tp>  _Node;
70       _Node* __cur = static_cast<_Node*>(_M_impl._M_node._M_next);
71       while (__cur != &_M_impl._M_node)
72         {
73           _Node* __tmp = __cur;
74           __cur = static_cast<_Node*>(__cur->_M_next);
75 #ifdef __GXX_EXPERIMENTAL_CXX0X__
76           _M_get_Node_allocator().destroy(__tmp);
77 #else
78           _M_get_Tp_allocator().destroy(std::__addressof(__tmp->_M_data));
79 #endif
80           _M_put_node(__tmp);
81         }
82     }
83
84 #ifdef __GXX_EXPERIMENTAL_CXX0X__
85   template<typename _Tp, typename _Alloc>
86     template<typename... _Args>
87       typename list<_Tp, _Alloc>::iterator
88       list<_Tp, _Alloc>::
89       emplace(iterator __position, _Args&&... __args)
90       {
91         _Node* __tmp = _M_create_node(std::forward<_Args>(__args)...);
92         __tmp->_M_hook(__position._M_node);
93         return iterator(__tmp);
94       }
95 #endif
96
97   template<typename _Tp, typename _Alloc>
98     typename list<_Tp, _Alloc>::iterator
99     list<_Tp, _Alloc>::
100     insert(iterator __position, const value_type& __x)
101     {
102       _Node* __tmp = _M_create_node(__x);
103       __tmp->_M_hook(__position._M_node);
104       return iterator(__tmp);
105     }
106
107   template<typename _Tp, typename _Alloc>
108     typename list<_Tp, _Alloc>::iterator
109     list<_Tp, _Alloc>::
110     erase(iterator __position)
111     {
112       iterator __ret = iterator(__position._M_node->_M_next);
113       _M_erase(__position);
114       return __ret;
115     }
116
117 #ifdef __GXX_EXPERIMENTAL_CXX0X__
118   template<typename _Tp, typename _Alloc>
119     void
120     list<_Tp, _Alloc>::
121     _M_default_append(size_type __n)
122     {
123       size_type __i = 0;
124       __try
125         {
126           for (; __i < __n; ++__i)
127             emplace_back();
128         }
129       __catch(...)
130         {
131           for (; __i; --__i)
132             pop_back();
133           __throw_exception_again;
134         }
135     }
136
137   template<typename _Tp, typename _Alloc>
138     void
139     list<_Tp, _Alloc>::
140     resize(size_type __new_size)
141     {
142       iterator __i = begin();
143       size_type __len = 0;
144       for (; __i != end() && __len < __new_size; ++__i, ++__len)
145         ;
146       if (__len == __new_size)
147         erase(__i, end());
148       else                          // __i == end()
149         _M_default_append(__new_size - __len);
150     }
151
152   template<typename _Tp, typename _Alloc>
153     void
154     list<_Tp, _Alloc>::
155     resize(size_type __new_size, const value_type& __x)
156     {
157       iterator __i = begin();
158       size_type __len = 0;
159       for (; __i != end() && __len < __new_size; ++__i, ++__len)
160         ;
161       if (__len == __new_size)
162         erase(__i, end());
163       else                          // __i == end()
164         insert(end(), __new_size - __len, __x);
165     }
166 #else
167   template<typename _Tp, typename _Alloc>
168     void
169     list<_Tp, _Alloc>::
170     resize(size_type __new_size, value_type __x)
171     {
172       iterator __i = begin();
173       size_type __len = 0;
174       for (; __i != end() && __len < __new_size; ++__i, ++__len)
175         ;
176       if (__len == __new_size)
177         erase(__i, end());
178       else                          // __i == end()
179         insert(end(), __new_size - __len, __x);
180     }
181 #endif
182
183   template<typename _Tp, typename _Alloc>
184     list<_Tp, _Alloc>&
185     list<_Tp, _Alloc>::
186     operator=(const list& __x)
187     {
188       if (this != &__x)
189         {
190           iterator __first1 = begin();
191           iterator __last1 = end();
192           const_iterator __first2 = __x.begin();
193           const_iterator __last2 = __x.end();
194           for (; __first1 != __last1 && __first2 != __last2;
195                ++__first1, ++__first2)
196             *__first1 = *__first2;
197           if (__first2 == __last2)
198             erase(__first1, __last1);
199           else
200             insert(__last1, __first2, __last2);
201         }
202       return *this;
203     }
204
205   template<typename _Tp, typename _Alloc>
206     void
207     list<_Tp, _Alloc>::
208     _M_fill_assign(size_type __n, const value_type& __val)
209     {
210       iterator __i = begin();
211       for (; __i != end() && __n > 0; ++__i, --__n)
212         *__i = __val;
213       if (__n > 0)
214         insert(end(), __n, __val);
215       else
216         erase(__i, end());
217     }
218
219   template<typename _Tp, typename _Alloc>
220     template <typename _InputIterator>
221       void
222       list<_Tp, _Alloc>::
223       _M_assign_dispatch(_InputIterator __first2, _InputIterator __last2,
224                          __false_type)
225       {
226         iterator __first1 = begin();
227         iterator __last1 = end();
228         for (; __first1 != __last1 && __first2 != __last2;
229              ++__first1, ++__first2)
230           *__first1 = *__first2;
231         if (__first2 == __last2)
232           erase(__first1, __last1);
233         else
234           insert(__last1, __first2, __last2);
235       }
236
237   template<typename _Tp, typename _Alloc>
238     void
239     list<_Tp, _Alloc>::
240     remove(const value_type& __value)
241     {
242       iterator __first = begin();
243       iterator __last = end();
244       iterator __extra = __last;
245       while (__first != __last)
246         {
247           iterator __next = __first;
248           ++__next;
249           if (*__first == __value)
250             {
251               // _GLIBCXX_RESOLVE_LIB_DEFECTS
252               // 526. Is it undefined if a function in the standard changes
253               // in parameters?
254               if (std::__addressof(*__first) != std::__addressof(__value))
255                 _M_erase(__first);
256               else
257                 __extra = __first;
258             }
259           __first = __next;
260         }
261       if (__extra != __last)
262         _M_erase(__extra);
263     }
264
265   template<typename _Tp, typename _Alloc>
266     void
267     list<_Tp, _Alloc>::
268     unique()
269     {
270       iterator __first = begin();
271       iterator __last = end();
272       if (__first == __last)
273         return;
274       iterator __next = __first;
275       while (++__next != __last)
276         {
277           if (*__first == *__next)
278             _M_erase(__next);
279           else
280             __first = __next;
281           __next = __first;
282         }
283     }
284
285   template<typename _Tp, typename _Alloc>
286     void
287     list<_Tp, _Alloc>::
288 #ifdef __GXX_EXPERIMENTAL_CXX0X__
289     merge(list&& __x)
290 #else
291     merge(list& __x)
292 #endif
293     {
294       // _GLIBCXX_RESOLVE_LIB_DEFECTS
295       // 300. list::merge() specification incomplete
296       if (this != &__x)
297         {
298           _M_check_equal_allocators(__x); 
299
300           iterator __first1 = begin();
301           iterator __last1 = end();
302           iterator __first2 = __x.begin();
303           iterator __last2 = __x.end();
304           while (__first1 != __last1 && __first2 != __last2)
305             if (*__first2 < *__first1)
306               {
307                 iterator __next = __first2;
308                 _M_transfer(__first1, __first2, ++__next);
309                 __first2 = __next;
310               }
311             else
312               ++__first1;
313           if (__first2 != __last2)
314             _M_transfer(__last1, __first2, __last2);
315         }
316     }
317
318   template<typename _Tp, typename _Alloc>
319     template <typename _StrictWeakOrdering>
320       void
321       list<_Tp, _Alloc>::
322 #ifdef __GXX_EXPERIMENTAL_CXX0X__
323       merge(list&& __x, _StrictWeakOrdering __comp)
324 #else
325       merge(list& __x, _StrictWeakOrdering __comp)
326 #endif
327       {
328         // _GLIBCXX_RESOLVE_LIB_DEFECTS
329         // 300. list::merge() specification incomplete
330         if (this != &__x)
331           {
332             _M_check_equal_allocators(__x);
333
334             iterator __first1 = begin();
335             iterator __last1 = end();
336             iterator __first2 = __x.begin();
337             iterator __last2 = __x.end();
338             while (__first1 != __last1 && __first2 != __last2)
339               if (__comp(*__first2, *__first1))
340                 {
341                   iterator __next = __first2;
342                   _M_transfer(__first1, __first2, ++__next);
343                   __first2 = __next;
344                 }
345               else
346                 ++__first1;
347             if (__first2 != __last2)
348               _M_transfer(__last1, __first2, __last2);
349           }
350       }
351
352   template<typename _Tp, typename _Alloc>
353     void
354     list<_Tp, _Alloc>::
355     sort()
356     {
357       // Do nothing if the list has length 0 or 1.
358       if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node
359           && this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node)
360       {
361         list __carry;
362         list __tmp[64];
363         list * __fill = &__tmp[0];
364         list * __counter;
365
366         do
367           {
368             __carry.splice(__carry.begin(), *this, begin());
369
370             for(__counter = &__tmp[0];
371                 __counter != __fill && !__counter->empty();
372                 ++__counter)
373               {
374                 __counter->merge(__carry);
375                 __carry.swap(*__counter);
376               }
377             __carry.swap(*__counter);
378             if (__counter == __fill)
379               ++__fill;
380           }
381         while ( !empty() );
382
383         for (__counter = &__tmp[1]; __counter != __fill; ++__counter)
384           __counter->merge(*(__counter - 1));
385         swap( *(__fill - 1) );
386       }
387     }
388
389   template<typename _Tp, typename _Alloc>
390     template <typename _Predicate>
391       void
392       list<_Tp, _Alloc>::
393       remove_if(_Predicate __pred)
394       {
395         iterator __first = begin();
396         iterator __last = end();
397         while (__first != __last)
398           {
399             iterator __next = __first;
400             ++__next;
401             if (__pred(*__first))
402               _M_erase(__first);
403             __first = __next;
404           }
405       }
406
407   template<typename _Tp, typename _Alloc>
408     template <typename _BinaryPredicate>
409       void
410       list<_Tp, _Alloc>::
411       unique(_BinaryPredicate __binary_pred)
412       {
413         iterator __first = begin();
414         iterator __last = end();
415         if (__first == __last)
416           return;
417         iterator __next = __first;
418         while (++__next != __last)
419           {
420             if (__binary_pred(*__first, *__next))
421               _M_erase(__next);
422             else
423               __first = __next;
424             __next = __first;
425           }
426       }
427
428   template<typename _Tp, typename _Alloc>
429     template <typename _StrictWeakOrdering>
430       void
431       list<_Tp, _Alloc>::
432       sort(_StrictWeakOrdering __comp)
433       {
434         // Do nothing if the list has length 0 or 1.
435         if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node
436             && this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node)
437           {
438             list __carry;
439             list __tmp[64];
440             list * __fill = &__tmp[0];
441             list * __counter;
442
443             do
444               {
445                 __carry.splice(__carry.begin(), *this, begin());
446
447                 for(__counter = &__tmp[0];
448                     __counter != __fill && !__counter->empty();
449                     ++__counter)
450                   {
451                     __counter->merge(__carry, __comp);
452                     __carry.swap(*__counter);
453                   }
454                 __carry.swap(*__counter);
455                 if (__counter == __fill)
456                   ++__fill;
457               }
458             while ( !empty() );
459
460             for (__counter = &__tmp[1]; __counter != __fill; ++__counter)
461               __counter->merge(*(__counter - 1), __comp);
462             swap(*(__fill - 1));
463           }
464       }
465
466 _GLIBCXX_END_NAMESPACE_CONTAINER
467 } // namespace std
468
469 #endif /* _LIST_TCC */
470