1 /////////////////////////////////////////////////////////////////////////////
3 // (C) Copyright Ion Gaztanaga 2008
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)
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>
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>
41 template <class ValueTraits
, class Compare
, class PrioCompare
, class SizeType
, bool ConstantTimeSize
>
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
;
52 struct treap_set_defaults
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
> >
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
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.
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
>
81 template<class Config
>
84 : private detail::clear_on_destructor_base
<treap_impl
<Config
> >
86 template<class C
> friend class detail::clear_on_destructor_base
;
88 typedef typename
Config::value_traits value_traits
;
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
;
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
;
126 typedef detail::size_holder
<constant_time_size
, size_type
> size_traits
;
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
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_
;
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_
; }
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
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>)
205 real_value_traits
&get_real_value_traits(detail::bool_
<true>)
206 { return data_
.get_value_traits(*this); }
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.
222 //! <b>Complexity</b>: Constant.
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
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.
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));
259 this->insert_unique(b
, e
);
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.
268 //! <b>Complexity</b>: Linear to elements contained in *this
269 //! if constant-time size option is disabled. Constant time otherwise.
271 //! <b>Throws</b>: Nothing.
275 //! <b>Effects</b>: Returns an iterator pointing to the beginning of the tree.
277 //! <b>Complexity</b>: Constant.
279 //! <b>Throws</b>: Nothing.
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.
285 //! <b>Complexity</b>: Constant.
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.
293 //! <b>Complexity</b>: Constant.
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.
301 //! <b>Complexity</b>: Constant.
303 //! <b>Throws</b>: Nothing.
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.
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.
317 //! <b>Complexity</b>: Constant.
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.
326 //! <b>Complexity</b>: Constant.
328 //! <b>Throws</b>: Nothing.
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..
334 //! <b>Complexity</b>: Constant.
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..
342 //! <b>Complexity</b>: Constant.
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
351 //! <b>Complexity</b>: Constant.
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.
360 //! <b>Complexity</b>: Constant.
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.
369 //! <b>Complexity</b>: Constant.
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.
378 //! <b>Complexity</b>: Constant.
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.
387 //! <b>Complexity</b>: Constant.
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.
396 //! <b>Complexity</b>: Constant.
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
405 //! <b>Complexity</b>: Constant.
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.
414 //! <b>Complexity</b>: Constant.
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.
423 //! <b>Complexity</b>: Constant.
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
432 //! <b>Effects</b>: Returns a const reference to the treap associated to the end iterator
434 //! <b>Throws</b>: Nothing.
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
443 //! <b>Effects</b>: Returns a const reference to the treap associated to the iterator
445 //! <b>Throws</b>: Nothing.
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
454 //! <b>Effects</b>: Returns a const reference to the tree associated to the iterator
456 //! <b>Throws</b>: Nothing.
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
465 //! <b>Effects</b>: Returns a const reference to the tree associated to the end iterator
467 //! <b>Throws</b>: Nothing.
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.
475 //! <b>Complexity</b>: Constant.
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.
483 //! <b>Complexity</b>: Constant.
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.
491 //! <b>Complexity</b>: Constant.
493 //! <b>Throws</b>: Nothing.
495 { return node_algorithms::unique(const_node_ptr(&priv_header())); }
497 //! <b>Effects</b>: Returns the number of elements stored in the tree.
499 //! <b>Complexity</b>: Linear to elements contained in *this
500 //! if constant-time size option is disabled. Constant time otherwise.
502 //! <b>Throws</b>: Nothing.
503 size_type
size() const
505 if(constant_time_size
)
506 return this->priv_size_traits().get_size();
508 return (size_type
)node_algorithms::size(const_node_ptr(&priv_header()));
512 //! <b>Effects</b>: Swaps the contents of two treaps.
514 //! <b>Complexity</b>: Constant.
516 //! <b>Throws</b>: If the comparison functor's swap call throws.
517 void swap(treap_impl
& other
)
521 swap(priv_comp(), priv_comp());
522 swap(priv_pcomp(), priv_pcomp());
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
534 //! <b>Effects</b>: Inserts value into the tree before the upper bound.
536 //! <b>Complexity</b>: Average complexity for insert element is at
537 //! most logarithmic.
539 //! <b>Throws</b>: If the internal value_compare or priority_compare funcstions throw. Strong guarantee.
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.
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)
564 //! <b>Complexity</b>: Logarithmic in general, but it is amortized
565 //! constant time if t is inserted immediately before hint.
567 //! <b>Throws</b>: If the internal value_compare or priority_compare funcstions throw. Strong guarantee.
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.
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.
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
595 //! <b>Throws</b>: If the internal value_compare or priority_compare funcstions throw.
596 //! Strong guarantee.
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());
605 this->insert_equal(end
, *b
);
608 //! <b>Requires</b>: value must be an lvalue
610 //! <b>Effects</b>: Inserts value into the tree if the value
611 //! is not already present.
613 //! <b>Complexity</b>: Average complexity for insert element is at
614 //! most logarithmic.
616 //! <b>Throws</b>: If the internal value_compare or priority_compare funcstions throw.
617 //! Strong guarantee.
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
);
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
633 //! <b>Effects</b>: Tries to insert x into the tree, using "hint" as a hint
634 //! to where it will be inserted.
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.
640 //! <b>Throws</b>: If the internal value_compare or priority_compare funcstions throw.
641 //! Strong guarantee.
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
);
651 return insert_unique_commit(value
, commit_data
);
654 //! <b>Requires</b>: Dereferencing iterator must yield an lvalue
655 //! of type value_type.
657 //! <b>Effects</b>: Tries to insert each element of a range into the tree.
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
663 //! <b>Throws</b>: If the internal value_compare or priority_compare funcstions throw.
664 //! Strong guarantee.
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
)
672 iterator
end(this->end());
674 this->insert_unique(end
, *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.
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.
695 //! <b>Complexity</b>: Average complexity is at most logarithmic.
697 //! <b>Throws</b>: If the key_value_comp ordering function throws. Strong guarantee.
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.
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.
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.
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)).
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".
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.
786 //! <b>Complexity</b>: Constant time.
788 //! <b>Throws</b>: Nothing
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.
805 //! <b>Complexity</b>: Average complexity for erase element is constant time.
807 //! <b>Throws</b>: if the internal priority_compare function throws. Strong guarantee.
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
);
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.
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.
832 //! <b>Throws</b>: if the internal priority_compare function throws. Strong guarantee.
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.
841 //! <b>Returns</b>: The number of erased elements.
843 //! <b>Complexity</b>: O(log(size() + N).
845 //! <b>Throws</b>: if the internal priority_compare function throws. Strong guarantee.
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.
857 //! <b>Complexity</b>: O(log(size() + N).
859 //! <b>Throws</b>: if the internal priority_compare function throws. Strong guarantee.
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
866 , typename
detail::enable_if_c
<!detail::is_convertible
<KeyValueCompare
, const_iterator
>::value
>::type
* = 0
870 std::pair
<iterator
,iterator
> p
= this->equal_range(key
, comp
);
872 private_erase(p
.first
, p
.second
, 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.
881 //! <b>Complexity</b>: Average complexity for erase element is constant time.
883 //! <b>Throws</b>: if the internal priority_compare function throws. Strong guarantee.
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
));
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
); }
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.
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.
910 //! <b>Throws</b>: if the internal priority_compare function throws. Strong guarantee.
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.
923 //! <b>Returns</b>: The number of erased elements.
925 //! <b>Complexity</b>: O(log(size() + N).
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.
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
);
937 private_erase(p
.first
, p
.second
, n
, disposer
);
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.
949 //! <b>Complexity</b>: O(log(size() + N).
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.
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
959 , typename
detail::enable_if_c
<!detail::is_convertible
<KeyValueCompare
, const_iterator
>::value
>::type
* = 0
963 std::pair
<iterator
,iterator
> p
= this->equal_range(key
, comp
);
965 private_erase(p
.first
, p
.second
, n
, disposer
);
969 //! <b>Effects</b>: Erases all of the elements.
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.
974 //! <b>Throws</b>: Nothing.
976 //! <b>Note</b>: Invalidates the iterators (but not the references)
977 //! to the erased elements. No destructors are called.
980 if(safemode_or_autounlink
){
981 this->clear_and_dispose(detail::null_disposer());
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.
994 //! <b>Throws</b>: Nothing.
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
1009 //! <b>Complexity</b>: Logarithmic to the number of elements contained plus lineal
1010 //! to number of objects with the given value.
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
1018 //! <b>Complexity</b>: Logarithmic to the number of elements contained plus lineal
1019 //! to number of objects with the given key.
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.
1032 //! <b>Complexity</b>: Logarithmic.
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.
1041 //! <b>Complexity</b>: Logarithmic.
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.
1050 //! <b>Complexity</b>: Logarithmic.
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.
1065 //! <b>Complexity</b>: Logarithmic.
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.
1080 //! <b>Complexity</b>: Logarithmic.
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
1090 //! <b>Complexity</b>: Logarithmic.
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.
1105 //! <b>Complexity</b>: Logarithmic.
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
1115 //! <b>Complexity</b>: Logarithmic.
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.
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.
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);
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.
1154 //! <b>Complexity</b>: Logarithmic.
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.
1163 //! <b>Complexity</b>: Logarithmic.
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.
1179 //! <b>Complexity</b>: Logarithmic.
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.
1189 //! <b>Complexity</b>: Logarithmic.
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.
1206 //! <b>Complexity</b>: Logarithmic.
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.
1217 //! <b>Complexity</b>: Logarithmic.
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).
1242 //! <b>Complexity</b>: Linear to erased plus inserted elements.
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
);
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();
1263 //! <b>Effects</b>: Unlinks the leftmost node from the tree.
1265 //! <b>Complexity</b>: Average complexity is constant time.
1267 //! <b>Throws</b>: Nothing.
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())));
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.
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.
1291 //! <b>Complexity</b>: Constant.
1293 //! <b>Throws</b>: Nothing.
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.
1309 //! <b>Effects</b>: Returns: a valid iterator i belonging to the set
1310 //! that points to the value
1312 //! <b>Complexity</b>: Constant.
1314 //! <b>Throws</b>: Nothing.
1316 //! <b>Note</b>: This static function is available only if the <i>value traits</i>
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.
1327 //! <b>Effects</b>: Returns: a valid const_iterator i belonging to the
1328 //! set that points to the value
1330 //! <b>Complexity</b>: Constant.
1332 //! <b>Throws</b>: Nothing.
1334 //! <b>Note</b>: This static function is available only if the <i>value traits</i>
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.
1345 //! <b>Effects</b>: Returns: a valid iterator i belonging to the set
1346 //! that points to the value
1348 //! <b>Complexity</b>: Constant.
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.
1357 //! <b>Effects</b>: Returns: a valid const_iterator i belonging to the
1358 //! set that points to the value
1360 //! <b>Complexity</b>: Constant.
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.
1368 //! <b>Effects</b>: init_node puts the hook of a value in a well-known default
1371 //! <b>Throws</b>: Nothing.
1373 //! <b>Complexity</b>: Constant time.
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
)); }
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
);
1390 iterator
private_erase(const_iterator b
, const_iterator e
, size_type
&n
)
1392 for(n
= 0; b
!= e
; ++n
)
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
1407 (r
, &node_plus_pred_t::header_plus_priority_size::header_plus_size_
);
1408 node_plus_pred_t
*pn
= detail::parent_from_member
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_
);
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
>
1424 template<class Config
>
1426 inline bool operator<
1427 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1428 (const treap_impl
<T
, Options
...> &x
, const treap_impl
<T
, Options
...> &y
)
1430 (const treap_impl
<Config
> &x
, const treap_impl
<Config
> &y
)
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
>
1437 template<class Config
>
1440 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1441 (const treap_impl
<T
, Options
...> &x
, const treap_impl
<T
, Options
...> &y
)
1443 (const treap_impl
<Config
> &x
, const treap_impl
<Config
> &y
)
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()){
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
) {
1463 const_iterator end2
= y
.end();
1464 while (i1
!= end1
&& i2
!= end2
&& *i1
== *i2
) {
1468 return i1
== end1
&& i2
== end2
;
1472 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1473 template<class T
, class ...Options
>
1475 template<class Config
>
1477 inline bool operator!=
1478 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1479 (const treap_impl
<T
, Options
...> &x
, const treap_impl
<T
, Options
...> &y
)
1481 (const treap_impl
<Config
> &x
, const treap_impl
<Config
> &y
)
1483 { return !(x
== y
); }
1485 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1486 template<class T
, class ...Options
>
1488 template<class Config
>
1490 inline bool operator>
1491 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1492 (const treap_impl
<T
, Options
...> &x
, const treap_impl
<T
, Options
...> &y
)
1494 (const treap_impl
<Config
> &x
, const treap_impl
<Config
> &y
)
1498 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1499 template<class T
, class ...Options
>
1501 template<class Config
>
1503 inline bool operator<=
1504 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1505 (const treap_impl
<T
, Options
...> &x
, const treap_impl
<T
, Options
...> &y
)
1507 (const treap_impl
<Config
> &x
, const treap_impl
<Config
> &y
)
1509 { return !(y
< x
); }
1511 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1512 template<class T
, class ...Options
>
1514 template<class Config
>
1516 inline bool operator>=
1517 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1518 (const treap_impl
<T
, Options
...> &x
, const treap_impl
<T
, Options
...> &y
)
1520 (const treap_impl
<Config
> &x
, const treap_impl
<Config
> &y
)
1522 { return !(x
< y
); }
1524 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1525 template<class T
, class ...Options
>
1527 template<class Config
>
1530 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1531 (treap_impl
<T
, Options
...> &x
, treap_impl
<T
, Options
...> &y
)
1533 (treap_impl
<Config
> &x
, treap_impl
<Config
> &y
)
1538 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1539 template<class T
, class O1
= none
, class O2
= none
1540 , class O3
= none
, class O4
= none
1543 template<class T
, class ...Options
>
1545 struct make_treap_opt
1547 typedef typename pack_options
1548 < treap_set_defaults
<T
>,
1549 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
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
1560 , typename
packed_options::compare
1561 , typename
packed_options::priority
1562 , typename
packed_options::size_type
1563 , packed_options::constant_time_size
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
>
1573 template<class T
, class O1
= none
, class O2
= none
1574 , class O3
= none
, class O4
= none
>
1580 < typename make_treap_opt
<T
,
1581 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1587 > implementation_defined
;
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
>
1597 template<class T
, class ...Options
>
1600 : public make_trie
<T
,
1601 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1608 typedef typename make_trie
1610 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
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
)); }
1658 } //namespace intrusive
1661 #include <boost/intrusive/detail/config_end.hpp>
1663 #endif //BOOST_INTRUSIVE_TRIE_HPP