treap.hpp 57 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371
  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2008-2013
  4. //
  5. // Distributed under the Boost Software License, Version 1.0.
  6. // (See accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //
  9. // See http://www.boost.org/libs/intrusive for documentation.
  10. //
  11. /////////////////////////////////////////////////////////////////////////////
  12. #ifndef BOOST_INTRUSIVE_TREAP_HPP
  13. #define BOOST_INTRUSIVE_TREAP_HPP
  14. #include <boost/intrusive/detail/config_begin.hpp>
  15. #include <boost/intrusive/intrusive_fwd.hpp>
  16. #include <boost/intrusive/detail/assert.hpp>
  17. #include <boost/intrusive/bs_set_hook.hpp>
  18. #include <boost/intrusive/bstree.hpp>
  19. #include <boost/intrusive/detail/tree_node.hpp>
  20. #include <boost/intrusive/detail/ebo_functor_holder.hpp>
  21. #include <boost/intrusive/pointer_traits.hpp>
  22. #include <boost/intrusive/detail/get_value_traits.hpp>
  23. #include <boost/intrusive/detail/mpl.hpp>
  24. #include <boost/intrusive/treap_algorithms.hpp>
  25. #include <boost/intrusive/link_mode.hpp>
  26. #include <boost/intrusive/priority_compare.hpp>
  27. #include <boost/intrusive/detail/node_cloner_disposer.hpp>
  28. #include <boost/intrusive/detail/key_nodeptr_comp.hpp>
  29. #include <boost/static_assert.hpp>
  30. #include <boost/move/utility_core.hpp>
  31. #include <boost/move/adl_move_swap.hpp>
  32. #include <cstddef>
  33. #include <boost/intrusive/detail/minimal_less_equal_header.hpp>
  34. #include <boost/intrusive/detail/minimal_pair_header.hpp> //std::pair
  35. #if defined(BOOST_HAS_PRAGMA_ONCE)
  36. # pragma once
  37. #endif
  38. namespace boost {
  39. namespace intrusive {
  40. /// @cond
  41. struct treap_defaults
  42. : bstree_defaults
  43. {
  44. typedef void priority;
  45. typedef void priority_of_value;
  46. };
  47. template<class ValuePtr, class VoidOrPrioOfValue, class VoidOrPrioComp>
  48. struct treap_prio_types
  49. {
  50. typedef typename
  51. boost::movelib::pointer_element<ValuePtr>::type value_type;
  52. typedef typename get_key_of_value
  53. < VoidOrPrioOfValue, value_type>::type priority_of_value;
  54. typedef typename priority_of_value::type priority_type;
  55. typedef typename get_prio_comp< VoidOrPrioComp
  56. , priority_type
  57. >::type priority_compare;
  58. };
  59. struct treap_tag;
  60. /// @endcond
  61. //! The class template treap is an intrusive treap container that
  62. //! is used to construct intrusive set and multiset containers. The no-throw
  63. //! guarantee holds only, if the key_compare object and priority_compare object
  64. //! don't throw.
  65. //!
  66. //! The template parameter \c T is the type to be managed by the container.
  67. //! The user can specify additional options and if no options are provided
  68. //! default options are used.
  69. //!
  70. //! The container supports the following options:
  71. //! \c base_hook<>/member_hook<>/value_traits<>,
  72. //! \c constant_time_size<>, \c size_type<>,
  73. //! \c compare<>, \c priority<> and \c priority_of_value<>
  74. #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
  75. template<class T, class ...Options>
  76. #else
  77. template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, class VoidOrPrioOfValue, class VoidOrPrioComp, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
  78. #endif
  79. class treap_impl
  80. /// @cond
  81. : public bstree_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType, ConstantTimeSize, BsTreeAlgorithms, HeaderHolder>
  82. //Use public inheritance to avoid MSVC bugs with closures
  83. , public detail::ebo_functor_holder
  84. < typename treap_prio_types<typename ValueTraits::pointer, VoidOrPrioOfValue, VoidOrPrioComp>::priority_compare
  85. , treap_tag>
  86. /// @endcond
  87. {
  88. public:
  89. typedef ValueTraits value_traits;
  90. /// @cond
  91. typedef bstree_impl< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType
  92. , ConstantTimeSize, BsTreeAlgorithms
  93. , HeaderHolder> tree_type;
  94. typedef tree_type implementation_defined;
  95. typedef treap_prio_types
  96. < typename ValueTraits::pointer
  97. , VoidOrPrioOfValue, VoidOrPrioComp> treap_prio_types_t;
  98. typedef detail::ebo_functor_holder
  99. <typename treap_prio_types_t::priority_compare, treap_tag> prio_base;
  100. /// @endcond
  101. typedef typename implementation_defined::pointer pointer;
  102. typedef typename implementation_defined::const_pointer const_pointer;
  103. typedef typename implementation_defined::value_type value_type;
  104. typedef typename implementation_defined::key_type key_type;
  105. typedef typename implementation_defined::key_of_value key_of_value;
  106. typedef typename implementation_defined::reference reference;
  107. typedef typename implementation_defined::const_reference const_reference;
  108. typedef typename implementation_defined::difference_type difference_type;
  109. typedef typename implementation_defined::size_type size_type;
  110. typedef typename implementation_defined::value_compare value_compare;
  111. typedef typename implementation_defined::key_compare key_compare;
  112. typedef typename implementation_defined::iterator iterator;
  113. typedef typename implementation_defined::const_iterator const_iterator;
  114. typedef typename implementation_defined::reverse_iterator reverse_iterator;
  115. typedef typename implementation_defined::const_reverse_iterator const_reverse_iterator;
  116. typedef typename implementation_defined::node_traits node_traits;
  117. typedef typename implementation_defined::node node;
  118. typedef typename implementation_defined::node_ptr node_ptr;
  119. typedef typename implementation_defined::const_node_ptr const_node_ptr;
  120. typedef BOOST_INTRUSIVE_IMPDEF(treap_algorithms<node_traits>) node_algorithms;
  121. typedef BOOST_INTRUSIVE_IMPDEF
  122. (typename treap_prio_types_t::priority_type) priority_type;
  123. typedef BOOST_INTRUSIVE_IMPDEF
  124. (typename treap_prio_types_t::priority_of_value) priority_of_value;
  125. typedef BOOST_INTRUSIVE_IMPDEF
  126. (typename treap_prio_types_t::priority_compare) priority_compare;
  127. static const bool constant_time_size = implementation_defined::constant_time_size;
  128. static const bool stateful_value_traits = implementation_defined::stateful_value_traits;
  129. static const bool safemode_or_autounlink = is_safe_autounlink<value_traits::link_mode>::value;
  130. typedef detail::key_nodeptr_comp<priority_compare, value_traits, priority_of_value> prio_node_prio_comp_t;
  131. template<class PrioPrioComp>
  132. detail::key_nodeptr_comp<PrioPrioComp, value_traits, priority_of_value> prio_node_prio_comp(PrioPrioComp priopriocomp) const
  133. { return detail::key_nodeptr_comp<PrioPrioComp, value_traits, priority_of_value>(priopriocomp, &this->get_value_traits()); }
  134. /// @cond
  135. private:
  136. //noncopyable
  137. BOOST_MOVABLE_BUT_NOT_COPYABLE(treap_impl)
  138. const priority_compare &priv_pcomp() const
  139. { return static_cast<const prio_base&>(*this).get(); }
  140. priority_compare &priv_pcomp()
  141. { return static_cast<prio_base&>(*this).get(); }
  142. /// @endcond
  143. public:
  144. typedef typename node_algorithms::insert_commit_data insert_commit_data;
  145. //! <b>Effects</b>: Constructs an empty container.
  146. //!
  147. //! <b>Complexity</b>: Constant.
  148. //!
  149. //! <b>Throws</b>: If value_traits::node_traits::node
  150. //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
  151. //! or the copy constructor of the value_compare/priority_compare objects throw. Basic guarantee.
  152. treap_impl()
  153. : tree_type(), prio_base()
  154. {}
  155. //! <b>Effects</b>: Constructs an empty container.
  156. //!
  157. //! <b>Complexity</b>: Constant.
  158. //!
  159. //! <b>Throws</b>: If value_traits::node_traits::node
  160. //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
  161. //! or the copy constructor of the value_compare/priority_compare objects throw. Basic guarantee.
  162. explicit treap_impl( const key_compare &cmp
  163. , const priority_compare &pcmp = priority_compare()
  164. , const value_traits &v_traits = value_traits())
  165. : tree_type(cmp, v_traits), prio_base(pcmp)
  166. {}
  167. //! <b>Requires</b>: Dereferencing iterator must yield an lvalue of type value_type.
  168. //! cmp must be a comparison function that induces a strict weak ordering.
  169. //!
  170. //! <b>Effects</b>: Constructs an empty container and inserts elements from
  171. //! [b, e).
  172. //!
  173. //! <b>Complexity</b>: Linear in N if [b, e) is already sorted using
  174. //! comp and otherwise N * log N, where N is the distance between first and last.
  175. //!
  176. //! <b>Throws</b>: If value_traits::node_traits::node
  177. //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
  178. //! or the copy constructor/operator() of the key_compare/priority_compare objects
  179. //! throw. Basic guarantee.
  180. template<class Iterator>
  181. treap_impl( bool unique, Iterator b, Iterator e
  182. , const key_compare &cmp = key_compare()
  183. , const priority_compare &pcmp = priority_compare()
  184. , const value_traits &v_traits = value_traits())
  185. : tree_type(cmp, v_traits), prio_base(pcmp)
  186. {
  187. if(unique)
  188. this->insert_unique(b, e);
  189. else
  190. this->insert_equal(b, e);
  191. }
  192. //! @copydoc ::boost::intrusive::bstree::bstree(bstree &&)
  193. treap_impl(BOOST_RV_REF(treap_impl) x)
  194. : tree_type(BOOST_MOVE_BASE(tree_type, x))
  195. , prio_base(::boost::move(x.priv_pcomp()))
  196. {}
  197. //! @copydoc ::boost::intrusive::bstree::operator=(bstree &&)
  198. treap_impl& operator=(BOOST_RV_REF(treap_impl) x)
  199. { this->swap(x); return *this; }
  200. #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
  201. //! @copydoc ::boost::intrusive::bstree::~bstree()
  202. ~treap_impl();
  203. //! @copydoc ::boost::intrusive::bstree::begin()
  204. iterator begin();
  205. //! @copydoc ::boost::intrusive::bstree::begin()const
  206. const_iterator begin() const;
  207. //! @copydoc ::boost::intrusive::bstree::cbegin()const
  208. const_iterator cbegin() const;
  209. //! @copydoc ::boost::intrusive::bstree::end()
  210. iterator end();
  211. //! @copydoc ::boost::intrusive::bstree::end()const
  212. const_iterator end() const;
  213. //! @copydoc ::boost::intrusive::bstree::cend()const
  214. const_iterator cend() const;
  215. #endif
  216. //! <b>Effects</b>: Returns an iterator pointing to the highest priority object of the treap.
  217. //!
  218. //! <b>Complexity</b>: Constant.
  219. //!
  220. //! <b>Throws</b>: Nothing.
  221. iterator top()
  222. { return this->tree_type::root(); }
  223. //! <b>Effects</b>: Returns a const_iterator pointing to the highest priority object of the treap..
  224. //!
  225. //! <b>Complexity</b>: Constant.
  226. //!
  227. //! <b>Throws</b>: Nothing.
  228. const_iterator top() const
  229. { return this->ctop(); }
  230. //! <b>Effects</b>: Returns a const_iterator pointing to the highest priority object of the treap..
  231. //!
  232. //! <b>Complexity</b>: Constant.
  233. //!
  234. //! <b>Throws</b>: Nothing.
  235. const_iterator ctop() const
  236. { return this->tree_type::root(); }
  237. #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
  238. //! @copydoc ::boost::intrusive::bstree::rbegin()
  239. reverse_iterator rbegin();
  240. //! @copydoc ::boost::intrusive::bstree::rbegin()const
  241. const_reverse_iterator rbegin() const;
  242. //! @copydoc ::boost::intrusive::bstree::crbegin()const
  243. const_reverse_iterator crbegin() const;
  244. //! @copydoc ::boost::intrusive::bstree::rend()
  245. reverse_iterator rend();
  246. //! @copydoc ::boost::intrusive::bstree::rend()const
  247. const_reverse_iterator rend() const;
  248. //! @copydoc ::boost::intrusive::bstree::crend()const
  249. const_reverse_iterator crend() const;
  250. //! @copydoc ::boost::intrusive::bstree::root()
  251. iterator root();
  252. //! @copydoc ::boost::intrusive::bstree::root()const
  253. const_iterator root() const;
  254. //! @copydoc ::boost::intrusive::bstree::croot()const
  255. const_iterator croot() const;
  256. #endif
  257. //! <b>Effects</b>: Returns a reverse_iterator pointing to the highest priority object of the
  258. //! reversed treap.
  259. //!
  260. //! <b>Complexity</b>: Constant.
  261. //!
  262. //! <b>Throws</b>: Nothing.
  263. reverse_iterator rtop()
  264. { return reverse_iterator(this->top()); }
  265. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the highest priority objec
  266. //! of the reversed treap.
  267. //!
  268. //! <b>Complexity</b>: Constant.
  269. //!
  270. //! <b>Throws</b>: Nothing.
  271. const_reverse_iterator rtop() const
  272. { return const_reverse_iterator(this->top()); }
  273. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the highest priority object
  274. //! of the reversed treap.
  275. //!
  276. //! <b>Complexity</b>: Constant.
  277. //!
  278. //! <b>Throws</b>: Nothing.
  279. const_reverse_iterator crtop() const
  280. { return const_reverse_iterator(this->top()); }
  281. #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
  282. //! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(iterator)
  283. static treap_impl &container_from_end_iterator(iterator end_iterator);
  284. //! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(const_iterator)
  285. static const treap_impl &container_from_end_iterator(const_iterator end_iterator);
  286. //! @copydoc ::boost::intrusive::bstree::container_from_iterator(iterator)
  287. static treap_impl &container_from_iterator(iterator it);
  288. //! @copydoc ::boost::intrusive::bstree::container_from_iterator(const_iterator)
  289. static const treap_impl &container_from_iterator(const_iterator it);
  290. //! @copydoc ::boost::intrusive::bstree::key_comp()const
  291. key_compare key_comp() const;
  292. //! @copydoc ::boost::intrusive::bstree::value_comp()const
  293. value_compare value_comp() const;
  294. //! @copydoc ::boost::intrusive::bstree::empty()const
  295. bool empty() const;
  296. //! @copydoc ::boost::intrusive::bstree::size()const
  297. size_type size() const;
  298. #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
  299. //! <b>Effects</b>: Returns the priority_compare object used by the container.
  300. //!
  301. //! <b>Complexity</b>: Constant.
  302. //!
  303. //! <b>Throws</b>: If priority_compare copy-constructor throws.
  304. priority_compare priority_comp() const
  305. { return this->priv_pcomp(); }
  306. //! <b>Effects</b>: Swaps the contents of two treaps.
  307. //!
  308. //! <b>Complexity</b>: Constant.
  309. //!
  310. //! <b>Throws</b>: If the comparison functor's swap call throws.
  311. void swap(treap_impl& other)
  312. {
  313. //This can throw
  314. ::boost::adl_move_swap(this->priv_pcomp(), other.priv_pcomp());
  315. tree_type::swap(other);
  316. }
  317. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
  318. //! Cloner should yield to nodes equivalent to the original nodes.
  319. //!
  320. //! <b>Effects</b>: Erases all the elements from *this
  321. //! calling Disposer::operator()(pointer), clones all the
  322. //! elements from src calling Cloner::operator()(const_reference )
  323. //! and inserts them on *this. Copies the predicate from the source container.
  324. //!
  325. //! If cloner throws, all cloned elements are unlinked and disposed
  326. //! calling Disposer::operator()(pointer).
  327. //!
  328. //! <b>Complexity</b>: Linear to erased plus inserted elements.
  329. //!
  330. //! <b>Throws</b>: If cloner throws or predicate copy assignment throws. Basic guarantee.
  331. template <class Cloner, class Disposer>
  332. void clone_from(const treap_impl &src, Cloner cloner, Disposer disposer)
  333. {
  334. tree_type::clone_from(src, cloner, disposer);
  335. this->priv_pcomp() = src.priv_pcomp();
  336. }
  337. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
  338. //! Cloner should yield to nodes equivalent to the original nodes.
  339. //!
  340. //! <b>Effects</b>: Erases all the elements from *this
  341. //! calling Disposer::operator()(pointer), clones all the
  342. //! elements from src calling Cloner::operator()(reference)
  343. //! and inserts them on *this. Copies the predicate from the source container.
  344. //!
  345. //! If cloner throws, all cloned elements are unlinked and disposed
  346. //! calling Disposer::operator()(pointer).
  347. //!
  348. //! <b>Complexity</b>: Linear to erased plus inserted elements.
  349. //!
  350. //! <b>Throws</b>: If cloner throws or predicate copy assignment throws. Basic guarantee.
  351. template <class Cloner, class Disposer>
  352. void clone_from(BOOST_RV_REF(treap_impl) src, Cloner cloner, Disposer disposer)
  353. {
  354. tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer);
  355. this->priv_pcomp() = ::boost::move(src.priv_pcomp());
  356. }
  357. //! <b>Requires</b>: value must be an lvalue
  358. //!
  359. //! <b>Effects</b>: Inserts value into the container before the upper bound.
  360. //!
  361. //! <b>Complexity</b>: Average complexity for insert element is at
  362. //! most logarithmic.
  363. //!
  364. //! <b>Throws</b>: If the internal key_compare or priority_compare functions throw. Strong guarantee.
  365. //!
  366. //! <b>Note</b>: Does not affect the validity of iterators and references.
  367. //! No copy-constructors are called.
  368. iterator insert_equal(reference value)
  369. {
  370. node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
  371. BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
  372. iterator ret
  373. ( node_algorithms::insert_equal_upper_bound
  374. ( this->tree_type::header_ptr()
  375. , to_insert
  376. , this->key_node_comp(this->key_comp())
  377. , this->prio_node_prio_comp(this->priv_pcomp()))
  378. , this->priv_value_traits_ptr());
  379. this->tree_type::sz_traits().increment();
  380. return ret;
  381. }
  382. //! <b>Requires</b>: value must be an lvalue, and "hint" must be
  383. //! a valid iterator.
  384. //!
  385. //! <b>Effects</b>: Inserts x into the container, using "hint" as a hint to
  386. //! where it will be inserted. If "hint" is the upper_bound
  387. //! the insertion takes constant time (two comparisons in the worst case)
  388. //!
  389. //! <b>Complexity</b>: Logarithmic in general, but it is amortized
  390. //! constant time if t is inserted immediately before hint.
  391. //!
  392. //! <b>Throws</b>: If the internal key_compare or priority_compare functions throw. Strong guarantee.
  393. //!
  394. //! <b>Note</b>: Does not affect the validity of iterators and references.
  395. //! No copy-constructors are called.
  396. iterator insert_equal(const_iterator hint, reference value)
  397. {
  398. node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
  399. BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
  400. iterator ret
  401. (node_algorithms::insert_equal
  402. ( this->tree_type::header_ptr()
  403. , hint.pointed_node()
  404. , to_insert
  405. , this->key_node_comp(this->key_comp())
  406. , this->prio_node_prio_comp(this->priv_pcomp()))
  407. , this->priv_value_traits_ptr());
  408. this->tree_type::sz_traits().increment();
  409. return ret;
  410. }
  411. //! <b>Requires</b>: Dereferencing iterator must yield an lvalue
  412. //! of type value_type.
  413. //!
  414. //! <b>Effects</b>: Inserts a each element of a range into the container
  415. //! before the upper bound of the key of each element.
  416. //!
  417. //! <b>Complexity</b>: Insert range is in general O(N * log(N)), where N is the
  418. //! size of the range. However, it is linear in N if the range is already sorted
  419. //! by key_comp().
  420. //!
  421. //! <b>Throws</b>: If the internal key_compare or priority_compare functions throw.
  422. //! Strong guarantee.
  423. //!
  424. //! <b>Note</b>: Does not affect the validity of iterators and references.
  425. //! No copy-constructors are called.
  426. template<class Iterator>
  427. void insert_equal(Iterator b, Iterator e)
  428. {
  429. iterator iend(this->end());
  430. for (; b != e; ++b)
  431. this->insert_equal(iend, *b);
  432. }
  433. //! <b>Requires</b>: value must be an lvalue
  434. //!
  435. //! <b>Effects</b>: Inserts value into the container if the value
  436. //! is not already present.
  437. //!
  438. //! <b>Complexity</b>: Average complexity for insert element is at
  439. //! most logarithmic.
  440. //!
  441. //! <b>Throws</b>: If the internal key_compare or priority_compare functions throw.
  442. //! Strong guarantee.
  443. //!
  444. //! <b>Note</b>: Does not affect the validity of iterators and references.
  445. //! No copy-constructors are called.
  446. std::pair<iterator, bool> insert_unique(reference value)
  447. {
  448. insert_commit_data commit_data;
  449. std::pair<iterator, bool> ret = this->insert_unique_check(key_of_value()(value), priority_of_value()(value), commit_data);
  450. if(!ret.second)
  451. return ret;
  452. return std::pair<iterator, bool> (this->insert_unique_commit(value, commit_data), true);
  453. }
  454. //! <b>Requires</b>: value must be an lvalue, and "hint" must be
  455. //! a valid iterator
  456. //!
  457. //! <b>Effects</b>: Tries to insert x into the container, using "hint" as a hint
  458. //! to where it will be inserted.
  459. //!
  460. //! <b>Complexity</b>: Logarithmic in general, but it is amortized
  461. //! constant time (two comparisons in the worst case)
  462. //! if t is inserted immediately before hint.
  463. //!
  464. //! <b>Throws</b>: If the internal key_compare or priority_compare functions throw.
  465. //! Strong guarantee.
  466. //!
  467. //! <b>Note</b>: Does not affect the validity of iterators and references.
  468. //! No copy-constructors are called.
  469. iterator insert_unique(const_iterator hint, reference value)
  470. {
  471. insert_commit_data commit_data;
  472. std::pair<iterator, bool> ret = this->insert_unique_check(hint, key_of_value()(value), priority_of_value()(value), commit_data);
  473. if(!ret.second)
  474. return ret.first;
  475. return this->insert_unique_commit(value, commit_data);
  476. }
  477. //! <b>Requires</b>: Dereferencing iterator must yield an lvalue
  478. //! of type value_type.
  479. //!
  480. //! <b>Effects</b>: Tries to insert each element of a range into the container.
  481. //!
  482. //! <b>Complexity</b>: Insert range is in general O(N * log(N)), where N is the
  483. //! size of the range. However, it is linear in N if the range is already sorted
  484. //! by key_comp().
  485. //!
  486. //! <b>Throws</b>: If the internal key_compare or priority_compare functions throw.
  487. //! Strong guarantee.
  488. //!
  489. //! <b>Note</b>: Does not affect the validity of iterators and references.
  490. //! No copy-constructors are called.
  491. template<class Iterator>
  492. void insert_unique(Iterator b, Iterator e)
  493. {
  494. if(this->empty()){
  495. iterator iend(this->end());
  496. for (; b != e; ++b)
  497. this->insert_unique(iend, *b);
  498. }
  499. else{
  500. for (; b != e; ++b)
  501. this->insert_unique(*b);
  502. }
  503. }
  504. //! <b>Effects</b>: Checks if a value can be inserted in the container, using
  505. //! a user provided key instead of the value itself.
  506. //!
  507. //! <b>Returns</b>: If there is an equivalent value
  508. //! returns a pair containing an iterator to the already present value
  509. //! and false. If the value can be inserted returns true in the returned
  510. //! pair boolean and fills "commit_data" that is meant to be used with
  511. //! the "insert_commit" function.
  512. //!
  513. //! <b>Complexity</b>: Average complexity is at most logarithmic.
  514. //!
  515. //! <b>Throws</b>: If the comparison or predicate functions throw. Strong guarantee.
  516. //!
  517. //! <b>Notes</b>: This function is used to improve performance when constructing
  518. //! a value_type is expensive: if there is an equivalent value
  519. //! the constructed object must be discarded. Many times, the part of the
  520. //! node that is used to impose the order is much cheaper to construct
  521. //! than the value_type and this function offers the possibility to use that
  522. //! part to check if the insertion will be successful.
  523. //!
  524. //! If the check is successful, the user can construct the value_type and use
  525. //! "insert_commit" to insert the object in constant-time. This gives a total
  526. //! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)).
  527. //!
  528. //! "commit_data" remains valid for a subsequent "insert_commit" only if no more
  529. //! objects are inserted or erased from the container.
  530. std::pair<iterator, bool> insert_unique_check
  531. ( const key_type &key, const priority_type &prio, insert_commit_data &commit_data)
  532. { return this->insert_unique_check(key, this->key_comp(), prio, this->priv_pcomp(), commit_data); }
  533. //! <b>Effects</b>: Checks if a value can be inserted in the container, using
  534. //! a user provided key instead of the value itself, using "hint"
  535. //! as a hint to where it will be inserted.
  536. //!
  537. //! <b>Returns</b>: If there is an equivalent value
  538. //! returns a pair containing an iterator to the already present value
  539. //! and false. If the value can be inserted returns true in the returned
  540. //! pair boolean and fills "commit_data" that is meant to be used with
  541. //! the "insert_commit" function.
  542. //!
  543. //! <b>Complexity</b>: Logarithmic in general, but it's amortized
  544. //! constant time if t is inserted immediately before hint.
  545. //!
  546. //! <b>Throws</b>: If the comparison or predicate functions throw. Strong guarantee.
  547. //!
  548. //! <b>Notes</b>: This function is used to improve performance when constructing
  549. //! a value_type is expensive: if there is an equivalent value
  550. //! the constructed object must be discarded. Many times, the part of the
  551. //! constructing that is used to impose the order is much cheaper to construct
  552. //! than the value_type and this function offers the possibility to use that key
  553. //! to check if the insertion will be successful.
  554. //!
  555. //! If the check is successful, the user can construct the value_type and use
  556. //! "insert_commit" to insert the object in constant-time. This can give a total
  557. //! constant-time complexity to the insertion: check(O(1)) + commit(O(1)).
  558. //!
  559. //! "commit_data" remains valid for a subsequent "insert_commit" only if no more
  560. //! objects are inserted or erased from the container.
  561. std::pair<iterator, bool> insert_unique_check
  562. ( const_iterator hint, const key_type &key, const priority_type &prio, insert_commit_data &commit_data)
  563. { return this->insert_unique_check(hint, key, this->key_comp(), prio, this->priv_pcomp(), commit_data); }
  564. //! <b>Requires</b>: comp must be a comparison function that induces
  565. //! the same strict weak ordering as key_compare.
  566. //! prio_value_pcomp must be a comparison function that induces
  567. //! the same strict weak ordering as priority_compare. The difference is that
  568. //! prio_value_pcomp and comp compare an arbitrary key/priority with the contained values.
  569. //!
  570. //! <b>Effects</b>: Checks if a value can be inserted in the container, using
  571. //! a user provided key instead of the value itself.
  572. //!
  573. //! <b>Returns</b>: If there is an equivalent value
  574. //! returns a pair containing an iterator to the already present value
  575. //! and false. If the value can be inserted returns true in the returned
  576. //! pair boolean and fills "commit_data" that is meant to be used with
  577. //! the "insert_commit" function.
  578. //!
  579. //! <b>Complexity</b>: Average complexity is at most logarithmic.
  580. //!
  581. //! <b>Throws</b>: If the comp or prio_value_pcomp
  582. //! ordering functions throw. Strong guarantee.
  583. //!
  584. //! <b>Notes</b>: This function is used to improve performance when constructing
  585. //! a value_type is expensive: if there is an equivalent value
  586. //! the constructed object must be discarded. Many times, the part of the
  587. //! node that is used to impose the order is much cheaper to construct
  588. //! than the value_type and this function offers the possibility to use that
  589. //! part to check if the insertion will be successful.
  590. //!
  591. //! If the check is successful, the user can construct the value_type and use
  592. //! "insert_commit" to insert the object in constant-time. This gives a total
  593. //! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)).
  594. //!
  595. //! "commit_data" remains valid for a subsequent "insert_commit" only if no more
  596. //! objects are inserted or erased from the container.
  597. template<class KeyType, class KeyTypeKeyCompare, class PrioType, class PrioValuePrioCompare>
  598. BOOST_INTRUSIVE_DOC1ST(std::pair<iterator BOOST_INTRUSIVE_I bool>
  599. , typename detail::disable_if_convertible
  600. <KeyType BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I
  601. std::pair<iterator BOOST_INTRUSIVE_I bool> >::type)
  602. insert_unique_check
  603. ( const KeyType &key, KeyTypeKeyCompare comp
  604. , const PrioType &prio, PrioValuePrioCompare prio_value_pcomp, insert_commit_data &commit_data)
  605. {
  606. std::pair<node_ptr, bool> const ret =
  607. (node_algorithms::insert_unique_check
  608. ( this->tree_type::header_ptr()
  609. , key, this->key_node_comp(comp)
  610. , prio, this->prio_node_prio_comp(prio_value_pcomp)
  611. , commit_data));
  612. return std::pair<iterator, bool>(iterator(ret.first, this->priv_value_traits_ptr()), ret.second);
  613. }
  614. //! <b>Requires</b>: comp must be a comparison function that induces
  615. //! the same strict weak ordering as key_compare.
  616. //! prio_value_pcomp must be a comparison function that induces
  617. //! the same strict weak ordering as priority_compare. The difference is that
  618. //! prio_value_pcomp and comp compare an arbitrary key/priority with the contained values.
  619. //!
  620. //! <b>Effects</b>: Checks if a value can be inserted in the container, using
  621. //! a user provided key instead of the value itself, using "hint"
  622. //! as a hint to where it will be inserted.
  623. //!
  624. //! <b>Returns</b>: If there is an equivalent value
  625. //! returns a pair containing an iterator to the already present value
  626. //! and false. If the value can be inserted returns true in the returned
  627. //! pair boolean and fills "commit_data" that is meant to be used with
  628. //! the "insert_commit" function.
  629. //!
  630. //! <b>Complexity</b>: Logarithmic in general, but it's amortized
  631. //! constant time if t is inserted immediately before hint.
  632. //!
  633. //! <b>Throws</b>: If the comp or prio_value_pcomp
  634. //! ordering functions throw. Strong guarantee.
  635. //!
  636. //! <b>Notes</b>: This function is used to improve performance when constructing
  637. //! a value_type is expensive: if there is an equivalent value
  638. //! the constructed object must be discarded. Many times, the part of the
  639. //! constructing that is used to impose the order is much cheaper to construct
  640. //! than the value_type and this function offers the possibility to use that key
  641. //! to check if the insertion will be successful.
  642. //!
  643. //! If the check is successful, the user can construct the value_type and use
  644. //! "insert_commit" to insert the object in constant-time. This can give a total
  645. //! constant-time complexity to the insertion: check(O(1)) + commit(O(1)).
  646. //!
  647. //! "commit_data" remains valid for a subsequent "insert_commit" only if no more
  648. //! objects are inserted or erased from the container.
  649. template<class KeyType, class KeyTypeKeyCompare, class PrioType, class PrioValuePrioCompare>
  650. std::pair<iterator, bool> insert_unique_check
  651. ( const_iterator hint
  652. , const KeyType &key
  653. , KeyTypeKeyCompare comp
  654. , const PrioType &prio
  655. , PrioValuePrioCompare prio_value_pcomp
  656. , insert_commit_data &commit_data)
  657. {
  658. std::pair<node_ptr, bool> const ret =
  659. (node_algorithms::insert_unique_check
  660. ( this->tree_type::header_ptr(), hint.pointed_node()
  661. , key, this->key_node_comp(comp)
  662. , prio, this->prio_node_prio_comp(prio_value_pcomp)
  663. , commit_data));
  664. return std::pair<iterator, bool>(iterator(ret.first, this->priv_value_traits_ptr()), ret.second);
  665. }
  666. //! <b>Requires</b>: value must be an lvalue of type value_type. commit_data
  667. //! must have been obtained from a previous call to "insert_check".
  668. //! No objects should have been inserted or erased from the container between
  669. //! the "insert_check" that filled "commit_data" and the call to "insert_commit".
  670. //!
  671. //! <b>Effects</b>: Inserts the value in the avl_set using the information obtained
  672. //! from the "commit_data" that a previous "insert_check" filled.
  673. //!
  674. //! <b>Returns</b>: An iterator to the newly inserted object.
  675. //!
  676. //! <b>Complexity</b>: Constant time.
  677. //!
  678. //! <b>Throws</b>: Nothing
  679. //!
  680. //! <b>Notes</b>: This function has only sense if a "insert_check" has been
  681. //! previously executed to fill "commit_data". No value should be inserted or
  682. //! erased between the "insert_check" and "insert_commit" calls.
  683. iterator insert_unique_commit(reference value, const insert_commit_data &commit_data)
  684. {
  685. node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
  686. BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
  687. node_algorithms::insert_unique_commit(this->tree_type::header_ptr(), to_insert, commit_data);
  688. this->tree_type::sz_traits().increment();
  689. return iterator(to_insert, this->priv_value_traits_ptr());
  690. }
  691. //! <b>Requires</b>: value must be an lvalue, "pos" must be
  692. //! a valid iterator (or end) and must be the succesor of value
  693. //! once inserted according to the predicate
  694. //!
  695. //! <b>Effects</b>: Inserts x into the container before "pos".
  696. //!
  697. //! <b>Complexity</b>: Constant time.
  698. //!
  699. //! <b>Throws</b>: If the internal priority_compare function throws. Strong guarantee.
  700. //!
  701. //! <b>Note</b>: This function does not check preconditions so if "pos" is not
  702. //! the successor of "value" container ordering invariant will be broken.
  703. //! This is a low-level function to be used only for performance reasons
  704. //! by advanced users.
  705. iterator insert_before(const_iterator pos, reference value)
  706. {
  707. node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
  708. BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
  709. iterator ret
  710. ( node_algorithms::insert_before
  711. ( this->tree_type::header_ptr()
  712. , pos.pointed_node()
  713. , to_insert
  714. , this->prio_node_prio_comp(this->priv_pcomp())
  715. )
  716. , this->priv_value_traits_ptr());
  717. this->tree_type::sz_traits().increment();
  718. return ret;
  719. }
  720. //! <b>Requires</b>: value must be an lvalue, and it must be no less
  721. //! than the greatest inserted key
  722. //!
  723. //! <b>Effects</b>: Inserts x into the container in the last position.
  724. //!
  725. //! <b>Complexity</b>: Constant time.
  726. //!
  727. //! <b>Throws</b>: If the internal priority_compare function throws. Strong guarantee.
  728. //!
  729. //! <b>Note</b>: This function does not check preconditions so if value is
  730. //! less than the greatest inserted key container ordering invariant will be broken.
  731. //! This function is slightly more efficient than using "insert_before".
  732. //! This is a low-level function to be used only for performance reasons
  733. //! by advanced users.
  734. void push_back(reference value)
  735. {
  736. node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
  737. BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
  738. node_algorithms::push_back
  739. (this->tree_type::header_ptr(), to_insert, this->prio_node_prio_comp(this->priv_pcomp()));
  740. this->tree_type::sz_traits().increment();
  741. }
  742. //! <b>Requires</b>: value must be an lvalue, and it must be no greater
  743. //! than the minimum inserted key
  744. //!
  745. //! <b>Effects</b>: Inserts x into the container in the first position.
  746. //!
  747. //! <b>Complexity</b>: Constant time.
  748. //!
  749. //! <b>Throws</b>: If the internal priority_compare function throws. Strong guarantee.
  750. //!
  751. //! <b>Note</b>: This function does not check preconditions so if value is
  752. //! greater than the minimum inserted key container ordering invariant will be broken.
  753. //! This function is slightly more efficient than using "insert_before".
  754. //! This is a low-level function to be used only for performance reasons
  755. //! by advanced users.
  756. void push_front(reference value)
  757. {
  758. node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
  759. BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
  760. node_algorithms::push_front
  761. (this->tree_type::header_ptr(), to_insert, this->prio_node_prio_comp(this->priv_pcomp()));
  762. this->tree_type::sz_traits().increment();
  763. }
  764. //! <b>Effects</b>: Erases the element pointed to by i.
  765. //!
  766. //! <b>Complexity</b>: Average complexity for erase element is constant time.
  767. //!
  768. //! <b>Throws</b>: if the internal priority_compare function throws. Strong guarantee.
  769. //!
  770. //! <b>Note</b>: Invalidates the iterators (but not the references)
  771. //! to the erased elements. No destructors are called.
  772. iterator erase(const_iterator i)
  773. {
  774. const_iterator ret(i);
  775. ++ret;
  776. node_ptr to_erase(i.pointed_node());
  777. BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || !node_algorithms::unique(to_erase));
  778. node_algorithms::erase
  779. (this->tree_type::header_ptr(), to_erase, this->prio_node_prio_comp(this->priv_pcomp()));
  780. this->tree_type::sz_traits().decrement();
  781. if(safemode_or_autounlink)
  782. node_algorithms::init(to_erase);
  783. return ret.unconst();
  784. }
  785. //! <b>Effects</b>: Erases the range pointed to by b end e.
  786. //!
  787. //! <b>Complexity</b>: Average complexity for erase range is at most
  788. //! O(log(size() + N)), where N is the number of elements in the range.
  789. //!
  790. //! <b>Throws</b>: if the internal priority_compare function throws. Strong guarantee.
  791. //!
  792. //! <b>Note</b>: Invalidates the iterators (but not the references)
  793. //! to the erased elements. No destructors are called.
  794. iterator erase(const_iterator b, const_iterator e)
  795. { size_type n; return private_erase(b, e, n); }
  796. //! <b>Effects</b>: Erases all the elements with the given value.
  797. //!
  798. //! <b>Returns</b>: The number of erased elements.
  799. //!
  800. //! <b>Complexity</b>: O(log(size() + N).
  801. //!
  802. //! <b>Throws</b>: if the internal priority_compare function throws. Strong guarantee.
  803. //!
  804. //! <b>Note</b>: Invalidates the iterators (but not the references)
  805. //! to the erased elements. No destructors are called.
  806. size_type erase(const key_type &key)
  807. { return this->erase(key, this->key_comp()); }
  808. //! <b>Effects</b>: Erases all the elements with the given key.
  809. //! according to the comparison functor "comp".
  810. //!
  811. //! <b>Returns</b>: The number of erased elements.
  812. //!
  813. //! <b>Complexity</b>: O(log(size() + N).
  814. //!
  815. //! <b>Throws</b>: if the internal priority_compare function throws.
  816. //! Equivalent guarantee to <i>while(beg != end) erase(beg++);</i>
  817. //!
  818. //! <b>Note</b>: Invalidates the iterators (but not the references)
  819. //! to the erased elements. No destructors are called.
  820. template<class KeyType, class KeyTypeKeyCompare>
  821. BOOST_INTRUSIVE_DOC1ST(size_type
  822. , typename detail::disable_if_convertible<KeyTypeKeyCompare BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I size_type>::type)
  823. erase(const KeyType& key, KeyTypeKeyCompare comp)
  824. {
  825. std::pair<iterator,iterator> p = this->equal_range(key, comp);
  826. size_type n;
  827. private_erase(p.first, p.second, n);
  828. return n;
  829. }
  830. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
  831. //!
  832. //! <b>Effects</b>: Erases the element pointed to by i.
  833. //! Disposer::operator()(pointer) is called for the removed element.
  834. //!
  835. //! <b>Complexity</b>: Average complexity for erase element is constant time.
  836. //!
  837. //! <b>Throws</b>: if the internal priority_compare function throws. Strong guarantee.
  838. //!
  839. //! <b>Note</b>: Invalidates the iterators
  840. //! to the erased elements.
  841. template<class Disposer>
  842. iterator erase_and_dispose(const_iterator i, Disposer disposer)
  843. {
  844. node_ptr to_erase(i.pointed_node());
  845. iterator ret(this->erase(i));
  846. disposer(this->get_value_traits().to_value_ptr(to_erase));
  847. return ret;
  848. }
  849. #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
  850. template<class Disposer>
  851. iterator erase_and_dispose(iterator i, Disposer disposer)
  852. { return this->erase_and_dispose(const_iterator(i), disposer); }
  853. #endif
  854. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
  855. //!
  856. //! <b>Effects</b>: Erases the range pointed to by b end e.
  857. //! Disposer::operator()(pointer) is called for the removed elements.
  858. //!
  859. //! <b>Complexity</b>: Average complexity for erase range is at most
  860. //! O(log(size() + N)), where N is the number of elements in the range.
  861. //!
  862. //! <b>Throws</b>: if the internal priority_compare function throws. Strong guarantee.
  863. //!
  864. //! <b>Note</b>: Invalidates the iterators
  865. //! to the erased elements.
  866. template<class Disposer>
  867. iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer)
  868. { size_type n; return private_erase(b, e, n, disposer); }
  869. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
  870. //!
  871. //! <b>Effects</b>: Erases all the elements with the given value.
  872. //! Disposer::operator()(pointer) is called for the removed elements.
  873. //!
  874. //! <b>Returns</b>: The number of erased elements.
  875. //!
  876. //! <b>Complexity</b>: O(log(size() + N).
  877. //!
  878. //! <b>Throws</b>: if the priority_compare function throws then weak guarantee and heap invariants are broken.
  879. //! The safest thing would be to clear or destroy the container.
  880. //!
  881. //! <b>Note</b>: Invalidates the iterators (but not the references)
  882. //! to the erased elements. No destructors are called.
  883. template<class Disposer>
  884. size_type erase_and_dispose(const key_type &key, Disposer disposer)
  885. {
  886. std::pair<iterator,iterator> p = this->equal_range(key);
  887. size_type n;
  888. private_erase(p.first, p.second, n, disposer);
  889. return n;
  890. }
  891. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
  892. //!
  893. //! <b>Effects</b>: Erases all the elements with the given key.
  894. //! according to the comparison functor "comp".
  895. //! Disposer::operator()(pointer) is called for the removed elements.
  896. //!
  897. //! <b>Returns</b>: The number of erased elements.
  898. //!
  899. //! <b>Complexity</b>: O(log(size() + N).
  900. //!
  901. //! <b>Throws</b>: if the priority_compare function throws then weak guarantee and heap invariants are broken.
  902. //! The safest thing would be to clear or destroy the container.
  903. //!
  904. //! <b>Note</b>: Invalidates the iterators
  905. //! to the erased elements.
  906. template<class KeyType, class KeyTypeKeyCompare, class Disposer>
  907. BOOST_INTRUSIVE_DOC1ST(size_type
  908. , typename detail::disable_if_convertible<KeyTypeKeyCompare BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I size_type>::type)
  909. erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer)
  910. {
  911. std::pair<iterator,iterator> p = this->equal_range(key, comp);
  912. size_type n;
  913. private_erase(p.first, p.second, n, disposer);
  914. return n;
  915. }
  916. //! <b>Effects</b>: Erases all of the elements.
  917. //!
  918. //! <b>Complexity</b>: Linear to the number of elements on the container.
  919. //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise.
  920. //!
  921. //! <b>Throws</b>: Nothing.
  922. //!
  923. //! <b>Note</b>: Invalidates the iterators (but not the references)
  924. //! to the erased elements. No destructors are called.
  925. void clear()
  926. { tree_type::clear(); }
  927. //! <b>Effects</b>: Erases all of the elements calling disposer(p) for
  928. //! each node to be erased.
  929. //! <b>Complexity</b>: Average complexity for is at most O(log(size() + N)),
  930. //! where N is the number of elements in the container.
  931. //!
  932. //! <b>Throws</b>: Nothing.
  933. //!
  934. //! <b>Note</b>: Invalidates the iterators (but not the references)
  935. //! to the erased elements. Calls N times to disposer functor.
  936. template<class Disposer>
  937. void clear_and_dispose(Disposer disposer)
  938. {
  939. node_algorithms::clear_and_dispose(this->tree_type::header_ptr()
  940. , detail::node_disposer<Disposer, value_traits, TreapAlgorithms>(disposer, &this->get_value_traits()));
  941. node_algorithms::init_header(this->tree_type::header_ptr());
  942. this->tree_type::sz_traits().set_size(0);
  943. }
  944. #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
  945. //! @copydoc ::boost::intrusive::bstree::merge_unique
  946. template<class T, class ...Options2> void merge_unique(sgtree<T, Options2...> &);
  947. #else
  948. template<class Compare2>
  949. void merge_unique(treap_impl
  950. <ValueTraits, VoidOrKeyOfValue, Compare2, VoidOrPrioOfValue, VoidOrPrioComp, SizeType, ConstantTimeSize, HeaderHolder> &source)
  951. #endif
  952. {
  953. node_ptr it (node_algorithms::begin_node(source.header_ptr()))
  954. , itend(node_algorithms::end_node (source.header_ptr()));
  955. while(it != itend){
  956. node_ptr const p(it);
  957. BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || !node_algorithms::unique(p));
  958. it = node_algorithms::next_node(it);
  959. if( node_algorithms::transfer_unique
  960. ( this->header_ptr(), this->key_node_comp(this->key_comp())
  961. , this->prio_node_prio_comp(this->priv_pcomp()), source.header_ptr(), p) ){
  962. this->sz_traits().increment();
  963. source.sz_traits().decrement();
  964. }
  965. }
  966. }
  967. #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
  968. //! @copydoc ::boost::intrusive::bstree::merge_equal(bstree<T, Options2...>&)
  969. template<class T, class ...Options2> void merge_equal(sgtree<T, Options2...> &);
  970. #else
  971. template<class Compare2>
  972. void merge_equal(treap_impl
  973. <ValueTraits, VoidOrKeyOfValue, Compare2, VoidOrPrioOfValue, VoidOrPrioComp, SizeType, ConstantTimeSize, HeaderHolder> &source)
  974. #endif
  975. {
  976. node_ptr it (node_algorithms::begin_node(source.header_ptr()))
  977. , itend(node_algorithms::end_node (source.header_ptr()));
  978. while(it != itend){
  979. node_ptr const p(it);
  980. BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || !node_algorithms::unique(p));
  981. it = node_algorithms::next_node(it);
  982. node_algorithms::transfer_equal
  983. ( this->header_ptr(), this->key_node_comp(this->key_comp())
  984. , this->prio_node_prio_comp(this->priv_pcomp()), source.header_ptr(), p);
  985. this->sz_traits().increment();
  986. source.sz_traits().decrement();
  987. }
  988. }
  989. //! @copydoc ::boost::intrusive::bstree::check(ExtraChecker)const
  990. template <class ExtraChecker>
  991. void check(ExtraChecker extra_checker) const
  992. {
  993. typedef detail::key_nodeptr_comp<priority_compare, value_traits, priority_of_value> nodeptr_prio_comp_t;
  994. tree_type::check(detail::treap_node_extra_checker
  995. <ValueTraits, nodeptr_prio_comp_t, ExtraChecker>
  996. (this->prio_node_prio_comp(this->priv_pcomp()), extra_checker));
  997. }
  998. //! @copydoc ::boost::intrusive::bstree::check()const
  999. void check() const
  1000. { check(detail::empty_node_checker<ValueTraits>()); }
  1001. #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
  1002. //! @copydoc ::boost::intrusive::bstree::count(const key_type &)const
  1003. size_type count(const key_type &key) const;
  1004. //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyTypeKeyCompare)const
  1005. template<class KeyType, class KeyTypeKeyCompare>
  1006. size_type count(const KeyType& key, KeyTypeKeyCompare comp) const;
  1007. //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)
  1008. iterator lower_bound(const key_type &key);
  1009. //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)
  1010. template<class KeyType, class KeyTypeKeyCompare>
  1011. iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
  1012. //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)const
  1013. const_iterator lower_bound(const key_type &key) const;
  1014. //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
  1015. template<class KeyType, class KeyTypeKeyCompare>
  1016. const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
  1017. //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)
  1018. iterator upper_bound(const key_type &key);
  1019. //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)
  1020. template<class KeyType, class KeyTypeKeyCompare>
  1021. iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
  1022. //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)const
  1023. const_iterator upper_bound(const key_type &key) const;
  1024. //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
  1025. template<class KeyType, class KeyTypeKeyCompare>
  1026. const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
  1027. //! @copydoc ::boost::intrusive::bstree::find(const key_type &)
  1028. iterator find(const key_type &key);
  1029. //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)
  1030. template<class KeyType, class KeyTypeKeyCompare>
  1031. iterator find(const KeyType& key, KeyTypeKeyCompare comp);
  1032. //! @copydoc ::boost::intrusive::bstree::find(const key_type &)const
  1033. const_iterator find(const key_type &key) const;
  1034. //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)const
  1035. template<class KeyType, class KeyTypeKeyCompare>
  1036. const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
  1037. //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)
  1038. std::pair<iterator,iterator> equal_range(const key_type &key);
  1039. //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)
  1040. template<class KeyType, class KeyTypeKeyCompare>
  1041. std::pair<iterator,iterator> equal_range(const KeyType& key, KeyTypeKeyCompare comp);
  1042. //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)const
  1043. std::pair<const_iterator, const_iterator>
  1044. equal_range(const key_type &key) const;
  1045. //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)const
  1046. template<class KeyType, class KeyTypeKeyCompare>
  1047. std::pair<const_iterator, const_iterator>
  1048. equal_range(const KeyType& key, KeyTypeKeyCompare comp) const;
  1049. //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)
  1050. std::pair<iterator,iterator> bounded_range
  1051. (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed);
  1052. //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
  1053. template<class KeyType, class KeyTypeKeyCompare>
  1054. std::pair<iterator,iterator> bounded_range
  1055. (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
  1056. //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)const
  1057. std::pair<const_iterator, const_iterator>
  1058. bounded_range(const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
  1059. //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
  1060. template<class KeyType, class KeyTypeKeyCompare>
  1061. std::pair<const_iterator, const_iterator> bounded_range
  1062. (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
  1063. //! @copydoc ::boost::intrusive::bstree::s_iterator_to(reference)
  1064. static iterator s_iterator_to(reference value);
  1065. //! @copydoc ::boost::intrusive::bstree::s_iterator_to(const_reference)
  1066. static const_iterator s_iterator_to(const_reference value);
  1067. //! @copydoc ::boost::intrusive::bstree::iterator_to(reference)
  1068. iterator iterator_to(reference value);
  1069. //! @copydoc ::boost::intrusive::bstree::iterator_to(const_reference)const
  1070. const_iterator iterator_to(const_reference value) const;
  1071. //! @copydoc ::boost::intrusive::bstree::init_node(reference)
  1072. static void init_node(reference value);
  1073. //! @copydoc ::boost::intrusive::bstree::unlink_leftmost_without_rebalance
  1074. pointer unlink_leftmost_without_rebalance();
  1075. //! @copydoc ::boost::intrusive::bstree::replace_node
  1076. void replace_node(iterator replace_this, reference with_this);
  1077. //! @copydoc ::boost::intrusive::bstree::remove_node
  1078. void remove_node(reference value);
  1079. friend bool operator< (const treap_impl &x, const treap_impl &y);
  1080. friend bool operator==(const treap_impl &x, const treap_impl &y);
  1081. friend bool operator!= (const treap_impl &x, const treap_impl &y);
  1082. friend bool operator>(const treap_impl &x, const treap_impl &y);
  1083. friend bool operator<=(const treap_impl &x, const treap_impl &y);
  1084. friend bool operator>=(const treap_impl &x, const treap_impl &y);
  1085. friend void swap(treap_impl &x, treap_impl &y);
  1086. #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
  1087. /// @cond
  1088. private:
  1089. template<class Disposer>
  1090. iterator private_erase(const_iterator b, const_iterator e, size_type &n, Disposer disposer)
  1091. {
  1092. for(n = 0; b != e; ++n)
  1093. this->erase_and_dispose(b++, disposer);
  1094. return b.unconst();
  1095. }
  1096. iterator private_erase(const_iterator b, const_iterator e, size_type &n)
  1097. {
  1098. for(n = 0; b != e; ++n)
  1099. this->erase(b++);
  1100. return b.unconst();
  1101. }
  1102. /// @endcond
  1103. };
  1104. //! Helper metafunction to define a \c treap that yields to the same type when the
  1105. //! same options (either explicitly or implicitly) are used.
  1106. #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
  1107. template<class T, class ...Options>
  1108. #else
  1109. template<class T, class O1 = void, class O2 = void
  1110. , class O3 = void, class O4 = void
  1111. , class O5 = void, class O6 = void
  1112. , class O7 = void>
  1113. #endif
  1114. struct make_treap
  1115. {
  1116. typedef typename pack_options
  1117. < treap_defaults,
  1118. #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
  1119. O1, O2, O3, O4, O5, O6, O7
  1120. #else
  1121. Options...
  1122. #endif
  1123. >::type packed_options;
  1124. typedef typename detail::get_value_traits
  1125. <T, typename packed_options::proto_value_traits>::type value_traits;
  1126. typedef treap_impl
  1127. < value_traits
  1128. , typename packed_options::key_of_value
  1129. , typename packed_options::compare
  1130. , typename packed_options::priority_of_value
  1131. , typename packed_options::priority
  1132. , typename packed_options::size_type
  1133. , packed_options::constant_time_size
  1134. , typename packed_options::header_holder_type
  1135. > implementation_defined;
  1136. /// @endcond
  1137. typedef implementation_defined type;
  1138. };
  1139. #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
  1140. #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
  1141. template<class T, class O1, class O2, class O3, class O4, class O5, class O6, class O7>
  1142. #else
  1143. template<class T, class ...Options>
  1144. #endif
  1145. class treap
  1146. : public make_treap<T,
  1147. #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
  1148. O1, O2, O3, O4, O5, O6, O7
  1149. #else
  1150. Options...
  1151. #endif
  1152. >::type
  1153. {
  1154. typedef typename make_treap
  1155. <T,
  1156. #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
  1157. O1, O2, O3, O4, O5, O6, O7
  1158. #else
  1159. Options...
  1160. #endif
  1161. >::type Base;
  1162. BOOST_MOVABLE_BUT_NOT_COPYABLE(treap)
  1163. public:
  1164. typedef typename Base::key_compare key_compare;
  1165. typedef typename Base::priority_compare priority_compare;
  1166. typedef typename Base::value_traits value_traits;
  1167. typedef typename Base::iterator iterator;
  1168. typedef typename Base::const_iterator const_iterator;
  1169. typedef typename Base::reverse_iterator reverse_iterator;
  1170. typedef typename Base::const_reverse_iterator const_reverse_iterator;
  1171. //Assert if passed value traits are compatible with the type
  1172. BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
  1173. BOOST_INTRUSIVE_FORCEINLINE treap()
  1174. : Base()
  1175. {}
  1176. BOOST_INTRUSIVE_FORCEINLINE explicit treap( const key_compare &cmp
  1177. , const priority_compare &pcmp = priority_compare()
  1178. , const value_traits &v_traits = value_traits())
  1179. : Base(cmp, pcmp, v_traits)
  1180. {}
  1181. template<class Iterator>
  1182. BOOST_INTRUSIVE_FORCEINLINE treap( bool unique, Iterator b, Iterator e
  1183. , const key_compare &cmp = key_compare()
  1184. , const priority_compare &pcmp = priority_compare()
  1185. , const value_traits &v_traits = value_traits())
  1186. : Base(unique, b, e, cmp, pcmp, v_traits)
  1187. {}
  1188. BOOST_INTRUSIVE_FORCEINLINE treap(BOOST_RV_REF(treap) x)
  1189. : Base(BOOST_MOVE_BASE(Base, x))
  1190. {}
  1191. BOOST_INTRUSIVE_FORCEINLINE treap& operator=(BOOST_RV_REF(treap) x)
  1192. { return static_cast<treap&>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
  1193. template <class Cloner, class Disposer>
  1194. BOOST_INTRUSIVE_FORCEINLINE void clone_from(const treap &src, Cloner cloner, Disposer disposer)
  1195. { Base::clone_from(src, cloner, disposer); }
  1196. template <class Cloner, class Disposer>
  1197. BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(treap) src, Cloner cloner, Disposer disposer)
  1198. { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
  1199. BOOST_INTRUSIVE_FORCEINLINE static treap &container_from_end_iterator(iterator end_iterator)
  1200. { return static_cast<treap &>(Base::container_from_end_iterator(end_iterator)); }
  1201. BOOST_INTRUSIVE_FORCEINLINE static const treap &container_from_end_iterator(const_iterator end_iterator)
  1202. { return static_cast<const treap &>(Base::container_from_end_iterator(end_iterator)); }
  1203. BOOST_INTRUSIVE_FORCEINLINE static treap &container_from_iterator(iterator it)
  1204. { return static_cast<treap &>(Base::container_from_iterator(it)); }
  1205. BOOST_INTRUSIVE_FORCEINLINE static const treap &container_from_iterator(const_iterator it)
  1206. { return static_cast<const treap &>(Base::container_from_iterator(it)); }
  1207. };
  1208. #endif
  1209. } //namespace intrusive
  1210. } //namespace boost
  1211. #include <boost/intrusive/detail/config_end.hpp>
  1212. #endif //BOOST_INTRUSIVE_TREAP_HPP