1 : // List implementation (out of line) -*- C++ -*-
2 :
3 : // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
4 : // 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 2, 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 : // You should have received a copy of the GNU General Public License along
18 : // with this library; see the file COPYING. If not, write to the Free
19 : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20 : // USA.
21 :
22 : // As a special exception, you may use this file as part of a free software
23 : // library without restriction. Specifically, if other files instantiate
24 : // templates or use macros or inline functions from this file, or you compile
25 : // this file and link it with other files to produce an executable, this
26 : // file does not by itself cause the resulting executable to be covered by
27 : // the GNU General Public License. This exception does not however
28 : // invalidate any other reasons why the executable file might be covered by
29 : // the GNU General Public License.
30 :
31 : /*
32 : *
33 : * Copyright (c) 1994
34 : * Hewlett-Packard Company
35 : *
36 : * Permission to use, copy, modify, distribute and sell this software
37 : * and its documentation for any purpose is hereby granted without fee,
38 : * provided that the above copyright notice appear in all copies and
39 : * that both that copyright notice and this permission notice appear
40 : * in supporting documentation. Hewlett-Packard Company makes no
41 : * representations about the suitability of this software for any
42 : * purpose. It is provided "as is" without express or implied warranty.
43 : *
44 : *
45 : * Copyright (c) 1996,1997
46 : * Silicon Graphics Computer Systems, Inc.
47 : *
48 : * Permission to use, copy, modify, distribute and sell this software
49 : * and its documentation for any purpose is hereby granted without fee,
50 : * provided that the above copyright notice appear in all copies and
51 : * that both that copyright notice and this permission notice appear
52 : * in supporting documentation. Silicon Graphics makes no
53 : * representations about the suitability of this software for any
54 : * purpose. It is provided "as is" without express or implied warranty.
55 : */
56 :
57 : /** @file list.tcc
58 : * This is an internal header file, included by other library headers.
59 : * You should not attempt to use it directly.
60 : */
61 :
62 : #ifndef _LIST_TCC
63 : #define _LIST_TCC 1
64 :
65 : _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
66 :
67 : template<typename _Tp, typename _Alloc>
68 : void
69 : _List_base<_Tp, _Alloc>::
70 19 : _M_clear()
71 : {
72 : typedef _List_node<_Tp> _Node;
73 19 : _Node* __cur = static_cast<_Node*>(this->_M_impl._M_node._M_next);
74 60 : while (__cur != &this->_M_impl._M_node)
75 : {
76 22 : _Node* __tmp = __cur;
77 22 : __cur = static_cast<_Node*>(__cur->_M_next);
78 22 : _M_get_Tp_allocator().destroy(&__tmp->_M_data);
79 22 : _M_put_node(__tmp);
80 : }
81 19 : }
82 :
83 : #ifdef __GXX_EXPERIMENTAL_CXX0X__
84 : template<typename _Tp, typename _Alloc>
85 : template<typename... _Args>
86 : typename list<_Tp, _Alloc>::iterator
87 : list<_Tp, _Alloc>::
88 : emplace(iterator __position, _Args&&... __args)
89 : {
90 : _Node* __tmp = _M_create_node(std::forward<_Args>(__args)...);
91 : __tmp->hook(__position._M_node);
92 : return iterator(__tmp);
93 : }
94 : #endif
95 :
96 : template<typename _Tp, typename _Alloc>
97 : typename list<_Tp, _Alloc>::iterator
98 : list<_Tp, _Alloc>::
99 : insert(iterator __position, const value_type& __x)
100 : {
101 : _Node* __tmp = _M_create_node(__x);
102 : __tmp->hook(__position._M_node);
103 : return iterator(__tmp);
104 : }
105 :
106 : template<typename _Tp, typename _Alloc>
107 : typename list<_Tp, _Alloc>::iterator
108 : list<_Tp, _Alloc>::
109 25 : erase(iterator __position)
110 : {
111 25 : iterator __ret = iterator(__position._M_node->_M_next);
112 25 : _M_erase(__position);
113 : return __ret;
114 : }
115 :
116 : template<typename _Tp, typename _Alloc>
117 : void
118 : list<_Tp, _Alloc>::
119 : resize(size_type __new_size, value_type __x)
120 : {
121 : iterator __i = begin();
122 : size_type __len = 0;
123 : for (; __i != end() && __len < __new_size; ++__i, ++__len)
124 : ;
125 : if (__len == __new_size)
126 : erase(__i, end());
127 : else // __i == end()
128 : insert(end(), __new_size - __len, __x);
129 : }
130 :
131 : template<typename _Tp, typename _Alloc>
132 : list<_Tp, _Alloc>&
133 : list<_Tp, _Alloc>::
134 : operator=(const list& __x)
135 : {
136 : if (this != &__x)
137 : {
138 : iterator __first1 = begin();
139 : iterator __last1 = end();
140 : const_iterator __first2 = __x.begin();
141 : const_iterator __last2 = __x.end();
142 : for (; __first1 != __last1 && __first2 != __last2;
143 : ++__first1, ++__first2)
144 : *__first1 = *__first2;
145 : if (__first2 == __last2)
146 : erase(__first1, __last1);
147 : else
148 : insert(__last1, __first2, __last2);
149 : }
150 : return *this;
151 : }
152 :
153 : template<typename _Tp, typename _Alloc>
154 : void
155 : list<_Tp, _Alloc>::
156 : _M_fill_assign(size_type __n, const value_type& __val)
157 : {
158 : iterator __i = begin();
159 : for (; __i != end() && __n > 0; ++__i, --__n)
160 : *__i = __val;
161 : if (__n > 0)
162 : insert(end(), __n, __val);
163 : else
164 : erase(__i, end());
165 : }
166 :
167 : template<typename _Tp, typename _Alloc>
168 : template <typename _InputIterator>
169 : void
170 : list<_Tp, _Alloc>::
171 : _M_assign_dispatch(_InputIterator __first2, _InputIterator __last2,
172 : __false_type)
173 : {
174 : iterator __first1 = begin();
175 : iterator __last1 = end();
176 : for (; __first1 != __last1 && __first2 != __last2;
177 : ++__first1, ++__first2)
178 : *__first1 = *__first2;
179 : if (__first2 == __last2)
180 : erase(__first1, __last1);
181 : else
182 : insert(__last1, __first2, __last2);
183 : }
184 :
185 : template<typename _Tp, typename _Alloc>
186 : void
187 : list<_Tp, _Alloc>::
188 : remove(const value_type& __value)
189 : {
190 : iterator __first = begin();
191 : iterator __last = end();
192 : iterator __extra = __last;
193 : while (__first != __last)
194 : {
195 : iterator __next = __first;
196 : ++__next;
197 : if (*__first == __value)
198 : {
199 : // _GLIBCXX_RESOLVE_LIB_DEFECTS
200 : // 526. Is it undefined if a function in the standard changes
201 : // in parameters?
202 : if (&*__first != &__value)
203 : _M_erase(__first);
204 : else
205 : __extra = __first;
206 : }
207 : __first = __next;
208 : }
209 : if (__extra != __last)
210 : _M_erase(__extra);
211 : }
212 :
213 : template<typename _Tp, typename _Alloc>
214 : void
215 : list<_Tp, _Alloc>::
216 : unique()
217 : {
218 : iterator __first = begin();
219 : iterator __last = end();
220 : if (__first == __last)
221 : return;
222 : iterator __next = __first;
223 : while (++__next != __last)
224 : {
225 : if (*__first == *__next)
226 : _M_erase(__next);
227 : else
228 : __first = __next;
229 : __next = __first;
230 : }
231 : }
232 :
233 : template<typename _Tp, typename _Alloc>
234 : void
235 : list<_Tp, _Alloc>::
236 : #ifdef __GXX_EXPERIMENTAL_CXX0X__
237 : merge(list&& __x)
238 : #else
239 : merge(list& __x)
240 : #endif
241 : {
242 : // _GLIBCXX_RESOLVE_LIB_DEFECTS
243 : // 300. list::merge() specification incomplete
244 : if (this != &__x)
245 : {
246 : _M_check_equal_allocators(__x);
247 :
248 : iterator __first1 = begin();
249 : iterator __last1 = end();
250 : iterator __first2 = __x.begin();
251 : iterator __last2 = __x.end();
252 : while (__first1 != __last1 && __first2 != __last2)
253 : if (*__first2 < *__first1)
254 : {
255 : iterator __next = __first2;
256 : _M_transfer(__first1, __first2, ++__next);
257 : __first2 = __next;
258 : }
259 : else
260 : ++__first1;
261 : if (__first2 != __last2)
262 : _M_transfer(__last1, __first2, __last2);
263 : }
264 : }
265 :
266 : template<typename _Tp, typename _Alloc>
267 : template <typename _StrictWeakOrdering>
268 : void
269 : list<_Tp, _Alloc>::
270 : #ifdef __GXX_EXPERIMENTAL_CXX0X__
271 : merge(list&& __x, _StrictWeakOrdering __comp)
272 : #else
273 : merge(list& __x, _StrictWeakOrdering __comp)
274 : #endif
275 : {
276 : // _GLIBCXX_RESOLVE_LIB_DEFECTS
277 : // 300. list::merge() specification incomplete
278 : if (this != &__x)
279 : {
280 : _M_check_equal_allocators(__x);
281 :
282 : iterator __first1 = begin();
283 : iterator __last1 = end();
284 : iterator __first2 = __x.begin();
285 : iterator __last2 = __x.end();
286 : while (__first1 != __last1 && __first2 != __last2)
287 : if (__comp(*__first2, *__first1))
288 : {
289 : iterator __next = __first2;
290 : _M_transfer(__first1, __first2, ++__next);
291 : __first2 = __next;
292 : }
293 : else
294 : ++__first1;
295 : if (__first2 != __last2)
296 : _M_transfer(__last1, __first2, __last2);
297 : }
298 : }
299 :
300 : template<typename _Tp, typename _Alloc>
301 : void
302 : list<_Tp, _Alloc>::
303 : sort()
304 : {
305 : // Do nothing if the list has length 0 or 1.
306 : if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node
307 : && this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node)
308 : {
309 : list __carry;
310 : list __tmp[64];
311 : list * __fill = &__tmp[0];
312 : list * __counter;
313 :
314 : do
315 : {
316 : __carry.splice(__carry.begin(), *this, begin());
317 :
318 : for(__counter = &__tmp[0];
319 : __counter != __fill && !__counter->empty();
320 : ++__counter)
321 : {
322 : __counter->merge(__carry);
323 : __carry.swap(*__counter);
324 : }
325 : __carry.swap(*__counter);
326 : if (__counter == __fill)
327 : ++__fill;
328 : }
329 : while ( !empty() );
330 :
331 : for (__counter = &__tmp[1]; __counter != __fill; ++__counter)
332 : __counter->merge(*(__counter - 1));
333 : swap( *(__fill - 1) );
334 : }
335 : }
336 :
337 : template<typename _Tp, typename _Alloc>
338 : template <typename _Predicate>
339 : void
340 : list<_Tp, _Alloc>::
341 : remove_if(_Predicate __pred)
342 : {
343 : iterator __first = begin();
344 : iterator __last = end();
345 : while (__first != __last)
346 : {
347 : iterator __next = __first;
348 : ++__next;
349 : if (__pred(*__first))
350 : _M_erase(__first);
351 : __first = __next;
352 : }
353 : }
354 :
355 : template<typename _Tp, typename _Alloc>
356 : template <typename _BinaryPredicate>
357 : void
358 : list<_Tp, _Alloc>::
359 : unique(_BinaryPredicate __binary_pred)
360 : {
361 : iterator __first = begin();
362 : iterator __last = end();
363 : if (__first == __last)
364 : return;
365 : iterator __next = __first;
366 : while (++__next != __last)
367 : {
368 : if (__binary_pred(*__first, *__next))
369 : _M_erase(__next);
370 : else
371 : __first = __next;
372 : __next = __first;
373 : }
374 : }
375 :
376 : template<typename _Tp, typename _Alloc>
377 : template <typename _StrictWeakOrdering>
378 : void
379 : list<_Tp, _Alloc>::
380 : sort(_StrictWeakOrdering __comp)
381 : {
382 : // Do nothing if the list has length 0 or 1.
383 : if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node
384 : && this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node)
385 : {
386 : list __carry;
387 : list __tmp[64];
388 : list * __fill = &__tmp[0];
389 : list * __counter;
390 :
391 : do
392 : {
393 : __carry.splice(__carry.begin(), *this, begin());
394 :
395 : for(__counter = &__tmp[0];
396 : __counter != __fill && !__counter->empty();
397 : ++__counter)
398 : {
399 : __counter->merge(__carry, __comp);
400 : __carry.swap(*__counter);
401 : }
402 : __carry.swap(*__counter);
403 : if (__counter == __fill)
404 : ++__fill;
405 : }
406 : while ( !empty() );
407 :
408 : for (__counter = &__tmp[1]; __counter != __fill; ++__counter)
409 : __counter->merge(*(__counter - 1), __comp);
410 : swap(*(__fill - 1));
411 : }
412 : }
413 :
414 : _GLIBCXX_END_NESTED_NAMESPACE
415 :
416 : #endif /* _LIST_TCC */
417 :
|