slist.hpp 67 KB

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