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