slist.hpp 66 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2004-2015. Distributed under the Boost
  4. // Software License, Version 1.0. (See accompanying file
  5. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // See http://www.boost.org/libs/container for documentation.
  8. //
  9. //////////////////////////////////////////////////////////////////////////////
  10. #ifndef BOOST_CONTAINER_SLIST_HPP
  11. #define BOOST_CONTAINER_SLIST_HPP
  12. #ifndef BOOST_CONFIG_HPP
  13. # include <boost/config.hpp>
  14. #endif
  15. #if defined(BOOST_HAS_PRAGMA_ONCE)
  16. # pragma once
  17. #endif
  18. #include <boost/container/detail/config_begin.hpp>
  19. #include <boost/container/detail/workaround.hpp>
  20. // container
  21. #include <boost/container/container_fwd.hpp>
  22. #include <boost/container/new_allocator.hpp> //new_allocator
  23. #include <boost/container/throw_exception.hpp>
  24. // container/detail
  25. #include <boost/container/detail/algorithm.hpp> //algo_equal(), algo_lexicographical_compare
  26. #include <boost/container/detail/compare_functors.hpp>
  27. #include <boost/container/detail/iterator.hpp>
  28. #include <boost/container/detail/iterators.hpp>
  29. #include <boost/container/detail/mpl.hpp>
  30. #include <boost/container/detail/node_alloc_holder.hpp>
  31. #include <boost/container/detail/type_traits.hpp>
  32. // intrusive
  33. #include <boost/intrusive/pointer_traits.hpp>
  34. #include <boost/intrusive/slist.hpp>
  35. // move
  36. #include <boost/move/iterator.hpp>
  37. #include <boost/move/traits.hpp>
  38. #include <boost/move/utility_core.hpp>
  39. // move/detail
  40. #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  41. #include <boost/move/detail/fwd_macros.hpp>
  42. #endif
  43. #include <boost/move/detail/move_helpers.hpp>
  44. // other
  45. #include <boost/core/no_exceptions_support.hpp>
  46. // std
  47. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  48. #include <initializer_list>
  49. #endif
  50. namespace boost {
  51. namespace container {
  52. #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  53. template <class T, class Allocator>
  54. class slist;
  55. namespace container_detail {
  56. template<class VoidPointer>
  57. struct slist_hook
  58. {
  59. typedef typename container_detail::bi::make_slist_base_hook
  60. <container_detail::bi::void_pointer<VoidPointer>, container_detail::bi::link_mode<container_detail::bi::normal_link> >::type type;
  61. };
  62. template <class T, class VoidPointer>
  63. struct slist_node
  64. : public slist_hook<VoidPointer>::type
  65. {
  66. private:
  67. slist_node();
  68. public:
  69. typedef T value_type;
  70. typedef typename slist_hook<VoidPointer>::type hook_type;
  71. T m_data;
  72. T &get_data()
  73. { return this->m_data; }
  74. const T &get_data() const
  75. { return this->m_data; }
  76. };
  77. template <class T, class VoidPointer>
  78. struct iiterator_node_value_type< slist_node<T,VoidPointer> > {
  79. typedef T type;
  80. };
  81. template<class Allocator>
  82. struct intrusive_slist_type
  83. {
  84. typedef boost::container::allocator_traits<Allocator> allocator_traits_type;
  85. typedef typename allocator_traits_type::value_type value_type;
  86. typedef typename boost::intrusive::pointer_traits
  87. <typename allocator_traits_type::pointer>::template
  88. rebind_pointer<void>::type
  89. void_pointer;
  90. typedef typename container_detail::slist_node
  91. <value_type, void_pointer> node_type;
  92. typedef typename container_detail::bi::make_slist
  93. <node_type
  94. ,container_detail::bi::base_hook<typename slist_hook<void_pointer>::type>
  95. ,container_detail::bi::constant_time_size<true>
  96. , container_detail::bi::size_type
  97. <typename allocator_traits_type::size_type>
  98. >::type container_type;
  99. typedef container_type type ;
  100. };
  101. } //namespace container_detail {
  102. #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  103. //! An slist is a singly linked list: a list where each element is linked to the next
  104. //! element, but not to the previous element. That is, it is a Sequence that
  105. //! supports forward but not backward traversal, and (amortized) constant time
  106. //! insertion and removal of elements. Slists, like lists, have the important
  107. //! property that insertion and splicing do not invalidate iterators to list elements,
  108. //! and that even removal invalidates only the iterators that point to the elements
  109. //! that are removed. The ordering of iterators may be changed (that is,
  110. //! slist<T>::iterator might have a different predecessor or successor after a list
  111. //! operation than it did before), but the iterators themselves will not be invalidated
  112. //! or made to point to different elements unless that invalidation or mutation is explicit.
  113. //!
  114. //! The main difference between slist and list is that list's iterators are bidirectional
  115. //! iterators, while slist's iterators are forward iterators. This means that slist is
  116. //! less versatile than list; frequently, however, bidirectional iterators are
  117. //! unnecessary. You should usually use slist unless you actually need the extra
  118. //! functionality of list, because singly linked lists are smaller and faster than double
  119. //! linked lists.
  120. //!
  121. //! Important performance note: like every other Sequence, slist defines the member
  122. //! functions insert and erase. Using these member functions carelessly, however, can
  123. //! result in disastrously slow programs. The problem is that insert's first argument is
  124. //! an iterator p, and that it inserts the new element(s) before p. This means that
  125. //! insert must find the iterator just before p; this is a constant-time operation
  126. //! for list, since list has bidirectional iterators, but for slist it must find that
  127. //! iterator by traversing the list from the beginning up to p. In other words:
  128. //! insert and erase are slow operations anywhere but near the beginning of the slist.
  129. //!
  130. //! Slist provides the member functions insert_after and erase_after, which are constant
  131. //! time operations: you should always use insert_after and erase_after whenever
  132. //! possible. If you find that insert_after and erase_after aren't adequate for your
  133. //! needs, and that you often need to use insert and erase in the middle of the list,
  134. //! then you should probably use list instead of slist.
  135. //!
  136. //! \tparam T The type of object that is stored in the list
  137. //! \tparam Allocator The allocator used for all internal memory management
  138. #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
  139. template <class T, class Allocator = new_allocator<T> >
  140. #else
  141. template <class T, class Allocator>
  142. #endif
  143. class slist
  144. : protected container_detail::node_alloc_holder
  145. <Allocator, typename container_detail::intrusive_slist_type<Allocator>::type>
  146. {
  147. #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  148. typedef typename
  149. container_detail::intrusive_slist_type<Allocator>::type Icont;
  150. typedef container_detail::node_alloc_holder<Allocator, Icont> AllocHolder;
  151. typedef typename AllocHolder::NodePtr NodePtr;
  152. typedef typename AllocHolder::NodeAlloc NodeAlloc;
  153. typedef typename AllocHolder::ValAlloc ValAlloc;
  154. typedef typename AllocHolder::Node Node;
  155. typedef container_detail::allocator_destroyer<NodeAlloc> Destroyer;
  156. typedef typename AllocHolder::alloc_version alloc_version;
  157. typedef boost::container::
  158. allocator_traits<Allocator> allocator_traits_type;
  159. typedef boost::container::equal_to_value<Allocator> equal_to_value_type;
  160. BOOST_COPYABLE_AND_MOVABLE(slist)
  161. typedef container_detail::iterator_from_iiterator<typename Icont::iterator, false> iterator_impl;
  162. typedef container_detail::iterator_from_iiterator<typename Icont::iterator, true > const_iterator_impl;
  163. #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  164. public:
  165. //////////////////////////////////////////////
  166. //
  167. // types
  168. //
  169. //////////////////////////////////////////////
  170. typedef T value_type;
  171. typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
  172. typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
  173. typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
  174. typedef typename ::boost::container::allocator_traits<Allocator>::const_reference const_reference;
  175. typedef typename ::boost::container::allocator_traits<Allocator>::size_type size_type;
  176. typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type;
  177. typedef Allocator allocator_type;
  178. typedef BOOST_CONTAINER_IMPDEF(NodeAlloc) stored_allocator_type;
  179. typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator;
  180. typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator;
  181. public:
  182. //////////////////////////////////////////////
  183. //
  184. // construct/copy/destroy
  185. //
  186. //////////////////////////////////////////////
  187. //! <b>Effects</b>: Constructs a list taking the allocator as parameter.
  188. //!
  189. //! <b>Throws</b>: If allocator_type's copy constructor throws.
  190. //!
  191. //! <b>Complexity</b>: Constant.
  192. slist()
  193. : AllocHolder()
  194. {}
  195. //! <b>Effects</b>: Constructs a list taking the allocator as parameter.
  196. //!
  197. //! <b>Throws</b>: Nothing
  198. //!
  199. //! <b>Complexity</b>: Constant.
  200. explicit slist(const allocator_type& a) BOOST_NOEXCEPT_OR_NOTHROW
  201. : AllocHolder(a)
  202. {}
  203. //! <b>Effects</b>: Constructs a list
  204. //! and inserts n value-initialized value_types.
  205. //!
  206. //! <b>Throws</b>: If allocator_type's default constructor
  207. //! throws or T's default or copy constructor throws.
  208. //!
  209. //! <b>Complexity</b>: Linear to n.
  210. explicit slist(size_type n)
  211. : AllocHolder(allocator_type())
  212. { this->resize(n); }
  213. //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
  214. //! and inserts n copies of value.
  215. //!
  216. //! <b>Throws</b>: If allocator_type's default constructor
  217. //! throws or T's default or copy constructor throws.
  218. //!
  219. //! <b>Complexity</b>: Linear to n.
  220. slist(size_type n, const allocator_type &a)
  221. : AllocHolder(a)
  222. { this->resize(n); }
  223. //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
  224. //! and inserts n copies of value.
  225. //!
  226. //! <b>Throws</b>: If allocator_type's default constructor
  227. //! throws or T's default or copy constructor throws.
  228. //!
  229. //! <b>Complexity</b>: Linear to n.
  230. explicit slist(size_type n, const value_type& x, const allocator_type& a = allocator_type())
  231. : AllocHolder(a)
  232. { this->insert_after(this->cbefore_begin(), n, x); }
  233. //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
  234. //! and inserts a copy of the range [first, last) in the list.
  235. //!
  236. //! <b>Throws</b>: If allocator_type's default constructor
  237. //! throws or T's constructor taking a dereferenced InIt throws.
  238. //!
  239. //! <b>Complexity</b>: Linear to the range [first, last).
  240. template <class InpIt>
  241. slist(InpIt first, InpIt last, const allocator_type& a = allocator_type())
  242. : AllocHolder(a)
  243. { this->insert_after(this->cbefore_begin(), first, last); }
  244. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  245. //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
  246. //! and inserts a copy of the range [il.begin(), il.end()) in the list.
  247. //!
  248. //! <b>Throws</b>: If allocator_type's default constructor
  249. //! throws or T's constructor taking a dereferenced std::initializer_list iterator throws.
  250. //!
  251. //! <b>Complexity</b>: Linear to the range [il.begin(), il.end()).
  252. slist(std::initializer_list<value_type> il, const allocator_type& a = allocator_type())
  253. : AllocHolder(a)
  254. { this->insert_after(this->cbefore_begin(), il.begin(), il.end()); }
  255. #endif
  256. //! <b>Effects</b>: Copy constructs a list.
  257. //!
  258. //! <b>Postcondition</b>: x == *this.
  259. //!
  260. //! <b>Throws</b>: If allocator_type's default constructor
  261. //!
  262. //! <b>Complexity</b>: Linear to the elements x contains.
  263. slist(const slist& x)
  264. : AllocHolder(x)
  265. { this->insert_after(this->cbefore_begin(), x.begin(), x.end()); }
  266. //! <b>Effects</b>: Move constructor. Moves x's resources to *this.
  267. //!
  268. //! <b>Throws</b>: If allocator_type's copy constructor throws.
  269. //!
  270. //! <b>Complexity</b>: Constant.
  271. slist(BOOST_RV_REF(slist) x)
  272. : AllocHolder(BOOST_MOVE_BASE(AllocHolder, x))
  273. {}
  274. //! <b>Effects</b>: Copy constructs a list using the specified allocator.
  275. //!
  276. //! <b>Postcondition</b>: x == *this.
  277. //!
  278. //! <b>Throws</b>: If allocator_type's default constructor
  279. //!
  280. //! <b>Complexity</b>: Linear to the elements x contains.
  281. slist(const slist& x, const allocator_type &a)
  282. : AllocHolder(a)
  283. { this->insert_after(this->cbefore_begin(), x.begin(), x.end()); }
  284. //! <b>Effects</b>: Move constructor using the specified allocator.
  285. //! Moves x's resources to *this.
  286. //!
  287. //! <b>Throws</b>: If allocation or value_type's copy constructor throws.
  288. //!
  289. //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
  290. slist(BOOST_RV_REF(slist) x, const allocator_type &a)
  291. : AllocHolder(a)
  292. {
  293. if(this->node_alloc() == x.node_alloc()){
  294. this->icont().swap(x.icont());
  295. }
  296. else{
  297. this->insert_after(this->cbefore_begin(), boost::make_move_iterator(x.begin()), boost::make_move_iterator(x.end()));
  298. }
  299. }
  300. //! <b>Effects</b>: Destroys the list. All stored values are destroyed
  301. //! and used memory is deallocated.
  302. //!
  303. //! <b>Throws</b>: Nothing.
  304. //!
  305. //! <b>Complexity</b>: Linear to the number of elements.
  306. ~slist() BOOST_NOEXCEPT_OR_NOTHROW
  307. {} //AllocHolder clears the slist
  308. //! <b>Effects</b>: Makes *this contain the same elements as x.
  309. //!
  310. //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
  311. //! of each of x's elements.
  312. //!
  313. //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
  314. //!
  315. //! <b>Complexity</b>: Linear to the number of elements in x.
  316. slist& operator= (BOOST_COPY_ASSIGN_REF(slist) x)
  317. {
  318. if (&x != this){
  319. NodeAlloc &this_alloc = this->node_alloc();
  320. const NodeAlloc &x_alloc = x.node_alloc();
  321. container_detail::bool_<allocator_traits_type::
  322. propagate_on_container_copy_assignment::value> flag;
  323. if(flag && this_alloc != x_alloc){
  324. this->clear();
  325. }
  326. this->AllocHolder::copy_assign_alloc(x);
  327. this->assign(x.begin(), x.end());
  328. }
  329. return *this;
  330. }
  331. //! <b>Effects</b>: Makes *this contain the same elements as x.
  332. //!
  333. //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
  334. //! of each of x's elements.
  335. //!
  336. //! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
  337. //! is false and (allocation throws or value_type's move constructor throws)
  338. //!
  339. //! <b>Complexity</b>: Constant if allocator_traits_type::
  340. //! propagate_on_container_move_assignment is true or
  341. //! this->get>allocator() == x.get_allocator(). Linear otherwise.
  342. slist& operator= (BOOST_RV_REF(slist) x)
  343. BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value
  344. || allocator_traits_type::is_always_equal::value)
  345. {
  346. BOOST_ASSERT(this != &x);
  347. NodeAlloc &this_alloc = this->node_alloc();
  348. NodeAlloc &x_alloc = x.node_alloc();
  349. const bool propagate_alloc = allocator_traits_type::
  350. propagate_on_container_move_assignment::value;
  351. const bool allocators_equal = this_alloc == x_alloc; (void)allocators_equal;
  352. //Resources can be transferred if both allocators are
  353. //going to be equal after this function (either propagated or already equal)
  354. if(propagate_alloc || allocators_equal){
  355. //Destroy
  356. this->clear();
  357. //Move allocator if needed
  358. this->AllocHolder::move_assign_alloc(x);
  359. //Obtain resources
  360. this->icont() = boost::move(x.icont());
  361. }
  362. //Else do a one by one move
  363. else{
  364. this->assign( boost::make_move_iterator(x.begin())
  365. , boost::make_move_iterator(x.end()));
  366. }
  367. return *this;
  368. }
  369. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  370. //! <b>Effects</b>: Makes *this contain the same elements as in il.
  371. //!
  372. //! <b>Postcondition</b>: this->size() == il.size(). *this contains a copy
  373. //! of each of il's elements.
  374. //!
  375. //! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
  376. //! is false and (allocation throws or value_type's move constructor throws)
  377. slist& operator=(std::initializer_list<value_type> il)
  378. {
  379. assign(il.begin(), il.end());
  380. return *this;
  381. }
  382. #endif
  383. //! <b>Effects</b>: Assigns the n copies of val to *this.
  384. //!
  385. //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
  386. //!
  387. //! <b>Complexity</b>: Linear to n.
  388. void assign(size_type n, const T& val)
  389. {
  390. typedef constant_iterator<value_type, difference_type> cvalue_iterator;
  391. return this->assign(cvalue_iterator(val, n), cvalue_iterator());
  392. }
  393. //! <b>Effects</b>: Assigns the range [first, last) to *this.
  394. //!
  395. //! <b>Throws</b>: If memory allocation throws or
  396. //! T's constructor from dereferencing InpIt throws.
  397. //!
  398. //! <b>Complexity</b>: Linear to n.
  399. template <class InpIt>
  400. void assign(InpIt first, InpIt last
  401. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  402. , typename container_detail::disable_if_convertible<InpIt, size_type>::type * = 0
  403. #endif
  404. )
  405. {
  406. iterator end_n(this->end());
  407. iterator prev(this->before_begin());
  408. iterator node(this->begin());
  409. while (node != end_n && first != last){
  410. *node = *first;
  411. prev = node;
  412. ++node;
  413. ++first;
  414. }
  415. if (first != last)
  416. this->insert_after(prev, first, last);
  417. else
  418. this->erase_after(prev, end_n);
  419. }
  420. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  421. //! <b>Effects</b>: Assigns the range [il.begin(), il.end()) to *this.
  422. //!
  423. //! <b>Throws</b>: If memory allocation throws or
  424. //! T's constructor from dereferencing std::initializer_list iterator throws.
  425. //!
  426. //! <b>Complexity</b>: Linear to range [il.begin(), il.end()).
  427. void assign(std::initializer_list<value_type> il)
  428. {
  429. assign(il.begin(), il.end());
  430. }
  431. #endif
  432. //! <b>Effects</b>: Returns a copy of the internal allocator.
  433. //!
  434. //! <b>Throws</b>: If allocator's copy constructor throws.
  435. //!
  436. //! <b>Complexity</b>: Constant.
  437. allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
  438. { return allocator_type(this->node_alloc()); }
  439. //! <b>Effects</b>: Returns a reference to the internal allocator.
  440. //!
  441. //! <b>Throws</b>: Nothing
  442. //!
  443. //! <b>Complexity</b>: Constant.
  444. //!
  445. //! <b>Note</b>: Non-standard extension.
  446. stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
  447. { return this->node_alloc(); }
  448. //! <b>Effects</b>: Returns a reference to the internal allocator.
  449. //!
  450. //! <b>Throws</b>: Nothing
  451. //!
  452. //! <b>Complexity</b>: Constant.
  453. //!
  454. //! <b>Note</b>: Non-standard extension.
  455. const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
  456. { return this->node_alloc(); }
  457. //////////////////////////////////////////////
  458. //
  459. // iterators
  460. //
  461. //////////////////////////////////////////////
  462. //! <b>Effects</b>: Returns a non-dereferenceable iterator that,
  463. //! when incremented, yields begin(). This iterator may be used
  464. //! as the argument to insert_after, erase_after, etc.
  465. //!
  466. //! <b>Throws</b>: Nothing.
  467. //!
  468. //! <b>Complexity</b>: Constant.
  469. iterator before_begin() BOOST_NOEXCEPT_OR_NOTHROW
  470. { return iterator(end()); }
  471. //! <b>Effects</b>: Returns a non-dereferenceable const_iterator
  472. //! that, when incremented, yields begin(). This iterator may be used
  473. //! as the argument to insert_after, erase_after, etc.
  474. //!
  475. //! <b>Throws</b>: Nothing.
  476. //!
  477. //! <b>Complexity</b>: Constant.
  478. const_iterator before_begin() const BOOST_NOEXCEPT_OR_NOTHROW
  479. { return this->cbefore_begin(); }
  480. //! <b>Effects</b>: Returns an iterator to the first element contained in the list.
  481. //!
  482. //! <b>Throws</b>: Nothing.
  483. //!
  484. //! <b>Complexity</b>: Constant.
  485. iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
  486. { return iterator(this->icont().begin()); }
  487. //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
  488. //!
  489. //! <b>Throws</b>: Nothing.
  490. //!
  491. //! <b>Complexity</b>: Constant.
  492. const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
  493. { return this->cbegin(); }
  494. //! <b>Effects</b>: Returns an iterator to the end of the list.
  495. //!
  496. //! <b>Throws</b>: Nothing.
  497. //!
  498. //! <b>Complexity</b>: Constant.
  499. iterator end() BOOST_NOEXCEPT_OR_NOTHROW
  500. { return iterator(this->icont().end()); }
  501. //! <b>Effects</b>: Returns a const_iterator to the end of the list.
  502. //!
  503. //! <b>Throws</b>: Nothing.
  504. //!
  505. //! <b>Complexity</b>: Constant.
  506. const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
  507. { return this->cend(); }
  508. //! <b>Effects</b>: Returns a non-dereferenceable const_iterator
  509. //! that, when incremented, yields begin(). This iterator may be used
  510. //! as the argument to insert_after, erase_after, etc.
  511. //!
  512. //! <b>Throws</b>: Nothing.
  513. //!
  514. //! <b>Complexity</b>: Constant.
  515. const_iterator cbefore_begin() const BOOST_NOEXCEPT_OR_NOTHROW
  516. { return const_iterator(end()); }
  517. //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
  518. //!
  519. //! <b>Throws</b>: Nothing.
  520. //!
  521. //! <b>Complexity</b>: Constant.
  522. const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
  523. { return const_iterator(this->non_const_icont().begin()); }
  524. //! <b>Effects</b>: Returns a const_iterator to the end of the list.
  525. //!
  526. //! <b>Throws</b>: Nothing.
  527. //!
  528. //! <b>Complexity</b>: Constant.
  529. const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
  530. { return const_iterator(this->non_const_icont().end()); }
  531. //! <b>Returns</b>: The iterator to the element before i in the sequence.
  532. //! Returns the end-iterator, if either i is the begin-iterator or the
  533. //! sequence is empty.
  534. //!
  535. //! <b>Throws</b>: Nothing.
  536. //!
  537. //! <b>Complexity</b>: Linear to the number of elements before i.
  538. //!
  539. //! <b>Note</b>: Non-standard extension.
  540. iterator previous(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
  541. { return iterator(this->icont().previous(p.get())); }
  542. //! <b>Returns</b>: The const_iterator to the element before i in the sequence.
  543. //! Returns the end-const_iterator, if either i is the begin-const_iterator or
  544. //! the sequence is empty.
  545. //!
  546. //! <b>Throws</b>: Nothing.
  547. //!
  548. //! <b>Complexity</b>: Linear to the number of elements before i.
  549. //!
  550. //! <b>Note</b>: Non-standard extension.
  551. const_iterator previous(const_iterator p)
  552. { return const_iterator(this->icont().previous(p.get())); }
  553. //////////////////////////////////////////////
  554. //
  555. // capacity
  556. //
  557. //////////////////////////////////////////////
  558. //! <b>Effects</b>: Returns true if the list contains no elements.
  559. //!
  560. //! <b>Throws</b>: Nothing.
  561. //!
  562. //! <b>Complexity</b>: Constant.
  563. bool empty() const
  564. { return !this->size(); }
  565. //! <b>Effects</b>: Returns the number of the elements contained in the list.
  566. //!
  567. //! <b>Throws</b>: Nothing.
  568. //!
  569. //! <b>Complexity</b>: Constant.
  570. size_type size() const
  571. { return this->icont().size(); }
  572. //! <b>Effects</b>: Returns the largest possible size of the list.
  573. //!
  574. //! <b>Throws</b>: Nothing.
  575. //!
  576. //! <b>Complexity</b>: Constant.
  577. size_type max_size() const
  578. { return AllocHolder::max_size(); }
  579. //! <b>Effects</b>: Inserts or erases elements at the end such that
  580. //! the size becomes n. New elements are value initialized.
  581. //!
  582. //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
  583. //!
  584. //! <b>Complexity</b>: Linear to the difference between size() and new_size.
  585. void resize(size_type new_size)
  586. {
  587. const_iterator last_pos;
  588. if(!priv_try_shrink(new_size, last_pos)){
  589. typedef value_init_construct_iterator<value_type, difference_type> value_init_iterator;
  590. this->insert_after(last_pos, value_init_iterator(new_size - this->size()), value_init_iterator());
  591. }
  592. }
  593. //! <b>Effects</b>: Inserts or erases elements at the end such that
  594. //! the size becomes n. New elements are copy constructed from x.
  595. //!
  596. //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
  597. //!
  598. //! <b>Complexity</b>: Linear to the difference between size() and new_size.
  599. void resize(size_type new_size, const T& x)
  600. {
  601. const_iterator last_pos;
  602. if(!priv_try_shrink(new_size, last_pos)){
  603. this->insert_after(last_pos, new_size, x);
  604. }
  605. }
  606. //////////////////////////////////////////////
  607. //
  608. // element access
  609. //
  610. //////////////////////////////////////////////
  611. //! <b>Requires</b>: !empty()
  612. //!
  613. //! <b>Effects</b>: Returns a reference to the first element
  614. //! from the beginning of the container.
  615. //!
  616. //! <b>Throws</b>: Nothing.
  617. //!
  618. //! <b>Complexity</b>: Constant.
  619. reference front()
  620. {
  621. BOOST_ASSERT(!this->empty());
  622. return *this->begin();
  623. }
  624. //! <b>Requires</b>: !empty()
  625. //!
  626. //! <b>Effects</b>: Returns a const reference to the first element
  627. //! from the beginning of the container.
  628. //!
  629. //! <b>Throws</b>: Nothing.
  630. //!
  631. //! <b>Complexity</b>: Constant.
  632. const_reference front() const
  633. {
  634. BOOST_ASSERT(!this->empty());
  635. return *this->begin();
  636. }
  637. //////////////////////////////////////////////
  638. //
  639. // modifiers
  640. //
  641. //////////////////////////////////////////////
  642. #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  643. //! <b>Effects</b>: Inserts an object of type T constructed with
  644. //! std::forward<Args>(args)... in the front of the list
  645. //!
  646. //! <b>Throws</b>: If memory allocation throws or
  647. //! T's copy constructor throws.
  648. //!
  649. //! <b>Complexity</b>: Amortized constant time.
  650. template <class... Args>
  651. void emplace_front(BOOST_FWD_REF(Args)... args)
  652. { this->emplace_after(this->cbefore_begin(), boost::forward<Args>(args)...); }
  653. //! <b>Effects</b>: Inserts an object of type T constructed with
  654. //! std::forward<Args>(args)... after prev
  655. //!
  656. //! <b>Throws</b>: If memory allocation throws or
  657. //! T's in-place constructor throws.
  658. //!
  659. //! <b>Complexity</b>: Constant
  660. template <class... Args>
  661. iterator emplace_after(const_iterator prev, BOOST_FWD_REF(Args)... args)
  662. {
  663. NodePtr pnode(AllocHolder::create_node(boost::forward<Args>(args)...));
  664. return iterator(this->icont().insert_after(prev.get(), *pnode));
  665. }
  666. #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  667. #define BOOST_CONTAINER_SLIST_EMPLACE_CODE(N) \
  668. BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
  669. void emplace_front(BOOST_MOVE_UREF##N)\
  670. { this->emplace_after(this->cbefore_begin() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);}\
  671. \
  672. BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
  673. iterator emplace_after(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
  674. {\
  675. NodePtr pnode (AllocHolder::create_node(BOOST_MOVE_FWD##N));\
  676. return iterator(this->icont().insert_after(p.get(), *pnode));\
  677. }\
  678. //
  679. BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SLIST_EMPLACE_CODE)
  680. #undef BOOST_CONTAINER_SLIST_EMPLACE_CODE
  681. #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  682. #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  683. //! <b>Effects</b>: Inserts a copy of x at the beginning of the list.
  684. //!
  685. //! <b>Throws</b>: If memory allocation throws or
  686. //! T's copy constructor throws.
  687. //!
  688. //! <b>Complexity</b>: Amortized constant time.
  689. void push_front(const T &x);
  690. //! <b>Effects</b>: Constructs a new element in the beginning of the list
  691. //! and moves the resources of x to this new element.
  692. //!
  693. //! <b>Throws</b>: If memory allocation throws.
  694. //!
  695. //! <b>Complexity</b>: Amortized constant time.
  696. void push_front(T &&x);
  697. #else
  698. BOOST_MOVE_CONVERSION_AWARE_CATCH(push_front, T, void, priv_push_front)
  699. #endif
  700. #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  701. //! <b>Requires</b>: p must be a valid iterator of *this.
  702. //!
  703. //! <b>Effects</b>: Inserts a copy of the value after prev_p.
  704. //!
  705. //! <b>Returns</b>: An iterator to the inserted element.
  706. //!
  707. //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
  708. //!
  709. //! <b>Complexity</b>: Amortized constant time.
  710. //!
  711. //! <b>Note</b>: Does not affect the validity of iterators and references of
  712. //! previous values.
  713. iterator insert_after(const_iterator prev_p, const T &x);
  714. //! <b>Requires</b>: prev_p must be a valid iterator of *this.
  715. //!
  716. //! <b>Effects</b>: Inserts a move constructed copy object from the value after the
  717. //! p pointed by prev_p.
  718. //!
  719. //! <b>Returns</b>: An iterator to the inserted element.
  720. //!
  721. //! <b>Throws</b>: If memory allocation throws.
  722. //!
  723. //! <b>Complexity</b>: Amortized constant time.
  724. //!
  725. //! <b>Note</b>: Does not affect the validity of iterators and references of
  726. //! previous values.
  727. iterator insert_after(const_iterator prev_p, T &&x);
  728. #else
  729. BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert_after, T, iterator, priv_insert_after, const_iterator, const_iterator)
  730. #endif
  731. //! <b>Requires</b>: prev_p must be a valid iterator of *this.
  732. //!
  733. //! <b>Effects</b>: Inserts n copies of x after prev_p.
  734. //!
  735. //! <b>Returns</b>: an iterator to the last inserted element or prev_p if n is 0.
  736. //!
  737. //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
  738. //!
  739. //!
  740. //! <b>Complexity</b>: Linear to n.
  741. //!
  742. //! <b>Note</b>: Does not affect the validity of iterators and references of
  743. //! previous values.
  744. iterator insert_after(const_iterator prev_p, size_type n, const value_type& x)
  745. {
  746. typedef constant_iterator<value_type, difference_type> cvalue_iterator;
  747. return this->insert_after(prev_p, cvalue_iterator(x, n), cvalue_iterator());
  748. }
  749. //! <b>Requires</b>: prev_p must be a valid iterator of *this.
  750. //!
  751. //! <b>Effects</b>: Inserts the range pointed by [first, last) after prev_p.
  752. //!
  753. //! <b>Returns</b>: an iterator to the last inserted element or prev_p if first == last.
  754. //!
  755. //! <b>Throws</b>: If memory allocation throws, T's constructor from a
  756. //! dereferenced InpIt throws.
  757. //!
  758. //! <b>Complexity</b>: Linear to the number of elements inserted.
  759. //!
  760. //! <b>Note</b>: Does not affect the validity of iterators and references of
  761. //! previous values.
  762. template <class InpIt>
  763. iterator insert_after(const_iterator prev_p, InpIt first, InpIt last
  764. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  765. , typename container_detail::enable_if_c
  766. < !container_detail::is_convertible<InpIt, size_type>::value
  767. && (container_detail::is_input_iterator<InpIt>::value
  768. || container_detail::is_same<alloc_version, version_1>::value
  769. )
  770. >::type * = 0
  771. #endif
  772. )
  773. {
  774. iterator ret_it(prev_p.get());
  775. for (; first != last; ++first){
  776. ret_it = iterator(this->icont().insert_after(ret_it.get(), *this->create_node_from_it(first)));
  777. }
  778. return ret_it;
  779. }
  780. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  781. //! <b>Requires</b>: prev_p must be a valid iterator of *this.
  782. //!
  783. //! <b>Effects</b>: Inserts the range pointed by [il.begin(), il.end()) after prev_p.
  784. //!
  785. //! <b>Returns</b>: an iterator to the last inserted element or prev_p if il.begin() == il.end().
  786. //!
  787. //! <b>Throws</b>: If memory allocation throws, T's constructor from a
  788. //! dereferenced std::initializer_list iterator throws.
  789. //!
  790. //! <b>Complexity</b>: Linear to the number of elements inserted.
  791. //!
  792. //! <b>Note</b>: Does not affect the validity of iterators and references of
  793. //! previous values.
  794. iterator insert_after(const_iterator prev_p, std::initializer_list<value_type> il)
  795. {
  796. return insert_after(prev_p, il.begin(), il.end());
  797. }
  798. #endif
  799. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  800. template <class FwdIt>
  801. iterator insert_after(const_iterator prev, FwdIt first, FwdIt last
  802. , typename container_detail::enable_if_c
  803. < !container_detail::is_convertible<FwdIt, size_type>::value
  804. && !(container_detail::is_input_iterator<FwdIt>::value
  805. || container_detail::is_same<alloc_version, version_1>::value
  806. )
  807. >::type * = 0
  808. )
  809. {
  810. //Optimized allocation and construction
  811. insertion_functor func(this->icont(), prev.get());
  812. this->allocate_many_and_construct(first, boost::container::iterator_distance(first, last), func);
  813. return iterator(func.inserted_first());
  814. }
  815. #endif
  816. //! <b>Effects</b>: Removes the first element from the list.
  817. //!
  818. //! <b>Throws</b>: Nothing.
  819. //!
  820. //! <b>Complexity</b>: Amortized constant time.
  821. void pop_front()
  822. {
  823. BOOST_ASSERT(!this->empty());
  824. this->icont().pop_front_and_dispose(Destroyer(this->node_alloc()));
  825. }
  826. //! <b>Effects</b>: Erases the element after the element pointed by prev_p
  827. //! of the list.
  828. //!
  829. //! <b>Returns</b>: the first element remaining beyond the removed elements,
  830. //! or end() if no such element exists.
  831. //!
  832. //! <b>Throws</b>: Nothing.
  833. //!
  834. //! <b>Complexity</b>: Constant.
  835. //!
  836. //! <b>Note</b>: Does not invalidate iterators or references to non erased elements.
  837. iterator erase_after(const_iterator prev_p)
  838. {
  839. return iterator(this->icont().erase_after_and_dispose(prev_p.get(), Destroyer(this->node_alloc())));
  840. }
  841. //! <b>Effects</b>: Erases the range (before_first, last) from
  842. //! the list.
  843. //!
  844. //! <b>Returns</b>: the first element remaining beyond the removed elements,
  845. //! or end() if no such element exists.
  846. //!
  847. //! <b>Throws</b>: Nothing.
  848. //!
  849. //! <b>Complexity</b>: Linear to the number of erased elements.
  850. //!
  851. //! <b>Note</b>: Does not invalidate iterators or references to non erased elements.
  852. iterator erase_after(const_iterator before_first, const_iterator last)
  853. {
  854. return iterator(this->icont().erase_after_and_dispose(before_first.get(), last.get(), Destroyer(this->node_alloc())));
  855. }
  856. //! <b>Effects</b>: Swaps the contents of *this and x.
  857. //!
  858. //! <b>Throws</b>: Nothing.
  859. //!
  860. //! <b>Complexity</b>: Linear to the number of elements on *this and x.
  861. void swap(slist& x)
  862. BOOST_NOEXCEPT_IF( allocator_traits_type::propagate_on_container_swap::value
  863. || allocator_traits_type::is_always_equal::value)
  864. {
  865. BOOST_ASSERT(allocator_traits_type::propagate_on_container_swap::value ||
  866. allocator_traits_type::is_always_equal::value ||
  867. this->get_stored_allocator() == x.get_stored_allocator());
  868. AllocHolder::swap(x);
  869. }
  870. //! <b>Effects</b>: Erases all the elements of the list.
  871. //!
  872. //! <b>Throws</b>: Nothing.
  873. //!
  874. //! <b>Complexity</b>: Linear to the number of elements in the list.
  875. void clear()
  876. { this->icont().clear_and_dispose(Destroyer(this->node_alloc())); }
  877. //////////////////////////////////////////////
  878. //
  879. // slist operations
  880. //
  881. //////////////////////////////////////////////
  882. //! <b>Requires</b>: p must point to an element contained
  883. //! by the list. x != *this
  884. //!
  885. //! <b>Effects</b>: Transfers all the elements of list x to this list, after the
  886. //! the element pointed by p. No destructors or copy constructors are called.
  887. //!
  888. //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
  889. //! are not equal.
  890. //!
  891. //! <b>Complexity</b>: Linear to the elements in x.
  892. //!
  893. //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
  894. //! this list. Iterators of this list and all the references are not invalidated.
  895. void splice_after(const_iterator prev_p, slist& x) BOOST_NOEXCEPT_OR_NOTHROW
  896. {
  897. BOOST_ASSERT(this != &x);
  898. BOOST_ASSERT(this->node_alloc() == x.node_alloc());
  899. this->icont().splice_after(prev_p.get(), x.icont());
  900. }
  901. //! <b>Requires</b>: p must point to an element contained
  902. //! by the list. x != *this
  903. //!
  904. //! <b>Effects</b>: Transfers all the elements of list x to this list, after the
  905. //! the element pointed by p. No destructors or copy constructors are called.
  906. //!
  907. //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
  908. //! are not equal.
  909. //!
  910. //! <b>Complexity</b>: Linear to the elements in x.
  911. //!
  912. //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
  913. //! this list. Iterators of this list and all the references are not invalidated.
  914. void splice_after(const_iterator prev_p, BOOST_RV_REF(slist) x) BOOST_NOEXCEPT_OR_NOTHROW
  915. { this->splice_after(prev_p, static_cast<slist&>(x)); }
  916. //! <b>Requires</b>: prev_p must be a valid iterator of this.
  917. //! i must point to an element contained in list x.
  918. //! this' allocator and x's allocator shall compare equal.
  919. //!
  920. //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
  921. //! after the element pointed by prev_p.
  922. //! If prev_p == prev or prev_p == ++prev, this function is a null operation.
  923. //!
  924. //! <b>Throws</b>: Nothing
  925. //!
  926. //! <b>Complexity</b>: Constant.
  927. //!
  928. //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
  929. //! list. Iterators of this list and all the references are not invalidated.
  930. void splice_after(const_iterator prev_p, slist& x, const_iterator prev) BOOST_NOEXCEPT_OR_NOTHROW
  931. {
  932. BOOST_ASSERT(this->node_alloc() == x.node_alloc());
  933. this->icont().splice_after(prev_p.get(), x.icont(), prev.get());
  934. }
  935. //! <b>Requires</b>: prev_p must be a valid iterator of this.
  936. //! i must point to an element contained in list x.
  937. //! this' allocator and x's allocator shall compare equal.
  938. //!
  939. //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
  940. //! after the element pointed by prev_p.
  941. //! If prev_p == prev or prev_p == ++prev, this function is a null operation.
  942. //!
  943. //! <b>Throws</b>: Nothing
  944. //!
  945. //! <b>Complexity</b>: Constant.
  946. //!
  947. //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
  948. //! list. Iterators of this list and all the references are not invalidated.
  949. void splice_after(const_iterator prev_p, BOOST_RV_REF(slist) x, const_iterator prev) BOOST_NOEXCEPT_OR_NOTHROW
  950. { this->splice_after(prev_p, static_cast<slist&>(x), prev); }
  951. //! <b>Requires</b>: prev_p must be a valid iterator of this.
  952. //! before_first and before_last must be valid iterators of x.
  953. //! prev_p must not be contained in [before_first, before_last) range.
  954. //! this' allocator and x's allocator shall compare equal.
  955. //!
  956. //! <b>Effects</b>: Transfers the range [before_first + 1, before_last + 1)
  957. //! from list x to this list, after the element pointed by prev_p.
  958. //!
  959. //! <b>Throws</b>: Nothing
  960. //!
  961. //! <b>Complexity</b>: Linear to the number of transferred elements.
  962. //!
  963. //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
  964. //! list. Iterators of this list and all the references are not invalidated.
  965. void splice_after(const_iterator prev_p, slist& x,
  966. const_iterator before_first, const_iterator before_last) BOOST_NOEXCEPT_OR_NOTHROW
  967. {
  968. BOOST_ASSERT(this->node_alloc() == x.node_alloc());
  969. this->icont().splice_after
  970. (prev_p.get(), x.icont(), before_first.get(), before_last.get());
  971. }
  972. //! <b>Requires</b>: prev_p must be a valid iterator of this.
  973. //! before_first and before_last must be valid iterators of x.
  974. //! prev_p must not be contained in [before_first, before_last) range.
  975. //! this' allocator and x's allocator shall compare equal.
  976. //!
  977. //! <b>Effects</b>: Transfers the range [before_first + 1, before_last + 1)
  978. //! from list x to this list, after the element pointed by prev_p.
  979. //!
  980. //! <b>Throws</b>: Nothing
  981. //!
  982. //! <b>Complexity</b>: Linear to the number of transferred elements.
  983. //!
  984. //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
  985. //! list. Iterators of this list and all the references are not invalidated.
  986. void splice_after(const_iterator prev_p, BOOST_RV_REF(slist) x,
  987. const_iterator before_first, const_iterator before_last) BOOST_NOEXCEPT_OR_NOTHROW
  988. { this->splice_after(prev_p, static_cast<slist&>(x), before_first, before_last); }
  989. //! <b>Requires</b>: prev_p must be a valid iterator of this.
  990. //! before_first and before_last must be valid iterators of x.
  991. //! prev_p must not be contained in [before_first, before_last) range.
  992. //! n == distance(before_first, before_last).
  993. //! this' allocator and x's allocator shall compare equal.
  994. //!
  995. //! <b>Effects</b>: Transfers the range [before_first + 1, before_last + 1)
  996. //! from list x to this list, after the element pointed by prev_p.
  997. //!
  998. //! <b>Throws</b>: Nothing
  999. //!
  1000. //! <b>Complexity</b>: Constant.
  1001. //!
  1002. //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
  1003. //! list. Iterators of this list and all the references are not invalidated.
  1004. void splice_after(const_iterator prev_p, slist& x,
  1005. const_iterator before_first, const_iterator before_last,
  1006. size_type n) BOOST_NOEXCEPT_OR_NOTHROW
  1007. {
  1008. BOOST_ASSERT(this->node_alloc() == x.node_alloc());
  1009. this->icont().splice_after
  1010. (prev_p.get(), x.icont(), before_first.get(), before_last.get(), n);
  1011. }
  1012. //! <b>Requires</b>: prev_p must be a valid iterator of this.
  1013. //! before_first and before_last must be valid iterators of x.
  1014. //! prev_p must not be contained in [before_first, before_last) range.
  1015. //! n == distance(before_first, before_last).
  1016. //! this' allocator and x's allocator shall compare equal.
  1017. //!
  1018. //! <b>Effects</b>: Transfers the range [before_first + 1, before_last + 1)
  1019. //! from list x to this list, after the element pointed by prev_p.
  1020. //!
  1021. //! <b>Throws</b>: Nothing
  1022. //!
  1023. //! <b>Complexity</b>: Constant.
  1024. //!
  1025. //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
  1026. //! list. Iterators of this list and all the references are not invalidated.
  1027. void splice_after(const_iterator prev_p, BOOST_RV_REF(slist) x,
  1028. const_iterator before_first, const_iterator before_last,
  1029. size_type n) BOOST_NOEXCEPT_OR_NOTHROW
  1030. { this->splice_after(prev_p, static_cast<slist&>(x), before_first, before_last, n); }
  1031. //! <b>Effects</b>: Removes all the elements that compare equal to value.
  1032. //!
  1033. //! <b>Throws</b>: Nothing.
  1034. //!
  1035. //! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality.
  1036. //!
  1037. //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
  1038. //! and iterators to elements that are not removed remain valid.
  1039. void remove(const T& value)
  1040. { this->remove_if(equal_to_value_type(value)); }
  1041. //! <b>Effects</b>: Removes all the elements for which a specified
  1042. //! predicate is satisfied.
  1043. //!
  1044. //! <b>Throws</b>: If pred throws.
  1045. //!
  1046. //! <b>Complexity</b>: Linear time. It performs exactly size() calls to the predicate.
  1047. //!
  1048. //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
  1049. //! and iterators to elements that are not removed remain valid.
  1050. template <class Pred>
  1051. void remove_if(Pred pred)
  1052. {
  1053. typedef value_to_node_compare<Node, Pred> value_to_node_compare_type;
  1054. this->icont().remove_and_dispose_if(value_to_node_compare_type(pred), Destroyer(this->node_alloc()));
  1055. }
  1056. //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
  1057. //! elements that are equal from the list.
  1058. //!
  1059. //! <b>Throws</b>: If comparison throws.
  1060. //!
  1061. //! <b>Complexity</b>: Linear time (size()-1 comparisons equality comparisons).
  1062. //!
  1063. //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
  1064. //! and iterators to elements that are not removed remain valid.
  1065. void unique()
  1066. { this->unique(value_equal()); }
  1067. //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
  1068. //! elements that satisfy some binary predicate from the list.
  1069. //!
  1070. //! <b>Throws</b>: If pred throws.
  1071. //!
  1072. //! <b>Complexity</b>: Linear time (size()-1 comparisons calls to pred()).
  1073. //!
  1074. //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
  1075. //! and iterators to elements that are not removed remain valid.
  1076. template <class Pred>
  1077. void unique(Pred pred)
  1078. {
  1079. typedef value_to_node_compare<Node, Pred> value_to_node_compare_type;
  1080. this->icont().unique_and_dispose(value_to_node_compare_type(pred), Destroyer(this->node_alloc()));
  1081. }
  1082. //! <b>Requires</b>: The lists x and *this must be distinct.
  1083. //!
  1084. //! <b>Effects</b>: This function removes all of x's elements and inserts them
  1085. //! in order into *this according to std::less<value_type>. The merge is stable;
  1086. //! that is, if an element from *this is equivalent to one from x, then the element
  1087. //! from *this will precede the one from x.
  1088. //!
  1089. //! <b>Throws</b>: If comparison throws.
  1090. //!
  1091. //! <b>Complexity</b>: This function is linear time: it performs at most
  1092. //! size() + x.size() - 1 comparisons.
  1093. void merge(slist & x)
  1094. { this->merge(x, value_less()); }
  1095. //! <b>Requires</b>: The lists x and *this must be distinct.
  1096. //!
  1097. //! <b>Effects</b>: This function removes all of x's elements and inserts them
  1098. //! in order into *this according to std::less<value_type>. The merge is stable;
  1099. //! that is, if an element from *this is equivalent to one from x, then the element
  1100. //! from *this will precede the one from x.
  1101. //!
  1102. //! <b>Throws</b>: If comparison throws.
  1103. //!
  1104. //! <b>Complexity</b>: This function is linear time: it performs at most
  1105. //! size() + x.size() - 1 comparisons.
  1106. void merge(BOOST_RV_REF(slist) x)
  1107. { this->merge(static_cast<slist&>(x)); }
  1108. //! <b>Requires</b>: p must be a comparison function that induces a strict weak
  1109. //! ordering and both *this and x must be sorted according to that ordering
  1110. //! The lists x and *this must be distinct.
  1111. //!
  1112. //! <b>Effects</b>: This function removes all of x's elements and inserts them
  1113. //! in order into *this. The merge is stable; that is, if an element from *this is
  1114. //! equivalent to one from x, then the element from *this will precede the one from x.
  1115. //!
  1116. //! <b>Throws</b>: If comp throws.
  1117. //!
  1118. //! <b>Complexity</b>: This function is linear time: it performs at most
  1119. //! size() + x.size() - 1 comparisons.
  1120. //!
  1121. //! <b>Note</b>: Iterators and references to *this are not invalidated.
  1122. template <class StrictWeakOrdering>
  1123. void merge(slist& x, StrictWeakOrdering comp)
  1124. {
  1125. typedef value_to_node_compare<Node, StrictWeakOrdering> value_to_node_compare_type;
  1126. BOOST_ASSERT(this->node_alloc() == x.node_alloc());
  1127. this->icont().merge(x.icont(), value_to_node_compare_type(comp));
  1128. }
  1129. //! <b>Requires</b>: p must be a comparison function that induces a strict weak
  1130. //! ordering and both *this and x must be sorted according to that ordering
  1131. //! The lists x and *this must be distinct.
  1132. //!
  1133. //! <b>Effects</b>: This function removes all of x's elements and inserts them
  1134. //! in order into *this. The merge is stable; that is, if an element from *this is
  1135. //! equivalent to one from x, then the element from *this will precede the one from x.
  1136. //!
  1137. //! <b>Throws</b>: If comp throws.
  1138. //!
  1139. //! <b>Complexity</b>: This function is linear time: it performs at most
  1140. //! size() + x.size() - 1 comparisons.
  1141. //!
  1142. //! <b>Note</b>: Iterators and references to *this are not invalidated.
  1143. template <class StrictWeakOrdering>
  1144. void merge(BOOST_RV_REF(slist) x, StrictWeakOrdering comp)
  1145. { this->merge(static_cast<slist&>(x), comp); }
  1146. //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
  1147. //! The sort is stable, that is, the relative order of equivalent elements is preserved.
  1148. //!
  1149. //! <b>Throws</b>: If comparison throws.
  1150. //!
  1151. //! <b>Notes</b>: Iterators and references are not invalidated.
  1152. //!
  1153. //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N
  1154. //! is the list's size.
  1155. void sort()
  1156. { this->sort(value_less()); }
  1157. //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
  1158. //! The sort is stable, that is, the relative order of equivalent elements is preserved.
  1159. //!
  1160. //! <b>Throws</b>: If comp throws.
  1161. //!
  1162. //! <b>Notes</b>: Iterators and references are not invalidated.
  1163. //!
  1164. //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N
  1165. //! is the list's size.
  1166. template <class StrictWeakOrdering>
  1167. void sort(StrictWeakOrdering comp)
  1168. {
  1169. typedef value_to_node_compare<Node, StrictWeakOrdering> value_to_node_compare_type;
  1170. // nothing if the slist has length 0 or 1.
  1171. if (this->size() < 2)
  1172. return;
  1173. this->icont().sort(value_to_node_compare_type(comp));
  1174. }
  1175. //! <b>Effects</b>: Reverses the order of elements in the list.
  1176. //!
  1177. //! <b>Throws</b>: Nothing.
  1178. //!
  1179. //! <b>Complexity</b>: This function is linear time.
  1180. //!
  1181. //! <b>Note</b>: Iterators and references are not invalidated
  1182. void reverse() BOOST_NOEXCEPT_OR_NOTHROW
  1183. { this->icont().reverse(); }
  1184. //////////////////////////////////////////////
  1185. //
  1186. // list compatibility interface
  1187. //
  1188. //////////////////////////////////////////////
  1189. #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  1190. //! <b>Effects</b>: Inserts an object of type T constructed with
  1191. //! std::forward<Args>(args)... before p
  1192. //!
  1193. //! <b>Throws</b>: If memory allocation throws or
  1194. //! T's in-place constructor throws.
  1195. //!
  1196. //! <b>Complexity</b>: Linear to the elements before p
  1197. template <class... Args>
  1198. iterator emplace(const_iterator p, BOOST_FWD_REF(Args)... args)
  1199. { return this->emplace_after(this->previous(p), boost::forward<Args>(args)...); }
  1200. #else
  1201. #define BOOST_CONTAINER_SLIST_EMPLACE_CODE(N) \
  1202. BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
  1203. iterator emplace(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
  1204. {\
  1205. return this->emplace_after(this->previous(p) BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
  1206. }\
  1207. //
  1208. BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SLIST_EMPLACE_CODE)
  1209. #undef BOOST_CONTAINER_SLIST_EMPLACE_CODE
  1210. #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  1211. #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  1212. //! <b>Requires</b>: p must be a valid iterator of *this.
  1213. //!
  1214. //! <b>Effects</b>: Insert a copy of x before p.
  1215. //!
  1216. //! <b>Returns</b>: an iterator to the inserted element.
  1217. //!
  1218. //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
  1219. //!
  1220. //! <b>Complexity</b>: Linear to the elements before p.
  1221. iterator insert(const_iterator p, const T &x);
  1222. //! <b>Requires</b>: p must be a valid iterator of *this.
  1223. //!
  1224. //! <b>Effects</b>: Insert a new element before p with x's resources.
  1225. //!
  1226. //! <b>Returns</b>: an iterator to the inserted element.
  1227. //!
  1228. //! <b>Throws</b>: If memory allocation throws.
  1229. //!
  1230. //! <b>Complexity</b>: Linear to the elements before p.
  1231. iterator insert(const_iterator prev_p, T &&x);
  1232. #else
  1233. BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator, const_iterator)
  1234. #endif
  1235. //! <b>Requires</b>: p must be a valid iterator of *this.
  1236. //!
  1237. //! <b>Effects</b>: Inserts n copies of x before p.
  1238. //!
  1239. //! <b>Returns</b>: an iterator to the first inserted element or p if n == 0.
  1240. //!
  1241. //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
  1242. //!
  1243. //! <b>Complexity</b>: Linear to n plus linear to the elements before p.
  1244. iterator insert(const_iterator p, size_type n, const value_type& x)
  1245. {
  1246. const_iterator prev(this->previous(p));
  1247. this->insert_after(prev, n, x);
  1248. return ++iterator(prev.get());
  1249. }
  1250. //! <b>Requires</b>: p must be a valid iterator of *this.
  1251. //!
  1252. //! <b>Effects</b>: Insert a copy of the [first, last) range before p.
  1253. //!
  1254. //! <b>Returns</b>: an iterator to the first inserted element or p if first == last.
  1255. //!
  1256. //! <b>Throws</b>: If memory allocation throws, T's constructor from a
  1257. //! dereferenced InpIt throws.
  1258. //!
  1259. //! <b>Complexity</b>: Linear to distance [first, last) plus
  1260. //! linear to the elements before p.
  1261. template <class InIter>
  1262. iterator insert(const_iterator p, InIter first, InIter last)
  1263. {
  1264. const_iterator prev(this->previous(p));
  1265. this->insert_after(prev, first, last);
  1266. return ++iterator(prev.get());
  1267. }
  1268. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  1269. //! <b>Requires</b>: p must be a valid iterator of *this.
  1270. //!
  1271. //! <b>Effects</b>: Insert a copy of the [il.begin(), il.end()) range before p.
  1272. //!
  1273. //! <b>Returns</b>: an iterator to the first inserted element or p if il.begin() == il.end().
  1274. //!
  1275. //! <b>Throws</b>: If memory allocation throws, T's constructor from a
  1276. //! dereferenced std::initializer_list iterator throws.
  1277. //!
  1278. //! <b>Complexity</b>: Linear to the range [il.begin(), il.end()) plus
  1279. //! linear to the elements before p.
  1280. iterator insert(const_iterator p, std::initializer_list<value_type> il)
  1281. {
  1282. return insert(p, il.begin(), il.end());
  1283. }
  1284. #endif
  1285. //! <b>Requires</b>: p must be a valid iterator of *this.
  1286. //!
  1287. //! <b>Effects</b>: Erases the element at p p.
  1288. //!
  1289. //! <b>Throws</b>: Nothing.
  1290. //!
  1291. //! <b>Complexity</b>: Linear to the number of elements before p.
  1292. iterator erase(const_iterator p) BOOST_NOEXCEPT_OR_NOTHROW
  1293. { return iterator(this->erase_after(previous(p))); }
  1294. //! <b>Requires</b>: first and last must be valid iterator to elements in *this.
  1295. //!
  1296. //! <b>Effects</b>: Erases the elements pointed by [first, last).
  1297. //!
  1298. //! <b>Throws</b>: Nothing.
  1299. //!
  1300. //! <b>Complexity</b>: Linear to the distance between first and last plus
  1301. //! linear to the elements before first.
  1302. iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
  1303. { return iterator(this->erase_after(previous(first), last)); }
  1304. //! <b>Requires</b>: p must point to an element contained
  1305. //! by the list. x != *this. this' allocator and x's allocator shall compare equal
  1306. //!
  1307. //! <b>Effects</b>: Transfers all the elements of list x to this list, before the
  1308. //! the element pointed by p. No destructors or copy constructors are called.
  1309. //!
  1310. //! <b>Throws</b>: Nothing
  1311. //!
  1312. //! <b>Complexity</b>: Linear in distance(begin(), p), and linear in x.size().
  1313. //!
  1314. //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
  1315. //! this list. Iterators of this list and all the references are not invalidated.
  1316. void splice(const_iterator p, slist& x) BOOST_NOEXCEPT_OR_NOTHROW
  1317. { this->splice_after(this->previous(p), x); }
  1318. //! <b>Requires</b>: p must point to an element contained
  1319. //! by the list. x != *this. this' allocator and x's allocator shall compare equal
  1320. //!
  1321. //! <b>Effects</b>: Transfers all the elements of list x to this list, before the
  1322. //! the element pointed by p. No destructors or copy constructors are called.
  1323. //!
  1324. //! <b>Throws</b>: Nothing
  1325. //!
  1326. //! <b>Complexity</b>: Linear in distance(begin(), p), and linear in x.size().
  1327. //!
  1328. //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
  1329. //! this list. Iterators of this list and all the references are not invalidated.
  1330. void splice(const_iterator p, BOOST_RV_REF(slist) x) BOOST_NOEXCEPT_OR_NOTHROW
  1331. { this->splice(p, static_cast<slist&>(x)); }
  1332. //! <b>Requires</b>: p must point to an element contained
  1333. //! by this list. i must point to an element contained in list x.
  1334. //! this' allocator and x's allocator shall compare equal
  1335. //!
  1336. //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
  1337. //! before the the element pointed by p. No destructors or copy constructors are called.
  1338. //! If p == i or p == ++i, this function is a null operation.
  1339. //!
  1340. //! <b>Throws</b>: Nothing
  1341. //!
  1342. //! <b>Complexity</b>: Linear in distance(begin(), p), and in distance(x.begin(), i).
  1343. //!
  1344. //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
  1345. //! list. Iterators of this list and all the references are not invalidated.
  1346. void splice(const_iterator p, slist& x, const_iterator i) BOOST_NOEXCEPT_OR_NOTHROW
  1347. { this->splice_after(this->previous(p), x, this->previous(i)); }
  1348. //! <b>Requires</b>: p must point to an element contained
  1349. //! by this list. i must point to an element contained in list x.
  1350. //! this' allocator and x's allocator shall compare equal.
  1351. //!
  1352. //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
  1353. //! before the the element pointed by p. No destructors or copy constructors are called.
  1354. //! If p == i or p == ++i, this function is a null operation.
  1355. //!
  1356. //! <b>Throws</b>: Nothing
  1357. //!
  1358. //! <b>Complexity</b>: Linear in distance(begin(), p), and in distance(x.begin(), i).
  1359. //!
  1360. //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
  1361. //! list. Iterators of this list and all the references are not invalidated.
  1362. void splice(const_iterator p, BOOST_RV_REF(slist) x, const_iterator i) BOOST_NOEXCEPT_OR_NOTHROW
  1363. { this->splice(p, static_cast<slist&>(x), i); }
  1364. //! <b>Requires</b>: p must point to an element contained
  1365. //! by this list. first and last must point to elements contained in list x.
  1366. //!
  1367. //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
  1368. //! before the the element pointed by p. No destructors or copy constructors are called.
  1369. //! this' allocator and x's allocator shall compare equal.
  1370. //!
  1371. //! <b>Throws</b>: Nothing
  1372. //!
  1373. //! <b>Complexity</b>: Linear in distance(begin(), p), in distance(x.begin(), first),
  1374. //! and in distance(first, last).
  1375. //!
  1376. //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
  1377. //! list. Iterators of this list and all the references are not invalidated.
  1378. void splice(const_iterator p, slist& x, const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
  1379. { this->splice_after(this->previous(p), x, this->previous(first), this->previous(last)); }
  1380. //! <b>Requires</b>: p must point to an element contained
  1381. //! by this list. first and last must point to elements contained in list x.
  1382. //! this' allocator and x's allocator shall compare equal
  1383. //!
  1384. //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
  1385. //! before the the element pointed by p. No destructors or copy constructors are called.
  1386. //!
  1387. //! <b>Throws</b>: Nothing
  1388. //!
  1389. //! <b>Complexity</b>: Linear in distance(begin(), p), in distance(x.begin(), first),
  1390. //! and in distance(first, last).
  1391. //!
  1392. //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
  1393. //! list. Iterators of this list and all the references are not invalidated.
  1394. void splice(const_iterator p, BOOST_RV_REF(slist) x, const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
  1395. { this->splice(p, static_cast<slist&>(x), first, last); }
  1396. //! <b>Effects</b>: Returns true if x and y are equal
  1397. //!
  1398. //! <b>Complexity</b>: Linear to the number of elements in the container.
  1399. friend bool operator==(const slist& x, const slist& y)
  1400. { return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); }
  1401. //! <b>Effects</b>: Returns true if x and y are unequal
  1402. //!
  1403. //! <b>Complexity</b>: Linear to the number of elements in the container.
  1404. friend bool operator!=(const slist& x, const slist& y)
  1405. { return !(x == y); }
  1406. //! <b>Effects</b>: Returns true if x is less than y
  1407. //!
  1408. //! <b>Complexity</b>: Linear to the number of elements in the container.
  1409. friend bool operator<(const slist& x, const slist& y)
  1410. { return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
  1411. //! <b>Effects</b>: Returns true if x is greater than y
  1412. //!
  1413. //! <b>Complexity</b>: Linear to the number of elements in the container.
  1414. friend bool operator>(const slist& x, const slist& y)
  1415. { return y < x; }
  1416. //! <b>Effects</b>: Returns true if x is equal or less than y
  1417. //!
  1418. //! <b>Complexity</b>: Linear to the number of elements in the container.
  1419. friend bool operator<=(const slist& x, const slist& y)
  1420. { return !(y < x); }
  1421. //! <b>Effects</b>: Returns true if x is equal or greater than y
  1422. //!
  1423. //! <b>Complexity</b>: Linear to the number of elements in the container.
  1424. friend bool operator>=(const slist& x, const slist& y)
  1425. { return !(x < y); }
  1426. //! <b>Effects</b>: x.swap(y)
  1427. //!
  1428. //! <b>Complexity</b>: Constant.
  1429. friend void swap(slist& x, slist& y)
  1430. { x.swap(y); }
  1431. #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  1432. private:
  1433. void priv_push_front (const T &x)
  1434. { this->insert_after(this->cbefore_begin(), x); }
  1435. void priv_push_front (BOOST_RV_REF(T) x)
  1436. { this->insert_after(this->cbefore_begin(), ::boost::move(x)); }
  1437. bool priv_try_shrink(size_type new_size, const_iterator &last_pos)
  1438. {
  1439. typename Icont::iterator end_n(this->icont().end()), cur(this->icont().before_begin()), cur_next;
  1440. while (++(cur_next = cur) != end_n && new_size > 0){
  1441. --new_size;
  1442. cur = cur_next;
  1443. }
  1444. last_pos = const_iterator(cur);
  1445. if (cur_next != end_n){
  1446. this->erase_after(last_pos, const_iterator(end_n));
  1447. return true;
  1448. }
  1449. else{
  1450. return false;
  1451. }
  1452. }
  1453. template<class U>
  1454. iterator priv_insert(const_iterator p, BOOST_FWD_REF(U) x)
  1455. { return this->insert_after(previous(p), ::boost::forward<U>(x)); }
  1456. template<class U>
  1457. iterator priv_insert_after(const_iterator prev_p, BOOST_FWD_REF(U) x)
  1458. { return iterator(this->icont().insert_after(prev_p.get(), *this->create_node(::boost::forward<U>(x)))); }
  1459. class insertion_functor;
  1460. friend class insertion_functor;
  1461. class insertion_functor
  1462. {
  1463. Icont &icont_;
  1464. typedef typename Icont::iterator iiterator;
  1465. typedef typename Icont::const_iterator iconst_iterator;
  1466. const iconst_iterator prev_;
  1467. iiterator ret_;
  1468. public:
  1469. insertion_functor(Icont &icont, typename Icont::const_iterator prev)
  1470. : icont_(icont), prev_(prev), ret_(prev.unconst())
  1471. {}
  1472. void operator()(Node &n)
  1473. {
  1474. ret_ = this->icont_.insert_after(prev_, n);
  1475. }
  1476. iiterator inserted_first() const
  1477. { return ret_; }
  1478. };
  1479. //Functors for member algorithm defaults
  1480. struct value_less
  1481. {
  1482. bool operator()(const value_type &a, const value_type &b) const
  1483. { return a < b; }
  1484. };
  1485. struct value_equal
  1486. {
  1487. bool operator()(const value_type &a, const value_type &b) const
  1488. { return a == b; }
  1489. };
  1490. struct value_equal_to_this
  1491. {
  1492. explicit value_equal_to_this(const value_type &ref)
  1493. : m_ref(ref){}
  1494. bool operator()(const value_type &val) const
  1495. { return m_ref == val; }
  1496. const value_type &m_ref;
  1497. };
  1498. #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  1499. };
  1500. }}
  1501. #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  1502. namespace boost {
  1503. //!has_trivial_destructor_after_move<> == true_type
  1504. //!specialization for optimizations
  1505. template <class T, class Allocator>
  1506. struct has_trivial_destructor_after_move<boost::container::slist<T, Allocator> >
  1507. {
  1508. typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
  1509. static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
  1510. ::boost::has_trivial_destructor_after_move<pointer>::value;
  1511. };
  1512. namespace container {
  1513. }} //namespace boost{ namespace container {
  1514. #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  1515. // Specialization of insert_iterator so that insertions will be constant
  1516. // time rather than linear time.
  1517. #include <boost/move/detail/std_ns_begin.hpp>
  1518. BOOST_CONTAINER_DOC1ST(namespace std {, BOOST_MOVE_STD_NS_BEG)
  1519. template <class T, class Allocator>
  1520. class insert_iterator<boost::container::slist<T, Allocator> >
  1521. {
  1522. protected:
  1523. typedef boost::container::slist<T, Allocator> Container;
  1524. Container* container;
  1525. typename Container::iterator iter;
  1526. public:
  1527. typedef Container container_type;
  1528. typedef output_iterator_tag iterator_category;
  1529. typedef void value_type;
  1530. typedef void difference_type;
  1531. typedef void pointer;
  1532. typedef void reference;
  1533. insert_iterator(Container& x,
  1534. typename Container::iterator i,
  1535. bool is_previous = false)
  1536. : container(&x), iter(is_previous ? i : x.previous(i)){ }
  1537. insert_iterator<Container>&
  1538. operator=(const typename Container::value_type& value)
  1539. {
  1540. iter = container->insert_after(iter, value);
  1541. return *this;
  1542. }
  1543. insert_iterator<Container>& operator*(){ return *this; }
  1544. insert_iterator<Container>& operator++(){ return *this; }
  1545. insert_iterator<Container>& operator++(int){ return *this; }
  1546. };
  1547. BOOST_CONTAINER_DOC1ST( }, BOOST_MOVE_STD_NS_END)
  1548. #include <boost/move/detail/std_ns_end.hpp>
  1549. #include <boost/container/detail/config_end.hpp>
  1550. #endif // BOOST_CONTAINER_SLIST_HPP