slist.hpp 62 KB

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