sgtree.hpp 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073
  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2007-2014
  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 <boost/intrusive/intrusive_fwd.hpp>
  21. #include <boost/intrusive/detail/assert.hpp>
  22. #include <boost/static_assert.hpp>
  23. #include <boost/intrusive/bs_set_hook.hpp>
  24. #include <boost/intrusive/bstree.hpp>
  25. #include <boost/intrusive/detail/tree_node.hpp>
  26. #include <boost/intrusive/pointer_traits.hpp>
  27. #include <boost/intrusive/detail/mpl.hpp>
  28. #include <boost/intrusive/detail/math.hpp>
  29. #include <boost/intrusive/detail/get_value_traits.hpp>
  30. #include <boost/intrusive/sgtree_algorithms.hpp>
  31. #include <boost/intrusive/detail/key_nodeptr_comp.hpp>
  32. #include <boost/intrusive/link_mode.hpp>
  33. #include <boost/move/utility_core.hpp>
  34. #include <boost/move/adl_move_swap.hpp>
  35. #include <cstddef>
  36. #include <boost/intrusive/detail/minimal_less_equal_header.hpp>
  37. #include <boost/intrusive/detail/minimal_pair_header.hpp> //std::pair
  38. #include <cstddef>
  39. #if defined(BOOST_HAS_PRAGMA_ONCE)
  40. # pragma once
  41. #endif
  42. namespace boost {
  43. namespace intrusive {
  44. /// @cond
  45. namespace detail{
  46. /////////////////////////////////////////////////////////////
  47. //
  48. // Halpha for fixed floating_point<false> option
  49. //
  50. /////////////////////////////////////////////////////////////
  51. //! Returns floor(log2(n)/log2(sqrt(2))) -> floor(2*log2(n))
  52. //! Undefined if N is 0.
  53. //!
  54. //! This function does not use float point operations.
  55. inline std::size_t calculate_h_sqrt2 (std::size_t n)
  56. {
  57. std::size_t f_log2 = detail::floor_log2(n);
  58. return (2*f_log2) + static_cast<std::size_t>(n >= detail::sqrt2_pow_2xplus1(f_log2));
  59. }
  60. struct h_alpha_sqrt2_t
  61. {
  62. h_alpha_sqrt2_t(void){}
  63. std::size_t operator()(std::size_t n) const
  64. { return calculate_h_sqrt2(n); }
  65. };
  66. struct alpha_0_75_by_max_size_t
  67. {
  68. alpha_0_75_by_max_size_t(void){}
  69. std::size_t operator()(std::size_t max_tree_size) const
  70. {
  71. const std::size_t max_tree_size_limit = ((~std::size_t(0))/std::size_t(3));
  72. return max_tree_size > max_tree_size_limit ? max_tree_size/4*3 : max_tree_size*3/4;
  73. }
  74. };
  75. /////////////////////////////////////////////////////////////
  76. //
  77. // Halpha for fixed floating_point<true> option
  78. //
  79. /////////////////////////////////////////////////////////////
  80. struct h_alpha_t
  81. {
  82. explicit h_alpha_t(float inv_minus_logalpha)
  83. : inv_minus_logalpha_(inv_minus_logalpha)
  84. {}
  85. std::size_t operator()(std::size_t n) const
  86. {
  87. ////////////////////////////////////////////////////////////
  88. // This function must return "floor(log2(1/alpha(n)))" ->
  89. // floor(log2(n)/log(1/alpha)) ->
  90. // floor(log2(n)/-log2(alpha))
  91. // floor(log2(n)*(1/-log2(alpha)))
  92. ////////////////////////////////////////////////////////////
  93. return static_cast<std::size_t>(detail::fast_log2(float(n))*inv_minus_logalpha_);
  94. }
  95. private:
  96. //Since the function will be repeatedly called
  97. //precalculate constant data to avoid repeated
  98. //calls to log and division.
  99. //This will store 1/(-std::log2(alpha_))
  100. float inv_minus_logalpha_;
  101. };
  102. struct alpha_by_max_size_t
  103. {
  104. explicit alpha_by_max_size_t(float alpha)
  105. : alpha_(alpha)
  106. {}
  107. float operator()(std::size_t max_tree_size) const
  108. { return float(max_tree_size)*alpha_; }
  109. private:
  110. float alpha_;
  111. };
  112. template<bool Activate, class SizeType>
  113. struct alpha_holder
  114. {
  115. typedef boost::intrusive::detail::h_alpha_t h_alpha_t;
  116. typedef boost::intrusive::detail::alpha_by_max_size_t multiply_by_alpha_t;
  117. alpha_holder()
  118. : max_tree_size_()
  119. { set_alpha(0.70711f); } // ~1/sqrt(2)
  120. float get_alpha() const
  121. { return alpha_; }
  122. void set_alpha(float alpha)
  123. {
  124. alpha_ = alpha;
  125. inv_minus_logalpha_ = 1/(-detail::fast_log2(alpha));
  126. }
  127. h_alpha_t get_h_alpha_t() const
  128. { return h_alpha_t(inv_minus_logalpha_); }
  129. multiply_by_alpha_t get_multiply_by_alpha_t() const
  130. { return multiply_by_alpha_t(alpha_); }
  131. SizeType &get_max_tree_size()
  132. { return max_tree_size_; }
  133. protected:
  134. float alpha_;
  135. float inv_minus_logalpha_;
  136. SizeType max_tree_size_;
  137. };
  138. template<class SizeType>
  139. struct alpha_holder<false, SizeType>
  140. {
  141. //This specialization uses alpha = 1/sqrt(2)
  142. //without using floating point operations
  143. //Downside: alpha CAN't be changed.
  144. typedef boost::intrusive::detail::h_alpha_sqrt2_t h_alpha_t;
  145. typedef boost::intrusive::detail::alpha_0_75_by_max_size_t multiply_by_alpha_t;
  146. alpha_holder()
  147. : max_tree_size_()
  148. {}
  149. float get_alpha() const
  150. { return 0.70710677f; }
  151. void set_alpha(float)
  152. { //alpha CAN't be changed.
  153. BOOST_INTRUSIVE_INVARIANT_ASSERT(0);
  154. }
  155. h_alpha_t get_h_alpha_t() const
  156. { return h_alpha_t(); }
  157. multiply_by_alpha_t get_multiply_by_alpha_t() const
  158. { return multiply_by_alpha_t(); }
  159. SizeType &get_max_tree_size()
  160. { return max_tree_size_; }
  161. protected:
  162. SizeType max_tree_size_;
  163. };
  164. } //namespace detail{
  165. struct sgtree_defaults
  166. : bstree_defaults
  167. {
  168. static const bool floating_point = true;
  169. };
  170. /// @endcond
  171. //! The class template sgtree is an intrusive scapegoat tree container, that
  172. //! is used to construct intrusive sg_set and sg_multiset containers.
  173. //! The no-throw guarantee holds only, if the value_compare object
  174. //! doesn't throw.
  175. //!
  176. //! The template parameter \c T is the type to be managed by the container.
  177. //! The user can specify additional options and if no options are provided
  178. //! default options are used.
  179. //!
  180. //! The container supports the following options:
  181. //! \c base_hook<>/member_hook<>/value_traits<>,
  182. //! \c floating_point<>, \c size_type<> and
  183. //! \c compare<>.
  184. #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
  185. template<class T, class ...Options>
  186. #else
  187. template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, class SizeType, bool FloatingPoint, typename HeaderHolder>
  188. #endif
  189. class sgtree_impl
  190. /// @cond
  191. : public bstree_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType, true, SgTreeAlgorithms, HeaderHolder>
  192. , public detail::alpha_holder<FloatingPoint, SizeType>
  193. /// @endcond
  194. {
  195. public:
  196. typedef ValueTraits value_traits;
  197. /// @cond
  198. typedef bstree_impl< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType
  199. , true, SgTreeAlgorithms, HeaderHolder> tree_type;
  200. typedef tree_type implementation_defined;
  201. /// @endcond
  202. typedef typename implementation_defined::pointer pointer;
  203. typedef typename implementation_defined::const_pointer const_pointer;
  204. typedef typename implementation_defined::value_type value_type;
  205. typedef typename implementation_defined::key_type key_type;
  206. typedef typename implementation_defined::key_of_value key_of_value;
  207. typedef typename implementation_defined::reference reference;
  208. typedef typename implementation_defined::const_reference const_reference;
  209. typedef typename implementation_defined::difference_type difference_type;
  210. typedef typename implementation_defined::size_type size_type;
  211. typedef typename implementation_defined::value_compare value_compare;
  212. typedef typename implementation_defined::key_compare key_compare;
  213. typedef typename implementation_defined::iterator iterator;
  214. typedef typename implementation_defined::const_iterator const_iterator;
  215. typedef typename implementation_defined::reverse_iterator reverse_iterator;
  216. typedef typename implementation_defined::const_reverse_iterator const_reverse_iterator;
  217. typedef typename implementation_defined::node_traits node_traits;
  218. typedef typename implementation_defined::node node;
  219. typedef typename implementation_defined::node_ptr node_ptr;
  220. typedef typename implementation_defined::const_node_ptr const_node_ptr;
  221. typedef BOOST_INTRUSIVE_IMPDEF(sgtree_algorithms<node_traits>) node_algorithms;
  222. static const bool constant_time_size = implementation_defined::constant_time_size;
  223. static const bool floating_point = FloatingPoint;
  224. static const bool stateful_value_traits = implementation_defined::stateful_value_traits;
  225. /// @cond
  226. private:
  227. //noncopyable
  228. typedef detail::alpha_holder<FloatingPoint, SizeType> alpha_traits;
  229. typedef typename alpha_traits::h_alpha_t h_alpha_t;
  230. typedef typename alpha_traits::multiply_by_alpha_t multiply_by_alpha_t;
  231. BOOST_MOVABLE_BUT_NOT_COPYABLE(sgtree_impl)
  232. BOOST_STATIC_ASSERT(((int)value_traits::link_mode != (int)auto_unlink));
  233. enum { safemode_or_autounlink =
  234. (int)value_traits::link_mode == (int)auto_unlink ||
  235. (int)value_traits::link_mode == (int)safe_link };
  236. /// @endcond
  237. public:
  238. typedef BOOST_INTRUSIVE_IMPDEF(typename node_algorithms::insert_commit_data) insert_commit_data;
  239. //! @copydoc ::boost::intrusive::bstree::bstree()
  240. sgtree_impl()
  241. : tree_type()
  242. {}
  243. //! @copydoc ::boost::intrusive::bstree::bstree(const key_compare &,const value_traits &)
  244. explicit sgtree_impl( const key_compare &cmp, const value_traits &v_traits = value_traits())
  245. : tree_type(cmp, v_traits)
  246. {}
  247. //! @copydoc ::boost::intrusive::bstree::bstree(bool,Iterator,Iterator,const key_compare &,const value_traits &)
  248. template<class Iterator>
  249. sgtree_impl( bool unique, Iterator b, Iterator e
  250. , const key_compare &cmp = key_compare()
  251. , const value_traits &v_traits = value_traits())
  252. : tree_type(cmp, v_traits)
  253. {
  254. if(unique)
  255. this->insert_unique(b, e);
  256. else
  257. this->insert_equal(b, e);
  258. }
  259. //! @copydoc ::boost::intrusive::bstree::bstree(bstree &&)
  260. sgtree_impl(BOOST_RV_REF(sgtree_impl) x)
  261. : tree_type(BOOST_MOVE_BASE(tree_type, x)), alpha_traits(x.get_alpha_traits())
  262. { ::boost::adl_move_swap(this->get_alpha_traits(), x.get_alpha_traits()); }
  263. //! @copydoc ::boost::intrusive::bstree::operator=(bstree &&)
  264. sgtree_impl& operator=(BOOST_RV_REF(sgtree_impl) x)
  265. {
  266. this->get_alpha_traits() = x.get_alpha_traits();
  267. return static_cast<sgtree_impl&>(tree_type::operator=(BOOST_MOVE_BASE(tree_type, x)));
  268. }
  269. /// @cond
  270. private:
  271. const alpha_traits &get_alpha_traits() const
  272. { return *this; }
  273. alpha_traits &get_alpha_traits()
  274. { return *this; }
  275. h_alpha_t get_h_alpha_func() const
  276. { return this->get_alpha_traits().get_h_alpha_t(); }
  277. multiply_by_alpha_t get_alpha_by_max_size_func() const
  278. { return this->get_alpha_traits().get_multiply_by_alpha_t(); }
  279. /// @endcond
  280. public:
  281. #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
  282. //! @copydoc ::boost::intrusive::bstree::~bstree()
  283. ~sgtree_impl();
  284. //! @copydoc ::boost::intrusive::bstree::begin()
  285. iterator begin();
  286. //! @copydoc ::boost::intrusive::bstree::begin()const
  287. const_iterator begin() const;
  288. //! @copydoc ::boost::intrusive::bstree::cbegin()const
  289. const_iterator cbegin() const;
  290. //! @copydoc ::boost::intrusive::bstree::end()
  291. iterator end();
  292. //! @copydoc ::boost::intrusive::bstree::end()const
  293. const_iterator end() const;
  294. //! @copydoc ::boost::intrusive::bstree::cend()const
  295. const_iterator cend() const;
  296. //! @copydoc ::boost::intrusive::bstree::rbegin()
  297. reverse_iterator rbegin();
  298. //! @copydoc ::boost::intrusive::bstree::rbegin()const
  299. const_reverse_iterator rbegin() const;
  300. //! @copydoc ::boost::intrusive::bstree::crbegin()const
  301. const_reverse_iterator crbegin() const;
  302. //! @copydoc ::boost::intrusive::bstree::rend()
  303. reverse_iterator rend();
  304. //! @copydoc ::boost::intrusive::bstree::rend()const
  305. const_reverse_iterator rend() const;
  306. //! @copydoc ::boost::intrusive::bstree::crend()const
  307. const_reverse_iterator crend() const;
  308. //! @copydoc ::boost::intrusive::bstree::root()
  309. iterator root();
  310. //! @copydoc ::boost::intrusive::bstree::root()const
  311. const_iterator root() const;
  312. //! @copydoc ::boost::intrusive::bstree::croot()const
  313. const_iterator croot() const;
  314. //! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(iterator)
  315. static sgtree_impl &container_from_end_iterator(iterator end_iterator);
  316. //! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(const_iterator)
  317. static const sgtree_impl &container_from_end_iterator(const_iterator end_iterator);
  318. //! @copydoc ::boost::intrusive::bstree::container_from_iterator(iterator)
  319. static sgtree_impl &container_from_iterator(iterator it);
  320. //! @copydoc ::boost::intrusive::bstree::container_from_iterator(const_iterator)
  321. static const sgtree_impl &container_from_iterator(const_iterator it);
  322. //! @copydoc ::boost::intrusive::bstree::key_comp()const
  323. key_compare key_comp() const;
  324. //! @copydoc ::boost::intrusive::bstree::value_comp()const
  325. value_compare value_comp() const;
  326. //! @copydoc ::boost::intrusive::bstree::empty()const
  327. bool empty() const;
  328. //! @copydoc ::boost::intrusive::bstree::size()const
  329. size_type size() const;
  330. #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
  331. //! @copydoc ::boost::intrusive::bstree::swap
  332. void swap(sgtree_impl& other)
  333. {
  334. //This can throw
  335. this->tree_type::swap(static_cast<tree_type&>(other));
  336. ::boost::adl_move_swap(this->get_alpha_traits(), other.get_alpha_traits());
  337. }
  338. //! @copydoc ::boost::intrusive::bstree::clone_from(const bstree&,Cloner,Disposer)
  339. //! Additional notes: it also copies the alpha factor from the source container.
  340. template <class Cloner, class Disposer>
  341. void clone_from(const sgtree_impl &src, Cloner cloner, Disposer disposer)
  342. {
  343. tree_type::clone_from(src, cloner, disposer);
  344. this->get_alpha_traits() = src.get_alpha_traits();
  345. }
  346. //! @copydoc ::boost::intrusive::bstree::clone_from(bstree&&,Cloner,Disposer)
  347. //! Additional notes: it also copies the alpha factor from the source container.
  348. template <class Cloner, class Disposer>
  349. void clone_from(BOOST_RV_REF(sgtree_impl) src, Cloner cloner, Disposer disposer)
  350. {
  351. tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer);
  352. this->get_alpha_traits() = ::boost::move(src.get_alpha_traits());
  353. }
  354. //! @copydoc ::boost::intrusive::bstree::insert_equal(reference)
  355. iterator insert_equal(reference value)
  356. {
  357. node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
  358. BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
  359. std::size_t max_tree_size = (std::size_t)this->max_tree_size_;
  360. node_ptr p = node_algorithms::insert_equal_upper_bound
  361. (this->tree_type::header_ptr(), to_insert, this->key_node_comp(this->key_comp())
  362. , (size_type)this->size(), this->get_h_alpha_func(), max_tree_size);
  363. this->tree_type::sz_traits().increment();
  364. this->max_tree_size_ = (size_type)max_tree_size;
  365. return iterator(p, this->priv_value_traits_ptr());
  366. }
  367. //! @copydoc ::boost::intrusive::bstree::insert_equal(const_iterator,reference)
  368. iterator insert_equal(const_iterator hint, 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. std::size_t max_tree_size = (std::size_t)this->max_tree_size_;
  373. node_ptr p = node_algorithms::insert_equal
  374. ( this->tree_type::header_ptr(), hint.pointed_node(), to_insert, this->key_node_comp(this->key_comp())
  375. , (std::size_t)this->size(), this->get_h_alpha_func(), max_tree_size);
  376. this->tree_type::sz_traits().increment();
  377. this->max_tree_size_ = (size_type)max_tree_size;
  378. return iterator(p, this->priv_value_traits_ptr());
  379. }
  380. //! @copydoc ::boost::intrusive::bstree::insert_equal(Iterator,Iterator)
  381. template<class Iterator>
  382. void insert_equal(Iterator b, Iterator e)
  383. {
  384. iterator iend(this->end());
  385. for (; b != e; ++b)
  386. this->insert_equal(iend, *b);
  387. }
  388. //! @copydoc ::boost::intrusive::bstree::insert_unique(reference)
  389. std::pair<iterator, bool> insert_unique(reference value)
  390. {
  391. insert_commit_data commit_data;
  392. std::pair<iterator, bool> ret = this->insert_unique_check
  393. (key_of_value()(value), this->key_comp(), commit_data);
  394. if(!ret.second)
  395. return ret;
  396. return std::pair<iterator, bool> (this->insert_unique_commit(value, commit_data), true);
  397. }
  398. //! @copydoc ::boost::intrusive::bstree::insert_unique(const_iterator,reference)
  399. iterator insert_unique(const_iterator hint, reference value)
  400. {
  401. insert_commit_data commit_data;
  402. std::pair<iterator, bool> ret = this->insert_unique_check
  403. (hint, key_of_value()(value), this->key_comp(), commit_data);
  404. if(!ret.second)
  405. return ret.first;
  406. return this->insert_unique_commit(value, commit_data);
  407. }
  408. //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
  409. template<class KeyType, class KeyTypeKeyCompare>
  410. BOOST_INTRUSIVE_DOC1ST(std::pair<iterator BOOST_INTRUSIVE_I bool>
  411. , typename detail::disable_if_convertible
  412. <KeyType BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I
  413. std::pair<iterator BOOST_INTRUSIVE_I bool> >::type)
  414. insert_unique_check
  415. (const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data)
  416. {
  417. std::pair<node_ptr, bool> ret =
  418. node_algorithms::insert_unique_check
  419. (this->tree_type::header_ptr(), key, this->key_node_comp(comp), commit_data);
  420. return std::pair<iterator, bool>(iterator(ret.first, this->priv_value_traits_ptr()), ret.second);
  421. }
  422. //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
  423. template<class KeyType, class KeyTypeKeyCompare>
  424. std::pair<iterator, bool> insert_unique_check
  425. (const_iterator hint, const KeyType &key
  426. ,KeyTypeKeyCompare comp, insert_commit_data &commit_data)
  427. {
  428. std::pair<node_ptr, bool> ret =
  429. node_algorithms::insert_unique_check
  430. (this->tree_type::header_ptr(), hint.pointed_node(), key, this->key_node_comp(comp), commit_data);
  431. return std::pair<iterator, bool>(iterator(ret.first, this->priv_value_traits_ptr()), ret.second);
  432. }
  433. //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const key_type&,insert_commit_data&)
  434. std::pair<iterator, bool> insert_unique_check
  435. (const key_type &key, insert_commit_data &commit_data)
  436. { return this->insert_unique_check(key, this->key_comp(), commit_data); }
  437. //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const key_type&,insert_commit_data&)
  438. std::pair<iterator, bool> insert_unique_check
  439. (const_iterator hint, const key_type &key, insert_commit_data &commit_data)
  440. { return this->insert_unique_check(hint, key, this->key_comp(), commit_data); }
  441. //! @copydoc ::boost::intrusive::bstree::insert_unique_commit
  442. iterator insert_unique_commit(reference value, const insert_commit_data &commit_data)
  443. {
  444. node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
  445. BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
  446. std::size_t max_tree_size = (std::size_t)this->max_tree_size_;
  447. node_algorithms::insert_unique_commit
  448. ( this->tree_type::header_ptr(), to_insert, commit_data
  449. , (std::size_t)this->size(), this->get_h_alpha_func(), max_tree_size);
  450. this->tree_type::sz_traits().increment();
  451. this->max_tree_size_ = (size_type)max_tree_size;
  452. return iterator(to_insert, this->priv_value_traits_ptr());
  453. }
  454. //! @copydoc ::boost::intrusive::bstree::insert_unique(Iterator,Iterator)
  455. template<class Iterator>
  456. void insert_unique(Iterator b, Iterator e)
  457. {
  458. if(this->empty()){
  459. iterator iend(this->end());
  460. for (; b != e; ++b)
  461. this->insert_unique(iend, *b);
  462. }
  463. else{
  464. for (; b != e; ++b)
  465. this->insert_unique(*b);
  466. }
  467. }
  468. //! @copydoc ::boost::intrusive::bstree::insert_before
  469. iterator insert_before(const_iterator pos, reference value)
  470. {
  471. node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
  472. BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
  473. std::size_t max_tree_size = (std::size_t)this->max_tree_size_;
  474. node_ptr p = node_algorithms::insert_before
  475. ( this->tree_type::header_ptr(), pos.pointed_node(), to_insert
  476. , (size_type)this->size(), this->get_h_alpha_func(), max_tree_size);
  477. this->tree_type::sz_traits().increment();
  478. this->max_tree_size_ = (size_type)max_tree_size;
  479. return iterator(p, this->priv_value_traits_ptr());
  480. }
  481. //! @copydoc ::boost::intrusive::bstree::push_back
  482. void push_back(reference value)
  483. {
  484. node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
  485. BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
  486. std::size_t max_tree_size = (std::size_t)this->max_tree_size_;
  487. node_algorithms::push_back
  488. ( this->tree_type::header_ptr(), to_insert
  489. , (size_type)this->size(), this->get_h_alpha_func(), max_tree_size);
  490. this->tree_type::sz_traits().increment();
  491. this->max_tree_size_ = (size_type)max_tree_size;
  492. }
  493. //! @copydoc ::boost::intrusive::bstree::push_front
  494. void push_front(reference value)
  495. {
  496. node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
  497. BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
  498. std::size_t max_tree_size = (std::size_t)this->max_tree_size_;
  499. node_algorithms::push_front
  500. ( this->tree_type::header_ptr(), to_insert
  501. , (size_type)this->size(), this->get_h_alpha_func(), max_tree_size);
  502. this->tree_type::sz_traits().increment();
  503. this->max_tree_size_ = (size_type)max_tree_size;
  504. }
  505. //! @copydoc ::boost::intrusive::bstree::erase(const_iterator)
  506. iterator erase(const_iterator i)
  507. {
  508. const_iterator ret(i);
  509. ++ret;
  510. node_ptr to_erase(i.pointed_node());
  511. BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || !node_algorithms::unique(to_erase));
  512. std::size_t max_tree_size = this->max_tree_size_;
  513. node_algorithms::erase
  514. ( this->tree_type::header_ptr(), to_erase, (std::size_t)this->size()
  515. , max_tree_size, this->get_alpha_by_max_size_func());
  516. this->max_tree_size_ = (size_type)max_tree_size;
  517. this->tree_type::sz_traits().decrement();
  518. if(safemode_or_autounlink)
  519. node_algorithms::init(to_erase);
  520. return ret.unconst();
  521. }
  522. //! @copydoc ::boost::intrusive::bstree::erase(const_iterator,const_iterator)
  523. iterator erase(const_iterator b, const_iterator e)
  524. { size_type n; return private_erase(b, e, n); }
  525. //! @copydoc ::boost::intrusive::bstree::erase(const key_type &)
  526. size_type erase(const key_type &key)
  527. { return this->erase(key, this->key_comp()); }
  528. //! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyTypeKeyCompare)
  529. template<class KeyType, class KeyTypeKeyCompare>
  530. BOOST_INTRUSIVE_DOC1ST(size_type
  531. , typename detail::disable_if_convertible<KeyTypeKeyCompare BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I size_type>::type)
  532. erase(const KeyType& key, KeyTypeKeyCompare comp)
  533. {
  534. std::pair<iterator,iterator> p = this->equal_range(key, comp);
  535. size_type n;
  536. private_erase(p.first, p.second, n);
  537. return n;
  538. }
  539. //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,Disposer)
  540. template<class Disposer>
  541. iterator erase_and_dispose(const_iterator i, Disposer disposer)
  542. {
  543. node_ptr to_erase(i.pointed_node());
  544. iterator ret(this->erase(i));
  545. disposer(this->get_value_traits().to_value_ptr(to_erase));
  546. return ret;
  547. }
  548. #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
  549. template<class Disposer>
  550. iterator erase_and_dispose(iterator i, Disposer disposer)
  551. { return this->erase_and_dispose(const_iterator(i), disposer); }
  552. #endif
  553. //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,const_iterator,Disposer)
  554. template<class Disposer>
  555. iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer)
  556. { size_type n; return private_erase(b, e, n, disposer); }
  557. //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const key_type &, Disposer)
  558. template<class Disposer>
  559. size_type erase_and_dispose(const key_type &key, Disposer disposer)
  560. {
  561. std::pair<iterator,iterator> p = this->equal_range(key);
  562. size_type n;
  563. private_erase(p.first, p.second, n, disposer);
  564. return n;
  565. }
  566. //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
  567. template<class KeyType, class KeyTypeKeyCompare, class Disposer>
  568. BOOST_INTRUSIVE_DOC1ST(size_type
  569. , typename detail::disable_if_convertible<KeyTypeKeyCompare BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I size_type>::type)
  570. erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer)
  571. {
  572. std::pair<iterator,iterator> p = this->equal_range(key, comp);
  573. size_type n;
  574. private_erase(p.first, p.second, n, disposer);
  575. return n;
  576. }
  577. //! @copydoc ::boost::intrusive::bstree::clear
  578. void clear()
  579. {
  580. tree_type::clear();
  581. this->max_tree_size_ = 0;
  582. }
  583. //! @copydoc ::boost::intrusive::bstree::clear_and_dispose
  584. template<class Disposer>
  585. void clear_and_dispose(Disposer disposer)
  586. {
  587. tree_type::clear_and_dispose(disposer);
  588. this->max_tree_size_ = 0;
  589. }
  590. #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
  591. //! @copydoc ::boost::intrusive::bstree::merge_unique
  592. template<class T, class ...Options2> void merge_unique(sgtree<T, Options2...> &);
  593. #else
  594. template<class Compare2>
  595. void merge_unique(sgtree_impl
  596. <ValueTraits, VoidOrKeyOfValue, Compare2, SizeType, FloatingPoint, HeaderHolder> &source)
  597. #endif
  598. {
  599. node_ptr it (node_algorithms::begin_node(source.header_ptr()))
  600. , itend(node_algorithms::end_node (source.header_ptr()));
  601. while(it != itend){
  602. node_ptr const p(it);
  603. BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || !node_algorithms::unique(p));
  604. it = node_algorithms::next_node(it);
  605. std::size_t max_tree1_size = this->max_tree_size_;
  606. std::size_t max_tree2_size = source.get_max_tree_size();
  607. if( node_algorithms::transfer_unique
  608. ( this->header_ptr(), this->key_node_comp(this->key_comp()), this->size(), max_tree1_size
  609. , source.header_ptr(), p, source.size(), max_tree2_size
  610. , this->get_h_alpha_func(), this->get_alpha_by_max_size_func()) ){
  611. this->max_tree_size_ = (size_type)max_tree1_size;
  612. this->sz_traits().increment();
  613. source.get_max_tree_size() = (size_type)max_tree2_size;
  614. source.sz_traits().decrement();
  615. }
  616. }
  617. }
  618. #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
  619. //! @copydoc ::boost::intrusive::bstree::merge_equal
  620. template<class T, class ...Options2> void merge_equal(sgtree<T, Options2...> &);
  621. #else
  622. template<class Compare2>
  623. void merge_equal(sgtree_impl
  624. <ValueTraits, VoidOrKeyOfValue, Compare2, SizeType, FloatingPoint, HeaderHolder> &source)
  625. #endif
  626. {
  627. node_ptr it (node_algorithms::begin_node(source.header_ptr()))
  628. , itend(node_algorithms::end_node (source.header_ptr()));
  629. while(it != itend){
  630. node_ptr const p(it);
  631. BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || !node_algorithms::unique(p));
  632. it = node_algorithms::next_node(it);
  633. std::size_t max_tree1_size = this->max_tree_size_;
  634. std::size_t max_tree2_size = source.get_max_tree_size();
  635. node_algorithms::transfer_equal
  636. ( this->header_ptr(), this->key_node_comp(this->key_comp()), this->size(), max_tree1_size
  637. , source.header_ptr(), p, source.size(), max_tree2_size
  638. , this->get_h_alpha_func(), this->get_alpha_by_max_size_func());
  639. this->max_tree_size_ = (size_type)max_tree1_size;
  640. this->sz_traits().increment();
  641. source.get_max_tree_size() = (size_type)max_tree2_size;
  642. source.sz_traits().decrement();
  643. }
  644. }
  645. #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
  646. //! @copydoc ::boost::intrusive::bstree::count(const key_type &)const
  647. size_type count(const key_type &key) const;
  648. //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyTypeKeyCompare)const
  649. template<class KeyType, class KeyTypeKeyCompare>
  650. size_type count(const KeyType& key, KeyTypeKeyCompare comp) const;
  651. //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)
  652. iterator lower_bound(const key_type &key);
  653. //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)
  654. template<class KeyType, class KeyTypeKeyCompare>
  655. iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
  656. //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)const
  657. const_iterator lower_bound(const key_type &key) const;
  658. //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
  659. template<class KeyType, class KeyTypeKeyCompare>
  660. const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
  661. //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)
  662. iterator upper_bound(const key_type &key);
  663. //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)
  664. template<class KeyType, class KeyTypeKeyCompare>
  665. iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
  666. //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)const
  667. const_iterator upper_bound(const key_type &key) const;
  668. //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
  669. template<class KeyType, class KeyTypeKeyCompare>
  670. const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
  671. //! @copydoc ::boost::intrusive::bstree::find(const key_type &)
  672. iterator find(const key_type &key);
  673. //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)
  674. template<class KeyType, class KeyTypeKeyCompare>
  675. iterator find(const KeyType& key, KeyTypeKeyCompare comp);
  676. //! @copydoc ::boost::intrusive::bstree::find(const key_type &)const
  677. const_iterator find(const key_type &key) const;
  678. //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)const
  679. template<class KeyType, class KeyTypeKeyCompare>
  680. const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
  681. //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)
  682. std::pair<iterator,iterator> equal_range(const key_type &key);
  683. //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)
  684. template<class KeyType, class KeyTypeKeyCompare>
  685. std::pair<iterator,iterator> equal_range(const KeyType& key, KeyTypeKeyCompare comp);
  686. //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)const
  687. std::pair<const_iterator, const_iterator>
  688. equal_range(const key_type &key) const;
  689. //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)const
  690. template<class KeyType, class KeyTypeKeyCompare>
  691. std::pair<const_iterator, const_iterator>
  692. equal_range(const KeyType& key, KeyTypeKeyCompare comp) const;
  693. //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)
  694. std::pair<iterator,iterator> bounded_range
  695. (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed);
  696. //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
  697. template<class KeyType, class KeyTypeKeyCompare>
  698. std::pair<iterator,iterator> bounded_range
  699. (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
  700. //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)const
  701. std::pair<const_iterator, const_iterator>
  702. bounded_range(const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
  703. //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
  704. template<class KeyType, class KeyTypeKeyCompare>
  705. std::pair<const_iterator, const_iterator> bounded_range
  706. (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
  707. //! @copydoc ::boost::intrusive::bstree::s_iterator_to(reference)
  708. static iterator s_iterator_to(reference value);
  709. //! @copydoc ::boost::intrusive::bstree::s_iterator_to(const_reference)
  710. static const_iterator s_iterator_to(const_reference value);
  711. //! @copydoc ::boost::intrusive::bstree::iterator_to(reference)
  712. iterator iterator_to(reference value);
  713. //! @copydoc ::boost::intrusive::bstree::iterator_to(const_reference)const
  714. const_iterator iterator_to(const_reference value) const;
  715. //! @copydoc ::boost::intrusive::bstree::init_node(reference)
  716. static void init_node(reference value);
  717. //! @copydoc ::boost::intrusive::bstree::unlink_leftmost_without_rebalance
  718. pointer unlink_leftmost_without_rebalance();
  719. //! @copydoc ::boost::intrusive::bstree::replace_node
  720. void replace_node(iterator replace_this, reference with_this);
  721. //! @copydoc ::boost::intrusive::bstree::remove_node
  722. void remove_node(reference value);
  723. //! @copydoc ::boost::intrusive::bstree::rebalance
  724. void rebalance();
  725. //! @copydoc ::boost::intrusive::bstree::rebalance_subtree
  726. iterator rebalance_subtree(iterator root);
  727. friend bool operator< (const sgtree_impl &x, const sgtree_impl &y);
  728. friend bool operator==(const sgtree_impl &x, const sgtree_impl &y);
  729. friend bool operator!= (const sgtree_impl &x, const sgtree_impl &y);
  730. friend bool operator>(const sgtree_impl &x, const sgtree_impl &y);
  731. friend bool operator<=(const sgtree_impl &x, const sgtree_impl &y);
  732. friend bool operator>=(const sgtree_impl &x, const sgtree_impl &y);
  733. friend void swap(sgtree_impl &x, sgtree_impl &y);
  734. #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
  735. //! <b>Returns</b>: The balance factor (alpha) used in this tree
  736. //!
  737. //! <b>Throws</b>: Nothing.
  738. //!
  739. //! <b>Complexity</b>: Constant.
  740. float balance_factor() const
  741. { return this->get_alpha_traits().get_alpha(); }
  742. //! <b>Requires</b>: new_alpha must be a value between 0.5 and 1.0
  743. //!
  744. //! <b>Effects</b>: Establishes a new balance factor (alpha) and rebalances
  745. //! the tree if the new balance factor is stricter (less) than the old factor.
  746. //!
  747. //! <b>Throws</b>: Nothing.
  748. //!
  749. //! <b>Complexity</b>: Linear to the elements in the subtree.
  750. void balance_factor(float new_alpha)
  751. {
  752. //The alpha factor CAN't be changed if the fixed, floating operation-less
  753. //1/sqrt(2) alpha factor option is activated
  754. BOOST_STATIC_ASSERT((floating_point));
  755. BOOST_INTRUSIVE_INVARIANT_ASSERT((new_alpha > 0.5f && new_alpha < 1.0f));
  756. if(new_alpha >= 0.5f && new_alpha < 1.0f){
  757. float old_alpha = this->get_alpha_traits().get_alpha();
  758. this->get_alpha_traits().set_alpha(new_alpha);
  759. if(new_alpha < old_alpha){
  760. this->max_tree_size_ = this->size();
  761. this->rebalance();
  762. }
  763. }
  764. }
  765. /// @cond
  766. private:
  767. template<class Disposer>
  768. iterator private_erase(const_iterator b, const_iterator e, size_type &n, Disposer disposer)
  769. {
  770. for(n = 0; b != e; ++n)
  771. this->erase_and_dispose(b++, disposer);
  772. return b.unconst();
  773. }
  774. iterator private_erase(const_iterator b, const_iterator e, size_type &n)
  775. {
  776. for(n = 0; b != e; ++n)
  777. this->erase(b++);
  778. return b.unconst();
  779. }
  780. /// @endcond
  781. };
  782. //! Helper metafunction to define a \c sgtree that yields to the same type when the
  783. //! same options (either explicitly or implicitly) are used.
  784. #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
  785. template<class T, class ...Options>
  786. #else
  787. template<class T, class O1 = void, class O2 = void
  788. , class O3 = void, class O4 = void
  789. , class O5 = void, class O6 = void>
  790. #endif
  791. struct make_sgtree
  792. {
  793. /// @cond
  794. typedef typename pack_options
  795. < sgtree_defaults,
  796. #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
  797. O1, O2, O3, O4, O5, O6
  798. #else
  799. Options...
  800. #endif
  801. >::type packed_options;
  802. typedef typename detail::get_value_traits
  803. <T, typename packed_options::proto_value_traits>::type value_traits;
  804. typedef sgtree_impl
  805. < value_traits
  806. , typename packed_options::key_of_value
  807. , typename packed_options::compare
  808. , typename packed_options::size_type
  809. , packed_options::floating_point
  810. , typename packed_options::header_holder_type
  811. > implementation_defined;
  812. /// @endcond
  813. typedef implementation_defined type;
  814. };
  815. #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
  816. #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
  817. template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
  818. #else
  819. template<class T, class ...Options>
  820. #endif
  821. class sgtree
  822. : public make_sgtree<T,
  823. #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
  824. O1, O2, O3, O4, O5, O6
  825. #else
  826. Options...
  827. #endif
  828. >::type
  829. {
  830. typedef typename make_sgtree
  831. <T,
  832. #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
  833. O1, O2, O3, O4, O5, O6
  834. #else
  835. Options...
  836. #endif
  837. >::type Base;
  838. BOOST_MOVABLE_BUT_NOT_COPYABLE(sgtree)
  839. public:
  840. typedef typename Base::key_compare key_compare;
  841. typedef typename Base::value_traits value_traits;
  842. typedef typename Base::iterator iterator;
  843. typedef typename Base::const_iterator const_iterator;
  844. typedef typename Base::reverse_iterator reverse_iterator;
  845. typedef typename Base::const_reverse_iterator const_reverse_iterator;
  846. //Assert if passed value traits are compatible with the type
  847. BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
  848. BOOST_INTRUSIVE_FORCEINLINE sgtree()
  849. : Base()
  850. {}
  851. BOOST_INTRUSIVE_FORCEINLINE explicit sgtree(const key_compare &cmp, const value_traits &v_traits = value_traits())
  852. : Base(cmp, v_traits)
  853. {}
  854. template<class Iterator>
  855. BOOST_INTRUSIVE_FORCEINLINE sgtree( bool unique, Iterator b, Iterator e
  856. , const key_compare &cmp = key_compare()
  857. , const value_traits &v_traits = value_traits())
  858. : Base(unique, b, e, cmp, v_traits)
  859. {}
  860. BOOST_INTRUSIVE_FORCEINLINE sgtree(BOOST_RV_REF(sgtree) x)
  861. : Base(BOOST_MOVE_BASE(Base, x))
  862. {}
  863. BOOST_INTRUSIVE_FORCEINLINE sgtree& operator=(BOOST_RV_REF(sgtree) x)
  864. { return static_cast<sgtree &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
  865. template <class Cloner, class Disposer>
  866. BOOST_INTRUSIVE_FORCEINLINE void clone_from(const sgtree &src, Cloner cloner, Disposer disposer)
  867. { Base::clone_from(src, cloner, disposer); }
  868. template <class Cloner, class Disposer>
  869. BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(sgtree) src, Cloner cloner, Disposer disposer)
  870. { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
  871. BOOST_INTRUSIVE_FORCEINLINE static sgtree &container_from_end_iterator(iterator end_iterator)
  872. { return static_cast<sgtree &>(Base::container_from_end_iterator(end_iterator)); }
  873. BOOST_INTRUSIVE_FORCEINLINE static const sgtree &container_from_end_iterator(const_iterator end_iterator)
  874. { return static_cast<const sgtree &>(Base::container_from_end_iterator(end_iterator)); }
  875. BOOST_INTRUSIVE_FORCEINLINE static sgtree &container_from_iterator(iterator it)
  876. { return static_cast<sgtree &>(Base::container_from_iterator(it)); }
  877. BOOST_INTRUSIVE_FORCEINLINE static const sgtree &container_from_iterator(const_iterator it)
  878. { return static_cast<const sgtree &>(Base::container_from_iterator(it)); }
  879. };
  880. #endif
  881. } //namespace intrusive
  882. } //namespace boost
  883. #include <boost/intrusive/detail/config_end.hpp>
  884. #endif //BOOST_INTRUSIVE_SGTREE_HPP