fix doc example typo
[boost.git] / boost / intrusive / treap.hpp
blob7298db303c5480444ff26b2d88ea757944935cac
1 /////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 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_TRIE_HPP
13 #define BOOST_INTRUSIVE_TRIE_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/bs_set_hook.hpp>
26 #include <boost/intrusive/detail/tree_node.hpp>
27 #include <boost/intrusive/detail/ebo_functor_holder.hpp>
28 #include <boost/intrusive/detail/pointer_to_other.hpp>
29 #include <boost/intrusive/detail/clear_on_destructor_base.hpp>
30 #include <boost/intrusive/options.hpp>
31 #include <boost/intrusive/detail/mpl.hpp>
32 #include <boost/intrusive/treap_algorithms.hpp>
33 #include <boost/intrusive/link_mode.hpp>
34 #include <boost/intrusive/priority_compare.hpp>
36 namespace boost {
37 namespace intrusive {
39 /// @cond
41 template <class ValueTraits, class Compare, class PrioCompare, class SizeType, bool ConstantTimeSize>
42 struct treap_setopt
44 typedef ValueTraits value_traits;
45 typedef Compare compare;
46 typedef PrioCompare priority_compare;
47 typedef SizeType size_type;
48 static const bool constant_time_size = ConstantTimeSize;
51 template <class T>
52 struct treap_set_defaults
53 : pack_options
54 < none
55 , base_hook<detail::default_bs_set_hook>
56 , constant_time_size<true>
57 , size_type<std::size_t>
58 , compare<std::less<T> >
59 , priority<boost::intrusive::priority_compare<T> >
60 >::type
61 {};
63 /// @endcond
65 //! The class template treap is an intrusive treap container that
66 //! is used to construct intrusive set and multiset containers. The no-throw
67 //! guarantee holds only, if the value_compare object and priority_compare object
68 //! don't throw.
69 //!
70 //! The template parameter \c T is the type to be managed by the container.
71 //! The user can specify additional options and if no options are provided
72 //! default options are used.
73 //!
74 //! The container supports the following options:
75 //! \c base_hook<>/member_hook<>/value_traits<>,
76 //! \c constant_time_size<>, \c size_type<>,
77 //! \c compare<> and \c priority_compare<>
78 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
79 template<class T, class ...Options>
80 #else
81 template<class Config>
82 #endif
83 class treap_impl
84 : private detail::clear_on_destructor_base<treap_impl<Config> >
86 template<class C> friend class detail::clear_on_destructor_base;
87 public:
88 typedef typename Config::value_traits value_traits;
89 /// @cond
90 static const bool external_value_traits =
91 detail::external_value_traits_is_true<value_traits>::value;
92 typedef typename detail::eval_if_c
93 < external_value_traits
94 , detail::eval_value_traits<value_traits>
95 , detail::identity<value_traits>
96 >::type real_value_traits;
97 /// @endcond
98 typedef typename real_value_traits::pointer pointer;
99 typedef typename real_value_traits::const_pointer const_pointer;
100 typedef typename std::iterator_traits<pointer>::value_type value_type;
101 typedef value_type key_type;
102 typedef typename std::iterator_traits<pointer>::reference reference;
103 typedef typename std::iterator_traits<const_pointer>::reference const_reference;
104 typedef typename std::iterator_traits<pointer>::difference_type difference_type;
105 typedef typename Config::size_type size_type;
106 typedef typename Config::compare value_compare;
107 typedef typename Config::priority_compare priority_compare;
108 typedef value_compare key_compare;
109 typedef tree_iterator<treap_impl, false> iterator;
110 typedef tree_iterator<treap_impl, true> const_iterator;
111 typedef std::reverse_iterator<iterator> reverse_iterator;
112 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
113 typedef typename real_value_traits::node_traits node_traits;
114 typedef typename node_traits::node node;
115 typedef typename boost::pointer_to_other
116 <pointer, node>::type node_ptr;
117 typedef typename boost::pointer_to_other
118 <node_ptr, const node>::type const_node_ptr;
119 typedef treap_algorithms<node_traits> node_algorithms;
121 static const bool constant_time_size = Config::constant_time_size;
122 static const bool stateful_value_traits = detail::store_cont_ptr_on_it<treap_impl>::value;
124 /// @cond
125 private:
126 typedef detail::size_holder<constant_time_size, size_type> size_traits;
128 //noncopyable
129 treap_impl (const treap_impl&);
130 treap_impl operator =(const treap_impl&);
132 enum { safemode_or_autounlink =
133 (int)real_value_traits::link_mode == (int)auto_unlink ||
134 (int)real_value_traits::link_mode == (int)safe_link };
136 //Constant-time size is incompatible with auto-unlink hooks!
137 BOOST_STATIC_ASSERT(!(constant_time_size && ((int)real_value_traits::link_mode == (int)auto_unlink)));
139 struct header_plus_size : public size_traits
140 { node header_; };
142 struct node_plus_pred_t : public detail::ebo_functor_holder<value_compare>
144 node_plus_pred_t(const value_compare &comp, const priority_compare &p_comp)
145 : detail::ebo_functor_holder<value_compare>(comp)
146 , header_plus_priority_size_(p_comp)
148 struct header_plus_priority_size
149 : public detail::ebo_functor_holder<priority_compare>
151 header_plus_priority_size(const priority_compare &p_comp)
152 : detail::ebo_functor_holder<priority_compare>(p_comp)
154 header_plus_size header_plus_size_;
155 } header_plus_priority_size_;
158 struct data_t : public treap_impl::value_traits
160 typedef typename treap_impl::value_traits value_traits;
161 data_t(const value_compare & comp, const priority_compare &pcomp, const value_traits &val_traits)
162 : value_traits(val_traits), node_plus_pred_(comp, pcomp)
164 node_plus_pred_t node_plus_pred_;
165 } data_;
167 const value_compare &priv_comp() const
168 { return data_.node_plus_pred_.get(); }
170 value_compare &priv_comp()
171 { return data_.node_plus_pred_.get(); }
173 const priority_compare &priv_pcomp() const
174 { return data_.node_plus_pred_.header_plus_priority_size_.get(); }
176 priority_compare &priv_pcomp()
177 { return data_.node_plus_pred_.header_plus_priority_size_.get(); }
179 const node &priv_header() const
180 { return data_.node_plus_pred_.header_plus_priority_size_.header_plus_size_.header_; }
182 node &priv_header()
183 { return data_.node_plus_pred_.header_plus_priority_size_.header_plus_size_.header_; }
185 static node_ptr uncast(const_node_ptr ptr)
187 return node_ptr(const_cast<node*>(detail::get_pointer(ptr)));
190 size_traits &priv_size_traits()
191 { return data_.node_plus_pred_.header_plus_priority_size_.header_plus_size_; }
193 const size_traits &priv_size_traits() const
194 { return data_.node_plus_pred_.header_plus_priority_size_.header_plus_size_; }
196 const real_value_traits &get_real_value_traits(detail::bool_<false>) const
197 { return data_; }
199 const real_value_traits &get_real_value_traits(detail::bool_<true>) const
200 { return data_.get_value_traits(*this); }
202 real_value_traits &get_real_value_traits(detail::bool_<false>)
203 { return data_; }
205 real_value_traits &get_real_value_traits(detail::bool_<true>)
206 { return data_.get_value_traits(*this); }
208 /// @endcond
210 public:
212 const real_value_traits &get_real_value_traits() const
213 { return this->get_real_value_traits(detail::bool_<external_value_traits>()); }
215 real_value_traits &get_real_value_traits()
216 { return this->get_real_value_traits(detail::bool_<external_value_traits>()); }
218 typedef typename node_algorithms::insert_commit_data insert_commit_data;
220 //! <b>Effects</b>: Constructs an empty tree.
221 //!
222 //! <b>Complexity</b>: Constant.
223 //!
224 //! <b>Throws</b>: If value_traits::node_traits::node
225 //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
226 //! or the copy constructor of the value_compare/priority_compare objects throw. Basic guarantee.
227 treap_impl( const value_compare &cmp = value_compare()
228 , const priority_compare &pcmp = priority_compare()
229 , const value_traits &v_traits = value_traits())
230 : data_(cmp, pcmp, v_traits)
232 node_algorithms::init_header(&priv_header());
233 this->priv_size_traits().set_size(size_type(0));
236 //! <b>Requires</b>: Dereferencing iterator must yield an lvalue of type value_type.
237 //! cmp must be a comparison function that induces a strict weak ordering.
239 //! <b>Effects</b>: Constructs an empty tree and inserts elements from
240 //! [b, e).
242 //! <b>Complexity</b>: Linear in N if [b, e) is already sorted using
243 //! comp and otherwise N * log N, where N is the distance between first and last.
244 //!
245 //! <b>Throws</b>: If value_traits::node_traits::node
246 //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
247 //! or the copy constructor/operator() of the value_compare/priority_compare objects
248 //! throw. Basic guarantee.
249 template<class Iterator>
250 treap_impl( bool unique, Iterator b, Iterator e
251 , const value_compare &cmp = value_compare()
252 , const priority_compare &pcmp = priority_compare()
253 , const value_traits &v_traits = value_traits())
254 : data_(cmp, pcmp, v_traits)
256 node_algorithms::init_header(&priv_header());
257 this->priv_size_traits().set_size(size_type(0));
258 if(unique)
259 this->insert_unique(b, e);
260 else
261 this->insert_equal(b, e);
264 //! <b>Effects</b>: Detaches all elements from this. The objects in the set
265 //! are not deleted (i.e. no destructors are called), but the nodes according to
266 //! the value_traits template parameter are reinitialized and thus can be reused.
267 //!
268 //! <b>Complexity</b>: Linear to elements contained in *this
269 //! if constant-time size option is disabled. Constant time otherwise.
270 //!
271 //! <b>Throws</b>: Nothing.
272 ~treap_impl()
275 //! <b>Effects</b>: Returns an iterator pointing to the beginning of the tree.
276 //!
277 //! <b>Complexity</b>: Constant.
278 //!
279 //! <b>Throws</b>: Nothing.
280 iterator begin()
281 { return iterator (node_traits::get_left(node_ptr(&priv_header())), this); }
283 //! <b>Effects</b>: Returns a const_iterator pointing to the beginning of the tree.
284 //!
285 //! <b>Complexity</b>: Constant.
286 //!
287 //! <b>Throws</b>: Nothing.
288 const_iterator begin() const
289 { return this->cbegin(); }
291 //! <b>Effects</b>: Returns a const_iterator pointing to the beginning of the tree.
292 //!
293 //! <b>Complexity</b>: Constant.
294 //!
295 //! <b>Throws</b>: Nothing.
296 const_iterator cbegin() const
297 { return const_iterator (node_traits::get_left(const_node_ptr(&priv_header())), this); }
299 //! <b>Effects</b>: Returns an iterator pointing to the end of the tree.
300 //!
301 //! <b>Complexity</b>: Constant.
302 //!
303 //! <b>Throws</b>: Nothing.
304 iterator end()
305 { return iterator (node_ptr(&priv_header()), this); }
307 //! <b>Effects</b>: Returns a const_iterator pointing to the end of the tree.
309 //! <b>Complexity</b>: Constant.
310 //!
311 //! <b>Throws</b>: Nothing.
312 const_iterator end() const
313 { return this->cend(); }
315 //! <b>Effects</b>: Returns a const_iterator pointing to the end of the tree.
316 //!
317 //! <b>Complexity</b>: Constant.
318 //!
319 //! <b>Throws</b>: Nothing.
320 const_iterator cend() const
321 { return const_iterator (uncast(const_node_ptr(&priv_header())), this); }
324 //! <b>Effects</b>: Returns an iterator pointing to the highest priority object of the tree.
325 //!
326 //! <b>Complexity</b>: Constant.
327 //!
328 //! <b>Throws</b>: Nothing.
329 iterator top()
330 { return this->empty() ? this->end() : iterator (node_traits::get_parent(node_ptr(&priv_header())), this); }
332 //! <b>Effects</b>: Returns a const_iterator pointing to the highest priority object of the tree..
333 //!
334 //! <b>Complexity</b>: Constant.
335 //!
336 //! <b>Throws</b>: Nothing.
337 const_iterator top() const
338 { return this->ctop(); }
340 //! <b>Effects</b>: Returns a const_iterator pointing to the highest priority object of the tree..
341 //!
342 //! <b>Complexity</b>: Constant.
343 //!
344 //! <b>Throws</b>: Nothing.
345 const_iterator ctop() const
346 { return this->empty() ? this->cend() : const_iterator (node_traits::get_parent(const_node_ptr(&priv_header())), this); }
348 //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning of the
349 //! reversed tree.
350 //!
351 //! <b>Complexity</b>: Constant.
352 //!
353 //! <b>Throws</b>: Nothing.
354 reverse_iterator rbegin()
355 { return reverse_iterator(this->end()); }
357 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
358 //! of the reversed tree.
359 //!
360 //! <b>Complexity</b>: Constant.
361 //!
362 //! <b>Throws</b>: Nothing.
363 const_reverse_iterator rbegin() const
364 { return const_reverse_iterator(this->end()); }
366 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
367 //! of the reversed tree.
368 //!
369 //! <b>Complexity</b>: Constant.
370 //!
371 //! <b>Throws</b>: Nothing.
372 const_reverse_iterator crbegin() const
373 { return const_reverse_iterator(this->end()); }
375 //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
376 //! of the reversed tree.
377 //!
378 //! <b>Complexity</b>: Constant.
379 //!
380 //! <b>Throws</b>: Nothing.
381 reverse_iterator rend()
382 { return reverse_iterator(this->begin()); }
384 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
385 //! of the reversed tree.
386 //!
387 //! <b>Complexity</b>: Constant.
388 //!
389 //! <b>Throws</b>: Nothing.
390 const_reverse_iterator rend() const
391 { return const_reverse_iterator(this->begin()); }
393 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
394 //! of the reversed tree.
395 //!
396 //! <b>Complexity</b>: Constant.
397 //!
398 //! <b>Throws</b>: Nothing.
399 const_reverse_iterator crend() const
400 { return const_reverse_iterator(this->begin()); }
402 //! <b>Effects</b>: Returns a reverse_iterator pointing to the highest priority object of the
403 //! reversed tree.
404 //!
405 //! <b>Complexity</b>: Constant.
406 //!
407 //! <b>Throws</b>: Nothing.
408 reverse_iterator rtop()
409 { return reverse_iterator(this->top()); }
411 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the highest priority objec
412 //! of the reversed tree.
413 //!
414 //! <b>Complexity</b>: Constant.
415 //!
416 //! <b>Throws</b>: Nothing.
417 const_reverse_iterator rtop() const
418 { return const_reverse_iterator(this->top()); }
420 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the highest priority object
421 //! of the reversed tree.
422 //!
423 //! <b>Complexity</b>: Constant.
424 //!
425 //! <b>Throws</b>: Nothing.
426 const_reverse_iterator crtop() const
427 { return const_reverse_iterator(this->top()); }
429 //! <b>Precondition</b>: end_iterator must be a valid end iterator
430 //! of treap.
431 //!
432 //! <b>Effects</b>: Returns a const reference to the treap associated to the end iterator
433 //!
434 //! <b>Throws</b>: Nothing.
435 //!
436 //! <b>Complexity</b>: Constant.
437 static treap_impl &container_from_end_iterator(iterator end_iterator)
438 { return priv_container_from_end_iterator(end_iterator); }
440 //! <b>Precondition</b>: end_iterator must be a valid end const_iterator
441 //! of treap.
442 //!
443 //! <b>Effects</b>: Returns a const reference to the treap associated to the iterator
444 //!
445 //! <b>Throws</b>: Nothing.
446 //!
447 //! <b>Complexity</b>: Constant.
448 static const treap_impl &container_from_end_iterator(const_iterator end_iterator)
449 { return priv_container_from_end_iterator(end_iterator); }
451 //! <b>Precondition</b>: it must be a valid iterator
452 //! of treap.
453 //!
454 //! <b>Effects</b>: Returns a const reference to the tree associated to the iterator
455 //!
456 //! <b>Throws</b>: Nothing.
457 //!
458 //! <b>Complexity</b>: Logarithmic.
459 static treap_impl &container_from_iterator(iterator it)
460 { return priv_container_from_iterator(it); }
462 //! <b>Precondition</b>: it must be a valid end const_iterator
463 //! of treap.
464 //!
465 //! <b>Effects</b>: Returns a const reference to the tree associated to the end iterator
466 //!
467 //! <b>Throws</b>: Nothing.
468 //!
469 //! <b>Complexity</b>: Logarithmic.
470 static const treap_impl &container_from_iterator(const_iterator it)
471 { return priv_container_from_iterator(it); }
473 //! <b>Effects</b>: Returns the value_compare object used by the tree.
474 //!
475 //! <b>Complexity</b>: Constant.
476 //!
477 //! <b>Throws</b>: If value_compare copy-constructor throws.
478 value_compare value_comp() const
479 { return this->priv_comp(); }
481 //! <b>Effects</b>: Returns the priority_compare object used by the tree.
482 //!
483 //! <b>Complexity</b>: Constant.
484 //!
485 //! <b>Throws</b>: If priority_compare copy-constructor throws.
486 priority_compare priority_comp() const
487 { return this->priv_pcomp(); }
489 //! <b>Effects</b>: Returns true if the container is empty.
490 //!
491 //! <b>Complexity</b>: Constant.
492 //!
493 //! <b>Throws</b>: Nothing.
494 bool empty() const
495 { return node_algorithms::unique(const_node_ptr(&priv_header())); }
497 //! <b>Effects</b>: Returns the number of elements stored in the tree.
498 //!
499 //! <b>Complexity</b>: Linear to elements contained in *this
500 //! if constant-time size option is disabled. Constant time otherwise.
501 //!
502 //! <b>Throws</b>: Nothing.
503 size_type size() const
505 if(constant_time_size)
506 return this->priv_size_traits().get_size();
507 else{
508 return (size_type)node_algorithms::size(const_node_ptr(&priv_header()));
512 //! <b>Effects</b>: Swaps the contents of two treaps.
513 //!
514 //! <b>Complexity</b>: Constant.
515 //!
516 //! <b>Throws</b>: If the comparison functor's swap call throws.
517 void swap(treap_impl& other)
519 //This can throw
520 using std::swap;
521 swap(priv_comp(), priv_comp());
522 swap(priv_pcomp(), priv_pcomp());
523 //These can't throw
524 node_algorithms::swap_tree(node_ptr(&priv_header()), node_ptr(&other.priv_header()));
525 if(constant_time_size){
526 size_type backup = this->priv_size_traits().get_size();
527 this->priv_size_traits().set_size(other.priv_size_traits().get_size());
528 other.priv_size_traits().set_size(backup);
532 //! <b>Requires</b>: value must be an lvalue
533 //!
534 //! <b>Effects</b>: Inserts value into the tree before the upper bound.
535 //!
536 //! <b>Complexity</b>: Average complexity for insert element is at
537 //! most logarithmic.
538 //!
539 //! <b>Throws</b>: If the internal value_compare or priority_compare funcstions throw. Strong guarantee.
540 //!
541 //! <b>Note</b>: Does not affect the validity of iterators and references.
542 //! No copy-constructors are called.
543 iterator insert_equal(reference value)
545 detail::key_nodeptr_comp<value_compare, treap_impl>
546 key_node_comp(priv_comp(), this);
547 detail::key_nodeptr_comp<priority_compare, treap_impl>
548 key_node_pcomp(priv_pcomp(), this);
549 node_ptr to_insert(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 this->priv_size_traits().increment();
553 return iterator(node_algorithms::insert_equal_upper_bound
554 (node_ptr(&priv_header()), to_insert, key_node_comp, key_node_pcomp), this);
557 //! <b>Requires</b>: value must be an lvalue, and "hint" must be
558 //! a valid iterator.
559 //!
560 //! <b>Effects</b>: Inserts x into the tree, using "hint" as a hint to
561 //! where it will be inserted. If "hint" is the upper_bound
562 //! the insertion takes constant time (two comparisons in the worst case)
563 //!
564 //! <b>Complexity</b>: Logarithmic in general, but it is amortized
565 //! constant time if t is inserted immediately before hint.
566 //!
567 //! <b>Throws</b>: If the internal value_compare or priority_compare funcstions throw. Strong guarantee.
568 //!
569 //! <b>Note</b>: Does not affect the validity of iterators and references.
570 //! No copy-constructors are called.
571 iterator insert_equal(const_iterator hint, reference value)
573 detail::key_nodeptr_comp<value_compare, treap_impl>
574 key_node_comp(priv_comp(), this);
575 detail::key_nodeptr_comp<priority_compare, treap_impl>
576 key_node_pcomp(priv_pcomp(), this);
577 node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
578 if(safemode_or_autounlink)
579 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
580 this->priv_size_traits().increment();
581 return iterator(node_algorithms::insert_equal
582 (node_ptr(&priv_header()), hint.pointed_node(), to_insert, key_node_comp, key_node_pcomp), this);
585 //! <b>Requires</b>: Dereferencing iterator must yield an lvalue
586 //! of type value_type.
587 //!
588 //! <b>Effects</b>: Inserts a each element of a range into the tree
589 //! before the upper bound of the key of each element.
590 //!
591 //! <b>Complexity</b>: Insert range is in general O(N * log(N)), where N is the
592 //! size of the range. However, it is linear in N if the range is already sorted
593 //! by value_comp().
594 //!
595 //! <b>Throws</b>: If the internal value_compare or priority_compare funcstions throw.
596 //! Strong guarantee.
597 //!
598 //! <b>Note</b>: Does not affect the validity of iterators and references.
599 //! No copy-constructors are called.
600 template<class Iterator>
601 void insert_equal(Iterator b, Iterator e)
603 iterator end(this->end());
604 for (; b != e; ++b)
605 this->insert_equal(end, *b);
608 //! <b>Requires</b>: value must be an lvalue
609 //!
610 //! <b>Effects</b>: Inserts value into the tree if the value
611 //! is not already present.
612 //!
613 //! <b>Complexity</b>: Average complexity for insert element is at
614 //! most logarithmic.
615 //!
616 //! <b>Throws</b>: If the internal value_compare or priority_compare funcstions throw.
617 //! Strong guarantee.
618 //!
619 //! <b>Note</b>: Does not affect the validity of iterators and references.
620 //! No copy-constructors are called.
621 std::pair<iterator, bool> insert_unique(reference value)
623 insert_commit_data commit_data;
624 std::pair<iterator, bool> ret = insert_unique_check(value, priv_comp(), priv_pcomp(), commit_data);
625 if(!ret.second)
626 return ret;
627 return std::pair<iterator, bool> (insert_unique_commit(value, commit_data), true);
630 //! <b>Requires</b>: value must be an lvalue, and "hint" must be
631 //! a valid iterator
632 //!
633 //! <b>Effects</b>: Tries to insert x into the tree, using "hint" as a hint
634 //! to where it will be inserted.
635 //!
636 //! <b>Complexity</b>: Logarithmic in general, but it is amortized
637 //! constant time (two comparisons in the worst case)
638 //! if t is inserted immediately before hint.
639 //!
640 //! <b>Throws</b>: If the internal value_compare or priority_compare funcstions throw.
641 //! Strong guarantee.
642 //!
643 //! <b>Note</b>: Does not affect the validity of iterators and references.
644 //! No copy-constructors are called.
645 iterator insert_unique(const_iterator hint, reference value)
647 insert_commit_data commit_data;
648 std::pair<iterator, bool> ret = insert_unique_check(hint, value, priv_comp(), priv_pcomp(), commit_data);
649 if(!ret.second)
650 return ret.first;
651 return insert_unique_commit(value, commit_data);
654 //! <b>Requires</b>: Dereferencing iterator must yield an lvalue
655 //! of type value_type.
656 //!
657 //! <b>Effects</b>: Tries to insert each element of a range into the tree.
658 //!
659 //! <b>Complexity</b>: Insert range is in general O(N * log(N)), where N is the
660 //! size of the range. However, it is linear in N if the range is already sorted
661 //! by value_comp().
662 //!
663 //! <b>Throws</b>: If the internal value_compare or priority_compare funcstions throw.
664 //! Strong guarantee.
665 //!
666 //! <b>Note</b>: Does not affect the validity of iterators and references.
667 //! No copy-constructors are called.
668 template<class Iterator>
669 void insert_unique(Iterator b, Iterator e)
671 if(this->empty()){
672 iterator end(this->end());
673 for (; b != e; ++b)
674 this->insert_unique(end, *b);
676 else{
677 for (; b != e; ++b)
678 this->insert_unique(*b);
682 //! <b>Requires</b>: key_value_comp must be a comparison function that induces
683 //! the same strict weak ordering as value_compare. The difference is that
684 //! key_value_comp compares an arbitrary key with the contained values.
685 //!
686 //! <b>Effects</b>: Checks if a value can be inserted in the container, using
687 //! a user provided key instead of the value itself.
689 //! <b>Returns</b>: If there is an equivalent value
690 //! returns a pair containing an iterator to the already present value
691 //! and false. If the value can be inserted returns true in the returned
692 //! pair boolean and fills "commit_data" that is meant to be used with
693 //! the "insert_commit" function.
694 //!
695 //! <b>Complexity</b>: Average complexity is at most logarithmic.
697 //! <b>Throws</b>: If the key_value_comp ordering function throws. Strong guarantee.
698 //!
699 //! <b>Notes</b>: This function is used to improve performance when constructing
700 //! a value_type is expensive: if there is an equivalent value
701 //! the constructed object must be discarded. Many times, the part of the
702 //! node that is used to impose the order is much cheaper to construct
703 //! than the value_type and this function offers the possibility to use that
704 //! part to check if the insertion will be successful.
706 //! If the check is successful, the user can construct the value_type and use
707 //! "insert_commit" to insert the object in constant-time. This gives a total
708 //! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)).
710 //! "commit_data" remains valid for a subsequent "insert_commit" only if no more
711 //! objects are inserted or erased from the container.
712 template<class KeyType, class KeyValueCompare, class KeyValuePrioCompare>
713 std::pair<iterator, bool> insert_unique_check
714 ( const KeyType &key, KeyValueCompare key_value_comp
715 , KeyValuePrioCompare key_value_pcomp, insert_commit_data &commit_data)
717 detail::key_nodeptr_comp<KeyValueCompare, treap_impl>
718 comp(key_value_comp, this);
719 detail::key_nodeptr_comp<KeyValuePrioCompare, treap_impl>
720 pcomp(key_value_pcomp, this);
721 std::pair<node_ptr, bool> ret =
722 (node_algorithms::insert_unique_check
723 (node_ptr(&priv_header()), key, comp, pcomp, commit_data));
724 return std::pair<iterator, bool>(iterator(ret.first, this), ret.second);
727 //! <b>Requires</b>: key_value_comp must be a comparison function that induces
728 //! the same strict weak ordering as value_compare. The difference is that
729 //! key_value_comp compares an arbitrary key with the contained values.
730 //!
731 //! <b>Effects</b>: Checks if a value can be inserted in the container, using
732 //! a user provided key instead of the value itself, using "hint"
733 //! as a hint to where it will be inserted.
735 //! <b>Returns</b>: If there is an equivalent value
736 //! returns a pair containing an iterator to the already present value
737 //! and false. If the value can be inserted returns true in the returned
738 //! pair boolean and fills "commit_data" that is meant to be used with
739 //! the "insert_commit" function.
740 //!
741 //! <b>Complexity</b>: Logarithmic in general, but it's amortized
742 //! constant time if t is inserted immediately before hint.
744 //! <b>Throws</b>: If the key_value_comp ordering function throws. Strong guarantee.
745 //!
746 //! <b>Notes</b>: This function is used to improve performance when constructing
747 //! a value_type is expensive: if there is an equivalent value
748 //! the constructed object must be discarded. Many times, the part of the
749 //! constructing that is used to impose the order is much cheaper to construct
750 //! than the value_type and this function offers the possibility to use that key
751 //! to check if the insertion will be successful.
753 //! If the check is successful, the user can construct the value_type and use
754 //! "insert_commit" to insert the object in constant-time. This can give a total
755 //! constant-time complexity to the insertion: check(O(1)) + commit(O(1)).
756 //!
757 //! "commit_data" remains valid for a subsequent "insert_commit" only if no more
758 //! objects are inserted or erased from the container.
759 template<class KeyType, class KeyValueCompare, class KeyValuePrioCompare>
760 std::pair<iterator, bool> insert_unique_check
761 ( const_iterator hint, const KeyType &key
762 , KeyValueCompare key_value_comp
763 , KeyValuePrioCompare key_value_pcomp
764 , insert_commit_data &commit_data)
766 detail::key_nodeptr_comp<KeyValueCompare, treap_impl>
767 comp(key_value_comp, this);
768 detail::key_nodeptr_comp<KeyValuePrioCompare, treap_impl>
769 pcomp(key_value_pcomp, this);
770 std::pair<node_ptr, bool> ret =
771 (node_algorithms::insert_unique_check
772 (node_ptr(&priv_header()), hint.pointed_node(), key, comp, pcomp, commit_data));
773 return std::pair<iterator, bool>(iterator(ret.first, this), ret.second);
776 //! <b>Requires</b>: value must be an lvalue of type value_type. commit_data
777 //! must have been obtained from a previous call to "insert_check".
778 //! No objects should have been inserted or erased from the container between
779 //! the "insert_check" that filled "commit_data" and the call to "insert_commit".
780 //!
781 //! <b>Effects</b>: Inserts the value in the avl_set using the information obtained
782 //! from the "commit_data" that a previous "insert_check" filled.
784 //! <b>Returns</b>: An iterator to the newly inserted object.
785 //!
786 //! <b>Complexity</b>: Constant time.
788 //! <b>Throws</b>: Nothing
789 //!
790 //! <b>Notes</b>: This function has only sense if a "insert_check" has been
791 //! previously executed to fill "commit_data". No value should be inserted or
792 //! erased between the "insert_check" and "insert_commit" calls.
793 iterator insert_unique_commit(reference value, const insert_commit_data &commit_data)
795 node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
796 if(safemode_or_autounlink)
797 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
798 this->priv_size_traits().increment();
799 node_algorithms::insert_unique_commit(node_ptr(&priv_header()), to_insert, commit_data);
800 return iterator(to_insert, this);
803 //! <b>Effects</b>: Erases the element pointed to by pos.
804 //!
805 //! <b>Complexity</b>: Average complexity for erase element is constant time.
806 //!
807 //! <b>Throws</b>: if the internal priority_compare function throws. Strong guarantee.
808 //!
809 //! <b>Note</b>: Invalidates the iterators (but not the references)
810 //! to the erased elements. No destructors are called.
811 iterator erase(const_iterator i)
813 const_iterator ret(i);
814 ++ret;
815 node_ptr to_erase(i.pointed_node());
816 if(safemode_or_autounlink)
817 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!node_algorithms::unique(to_erase));
818 detail::key_nodeptr_comp<priority_compare, treap_impl>
819 key_node_pcomp(priv_pcomp(), this);
820 node_algorithms::erase(&priv_header(), to_erase,key_node_pcomp);
821 this->priv_size_traits().decrement();
822 if(safemode_or_autounlink)
823 node_algorithms::init(to_erase);
824 return ret.unconst();
827 //! <b>Effects</b>: Erases the range pointed to by b end e.
828 //!
829 //! <b>Complexity</b>: Average complexity for erase range is at most
830 //! O(log(size() + N)), where N is the number of elements in the range.
831 //!
832 //! <b>Throws</b>: if the internal priority_compare function throws. Strong guarantee.
833 //!
834 //! <b>Note</b>: Invalidates the iterators (but not the references)
835 //! to the erased elements. No destructors are called.
836 iterator erase(const_iterator b, const_iterator e)
837 { size_type n; return private_erase(b, e, n); }
839 //! <b>Effects</b>: Erases all the elements with the given value.
840 //!
841 //! <b>Returns</b>: The number of erased elements.
842 //!
843 //! <b>Complexity</b>: O(log(size() + N).
844 //!
845 //! <b>Throws</b>: if the internal priority_compare function throws. Strong guarantee.
846 //!
847 //! <b>Note</b>: Invalidates the iterators (but not the references)
848 //! to the erased elements. No destructors are called.
849 size_type erase(const_reference value)
850 { return this->erase(value, priv_comp()); }
852 //! <b>Effects</b>: Erases all the elements with the given key.
853 //! according to the comparison functor "comp".
855 //! <b>Returns</b>: The number of erased elements.
856 //!
857 //! <b>Complexity</b>: O(log(size() + N).
858 //!
859 //! <b>Throws</b>: if the internal priority_compare function throws. Strong guarantee.
860 //!
861 //! <b>Note</b>: Invalidates the iterators (but not the references)
862 //! to the erased elements. No destructors are called.
863 template<class KeyType, class KeyValueCompare>
864 size_type erase(const KeyType& key, KeyValueCompare comp
865 /// @cond
866 , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
867 /// @endcond
870 std::pair<iterator,iterator> p = this->equal_range(key, comp);
871 size_type n;
872 private_erase(p.first, p.second, n);
873 return n;
876 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
878 //! <b>Effects</b>: Erases the element pointed to by pos.
879 //! Disposer::operator()(pointer) is called for the removed element.
880 //!
881 //! <b>Complexity</b>: Average complexity for erase element is constant time.
882 //!
883 //! <b>Throws</b>: if the internal priority_compare function throws. Strong guarantee.
884 //!
885 //! <b>Note</b>: Invalidates the iterators
886 //! to the erased elements.
887 template<class Disposer>
888 iterator erase_and_dispose(const_iterator i, Disposer disposer)
890 node_ptr to_erase(i.pointed_node());
891 iterator ret(this->erase(i));
892 disposer(get_real_value_traits().to_value_ptr(to_erase));
893 return ret;
896 #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
897 template<class Disposer>
898 iterator erase_and_dispose(iterator i, Disposer disposer)
899 { return this->erase_and_dispose(const_iterator(i), disposer); }
900 #endif
902 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
904 //! <b>Effects</b>: Erases the range pointed to by b end e.
905 //! Disposer::operator()(pointer) is called for the removed elements.
906 //!
907 //! <b>Complexity</b>: Average complexity for erase range is at most
908 //! O(log(size() + N)), where N is the number of elements in the range.
909 //!
910 //! <b>Throws</b>: if the internal priority_compare function throws. Strong guarantee.
911 //!
912 //! <b>Note</b>: Invalidates the iterators
913 //! to the erased elements.
914 template<class Disposer>
915 iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer)
916 { size_type n; return private_erase(b, e, n, disposer); }
918 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
920 //! <b>Effects</b>: Erases all the elements with the given value.
921 //! Disposer::operator()(pointer) is called for the removed elements.
922 //!
923 //! <b>Returns</b>: The number of erased elements.
924 //!
925 //! <b>Complexity</b>: O(log(size() + N).
926 //!
927 //! <b>Throws</b>: if the priority_compare function throws then weak guarantee and heap invariants are broken.
928 //! The safest thing would be to clear or destroy the container.
929 //!
930 //! <b>Note</b>: Invalidates the iterators (but not the references)
931 //! to the erased elements. No destructors are called.
932 template<class Disposer>
933 size_type erase_and_dispose(const_reference value, Disposer disposer)
935 std::pair<iterator,iterator> p = this->equal_range(value);
936 size_type n;
937 private_erase(p.first, p.second, n, disposer);
938 return n;
941 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
943 //! <b>Effects</b>: Erases all the elements with the given key.
944 //! according to the comparison functor "comp".
945 //! Disposer::operator()(pointer) is called for the removed elements.
947 //! <b>Returns</b>: The number of erased elements.
948 //!
949 //! <b>Complexity</b>: O(log(size() + N).
950 //!
951 //! <b>Throws</b>: if the priority_compare function throws then weak guarantee and heap invariants are broken.
952 //! The safest thing would be to clear or destroy the container.
953 //!
954 //! <b>Note</b>: Invalidates the iterators
955 //! to the erased elements.
956 template<class KeyType, class KeyValueCompare, class Disposer>
957 size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer
958 /// @cond
959 , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
960 /// @endcond
963 std::pair<iterator,iterator> p = this->equal_range(key, comp);
964 size_type n;
965 private_erase(p.first, p.second, n, disposer);
966 return n;
969 //! <b>Effects</b>: Erases all of the elements.
970 //!
971 //! <b>Complexity</b>: Linear to the number of elements on the container.
972 //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise.
973 //!
974 //! <b>Throws</b>: Nothing.
975 //!
976 //! <b>Note</b>: Invalidates the iterators (but not the references)
977 //! to the erased elements. No destructors are called.
978 void clear()
980 if(safemode_or_autounlink){
981 this->clear_and_dispose(detail::null_disposer());
983 else{
984 node_algorithms::init_header(&priv_header());
985 this->priv_size_traits().set_size(0);
989 //! <b>Effects</b>: Erases all of the elements calling disposer(p) for
990 //! each node to be erased.
991 //! <b>Complexity</b>: Average complexity for is at most O(log(size() + N)),
992 //! where N is the number of elements in the container.
993 //!
994 //! <b>Throws</b>: Nothing.
995 //!
996 //! <b>Note</b>: Invalidates the iterators (but not the references)
997 //! to the erased elements. Calls N times to disposer functor.
998 template<class Disposer>
999 void clear_and_dispose(Disposer disposer)
1001 node_algorithms::clear_and_dispose(node_ptr(&priv_header())
1002 , detail::node_disposer<Disposer, treap_impl>(disposer, this));
1003 node_algorithms::init_header(&priv_header());
1004 this->priv_size_traits().set_size(0);
1007 //! <b>Effects</b>: Returns the number of contained elements with the given value
1008 //!
1009 //! <b>Complexity</b>: Logarithmic to the number of elements contained plus lineal
1010 //! to number of objects with the given value.
1011 //!
1012 //! <b>Throws</b>: Nothing.
1013 size_type count(const_reference value) const
1014 { return this->count(value, priv_comp()); }
1016 //! <b>Effects</b>: Returns the number of contained elements with the given key
1017 //!
1018 //! <b>Complexity</b>: Logarithmic to the number of elements contained plus lineal
1019 //! to number of objects with the given key.
1020 //!
1021 //! <b>Throws</b>: Nothing.
1022 template<class KeyType, class KeyValueCompare>
1023 size_type count(const KeyType &key, KeyValueCompare comp) const
1025 std::pair<const_iterator, const_iterator> ret = this->equal_range(key, comp);
1026 return std::distance(ret.first, ret.second);
1029 //! <b>Effects</b>: Returns an iterator to the first element whose
1030 //! key is not less than k or end() if that element does not exist.
1031 //!
1032 //! <b>Complexity</b>: Logarithmic.
1033 //!
1034 //! <b>Throws</b>: Nothing.
1035 iterator lower_bound(const_reference value)
1036 { return this->lower_bound(value, priv_comp()); }
1038 //! <b>Effects</b>: Returns an iterator to the first element whose
1039 //! key is not less than k or end() if that element does not exist.
1040 //!
1041 //! <b>Complexity</b>: Logarithmic.
1042 //!
1043 //! <b>Throws</b>: Nothing.
1044 const_iterator lower_bound(const_reference value) const
1045 { return this->lower_bound(value, priv_comp()); }
1047 //! <b>Effects</b>: Returns an iterator to the first element whose
1048 //! key is not less than k or end() if that element does not exist.
1049 //!
1050 //! <b>Complexity</b>: Logarithmic.
1051 //!
1052 //! <b>Throws</b>: Nothing.
1053 template<class KeyType, class KeyValueCompare>
1054 iterator lower_bound(const KeyType &key, KeyValueCompare comp)
1056 detail::key_nodeptr_comp<KeyValueCompare, treap_impl>
1057 key_node_comp(comp, this);
1058 return iterator(node_algorithms::lower_bound
1059 (const_node_ptr(&priv_header()), key, key_node_comp), this);
1062 //! <b>Effects</b>: Returns a const iterator to the first element whose
1063 //! key is not less than k or end() if that element does not exist.
1064 //!
1065 //! <b>Complexity</b>: Logarithmic.
1066 //!
1067 //! <b>Throws</b>: Nothing.
1068 template<class KeyType, class KeyValueCompare>
1069 const_iterator lower_bound(const KeyType &key, KeyValueCompare comp) const
1071 detail::key_nodeptr_comp<KeyValueCompare, treap_impl>
1072 key_node_comp(comp, this);
1073 return const_iterator(node_algorithms::lower_bound
1074 (const_node_ptr(&priv_header()), key, key_node_comp), this);
1077 //! <b>Effects</b>: Returns an iterator to the first element whose
1078 //! key is greater than k or end() if that element does not exist.
1079 //!
1080 //! <b>Complexity</b>: Logarithmic.
1081 //!
1082 //! <b>Throws</b>: Nothing.
1083 iterator upper_bound(const_reference value)
1084 { return this->upper_bound(value, priv_comp()); }
1086 //! <b>Effects</b>: Returns an iterator to the first element whose
1087 //! key is greater than k according to comp or end() if that element
1088 //! does not exist.
1090 //! <b>Complexity</b>: Logarithmic.
1091 //!
1092 //! <b>Throws</b>: Nothing.
1093 template<class KeyType, class KeyValueCompare>
1094 iterator upper_bound(const KeyType &key, KeyValueCompare comp)
1096 detail::key_nodeptr_comp<KeyValueCompare, treap_impl>
1097 key_node_comp(comp, this);
1098 return iterator(node_algorithms::upper_bound
1099 (const_node_ptr(&priv_header()), key, key_node_comp), this);
1102 //! <b>Effects</b>: Returns an iterator to the first element whose
1103 //! key is greater than k or end() if that element does not exist.
1104 //!
1105 //! <b>Complexity</b>: Logarithmic.
1106 //!
1107 //! <b>Throws</b>: Nothing.
1108 const_iterator upper_bound(const_reference value) const
1109 { return this->upper_bound(value, priv_comp()); }
1111 //! <b>Effects</b>: Returns an iterator to the first element whose
1112 //! key is greater than k according to comp or end() if that element
1113 //! does not exist.
1115 //! <b>Complexity</b>: Logarithmic.
1116 //!
1117 //! <b>Throws</b>: Nothing.
1118 template<class KeyType, class KeyValueCompare>
1119 const_iterator upper_bound(const KeyType &key, KeyValueCompare comp) const
1121 detail::key_nodeptr_comp<KeyValueCompare, treap_impl>
1122 key_node_comp(comp, this);
1123 return const_iterator(node_algorithms::upper_bound
1124 (const_node_ptr(&priv_header()), key, key_node_comp), this);
1127 //! <b>Effects</b>: Finds an iterator to the first element whose key is
1128 //! k or end() if that element does not exist.
1130 //! <b>Complexity</b>: Logarithmic.
1131 //!
1132 //! <b>Throws</b>: Nothing.
1133 iterator find(const_reference value)
1134 { return this->find(value, priv_comp()); }
1136 //! <b>Effects</b>: Finds an iterator to the first element whose key is
1137 //! k or end() if that element does not exist.
1139 //! <b>Complexity</b>: Logarithmic.
1140 //!
1141 //! <b>Throws</b>: Nothing.
1142 template<class KeyType, class KeyValueCompare>
1143 iterator find(const KeyType &key, KeyValueCompare comp)
1145 detail::key_nodeptr_comp<KeyValueCompare, treap_impl>
1146 key_node_comp(comp, this);
1147 return iterator
1148 (node_algorithms::find(const_node_ptr(&priv_header()), key, key_node_comp), this);
1151 //! <b>Effects</b>: Finds a const_iterator to the first element whose key is
1152 //! k or end() if that element does not exist.
1153 //!
1154 //! <b>Complexity</b>: Logarithmic.
1155 //!
1156 //! <b>Throws</b>: Nothing.
1157 const_iterator find(const_reference value) const
1158 { return this->find(value, priv_comp()); }
1160 //! <b>Effects</b>: Finds a const_iterator to the first element whose key is
1161 //! k or end() if that element does not exist.
1162 //!
1163 //! <b>Complexity</b>: Logarithmic.
1164 //!
1165 //! <b>Throws</b>: Nothing.
1166 template<class KeyType, class KeyValueCompare>
1167 const_iterator find(const KeyType &key, KeyValueCompare comp) const
1169 detail::key_nodeptr_comp<KeyValueCompare, treap_impl>
1170 key_node_comp(comp, this);
1171 return const_iterator
1172 (node_algorithms::find(const_node_ptr(&priv_header()), key, key_node_comp), this);
1175 //! <b>Effects</b>: Finds a range containing all elements whose key is k or
1176 //! an empty range that indicates the position where those elements would be
1177 //! if they there is no elements with key k.
1178 //!
1179 //! <b>Complexity</b>: Logarithmic.
1180 //!
1181 //! <b>Throws</b>: Nothing.
1182 std::pair<iterator,iterator> equal_range(const_reference value)
1183 { return this->equal_range(value, priv_comp()); }
1185 //! <b>Effects</b>: Finds a range containing all elements whose key is k or
1186 //! an empty range that indicates the position where those elements would be
1187 //! if they there is no elements with key k.
1188 //!
1189 //! <b>Complexity</b>: Logarithmic.
1190 //!
1191 //! <b>Throws</b>: Nothing.
1192 template<class KeyType, class KeyValueCompare>
1193 std::pair<iterator,iterator> equal_range(const KeyType &key, KeyValueCompare comp)
1195 detail::key_nodeptr_comp<KeyValueCompare, treap_impl>
1196 key_node_comp(comp, this);
1197 std::pair<node_ptr, node_ptr> ret
1198 (node_algorithms::equal_range(const_node_ptr(&priv_header()), key, key_node_comp));
1199 return std::pair<iterator, iterator>(iterator(ret.first, this), iterator(ret.second, this));
1202 //! <b>Effects</b>: Finds a range containing all elements whose key is k or
1203 //! an empty range that indicates the position where those elements would be
1204 //! if they there is no elements with key k.
1205 //!
1206 //! <b>Complexity</b>: Logarithmic.
1207 //!
1208 //! <b>Throws</b>: Nothing.
1209 std::pair<const_iterator, const_iterator>
1210 equal_range(const_reference value) const
1211 { return this->equal_range(value, priv_comp()); }
1213 //! <b>Effects</b>: Finds a range containing all elements whose key is k or
1214 //! an empty range that indicates the position where those elements would be
1215 //! if they there is no elements with key k.
1216 //!
1217 //! <b>Complexity</b>: Logarithmic.
1218 //!
1219 //! <b>Throws</b>: Nothing.
1220 template<class KeyType, class KeyValueCompare>
1221 std::pair<const_iterator, const_iterator>
1222 equal_range(const KeyType &key, KeyValueCompare comp) const
1224 detail::key_nodeptr_comp<KeyValueCompare, treap_impl>
1225 key_node_comp(comp, this);
1226 std::pair<node_ptr, node_ptr> ret
1227 (node_algorithms::equal_range(const_node_ptr(&priv_header()), key, key_node_comp));
1228 return std::pair<const_iterator, const_iterator>(const_iterator(ret.first, this), const_iterator(ret.second, this));
1231 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
1232 //! Cloner should yield to nodes equivalent to the original nodes.
1234 //! <b>Effects</b>: Erases all the elements from *this
1235 //! calling Disposer::operator()(pointer), clones all the
1236 //! elements from src calling Cloner::operator()(const_reference )
1237 //! and inserts them on *this. Copies the predicate from the source container.
1239 //! If cloner throws, all cloned elements are unlinked and disposed
1240 //! calling Disposer::operator()(pointer).
1241 //!
1242 //! <b>Complexity</b>: Linear to erased plus inserted elements.
1243 //!
1244 //! <b>Throws</b>: If cloner throws or predicate copy assignment throws. Basic guarantee.
1245 template <class Cloner, class Disposer>
1246 void clone_from(const treap_impl &src, Cloner cloner, Disposer disposer)
1248 this->clear_and_dispose(disposer);
1249 if(!src.empty()){
1250 detail::exception_disposer<treap_impl, Disposer>
1251 rollback(*this, disposer);
1252 node_algorithms::clone
1253 (const_node_ptr(&src.priv_header())
1254 ,node_ptr(&this->priv_header())
1255 ,detail::node_cloner<Cloner, treap_impl>(cloner, this)
1256 ,detail::node_disposer<Disposer, treap_impl>(disposer, this));
1257 this->priv_size_traits().set_size(src.priv_size_traits().get_size());
1258 this->priv_comp() = src.priv_comp();
1259 rollback.release();
1263 //! <b>Effects</b>: Unlinks the leftmost node from the tree.
1264 //!
1265 //! <b>Complexity</b>: Average complexity is constant time.
1266 //!
1267 //! <b>Throws</b>: Nothing.
1268 //!
1269 //! <b>Notes</b>: This function breaks the tree and the tree can
1270 //! only be used for more unlink_leftmost_without_rebalance calls.
1271 //! This function is normally used to achieve a step by step
1272 //! controlled destruction of the tree.
1273 pointer unlink_leftmost_without_rebalance()
1275 node_ptr to_be_disposed(node_algorithms::unlink_leftmost_without_rebalance
1276 (node_ptr(&priv_header())));
1277 if(!to_be_disposed)
1278 return 0;
1279 this->priv_size_traits().decrement();
1280 if(safemode_or_autounlink)//If this is commented does not work with normal_link
1281 node_algorithms::init(to_be_disposed);
1282 return get_real_value_traits().to_value_ptr(to_be_disposed);
1285 //! <b>Requires</b>: replace_this must be a valid iterator of *this
1286 //! and with_this must not be inserted in any tree.
1287 //!
1288 //! <b>Effects</b>: Replaces replace_this in its position in the
1289 //! tree with with_this. The tree does not need to be rebalanced.
1290 //!
1291 //! <b>Complexity</b>: Constant.
1292 //!
1293 //! <b>Throws</b>: Nothing.
1294 //!
1295 //! <b>Note</b>: This function will break container ordering invariants if
1296 //! with_this is not equivalent to *replace_this according to the
1297 //! ordering and priority rules. This function is faster than erasing and inserting
1298 //! the node, since no rebalancing or comparison is needed.
1299 void replace_node(iterator replace_this, reference with_this)
1301 node_algorithms::replace_node( get_real_value_traits().to_node_ptr(*replace_this)
1302 , node_ptr(&priv_header())
1303 , get_real_value_traits().to_node_ptr(with_this));
1306 //! <b>Requires</b>: value must be an lvalue and shall be in a set of
1307 //! appropriate type. Otherwise the behavior is undefined.
1308 //!
1309 //! <b>Effects</b>: Returns: a valid iterator i belonging to the set
1310 //! that points to the value
1311 //!
1312 //! <b>Complexity</b>: Constant.
1313 //!
1314 //! <b>Throws</b>: Nothing.
1315 //!
1316 //! <b>Note</b>: This static function is available only if the <i>value traits</i>
1317 //! is stateless.
1318 static iterator s_iterator_to(reference value)
1320 BOOST_STATIC_ASSERT((!stateful_value_traits));
1321 return iterator (value_traits::to_node_ptr(value), 0);
1324 //! <b>Requires</b>: value must be an lvalue and shall be in a set of
1325 //! appropriate type. Otherwise the behavior is undefined.
1326 //!
1327 //! <b>Effects</b>: Returns: a valid const_iterator i belonging to the
1328 //! set that points to the value
1329 //!
1330 //! <b>Complexity</b>: Constant.
1331 //!
1332 //! <b>Throws</b>: Nothing.
1333 //!
1334 //! <b>Note</b>: This static function is available only if the <i>value traits</i>
1335 //! is stateless.
1336 static const_iterator s_iterator_to(const_reference value)
1338 BOOST_STATIC_ASSERT((!stateful_value_traits));
1339 return const_iterator (value_traits::to_node_ptr(const_cast<reference> (value)), 0);
1342 //! <b>Requires</b>: value must be an lvalue and shall be in a set of
1343 //! appropriate type. Otherwise the behavior is undefined.
1344 //!
1345 //! <b>Effects</b>: Returns: a valid iterator i belonging to the set
1346 //! that points to the value
1347 //!
1348 //! <b>Complexity</b>: Constant.
1349 //!
1350 //! <b>Throws</b>: Nothing.
1351 iterator iterator_to(reference value)
1352 { return iterator (value_traits::to_node_ptr(value), this); }
1354 //! <b>Requires</b>: value must be an lvalue and shall be in a set of
1355 //! appropriate type. Otherwise the behavior is undefined.
1356 //!
1357 //! <b>Effects</b>: Returns: a valid const_iterator i belonging to the
1358 //! set that points to the value
1359 //!
1360 //! <b>Complexity</b>: Constant.
1361 //!
1362 //! <b>Throws</b>: Nothing.
1363 const_iterator iterator_to(const_reference value) const
1364 { return const_iterator (value_traits::to_node_ptr(const_cast<reference> (value)), this); }
1366 //! <b>Requires</b>: value shall not be in a tree.
1367 //!
1368 //! <b>Effects</b>: init_node puts the hook of a value in a well-known default
1369 //! state.
1370 //!
1371 //! <b>Throws</b>: Nothing.
1372 //!
1373 //! <b>Complexity</b>: Constant time.
1374 //!
1375 //! <b>Note</b>: This function puts the hook in the well-known default state
1376 //! used by auto_unlink and safe hooks.
1377 static void init_node(reference value)
1378 { node_algorithms::init(value_traits::to_node_ptr(value)); }
1380 /// @cond
1381 private:
1382 template<class Disposer>
1383 iterator private_erase(const_iterator b, const_iterator e, size_type &n, Disposer disposer)
1385 for(n = 0; b != e; ++n)
1386 this->erase_and_dispose(b++, disposer);
1387 return b.unconst();
1390 iterator private_erase(const_iterator b, const_iterator e, size_type &n)
1392 for(n = 0; b != e; ++n)
1393 this->erase(b++);
1394 return b.unconst();
1396 /// @endcond
1398 private:
1399 static treap_impl &priv_container_from_end_iterator(const const_iterator &end_iterator)
1401 header_plus_size *r = detail::parent_from_member<header_plus_size, node>
1402 ( detail::get_pointer(end_iterator.pointed_node()), &header_plus_size::header_);
1403 typename node_plus_pred_t::header_plus_priority_size *n =
1404 detail::parent_from_member
1405 < typename node_plus_pred_t::header_plus_priority_size
1406 , header_plus_size>
1407 (r, &node_plus_pred_t::header_plus_priority_size::header_plus_size_);
1408 node_plus_pred_t *pn = detail::parent_from_member
1409 < node_plus_pred_t
1410 , typename node_plus_pred_t::header_plus_priority_size>
1411 (n, &node_plus_pred_t::header_plus_priority_size_);
1412 data_t *d = detail::parent_from_member<data_t, node_plus_pred_t>(pn, &data_t::node_plus_pred_);
1413 treap_impl *tr = detail::parent_from_member<treap_impl, data_t>(d, &treap_impl::data_);
1414 return *tr;
1417 static treap_impl &priv_container_from_iterator(const const_iterator &it)
1418 { return priv_container_from_end_iterator(it.end_iterator_from_it()); }
1421 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1422 template<class T, class ...Options>
1423 #else
1424 template<class Config>
1425 #endif
1426 inline bool operator<
1427 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1428 (const treap_impl<T, Options...> &x, const treap_impl<T, Options...> &y)
1429 #else
1430 (const treap_impl<Config> &x, const treap_impl<Config> &y)
1431 #endif
1432 { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
1434 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1435 template<class T, class ...Options>
1436 #else
1437 template<class Config>
1438 #endif
1439 bool operator==
1440 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1441 (const treap_impl<T, Options...> &x, const treap_impl<T, Options...> &y)
1442 #else
1443 (const treap_impl<Config> &x, const treap_impl<Config> &y)
1444 #endif
1446 typedef treap_impl<Config> tree_type;
1447 typedef typename tree_type::const_iterator const_iterator;
1449 if(tree_type::constant_time_size && x.size() != y.size()){
1450 return false;
1452 const_iterator end1 = x.end();
1453 const_iterator i1 = x.begin();
1454 const_iterator i2 = y.begin();
1455 if(tree_type::constant_time_size){
1456 while (i1 != end1 && *i1 == *i2) {
1457 ++i1;
1458 ++i2;
1460 return i1 == end1;
1462 else{
1463 const_iterator end2 = y.end();
1464 while (i1 != end1 && i2 != end2 && *i1 == *i2) {
1465 ++i1;
1466 ++i2;
1468 return i1 == end1 && i2 == end2;
1472 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1473 template<class T, class ...Options>
1474 #else
1475 template<class Config>
1476 #endif
1477 inline bool operator!=
1478 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1479 (const treap_impl<T, Options...> &x, const treap_impl<T, Options...> &y)
1480 #else
1481 (const treap_impl<Config> &x, const treap_impl<Config> &y)
1482 #endif
1483 { return !(x == y); }
1485 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1486 template<class T, class ...Options>
1487 #else
1488 template<class Config>
1489 #endif
1490 inline bool operator>
1491 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1492 (const treap_impl<T, Options...> &x, const treap_impl<T, Options...> &y)
1493 #else
1494 (const treap_impl<Config> &x, const treap_impl<Config> &y)
1495 #endif
1496 { return y < x; }
1498 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1499 template<class T, class ...Options>
1500 #else
1501 template<class Config>
1502 #endif
1503 inline bool operator<=
1504 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1505 (const treap_impl<T, Options...> &x, const treap_impl<T, Options...> &y)
1506 #else
1507 (const treap_impl<Config> &x, const treap_impl<Config> &y)
1508 #endif
1509 { return !(y < x); }
1511 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1512 template<class T, class ...Options>
1513 #else
1514 template<class Config>
1515 #endif
1516 inline bool operator>=
1517 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1518 (const treap_impl<T, Options...> &x, const treap_impl<T, Options...> &y)
1519 #else
1520 (const treap_impl<Config> &x, const treap_impl<Config> &y)
1521 #endif
1522 { return !(x < y); }
1524 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1525 template<class T, class ...Options>
1526 #else
1527 template<class Config>
1528 #endif
1529 inline void swap
1530 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1531 (treap_impl<T, Options...> &x, treap_impl<T, Options...> &y)
1532 #else
1533 (treap_impl<Config> &x, treap_impl<Config> &y)
1534 #endif
1535 { x.swap(y); }
1537 /// @cond
1538 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1539 template<class T, class O1 = none, class O2 = none
1540 , class O3 = none, class O4 = none
1542 #else
1543 template<class T, class ...Options>
1544 #endif
1545 struct make_treap_opt
1547 typedef typename pack_options
1548 < treap_set_defaults<T>,
1549 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1550 O1, O2, O3, O4
1551 #else
1552 Options...
1553 #endif
1554 >::type packed_options;
1555 typedef typename detail::get_value_traits
1556 <T, typename packed_options::value_traits>::type value_traits;
1558 typedef treap_setopt
1559 < value_traits
1560 , typename packed_options::compare
1561 , typename packed_options::priority
1562 , typename packed_options::size_type
1563 , packed_options::constant_time_size
1564 > type;
1566 /// @endcond
1568 //! Helper metafunction to define a \c treap that yields to the same type when the
1569 //! same options (either explicitly or implicitly) are used.
1570 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1571 template<class T, class ...Options>
1572 #else
1573 template<class T, class O1 = none, class O2 = none
1574 , class O3 = none, class O4 = none>
1575 #endif
1576 struct make_trie
1578 /// @cond
1579 typedef treap_impl
1580 < typename make_treap_opt<T,
1581 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1582 O1, O2, O3, O4
1583 #else
1584 Options...
1585 #endif
1586 >::type
1587 > implementation_defined;
1588 /// @endcond
1589 typedef implementation_defined type;
1592 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
1594 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1595 template<class T, class O1, class O2, class O3, class O4>
1596 #else
1597 template<class T, class ...Options>
1598 #endif
1599 class treap
1600 : public make_trie<T,
1601 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1602 O1, O2, O3, O4
1603 #else
1604 Options...
1605 #endif
1606 >::type
1608 typedef typename make_trie
1609 <T,
1610 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1611 O1, O2, O3, O4
1612 #else
1613 Options...
1614 #endif
1615 >::type Base;
1617 public:
1618 typedef typename Base::value_compare value_compare;
1619 typedef typename Base::priority_compare priority_compare;
1620 typedef typename Base::value_traits value_traits;
1621 typedef typename Base::real_value_traits real_value_traits;
1622 typedef typename Base::iterator iterator;
1623 typedef typename Base::const_iterator const_iterator;
1625 //Assert if passed value traits are compatible with the type
1626 BOOST_STATIC_ASSERT((detail::is_same<typename real_value_traits::value_type, T>::value));
1628 treap( const value_compare &cmp = value_compare()
1629 , const priority_compare &pcmp = priority_compare()
1630 , const value_traits &v_traits = value_traits())
1631 : Base(cmp, pcmp, v_traits)
1634 template<class Iterator>
1635 treap( bool unique, Iterator b, Iterator e
1636 , const value_compare &cmp = value_compare()
1637 , const priority_compare &pcmp = priority_compare()
1638 , const value_traits &v_traits = value_traits())
1639 : Base(unique, b, e, cmp, pcmp, v_traits)
1642 static treap &container_from_end_iterator(iterator end_iterator)
1643 { return static_cast<treap &>(Base::container_from_end_iterator(end_iterator)); }
1645 static const treap &container_from_end_iterator(const_iterator end_iterator)
1646 { return static_cast<const treap &>(Base::container_from_end_iterator(end_iterator)); }
1648 static treap &container_from_it(iterator it)
1649 { return static_cast<treap &>(Base::container_from_iterator(it)); }
1651 static const treap &container_from_it(const_iterator it)
1652 { return static_cast<const treap &>(Base::container_from_iterator(it)); }
1655 #endif
1658 } //namespace intrusive
1659 } //namespace boost
1661 #include <boost/intrusive/detail/config_end.hpp>
1663 #endif //BOOST_INTRUSIVE_TRIE_HPP