| 1 |
/* |
| 2 |
* Copyright (c) 1996,1997 |
| 3 |
* Silicon Graphics Computer Systems, Inc. |
| 4 |
* |
| 5 |
* Copyright (c) 1997 |
| 6 |
* Moscow Center for SPARC Technology |
| 7 |
* |
| 8 |
* Copyright (c) 1999 |
| 9 |
* Boris Fomitchev |
| 10 |
* |
| 11 |
* Copyright (c) 2012 |
| 12 |
* Petr Ovtchenkov |
| 13 |
* |
| 14 |
* This material is provided "as is", with absolutely no warranty expressed |
| 15 |
* or implied. Any use is at your own risk. |
| 16 |
* |
| 17 |
* Permission to use or copy this software for any purpose is hereby granted |
| 18 |
* without fee, provided the above notices are retained on all copies. |
| 19 |
* Permission to modify the code and to distribute modified code is granted, |
| 20 |
* provided the above notices are retained, and a notice that the code was |
| 21 |
* modified is included with the above copyright notice. |
| 22 |
* |
| 23 |
*/ |
| 24 |
|
| 25 |
#ifndef _STLP_FORWARD_LIST |
| 26 |
#define _STLP_FORWARD_LIST |
| 27 |
|
| 28 |
#ifndef _STLP_OUTERMOST_HEADER_ID |
| 29 |
# define _STLP_OUTERMOST_HEADER_ID 0x58 |
| 30 |
# include <stl/_prolog.h> |
| 31 |
#endif |
| 32 |
|
| 33 |
#include <utility> |
| 34 |
|
| 35 |
#ifndef _STLP_INTERNAL_ALGOBASE_H |
| 36 |
# include <stl/_algobase.h> |
| 37 |
#endif |
| 38 |
|
| 39 |
#ifndef _STLP_INTERNAL_ALLOC_H |
| 40 |
# include <stl/_alloc.h> |
| 41 |
#endif |
| 42 |
|
| 43 |
#ifndef _STLP_INTERNAL_ITERATOR_H |
| 44 |
# include <stl/_iterator.h> |
| 45 |
#endif |
| 46 |
|
| 47 |
#ifndef _STLP_INTERNAL_FUNCTION_BASE_H |
| 48 |
# include <stl/_function_base.h> |
| 49 |
#endif |
| 50 |
|
| 51 |
#ifndef _STLP_CSTDDEF |
| 52 |
# include <cstddef> |
| 53 |
#endif |
| 54 |
|
| 55 |
_STLP_BEGIN_NAMESPACE |
| 56 |
|
| 57 |
template <class _Tp, class _Alloc> class forward_list; |
| 58 |
|
| 59 |
_STLP_MOVE_TO_PRIV_NAMESPACE |
| 60 |
|
| 61 |
struct _Slist_node_base |
| 62 |
{ |
| 63 |
_Slist_node_base* _M_next; |
| 64 |
}; |
| 65 |
|
| 66 |
template <class _Tp> |
| 67 |
struct _Slist_node : |
| 68 |
public _Slist_node_base |
| 69 |
{ |
| 70 |
_Slist_node() = default; |
| 71 |
_Slist_node( const _Slist_node& ) = default; |
| 72 |
_Slist_node( _Slist_node&& ) = default; |
| 73 |
_Slist_node& operator =( const _Slist_node& ) = default; |
| 74 |
~_Slist_node() = default; |
| 75 |
|
| 76 |
_Tp _M_data; |
| 77 |
}; |
| 78 |
|
| 79 |
template <class _Tp> class _Slist_iterator; |
| 80 |
template <class _Tp> class _Slist_iterator<_Tp const>; |
| 81 |
|
| 82 |
template <class _Tp> |
| 83 |
class _Slist_iterator |
| 84 |
{ |
| 85 |
public: |
| 86 |
typedef typename remove_const<_Tp>::type value_type; |
| 87 |
typedef value_type* pointer; |
| 88 |
typedef value_type& reference; |
| 89 |
typedef forward_iterator_tag iterator_category; |
| 90 |
typedef size_t size_type; |
| 91 |
typedef ptrdiff_t difference_type; |
| 92 |
|
| 93 |
private: |
| 94 |
typedef _Slist_iterator<value_type> _Self; |
| 95 |
typedef _Slist_node<value_type> _Node; |
| 96 |
|
| 97 |
public: |
| 98 |
_Slist_iterator() = default; |
| 99 |
_Slist_iterator(const _Slist_iterator&) = default; |
| 100 |
_Slist_iterator(_Slist_iterator&&) = default; |
| 101 |
|
| 102 |
private: |
| 103 |
explicit _Slist_iterator(_Slist_node_base* __x) : |
| 104 |
_M_node(static_cast<_Node*>(__x)) |
| 105 |
{ } |
| 106 |
|
| 107 |
public: |
| 108 |
_Slist_iterator& operator =( const _Slist_iterator& ) = default; |
| 109 |
|
| 110 |
reference operator *() const |
| 111 |
{ return _M_node->_M_data; } |
| 112 |
|
| 113 |
const pointer operator ->() const |
| 114 |
{ return &_M_node->_M_data; } |
| 115 |
|
| 116 |
_Self& operator ++() |
| 117 |
{ |
| 118 |
_M_incr(); |
| 119 |
return *this; |
| 120 |
} |
| 121 |
_Self operator ++(int) |
| 122 |
{ |
| 123 |
_Self __tmp = *this; |
| 124 |
_M_incr(); |
| 125 |
return __tmp; |
| 126 |
} |
| 127 |
|
| 128 |
bool operator ==(const _Self& __y ) const |
| 129 |
{ return _M_node == __y._M_node; } |
| 130 |
bool operator ==(const _Slist_iterator<_Tp const>& __y ) const |
| 131 |
{ return _M_node == reinterpret_cast<_Node*>(__y._M_node); } |
| 132 |
bool operator !=(const _Self& __y ) const |
| 133 |
{ return _M_node != __y._M_node; } |
| 134 |
bool operator !=(const _Slist_iterator<_Tp const>& __y ) const |
| 135 |
{ return _M_node != reinterpret_cast<_Node*>(__y._M_node); } |
| 136 |
|
| 137 |
private: |
| 138 |
void _M_incr() |
| 139 |
{ _M_node = static_cast<_Node*>(_M_node->_M_next); } |
| 140 |
_Node* _M_node; |
| 141 |
|
| 142 |
template <class _TTp, class _Alloc> |
| 143 |
friend class _STLP_STD::forward_list; |
| 144 |
|
| 145 |
template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All> |
| 146 |
friend class hashtable; |
| 147 |
|
| 148 |
friend class _Slist_iterator<_Tp const>; |
| 149 |
}; |
| 150 |
|
| 151 |
template <class _Tp> |
| 152 |
class _Slist_iterator<_Tp const> |
| 153 |
{ |
| 154 |
public: |
| 155 |
typedef _Tp value_type; |
| 156 |
typedef value_type const* pointer; |
| 157 |
typedef value_type const& reference; |
| 158 |
typedef forward_iterator_tag iterator_category; |
| 159 |
typedef size_t size_type; |
| 160 |
typedef ptrdiff_t difference_type; |
| 161 |
|
| 162 |
private: |
| 163 |
typedef _Slist_iterator<value_type const> _Self; |
| 164 |
typedef _Slist_node<value_type const> _Node; |
| 165 |
|
| 166 |
public: |
| 167 |
_Slist_iterator() = default; |
| 168 |
_Slist_iterator(const _Slist_iterator&) = default; |
| 169 |
_Slist_iterator(_Slist_iterator&&) = default; |
| 170 |
_Slist_iterator(const _Slist_iterator<value_type>& x) : |
| 171 |
_M_node( reinterpret_cast<_Node*>(x._M_node) ) |
| 172 |
{ } |
| 173 |
|
| 174 |
private: |
| 175 |
explicit _Slist_iterator(_Slist_node_base* __x) : |
| 176 |
_M_node(static_cast<_Node*>(__x)) |
| 177 |
{ } |
| 178 |
|
| 179 |
public: |
| 180 |
_Slist_iterator& operator =( const _Slist_iterator& ) = default; |
| 181 |
_Slist_iterator& operator =( const _Slist_iterator<value_type>& x ) |
| 182 |
{ |
| 183 |
_M_node = reinterpret_cast<_Node*>(x._M_node); |
| 184 |
return *this; |
| 185 |
} |
| 186 |
|
| 187 |
reference operator *() const |
| 188 |
{ return _M_node->_M_data; } |
| 189 |
|
| 190 |
const pointer operator ->() const |
| 191 |
{ return &_M_node->_M_data; } |
| 192 |
|
| 193 |
_Self& operator++() |
| 194 |
{ |
| 195 |
_M_incr(); |
| 196 |
return *this; |
| 197 |
} |
| 198 |
_Self operator++(int) |
| 199 |
{ |
| 200 |
_Self __tmp = *this; |
| 201 |
_M_incr(); |
| 202 |
return __tmp; |
| 203 |
} |
| 204 |
|
| 205 |
bool operator ==(const _Self& __y ) const |
| 206 |
{ return _M_node == __y._M_node; } |
| 207 |
bool operator ==(const _Slist_iterator<_Tp>& __y ) const |
| 208 |
{ return _M_node == reinterpret_cast<_Node*>(__y._M_node); } |
| 209 |
bool operator !=(const _Self& __y ) const |
| 210 |
{ return _M_node != __y._M_node; } |
| 211 |
bool operator !=(const _Slist_iterator<_Tp>& __y ) const |
| 212 |
{ return _M_node != reinterpret_cast<_Node*>(__y._M_node); } |
| 213 |
|
| 214 |
private: |
| 215 |
void _M_incr() |
| 216 |
{ _M_node = static_cast<_Node*>(_M_node->_M_next); } |
| 217 |
|
| 218 |
_Node* _M_node; |
| 219 |
|
| 220 |
template <class _TTp, class _Alloc> |
| 221 |
friend class _STLP_STD::forward_list; |
| 222 |
|
| 223 |
template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All> |
| 224 |
friend class hashtable; |
| 225 |
|
| 226 |
friend class _Slist_iterator<_Tp>; |
| 227 |
}; |
| 228 |
|
| 229 |
#if defined (_STLP_USE_PTR_SPECIALIZATIONS) |
| 230 |
# define forward_list _STLP_PTR_IMPL_NAME(forward_list) |
| 231 |
#elif defined (_STLP_DEBUG) |
| 232 |
# define forward_list _STLP_NON_DBG_NAME(forward_list) |
| 233 |
#else |
| 234 |
_STLP_MOVE_TO_STD_NAMESPACE |
| 235 |
#endif |
| 236 |
|
| 237 |
template <class _Tp, class _Alloc = allocator<_Tp>> |
| 238 |
class forward_list |
| 239 |
{ |
| 240 |
private: |
| 241 |
typedef _STLP_PRIV _Slist_node<_Tp> _Node; |
| 242 |
typedef typename _Alloc::template rebind<_Node>::other _M_node_allocator_type; |
| 243 |
typedef _STLP_PRIV _Slist_node_base _Node_base; |
| 244 |
|
| 245 |
typedef _STLP_PRIV _STLP_alloc_proxy<_Node_base, _M_node_allocator_type> _AllocProxy; |
| 246 |
typedef forward_list<_Tp,_Alloc> _Self; |
| 247 |
|
| 248 |
public: |
| 249 |
typedef typename remove_const<_Tp>::type value_type; |
| 250 |
typedef value_type& reference; |
| 251 |
typedef const value_type& const_reference; |
| 252 |
typedef _STLP_PRIV _Slist_iterator<typename remove_const<_Tp>::type> iterator; |
| 253 |
typedef _STLP_PRIV _Slist_iterator<typename add_const<_Tp>::type> const_iterator; |
| 254 |
typedef size_t size_type; |
| 255 |
typedef ptrdiff_t difference_type; |
| 256 |
|
| 257 |
typedef _Alloc allocator_type; |
| 258 |
typedef typename allocator_traits<allocator_type>::pointer pointer; |
| 259 |
typedef typename allocator_traits<allocator_type>::const_pointer const_pointer; |
| 260 |
|
| 261 |
private: |
| 262 |
_Node* __slist_make_link(_Node_base* __prev_node, _Node* __new_node) |
| 263 |
{ |
| 264 |
__new_node->_M_next = __prev_node->_M_next; |
| 265 |
__prev_node->_M_next = __new_node; |
| 266 |
return __new_node; |
| 267 |
} |
| 268 |
|
| 269 |
_Node* _M_create_node(const value_type& __x) |
| 270 |
{ |
| 271 |
_Node* __node = this->_M_head.allocate(1); |
| 272 |
_STLP_TRY { |
| 273 |
_Self::get_allocator().construct( &__node->_M_data, __x ); |
| 274 |
__node->_M_next = 0; |
| 275 |
} |
| 276 |
_STLP_UNWIND(this->_M_head.deallocate(__node, 1)) |
| 277 |
return __node; |
| 278 |
} |
| 279 |
|
| 280 |
_Node* _M_create_node(value_type&& __x) |
| 281 |
{ |
| 282 |
_Node* __node = this->_M_head.allocate(1); |
| 283 |
_STLP_TRY { |
| 284 |
_Self::get_allocator().construct( &__node->_M_data, _STLP_STD::move(__x) ); |
| 285 |
__node->_M_next = 0; |
| 286 |
} |
| 287 |
_STLP_UNWIND(this->_M_head.deallocate(__node, 1)) |
| 288 |
return __node; |
| 289 |
} |
| 290 |
|
| 291 |
public: |
| 292 |
allocator_type get_allocator() const |
| 293 |
{ return (const _M_node_allocator_type&)_M_head; } |
| 294 |
|
| 295 |
explicit forward_list(const allocator_type& __a = allocator_type()) : |
| 296 |
_M_head(__a) |
| 297 |
{ _M_head._M_data._M_next = 0; } |
| 298 |
|
| 299 |
explicit forward_list(size_type __n) : |
| 300 |
_M_head(allocator_type()) |
| 301 |
{ |
| 302 |
_M_head._M_data._M_next = 0; |
| 303 |
_M_insert_after_fill(&this->_M_head._M_data, __n, _STLP_DEFAULT_CONSTRUCTED(_Tp)); |
| 304 |
} |
| 305 |
|
| 306 |
forward_list(size_type __n, const value_type& __x, const allocator_type& __a = allocator_type()) : |
| 307 |
_M_head(__a, _STLP_PRIV _Slist_node_base() ) |
| 308 |
{ |
| 309 |
_M_head._M_data._M_next = 0; |
| 310 |
_M_insert_after_fill(&this->_M_head._M_data, __n, __x); |
| 311 |
} |
| 312 |
|
| 313 |
// We don't need any dispatching tricks here, because _M_insert_after_range |
| 314 |
// already does them. |
| 315 |
template <class _InputIterator> |
| 316 |
forward_list(_InputIterator __first, _InputIterator __last, |
| 317 |
const allocator_type& __a = allocator_type() ) : |
| 318 |
_M_head(__a, _STLP_PRIV _Slist_node_base() ) |
| 319 |
{ |
| 320 |
_M_head._M_data._M_next = 0; |
| 321 |
_M_insert_after_range(&this->_M_head._M_data, __first, __last); |
| 322 |
} |
| 323 |
|
| 324 |
forward_list(const _Self& __x) : |
| 325 |
_M_head(__x.get_allocator(), _STLP_PRIV _Slist_node_base() ) |
| 326 |
{ |
| 327 |
_M_head._M_data._M_next = 0; |
| 328 |
_M_insert_after_range(&this->_M_head._M_data, __x.begin(), __x.end()); |
| 329 |
} |
| 330 |
|
| 331 |
forward_list(_Self&& __x) : |
| 332 |
_M_head(__x.get_allocator(), _STLP_PRIV _Slist_node_base() ) |
| 333 |
{ |
| 334 |
_M_head._M_data._M_next = __x._M_head._M_data._M_next; |
| 335 |
__x._M_head._M_data._M_next = 0; |
| 336 |
} |
| 337 |
|
| 338 |
forward_list(const _Self& __x, const allocator_type& __a) : |
| 339 |
_M_head(__a, _STLP_PRIV _Slist_node_base() ) |
| 340 |
{ |
| 341 |
_M_head._M_data._M_next = 0; |
| 342 |
_M_insert_after_range(&this->_M_head._M_data, __x.begin(), __x.end()); |
| 343 |
} |
| 344 |
|
| 345 |
forward_list(_Self&& __x, const allocator_type& __a) : |
| 346 |
_M_head(__a, _STLP_PRIV _Slist_node_base() ) |
| 347 |
{ |
| 348 |
_M_head._M_data._M_next = __x._M_head._M_data._M_next; |
| 349 |
__x._M_head._M_data._M_next = 0; |
| 350 |
} |
| 351 |
|
| 352 |
_Self& operator =(const _Self& __x); |
| 353 |
|
| 354 |
~forward_list() |
| 355 |
{ _M_erase_after(&_M_head._M_data, 0); } |
| 356 |
|
| 357 |
private: |
| 358 |
template <class S> |
| 359 |
void _M_assign_dispatch( size_type __n, S __val, const true_type& ) |
| 360 |
{ |
| 361 |
_Node_base* __prev = &this->_M_head._M_data; |
| 362 |
_Node_base* __node = this->_M_head._M_data._M_next; |
| 363 |
for ( ; __node != 0 && __n > 0 ; --__n) { |
| 364 |
__STATIC_CAST(_Node*, __node)->_M_data = __val; |
| 365 |
__prev = __node; |
| 366 |
__node = __node->_M_next; |
| 367 |
} |
| 368 |
if (__n > 0) { |
| 369 |
_M_insert_after_fill(__prev, __n, __val); |
| 370 |
} else { |
| 371 |
this->_M_erase_after(__prev, 0); |
| 372 |
} |
| 373 |
} |
| 374 |
|
| 375 |
template <class _InputIterator> |
| 376 |
void _M_assign_dispatch( _InputIterator __first, _InputIterator __last, const false_type& ) |
| 377 |
{ |
| 378 |
_Node_base* __prev = &this->_M_head._M_data; |
| 379 |
_Node_base* __node = this->_M_head._M_data._M_next; |
| 380 |
while (__node != 0 && __first != __last) { |
| 381 |
__STATIC_CAST(_Node*, __node)->_M_data = *__first; |
| 382 |
__prev = __node; |
| 383 |
__node = __node->_M_next; |
| 384 |
++__first; |
| 385 |
} |
| 386 |
if (__first != __last) { |
| 387 |
_M_insert_after_range(__prev, __first, __last); |
| 388 |
} else { |
| 389 |
this->_M_erase_after(__prev, 0); |
| 390 |
} |
| 391 |
} |
| 392 |
|
| 393 |
public: |
| 394 |
// assign(), a generalized assignment member function. Two |
| 395 |
// versions: one that takes a count, and one that takes a range. |
| 396 |
// The range version is a member template, so we dispatch on whether |
| 397 |
// or not the type is an integer. |
| 398 |
|
| 399 |
template <class _InputIterator> |
| 400 |
void assign(_InputIterator __first, _InputIterator __last) |
| 401 |
{ _Self::_M_assign_dispatch(__first, __last, typename is_convertible<_InputIterator,size_type>::type() ); } |
| 402 |
|
| 403 |
void assign(size_type __n, const _Tp& __val) |
| 404 |
{ _Self::_M_assign_dispatch( __n, __val, true_type() ); } |
| 405 |
|
| 406 |
iterator before_begin() |
| 407 |
{ return iterator(&this->_M_head._M_data); } |
| 408 |
const_iterator before_begin() const |
| 409 |
{ return const_iterator(__CONST_CAST(_Node_base*, &this->_M_head._M_data)); } |
| 410 |
|
| 411 |
iterator begin() |
| 412 |
{ return iterator(this->_M_head._M_data._M_next); } |
| 413 |
const_iterator begin() const |
| 414 |
{ return const_iterator(this->_M_head._M_data._M_next);} |
| 415 |
const_iterator cbegin() const |
| 416 |
{ return const_iterator(this->_M_head._M_data._M_next);} |
| 417 |
|
| 418 |
iterator end() { return iterator(0); } |
| 419 |
const_iterator end() const { return const_iterator(0); } |
| 420 |
const_iterator cend() const { return const_iterator(0); } |
| 421 |
|
| 422 |
size_type size() const |
| 423 |
{ |
| 424 |
size_type __result = 0; |
| 425 |
for ( _Node_base* __node = this->_M_head._M_data._M_next; __node != 0; __node = __node->_M_next) { |
| 426 |
++__result; |
| 427 |
} |
| 428 |
return __result; |
| 429 |
} |
| 430 |
|
| 431 |
size_type max_size() const { return size_type(-1); } |
| 432 |
|
| 433 |
bool empty() const { return this->_M_head._M_data._M_next == 0; } |
| 434 |
|
| 435 |
void swap(_Self& __x) |
| 436 |
{ /* this->_M_head.swap(__x._M_head); */ _STLP_STD::swap(this->_M_head, __x._M_head); } |
| 437 |
#if defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && !defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER) |
| 438 |
void _M_swap_workaround(_Self& __x) { swap(__x); } |
| 439 |
#endif |
| 440 |
|
| 441 |
reference front() |
| 442 |
{ return *begin(); } |
| 443 |
const_reference front() const |
| 444 |
{ return *begin(); } |
| 445 |
void push_front(const value_type& __x) |
| 446 |
{ _Self::__slist_make_link(&this->_M_head._M_data, _M_create_node(__x)); } |
| 447 |
void push_front(value_type&& __x) |
| 448 |
{ _Self::__slist_make_link(&this->_M_head._M_data, _M_create_node(_STLP_STD::move(__x))); } |
| 449 |
|
| 450 |
void pop_front() |
| 451 |
{ |
| 452 |
_Node* __node = __STATIC_CAST(_Node*, this->_M_head._M_data._M_next); |
| 453 |
this->_M_head._M_data._M_next = __node->_M_next; |
| 454 |
this->get_allocator().destroy( &__node->_M_data ); |
| 455 |
this->_M_head.deallocate(__node, 1); |
| 456 |
} |
| 457 |
|
| 458 |
private: |
| 459 |
_Node* _M_insert_after(_Node_base* __pos, const value_type& __x) |
| 460 |
{ return _Self::__slist_make_link(__pos, _M_create_node(__x)); } |
| 461 |
|
| 462 |
_Node* _M_insert_after(_Node_base* __pos, value_type&& __x) |
| 463 |
{ return _Self::__slist_make_link(__pos, _M_create_node(_STLP_STD::move(__x))); } |
| 464 |
|
| 465 |
void _M_insert_after_fill(_Node_base* __pos, size_type __n, const value_type& __x) |
| 466 |
{ |
| 467 |
for (size_type __i = 0; __i < __n; ++__i) { |
| 468 |
__pos = _Self::__slist_make_link(__pos, _M_create_node(__x)); |
| 469 |
} |
| 470 |
} |
| 471 |
|
| 472 |
// Check whether it's an integral type. If so, it's not an iterator. |
| 473 |
template <class _InIter> |
| 474 |
void _M_insert_after_range(_Node_base* __pos, _InIter __first, _InIter __last) |
| 475 |
{ |
| 476 |
typedef typename is_integral<_InIter>::type _Integral; |
| 477 |
_M_insert_after_range(__pos, __first, __last, _Integral()); |
| 478 |
} |
| 479 |
|
| 480 |
template <class _Integer> |
| 481 |
void _M_insert_after_range(_Node_base* __pos, _Integer __n, _Integer __x, const true_type&) |
| 482 |
{ _M_insert_after_fill(__pos, __n, __x); } |
| 483 |
|
| 484 |
template <class _InIter> |
| 485 |
void _M_insert_after_range(_Node_base* __pos, _InIter __first, _InIter __last, const false_type&) |
| 486 |
{ |
| 487 |
while (__first != __last) { |
| 488 |
__pos = _Self::__slist_make_link(__pos, _M_create_node(*__first)); |
| 489 |
++__first; |
| 490 |
} |
| 491 |
} |
| 492 |
|
| 493 |
public: |
| 494 |
iterator insert_after(const_iterator __pos, const value_type& __x) |
| 495 |
{ return iterator(_M_insert_after(__pos._M_node, __x)); } |
| 496 |
iterator insert_after(const_iterator __pos, value_type&& __x) |
| 497 |
{ return iterator(_M_insert_after(__pos._M_node, _STLP_STD::move(__x))); } |
| 498 |
|
| 499 |
void insert_after(const_iterator __pos, size_type __n, const value_type& __x) |
| 500 |
{ _M_insert_after_fill(__pos._M_node, __n, __x); } |
| 501 |
|
| 502 |
// We don't need any dispatching tricks here, because _M_insert_after_range |
| 503 |
// already does them. |
| 504 |
template <class _InIter> |
| 505 |
void insert_after(const_iterator __pos, _InIter __first, _InIter __last) |
| 506 |
{ _M_insert_after_range(__pos._M_node, __first, __last); } |
| 507 |
|
| 508 |
iterator erase_after(const_iterator __pos) |
| 509 |
{ return iterator(this->_M_erase_after(__pos._M_node)); } |
| 510 |
iterator erase_after(const_iterator __before_first, const_iterator __last) |
| 511 |
{ return iterator(this->_M_erase_after(__before_first._M_node, __last._M_node)); } |
| 512 |
|
| 513 |
void resize(size_type new_size, const value_type& __x); |
| 514 |
|
| 515 |
void resize(size_type new_size) |
| 516 |
{ resize(new_size, value_type()); } |
| 517 |
|
| 518 |
void clear() |
| 519 |
{ this->_M_erase_after(&this->_M_head._M_data, 0); } |
| 520 |
|
| 521 |
// Removes all of the elements from the list __x to *this, inserting |
| 522 |
// them immediately after __pos. __x must not be *this. Complexity: |
| 523 |
// linear in __x.size(). |
| 524 |
void splice_after(const_iterator __pos, _Self& __x) |
| 525 |
{ |
| 526 |
if ( !__x.empty() ) { |
| 527 |
if ( get_allocator() == __x.get_allocator() ) { |
| 528 |
_Node_base* tmp = __pos._M_node->_M_next; |
| 529 |
_Node_base* __node = __pos._M_node->_M_next = __x._M_head._M_data._M_next; |
| 530 |
while (__node->_M_next) { |
| 531 |
__node = __node->_M_next; |
| 532 |
} |
| 533 |
__node->_M_next = tmp; |
| 534 |
__x._M_head._M_data._M_next = 0; |
| 535 |
} else { |
| 536 |
insert_after(__pos, __x.begin(), __x.end() ); |
| 537 |
__x.clear(); |
| 538 |
} |
| 539 |
} |
| 540 |
} |
| 541 |
|
| 542 |
void splice_after(const_iterator __pos, _Self&& __x) |
| 543 |
{ |
| 544 |
if ( !__x.empty() ) { |
| 545 |
if ( get_allocator() == __x.get_allocator() ) { |
| 546 |
_Node_base* tmp = __pos._M_node->_M_next; |
| 547 |
_Node_base* __node = __pos._M_node->_M_next = __x._M_head._M_data._M_next; |
| 548 |
while (__node->_M_next) { |
| 549 |
__node = __node->_M_next; |
| 550 |
} |
| 551 |
__node->_M_next = tmp; |
| 552 |
__x._M_head._M_data._M_next = 0; |
| 553 |
} else { |
| 554 |
insert_after(__pos, __x.begin(), __x.end() ); |
| 555 |
__x.clear(); |
| 556 |
} |
| 557 |
} |
| 558 |
} |
| 559 |
|
| 560 |
// Moves the range (first, last) to *this, |
| 561 |
// inserting it immediately after __pos. This is O(distance(first,last)) time. |
| 562 |
void splice_after(const_iterator __pos, _Self& __x, const_iterator first, const_iterator last) |
| 563 |
{ |
| 564 |
if ( first._M_node->_M_next == last._M_node ) { |
| 565 |
return; |
| 566 |
} |
| 567 |
|
| 568 |
if ( get_allocator() == __x.get_allocator() ) { |
| 569 |
_Node_base* tmp = __pos._M_node->_M_next; |
| 570 |
_Node_base* __node = __pos._M_node->_M_next = first._M_node->_M_next; |
| 571 |
while ( __node->_M_next != last._M_node ) { |
| 572 |
__node = __node->_M_next; |
| 573 |
} |
| 574 |
__node->_M_next = tmp; |
| 575 |
first._M_node->_M_next = last._M_node; |
| 576 |
} else { |
| 577 |
const_iterator tmp = first++; |
| 578 |
insert_after(__pos, first, last); |
| 579 |
__x.erase_after(tmp, last); |
| 580 |
} |
| 581 |
} |
| 582 |
|
| 583 |
void splice_after(const_iterator __pos, _Self&& __x, const_iterator first, const_iterator last) |
| 584 |
{ |
| 585 |
if ( first._M_node->_M_next == last._M_node ) { |
| 586 |
return; |
| 587 |
} |
| 588 |
|
| 589 |
if ( get_allocator() == __x.get_allocator() ) { |
| 590 |
_Node_base* tmp = __pos._M_node->_M_next; |
| 591 |
_Node_base* __node = __pos._M_node->_M_next = first._M_node->_M_next; |
| 592 |
while ( __node->_M_next != last._M_node ) { |
| 593 |
__node = __node->_M_next; |
| 594 |
} |
| 595 |
__node->_M_next = tmp; |
| 596 |
first._M_node->_M_next = last._M_node; |
| 597 |
} else { |
| 598 |
const_iterator tmp = first++; |
| 599 |
insert_after(__pos, first, last); |
| 600 |
__x.erase_after(tmp, last); |
| 601 |
} |
| 602 |
} |
| 603 |
|
| 604 |
// Moves the element that follows __prev to *this, inserting it immediately |
| 605 |
// after __pos. This is constant time. |
| 606 |
void splice_after(const_iterator __pos, _Self& __x, const_iterator __prev) |
| 607 |
{ |
| 608 |
if ( (__pos != __prev) && (__pos._M_node != __prev._M_node->_M_next) ) { |
| 609 |
if ( get_allocator() == __x.get_allocator() ) { |
| 610 |
_Node_base* tmp = __pos._M_node->_M_next; |
| 611 |
__pos._M_node->_M_next = __prev._M_node->_M_next; |
| 612 |
__prev._M_node->_M_next = __prev._M_node->_M_next->_M_next; |
| 613 |
__pos._M_node->_M_next->_M_next = tmp; |
| 614 |
} else { |
| 615 |
const_iterator tmp = __prev++; |
| 616 |
insert_after(__pos, *__prev); |
| 617 |
__x.erase_after(tmp); |
| 618 |
} |
| 619 |
} |
| 620 |
} |
| 621 |
|
| 622 |
void splice_after(const_iterator __pos, _Self&& __x, const_iterator __prev) |
| 623 |
{ |
| 624 |
if ( (__pos != __prev) && (__pos._M_node != __prev._M_node->_M_next) ) { |
| 625 |
if ( get_allocator() == __x.get_allocator() ) { |
| 626 |
_Node_base* tmp = __pos._M_node->_M_next; |
| 627 |
__pos._M_node->_M_next = __prev._M_node->_M_next; |
| 628 |
__prev._M_node->_M_next = __prev._M_node->_M_next->_M_next; |
| 629 |
__pos._M_node->_M_next->_M_next = tmp; |
| 630 |
} else { |
| 631 |
const_iterator tmp = __prev++; |
| 632 |
insert_after(__pos, *__prev); |
| 633 |
__x.erase_after(tmp); |
| 634 |
} |
| 635 |
} |
| 636 |
} |
| 637 |
|
| 638 |
void reverse() |
| 639 |
{ |
| 640 |
if (this->_M_head._M_data._M_next) { |
| 641 |
_Node_base* __cur = this->_M_head._M_data._M_next; |
| 642 |
_Node_base* __prev = __cur; |
| 643 |
_Node_base* __next; |
| 644 |
__cur = __cur->_M_next; |
| 645 |
__prev->_M_next = 0; |
| 646 |
while ( __cur ) { |
| 647 |
__next = __cur->_M_next; |
| 648 |
__cur->_M_next = __prev; |
| 649 |
__prev = __cur; |
| 650 |
__cur = __next; |
| 651 |
} |
| 652 |
this->_M_head._M_data._M_next = __prev; |
| 653 |
} |
| 654 |
} |
| 655 |
|
| 656 |
void remove(const value_type& __val); |
| 657 |
|
| 658 |
void unique() |
| 659 |
{ this->unique( equal_to<value_type>() ); } |
| 660 |
void merge(_Self& __x) |
| 661 |
{ this->merge( __x, less<value_type>() ); } |
| 662 |
void sort() |
| 663 |
{ this->sort( less<value_type>() ); } |
| 664 |
|
| 665 |
template <class _Predicate> |
| 666 |
void remove_if(_Predicate __pred) |
| 667 |
{ |
| 668 |
_Node_base* __cur = &this->_M_head._M_data; |
| 669 |
while (__cur->_M_next) { |
| 670 |
if (__pred(__STATIC_CAST(_Node*, __cur->_M_next)->_M_data)) { |
| 671 |
this->_M_erase_after(__cur); |
| 672 |
} else { |
| 673 |
__cur = __cur->_M_next; |
| 674 |
} |
| 675 |
} |
| 676 |
} |
| 677 |
|
| 678 |
template <class _BinaryPredicate> |
| 679 |
void unique(_BinaryPredicate __pred) |
| 680 |
{ |
| 681 |
/* |
| 682 |
iterator i2 = begin(); |
| 683 |
if ( i1 != end() ) { |
| 684 |
iterator i1 = i2++; |
| 685 |
if ( i2 != end() ) { |
| 686 |
if ( *i1 == *i2 ) { |
| 687 |
erase_after( i1 ); |
| 688 |
} |
| 689 |
} |
| 690 |
} |
| 691 |
*/ |
| 692 |
|
| 693 |
iterator __ite = this->begin(); |
| 694 |
if (__ite != this->end()) { |
| 695 |
while (__ite._M_node->_M_next) { |
| 696 |
if ( __pred( *__ite, static_cast<_Node*>(__ite._M_node->_M_next)->_M_data ) ) { |
| 697 |
this->erase_after(__ite); |
| 698 |
} else { |
| 699 |
++__ite; |
| 700 |
} |
| 701 |
} |
| 702 |
} |
| 703 |
} |
| 704 |
|
| 705 |
template <class _StrictWeakOrdering> |
| 706 |
void merge(_Self& __x, _StrictWeakOrdering __comp); |
| 707 |
|
| 708 |
template <class _StrictWeakOrdering> |
| 709 |
void sort(_StrictWeakOrdering __comp); |
| 710 |
|
| 711 |
private: |
| 712 |
_Node_base* _M_erase_after(_Node_base* __pos) |
| 713 |
{ |
| 714 |
_Node* __next = __STATIC_CAST(_Node*, __pos->_M_next); |
| 715 |
_Node_base* __next_next = __next->_M_next; |
| 716 |
__pos->_M_next = __next_next; |
| 717 |
this->get_allocator().destroy( &__next->_M_data ); |
| 718 |
_M_head.deallocate(__next,1); |
| 719 |
return __next_next; |
| 720 |
} |
| 721 |
_Node_base* _M_erase_after(_Node_base*, _Node_base*); |
| 722 |
|
| 723 |
_AllocProxy _M_head; |
| 724 |
}; |
| 725 |
|
| 726 |
#if defined (forward_list) |
| 727 |
_STLP_MOVE_TO_STD_NAMESPACE |
| 728 |
# undef forward_list |
| 729 |
#endif // forward_list |
| 730 |
|
| 731 |
_STLP_END_NAMESPACE |
| 732 |
|
| 733 |
#include <stl/_forward_list.c> |
| 734 |
|
| 735 |
#if defined (_STLP_USE_PTR_SPECIALIZATIONS) |
| 736 |
# include <stl/pointers/_forward_list.h> |
| 737 |
#endif |
| 738 |
|
| 739 |
#if defined (_STLP_DEBUG) |
| 740 |
# include <stl/debug/_forward_list.h> |
| 741 |
#endif |
| 742 |
|
| 743 |
_STLP_BEGIN_NAMESPACE |
| 744 |
|
| 745 |
template <class _Tp1, class _Alloc1, class _Tp2, class _Alloc2> |
| 746 |
inline |
| 747 |
bool _STLP_CALL operator ==(const forward_list<_Tp1,_Alloc1>& _SL1, const forward_list<_Tp2,_Alloc2>& _SL2) |
| 748 |
{ |
| 749 |
typedef typename forward_list<_Tp1,_Alloc1>::const_iterator const_iterator1; |
| 750 |
typedef typename forward_list<_Tp2,_Alloc2>::const_iterator const_iterator2; |
| 751 |
const_iterator1 __end1 = _SL1.end(); |
| 752 |
const_iterator2 __end2 = _SL2.end(); |
| 753 |
|
| 754 |
const_iterator1 __i1 = _SL1.begin(); |
| 755 |
const_iterator2 __i2 = _SL2.begin(); |
| 756 |
while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) { |
| 757 |
++__i1; |
| 758 |
++__i2; |
| 759 |
} |
| 760 |
return __i1 == __end1 && __i2 == __end2; |
| 761 |
} |
| 762 |
|
| 763 |
template <class _Tp1, class _Alloc1, class _Tp2, class _Alloc2> |
| 764 |
inline |
| 765 |
bool _STLP_CALL operator <(const forward_list<_Tp1,_Alloc1>& x, const forward_list<_Tp2,_Alloc2>& y) |
| 766 |
{ return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } |
| 767 |
|
| 768 |
template <class _Tp, class _Alloc> |
| 769 |
inline void _STLP_CALL swap( forward_list<_Tp,_Alloc>& x, forward_list<_Tp,_Alloc>& y ) |
| 770 |
{ x.swap( y ); } |
| 771 |
|
| 772 |
#if 0 |
| 773 |
#if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) |
| 774 |
|
| 775 |
// Specialization of insert_iterator so that insertions will be constant |
| 776 |
// time rather than linear time. |
| 777 |
template <class _Tp, class _Alloc> |
| 778 |
class insert_iterator<forward_list<_Tp, _Alloc> > |
| 779 |
{ |
| 780 |
protected: |
| 781 |
typedef forward_list<_Tp, _Alloc> _Container; |
| 782 |
_Container* _M_container; |
| 783 |
typename _Container::iterator _M_iter; |
| 784 |
public: |
| 785 |
typedef _Container container_type; |
| 786 |
typedef output_iterator_tag iterator_category; |
| 787 |
typedef void value_type; |
| 788 |
typedef void difference_type; |
| 789 |
typedef void pointer; |
| 790 |
typedef void reference; |
| 791 |
|
| 792 |
insert_iterator(_Container& __x, typename _Container::iterator __i) : |
| 793 |
_M_container(&__x), |
| 794 |
_M_iter( __i == __x.begin() ? __x.before_begin() : __x.previous(__i) ) // ups, prev!?... |
| 795 |
{ } |
| 796 |
|
| 797 |
insert_iterator<_Container>& |
| 798 |
operator = (const typename _Container::value_type& __val) |
| 799 |
{ |
| 800 |
_M_iter = _M_container->insert_after(_M_iter, __val); |
| 801 |
return *this; |
| 802 |
} |
| 803 |
|
| 804 |
insert_iterator<_Container>& operator*() { return *this; } |
| 805 |
insert_iterator<_Container>& operator++() { return *this; } |
| 806 |
insert_iterator<_Container>& operator++(int) { return *this; } |
| 807 |
}; |
| 808 |
#endif /* _STLP_CLASS_PARTIAL_SPECIALIZATION */ |
| 809 |
#endif // 0 |
| 810 |
|
| 811 |
_STLP_END_NAMESPACE |
| 812 |
|
| 813 |
#if (_STLP_OUTERMOST_HEADER_ID == 0x58) |
| 814 |
# include <stl/_epilog.h> |
| 815 |
# undef _STLP_OUTERMOST_HEADER_ID |
| 816 |
#endif |
| 817 |
|
| 818 |
#endif /* _STLP_FORWARD_LIST */ |
| 819 |
|
| 820 |
// Local Variables: |
| 821 |
// mode:C++ |
| 822 |
// End: |