![]() |
|
|||
File indexing completed on 2025-07-15 08:29:45
0001 ////////////////////////////////////////////////////////////////////////////// 0002 // 0003 // (C) Copyright Ion Gaztanaga 2004-2015. Distributed under the Boost 0004 // Software License, Version 1.0. (See accompanying file 0005 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 0006 // 0007 // See http://www.boost.org/libs/container for documentation. 0008 // 0009 ////////////////////////////////////////////////////////////////////////////// 0010 0011 #ifndef BOOST_CONTAINER_SLIST_HPP 0012 #define BOOST_CONTAINER_SLIST_HPP 0013 0014 #ifndef BOOST_CONFIG_HPP 0015 # include <boost/config.hpp> 0016 #endif 0017 0018 #if defined(BOOST_HAS_PRAGMA_ONCE) 0019 # pragma once 0020 #endif 0021 0022 #include <boost/container/detail/config_begin.hpp> 0023 #include <boost/container/detail/workaround.hpp> 0024 0025 // container 0026 #include <boost/container/container_fwd.hpp> 0027 #include <boost/container/new_allocator.hpp> //new_allocator 0028 #include <boost/container/throw_exception.hpp> 0029 // container/detail 0030 #include <boost/container/detail/algorithm.hpp> //algo_equal(), algo_lexicographical_compare 0031 #include <boost/container/detail/compare_functors.hpp> 0032 #include <boost/container/detail/iterator.hpp> 0033 #include <boost/container/detail/iterators.hpp> 0034 #include <boost/container/detail/mpl.hpp> 0035 #include <boost/container/detail/node_alloc_holder.hpp> 0036 #include <boost/container/detail/type_traits.hpp> 0037 #include <boost/container/detail/value_functors.hpp> 0038 // intrusive 0039 #include <boost/intrusive/pointer_traits.hpp> 0040 #include <boost/intrusive/slist.hpp> 0041 // move 0042 #include <boost/move/iterator.hpp> 0043 #include <boost/move/traits.hpp> 0044 #include <boost/move/utility_core.hpp> 0045 // move/detail 0046 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) 0047 #include <boost/move/detail/fwd_macros.hpp> 0048 #endif 0049 #include <boost/move/detail/move_helpers.hpp> 0050 0051 // std 0052 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) 0053 #include <initializer_list> 0054 #endif 0055 0056 namespace boost { 0057 namespace container { 0058 0059 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED 0060 0061 template <class T, class Allocator> 0062 class slist; 0063 0064 namespace dtl { 0065 0066 template<class VoidPointer> 0067 struct slist_hook 0068 { 0069 typedef typename dtl::bi::make_slist_base_hook 0070 <dtl::bi::void_pointer<VoidPointer>, dtl::bi::link_mode<dtl::bi::normal_link> >::type type; 0071 }; 0072 0073 template <class T, class VoidPointer> 0074 struct iiterator_node_value_type< base_node<T, slist_hook<VoidPointer> > > 0075 { 0076 typedef T type; 0077 }; 0078 0079 template<class Allocator> 0080 struct intrusive_slist_type 0081 { 0082 typedef boost::container::allocator_traits<Allocator> allocator_traits_type; 0083 typedef typename allocator_traits_type::value_type value_type; 0084 typedef typename boost::intrusive::pointer_traits 0085 <typename allocator_traits_type::pointer>::template 0086 rebind_pointer<void>::type 0087 void_pointer; 0088 typedef base_node<value_type, slist_hook<void_pointer> > node_type; 0089 0090 typedef typename dtl::bi::make_slist 0091 <node_type 0092 ,dtl::bi::base_hook<typename slist_hook<void_pointer>::type> 0093 ,dtl::bi::constant_time_size<true> 0094 , dtl::bi::size_type 0095 <typename allocator_traits_type::size_type> 0096 >::type container_type; 0097 typedef container_type type ; 0098 }; 0099 0100 } //namespace dtl { 0101 0102 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED 0103 0104 //! An slist is a singly linked list: a list where each element is linked to the next 0105 //! element, but not to the previous element. That is, it is a Sequence that 0106 //! supports forward but not backward traversal, and (amortized) constant time 0107 //! insertion and removal of elements. Slists, like lists, have the important 0108 //! property that insertion and splicing do not invalidate iterators to list elements, 0109 //! and that even removal invalidates only the iterators that point to the elements 0110 //! that are removed. The ordering of iterators may be changed (that is, 0111 //! slist<T>::iterator might have a different predecessor or successor after a list 0112 //! operation than it did before), but the iterators themselves will not be invalidated 0113 //! or made to point to different elements unless that invalidation or mutation is explicit. 0114 //! 0115 //! The main difference between slist and list is that list's iterators are bidirectional 0116 //! iterators, while slist's iterators are forward iterators. This means that slist is 0117 //! less versatile than list; frequently, however, bidirectional iterators are 0118 //! unnecessary. You should usually use slist unless you actually need the extra 0119 //! functionality of list, because singly linked lists are smaller and faster than double 0120 //! linked lists. 0121 //! 0122 //! Important performance note: like every other Sequence, slist defines the member 0123 //! functions insert and erase. Using these member functions carelessly, however, can 0124 //! result in disastrously slow programs. The problem is that insert's first argument is 0125 //! an iterator p, and that it inserts the new element(s) before p. This means that 0126 //! insert must find the iterator just before p; this is a constant-time operation 0127 //! for list, since list has bidirectional iterators, but for slist it must find that 0128 //! iterator by traversing the list from the beginning up to p. In other words: 0129 //! insert and erase are slow operations anywhere but near the beginning of the slist. 0130 //! 0131 //! Slist provides the member functions insert_after and erase_after, which are constant 0132 //! time operations: you should always use insert_after and erase_after whenever 0133 //! possible. If you find that insert_after and erase_after aren't adequate for your 0134 //! needs, and that you often need to use insert and erase in the middle of the list, 0135 //! then you should probably use list instead of slist. 0136 //! 0137 //! \tparam T The type of object that is stored in the list 0138 //! \tparam Allocator The allocator used for all internal memory management, use void 0139 //! for the default allocator 0140 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED 0141 template <class T, class Allocator = void > 0142 #else 0143 template <class T, class Allocator> 0144 #endif 0145 class slist 0146 : protected dtl::node_alloc_holder 0147 < typename real_allocator<T, Allocator>::type 0148 , typename dtl::intrusive_slist_type<typename real_allocator<T, Allocator>::type>::type> 0149 { 0150 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED 0151 typedef typename real_allocator<T, Allocator>::type ValueAllocator; 0152 typedef typename 0153 dtl::intrusive_slist_type<ValueAllocator>::type Icont; 0154 typedef dtl::node_alloc_holder<ValueAllocator, Icont> AllocHolder; 0155 typedef typename AllocHolder::NodePtr NodePtr; 0156 typedef typename AllocHolder::NodeAlloc NodeAlloc; 0157 typedef typename AllocHolder::ValAlloc ValAlloc; 0158 typedef typename AllocHolder::Node Node; 0159 typedef dtl::allocator_node_destroyer<NodeAlloc> Destroyer; 0160 typedef typename AllocHolder::alloc_version alloc_version; 0161 typedef boost::container:: 0162 allocator_traits<ValueAllocator> allocator_traits_type; 0163 typedef boost::container::equal_to_value 0164 <typename allocator_traits_type::value_type> equal_to_value_type; 0165 0166 BOOST_COPYABLE_AND_MOVABLE(slist) 0167 typedef dtl::iterator_from_iiterator<typename Icont::iterator, false> iterator_impl; 0168 typedef dtl::iterator_from_iiterator<typename Icont::iterator, true > const_iterator_impl; 0169 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED 0170 0171 public: 0172 ////////////////////////////////////////////// 0173 // 0174 // types 0175 // 0176 ////////////////////////////////////////////// 0177 0178 typedef T value_type; 0179 typedef typename ::boost::container::allocator_traits<ValueAllocator>::pointer pointer; 0180 typedef typename ::boost::container::allocator_traits<ValueAllocator>::const_pointer const_pointer; 0181 typedef typename ::boost::container::allocator_traits<ValueAllocator>::reference reference; 0182 typedef typename ::boost::container::allocator_traits<ValueAllocator>::const_reference const_reference; 0183 typedef typename ::boost::container::allocator_traits<ValueAllocator>::size_type size_type; 0184 typedef typename ::boost::container::allocator_traits<ValueAllocator>::difference_type difference_type; 0185 typedef ValueAllocator allocator_type; 0186 typedef BOOST_CONTAINER_IMPDEF(NodeAlloc) stored_allocator_type; 0187 typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator; 0188 typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator; 0189 0190 public: 0191 0192 ////////////////////////////////////////////// 0193 // 0194 // constructFr/copy/destroy 0195 // 0196 ////////////////////////////////////////////// 0197 0198 //! <b>Effects</b>: Constructs a list taking the allocator as parameter. 0199 //! 0200 //! <b>Throws</b>: If allocator_type's copy constructor throws. 0201 //! 0202 //! <b>Complexity</b>: Constant. 0203 slist() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<ValueAllocator>::value) 0204 : AllocHolder() 0205 {} 0206 0207 //! <b>Effects</b>: Constructs a list taking the allocator as parameter. 0208 //! 0209 //! <b>Throws</b>: Nothing 0210 //! 0211 //! <b>Complexity</b>: Constant. 0212 explicit slist(const allocator_type& a) BOOST_NOEXCEPT_OR_NOTHROW 0213 : AllocHolder(a) 0214 {} 0215 0216 //! <b>Effects</b>: Constructs a list 0217 //! and inserts n value-initialized value_types. 0218 //! 0219 //! <b>Throws</b>: If allocator_type's default constructor 0220 //! throws or T's default or copy constructor throws. 0221 //! 0222 //! <b>Complexity</b>: Linear to n. 0223 explicit slist(size_type n) 0224 : AllocHolder(allocator_type()) 0225 { this->resize(n); } 0226 0227 //! <b>Effects</b>: Constructs a list that will use a copy of allocator a 0228 //! and inserts n copies of value. 0229 //! 0230 //! <b>Throws</b>: If allocator_type's default constructor 0231 //! throws or T's default or copy constructor throws. 0232 //! 0233 //! <b>Complexity</b>: Linear to n. 0234 slist(size_type n, const allocator_type &a) 0235 : AllocHolder(a) 0236 { this->resize(n); } 0237 0238 //! <b>Effects</b>: Constructs a list that will use a copy of allocator a 0239 //! and inserts n copies of value. 0240 //! 0241 //! <b>Throws</b>: If allocator_type's default constructor 0242 //! throws or T's default or copy constructor throws. 0243 //! 0244 //! <b>Complexity</b>: Linear to n. 0245 explicit slist(size_type n, const value_type& x, const allocator_type& a = allocator_type()) 0246 : AllocHolder(a) 0247 { this->insert_after(this->cbefore_begin(), n, x); } 0248 0249 //! <b>Effects</b>: Constructs a list that will use a copy of allocator a 0250 //! and inserts a copy of the range [first, last) in the list. 0251 //! 0252 //! <b>Throws</b>: If allocator_type's default constructor 0253 //! throws or T's constructor taking a dereferenced InIt throws. 0254 //! 0255 //! <b>Complexity</b>: Linear to the range [first, last). 0256 template <class InpIt> 0257 slist(InpIt first, InpIt last, const allocator_type& a = allocator_type()) 0258 : AllocHolder(a) 0259 { this->insert_after(this->cbefore_begin(), first, last); } 0260 0261 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) 0262 //! <b>Effects</b>: Constructs a list that will use a copy of allocator a 0263 //! and inserts a copy of the range [il.begin(), il.end()) in the list. 0264 //! 0265 //! <b>Throws</b>: If allocator_type's default constructor 0266 //! throws or T's constructor taking a dereferenced std::initializer_list iterator throws. 0267 //! 0268 //! <b>Complexity</b>: Linear to the range [il.begin(), il.end()). 0269 slist(std::initializer_list<value_type> il, const allocator_type& a = allocator_type()) 0270 : AllocHolder(a) 0271 { this->insert_after(this->cbefore_begin(), il.begin(), il.end()); } 0272 #endif 0273 0274 //! <b>Effects</b>: Copy constructs a list. 0275 //! 0276 //! <b>Postcondition</b>: x == *this. 0277 //! 0278 //! <b>Throws</b>: If allocator_type's default constructor 0279 //! 0280 //! <b>Complexity</b>: Linear to the elements x contains. 0281 slist(const slist& x) 0282 : AllocHolder(x) 0283 { this->insert_after(this->cbefore_begin(), x.begin(), x.end()); } 0284 0285 //! <b>Effects</b>: Move constructor. Moves x's resources to *this. 0286 //! 0287 //! <b>Throws</b>: If allocator_type's copy constructor throws. 0288 //! 0289 //! <b>Complexity</b>: Constant. 0290 slist(BOOST_RV_REF(slist) x) BOOST_NOEXCEPT_OR_NOTHROW 0291 : AllocHolder(BOOST_MOVE_BASE(AllocHolder, x)) 0292 {} 0293 0294 //! <b>Effects</b>: Copy constructs a list using the specified allocator. 0295 //! 0296 //! <b>Postcondition</b>: x == *this. 0297 //! 0298 //! <b>Throws</b>: If allocator_type's default constructor 0299 //! 0300 //! <b>Complexity</b>: Linear to the elements x contains. 0301 slist(const slist& x, const allocator_type &a) 0302 : AllocHolder(a) 0303 { this->insert_after(this->cbefore_begin(), x.begin(), x.end()); } 0304 0305 //! <b>Effects</b>: Move constructor using the specified allocator. 0306 //! Moves x's resources to *this. 0307 //! 0308 //! <b>Throws</b>: If allocation or value_type's copy constructor throws. 0309 //! 0310 //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise. 0311 slist(BOOST_RV_REF(slist) x, const allocator_type &a) 0312 : AllocHolder(a) 0313 { 0314 slist & sr = x; 0315 if(this->node_alloc() == sr.node_alloc()){ 0316 this->icont().swap(sr.icont()); 0317 } 0318 else{ 0319 this->insert_after(this->cbefore_begin(), boost::make_move_iterator(sr.begin()), boost::make_move_iterator(sr.end())); 0320 } 0321 } 0322 0323 //! <b>Effects</b>: Destroys the list. All stored values are destroyed 0324 //! and used memory is deallocated. 0325 //! 0326 //! <b>Throws</b>: Nothing. 0327 //! 0328 //! <b>Complexity</b>: Linear to the number of elements. 0329 ~slist() BOOST_NOEXCEPT_OR_NOTHROW 0330 {} //AllocHolder clears the slist 0331 0332 //! <b>Effects</b>: Makes *this contain the same elements as x. 0333 //! 0334 //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy 0335 //! of each of x's elements. 0336 //! 0337 //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws. 0338 //! 0339 //! <b>Complexity</b>: Linear to the number of elements in x. 0340 slist& operator= (BOOST_COPY_ASSIGN_REF(slist) x) 0341 { 0342 if (BOOST_LIKELY(this != &x)) { 0343 NodeAlloc &this_alloc = this->node_alloc(); 0344 const NodeAlloc &x_alloc = x.node_alloc(); 0345 dtl::bool_<allocator_traits_type:: 0346 propagate_on_container_copy_assignment::value> flag; 0347 if(flag && this_alloc != x_alloc){ 0348 this->clear(); 0349 } 0350 this->AllocHolder::copy_assign_alloc(x); 0351 this->assign(x.begin(), x.end()); 0352 } 0353 return *this; 0354 } 0355 0356 //! <b>Effects</b>: Makes *this contain the same elements as x. 0357 //! 0358 //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy 0359 //! of each of x's elements. 0360 //! 0361 //! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment 0362 //! is false and (allocation throws or value_type's move constructor throws) 0363 //! 0364 //! <b>Complexity</b>: Constant if allocator_traits_type:: 0365 //! propagate_on_container_move_assignment is true or 0366 //! this->get>allocator() == x.get_allocator(). Linear otherwise. 0367 slist& operator=(BOOST_RV_REF(slist) x) 0368 BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value 0369 || allocator_traits_type::is_always_equal::value) 0370 { 0371 if (BOOST_LIKELY(this != &x)) { 0372 //We know resources can be transferred at comiple time if both allocators are 0373 //always equal or the allocator is going to be propagated 0374 const bool can_steal_resources_alloc 0375 = allocator_traits_type::propagate_on_container_move_assignment::value 0376 || allocator_traits_type::is_always_equal::value; 0377 dtl::bool_<can_steal_resources_alloc> flag; 0378 this->priv_move_assign(boost::move(x), flag); 0379 } 0380 return *this; 0381 } 0382 0383 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) 0384 //! <b>Effects</b>: Makes *this contain the same elements as in il. 0385 //! 0386 //! <b>Postcondition</b>: this->size() == il.size(). *this contains a copy 0387 //! of each of il's elements. 0388 //! 0389 //! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment 0390 //! is false and (allocation throws or value_type's move constructor throws) 0391 slist& operator=(std::initializer_list<value_type> il) 0392 { 0393 assign(il.begin(), il.end()); 0394 return *this; 0395 } 0396 #endif 0397 0398 //! <b>Effects</b>: Assigns the n copies of val to *this. 0399 //! 0400 //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws. 0401 //! 0402 //! <b>Complexity</b>: Linear to n. 0403 void assign(size_type n, const T& val) 0404 { 0405 typedef constant_iterator<value_type> cvalue_iterator; 0406 return this->assign(cvalue_iterator(val, n), cvalue_iterator()); 0407 } 0408 0409 //! <b>Effects</b>: Assigns the range [first, last) to *this. 0410 //! 0411 //! <b>Throws</b>: If memory allocation throws or 0412 //! T's constructor from dereferencing InpIt throws. 0413 //! 0414 //! <b>Complexity</b>: Linear to n. 0415 template <class InpIt> 0416 void assign(InpIt first, InpIt last 0417 #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) 0418 , typename dtl::disable_if_convertible<InpIt, size_type>::type * = 0 0419 #endif 0420 ) 0421 { 0422 iterator end_n(this->end()); 0423 iterator prev(this->before_begin()); 0424 iterator node(this->begin()); 0425 while (node != end_n && first != last){ 0426 *node = *first; 0427 prev = node; 0428 ++node; 0429 ++first; 0430 } 0431 if (first != last) 0432 this->insert_after(prev, first, last); 0433 else 0434 this->erase_after(prev, end_n); 0435 } 0436 0437 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) 0438 //! <b>Effects</b>: Assigns the range [il.begin(), il.end()) to *this. 0439 //! 0440 //! <b>Throws</b>: If memory allocation throws or 0441 //! T's constructor from dereferencing std::initializer_list iterator throws. 0442 //! 0443 //! <b>Complexity</b>: Linear to range [il.begin(), il.end()). 0444 0445 void assign(std::initializer_list<value_type> il) 0446 { 0447 assign(il.begin(), il.end()); 0448 } 0449 #endif 0450 //! <b>Effects</b>: Returns a copy of the internal allocator. 0451 //! 0452 //! <b>Throws</b>: If allocator's copy constructor throws. 0453 //! 0454 //! <b>Complexity</b>: Constant. 0455 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline 0456 allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW 0457 { return allocator_type(this->node_alloc()); } 0458 0459 //! <b>Effects</b>: Returns a reference to the internal allocator. 0460 //! 0461 //! <b>Throws</b>: Nothing 0462 //! 0463 //! <b>Complexity</b>: Constant. 0464 //! 0465 //! <b>Note</b>: Non-standard extension. 0466 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline 0467 stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW 0468 { return this->node_alloc(); } 0469 0470 //! <b>Effects</b>: Returns a reference to the internal allocator. 0471 //! 0472 //! <b>Throws</b>: Nothing 0473 //! 0474 //! <b>Complexity</b>: Constant. 0475 //! 0476 //! <b>Note</b>: Non-standard extension. 0477 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline 0478 const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW 0479 { return this->node_alloc(); } 0480 0481 ////////////////////////////////////////////// 0482 // 0483 // iterators 0484 // 0485 ////////////////////////////////////////////// 0486 0487 //! <b>Effects</b>: Returns a non-dereferenceable iterator that, 0488 //! when incremented, yields begin(). This iterator may be used 0489 //! as the argument to insert_after, erase_after, etc. 0490 //! 0491 //! <b>Throws</b>: Nothing. 0492 //! 0493 //! <b>Complexity</b>: Constant. 0494 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline 0495 iterator before_begin() BOOST_NOEXCEPT_OR_NOTHROW 0496 { return iterator(end()); } 0497 0498 //! <b>Effects</b>: Returns a non-dereferenceable const_iterator 0499 //! that, when incremented, yields begin(). This iterator may be used 0500 //! as the argument to insert_after, erase_after, etc. 0501 //! 0502 //! <b>Throws</b>: Nothing. 0503 //! 0504 //! <b>Complexity</b>: Constant. 0505 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline 0506 const_iterator before_begin() const BOOST_NOEXCEPT_OR_NOTHROW 0507 { return this->cbefore_begin(); } 0508 0509 //! <b>Effects</b>: Returns an iterator to the first element contained in the list. 0510 //! 0511 //! <b>Throws</b>: Nothing. 0512 //! 0513 //! <b>Complexity</b>: Constant. 0514 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline 0515 iterator begin() BOOST_NOEXCEPT_OR_NOTHROW 0516 { return iterator(this->icont().begin()); } 0517 0518 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list. 0519 //! 0520 //! <b>Throws</b>: Nothing. 0521 //! 0522 //! <b>Complexity</b>: Constant. 0523 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline 0524 const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW 0525 { return this->cbegin(); } 0526 0527 //! <b>Effects</b>: Returns an iterator to the end of the list. 0528 //! 0529 //! <b>Throws</b>: Nothing. 0530 //! 0531 //! <b>Complexity</b>: Constant. 0532 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline 0533 iterator end() BOOST_NOEXCEPT_OR_NOTHROW 0534 { return iterator(this->icont().end()); } 0535 0536 //! <b>Effects</b>: Returns a const_iterator to the end of the list. 0537 //! 0538 //! <b>Throws</b>: Nothing. 0539 //! 0540 //! <b>Complexity</b>: Constant. 0541 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline 0542 const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW 0543 { return this->cend(); } 0544 0545 //! <b>Effects</b>: Returns a non-dereferenceable const_iterator 0546 //! that, when incremented, yields begin(). This iterator may be used 0547 //! as the argument to insert_after, erase_after, etc. 0548 //! 0549 //! <b>Throws</b>: Nothing. 0550 //! 0551 //! <b>Complexity</b>: Constant. 0552 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline 0553 const_iterator cbefore_begin() const BOOST_NOEXCEPT_OR_NOTHROW 0554 { return const_iterator(end()); } 0555 0556 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list. 0557 //! 0558 //! <b>Throws</b>: Nothing. 0559 //! 0560 //! <b>Complexity</b>: Constant. 0561 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline 0562 const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW 0563 { return const_iterator(this->non_const_icont().begin()); } 0564 0565 //! <b>Effects</b>: Returns a const_iterator to the end of the list. 0566 //! 0567 //! <b>Throws</b>: Nothing. 0568 //! 0569 //! <b>Complexity</b>: Constant. 0570 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline 0571 const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW 0572 { return const_iterator(this->non_const_icont().end()); } 0573 0574 //! <b>Returns</b>: The iterator to the element before i in the sequence. 0575 //! Returns the end-iterator, if either i is the begin-iterator or the 0576 //! sequence is empty. 0577 //! 0578 //! <b>Throws</b>: Nothing. 0579 //! 0580 //! <b>Complexity</b>: Linear to the number of elements before i. 0581 //! 0582 //! <b>Note</b>: Non-standard extension. 0583 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline 0584 iterator previous(iterator p) BOOST_NOEXCEPT_OR_NOTHROW 0585 { return iterator(this->icont().previous(p.get())); } 0586 0587 //! <b>Returns</b>: The const_iterator to the element before i in the sequence. 0588 //! Returns the end-const_iterator, if either i is the begin-const_iterator or 0589 //! the sequence is empty. 0590 //! 0591 //! <b>Throws</b>: Nothing. 0592 //! 0593 //! <b>Complexity</b>: Linear to the number of elements before i. 0594 //! 0595 //! <b>Note</b>: Non-standard extension. 0596 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline 0597 const_iterator previous(const_iterator p) 0598 { return const_iterator(this->icont().previous(p.get())); } 0599 0600 ////////////////////////////////////////////// 0601 // 0602 // capacity 0603 // 0604 ////////////////////////////////////////////// 0605 0606 //! <b>Effects</b>: Returns true if the list contains no elements. 0607 //! 0608 //! <b>Throws</b>: Nothing. 0609 //! 0610 //! <b>Complexity</b>: Constant. 0611 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline 0612 bool empty() const 0613 { return !this->size(); } 0614 0615 //! <b>Effects</b>: Returns the number of the elements contained in the list. 0616 //! 0617 //! <b>Throws</b>: Nothing. 0618 //! 0619 //! <b>Complexity</b>: Constant. 0620 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline 0621 size_type size() const 0622 { return this->icont().size(); } 0623 0624 //! <b>Effects</b>: Returns the largest possible size of the list. 0625 //! 0626 //! <b>Throws</b>: Nothing. 0627 //! 0628 //! <b>Complexity</b>: Constant. 0629 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline 0630 size_type max_size() const 0631 { return AllocHolder::max_size(); } 0632 0633 //! <b>Effects</b>: Inserts or erases elements at the end such that 0634 //! the size becomes n. New elements are value initialized. 0635 //! 0636 //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws. 0637 //! 0638 //! <b>Complexity</b>: Linear to the difference between size() and new_size. 0639 void resize(size_type new_size) 0640 { 0641 const_iterator last_pos; 0642 if(!priv_try_shrink(new_size, last_pos)){ 0643 typedef value_init_construct_iterator<value_type> value_init_iterator; 0644 this->insert_after(last_pos, value_init_iterator(new_size - this->size()), value_init_iterator()); 0645 } 0646 } 0647 0648 //! <b>Effects</b>: Inserts or erases elements at the end such that 0649 //! the size becomes n. New elements are copy constructed from x. 0650 //! 0651 //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws. 0652 //! 0653 //! <b>Complexity</b>: Linear to the difference between size() and new_size. 0654 void resize(size_type new_size, const T& x) 0655 { 0656 const_iterator last_pos; 0657 if(!priv_try_shrink(new_size, last_pos)){ 0658 this->insert_after(last_pos, new_size, x); 0659 } 0660 } 0661 0662 ////////////////////////////////////////////// 0663 // 0664 // element access 0665 // 0666 ////////////////////////////////////////////// 0667 0668 //! <b>Requires</b>: !empty() 0669 //! 0670 //! <b>Effects</b>: Returns a reference to the first element 0671 //! from the beginning of the container. 0672 //! 0673 //! <b>Throws</b>: Nothing. 0674 //! 0675 //! <b>Complexity</b>: Constant. 0676 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline 0677 reference front() 0678 { 0679 BOOST_ASSERT(!this->empty()); 0680 return *this->begin(); 0681 } 0682 0683 //! <b>Requires</b>: !empty() 0684 //! 0685 //! <b>Effects</b>: Returns a const reference to the first element 0686 //! from the beginning of the container. 0687 //! 0688 //! <b>Throws</b>: Nothing. 0689 //! 0690 //! <b>Complexity</b>: Constant. 0691 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline 0692 const_reference front() const 0693 { 0694 BOOST_ASSERT(!this->empty()); 0695 return *this->begin(); 0696 } 0697 0698 ////////////////////////////////////////////// 0699 // 0700 // modifiers 0701 // 0702 ////////////////////////////////////////////// 0703 0704 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) 0705 0706 //! <b>Effects</b>: Inserts an object of type T constructed with 0707 //! std::forward<Args>(args)... in the front of the list 0708 //! 0709 //! <b>Returns</b>: A reference to the created object. 0710 //! 0711 //! <b>Throws</b>: If memory allocation throws or 0712 //! T's copy constructor throws. 0713 //! 0714 //! <b>Complexity</b>: Amortized constant time. 0715 template <class... Args> 0716 reference emplace_front(BOOST_FWD_REF(Args)... args) 0717 { return *this->emplace_after(this->cbefore_begin(), boost::forward<Args>(args)...); } 0718 0719 //! <b>Effects</b>: Inserts an object of type T constructed with 0720 //! std::forward<Args>(args)... after prev 0721 //! 0722 //! <b>Throws</b>: If memory allocation throws or 0723 //! T's in-place constructor throws. 0724 //! 0725 //! <b>Complexity</b>: Constant 0726 template <class... Args> 0727 iterator emplace_after(const_iterator prev, BOOST_FWD_REF(Args)... args) 0728 { 0729 NodePtr pnode(AllocHolder::create_node(boost::forward<Args>(args)...)); 0730 return iterator(this->icont().insert_after(prev.get(), *pnode)); 0731 } 0732 0733 #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) 0734 0735 #define BOOST_CONTAINER_SLIST_EMPLACE_CODE(N) \ 0736 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ 0737 reference emplace_front(BOOST_MOVE_UREF##N)\ 0738 { return *this->emplace_after(this->cbefore_begin() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);}\ 0739 \ 0740 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ 0741 iterator emplace_after(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ 0742 {\ 0743 NodePtr pnode (AllocHolder::create_node(BOOST_MOVE_FWD##N));\ 0744 return iterator(this->icont().insert_after(p.get(), *pnode));\ 0745 }\ 0746 // 0747 BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SLIST_EMPLACE_CODE) 0748 #undef BOOST_CONTAINER_SLIST_EMPLACE_CODE 0749 0750 #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) 0751 0752 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) 0753 //! <b>Effects</b>: Inserts a copy of x at the beginning of the list. 0754 //! 0755 //! <b>Throws</b>: If memory allocation throws or 0756 //! T's copy constructor throws. 0757 //! 0758 //! <b>Complexity</b>: Amortized constant time. 0759 void push_front(const T &x); 0760 0761 //! <b>Effects</b>: Constructs a new element in the beginning of the list 0762 //! and moves the resources of x to this new element. 0763 //! 0764 //! <b>Throws</b>: If memory allocation throws. 0765 //! 0766 //! <b>Complexity</b>: Amortized constant time. 0767 void push_front(T &&x); 0768 #else 0769 BOOST_MOVE_CONVERSION_AWARE_CATCH(push_front, T, void, priv_push_front) 0770 #endif 0771 0772 0773 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) 0774 //! <b>Requires</b>: p must be a valid iterator of *this. 0775 //! 0776 //! <b>Effects</b>: Inserts a copy of the value after prev_p. 0777 //! 0778 //! <b>Returns</b>: An iterator to the inserted element. 0779 //! 0780 //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws. 0781 //! 0782 //! <b>Complexity</b>: Amortized constant time. 0783 //! 0784 //! <b>Note</b>: Does not affect the validity of iterators and references of 0785 //! previous values. 0786 iterator insert_after(const_iterator prev_p, const T &x); 0787 0788 //! <b>Requires</b>: prev_p must be a valid iterator of *this. 0789 //! 0790 //! <b>Effects</b>: Inserts a move constructed copy object from the value after the 0791 //! element pointed by prev_p. 0792 //! 0793 //! <b>Returns</b>: An iterator to the inserted element. 0794 //! 0795 //! <b>Throws</b>: If memory allocation throws. 0796 //! 0797 //! <b>Complexity</b>: Amortized constant time. 0798 //! 0799 //! <b>Note</b>: Does not affect the validity of iterators and references of 0800 //! previous values. 0801 iterator insert_after(const_iterator prev_p, T &&x); 0802 #else 0803 BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert_after, T, iterator, priv_insert_after, const_iterator, const_iterator) 0804 #endif 0805 0806 //! <b>Requires</b>: prev_p must be a valid iterator of *this. 0807 //! 0808 //! <b>Effects</b>: Inserts n copies of x after prev_p. 0809 //! 0810 //! <b>Returns</b>: an iterator to the last inserted element or prev_p if n is 0. 0811 //! 0812 //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws. 0813 //! 0814 //! 0815 //! <b>Complexity</b>: Linear to n. 0816 //! 0817 //! <b>Note</b>: Does not affect the validity of iterators and references of 0818 //! previous values. 0819 iterator insert_after(const_iterator prev_p, size_type n, const value_type& x) 0820 { 0821 typedef constant_iterator<value_type> cvalue_iterator; 0822 return this->insert_after(prev_p, cvalue_iterator(x, n), cvalue_iterator()); 0823 } 0824 0825 //! <b>Requires</b>: prev_p must be a valid iterator of *this. 0826 //! 0827 //! <b>Effects</b>: Inserts the range pointed by [first, last) after prev_p. 0828 //! 0829 //! <b>Returns</b>: an iterator to the last inserted element or prev_p if first == last. 0830 //! 0831 //! <b>Throws</b>: If memory allocation throws, T's constructor from a 0832 //! dereferenced InpIt throws. 0833 //! 0834 //! <b>Complexity</b>: Linear to the number of elements inserted. 0835 //! 0836 //! <b>Note</b>: Does not affect the validity of iterators and references of 0837 //! previous values. 0838 template <class InpIt> 0839 iterator insert_after(const_iterator prev_p, InpIt first, InpIt last 0840 #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) 0841 , typename dtl::enable_if_c 0842 < !dtl::is_convertible<InpIt, size_type>::value 0843 && (dtl::is_input_iterator<InpIt>::value 0844 || dtl::is_same<alloc_version, version_1>::value 0845 ) 0846 >::type * = 0 0847 #endif 0848 ) 0849 { 0850 iterator ret_it(prev_p.get()); 0851 for (; first != last; ++first){ 0852 ret_it = iterator(this->icont().insert_after(ret_it.get(), *this->create_node_from_it(first))); 0853 } 0854 return ret_it; 0855 } 0856 0857 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) 0858 //! <b>Requires</b>: prev_p must be a valid iterator of *this. 0859 //! 0860 //! <b>Effects</b>: Inserts the range pointed by [il.begin(), il.end()) after prev_p. 0861 //! 0862 //! <b>Returns</b>: an iterator to the last inserted element or prev_p if il.begin() == il.end(). 0863 //! 0864 //! <b>Throws</b>: If memory allocation throws, T's constructor from a 0865 //! dereferenced std::initializer_list iterator throws. 0866 //! 0867 //! <b>Complexity</b>: Linear to the number of elements inserted. 0868 //! 0869 //! <b>Note</b>: Does not affect the validity of iterators and references of 0870 //! previous values. 0871 iterator insert_after(const_iterator prev_p, std::initializer_list<value_type> il) 0872 { 0873 return insert_after(prev_p, il.begin(), il.end()); 0874 } 0875 #endif 0876 #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) 0877 template <class FwdIt> 0878 iterator insert_after(const_iterator prev, FwdIt first, FwdIt last 0879 , typename dtl::enable_if_c 0880 < !dtl::is_convertible<FwdIt, size_type>::value 0881 && !(dtl::is_input_iterator<FwdIt>::value 0882 || dtl::is_same<alloc_version, version_1>::value 0883 ) 0884 >::type * = 0 0885 ) 0886 { 0887 //Optimized allocation and construction 0888 insertion_functor func(this->icont(), prev.get()); 0889 this->allocate_many_and_construct(first, boost::container::iterator_udistance(first, last), func); 0890 return iterator(func.inserted_first()); 0891 } 0892 #endif 0893 0894 //! <b>Effects</b>: Removes the first element from the list. 0895 //! 0896 //! <b>Throws</b>: Nothing. 0897 //! 0898 //! <b>Complexity</b>: Amortized constant time. 0899 void pop_front() 0900 { 0901 BOOST_ASSERT(!this->empty()); 0902 this->icont().pop_front_and_dispose(Destroyer(this->node_alloc())); 0903 } 0904 0905 //! <b>Effects</b>: Erases the element after the element pointed by prev_p 0906 //! of the list. 0907 //! 0908 //! <b>Returns</b>: the first element remaining beyond the removed elements, 0909 //! or end() if no such element exists. 0910 //! 0911 //! <b>Throws</b>: Nothing. 0912 //! 0913 //! <b>Complexity</b>: Constant. 0914 //! 0915 //! <b>Note</b>: Does not invalidate iterators or references to non erased elements. 0916 iterator erase_after(const_iterator prev_p) 0917 { 0918 return iterator(this->icont().erase_after_and_dispose(prev_p.get(), Destroyer(this->node_alloc()))); 0919 } 0920 0921 //! <b>Effects</b>: Erases the range (before_first, last) from 0922 //! the list. 0923 //! 0924 //! <b>Returns</b>: the first element remaining beyond the removed elements, 0925 //! or end() if no such element exists. 0926 //! 0927 //! <b>Throws</b>: Nothing. 0928 //! 0929 //! <b>Complexity</b>: Linear to the number of erased elements. 0930 //! 0931 //! <b>Note</b>: Does not invalidate iterators or references to non erased elements. 0932 iterator erase_after(const_iterator before_first, const_iterator last) 0933 { 0934 return iterator(this->icont().erase_after_and_dispose(before_first.get(), last.get(), Destroyer(this->node_alloc()))); 0935 } 0936 0937 //! <b>Effects</b>: Swaps the contents of *this and x. 0938 //! 0939 //! <b>Throws</b>: Nothing. 0940 //! 0941 //! <b>Complexity</b>: Linear to the number of elements on *this and x. 0942 void swap(slist& x) 0943 BOOST_NOEXCEPT_IF( allocator_traits_type::propagate_on_container_swap::value 0944 || allocator_traits_type::is_always_equal::value) 0945 { 0946 BOOST_ASSERT(allocator_traits_type::propagate_on_container_swap::value || 0947 allocator_traits_type::is_always_equal::value || 0948 this->get_stored_allocator() == x.get_stored_allocator()); 0949 AllocHolder::swap(x); 0950 } 0951 0952 //! <b>Effects</b>: Erases all the elements of the list. 0953 //! 0954 //! <b>Throws</b>: Nothing. 0955 //! 0956 //! <b>Complexity</b>: Linear to the number of elements in the list. 0957 void clear() 0958 { this->icont().clear_and_dispose(Destroyer(this->node_alloc())); } 0959 0960 ////////////////////////////////////////////// 0961 // 0962 // slist operations 0963 // 0964 ////////////////////////////////////////////// 0965 0966 //! <b>Requires</b>: p must point to an element contained 0967 //! by the list. x != *this 0968 //! 0969 //! <b>Effects</b>: Transfers all the elements of list x to this list, after the 0970 //! the element pointed by p. No destructors or copy constructors are called. 0971 //! 0972 //! <b>Throws</b>: runtime_error if this' allocator and x's allocator 0973 //! are not equal. 0974 //! 0975 //! <b>Complexity</b>: Linear to the elements in x. 0976 //! 0977 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of 0978 //! this list. Iterators of this list and all the references are not invalidated. 0979 void splice_after(const_iterator prev_p, slist& x) BOOST_NOEXCEPT_OR_NOTHROW 0980 { 0981 BOOST_ASSERT(this != &x); 0982 BOOST_ASSERT(this->node_alloc() == x.node_alloc()); 0983 this->icont().splice_after(prev_p.get(), x.icont()); 0984 } 0985 0986 //! <b>Requires</b>: p must point to an element contained 0987 //! by the list. x != *this 0988 //! 0989 //! <b>Effects</b>: Transfers all the elements of list x to this list, after the 0990 //! the element pointed by p. No destructors or copy constructors are called. 0991 //! 0992 //! <b>Throws</b>: runtime_error if this' allocator and x's allocator 0993 //! are not equal. 0994 //! 0995 //! <b>Complexity</b>: Linear to the elements in x. 0996 //! 0997 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of 0998 //! this list. Iterators of this list and all the references are not invalidated. 0999 void splice_after(const_iterator prev_p, BOOST_RV_REF(slist) x) BOOST_NOEXCEPT_OR_NOTHROW 1000 { this->splice_after(prev_p, BOOST_MOVE_TO_LV(x)); } 1001 1002 //! <b>Requires</b>: prev_p must be a valid iterator of this. 1003 //! i must point to an element contained in list x. 1004 //! this' allocator and x's allocator shall compare equal. 1005 //! 1006 //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list, 1007 //! after the element pointed by prev_p. 1008 //! If prev_p == prev or prev_p == ++prev, this function is a null operation. 1009 //! 1010 //! <b>Throws</b>: Nothing 1011 //! 1012 //! <b>Complexity</b>: Constant. 1013 //! 1014 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this 1015 //! list. Iterators of this list and all the references are not invalidated. 1016 void splice_after(const_iterator prev_p, slist& x, const_iterator prev) BOOST_NOEXCEPT_OR_NOTHROW 1017 { 1018 BOOST_ASSERT(this->node_alloc() == x.node_alloc()); 1019 this->icont().splice_after(prev_p.get(), x.icont(), prev.get()); 1020 } 1021 1022 //! <b>Requires</b>: prev_p must be a valid iterator of this. 1023 //! i must point to an element contained in list x. 1024 //! this' allocator and x's allocator shall compare equal. 1025 //! 1026 //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list, 1027 //! after the element pointed by prev_p. 1028 //! If prev_p == prev or prev_p == ++prev, this function is a null operation. 1029 //! 1030 //! <b>Throws</b>: Nothing 1031 //! 1032 //! <b>Complexity</b>: Constant. 1033 //! 1034 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this 1035 //! list. Iterators of this list and all the references are not invalidated. 1036 void splice_after(const_iterator prev_p, BOOST_RV_REF(slist) x, const_iterator prev) BOOST_NOEXCEPT_OR_NOTHROW 1037 { this->splice_after(prev_p, BOOST_MOVE_TO_LV(x), prev); } 1038 1039 //! <b>Requires</b>: prev_p must be a valid iterator of this. 1040 //! before_first and before_last must be valid iterators of x. 1041 //! prev_p must not be contained in [before_first, before_last) range. 1042 //! this' allocator and x's allocator shall compare equal. 1043 //! 1044 //! <b>Effects</b>: Transfers the range [before_first + 1, before_last + 1) 1045 //! from list x to this list, after the element pointed by prev_p. 1046 //! 1047 //! <b>Throws</b>: Nothing 1048 //! 1049 //! <b>Complexity</b>: Linear to the number of transferred elements. 1050 //! 1051 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this 1052 //! list. Iterators of this list and all the references are not invalidated. 1053 void splice_after(const_iterator prev_p, slist& x, 1054 const_iterator before_first, const_iterator before_last) BOOST_NOEXCEPT_OR_NOTHROW 1055 { 1056 BOOST_ASSERT(this->node_alloc() == x.node_alloc()); 1057 this->icont().splice_after 1058 (prev_p.get(), x.icont(), before_first.get(), before_last.get()); 1059 } 1060 1061 //! <b>Requires</b>: prev_p must be a valid iterator of this. 1062 //! before_first and before_last must be valid iterators of x. 1063 //! prev_p must not be contained in [before_first, before_last) range. 1064 //! this' allocator and x's allocator shall compare equal. 1065 //! 1066 //! <b>Effects</b>: Transfers the range [before_first + 1, before_last + 1) 1067 //! from list x to this list, after the element pointed by prev_p. 1068 //! 1069 //! <b>Throws</b>: Nothing 1070 //! 1071 //! <b>Complexity</b>: Linear to the number of transferred elements. 1072 //! 1073 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this 1074 //! list. Iterators of this list and all the references are not invalidated. 1075 void splice_after(const_iterator prev_p, BOOST_RV_REF(slist) x, 1076 const_iterator before_first, const_iterator before_last) BOOST_NOEXCEPT_OR_NOTHROW 1077 { this->splice_after(prev_p, BOOST_MOVE_TO_LV(x), before_first, before_last); } 1078 1079 //! <b>Requires</b>: prev_p must be a valid iterator of this. 1080 //! before_first and before_last must be valid iterators of x. 1081 //! prev_p must not be contained in [before_first, before_last) range. 1082 //! n == distance(before_first, before_last). 1083 //! this' allocator and x's allocator shall compare equal. 1084 //! 1085 //! <b>Effects</b>: Transfers the range [before_first + 1, before_last + 1) 1086 //! from list x to this list, after the element pointed by prev_p. 1087 //! 1088 //! <b>Throws</b>: Nothing 1089 //! 1090 //! <b>Complexity</b>: Constant. 1091 //! 1092 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this 1093 //! list. Iterators of this list and all the references are not invalidated. 1094 void splice_after(const_iterator prev_p, slist& x, 1095 const_iterator before_first, const_iterator before_last, 1096 size_type n) BOOST_NOEXCEPT_OR_NOTHROW 1097 { 1098 BOOST_ASSERT(this->node_alloc() == x.node_alloc()); 1099 this->icont().splice_after 1100 (prev_p.get(), x.icont(), before_first.get(), before_last.get(), n); 1101 } 1102 1103 //! <b>Requires</b>: prev_p must be a valid iterator of this. 1104 //! before_first and before_last must be valid iterators of x. 1105 //! prev_p must not be contained in [before_first, before_last) range. 1106 //! n == distance(before_first, before_last). 1107 //! this' allocator and x's allocator shall compare equal. 1108 //! 1109 //! <b>Effects</b>: Transfers the range [before_first + 1, before_last + 1) 1110 //! from list x to this list, after the element pointed by prev_p. 1111 //! 1112 //! <b>Throws</b>: Nothing 1113 //! 1114 //! <b>Complexity</b>: Constant. 1115 //! 1116 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this 1117 //! list. Iterators of this list and all the references are not invalidated. 1118 void splice_after(const_iterator prev_p, BOOST_RV_REF(slist) x, 1119 const_iterator before_first, const_iterator before_last, 1120 size_type n) BOOST_NOEXCEPT_OR_NOTHROW 1121 { this->splice_after(prev_p, BOOST_MOVE_TO_LV(x), before_first, before_last, n); } 1122 1123 //! <b>Effects</b>: Removes all the elements that compare equal to value. 1124 //! 1125 //! <b>Throws</b>: Nothing. 1126 //! 1127 //! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality. 1128 //! 1129 //! <b>Note</b>: The relative order of elements that are not removed is unchanged, 1130 //! and iterators to elements that are not removed remain valid. 1131 void remove(const T& value) 1132 { this->remove_if(equal_to_value_type(value)); } 1133 1134 //! <b>Effects</b>: Removes all the elements for which a specified 1135 //! predicate is satisfied. 1136 //! 1137 //! <b>Throws</b>: If pred throws. 1138 //! 1139 //! <b>Complexity</b>: Linear time. It performs exactly size() calls to the predicate. 1140 //! 1141 //! <b>Note</b>: The relative order of elements that are not removed is unchanged, 1142 //! and iterators to elements that are not removed remain valid. 1143 template <class Pred> 1144 void remove_if(Pred pred) 1145 { 1146 typedef value_to_node_compare<Node, Pred> value_to_node_compare_type; 1147 this->icont().remove_and_dispose_if(value_to_node_compare_type(pred), Destroyer(this->node_alloc())); 1148 } 1149 1150 //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent 1151 //! elements that are equal from the list. 1152 //! 1153 //! <b>Throws</b>: If comparison throws. 1154 //! 1155 //! <b>Complexity</b>: Linear time (size()-1 comparisons equality comparisons). 1156 //! 1157 //! <b>Note</b>: The relative order of elements that are not removed is unchanged, 1158 //! and iterators to elements that are not removed remain valid. 1159 void unique() 1160 { this->unique(value_equal_t()); } 1161 1162 //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent 1163 //! elements that satisfy some binary predicate from the list. 1164 //! 1165 //! <b>Throws</b>: If pred throws. 1166 //! 1167 //! <b>Complexity</b>: Linear time (size()-1 comparisons calls to pred()). 1168 //! 1169 //! <b>Note</b>: The relative order of elements that are not removed is unchanged, 1170 //! and iterators to elements that are not removed remain valid. 1171 template <class Pred> 1172 void unique(Pred pred) 1173 { 1174 typedef value_to_node_compare<Node, Pred> value_to_node_compare_type; 1175 this->icont().unique_and_dispose(value_to_node_compare_type(pred), Destroyer(this->node_alloc())); 1176 } 1177 1178 //! <b>Requires</b>: The lists x and *this must be distinct. 1179 //! 1180 //! <b>Effects</b>: This function removes all of x's elements and inserts them 1181 //! in order into *this according to std::less<value_type>. The merge is stable; 1182 //! that is, if an element from *this is equivalent to one from x, then the element 1183 //! from *this will precede the one from x. 1184 //! 1185 //! <b>Throws</b>: If comparison throws. 1186 //! 1187 //! <b>Complexity</b>: This function is linear time: it performs at most 1188 //! size() + x.size() - 1 comparisons. 1189 void merge(slist & x) 1190 { this->merge(x, value_less_t()); } 1191 1192 //! <b>Requires</b>: The lists x and *this must be distinct. 1193 //! 1194 //! <b>Effects</b>: This function removes all of x's elements and inserts them 1195 //! in order into *this according to std::less<value_type>. The merge is stable; 1196 //! that is, if an element from *this is equivalent to one from x, then the element 1197 //! from *this will precede the one from x. 1198 //! 1199 //! <b>Throws</b>: If comparison throws. 1200 //! 1201 //! <b>Complexity</b>: This function is linear time: it performs at most 1202 //! size() + x.size() - 1 comparisons. 1203 void merge(BOOST_RV_REF(slist) x) 1204 { this->merge(BOOST_MOVE_TO_LV(x)); } 1205 1206 //! <b>Requires</b>: p must be a comparison function that induces a strict weak 1207 //! ordering and both *this and x must be sorted according to that ordering 1208 //! The lists x and *this must be distinct. 1209 //! 1210 //! <b>Effects</b>: This function removes all of x's elements and inserts them 1211 //! in order into *this. The merge is stable; that is, if an element from *this is 1212 //! equivalent to one from x, then the element from *this will precede the one from x. 1213 //! 1214 //! <b>Throws</b>: If comp throws. 1215 //! 1216 //! <b>Complexity</b>: This function is linear time: it performs at most 1217 //! size() + x.size() - 1 comparisons. 1218 //! 1219 //! <b>Note</b>: Iterators and references to *this are not invalidated. 1220 template <class StrictWeakOrdering> 1221 void merge(slist& x, StrictWeakOrdering comp) 1222 { 1223 typedef value_to_node_compare<Node, StrictWeakOrdering> value_to_node_compare_type; 1224 BOOST_ASSERT(this->node_alloc() == x.node_alloc()); 1225 this->icont().merge(x.icont(), value_to_node_compare_type(comp)); 1226 } 1227 1228 //! <b>Requires</b>: p must be a comparison function that induces a strict weak 1229 //! ordering and both *this and x must be sorted according to that ordering 1230 //! The lists x and *this must be distinct. 1231 //! 1232 //! <b>Effects</b>: This function removes all of x's elements and inserts them 1233 //! in order into *this. The merge is stable; that is, if an element from *this is 1234 //! equivalent to one from x, then the element from *this will precede the one from x. 1235 //! 1236 //! <b>Throws</b>: If comp throws. 1237 //! 1238 //! <b>Complexity</b>: This function is linear time: it performs at most 1239 //! size() + x.size() - 1 comparisons. 1240 //! 1241 //! <b>Note</b>: Iterators and references to *this are not invalidated. 1242 template <class StrictWeakOrdering> 1243 void merge(BOOST_RV_REF(slist) x, StrictWeakOrdering comp) 1244 { this->merge(BOOST_MOVE_TO_LV(x), comp); } 1245 1246 //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>. 1247 //! The sort is stable, that is, the relative order of equivalent elements is preserved. 1248 //! 1249 //! <b>Throws</b>: If comparison throws. 1250 //! 1251 //! <b>Notes</b>: Iterators and references are not invalidated. 1252 //! 1253 //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N 1254 //! is the list's size. 1255 void sort() 1256 { this->sort(value_less_t()); } 1257 1258 //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>. 1259 //! The sort is stable, that is, the relative order of equivalent elements is preserved. 1260 //! 1261 //! <b>Throws</b>: If comp throws. 1262 //! 1263 //! <b>Notes</b>: Iterators and references are not invalidated. 1264 //! 1265 //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N 1266 //! is the list's size. 1267 template <class StrictWeakOrdering> 1268 void sort(StrictWeakOrdering comp) 1269 { 1270 typedef value_to_node_compare<Node, StrictWeakOrdering> value_to_node_compare_type; 1271 // nothing if the slist has length 0 or 1. 1272 if (this->size() < 2) 1273 return; 1274 this->icont().sort(value_to_node_compare_type(comp)); 1275 } 1276 1277 //! <b>Effects</b>: Reverses the order of elements in the list. 1278 //! 1279 //! <b>Throws</b>: Nothing. 1280 //! 1281 //! <b>Complexity</b>: This function is linear time. 1282 //! 1283 //! <b>Note</b>: Iterators and references are not invalidated 1284 void reverse() BOOST_NOEXCEPT_OR_NOTHROW 1285 { this->icont().reverse(); } 1286 1287 ////////////////////////////////////////////// 1288 // 1289 // list compatibility interface 1290 // 1291 ////////////////////////////////////////////// 1292 1293 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) 1294 1295 //! <b>Effects</b>: Inserts an object of type T constructed with 1296 //! std::forward<Args>(args)... before p 1297 //! 1298 //! <b>Throws</b>: If memory allocation throws or 1299 //! T's in-place constructor throws. 1300 //! 1301 //! <b>Complexity</b>: Linear to the elements before p 1302 template <class... Args> 1303 iterator emplace(const_iterator p, BOOST_FWD_REF(Args)... args) 1304 { return this->emplace_after(this->previous(p), boost::forward<Args>(args)...); } 1305 1306 #else 1307 1308 #define BOOST_CONTAINER_SLIST_EMPLACE_CODE(N) \ 1309 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ 1310 iterator emplace(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ 1311 {\ 1312 return this->emplace_after(this->previous(p) BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ 1313 }\ 1314 // 1315 BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SLIST_EMPLACE_CODE) 1316 #undef BOOST_CONTAINER_SLIST_EMPLACE_CODE 1317 1318 #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) 1319 1320 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) 1321 //! <b>Requires</b>: p must be a valid iterator of *this. 1322 //! 1323 //! <b>Effects</b>: Insert a copy of x before p. 1324 //! 1325 //! <b>Returns</b>: an iterator to the inserted element. 1326 //! 1327 //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws. 1328 //! 1329 //! <b>Complexity</b>: Linear to the elements before p. 1330 iterator insert(const_iterator p, const T &x); 1331 1332 //! <b>Requires</b>: p must be a valid iterator of *this. 1333 //! 1334 //! <b>Effects</b>: Insert a new element before p with x's resources. 1335 //! 1336 //! <b>Returns</b>: an iterator to the inserted element. 1337 //! 1338 //! <b>Throws</b>: If memory allocation throws. 1339 //! 1340 //! <b>Complexity</b>: Linear to the elements before p. 1341 iterator insert(const_iterator prev_p, T &&x); 1342 #else 1343 BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator, const_iterator) 1344 #endif 1345 1346 //! <b>Requires</b>: p must be a valid iterator of *this. 1347 //! 1348 //! <b>Effects</b>: Inserts n copies of x before p. 1349 //! 1350 //! <b>Returns</b>: an iterator to the first inserted element or p if n == 0. 1351 //! 1352 //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws. 1353 //! 1354 //! <b>Complexity</b>: Linear to n plus linear to the elements before p. 1355 iterator insert(const_iterator p, size_type n, const value_type& x) 1356 { 1357 const_iterator prev(this->previous(p)); 1358 this->insert_after(prev, n, x); 1359 return ++iterator(prev.get()); 1360 } 1361 1362 //! <b>Requires</b>: p must be a valid iterator of *this. 1363 //! 1364 //! <b>Effects</b>: Insert a copy of the [first, last) range before p. 1365 //! 1366 //! <b>Returns</b>: an iterator to the first inserted element or p if first == last. 1367 //! 1368 //! <b>Throws</b>: If memory allocation throws, T's constructor from a 1369 //! dereferenced InpIt throws. 1370 //! 1371 //! <b>Complexity</b>: Linear to distance [first, last) plus 1372 //! linear to the elements before p. 1373 template <class InIter> 1374 iterator insert(const_iterator p, InIter first, InIter last) 1375 { 1376 const_iterator prev(this->previous(p)); 1377 this->insert_after(prev, first, last); 1378 return ++iterator(prev.get()); 1379 } 1380 1381 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) 1382 //! <b>Requires</b>: p must be a valid iterator of *this. 1383 //! 1384 //! <b>Effects</b>: Insert a copy of the [il.begin(), il.end()) range before p. 1385 //! 1386 //! <b>Returns</b>: an iterator to the first inserted element or p if il.begin() == il.end(). 1387 //! 1388 //! <b>Throws</b>: If memory allocation throws, T's constructor from a 1389 //! dereferenced std::initializer_list iterator throws. 1390 //! 1391 //! <b>Complexity</b>: Linear to the range [il.begin(), il.end()) plus 1392 //! linear to the elements before p. 1393 iterator insert(const_iterator p, std::initializer_list<value_type> il) 1394 { 1395 return insert(p, il.begin(), il.end()); 1396 } 1397 #endif 1398 1399 //! <b>Requires</b>: p must be a valid iterator of *this. 1400 //! 1401 //! <b>Effects</b>: Erases the element at p. 1402 //! 1403 //! <b>Throws</b>: Nothing. 1404 //! 1405 //! <b>Complexity</b>: Linear to the number of elements before p. 1406 iterator erase(const_iterator p) BOOST_NOEXCEPT_OR_NOTHROW 1407 { return iterator(this->erase_after(previous(p))); } 1408 1409 //! <b>Requires</b>: first and last must be valid iterator to elements in *this. 1410 //! 1411 //! <b>Effects</b>: Erases the elements pointed by [first, last). 1412 //! 1413 //! <b>Throws</b>: Nothing. 1414 //! 1415 //! <b>Complexity</b>: Linear to the distance between first and last plus 1416 //! linear to the elements before first. 1417 iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW 1418 { return iterator(this->erase_after(previous(first), last)); } 1419 1420 //! <b>Requires</b>: p must point to an element contained 1421 //! by the list. x != *this. this' allocator and x's allocator shall compare equal 1422 //! 1423 //! <b>Effects</b>: Transfers all the elements of list x to this list, before the 1424 //! the element pointed by p. No destructors or copy constructors are called. 1425 //! 1426 //! <b>Throws</b>: Nothing 1427 //! 1428 //! <b>Complexity</b>: Linear in distance(begin(), p), and linear in x.size(). 1429 //! 1430 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of 1431 //! this list. Iterators of this list and all the references are not invalidated. 1432 void splice(const_iterator p, slist& x) BOOST_NOEXCEPT_OR_NOTHROW 1433 { this->splice_after(this->previous(p), x); } 1434 1435 //! <b>Requires</b>: p must point to an element contained 1436 //! by the list. x != *this. this' allocator and x's allocator shall compare equal 1437 //! 1438 //! <b>Effects</b>: Transfers all the elements of list x to this list, before the 1439 //! the element pointed by p. No destructors or copy constructors are called. 1440 //! 1441 //! <b>Throws</b>: Nothing 1442 //! 1443 //! <b>Complexity</b>: Linear in distance(begin(), p), and linear in x.size(). 1444 //! 1445 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of 1446 //! this list. Iterators of this list and all the references are not invalidated. 1447 void splice(const_iterator p, BOOST_RV_REF(slist) x) BOOST_NOEXCEPT_OR_NOTHROW 1448 { this->splice(p, BOOST_MOVE_TO_LV(x)); } 1449 1450 //! <b>Requires</b>: p must point to an element contained 1451 //! by this list. i must point to an element contained in list x. 1452 //! this' allocator and x's allocator shall compare equal 1453 //! 1454 //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list, 1455 //! before the element pointed by p. No destructors or copy constructors are called. 1456 //! If p == i or p == ++i, this function is a null operation. 1457 //! 1458 //! <b>Throws</b>: Nothing 1459 //! 1460 //! <b>Complexity</b>: Linear in distance(begin(), p), and in distance(x.begin(), i). 1461 //! 1462 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this 1463 //! list. Iterators of this list and all the references are not invalidated. 1464 void splice(const_iterator p, slist& x, const_iterator i) BOOST_NOEXCEPT_OR_NOTHROW 1465 { this->splice_after(this->previous(p), x, x.previous(i)); } 1466 1467 //! <b>Requires</b>: p must point to an element contained 1468 //! by this list. i must point to an element contained in list x. 1469 //! this' allocator and x's allocator shall compare equal. 1470 //! 1471 //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list, 1472 //! before the element pointed by p. No destructors or copy constructors are called. 1473 //! If p == i or p == ++i, this function is a null operation. 1474 //! 1475 //! <b>Throws</b>: Nothing 1476 //! 1477 //! <b>Complexity</b>: Linear in distance(begin(), p), and in distance(x.begin(), i). 1478 //! 1479 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this 1480 //! list. Iterators of this list and all the references are not invalidated. 1481 void splice(const_iterator p, BOOST_RV_REF(slist) x, const_iterator i) BOOST_NOEXCEPT_OR_NOTHROW 1482 { this->splice(p, BOOST_MOVE_TO_LV(x), i); } 1483 1484 //! <b>Requires</b>: p must point to an element contained 1485 //! by this list. first and last must point to elements contained in list x. 1486 //! 1487 //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list, 1488 //! before the element pointed by p. No destructors or copy constructors are called. 1489 //! this' allocator and x's allocator shall compare equal. 1490 //! 1491 //! <b>Throws</b>: Nothing 1492 //! 1493 //! <b>Complexity</b>: Linear in distance(begin(), p), in distance(x.begin(), first), 1494 //! and in distance(first, last). 1495 //! 1496 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this 1497 //! list. Iterators of this list and all the references are not invalidated. 1498 void splice(const_iterator p, slist& x, const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW 1499 { this->splice_after(this->previous(p), x, x.previous(first), x.previous(last)); } 1500 1501 //! <b>Requires</b>: p must point to an element contained 1502 //! by this list. first and last must point to elements contained in list x. 1503 //! this' allocator and x's allocator shall compare equal 1504 //! 1505 //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list, 1506 //! before the element pointed by p. No destructors or copy constructors are called. 1507 //! 1508 //! <b>Throws</b>: Nothing 1509 //! 1510 //! <b>Complexity</b>: Linear in distance(begin(), p), in distance(x.begin(), first), 1511 //! and in distance(first, last). 1512 //! 1513 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this 1514 //! list. Iterators of this list and all the references are not invalidated. 1515 void splice(const_iterator p, BOOST_RV_REF(slist) x, const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW 1516 { this->splice(p, BOOST_MOVE_TO_LV(x), first, last); } 1517 1518 //! <b>Effects</b>: Returns true if x and y are equal 1519 //! 1520 //! <b>Complexity</b>: Linear to the number of elements in the container. 1521 friend bool operator==(const slist& x, const slist& y) 1522 { return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); } 1523 1524 //! <b>Effects</b>: Returns true if x and y are unequal 1525 //! 1526 //! <b>Complexity</b>: Linear to the number of elements in the container. 1527 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline 1528 friend bool operator!=(const slist& x, const slist& y) 1529 { return !(x == y); } 1530 1531 //! <b>Effects</b>: Returns true if x is less than y 1532 //! 1533 //! <b>Complexity</b>: Linear to the number of elements in the container. 1534 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline 1535 friend bool operator<(const slist& x, const slist& y) 1536 { return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } 1537 1538 //! <b>Effects</b>: Returns true if x is greater than y 1539 //! 1540 //! <b>Complexity</b>: Linear to the number of elements in the container. 1541 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline 1542 friend bool operator>(const slist& x, const slist& y) 1543 { return y < x; } 1544 1545 //! <b>Effects</b>: Returns true if x is equal or less than y 1546 //! 1547 //! <b>Complexity</b>: Linear to the number of elements in the container. 1548 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline 1549 friend bool operator<=(const slist& x, const slist& y) 1550 { return !(y < x); } 1551 1552 //! <b>Effects</b>: Returns true if x is equal or greater than y 1553 //! 1554 //! <b>Complexity</b>: Linear to the number of elements in the container. 1555 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline 1556 friend bool operator>=(const slist& x, const slist& y) 1557 { return !(x < y); } 1558 1559 //! <b>Effects</b>: x.swap(y) 1560 //! 1561 //! <b>Complexity</b>: Constant. 1562 friend void swap(slist& x, slist& y) 1563 BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT(x.swap(y))) 1564 { x.swap(y); } 1565 1566 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED 1567 private: 1568 void priv_move_assign(BOOST_RV_REF(slist) x, dtl::bool_<true> /*steal_resources*/) 1569 { 1570 //Destroy objects but retain memory in case x reuses it in the future 1571 this->clear(); 1572 //Move allocator if needed 1573 this->AllocHolder::move_assign_alloc(x); 1574 //Obtain resources 1575 this->icont() = boost::move(x.icont()); 1576 } 1577 1578 void priv_move_assign(BOOST_RV_REF(slist) x, dtl::bool_<false> /*steal_resources*/) 1579 { 1580 //We can't guarantee a compile-time equal allocator or propagation so fallback to runtime 1581 //Resources can be transferred if both allocators are equal 1582 if (this->node_alloc() == x.node_alloc()) { 1583 this->priv_move_assign(boost::move(x), dtl::true_()); 1584 } 1585 else { 1586 this->assign(boost::make_move_iterator(x.begin()), boost::make_move_iterator(x.end())); 1587 } 1588 } 1589 1590 template<class U> 1591 void priv_push_front(BOOST_FWD_REF(U) x) 1592 { this->icont().push_front(*this->create_node(::boost::forward<U>(x))); } 1593 1594 bool priv_try_shrink(size_type new_size, const_iterator &last_pos) 1595 { 1596 typename Icont::iterator end_n(this->icont().end()), cur(this->icont().before_begin()), cur_next; 1597 while (++(cur_next = cur) != end_n && new_size > 0){ 1598 --new_size; 1599 cur = cur_next; 1600 } 1601 last_pos = const_iterator(cur); 1602 if (cur_next != end_n){ 1603 this->erase_after(last_pos, const_iterator(end_n)); 1604 return true; 1605 } 1606 else{ 1607 return false; 1608 } 1609 } 1610 1611 template<class U> 1612 iterator priv_insert(const_iterator p, BOOST_FWD_REF(U) x) 1613 { return this->insert_after(previous(p), ::boost::forward<U>(x)); } 1614 1615 template<class U> 1616 iterator priv_insert_after(const_iterator prev_p, BOOST_FWD_REF(U) x) 1617 { return iterator(this->icont().insert_after(prev_p.get(), *this->create_node(::boost::forward<U>(x)))); } 1618 1619 class insertion_functor; 1620 friend class insertion_functor; 1621 1622 class insertion_functor 1623 { 1624 Icont &icont_; 1625 typedef typename Icont::iterator iiterator; 1626 typedef typename Icont::const_iterator iconst_iterator; 1627 const iconst_iterator prev_; 1628 iiterator ret_; 1629 1630 public: 1631 insertion_functor(Icont &icont, typename Icont::const_iterator prev) 1632 : icont_(icont), prev_(prev), ret_(prev.unconst()) 1633 {} 1634 1635 void operator()(Node &n) 1636 { 1637 ret_ = this->icont_.insert_after(prev_, n); 1638 } 1639 1640 iiterator inserted_first() const 1641 { return ret_; } 1642 }; 1643 1644 //Functors for member algorithm defaults 1645 typedef value_less<value_type> value_less_t; 1646 typedef value_equal<value_type> value_equal_t; 1647 1648 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED 1649 }; 1650 1651 #ifndef BOOST_CONTAINER_NO_CXX17_CTAD 1652 1653 template <typename InpIt> 1654 slist(InpIt, InpIt) -> 1655 slist<typename iterator_traits<InpIt>::value_type>; 1656 1657 template <typename InpIt, typename Allocator> 1658 slist(InpIt, InpIt, Allocator const&) -> 1659 slist<typename iterator_traits<InpIt>::value_type, Allocator>; 1660 1661 #endif 1662 1663 }} 1664 1665 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED 1666 1667 namespace boost { 1668 1669 //!has_trivial_destructor_after_move<> == true_type 1670 //!specialization for optimizations 1671 template <class T, class Allocator> 1672 struct has_trivial_destructor_after_move<boost::container::slist<T, Allocator> > 1673 { 1674 typedef typename boost::container::slist<T, Allocator>::allocator_type allocator_type; 1675 typedef typename ::boost::container::allocator_traits<allocator_type>::pointer pointer; 1676 BOOST_STATIC_CONSTEXPR bool value = ::boost::has_trivial_destructor_after_move<allocator_type>::value && 1677 ::boost::has_trivial_destructor_after_move<pointer>::value; 1678 }; 1679 1680 namespace container { 1681 1682 }} //namespace boost{ namespace container { 1683 1684 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED 1685 1686 // Specialization of insert_iterator so that insertions will be constant 1687 // time rather than linear time. 1688 1689 #include <boost/move/detail/std_ns_begin.hpp> 1690 BOOST_CONTAINER_DOC1ST(namespace std {, BOOST_MOVE_STD_NS_BEG) 1691 1692 //! A specialization of insert_iterator 1693 //! that works with slist 1694 template <class T, class ValueAllocator> 1695 class insert_iterator<boost::container::slist<T, ValueAllocator> > 1696 { 1697 private: 1698 typedef boost::container::slist<T, ValueAllocator> Container; 1699 Container* container; 1700 typename Container::iterator iter; 1701 1702 public: 1703 typedef Container container_type; 1704 typedef output_iterator_tag iterator_category; 1705 typedef void value_type; 1706 typedef void difference_type; 1707 typedef void pointer; 1708 typedef void reference; 1709 1710 insert_iterator(Container& x, 1711 typename Container::iterator i, 1712 bool is_previous = false) 1713 : container(&x), iter(is_previous ? i : x.previous(i)){ } 1714 1715 insert_iterator<Container>& 1716 operator=(const typename Container::value_type& value) 1717 { 1718 iter = container->insert_after(iter, value); 1719 return *this; 1720 } 1721 insert_iterator<Container>& operator*(){ return *this; } 1722 insert_iterator<Container>& operator++(){ return *this; } 1723 insert_iterator<Container>& operator++(int){ return *this; } 1724 }; 1725 1726 BOOST_CONTAINER_DOC1ST( }, BOOST_MOVE_STD_NS_END) 1727 #include <boost/move/detail/std_ns_end.hpp> 1728 1729 #include <boost/container/detail/config_end.hpp> 1730 1731 #endif // BOOST_CONTAINER_SLIST_HPP
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |