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