sgtree.hpp 68 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877
  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2007-2009
  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. //
  13. // The option that yields to non-floating point 1/sqrt(2) alpha is taken
  14. // from the scapegoat tree implementation of the PSPP library.
  15. //
  16. /////////////////////////////////////////////////////////////////////////////
  17. #ifndef BOOST_INTRUSIVE_SGTREE_HPP
  18. #define BOOST_INTRUSIVE_SGTREE_HPP
  19. #include <boost/intrusive/detail/config_begin.hpp>
  20. #include <algorithm>
  21. #include <cstddef>
  22. #include <functional>
  23. #include <iterator>
  24. #include <utility>
  25. #include <cmath>
  26. #include <cstddef>
  27. #include <boost/intrusive/detail/assert.hpp>
  28. #include <boost/static_assert.hpp>
  29. #include <boost/intrusive/intrusive_fwd.hpp>
  30. #include <boost/intrusive/bs_set_hook.hpp>
  31. #include <boost/intrusive/detail/tree_node.hpp>
  32. #include <boost/intrusive/detail/ebo_functor_holder.hpp>
  33. #include <boost/intrusive/detail/pointer_to_other.hpp>
  34. #include <boost/intrusive/detail/clear_on_destructor_base.hpp>
  35. #include <boost/intrusive/detail/mpl.hpp>
  36. #include <boost/intrusive/options.hpp>
  37. #include <boost/intrusive/sgtree_algorithms.hpp>
  38. #include <boost/intrusive/link_mode.hpp>
  39. namespace boost {
  40. namespace intrusive {
  41. /// @cond
  42. namespace detail{
  43. //! Returns floor(log(n)/log(sqrt(2))) -> floor(2*log2(n))
  44. //! Undefined if N is 0.
  45. //!
  46. //! This function does not use float point operations.
  47. inline std::size_t calculate_h_sqrt2 (std::size_t n)
  48. {
  49. std::size_t f_log2 = detail::floor_log2(n);
  50. return (2*f_log2) + (n >= detail::sqrt2_pow_2xplus1 (f_log2));
  51. }
  52. struct h_alpha_sqrt2_t
  53. {
  54. h_alpha_sqrt2_t(void){}
  55. std::size_t operator()(std::size_t n) const
  56. { return calculate_h_sqrt2(n); }
  57. };
  58. struct alpha_0_75_by_max_size_t
  59. {
  60. alpha_0_75_by_max_size_t(void){}
  61. std::size_t operator()(std::size_t max_tree_size) const
  62. {
  63. const std::size_t max_tree_size_limit = ((~std::size_t(0))/std::size_t(3));
  64. return max_tree_size > max_tree_size_limit ? max_tree_size/4*3 : max_tree_size*3/4;
  65. }
  66. };
  67. struct h_alpha_t
  68. {
  69. h_alpha_t(float inv_minus_logalpha)
  70. : inv_minus_logalpha_(inv_minus_logalpha)
  71. {}
  72. std::size_t operator()(std::size_t n) const
  73. {
  74. //Returns floor(log1/alpha(n)) ->
  75. // floor(log(n)/log(1/alpha)) ->
  76. // floor(log(n)/(-log(alpha)))
  77. //return static_cast<std::size_t>(std::log(float(n))*inv_minus_logalpha_);
  78. return static_cast<std::size_t>(detail::fast_log2(float(n))*inv_minus_logalpha_);
  79. }
  80. private:
  81. //Since the function will be repeatedly called
  82. //precalculate constant data to avoid repeated
  83. //calls to log and division.
  84. //This will store 1/(-std::log(alpha_))
  85. float inv_minus_logalpha_;
  86. };
  87. struct alpha_by_max_size_t
  88. {
  89. alpha_by_max_size_t(float alpha)
  90. : alpha_(alpha)
  91. {}
  92. float operator()(std::size_t max_tree_size) const
  93. { return float(max_tree_size)*alpha_; }
  94. private:
  95. float alpha_;
  96. float inv_minus_logalpha_;
  97. };
  98. template<bool Activate>
  99. struct alpha_holder
  100. {
  101. typedef boost::intrusive::detail::h_alpha_t h_alpha_t;
  102. typedef boost::intrusive::detail::alpha_by_max_size_t multiply_by_alpha_t;
  103. alpha_holder()
  104. { set_alpha(0.7f); }
  105. float get_alpha() const
  106. { return alpha_; }
  107. void set_alpha(float alpha)
  108. {
  109. alpha_ = alpha;
  110. inv_minus_logalpha_ = 1/(-detail::fast_log2(alpha));
  111. }
  112. h_alpha_t get_h_alpha_t() const
  113. { return h_alpha_t(inv_minus_logalpha_); }
  114. multiply_by_alpha_t get_multiply_by_alpha_t() const
  115. { return multiply_by_alpha_t(alpha_); }
  116. private:
  117. float alpha_;
  118. float inv_minus_logalpha_;
  119. };
  120. template<>
  121. struct alpha_holder<false>
  122. {
  123. //This specialization uses alpha = 1/sqrt(2)
  124. //without using floating point operations
  125. //Downside: alpha CAN't be changed.
  126. typedef boost::intrusive::detail::h_alpha_sqrt2_t h_alpha_t;
  127. typedef boost::intrusive::detail::alpha_0_75_by_max_size_t multiply_by_alpha_t;
  128. float get_alpha() const
  129. { return 0.70710677f; }
  130. void set_alpha(float)
  131. { //alpha CAN't be changed.
  132. BOOST_INTRUSIVE_INVARIANT_ASSERT(0);
  133. }
  134. h_alpha_t get_h_alpha_t() const
  135. { return h_alpha_t(); }
  136. multiply_by_alpha_t get_multiply_by_alpha_t() const
  137. { return multiply_by_alpha_t(); }
  138. };
  139. } //namespace detail{
  140. template <class ValueTraits, class Compare, class SizeType, bool FloatingPoint>
  141. struct sg_setopt
  142. {
  143. typedef ValueTraits value_traits;
  144. typedef Compare compare;
  145. typedef SizeType size_type;
  146. static const bool floating_point = FloatingPoint;
  147. };
  148. template <class T>
  149. struct sg_set_defaults
  150. : pack_options
  151. < none
  152. , base_hook<detail::default_bs_set_hook>
  153. , floating_point<true>
  154. , size_type<std::size_t>
  155. , compare<std::less<T> >
  156. >::type
  157. {};
  158. /// @endcond
  159. //! The class template sgtree is an intrusive scapegoat tree container, that
  160. //! is used to construct intrusive sg_set and sg_multiset containers.
  161. //! The no-throw guarantee holds only, if the value_compare object
  162. //! doesn't throw.
  163. //!
  164. //! The template parameter \c T is the type to be managed by the container.
  165. //! The user can specify additional options and if no options are provided
  166. //! default options are used.
  167. //!
  168. //! The container supports the following options:
  169. //! \c base_hook<>/member_hook<>/value_traits<>,
  170. //! \c floating_point<>, \c size_type<> and
  171. //! \c compare<>.
  172. #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
  173. template<class T, class ...Options>
  174. #else
  175. template<class Config>
  176. #endif
  177. class sgtree_impl
  178. : private detail::clear_on_destructor_base<sgtree_impl<Config> >
  179. {
  180. template<class C> friend class detail::clear_on_destructor_base;
  181. public:
  182. typedef typename Config::value_traits value_traits;
  183. /// @cond
  184. static const bool external_value_traits =
  185. detail::external_value_traits_is_true<value_traits>::value;
  186. typedef typename detail::eval_if_c
  187. < external_value_traits
  188. , detail::eval_value_traits<value_traits>
  189. , detail::identity<value_traits>
  190. >::type real_value_traits;
  191. /// @endcond
  192. typedef typename real_value_traits::pointer pointer;
  193. typedef typename real_value_traits::const_pointer const_pointer;
  194. typedef typename std::iterator_traits<pointer>::value_type value_type;
  195. typedef value_type key_type;
  196. typedef typename std::iterator_traits<pointer>::reference reference;
  197. typedef typename std::iterator_traits<const_pointer>::reference const_reference;
  198. typedef typename std::iterator_traits<pointer>::difference_type difference_type;
  199. typedef typename Config::size_type size_type;
  200. typedef typename Config::compare value_compare;
  201. typedef value_compare key_compare;
  202. typedef tree_iterator<sgtree_impl, false> iterator;
  203. typedef tree_iterator<sgtree_impl, true> const_iterator;
  204. typedef std::reverse_iterator<iterator> reverse_iterator;
  205. typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
  206. typedef typename real_value_traits::node_traits node_traits;
  207. typedef typename node_traits::node node;
  208. typedef typename boost::pointer_to_other
  209. <pointer, node>::type node_ptr;
  210. typedef typename boost::pointer_to_other
  211. <node_ptr, const node>::type const_node_ptr;
  212. typedef sgtree_algorithms<node_traits> node_algorithms;
  213. static const bool floating_point = Config::floating_point;
  214. static const bool constant_time_size = true;
  215. static const bool stateful_value_traits = detail::is_stateful_value_traits<real_value_traits>::value;
  216. /// @cond
  217. private:
  218. typedef detail::size_holder<true, size_type> size_traits;
  219. typedef detail::alpha_holder<floating_point> alpha_traits;
  220. typedef typename alpha_traits::h_alpha_t h_alpha_t;
  221. typedef typename alpha_traits::multiply_by_alpha_t multiply_by_alpha_t;
  222. //noncopyable
  223. sgtree_impl (const sgtree_impl&);
  224. sgtree_impl operator =(const sgtree_impl&);
  225. enum { safemode_or_autounlink =
  226. (int)real_value_traits::link_mode == (int)auto_unlink ||
  227. (int)real_value_traits::link_mode == (int)safe_link };
  228. BOOST_STATIC_ASSERT(((int)real_value_traits::link_mode != (int)auto_unlink));
  229. //BOOST_STATIC_ASSERT((
  230. // (int)real_value_traits::link_mode != (int)auto_unlink ||
  231. // !floating_point
  232. // ));
  233. struct header_plus_alpha : public alpha_traits
  234. { node header_; };
  235. struct node_plus_pred_t : public detail::ebo_functor_holder<value_compare>
  236. {
  237. node_plus_pred_t(const value_compare &comp)
  238. : detail::ebo_functor_holder<value_compare>(comp)
  239. {}
  240. header_plus_alpha header_plus_alpha_;
  241. size_traits size_traits_;
  242. };
  243. struct data_t : public sgtree_impl::value_traits
  244. {
  245. typedef typename sgtree_impl::value_traits value_traits;
  246. data_t(const value_compare & comp, const value_traits &val_traits)
  247. : value_traits(val_traits), node_plus_pred_(comp)
  248. , max_tree_size_(0)
  249. {}
  250. node_plus_pred_t node_plus_pred_;
  251. size_type max_tree_size_;
  252. } data_;
  253. float priv_alpha() const
  254. { return this->priv_alpha_traits().get_alpha(); }
  255. void priv_alpha(float alpha)
  256. { return this->priv_alpha_traits().set_alpha(alpha); }
  257. const value_compare &priv_comp() const
  258. { return data_.node_plus_pred_.get(); }
  259. value_compare &priv_comp()
  260. { return data_.node_plus_pred_.get(); }
  261. const node &priv_header() const
  262. { return data_.node_plus_pred_.header_plus_alpha_.header_; }
  263. node &priv_header()
  264. { return data_.node_plus_pred_.header_plus_alpha_.header_; }
  265. static node_ptr uncast(const_node_ptr ptr)
  266. { return node_ptr(const_cast<node*>(detail::get_pointer(ptr))); }
  267. size_traits &priv_size_traits()
  268. { return data_.node_plus_pred_.size_traits_; }
  269. const size_traits &priv_size_traits() const
  270. { return data_.node_plus_pred_.size_traits_; }
  271. alpha_traits &priv_alpha_traits()
  272. { return data_.node_plus_pred_.header_plus_alpha_; }
  273. const alpha_traits &priv_alpha_traits() const
  274. { return data_.node_plus_pred_.header_plus_alpha_; }
  275. const real_value_traits &get_real_value_traits(detail::bool_<false>) const
  276. { return data_; }
  277. const real_value_traits &get_real_value_traits(detail::bool_<true>) const
  278. { return data_.get_value_traits(*this); }
  279. real_value_traits &get_real_value_traits(detail::bool_<false>)
  280. { return data_; }
  281. real_value_traits &get_real_value_traits(detail::bool_<true>)
  282. { return data_.get_value_traits(*this); }
  283. h_alpha_t get_h_alpha_func() const
  284. { return priv_alpha_traits().get_h_alpha_t(); }
  285. multiply_by_alpha_t get_alpha_by_max_size_func() const
  286. { return priv_alpha_traits().get_multiply_by_alpha_t(); }
  287. /// @endcond
  288. public:
  289. const real_value_traits &get_real_value_traits() const
  290. { return this->get_real_value_traits(detail::bool_<external_value_traits>()); }
  291. real_value_traits &get_real_value_traits()
  292. { return this->get_real_value_traits(detail::bool_<external_value_traits>()); }
  293. typedef typename node_algorithms::insert_commit_data insert_commit_data;
  294. //! <b>Effects</b>: Constructs an empty tree.
  295. //!
  296. //! <b>Complexity</b>: Constant.
  297. //!
  298. //! <b>Throws</b>: If value_traits::node_traits::node
  299. //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
  300. //! or the copy constructorof the value_compare object throws. Basic guarantee.
  301. sgtree_impl( const value_compare &cmp = value_compare()
  302. , const value_traits &v_traits = value_traits())
  303. : data_(cmp, v_traits)
  304. {
  305. node_algorithms::init_header(&priv_header());
  306. this->priv_size_traits().set_size(size_type(0));
  307. }
  308. //! <b>Requires</b>: Dereferencing iterator must yield an lvalue of type value_type.
  309. //! cmp must be a comparison function that induces a strict weak ordering.
  310. //!
  311. //! <b>Effects</b>: Constructs an empty tree and inserts elements from
  312. //! [b, e).
  313. //!
  314. //! <b>Complexity</b>: Linear in N if [b, e) is already sorted using
  315. //! comp and otherwise N * log N, where N is the distance between first and last.
  316. //!
  317. //! <b>Throws</b>: If value_traits::node_traits::node
  318. //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
  319. //! or the copy constructor/operator() of the value_compare object throws. Basic guarantee.
  320. template<class Iterator>
  321. sgtree_impl( bool unique, Iterator b, Iterator e
  322. , const value_compare &cmp = value_compare()
  323. , const value_traits &v_traits = value_traits())
  324. : data_(cmp, v_traits)
  325. {
  326. node_algorithms::init_header(&priv_header());
  327. this->priv_size_traits().set_size(size_type(0));
  328. if(unique)
  329. this->insert_unique(b, e);
  330. else
  331. this->insert_equal(b, e);
  332. }
  333. //! <b>Effects</b>: Detaches all elements from this. The objects in the set
  334. //! are not deleted (i.e. no destructors are called), but the nodes according to
  335. //! the value_traits template parameter are reinitialized and thus can be reused.
  336. //!
  337. //! <b>Complexity</b>: Linear to elements contained in *this.
  338. //!
  339. //! <b>Throws</b>: Nothing.
  340. ~sgtree_impl()
  341. {}
  342. //! <b>Effects</b>: Returns an iterator pointing to the beginning of the tree.
  343. //!
  344. //! <b>Complexity</b>: Constant.
  345. //!
  346. //! <b>Throws</b>: Nothing.
  347. iterator begin()
  348. { return iterator (node_traits::get_left(node_ptr(&priv_header())), this); }
  349. //! <b>Effects</b>: Returns a const_iterator pointing to the beginning of the tree.
  350. //!
  351. //! <b>Complexity</b>: Constant.
  352. //!
  353. //! <b>Throws</b>: Nothing.
  354. const_iterator begin() const
  355. { return cbegin(); }
  356. //! <b>Effects</b>: Returns a const_iterator pointing to the beginning of the tree.
  357. //!
  358. //! <b>Complexity</b>: Constant.
  359. //!
  360. //! <b>Throws</b>: Nothing.
  361. const_iterator cbegin() const
  362. { return const_iterator (node_traits::get_left(const_node_ptr(&priv_header())), this); }
  363. //! <b>Effects</b>: Returns an iterator pointing to the end of the tree.
  364. //!
  365. //! <b>Complexity</b>: Constant.
  366. //!
  367. //! <b>Throws</b>: Nothing.
  368. iterator end()
  369. { return iterator (node_ptr(&priv_header()), this); }
  370. //! <b>Effects</b>: Returns a const_iterator pointing to the end of the tree.
  371. //!
  372. //! <b>Complexity</b>: Constant.
  373. //!
  374. //! <b>Throws</b>: Nothing.
  375. const_iterator end() const
  376. { return cend(); }
  377. //! <b>Effects</b>: Returns a const_iterator pointing to the end of the tree.
  378. //!
  379. //! <b>Complexity</b>: Constant.
  380. //!
  381. //! <b>Throws</b>: Nothing.
  382. const_iterator cend() const
  383. { return const_iterator (uncast(const_node_ptr(&priv_header())), this); }
  384. //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning of the
  385. //! reversed tree.
  386. //!
  387. //! <b>Complexity</b>: Constant.
  388. //!
  389. //! <b>Throws</b>: Nothing.
  390. reverse_iterator rbegin()
  391. { return reverse_iterator(end()); }
  392. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
  393. //! of the reversed tree.
  394. //!
  395. //! <b>Complexity</b>: Constant.
  396. //!
  397. //! <b>Throws</b>: Nothing.
  398. const_reverse_iterator rbegin() const
  399. { return const_reverse_iterator(end()); }
  400. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
  401. //! of the reversed tree.
  402. //!
  403. //! <b>Complexity</b>: Constant.
  404. //!
  405. //! <b>Throws</b>: Nothing.
  406. const_reverse_iterator crbegin() const
  407. { return const_reverse_iterator(end()); }
  408. //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
  409. //! of the reversed tree.
  410. //!
  411. //! <b>Complexity</b>: Constant.
  412. //!
  413. //! <b>Throws</b>: Nothing.
  414. reverse_iterator rend()
  415. { return reverse_iterator(begin()); }
  416. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
  417. //! of the reversed tree.
  418. //!
  419. //! <b>Complexity</b>: Constant.
  420. //!
  421. //! <b>Throws</b>: Nothing.
  422. const_reverse_iterator rend() const
  423. { return const_reverse_iterator(begin()); }
  424. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
  425. //! of the reversed tree.
  426. //!
  427. //! <b>Complexity</b>: Constant.
  428. //!
  429. //! <b>Throws</b>: Nothing.
  430. const_reverse_iterator crend() const
  431. { return const_reverse_iterator(begin()); }
  432. //! <b>Precondition</b>: end_iterator must be a valid end iterator
  433. //! of sgtree.
  434. //!
  435. //! <b>Effects</b>: Returns a const reference to the sgtree associated to the end iterator
  436. //!
  437. //! <b>Throws</b>: Nothing.
  438. //!
  439. //! <b>Complexity</b>: Constant.
  440. static sgtree_impl &container_from_end_iterator(iterator end_iterator)
  441. { return priv_container_from_end_iterator(end_iterator); }
  442. //! <b>Precondition</b>: end_iterator must be a valid end const_iterator
  443. //! of sgtree.
  444. //!
  445. //! <b>Effects</b>: Returns a const reference to the sgtree associated to the end iterator
  446. //!
  447. //! <b>Throws</b>: Nothing.
  448. //!
  449. //! <b>Complexity</b>: Constant.
  450. static const sgtree_impl &container_from_end_iterator(const_iterator end_iterator)
  451. { return priv_container_from_end_iterator(end_iterator); }
  452. //! <b>Precondition</b>: it must be a valid iterator
  453. //! of rbtree.
  454. //!
  455. //! <b>Effects</b>: Returns a const reference to the tree associated to the iterator
  456. //!
  457. //! <b>Throws</b>: Nothing.
  458. //!
  459. //! <b>Complexity</b>: Logarithmic.
  460. static sgtree_impl &container_from_iterator(iterator it)
  461. { return priv_container_from_iterator(it); }
  462. //! <b>Precondition</b>: it must be a valid end const_iterator
  463. //! of rbtree.
  464. //!
  465. //! <b>Effects</b>: Returns a const reference to the tree associated to the iterator
  466. //!
  467. //! <b>Throws</b>: Nothing.
  468. //!
  469. //! <b>Complexity</b>: Logarithmic.
  470. static const sgtree_impl &container_from_iterator(const_iterator it)
  471. { return priv_container_from_iterator(it); }
  472. //! <b>Effects</b>: Returns the value_compare object used by the tree.
  473. //!
  474. //! <b>Complexity</b>: Constant.
  475. //!
  476. //! <b>Throws</b>: If value_compare copy-constructor throws.
  477. value_compare value_comp() const
  478. { return priv_comp(); }
  479. //! <b>Effects</b>: Returns true if the container is empty.
  480. //!
  481. //! <b>Complexity</b>: Constant.
  482. //!
  483. //! <b>Throws</b>: Nothing.
  484. bool empty() const
  485. { return node_algorithms::unique(const_node_ptr(&priv_header())); }
  486. //! <b>Effects</b>: Returns the number of elements stored in the tree.
  487. //!
  488. //! <b>Complexity</b>: Linear to elements contained in *this
  489. //! if constant-time size option is disabled. Constant time otherwise.
  490. //!
  491. //! <b>Throws</b>: Nothing.
  492. size_type size() const
  493. {
  494. if(constant_time_size)
  495. return this->priv_size_traits().get_size();
  496. else{
  497. return (size_type)node_algorithms::size(const_node_ptr(&priv_header()));
  498. }
  499. }
  500. //! <b>Effects</b>: Swaps the contents of two sgtrees.
  501. //!
  502. //! <b>Complexity</b>: Constant.
  503. //!
  504. //! <b>Throws</b>: If the comparison functor's swap call throws.
  505. void swap(sgtree_impl& other)
  506. {
  507. //This can throw
  508. using std::swap;
  509. swap(priv_comp(), priv_comp());
  510. swap(priv_alpha_traits(), priv_alpha_traits());
  511. swap(data_.max_tree_size_, other.data_.max_tree_size_);
  512. //These can't throw
  513. node_algorithms::swap_tree(node_ptr(&priv_header()), node_ptr(&other.priv_header()));
  514. if(constant_time_size){
  515. size_type backup = this->priv_size_traits().get_size();
  516. this->priv_size_traits().set_size(other.priv_size_traits().get_size());
  517. other.priv_size_traits().set_size(backup);
  518. }
  519. }
  520. //! <b>Requires</b>: value must be an lvalue
  521. //!
  522. //! <b>Effects</b>: Inserts value into the tree before the upper bound.
  523. //!
  524. //! <b>Complexity</b>: Average complexity for insert element is at
  525. //! most logarithmic.
  526. //!
  527. //! <b>Throws</b>: If the internal value_compare ordering function throws. Strong guarantee.
  528. //!
  529. //! <b>Note</b>: Does not affect the validity of iterators and references.
  530. //! No copy-constructors are called.
  531. iterator insert_equal(reference value)
  532. {
  533. detail::key_nodeptr_comp<value_compare, sgtree_impl>
  534. key_node_comp(priv_comp(), this);
  535. node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
  536. if(safemode_or_autounlink)
  537. BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
  538. this->priv_size_traits().increment();
  539. std::size_t max_tree_size = (std::size_t)data_.max_tree_size_;
  540. node_ptr p = node_algorithms::insert_equal_upper_bound
  541. (node_ptr(&priv_header()), to_insert, key_node_comp
  542. , (size_type)this->size(), this->get_h_alpha_func(), max_tree_size);
  543. data_.max_tree_size_ = (size_type)max_tree_size;
  544. return iterator(p, this);
  545. }
  546. //! <b>Requires</b>: value must be an lvalue, and "hint" must be
  547. //! a valid iterator.
  548. //!
  549. //! <b>Effects</b>: Inserts x into the tree, using "hint" as a hint to
  550. //! where it will be inserted. If "hint" is the upper_bound
  551. //! the insertion takes constant time (two comparisons in the worst case)
  552. //!
  553. //! <b>Complexity</b>: Logarithmic in general, but it is amortized
  554. //! constant time if t is inserted immediately before hint.
  555. //!
  556. //! <b>Throws</b>: Nothing.
  557. //!
  558. //! <b>Note</b>: Does not affect the validity of iterators and references.
  559. //! No copy-constructors are called.
  560. iterator insert_equal(const_iterator hint, reference value)
  561. {
  562. detail::key_nodeptr_comp<value_compare, sgtree_impl>
  563. key_node_comp(priv_comp(), this);
  564. node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
  565. if(safemode_or_autounlink)
  566. BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
  567. this->priv_size_traits().increment();
  568. std::size_t max_tree_size = (std::size_t)data_.max_tree_size_;
  569. node_ptr p = node_algorithms::insert_equal
  570. (node_ptr(&priv_header()), hint.pointed_node(), to_insert, key_node_comp
  571. , (std::size_t)this->size(), this->get_h_alpha_func(), max_tree_size);
  572. data_.max_tree_size_ = (size_type)max_tree_size;
  573. return iterator(p, this);
  574. }
  575. //! <b>Requires</b>: Dereferencing iterator must yield an lvalue
  576. //! of type value_type.
  577. //!
  578. //! <b>Effects</b>: Inserts a each element of a range into the tree
  579. //! before the upper bound of the key of each element.
  580. //!
  581. //! <b>Complexity</b>: Insert range is in general O(N * log(N)), where N is the
  582. //! size of the range. However, it is linear in N if the range is already sorted
  583. //! by value_comp().
  584. //!
  585. //! <b>Throws</b>: Nothing.
  586. //!
  587. //! <b>Note</b>: Does not affect the validity of iterators and references.
  588. //! No copy-constructors are called.
  589. template<class Iterator>
  590. void insert_equal(Iterator b, Iterator e)
  591. {
  592. iterator end(this->end());
  593. for (; b != e; ++b)
  594. this->insert_equal(end, *b);
  595. }
  596. //! <b>Requires</b>: value must be an lvalue
  597. //!
  598. //! <b>Effects</b>: Inserts value into the tree if the value
  599. //! is not already present.
  600. //!
  601. //! <b>Complexity</b>: Average complexity for insert element is at
  602. //! most logarithmic.
  603. //!
  604. //! <b>Throws</b>: Nothing.
  605. //!
  606. //! <b>Note</b>: Does not affect the validity of iterators and references.
  607. //! No copy-constructors are called.
  608. std::pair<iterator, bool> insert_unique(reference value)
  609. {
  610. insert_commit_data commit_data;
  611. std::pair<iterator, bool> ret = insert_unique_check(value, priv_comp(), commit_data);
  612. if(!ret.second)
  613. return ret;
  614. return std::pair<iterator, bool> (insert_unique_commit(value, commit_data), true);
  615. }
  616. //! <b>Requires</b>: value must be an lvalue, and "hint" must be
  617. //! a valid iterator
  618. //!
  619. //! <b>Effects</b>: Tries to insert x into the tree, using "hint" as a hint
  620. //! to where it will be inserted.
  621. //!
  622. //! <b>Complexity</b>: Logarithmic in general, but it is amortized
  623. //! constant time (two comparisons in the worst case)
  624. //! if t is inserted immediately before hint.
  625. //!
  626. //! <b>Throws</b>: Nothing.
  627. //!
  628. //! <b>Note</b>: Does not affect the validity of iterators and references.
  629. //! No copy-constructors are called.
  630. iterator insert_unique(const_iterator hint, reference value)
  631. {
  632. insert_commit_data commit_data;
  633. std::pair<iterator, bool> ret = insert_unique_check(hint, value, priv_comp(), commit_data);
  634. if(!ret.second)
  635. return ret.first;
  636. return insert_unique_commit(value, commit_data);
  637. }
  638. //! <b>Requires</b>: Dereferencing iterator must yield an lvalue
  639. //! of type value_type.
  640. //!
  641. //! <b>Effects</b>: Tries to insert each element of a range into the tree.
  642. //!
  643. //! <b>Complexity</b>: Insert range is in general O(N * log(N)), where N is the
  644. //! size of the range. However, it is linear in N if the range is already sorted
  645. //! by value_comp().
  646. //!
  647. //! <b>Throws</b>: Nothing.
  648. //!
  649. //! <b>Note</b>: Does not affect the validity of iterators and references.
  650. //! No copy-constructors are called.
  651. template<class Iterator>
  652. void insert_unique(Iterator b, Iterator e)
  653. {
  654. if(this->empty()){
  655. iterator end(this->end());
  656. for (; b != e; ++b)
  657. this->insert_unique(end, *b);
  658. }
  659. else{
  660. for (; b != e; ++b)
  661. this->insert_unique(*b);
  662. }
  663. }
  664. //! <b>Requires</b>: key_value_comp must be a comparison function that induces
  665. //! the same strict weak ordering as value_compare. The difference is that
  666. //! key_value_comp compares an arbitrary key with the contained values.
  667. //!
  668. //! <b>Effects</b>: Checks if a value can be inserted in the container, using
  669. //! a user provided key instead of the value itself.
  670. //!
  671. //! <b>Returns</b>: If there is an equivalent value
  672. //! returns a pair containing an iterator to the already present value
  673. //! and false. If the value can be inserted returns true in the returned
  674. //! pair boolean and fills "commit_data" that is meant to be used with
  675. //! the "insert_commit" function.
  676. //!
  677. //! <b>Complexity</b>: Average complexity is at most logarithmic.
  678. //!
  679. //! <b>Throws</b>: If the key_value_comp ordering function throws. Strong guarantee.
  680. //!
  681. //! <b>Notes</b>: This function is used to improve performance when constructing
  682. //! a value_type is expensive: if there is an equivalent value
  683. //! the constructed object must be discarded. Many times, the part of the
  684. //! node that is used to impose the order is much cheaper to construct
  685. //! than the value_type and this function offers the possibility to use that
  686. //! part to check if the insertion will be successful.
  687. //!
  688. //! If the check is successful, the user can construct the value_type and use
  689. //! "insert_commit" to insert the object in constant-time. This gives a total
  690. //! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)).
  691. //!
  692. //! "commit_data" remains valid for a subsequent "insert_commit" only if no more
  693. //! objects are inserted or erased from the container.
  694. template<class KeyType, class KeyValueCompare>
  695. std::pair<iterator, bool> insert_unique_check
  696. (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data)
  697. {
  698. detail::key_nodeptr_comp<KeyValueCompare, sgtree_impl>
  699. comp(key_value_comp, this);
  700. std::pair<node_ptr, bool> ret =
  701. (node_algorithms::insert_unique_check
  702. (node_ptr(&priv_header()), key, comp, commit_data));
  703. return std::pair<iterator, bool>(iterator(ret.first, this), ret.second);
  704. }
  705. //! <b>Requires</b>: key_value_comp must be a comparison function that induces
  706. //! the same strict weak ordering as value_compare. The difference is that
  707. //! key_value_comp compares an arbitrary key with the contained values.
  708. //!
  709. //! <b>Effects</b>: Checks if a value can be inserted in the container, using
  710. //! a user provided key instead of the value itself, using "hint"
  711. //! as a hint to where it will be inserted.
  712. //!
  713. //! <b>Returns</b>: If there is an equivalent value
  714. //! returns a pair containing an iterator to the already present value
  715. //! and false. If the value can be inserted returns true in the returned
  716. //! pair boolean and fills "commit_data" that is meant to be used with
  717. //! the "insert_commit" function.
  718. //!
  719. //! <b>Complexity</b>: Logarithmic in general, but it's amortized
  720. //! constant time if t is inserted immediately before hint.
  721. //!
  722. //! <b>Throws</b>: If the key_value_comp ordering function throws. Strong guarantee.
  723. //!
  724. //! <b>Notes</b>: This function is used to improve performance when constructing
  725. //! a value_type is expensive: if there is an equivalent value
  726. //! the constructed object must be discarded. Many times, the part of the
  727. //! constructing that is used to impose the order is much cheaper to construct
  728. //! than the value_type and this function offers the possibility to use that key
  729. //! to check if the insertion will be successful.
  730. //!
  731. //! If the check is successful, the user can construct the value_type and use
  732. //! "insert_commit" to insert the object in constant-time. This can give a total
  733. //! constant-time complexity to the insertion: check(O(1)) + commit(O(1)).
  734. //!
  735. //! "commit_data" remains valid for a subsequent "insert_commit" only if no more
  736. //! objects are inserted or erased from the container.
  737. template<class KeyType, class KeyValueCompare>
  738. std::pair<iterator, bool> insert_unique_check
  739. (const_iterator hint, const KeyType &key
  740. ,KeyValueCompare key_value_comp, insert_commit_data &commit_data)
  741. {
  742. detail::key_nodeptr_comp<KeyValueCompare, sgtree_impl>
  743. comp(key_value_comp, this);
  744. std::pair<node_ptr, bool> ret =
  745. (node_algorithms::insert_unique_check
  746. (node_ptr(&priv_header()), hint.pointed_node(), key, comp, commit_data));
  747. return std::pair<iterator, bool>(iterator(ret.first, this), ret.second);
  748. }
  749. //! <b>Requires</b>: value must be an lvalue of type value_type. commit_data
  750. //! must have been obtained from a previous call to "insert_check".
  751. //! No objects should have been inserted or erased from the container between
  752. //! the "insert_check" that filled "commit_data" and the call to "insert_commit".
  753. //!
  754. //! <b>Effects</b>: Inserts the value in the avl_set using the information obtained
  755. //! from the "commit_data" that a previous "insert_check" filled.
  756. //!
  757. //! <b>Returns</b>: An iterator to the newly inserted object.
  758. //!
  759. //! <b>Complexity</b>: Constant time.
  760. //!
  761. //! <b>Throws</b>: Nothing.
  762. //!
  763. //! <b>Notes</b>: This function has only sense if a "insert_check" has been
  764. //! previously executed to fill "commit_data". No value should be inserted or
  765. //! erased between the "insert_check" and "insert_commit" calls.
  766. iterator insert_unique_commit(reference value, const insert_commit_data &commit_data)
  767. {
  768. node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
  769. if(safemode_or_autounlink)
  770. BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
  771. this->priv_size_traits().increment();
  772. std::size_t max_tree_size = (std::size_t)data_.max_tree_size_;
  773. node_algorithms::insert_unique_commit
  774. ( node_ptr(&priv_header()), to_insert, commit_data
  775. , (std::size_t)this->size(), this->get_h_alpha_func(), max_tree_size);
  776. data_.max_tree_size_ = (size_type)max_tree_size;
  777. return iterator(to_insert, this);
  778. }
  779. //! <b>Requires</b>: value must be an lvalue, "pos" must be
  780. //! a valid iterator (or end) and must be the succesor of value
  781. //! once inserted according to the predicate
  782. //!
  783. //! <b>Effects</b>: Inserts x into the tree before "pos".
  784. //!
  785. //! <b>Complexity</b>: Constant time.
  786. //!
  787. //! <b>Throws</b>: Nothing.
  788. //!
  789. //! <b>Note</b>: This function does not check preconditions so if "pos" is not
  790. //! the successor of "value" tree ordering invariant will be broken.
  791. //! This is a low-level function to be used only for performance reasons
  792. //! by advanced users.
  793. iterator insert_before(const_iterator pos, reference value)
  794. {
  795. node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
  796. if(safemode_or_autounlink)
  797. BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
  798. this->priv_size_traits().increment();
  799. std::size_t max_tree_size = (std::size_t)data_.max_tree_size_;
  800. node_ptr p = node_algorithms::insert_before
  801. ( node_ptr(&priv_header()), pos.pointed_node(), to_insert
  802. , (size_type)this->size(), this->get_h_alpha_func(), max_tree_size);
  803. data_.max_tree_size_ = (size_type)max_tree_size;
  804. return iterator(p, this);
  805. }
  806. //! <b>Requires</b>: value must be an lvalue, and it must be no less
  807. //! than the greatest inserted key
  808. //!
  809. //! <b>Effects</b>: Inserts x into the tree in the last position.
  810. //!
  811. //! <b>Complexity</b>: Constant time.
  812. //!
  813. //! <b>Throws</b>: Nothing.
  814. //!
  815. //! <b>Note</b>: This function does not check preconditions so if value is
  816. //! less than the greatest inserted key tree ordering invariant will be broken.
  817. //! This function is slightly more efficient than using "insert_before".
  818. //! This is a low-level function to be used only for performance reasons
  819. //! by advanced users.
  820. void push_back(reference value)
  821. {
  822. node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
  823. if(safemode_or_autounlink)
  824. BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
  825. this->priv_size_traits().increment();
  826. std::size_t max_tree_size = (std::size_t)data_.max_tree_size_;
  827. node_algorithms::push_back
  828. ( node_ptr(&priv_header()), to_insert
  829. , (size_type)this->size(), this->get_h_alpha_func(), max_tree_size);
  830. data_.max_tree_size_ = (size_type)max_tree_size;
  831. }
  832. //! <b>Requires</b>: value must be an lvalue, and it must be no greater
  833. //! than the minimum inserted key
  834. //!
  835. //! <b>Effects</b>: Inserts x into the tree in the first position.
  836. //!
  837. //! <b>Complexity</b>: Constant time.
  838. //!
  839. //! <b>Throws</b>: Nothing.
  840. //!
  841. //! <b>Note</b>: This function does not check preconditions so if value is
  842. //! greater than the minimum inserted key tree ordering invariant will be broken.
  843. //! This function is slightly more efficient than using "insert_before".
  844. //! This is a low-level function to be used only for performance reasons
  845. //! by advanced users.
  846. void push_front(reference value)
  847. {
  848. node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
  849. if(safemode_or_autounlink)
  850. BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
  851. this->priv_size_traits().increment();
  852. std::size_t max_tree_size = (std::size_t)data_.max_tree_size_;
  853. node_algorithms::push_front
  854. ( node_ptr(&priv_header()), to_insert
  855. , (size_type)this->size(), this->get_h_alpha_func(), max_tree_size);
  856. data_.max_tree_size_ = (size_type)max_tree_size;
  857. }
  858. //! <b>Effects</b>: Erases the element pointed to by pos.
  859. //!
  860. //! <b>Complexity</b>: Average complexity for erase element is constant time.
  861. //!
  862. //! <b>Throws</b>: Nothing.
  863. //!
  864. //! <b>Note</b>: Invalidates the iterators (but not the references)
  865. //! to the erased elements. No destructors are called.
  866. iterator erase(const_iterator i)
  867. {
  868. const_iterator ret(i);
  869. ++ret;
  870. node_ptr to_erase(i.pointed_node());
  871. if(safemode_or_autounlink)
  872. BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!node_algorithms::unique(to_erase));
  873. std::size_t max_tree_size = data_.max_tree_size_;
  874. node_algorithms::erase
  875. ( &priv_header(), to_erase, (std::size_t)this->size()
  876. , max_tree_size, this->get_alpha_by_max_size_func());
  877. data_.max_tree_size_ = (size_type)max_tree_size;
  878. this->priv_size_traits().decrement();
  879. if(safemode_or_autounlink)
  880. node_algorithms::init(to_erase);
  881. return ret.unconst();
  882. }
  883. //! <b>Effects</b>: Erases the range pointed to by b end e.
  884. //!
  885. //! <b>Complexity</b>: Average complexity for erase range is at most
  886. //! O(log(size() + N)), where N is the number of elements in the range.
  887. //!
  888. //! <b>Throws</b>: Nothing.
  889. //!
  890. //! <b>Note</b>: Invalidates the iterators (but not the references)
  891. //! to the erased elements. No destructors are called.
  892. iterator erase(const_iterator b, const_iterator e)
  893. { size_type n; return private_erase(b, e, n); }
  894. //! <b>Effects</b>: Erases all the elements with the given value.
  895. //!
  896. //! <b>Returns</b>: The number of erased elements.
  897. //!
  898. //! <b>Complexity</b>: O(log(size() + N).
  899. //!
  900. //! <b>Throws</b>: Nothing.
  901. //!
  902. //! <b>Note</b>: Invalidates the iterators (but not the references)
  903. //! to the erased elements. No destructors are called.
  904. size_type erase(const_reference value)
  905. { return this->erase(value, priv_comp()); }
  906. //! <b>Effects</b>: Erases all the elements with the given key.
  907. //! according to the comparison functor "comp".
  908. //!
  909. //! <b>Returns</b>: The number of erased elements.
  910. //!
  911. //! <b>Complexity</b>: O(log(size() + N).
  912. //!
  913. //! <b>Throws</b>: Nothing.
  914. //!
  915. //! <b>Note</b>: Invalidates the iterators (but not the references)
  916. //! to the erased elements. No destructors are called.
  917. template<class KeyType, class KeyValueCompare>
  918. size_type erase(const KeyType& key, KeyValueCompare comp
  919. /// @cond
  920. , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
  921. /// @endcond
  922. )
  923. {
  924. std::pair<iterator,iterator> p = this->equal_range(key, comp);
  925. size_type n;
  926. private_erase(p.first, p.second, n);
  927. return n;
  928. }
  929. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
  930. //!
  931. //! <b>Effects</b>: Erases the element pointed to by pos.
  932. //! Disposer::operator()(pointer) is called for the removed element.
  933. //!
  934. //! <b>Complexity</b>: Average complexity for erase element is constant time.
  935. //!
  936. //! <b>Throws</b>: Nothing.
  937. //!
  938. //! <b>Note</b>: Invalidates the iterators
  939. //! to the erased elements.
  940. template<class Disposer>
  941. iterator erase_and_dispose(const_iterator i, Disposer disposer)
  942. {
  943. node_ptr to_erase(i.pointed_node());
  944. iterator ret(this->erase(i));
  945. disposer(get_real_value_traits().to_value_ptr(to_erase));
  946. return ret;
  947. }
  948. #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
  949. template<class Disposer>
  950. iterator erase_and_dispose(iterator i, Disposer disposer)
  951. { return this->erase_and_dispose(const_iterator(i), disposer); }
  952. #endif
  953. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
  954. //!
  955. //! <b>Effects</b>: Erases the range pointed to by b end e.
  956. //! Disposer::operator()(pointer) is called for the removed elements.
  957. //!
  958. //! <b>Complexity</b>: Average complexity for erase range is at most
  959. //! O(log(size() + N)), where N is the number of elements in the range.
  960. //!
  961. //! <b>Throws</b>: Nothing.
  962. //!
  963. //! <b>Note</b>: Invalidates the iterators
  964. //! to the erased elements.
  965. template<class Disposer>
  966. iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer)
  967. { size_type n; return private_erase(b, e, n, disposer); }
  968. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
  969. //!
  970. //! <b>Effects</b>: Erases all the elements with the given value.
  971. //! Disposer::operator()(pointer) is called for the removed elements.
  972. //!
  973. //! <b>Returns</b>: The number of erased elements.
  974. //!
  975. //! <b>Complexity</b>: O(log(size() + N).
  976. //!
  977. //! <b>Throws</b>: Nothing.
  978. //!
  979. //! <b>Note</b>: Invalidates the iterators (but not the references)
  980. //! to the erased elements. No destructors are called.
  981. template<class Disposer>
  982. size_type erase_and_dispose(const_reference value, Disposer disposer)
  983. {
  984. std::pair<iterator,iterator> p = this->equal_range(value);
  985. size_type n;
  986. private_erase(p.first, p.second, n, disposer);
  987. return n;
  988. }
  989. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
  990. //!
  991. //! <b>Effects</b>: Erases all the elements with the given key.
  992. //! according to the comparison functor "comp".
  993. //! Disposer::operator()(pointer) is called for the removed elements.
  994. //!
  995. //! <b>Returns</b>: The number of erased elements.
  996. //!
  997. //! <b>Complexity</b>: O(log(size() + N).
  998. //!
  999. //! <b>Throws</b>: Nothing.
  1000. //!
  1001. //! <b>Note</b>: Invalidates the iterators
  1002. //! to the erased elements.
  1003. template<class KeyType, class KeyValueCompare, class Disposer>
  1004. size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer
  1005. /// @cond
  1006. , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
  1007. /// @endcond
  1008. )
  1009. {
  1010. std::pair<iterator,iterator> p = this->equal_range(key, comp);
  1011. size_type n;
  1012. private_erase(p.first, p.second, n, disposer);
  1013. return n;
  1014. }
  1015. //! <b>Effects</b>: Erases all of the elements.
  1016. //!
  1017. //! <b>Complexity</b>: Linear to the number of elements on the container.
  1018. //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise.
  1019. //!
  1020. //! <b>Throws</b>: Nothing.
  1021. //!
  1022. //! <b>Note</b>: Invalidates the iterators (but not the references)
  1023. //! to the erased elements. No destructors are called.
  1024. void clear()
  1025. {
  1026. if(safemode_or_autounlink){
  1027. this->clear_and_dispose(detail::null_disposer());
  1028. }
  1029. else{
  1030. node_algorithms::init_header(&priv_header());
  1031. this->priv_size_traits().set_size(0);
  1032. }
  1033. }
  1034. //! <b>Effects</b>: Erases all of the elements calling disposer(p) for
  1035. //! each node to be erased.
  1036. //! <b>Complexity</b>: Average complexity for is at most O(log(size() + N)),
  1037. //! where N is the number of elements in the container.
  1038. //!
  1039. //! <b>Throws</b>: Nothing.
  1040. //!
  1041. //! <b>Note</b>: Invalidates the iterators (but not the references)
  1042. //! to the erased elements. Calls N times to disposer functor.
  1043. template<class Disposer>
  1044. void clear_and_dispose(Disposer disposer)
  1045. {
  1046. node_algorithms::clear_and_dispose(node_ptr(&priv_header())
  1047. , detail::node_disposer<Disposer, sgtree_impl>(disposer, this));
  1048. this->priv_size_traits().set_size(0);
  1049. }
  1050. //! <b>Effects</b>: Returns the number of contained elements with the given value
  1051. //!
  1052. //! <b>Complexity</b>: Logarithmic to the number of elements contained plus lineal
  1053. //! to number of objects with the given value.
  1054. //!
  1055. //! <b>Throws</b>: Nothing.
  1056. size_type count(const_reference value) const
  1057. { return this->count(value, priv_comp()); }
  1058. //! <b>Effects</b>: Returns the number of contained elements with the given key
  1059. //!
  1060. //! <b>Complexity</b>: Logarithmic to the number of elements contained plus lineal
  1061. //! to number of objects with the given key.
  1062. //!
  1063. //! <b>Throws</b>: Nothing.
  1064. template<class KeyType, class KeyValueCompare>
  1065. size_type count(const KeyType &key, KeyValueCompare comp) const
  1066. {
  1067. std::pair<const_iterator, const_iterator> ret = this->equal_range(key, comp);
  1068. return std::distance(ret.first, ret.second);
  1069. }
  1070. //! <b>Effects</b>: Returns an iterator to the first element whose
  1071. //! key is not less than k or end() if that element does not exist.
  1072. //!
  1073. //! <b>Complexity</b>: Logarithmic.
  1074. //!
  1075. //! <b>Throws</b>: Nothing.
  1076. iterator lower_bound(const_reference value)
  1077. { return this->lower_bound(value, priv_comp()); }
  1078. //! <b>Effects</b>: Returns an iterator to the first element whose
  1079. //! key is not less than k or end() if that element does not exist.
  1080. //!
  1081. //! <b>Complexity</b>: Logarithmic.
  1082. //!
  1083. //! <b>Throws</b>: Nothing.
  1084. const_iterator lower_bound(const_reference value) const
  1085. { return this->lower_bound(value, priv_comp()); }
  1086. //! <b>Effects</b>: Returns an iterator to the first element whose
  1087. //! key is not less than k or end() if that element does not exist.
  1088. //!
  1089. //! <b>Complexity</b>: Logarithmic.
  1090. //!
  1091. //! <b>Throws</b>: Nothing.
  1092. template<class KeyType, class KeyValueCompare>
  1093. iterator lower_bound(const KeyType &key, KeyValueCompare comp)
  1094. {
  1095. detail::key_nodeptr_comp<KeyValueCompare, sgtree_impl>
  1096. key_node_comp(comp, this);
  1097. return iterator(node_algorithms::lower_bound
  1098. (const_node_ptr(&priv_header()), key, key_node_comp), this);
  1099. }
  1100. //! <b>Effects</b>: Returns a const iterator to the first element whose
  1101. //! key is not less than k or end() if that element does not exist.
  1102. //!
  1103. //! <b>Complexity</b>: Logarithmic.
  1104. //!
  1105. //! <b>Throws</b>: Nothing.
  1106. template<class KeyType, class KeyValueCompare>
  1107. const_iterator lower_bound(const KeyType &key, KeyValueCompare comp) const
  1108. {
  1109. detail::key_nodeptr_comp<KeyValueCompare, sgtree_impl>
  1110. key_node_comp(comp, this);
  1111. return const_iterator(node_algorithms::lower_bound
  1112. (const_node_ptr(&priv_header()), key, key_node_comp), this);
  1113. }
  1114. //! <b>Effects</b>: Returns an iterator to the first element whose
  1115. //! key is greater than k or end() if that element does not exist.
  1116. //!
  1117. //! <b>Complexity</b>: Logarithmic.
  1118. //!
  1119. //! <b>Throws</b>: Nothing.
  1120. iterator upper_bound(const_reference value)
  1121. { return this->upper_bound(value, priv_comp()); }
  1122. //! <b>Effects</b>: Returns an iterator to the first element whose
  1123. //! key is greater than k according to comp or end() if that element
  1124. //! does not exist.
  1125. //!
  1126. //! <b>Complexity</b>: Logarithmic.
  1127. //!
  1128. //! <b>Throws</b>: Nothing.
  1129. template<class KeyType, class KeyValueCompare>
  1130. iterator upper_bound(const KeyType &key, KeyValueCompare comp)
  1131. {
  1132. detail::key_nodeptr_comp<KeyValueCompare, sgtree_impl>
  1133. key_node_comp(comp, this);
  1134. return iterator(node_algorithms::upper_bound
  1135. (const_node_ptr(&priv_header()), key, key_node_comp), this);
  1136. }
  1137. //! <b>Effects</b>: Returns an iterator to the first element whose
  1138. //! key is greater than k or end() if that element does not exist.
  1139. //!
  1140. //! <b>Complexity</b>: Logarithmic.
  1141. //!
  1142. //! <b>Throws</b>: Nothing.
  1143. const_iterator upper_bound(const_reference value) const
  1144. { return this->upper_bound(value, priv_comp()); }
  1145. //! <b>Effects</b>: Returns an iterator to the first element whose
  1146. //! key is greater than k according to comp or end() if that element
  1147. //! does not exist.
  1148. //!
  1149. //! <b>Complexity</b>: Logarithmic.
  1150. //!
  1151. //! <b>Throws</b>: Nothing.
  1152. template<class KeyType, class KeyValueCompare>
  1153. const_iterator upper_bound(const KeyType &key, KeyValueCompare comp) const
  1154. {
  1155. detail::key_nodeptr_comp<KeyValueCompare, sgtree_impl>
  1156. key_node_comp(comp, this);
  1157. return const_iterator(node_algorithms::upper_bound
  1158. (const_node_ptr(&priv_header()), key, key_node_comp), this);
  1159. }
  1160. //! <b>Effects</b>: Finds an iterator to the first element whose key is
  1161. //! k or end() if that element does not exist.
  1162. //!
  1163. //! <b>Complexity</b>: Logarithmic.
  1164. //!
  1165. //! <b>Throws</b>: Nothing.
  1166. iterator find(const_reference value)
  1167. { return this->find(value, priv_comp()); }
  1168. //! <b>Effects</b>: Finds an iterator to the first element whose key is
  1169. //! k or end() if that element does not exist.
  1170. //!
  1171. //! <b>Complexity</b>: Logarithmic.
  1172. //!
  1173. //! <b>Throws</b>: Nothing.
  1174. template<class KeyType, class KeyValueCompare>
  1175. iterator find(const KeyType &key, KeyValueCompare comp)
  1176. {
  1177. detail::key_nodeptr_comp<KeyValueCompare, sgtree_impl>
  1178. key_node_comp(comp, this);
  1179. return iterator
  1180. (node_algorithms::find(const_node_ptr(&priv_header()), key, key_node_comp), this);
  1181. }
  1182. //! <b>Effects</b>: Finds a const_iterator to the first element whose key is
  1183. //! k or end() if that element does not exist.
  1184. //!
  1185. //! <b>Complexity</b>: Logarithmic.
  1186. //!
  1187. //! <b>Throws</b>: Nothing.
  1188. const_iterator find(const_reference value) const
  1189. { return this->find(value, priv_comp()); }
  1190. //! <b>Effects</b>: Finds a const_iterator to the first element whose key is
  1191. //! k or end() if that element does not exist.
  1192. //!
  1193. //! <b>Complexity</b>: Logarithmic.
  1194. //!
  1195. //! <b>Throws</b>: Nothing.
  1196. template<class KeyType, class KeyValueCompare>
  1197. const_iterator find(const KeyType &key, KeyValueCompare comp) const
  1198. {
  1199. detail::key_nodeptr_comp<KeyValueCompare, sgtree_impl>
  1200. key_node_comp(comp, this);
  1201. return const_iterator
  1202. (node_algorithms::find(const_node_ptr(&priv_header()), key, key_node_comp), this);
  1203. }
  1204. //! <b>Effects</b>: Finds a range containing all elements whose key is k or
  1205. //! an empty range that indicates the position where those elements would be
  1206. //! if they there is no elements with key k.
  1207. //!
  1208. //! <b>Complexity</b>: Logarithmic.
  1209. //!
  1210. //! <b>Throws</b>: Nothing.
  1211. std::pair<iterator,iterator> equal_range(const_reference value)
  1212. { return this->equal_range(value, priv_comp()); }
  1213. //! <b>Effects</b>: Finds a range containing all elements whose key is k or
  1214. //! an empty range that indicates the position where those elements would be
  1215. //! if they there is no elements with key k.
  1216. //!
  1217. //! <b>Complexity</b>: Logarithmic.
  1218. //!
  1219. //! <b>Throws</b>: Nothing.
  1220. template<class KeyType, class KeyValueCompare>
  1221. std::pair<iterator,iterator> equal_range(const KeyType &key, KeyValueCompare comp)
  1222. {
  1223. detail::key_nodeptr_comp<KeyValueCompare, sgtree_impl>
  1224. key_node_comp(comp, this);
  1225. std::pair<node_ptr, node_ptr> ret
  1226. (node_algorithms::equal_range(const_node_ptr(&priv_header()), key, key_node_comp));
  1227. return std::pair<iterator, iterator>(iterator(ret.first, this), iterator(ret.second, this));
  1228. }
  1229. //! <b>Effects</b>: Finds a range containing all elements whose key is k or
  1230. //! an empty range that indicates the position where those elements would be
  1231. //! if they there is no elements with key k.
  1232. //!
  1233. //! <b>Complexity</b>: Logarithmic.
  1234. //!
  1235. //! <b>Throws</b>: Nothing.
  1236. std::pair<const_iterator, const_iterator>
  1237. equal_range(const_reference value) const
  1238. { return this->equal_range(value, priv_comp()); }
  1239. //! <b>Effects</b>: Finds a range containing all elements whose key is k or
  1240. //! an empty range that indicates the position where those elements would be
  1241. //! if they there is no elements with key k.
  1242. //!
  1243. //! <b>Complexity</b>: Logarithmic.
  1244. //!
  1245. //! <b>Throws</b>: Nothing.
  1246. template<class KeyType, class KeyValueCompare>
  1247. std::pair<const_iterator, const_iterator>
  1248. equal_range(const KeyType &key, KeyValueCompare comp) const
  1249. {
  1250. detail::key_nodeptr_comp<KeyValueCompare, sgtree_impl>
  1251. key_node_comp(comp, this);
  1252. std::pair<node_ptr, node_ptr> ret
  1253. (node_algorithms::equal_range(const_node_ptr(&priv_header()), key, key_node_comp));
  1254. return std::pair<const_iterator, const_iterator>(const_iterator(ret.first, this), const_iterator(ret.second, this));
  1255. }
  1256. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
  1257. //! Cloner should yield to nodes equivalent to the original nodes.
  1258. //!
  1259. //! <b>Effects</b>: Erases all the elements from *this
  1260. //! calling Disposer::operator()(pointer), clones all the
  1261. //! elements from src calling Cloner::operator()(const_reference )
  1262. //! and inserts them on *this. Copies the predicate from the source container.
  1263. //!
  1264. //! If cloner throws, all cloned elements are unlinked and disposed
  1265. //! calling Disposer::operator()(pointer).
  1266. //!
  1267. //! <b>Complexity</b>: Linear to erased plus inserted elements.
  1268. //!
  1269. //! <b>Throws</b>: If cloner throws or predicate copy assignment throws. Basic guarantee.
  1270. template <class Cloner, class Disposer>
  1271. void clone_from(const sgtree_impl &src, Cloner cloner, Disposer disposer)
  1272. {
  1273. this->clear_and_dispose(disposer);
  1274. if(!src.empty()){
  1275. detail::exception_disposer<sgtree_impl, Disposer>
  1276. rollback(*this, disposer);
  1277. node_algorithms::clone
  1278. (const_node_ptr(&src.priv_header())
  1279. ,node_ptr(&this->priv_header())
  1280. ,detail::node_cloner<Cloner, sgtree_impl>(cloner, this)
  1281. ,detail::node_disposer<Disposer, sgtree_impl>(disposer, this));
  1282. this->priv_size_traits().set_size(src.priv_size_traits().get_size());
  1283. this->priv_comp() = src.priv_comp();
  1284. rollback.release();
  1285. }
  1286. }
  1287. //! <b>Effects</b>: Unlinks the leftmost node from the tree.
  1288. //!
  1289. //! <b>Complexity</b>: Average complexity is constant time.
  1290. //!
  1291. //! <b>Throws</b>: Nothing.
  1292. //!
  1293. //! <b>Notes</b>: This function breaks the tree and the tree can
  1294. //! only be used for more unlink_leftmost_without_rebalance calls.
  1295. //! This function is normally used to achieve a step by step
  1296. //! controlled destruction of the tree.
  1297. pointer unlink_leftmost_without_rebalance()
  1298. {
  1299. node_ptr to_be_disposed(node_algorithms::unlink_leftmost_without_rebalance
  1300. (node_ptr(&priv_header())));
  1301. if(!to_be_disposed)
  1302. return 0;
  1303. this->priv_size_traits().decrement();
  1304. if(safemode_or_autounlink)//If this is commented does not work with normal_link
  1305. node_algorithms::init(to_be_disposed);
  1306. return get_real_value_traits().to_value_ptr(to_be_disposed);
  1307. }
  1308. //! <b>Requires</b>: replace_this must be a valid iterator of *this
  1309. //! and with_this must not be inserted in any tree.
  1310. //!
  1311. //! <b>Effects</b>: Replaces replace_this in its position in the
  1312. //! tree with with_this. The tree does not need to be rebalanced.
  1313. //!
  1314. //! <b>Complexity</b>: Constant.
  1315. //!
  1316. //! <b>Throws</b>: Nothing.
  1317. //!
  1318. //! <b>Note</b>: This function will break container ordering invariants if
  1319. //! with_this is not equivalent to *replace_this according to the
  1320. //! ordering rules. This function is faster than erasing and inserting
  1321. //! the node, since no rebalancing or comparison is needed.
  1322. void replace_node(iterator replace_this, reference with_this)
  1323. {
  1324. node_algorithms::replace_node( get_real_value_traits().to_node_ptr(*replace_this)
  1325. , node_ptr(&priv_header())
  1326. , get_real_value_traits().to_node_ptr(with_this));
  1327. }
  1328. //! <b>Requires</b>: value must be an lvalue and shall be in a set of
  1329. //! appropriate type. Otherwise the behavior is undefined.
  1330. //!
  1331. //! <b>Effects</b>: Returns: a valid iterator i belonging to the set
  1332. //! that points to the value
  1333. //!
  1334. //! <b>Complexity</b>: Constant.
  1335. //!
  1336. //! <b>Throws</b>: Nothing.
  1337. //!
  1338. //! <b>Note</b>: This static function is available only if the <i>value traits</i>
  1339. //! is stateless.
  1340. static iterator s_iterator_to(reference value)
  1341. {
  1342. BOOST_STATIC_ASSERT((!stateful_value_traits));
  1343. return iterator (value_traits::to_node_ptr(value), 0);
  1344. }
  1345. //! <b>Requires</b>: value must be an lvalue and shall be in a set of
  1346. //! appropriate type. Otherwise the behavior is undefined.
  1347. //!
  1348. //! <b>Effects</b>: Returns: a valid const_iterator i belonging to the
  1349. //! set that points to the value
  1350. //!
  1351. //! <b>Complexity</b>: Constant.
  1352. //!
  1353. //! <b>Throws</b>: Nothing.
  1354. //!
  1355. //! <b>Note</b>: This static function is available only if the <i>value traits</i>
  1356. //! is stateless.
  1357. static const_iterator s_iterator_to(const_reference value)
  1358. {
  1359. BOOST_STATIC_ASSERT((!stateful_value_traits));
  1360. return const_iterator (value_traits::to_node_ptr(const_cast<reference> (value)), 0);
  1361. }
  1362. //! <b>Requires</b>: value must be an lvalue and shall be in a set of
  1363. //! appropriate type. Otherwise the behavior is undefined.
  1364. //!
  1365. //! <b>Effects</b>: Returns: a valid iterator i belonging to the set
  1366. //! that points to the value
  1367. //!
  1368. //! <b>Complexity</b>: Constant.
  1369. //!
  1370. //! <b>Throws</b>: Nothing.
  1371. iterator iterator_to(reference value)
  1372. { return iterator (value_traits::to_node_ptr(value), this); }
  1373. //! <b>Requires</b>: value must be an lvalue and shall be in a set of
  1374. //! appropriate type. Otherwise the behavior is undefined.
  1375. //!
  1376. //! <b>Effects</b>: Returns: a valid const_iterator i belonging to the
  1377. //! set that points to the value
  1378. //!
  1379. //! <b>Complexity</b>: Constant.
  1380. //!
  1381. //! <b>Throws</b>: Nothing.
  1382. const_iterator iterator_to(const_reference value) const
  1383. { return const_iterator (value_traits::to_node_ptr(const_cast<reference> (value)), this); }
  1384. //! <b>Requires</b>: value shall not be in a tree.
  1385. //!
  1386. //! <b>Effects</b>: init_node puts the hook of a value in a well-known default
  1387. //! state.
  1388. //!
  1389. //! <b>Throws</b>: Nothing.
  1390. //!
  1391. //! <b>Complexity</b>: Constant time.
  1392. //!
  1393. //! <b>Note</b>: This function puts the hook in the well-known default state
  1394. //! used by auto_unlink and safe hooks.
  1395. static void init_node(reference value)
  1396. { node_algorithms::init(value_traits::to_node_ptr(value)); }
  1397. //! <b>Effects</b>: Rebalances the tree.
  1398. //!
  1399. //! <b>Throws</b>: Nothing.
  1400. //!
  1401. //! <b>Complexity</b>: Linear.
  1402. void rebalance()
  1403. { node_algorithms::rebalance(node_ptr(&priv_header())); }
  1404. //! <b>Requires</b>: old_root is a node of a tree.
  1405. //!
  1406. //! <b>Effects</b>: Rebalances the subtree rooted at old_root.
  1407. //!
  1408. //! <b>Returns</b>: The new root of the subtree.
  1409. //!
  1410. //! <b>Throws</b>: Nothing.
  1411. //!
  1412. //! <b>Complexity</b>: Linear to the elements in the subtree.
  1413. iterator rebalance_subtree(iterator root)
  1414. { return iterator(node_algorithms::rebalance_subtree(root.pointed_node()), this); }
  1415. //! <b>Returns</b>: The balance factor (alpha) used in this tree
  1416. //!
  1417. //! <b>Throws</b>: Nothing.
  1418. //!
  1419. //! <b>Complexity</b>: Constant.
  1420. float balance_factor() const
  1421. { return this->priv_alpha(); }
  1422. //! <b>Requires</b>: new_alpha must be a value between 0.5 and 1.0
  1423. //!
  1424. //! <b>Effects</b>: Establishes a new balance factor (alpha) and rebalances
  1425. //! the tree if the new balance factor is stricter (less) than the old factor.
  1426. //!
  1427. //! <b>Throws</b>: Nothing.
  1428. //!
  1429. //! <b>Complexity</b>: Linear to the elements in the subtree.
  1430. void balance_factor(float new_alpha)
  1431. {
  1432. BOOST_INTRUSIVE_INVARIANT_ASSERT((new_alpha > 0.5f && new_alpha < 1.0f));
  1433. if(new_alpha < 0.5f && new_alpha >= 1.0f) return;
  1434. //The alpha factor CAN't be changed if the fixed, floating operation-less
  1435. //1/sqrt(2) alpha factor option is activated
  1436. BOOST_STATIC_ASSERT((floating_point));
  1437. float old_alpha = this->priv_alpha();
  1438. this->priv_alpha(new_alpha);
  1439. if(new_alpha < old_alpha){
  1440. data_.max_tree_size_ = this->size();
  1441. this->rebalance();
  1442. }
  1443. }
  1444. /*
  1445. //! <b>Effects</b>: removes x from a tree of the appropriate type. It has no effect,
  1446. //! if x is not in such a tree.
  1447. //!
  1448. //! <b>Throws</b>: Nothing.
  1449. //!
  1450. //! <b>Complexity</b>: Constant time.
  1451. //!
  1452. //! <b>Note</b>: This static function is only usable with the "safe mode"
  1453. //! hook and non-constant time size lists. Otherwise, the user must use
  1454. //! the non-static "erase(reference )" member. If the user calls
  1455. //! this function with a non "safe mode" or constant time size list
  1456. //! a compilation error will be issued.
  1457. template<class T>
  1458. static void remove_node(T& value)
  1459. {
  1460. //This function is only usable for safe mode hooks and non-constant
  1461. //time lists.
  1462. //BOOST_STATIC_ASSERT((!(safemode_or_autounlink && constant_time_size)));
  1463. BOOST_STATIC_ASSERT((!constant_time_size));
  1464. BOOST_STATIC_ASSERT((boost::is_convertible<T, value_type>::value));
  1465. node_ptr to_remove(value_traits::to_node_ptr(value));
  1466. node_algorithms::unlink_and_rebalance(to_remove);
  1467. if(safemode_or_autounlink)
  1468. node_algorithms::init(to_remove);
  1469. }
  1470. */
  1471. /// @cond
  1472. private:
  1473. template<class Disposer>
  1474. iterator private_erase(const_iterator b, const_iterator e, size_type &n, Disposer disposer)
  1475. {
  1476. for(n = 0; b != e; ++n)
  1477. this->erase_and_dispose(b++, disposer);
  1478. return b.unconst();
  1479. }
  1480. iterator private_erase(const_iterator b, const_iterator e, size_type &n)
  1481. {
  1482. for(n = 0; b != e; ++n)
  1483. this->erase(b++);
  1484. return b.unconst();
  1485. }
  1486. /// @endcond
  1487. private:
  1488. static sgtree_impl &priv_container_from_end_iterator(const const_iterator &end_iterator)
  1489. {
  1490. header_plus_alpha *r = detail::parent_from_member<header_plus_alpha, node>
  1491. ( detail::get_pointer(end_iterator.pointed_node()), &header_plus_alpha::header_);
  1492. node_plus_pred_t *n = detail::parent_from_member
  1493. <node_plus_pred_t, header_plus_alpha>(r, &node_plus_pred_t::header_plus_alpha_);
  1494. data_t *d = detail::parent_from_member<data_t, node_plus_pred_t>(n, &data_t::node_plus_pred_);
  1495. sgtree_impl *scapegoat = detail::parent_from_member<sgtree_impl, data_t>(d, &sgtree_impl::data_);
  1496. return *scapegoat;
  1497. }
  1498. static sgtree_impl &priv_container_from_iterator(const const_iterator &it)
  1499. { return priv_container_from_end_iterator(it.end_iterator_from_it()); }
  1500. };
  1501. #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
  1502. template<class T, class ...Options>
  1503. #else
  1504. template<class Config>
  1505. #endif
  1506. inline bool operator<
  1507. #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
  1508. (const sgtree_impl<T, Options...> &x, const sgtree_impl<T, Options...> &y)
  1509. #else
  1510. (const sgtree_impl<Config> &x, const sgtree_impl<Config> &y)
  1511. #endif
  1512. { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
  1513. #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
  1514. template<class T, class ...Options>
  1515. #else
  1516. template<class Config>
  1517. #endif
  1518. bool operator==
  1519. #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
  1520. (const sgtree_impl<T, Options...> &x, const sgtree_impl<T, Options...> &y)
  1521. #else
  1522. (const sgtree_impl<Config> &x, const sgtree_impl<Config> &y)
  1523. #endif
  1524. {
  1525. typedef sgtree_impl<Config> tree_type;
  1526. typedef typename tree_type::const_iterator const_iterator;
  1527. if(tree_type::constant_time_size && x.size() != y.size()){
  1528. return false;
  1529. }
  1530. const_iterator end1 = x.end();
  1531. const_iterator i1 = x.begin();
  1532. const_iterator i2 = y.begin();
  1533. if(tree_type::constant_time_size){
  1534. while (i1 != end1 && *i1 == *i2) {
  1535. ++i1;
  1536. ++i2;
  1537. }
  1538. return i1 == end1;
  1539. }
  1540. else{
  1541. const_iterator end2 = y.end();
  1542. while (i1 != end1 && i2 != end2 && *i1 == *i2) {
  1543. ++i1;
  1544. ++i2;
  1545. }
  1546. return i1 == end1 && i2 == end2;
  1547. }
  1548. }
  1549. #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
  1550. template<class T, class ...Options>
  1551. #else
  1552. template<class Config>
  1553. #endif
  1554. inline bool operator!=
  1555. #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
  1556. (const sgtree_impl<T, Options...> &x, const sgtree_impl<T, Options...> &y)
  1557. #else
  1558. (const sgtree_impl<Config> &x, const sgtree_impl<Config> &y)
  1559. #endif
  1560. { return !(x == y); }
  1561. #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
  1562. template<class T, class ...Options>
  1563. #else
  1564. template<class Config>
  1565. #endif
  1566. inline bool operator>
  1567. #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
  1568. (const sgtree_impl<T, Options...> &x, const sgtree_impl<T, Options...> &y)
  1569. #else
  1570. (const sgtree_impl<Config> &x, const sgtree_impl<Config> &y)
  1571. #endif
  1572. { return y < x; }
  1573. #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
  1574. template<class T, class ...Options>
  1575. #else
  1576. template<class Config>
  1577. #endif
  1578. inline bool operator<=
  1579. #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
  1580. (const sgtree_impl<T, Options...> &x, const sgtree_impl<T, Options...> &y)
  1581. #else
  1582. (const sgtree_impl<Config> &x, const sgtree_impl<Config> &y)
  1583. #endif
  1584. { return !(y < x); }
  1585. #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
  1586. template<class T, class ...Options>
  1587. #else
  1588. template<class Config>
  1589. #endif
  1590. inline bool operator>=
  1591. #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
  1592. (const sgtree_impl<T, Options...> &x, const sgtree_impl<T, Options...> &y)
  1593. #else
  1594. (const sgtree_impl<Config> &x, const sgtree_impl<Config> &y)
  1595. #endif
  1596. { return !(x < y); }
  1597. #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
  1598. template<class T, class ...Options>
  1599. #else
  1600. template<class Config>
  1601. #endif
  1602. inline void swap
  1603. #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
  1604. (sgtree_impl<T, Options...> &x, sgtree_impl<T, Options...> &y)
  1605. #else
  1606. (sgtree_impl<Config> &x, sgtree_impl<Config> &y)
  1607. #endif
  1608. { x.swap(y); }
  1609. /// @cond
  1610. #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
  1611. template<class T, class O1 = none, class O2 = none
  1612. , class O3 = none, class O4 = none>
  1613. #else
  1614. template<class T, class ...Options>
  1615. #endif
  1616. struct make_sgtree_opt
  1617. {
  1618. typedef typename pack_options
  1619. < sg_set_defaults<T>,
  1620. #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
  1621. O1, O2, O3, O4
  1622. #else
  1623. Options...
  1624. #endif
  1625. >::type packed_options;
  1626. typedef typename detail::get_value_traits
  1627. <T, typename packed_options::value_traits>::type value_traits;
  1628. typedef sg_setopt
  1629. < value_traits
  1630. , typename packed_options::compare
  1631. , typename packed_options::size_type
  1632. , packed_options::floating_point
  1633. > type;
  1634. };
  1635. /// @endcond
  1636. //! Helper metafunction to define a \c sgtree that yields to the same type when the
  1637. //! same options (either explicitly or implicitly) are used.
  1638. #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
  1639. template<class T, class ...Options>
  1640. #else
  1641. template<class T, class O1 = none, class O2 = none
  1642. , class O3 = none, class O4 = none>
  1643. #endif
  1644. struct make_sgtree
  1645. {
  1646. /// @cond
  1647. typedef sgtree_impl
  1648. < typename make_sgtree_opt<T,
  1649. #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
  1650. O1, O2, O3, O4
  1651. #else
  1652. Options...
  1653. #endif
  1654. >::type
  1655. > implementation_defined;
  1656. /// @endcond
  1657. typedef implementation_defined type;
  1658. };
  1659. #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
  1660. #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
  1661. template<class T, class O1, class O2, class O3, class O4>
  1662. #else
  1663. template<class T, class ...Options>
  1664. #endif
  1665. class sgtree
  1666. : public make_sgtree<T,
  1667. #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
  1668. O1, O2, O3, O4
  1669. #else
  1670. Options...
  1671. #endif
  1672. >::type
  1673. {
  1674. typedef typename make_sgtree
  1675. <T,
  1676. #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
  1677. O1, O2, O3, O4
  1678. #else
  1679. Options...
  1680. #endif
  1681. >::type Base;
  1682. public:
  1683. typedef typename Base::value_compare value_compare;
  1684. typedef typename Base::value_traits value_traits;
  1685. typedef typename Base::real_value_traits real_value_traits;
  1686. typedef typename Base::iterator iterator;
  1687. typedef typename Base::const_iterator const_iterator;
  1688. //Assert if passed value traits are compatible with the type
  1689. BOOST_STATIC_ASSERT((detail::is_same<typename real_value_traits::value_type, T>::value));
  1690. sgtree( const value_compare &cmp = value_compare()
  1691. , const value_traits &v_traits = value_traits())
  1692. : Base(cmp, v_traits)
  1693. {}
  1694. template<class Iterator>
  1695. sgtree( bool unique, Iterator b, Iterator e
  1696. , const value_compare &cmp = value_compare()
  1697. , const value_traits &v_traits = value_traits())
  1698. : Base(unique, b, e, cmp, v_traits)
  1699. {}
  1700. static sgtree &container_from_end_iterator(iterator end_iterator)
  1701. { return static_cast<sgtree &>(Base::container_from_end_iterator(end_iterator)); }
  1702. static const sgtree &container_from_end_iterator(const_iterator end_iterator)
  1703. { return static_cast<const sgtree &>(Base::container_from_end_iterator(end_iterator)); }
  1704. };
  1705. #endif
  1706. } //namespace intrusive
  1707. } //namespace boost
  1708. #include <boost/intrusive/detail/config_end.hpp>
  1709. #endif //BOOST_INTRUSIVE_SGTREE_HPP