list.hpp 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2005-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. #ifndef BOOST_CONTAINER_LIST_HPP
  10. #define BOOST_CONTAINER_LIST_HPP
  11. #if defined(_MSC_VER)
  12. # pragma once
  13. #endif
  14. #include <boost/container/detail/config_begin.hpp>
  15. #include <boost/container/detail/workaround.hpp>
  16. #include <boost/container/container_fwd.hpp>
  17. #include <boost/container/detail/version_type.hpp>
  18. #include <boost/container/detail/iterators.hpp>
  19. #include <boost/container/detail/mpl.hpp>
  20. #include <boost/container/throw_exception.hpp>
  21. #include <boost/move/utility.hpp>
  22. #include <boost/move/iterator.hpp>
  23. #include <boost/move/detail/move_helpers.hpp>
  24. #include <boost/intrusive/pointer_traits.hpp>
  25. #include <boost/container/detail/utilities.hpp>
  26. #include <boost/container/detail/algorithms.hpp>
  27. #include <boost/type_traits/has_trivial_destructor.hpp>
  28. #include <boost/intrusive/list.hpp>
  29. #include <boost/assert.hpp>
  30. #include <boost/container/detail/node_alloc_holder.hpp>
  31. #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  32. #else
  33. //Preprocessor library to emulate perfect forwarding
  34. #include <boost/container/detail/preprocessor.hpp>
  35. #endif
  36. #include <iterator>
  37. #include <utility>
  38. #include <memory>
  39. #include <functional>
  40. #include <algorithm>
  41. namespace boost {
  42. namespace container {
  43. /// @cond
  44. namespace container_detail {
  45. template<class VoidPointer>
  46. struct list_hook
  47. {
  48. typedef typename container_detail::bi::make_list_base_hook
  49. <container_detail::bi::void_pointer<VoidPointer>, container_detail::bi::link_mode<container_detail::bi::normal_link> >::type type;
  50. };
  51. template <class T, class VoidPointer>
  52. struct list_node
  53. : public list_hook<VoidPointer>::type
  54. {
  55. private:
  56. list_node();
  57. public:
  58. typedef T value_type;
  59. typedef typename list_hook<VoidPointer>::type hook_type;
  60. T m_data;
  61. T &get_data()
  62. { return this->m_data; }
  63. const T &get_data() const
  64. { return this->m_data; }
  65. };
  66. template<class Allocator>
  67. struct intrusive_list_type
  68. {
  69. typedef boost::container::allocator_traits<Allocator> allocator_traits_type;
  70. typedef typename allocator_traits_type::value_type value_type;
  71. typedef typename boost::intrusive::pointer_traits
  72. <typename allocator_traits_type::pointer>::template
  73. rebind_pointer<void>::type
  74. void_pointer;
  75. typedef typename container_detail::list_node
  76. <value_type, void_pointer> node_type;
  77. typedef typename container_detail::bi::make_list
  78. < node_type
  79. , container_detail::bi::base_hook<typename list_hook<void_pointer>::type>
  80. , container_detail::bi::constant_time_size<true>
  81. , container_detail::bi::size_type
  82. <typename allocator_traits_type::size_type>
  83. >::type container_type;
  84. typedef container_type type ;
  85. };
  86. } //namespace container_detail {
  87. /// @endcond
  88. //! A list is a doubly linked list. That is, it is a Sequence that supports both
  89. //! forward and backward traversal, and (amortized) constant time insertion and
  90. //! removal of elements at the beginning or the end, or in the middle. Lists have
  91. //! the important property that insertion and splicing do not invalidate iterators
  92. //! to list elements, and that even removal invalidates only the iterators that point
  93. //! to the elements that are removed. The ordering of iterators may be changed
  94. //! (that is, list<T>::iterator might have a different predecessor or successor
  95. //! after a list operation than it did before), but the iterators themselves will
  96. //! not be invalidated or made to point to different elements unless that invalidation
  97. //! or mutation is explicit.
  98. #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
  99. template <class T, class Allocator = std::allocator<T> >
  100. #else
  101. template <class T, class Allocator>
  102. #endif
  103. class list
  104. : protected container_detail::node_alloc_holder
  105. <Allocator, typename container_detail::intrusive_list_type<Allocator>::type>
  106. {
  107. /// @cond
  108. typedef typename
  109. container_detail::intrusive_list_type<Allocator>::type Icont;
  110. typedef container_detail::node_alloc_holder<Allocator, Icont> AllocHolder;
  111. typedef typename AllocHolder::NodePtr NodePtr;
  112. typedef typename AllocHolder::NodeAlloc NodeAlloc;
  113. typedef typename AllocHolder::ValAlloc ValAlloc;
  114. typedef typename AllocHolder::Node Node;
  115. typedef container_detail::allocator_destroyer<NodeAlloc> Destroyer;
  116. typedef typename AllocHolder::allocator_v1 allocator_v1;
  117. typedef typename AllocHolder::allocator_v2 allocator_v2;
  118. typedef typename AllocHolder::alloc_version alloc_version;
  119. typedef boost::container::allocator_traits<Allocator> allocator_traits_type;
  120. class equal_to_value
  121. {
  122. typedef typename AllocHolder::value_type value_type;
  123. const value_type &t_;
  124. public:
  125. equal_to_value(const value_type &t)
  126. : t_(t)
  127. {}
  128. bool operator()(const value_type &t)const
  129. { return t_ == t; }
  130. };
  131. template<class Pred>
  132. struct ValueCompareToNodeCompare
  133. : Pred
  134. {
  135. ValueCompareToNodeCompare(Pred pred)
  136. : Pred(pred)
  137. {}
  138. bool operator()(const Node &a, const Node &b) const
  139. { return static_cast<const Pred&>(*this)(a.m_data, b.m_data); }
  140. bool operator()(const Node &a) const
  141. { return static_cast<const Pred&>(*this)(a.m_data); }
  142. };
  143. BOOST_COPYABLE_AND_MOVABLE(list)
  144. typedef container_detail::iterator<typename Icont::iterator, false> iterator_impl;
  145. typedef container_detail::iterator<typename Icont::iterator, true> const_iterator_impl;
  146. /// @endcond
  147. public:
  148. //////////////////////////////////////////////
  149. //
  150. // types
  151. //
  152. //////////////////////////////////////////////
  153. typedef T value_type;
  154. typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
  155. typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
  156. typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
  157. typedef typename ::boost::container::allocator_traits<Allocator>::const_reference const_reference;
  158. typedef typename ::boost::container::allocator_traits<Allocator>::size_type size_type;
  159. typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type;
  160. typedef Allocator allocator_type;
  161. typedef BOOST_CONTAINER_IMPDEF(NodeAlloc) stored_allocator_type;
  162. typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator;
  163. typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator;
  164. typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<iterator>) reverse_iterator;
  165. typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<const_iterator>) const_reverse_iterator;
  166. //////////////////////////////////////////////
  167. //
  168. // construct/copy/destroy
  169. //
  170. //////////////////////////////////////////////
  171. //! <b>Effects</b>: Default constructs a list.
  172. //!
  173. //! <b>Throws</b>: If allocator_type's default constructor throws.
  174. //!
  175. //! <b>Complexity</b>: Constant.
  176. list()
  177. : AllocHolder()
  178. {}
  179. //! <b>Effects</b>: Constructs a list taking the allocator as parameter.
  180. //!
  181. //! <b>Throws</b>: Nothing
  182. //!
  183. //! <b>Complexity</b>: Constant.
  184. explicit list(const allocator_type &a) BOOST_CONTAINER_NOEXCEPT
  185. : AllocHolder(a)
  186. {}
  187. //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
  188. //! and inserts n copies of value.
  189. //!
  190. //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
  191. //! throws or T's default or copy constructor throws.
  192. //!
  193. //! <b>Complexity</b>: Linear to n.
  194. explicit list(size_type n)
  195. : AllocHolder(Allocator())
  196. { this->resize(n); }
  197. //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
  198. //! and inserts n copies of value.
  199. //!
  200. //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
  201. //! throws or T's default or copy constructor throws.
  202. //!
  203. //! <b>Complexity</b>: Linear to n.
  204. list(size_type n, const T& value, const Allocator& a = Allocator())
  205. : AllocHolder(a)
  206. { this->insert(this->cbegin(), n, value); }
  207. //! <b>Effects</b>: Copy constructs a list.
  208. //!
  209. //! <b>Postcondition</b>: x == *this.
  210. //!
  211. //! <b>Throws</b>: If allocator_type's default constructor or copy constructor throws.
  212. //!
  213. //! <b>Complexity</b>: Linear to the elements x contains.
  214. list(const list& x)
  215. : AllocHolder(x)
  216. { this->insert(this->cbegin(), x.begin(), x.end()); }
  217. //! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
  218. //!
  219. //! <b>Throws</b>: If allocator_type's copy constructor throws.
  220. //!
  221. //! <b>Complexity</b>: Constant.
  222. list(BOOST_RV_REF(list) x)
  223. : AllocHolder(boost::move(static_cast<AllocHolder&>(x)))
  224. {}
  225. //! <b>Effects</b>: Copy constructs a list using the specified allocator.
  226. //!
  227. //! <b>Postcondition</b>: x == *this.
  228. //!
  229. //! <b>Throws</b>: If allocator_type's default constructor or copy constructor throws.
  230. //!
  231. //! <b>Complexity</b>: Linear to the elements x contains.
  232. list(const list& x, const allocator_type &a)
  233. : AllocHolder(a)
  234. { this->insert(this->cbegin(), x.begin(), x.end()); }
  235. //! <b>Effects</b>: Move constructor sing the specified allocator.
  236. //! Moves mx's resources to *this.
  237. //!
  238. //! <b>Throws</b>: If allocation or value_type's copy constructor throws.
  239. //!
  240. //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
  241. list(BOOST_RV_REF(list) x, const allocator_type &a)
  242. : AllocHolder(a)
  243. {
  244. if(this->node_alloc() == x.node_alloc()){
  245. this->icont().swap(x.icont());
  246. }
  247. else{
  248. this->insert(this->cbegin(), x.begin(), x.end());
  249. }
  250. }
  251. //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
  252. //! and inserts a copy of the range [first, last) in the list.
  253. //!
  254. //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
  255. //! throws or T's constructor taking an dereferenced InIt throws.
  256. //!
  257. //! <b>Complexity</b>: Linear to the range [first, last).
  258. template <class InpIt>
  259. list(InpIt first, InpIt last, const Allocator &a = Allocator())
  260. : AllocHolder(a)
  261. { this->insert(this->cbegin(), first, last); }
  262. //! <b>Effects</b>: Destroys the list. All stored values are destroyed
  263. //! and used memory is deallocated.
  264. //!
  265. //! <b>Throws</b>: Nothing.
  266. //!
  267. //! <b>Complexity</b>: Linear to the number of elements.
  268. ~list() BOOST_CONTAINER_NOEXCEPT
  269. {} //AllocHolder clears the list
  270. //! <b>Effects</b>: Makes *this contain the same elements as x.
  271. //!
  272. //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
  273. //! of each of x's elements.
  274. //!
  275. //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
  276. //!
  277. //! <b>Complexity</b>: Linear to the number of elements in x.
  278. list& operator=(BOOST_COPY_ASSIGN_REF(list) x)
  279. {
  280. if (&x != this){
  281. NodeAlloc &this_alloc = this->node_alloc();
  282. const NodeAlloc &x_alloc = x.node_alloc();
  283. container_detail::bool_<allocator_traits_type::
  284. propagate_on_container_copy_assignment::value> flag;
  285. if(flag && this_alloc != x_alloc){
  286. this->clear();
  287. }
  288. this->AllocHolder::copy_assign_alloc(x);
  289. this->assign(x.begin(), x.end());
  290. }
  291. return *this;
  292. }
  293. //! <b>Effects</b>: Move assignment. All mx's values are transferred to *this.
  294. //!
  295. //! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
  296. //! before the function.
  297. //!
  298. //! <b>Throws</b>: If allocator_type's copy constructor throws.
  299. //!
  300. //! <b>Complexity</b>: Constant.
  301. list& operator=(BOOST_RV_REF(list) x)
  302. {
  303. if (&x != this){
  304. NodeAlloc &this_alloc = this->node_alloc();
  305. NodeAlloc &x_alloc = x.node_alloc();
  306. //If allocators are equal we can just swap pointers
  307. if(this_alloc == x_alloc){
  308. //Destroy and swap pointers
  309. this->clear();
  310. this->icont() = boost::move(x.icont());
  311. //Move allocator if needed
  312. this->AllocHolder::move_assign_alloc(x);
  313. }
  314. //If unequal allocators, then do a one by one move
  315. else{
  316. this->assign( boost::make_move_iterator(x.begin())
  317. , boost::make_move_iterator(x.end()));
  318. }
  319. }
  320. return *this;
  321. }
  322. //! <b>Effects</b>: Assigns the n copies of val to *this.
  323. //!
  324. //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
  325. //!
  326. //! <b>Complexity</b>: Linear to n.
  327. void assign(size_type n, const T& val)
  328. {
  329. typedef constant_iterator<value_type, difference_type> cvalue_iterator;
  330. return this->assign(cvalue_iterator(val, n), cvalue_iterator());
  331. }
  332. //! <b>Effects</b>: Assigns the the range [first, last) to *this.
  333. //!
  334. //! <b>Throws</b>: If memory allocation throws or
  335. //! T's constructor from dereferencing InpIt throws.
  336. //!
  337. //! <b>Complexity</b>: Linear to n.
  338. template <class InpIt>
  339. void assign(InpIt first, InpIt last
  340. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  341. , typename container_detail::enable_if_c
  342. < !container_detail::is_convertible<InpIt, size_type>::value
  343. >::type * = 0
  344. #endif
  345. )
  346. {
  347. iterator first1 = this->begin();
  348. const iterator last1 = this->end();
  349. for ( ; first1 != last1 && first != last; ++first1, ++first)
  350. *first1 = *first;
  351. if (first == last)
  352. this->erase(first1, last1);
  353. else{
  354. this->insert(last1, first, last);
  355. }
  356. }
  357. //! <b>Effects</b>: Returns a copy of the internal allocator.
  358. //!
  359. //! <b>Throws</b>: If allocator's copy constructor throws.
  360. //!
  361. //! <b>Complexity</b>: Constant.
  362. allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
  363. { return allocator_type(this->node_alloc()); }
  364. //! <b>Effects</b>: Returns a reference to the internal allocator.
  365. //!
  366. //! <b>Throws</b>: Nothing
  367. //!
  368. //! <b>Complexity</b>: Constant.
  369. //!
  370. //! <b>Note</b>: Non-standard extension.
  371. stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
  372. { return this->node_alloc(); }
  373. //! <b>Effects</b>: Returns a reference to the internal allocator.
  374. //!
  375. //! <b>Throws</b>: Nothing
  376. //!
  377. //! <b>Complexity</b>: Constant.
  378. //!
  379. //! <b>Note</b>: Non-standard extension.
  380. const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
  381. { return this->node_alloc(); }
  382. //////////////////////////////////////////////
  383. //
  384. // iterators
  385. //
  386. //////////////////////////////////////////////
  387. //! <b>Effects</b>: Returns an iterator to the first element contained in the list.
  388. //!
  389. //! <b>Throws</b>: Nothing.
  390. //!
  391. //! <b>Complexity</b>: Constant.
  392. iterator begin() BOOST_CONTAINER_NOEXCEPT
  393. { return iterator(this->icont().begin()); }
  394. //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
  395. //!
  396. //! <b>Throws</b>: Nothing.
  397. //!
  398. //! <b>Complexity</b>: Constant.
  399. const_iterator begin() const BOOST_CONTAINER_NOEXCEPT
  400. { return this->cbegin(); }
  401. //! <b>Effects</b>: Returns an iterator to the end of the list.
  402. //!
  403. //! <b>Throws</b>: Nothing.
  404. //!
  405. //! <b>Complexity</b>: Constant.
  406. iterator end() BOOST_CONTAINER_NOEXCEPT
  407. { return iterator(this->icont().end()); }
  408. //! <b>Effects</b>: Returns a const_iterator to the end of the list.
  409. //!
  410. //! <b>Throws</b>: Nothing.
  411. //!
  412. //! <b>Complexity</b>: Constant.
  413. const_iterator end() const BOOST_CONTAINER_NOEXCEPT
  414. { return this->cend(); }
  415. //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
  416. //! of the reversed list.
  417. //!
  418. //! <b>Throws</b>: Nothing.
  419. //!
  420. //! <b>Complexity</b>: Constant.
  421. reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT
  422. { return reverse_iterator(end()); }
  423. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
  424. //! of the reversed list.
  425. //!
  426. //! <b>Throws</b>: Nothing.
  427. //!
  428. //! <b>Complexity</b>: Constant.
  429. const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT
  430. { return this->crbegin(); }
  431. //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
  432. //! of the reversed list.
  433. //!
  434. //! <b>Throws</b>: Nothing.
  435. //!
  436. //! <b>Complexity</b>: Constant.
  437. reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT
  438. { return reverse_iterator(begin()); }
  439. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
  440. //! of the reversed list.
  441. //!
  442. //! <b>Throws</b>: Nothing.
  443. //!
  444. //! <b>Complexity</b>: Constant.
  445. const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT
  446. { return this->crend(); }
  447. //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
  448. //!
  449. //! <b>Throws</b>: Nothing.
  450. //!
  451. //! <b>Complexity</b>: Constant.
  452. const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
  453. { return const_iterator(this->non_const_icont().begin()); }
  454. //! <b>Effects</b>: Returns a const_iterator to the end of the list.
  455. //!
  456. //! <b>Throws</b>: Nothing.
  457. //!
  458. //! <b>Complexity</b>: Constant.
  459. const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
  460. { return const_iterator(this->non_const_icont().end()); }
  461. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
  462. //! of the reversed list.
  463. //!
  464. //! <b>Throws</b>: Nothing.
  465. //!
  466. //! <b>Complexity</b>: Constant.
  467. const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT
  468. { return const_reverse_iterator(this->cend()); }
  469. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
  470. //! of the reversed list.
  471. //!
  472. //! <b>Throws</b>: Nothing.
  473. //!
  474. //! <b>Complexity</b>: Constant.
  475. const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT
  476. { return const_reverse_iterator(this->cbegin()); }
  477. //////////////////////////////////////////////
  478. //
  479. // capacity
  480. //
  481. //////////////////////////////////////////////
  482. //! <b>Effects</b>: Returns true if the list contains no elements.
  483. //!
  484. //! <b>Throws</b>: Nothing.
  485. //!
  486. //! <b>Complexity</b>: Constant.
  487. bool empty() const BOOST_CONTAINER_NOEXCEPT
  488. { return !this->size(); }
  489. //! <b>Effects</b>: Returns the number of the elements contained in the list.
  490. //!
  491. //! <b>Throws</b>: Nothing.
  492. //!
  493. //! <b>Complexity</b>: Constant.
  494. size_type size() const BOOST_CONTAINER_NOEXCEPT
  495. { return this->icont().size(); }
  496. //! <b>Effects</b>: Returns the largest possible size of the list.
  497. //!
  498. //! <b>Throws</b>: Nothing.
  499. //!
  500. //! <b>Complexity</b>: Constant.
  501. size_type max_size() const BOOST_CONTAINER_NOEXCEPT
  502. { return AllocHolder::max_size(); }
  503. //! <b>Effects</b>: Inserts or erases elements at the end such that
  504. //! the size becomes n. New elements are value initialized.
  505. //!
  506. //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
  507. //!
  508. //! <b>Complexity</b>: Linear to the difference between size() and new_size.
  509. void resize(size_type new_size)
  510. {
  511. if(!priv_try_shrink(new_size)){
  512. typedef value_init_construct_iterator<value_type, difference_type> value_init_iterator;
  513. this->insert(this->cend(), value_init_iterator(new_size - this->size()), value_init_iterator());
  514. }
  515. }
  516. //! <b>Effects</b>: Inserts or erases elements at the end such that
  517. //! the size becomes n. New elements are copy constructed from x.
  518. //!
  519. //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
  520. //!
  521. //! <b>Complexity</b>: Linear to the difference between size() and new_size.
  522. void resize(size_type new_size, const T& x)
  523. {
  524. if(!priv_try_shrink(new_size)){
  525. this->insert(this->cend(), new_size - this->size(), x);
  526. }
  527. }
  528. //////////////////////////////////////////////
  529. //
  530. // element access
  531. //
  532. //////////////////////////////////////////////
  533. //! <b>Requires</b>: !empty()
  534. //!
  535. //! <b>Effects</b>: Returns a reference to the first element
  536. //! from the beginning of the container.
  537. //!
  538. //! <b>Throws</b>: Nothing.
  539. //!
  540. //! <b>Complexity</b>: Constant.
  541. reference front() BOOST_CONTAINER_NOEXCEPT
  542. { return *this->begin(); }
  543. //! <b>Requires</b>: !empty()
  544. //!
  545. //! <b>Effects</b>: Returns a const reference to the first element
  546. //! from the beginning of the container.
  547. //!
  548. //! <b>Throws</b>: Nothing.
  549. //!
  550. //! <b>Complexity</b>: Constant.
  551. const_reference front() const BOOST_CONTAINER_NOEXCEPT
  552. { return *this->begin(); }
  553. //! <b>Requires</b>: !empty()
  554. //!
  555. //! <b>Effects</b>: Returns a reference to the first element
  556. //! from the beginning of the container.
  557. //!
  558. //! <b>Throws</b>: Nothing.
  559. //!
  560. //! <b>Complexity</b>: Constant.
  561. reference back() BOOST_CONTAINER_NOEXCEPT
  562. { return *(--this->end()); }
  563. //! <b>Requires</b>: !empty()
  564. //!
  565. //! <b>Effects</b>: Returns a const reference to the first element
  566. //! from the beginning of the container.
  567. //!
  568. //! <b>Throws</b>: Nothing.
  569. //!
  570. //! <b>Complexity</b>: Constant.
  571. const_reference back() const BOOST_CONTAINER_NOEXCEPT
  572. { return *(--this->end()); }
  573. //////////////////////////////////////////////
  574. //
  575. // modifiers
  576. //
  577. //////////////////////////////////////////////
  578. #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  579. //! <b>Effects</b>: Inserts an object of type T constructed with
  580. //! std::forward<Args>(args)... in the end of the list.
  581. //!
  582. //! <b>Throws</b>: If memory allocation throws or
  583. //! T's in-place constructor throws.
  584. //!
  585. //! <b>Complexity</b>: Constant
  586. template <class... Args>
  587. void emplace_back(Args&&... args)
  588. { this->emplace(this->cend(), boost::forward<Args>(args)...); }
  589. //! <b>Effects</b>: Inserts an object of type T constructed with
  590. //! std::forward<Args>(args)... in the beginning of the list.
  591. //!
  592. //! <b>Throws</b>: If memory allocation throws or
  593. //! T's in-place constructor throws.
  594. //!
  595. //! <b>Complexity</b>: Constant
  596. template <class... Args>
  597. void emplace_front(Args&&... args)
  598. { this->emplace(this->cbegin(), boost::forward<Args>(args)...); }
  599. //! <b>Effects</b>: Inserts an object of type T constructed with
  600. //! std::forward<Args>(args)... before p.
  601. //!
  602. //! <b>Throws</b>: If memory allocation throws or
  603. //! T's in-place constructor throws.
  604. //!
  605. //! <b>Complexity</b>: Constant
  606. template <class... Args>
  607. iterator emplace(const_iterator p, Args&&... args)
  608. {
  609. NodePtr pnode(AllocHolder::create_node(boost::forward<Args>(args)...));
  610. return iterator(this->icont().insert(p.get(), *pnode));
  611. }
  612. #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
  613. #define BOOST_PP_LOCAL_MACRO(n) \
  614. BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
  615. void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
  616. { \
  617. this->emplace(this->cend() \
  618. BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
  619. } \
  620. \
  621. BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
  622. void emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
  623. { \
  624. this->emplace(this->cbegin() \
  625. BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
  626. } \
  627. \
  628. BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
  629. iterator emplace(const_iterator p \
  630. BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
  631. { \
  632. NodePtr pnode (AllocHolder::create_node \
  633. (BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
  634. return iterator(this->icont().insert(p.get(), *pnode)); \
  635. } \
  636. //!
  637. #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
  638. #include BOOST_PP_LOCAL_ITERATE()
  639. #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
  640. #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  641. //! <b>Effects</b>: Inserts a copy of x at the beginning of the list.
  642. //!
  643. //! <b>Throws</b>: If memory allocation throws or
  644. //! T's copy constructor throws.
  645. //!
  646. //! <b>Complexity</b>: Amortized constant time.
  647. void push_front(const T &x);
  648. //! <b>Effects</b>: Constructs a new element in the beginning of the list
  649. //! and moves the resources of mx to this new element.
  650. //!
  651. //! <b>Throws</b>: If memory allocation throws.
  652. //!
  653. //! <b>Complexity</b>: Amortized constant time.
  654. void push_front(T &&x);
  655. #else
  656. BOOST_MOVE_CONVERSION_AWARE_CATCH(push_front, T, void, priv_push_front)
  657. #endif
  658. #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  659. //! <b>Effects</b>: Inserts a copy of x at the end of the list.
  660. //!
  661. //! <b>Throws</b>: If memory allocation throws or
  662. //! T's copy constructor throws.
  663. //!
  664. //! <b>Complexity</b>: Amortized constant time.
  665. void push_back(const T &x);
  666. //! <b>Effects</b>: Constructs a new element in the end of the list
  667. //! and moves the resources of mx to this new element.
  668. //!
  669. //! <b>Throws</b>: If memory allocation throws.
  670. //!
  671. //! <b>Complexity</b>: Amortized constant time.
  672. void push_back(T &&x);
  673. #else
  674. BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back)
  675. #endif
  676. #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  677. //! <b>Requires</b>: position must be a valid iterator of *this.
  678. //!
  679. //! <b>Effects</b>: Insert a copy of x before position.
  680. //!
  681. //! <b>Returns</b>: an iterator to the inserted element.
  682. //!
  683. //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
  684. //!
  685. //! <b>Complexity</b>: Amortized constant time.
  686. iterator insert(const_iterator position, const T &x);
  687. //! <b>Requires</b>: position must be a valid iterator of *this.
  688. //!
  689. //! <b>Effects</b>: Insert a new element before position with mx's resources.
  690. //!
  691. //! <b>Returns</b>: an iterator to the inserted element.
  692. //!
  693. //! <b>Throws</b>: If memory allocation throws.
  694. //!
  695. //! <b>Complexity</b>: Amortized constant time.
  696. iterator insert(const_iterator position, T &&x);
  697. #else
  698. BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator, const_iterator)
  699. #endif
  700. //! <b>Requires</b>: p must be a valid iterator of *this.
  701. //!
  702. //! <b>Effects</b>: Inserts n copies of x before p.
  703. //!
  704. //! <b>Returns</b>: an iterator to the first inserted element or p if n is 0.
  705. //!
  706. //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
  707. //!
  708. //! <b>Complexity</b>: Linear to n.
  709. iterator insert(const_iterator p, size_type n, const T& x)
  710. {
  711. typedef constant_iterator<value_type, difference_type> cvalue_iterator;
  712. return this->insert(p, cvalue_iterator(x, n), cvalue_iterator());
  713. }
  714. //! <b>Requires</b>: p must be a valid iterator of *this.
  715. //!
  716. //! <b>Effects</b>: Insert a copy of the [first, last) range before p.
  717. //!
  718. //! <b>Returns</b>: an iterator to the first inserted element or p if first == last.
  719. //!
  720. //! <b>Throws</b>: If memory allocation throws, T's constructor from a
  721. //! dereferenced InpIt throws.
  722. //!
  723. //! <b>Complexity</b>: Linear to std::distance [first, last).
  724. template <class InpIt>
  725. iterator insert(const_iterator p, InpIt first, InpIt last
  726. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  727. , typename container_detail::enable_if_c
  728. < !container_detail::is_convertible<InpIt, size_type>::value
  729. && (container_detail::is_input_iterator<InpIt>::value
  730. || container_detail::is_same<alloc_version, allocator_v1>::value
  731. )
  732. >::type * = 0
  733. #endif
  734. )
  735. {
  736. const typename Icont::iterator ipos(p.get());
  737. iterator ret_it(ipos);
  738. if(first != last){
  739. ret_it = iterator(this->icont().insert(ipos, *this->create_node_from_it(first)));
  740. ++first;
  741. }
  742. for (; first != last; ++first){
  743. this->icont().insert(ipos, *this->create_node_from_it(first));
  744. }
  745. return ret_it;
  746. }
  747. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  748. template <class FwdIt>
  749. iterator insert(const_iterator p, FwdIt first, FwdIt last
  750. , typename container_detail::enable_if_c
  751. < !container_detail::is_convertible<FwdIt, size_type>::value
  752. && !(container_detail::is_input_iterator<FwdIt>::value
  753. || container_detail::is_same<alloc_version, allocator_v1>::value
  754. )
  755. >::type * = 0
  756. )
  757. {
  758. //Optimized allocation and construction
  759. insertion_functor func(this->icont(), p.get());
  760. iterator before_p(p.get());
  761. --before_p;
  762. this->allocate_many_and_construct(first, std::distance(first, last), func);
  763. return ++before_p;
  764. }
  765. #endif
  766. //! <b>Effects</b>: Removes the first element from the list.
  767. //!
  768. //! <b>Throws</b>: Nothing.
  769. //!
  770. //! <b>Complexity</b>: Amortized constant time.
  771. void pop_front() BOOST_CONTAINER_NOEXCEPT
  772. { this->erase(this->cbegin()); }
  773. //! <b>Effects</b>: Removes the last element from the list.
  774. //!
  775. //! <b>Throws</b>: Nothing.
  776. //!
  777. //! <b>Complexity</b>: Amortized constant time.
  778. void pop_back() BOOST_CONTAINER_NOEXCEPT
  779. { const_iterator tmp = this->cend(); this->erase(--tmp); }
  780. //! <b>Requires</b>: p must be a valid iterator of *this.
  781. //!
  782. //! <b>Effects</b>: Erases the element at p p.
  783. //!
  784. //! <b>Throws</b>: Nothing.
  785. //!
  786. //! <b>Complexity</b>: Amortized constant time.
  787. iterator erase(const_iterator p) BOOST_CONTAINER_NOEXCEPT
  788. { return iterator(this->icont().erase_and_dispose(p.get(), Destroyer(this->node_alloc()))); }
  789. //! <b>Requires</b>: first and last must be valid iterator to elements in *this.
  790. //!
  791. //! <b>Effects</b>: Erases the elements pointed by [first, last).
  792. //!
  793. //! <b>Throws</b>: Nothing.
  794. //!
  795. //! <b>Complexity</b>: Linear to the distance between first and last.
  796. iterator erase(const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
  797. { return iterator(AllocHolder::erase_range(first.get(), last.get(), alloc_version())); }
  798. //! <b>Effects</b>: Swaps the contents of *this and x.
  799. //!
  800. //! <b>Throws</b>: Nothing.
  801. //!
  802. //! <b>Complexity</b>: Constant.
  803. void swap(list& x)
  804. { AllocHolder::swap(x); }
  805. //! <b>Effects</b>: Erases all the elements of the list.
  806. //!
  807. //! <b>Throws</b>: Nothing.
  808. //!
  809. //! <b>Complexity</b>: Linear to the number of elements in the list.
  810. void clear() BOOST_CONTAINER_NOEXCEPT
  811. { AllocHolder::clear(alloc_version()); }
  812. //////////////////////////////////////////////
  813. //
  814. // slist operations
  815. //
  816. //////////////////////////////////////////////
  817. //! <b>Requires</b>: p must point to an element contained
  818. //! by the list. x != *this. this' allocator and x's allocator shall compare equal
  819. //!
  820. //! <b>Effects</b>: Transfers all the elements of list x to this list, before the
  821. //! the element pointed by p. No destructors or copy constructors are called.
  822. //!
  823. //! <b>Throws</b>: Nothing
  824. //!
  825. //! <b>Complexity</b>: Constant.
  826. //!
  827. //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
  828. //! this list. Iterators of this list and all the references are not invalidated.
  829. void splice(const_iterator p, list& x) BOOST_CONTAINER_NOEXCEPT
  830. {
  831. BOOST_ASSERT(this != &x);
  832. BOOST_ASSERT(this->node_alloc() == x.node_alloc());
  833. this->icont().splice(p.get(), x.icont());
  834. }
  835. //! <b>Requires</b>: p must point to an element contained
  836. //! by the list. x != *this. this' allocator and x's allocator shall compare equal
  837. //!
  838. //! <b>Effects</b>: Transfers all the elements of list x to this list, before the
  839. //! the element pointed by p. No destructors or copy constructors are called.
  840. //!
  841. //! <b>Throws</b>: Nothing
  842. //!
  843. //! <b>Complexity</b>: Constant.
  844. //!
  845. //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
  846. //! this list. Iterators of this list and all the references are not invalidated.
  847. void splice(const_iterator p, BOOST_RV_REF(list) x) BOOST_CONTAINER_NOEXCEPT
  848. { this->splice(p, static_cast<list&>(x)); }
  849. //! <b>Requires</b>: p must point to an element contained
  850. //! by this list. i must point to an element contained in list x.
  851. //! this' allocator and x's allocator shall compare equal
  852. //!
  853. //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
  854. //! before the the element pointed by p. No destructors or copy constructors are called.
  855. //! If p == i or p == ++i, this function is a null operation.
  856. //!
  857. //! <b>Throws</b>: Nothing
  858. //!
  859. //! <b>Complexity</b>: Constant.
  860. //!
  861. //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
  862. //! list. Iterators of this list and all the references are not invalidated.
  863. void splice(const_iterator p, list &x, const_iterator i) BOOST_CONTAINER_NOEXCEPT
  864. {
  865. //BOOST_ASSERT(this != &x);
  866. BOOST_ASSERT(this->node_alloc() == x.node_alloc());
  867. this->icont().splice(p.get(), x.icont(), i.get());
  868. }
  869. //! <b>Requires</b>: p must point to an element contained
  870. //! by this list. i must point to an element contained in list x.
  871. //! this' allocator and x's allocator shall compare equal.
  872. //!
  873. //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
  874. //! before the the element pointed by p. No destructors or copy constructors are called.
  875. //! If p == i or p == ++i, this function is a null operation.
  876. //!
  877. //! <b>Throws</b>: Nothing
  878. //!
  879. //! <b>Complexity</b>: Constant.
  880. //!
  881. //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
  882. //! list. Iterators of this list and all the references are not invalidated.
  883. void splice(const_iterator p, BOOST_RV_REF(list) x, const_iterator i) BOOST_CONTAINER_NOEXCEPT
  884. { this->splice(p, static_cast<list&>(x), i); }
  885. //! <b>Requires</b>: p must point to an element contained
  886. //! by this list. first and last must point to elements contained in list x.
  887. //! this' allocator and x's allocator shall compare equal
  888. //!
  889. //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
  890. //! before the the element pointed by p. No destructors or copy constructors are called.
  891. //!
  892. //! <b>Throws</b>: Nothing
  893. //!
  894. //! <b>Complexity</b>: Linear to the number of elements transferred.
  895. //!
  896. //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
  897. //! list. Iterators of this list and all the references are not invalidated.
  898. void splice(const_iterator p, list &x, const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
  899. {
  900. BOOST_ASSERT(this->node_alloc() == x.node_alloc());
  901. this->icont().splice(p.get(), x.icont(), first.get(), last.get());
  902. }
  903. //! <b>Requires</b>: p must point to an element contained
  904. //! by this list. first and last must point to elements contained in list x.
  905. //! this' allocator and x's allocator shall compare equal.
  906. //!
  907. //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
  908. //! before the the element pointed by p. No destructors or copy constructors are called.
  909. //!
  910. //! <b>Throws</b>: Nothing
  911. //!
  912. //! <b>Complexity</b>: Linear to the number of elements transferred.
  913. //!
  914. //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
  915. //! list. Iterators of this list and all the references are not invalidated.
  916. void splice(const_iterator p, BOOST_RV_REF(list) x, const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
  917. { this->splice(p, static_cast<list&>(x), first, last); }
  918. //! <b>Requires</b>: p must point to an element contained
  919. //! by this list. first and last must point to elements contained in list x.
  920. //! n == std::distance(first, last). this' allocator and x's allocator shall compare equal
  921. //!
  922. //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
  923. //! before the the element pointed by p. No destructors or copy constructors are called.
  924. //!
  925. //! <b>Throws</b>: Nothing
  926. //!
  927. //! <b>Complexity</b>: Constant.
  928. //!
  929. //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
  930. //! list. Iterators of this list and all the references are not invalidated.
  931. //!
  932. //! <b>Note</b>: Non-standard extension
  933. void splice(const_iterator p, list &x, const_iterator first, const_iterator last, size_type n) BOOST_CONTAINER_NOEXCEPT
  934. {
  935. BOOST_ASSERT(this->node_alloc() == x.node_alloc());
  936. this->icont().splice(p.get(), x.icont(), first.get(), last.get(), n);
  937. }
  938. //! <b>Requires</b>: p must point to an element contained
  939. //! by this list. first and last must point to elements contained in list x.
  940. //! n == std::distance(first, last). this' allocator and x's allocator shall compare equal
  941. //!
  942. //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
  943. //! before the the element pointed by p. No destructors or copy constructors are called.
  944. //!
  945. //! <b>Throws</b>: Nothing
  946. //!
  947. //! <b>Complexity</b>: Constant.
  948. //!
  949. //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
  950. //! list. Iterators of this list and all the references are not invalidated.
  951. //!
  952. //! <b>Note</b>: Non-standard extension
  953. void splice(const_iterator p, BOOST_RV_REF(list) x, const_iterator first, const_iterator last, size_type n) BOOST_CONTAINER_NOEXCEPT
  954. { this->splice(p, static_cast<list&>(x), first, last, n); }
  955. //! <b>Effects</b>: Removes all the elements that compare equal to value.
  956. //!
  957. //! <b>Throws</b>: If comparison throws.
  958. //!
  959. //! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality.
  960. //!
  961. //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
  962. //! and iterators to elements that are not removed remain valid.
  963. void remove(const T& value)
  964. { this->remove_if(equal_to_value(value)); }
  965. //! <b>Effects</b>: Removes all the elements for which a specified
  966. //! predicate is satisfied.
  967. //!
  968. //! <b>Throws</b>: If pred throws.
  969. //!
  970. //! <b>Complexity</b>: Linear time. It performs exactly size() calls to the predicate.
  971. //!
  972. //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
  973. //! and iterators to elements that are not removed remain valid.
  974. template <class Pred>
  975. void remove_if(Pred pred)
  976. {
  977. typedef ValueCompareToNodeCompare<Pred> Predicate;
  978. this->icont().remove_and_dispose_if(Predicate(pred), Destroyer(this->node_alloc()));
  979. }
  980. //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
  981. //! elements that are equal from the list.
  982. //!
  983. //! <b>Throws</b>: If comparison throws.
  984. //!
  985. //! <b>Complexity</b>: Linear time (size()-1 comparisons equality comparisons).
  986. //!
  987. //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
  988. //! and iterators to elements that are not removed remain valid.
  989. void unique()
  990. { this->unique(value_equal()); }
  991. //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
  992. //! elements that satisfy some binary predicate from the list.
  993. //!
  994. //! <b>Throws</b>: If pred throws.
  995. //!
  996. //! <b>Complexity</b>: Linear time (size()-1 comparisons calls to pred()).
  997. //!
  998. //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
  999. //! and iterators to elements that are not removed remain valid.
  1000. template <class BinaryPredicate>
  1001. void unique(BinaryPredicate binary_pred)
  1002. {
  1003. typedef ValueCompareToNodeCompare<BinaryPredicate> Predicate;
  1004. this->icont().unique_and_dispose(Predicate(binary_pred), Destroyer(this->node_alloc()));
  1005. }
  1006. //! <b>Requires</b>: The lists x and *this must be distinct.
  1007. //!
  1008. //! <b>Effects</b>: This function removes all of x's elements and inserts them
  1009. //! in order into *this according to std::less<value_type>. The merge is stable;
  1010. //! that is, if an element from *this is equivalent to one from x, then the element
  1011. //! from *this will precede the one from x.
  1012. //!
  1013. //! <b>Throws</b>: If comparison throws.
  1014. //!
  1015. //! <b>Complexity</b>: This function is linear time: it performs at most
  1016. //! size() + x.size() - 1 comparisons.
  1017. void merge(list &x)
  1018. { this->merge(x, value_less()); }
  1019. //! <b>Requires</b>: The lists x and *this must be distinct.
  1020. //!
  1021. //! <b>Effects</b>: This function removes all of x's elements and inserts them
  1022. //! in order into *this according to std::less<value_type>. The merge is stable;
  1023. //! that is, if an element from *this is equivalent to one from x, then the element
  1024. //! from *this will precede the one from x.
  1025. //!
  1026. //! <b>Throws</b>: If comparison throws.
  1027. //!
  1028. //! <b>Complexity</b>: This function is linear time: it performs at most
  1029. //! size() + x.size() - 1 comparisons.
  1030. void merge(BOOST_RV_REF(list) x)
  1031. { this->merge(static_cast<list&>(x)); }
  1032. //! <b>Requires</b>: p must be a comparison function that induces a strict weak
  1033. //! ordering and both *this and x must be sorted according to that ordering
  1034. //! The lists x and *this must be distinct.
  1035. //!
  1036. //! <b>Effects</b>: This function removes all of x's elements and inserts them
  1037. //! in order into *this. The merge is stable; that is, if an element from *this is
  1038. //! equivalent to one from x, then the element from *this will precede the one from x.
  1039. //!
  1040. //! <b>Throws</b>: If comp throws.
  1041. //!
  1042. //! <b>Complexity</b>: This function is linear time: it performs at most
  1043. //! size() + x.size() - 1 comparisons.
  1044. //!
  1045. //! <b>Note</b>: Iterators and references to *this are not invalidated.
  1046. template <class StrictWeakOrdering>
  1047. void merge(list &x, const StrictWeakOrdering &comp)
  1048. {
  1049. BOOST_ASSERT(this->node_alloc() == x.node_alloc());
  1050. this->icont().merge(x.icont(),
  1051. ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
  1052. }
  1053. //! <b>Requires</b>: p must be a comparison function that induces a strict weak
  1054. //! ordering and both *this and x must be sorted according to that ordering
  1055. //! The lists x and *this must be distinct.
  1056. //!
  1057. //! <b>Effects</b>: This function removes all of x's elements and inserts them
  1058. //! in order into *this. The merge is stable; that is, if an element from *this is
  1059. //! equivalent to one from x, then the element from *this will precede the one from x.
  1060. //!
  1061. //! <b>Throws</b>: If comp throws.
  1062. //!
  1063. //! <b>Complexity</b>: This function is linear time: it performs at most
  1064. //! size() + x.size() - 1 comparisons.
  1065. //!
  1066. //! <b>Note</b>: Iterators and references to *this are not invalidated.
  1067. template <class StrictWeakOrdering>
  1068. void merge(BOOST_RV_REF(list) x, StrictWeakOrdering comp)
  1069. { this->merge(static_cast<list&>(x), comp); }
  1070. //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
  1071. //! The sort is stable, that is, the relative order of equivalent elements is preserved.
  1072. //!
  1073. //! <b>Throws</b>: If comparison throws.
  1074. //!
  1075. //! <b>Notes</b>: Iterators and references are not invalidated.
  1076. //!
  1077. //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N
  1078. //! is the list's size.
  1079. void sort()
  1080. { this->sort(value_less()); }
  1081. //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
  1082. //! The sort is stable, that is, the relative order of equivalent elements is preserved.
  1083. //!
  1084. //! <b>Throws</b>: If comp throws.
  1085. //!
  1086. //! <b>Notes</b>: Iterators and references are not invalidated.
  1087. //!
  1088. //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N
  1089. //! is the list's size.
  1090. template <class StrictWeakOrdering>
  1091. void sort(StrictWeakOrdering comp)
  1092. {
  1093. // nothing if the list has length 0 or 1.
  1094. if (this->size() < 2)
  1095. return;
  1096. this->icont().sort(ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
  1097. }
  1098. //! <b>Effects</b>: Reverses the order of elements in the list.
  1099. //!
  1100. //! <b>Throws</b>: Nothing.
  1101. //!
  1102. //! <b>Complexity</b>: This function is linear time.
  1103. //!
  1104. //! <b>Note</b>: Iterators and references are not invalidated
  1105. void reverse() BOOST_CONTAINER_NOEXCEPT
  1106. { this->icont().reverse(); }
  1107. /// @cond
  1108. private:
  1109. bool priv_try_shrink(size_type new_size)
  1110. {
  1111. const size_type len = this->size();
  1112. if(len > new_size){
  1113. const const_iterator iend = this->cend();
  1114. size_type to_erase = len - new_size;
  1115. const_iterator ifirst;
  1116. if(to_erase < len/2u){
  1117. ifirst = iend;
  1118. while(to_erase--){
  1119. --ifirst;
  1120. }
  1121. }
  1122. else{
  1123. ifirst = this->cbegin();
  1124. size_type to_skip = len - to_erase;
  1125. while(to_skip--){
  1126. ++ifirst;
  1127. }
  1128. }
  1129. this->erase(ifirst, iend);
  1130. return true;
  1131. }
  1132. else{
  1133. return false;
  1134. }
  1135. }
  1136. iterator priv_insert(const_iterator p, const T &x)
  1137. {
  1138. NodePtr tmp = AllocHolder::create_node(x);
  1139. return iterator(this->icont().insert(p.get(), *tmp));
  1140. }
  1141. iterator priv_insert(const_iterator p, BOOST_RV_REF(T) x)
  1142. {
  1143. NodePtr tmp = AllocHolder::create_node(boost::move(x));
  1144. return iterator(this->icont().insert(p.get(), *tmp));
  1145. }
  1146. void priv_push_back (const T &x)
  1147. { this->insert(this->cend(), x); }
  1148. void priv_push_back (BOOST_RV_REF(T) x)
  1149. { this->insert(this->cend(), boost::move(x)); }
  1150. void priv_push_front (const T &x)
  1151. { this->insert(this->cbegin(), x); }
  1152. void priv_push_front (BOOST_RV_REF(T) x)
  1153. { this->insert(this->cbegin(), boost::move(x)); }
  1154. class insertion_functor;
  1155. friend class insertion_functor;
  1156. class insertion_functor
  1157. {
  1158. Icont &icont_;
  1159. typedef typename Icont::const_iterator iconst_iterator;
  1160. const iconst_iterator pos_;
  1161. public:
  1162. insertion_functor(Icont &icont, typename Icont::const_iterator pos)
  1163. : icont_(icont), pos_(pos)
  1164. {}
  1165. void operator()(Node &n)
  1166. {
  1167. this->icont_.insert(pos_, n);
  1168. }
  1169. };
  1170. //Functors for member algorithm defaults
  1171. struct value_less
  1172. {
  1173. bool operator()(const value_type &a, const value_type &b) const
  1174. { return a < b; }
  1175. };
  1176. struct value_equal
  1177. {
  1178. bool operator()(const value_type &a, const value_type &b) const
  1179. { return a == b; }
  1180. };
  1181. /// @endcond
  1182. };
  1183. template <class T, class Allocator>
  1184. inline bool operator==(const list<T,Allocator>& x, const list<T,Allocator>& y)
  1185. {
  1186. if(x.size() != y.size()){
  1187. return false;
  1188. }
  1189. typedef typename list<T,Allocator>::const_iterator const_iterator;
  1190. const_iterator end1 = x.end();
  1191. const_iterator i1 = x.begin();
  1192. const_iterator i2 = y.begin();
  1193. while (i1 != end1 && *i1 == *i2) {
  1194. ++i1;
  1195. ++i2;
  1196. }
  1197. return i1 == end1;
  1198. }
  1199. template <class T, class Allocator>
  1200. inline bool operator<(const list<T,Allocator>& x,
  1201. const list<T,Allocator>& y)
  1202. {
  1203. return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
  1204. }
  1205. template <class T, class Allocator>
  1206. inline bool operator!=(const list<T,Allocator>& x, const list<T,Allocator>& y)
  1207. {
  1208. return !(x == y);
  1209. }
  1210. template <class T, class Allocator>
  1211. inline bool operator>(const list<T,Allocator>& x, const list<T,Allocator>& y)
  1212. {
  1213. return y < x;
  1214. }
  1215. template <class T, class Allocator>
  1216. inline bool operator<=(const list<T,Allocator>& x, const list<T,Allocator>& y)
  1217. {
  1218. return !(y < x);
  1219. }
  1220. template <class T, class Allocator>
  1221. inline bool operator>=(const list<T,Allocator>& x, const list<T,Allocator>& y)
  1222. {
  1223. return !(x < y);
  1224. }
  1225. template <class T, class Allocator>
  1226. inline void swap(list<T, Allocator>& x, list<T, Allocator>& y)
  1227. {
  1228. x.swap(y);
  1229. }
  1230. /// @cond
  1231. } //namespace container {
  1232. //!has_trivial_destructor_after_move<> == true_type
  1233. //!specialization for optimizations
  1234. template <class T, class Allocator>
  1235. struct has_trivial_destructor_after_move<boost::container::list<T, Allocator> >
  1236. : public ::boost::has_trivial_destructor_after_move<Allocator>
  1237. {};
  1238. namespace container {
  1239. /// @endcond
  1240. }}
  1241. #include <boost/container/detail/config_end.hpp>
  1242. #endif // BOOST_CONTAINER_LIST_HPP