fix doc example typo
[boost.git] / boost / intrusive / rbtree.hpp
blob572b5450b28927a9432fde43c2334e9cde5b4230
1 /////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 2006-2008
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.
11 /////////////////////////////////////////////////////////////////////////////
12 #ifndef BOOST_INTRUSIVE_RBTREE_HPP
13 #define BOOST_INTRUSIVE_RBTREE_HPP
15 #include <boost/intrusive/detail/config_begin.hpp>
16 #include <algorithm>
17 #include <cstddef>
18 #include <functional>
19 #include <iterator>
20 #include <utility>
22 #include <boost/intrusive/detail/assert.hpp>
23 #include <boost/static_assert.hpp>
24 #include <boost/intrusive/intrusive_fwd.hpp>
25 #include <boost/intrusive/set_hook.hpp>
26 #include <boost/intrusive/detail/rbtree_node.hpp>
27 #include <boost/intrusive/detail/tree_node.hpp>
28 #include <boost/intrusive/detail/ebo_functor_holder.hpp>
29 #include <boost/intrusive/detail/mpl.hpp>
30 #include <boost/intrusive/detail/pointer_to_other.hpp>
31 #include <boost/intrusive/detail/clear_on_destructor_base.hpp>
32 #include <boost/intrusive/options.hpp>
33 #include <boost/intrusive/rbtree_algorithms.hpp>
34 #include <boost/intrusive/link_mode.hpp>
36 namespace boost {
37 namespace intrusive {
39 /// @cond
41 template <class ValueTraits, class Compare, class SizeType, bool ConstantTimeSize>
42 struct setopt
44 typedef ValueTraits value_traits;
45 typedef Compare compare;
46 typedef SizeType size_type;
47 static const bool constant_time_size = ConstantTimeSize;
50 template <class T>
51 struct set_defaults
52 : pack_options
53 < none
54 , base_hook<detail::default_set_hook>
55 , constant_time_size<true>
56 , size_type<std::size_t>
57 , compare<std::less<T> >
58 >::type
59 {};
61 /// @endcond
63 //! The class template rbtree is an intrusive red-black tree container, that
64 //! is used to construct intrusive set and multiset containers. The no-throw
65 //! guarantee holds only, if the value_compare object
66 //! doesn't throw.
67 //!
68 //! The template parameter \c T is the type to be managed by the container.
69 //! The user can specify additional options and if no options are provided
70 //! default options are used.
71 //!
72 //! The container supports the following options:
73 //! \c base_hook<>/member_hook<>/value_traits<>,
74 //! \c constant_time_size<>, \c size_type<> and
75 //! \c compare<>.
76 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
77 template<class T, class ...Options>
78 #else
79 template<class Config>
80 #endif
81 class rbtree_impl
82 : private detail::clear_on_destructor_base<rbtree_impl<Config> >
84 template<class C> friend class detail::clear_on_destructor_base;
85 public:
86 typedef typename Config::value_traits value_traits;
87 /// @cond
88 static const bool external_value_traits =
89 detail::external_value_traits_is_true<value_traits>::value;
90 typedef typename detail::eval_if_c
91 < external_value_traits
92 , detail::eval_value_traits<value_traits>
93 , detail::identity<value_traits>
94 >::type real_value_traits;
95 /// @endcond
96 typedef typename real_value_traits::pointer pointer;
97 typedef typename real_value_traits::const_pointer const_pointer;
98 typedef typename std::iterator_traits<pointer>::value_type value_type;
99 typedef value_type key_type;
100 typedef typename std::iterator_traits<pointer>::reference reference;
101 typedef typename std::iterator_traits<const_pointer>::reference const_reference;
102 typedef typename std::iterator_traits<pointer>::difference_type difference_type;
103 typedef typename Config::size_type size_type;
104 typedef typename Config::compare value_compare;
105 typedef value_compare key_compare;
106 typedef tree_iterator<rbtree_impl, false> iterator;
107 typedef tree_iterator<rbtree_impl, true> const_iterator;
108 typedef std::reverse_iterator<iterator> reverse_iterator;
109 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
110 typedef typename real_value_traits::node_traits node_traits;
111 typedef typename node_traits::node node;
112 typedef typename boost::pointer_to_other
113 <pointer, node>::type node_ptr;
114 typedef typename boost::pointer_to_other
115 <node_ptr, const node>::type const_node_ptr;
116 typedef rbtree_algorithms<node_traits> node_algorithms;
118 static const bool constant_time_size = Config::constant_time_size;
119 static const bool stateful_value_traits = detail::store_cont_ptr_on_it<rbtree_impl>::value;
121 /// @cond
122 private:
123 typedef detail::size_holder<constant_time_size, size_type> size_traits;
125 //noncopyable
126 rbtree_impl (const rbtree_impl&);
127 rbtree_impl operator =(const rbtree_impl&);
129 enum { safemode_or_autounlink =
130 (int)real_value_traits::link_mode == (int)auto_unlink ||
131 (int)real_value_traits::link_mode == (int)safe_link };
133 //Constant-time size is incompatible with auto-unlink hooks!
134 BOOST_STATIC_ASSERT(!(constant_time_size && ((int)real_value_traits::link_mode == (int)auto_unlink)));
136 struct header_plus_size : public size_traits
137 { node header_; };
139 struct node_plus_pred_t : public detail::ebo_functor_holder<value_compare>
141 node_plus_pred_t(const value_compare &comp)
142 : detail::ebo_functor_holder<value_compare>(comp)
144 header_plus_size header_plus_size_;
147 struct data_t : public rbtree_impl::value_traits
149 typedef typename rbtree_impl::value_traits value_traits;
150 data_t(const value_compare & comp, const value_traits &val_traits)
151 : value_traits(val_traits), node_plus_pred_(comp)
153 node_plus_pred_t node_plus_pred_;
154 } data_;
156 const value_compare &priv_comp() const
157 { return data_.node_plus_pred_.get(); }
159 value_compare &priv_comp()
160 { return data_.node_plus_pred_.get(); }
162 const node &priv_header() const
163 { return data_.node_plus_pred_.header_plus_size_.header_; }
165 node &priv_header()
166 { return data_.node_plus_pred_.header_plus_size_.header_; }
168 static node_ptr uncast(const_node_ptr ptr)
170 return node_ptr(const_cast<node*>(detail::get_pointer(ptr)));
173 size_traits &priv_size_traits()
174 { return data_.node_plus_pred_.header_plus_size_; }
176 const size_traits &priv_size_traits() const
177 { return data_.node_plus_pred_.header_plus_size_; }
179 const real_value_traits &get_real_value_traits(detail::bool_<false>) const
180 { return data_; }
182 const real_value_traits &get_real_value_traits(detail::bool_<true>) const
183 { return data_.get_value_traits(*this); }
185 real_value_traits &get_real_value_traits(detail::bool_<false>)
186 { return data_; }
188 real_value_traits &get_real_value_traits(detail::bool_<true>)
189 { return data_.get_value_traits(*this); }
191 /// @endcond
193 public:
195 const real_value_traits &get_real_value_traits() const
196 { return this->get_real_value_traits(detail::bool_<external_value_traits>()); }
198 real_value_traits &get_real_value_traits()
199 { return this->get_real_value_traits(detail::bool_<external_value_traits>()); }
201 typedef typename node_algorithms::insert_commit_data insert_commit_data;
203 //! <b>Effects</b>: Constructs an empty tree.
204 //!
205 //! <b>Complexity</b>: Constant.
206 //!
207 //! <b>Throws</b>: If value_traits::node_traits::node
208 //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
209 //! or the copy constructorof the value_compare object throws. Basic guarantee.
210 rbtree_impl( const value_compare &cmp = value_compare()
211 , const value_traits &v_traits = value_traits())
212 : data_(cmp, v_traits)
214 node_algorithms::init_header(&priv_header());
215 this->priv_size_traits().set_size(size_type(0));
218 //! <b>Requires</b>: Dereferencing iterator must yield an lvalue of type value_type.
219 //! cmp must be a comparison function that induces a strict weak ordering.
221 //! <b>Effects</b>: Constructs an empty tree and inserts elements from
222 //! [b, e).
224 //! <b>Complexity</b>: Linear in N if [b, e) is already sorted using
225 //! comp and otherwise N * log N, where N is the distance between first and last.
226 //!
227 //! <b>Throws</b>: If value_traits::node_traits::node
228 //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
229 //! or the copy constructor/operator() of the value_compare object throws. Basic guarantee.
230 template<class Iterator>
231 rbtree_impl( bool unique, Iterator b, Iterator e
232 , const value_compare &cmp = value_compare()
233 , const value_traits &v_traits = value_traits())
234 : data_(cmp, v_traits)
236 node_algorithms::init_header(&priv_header());
237 this->priv_size_traits().set_size(size_type(0));
238 if(unique)
239 this->insert_unique(b, e);
240 else
241 this->insert_equal(b, e);
244 //! <b>Effects</b>: Detaches all elements from this. The objects in the set
245 //! are not deleted (i.e. no destructors are called), but the nodes according to
246 //! the value_traits template parameter are reinitialized and thus can be reused.
247 //!
248 //! <b>Complexity</b>: Linear to elements contained in *this.
249 //!
250 //! <b>Throws</b>: Nothing.
251 ~rbtree_impl()
254 //! <b>Effects</b>: Returns an iterator pointing to the beginning of the tree.
255 //!
256 //! <b>Complexity</b>: Constant.
257 //!
258 //! <b>Throws</b>: Nothing.
259 iterator begin()
260 { return iterator (node_traits::get_left(node_ptr(&priv_header())), this); }
262 //! <b>Effects</b>: Returns a const_iterator pointing to the beginning of the tree.
263 //!
264 //! <b>Complexity</b>: Constant.
265 //!
266 //! <b>Throws</b>: Nothing.
267 const_iterator begin() const
268 { return cbegin(); }
270 //! <b>Effects</b>: Returns a const_iterator pointing to the beginning of the tree.
271 //!
272 //! <b>Complexity</b>: Constant.
273 //!
274 //! <b>Throws</b>: Nothing.
275 const_iterator cbegin() const
276 { return const_iterator (node_traits::get_left(const_node_ptr(&priv_header())), this); }
278 //! <b>Effects</b>: Returns an iterator pointing to the end of the tree.
279 //!
280 //! <b>Complexity</b>: Constant.
281 //!
282 //! <b>Throws</b>: Nothing.
283 iterator end()
284 { return iterator (node_ptr(&priv_header()), this); }
286 //! <b>Effects</b>: Returns a const_iterator pointing to the end of the tree.
288 //! <b>Complexity</b>: Constant.
289 //!
290 //! <b>Throws</b>: Nothing.
291 const_iterator end() const
292 { return cend(); }
294 //! <b>Effects</b>: Returns a const_iterator pointing to the end of the tree.
295 //!
296 //! <b>Complexity</b>: Constant.
297 //!
298 //! <b>Throws</b>: Nothing.
299 const_iterator cend() const
300 { return const_iterator (uncast(const_node_ptr(&priv_header())), this); }
302 //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning of the
303 //! reversed tree.
304 //!
305 //! <b>Complexity</b>: Constant.
306 //!
307 //! <b>Throws</b>: Nothing.
308 reverse_iterator rbegin()
309 { return reverse_iterator(end()); }
311 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
312 //! of the reversed tree.
313 //!
314 //! <b>Complexity</b>: Constant.
315 //!
316 //! <b>Throws</b>: Nothing.
317 const_reverse_iterator rbegin() const
318 { return const_reverse_iterator(end()); }
320 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
321 //! of the reversed tree.
322 //!
323 //! <b>Complexity</b>: Constant.
324 //!
325 //! <b>Throws</b>: Nothing.
326 const_reverse_iterator crbegin() const
327 { return const_reverse_iterator(end()); }
329 //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
330 //! of the reversed tree.
331 //!
332 //! <b>Complexity</b>: Constant.
333 //!
334 //! <b>Throws</b>: Nothing.
335 reverse_iterator rend()
336 { return reverse_iterator(begin()); }
338 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
339 //! of the reversed tree.
340 //!
341 //! <b>Complexity</b>: Constant.
342 //!
343 //! <b>Throws</b>: Nothing.
344 const_reverse_iterator rend() const
345 { return const_reverse_iterator(begin()); }
347 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
348 //! of the reversed tree.
349 //!
350 //! <b>Complexity</b>: Constant.
351 //!
352 //! <b>Throws</b>: Nothing.
353 const_reverse_iterator crend() const
354 { return const_reverse_iterator(begin()); }
356 //! <b>Precondition</b>: end_iterator must be a valid end iterator
357 //! of rbtree.
358 //!
359 //! <b>Effects</b>: Returns a const reference to the rbtree associated to the end iterator
360 //!
361 //! <b>Throws</b>: Nothing.
362 //!
363 //! <b>Complexity</b>: Constant.
364 static rbtree_impl &container_from_end_iterator(iterator end_iterator)
365 { return priv_container_from_end_iterator(end_iterator); }
367 //! <b>Precondition</b>: end_iterator must be a valid end const_iterator
368 //! of rbtree.
369 //!
370 //! <b>Effects</b>: Returns a const reference to the rbtree associated to the iterator
371 //!
372 //! <b>Throws</b>: Nothing.
373 //!
374 //! <b>Complexity</b>: Constant.
375 static const rbtree_impl &container_from_end_iterator(const_iterator end_iterator)
376 { return priv_container_from_end_iterator(end_iterator); }
378 //! <b>Precondition</b>: it must be a valid iterator
379 //! of rbtree.
380 //!
381 //! <b>Effects</b>: Returns a const reference to the tree associated to the iterator
382 //!
383 //! <b>Throws</b>: Nothing.
384 //!
385 //! <b>Complexity</b>: Logarithmic.
386 static rbtree_impl &container_from_iterator(iterator it)
387 { return priv_container_from_iterator(it); }
389 //! <b>Precondition</b>: it must be a valid end const_iterator
390 //! of rbtree.
391 //!
392 //! <b>Effects</b>: Returns a const reference to the tree associated to the end iterator
393 //!
394 //! <b>Throws</b>: Nothing.
395 //!
396 //! <b>Complexity</b>: Logarithmic.
397 static const rbtree_impl &container_from_iterator(const_iterator it)
398 { return priv_container_from_iterator(it); }
400 //! <b>Effects</b>: Returns the value_compare object used by the tree.
401 //!
402 //! <b>Complexity</b>: Constant.
403 //!
404 //! <b>Throws</b>: If value_compare copy-constructor throws.
405 value_compare value_comp() const
406 { return priv_comp(); }
408 //! <b>Effects</b>: Returns true if the container is empty.
409 //!
410 //! <b>Complexity</b>: Constant.
411 //!
412 //! <b>Throws</b>: Nothing.
413 bool empty() const
414 { return node_algorithms::unique(const_node_ptr(&priv_header())); }
416 //! <b>Effects</b>: Returns the number of elements stored in the tree.
417 //!
418 //! <b>Complexity</b>: Linear to elements contained in *this
419 //! if constant-time size option is disabled. Constant time otherwise.
420 //!
421 //! <b>Throws</b>: Nothing.
422 size_type size() const
424 if(constant_time_size)
425 return this->priv_size_traits().get_size();
426 else{
427 return (size_type)node_algorithms::size(const_node_ptr(&priv_header()));
431 //! <b>Effects</b>: Swaps the contents of two rbtrees.
432 //!
433 //! <b>Complexity</b>: Constant.
434 //!
435 //! <b>Throws</b>: If the comparison functor's swap call throws.
436 void swap(rbtree_impl& other)
438 //This can throw
439 using std::swap;
440 swap(priv_comp(), priv_comp());
441 //These can't throw
442 node_algorithms::swap_tree(node_ptr(&priv_header()), node_ptr(&other.priv_header()));
443 if(constant_time_size){
444 size_type backup = this->priv_size_traits().get_size();
445 this->priv_size_traits().set_size(other.priv_size_traits().get_size());
446 other.priv_size_traits().set_size(backup);
450 //! <b>Requires</b>: value must be an lvalue
451 //!
452 //! <b>Effects</b>: Inserts value into the tree before the upper bound.
453 //!
454 //! <b>Complexity</b>: Average complexity for insert element is at
455 //! most logarithmic.
456 //!
457 //! <b>Throws</b>: If the internal value_compare ordering function throws. Strong guarantee.
458 //!
459 //! <b>Note</b>: Does not affect the validity of iterators and references.
460 //! No copy-constructors are called.
461 iterator insert_equal(reference value)
463 detail::key_nodeptr_comp<value_compare, rbtree_impl>
464 key_node_comp(priv_comp(), this);
465 node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
466 if(safemode_or_autounlink)
467 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
468 this->priv_size_traits().increment();
469 return iterator(node_algorithms::insert_equal_upper_bound
470 (node_ptr(&priv_header()), to_insert, key_node_comp), this);
473 //! <b>Requires</b>: value must be an lvalue, and "hint" must be
474 //! a valid iterator.
475 //!
476 //! <b>Effects</b>: Inserts x into the tree, using "hint" as a hint to
477 //! where it will be inserted. If "hint" is the upper_bound
478 //! the insertion takes constant time (two comparisons in the worst case)
479 //!
480 //! <b>Complexity</b>: Logarithmic in general, but it is amortized
481 //! constant time if t is inserted immediately before hint.
482 //!
483 //! <b>Throws</b>: If the internal value_compare ordering function throws. Strong guarantee.
484 //!
485 //! <b>Note</b>: Does not affect the validity of iterators and references.
486 //! No copy-constructors are called.
487 iterator insert_equal(const_iterator hint, reference value)
489 detail::key_nodeptr_comp<value_compare, rbtree_impl>
490 key_node_comp(priv_comp(), this);
491 node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
492 if(safemode_or_autounlink)
493 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
494 this->priv_size_traits().increment();
495 return iterator(node_algorithms::insert_equal
496 (node_ptr(&priv_header()), hint.pointed_node(), to_insert, key_node_comp), this);
499 //! <b>Requires</b>: Dereferencing iterator must yield an lvalue
500 //! of type value_type.
501 //!
502 //! <b>Effects</b>: Inserts a each element of a range into the tree
503 //! before the upper bound of the key of each element.
504 //!
505 //! <b>Complexity</b>: Insert range is in general O(N * log(N)), where N is the
506 //! size of the range. However, it is linear in N if the range is already sorted
507 //! by value_comp().
508 //!
509 //! <b>Throws</b>: Nothing.
510 //!
511 //! <b>Note</b>: Does not affect the validity of iterators and references.
512 //! No copy-constructors are called.
513 template<class Iterator>
514 void insert_equal(Iterator b, Iterator e)
516 iterator iend(this->end());
517 for (; b != e; ++b)
518 this->insert_equal(iend, *b);
521 //! <b>Requires</b>: value must be an lvalue
522 //!
523 //! <b>Effects</b>: Inserts value into the tree if the value
524 //! is not already present.
525 //!
526 //! <b>Complexity</b>: Average complexity for insert element is at
527 //! most logarithmic.
528 //!
529 //! <b>Throws</b>: Nothing.
530 //!
531 //! <b>Note</b>: Does not affect the validity of iterators and references.
532 //! No copy-constructors are called.
533 std::pair<iterator, bool> insert_unique(reference value)
535 insert_commit_data commit_data;
536 std::pair<iterator, bool> ret = insert_unique_check(value, priv_comp(), commit_data);
537 if(!ret.second)
538 return ret;
539 return std::pair<iterator, bool> (insert_unique_commit(value, commit_data), true);
542 //! <b>Requires</b>: value must be an lvalue, and "hint" must be
543 //! a valid iterator
544 //!
545 //! <b>Effects</b>: Tries to insert x into the tree, using "hint" as a hint
546 //! to where it will be inserted.
547 //!
548 //! <b>Complexity</b>: Logarithmic in general, but it is amortized
549 //! constant time (two comparisons in the worst case)
550 //! if t is inserted immediately before hint.
551 //!
552 //! <b>Throws</b>: Nothing.
553 //!
554 //! <b>Note</b>: Does not affect the validity of iterators and references.
555 //! No copy-constructors are called.
556 iterator insert_unique(const_iterator hint, reference value)
558 insert_commit_data commit_data;
559 std::pair<iterator, bool> ret = insert_unique_check(hint, value, priv_comp(), commit_data);
560 if(!ret.second)
561 return ret.first;
562 return insert_unique_commit(value, commit_data);
565 //! <b>Requires</b>: Dereferencing iterator must yield an lvalue
566 //! of type value_type.
567 //!
568 //! <b>Effects</b>: Tries to insert each element of a range into the tree.
569 //!
570 //! <b>Complexity</b>: Insert range is in general O(N * log(N)), where N is the
571 //! size of the range. However, it is linear in N if the range is already sorted
572 //! by value_comp().
573 //!
574 //! <b>Throws</b>: Nothing.
575 //!
576 //! <b>Note</b>: Does not affect the validity of iterators and references.
577 //! No copy-constructors are called.
578 template<class Iterator>
579 void insert_unique(Iterator b, Iterator e)
581 if(this->empty()){
582 iterator iend(this->end());
583 for (; b != e; ++b)
584 this->insert_unique(iend, *b);
586 else{
587 for (; b != e; ++b)
588 this->insert_unique(*b);
592 //! <b>Requires</b>: key_value_comp must be a comparison function that induces
593 //! the same strict weak ordering as value_compare. The difference is that
594 //! key_value_comp compares an arbitrary key with the contained values.
595 //!
596 //! <b>Effects</b>: Checks if a value can be inserted in the container, using
597 //! a user provided key instead of the value itself.
599 //! <b>Returns</b>: If there is an equivalent value
600 //! returns a pair containing an iterator to the already present value
601 //! and false. If the value can be inserted returns true in the returned
602 //! pair boolean and fills "commit_data" that is meant to be used with
603 //! the "insert_commit" function.
604 //!
605 //! <b>Complexity</b>: Average complexity is at most logarithmic.
607 //! <b>Throws</b>: If the key_value_comp ordering function throws. Strong guarantee.
608 //!
609 //! <b>Notes</b>: This function is used to improve performance when constructing
610 //! a value_type is expensive: if there is an equivalent value
611 //! the constructed object must be discarded. Many times, the part of the
612 //! node that is used to impose the order is much cheaper to construct
613 //! than the value_type and this function offers the possibility to use that
614 //! part to check if the insertion will be successful.
616 //! If the check is successful, the user can construct the value_type and use
617 //! "insert_commit" to insert the object in constant-time. This gives a total
618 //! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)).
620 //! "commit_data" remains valid for a subsequent "insert_commit" only if no more
621 //! objects are inserted or erased from the container.
622 template<class KeyType, class KeyValueCompare>
623 std::pair<iterator, bool> insert_unique_check
624 (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data)
626 detail::key_nodeptr_comp<KeyValueCompare, rbtree_impl>
627 comp(key_value_comp, this);
628 std::pair<node_ptr, bool> ret =
629 (node_algorithms::insert_unique_check
630 (node_ptr(&priv_header()), key, comp, commit_data));
631 return std::pair<iterator, bool>(iterator(ret.first, this), ret.second);
634 //! <b>Requires</b>: key_value_comp must be a comparison function that induces
635 //! the same strict weak ordering as value_compare. The difference is that
636 //! key_value_comp compares an arbitrary key with the contained values.
637 //!
638 //! <b>Effects</b>: Checks if a value can be inserted in the container, using
639 //! a user provided key instead of the value itself, using "hint"
640 //! as a hint to where it will be inserted.
642 //! <b>Returns</b>: If there is an equivalent value
643 //! returns a pair containing an iterator to the already present value
644 //! and false. If the value can be inserted returns true in the returned
645 //! pair boolean and fills "commit_data" that is meant to be used with
646 //! the "insert_commit" function.
647 //!
648 //! <b>Complexity</b>: Logarithmic in general, but it's amortized
649 //! constant time if t is inserted immediately before hint.
651 //! <b>Throws</b>: If the key_value_comp ordering function throws. Strong guarantee.
652 //!
653 //! <b>Notes</b>: This function is used to improve performance when constructing
654 //! a value_type is expensive: if there is an equivalent value
655 //! the constructed object must be discarded. Many times, the part of the
656 //! constructing that is used to impose the order is much cheaper to construct
657 //! than the value_type and this function offers the possibility to use that key
658 //! to check if the insertion will be successful.
660 //! If the check is successful, the user can construct the value_type and use
661 //! "insert_commit" to insert the object in constant-time. This can give a total
662 //! constant-time complexity to the insertion: check(O(1)) + commit(O(1)).
663 //!
664 //! "commit_data" remains valid for a subsequent "insert_commit" only if no more
665 //! objects are inserted or erased from the container.
666 template<class KeyType, class KeyValueCompare>
667 std::pair<iterator, bool> insert_unique_check
668 (const_iterator hint, const KeyType &key
669 ,KeyValueCompare key_value_comp, insert_commit_data &commit_data)
671 detail::key_nodeptr_comp<KeyValueCompare, rbtree_impl>
672 comp(key_value_comp, this);
673 std::pair<node_ptr, bool> ret =
674 (node_algorithms::insert_unique_check
675 (node_ptr(&priv_header()), hint.pointed_node(), key, comp, commit_data));
676 return std::pair<iterator, bool>(iterator(ret.first, this), ret.second);
679 //! <b>Requires</b>: value must be an lvalue of type value_type. commit_data
680 //! must have been obtained from a previous call to "insert_check".
681 //! No objects should have been inserted or erased from the container between
682 //! the "insert_check" that filled "commit_data" and the call to "insert_commit".
683 //!
684 //! <b>Effects</b>: Inserts the value in the avl_set using the information obtained
685 //! from the "commit_data" that a previous "insert_check" filled.
687 //! <b>Returns</b>: An iterator to the newly inserted object.
688 //!
689 //! <b>Complexity</b>: Constant time.
691 //! <b>Throws</b>: Nothing.
692 //!
693 //! <b>Notes</b>: This function has only sense if a "insert_check" has been
694 //! previously executed to fill "commit_data". No value should be inserted or
695 //! erased between the "insert_check" and "insert_commit" calls.
696 iterator insert_unique_commit(reference value, const insert_commit_data &commit_data)
698 node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
699 if(safemode_or_autounlink)
700 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
701 this->priv_size_traits().increment();
702 node_algorithms::insert_unique_commit
703 (node_ptr(&priv_header()), to_insert, commit_data);
704 return iterator(to_insert, this);
707 //! <b>Effects</b>: Erases the element pointed to by pos.
708 //!
709 //! <b>Complexity</b>: Average complexity for erase element is constant time.
710 //!
711 //! <b>Throws</b>: Nothing.
712 //!
713 //! <b>Note</b>: Invalidates the iterators (but not the references)
714 //! to the erased elements. No destructors are called.
715 iterator erase(const_iterator i)
717 const_iterator ret(i);
718 ++ret;
719 node_ptr to_erase(i.pointed_node());
720 if(safemode_or_autounlink)
721 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!node_algorithms::unique(to_erase));
722 node_algorithms::erase(&priv_header(), to_erase);
723 this->priv_size_traits().decrement();
724 if(safemode_or_autounlink)
725 node_algorithms::init(to_erase);
726 return ret.unconst();
729 //! <b>Effects</b>: Erases the range pointed to by b end e.
730 //!
731 //! <b>Complexity</b>: Average complexity for erase range is at most
732 //! O(log(size() + N)), where N is the number of elements in the range.
733 //!
734 //! <b>Throws</b>: Nothing.
735 //!
736 //! <b>Note</b>: Invalidates the iterators (but not the references)
737 //! to the erased elements. No destructors are called.
738 iterator erase(const_iterator b, const_iterator e)
739 { size_type n; return private_erase(b, e, n); }
741 //! <b>Effects</b>: Erases all the elements with the given value.
742 //!
743 //! <b>Returns</b>: The number of erased elements.
744 //!
745 //! <b>Complexity</b>: O(log(size() + N).
746 //!
747 //! <b>Throws</b>: Nothing.
748 //!
749 //! <b>Note</b>: Invalidates the iterators (but not the references)
750 //! to the erased elements. No destructors are called.
751 size_type erase(const_reference value)
752 { return this->erase(value, priv_comp()); }
754 //! <b>Effects</b>: Erases all the elements with the given key.
755 //! according to the comparison functor "comp".
757 //! <b>Returns</b>: The number of erased elements.
758 //!
759 //! <b>Complexity</b>: O(log(size() + N).
760 //!
761 //! <b>Throws</b>: Nothing.
762 //!
763 //! <b>Note</b>: Invalidates the iterators (but not the references)
764 //! to the erased elements. No destructors are called.
765 template<class KeyType, class KeyValueCompare>
766 size_type erase(const KeyType& key, KeyValueCompare comp
767 /// @cond
768 , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
769 /// @endcond
772 std::pair<iterator,iterator> p = this->equal_range(key, comp);
773 size_type n;
774 private_erase(p.first, p.second, n);
775 return n;
778 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
780 //! <b>Effects</b>: Erases the element pointed to by pos.
781 //! Disposer::operator()(pointer) is called for the removed element.
782 //!
783 //! <b>Complexity</b>: Average complexity for erase element is constant time.
784 //!
785 //! <b>Throws</b>: Nothing.
786 //!
787 //! <b>Note</b>: Invalidates the iterators
788 //! to the erased elements.
789 template<class Disposer>
790 iterator erase_and_dispose(const_iterator i, Disposer disposer)
792 node_ptr to_erase(i.pointed_node());
793 iterator ret(this->erase(i));
794 disposer(get_real_value_traits().to_value_ptr(to_erase));
795 return ret;
798 #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
799 template<class Disposer>
800 iterator erase_and_dispose(iterator i, Disposer disposer)
801 { return this->erase_and_dispose(const_iterator(i), disposer); }
802 #endif
804 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
806 //! <b>Effects</b>: Erases all the elements with the given value.
807 //! Disposer::operator()(pointer) is called for the removed elements.
808 //!
809 //! <b>Returns</b>: The number of erased elements.
810 //!
811 //! <b>Complexity</b>: O(log(size() + N).
812 //!
813 //! <b>Throws</b>: Nothing.
814 //!
815 //! <b>Note</b>: Invalidates the iterators (but not the references)
816 //! to the erased elements. No destructors are called.
817 template<class Disposer>
818 size_type erase_and_dispose(const_reference value, Disposer disposer)
820 std::pair<iterator,iterator> p = this->equal_range(value);
821 size_type n;
822 private_erase(p.first, p.second, n, disposer);
823 return n;
826 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
828 //! <b>Effects</b>: Erases the range pointed to by b end e.
829 //! Disposer::operator()(pointer) is called for the removed elements.
830 //!
831 //! <b>Complexity</b>: Average complexity for erase range is at most
832 //! O(log(size() + N)), where N is the number of elements in the range.
833 //!
834 //! <b>Throws</b>: Nothing.
835 //!
836 //! <b>Note</b>: Invalidates the iterators
837 //! to the erased elements.
838 template<class Disposer>
839 iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer)
840 { size_type n; return private_erase(b, e, n, disposer); }
842 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
844 //! <b>Effects</b>: Erases all the elements with the given key.
845 //! according to the comparison functor "comp".
846 //! Disposer::operator()(pointer) is called for the removed elements.
848 //! <b>Returns</b>: The number of erased elements.
849 //!
850 //! <b>Complexity</b>: O(log(size() + N).
851 //!
852 //! <b>Throws</b>: Nothing.
853 //!
854 //! <b>Note</b>: Invalidates the iterators
855 //! to the erased elements.
856 template<class KeyType, class KeyValueCompare, class Disposer>
857 size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer
858 /// @cond
859 , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
860 /// @endcond
863 std::pair<iterator,iterator> p = this->equal_range(key, comp);
864 size_type n;
865 private_erase(p.first, p.second, n, disposer);
866 return n;
869 //! <b>Effects</b>: Erases all of the elements.
870 //!
871 //! <b>Complexity</b>: Linear to the number of elements on the container.
872 //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise.
873 //!
874 //! <b>Throws</b>: Nothing.
875 //!
876 //! <b>Note</b>: Invalidates the iterators (but not the references)
877 //! to the erased elements. No destructors are called.
878 void clear()
880 if(safemode_or_autounlink){
881 this->clear_and_dispose(detail::null_disposer());
883 else{
884 node_algorithms::init_header(&priv_header());
885 this->priv_size_traits().set_size(0);
889 //! <b>Effects</b>: Erases all of the elements calling disposer(p) for
890 //! each node to be erased.
891 //! <b>Complexity</b>: Average complexity for is at most O(log(size() + N)),
892 //! where N is the number of elements in the container.
893 //!
894 //! <b>Throws</b>: Nothing.
895 //!
896 //! <b>Note</b>: Invalidates the iterators (but not the references)
897 //! to the erased elements. Calls N times to disposer functor.
898 template<class Disposer>
899 void clear_and_dispose(Disposer disposer)
901 node_algorithms::clear_and_dispose(node_ptr(&priv_header())
902 , detail::node_disposer<Disposer, rbtree_impl>(disposer, this));
903 node_algorithms::init_header(&priv_header());
904 this->priv_size_traits().set_size(0);
907 //! <b>Effects</b>: Returns the number of contained elements with the given value
908 //!
909 //! <b>Complexity</b>: Logarithmic to the number of elements contained plus lineal
910 //! to number of objects with the given value.
911 //!
912 //! <b>Throws</b>: Nothing.
913 size_type count(const_reference value) const
914 { return this->count(value, priv_comp()); }
916 //! <b>Effects</b>: Returns the number of contained elements with the given key
917 //!
918 //! <b>Complexity</b>: Logarithmic to the number of elements contained plus lineal
919 //! to number of objects with the given key.
920 //!
921 //! <b>Throws</b>: Nothing.
922 template<class KeyType, class KeyValueCompare>
923 size_type count(const KeyType &key, KeyValueCompare comp) const
925 std::pair<const_iterator, const_iterator> ret = this->equal_range(key, comp);
926 return std::distance(ret.first, ret.second);
929 //! <b>Effects</b>: Returns an iterator to the first element whose
930 //! key is not less than k or end() if that element does not exist.
931 //!
932 //! <b>Complexity</b>: Logarithmic.
933 //!
934 //! <b>Throws</b>: Nothing.
935 iterator lower_bound(const_reference value)
936 { return this->lower_bound(value, priv_comp()); }
938 //! <b>Effects</b>: Returns an iterator to the first element whose
939 //! key is not less than k or end() if that element does not exist.
940 //!
941 //! <b>Complexity</b>: Logarithmic.
942 //!
943 //! <b>Throws</b>: Nothing.
944 const_iterator lower_bound(const_reference value) const
945 { return this->lower_bound(value, priv_comp()); }
947 //! <b>Effects</b>: Returns an iterator to the first element whose
948 //! key is not less than k or end() if that element does not exist.
949 //!
950 //! <b>Complexity</b>: Logarithmic.
951 //!
952 //! <b>Throws</b>: Nothing.
953 template<class KeyType, class KeyValueCompare>
954 iterator lower_bound(const KeyType &key, KeyValueCompare comp)
956 detail::key_nodeptr_comp<KeyValueCompare, rbtree_impl>
957 key_node_comp(comp, this);
958 return iterator(node_algorithms::lower_bound
959 (const_node_ptr(&priv_header()), key, key_node_comp), this);
962 //! <b>Effects</b>: Returns a const iterator to the first element whose
963 //! key is not less than k or end() if that element does not exist.
964 //!
965 //! <b>Complexity</b>: Logarithmic.
966 //!
967 //! <b>Throws</b>: Nothing.
968 template<class KeyType, class KeyValueCompare>
969 const_iterator lower_bound(const KeyType &key, KeyValueCompare comp) const
971 detail::key_nodeptr_comp<KeyValueCompare, rbtree_impl>
972 key_node_comp(comp, this);
973 return const_iterator(node_algorithms::lower_bound
974 (const_node_ptr(&priv_header()), key, key_node_comp), this);
977 //! <b>Effects</b>: Returns an iterator to the first element whose
978 //! key is greater than k or end() if that element does not exist.
979 //!
980 //! <b>Complexity</b>: Logarithmic.
981 //!
982 //! <b>Throws</b>: Nothing.
983 iterator upper_bound(const_reference value)
984 { return this->upper_bound(value, priv_comp()); }
986 //! <b>Effects</b>: Returns an iterator to the first element whose
987 //! key is greater than k according to comp or end() if that element
988 //! does not exist.
990 //! <b>Complexity</b>: Logarithmic.
991 //!
992 //! <b>Throws</b>: Nothing.
993 template<class KeyType, class KeyValueCompare>
994 iterator upper_bound(const KeyType &key, KeyValueCompare comp)
996 detail::key_nodeptr_comp<KeyValueCompare, rbtree_impl>
997 key_node_comp(comp, this);
998 return iterator(node_algorithms::upper_bound
999 (const_node_ptr(&priv_header()), key, key_node_comp), this);
1002 //! <b>Effects</b>: Returns an iterator to the first element whose
1003 //! key is greater than k or end() if that element does not exist.
1004 //!
1005 //! <b>Complexity</b>: Logarithmic.
1006 //!
1007 //! <b>Throws</b>: Nothing.
1008 const_iterator upper_bound(const_reference value) const
1009 { return this->upper_bound(value, priv_comp()); }
1011 //! <b>Effects</b>: Returns an iterator to the first element whose
1012 //! key is greater than k according to comp or end() if that element
1013 //! does not exist.
1015 //! <b>Complexity</b>: Logarithmic.
1016 //!
1017 //! <b>Throws</b>: Nothing.
1018 template<class KeyType, class KeyValueCompare>
1019 const_iterator upper_bound(const KeyType &key, KeyValueCompare comp) const
1021 detail::key_nodeptr_comp<KeyValueCompare, rbtree_impl>
1022 key_node_comp(comp, this);
1023 return const_iterator(node_algorithms::upper_bound
1024 (const_node_ptr(&priv_header()), key, key_node_comp), this);
1027 //! <b>Effects</b>: Finds an iterator to the first element whose key is
1028 //! k or end() if that element does not exist.
1030 //! <b>Complexity</b>: Logarithmic.
1031 //!
1032 //! <b>Throws</b>: Nothing.
1033 iterator find(const_reference value)
1034 { return this->find(value, priv_comp()); }
1036 //! <b>Effects</b>: Finds an iterator to the first element whose key is
1037 //! k or end() if that element does not exist.
1039 //! <b>Complexity</b>: Logarithmic.
1040 //!
1041 //! <b>Throws</b>: Nothing.
1042 template<class KeyType, class KeyValueCompare>
1043 iterator find(const KeyType &key, KeyValueCompare comp)
1045 detail::key_nodeptr_comp<KeyValueCompare, rbtree_impl>
1046 key_node_comp(comp, this);
1047 return iterator
1048 (node_algorithms::find(const_node_ptr(&priv_header()), key, key_node_comp), this);
1051 //! <b>Effects</b>: Finds a const_iterator to the first element whose key is
1052 //! k or end() if that element does not exist.
1053 //!
1054 //! <b>Complexity</b>: Logarithmic.
1055 //!
1056 //! <b>Throws</b>: Nothing.
1057 const_iterator find(const_reference value) const
1058 { return this->find(value, priv_comp()); }
1060 //! <b>Effects</b>: Finds a const_iterator to the first element whose key is
1061 //! k or end() if that element does not exist.
1062 //!
1063 //! <b>Complexity</b>: Logarithmic.
1064 //!
1065 //! <b>Throws</b>: Nothing.
1066 template<class KeyType, class KeyValueCompare>
1067 const_iterator find(const KeyType &key, KeyValueCompare comp) const
1069 detail::key_nodeptr_comp<KeyValueCompare, rbtree_impl>
1070 key_node_comp(comp, this);
1071 return const_iterator
1072 (node_algorithms::find(const_node_ptr(&priv_header()), key, key_node_comp), this);
1075 //! <b>Effects</b>: Finds a range containing all elements whose key is k or
1076 //! an empty range that indicates the position where those elements would be
1077 //! if they there is no elements with key k.
1078 //!
1079 //! <b>Complexity</b>: Logarithmic.
1080 //!
1081 //! <b>Throws</b>: Nothing.
1082 std::pair<iterator,iterator> equal_range(const_reference value)
1083 { return this->equal_range(value, priv_comp()); }
1085 //! <b>Effects</b>: Finds a range containing all elements whose key is k or
1086 //! an empty range that indicates the position where those elements would be
1087 //! if they there is no elements with key k.
1088 //!
1089 //! <b>Complexity</b>: Logarithmic.
1090 //!
1091 //! <b>Throws</b>: Nothing.
1092 template<class KeyType, class KeyValueCompare>
1093 std::pair<iterator,iterator> equal_range(const KeyType &key, KeyValueCompare comp)
1095 detail::key_nodeptr_comp<KeyValueCompare, rbtree_impl>
1096 key_node_comp(comp, this);
1097 std::pair<node_ptr, node_ptr> ret
1098 (node_algorithms::equal_range(const_node_ptr(&priv_header()), key, key_node_comp));
1099 return std::pair<iterator, iterator>(iterator(ret.first, this), iterator(ret.second, this));
1102 //! <b>Effects</b>: Finds a range containing all elements whose key is k or
1103 //! an empty range that indicates the position where those elements would be
1104 //! if they there is no elements with key k.
1105 //!
1106 //! <b>Complexity</b>: Logarithmic.
1107 //!
1108 //! <b>Throws</b>: Nothing.
1109 std::pair<const_iterator, const_iterator>
1110 equal_range(const_reference value) const
1111 { return this->equal_range(value, priv_comp()); }
1113 //! <b>Effects</b>: Finds a range containing all elements whose key is k or
1114 //! an empty range that indicates the position where those elements would be
1115 //! if they there is no elements with key k.
1116 //!
1117 //! <b>Complexity</b>: Logarithmic.
1118 //!
1119 //! <b>Throws</b>: Nothing.
1120 template<class KeyType, class KeyValueCompare>
1121 std::pair<const_iterator, const_iterator>
1122 equal_range(const KeyType &key, KeyValueCompare comp) const
1124 detail::key_nodeptr_comp<KeyValueCompare, rbtree_impl>
1125 key_node_comp(comp, this);
1126 std::pair<node_ptr, node_ptr> ret
1127 (node_algorithms::equal_range(const_node_ptr(&priv_header()), key, key_node_comp));
1128 return std::pair<const_iterator, const_iterator>(const_iterator(ret.first, this), const_iterator(ret.second, this));
1131 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
1132 //! Cloner should yield to nodes equivalent to the original nodes.
1134 //! <b>Effects</b>: Erases all the elements from *this
1135 //! calling Disposer::operator()(pointer), clones all the
1136 //! elements from src calling Cloner::operator()(const_reference )
1137 //! and inserts them on *this. Copies the predicate from the source container.
1139 //! If cloner throws, all cloned elements are unlinked and disposed
1140 //! calling Disposer::operator()(pointer).
1141 //!
1142 //! <b>Complexity</b>: Linear to erased plus inserted elements.
1143 //!
1144 //! <b>Throws</b>: If cloner throws or predicate copy assignment throws. Basic guarantee.
1145 template <class Cloner, class Disposer>
1146 void clone_from(const rbtree_impl &src, Cloner cloner, Disposer disposer)
1148 this->clear_and_dispose(disposer);
1149 if(!src.empty()){
1150 detail::exception_disposer<rbtree_impl, Disposer>
1151 rollback(*this, disposer);
1152 node_algorithms::clone
1153 (const_node_ptr(&src.priv_header())
1154 ,node_ptr(&this->priv_header())
1155 ,detail::node_cloner<Cloner, rbtree_impl>(cloner, this)
1156 ,detail::node_disposer<Disposer, rbtree_impl>(disposer, this));
1157 this->priv_size_traits().set_size(src.priv_size_traits().get_size());
1158 this->priv_comp() = src.priv_comp();
1159 rollback.release();
1163 //! <b>Effects</b>: Unlinks the leftmost node from the tree.
1164 //!
1165 //! <b>Complexity</b>: Average complexity is constant time.
1166 //!
1167 //! <b>Throws</b>: Nothing.
1168 //!
1169 //! <b>Notes</b>: This function breaks the tree and the tree can
1170 //! only be used for more unlink_leftmost_without_rebalance calls.
1171 //! This function is normally used to achieve a step by step
1172 //! controlled destruction of the tree.
1173 pointer unlink_leftmost_without_rebalance()
1175 node_ptr to_be_disposed(node_algorithms::unlink_leftmost_without_rebalance
1176 (node_ptr(&priv_header())));
1177 if(!to_be_disposed)
1178 return 0;
1179 this->priv_size_traits().decrement();
1180 if(safemode_or_autounlink)//If this is commented does not work with normal_link
1181 node_algorithms::init(to_be_disposed);
1182 return get_real_value_traits().to_value_ptr(to_be_disposed);
1185 //! <b>Requires</b>: replace_this must be a valid iterator of *this
1186 //! and with_this must not be inserted in any tree.
1187 //!
1188 //! <b>Effects</b>: Replaces replace_this in its position in the
1189 //! tree with with_this. The tree does not need to be rebalanced.
1190 //!
1191 //! <b>Complexity</b>: Constant.
1192 //!
1193 //! <b>Throws</b>: Nothing.
1194 //!
1195 //! <b>Note</b>: This function will break container ordering invariants if
1196 //! with_this is not equivalent to *replace_this according to the
1197 //! ordering rules. This function is faster than erasing and inserting
1198 //! the node, since no rebalancing or comparison is needed.
1199 void replace_node(iterator replace_this, reference with_this)
1201 node_algorithms::replace_node( get_real_value_traits().to_node_ptr(*replace_this)
1202 , node_ptr(&priv_header())
1203 , get_real_value_traits().to_node_ptr(with_this));
1206 //! <b>Requires</b>: value must be an lvalue and shall be in a set of
1207 //! appropriate type. Otherwise the behavior is undefined.
1208 //!
1209 //! <b>Effects</b>: Returns: a valid iterator i belonging to the set
1210 //! that points to the value
1211 //!
1212 //! <b>Complexity</b>: Constant.
1213 //!
1214 //! <b>Throws</b>: Nothing.
1215 //!
1216 //! <b>Note</b>: This static function is available only if the <i>value traits</i>
1217 //! is stateless.
1218 static iterator s_iterator_to(reference value)
1220 BOOST_STATIC_ASSERT((!stateful_value_traits));
1221 return iterator (value_traits::to_node_ptr(value), 0);
1224 //! <b>Requires</b>: value must be an lvalue and shall be in a set of
1225 //! appropriate type. Otherwise the behavior is undefined.
1226 //!
1227 //! <b>Effects</b>: Returns: a valid const_iterator i belonging to the
1228 //! set that points to the value
1229 //!
1230 //! <b>Complexity</b>: Constant.
1231 //!
1232 //! <b>Throws</b>: Nothing.
1233 //!
1234 //! <b>Note</b>: This static function is available only if the <i>value traits</i>
1235 //! is stateless.
1236 static const_iterator s_iterator_to(const_reference value)
1238 BOOST_STATIC_ASSERT((!stateful_value_traits));
1239 return const_iterator (value_traits::to_node_ptr(const_cast<reference> (value)), 0);
1242 //! <b>Requires</b>: value must be an lvalue and shall be in a set of
1243 //! appropriate type. Otherwise the behavior is undefined.
1244 //!
1245 //! <b>Effects</b>: Returns: a valid iterator i belonging to the set
1246 //! that points to the value
1247 //!
1248 //! <b>Complexity</b>: Constant.
1249 //!
1250 //! <b>Throws</b>: Nothing.
1251 iterator iterator_to(reference value)
1252 { return iterator (value_traits::to_node_ptr(value), this); }
1254 //! <b>Requires</b>: value must be an lvalue and shall be in a set of
1255 //! appropriate type. Otherwise the behavior is undefined.
1256 //!
1257 //! <b>Effects</b>: Returns: a valid const_iterator i belonging to the
1258 //! set that points to the value
1259 //!
1260 //! <b>Complexity</b>: Constant.
1261 //!
1262 //! <b>Throws</b>: Nothing.
1263 const_iterator iterator_to(const_reference value) const
1264 { return const_iterator (value_traits::to_node_ptr(const_cast<reference> (value)), this); }
1266 //! <b>Requires</b>: value shall not be in a tree.
1267 //!
1268 //! <b>Effects</b>: init_node puts the hook of a value in a well-known default
1269 //! state.
1270 //!
1271 //! <b>Throws</b>: Nothing.
1272 //!
1273 //! <b>Complexity</b>: Constant time.
1274 //!
1275 //! <b>Note</b>: This function puts the hook in the well-known default state
1276 //! used by auto_unlink and safe hooks.
1277 static void init_node(reference value)
1278 { node_algorithms::init(value_traits::to_node_ptr(value)); }
1280 //! <b>Effects</b>: removes "value" from the container.
1281 //!
1282 //! <b>Throws</b>: Nothing.
1283 //!
1284 //! <b>Complexity</b>: Logarithmic time.
1285 //!
1286 //! <b>Note</b>: This static function is only usable with non-constant
1287 //! time size containers that have stateless comparison functors.
1289 //! If the user calls
1290 //! this function with a constant time size container or stateful comparison
1291 //! functor a compilation error will be issued.
1292 static void remove_node(reference value)
1294 BOOST_STATIC_ASSERT((!constant_time_size));
1295 node_ptr to_remove(value_traits::to_node_ptr(value));
1296 node_algorithms::unlink(to_remove);
1297 if(safemode_or_autounlink)
1298 node_algorithms::init(to_remove);
1301 /// @cond
1302 private:
1303 template<class Disposer>
1304 iterator private_erase(const_iterator b, const_iterator e, size_type &n, Disposer disposer)
1306 for(n = 0; b != e; ++n)
1307 this->erase_and_dispose(b++, disposer);
1308 return b.unconst();
1311 iterator private_erase(const_iterator b, const_iterator e, size_type &n)
1313 for(n = 0; b != e; ++n)
1314 this->erase(b++);
1315 return b.unconst();
1317 /// @endcond
1319 private:
1320 static rbtree_impl &priv_container_from_end_iterator(const const_iterator &end_iterator)
1322 header_plus_size *r = detail::parent_from_member<header_plus_size, node>
1323 ( detail::get_pointer(end_iterator.pointed_node()), &header_plus_size::header_);
1324 node_plus_pred_t *n = detail::parent_from_member
1325 <node_plus_pred_t, header_plus_size>(r, &node_plus_pred_t::header_plus_size_);
1326 data_t *d = detail::parent_from_member<data_t, node_plus_pred_t>(n, &data_t::node_plus_pred_);
1327 rbtree_impl *rb = detail::parent_from_member<rbtree_impl, data_t>(d, &rbtree_impl::data_);
1328 return *rb;
1331 static rbtree_impl &priv_container_from_iterator(const const_iterator &it)
1332 { return priv_container_from_end_iterator(it.end_iterator_from_it()); }
1335 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1336 template<class T, class ...Options>
1337 #else
1338 template<class Config>
1339 #endif
1340 inline bool operator<
1341 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1342 (const rbtree_impl<T, Options...> &x, const rbtree_impl<T, Options...> &y)
1343 #else
1344 (const rbtree_impl<Config> &x, const rbtree_impl<Config> &y)
1345 #endif
1346 { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
1348 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1349 template<class T, class ...Options>
1350 #else
1351 template<class Config>
1352 #endif
1353 bool operator==
1354 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1355 (const rbtree_impl<T, Options...> &x, const rbtree_impl<T, Options...> &y)
1356 #else
1357 (const rbtree_impl<Config> &x, const rbtree_impl<Config> &y)
1358 #endif
1360 typedef rbtree_impl<Config> tree_type;
1361 typedef typename tree_type::const_iterator const_iterator;
1363 if(tree_type::constant_time_size && x.size() != y.size()){
1364 return false;
1366 const_iterator end1 = x.end();
1367 const_iterator i1 = x.begin();
1368 const_iterator i2 = y.begin();
1369 if(tree_type::constant_time_size){
1370 while (i1 != end1 && *i1 == *i2) {
1371 ++i1;
1372 ++i2;
1374 return i1 == end1;
1376 else{
1377 const_iterator end2 = y.end();
1378 while (i1 != end1 && i2 != end2 && *i1 == *i2) {
1379 ++i1;
1380 ++i2;
1382 return i1 == end1 && i2 == end2;
1386 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1387 template<class T, class ...Options>
1388 #else
1389 template<class Config>
1390 #endif
1391 inline bool operator!=
1392 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1393 (const rbtree_impl<T, Options...> &x, const rbtree_impl<T, Options...> &y)
1394 #else
1395 (const rbtree_impl<Config> &x, const rbtree_impl<Config> &y)
1396 #endif
1397 { return !(x == y); }
1399 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1400 template<class T, class ...Options>
1401 #else
1402 template<class Config>
1403 #endif
1404 inline bool operator>
1405 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1406 (const rbtree_impl<T, Options...> &x, const rbtree_impl<T, Options...> &y)
1407 #else
1408 (const rbtree_impl<Config> &x, const rbtree_impl<Config> &y)
1409 #endif
1410 { return y < x; }
1412 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1413 template<class T, class ...Options>
1414 #else
1415 template<class Config>
1416 #endif
1417 inline bool operator<=
1418 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1419 (const rbtree_impl<T, Options...> &x, const rbtree_impl<T, Options...> &y)
1420 #else
1421 (const rbtree_impl<Config> &x, const rbtree_impl<Config> &y)
1422 #endif
1423 { return !(y < x); }
1425 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1426 template<class T, class ...Options>
1427 #else
1428 template<class Config>
1429 #endif
1430 inline bool operator>=
1431 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1432 (const rbtree_impl<T, Options...> &x, const rbtree_impl<T, Options...> &y)
1433 #else
1434 (const rbtree_impl<Config> &x, const rbtree_impl<Config> &y)
1435 #endif
1436 { return !(x < y); }
1438 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1439 template<class T, class ...Options>
1440 #else
1441 template<class Config>
1442 #endif
1443 inline void swap
1444 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1445 (rbtree_impl<T, Options...> &x, rbtree_impl<T, Options...> &y)
1446 #else
1447 (rbtree_impl<Config> &x, rbtree_impl<Config> &y)
1448 #endif
1449 { x.swap(y); }
1451 /// @cond
1452 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1453 template<class T, class O1 = none, class O2 = none
1454 , class O3 = none, class O4 = none
1456 #else
1457 template<class T, class ...Options>
1458 #endif
1459 struct make_rbtree_opt
1461 typedef typename pack_options
1462 < set_defaults<T>,
1463 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1464 O1, O2, O3, O4
1465 #else
1466 Options...
1467 #endif
1468 >::type packed_options;
1469 typedef typename detail::get_value_traits
1470 <T, typename packed_options::value_traits>::type value_traits;
1472 typedef setopt
1473 < value_traits
1474 , typename packed_options::compare
1475 , typename packed_options::size_type
1476 , packed_options::constant_time_size
1477 > type;
1479 /// @endcond
1481 //! Helper metafunction to define a \c rbtree that yields to the same type when the
1482 //! same options (either explicitly or implicitly) are used.
1483 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1484 template<class T, class ...Options>
1485 #else
1486 template<class T, class O1 = none, class O2 = none
1487 , class O3 = none, class O4 = none>
1488 #endif
1489 struct make_rbtree
1491 /// @cond
1492 typedef rbtree_impl
1493 < typename make_rbtree_opt<T,
1494 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1495 O1, O2, O3, O4
1496 #else
1497 Options...
1498 #endif
1499 >::type
1500 > implementation_defined;
1501 /// @endcond
1502 typedef implementation_defined type;
1505 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
1507 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1508 template<class T, class O1, class O2, class O3, class O4>
1509 #else
1510 template<class T, class ...Options>
1511 #endif
1512 class rbtree
1513 : public make_rbtree<T,
1514 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1515 O1, O2, O3, O4
1516 #else
1517 Options...
1518 #endif
1519 >::type
1521 typedef typename make_rbtree
1522 <T,
1523 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1524 O1, O2, O3, O4
1525 #else
1526 Options...
1527 #endif
1528 >::type Base;
1530 public:
1531 typedef typename Base::value_compare value_compare;
1532 typedef typename Base::value_traits value_traits;
1533 typedef typename Base::real_value_traits real_value_traits;
1534 typedef typename Base::iterator iterator;
1535 typedef typename Base::const_iterator const_iterator;
1537 //Assert if passed value traits are compatible with the type
1538 BOOST_STATIC_ASSERT((detail::is_same<typename real_value_traits::value_type, T>::value));
1540 rbtree( const value_compare &cmp = value_compare()
1541 , const value_traits &v_traits = value_traits())
1542 : Base(cmp, v_traits)
1545 template<class Iterator>
1546 rbtree( bool unique, Iterator b, Iterator e
1547 , const value_compare &cmp = value_compare()
1548 , const value_traits &v_traits = value_traits())
1549 : Base(unique, b, e, cmp, v_traits)
1552 static rbtree &container_from_end_iterator(iterator end_iterator)
1553 { return static_cast<rbtree &>(Base::container_from_end_iterator(end_iterator)); }
1555 static const rbtree &container_from_end_iterator(const_iterator end_iterator)
1556 { return static_cast<const rbtree &>(Base::container_from_end_iterator(end_iterator)); }
1558 static rbtree &container_from_it(iterator it)
1559 { return static_cast<rbtree &>(Base::container_from_iterator(it)); }
1561 static const rbtree &container_from_it(const_iterator it)
1562 { return static_cast<const rbtree &>(Base::container_from_iterator(it)); }
1565 #endif
1568 } //namespace intrusive
1569 } //namespace boost
1571 #include <boost/intrusive/detail/config_end.hpp>
1573 #endif //BOOST_INTRUSIVE_RBTREE_HPP