mirror of
https://github.com/boostorg/intrusive.git
synced 2025-05-11 13:13:57 +00:00
Reverted git mess.
This commit is contained in:
parent
27e5ad9183
commit
68fa82e5e8
@ -33,10 +33,12 @@ doxygen autodoc
|
|||||||
\"BOOST_RV_REF_END=&&\" \\
|
\"BOOST_RV_REF_END=&&\" \\
|
||||||
\"list_impl=list\" \\
|
\"list_impl=list\" \\
|
||||||
\"slist_impl=slist\" \\
|
\"slist_impl=slist\" \\
|
||||||
|
\"bstree_impl=bstree\" \\
|
||||||
|
\"bs_set_impl=bs_set\" \\
|
||||||
|
\"bs_multiset_impl=bs_multiset\" \\
|
||||||
|
\"rbtree_impl=rbtree\" \\
|
||||||
\"set_impl=set\" \\
|
\"set_impl=set\" \\
|
||||||
\"multiset_impl=multiset\" \\
|
\"multiset_impl=multiset\" \\
|
||||||
\"bstree_impl=bstree\" \\
|
|
||||||
\"rbtree_impl=rbtree\" \\
|
|
||||||
\"unordered_set_impl=unordered_set\" \\
|
\"unordered_set_impl=unordered_set\" \\
|
||||||
\"unordered_multiset_impl=unordered_multiset\" \\
|
\"unordered_multiset_impl=unordered_multiset\" \\
|
||||||
\"hashtable_impl=hashtable\" \\
|
\"hashtable_impl=hashtable\" \\
|
||||||
@ -51,7 +53,9 @@ doxygen autodoc
|
|||||||
\"avltree_impl=avltree\" \\
|
\"avltree_impl=avltree\" \\
|
||||||
\"treap_set_impl=treap_set\" \\
|
\"treap_set_impl=treap_set\" \\
|
||||||
\"treap_multiset_impl=treap_multiset\" \\
|
\"treap_multiset_impl=treap_multiset\" \\
|
||||||
\"treap_impl=treap\""
|
\"treap_impl=treap\" \\
|
||||||
|
\"BOOST_INTRUSIVE_OPTION_CONSTANT(OPTION_NAME, TYPE, VALUE, CONSTANT_NAME) = template<TYPE VALUE> struct OPTION_NAME{};\" \\
|
||||||
|
\"BOOST_INTRUSIVE_OPTION_TYPE(OPTION_NAME, TYPE, TYPEDEF_EXPR, TYPEDEF_NAME) = template<class TYPE> struct OPTION_NAME{};\" "
|
||||||
;
|
;
|
||||||
|
|
||||||
xml intrusive : intrusive.qbk
|
xml intrusive : intrusive.qbk
|
||||||
|
@ -871,11 +871,11 @@ the section [link intrusive.usage How to use Boost.Intrusive]:
|
|||||||
* [*`linear<bool Enable>`]: the singly linked list is implemented as a
|
* [*`linear<bool Enable>`]: the singly linked list is implemented as a
|
||||||
null-terminated list instead of a circular list. This allows `O(1)` swap,
|
null-terminated list instead of a circular list. This allows `O(1)` swap,
|
||||||
but losses some operations like `container_from_end_iterator`.
|
but losses some operations like `container_from_end_iterator`.
|
||||||
* [*`cache_last<bool Enable>`]: the singly linked also stores a pointer to the
|
* [*`cache_last<bool Enable>`]: `slist` also stores a pointer to the
|
||||||
last element of the singly linked list. This allows `O(1)` swap,
|
last element of the singly linked list. This allows `O(1)` swap,
|
||||||
`splice_after(iterator, slist &)` and makes the list offer new functions
|
`splice_after(iterator, slist &)` and makes the list offer new functions
|
||||||
like `push_back(reference)` and `back()`. Logically, the size an empty list is
|
like `push_back(reference)` and `back()`. Logically, the size an empty list is
|
||||||
increased in `sizeof(void_pointer)` and the the cached last node pointer must
|
increased in `sizeof(void_pointer)` and the cached last node pointer must
|
||||||
be updated in every operation, and that might incur in a slight performance impact.
|
be updated in every operation, and that might incur in a slight performance impact.
|
||||||
|
|
||||||
`auto_unlink` hooks are not usable if `linear<true>` and/or `cache_last<true>` options are
|
`auto_unlink` hooks are not usable if `linear<true>` and/or `cache_last<true>` options are
|
||||||
@ -1364,163 +1364,6 @@ the unordered container:
|
|||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
[section:splay_set_multiset Intrusive splay tree based associative containers: splay_set, splay_multiset and , splay_tree]
|
|
||||||
|
|
||||||
C++ associative containers are usually based on red-black tree implementations (e.g.: STL,
|
|
||||||
Boost.Intrusive associative containers). However, there are other interesting data
|
|
||||||
structures that offer some advantages (and also disadvantages).
|
|
||||||
|
|
||||||
Splay trees are self-adjusting binary search trees used typically in caches, memory
|
|
||||||
allocators and other applications, because splay trees have a "caching effect": recently
|
|
||||||
accessed elements have better access times than elements accessed less frequently.
|
|
||||||
For more information on splay trees see [@http://en.wikipedia.org/wiki/Splay_tree Wikipedia entry].
|
|
||||||
|
|
||||||
[*Boost.Intrusive] offers 3 containers based on splay trees:
|
|
||||||
[classref boost::intrusive::splay_set splay_set],
|
|
||||||
[classref boost::intrusive::splay_multiset splay_multiset] and
|
|
||||||
[classref boost::intrusive::splaytree splaytree]. The first two are similar to
|
|
||||||
[classref boost::intrusive::set set] or
|
|
||||||
[classref boost::intrusive::multiset multiset] and the latter is a generalization
|
|
||||||
that offers functions both to insert unique and multiple keys.
|
|
||||||
|
|
||||||
The memory overhead of these containers with Boost.Intrusive hooks is usually 3 pointers.
|
|
||||||
An empty, non constant-time size splay container has also a size of 3 pointers.
|
|
||||||
|
|
||||||
[section:splay_set_multiset_disadvantages Advantages and disadvantages of splay tree based containers]
|
|
||||||
|
|
||||||
Splay tree based intrusive containers have logarithmic complexity in many
|
|
||||||
operations like searches, insertions, erasures, etc., but if some elements are
|
|
||||||
more frequently accessed than others, splay trees perform faster searches than equivalent
|
|
||||||
balanced binary trees (such as red-black trees).
|
|
||||||
|
|
||||||
The caching effect offered by splay trees comes with a cost: the tree must be
|
|
||||||
rebalanced when an element is searched. This disallows const versions of search
|
|
||||||
functions like `find()`, `lower_bound()`, `upper_bound()`, `equal_range()`,
|
|
||||||
`count()`, etc.
|
|
||||||
|
|
||||||
Because of this, splay-tree based associative containers are not drop-in
|
|
||||||
replacements of [classref boost::intrusive::set set]/
|
|
||||||
[classref boost::intrusive::multiset multiset].
|
|
||||||
|
|
||||||
Apart from this, if element searches are randomized, the tree will be rebalanced
|
|
||||||
without taking advantage of the cache effect, so splay trees can offer worse
|
|
||||||
performance than other balanced trees for some search patterns.
|
|
||||||
|
|
||||||
[endsect]
|
|
||||||
|
|
||||||
[section:splay_set_multiset_hooks splay_set, splay_multiset and splaytree hooks]
|
|
||||||
|
|
||||||
[classref boost::intrusive::splay_set splay_set],
|
|
||||||
[classref boost::intrusive::splay_multiset splay_multiset] and
|
|
||||||
[classref boost::intrusive::splaytree splaytree]
|
|
||||||
share the same hooks.
|
|
||||||
|
|
||||||
[c++]
|
|
||||||
|
|
||||||
template <class ...Options>
|
|
||||||
class splay_set_base_hook;
|
|
||||||
|
|
||||||
* [classref boost::intrusive::splay_set_base_hook splay_set_base_hook]:
|
|
||||||
the user class derives publicly from this class to make
|
|
||||||
it compatible with splay tree based containers.
|
|
||||||
|
|
||||||
[c++]
|
|
||||||
|
|
||||||
template <class ...Options>
|
|
||||||
class splay_set_member_hook;
|
|
||||||
|
|
||||||
* [classref boost::intrusive::set_member_hook set_member_hook]:
|
|
||||||
the user class contains a public member of this class to make
|
|
||||||
it compatible with splay tree based containers.
|
|
||||||
|
|
||||||
[classref boost::intrusive::splay_set_base_hook splay_set_base_hook] and
|
|
||||||
[classref boost::intrusive::splay_set_member_hook splay_set_member_hook] receive
|
|
||||||
the same options explained in the section
|
|
||||||
[link intrusive.usage How to use Boost.Intrusive]:
|
|
||||||
|
|
||||||
* [*`tag<class Tag>`] (for base hooks only): This argument serves as a tag,
|
|
||||||
so you can derive from more than one base hook.
|
|
||||||
Default: `tag<default_tag>`.
|
|
||||||
|
|
||||||
* [*`link_mode<link_mode_type LinkMode>`]: The linking policy.
|
|
||||||
Default: `link_mode<safe_link>`.
|
|
||||||
|
|
||||||
* [*`void_pointer<class VoidPointer>`]: The pointer type to be used
|
|
||||||
internally in the hook and propagated to the container.
|
|
||||||
Default: `void_pointer<void*>`.
|
|
||||||
|
|
||||||
[endsect]
|
|
||||||
|
|
||||||
[section:set_multiset_containers splay_set, splay_multiset and splaytree containers]
|
|
||||||
|
|
||||||
[c++]
|
|
||||||
|
|
||||||
template <class T, class ...Options>
|
|
||||||
class splay_set;
|
|
||||||
|
|
||||||
template <class T, class ...Options>
|
|
||||||
class splay_multiset;
|
|
||||||
|
|
||||||
template <class T, class ...Options>
|
|
||||||
class splaytree;
|
|
||||||
|
|
||||||
These containers receive the same options explained in the section
|
|
||||||
[link intrusive.usage How to use Boost.Intrusive]:
|
|
||||||
|
|
||||||
* [*`base_hook<class Hook>`] / [*`member_hook<class T, class Hook, Hook T::* PtrToMember>`] /
|
|
||||||
[*`value_traits<class ValueTraits>`]: To specify the hook type or value traits used
|
|
||||||
to configure the container. (To learn about value traits go to the section
|
|
||||||
[link intrusive.value_traits Containers with custom ValueTraits].)
|
|
||||||
|
|
||||||
* [*`constant_time_size<bool Enabled>`]: To activate the constant-time `size()` operation.
|
|
||||||
Default: `constant_time_size<true>`
|
|
||||||
|
|
||||||
* [*`size_type<bool Enabled>`]: To specify the type that will be used to store the size
|
|
||||||
of the container. Default: `size_type<std::size_t>`
|
|
||||||
|
|
||||||
And they also can receive an additional option:
|
|
||||||
|
|
||||||
* [*`compare<class Compare>`]: Comparison function for the objects to be inserted
|
|
||||||
in containers. The comparison functor must induce a strict weak ordering.
|
|
||||||
Default: `compare< std::less<T> >`
|
|
||||||
|
|
||||||
[endsect]
|
|
||||||
|
|
||||||
[section:splay_set_bst_hook Splay trees with BST hooks]
|
|
||||||
|
|
||||||
Intrusive splay containers can also use plain binary search tree hooks
|
|
||||||
[classref boost::intrusive::bs_set_base_hook bs_set_base_hook] and
|
|
||||||
[classref boost::intrusive::bs_set_base_hook bs_set_base_hook].
|
|
||||||
These hooks can be used by other intrusive containers like
|
|
||||||
intrusive scapegoat containers
|
|
||||||
[classref boost::intrusive::sg_set sg_set] and
|
|
||||||
[classref boost::intrusive::sg_multiset sg_multiset]. A programmer
|
|
||||||
might prefer using a binary search tree hook so that the same type
|
|
||||||
can be inserted in some situations in a splay container but
|
|
||||||
also inserted in other compatible containers when
|
|
||||||
the hook is not being used in a splay container.
|
|
||||||
|
|
||||||
[classref boost::intrusive::bs_set_base_hook bs_set_base_hook] and
|
|
||||||
[classref boost::intrusive::bs_set_base_hook bs_set_member_hook] admit
|
|
||||||
the same options as [classref boost::intrusive::splay_set_base_hook splay_set_base_hook].
|
|
||||||
|
|
||||||
[endsect]
|
|
||||||
|
|
||||||
[section:splay_set_multiset_example Example]
|
|
||||||
|
|
||||||
Now let's see a small example using both splay hooks,
|
|
||||||
binary search tree hooks and
|
|
||||||
[classref boost::intrusive::splay_set splay_set]/
|
|
||||||
[classref boost::intrusive::splay_multiset splay_multiset]
|
|
||||||
containers:
|
|
||||||
|
|
||||||
[import ../example/doc_splay_set.cpp]
|
|
||||||
[doc_splay_set_code]
|
|
||||||
|
|
||||||
[endsect]
|
|
||||||
|
|
||||||
[endsect]
|
|
||||||
|
|
||||||
[section:avl_set_multiset Intrusive avl tree based associative containers: avl_set, avl_multiset and avltree]
|
[section:avl_set_multiset Intrusive avl tree based associative containers: avl_set, avl_multiset and avltree]
|
||||||
|
|
||||||
Similar to red-black trees, AVL trees are balanced binary trees.
|
Similar to red-black trees, AVL trees are balanced binary trees.
|
||||||
@ -1649,6 +1492,103 @@ containers:
|
|||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
|
[section:splay_set_multiset Intrusive splay tree based associative containers: splay_set, splay_multiset and , splay_tree]
|
||||||
|
|
||||||
|
C++ associative containers are usually based on red-black tree implementations (e.g.: STL,
|
||||||
|
Boost.Intrusive associative containers). However, there are other interesting data
|
||||||
|
structures that offer some advantages (and also disadvantages).
|
||||||
|
|
||||||
|
Splay trees are self-adjusting binary search trees used typically in caches, memory
|
||||||
|
allocators and other applications, because splay trees have a "caching effect": recently
|
||||||
|
accessed elements have better access times than elements accessed less frequently.
|
||||||
|
For more information on splay trees see [@http://en.wikipedia.org/wiki/Splay_tree the corresponding Wikipedia entry].
|
||||||
|
|
||||||
|
[*Boost.Intrusive] offers 3 containers based on splay trees:
|
||||||
|
[classref boost::intrusive::splay_set splay_set],
|
||||||
|
[classref boost::intrusive::splay_multiset splay_multiset] and
|
||||||
|
[classref boost::intrusive::splaytree splaytree]. The first two are similar to
|
||||||
|
[classref boost::intrusive::set set] or
|
||||||
|
[classref boost::intrusive::multiset multiset] and the latter is a generalization
|
||||||
|
that offers functions both to insert unique and multiple keys.
|
||||||
|
|
||||||
|
The memory overhead of these containers with Boost.Intrusive hooks is usually 3 pointers.
|
||||||
|
An empty, non constant-time size splay container has also a size of 3 pointers.
|
||||||
|
|
||||||
|
[section:splay_set_multiset_disadvantages Advantages and disadvantages of splay tree based containers]
|
||||||
|
|
||||||
|
Splay tree based intrusive containers have logarithmic complexity in many
|
||||||
|
operations like searches, insertions, erasures, etc., but if some elements are
|
||||||
|
more frequently accessed than others, splay trees perform faster searches than equivalent
|
||||||
|
balanced binary trees (such as red-black trees).
|
||||||
|
|
||||||
|
The caching effect offered by splay trees comes with a cost: the tree must be
|
||||||
|
rebalanced when an element is searched. To maintain const-correctness and thread-safety
|
||||||
|
guarantees, this caching effect is not updated when const versions of
|
||||||
|
search functions like `find()`, `lower_bound()`, `upper_bound()`, `equal_range()`,
|
||||||
|
`count()`... are called. This means that using splay-tree based associative containers as drop-in
|
||||||
|
replacements of [classref boost::intrusive::set set]/
|
||||||
|
[classref boost::intrusive::multiset multiset], specially for const search functions,
|
||||||
|
might not result in desired performance improvements.
|
||||||
|
|
||||||
|
If element searches are randomized, the tree will be continuously srebalanced
|
||||||
|
without taking advantage of the cache effect, so splay trees can offer worse
|
||||||
|
performance than other balanced trees for several search patterns.
|
||||||
|
|
||||||
|
[*Boost.Intrusive] splay associative containers don't use their own hook types but plain Binary search tree hooks.
|
||||||
|
See [link intrusive.bst_hooks Binary search tree hooks: bs_set_base_hook and bs_set_member_hook] section for more
|
||||||
|
information about these hooks.
|
||||||
|
|
||||||
|
[endsect]
|
||||||
|
|
||||||
|
[section:set_multiset_containers splay_set, splay_multiset and splaytree containers]
|
||||||
|
|
||||||
|
[c++]
|
||||||
|
|
||||||
|
template <class T, class ...Options>
|
||||||
|
class splay_set;
|
||||||
|
|
||||||
|
template <class T, class ...Options>
|
||||||
|
class splay_multiset;
|
||||||
|
|
||||||
|
template <class T, class ...Options>
|
||||||
|
class splaytree;
|
||||||
|
|
||||||
|
These containers receive the same options explained in the section
|
||||||
|
[link intrusive.usage How to use Boost.Intrusive]:
|
||||||
|
|
||||||
|
* [*`base_hook<class Hook>`] / [*`member_hook<class T, class Hook, Hook T::* PtrToMember>`] /
|
||||||
|
[*`value_traits<class ValueTraits>`]: To specify the hook type or value traits used
|
||||||
|
to configure the container. (To learn about value traits go to the section
|
||||||
|
[link intrusive.value_traits Containers with custom ValueTraits].)
|
||||||
|
|
||||||
|
* [*`constant_time_size<bool Enabled>`]: To activate the constant-time `size()` operation.
|
||||||
|
Default: `constant_time_size<true>`
|
||||||
|
|
||||||
|
* [*`size_type<bool Enabled>`]: To specify the type that will be used to store the size
|
||||||
|
of the container. Default: `size_type<std::size_t>`
|
||||||
|
|
||||||
|
And they also can receive an additional option:
|
||||||
|
|
||||||
|
* [*`compare<class Compare>`]: Comparison function for the objects to be inserted
|
||||||
|
in containers. The comparison functor must induce a strict weak ordering.
|
||||||
|
Default: `compare< std::less<T> >`
|
||||||
|
|
||||||
|
[endsect]
|
||||||
|
|
||||||
|
[section:splay_set_multiset_example Example]
|
||||||
|
|
||||||
|
Now let's see a small example using
|
||||||
|
[classref boost::intrusive::splay_set splay_set]/
|
||||||
|
[classref boost::intrusive::splay_multiset splay_multiset]
|
||||||
|
containers:
|
||||||
|
|
||||||
|
[import ../example/doc_splay_set.cpp]
|
||||||
|
[doc_splay_set_code]
|
||||||
|
|
||||||
|
[endsect]
|
||||||
|
|
||||||
|
[endsect]
|
||||||
|
|
||||||
|
|
||||||
[section:sg_set_multiset Intrusive scapegoat tree based associative containers: sg_set, sg_multiset and sgtree]
|
[section:sg_set_multiset Intrusive scapegoat tree based associative containers: sg_set, sg_multiset and sgtree]
|
||||||
|
|
||||||
@ -1705,50 +1645,9 @@ An empty, [classref boost::intrusive::sg_set sg_set],
|
|||||||
has also the size of 3 pointers, two integers and two floating point values
|
has also the size of 3 pointers, two integers and two floating point values
|
||||||
(equivalent to the size of 7 pointers on most systems).
|
(equivalent to the size of 7 pointers on most systems).
|
||||||
|
|
||||||
[section:sg_set_multiset_hooks Using binary search tree hooks: bs_set_base_hook and bs_set_member_hook]
|
[*Boost.Intrusive] scapegoat associative containers don't use their own hook types but plain Binary search tree hooks.
|
||||||
|
See [link intrusive.bst_hooks Binary search tree hooks: bs_set_base_hook and bs_set_member_hook] section for more
|
||||||
[classref boost::intrusive::sg_set sg_set],
|
information about these hooks.
|
||||||
[classref boost::intrusive::sg_multiset sg_multiset] and
|
|
||||||
[classref boost::intrusive::sgtree sgtree] don't use their
|
|
||||||
own hooks but plain binary search tree hooks. This has many advantages
|
|
||||||
since binary search tree hooks can also be used to insert values in
|
|
||||||
splay and treap containers.
|
|
||||||
|
|
||||||
[c++]
|
|
||||||
|
|
||||||
template <class ...Options>
|
|
||||||
class bs_set_base_hook;
|
|
||||||
|
|
||||||
* [classref boost::intrusive::bs_set_base_hook bs_set_base_hook]:
|
|
||||||
the user class derives publicly from this class to make
|
|
||||||
it compatible with scapegoat tree based containers.
|
|
||||||
|
|
||||||
[c++]
|
|
||||||
|
|
||||||
template <class ...Options>
|
|
||||||
class bs_set_member_hook;
|
|
||||||
|
|
||||||
* [classref boost::intrusive::set_member_hook set_member_hook]:
|
|
||||||
the user class contains a public member of this class to make
|
|
||||||
it compatible with scapegoat tree based containers.
|
|
||||||
|
|
||||||
[classref boost::intrusive::bs_set_base_hook bs_set_base_hook] and
|
|
||||||
[classref boost::intrusive::bs_set_member_hook bs_set_member_hook] receive
|
|
||||||
the same options explained in the section
|
|
||||||
[link intrusive.usage How to use Boost.Intrusive]:
|
|
||||||
|
|
||||||
* [*`tag<class Tag>`] (for base hooks only): This argument serves as a tag,
|
|
||||||
so you can derive from more than one base hook.
|
|
||||||
Default: `tag<default_tag>`.
|
|
||||||
|
|
||||||
* [*`link_mode<link_mode_type LinkMode>`]: The linking policy.
|
|
||||||
Default: `link_mode<safe_link>`.
|
|
||||||
|
|
||||||
* [*`void_pointer<class VoidPointer>`]: The pointer type to be used
|
|
||||||
internally in the hook and propagated to the container.
|
|
||||||
Default: `void_pointer<void*>`.
|
|
||||||
|
|
||||||
[endsect]
|
|
||||||
|
|
||||||
[section:sg_set_multiset_containers sg_set, sg_multiset and sgtree containers]
|
[section:sg_set_multiset_containers sg_set, sg_multiset and sgtree containers]
|
||||||
|
|
||||||
@ -1791,7 +1690,7 @@ And they also can receive additional options:
|
|||||||
|
|
||||||
[section:sg_set_multiset_example Example]
|
[section:sg_set_multiset_example Example]
|
||||||
|
|
||||||
Now let's see a small example using both hooks and
|
Now let's see a small example using binary search tree hooks and
|
||||||
[classref boost::intrusive::sg_set sg_set]/
|
[classref boost::intrusive::sg_set sg_set]/
|
||||||
[classref boost::intrusive::sg_multiset sg_multiset]
|
[classref boost::intrusive::sg_multiset sg_multiset]
|
||||||
containers:
|
containers:
|
||||||
@ -1841,50 +1740,9 @@ An empty, [classref boost::intrusive::treap_set treap_set],
|
|||||||
has also the size of 3 pointers and an integer (supposing empty function objects for key and priority
|
has also the size of 3 pointers and an integer (supposing empty function objects for key and priority
|
||||||
comparison and constant-time size).
|
comparison and constant-time size).
|
||||||
|
|
||||||
[section:treap_set_multiset_hooks Using binary search tree hooks: bs_set_base_hook and bs_set_member_hook]
|
[*Boost.Intrusive] treap associative containers don't use their own hook types but plain Binary search tree hooks.
|
||||||
|
See [link intrusive.bst_hooks Binary search tree hooks: bs_set_base_hook and bs_set_member_hook] section for more
|
||||||
[classref boost::intrusive::treap_set treap_set],
|
information about these hooks.
|
||||||
[classref boost::intrusive::treap_multiset treap_multiset] and
|
|
||||||
[classref boost::intrusive::treap treap] don't use their
|
|
||||||
own hooks but plain binary search tree hooks. This has many advantages
|
|
||||||
since binary search tree hooks can also be used to insert values in
|
|
||||||
splay containers and scapegoat trees.
|
|
||||||
|
|
||||||
[c++]
|
|
||||||
|
|
||||||
template <class ...Options>
|
|
||||||
class bs_set_base_hook;
|
|
||||||
|
|
||||||
* [classref boost::intrusive::bs_set_base_hook bs_set_base_hook]:
|
|
||||||
the user class derives publicly from this class to make
|
|
||||||
it compatible with scapegoat tree based containers.
|
|
||||||
|
|
||||||
[c++]
|
|
||||||
|
|
||||||
template <class ...Options>
|
|
||||||
class bs_set_member_hook;
|
|
||||||
|
|
||||||
* [classref boost::intrusive::set_member_hook set_member_hook]:
|
|
||||||
the user class contains a public member of this class to make
|
|
||||||
it compatible with scapegoat tree based containers.
|
|
||||||
|
|
||||||
[classref boost::intrusive::bs_set_base_hook bs_set_base_hook] and
|
|
||||||
[classref boost::intrusive::bs_set_member_hook bs_set_member_hook] receive
|
|
||||||
the same options explained in the section
|
|
||||||
[link intrusive.usage How to use Boost.Intrusive]:
|
|
||||||
|
|
||||||
* [*`tag<class Tag>`] (for base hooks only): This argument serves as a tag,
|
|
||||||
so you can derive from more than one base hook.
|
|
||||||
Default: `tag<default_tag>`.
|
|
||||||
|
|
||||||
* [*`link_mode<link_mode_type LinkMode>`]: The linking policy.
|
|
||||||
Default: `link_mode<safe_link>`.
|
|
||||||
|
|
||||||
* [*`void_pointer<class VoidPointer>`]: The pointer type to be used
|
|
||||||
internally in the hook and propagated to the container.
|
|
||||||
Default: `void_pointer<void*>`.
|
|
||||||
|
|
||||||
[endsect]
|
|
||||||
|
|
||||||
[section:treap_set_multiset_containers treap_set, treap_multiset and treap containers]
|
[section:treap_set_multiset_containers treap_set, treap_multiset and treap containers]
|
||||||
|
|
||||||
@ -1967,7 +1825,7 @@ the strongest possible behaviour in these situations. In summary:
|
|||||||
|
|
||||||
[section:treap_set_multiset_example Example]
|
[section:treap_set_multiset_example Example]
|
||||||
|
|
||||||
Now let's see a small example using both hooks and
|
Now let's see a small example using binary search tree hooks and
|
||||||
[classref boost::intrusive::treap_set treap_set]/
|
[classref boost::intrusive::treap_set treap_set]/
|
||||||
[classref boost::intrusive::treap_multiset treap_multiset]
|
[classref boost::intrusive::treap_multiset treap_multiset]
|
||||||
containers:
|
containers:
|
||||||
@ -1979,6 +1837,48 @@ containers:
|
|||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
|
[section:bst_hooks Binary search tree hooks: bs_set_base_hook and bs_set_member_hook]
|
||||||
|
|
||||||
|
Binary search tree hooks can be used with several tree-like containers that don't
|
||||||
|
need any additional metadata for rebalancing operations. This has many advantages
|
||||||
|
since binary search tree hooks can also be used to insert values in
|
||||||
|
plain binary search tree, splay tree, scapegoat tree, and treap containers.
|
||||||
|
|
||||||
|
[c++]
|
||||||
|
|
||||||
|
template <class ...Options>
|
||||||
|
class bs_set_base_hook;
|
||||||
|
|
||||||
|
* [classref boost::intrusive::bs_set_base_hook bs_set_base_hook]:
|
||||||
|
the user class derives publicly from this class to make
|
||||||
|
it compatible with the mentioned tree based containers.
|
||||||
|
|
||||||
|
[c++]
|
||||||
|
|
||||||
|
template <class ...Options>
|
||||||
|
class bs_set_member_hook;
|
||||||
|
|
||||||
|
* [classref boost::intrusive::bs_set_member_hook bs_set_member_hook]:
|
||||||
|
the user class contains a public member of this class to make
|
||||||
|
it compatible with the mentioned tree based containers.
|
||||||
|
|
||||||
|
[classref boost::intrusive::bs_set_base_hook bs_set_base_hook] and
|
||||||
|
[classref boost::intrusive::bs_set_member_hook bs_set_member_hook] receive
|
||||||
|
the same options explained in the section
|
||||||
|
[link intrusive.usage How to use Boost.Intrusive]:
|
||||||
|
|
||||||
|
* [*`tag<class Tag>`] (for base hooks only): This argument serves as a tag,
|
||||||
|
so you can derive from more than one base hook.
|
||||||
|
Default: `tag<default_tag>`.
|
||||||
|
|
||||||
|
* [*`link_mode<link_mode_type LinkMode>`]: The linking policy.
|
||||||
|
Default: `link_mode<safe_link>`.
|
||||||
|
|
||||||
|
* [*`void_pointer<class VoidPointer>`]: The pointer type to be used
|
||||||
|
internally in the hook and propagated to the container.
|
||||||
|
Default: `void_pointer<void*>`.
|
||||||
|
|
||||||
|
[endsect]
|
||||||
|
|
||||||
[section:advanced_lookups_insertions Advanced lookup and insertion functions for associative containers]
|
[section:advanced_lookups_insertions Advanced lookup and insertion functions for associative containers]
|
||||||
|
|
||||||
@ -3582,7 +3482,7 @@ and also derives from `test_class`.
|
|||||||
`func_ptr_adaptor` is just a functor adaptor to convert function objects taking
|
`func_ptr_adaptor` is just a functor adaptor to convert function objects taking
|
||||||
`test_list` objects to function objects taking pointers to them.
|
`test_list` objects to function objects taking pointers to them.
|
||||||
|
|
||||||
You can find the full test code code in the
|
You can find the full test code in the
|
||||||
[@../../libs/intrusive/perf/perf_list.cpp perf_list.cpp] source file.
|
[@../../libs/intrusive/perf/perf_list.cpp perf_list.cpp] source file.
|
||||||
|
|
||||||
[section:performance_results_push_back Back insertion and destruction]
|
[section:performance_results_push_back Back insertion and destruction]
|
||||||
@ -3884,10 +3784,28 @@ to be inserted in intrusive containers are allocated using `std::vector` or `std
|
|||||||
|
|
||||||
[section:release_notes Release Notes]
|
[section:release_notes Release Notes]
|
||||||
|
|
||||||
|
[section:release_notes_boost_1_56_00 Boost 1.56 Release]
|
||||||
|
|
||||||
|
* Improved Doxygen generated reference and updated and fixed forward-declaration header.
|
||||||
|
|
||||||
|
* [*ABI breaking]: Fixed ABI regression introduced in Boost 1.55 version, mainly noticeable on MSVC compilers.
|
||||||
|
|
||||||
|
* [*Source breaking]: Removed previously deprecated `xxx_dont_splay` functions from splay containers,
|
||||||
|
`splay_set_base_hook` and `splay_set_member_hook`from splay containers and `bool splay = true`
|
||||||
|
extra parameter is `splaytree_algorithms` functions.
|
||||||
|
|
||||||
|
* Fixed bugs:
|
||||||
|
* [@https://svn.boost.org/trac/boost/ticket/9332 #9332: ['"has_member_function_callable_with.hpp compile error on msvc-12.0"]].
|
||||||
|
|
||||||
|
* Optimized tree rebalancing code to avoid redundant assignments.
|
||||||
|
|
||||||
|
[endsect]
|
||||||
|
|
||||||
[section:release_notes_boost_1_55_00 Boost 1.55 Release]
|
[section:release_notes_boost_1_55_00 Boost 1.55 Release]
|
||||||
|
|
||||||
* [*Source breaking]: Deprecated `xxx_dont_splay` functions from splay containers.
|
* [*Source breaking]: Deprecated `xxx_dont_splay` functions from splay containers.
|
||||||
Deprecated `splay_set_hook` from splay containers, use `bs_set_hook` instead.
|
Deprecated `splay_set_base_hook` and `splay_set_member_hook`from splay containers, use
|
||||||
|
`bs_set_base_hook` or `bs_set_member_hook` instead.
|
||||||
Both will be removed in Boost 1.56.
|
Both will be removed in Boost 1.56.
|
||||||
|
|
||||||
* [*ABI breaking]: Hash containers' end iterator was implemented pointing to one-past the end of the bucket array
|
* [*ABI breaking]: Hash containers' end iterator was implemented pointing to one-past the end of the bucket array
|
||||||
|
@ -24,7 +24,8 @@ class MyClass : public auto_unlink_hook
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
MyClass(int i = 0) : int_(i) {}
|
MyClass(int i = 0) : int_(i) {}
|
||||||
void unlink() { auto_unlink_hook::unlink(); }
|
int get_int() { return int_; }
|
||||||
|
void unlink() { auto_unlink_hook::unlink(); }
|
||||||
bool is_linked() { return auto_unlink_hook::is_linked(); }
|
bool is_linked() { return auto_unlink_hook::is_linked(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,129 +0,0 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// (C) Copyright Ion Gaztanaga 2007-2013
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
|
||||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// See http://www.boost.org/libs/intrusive for documentation.
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//[doc_external_value_traits
|
|
||||||
#include <boost/intrusive/list.hpp>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
using namespace boost::intrusive;
|
|
||||||
|
|
||||||
//This type is not modifiable so we can't store hooks or custom nodes
|
|
||||||
typedef int identifier_t;
|
|
||||||
|
|
||||||
//This value traits will associate elements from an array of identifiers with
|
|
||||||
//elements of an array of nodes. The element i of the value array will use the
|
|
||||||
//node i of the node array:
|
|
||||||
class external_traits
|
|
||||||
{
|
|
||||||
//Non-copyable
|
|
||||||
external_traits(const external_traits &);
|
|
||||||
external_traits& operator=(const external_traits &);
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef list_node_traits<void*> node_traits;
|
|
||||||
typedef node_traits::node node;
|
|
||||||
typedef node * node_ptr;
|
|
||||||
typedef const node * const_node_ptr;
|
|
||||||
typedef identifier_t value_type;
|
|
||||||
typedef identifier_t * pointer;
|
|
||||||
typedef const identifier_t * const_pointer;
|
|
||||||
static const link_mode_type link_mode = normal_link;
|
|
||||||
|
|
||||||
external_traits(pointer ids, std::size_t NumElements)
|
|
||||||
: ids_(ids), nodes_(NumElements)
|
|
||||||
{}
|
|
||||||
|
|
||||||
///Note: non static functions!
|
|
||||||
node_ptr to_node_ptr (value_type &value)
|
|
||||||
{ return &this->nodes_[0] + (&value - this->ids_); }
|
|
||||||
const_node_ptr to_node_ptr (const value_type &value) const
|
|
||||||
{ return &this->nodes_[0] + (&value - this->ids_); }
|
|
||||||
pointer to_value_ptr(node_ptr n)
|
|
||||||
{ return this->ids_ + (n - &this->nodes_[0]); }
|
|
||||||
const_pointer to_value_ptr(const_node_ptr n) const
|
|
||||||
{ return this->ids_ + (n - &this->nodes_[0]); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
pointer ids_;
|
|
||||||
//This is an array of nodes that is necessary to form the linked list
|
|
||||||
std::vector<list_node_traits<void*>::node> nodes_;
|
|
||||||
};
|
|
||||||
|
|
||||||
//This is the value traits class that will be stored in the container
|
|
||||||
//and that will lead to the external traits using the address
|
|
||||||
//of the container.
|
|
||||||
struct internal_traits
|
|
||||||
{
|
|
||||||
static const bool external_value_traits = true;
|
|
||||||
typedef external_traits value_traits;
|
|
||||||
|
|
||||||
template<class Container>
|
|
||||||
value_traits &get_value_traits(Container &cont);
|
|
||||||
|
|
||||||
template<class Container>
|
|
||||||
const value_traits &get_value_traits(const Container &cont) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
//The intrusive list that will use external value traits
|
|
||||||
typedef list<identifier_t, value_traits<internal_traits> > List;
|
|
||||||
|
|
||||||
class data_holder
|
|
||||||
: public List
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
data_holder(identifier_t *ids, std::size_t NumElements)
|
|
||||||
: List()
|
|
||||||
, external_traits_(ids, NumElements)
|
|
||||||
{}
|
|
||||||
external_traits external_traits_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class Container>
|
|
||||||
internal_traits::value_traits &internal_traits::get_value_traits(Container &cont)
|
|
||||||
{ return static_cast<data_holder&>(cont).external_traits_; }
|
|
||||||
|
|
||||||
template<class Container>
|
|
||||||
const internal_traits::value_traits &internal_traits::get_value_traits(const Container &cont) const
|
|
||||||
{ return static_cast<const data_holder&>(cont).external_traits_; }
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
const int NumElements = 100;
|
|
||||||
|
|
||||||
//This is an array of ids that we want to "store"
|
|
||||||
identifier_t ids [NumElements];
|
|
||||||
|
|
||||||
//Initialize id objects, each one with a different number
|
|
||||||
for(int i = 0; i != NumElements; ++i) ids[i] = i;
|
|
||||||
|
|
||||||
//The data holding the list and the external traits
|
|
||||||
data_holder data(ids, NumElements);
|
|
||||||
|
|
||||||
//This list will store ids without modifying identifier_t instances
|
|
||||||
//Stateful value traits must be explicitly passed in the constructor.
|
|
||||||
List &my_list = data;
|
|
||||||
|
|
||||||
//Insert ids in reverse order in the list
|
|
||||||
for(identifier_t * it(&ids[0]), *itend(&ids[NumElements]); it != itend; ++it)
|
|
||||||
my_list.push_front(*it);
|
|
||||||
|
|
||||||
//Now test lists
|
|
||||||
List::const_iterator list_it (my_list.cbegin());
|
|
||||||
identifier_t *it_val(&ids[NumElements]-1), *it_rbeg_val(&ids[0] -1);
|
|
||||||
|
|
||||||
//Test the objects inserted in the base hook list
|
|
||||||
for(; it_val != it_rbeg_val; --it_val, ++list_it){
|
|
||||||
if(&*list_it != &*it_val) return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
//]
|
|
@ -11,7 +11,6 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
//[doc_splay_set_code
|
//[doc_splay_set_code
|
||||||
#include <boost/intrusive/splay_set.hpp>
|
#include <boost/intrusive/splay_set.hpp>
|
||||||
#include <boost/intrusive/bs_set_hook.hpp>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
@ -20,14 +19,13 @@ using namespace boost::intrusive;
|
|||||||
class mytag;
|
class mytag;
|
||||||
|
|
||||||
class MyClass
|
class MyClass
|
||||||
: public splay_set_base_hook<> //This is an splay tree base hook
|
: public bs_set_base_hook<>
|
||||||
, public bs_set_base_hook< tag<mytag> > //This is a binary search tree base hook
|
|
||||||
{
|
{
|
||||||
int int_;
|
int int_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//This is a member hook
|
//This is a member hook
|
||||||
splay_set_member_hook<> member_hook_;
|
bs_set_member_hook<> member_hook_;
|
||||||
|
|
||||||
MyClass(int i)
|
MyClass(int i)
|
||||||
: int_(i)
|
: int_(i)
|
||||||
@ -43,11 +41,8 @@ class MyClass
|
|||||||
//Define a set using the base hook that will store values in reverse order
|
//Define a set using the base hook that will store values in reverse order
|
||||||
typedef splay_set< MyClass, compare<std::greater<MyClass> > > BaseSplaySet;
|
typedef splay_set< MyClass, compare<std::greater<MyClass> > > BaseSplaySet;
|
||||||
|
|
||||||
//Define a set using the binary search tree hook
|
|
||||||
typedef splay_set< MyClass, base_hook<bs_set_base_hook< tag<mytag> > > > BaseBsSplaySet;
|
|
||||||
|
|
||||||
//Define an multiset using the member hook
|
//Define an multiset using the member hook
|
||||||
typedef member_hook<MyClass, splay_set_member_hook<>, &MyClass::member_hook_> MemberOption;
|
typedef member_hook<MyClass, bs_set_member_hook<>, &MyClass::member_hook_> MemberOption;
|
||||||
typedef splay_multiset< MyClass, MemberOption> MemberSplayMultiset;
|
typedef splay_multiset< MyClass, MemberOption> MemberSplayMultiset;
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
@ -59,21 +54,18 @@ int main()
|
|||||||
for(int i = 0; i < 100; ++i) values.push_back(MyClass(i));
|
for(int i = 0; i < 100; ++i) values.push_back(MyClass(i));
|
||||||
|
|
||||||
BaseSplaySet baseset;
|
BaseSplaySet baseset;
|
||||||
BaseBsSplaySet bsbaseset;
|
|
||||||
MemberSplayMultiset membermultiset;
|
MemberSplayMultiset membermultiset;
|
||||||
|
|
||||||
|
|
||||||
//Insert values in the container
|
//Insert values in the container
|
||||||
for(VectIt it(values.begin()), itend(values.end()); it != itend; ++it){
|
for(VectIt it(values.begin()), itend(values.end()); it != itend; ++it){
|
||||||
baseset.insert(*it);
|
baseset.insert(*it);
|
||||||
bsbaseset.insert(*it);
|
|
||||||
membermultiset.insert(*it);
|
membermultiset.insert(*it);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Now test sets
|
//Now test sets
|
||||||
{
|
{
|
||||||
BaseSplaySet::reverse_iterator rbit(baseset.rbegin());
|
BaseSplaySet::reverse_iterator rbit(baseset.rbegin());
|
||||||
BaseBsSplaySet::iterator bsit(bsbaseset.begin());
|
|
||||||
MemberSplayMultiset::iterator mit(membermultiset.begin());
|
MemberSplayMultiset::iterator mit(membermultiset.begin());
|
||||||
VectIt it(values.begin()), itend(values.end());
|
VectIt it(values.begin()), itend(values.end());
|
||||||
|
|
||||||
@ -83,8 +75,7 @@ int main()
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Test the objects inserted in member and binary search hook sets
|
//Test the objects inserted in member and binary search hook sets
|
||||||
for(it = values.begin(); it != itend; ++it, ++bsit, ++mit){
|
for(it = values.begin(); it != itend; ++it, ++mit){
|
||||||
if(&*bsit != &*it) return 1;
|
|
||||||
if(&*mit != &*it) return 1;
|
if(&*mit != &*it) return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ struct make_any_base_hook
|
|||||||
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link, \c safe_link).
|
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link, \c safe_link).
|
||||||
//!
|
//!
|
||||||
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
||||||
//! and the the container configured to use this hook.
|
//! and the container configured to use this hook.
|
||||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template<class ...Options>
|
template<class ...Options>
|
||||||
#else
|
#else
|
||||||
@ -175,7 +175,7 @@ struct make_any_member_hook
|
|||||||
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link or \c safe_link).
|
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link or \c safe_link).
|
||||||
//!
|
//!
|
||||||
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
||||||
//! and the the container configured to use this hook.
|
//! and the container configured to use this hook.
|
||||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template<class ...Options>
|
template<class ...Options>
|
||||||
#else
|
#else
|
||||||
|
@ -249,13 +249,19 @@ class avl_set_impl
|
|||||||
template<class Disposer>
|
template<class Disposer>
|
||||||
void clear_and_dispose(Disposer disposer);
|
void clear_and_dispose(Disposer disposer);
|
||||||
|
|
||||||
|
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::avltree::count(const_reference)const
|
//! @copydoc ::boost::intrusive::avltree::count(const_reference)const
|
||||||
size_type count(const_reference value) const;
|
size_type count(const_reference value) const
|
||||||
|
{ return static_cast<size_type>(this->tree_type::find(value) != this->tree_type::cend()); }
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::avltree::count(const KeyType&,KeyValueCompare)const
|
//! @copydoc ::boost::intrusive::avltree::count(const KeyType&,KeyValueCompare)const
|
||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
size_type count(const KeyType& key, KeyValueCompare comp) const;
|
size_type count(const KeyType& key, KeyValueCompare comp) const
|
||||||
|
{ return static_cast<size_type>(this->tree_type::find(key, comp) != this->tree_type::cend()); }
|
||||||
|
|
||||||
|
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::avltree::lower_bound(const_reference)
|
//! @copydoc ::boost::intrusive::avltree::lower_bound(const_reference)
|
||||||
iterator lower_bound(const_reference value);
|
iterator lower_bound(const_reference value);
|
||||||
|
|
||||||
@ -298,21 +304,29 @@ class avl_set_impl
|
|||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
const_iterator find(const KeyType& key, KeyValueCompare comp) const;
|
const_iterator find(const KeyType& key, KeyValueCompare comp) const;
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::avltree::equal_range(const_reference)
|
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
std::pair<iterator,iterator> equal_range(const_reference value);
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::avltree::equal_range(const KeyType&,KeyValueCompare)
|
//! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)
|
||||||
|
std::pair<iterator,iterator> equal_range(const_reference value)
|
||||||
|
{ return this->tree_type::lower_bound_range(value); }
|
||||||
|
|
||||||
|
//! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)
|
||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
|
std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp)
|
||||||
|
{ return this->tree_type::lower_bound_range(key, comp); }
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::avltree::equal_range(const_reference)const
|
//! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)const
|
||||||
std::pair<const_iterator, const_iterator>
|
std::pair<const_iterator, const_iterator>
|
||||||
equal_range(const_reference value) const;
|
equal_range(const_reference value) const
|
||||||
|
{ return this->tree_type::lower_bound_range(value); }
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::avltree::equal_range(const KeyType&,KeyValueCompare)const
|
//! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)const
|
||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
std::pair<const_iterator, const_iterator>
|
std::pair<const_iterator, const_iterator>
|
||||||
equal_range(const KeyType& key, KeyValueCompare comp) const;
|
equal_range(const KeyType& key, KeyValueCompare comp) const
|
||||||
|
{ return this->tree_type::lower_bound_range(key, comp); }
|
||||||
|
|
||||||
|
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::avltree::bounded_range(const_reference,const_reference,bool,bool)
|
//! @copydoc ::boost::intrusive::avltree::bounded_range(const_reference,const_reference,bool,bool)
|
||||||
std::pair<iterator,iterator> bounded_range
|
std::pair<iterator,iterator> bounded_range
|
||||||
@ -692,7 +706,7 @@ class avl_multiset_impl
|
|||||||
//! @copydoc ::boost::intrusive::avltree::count(const KeyType&,KeyValueCompare)const
|
//! @copydoc ::boost::intrusive::avltree::count(const KeyType&,KeyValueCompare)const
|
||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
size_type count(const KeyType& key, KeyValueCompare comp) const;
|
size_type count(const KeyType& key, KeyValueCompare comp) const;
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::avltree::lower_bound(const_reference)
|
//! @copydoc ::boost::intrusive::avltree::lower_bound(const_reference)
|
||||||
iterator lower_bound(const_reference value);
|
iterator lower_bound(const_reference value);
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ struct make_avl_set_base_hook
|
|||||||
//! unique tag.
|
//! unique tag.
|
||||||
//!
|
//!
|
||||||
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
||||||
//! and the the container configured to use this hook.
|
//! and the container configured to use this hook.
|
||||||
//!
|
//!
|
||||||
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
|
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
|
||||||
//! \c auto_unlink or \c safe_link).
|
//! \c auto_unlink or \c safe_link).
|
||||||
@ -200,7 +200,7 @@ struct make_avl_set_member_hook
|
|||||||
//! \c link_mode<> and \c optimize_size<>.
|
//! \c link_mode<> and \c optimize_size<>.
|
||||||
//!
|
//!
|
||||||
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
||||||
//! and the the container configured to use this hook.
|
//! and the container configured to use this hook.
|
||||||
//!
|
//!
|
||||||
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
|
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
|
||||||
//! \c auto_unlink or \c safe_link).
|
//! \c auto_unlink or \c safe_link).
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#define BOOST_INTRUSIVE_AVLTREE_HPP
|
#define BOOST_INTRUSIVE_AVLTREE_HPP
|
||||||
|
|
||||||
#include <boost/intrusive/detail/config_begin.hpp>
|
#include <boost/intrusive/detail/config_begin.hpp>
|
||||||
|
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
@ -21,7 +22,6 @@
|
|||||||
|
|
||||||
#include <boost/intrusive/detail/assert.hpp>
|
#include <boost/intrusive/detail/assert.hpp>
|
||||||
#include <boost/static_assert.hpp>
|
#include <boost/static_assert.hpp>
|
||||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
|
||||||
#include <boost/intrusive/avl_set_hook.hpp>
|
#include <boost/intrusive/avl_set_hook.hpp>
|
||||||
#include <boost/intrusive/detail/avltree_node.hpp>
|
#include <boost/intrusive/detail/avltree_node.hpp>
|
||||||
#include <boost/intrusive/bstree.hpp>
|
#include <boost/intrusive/bstree.hpp>
|
||||||
@ -296,7 +296,7 @@ class avltree_impl
|
|||||||
//! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const
|
//! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const
|
||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
size_type count(const KeyType& key, KeyValueCompare comp) const;
|
size_type count(const KeyType& key, KeyValueCompare comp) const;
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)
|
//! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)
|
||||||
iterator lower_bound(const_reference value);
|
iterator lower_bound(const_reference value);
|
||||||
|
|
||||||
@ -487,14 +487,13 @@ class avltree
|
|||||||
public:
|
public:
|
||||||
typedef typename Base::value_compare value_compare;
|
typedef typename Base::value_compare value_compare;
|
||||||
typedef typename Base::value_traits value_traits;
|
typedef typename Base::value_traits value_traits;
|
||||||
typedef typename Base::real_value_traits real_value_traits;
|
|
||||||
typedef typename Base::iterator iterator;
|
typedef typename Base::iterator iterator;
|
||||||
typedef typename Base::const_iterator const_iterator;
|
typedef typename Base::const_iterator const_iterator;
|
||||||
typedef typename Base::reverse_iterator reverse_iterator;
|
typedef typename Base::reverse_iterator reverse_iterator;
|
||||||
typedef typename Base::const_reverse_iterator const_reverse_iterator;
|
typedef typename Base::const_reverse_iterator const_reverse_iterator;
|
||||||
|
|
||||||
//Assert if passed value traits are compatible with the type
|
//Assert if passed value traits are compatible with the type
|
||||||
BOOST_STATIC_ASSERT((detail::is_same<typename real_value_traits::value_type, T>::value));
|
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
|
||||||
|
|
||||||
explicit avltree( const value_compare &cmp = value_compare()
|
explicit avltree( const value_compare &cmp = value_compare()
|
||||||
, const value_traits &v_traits = value_traits())
|
, const value_traits &v_traits = value_traits())
|
||||||
|
@ -15,9 +15,9 @@
|
|||||||
#define BOOST_INTRUSIVE_AVLTREE_ALGORITHMS_HPP
|
#define BOOST_INTRUSIVE_AVLTREE_ALGORITHMS_HPP
|
||||||
|
|
||||||
#include <boost/intrusive/detail/config_begin.hpp>
|
#include <boost/intrusive/detail/config_begin.hpp>
|
||||||
|
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
|
||||||
|
|
||||||
#include <boost/intrusive/detail/assert.hpp>
|
#include <boost/intrusive/detail/assert.hpp>
|
||||||
#include <boost/intrusive/detail/utilities.hpp>
|
#include <boost/intrusive/detail/utilities.hpp>
|
||||||
@ -49,15 +49,6 @@ struct avltree_node_cloner
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class NodeTraits>
|
|
||||||
struct avltree_erase_fixup
|
|
||||||
{
|
|
||||||
typedef typename NodeTraits::node_ptr node_ptr;
|
|
||||||
|
|
||||||
void operator()(const node_ptr & to_erase, const node_ptr & successor)
|
|
||||||
{ NodeTraits::set_balance(successor, NodeTraits::get_balance(to_erase)); }
|
|
||||||
};
|
|
||||||
|
|
||||||
/// @endcond
|
/// @endcond
|
||||||
|
|
||||||
//! avltree_algorithms is configured with a NodeTraits class, which encapsulates the
|
//! avltree_algorithms is configured with a NodeTraits class, which encapsulates the
|
||||||
@ -225,7 +216,10 @@ class avltree_algorithms
|
|||||||
static node_ptr erase(const node_ptr & header, const node_ptr & z)
|
static node_ptr erase(const node_ptr & header, const node_ptr & z)
|
||||||
{
|
{
|
||||||
typename bstree_algo::data_for_rebalance info;
|
typename bstree_algo::data_for_rebalance info;
|
||||||
bstree_algo::erase(header, z, avltree_erase_fixup<NodeTraits>(), info);
|
bstree_algo::erase(header, z, info);
|
||||||
|
if(info.y != z){
|
||||||
|
NodeTraits::set_balance(info.y, NodeTraits::get_balance(z));
|
||||||
|
}
|
||||||
//Rebalance avltree
|
//Rebalance avltree
|
||||||
rebalance_after_erasure(header, info.x, info.x_parent);
|
rebalance_after_erasure(header, info.x, info.x_parent);
|
||||||
return z;
|
return z;
|
||||||
@ -274,6 +268,7 @@ class avltree_algorithms
|
|||||||
//! @copydoc ::boost::intrusive::bstree_algorithms::count(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
//! @copydoc ::boost::intrusive::bstree_algorithms::count(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
||||||
template<class KeyType, class KeyNodePtrCompare>
|
template<class KeyType, class KeyNodePtrCompare>
|
||||||
static std::size_t count(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp);
|
static std::size_t count(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp);
|
||||||
|
|
||||||
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_upper_bound(const node_ptr&,const node_ptr&,NodePtrCompare)
|
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_upper_bound(const node_ptr&,const node_ptr&,NodePtrCompare)
|
||||||
@ -357,40 +352,92 @@ class avltree_algorithms
|
|||||||
|
|
||||||
|
|
||||||
/// @cond
|
/// @cond
|
||||||
|
static bool verify(const node_ptr &header)
|
||||||
|
{
|
||||||
|
std::size_t height;
|
||||||
|
std::size_t count;
|
||||||
|
return verify_recursion(NodeTraits::get_parent(header), count, height);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static void rebalance_after_erasure(const node_ptr & header, const node_ptr & xnode, const node_ptr & xnode_parent)
|
static bool verify_recursion(node_ptr n, std::size_t &count, std::size_t &height)
|
||||||
|
{
|
||||||
|
if (!n){
|
||||||
|
count = 0;
|
||||||
|
height = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
std::size_t leftcount, rightcount;
|
||||||
|
std::size_t leftheight, rightheight;
|
||||||
|
if(!verify_recursion(NodeTraits::get_left (n), leftcount, leftheight) ||
|
||||||
|
!verify_recursion(NodeTraits::get_right(n), rightcount, rightheight) ){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
count = 1u + leftcount + rightcount;
|
||||||
|
height = 1u + (leftheight > rightheight ? leftheight : rightheight);
|
||||||
|
|
||||||
|
//If equal height, balance must be zero
|
||||||
|
if(rightheight == leftheight){
|
||||||
|
if(NodeTraits::get_balance(n) != NodeTraits::zero()){
|
||||||
|
BOOST_ASSERT(0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//If right is taller than left, then the difference must be at least 1 and the balance positive
|
||||||
|
else if(rightheight > leftheight){
|
||||||
|
if(rightheight - leftheight > 1 ){
|
||||||
|
BOOST_ASSERT(0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if(NodeTraits::get_balance(n) != NodeTraits::positive()){
|
||||||
|
BOOST_ASSERT(0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//If left is taller than right, then the difference must be at least 1 and the balance negative
|
||||||
|
else{
|
||||||
|
if(leftheight - rightheight > 1 ){
|
||||||
|
BOOST_ASSERT(0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if(NodeTraits::get_balance(n) != NodeTraits::negative()){
|
||||||
|
BOOST_ASSERT(0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rebalance_after_erasure(const node_ptr & header, node_ptr x, node_ptr x_parent)
|
||||||
{
|
{
|
||||||
node_ptr x(xnode), x_parent(xnode_parent);
|
|
||||||
for (node_ptr root = NodeTraits::get_parent(header); x != root; root = NodeTraits::get_parent(header)) {
|
for (node_ptr root = NodeTraits::get_parent(header); x != root; root = NodeTraits::get_parent(header)) {
|
||||||
const balance x_parent_balance = NodeTraits::get_balance(x_parent);
|
const balance x_parent_balance = NodeTraits::get_balance(x_parent);
|
||||||
|
//Don't cache x_is_leftchild or similar because x can be null and
|
||||||
|
//equal to both x_parent_left and x_parent_right
|
||||||
|
const node_ptr x_parent_left (NodeTraits::get_left(x_parent));
|
||||||
|
const node_ptr x_parent_right(NodeTraits::get_right(x_parent));
|
||||||
|
|
||||||
if(x_parent_balance == NodeTraits::zero()){
|
if(x_parent_balance == NodeTraits::zero()){
|
||||||
NodeTraits::set_balance(x_parent,
|
NodeTraits::set_balance( x_parent, x == x_parent_right ? NodeTraits::negative() : NodeTraits::positive() );
|
||||||
(x == NodeTraits::get_right(x_parent) ? NodeTraits::negative() : NodeTraits::positive()));
|
|
||||||
break; // the height didn't change, let's stop here
|
break; // the height didn't change, let's stop here
|
||||||
}
|
}
|
||||||
else if(x_parent_balance == NodeTraits::negative()){
|
else if(x_parent_balance == NodeTraits::negative()){
|
||||||
if (x == NodeTraits::get_left(x_parent)) {
|
if (x == x_parent_left) { ////x is left child or x and sibling are null
|
||||||
NodeTraits::set_balance(x_parent, NodeTraits::zero()); // balanced
|
NodeTraits::set_balance(x_parent, NodeTraits::zero()); // balanced
|
||||||
x = x_parent;
|
x = x_parent;
|
||||||
x_parent = NodeTraits::get_parent(x_parent);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// x is right child
|
// x is right child (x_parent_left is the left child)
|
||||||
// a is left child
|
BOOST_INTRUSIVE_INVARIANT_ASSERT(x_parent_left);
|
||||||
node_ptr a = NodeTraits::get_left(x_parent);
|
if (NodeTraits::get_balance(x_parent_left) == NodeTraits::positive()) {
|
||||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(a);
|
// x_parent_left MUST have a right child
|
||||||
if (NodeTraits::get_balance(a) == NodeTraits::positive()) {
|
BOOST_INTRUSIVE_INVARIANT_ASSERT(NodeTraits::get_right(x_parent_left));
|
||||||
// a MUST have a right child
|
x = avl_rotate_left_right(x_parent, x_parent_left, header);
|
||||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(NodeTraits::get_right(a));
|
|
||||||
rotate_left_right(x_parent, header);
|
|
||||||
x = NodeTraits::get_parent(x_parent);
|
|
||||||
x_parent = NodeTraits::get_parent(x);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rotate_right(x_parent, header);
|
avl_rotate_right(x_parent, x_parent_left, header);
|
||||||
x = NodeTraits::get_parent(x_parent);
|
x = x_parent_left;
|
||||||
x_parent = NodeTraits::get_parent(x);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if changed from negative to NodeTraits::positive(), no need to check above
|
// if changed from negative to NodeTraits::positive(), no need to check above
|
||||||
@ -400,28 +447,22 @@ class avltree_algorithms
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(x_parent_balance == NodeTraits::positive()){
|
else if(x_parent_balance == NodeTraits::positive()){
|
||||||
if (x == NodeTraits::get_right(x_parent)) {
|
if (x == x_parent_right) { //x is right child or x and sibling are null
|
||||||
NodeTraits::set_balance(x_parent, NodeTraits::zero()); // balanced
|
NodeTraits::set_balance(x_parent, NodeTraits::zero()); // balanced
|
||||||
x = x_parent;
|
x = x_parent;
|
||||||
x_parent = NodeTraits::get_parent(x_parent);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// x is left child
|
// x is left child (x_parent_right is the right child)
|
||||||
// a is right child
|
const node_ptr x_parent_right(NodeTraits::get_right(x_parent));
|
||||||
node_ptr a = NodeTraits::get_right(x_parent);
|
BOOST_INTRUSIVE_INVARIANT_ASSERT(x_parent_right);
|
||||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(a);
|
if (NodeTraits::get_balance(x_parent_right) == NodeTraits::negative()) {
|
||||||
if (NodeTraits::get_balance(a) == NodeTraits::negative()) {
|
// x_parent_right MUST have then a left child
|
||||||
// a MUST have then a left child
|
BOOST_INTRUSIVE_INVARIANT_ASSERT(NodeTraits::get_left(x_parent_right));
|
||||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(NodeTraits::get_left(a));
|
x = avl_rotate_right_left(x_parent, x_parent_right, header);
|
||||||
rotate_right_left(x_parent, header);
|
|
||||||
|
|
||||||
x = NodeTraits::get_parent(x_parent);
|
|
||||||
x_parent = NodeTraits::get_parent(x);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rotate_left(x_parent, header);
|
avl_rotate_left(x_parent, x_parent_right, header);
|
||||||
x = NodeTraits::get_parent(x_parent);
|
x = x_parent_right;
|
||||||
x_parent = NodeTraits::get_parent(x);
|
|
||||||
}
|
}
|
||||||
// if changed from NodeTraits::positive() to negative, no need to check above
|
// if changed from NodeTraits::positive() to negative, no need to check above
|
||||||
if (NodeTraits::get_balance(x) == NodeTraits::negative()){
|
if (NodeTraits::get_balance(x) == NodeTraits::negative()){
|
||||||
@ -432,47 +473,47 @@ class avltree_algorithms
|
|||||||
else{
|
else{
|
||||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(false); // never reached
|
BOOST_INTRUSIVE_INVARIANT_ASSERT(false); // never reached
|
||||||
}
|
}
|
||||||
|
x_parent = NodeTraits::get_parent(x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rebalance_after_insertion(const node_ptr & header, const node_ptr & xnode)
|
static void rebalance_after_insertion(const node_ptr & header, node_ptr x)
|
||||||
{
|
{
|
||||||
node_ptr x(xnode);
|
|
||||||
NodeTraits::set_balance(x, NodeTraits::zero());
|
NodeTraits::set_balance(x, NodeTraits::zero());
|
||||||
// Rebalance.
|
// Rebalance.
|
||||||
for(node_ptr root = NodeTraits::get_parent(header); x != root; root = NodeTraits::get_parent(header)){
|
for(node_ptr root = NodeTraits::get_parent(header); x != root; root = NodeTraits::get_parent(header)){
|
||||||
const balance x_parent_balance = NodeTraits::get_balance(NodeTraits::get_parent(x));
|
node_ptr const x_parent(NodeTraits::get_parent(x));
|
||||||
|
node_ptr const x_parent_left(NodeTraits::get_left(x_parent));
|
||||||
|
const balance x_parent_balance = NodeTraits::get_balance(x_parent);
|
||||||
|
const bool x_is_leftchild(x == x_parent_left);
|
||||||
if(x_parent_balance == NodeTraits::zero()){
|
if(x_parent_balance == NodeTraits::zero()){
|
||||||
// if x is left, parent will have parent->bal_factor = negative
|
// if x is left, parent will have parent->bal_factor = negative
|
||||||
// else, parent->bal_factor = NodeTraits::positive()
|
// else, parent->bal_factor = NodeTraits::positive()
|
||||||
NodeTraits::set_balance( NodeTraits::get_parent(x)
|
NodeTraits::set_balance( x_parent, x_is_leftchild ? NodeTraits::negative() : NodeTraits::positive() );
|
||||||
, x == NodeTraits::get_left(NodeTraits::get_parent(x))
|
x = x_parent;
|
||||||
? NodeTraits::negative() : NodeTraits::positive() );
|
|
||||||
x = NodeTraits::get_parent(x);
|
|
||||||
}
|
}
|
||||||
else if(x_parent_balance == NodeTraits::positive()){
|
else if(x_parent_balance == NodeTraits::positive()){
|
||||||
// if x is a left child, parent->bal_factor = zero
|
// if x is a left child, parent->bal_factor = zero
|
||||||
if (x == NodeTraits::get_left(NodeTraits::get_parent(x)))
|
if (x_is_leftchild)
|
||||||
NodeTraits::set_balance(NodeTraits::get_parent(x), NodeTraits::zero());
|
NodeTraits::set_balance(x_parent, NodeTraits::zero());
|
||||||
else{ // x is a right child, needs rebalancing
|
else{ // x is a right child, needs rebalancing
|
||||||
if (NodeTraits::get_balance(x) == NodeTraits::negative())
|
if (NodeTraits::get_balance(x) == NodeTraits::negative())
|
||||||
rotate_right_left(NodeTraits::get_parent(x), header);
|
avl_rotate_right_left(x_parent, x, header);
|
||||||
else
|
else
|
||||||
rotate_left(NodeTraits::get_parent(x), header);
|
avl_rotate_left(x_parent, x, header);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if(x_parent_balance == NodeTraits::negative()){
|
else if(x_parent_balance == NodeTraits::negative()){
|
||||||
// if x is a left child, needs rebalancing
|
// if x is a left child, needs rebalancing
|
||||||
if (x == NodeTraits::get_left(NodeTraits::get_parent(x))) {
|
if (x_is_leftchild) {
|
||||||
if (NodeTraits::get_balance(x) == NodeTraits::positive())
|
if (NodeTraits::get_balance(x) == NodeTraits::positive())
|
||||||
rotate_left_right(NodeTraits::get_parent(x), header);
|
avl_rotate_left_right(x_parent, x, header);
|
||||||
else
|
else
|
||||||
rotate_right(NodeTraits::get_parent(x), header);
|
avl_rotate_right(x_parent, x, header);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
NodeTraits::set_balance(NodeTraits::get_parent(x), NodeTraits::zero());
|
NodeTraits::set_balance(x_parent, NodeTraits::zero());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
@ -486,26 +527,28 @@ class avltree_algorithms
|
|||||||
// balancing...
|
// balancing...
|
||||||
const balance c_balance = NodeTraits::get_balance(c);
|
const balance c_balance = NodeTraits::get_balance(c);
|
||||||
const balance zero_balance = NodeTraits::zero();
|
const balance zero_balance = NodeTraits::zero();
|
||||||
|
const balance posi_balance = NodeTraits::positive();
|
||||||
|
const balance nega_balance = NodeTraits::negative();
|
||||||
NodeTraits::set_balance(c, zero_balance);
|
NodeTraits::set_balance(c, zero_balance);
|
||||||
if(c_balance == NodeTraits::negative()){
|
if(c_balance == nega_balance){
|
||||||
NodeTraits::set_balance(a, NodeTraits::positive());
|
NodeTraits::set_balance(a, posi_balance);
|
||||||
NodeTraits::set_balance(b, zero_balance);
|
NodeTraits::set_balance(b, zero_balance);
|
||||||
}
|
}
|
||||||
else if(c_balance == zero_balance){
|
else if(c_balance == zero_balance){
|
||||||
NodeTraits::set_balance(a, zero_balance);
|
NodeTraits::set_balance(a, zero_balance);
|
||||||
NodeTraits::set_balance(b, zero_balance);
|
NodeTraits::set_balance(b, zero_balance);
|
||||||
}
|
}
|
||||||
else if(c_balance == NodeTraits::positive()){
|
else if(c_balance == posi_balance){
|
||||||
NodeTraits::set_balance(a, zero_balance);
|
NodeTraits::set_balance(a, zero_balance);
|
||||||
NodeTraits::set_balance(b, NodeTraits::negative());
|
NodeTraits::set_balance(b, nega_balance);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(false); // never reached
|
BOOST_INTRUSIVE_INVARIANT_ASSERT(false); // never reached
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rotate_left_right(const node_ptr a, const node_ptr & hdr)
|
static node_ptr avl_rotate_left_right(const node_ptr a, const node_ptr a_oldleft, const node_ptr & hdr)
|
||||||
{
|
{ // [note: 'a_oldleft' is 'b']
|
||||||
// | | //
|
// | | //
|
||||||
// a(-2) c //
|
// a(-2) c //
|
||||||
// / \ / \ //
|
// / \ / \ //
|
||||||
@ -513,16 +556,19 @@ class avltree_algorithms
|
|||||||
// (pos)b [g] b a //
|
// (pos)b [g] b a //
|
||||||
// / \ / \ / \ //
|
// / \ / \ / \ //
|
||||||
// [d] c [d] e f [g] //
|
// [d] c [d] e f [g] //
|
||||||
// / \ //
|
// / \ //
|
||||||
// e f //
|
// e f //
|
||||||
node_ptr b = NodeTraits::get_left(a), c = NodeTraits::get_right(b);
|
const node_ptr c = NodeTraits::get_right(a_oldleft);
|
||||||
bstree_algo::rotate_left(b, hdr);
|
bstree_algo::rotate_left_no_parent_fix(a_oldleft, c);
|
||||||
bstree_algo::rotate_right(a, hdr);
|
//No need to link c with a [NodeTraits::set_parent(c, a) + NodeTraits::set_left(a, c)]
|
||||||
left_right_balancing(a, b, c);
|
//as c is not root and another rotation is coming
|
||||||
|
bstree_algo::rotate_right(a, c, NodeTraits::get_parent(a), hdr);
|
||||||
|
left_right_balancing(a, a_oldleft, c);
|
||||||
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rotate_right_left(const node_ptr a, const node_ptr & hdr)
|
static node_ptr avl_rotate_right_left(const node_ptr a, const node_ptr a_oldright, const node_ptr & hdr)
|
||||||
{
|
{ // [note: 'a_oldright' is 'b']
|
||||||
// | | //
|
// | | //
|
||||||
// a(pos) c //
|
// a(pos) c //
|
||||||
// / \ / \ //
|
// / \ / \ //
|
||||||
@ -532,41 +578,42 @@ class avltree_algorithms
|
|||||||
// c [g] [d] e f [g] //
|
// c [g] [d] e f [g] //
|
||||||
// / \ //
|
// / \ //
|
||||||
// e f //
|
// e f //
|
||||||
node_ptr b = NodeTraits::get_right(a), c = NodeTraits::get_left(b);
|
const node_ptr c (NodeTraits::get_left(a_oldright));
|
||||||
bstree_algo::rotate_right(b, hdr);
|
bstree_algo::rotate_right_no_parent_fix(a_oldright, c);
|
||||||
bstree_algo::rotate_left(a, hdr);
|
//No need to link c with a [NodeTraits::set_parent(c, a) + NodeTraits::set_right(a, c)]
|
||||||
left_right_balancing(b, a, c);
|
//as c is not root and another rotation is coming.
|
||||||
|
bstree_algo::rotate_left(a, c, NodeTraits::get_parent(a), hdr);
|
||||||
|
left_right_balancing(a_oldright, a, c);
|
||||||
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rotate_left(const node_ptr x, const node_ptr & hdr)
|
static void avl_rotate_left(const node_ptr &x, const node_ptr &x_oldright, const node_ptr & hdr)
|
||||||
{
|
{
|
||||||
const node_ptr y = NodeTraits::get_right(x);
|
bstree_algo::rotate_left(x, x_oldright, NodeTraits::get_parent(x), hdr);
|
||||||
bstree_algo::rotate_left(x, hdr);
|
|
||||||
|
|
||||||
// reset the balancing factor
|
// reset the balancing factor
|
||||||
if (NodeTraits::get_balance(y) == NodeTraits::positive()) {
|
if (NodeTraits::get_balance(x_oldright) == NodeTraits::positive()) {
|
||||||
NodeTraits::set_balance(x, NodeTraits::zero());
|
NodeTraits::set_balance(x, NodeTraits::zero());
|
||||||
NodeTraits::set_balance(y, NodeTraits::zero());
|
NodeTraits::set_balance(x_oldright, NodeTraits::zero());
|
||||||
}
|
}
|
||||||
else { // this doesn't happen during insertions
|
else { // this doesn't happen during insertions
|
||||||
NodeTraits::set_balance(x, NodeTraits::positive());
|
NodeTraits::set_balance(x, NodeTraits::positive());
|
||||||
NodeTraits::set_balance(y, NodeTraits::negative());
|
NodeTraits::set_balance(x_oldright, NodeTraits::negative());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rotate_right(const node_ptr x, const node_ptr & hdr)
|
static void avl_rotate_right(const node_ptr &x, const node_ptr &x_oldleft, const node_ptr & hdr)
|
||||||
{
|
{
|
||||||
const node_ptr y = NodeTraits::get_left(x);
|
bstree_algo::rotate_right(x, x_oldleft, NodeTraits::get_parent(x), hdr);
|
||||||
bstree_algo::rotate_right(x, hdr);
|
|
||||||
|
|
||||||
// reset the balancing factor
|
// reset the balancing factor
|
||||||
if (NodeTraits::get_balance(y) == NodeTraits::negative()) {
|
if (NodeTraits::get_balance(x_oldleft) == NodeTraits::negative()) {
|
||||||
NodeTraits::set_balance(x, NodeTraits::zero());
|
NodeTraits::set_balance(x, NodeTraits::zero());
|
||||||
NodeTraits::set_balance(y, NodeTraits::zero());
|
NodeTraits::set_balance(x_oldleft, NodeTraits::zero());
|
||||||
}
|
}
|
||||||
else { // this doesn't happen during insertions
|
else { // this doesn't happen during insertions
|
||||||
NodeTraits::set_balance(x, NodeTraits::negative());
|
NodeTraits::set_balance(x, NodeTraits::negative());
|
||||||
NodeTraits::set_balance(y, NodeTraits::positive());
|
NodeTraits::set_balance(x_oldleft, NodeTraits::positive());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,13 +247,19 @@ class bs_set_impl
|
|||||||
template<class Disposer>
|
template<class Disposer>
|
||||||
void clear_and_dispose(Disposer disposer);
|
void clear_and_dispose(Disposer disposer);
|
||||||
|
|
||||||
|
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::count(const_reference)const
|
//! @copydoc ::boost::intrusive::bstree::count(const_reference)const
|
||||||
size_type count(const_reference value) const;
|
size_type count(const_reference value) const
|
||||||
|
{ return static_cast<size_type>(this->tree_type::find(value) == this->tree_type::cend()); }
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const
|
//! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const
|
||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
size_type count(const KeyType& key, KeyValueCompare comp) const;
|
size_type count(const KeyType& key, KeyValueCompare comp) const
|
||||||
|
{ return static_cast<size_type>(this->tree_type::find(key, comp) == this->tree_type::cend()); }
|
||||||
|
|
||||||
|
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)
|
//! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)
|
||||||
iterator lower_bound(const_reference value);
|
iterator lower_bound(const_reference value);
|
||||||
|
|
||||||
@ -296,21 +302,29 @@ class bs_set_impl
|
|||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
const_iterator find(const KeyType& key, KeyValueCompare comp) const;
|
const_iterator find(const KeyType& key, KeyValueCompare comp) const;
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)
|
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
std::pair<iterator,iterator> equal_range(const_reference value);
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)
|
//! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)
|
||||||
|
std::pair<iterator,iterator> equal_range(const_reference value)
|
||||||
|
{ return this->tree_type::lower_bound_range(value); }
|
||||||
|
|
||||||
|
//! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)
|
||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
|
std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp)
|
||||||
|
{ return this->tree_type::lower_bound_range(key, comp); }
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)const
|
//! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)const
|
||||||
std::pair<const_iterator, const_iterator>
|
std::pair<const_iterator, const_iterator>
|
||||||
equal_range(const_reference value) const;
|
equal_range(const_reference value) const
|
||||||
|
{ return this->tree_type::lower_bound_range(value); }
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)const
|
//! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)const
|
||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
std::pair<const_iterator, const_iterator>
|
std::pair<const_iterator, const_iterator>
|
||||||
equal_range(const KeyType& key, KeyValueCompare comp) const;
|
equal_range(const KeyType& key, KeyValueCompare comp) const
|
||||||
|
{ return this->tree_type::lower_bound_range(key, comp); }
|
||||||
|
|
||||||
|
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)
|
//! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)
|
||||||
std::pair<iterator,iterator> bounded_range
|
std::pair<iterator,iterator> bounded_range
|
||||||
|
@ -73,7 +73,7 @@ struct make_bs_set_base_hook
|
|||||||
//! unique tag.
|
//! unique tag.
|
||||||
//!
|
//!
|
||||||
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
||||||
//! and the the container configured to use this hook.
|
//! and the container configured to use this hook.
|
||||||
//!
|
//!
|
||||||
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
|
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
|
||||||
//! \c auto_unlink or \c safe_link).
|
//! \c auto_unlink or \c safe_link).
|
||||||
@ -196,7 +196,7 @@ struct make_bs_set_member_hook
|
|||||||
//! The hook admits the following options: \c void_pointer<>, \c link_mode<>.
|
//! The hook admits the following options: \c void_pointer<>, \c link_mode<>.
|
||||||
//!
|
//!
|
||||||
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
||||||
//! and the the container configured to use this hook.
|
//! and the container configured to use this hook.
|
||||||
//!
|
//!
|
||||||
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
|
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
|
||||||
//! \c auto_unlink or \c safe_link).
|
//! \c auto_unlink or \c safe_link).
|
||||||
|
@ -14,8 +14,8 @@
|
|||||||
#define BOOST_INTRUSIVE_BSTREE_ALGORITHMS_HPP
|
#define BOOST_INTRUSIVE_BSTREE_ALGORITHMS_HPP
|
||||||
|
|
||||||
#include <boost/intrusive/detail/config_begin.hpp>
|
#include <boost/intrusive/detail/config_begin.hpp>
|
||||||
#include <boost/intrusive/detail/assert.hpp>
|
|
||||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||||
|
#include <boost/intrusive/detail/assert.hpp>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <boost/intrusive/detail/utilities.hpp>
|
#include <boost/intrusive/detail/utilities.hpp>
|
||||||
#include <boost/intrusive/pointer_traits.hpp>
|
#include <boost/intrusive/pointer_traits.hpp>
|
||||||
@ -173,7 +173,20 @@ class bstree_algorithms
|
|||||||
static node_ptr end_node(const const_node_ptr & header)
|
static node_ptr end_node(const const_node_ptr & header)
|
||||||
{ return detail::uncast(header); }
|
{ return detail::uncast(header); }
|
||||||
|
|
||||||
//! <b>Requires</b>: 'node' is a node of the tree or an node initialized
|
//! <b>Requires</b>: 'header' is the header node of a tree.
|
||||||
|
//!
|
||||||
|
//! <b>Effects</b>: Returns the root of the tree if any, header otherwise
|
||||||
|
//!
|
||||||
|
//! <b>Complexity</b>: Constant time.
|
||||||
|
//!
|
||||||
|
//! <b>Throws</b>: Nothing.
|
||||||
|
static node_ptr root_node(const const_node_ptr & header)
|
||||||
|
{
|
||||||
|
node_ptr p = node_traits::get_parent(header);
|
||||||
|
return p ? p : detail::uncast(header);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! <b>Requires</b>: 'node' is a node of the tree or a node initialized
|
||||||
//! by init(...) or init_node.
|
//! by init(...) or init_node.
|
||||||
//!
|
//!
|
||||||
//! <b>Effects</b>: Returns true if the node is initialized by init() or init_node().
|
//! <b>Effects</b>: Returns true if the node is initialized by init() or init_node().
|
||||||
@ -487,18 +500,18 @@ class bstree_algorithms
|
|||||||
//! <b>Throws</b>: Nothing.
|
//! <b>Throws</b>: Nothing.
|
||||||
static node_ptr next_node(const node_ptr & node)
|
static node_ptr next_node(const node_ptr & node)
|
||||||
{
|
{
|
||||||
node_ptr p_right(NodeTraits::get_right(node));
|
node_ptr const n_right(NodeTraits::get_right(node));
|
||||||
if(p_right){
|
if(n_right){
|
||||||
return minimum(p_right);
|
return minimum(n_right);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
node_ptr p(node);
|
node_ptr n(node);
|
||||||
node_ptr x = NodeTraits::get_parent(p);
|
node_ptr p(NodeTraits::get_parent(n));
|
||||||
while(p == NodeTraits::get_right(x)){
|
while(n == NodeTraits::get_right(p)){
|
||||||
p = x;
|
n = p;
|
||||||
x = NodeTraits::get_parent(x);
|
p = NodeTraits::get_parent(p);
|
||||||
}
|
}
|
||||||
return NodeTraits::get_right(p) != x ? x : detail::uncast(p);
|
return NodeTraits::get_right(n) != p ? p : n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -536,7 +549,7 @@ class bstree_algorithms
|
|||||||
//! <b>Complexity</b>: Logarithmic to the size of the subtree.
|
//! <b>Complexity</b>: Logarithmic to the size of the subtree.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: Nothing.
|
//! <b>Throws</b>: Nothing.
|
||||||
static node_ptr minimum (node_ptr node)
|
static node_ptr minimum(node_ptr node)
|
||||||
{
|
{
|
||||||
for(node_ptr p_left = NodeTraits::get_left(node)
|
for(node_ptr p_left = NodeTraits::get_left(node)
|
||||||
;p_left
|
;p_left
|
||||||
@ -766,7 +779,7 @@ class bstree_algorithms
|
|||||||
//! ordering compatible with the strict weak ordering used to create the
|
//! ordering compatible with the strict weak ordering used to create the
|
||||||
//! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs.
|
//! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs.
|
||||||
//!
|
//!
|
||||||
//! <b>Effects</b>: Returns an node_ptr to the element that is equivalent to
|
//! <b>Effects</b>: Returns a node_ptr to the first element that is equivalent to
|
||||||
//! "key" according to "comp" or "header" if that element does not exist.
|
//! "key" according to "comp" or "header" if that element does not exist.
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Logarithmic.
|
//! <b>Complexity</b>: Logarithmic.
|
||||||
@ -825,7 +838,6 @@ class bstree_algorithms
|
|||||||
//If the upper_key is less than x, the target
|
//If the upper_key is less than x, the target
|
||||||
//range is on the left part
|
//range is on the left part
|
||||||
else if(comp(upper_key, x)){
|
else if(comp(upper_key, x)){
|
||||||
//y > upper_key
|
|
||||||
y = x;
|
y = x;
|
||||||
x = NodeTraits::get_left(x);
|
x = NodeTraits::get_left(x);
|
||||||
}
|
}
|
||||||
@ -864,7 +876,7 @@ class bstree_algorithms
|
|||||||
//! ordering compatible with the strict weak ordering used to create the
|
//! ordering compatible with the strict weak ordering used to create the
|
||||||
//! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs.
|
//! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs.
|
||||||
//!
|
//!
|
||||||
//! <b>Effects</b>: Returns the number of elements with a key equivalent to "key"pair of node_ptr delimiting a range containing
|
//! <b>Effects</b>: Returns the number of elements with a key equivalent to "key"
|
||||||
//! according to "comp".
|
//! according to "comp".
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Logarithmic.
|
//! <b>Complexity</b>: Logarithmic.
|
||||||
@ -908,7 +920,32 @@ class bstree_algorithms
|
|||||||
//! ordering compatible with the strict weak ordering used to create the
|
//! ordering compatible with the strict weak ordering used to create the
|
||||||
//! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs.
|
//! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs.
|
||||||
//!
|
//!
|
||||||
//! <b>Effects</b>: Returns an node_ptr to the first element that is
|
//! <b>Effects</b>: Returns an a pair of node_ptr delimiting a range containing
|
||||||
|
//! the first element that is equivalent to "key" according to "comp" or an
|
||||||
|
//! empty range that indicates the position where that element would be
|
||||||
|
//! if there are no equivalent elements.
|
||||||
|
//!
|
||||||
|
//! <b>Complexity</b>: Logarithmic.
|
||||||
|
//!
|
||||||
|
//! <b>Throws</b>: If "comp" throws.
|
||||||
|
template<class KeyType, class KeyNodePtrCompare>
|
||||||
|
static std::pair<node_ptr, node_ptr> lower_bound_range
|
||||||
|
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
||||||
|
{
|
||||||
|
node_ptr const lb(lower_bound(header, key, comp));
|
||||||
|
std::pair<node_ptr, node_ptr> ret_ii(lb, lb);
|
||||||
|
if(lb != header && !comp(key, lb)){
|
||||||
|
ret_ii.second = next_node(ret_ii.second);
|
||||||
|
}
|
||||||
|
return ret_ii;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! <b>Requires</b>: "header" must be the header node of a tree.
|
||||||
|
//! KeyNodePtrCompare is a function object that induces a strict weak
|
||||||
|
//! ordering compatible with the strict weak ordering used to create the
|
||||||
|
//! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs.
|
||||||
|
//!
|
||||||
|
//! <b>Effects</b>: Returns a node_ptr to the first element that is
|
||||||
//! not less than "key" according to "comp" or "header" if that element does
|
//! not less than "key" according to "comp" or "header" if that element does
|
||||||
//! not exist.
|
//! not exist.
|
||||||
//!
|
//!
|
||||||
@ -927,7 +964,7 @@ class bstree_algorithms
|
|||||||
//! ordering compatible with the strict weak ordering used to create the
|
//! ordering compatible with the strict weak ordering used to create the
|
||||||
//! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs.
|
//! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs.
|
||||||
//!
|
//!
|
||||||
//! <b>Effects</b>: Returns an node_ptr to the first element that is greater
|
//! <b>Effects</b>: Returns a node_ptr to the first element that is greater
|
||||||
//! than "key" according to "comp" or "header" if that element does not exist.
|
//! than "key" according to "comp" or "header" if that element does not exist.
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Logarithmic.
|
//! <b>Complexity</b>: Logarithmic.
|
||||||
@ -1025,16 +1062,12 @@ class bstree_algorithms
|
|||||||
//Since we've found the upper bound there is no other value with the same key if:
|
//Since we've found the upper bound there is no other value with the same key if:
|
||||||
// - There is no previous node
|
// - There is no previous node
|
||||||
// - The previous node is less than the key
|
// - The previous node is less than the key
|
||||||
if(!prev || comp(prev, key)){
|
const bool not_present = !prev || comp(prev, key);
|
||||||
|
if(not_present){
|
||||||
commit_data.link_left = left_child;
|
commit_data.link_left = left_child;
|
||||||
commit_data.node = y;
|
commit_data.node = y;
|
||||||
return std::pair<node_ptr, bool>(node_ptr(), true);
|
|
||||||
}
|
|
||||||
//If the previous value was not less than key, it means that it's equal
|
|
||||||
//(because we've checked the upper bound)
|
|
||||||
else{
|
|
||||||
return std::pair<node_ptr, bool>(prev, false);
|
|
||||||
}
|
}
|
||||||
|
return std::pair<node_ptr, bool>(prev, not_present);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! <b>Requires</b>: "header" must be the header node of a tree.
|
//! <b>Requires</b>: "header" must be the header node of a tree.
|
||||||
@ -1325,7 +1358,7 @@ class bstree_algorithms
|
|||||||
static void erase(const node_ptr & header, const node_ptr & z)
|
static void erase(const node_ptr & header, const node_ptr & z)
|
||||||
{
|
{
|
||||||
data_for_rebalance ignored;
|
data_for_rebalance ignored;
|
||||||
erase_impl(header, z, ignored);
|
erase(header, z, ignored);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! <b>Requires</b>: node is a tree node but not the header.
|
//! <b>Requires</b>: node is a tree node but not the header.
|
||||||
@ -1410,6 +1443,88 @@ class bstree_algorithms
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
static void erase(const node_ptr & header, const node_ptr & z, data_for_rebalance &info)
|
||||||
|
{
|
||||||
|
node_ptr y(z);
|
||||||
|
node_ptr x;
|
||||||
|
const node_ptr z_left(NodeTraits::get_left(z));
|
||||||
|
const node_ptr z_right(NodeTraits::get_right(z));
|
||||||
|
|
||||||
|
if(!z_left){
|
||||||
|
x = z_right; // x might be null.
|
||||||
|
}
|
||||||
|
else if(!z_right){ // z has exactly one non-null child. y == z.
|
||||||
|
x = z_left; // x is not null.
|
||||||
|
BOOST_ASSERT(x);
|
||||||
|
}
|
||||||
|
else{ //make y != z
|
||||||
|
// y = find z's successor
|
||||||
|
y = bstree_algorithms::minimum(z_right);
|
||||||
|
x = NodeTraits::get_right(y); // x might be null.
|
||||||
|
}
|
||||||
|
|
||||||
|
node_ptr x_parent;
|
||||||
|
const node_ptr z_parent(NodeTraits::get_parent(z));
|
||||||
|
const bool z_is_leftchild(NodeTraits::get_left(z_parent) == z);
|
||||||
|
|
||||||
|
if(y != z){ //has two children and y is the minimum of z
|
||||||
|
//y is z's successor and it has a null left child.
|
||||||
|
//x is the right child of y (it can be null)
|
||||||
|
//Relink y in place of z and link x with y's old parent
|
||||||
|
NodeTraits::set_parent(z_left, y);
|
||||||
|
NodeTraits::set_left(y, z_left);
|
||||||
|
if(y != z_right){
|
||||||
|
//Link y with the right tree of z
|
||||||
|
NodeTraits::set_right(y, z_right);
|
||||||
|
NodeTraits::set_parent(z_right, y);
|
||||||
|
//Link x with y's old parent (y must be a left child)
|
||||||
|
x_parent = NodeTraits::get_parent(y);
|
||||||
|
BOOST_ASSERT(NodeTraits::get_left(x_parent) == y);
|
||||||
|
if(x)
|
||||||
|
NodeTraits::set_parent(x, x_parent);
|
||||||
|
//Since y was the successor and not the right child of z, it must be a left child
|
||||||
|
NodeTraits::set_left(x_parent, x);
|
||||||
|
}
|
||||||
|
else{ //y was the right child of y so no need to fix x's position
|
||||||
|
x_parent = y;
|
||||||
|
}
|
||||||
|
NodeTraits::set_parent(y, z_parent);
|
||||||
|
bstree_algorithms::set_child(header, y, z_parent, z_is_leftchild);
|
||||||
|
}
|
||||||
|
else { // z has zero or one child, x is one child (it can be null)
|
||||||
|
//Just link x to z's parent
|
||||||
|
x_parent = z_parent;
|
||||||
|
if(x)
|
||||||
|
NodeTraits::set_parent(x, z_parent);
|
||||||
|
bstree_algorithms::set_child(header, x, z_parent, z_is_leftchild);
|
||||||
|
|
||||||
|
//Now update leftmost/rightmost in case z was one of them
|
||||||
|
if(NodeTraits::get_left(header) == z){
|
||||||
|
//z_left must be null because z is the leftmost
|
||||||
|
BOOST_ASSERT(!z_left);
|
||||||
|
NodeTraits::set_left(header, !z_right ?
|
||||||
|
z_parent : // makes leftmost == header if z == root
|
||||||
|
bstree_algorithms::minimum(z_right));
|
||||||
|
}
|
||||||
|
if(NodeTraits::get_right(header) == z){
|
||||||
|
//z_right must be null because z is the rightmost
|
||||||
|
BOOST_ASSERT(!z_right);
|
||||||
|
NodeTraits::set_right(header, !z_left ?
|
||||||
|
z_parent : // makes rightmost == header if z == root
|
||||||
|
bstree_algorithms::maximum(z_left));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//If z had 0/1 child, y == z and one of its children (and maybe null)
|
||||||
|
//If z had 2 children, y is the successor of z and x is the right child of y
|
||||||
|
info.x = x;
|
||||||
|
info.y = y;
|
||||||
|
//If z had 0/1 child, x_parent is the new parent of the old right child of y (z's successor)
|
||||||
|
//If z had 2 children, x_parent is the new parent of y (z_parent)
|
||||||
|
BOOST_ASSERT(!x || NodeTraits::get_parent(x) == x_parent);
|
||||||
|
info.x_parent = x_parent;
|
||||||
|
}
|
||||||
|
|
||||||
//! <b>Requires</b>: node is a node of the tree but it's not the header.
|
//! <b>Requires</b>: node is a node of the tree but it's not the header.
|
||||||
//!
|
//!
|
||||||
//! <b>Effects</b>: Returns the number of nodes of the subtree.
|
//! <b>Effects</b>: Returns the number of nodes of the subtree.
|
||||||
@ -1473,83 +1588,6 @@ class bstree_algorithms
|
|||||||
static bool is_right_child(const node_ptr & p)
|
static bool is_right_child(const node_ptr & p)
|
||||||
{ return NodeTraits::get_right(NodeTraits::get_parent(p)) == p; }
|
{ return NodeTraits::get_right(NodeTraits::get_parent(p)) == p; }
|
||||||
|
|
||||||
template<class F>
|
|
||||||
static void erase(const node_ptr & header, const node_ptr & z, F z_and_successor_fixup, data_for_rebalance &info)
|
|
||||||
{
|
|
||||||
erase_impl(header, z, info);
|
|
||||||
if(info.y != z){
|
|
||||||
z_and_successor_fixup(z, info.y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Fix header and own's parent data when replacing x with own, providing own's old data with parent
|
|
||||||
static void replace_own_impl(const node_ptr & own, const node_ptr & x, const node_ptr & header, const node_ptr & own_parent, bool own_was_left)
|
|
||||||
{
|
|
||||||
if(NodeTraits::get_parent(header) == own)
|
|
||||||
NodeTraits::set_parent(header, x);
|
|
||||||
else if(own_was_left)
|
|
||||||
NodeTraits::set_left(own_parent, x);
|
|
||||||
else
|
|
||||||
NodeTraits::set_right(own_parent, x);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Fix header and own's parent data when replacing x with own, supposing own
|
|
||||||
//links with its parent are still ok
|
|
||||||
static void replace_own(const node_ptr & own, const node_ptr & x, const node_ptr & header)
|
|
||||||
{
|
|
||||||
node_ptr own_parent(NodeTraits::get_parent(own));
|
|
||||||
bool own_is_left(NodeTraits::get_left(own_parent) == own);
|
|
||||||
replace_own_impl(own, x, header, own_parent, own_is_left);
|
|
||||||
}
|
|
||||||
|
|
||||||
// rotate parent p to left (no header and p's parent fixup)
|
|
||||||
static node_ptr rotate_left(const node_ptr & p)
|
|
||||||
{
|
|
||||||
node_ptr x(NodeTraits::get_right(p));
|
|
||||||
node_ptr x_left(NodeTraits::get_left(x));
|
|
||||||
NodeTraits::set_right(p, x_left);
|
|
||||||
if(x_left){
|
|
||||||
NodeTraits::set_parent(x_left, p);
|
|
||||||
}
|
|
||||||
NodeTraits::set_left(x, p);
|
|
||||||
NodeTraits::set_parent(p, x);
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
// rotate parent p to left (with header and p's parent fixup)
|
|
||||||
static void rotate_left(const node_ptr & p, const node_ptr & header)
|
|
||||||
{
|
|
||||||
bool p_was_left(is_left_child(p));
|
|
||||||
node_ptr p_old_parent(NodeTraits::get_parent(p));
|
|
||||||
node_ptr x(rotate_left(p));
|
|
||||||
NodeTraits::set_parent(x, p_old_parent);
|
|
||||||
replace_own_impl(p, x, header, p_old_parent, p_was_left);
|
|
||||||
}
|
|
||||||
|
|
||||||
// rotate parent p to right (no header and p's parent fixup)
|
|
||||||
static node_ptr rotate_right(const node_ptr & p)
|
|
||||||
{
|
|
||||||
node_ptr x(NodeTraits::get_left(p));
|
|
||||||
node_ptr x_right(NodeTraits::get_right(x));
|
|
||||||
NodeTraits::set_left(p, x_right);
|
|
||||||
if(x_right){
|
|
||||||
NodeTraits::set_parent(x_right, p);
|
|
||||||
}
|
|
||||||
NodeTraits::set_right(x, p);
|
|
||||||
NodeTraits::set_parent(p, x);
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
// rotate parent p to right (with header and p's parent fixup)
|
|
||||||
static void rotate_right(const node_ptr & p, const node_ptr & header)
|
|
||||||
{
|
|
||||||
bool p_was_left(is_left_child(p));
|
|
||||||
node_ptr p_old_parent(NodeTraits::get_parent(p));
|
|
||||||
node_ptr x(rotate_right(p));
|
|
||||||
NodeTraits::set_parent(x, p_old_parent);
|
|
||||||
replace_own_impl(p, x, header, p_old_parent, p_was_left);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void insert_before_check
|
static void insert_before_check
|
||||||
(const node_ptr &header, const node_ptr & pos
|
(const node_ptr &header, const node_ptr & pos
|
||||||
, insert_commit_data &commit_data
|
, insert_commit_data &commit_data
|
||||||
@ -1631,12 +1669,40 @@ class bstree_algorithms
|
|||||||
template<class NodePtrCompare>
|
template<class NodePtrCompare>
|
||||||
static void insert_equal_upper_bound_check
|
static void insert_equal_upper_bound_check
|
||||||
(const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp, insert_commit_data & commit_data, std::size_t *pdepth = 0)
|
(const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp, insert_commit_data & commit_data, std::size_t *pdepth = 0)
|
||||||
{ insert_equal_check_impl(true, h, new_node, comp, commit_data, pdepth); }
|
{
|
||||||
|
std::size_t depth = 0;
|
||||||
|
node_ptr y(h);
|
||||||
|
node_ptr x(NodeTraits::get_parent(y));
|
||||||
|
|
||||||
|
while(x){
|
||||||
|
++depth;
|
||||||
|
y = x;
|
||||||
|
x = comp(new_node, x) ?
|
||||||
|
NodeTraits::get_left(x) : NodeTraits::get_right(x);
|
||||||
|
}
|
||||||
|
if(pdepth) *pdepth = depth;
|
||||||
|
commit_data.link_left = (y == h) || comp(new_node, y);
|
||||||
|
commit_data.node = y;
|
||||||
|
}
|
||||||
|
|
||||||
template<class NodePtrCompare>
|
template<class NodePtrCompare>
|
||||||
static void insert_equal_lower_bound_check
|
static void insert_equal_lower_bound_check
|
||||||
(const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp, insert_commit_data & commit_data, std::size_t *pdepth = 0)
|
(const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp, insert_commit_data & commit_data, std::size_t *pdepth = 0)
|
||||||
{ insert_equal_check_impl(false, h, new_node, comp, commit_data, pdepth); }
|
{
|
||||||
|
std::size_t depth = 0;
|
||||||
|
node_ptr y(h);
|
||||||
|
node_ptr x(NodeTraits::get_parent(y));
|
||||||
|
|
||||||
|
while(x){
|
||||||
|
++depth;
|
||||||
|
y = x;
|
||||||
|
x = !comp(x, new_node) ?
|
||||||
|
NodeTraits::get_left(x) : NodeTraits::get_right(x);
|
||||||
|
}
|
||||||
|
if(pdepth) *pdepth = depth;
|
||||||
|
commit_data.link_left = (y == h) || !comp(y, new_node);
|
||||||
|
commit_data.node = y;
|
||||||
|
}
|
||||||
|
|
||||||
static void insert_commit
|
static void insert_commit
|
||||||
(const node_ptr & header, const node_ptr & new_node, const insert_commit_data &commit_data)
|
(const node_ptr & header, const node_ptr & new_node, const insert_commit_data &commit_data)
|
||||||
@ -1664,7 +1730,61 @@ class bstree_algorithms
|
|||||||
NodeTraits::set_left(new_node, node_ptr());
|
NodeTraits::set_left(new_node, node_ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Fix header and own's parent data when replacing x with own, providing own's old data with parent
|
||||||
|
static void set_child(const node_ptr & header, const node_ptr & new_child, const node_ptr & new_parent, const bool link_left)
|
||||||
|
{
|
||||||
|
if(new_parent == header)
|
||||||
|
NodeTraits::set_parent(header, new_child);
|
||||||
|
else if(link_left)
|
||||||
|
NodeTraits::set_left(new_parent, new_child);
|
||||||
|
else
|
||||||
|
NodeTraits::set_right(new_parent, new_child);
|
||||||
|
}
|
||||||
|
|
||||||
|
// rotate p to left (no header and p's parent fixup)
|
||||||
|
static void rotate_left_no_parent_fix(const node_ptr & p, const node_ptr &p_right)
|
||||||
|
{
|
||||||
|
node_ptr p_right_left(NodeTraits::get_left(p_right));
|
||||||
|
NodeTraits::set_right(p, p_right_left);
|
||||||
|
if(p_right_left){
|
||||||
|
NodeTraits::set_parent(p_right_left, p);
|
||||||
|
}
|
||||||
|
NodeTraits::set_left(p_right, p);
|
||||||
|
NodeTraits::set_parent(p, p_right);
|
||||||
|
}
|
||||||
|
|
||||||
|
// rotate p to left (with header and p's parent fixup)
|
||||||
|
static void rotate_left(const node_ptr & p, const node_ptr & p_right, const node_ptr & p_parent, const node_ptr & header)
|
||||||
|
{
|
||||||
|
const bool p_was_left(NodeTraits::get_left(p_parent) == p);
|
||||||
|
rotate_left_no_parent_fix(p, p_right);
|
||||||
|
NodeTraits::set_parent(p_right, p_parent);
|
||||||
|
set_child(header, p_right, p_parent, p_was_left);
|
||||||
|
}
|
||||||
|
|
||||||
|
// rotate p to right (no header and p's parent fixup)
|
||||||
|
static void rotate_right_no_parent_fix(const node_ptr & p, const node_ptr &p_left)
|
||||||
|
{
|
||||||
|
node_ptr p_left_right(NodeTraits::get_right(p_left));
|
||||||
|
NodeTraits::set_left(p, p_left_right);
|
||||||
|
if(p_left_right){
|
||||||
|
NodeTraits::set_parent(p_left_right, p);
|
||||||
|
}
|
||||||
|
NodeTraits::set_right(p_left, p);
|
||||||
|
NodeTraits::set_parent(p, p_left);
|
||||||
|
}
|
||||||
|
|
||||||
|
// rotate p to right (with header and p's parent fixup)
|
||||||
|
static void rotate_right(const node_ptr & p, const node_ptr & p_left, const node_ptr & p_parent, const node_ptr & header)
|
||||||
|
{
|
||||||
|
const bool p_was_left(NodeTraits::get_left(p_parent) == p);
|
||||||
|
rotate_right_no_parent_fix(p, p_left);
|
||||||
|
NodeTraits::set_parent(p_left, p_parent);
|
||||||
|
set_child(header, p_left, p_parent, p_was_left);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static void subtree_to_vine(node_ptr vine_tail, std::size_t &size)
|
static void subtree_to_vine(node_ptr vine_tail, std::size_t &size)
|
||||||
{
|
{
|
||||||
//Inspired by LibAVL:
|
//Inspired by LibAVL:
|
||||||
@ -1877,98 +1997,6 @@ class bstree_algorithms
|
|||||||
}
|
}
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class NodePtrCompare>
|
|
||||||
static void insert_equal_check_impl
|
|
||||||
(bool upper, const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp, insert_commit_data & commit_data, std::size_t *pdepth = 0)
|
|
||||||
{
|
|
||||||
std::size_t depth = 0;
|
|
||||||
node_ptr y(h);
|
|
||||||
node_ptr x(NodeTraits::get_parent(y));
|
|
||||||
bool link_left;
|
|
||||||
|
|
||||||
if(upper){
|
|
||||||
while(x){
|
|
||||||
++depth;
|
|
||||||
y = x;
|
|
||||||
x = comp(new_node, x) ?
|
|
||||||
NodeTraits::get_left(x) : NodeTraits::get_right(x);
|
|
||||||
}
|
|
||||||
link_left = (y == h) || comp(new_node, y);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
while(x){
|
|
||||||
++depth;
|
|
||||||
y = x;
|
|
||||||
x = !comp(x, new_node) ?
|
|
||||||
NodeTraits::get_left(x) : NodeTraits::get_right(x);
|
|
||||||
}
|
|
||||||
link_left = (y == h) || !comp(y, new_node);
|
|
||||||
}
|
|
||||||
|
|
||||||
commit_data.link_left = link_left;
|
|
||||||
commit_data.node = y;
|
|
||||||
if(pdepth) *pdepth = depth;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void erase_impl(const node_ptr & header, const node_ptr & z, data_for_rebalance &info)
|
|
||||||
{
|
|
||||||
node_ptr y(z);
|
|
||||||
node_ptr x;
|
|
||||||
node_ptr x_parent = node_ptr();
|
|
||||||
node_ptr z_left(NodeTraits::get_left(z));
|
|
||||||
node_ptr z_right(NodeTraits::get_right(z));
|
|
||||||
if(!z_left){
|
|
||||||
x = z_right; // x might be null.
|
|
||||||
}
|
|
||||||
else if(!z_right){ // z has exactly one non-null child. y == z.
|
|
||||||
x = z_left; // x is not null.
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
// find z's successor
|
|
||||||
y = bstree_algorithms::minimum (z_right);
|
|
||||||
x = NodeTraits::get_right(y); // x might be null.
|
|
||||||
}
|
|
||||||
|
|
||||||
if(y != z){
|
|
||||||
// relink y in place of z. y is z's successor
|
|
||||||
NodeTraits::set_parent(NodeTraits::get_left(z), y);
|
|
||||||
NodeTraits::set_left(y, NodeTraits::get_left(z));
|
|
||||||
if(y != NodeTraits::get_right(z)){
|
|
||||||
x_parent = NodeTraits::get_parent(y);
|
|
||||||
if(x)
|
|
||||||
NodeTraits::set_parent(x, x_parent);
|
|
||||||
NodeTraits::set_left(x_parent, x); // y must be a child of left_
|
|
||||||
NodeTraits::set_right(y, NodeTraits::get_right(z));
|
|
||||||
NodeTraits::set_parent(NodeTraits::get_right(z), y);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
x_parent = y;
|
|
||||||
bstree_algorithms::replace_own (z, y, header);
|
|
||||||
NodeTraits::set_parent(y, NodeTraits::get_parent(z));
|
|
||||||
}
|
|
||||||
else { // y == z --> z has only one child, or void
|
|
||||||
x_parent = NodeTraits::get_parent(z);
|
|
||||||
if(x)
|
|
||||||
NodeTraits::set_parent(x, x_parent);
|
|
||||||
bstree_algorithms::replace_own (z, x, header);
|
|
||||||
if(NodeTraits::get_left(header) == z){
|
|
||||||
NodeTraits::set_left(header, !NodeTraits::get_right(z) ? // z->get_left() must be null also
|
|
||||||
NodeTraits::get_parent(z) : // makes leftmost == header if z == root
|
|
||||||
bstree_algorithms::minimum (x));
|
|
||||||
}
|
|
||||||
if(NodeTraits::get_right(header) == z){
|
|
||||||
NodeTraits::set_right(header, !NodeTraits::get_left(z) ? // z->get_right() must be null also
|
|
||||||
NodeTraits::get_parent(z) : // makes rightmost == header if z == root
|
|
||||||
bstree_algorithms::maximum(x));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
info.x = x;
|
|
||||||
info.x_parent = x_parent;
|
|
||||||
info.y = y;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @cond
|
/// @cond
|
||||||
|
@ -13,6 +13,9 @@
|
|||||||
#ifndef BOOST_INTRUSIVE_DERIVATION_VALUE_TRAITS_HPP
|
#ifndef BOOST_INTRUSIVE_DERIVATION_VALUE_TRAITS_HPP
|
||||||
#define BOOST_INTRUSIVE_DERIVATION_VALUE_TRAITS_HPP
|
#define BOOST_INTRUSIVE_DERIVATION_VALUE_TRAITS_HPP
|
||||||
|
|
||||||
|
#include <boost/intrusive/detail/config_begin.hpp>
|
||||||
|
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||||
|
|
||||||
#include <boost/intrusive/link_mode.hpp>
|
#include <boost/intrusive/link_mode.hpp>
|
||||||
#include <boost/pointer_cast.hpp>
|
#include <boost/pointer_cast.hpp>
|
||||||
#include <boost/pointer_to_other.hpp>
|
#include <boost/pointer_to_other.hpp>
|
||||||
@ -24,7 +27,12 @@ namespace intrusive {
|
|||||||
//!This value traits template is used to create value traits
|
//!This value traits template is used to create value traits
|
||||||
//!from user defined node traits where value_traits::value_type will
|
//!from user defined node traits where value_traits::value_type will
|
||||||
//!derive from node_traits::node
|
//!derive from node_traits::node
|
||||||
template<class T, class NodeTraits, link_mode_type LinkMode = safe_link>
|
|
||||||
|
template<class T, class NodeTraits, link_mode_type LinkMode
|
||||||
|
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
|
= safe_link
|
||||||
|
#endif
|
||||||
|
>
|
||||||
struct derivation_value_traits
|
struct derivation_value_traits
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -67,4 +75,6 @@ struct derivation_value_traits
|
|||||||
} //namespace intrusive
|
} //namespace intrusive
|
||||||
} //namespace boost
|
} //namespace boost
|
||||||
|
|
||||||
|
#include <boost/intrusive/detail/config_end.hpp>
|
||||||
|
|
||||||
#endif //BOOST_INTRUSIVE_DERIVATION_VALUE_TRAITS_HPP
|
#endif //BOOST_INTRUSIVE_DERIVATION_VALUE_TRAITS_HPP
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
#ifndef BOOST_INTRUSIVE_DETAIL_ASSERT_HPP
|
#ifndef BOOST_INTRUSIVE_DETAIL_ASSERT_HPP
|
||||||
#define BOOST_INTRUSIVE_DETAIL_ASSERT_HPP
|
#define BOOST_INTRUSIVE_DETAIL_ASSERT_HPP
|
||||||
|
|
||||||
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
#if defined(_MSC_VER)
|
||||||
#pragma once
|
#pragma once
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -33,9 +33,9 @@ enum base_hook_type
|
|||||||
, SlistBaseHookId
|
, SlistBaseHookId
|
||||||
, RbTreeBaseHookId
|
, RbTreeBaseHookId
|
||||||
, HashBaseHookId
|
, HashBaseHookId
|
||||||
, SplayTreeBaseHookId
|
|
||||||
, AvlTreeBaseHookId
|
, AvlTreeBaseHookId
|
||||||
, BsTreeBaseHookId
|
, BsTreeBaseHookId
|
||||||
|
, TreapTreeBaseHookId
|
||||||
, AnyBaseHookId
|
, AnyBaseHookId
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -59,10 +59,6 @@ template <class HookTags>
|
|||||||
struct hook_tags_definer<HookTags, HashBaseHookId>
|
struct hook_tags_definer<HookTags, HashBaseHookId>
|
||||||
{ typedef HookTags default_hashtable_hook; };
|
{ typedef HookTags default_hashtable_hook; };
|
||||||
|
|
||||||
template <class HookTags>
|
|
||||||
struct hook_tags_definer<HookTags, SplayTreeBaseHookId>
|
|
||||||
{ typedef HookTags default_splaytree_hook; };
|
|
||||||
|
|
||||||
template <class HookTags>
|
template <class HookTags>
|
||||||
struct hook_tags_definer<HookTags, AvlTreeBaseHookId>
|
struct hook_tags_definer<HookTags, AvlTreeBaseHookId>
|
||||||
{ typedef HookTags default_avltree_hook; };
|
{ typedef HookTags default_avltree_hook; };
|
||||||
|
@ -70,11 +70,11 @@
|
|||||||
#error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END not defined!"
|
#error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END not defined!"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BOOST_PP_ITERATION_START() != 0
|
#if BOOST_PP_ITERATION_START() > BOOST_PP_ITERATION_FINISH()
|
||||||
#error "BOOST_PP_ITERATION_START() must be zero (0)"
|
#error "BOOST_PP_ITERATION_START() must be <= BOOST_PP_ITERATION_FINISH()"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BOOST_PP_ITERATION() == 0
|
#if BOOST_PP_ITERATION() == BOOST_PP_ITERATION_START()
|
||||||
|
|
||||||
BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN
|
BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN
|
||||||
|
|
||||||
@ -114,6 +114,119 @@
|
|||||||
};
|
};
|
||||||
//!
|
//!
|
||||||
|
|
||||||
|
#else //!defined(BOOST_INTRUSIVE_PERFECT_FORWARDING)
|
||||||
|
|
||||||
|
template<typename Fun, bool HasFunc, class ...Args>
|
||||||
|
struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl);
|
||||||
|
|
||||||
|
template<typename Fun, class ...Args>
|
||||||
|
struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl)
|
||||||
|
<Fun, false, Args...>
|
||||||
|
{
|
||||||
|
static const bool value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef BOOST_NO_CXX11_DECLTYPE
|
||||||
|
|
||||||
|
//Special case for 0 args
|
||||||
|
template< class F
|
||||||
|
, std::size_t N =
|
||||||
|
sizeof((boost::move_detail::declval<F>().
|
||||||
|
BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME (), 0))>
|
||||||
|
struct BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
|
||||||
|
{
|
||||||
|
boost_intrusive_has_member_function_callable_with::yes_type dummy;
|
||||||
|
BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)(int);
|
||||||
|
};
|
||||||
|
|
||||||
|
//For buggy compilers like MSVC 7.1+ ((F*)0)->func() does not
|
||||||
|
//SFINAE-out the zeroarg_checker_ instantiation but sizeof yields to 0.
|
||||||
|
template<class F>
|
||||||
|
struct BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<F, 0>
|
||||||
|
{
|
||||||
|
boost_intrusive_has_member_function_callable_with::no_type dummy;
|
||||||
|
BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)(int);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //#ifdef BOOST_NO_CXX11_DECLTYPE
|
||||||
|
|
||||||
|
template<typename Fun>
|
||||||
|
struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl)
|
||||||
|
<Fun, true>
|
||||||
|
{
|
||||||
|
#ifndef BOOST_NO_CXX11_DECLTYPE
|
||||||
|
template<class U, class V = decltype(boost::move_detail::declval<U>().BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME()) >
|
||||||
|
static boost_intrusive_has_member_function_callable_with::yes_type Test(U*);
|
||||||
|
#else
|
||||||
|
template<class U>
|
||||||
|
static BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
|
||||||
|
<U> Test(BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<U>*);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <class U>
|
||||||
|
static boost_intrusive_has_member_function_callable_with::no_type Test(...);
|
||||||
|
|
||||||
|
static const bool value = sizeof(Test< Fun >(0))
|
||||||
|
== sizeof(boost_intrusive_has_member_function_callable_with::yes_type);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Fun, class ...DontCares>
|
||||||
|
struct BOOST_PP_CAT( funwrap_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME )
|
||||||
|
: Fun
|
||||||
|
{
|
||||||
|
BOOST_PP_CAT( funwrap_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME )();
|
||||||
|
using Fun::BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME;
|
||||||
|
|
||||||
|
boost_intrusive_has_member_function_callable_with::private_type
|
||||||
|
BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME
|
||||||
|
( DontCares...) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Fun, class ...Args>
|
||||||
|
struct BOOST_PP_CAT( BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME), _impl)
|
||||||
|
<Fun, true , Args...>
|
||||||
|
{
|
||||||
|
template<class T>
|
||||||
|
struct make_dontcare
|
||||||
|
{
|
||||||
|
typedef boost_intrusive_has_member_function_callable_with::dont_care type;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef BOOST_PP_CAT( funwrap_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME )
|
||||||
|
<Fun, typename make_dontcare<Args>::type...> FunWrap;
|
||||||
|
|
||||||
|
static bool const value = (sizeof(boost_intrusive_has_member_function_callable_with::no_type) ==
|
||||||
|
sizeof(boost_intrusive_has_member_function_callable_with::is_private_type
|
||||||
|
( (::boost::move_detail::declval< FunWrap >().
|
||||||
|
BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME
|
||||||
|
( ::boost::move_detail::declval<Args>()... ), 0) )
|
||||||
|
)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Fun, class ...Args>
|
||||||
|
struct BOOST_PP_CAT( has_member_function_callable_with_
|
||||||
|
, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
|
||||||
|
: public BOOST_PP_CAT( BOOST_PP_CAT(has_member_function_callable_with_
|
||||||
|
, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl)
|
||||||
|
< Fun
|
||||||
|
, BOOST_PP_CAT( has_member_function_named_
|
||||||
|
, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME )<Fun>::value
|
||||||
|
, Args... >
|
||||||
|
{};
|
||||||
|
|
||||||
|
#endif //!defined(BOOST_INTRUSIVE_PERFECT_FORWARDING)
|
||||||
|
|
||||||
|
BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END
|
||||||
|
|
||||||
|
#endif //BOOST_PP_ITERATION() == BOOST_PP_ITERATION_START()
|
||||||
|
|
||||||
|
#if BOOST_PP_ITERATION() == 0
|
||||||
|
|
||||||
|
BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN
|
||||||
|
|
||||||
|
#if !defined(BOOST_INTRUSIVE_PERFECT_FORWARDING)
|
||||||
|
|
||||||
#if !defined(_MSC_VER) || (_MSC_VER < 1600)
|
#if !defined(_MSC_VER) || (_MSC_VER < 1600)
|
||||||
|
|
||||||
#if defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED)
|
#if defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED)
|
||||||
@ -171,9 +284,9 @@
|
|||||||
<Fun, true BOOST_PP_ENUM_TRAILING(BOOST_PP_SUB(BOOST_PP_ITERATION_FINISH(), BOOST_PP_ITERATION()), BOOST_INTRUSIVE_PP_IDENTITY, void)>
|
<Fun, true BOOST_PP_ENUM_TRAILING(BOOST_PP_SUB(BOOST_PP_ITERATION_FINISH(), BOOST_PP_ITERATION()), BOOST_INTRUSIVE_PP_IDENTITY, void)>
|
||||||
{
|
{
|
||||||
template<class U>
|
template<class U>
|
||||||
static decltype( boost::move_detail::declval<Fun>().BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME()
|
static decltype( boost::move_detail::declval<U>().BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME()
|
||||||
, boost_intrusive_has_member_function_callable_with::yes_type())
|
, boost_intrusive_has_member_function_callable_with::yes_type())
|
||||||
Test(Fun*);
|
Test(U*);
|
||||||
|
|
||||||
template<class U>
|
template<class U>
|
||||||
static boost_intrusive_has_member_function_callable_with::no_type Test(...);
|
static boost_intrusive_has_member_function_callable_with::no_type Test(...);
|
||||||
@ -185,96 +298,6 @@
|
|||||||
|
|
||||||
#else //#if !defined(BOOST_INTRUSIVE_PERFECT_FORWARDING)
|
#else //#if !defined(BOOST_INTRUSIVE_PERFECT_FORWARDING)
|
||||||
|
|
||||||
template<typename Fun, bool HasFunc, class ...Args>
|
|
||||||
struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl);
|
|
||||||
|
|
||||||
template<typename Fun, class ...Args>
|
|
||||||
struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl)
|
|
||||||
<Fun, false, Args...>
|
|
||||||
{
|
|
||||||
static const bool value = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
//Special case for 0 args
|
|
||||||
template< class F
|
|
||||||
, std::size_t N =
|
|
||||||
sizeof((boost::move_detail::declval<F>().
|
|
||||||
BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME (), 0))>
|
|
||||||
struct BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
|
|
||||||
{
|
|
||||||
boost_intrusive_has_member_function_callable_with::yes_type dummy;
|
|
||||||
BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)(int);
|
|
||||||
};
|
|
||||||
|
|
||||||
//For buggy compilers like MSVC 7.1+ ((F*)0)->func() does not
|
|
||||||
//SFINAE-out the zeroarg_checker_ instantiation but sizeof yields to 0.
|
|
||||||
template<class F>
|
|
||||||
struct BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<F, 0>
|
|
||||||
{
|
|
||||||
boost_intrusive_has_member_function_callable_with::no_type dummy;
|
|
||||||
BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)(int);
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Fun>
|
|
||||||
struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl)
|
|
||||||
<Fun, true>
|
|
||||||
{
|
|
||||||
template<class U>
|
|
||||||
static BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
|
|
||||||
<U> Test(BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<U>*);
|
|
||||||
|
|
||||||
template <class U>
|
|
||||||
static boost_intrusive_has_member_function_callable_with::no_type Test(...);
|
|
||||||
|
|
||||||
static const bool value = sizeof(Test< Fun >(0))
|
|
||||||
== sizeof(boost_intrusive_has_member_function_callable_with::yes_type);
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Fun, class ...DontCares>
|
|
||||||
struct BOOST_PP_CAT( funwrap_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME )
|
|
||||||
: Fun
|
|
||||||
{
|
|
||||||
BOOST_PP_CAT( funwrap_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME )();
|
|
||||||
using Fun::BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME;
|
|
||||||
|
|
||||||
boost_intrusive_has_member_function_callable_with::private_type
|
|
||||||
BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME
|
|
||||||
( DontCares...) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Fun, class ...Args>
|
|
||||||
struct BOOST_PP_CAT( BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME), _impl)
|
|
||||||
<Fun, true , Args...>
|
|
||||||
{
|
|
||||||
template<class T>
|
|
||||||
struct make_dontcare
|
|
||||||
{
|
|
||||||
typedef boost_intrusive_has_member_function_callable_with::dont_care type;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef BOOST_PP_CAT( funwrap_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME )
|
|
||||||
<Fun, typename make_dontcare<Args>::type...> FunWrap;
|
|
||||||
|
|
||||||
static bool const value = (sizeof(boost_intrusive_has_member_function_callable_with::no_type) ==
|
|
||||||
sizeof(boost_intrusive_has_member_function_callable_with::is_private_type
|
|
||||||
( (::boost::move_detail::declval< FunWrap >().
|
|
||||||
BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME
|
|
||||||
( ::boost::move_detail::declval<Args>()... ), 0) )
|
|
||||||
)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Fun, class ...Args>
|
|
||||||
struct BOOST_PP_CAT( has_member_function_callable_with_
|
|
||||||
, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
|
|
||||||
: public BOOST_PP_CAT( BOOST_PP_CAT(has_member_function_callable_with_
|
|
||||||
, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl)
|
|
||||||
< Fun
|
|
||||||
, BOOST_PP_CAT( has_member_function_named_
|
|
||||||
, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME )<Fun>::value
|
|
||||||
, Args... >
|
|
||||||
{};
|
|
||||||
|
|
||||||
#endif //#if !defined(BOOST_INTRUSIVE_PERFECT_FORWARDING)
|
#endif //#if !defined(BOOST_INTRUSIVE_PERFECT_FORWARDING)
|
||||||
|
|
||||||
BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END
|
BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
#ifndef BOOST_INTRUSIVE_ALLOCATOR_MEMORY_UTIL_HPP
|
#ifndef BOOST_INTRUSIVE_ALLOCATOR_MEMORY_UTIL_HPP
|
||||||
#define BOOST_INTRUSIVE_ALLOCATOR_MEMORY_UTIL_HPP
|
#define BOOST_INTRUSIVE_ALLOCATOR_MEMORY_UTIL_HPP
|
||||||
|
|
||||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
#if defined(_MSC_VER)
|
||||||
# pragma once
|
# pragma once
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -118,25 +118,25 @@ struct LowPriorityConversion
|
|||||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME pointer_to
|
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME pointer_to
|
||||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace intrusive { namespace detail {
|
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace intrusive { namespace detail {
|
||||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
#define BOOST_PP_ITERATION_PARAMS_1 (3, (1, 1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||||
#include BOOST_PP_ITERATE()
|
#include BOOST_PP_ITERATE()
|
||||||
|
|
||||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME static_cast_from
|
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME static_cast_from
|
||||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace intrusive { namespace detail {
|
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace intrusive { namespace detail {
|
||||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
#define BOOST_PP_ITERATION_PARAMS_1 (3, (1, 1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||||
#include BOOST_PP_ITERATE()
|
#include BOOST_PP_ITERATE()
|
||||||
|
|
||||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME const_cast_from
|
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME const_cast_from
|
||||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace intrusive { namespace detail {
|
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace intrusive { namespace detail {
|
||||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
#define BOOST_PP_ITERATION_PARAMS_1 (3, (1, 1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||||
#include BOOST_PP_ITERATE()
|
#include BOOST_PP_ITERATE()
|
||||||
|
|
||||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME dynamic_cast_from
|
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME dynamic_cast_from
|
||||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace intrusive { namespace detail {
|
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace intrusive { namespace detail {
|
||||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
#define BOOST_PP_ITERATION_PARAMS_1 (3, (1, 1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||||
#include BOOST_PP_ITERATE()
|
#include BOOST_PP_ITERATE()
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
@ -29,6 +29,12 @@ struct bool_
|
|||||||
static const bool value = C_;
|
static const bool value = C_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template< class Integer, Integer Value >
|
||||||
|
struct integer
|
||||||
|
{
|
||||||
|
static const Integer value = Value;
|
||||||
|
};
|
||||||
|
|
||||||
typedef bool_<true> true_;
|
typedef bool_<true> true_;
|
||||||
typedef bool_<false> false_;
|
typedef bool_<false> false_;
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#ifndef BOOST_INTRUSIVE_DETAIL_PREPROCESSOR_HPP
|
#ifndef BOOST_INTRUSIVE_DETAIL_PREPROCESSOR_HPP
|
||||||
#define BOOST_INTRUSIVE_DETAIL_PREPROCESSOR_HPP
|
#define BOOST_INTRUSIVE_DETAIL_PREPROCESSOR_HPP
|
||||||
|
|
||||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
#if defined(_MSC_VER)
|
||||||
# pragma once
|
# pragma once
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -13,12 +13,47 @@
|
|||||||
#ifndef BOOST_INTRUSIVE_FWD_HPP
|
#ifndef BOOST_INTRUSIVE_FWD_HPP
|
||||||
#define BOOST_INTRUSIVE_FWD_HPP
|
#define BOOST_INTRUSIVE_FWD_HPP
|
||||||
|
|
||||||
|
//! \file
|
||||||
|
//! This header file forward declares most Intrusive classes.
|
||||||
|
//!
|
||||||
|
//! It forward declares the following containers and hooks:
|
||||||
|
//! - boost::intrusive::slist / boost::intrusive::slist_base_hook / boost::intrusive::slist_member_hook
|
||||||
|
//! - boost::intrusive::list / boost::intrusive::list_base_hook / boost::intrusive::list_member_hook
|
||||||
|
//! - boost::intrusive::bstree / boost::intrusive::bs_set / boost::intrusive::bs_multiset /
|
||||||
|
//! boost::intrusive::bs_set_base_hook / boost::intrusive::bs_set_member_hook
|
||||||
|
//! - boost::intrusive::rbtree / boost::intrusive::set / boost::intrusive::multiset /
|
||||||
|
//! boost::intrusive::set_base_hook / boost::intrusive::set_member_hook
|
||||||
|
//! - boost::intrusive::avltree / boost::intrusive::avl_set / boost::intrusive::avl_multiset /
|
||||||
|
//! boost::intrusive::avl_set_base_hook / boost::intrusive::avl_set_member_hook
|
||||||
|
//! - boost::intrusive::splaytree / boost::intrusive::splay_set / boost::intrusive::splay_multiset
|
||||||
|
//! - boost::intrusive::sgtree / boost::intrusive::sg_set / boost::intrusive::sg_multiset
|
||||||
|
//! - boost::intrusive::treap / boost::intrusive::treap_set / boost::intrusive::treap_multiset
|
||||||
|
//! - boost::intrusive::hashtable / boost::intrusive::unordered_set / boost::intrusive::unordered_multiset /
|
||||||
|
//! boost::intrusive::unordered_set_base_hook / boost::intrusive::unordered_set_member_hook /
|
||||||
|
//! - boost::intrusive::any_base_hook / boost::intrusive::any_member_hook
|
||||||
|
//!
|
||||||
|
//! It forward declares the following container or hook options:
|
||||||
|
//! - boost::intrusive::constant_time_size / boost::intrusive::size_type / boost::intrusive::compare / boost::intrusive::equal
|
||||||
|
//! - boost::intrusive::floating_point / boost::intrusive::priority / boost::intrusive::hash
|
||||||
|
//! - boost::intrusive::value_traits / boost::intrusive::member_hook / boost::intrusive::function_hook / boost::intrusive::base_hook
|
||||||
|
//! - boost::intrusive::void_pointer / boost::intrusive::tag / boost::intrusive::link_mode
|
||||||
|
//! - boost::intrusive::optimize_size / boost::intrusive::linear / boost::intrusive::cache_last
|
||||||
|
//! - boost::intrusive::bucket_traits / boost::intrusive::store_hash / boost::intrusive::optimize_multikey
|
||||||
|
//! - boost::intrusive::power_2_buckets / boost::intrusive::cache_begin / boost::intrusive::compare_hash / boost::intrusive::incremental
|
||||||
|
//!
|
||||||
|
//! It forward declares the following value traits utilities:
|
||||||
|
//! - boost::intrusive::value_traits / boost::intrusive::derivation_value_traits /
|
||||||
|
//! boost::intrusive::trivial_value_traits
|
||||||
|
//!
|
||||||
|
//! Finally it forward declares the following general purpose utilities:
|
||||||
|
//! - boost::intrusive::pointer_plus_bits / boost::intrusive::priority_compare.
|
||||||
|
|
||||||
|
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <boost/intrusive/link_mode.hpp>
|
#include <boost/intrusive/link_mode.hpp>
|
||||||
#include <boost/intrusive/detail/workaround.hpp>
|
#include <boost/intrusive/detail/workaround.hpp>
|
||||||
|
|
||||||
/// @cond
|
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
namespace intrusive {
|
namespace intrusive {
|
||||||
|
|
||||||
@ -33,15 +68,33 @@ class circular_list_algorithms;
|
|||||||
template<class NodeTraits>
|
template<class NodeTraits>
|
||||||
class circular_slist_algorithms;
|
class circular_slist_algorithms;
|
||||||
|
|
||||||
|
template<class NodeTraits>
|
||||||
|
class linear_slist_algorithms;
|
||||||
|
|
||||||
|
template<class NodeTraits>
|
||||||
|
class bstree_algorithms;
|
||||||
|
|
||||||
template<class NodeTraits>
|
template<class NodeTraits>
|
||||||
class rbtree_algorithms;
|
class rbtree_algorithms;
|
||||||
|
|
||||||
|
template<class NodeTraits>
|
||||||
|
class avltree_algorithms;
|
||||||
|
|
||||||
|
template<class NodeTraits>
|
||||||
|
class sgtree_algorithms;
|
||||||
|
|
||||||
|
template<class NodeTraits>
|
||||||
|
class splaytree_algorithms;
|
||||||
|
|
||||||
|
template<class NodeTraits>
|
||||||
|
class treap_algorithms;
|
||||||
|
|
||||||
////////////////////////////
|
////////////////////////////
|
||||||
// Containers
|
// Containers
|
||||||
////////////////////////////
|
////////////////////////////
|
||||||
|
|
||||||
//slist
|
//slist
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template
|
template
|
||||||
< class T
|
< class T
|
||||||
, class O1 = void
|
, class O1 = void
|
||||||
@ -55,7 +108,7 @@ template<class T, class ...Options>
|
|||||||
#endif
|
#endif
|
||||||
class slist;
|
class slist;
|
||||||
|
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template
|
template
|
||||||
< class O1 = void
|
< class O1 = void
|
||||||
, class O2 = void
|
, class O2 = void
|
||||||
@ -66,7 +119,7 @@ template<class ...Options>
|
|||||||
#endif
|
#endif
|
||||||
class slist_base_hook;
|
class slist_base_hook;
|
||||||
|
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template
|
template
|
||||||
< class O1 = void
|
< class O1 = void
|
||||||
, class O2 = void
|
, class O2 = void
|
||||||
@ -78,7 +131,7 @@ template<class ...Options>
|
|||||||
class slist_member_hook;
|
class slist_member_hook;
|
||||||
|
|
||||||
//list
|
//list
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template
|
template
|
||||||
< class T
|
< class T
|
||||||
, class O1 = void
|
, class O1 = void
|
||||||
@ -90,7 +143,7 @@ template<class T, class ...Options>
|
|||||||
#endif
|
#endif
|
||||||
class list;
|
class list;
|
||||||
|
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template
|
template
|
||||||
< class O1 = void
|
< class O1 = void
|
||||||
, class O2 = void
|
, class O2 = void
|
||||||
@ -101,7 +154,7 @@ template<class ...Options>
|
|||||||
#endif
|
#endif
|
||||||
class list_base_hook;
|
class list_base_hook;
|
||||||
|
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template
|
template
|
||||||
< class O1 = void
|
< class O1 = void
|
||||||
, class O2 = void
|
, class O2 = void
|
||||||
@ -112,19 +165,8 @@ template<class ...Options>
|
|||||||
#endif
|
#endif
|
||||||
class list_member_hook;
|
class list_member_hook;
|
||||||
|
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
|
||||||
template
|
|
||||||
< class O1 = void
|
|
||||||
, class O2 = void
|
|
||||||
, class O3 = void
|
|
||||||
>
|
|
||||||
#else
|
|
||||||
template<class ...Options>
|
|
||||||
#endif
|
|
||||||
class list_hook;
|
|
||||||
|
|
||||||
//rbtree/set/multiset
|
//rbtree/set/multiset
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template
|
template
|
||||||
< class T
|
< class T
|
||||||
, class O1 = void
|
, class O1 = void
|
||||||
@ -137,7 +179,7 @@ template<class T, class ...Options>
|
|||||||
#endif
|
#endif
|
||||||
class rbtree;
|
class rbtree;
|
||||||
|
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template
|
template
|
||||||
< class T
|
< class T
|
||||||
, class O1 = void
|
, class O1 = void
|
||||||
@ -150,7 +192,7 @@ template<class T, class ...Options>
|
|||||||
#endif
|
#endif
|
||||||
class set;
|
class set;
|
||||||
|
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template
|
template
|
||||||
< class T
|
< class T
|
||||||
, class O1 = void
|
, class O1 = void
|
||||||
@ -163,7 +205,7 @@ template<class T, class ...Options>
|
|||||||
#endif
|
#endif
|
||||||
class multiset;
|
class multiset;
|
||||||
|
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template
|
template
|
||||||
< class O1 = void
|
< class O1 = void
|
||||||
, class O2 = void
|
, class O2 = void
|
||||||
@ -175,7 +217,7 @@ template<class ...Options>
|
|||||||
#endif
|
#endif
|
||||||
class set_base_hook;
|
class set_base_hook;
|
||||||
|
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template
|
template
|
||||||
< class O1 = void
|
< class O1 = void
|
||||||
, class O2 = void
|
, class O2 = void
|
||||||
@ -188,7 +230,7 @@ template<class ...Options>
|
|||||||
class set_member_hook;
|
class set_member_hook;
|
||||||
|
|
||||||
//splaytree/splay_set/splay_multiset
|
//splaytree/splay_set/splay_multiset
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template
|
template
|
||||||
< class T
|
< class T
|
||||||
, class O1 = void
|
, class O1 = void
|
||||||
@ -201,7 +243,7 @@ template<class T, class ...Options>
|
|||||||
#endif
|
#endif
|
||||||
class splaytree;
|
class splaytree;
|
||||||
|
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template
|
template
|
||||||
< class T
|
< class T
|
||||||
, class O1 = void
|
, class O1 = void
|
||||||
@ -214,7 +256,7 @@ template<class T, class ...Options>
|
|||||||
#endif
|
#endif
|
||||||
class splay_set;
|
class splay_set;
|
||||||
|
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template
|
template
|
||||||
< class T
|
< class T
|
||||||
, class O1 = void
|
, class O1 = void
|
||||||
@ -227,30 +269,8 @@ template<class T, class ...Options>
|
|||||||
#endif
|
#endif
|
||||||
class splay_multiset;
|
class splay_multiset;
|
||||||
|
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
|
||||||
template
|
|
||||||
< class O1 = void
|
|
||||||
, class O2 = void
|
|
||||||
, class O3 = void
|
|
||||||
>
|
|
||||||
#else
|
|
||||||
template<class ...Options>
|
|
||||||
#endif
|
|
||||||
class splay_set_base_hook;
|
|
||||||
|
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
|
||||||
template
|
|
||||||
< class O1 = void
|
|
||||||
, class O2 = void
|
|
||||||
, class O3 = void
|
|
||||||
>
|
|
||||||
#else
|
|
||||||
template<class ...Options>
|
|
||||||
#endif
|
|
||||||
class splay_set_member_hook;
|
|
||||||
|
|
||||||
//avltree/avl_set/avl_multiset
|
//avltree/avl_set/avl_multiset
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template
|
template
|
||||||
< class T
|
< class T
|
||||||
, class O1 = void
|
, class O1 = void
|
||||||
@ -263,7 +283,7 @@ template<class T, class ...Options>
|
|||||||
#endif
|
#endif
|
||||||
class avltree;
|
class avltree;
|
||||||
|
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template
|
template
|
||||||
< class T
|
< class T
|
||||||
, class O1 = void
|
, class O1 = void
|
||||||
@ -276,7 +296,7 @@ template<class T, class ...Options>
|
|||||||
#endif
|
#endif
|
||||||
class avl_set;
|
class avl_set;
|
||||||
|
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template
|
template
|
||||||
< class T
|
< class T
|
||||||
, class O1 = void
|
, class O1 = void
|
||||||
@ -289,7 +309,7 @@ template<class T, class ...Options>
|
|||||||
#endif
|
#endif
|
||||||
class avl_multiset;
|
class avl_multiset;
|
||||||
|
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template
|
template
|
||||||
< class O1 = void
|
< class O1 = void
|
||||||
, class O2 = void
|
, class O2 = void
|
||||||
@ -301,7 +321,7 @@ template<class ...Options>
|
|||||||
#endif
|
#endif
|
||||||
class avl_set_base_hook;
|
class avl_set_base_hook;
|
||||||
|
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template
|
template
|
||||||
< class O1 = void
|
< class O1 = void
|
||||||
, class O2 = void
|
, class O2 = void
|
||||||
@ -315,7 +335,7 @@ class avl_set_member_hook;
|
|||||||
|
|
||||||
|
|
||||||
//treap/treap_set/treap_multiset
|
//treap/treap_set/treap_multiset
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template
|
template
|
||||||
< class T
|
< class T
|
||||||
, class O1 = void
|
, class O1 = void
|
||||||
@ -328,7 +348,7 @@ template<class T, class ...Options>
|
|||||||
#endif
|
#endif
|
||||||
class treap;
|
class treap;
|
||||||
|
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template
|
template
|
||||||
< class T
|
< class T
|
||||||
, class O1 = void
|
, class O1 = void
|
||||||
@ -341,7 +361,7 @@ template<class T, class ...Options>
|
|||||||
#endif
|
#endif
|
||||||
class treap_set;
|
class treap_set;
|
||||||
|
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template
|
template
|
||||||
< class T
|
< class T
|
||||||
, class O1 = void
|
, class O1 = void
|
||||||
@ -354,12 +374,8 @@ template<class T, class ...Options>
|
|||||||
#endif
|
#endif
|
||||||
class treap_multiset;
|
class treap_multiset;
|
||||||
|
|
||||||
//Default priority comparison functor
|
|
||||||
template <class T>
|
|
||||||
struct priority_compare;
|
|
||||||
|
|
||||||
//sgtree/sg_set/sg_multiset
|
//sgtree/sg_set/sg_multiset
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template
|
template
|
||||||
< class T
|
< class T
|
||||||
, class O1 = void
|
, class O1 = void
|
||||||
@ -372,7 +388,7 @@ template<class T, class ...Options>
|
|||||||
#endif
|
#endif
|
||||||
class sgtree;
|
class sgtree;
|
||||||
|
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template
|
template
|
||||||
< class T
|
< class T
|
||||||
, class O1 = void
|
, class O1 = void
|
||||||
@ -385,7 +401,7 @@ template<class T, class ...Options>
|
|||||||
#endif
|
#endif
|
||||||
class sg_set;
|
class sg_set;
|
||||||
|
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template
|
template
|
||||||
< class T
|
< class T
|
||||||
, class O1 = void
|
, class O1 = void
|
||||||
@ -398,7 +414,7 @@ template<class T, class ...Options>
|
|||||||
#endif
|
#endif
|
||||||
class sg_multiset;
|
class sg_multiset;
|
||||||
|
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template
|
template
|
||||||
< class T
|
< class T
|
||||||
, class O1 = void
|
, class O1 = void
|
||||||
@ -411,7 +427,7 @@ template<class T, class ...Options>
|
|||||||
#endif
|
#endif
|
||||||
class bstree;
|
class bstree;
|
||||||
|
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template
|
template
|
||||||
< class T
|
< class T
|
||||||
, class O1 = void
|
, class O1 = void
|
||||||
@ -424,7 +440,7 @@ template<class T, class ...Options>
|
|||||||
#endif
|
#endif
|
||||||
class bs_set;
|
class bs_set;
|
||||||
|
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template
|
template
|
||||||
< class T
|
< class T
|
||||||
, class O1 = void
|
, class O1 = void
|
||||||
@ -437,7 +453,7 @@ template<class T, class ...Options>
|
|||||||
#endif
|
#endif
|
||||||
class bs_multiset;
|
class bs_multiset;
|
||||||
|
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template
|
template
|
||||||
< class O1 = void
|
< class O1 = void
|
||||||
, class O2 = void
|
, class O2 = void
|
||||||
@ -448,7 +464,7 @@ template<class ...Options>
|
|||||||
#endif
|
#endif
|
||||||
class bs_set_base_hook;
|
class bs_set_base_hook;
|
||||||
|
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template
|
template
|
||||||
< class O1 = void
|
< class O1 = void
|
||||||
, class O2 = void
|
, class O2 = void
|
||||||
@ -461,7 +477,7 @@ class bs_set_member_hook;
|
|||||||
|
|
||||||
//hashtable/unordered_set/unordered_multiset
|
//hashtable/unordered_set/unordered_multiset
|
||||||
|
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template
|
template
|
||||||
< class T
|
< class T
|
||||||
, class O1 = void
|
, class O1 = void
|
||||||
@ -480,7 +496,7 @@ template<class T, class ...Options>
|
|||||||
#endif
|
#endif
|
||||||
class hashtable;
|
class hashtable;
|
||||||
|
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template
|
template
|
||||||
< class T
|
< class T
|
||||||
, class O1 = void
|
, class O1 = void
|
||||||
@ -499,7 +515,7 @@ template<class T, class ...Options>
|
|||||||
#endif
|
#endif
|
||||||
class unordered_set;
|
class unordered_set;
|
||||||
|
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template
|
template
|
||||||
< class T
|
< class T
|
||||||
, class O1 = void
|
, class O1 = void
|
||||||
@ -518,7 +534,7 @@ template<class T, class ...Options>
|
|||||||
#endif
|
#endif
|
||||||
class unordered_multiset;
|
class unordered_multiset;
|
||||||
|
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template
|
template
|
||||||
< class O1 = void
|
< class O1 = void
|
||||||
, class O2 = void
|
, class O2 = void
|
||||||
@ -530,7 +546,7 @@ template<class ...Options>
|
|||||||
#endif
|
#endif
|
||||||
class unordered_set_base_hook;
|
class unordered_set_base_hook;
|
||||||
|
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template
|
template
|
||||||
< class O1 = void
|
< class O1 = void
|
||||||
, class O2 = void
|
, class O2 = void
|
||||||
@ -542,7 +558,7 @@ template<class ...Options>
|
|||||||
#endif
|
#endif
|
||||||
class unordered_set_member_hook;
|
class unordered_set_member_hook;
|
||||||
|
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template
|
template
|
||||||
< class O1 = void
|
< class O1 = void
|
||||||
, class O2 = void
|
, class O2 = void
|
||||||
@ -553,7 +569,7 @@ template<class ...Options>
|
|||||||
#endif
|
#endif
|
||||||
class any_base_hook;
|
class any_base_hook;
|
||||||
|
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template
|
template
|
||||||
< class O1 = void
|
< class O1 = void
|
||||||
, class O2 = void
|
, class O2 = void
|
||||||
@ -564,9 +580,126 @@ template<class ...Options>
|
|||||||
#endif
|
#endif
|
||||||
class any_member_hook;
|
class any_member_hook;
|
||||||
|
|
||||||
|
//Options
|
||||||
|
|
||||||
|
template<bool Enabled>
|
||||||
|
struct constant_time_size;
|
||||||
|
|
||||||
|
template<typename SizeType>
|
||||||
|
struct size_type;
|
||||||
|
|
||||||
|
template<typename Compare>
|
||||||
|
struct compare;
|
||||||
|
|
||||||
|
template<bool Enabled>
|
||||||
|
struct floating_point;
|
||||||
|
|
||||||
|
template<typename Equal>
|
||||||
|
struct equal;
|
||||||
|
|
||||||
|
template<typename Priority>
|
||||||
|
struct priority;
|
||||||
|
|
||||||
|
template<typename Hash>
|
||||||
|
struct hash;
|
||||||
|
|
||||||
|
template<typename ValueTraits> struct value_traits;
|
||||||
|
|
||||||
|
template< typename Parent
|
||||||
|
, typename MemberHook
|
||||||
|
, MemberHook Parent::* PtrToMember>
|
||||||
|
struct member_hook;
|
||||||
|
|
||||||
|
template<typename Functor>
|
||||||
|
struct function_hook;
|
||||||
|
|
||||||
|
template<typename BaseHook>
|
||||||
|
struct base_hook;
|
||||||
|
|
||||||
|
template<typename VoidPointer>
|
||||||
|
struct void_pointer;
|
||||||
|
|
||||||
|
template<typename Tag>
|
||||||
|
struct tag;
|
||||||
|
|
||||||
|
template<link_mode_type LinkType>
|
||||||
|
struct link_mode;
|
||||||
|
|
||||||
|
template<bool Enabled> struct
|
||||||
|
optimize_size;
|
||||||
|
|
||||||
|
template<bool Enabled>
|
||||||
|
struct linear;
|
||||||
|
|
||||||
|
template<bool Enabled>
|
||||||
|
struct cache_last;
|
||||||
|
|
||||||
|
template<typename BucketTraits>
|
||||||
|
struct bucket_traits;
|
||||||
|
|
||||||
|
template<bool Enabled>
|
||||||
|
struct store_hash;
|
||||||
|
|
||||||
|
template<bool Enabled>
|
||||||
|
struct optimize_multikey;
|
||||||
|
|
||||||
|
template<bool Enabled>
|
||||||
|
struct power_2_buckets;
|
||||||
|
|
||||||
|
template<bool Enabled>
|
||||||
|
struct cache_begin;
|
||||||
|
|
||||||
|
template<bool Enabled>
|
||||||
|
struct compare_hash;
|
||||||
|
|
||||||
|
template<bool Enabled>
|
||||||
|
struct incremental;
|
||||||
|
|
||||||
|
//Value traits
|
||||||
|
|
||||||
|
template<typename ValueTraits>
|
||||||
|
struct value_traits;
|
||||||
|
|
||||||
|
template< typename Parent
|
||||||
|
, typename MemberHook
|
||||||
|
, MemberHook Parent::* PtrToMember>
|
||||||
|
struct member_hook;
|
||||||
|
|
||||||
|
template< typename Functor>
|
||||||
|
struct function_hook;
|
||||||
|
|
||||||
|
template<typename BaseHook>
|
||||||
|
struct base_hook;
|
||||||
|
|
||||||
|
template<class T, class NodeTraits, link_mode_type LinkMode = safe_link>
|
||||||
|
struct derivation_value_traits;
|
||||||
|
|
||||||
|
template<class NodeTraits, link_mode_type LinkMode = normal_link>
|
||||||
|
struct trivial_value_traits;
|
||||||
|
|
||||||
|
//Additional utilities
|
||||||
|
|
||||||
|
template<typename VoidPointer, std::size_t Alignment>
|
||||||
|
struct max_pointer_plus_bits;
|
||||||
|
|
||||||
|
template<std::size_t Alignment>
|
||||||
|
struct max_pointer_plus_bits<void *, Alignment>;
|
||||||
|
|
||||||
|
template<typename Pointer, std::size_t NumBits>
|
||||||
|
struct pointer_plus_bits;
|
||||||
|
|
||||||
|
template<typename T, std::size_t NumBits>
|
||||||
|
struct pointer_plus_bits<T *, NumBits>;
|
||||||
|
|
||||||
|
template<typename Ptr>
|
||||||
|
struct pointer_traits;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct pointer_traits<T *>;
|
||||||
|
|
||||||
} //namespace intrusive {
|
} //namespace intrusive {
|
||||||
} //namespace boost {
|
} //namespace boost {
|
||||||
|
|
||||||
/// @endcond
|
#endif //#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||||
|
|
||||||
#endif //#ifndef BOOST_INTRUSIVE_FWD_HPP
|
#endif //#ifndef BOOST_INTRUSIVE_FWD_HPP
|
||||||
|
@ -77,7 +77,7 @@ struct make_list_base_hook
|
|||||||
//! \c auto_unlink or \c safe_link).
|
//! \c auto_unlink or \c safe_link).
|
||||||
//!
|
//!
|
||||||
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
||||||
//! and the the container configured to use this hook.
|
//! and the container configured to use this hook.
|
||||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template<class ...Options>
|
template<class ...Options>
|
||||||
#else
|
#else
|
||||||
@ -199,7 +199,7 @@ struct make_list_member_hook
|
|||||||
//! \c auto_unlink or \c safe_link).
|
//! \c auto_unlink or \c safe_link).
|
||||||
//!
|
//!
|
||||||
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
||||||
//! and the the container configured to use this hook.
|
//! and the container configured to use this hook.
|
||||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template<class ...Options>
|
template<class ...Options>
|
||||||
#else
|
#else
|
||||||
|
@ -13,6 +13,9 @@
|
|||||||
#ifndef BOOST_INTRUSIVE_MEMBER_VALUE_TRAITS_HPP
|
#ifndef BOOST_INTRUSIVE_MEMBER_VALUE_TRAITS_HPP
|
||||||
#define BOOST_INTRUSIVE_MEMBER_VALUE_TRAITS_HPP
|
#define BOOST_INTRUSIVE_MEMBER_VALUE_TRAITS_HPP
|
||||||
|
|
||||||
|
#include <boost/intrusive/detail/config_begin.hpp>
|
||||||
|
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||||
|
|
||||||
#include <boost/intrusive/link_mode.hpp>
|
#include <boost/intrusive/link_mode.hpp>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <boost/intrusive/detail/parent_from_member.hpp>
|
#include <boost/intrusive/detail/parent_from_member.hpp>
|
||||||
@ -26,7 +29,11 @@ namespace intrusive {
|
|||||||
//!store a node_traits::node
|
//!store a node_traits::node
|
||||||
template< class T, class NodeTraits
|
template< class T, class NodeTraits
|
||||||
, typename NodeTraits::node T::* PtrToMember
|
, typename NodeTraits::node T::* PtrToMember
|
||||||
, link_mode_type LinkMode = safe_link>
|
, link_mode_type LinkMode
|
||||||
|
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
|
= safe_link
|
||||||
|
#endif
|
||||||
|
>
|
||||||
struct member_value_traits
|
struct member_value_traits
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -67,4 +74,6 @@ struct member_value_traits
|
|||||||
} //namespace intrusive
|
} //namespace intrusive
|
||||||
} //namespace boost
|
} //namespace boost
|
||||||
|
|
||||||
|
#include <boost/intrusive/detail/config_end.hpp>
|
||||||
|
|
||||||
#endif //BOOST_INTRUSIVE_MEMBER_VALUE_TRAITS_HPP
|
#endif //BOOST_INTRUSIVE_MEMBER_VALUE_TRAITS_HPP
|
||||||
|
@ -16,15 +16,15 @@
|
|||||||
#include <boost/intrusive/detail/config_begin.hpp>
|
#include <boost/intrusive/detail/config_begin.hpp>
|
||||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||||
#include <boost/intrusive/link_mode.hpp>
|
#include <boost/intrusive/link_mode.hpp>
|
||||||
|
#include <boost/intrusive/pack_options.hpp>
|
||||||
#include <boost/intrusive/detail/mpl.hpp>
|
#include <boost/intrusive/detail/mpl.hpp>
|
||||||
#include <boost/intrusive/detail/utilities.hpp>
|
#include <boost/intrusive/detail/utilities.hpp>
|
||||||
#include <boost/static_assert.hpp>
|
#include <boost/static_assert.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
namespace intrusive {
|
namespace intrusive {
|
||||||
|
|
||||||
/// @cond
|
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
|
|
||||||
//typedef void default_tag;
|
//typedef void default_tag;
|
||||||
struct default_tag;
|
struct default_tag;
|
||||||
@ -34,8 +34,6 @@ namespace detail{
|
|||||||
|
|
||||||
struct default_hook_tag{};
|
struct default_hook_tag{};
|
||||||
|
|
||||||
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
|
||||||
|
|
||||||
#define BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER) \
|
#define BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER) \
|
||||||
struct BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER : public default_hook_tag\
|
struct BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER : public default_hook_tag\
|
||||||
{\
|
{\
|
||||||
@ -50,35 +48,9 @@ BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_rbtree_hook);
|
|||||||
BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_hashtable_hook);
|
BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_hashtable_hook);
|
||||||
BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_avltree_hook);
|
BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_avltree_hook);
|
||||||
BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_bstree_hook);
|
BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_bstree_hook);
|
||||||
//BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_splaytree_hook);
|
|
||||||
//BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_sgtree_hook);
|
|
||||||
//BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_treap_hook);
|
|
||||||
|
|
||||||
#undef BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION
|
#undef BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION
|
||||||
|
|
||||||
#endif //BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
|
||||||
|
|
||||||
template <class ValueTraits>
|
|
||||||
struct eval_value_traits
|
|
||||||
{
|
|
||||||
typedef typename ValueTraits::value_traits type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class ValueTraits>
|
|
||||||
struct get_real_value_traits
|
|
||||||
: public eval_if_c
|
|
||||||
< external_value_traits_bool_is_true<ValueTraits>::value
|
|
||||||
, eval_value_traits<ValueTraits>
|
|
||||||
, identity<ValueTraits>
|
|
||||||
>
|
|
||||||
{};
|
|
||||||
|
|
||||||
template <class BucketTraits>
|
|
||||||
struct eval_bucket_traits
|
|
||||||
{
|
|
||||||
typedef typename BucketTraits::bucket_traits type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T, class BaseHook>
|
template <class T, class BaseHook>
|
||||||
struct concrete_hook_base_value_traits
|
struct concrete_hook_base_value_traits
|
||||||
{
|
{
|
||||||
@ -165,7 +137,7 @@ struct get_value_traits
|
|||||||
//...get it's internal value traits using
|
//...get it's internal value traits using
|
||||||
//the provided T value type.
|
//the provided T value type.
|
||||||
, get_base_value_traits<T, supposed_value_traits>
|
, get_base_value_traits<T, supposed_value_traits>
|
||||||
//...else use it's internal value traits tag
|
//...else use its internal value traits tag
|
||||||
//(member hooks and custom value traits are in this group)
|
//(member hooks and custom value traits are in this group)
|
||||||
, detail::eval_if_c
|
, detail::eval_if_c
|
||||||
< internal_member_value_traits<supposed_value_traits>::value
|
< internal_member_value_traits<supposed_value_traits>::value
|
||||||
@ -191,7 +163,7 @@ struct get_node_traits
|
|||||||
//...get it's internal value traits using
|
//...get it's internal value traits using
|
||||||
//the provided T value type.
|
//the provided T value type.
|
||||||
, get_base_node_traits<supposed_value_traits>
|
, get_base_node_traits<supposed_value_traits>
|
||||||
//...else use it's internal value traits tag
|
//...else use its internal value traits tag
|
||||||
//(member hooks and custom value traits are in this group)
|
//(member hooks and custom value traits are in this group)
|
||||||
, detail::eval_if_c
|
, detail::eval_if_c
|
||||||
< internal_member_value_traits<supposed_value_traits>::value
|
< internal_member_value_traits<supposed_value_traits>::value
|
||||||
@ -203,50 +175,20 @@ struct get_node_traits
|
|||||||
|
|
||||||
} //namespace detail{
|
} //namespace detail{
|
||||||
|
|
||||||
/// @endcond
|
#endif //BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
|
|
||||||
//!This option setter specifies if the intrusive
|
//!This option setter specifies if the intrusive
|
||||||
//!container stores its size as a member to
|
//!container stores its size as a member to
|
||||||
//!obtain constant-time size() member.
|
//!obtain constant-time size() member.
|
||||||
template<bool Enabled>
|
BOOST_INTRUSIVE_OPTION_CONSTANT(constant_time_size, bool, Enabled, constant_time_size)
|
||||||
struct constant_time_size
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
static const bool constant_time_size = Enabled;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter specifies the type that
|
//!This option setter specifies the type that
|
||||||
//!the container will use to store its size.
|
//!the container will use to store its size.
|
||||||
template<class SizeType>
|
BOOST_INTRUSIVE_OPTION_TYPE(size_type, SizeType, SizeType, size_type)
|
||||||
struct size_type
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
typedef SizeType size_type;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter specifies the strict weak ordering
|
//!This option setter specifies the strict weak ordering
|
||||||
//!comparison functor for the value type
|
//!comparison functor for the value type
|
||||||
template<class Compare>
|
BOOST_INTRUSIVE_OPTION_TYPE(compare, Compare, Compare, compare)
|
||||||
struct compare
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
typedef Compare compare;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter for scapegoat containers specifies if
|
//!This option setter for scapegoat containers specifies if
|
||||||
//!the intrusive scapegoat container should use a non-variable
|
//!the intrusive scapegoat container should use a non-variable
|
||||||
@ -260,74 +202,39 @@ struct compare
|
|||||||
//!If the user only needs an alpha value near 1/sqrt(2), this
|
//!If the user only needs an alpha value near 1/sqrt(2), this
|
||||||
//!option also improves performance since avoids logarithm
|
//!option also improves performance since avoids logarithm
|
||||||
//!and division operations when rebalancing the tree.
|
//!and division operations when rebalancing the tree.
|
||||||
template<bool Enabled>
|
BOOST_INTRUSIVE_OPTION_CONSTANT(floating_point, bool, Enabled, floating_point)
|
||||||
struct floating_point
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
static const bool floating_point = Enabled;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter specifies the equality
|
//!This option setter specifies the equality
|
||||||
//!functor for the value type
|
//!functor for the value type
|
||||||
template<class Equal>
|
BOOST_INTRUSIVE_OPTION_TYPE(equal, Equal, Equal, equal)
|
||||||
struct equal
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
typedef Equal equal;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter specifies the equality
|
//!This option setter specifies the equality
|
||||||
//!functor for the value type
|
//!functor for the value type
|
||||||
template<class Priority>
|
BOOST_INTRUSIVE_OPTION_TYPE(priority, Priority, Priority, priority)
|
||||||
struct priority
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
typedef Priority priority;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter specifies the hash
|
//!This option setter specifies the hash
|
||||||
//!functor for the value type
|
//!functor for the value type
|
||||||
template<class Hash>
|
BOOST_INTRUSIVE_OPTION_TYPE(hash, Hash, Hash, hash)
|
||||||
struct hash
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
typedef Hash hash;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter specifies the relationship between the type
|
//!This option setter specifies the relationship between the type
|
||||||
//!to be managed by the container (the value type) and the node to be
|
//!to be managed by the container (the value type) and the node to be
|
||||||
//!used in the node algorithms. It also specifies the linking policy.
|
//!used in the node algorithms. It also specifies the linking policy.
|
||||||
template<typename ValueTraits>
|
BOOST_INTRUSIVE_OPTION_TYPE(value_traits, ValueTraits, ValueTraits, proto_value_traits)
|
||||||
struct value_traits
|
|
||||||
{
|
//#define BOOST_INTRUSIVE_COMMA ,
|
||||||
/// @cond
|
//#define BOOST_INTRUSIVE_LESS <
|
||||||
template<class Base>
|
//#define BOOST_INTRUSIVE_MORE >
|
||||||
struct pack : Base
|
//BOOST_INTRUSIVE_OPTION_TYPE (member_hook, Parent BOOST_INTRUSIVE_COMMA class MemberHook BOOST_INTRUSIVE_COMMA MemberHook Parent::* PtrToMember , mhtraits BOOST_INTRUSIVE_LESS Parent BOOST_INTRUSIVE_COMMA MemberHook BOOST_INTRUSIVE_COMMA PtrToMember BOOST_INTRUSIVE_MORE , proto_value_traits)
|
||||||
{
|
//template< class Parent , class MemberHook , MemberHook Parent::* PtrToMember>
|
||||||
typedef ValueTraits proto_value_traits;
|
//struct member_hook {
|
||||||
};
|
// template<class Base> struct pack : Base {
|
||||||
/// @endcond
|
// typedef mhtraits < Parent , MemberHook , PtrToMember > proto_value_traits;
|
||||||
};
|
// };
|
||||||
|
//};
|
||||||
|
//
|
||||||
|
//#undef BOOST_INTRUSIVE_COMMA
|
||||||
|
//#undef BOOST_INTRUSIVE_LESS
|
||||||
|
//#undef BOOST_INTRUSIVE_MORE
|
||||||
|
|
||||||
//!This option setter specifies the member hook the
|
//!This option setter specifies the member hook the
|
||||||
//!container must use.
|
//!container must use.
|
||||||
@ -336,27 +243,21 @@ template< typename Parent
|
|||||||
, MemberHook Parent::* PtrToMember>
|
, MemberHook Parent::* PtrToMember>
|
||||||
struct member_hook
|
struct member_hook
|
||||||
{
|
{
|
||||||
/// @cond
|
// @cond
|
||||||
/*
|
// typedef typename MemberHook::hooktags::node_traits node_traits;
|
||||||
typedef typename MemberHook::hooktags::node_traits node_traits;
|
// typedef typename node_traits::node node_type;
|
||||||
typedef typename node_traits::node node_type;
|
// typedef node_type Parent::* Ptr2MemNode;
|
||||||
typedef node_type Parent::* Ptr2MemNode;
|
// typedef mhtraits
|
||||||
typedef mhtraits
|
// < Parent
|
||||||
< Parent
|
// , node_traits
|
||||||
, node_traits
|
// //This cast is really ugly but necessary to reduce template bloat.
|
||||||
//This cast is really ugly but necessary to reduce template bloat.
|
// //Since we control the layout between the hook and the node, and there is
|
||||||
//Since we control the layout between the hook and the node, and there is
|
// //always single inheritance, the offset of the node is exactly the offset of
|
||||||
//always single inheritance, the offset of the node is exactly the offset of
|
// //the hook. Since the node type is shared between all member hooks, this saves
|
||||||
//the hook. Since the node type is shared between all member hooks, this saves
|
// //quite a lot of symbol stuff.
|
||||||
//quite a lot of symbol stuff.
|
// , (Ptr2MemNode)PtrToMember
|
||||||
, (Ptr2MemNode)PtrToMember
|
// , MemberHook::hooktags::link_mode> member_value_traits;
|
||||||
, MemberHook::hooktags::link_mode> member_value_traits;
|
typedef mhtraits <Parent, MemberHook, PtrToMember> member_value_traits;
|
||||||
*/
|
|
||||||
typedef mhtraits
|
|
||||||
< Parent
|
|
||||||
, MemberHook
|
|
||||||
, PtrToMember
|
|
||||||
> member_value_traits;
|
|
||||||
template<class Base>
|
template<class Base>
|
||||||
struct pack : Base
|
struct pack : Base
|
||||||
{
|
{
|
||||||
@ -365,158 +266,55 @@ struct member_hook
|
|||||||
/// @endcond
|
/// @endcond
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//!This option setter specifies the function object that will
|
//!This option setter specifies the function object that will
|
||||||
//!be used to convert between values to be inserted in a container
|
//!be used to convert between values to be inserted in a container
|
||||||
//!and the hook to be used for that purpose.
|
//!and the hook to be used for that purpose.
|
||||||
template< typename Functor>
|
BOOST_INTRUSIVE_OPTION_TYPE(function_hook, Functor, fhtraits<Functor>, proto_value_traits)
|
||||||
struct function_hook
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
typedef fhtraits
|
|
||||||
<Functor> function_value_traits;
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
typedef function_value_traits proto_value_traits;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//!This option setter specifies that the container
|
//!This option setter specifies that the container
|
||||||
//!must use the specified base hook
|
//!must use the specified base hook
|
||||||
template<typename BaseHook>
|
BOOST_INTRUSIVE_OPTION_TYPE(base_hook, BaseHook, BaseHook, proto_value_traits)
|
||||||
struct base_hook
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
typedef BaseHook proto_value_traits;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter specifies the type of
|
//!This option setter specifies the type of
|
||||||
//!a void pointer. This will instruct the hook
|
//!a void pointer. This will instruct the hook
|
||||||
//!to use this type of pointer instead of the
|
//!to use this type of pointer instead of the
|
||||||
//!default one
|
//!default one
|
||||||
template<class VoidPointer>
|
BOOST_INTRUSIVE_OPTION_TYPE(void_pointer, VoidPointer, VoidPointer, void_pointer)
|
||||||
struct void_pointer
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
typedef VoidPointer void_pointer;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter specifies the type of
|
//!This option setter specifies the type of
|
||||||
//!the tag of a base hook. A type cannot have two
|
//!the tag of a base hook. A type cannot have two
|
||||||
//!base hooks of the same type, so a tag can be used
|
//!base hooks of the same type, so a tag can be used
|
||||||
//!to differentiate two base hooks with otherwise same type
|
//!to differentiate two base hooks with otherwise same type
|
||||||
template<class Tag>
|
BOOST_INTRUSIVE_OPTION_TYPE(tag, Tag, Tag, tag)
|
||||||
struct tag
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
typedef Tag tag;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter specifies the link mode
|
//!This option setter specifies the link mode
|
||||||
//!(normal_link, safe_link or auto_unlink)
|
//!(normal_link, safe_link or auto_unlink)
|
||||||
template<link_mode_type LinkType>
|
BOOST_INTRUSIVE_OPTION_CONSTANT(link_mode, link_mode_type, LinkType, link_mode)
|
||||||
struct link_mode
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
static const link_mode_type link_mode = LinkType;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter specifies if the hook
|
//!This option setter specifies if the hook
|
||||||
//!should be optimized for size instead of for speed.
|
//!should be optimized for size instead of for speed.
|
||||||
template<bool Enabled>
|
BOOST_INTRUSIVE_OPTION_CONSTANT(optimize_size, bool, Enabled, optimize_size)
|
||||||
struct optimize_size
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
static const bool optimize_size = Enabled;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter specifies if the list container should
|
//!This option setter specifies if the slist container should
|
||||||
//!use a linear implementation instead of a circular one.
|
//!use a linear implementation instead of a circular one.
|
||||||
template<bool Enabled>
|
BOOST_INTRUSIVE_OPTION_CONSTANT(linear, bool, Enabled, linear)
|
||||||
struct linear
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
static const bool linear = Enabled;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter specifies if the list container should
|
//!If true, slist also stores a pointer to the last element of the singly linked list.
|
||||||
//!use a linear implementation instead of a circular one.
|
//!This allows O(1) swap and splice_after(iterator, slist &) for circular slists and makes
|
||||||
template<bool Enabled>
|
//!possible new functions like push_back(reference) and back().
|
||||||
struct cache_last
|
BOOST_INTRUSIVE_OPTION_CONSTANT(cache_last, bool, Enabled, cache_last)
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
static const bool cache_last = Enabled;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter specifies the bucket traits
|
//!This option setter specifies the bucket traits
|
||||||
//!class for unordered associative containers. When this option is specified,
|
//!class for unordered associative containers. When this option is specified,
|
||||||
//!instead of using the default bucket traits, a user defined holder will be defined
|
//!instead of using the default bucket traits, a user defined holder will be defined
|
||||||
template<class BucketTraits>
|
BOOST_INTRUSIVE_OPTION_TYPE(bucket_traits, BucketTraits, BucketTraits, bucket_traits)
|
||||||
struct bucket_traits
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
typedef BucketTraits bucket_traits;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter specifies if the unordered hook
|
//!This option setter specifies if the unordered hook
|
||||||
//!should offer room to store the hash value.
|
//!should offer room to store the hash value.
|
||||||
//!Storing the hash in the hook will speed up rehashing
|
//!Storing the hash in the hook will speed up rehashing
|
||||||
//!processes in applications where rehashing is frequent,
|
//!processes in applications where rehashing is frequent,
|
||||||
//!rehashing might throw or the value is heavy to hash.
|
//!rehashing might throw or the value is heavy to hash.
|
||||||
template<bool Enabled>
|
BOOST_INTRUSIVE_OPTION_CONSTANT(store_hash, bool, Enabled, store_hash)
|
||||||
struct store_hash
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
static const bool store_hash = Enabled;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter specifies if the unordered hook
|
//!This option setter specifies if the unordered hook
|
||||||
//!should offer room to store another link to another node
|
//!should offer room to store another link to another node
|
||||||
@ -524,51 +322,20 @@ struct store_hash
|
|||||||
//!Storing this link will speed up lookups and insertions on
|
//!Storing this link will speed up lookups and insertions on
|
||||||
//!unordered_multiset containers with a great number of elements
|
//!unordered_multiset containers with a great number of elements
|
||||||
//!with the same key.
|
//!with the same key.
|
||||||
template<bool Enabled>
|
BOOST_INTRUSIVE_OPTION_CONSTANT(optimize_multikey, bool, Enabled, optimize_multikey)
|
||||||
struct optimize_multikey
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
static const bool optimize_multikey = Enabled;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter specifies if the bucket array will be always power of two.
|
//!This option setter specifies if the bucket array will be always power of two.
|
||||||
//!This allows using masks instead of the default modulo operation to determine
|
//!This allows using masks instead of the default modulo operation to determine
|
||||||
//!the bucket number from the hash value, leading to better performance.
|
//!the bucket number from the hash value, leading to better performance.
|
||||||
//!In debug mode, if power of two buckets mode is activated, the bucket length
|
//!In debug mode, if power of two buckets mode is activated, the bucket length
|
||||||
//!will be checked to through assertions to assure the bucket length is power of two.
|
//!will be checked to through assertions to assure the bucket length is power of two.
|
||||||
template<bool Enabled>
|
BOOST_INTRUSIVE_OPTION_CONSTANT(power_2_buckets, bool, Enabled, power_2_buckets)
|
||||||
struct power_2_buckets
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
static const bool power_2_buckets = Enabled;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter specifies if the container will cache a pointer to the first
|
//!This option setter specifies if the container will cache a pointer to the first
|
||||||
//!non-empty bucket so that begin() is always constant-time.
|
//!non-empty bucket so that begin() is always constant-time.
|
||||||
//!This is specially helpful when we can have containers with a few elements
|
//!This is specially helpful when we can have containers with a few elements
|
||||||
//!but with big bucket arrays (that is, hashtables with low load factors).
|
//!but with big bucket arrays (that is, hashtables with low load factors).
|
||||||
template<bool Enabled>
|
BOOST_INTRUSIVE_OPTION_CONSTANT(cache_begin, bool, Enabled, cache_begin)
|
||||||
struct cache_begin
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
static const bool cache_begin = Enabled;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//!This option setter specifies if the container will compare the hash value
|
//!This option setter specifies if the container will compare the hash value
|
||||||
//!before comparing objects. This option can't be specified if store_hash<>
|
//!before comparing objects. This option can't be specified if store_hash<>
|
||||||
@ -576,17 +343,7 @@ struct cache_begin
|
|||||||
//!This is specially helpful when we have containers with a high load factor.
|
//!This is specially helpful when we have containers with a high load factor.
|
||||||
//!and the comparison function is much more expensive that comparing already
|
//!and the comparison function is much more expensive that comparing already
|
||||||
//!stored hash values.
|
//!stored hash values.
|
||||||
template<bool Enabled>
|
BOOST_INTRUSIVE_OPTION_CONSTANT(compare_hash, bool, Enabled, compare_hash)
|
||||||
struct compare_hash
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
static const bool compare_hash = Enabled;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter specifies if the hash container will use incremental
|
//!This option setter specifies if the hash container will use incremental
|
||||||
//!hashing. With incremental hashing the cost of hash table expansion is spread
|
//!hashing. With incremental hashing the cost of hash table expansion is spread
|
||||||
@ -594,17 +351,7 @@ struct compare_hash
|
|||||||
//!Therefore linear hashing is well suited for interactive applications or real-time
|
//!Therefore linear hashing is well suited for interactive applications or real-time
|
||||||
//!appplications where the worst-case insertion time of non-incremental hash containers
|
//!appplications where the worst-case insertion time of non-incremental hash containers
|
||||||
//!(rehashing the whole bucket array) is not admisible.
|
//!(rehashing the whole bucket array) is not admisible.
|
||||||
template<bool Enabled>
|
BOOST_INTRUSIVE_OPTION_CONSTANT(incremental, bool, Enabled, incremental)
|
||||||
struct incremental
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
static const bool incremental = Enabled;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
/// @cond
|
/// @cond
|
||||||
|
|
||||||
@ -615,210 +362,6 @@ struct none
|
|||||||
{};
|
{};
|
||||||
};
|
};
|
||||||
|
|
||||||
//To-do: pass to variadic templates
|
|
||||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
|
||||||
|
|
||||||
template<class Prev, class Next>
|
|
||||||
struct do_pack
|
|
||||||
{
|
|
||||||
//Use "pack" member template to pack options
|
|
||||||
typedef typename Next::template pack<Prev> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class Prev>
|
|
||||||
struct do_pack<Prev, void>
|
|
||||||
{
|
|
||||||
//Avoid packing "void" to shorten template names
|
|
||||||
typedef Prev type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template
|
|
||||||
< class DefaultOptions
|
|
||||||
, class O1 = void
|
|
||||||
, class O2 = void
|
|
||||||
, class O3 = void
|
|
||||||
, class O4 = void
|
|
||||||
, class O5 = void
|
|
||||||
, class O6 = void
|
|
||||||
, class O7 = void
|
|
||||||
, class O8 = void
|
|
||||||
, class O9 = void
|
|
||||||
, class O10 = void
|
|
||||||
, class O11 = void
|
|
||||||
>
|
|
||||||
struct pack_options
|
|
||||||
{
|
|
||||||
// join options
|
|
||||||
typedef
|
|
||||||
typename do_pack
|
|
||||||
< typename do_pack
|
|
||||||
< typename do_pack
|
|
||||||
< typename do_pack
|
|
||||||
< typename do_pack
|
|
||||||
< typename do_pack
|
|
||||||
< typename do_pack
|
|
||||||
< typename do_pack
|
|
||||||
< typename do_pack
|
|
||||||
< typename do_pack
|
|
||||||
< typename do_pack
|
|
||||||
< DefaultOptions
|
|
||||||
, O1
|
|
||||||
>::type
|
|
||||||
, O2
|
|
||||||
>::type
|
|
||||||
, O3
|
|
||||||
>::type
|
|
||||||
, O4
|
|
||||||
>::type
|
|
||||||
, O5
|
|
||||||
>::type
|
|
||||||
, O6
|
|
||||||
>::type
|
|
||||||
, O7
|
|
||||||
>::type
|
|
||||||
, O8
|
|
||||||
>::type
|
|
||||||
, O9
|
|
||||||
>::type
|
|
||||||
, O10
|
|
||||||
>::type
|
|
||||||
, O11
|
|
||||||
>::type
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
|
|
||||||
//index_tuple
|
|
||||||
template<int... Indexes>
|
|
||||||
struct index_tuple{};
|
|
||||||
|
|
||||||
//build_number_seq
|
|
||||||
template<std::size_t Num, typename Tuple = index_tuple<> >
|
|
||||||
struct build_number_seq;
|
|
||||||
|
|
||||||
template<std::size_t Num, int... Indexes>
|
|
||||||
struct build_number_seq<Num, index_tuple<Indexes...> >
|
|
||||||
: build_number_seq<Num - 1, index_tuple<Indexes..., sizeof...(Indexes)> >
|
|
||||||
{};
|
|
||||||
|
|
||||||
template<int... Indexes>
|
|
||||||
struct build_number_seq<0, index_tuple<Indexes...> >
|
|
||||||
{ typedef index_tuple<Indexes...> type; };
|
|
||||||
|
|
||||||
template<class ...Types>
|
|
||||||
struct typelist
|
|
||||||
{};
|
|
||||||
|
|
||||||
//invert_typelist
|
|
||||||
template<class T>
|
|
||||||
struct invert_typelist;
|
|
||||||
|
|
||||||
template<int I, typename Tuple>
|
|
||||||
struct typelist_element;
|
|
||||||
|
|
||||||
template<int I, typename Head, typename... Tail>
|
|
||||||
struct typelist_element<I, typelist<Head, Tail...> >
|
|
||||||
{
|
|
||||||
typedef typename typelist_element<I-1, typelist<Tail...> >::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Head, typename... Tail>
|
|
||||||
struct typelist_element<0, typelist<Head, Tail...> >
|
|
||||||
{
|
|
||||||
typedef Head type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<int ...Ints, class ...Types>
|
|
||||||
typelist<typename typelist_element<(sizeof...(Types) - 1) - Ints, typelist<Types...> >::type...>
|
|
||||||
inverted_typelist(index_tuple<Ints...>, typelist<Types...>)
|
|
||||||
{
|
|
||||||
return typelist<typename typelist_element<(sizeof...(Types) - 1) - Ints, typelist<Types...> >::type...>();
|
|
||||||
}
|
|
||||||
|
|
||||||
//sizeof_typelist
|
|
||||||
template<class Typelist>
|
|
||||||
struct sizeof_typelist;
|
|
||||||
|
|
||||||
template<class ...Types>
|
|
||||||
struct sizeof_typelist< typelist<Types...> >
|
|
||||||
{
|
|
||||||
static const std::size_t value = sizeof...(Types);
|
|
||||||
};
|
|
||||||
|
|
||||||
//invert_typelist_impl
|
|
||||||
template<class Typelist, class Indexes>
|
|
||||||
struct invert_typelist_impl;
|
|
||||||
|
|
||||||
|
|
||||||
template<class Typelist, int ...Ints>
|
|
||||||
struct invert_typelist_impl< Typelist, index_tuple<Ints...> >
|
|
||||||
{
|
|
||||||
static const std::size_t last_idx = sizeof_typelist<Typelist>::value - 1;
|
|
||||||
typedef typelist
|
|
||||||
<typename typelist_element<last_idx - Ints, Typelist>::type...> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class Typelist, int Int>
|
|
||||||
struct invert_typelist_impl< Typelist, index_tuple<Int> >
|
|
||||||
{
|
|
||||||
typedef Typelist type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class Typelist>
|
|
||||||
struct invert_typelist_impl< Typelist, index_tuple<> >
|
|
||||||
{
|
|
||||||
typedef Typelist type;
|
|
||||||
};
|
|
||||||
|
|
||||||
//invert_typelist
|
|
||||||
template<class Typelist>
|
|
||||||
struct invert_typelist;
|
|
||||||
|
|
||||||
template<class ...Types>
|
|
||||||
struct invert_typelist< typelist<Types...> >
|
|
||||||
{
|
|
||||||
typedef typelist<Types...> typelist_t;
|
|
||||||
typedef typename build_number_seq<sizeof...(Types)>::type indexes_t;
|
|
||||||
typedef typename invert_typelist_impl<typelist_t, indexes_t>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
//Do pack
|
|
||||||
template<class Typelist>
|
|
||||||
struct do_pack;
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct do_pack<typelist<> >;
|
|
||||||
|
|
||||||
template<class Prev>
|
|
||||||
struct do_pack<typelist<Prev> >
|
|
||||||
{
|
|
||||||
typedef Prev type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class Prev, class Last>
|
|
||||||
struct do_pack<typelist<Prev, Last> >
|
|
||||||
{
|
|
||||||
typedef typename Prev::template pack<Last> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class Prev, class ...Others>
|
|
||||||
struct do_pack<typelist<Prev, Others...> >
|
|
||||||
{
|
|
||||||
typedef typename Prev::template pack
|
|
||||||
<typename do_pack<typelist<Others...> >::type> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template<class ...Options>
|
|
||||||
struct pack_options
|
|
||||||
{
|
|
||||||
typedef typelist<Options...> typelist_t;
|
|
||||||
typedef typename invert_typelist<typelist_t>::type inverted_typelist;
|
|
||||||
typedef typename do_pack<inverted_typelist>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct hook_defaults
|
struct hook_defaults
|
||||||
{
|
{
|
||||||
typedef void* void_pointer;
|
typedef void* void_pointer;
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
#define BOOST_INTRUSIVE_GET_PARENT_FROM_MEMBER_HPP
|
#define BOOST_INTRUSIVE_GET_PARENT_FROM_MEMBER_HPP
|
||||||
|
|
||||||
#include <boost/intrusive/detail/config_begin.hpp>
|
#include <boost/intrusive/detail/config_begin.hpp>
|
||||||
|
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||||
|
|
||||||
#include <boost/intrusive/detail/parent_from_member.hpp>
|
#include <boost/intrusive/detail/parent_from_member.hpp>
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
#ifndef BOOST_INTRUSIVE_POINTER_PLUS_BITS_HPP
|
#ifndef BOOST_INTRUSIVE_POINTER_PLUS_BITS_HPP
|
||||||
#define BOOST_INTRUSIVE_POINTER_PLUS_BITS_HPP
|
#define BOOST_INTRUSIVE_POINTER_PLUS_BITS_HPP
|
||||||
|
|
||||||
|
#include <boost/intrusive/detail/config_begin.hpp>
|
||||||
|
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||||
#include <boost/intrusive/detail/mpl.hpp> //ls_zeros
|
#include <boost/intrusive/detail/mpl.hpp> //ls_zeros
|
||||||
#include <boost/intrusive/detail/assert.hpp> //BOOST_INTRUSIVE_INVARIANT_ASSERT
|
#include <boost/intrusive/detail/assert.hpp> //BOOST_INTRUSIVE_INVARIANT_ASSERT
|
||||||
|
|
||||||
@ -83,4 +85,6 @@ struct pointer_plus_bits<T*, NumBits>
|
|||||||
} //namespace intrusive
|
} //namespace intrusive
|
||||||
} //namespace boost
|
} //namespace boost
|
||||||
|
|
||||||
|
#include <boost/intrusive/detail/config_end.hpp>
|
||||||
|
|
||||||
#endif //BOOST_INTRUSIVE_POINTER_PLUS_BITS_HPP
|
#endif //BOOST_INTRUSIVE_POINTER_PLUS_BITS_HPP
|
||||||
|
@ -17,11 +17,12 @@
|
|||||||
#ifndef BOOST_INTRUSIVE_POINTER_TRAITS_HPP
|
#ifndef BOOST_INTRUSIVE_POINTER_TRAITS_HPP
|
||||||
#define BOOST_INTRUSIVE_POINTER_TRAITS_HPP
|
#define BOOST_INTRUSIVE_POINTER_TRAITS_HPP
|
||||||
|
|
||||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
#if defined(_MSC_VER)
|
||||||
# pragma once
|
# pragma once
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <boost/intrusive/detail/config_begin.hpp>
|
#include <boost/intrusive/detail/config_begin.hpp>
|
||||||
|
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||||
#include <boost/intrusive/detail/workaround.hpp>
|
#include <boost/intrusive/detail/workaround.hpp>
|
||||||
#include <boost/intrusive/detail/memory_util.hpp>
|
#include <boost/intrusive/detail/memory_util.hpp>
|
||||||
#include <boost/type_traits/integral_constant.hpp>
|
#include <boost/type_traits/integral_constant.hpp>
|
||||||
|
@ -23,8 +23,12 @@ namespace intrusive {
|
|||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
struct priority_compare
|
struct priority_compare
|
||||||
: public std::binary_function<T, T, bool>
|
|
||||||
{
|
{
|
||||||
|
//Compatibility with std::binary_function
|
||||||
|
typedef T first_argument_type;
|
||||||
|
typedef T second_argument_type;
|
||||||
|
typedef bool result_type;
|
||||||
|
|
||||||
bool operator()(const T &val, const T &val2) const
|
bool operator()(const T &val, const T &val2) const
|
||||||
{
|
{
|
||||||
return priority_order(val, val2);
|
return priority_order(val, val2);
|
||||||
|
@ -13,13 +13,13 @@
|
|||||||
#define BOOST_INTRUSIVE_RBTREE_HPP
|
#define BOOST_INTRUSIVE_RBTREE_HPP
|
||||||
|
|
||||||
#include <boost/intrusive/detail/config_begin.hpp>
|
#include <boost/intrusive/detail/config_begin.hpp>
|
||||||
|
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include <boost/intrusive/detail/assert.hpp>
|
#include <boost/intrusive/detail/assert.hpp>
|
||||||
#include <boost/static_assert.hpp>
|
#include <boost/static_assert.hpp>
|
||||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
|
||||||
#include <boost/intrusive/set_hook.hpp>
|
#include <boost/intrusive/set_hook.hpp>
|
||||||
#include <boost/intrusive/detail/rbtree_node.hpp>
|
#include <boost/intrusive/detail/rbtree_node.hpp>
|
||||||
#include <boost/intrusive/bstree.hpp>
|
#include <boost/intrusive/bstree.hpp>
|
||||||
@ -292,7 +292,7 @@ class rbtree_impl
|
|||||||
//! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const
|
//! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const
|
||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
size_type count(const KeyType& key, KeyValueCompare comp) const;
|
size_type count(const KeyType& key, KeyValueCompare comp) const;
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)
|
//! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)
|
||||||
iterator lower_bound(const_reference value);
|
iterator lower_bound(const_reference value);
|
||||||
|
|
||||||
@ -483,14 +483,13 @@ class rbtree
|
|||||||
public:
|
public:
|
||||||
typedef typename Base::value_compare value_compare;
|
typedef typename Base::value_compare value_compare;
|
||||||
typedef typename Base::value_traits value_traits;
|
typedef typename Base::value_traits value_traits;
|
||||||
typedef typename Base::real_value_traits real_value_traits;
|
|
||||||
typedef typename Base::iterator iterator;
|
typedef typename Base::iterator iterator;
|
||||||
typedef typename Base::const_iterator const_iterator;
|
typedef typename Base::const_iterator const_iterator;
|
||||||
typedef typename Base::reverse_iterator reverse_iterator;
|
typedef typename Base::reverse_iterator reverse_iterator;
|
||||||
typedef typename Base::const_reverse_iterator const_reverse_iterator;
|
typedef typename Base::const_reverse_iterator const_reverse_iterator;
|
||||||
|
|
||||||
//Assert if passed value traits are compatible with the type
|
//Assert if passed value traits are compatible with the type
|
||||||
BOOST_STATIC_ASSERT((detail::is_same<typename real_value_traits::value_type, T>::value));
|
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
|
||||||
|
|
||||||
explicit rbtree( const value_compare &cmp = value_compare()
|
explicit rbtree( const value_compare &cmp = value_compare()
|
||||||
, const value_traits &v_traits = value_traits())
|
, const value_traits &v_traits = value_traits())
|
||||||
|
@ -10,31 +10,6 @@
|
|||||||
// See http://www.boost.org/libs/intrusive for documentation.
|
// See http://www.boost.org/libs/intrusive for documentation.
|
||||||
//
|
//
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
// The internal implementation of red-black trees is based on that of SGI STL
|
|
||||||
// stl_tree.h file:
|
|
||||||
//
|
|
||||||
// Copyright (c) 1996,1997
|
|
||||||
// Silicon Graphics Computer Systems, Inc.
|
|
||||||
//
|
|
||||||
// Permission to use, copy, modify, distribute and sell this software
|
|
||||||
// and its documentation for any purpose is hereby granted without fee,
|
|
||||||
// provided that the above copyright notice appear in all copies and
|
|
||||||
// that both that copyright notice and this permission notice appear
|
|
||||||
// in supporting documentation. Silicon Graphics makes no
|
|
||||||
// representations about the suitability of this software for any
|
|
||||||
// purpose. It is provided "as is" without express or implied warranty.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Copyright (c) 1994
|
|
||||||
// Hewlett-Packard Company
|
|
||||||
//
|
|
||||||
// Permission to use, copy, modify, distribute and sell this software
|
|
||||||
// and its documentation for any purpose is hereby granted without fee,
|
|
||||||
// provided that the above copyright notice appear in all copies and
|
|
||||||
// that both that copyright notice and this permission notice appear
|
|
||||||
// in supporting documentation. Hewlett-Packard Company makes no
|
|
||||||
// representations about the suitability of this software for any
|
|
||||||
// purpose. It is provided "as is" without express or implied warranty.
|
|
||||||
//
|
//
|
||||||
// The tree destruction algorithm is based on Julienne Walker and The EC Team code:
|
// The tree destruction algorithm is based on Julienne Walker and The EC Team code:
|
||||||
//
|
//
|
||||||
@ -49,9 +24,9 @@
|
|||||||
#define BOOST_INTRUSIVE_RBTREE_ALGORITHMS_HPP
|
#define BOOST_INTRUSIVE_RBTREE_ALGORITHMS_HPP
|
||||||
|
|
||||||
#include <boost/intrusive/detail/config_begin.hpp>
|
#include <boost/intrusive/detail/config_begin.hpp>
|
||||||
|
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
|
||||||
|
|
||||||
#include <boost/intrusive/detail/assert.hpp>
|
#include <boost/intrusive/detail/assert.hpp>
|
||||||
#include <boost/intrusive/detail/utilities.hpp>
|
#include <boost/intrusive/detail/utilities.hpp>
|
||||||
@ -82,21 +57,6 @@ struct rbtree_node_cloner
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class NodeTraits>
|
|
||||||
struct rbtree_erase_fixup
|
|
||||||
{
|
|
||||||
typedef typename NodeTraits::node_ptr node_ptr;
|
|
||||||
typedef typename NodeTraits::color color;
|
|
||||||
|
|
||||||
void operator()(const node_ptr & to_erase, const node_ptr & successor)
|
|
||||||
{
|
|
||||||
//Swap color of y and z
|
|
||||||
color tmp(NodeTraits::get_color(successor));
|
|
||||||
NodeTraits::set_color(successor, NodeTraits::get_color(to_erase));
|
|
||||||
NodeTraits::set_color(to_erase, tmp);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif //#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
#endif //#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
|
|
||||||
//! rbtree_algorithms provides basic algorithms to manipulate
|
//! rbtree_algorithms provides basic algorithms to manipulate
|
||||||
@ -270,10 +230,18 @@ class rbtree_algorithms
|
|||||||
static node_ptr erase(const node_ptr & header, const node_ptr & z)
|
static node_ptr erase(const node_ptr & header, const node_ptr & z)
|
||||||
{
|
{
|
||||||
typename bstree_algo::data_for_rebalance info;
|
typename bstree_algo::data_for_rebalance info;
|
||||||
bstree_algo::erase(header, z, rbtree_erase_fixup<NodeTraits>(), info);
|
bstree_algo::erase(header, z, info);
|
||||||
|
|
||||||
//Rebalance rbtree
|
color new_z_color;
|
||||||
if(NodeTraits::get_color(z) != NodeTraits::red()){
|
if(info.y != z){
|
||||||
|
new_z_color = NodeTraits::get_color(info.y);
|
||||||
|
NodeTraits::set_color(info.y, NodeTraits::get_color(z));
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
new_z_color = NodeTraits::get_color(z);
|
||||||
|
}
|
||||||
|
//Rebalance rbtree if needed
|
||||||
|
if(new_z_color != NodeTraits::red()){
|
||||||
rebalance_after_erasure(header, info.x, info.x_parent);
|
rebalance_after_erasure(header, info.x, info.x_parent);
|
||||||
}
|
}
|
||||||
return z;
|
return z;
|
||||||
@ -322,6 +290,7 @@ class rbtree_algorithms
|
|||||||
//! @copydoc ::boost::intrusive::bstree_algorithms::count(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
//! @copydoc ::boost::intrusive::bstree_algorithms::count(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
||||||
template<class KeyType, class KeyNodePtrCompare>
|
template<class KeyType, class KeyNodePtrCompare>
|
||||||
static std::size_t count(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp);
|
static std::size_t count(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp);
|
||||||
|
|
||||||
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_upper_bound(const node_ptr&,const node_ptr&,NodePtrCompare)
|
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_upper_bound(const node_ptr&,const node_ptr&,NodePtrCompare)
|
||||||
@ -411,64 +380,76 @@ class rbtree_algorithms
|
|||||||
|
|
||||||
static void rebalance_after_erasure(const node_ptr & header, node_ptr x, node_ptr x_parent)
|
static void rebalance_after_erasure(const node_ptr & header, node_ptr x, node_ptr x_parent)
|
||||||
{
|
{
|
||||||
while(x != NodeTraits::get_parent(header) && (!x || NodeTraits::get_color(x) == NodeTraits::black())){
|
while(1){
|
||||||
if(x == NodeTraits::get_left(x_parent)){
|
if(x_parent == header || (x && NodeTraits::get_color(x) != NodeTraits::black())){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//Don't cache x_is_leftchild or similar because x can be null and
|
||||||
|
//equal to both x_parent_left and x_parent_right
|
||||||
|
const node_ptr x_parent_left(NodeTraits::get_left(x_parent));
|
||||||
|
if(x == x_parent_left){ //x is left child
|
||||||
node_ptr w = NodeTraits::get_right(x_parent);
|
node_ptr w = NodeTraits::get_right(x_parent);
|
||||||
BOOST_ASSERT(w);
|
BOOST_ASSERT(w);
|
||||||
if(NodeTraits::get_color(w) == NodeTraits::red()){
|
if(NodeTraits::get_color(w) == NodeTraits::red()){
|
||||||
NodeTraits::set_color(w, NodeTraits::black());
|
NodeTraits::set_color(w, NodeTraits::black());
|
||||||
NodeTraits::set_color(x_parent, NodeTraits::red());
|
NodeTraits::set_color(x_parent, NodeTraits::red());
|
||||||
bstree_algo::rotate_left(x_parent, header);
|
bstree_algo::rotate_left(x_parent, w, NodeTraits::get_parent(x_parent), header);
|
||||||
w = NodeTraits::get_right(x_parent);
|
w = NodeTraits::get_right(x_parent);
|
||||||
}
|
}
|
||||||
if((!NodeTraits::get_left(w) || NodeTraits::get_color(NodeTraits::get_left(w)) == NodeTraits::black()) &&
|
node_ptr const w_left (NodeTraits::get_left(w));
|
||||||
(!NodeTraits::get_right(w) || NodeTraits::get_color(NodeTraits::get_right(w)) == NodeTraits::black())){
|
node_ptr const w_right(NodeTraits::get_right(w));
|
||||||
|
if((!w_left || NodeTraits::get_color(w_left) == NodeTraits::black()) &&
|
||||||
|
(!w_right || NodeTraits::get_color(w_right) == NodeTraits::black())){
|
||||||
NodeTraits::set_color(w, NodeTraits::red());
|
NodeTraits::set_color(w, NodeTraits::red());
|
||||||
x = x_parent;
|
x = x_parent;
|
||||||
x_parent = NodeTraits::get_parent(x_parent);
|
x_parent = NodeTraits::get_parent(x_parent);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(!NodeTraits::get_right(w) || NodeTraits::get_color(NodeTraits::get_right(w)) == NodeTraits::black()){
|
if(!w_right || NodeTraits::get_color(w_right) == NodeTraits::black()){
|
||||||
NodeTraits::set_color(NodeTraits::get_left(w), NodeTraits::black());
|
NodeTraits::set_color(w_left, NodeTraits::black());
|
||||||
NodeTraits::set_color(w, NodeTraits::red());
|
NodeTraits::set_color(w, NodeTraits::red());
|
||||||
bstree_algo::rotate_right(w, header);
|
bstree_algo::rotate_right(w, w_left, NodeTraits::get_parent(w), header);
|
||||||
w = NodeTraits::get_right(x_parent);
|
w = NodeTraits::get_right(x_parent);
|
||||||
}
|
}
|
||||||
NodeTraits::set_color(w, NodeTraits::get_color(x_parent));
|
NodeTraits::set_color(w, NodeTraits::get_color(x_parent));
|
||||||
NodeTraits::set_color(x_parent, NodeTraits::black());
|
NodeTraits::set_color(x_parent, NodeTraits::black());
|
||||||
if(NodeTraits::get_right(w))
|
const node_ptr new_wright(NodeTraits::get_right(w));
|
||||||
NodeTraits::set_color(NodeTraits::get_right(w), NodeTraits::black());
|
if(new_wright)
|
||||||
bstree_algo::rotate_left(x_parent, header);
|
NodeTraits::set_color(new_wright, NodeTraits::black());
|
||||||
|
bstree_algo::rotate_left(x_parent, NodeTraits::get_right(x_parent), NodeTraits::get_parent(x_parent), header);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// same as above, with right_ <-> left_.
|
// same as above, with right_ <-> left_.
|
||||||
node_ptr w = NodeTraits::get_left(x_parent);
|
node_ptr w = x_parent_left;
|
||||||
if(NodeTraits::get_color(w) == NodeTraits::red()){
|
if(NodeTraits::get_color(w) == NodeTraits::red()){
|
||||||
NodeTraits::set_color(w, NodeTraits::black());
|
NodeTraits::set_color(w, NodeTraits::black());
|
||||||
NodeTraits::set_color(x_parent, NodeTraits::red());
|
NodeTraits::set_color(x_parent, NodeTraits::red());
|
||||||
bstree_algo::rotate_right(x_parent, header);
|
bstree_algo::rotate_right(x_parent, w, NodeTraits::get_parent(x_parent), header);
|
||||||
w = NodeTraits::get_left(x_parent);
|
w = NodeTraits::get_left(x_parent);
|
||||||
}
|
}
|
||||||
if((!NodeTraits::get_right(w) || NodeTraits::get_color(NodeTraits::get_right(w)) == NodeTraits::black()) &&
|
node_ptr const w_left (NodeTraits::get_left(w));
|
||||||
(!NodeTraits::get_left(w) || NodeTraits::get_color(NodeTraits::get_left(w)) == NodeTraits::black())){
|
node_ptr const w_right(NodeTraits::get_right(w));
|
||||||
|
if((!w_right || NodeTraits::get_color(w_right) == NodeTraits::black()) &&
|
||||||
|
(!w_left || NodeTraits::get_color(w_left) == NodeTraits::black())){
|
||||||
NodeTraits::set_color(w, NodeTraits::red());
|
NodeTraits::set_color(w, NodeTraits::red());
|
||||||
x = x_parent;
|
x = x_parent;
|
||||||
x_parent = NodeTraits::get_parent(x_parent);
|
x_parent = NodeTraits::get_parent(x_parent);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(!NodeTraits::get_left(w) || NodeTraits::get_color(NodeTraits::get_left(w)) == NodeTraits::black()){
|
if(!w_left || NodeTraits::get_color(w_left) == NodeTraits::black()){
|
||||||
NodeTraits::set_color(NodeTraits::get_right(w), NodeTraits::black());
|
NodeTraits::set_color(w_right, NodeTraits::black());
|
||||||
NodeTraits::set_color(w, NodeTraits::red());
|
NodeTraits::set_color(w, NodeTraits::red());
|
||||||
bstree_algo::rotate_left(w, header);
|
bstree_algo::rotate_left(w, w_right, NodeTraits::get_parent(w), header);
|
||||||
w = NodeTraits::get_left(x_parent);
|
w = NodeTraits::get_left(x_parent);
|
||||||
}
|
}
|
||||||
NodeTraits::set_color(w, NodeTraits::get_color(x_parent));
|
NodeTraits::set_color(w, NodeTraits::get_color(x_parent));
|
||||||
NodeTraits::set_color(x_parent, NodeTraits::black());
|
NodeTraits::set_color(x_parent, NodeTraits::black());
|
||||||
if(NodeTraits::get_left(w))
|
const node_ptr new_wleft(NodeTraits::get_left(w));
|
||||||
NodeTraits::set_color(NodeTraits::get_left(w), NodeTraits::black());
|
if(new_wleft)
|
||||||
bstree_algo::rotate_right(x_parent, header);
|
NodeTraits::set_color(new_wleft, NodeTraits::black());
|
||||||
|
bstree_algo::rotate_right(x_parent, NodeTraits::get_left(x_parent), NodeTraits::get_parent(x_parent), header);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -480,48 +461,49 @@ class rbtree_algorithms
|
|||||||
static void rebalance_after_insertion(const node_ptr & header, node_ptr p)
|
static void rebalance_after_insertion(const node_ptr & header, node_ptr p)
|
||||||
{
|
{
|
||||||
NodeTraits::set_color(p, NodeTraits::red());
|
NodeTraits::set_color(p, NodeTraits::red());
|
||||||
while(p != NodeTraits::get_parent(header) && NodeTraits::get_color(NodeTraits::get_parent(p)) == NodeTraits::red()){
|
while(1){
|
||||||
node_ptr p_parent(NodeTraits::get_parent(p));
|
node_ptr p_parent(NodeTraits::get_parent(p));
|
||||||
node_ptr p_parent_parent(NodeTraits::get_parent(p_parent));
|
const node_ptr p_grandparent(NodeTraits::get_parent(p_parent));
|
||||||
if(bstree_algo::is_left_child(p_parent)){
|
if(p_parent == header || NodeTraits::get_color(p_parent) == NodeTraits::black() || p_grandparent == header){
|
||||||
node_ptr x = NodeTraits::get_right(p_parent_parent);
|
break;
|
||||||
if(x && NodeTraits::get_color(x) == NodeTraits::red()){
|
|
||||||
NodeTraits::set_color(p_parent, NodeTraits::black());
|
|
||||||
NodeTraits::set_color(p_parent_parent, NodeTraits::red());
|
|
||||||
NodeTraits::set_color(x, NodeTraits::black());
|
|
||||||
p = p_parent_parent;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if(!bstree_algo::is_left_child(p)){
|
|
||||||
p = p_parent;
|
|
||||||
bstree_algo::rotate_left(p, header);
|
|
||||||
}
|
|
||||||
node_ptr new_p_parent(NodeTraits::get_parent(p));
|
|
||||||
node_ptr new_p_parent_parent(NodeTraits::get_parent(new_p_parent));
|
|
||||||
NodeTraits::set_color(new_p_parent, NodeTraits::black());
|
|
||||||
NodeTraits::set_color(new_p_parent_parent, NodeTraits::red());
|
|
||||||
bstree_algo::rotate_right(new_p_parent_parent, header);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else{
|
|
||||||
node_ptr x = NodeTraits::get_left(p_parent_parent);
|
NodeTraits::set_color(p_grandparent, NodeTraits::red());
|
||||||
if(x && NodeTraits::get_color(x) == NodeTraits::red()){
|
node_ptr const p_grandparent_left (NodeTraits::get_left (p_grandparent));
|
||||||
NodeTraits::set_color(p_parent, NodeTraits::black());
|
bool const p_parent_is_left_child = p_parent == p_grandparent_left;
|
||||||
NodeTraits::set_color(p_parent_parent, NodeTraits::red());
|
node_ptr const x(p_parent_is_left_child ? NodeTraits::get_right(p_grandparent) : p_grandparent_left);
|
||||||
NodeTraits::set_color(x, NodeTraits::black());
|
|
||||||
p = p_parent_parent;
|
if(x && NodeTraits::get_color(x) == NodeTraits::red()){
|
||||||
}
|
NodeTraits::set_color(x, NodeTraits::black());
|
||||||
else{
|
NodeTraits::set_color(p_parent, NodeTraits::black());
|
||||||
if(bstree_algo::is_left_child(p)){
|
p = p_grandparent;
|
||||||
p = p_parent;
|
}
|
||||||
bstree_algo::rotate_right(p, header);
|
else{ //Final step
|
||||||
|
const bool p_is_left_child(NodeTraits::get_left(p_parent) == p);
|
||||||
|
if(p_parent_is_left_child){ //p_parent is left child
|
||||||
|
if(!p_is_left_child){ //p is right child
|
||||||
|
bstree_algo::rotate_left_no_parent_fix(p_parent, p);
|
||||||
|
//No need to link p and p_grandparent:
|
||||||
|
// [NodeTraits::set_parent(p, p_grandparent) + NodeTraits::set_left(p_grandparent, p)]
|
||||||
|
//as p_grandparent is not the header, another rotation is coming and p_parent
|
||||||
|
//will be the left child of p_grandparent
|
||||||
|
p_parent = p;
|
||||||
}
|
}
|
||||||
node_ptr new_p_parent(NodeTraits::get_parent(p));
|
bstree_algo::rotate_right(p_grandparent, p_parent, NodeTraits::get_parent(p_grandparent), header);
|
||||||
node_ptr new_p_parent_parent(NodeTraits::get_parent(new_p_parent));
|
|
||||||
NodeTraits::set_color(new_p_parent, NodeTraits::black());
|
|
||||||
NodeTraits::set_color(new_p_parent_parent, NodeTraits::red());
|
|
||||||
bstree_algo::rotate_left(new_p_parent_parent, header);
|
|
||||||
}
|
}
|
||||||
|
else{ //p_parent is right child
|
||||||
|
if(p_is_left_child){ //p is left child
|
||||||
|
bstree_algo::rotate_right_no_parent_fix(p_parent, p);
|
||||||
|
//No need to link p and p_grandparent:
|
||||||
|
// [NodeTraits::set_parent(p, p_grandparent) + NodeTraits::set_right(p_grandparent, p)]
|
||||||
|
//as p_grandparent is not the header, another rotation is coming and p_parent
|
||||||
|
//will be the right child of p_grandparent
|
||||||
|
p_parent = p;
|
||||||
|
}
|
||||||
|
bstree_algo::rotate_left(p_grandparent, p_parent, NodeTraits::get_parent(p_grandparent), header);
|
||||||
|
}
|
||||||
|
NodeTraits::set_color(p_parent, NodeTraits::black());
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NodeTraits::set_color(NodeTraits::get_parent(header), NodeTraits::black());
|
NodeTraits::set_color(NodeTraits::get_parent(header), NodeTraits::black());
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
#include <boost/intrusive/detail/config_begin.hpp>
|
#include <boost/intrusive/detail/config_begin.hpp>
|
||||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||||
|
|
||||||
#include <boost/intrusive/detail/mpl.hpp>
|
#include <boost/intrusive/detail/mpl.hpp>
|
||||||
#include <boost/intrusive/rbtree.hpp>
|
#include <boost/intrusive/rbtree.hpp>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
@ -248,13 +249,19 @@ class set_impl
|
|||||||
template<class Disposer>
|
template<class Disposer>
|
||||||
void clear_and_dispose(Disposer disposer);
|
void clear_and_dispose(Disposer disposer);
|
||||||
|
|
||||||
|
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::rbtree::count(const_reference)const
|
//! @copydoc ::boost::intrusive::rbtree::count(const_reference)const
|
||||||
size_type count(const_reference value) const;
|
size_type count(const_reference value) const
|
||||||
|
{ return static_cast<size_type>(this->tree_type::find(value) != this->tree_type::cend()); }
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::rbtree::count(const KeyType&,KeyValueCompare)const
|
//! @copydoc ::boost::intrusive::rbtree::count(const KeyType&,KeyValueCompare)const
|
||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
size_type count(const KeyType& key, KeyValueCompare comp) const;
|
size_type count(const KeyType& key, KeyValueCompare comp) const
|
||||||
|
{ return static_cast<size_type>(this->tree_type::find(key, comp) != this->tree_type::cend()); }
|
||||||
|
|
||||||
|
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::rbtree::lower_bound(const_reference)
|
//! @copydoc ::boost::intrusive::rbtree::lower_bound(const_reference)
|
||||||
iterator lower_bound(const_reference value);
|
iterator lower_bound(const_reference value);
|
||||||
|
|
||||||
@ -297,21 +304,29 @@ class set_impl
|
|||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
const_iterator find(const KeyType& key, KeyValueCompare comp) const;
|
const_iterator find(const KeyType& key, KeyValueCompare comp) const;
|
||||||
|
|
||||||
|
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)
|
//! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)
|
||||||
std::pair<iterator,iterator> equal_range(const_reference value);
|
std::pair<iterator,iterator> equal_range(const_reference value)
|
||||||
|
{ return this->tree_type::lower_bound_range(value); }
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)
|
//! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)
|
||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
|
std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp)
|
||||||
|
{ return this->tree_type::lower_bound_range(key, comp); }
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)const
|
//! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)const
|
||||||
std::pair<const_iterator, const_iterator>
|
std::pair<const_iterator, const_iterator>
|
||||||
equal_range(const_reference value) const;
|
equal_range(const_reference value) const
|
||||||
|
{ return this->tree_type::lower_bound_range(value); }
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)const
|
//! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)const
|
||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
std::pair<const_iterator, const_iterator>
|
std::pair<const_iterator, const_iterator>
|
||||||
equal_range(const KeyType& key, KeyValueCompare comp) const;
|
equal_range(const KeyType& key, KeyValueCompare comp) const
|
||||||
|
{ return this->tree_type::lower_bound_range(key, comp); }
|
||||||
|
|
||||||
|
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::rbtree::bounded_range(const_reference,const_reference,bool,bool)
|
//! @copydoc ::boost::intrusive::rbtree::bounded_range(const_reference,const_reference,bool,bool)
|
||||||
std::pair<iterator,iterator> bounded_range
|
std::pair<iterator,iterator> bounded_range
|
||||||
@ -691,7 +706,7 @@ class multiset_impl
|
|||||||
//! @copydoc ::boost::intrusive::rbtree::count(const KeyType&,KeyValueCompare)const
|
//! @copydoc ::boost::intrusive::rbtree::count(const KeyType&,KeyValueCompare)const
|
||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
size_type count(const KeyType& key, KeyValueCompare comp) const;
|
size_type count(const KeyType& key, KeyValueCompare comp) const;
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::rbtree::lower_bound(const_reference)
|
//! @copydoc ::boost::intrusive::rbtree::lower_bound(const_reference)
|
||||||
iterator lower_bound(const_reference value);
|
iterator lower_bound(const_reference value);
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include <boost/intrusive/detail/config_begin.hpp>
|
#include <boost/intrusive/detail/config_begin.hpp>
|
||||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||||
|
|
||||||
#include <boost/intrusive/detail/utilities.hpp>
|
#include <boost/intrusive/detail/utilities.hpp>
|
||||||
#include <boost/intrusive/detail/rbtree_node.hpp>
|
#include <boost/intrusive/detail/rbtree_node.hpp>
|
||||||
#include <boost/intrusive/rbtree_algorithms.hpp>
|
#include <boost/intrusive/rbtree_algorithms.hpp>
|
||||||
@ -76,7 +77,7 @@ struct make_set_base_hook
|
|||||||
//! unique tag.
|
//! unique tag.
|
||||||
//!
|
//!
|
||||||
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
||||||
//! and the the container configured to use this hook.
|
//! and the container configured to use this hook.
|
||||||
//!
|
//!
|
||||||
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
|
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
|
||||||
//! \c auto_unlink or \c safe_link).
|
//! \c auto_unlink or \c safe_link).
|
||||||
@ -203,7 +204,7 @@ struct make_set_member_hook
|
|||||||
//! \c link_mode<> and \c optimize_size<>.
|
//! \c link_mode<> and \c optimize_size<>.
|
||||||
//!
|
//!
|
||||||
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
||||||
//! and the the container configured to use this hook.
|
//! and the container configured to use this hook.
|
||||||
//!
|
//!
|
||||||
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
|
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
|
||||||
//! \c auto_unlink or \c safe_link).
|
//! \c auto_unlink or \c safe_link).
|
||||||
|
@ -247,13 +247,19 @@ class sg_set_impl
|
|||||||
template<class Disposer>
|
template<class Disposer>
|
||||||
void clear_and_dispose(Disposer disposer);
|
void clear_and_dispose(Disposer disposer);
|
||||||
|
|
||||||
|
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::sgtree::count(const_reference)const
|
//! @copydoc ::boost::intrusive::sgtree::count(const_reference)const
|
||||||
size_type count(const_reference value) const;
|
size_type count(const_reference value) const
|
||||||
|
{ return static_cast<size_type>(this->tree_type::find(value) != this->tree_type::cend()); }
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::sgtree::count(const KeyType&,KeyValueCompare)const
|
//! @copydoc ::boost::intrusive::sgtree::count(const KeyType&,KeyValueCompare)const
|
||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
size_type count(const KeyType& key, KeyValueCompare comp) const;
|
size_type count(const KeyType& key, KeyValueCompare comp) const
|
||||||
|
{ return static_cast<size_type>(this->tree_type::find(key, comp) != this->tree_type::cend()); }
|
||||||
|
|
||||||
|
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::sgtree::lower_bound(const_reference)
|
//! @copydoc ::boost::intrusive::sgtree::lower_bound(const_reference)
|
||||||
iterator lower_bound(const_reference value);
|
iterator lower_bound(const_reference value);
|
||||||
|
|
||||||
@ -296,21 +302,29 @@ class sg_set_impl
|
|||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
const_iterator find(const KeyType& key, KeyValueCompare comp) const;
|
const_iterator find(const KeyType& key, KeyValueCompare comp) const;
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::sgtree::equal_range(const_reference)
|
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
std::pair<iterator,iterator> equal_range(const_reference value);
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::sgtree::equal_range(const KeyType&,KeyValueCompare)
|
//! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)
|
||||||
|
std::pair<iterator,iterator> equal_range(const_reference value)
|
||||||
|
{ return this->tree_type::lower_bound_range(value); }
|
||||||
|
|
||||||
|
//! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)
|
||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
|
std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp)
|
||||||
|
{ return this->tree_type::lower_bound_range(key, comp); }
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::sgtree::equal_range(const_reference)const
|
//! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)const
|
||||||
std::pair<const_iterator, const_iterator>
|
std::pair<const_iterator, const_iterator>
|
||||||
equal_range(const_reference value) const;
|
equal_range(const_reference value) const
|
||||||
|
{ return this->tree_type::lower_bound_range(value); }
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::sgtree::equal_range(const KeyType&,KeyValueCompare)const
|
//! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)const
|
||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
std::pair<const_iterator, const_iterator>
|
std::pair<const_iterator, const_iterator>
|
||||||
equal_range(const KeyType& key, KeyValueCompare comp) const;
|
equal_range(const KeyType& key, KeyValueCompare comp) const
|
||||||
|
{ return this->tree_type::lower_bound_range(key, comp); }
|
||||||
|
|
||||||
|
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::sgtree::bounded_range(const_reference,const_reference,bool,bool)
|
//! @copydoc ::boost::intrusive::sgtree::bounded_range(const_reference,const_reference,bool,bool)
|
||||||
std::pair<iterator,iterator> bounded_range
|
std::pair<iterator,iterator> bounded_range
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#define BOOST_INTRUSIVE_SGTREE_HPP
|
#define BOOST_INTRUSIVE_SGTREE_HPP
|
||||||
|
|
||||||
#include <boost/intrusive/detail/config_begin.hpp>
|
#include <boost/intrusive/detail/config_begin.hpp>
|
||||||
|
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
@ -28,7 +29,6 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <boost/intrusive/detail/assert.hpp>
|
#include <boost/intrusive/detail/assert.hpp>
|
||||||
#include <boost/static_assert.hpp>
|
#include <boost/static_assert.hpp>
|
||||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
|
||||||
#include <boost/intrusive/bs_set_hook.hpp>
|
#include <boost/intrusive/bs_set_hook.hpp>
|
||||||
#include <boost/intrusive/bstree.hpp>
|
#include <boost/intrusive/bstree.hpp>
|
||||||
#include <boost/intrusive/detail/tree_node.hpp>
|
#include <boost/intrusive/detail/tree_node.hpp>
|
||||||
@ -48,6 +48,12 @@ namespace intrusive {
|
|||||||
|
|
||||||
namespace detail{
|
namespace detail{
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Halpha for fixed floating_point<false> option
|
||||||
|
//
|
||||||
|
/////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
//! Returns floor(log2(n)/log2(sqrt(2))) -> floor(2*log2(n))
|
//! Returns floor(log2(n)/log2(sqrt(2))) -> floor(2*log2(n))
|
||||||
//! Undefined if N is 0.
|
//! Undefined if N is 0.
|
||||||
//!
|
//!
|
||||||
@ -55,7 +61,7 @@ namespace detail{
|
|||||||
inline std::size_t calculate_h_sqrt2 (std::size_t n)
|
inline std::size_t calculate_h_sqrt2 (std::size_t n)
|
||||||
{
|
{
|
||||||
std::size_t f_log2 = detail::floor_log2(n);
|
std::size_t f_log2 = detail::floor_log2(n);
|
||||||
return (2*f_log2) + (n >= detail::sqrt2_pow_2xplus1 (f_log2));
|
return (2*f_log2) + static_cast<std::size_t>(n >= detail::sqrt2_pow_2xplus1(f_log2));
|
||||||
}
|
}
|
||||||
|
|
||||||
struct h_alpha_sqrt2_t
|
struct h_alpha_sqrt2_t
|
||||||
@ -76,6 +82,12 @@ struct alpha_0_75_by_max_size_t
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Halpha for fixed floating_point<true> option
|
||||||
|
//
|
||||||
|
/////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
struct h_alpha_t
|
struct h_alpha_t
|
||||||
{
|
{
|
||||||
explicit h_alpha_t(float inv_minus_logalpha)
|
explicit h_alpha_t(float inv_minus_logalpha)
|
||||||
@ -84,9 +96,12 @@ struct h_alpha_t
|
|||||||
|
|
||||||
std::size_t operator()(std::size_t n) const
|
std::size_t operator()(std::size_t n) const
|
||||||
{
|
{
|
||||||
//Returns floor(log2(1/alpha(n))) ->
|
////////////////////////////////////////////////////////////
|
||||||
// floor(log2(n)/log(1/alpha)) ->
|
// This function must return "floor(log2(1/alpha(n)))" ->
|
||||||
// floor(log2(n)/(-log2(alpha)))
|
// floor(log2(n)/log(1/alpha)) ->
|
||||||
|
// floor(log2(n)/-log2(alpha))
|
||||||
|
// floor(log2(n)*(1/-log2(alpha)))
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
//return static_cast<std::size_t>(std::log(float(n))*inv_minus_logalpha_);
|
//return static_cast<std::size_t>(std::log(float(n))*inv_minus_logalpha_);
|
||||||
return static_cast<std::size_t>(detail::fast_log2(float(n))*inv_minus_logalpha_);
|
return static_cast<std::size_t>(detail::fast_log2(float(n))*inv_minus_logalpha_);
|
||||||
}
|
}
|
||||||
@ -119,7 +134,7 @@ struct alpha_holder
|
|||||||
typedef boost::intrusive::detail::alpha_by_max_size_t multiply_by_alpha_t;
|
typedef boost::intrusive::detail::alpha_by_max_size_t multiply_by_alpha_t;
|
||||||
|
|
||||||
alpha_holder() : max_tree_size_(0)
|
alpha_holder() : max_tree_size_(0)
|
||||||
{ set_alpha(0.7f); }
|
{ set_alpha(0.70711f); } // ~1/sqrt(2)
|
||||||
|
|
||||||
float get_alpha() const
|
float get_alpha() const
|
||||||
{ return alpha_; }
|
{ return alpha_; }
|
||||||
@ -211,7 +226,6 @@ class sgtree_impl
|
|||||||
typedef bstree_impl< ValueTraits, VoidOrKeyComp, SizeType
|
typedef bstree_impl< ValueTraits, VoidOrKeyComp, SizeType
|
||||||
, true, SgTreeAlgorithms> tree_type;
|
, true, SgTreeAlgorithms> tree_type;
|
||||||
typedef tree_type implementation_defined;
|
typedef tree_type implementation_defined;
|
||||||
typedef typename tree_type::real_value_traits real_value_traits;
|
|
||||||
|
|
||||||
/// @endcond
|
/// @endcond
|
||||||
|
|
||||||
@ -248,11 +262,11 @@ class sgtree_impl
|
|||||||
typedef typename alpha_traits::multiply_by_alpha_t multiply_by_alpha_t;
|
typedef typename alpha_traits::multiply_by_alpha_t multiply_by_alpha_t;
|
||||||
|
|
||||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(sgtree_impl)
|
BOOST_MOVABLE_BUT_NOT_COPYABLE(sgtree_impl)
|
||||||
BOOST_STATIC_ASSERT(((int)real_value_traits::link_mode != (int)auto_unlink));
|
BOOST_STATIC_ASSERT(((int)value_traits::link_mode != (int)auto_unlink));
|
||||||
|
|
||||||
enum { safemode_or_autounlink =
|
enum { safemode_or_autounlink =
|
||||||
(int)real_value_traits::link_mode == (int)auto_unlink ||
|
(int)value_traits::link_mode == (int)auto_unlink ||
|
||||||
(int)real_value_traits::link_mode == (int)safe_link };
|
(int)value_traits::link_mode == (int)safe_link };
|
||||||
|
|
||||||
/// @endcond
|
/// @endcond
|
||||||
|
|
||||||
@ -397,9 +411,9 @@ class sgtree_impl
|
|||||||
//! @copydoc ::boost::intrusive::bstree::insert_equal(reference)
|
//! @copydoc ::boost::intrusive::bstree::insert_equal(reference)
|
||||||
iterator insert_equal(reference value)
|
iterator insert_equal(reference value)
|
||||||
{
|
{
|
||||||
detail::key_nodeptr_comp<value_compare, real_value_traits>
|
detail::key_nodeptr_comp<value_compare, value_traits>
|
||||||
key_node_comp(this->value_comp(), &this->get_real_value_traits());
|
key_node_comp(this->value_comp(), &this->get_value_traits());
|
||||||
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
|
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
|
||||||
if(safemode_or_autounlink)
|
if(safemode_or_autounlink)
|
||||||
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
|
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
|
||||||
std::size_t max_tree_size = (std::size_t)this->max_tree_size_;
|
std::size_t max_tree_size = (std::size_t)this->max_tree_size_;
|
||||||
@ -408,15 +422,15 @@ class sgtree_impl
|
|||||||
, (size_type)this->size(), this->get_h_alpha_func(), max_tree_size);
|
, (size_type)this->size(), this->get_h_alpha_func(), max_tree_size);
|
||||||
this->tree_type::sz_traits().increment();
|
this->tree_type::sz_traits().increment();
|
||||||
this->max_tree_size_ = (size_type)max_tree_size;
|
this->max_tree_size_ = (size_type)max_tree_size;
|
||||||
return iterator(p, this->real_value_traits_ptr());
|
return iterator(p, this->value_traits_ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::insert_equal(const_iterator,reference)
|
//! @copydoc ::boost::intrusive::bstree::insert_equal(const_iterator,reference)
|
||||||
iterator insert_equal(const_iterator hint, reference value)
|
iterator insert_equal(const_iterator hint, reference value)
|
||||||
{
|
{
|
||||||
detail::key_nodeptr_comp<value_compare, real_value_traits>
|
detail::key_nodeptr_comp<value_compare, value_traits>
|
||||||
key_node_comp(this->value_comp(), &this->get_real_value_traits());
|
key_node_comp(this->value_comp(), &this->get_value_traits());
|
||||||
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
|
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
|
||||||
if(safemode_or_autounlink)
|
if(safemode_or_autounlink)
|
||||||
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
|
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
|
||||||
std::size_t max_tree_size = (std::size_t)this->max_tree_size_;
|
std::size_t max_tree_size = (std::size_t)this->max_tree_size_;
|
||||||
@ -425,7 +439,7 @@ class sgtree_impl
|
|||||||
, (std::size_t)this->size(), this->get_h_alpha_func(), max_tree_size);
|
, (std::size_t)this->size(), this->get_h_alpha_func(), max_tree_size);
|
||||||
this->tree_type::sz_traits().increment();
|
this->tree_type::sz_traits().increment();
|
||||||
this->max_tree_size_ = (size_type)max_tree_size;
|
this->max_tree_size_ = (size_type)max_tree_size;
|
||||||
return iterator(p, this->real_value_traits_ptr());
|
return iterator(p, this->value_traits_ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::insert_equal(Iterator,Iterator)
|
//! @copydoc ::boost::intrusive::bstree::insert_equal(Iterator,Iterator)
|
||||||
@ -462,12 +476,12 @@ class sgtree_impl
|
|||||||
std::pair<iterator, bool> insert_unique_check
|
std::pair<iterator, bool> insert_unique_check
|
||||||
(const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data)
|
(const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data)
|
||||||
{
|
{
|
||||||
detail::key_nodeptr_comp<KeyValueCompare, real_value_traits>
|
detail::key_nodeptr_comp<KeyValueCompare, value_traits>
|
||||||
comp(key_value_comp, &this->get_real_value_traits());
|
comp(key_value_comp, &this->get_value_traits());
|
||||||
std::pair<node_ptr, bool> ret =
|
std::pair<node_ptr, bool> ret =
|
||||||
(node_algorithms::insert_unique_check
|
(node_algorithms::insert_unique_check
|
||||||
(this->tree_type::header_ptr(), key, comp, commit_data));
|
(this->tree_type::header_ptr(), key, comp, commit_data));
|
||||||
return std::pair<iterator, bool>(iterator(ret.first, this->real_value_traits_ptr()), ret.second);
|
return std::pair<iterator, bool>(iterator(ret.first, this->value_traits_ptr()), ret.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const KeyType&,KeyValueCompare,insert_commit_data&)
|
//! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const KeyType&,KeyValueCompare,insert_commit_data&)
|
||||||
@ -476,18 +490,18 @@ class sgtree_impl
|
|||||||
(const_iterator hint, const KeyType &key
|
(const_iterator hint, const KeyType &key
|
||||||
,KeyValueCompare key_value_comp, insert_commit_data &commit_data)
|
,KeyValueCompare key_value_comp, insert_commit_data &commit_data)
|
||||||
{
|
{
|
||||||
detail::key_nodeptr_comp<KeyValueCompare, real_value_traits>
|
detail::key_nodeptr_comp<KeyValueCompare, value_traits>
|
||||||
comp(key_value_comp, &this->get_real_value_traits());
|
comp(key_value_comp, &this->get_value_traits());
|
||||||
std::pair<node_ptr, bool> ret =
|
std::pair<node_ptr, bool> ret =
|
||||||
(node_algorithms::insert_unique_check
|
(node_algorithms::insert_unique_check
|
||||||
(this->tree_type::header_ptr(), hint.pointed_node(), key, comp, commit_data));
|
(this->tree_type::header_ptr(), hint.pointed_node(), key, comp, commit_data));
|
||||||
return std::pair<iterator, bool>(iterator(ret.first, this->real_value_traits_ptr()), ret.second);
|
return std::pair<iterator, bool>(iterator(ret.first, this->value_traits_ptr()), ret.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::insert_unique_commit
|
//! @copydoc ::boost::intrusive::bstree::insert_unique_commit
|
||||||
iterator insert_unique_commit(reference value, const insert_commit_data &commit_data)
|
iterator insert_unique_commit(reference value, const insert_commit_data &commit_data)
|
||||||
{
|
{
|
||||||
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
|
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
|
||||||
if(safemode_or_autounlink)
|
if(safemode_or_autounlink)
|
||||||
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
|
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
|
||||||
std::size_t max_tree_size = (std::size_t)this->max_tree_size_;
|
std::size_t max_tree_size = (std::size_t)this->max_tree_size_;
|
||||||
@ -496,7 +510,7 @@ class sgtree_impl
|
|||||||
, (std::size_t)this->size(), this->get_h_alpha_func(), max_tree_size);
|
, (std::size_t)this->size(), this->get_h_alpha_func(), max_tree_size);
|
||||||
this->tree_type::sz_traits().increment();
|
this->tree_type::sz_traits().increment();
|
||||||
this->max_tree_size_ = (size_type)max_tree_size;
|
this->max_tree_size_ = (size_type)max_tree_size;
|
||||||
return iterator(to_insert, this->real_value_traits_ptr());
|
return iterator(to_insert, this->value_traits_ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::insert_unique(Iterator,Iterator)
|
//! @copydoc ::boost::intrusive::bstree::insert_unique(Iterator,Iterator)
|
||||||
@ -517,7 +531,7 @@ class sgtree_impl
|
|||||||
//! @copydoc ::boost::intrusive::bstree::insert_before
|
//! @copydoc ::boost::intrusive::bstree::insert_before
|
||||||
iterator insert_before(const_iterator pos, reference value)
|
iterator insert_before(const_iterator pos, reference value)
|
||||||
{
|
{
|
||||||
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
|
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
|
||||||
if(safemode_or_autounlink)
|
if(safemode_or_autounlink)
|
||||||
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
|
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
|
||||||
std::size_t max_tree_size = (std::size_t)this->max_tree_size_;
|
std::size_t max_tree_size = (std::size_t)this->max_tree_size_;
|
||||||
@ -526,13 +540,13 @@ class sgtree_impl
|
|||||||
, (size_type)this->size(), this->get_h_alpha_func(), max_tree_size);
|
, (size_type)this->size(), this->get_h_alpha_func(), max_tree_size);
|
||||||
this->tree_type::sz_traits().increment();
|
this->tree_type::sz_traits().increment();
|
||||||
this->max_tree_size_ = (size_type)max_tree_size;
|
this->max_tree_size_ = (size_type)max_tree_size;
|
||||||
return iterator(p, this->real_value_traits_ptr());
|
return iterator(p, this->value_traits_ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::push_back
|
//! @copydoc ::boost::intrusive::bstree::push_back
|
||||||
void push_back(reference value)
|
void push_back(reference value)
|
||||||
{
|
{
|
||||||
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
|
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
|
||||||
if(safemode_or_autounlink)
|
if(safemode_or_autounlink)
|
||||||
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
|
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
|
||||||
std::size_t max_tree_size = (std::size_t)this->max_tree_size_;
|
std::size_t max_tree_size = (std::size_t)this->max_tree_size_;
|
||||||
@ -546,7 +560,7 @@ class sgtree_impl
|
|||||||
//! @copydoc ::boost::intrusive::bstree::push_front
|
//! @copydoc ::boost::intrusive::bstree::push_front
|
||||||
void push_front(reference value)
|
void push_front(reference value)
|
||||||
{
|
{
|
||||||
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
|
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
|
||||||
if(safemode_or_autounlink)
|
if(safemode_or_autounlink)
|
||||||
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
|
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
|
||||||
std::size_t max_tree_size = (std::size_t)this->max_tree_size_;
|
std::size_t max_tree_size = (std::size_t)this->max_tree_size_;
|
||||||
@ -605,7 +619,7 @@ class sgtree_impl
|
|||||||
{
|
{
|
||||||
node_ptr to_erase(i.pointed_node());
|
node_ptr to_erase(i.pointed_node());
|
||||||
iterator ret(this->erase(i));
|
iterator ret(this->erase(i));
|
||||||
disposer(this->get_real_value_traits().to_value_ptr(to_erase));
|
disposer(this->get_value_traits().to_value_ptr(to_erase));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -666,7 +680,7 @@ class sgtree_impl
|
|||||||
//! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const
|
//! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const
|
||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
size_type count(const KeyType& key, KeyValueCompare comp) const;
|
size_type count(const KeyType& key, KeyValueCompare comp) const;
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)
|
//! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)
|
||||||
iterator lower_bound(const_reference value);
|
iterator lower_bound(const_reference value);
|
||||||
|
|
||||||
@ -915,14 +929,13 @@ class sgtree
|
|||||||
public:
|
public:
|
||||||
typedef typename Base::value_compare value_compare;
|
typedef typename Base::value_compare value_compare;
|
||||||
typedef typename Base::value_traits value_traits;
|
typedef typename Base::value_traits value_traits;
|
||||||
typedef typename Base::real_value_traits real_value_traits;
|
|
||||||
typedef typename Base::iterator iterator;
|
typedef typename Base::iterator iterator;
|
||||||
typedef typename Base::const_iterator const_iterator;
|
typedef typename Base::const_iterator const_iterator;
|
||||||
typedef typename Base::reverse_iterator reverse_iterator;
|
typedef typename Base::reverse_iterator reverse_iterator;
|
||||||
typedef typename Base::const_reverse_iterator const_reverse_iterator;
|
typedef typename Base::const_reverse_iterator const_reverse_iterator;
|
||||||
|
|
||||||
//Assert if passed value traits are compatible with the type
|
//Assert if passed value traits are compatible with the type
|
||||||
BOOST_STATIC_ASSERT((detail::is_same<typename real_value_traits::value_type, T>::value));
|
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
|
||||||
|
|
||||||
explicit sgtree( const value_compare &cmp = value_compare()
|
explicit sgtree( const value_compare &cmp = value_compare()
|
||||||
, const value_traits &v_traits = value_traits())
|
, const value_traits &v_traits = value_traits())
|
||||||
|
@ -18,9 +18,9 @@
|
|||||||
#define BOOST_INTRUSIVE_SGTREE_ALGORITHMS_HPP
|
#define BOOST_INTRUSIVE_SGTREE_ALGORITHMS_HPP
|
||||||
|
|
||||||
#include <boost/intrusive/detail/config_begin.hpp>
|
#include <boost/intrusive/detail/config_begin.hpp>
|
||||||
|
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
|
||||||
#include <boost/intrusive/detail/assert.hpp>
|
#include <boost/intrusive/detail/assert.hpp>
|
||||||
#include <boost/intrusive/detail/utilities.hpp>
|
#include <boost/intrusive/detail/utilities.hpp>
|
||||||
#include <boost/intrusive/bstree_algorithms.hpp>
|
#include <boost/intrusive/bstree_algorithms.hpp>
|
||||||
@ -187,6 +187,7 @@ class sgtree_algorithms
|
|||||||
//! @copydoc ::boost::intrusive::bstree_algorithms::count(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
//! @copydoc ::boost::intrusive::bstree_algorithms::count(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
||||||
template<class KeyType, class KeyNodePtrCompare>
|
template<class KeyType, class KeyNodePtrCompare>
|
||||||
static std::size_t count(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp);
|
static std::size_t count(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp);
|
||||||
|
|
||||||
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_upper_bound(const node_ptr&,const node_ptr&,NodePtrCompare)
|
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_upper_bound(const node_ptr&,const node_ptr&,NodePtrCompare)
|
||||||
@ -330,25 +331,21 @@ class sgtree_algorithms
|
|||||||
//than the weight balanced method.
|
//than the weight balanced method.
|
||||||
node_ptr s = x;
|
node_ptr s = x;
|
||||||
std::size_t size = 1;
|
std::size_t size = 1;
|
||||||
for(std::size_t ancestor = 1; true; ++ancestor){
|
for(std::size_t ancestor = 1; ancestor != depth; ++ancestor){
|
||||||
if(ancestor == depth){ //Check if whole tree must be rebuilt
|
const node_ptr s_parent = NodeTraits::get_parent(s);
|
||||||
max_tree_size = tree_size;
|
const node_ptr s_parent_left = NodeTraits::get_left(s_parent);
|
||||||
bstree_algo::rebalance_subtree(NodeTraits::get_parent(s));
|
//Obtain parent's size (previous size + parent + sibling tree)
|
||||||
break;
|
const node_ptr s_sibling = s_parent_left == s ? NodeTraits::get_right(s_parent) : s_parent_left;
|
||||||
}
|
size += 1 + bstree_algo::subtree_size(s_sibling);
|
||||||
else{ //Go to the next scapegoat candidate
|
s = s_parent;
|
||||||
const node_ptr s_parent = NodeTraits::get_parent(s);
|
if(ancestor > h_alpha(size)){ //is 's' scapegoat?
|
||||||
const node_ptr s_parent_left = NodeTraits::get_left(s_parent);
|
bstree_algo::rebalance_subtree(s);
|
||||||
//Obtain parent's size (previous size + parent + sibling tree)
|
return;
|
||||||
const node_ptr s_sibling = s_parent_left == s ? NodeTraits::get_right(s_parent) : s_parent_left;
|
|
||||||
size += 1 + bstree_algo::subtree_size(s_sibling);
|
|
||||||
s = s_parent;
|
|
||||||
if(ancestor > h_alpha(size)){ //is 's' scapegoat?
|
|
||||||
bstree_algo::rebalance_subtree(s);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//The whole tree must be rebuilt
|
||||||
|
max_tree_size = tree_size;
|
||||||
|
bstree_algo::rebalance_subtree(NodeTraits::get_parent(s));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// @endcond
|
/// @endcond
|
||||||
|
@ -80,7 +80,7 @@ struct make_slist_base_hook
|
|||||||
//! \c auto_unlink or \c safe_link).
|
//! \c auto_unlink or \c safe_link).
|
||||||
//!
|
//!
|
||||||
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
||||||
//! and the the container configured to use this hook.
|
//! and the container configured to use this hook.
|
||||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template<class ...Options>
|
template<class ...Options>
|
||||||
#else
|
#else
|
||||||
@ -203,7 +203,7 @@ struct make_slist_member_hook
|
|||||||
//! \c auto_unlink or \c safe_link).
|
//! \c auto_unlink or \c safe_link).
|
||||||
//!
|
//!
|
||||||
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
||||||
//! and the the container configured to use this hook.
|
//! and the container configured to use this hook.
|
||||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template<class ...Options>
|
template<class ...Options>
|
||||||
#else
|
#else
|
||||||
|
@ -247,12 +247,18 @@ class splay_set_impl
|
|||||||
template<class Disposer>
|
template<class Disposer>
|
||||||
void clear_and_dispose(Disposer disposer);
|
void clear_and_dispose(Disposer disposer);
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::count(const_reference)
|
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
size_type count(const_reference value);
|
|
||||||
|
//! @copydoc ::boost::intrusive::splaytree::count(const_reference)const
|
||||||
|
size_type count(const_reference value) const
|
||||||
|
{ return static_cast<size_type>(this->tree_type::find(value) != this->tree_type::cend()); }
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::count(const KeyType&,KeyValueCompare)const
|
//! @copydoc ::boost::intrusive::splaytree::count(const KeyType&,KeyValueCompare)const
|
||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
size_type count(const KeyType& key, KeyValueCompare comp);
|
size_type count(const KeyType& key, KeyValueCompare comp) const
|
||||||
|
{ return static_cast<size_type>(this->tree_type::find(key, comp) != this->tree_type::cend()); }
|
||||||
|
|
||||||
|
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::count(const_reference)const
|
//! @copydoc ::boost::intrusive::splaytree::count(const_reference)const
|
||||||
size_type count(const_reference value) const;
|
size_type count(const_reference value) const;
|
||||||
@ -261,13 +267,6 @@ class splay_set_impl
|
|||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
size_type count(const KeyType& key, KeyValueCompare comp) const;
|
size_type count(const KeyType& key, KeyValueCompare comp) const;
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::count_dont_splay(const_reference)const
|
|
||||||
size_type count_dont_splay(const_reference value) const;
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::count_dont_splay(const KeyType&,KeyValueCompare)const
|
|
||||||
template<class KeyType, class KeyValueCompare>
|
|
||||||
size_type count_dont_splay(const KeyType& key, KeyValueCompare comp) const;
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::lower_bound(const_reference)
|
//! @copydoc ::boost::intrusive::splaytree::lower_bound(const_reference)
|
||||||
iterator lower_bound(const_reference value);
|
iterator lower_bound(const_reference value);
|
||||||
|
|
||||||
@ -282,13 +281,6 @@ class splay_set_impl
|
|||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
|
const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::lower_bound_dont_splay(const_reference)const
|
|
||||||
const_iterator lower_bound_dont_splay(const_reference value) const;
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::lower_bound_dont_splay(const KeyType&,KeyValueCompare)const
|
|
||||||
template<class KeyType, class KeyValueCompare>
|
|
||||||
const_iterator lower_bound_dont_splay(const KeyType& key, KeyValueCompare comp) const;
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::upper_bound(const_reference)
|
//! @copydoc ::boost::intrusive::splaytree::upper_bound(const_reference)
|
||||||
iterator upper_bound(const_reference value);
|
iterator upper_bound(const_reference value);
|
||||||
|
|
||||||
@ -303,13 +295,6 @@ class splay_set_impl
|
|||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
|
const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::upper_bound_dont_splay(const_reference)const
|
|
||||||
const_iterator upper_bound_dont_splay(const_reference value) const;
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::upper_bound_dont_splay(const KeyType&,KeyValueCompare)const
|
|
||||||
template<class KeyType, class KeyValueCompare>
|
|
||||||
const_iterator upper_bound_dont_splay(const KeyType& key, KeyValueCompare comp) const;
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::find(const_reference)
|
//! @copydoc ::boost::intrusive::splaytree::find(const_reference)
|
||||||
iterator find(const_reference value);
|
iterator find(const_reference value);
|
||||||
|
|
||||||
@ -324,37 +309,29 @@ class splay_set_impl
|
|||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
const_iterator find(const KeyType& key, KeyValueCompare comp) const;
|
const_iterator find(const KeyType& key, KeyValueCompare comp) const;
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::find_dont_splay(const_reference)const
|
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
const_iterator find_dont_splay(const_reference value) const;
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::find_dont_splay(const KeyType&,KeyValueCompare)const
|
//! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)
|
||||||
|
std::pair<iterator,iterator> equal_range(const_reference value)
|
||||||
|
{ return this->tree_type::lower_bound_range(value); }
|
||||||
|
|
||||||
|
//! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)
|
||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
const_iterator find_dont_splay(const KeyType& key, KeyValueCompare comp) const;
|
std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp)
|
||||||
|
{ return this->tree_type::lower_bound_range(key, comp); }
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::equal_range(const_reference)
|
//! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)const
|
||||||
std::pair<iterator,iterator> equal_range(const_reference value);
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::equal_range(const KeyType&,KeyValueCompare)
|
|
||||||
template<class KeyType, class KeyValueCompare>
|
|
||||||
std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::equal_range(const_reference)const
|
|
||||||
std::pair<const_iterator, const_iterator>
|
std::pair<const_iterator, const_iterator>
|
||||||
equal_range(const_reference value) const;
|
equal_range(const_reference value) const
|
||||||
|
{ return this->tree_type::lower_bound_range(value); }
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::equal_range(const KeyType&,KeyValueCompare)const
|
//! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)const
|
||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
std::pair<const_iterator, const_iterator>
|
std::pair<const_iterator, const_iterator>
|
||||||
equal_range(const KeyType& key, KeyValueCompare comp) const;
|
equal_range(const KeyType& key, KeyValueCompare comp) const
|
||||||
|
{ return this->tree_type::lower_bound_range(key, comp); }
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::equal_range_dont_splay(const_reference)const
|
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
std::pair<const_iterator, const_iterator>
|
|
||||||
equal_range_dont_splay(const_reference value) const;
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::equal_range_dont_splay(const KeyType&,KeyValueCompare)const
|
|
||||||
template<class KeyType, class KeyValueCompare>
|
|
||||||
std::pair<const_iterator, const_iterator>
|
|
||||||
equal_range_dont_splay(const KeyType& key, KeyValueCompare comp) const;
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::bounded_range(const_reference,const_reference,bool,bool)
|
//! @copydoc ::boost::intrusive::splaytree::bounded_range(const_reference,const_reference,bool,bool)
|
||||||
std::pair<iterator,iterator> bounded_range
|
std::pair<iterator,iterator> bounded_range
|
||||||
@ -374,15 +351,6 @@ class splay_set_impl
|
|||||||
std::pair<const_iterator, const_iterator> bounded_range
|
std::pair<const_iterator, const_iterator> bounded_range
|
||||||
(const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
|
(const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::bounded_range_dont_splay(const_reference,const_reference,bool,bool)const
|
|
||||||
std::pair<const_iterator, const_iterator> bounded_range_dont_splay
|
|
||||||
(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::bounded_range_dont_splay(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
|
|
||||||
template<class KeyType, class KeyValueCompare>
|
|
||||||
std::pair<const_iterator, const_iterator> bounded_range_dont_splay
|
|
||||||
(const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::s_iterator_to(reference)
|
//! @copydoc ::boost::intrusive::splaytree::s_iterator_to(reference)
|
||||||
static iterator s_iterator_to(reference value);
|
static iterator s_iterator_to(reference value);
|
||||||
|
|
||||||
@ -760,20 +728,6 @@ class splay_multiset_impl
|
|||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
size_type count(const KeyType& key, KeyValueCompare comp);
|
size_type count(const KeyType& key, KeyValueCompare comp);
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::count(const_reference)const
|
|
||||||
size_type count(const_reference value) const;
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::count(const KeyType&,KeyValueCompare)const
|
|
||||||
template<class KeyType, class KeyValueCompare>
|
|
||||||
size_type count(const KeyType& key, KeyValueCompare comp) const;
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::count_dont_splay(const_reference)const
|
|
||||||
size_type count_dont_splay(const_reference value) const;
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::count_dont_splay(const KeyType&,KeyValueCompare)const
|
|
||||||
template<class KeyType, class KeyValueCompare>
|
|
||||||
size_type count_dont_splay(const KeyType& key, KeyValueCompare comp) const;
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::lower_bound(const_reference)
|
//! @copydoc ::boost::intrusive::splaytree::lower_bound(const_reference)
|
||||||
iterator lower_bound(const_reference value);
|
iterator lower_bound(const_reference value);
|
||||||
|
|
||||||
@ -788,13 +742,6 @@ class splay_multiset_impl
|
|||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
|
const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::lower_bound_dont_splay(const_reference)const
|
|
||||||
const_iterator lower_bound_dont_splay(const_reference value) const;
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::lower_bound_dont_splay(const KeyType&,KeyValueCompare)const
|
|
||||||
template<class KeyType, class KeyValueCompare>
|
|
||||||
const_iterator lower_bound_dont_splay(const KeyType& key, KeyValueCompare comp) const;
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::upper_bound(const_reference)
|
//! @copydoc ::boost::intrusive::splaytree::upper_bound(const_reference)
|
||||||
iterator upper_bound(const_reference value);
|
iterator upper_bound(const_reference value);
|
||||||
|
|
||||||
@ -809,13 +756,6 @@ class splay_multiset_impl
|
|||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
|
const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::upper_bound_dont_splay(const_reference)const
|
|
||||||
const_iterator upper_bound_dont_splay(const_reference value) const;
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::upper_bound_dont_splay(const KeyType&,KeyValueCompare)const
|
|
||||||
template<class KeyType, class KeyValueCompare>
|
|
||||||
const_iterator upper_bound_dont_splay(const KeyType& key, KeyValueCompare comp) const;
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::find(const_reference)
|
//! @copydoc ::boost::intrusive::splaytree::find(const_reference)
|
||||||
iterator find(const_reference value);
|
iterator find(const_reference value);
|
||||||
|
|
||||||
@ -830,13 +770,6 @@ class splay_multiset_impl
|
|||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
const_iterator find(const KeyType& key, KeyValueCompare comp) const;
|
const_iterator find(const KeyType& key, KeyValueCompare comp) const;
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::find_dont_splay(const_reference)const
|
|
||||||
const_iterator find_dont_splay(const_reference value) const;
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::find_dont_splay(const KeyType&,KeyValueCompare)const
|
|
||||||
template<class KeyType, class KeyValueCompare>
|
|
||||||
const_iterator find_dont_splay(const KeyType& key, KeyValueCompare comp) const;
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::equal_range(const_reference)
|
//! @copydoc ::boost::intrusive::splaytree::equal_range(const_reference)
|
||||||
std::pair<iterator,iterator> equal_range(const_reference value);
|
std::pair<iterator,iterator> equal_range(const_reference value);
|
||||||
|
|
||||||
@ -853,15 +786,6 @@ class splay_multiset_impl
|
|||||||
std::pair<const_iterator, const_iterator>
|
std::pair<const_iterator, const_iterator>
|
||||||
equal_range(const KeyType& key, KeyValueCompare comp) const;
|
equal_range(const KeyType& key, KeyValueCompare comp) const;
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::equal_range_dont_splay(const_reference)const
|
|
||||||
std::pair<const_iterator, const_iterator>
|
|
||||||
equal_range_dont_splay(const_reference value) const;
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::equal_range_dont_splay(const KeyType&,KeyValueCompare)const
|
|
||||||
template<class KeyType, class KeyValueCompare>
|
|
||||||
std::pair<const_iterator, const_iterator>
|
|
||||||
equal_range_dont_splay(const KeyType& key, KeyValueCompare comp) const;
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::bounded_range(const_reference,const_reference,bool,bool)
|
//! @copydoc ::boost::intrusive::splaytree::bounded_range(const_reference,const_reference,bool,bool)
|
||||||
std::pair<iterator,iterator> bounded_range
|
std::pair<iterator,iterator> bounded_range
|
||||||
(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
|
(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
|
||||||
@ -880,15 +804,6 @@ class splay_multiset_impl
|
|||||||
std::pair<const_iterator, const_iterator> bounded_range
|
std::pair<const_iterator, const_iterator> bounded_range
|
||||||
(const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
|
(const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::bounded_range_dont_splay(const_reference,const_reference,bool,bool)const
|
|
||||||
std::pair<const_iterator, const_iterator> bounded_range_dont_splay
|
|
||||||
(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::bounded_range_dont_splay(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
|
|
||||||
template<class KeyType, class KeyValueCompare>
|
|
||||||
std::pair<const_iterator, const_iterator> bounded_range_dont_splay
|
|
||||||
(const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::splaytree::s_iterator_to(reference)
|
//! @copydoc ::boost::intrusive::splaytree::s_iterator_to(reference)
|
||||||
static iterator s_iterator_to(reference value);
|
static iterator s_iterator_to(reference value);
|
||||||
|
|
||||||
|
@ -1,286 +0,0 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// (C) Copyright Olaf Krzikalla 2004-2006.
|
|
||||||
// (C) Copyright Ion Gaztanaga 2006-2013
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
|
||||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// See http://www.boost.org/libs/intrusive for documentation.
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
#ifndef BOOST_INTRUSIVE_SPLAY_SET_HOOK_HPP
|
|
||||||
#define BOOST_INTRUSIVE_SPLAY_SET_HOOK_HPP
|
|
||||||
|
|
||||||
#include <boost/intrusive/detail/config_begin.hpp>
|
|
||||||
#include <boost/intrusive/bs_set_hook.hpp>
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
namespace intrusive {
|
|
||||||
|
|
||||||
//! Helper metafunction to define a \c splay_set_base_hook that yields to the same
|
|
||||||
//! type when the same options (either explicitly or implicitly) are used.
|
|
||||||
//! <b>WARNING: </b> Deprecated class, use `make_bs_set_base_hook` instead.
|
|
||||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
|
||||||
template<class ...Options>
|
|
||||||
#else
|
|
||||||
template<class O1 = void, class O2 = void, class O3 = void>
|
|
||||||
#endif
|
|
||||||
struct make_splay_set_base_hook
|
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
|
||||||
#if defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
|
||||||
: public make_bs_set_base_hook<Options...>
|
|
||||||
#else
|
|
||||||
: public make_bs_set_base_hook<O1, O2, O3>
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
typedef typename make_bs_set_base_hook
|
|
||||||
<
|
|
||||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
|
||||||
O1, O2, O3
|
|
||||||
#else
|
|
||||||
Options...
|
|
||||||
#endif
|
|
||||||
>::type implementation_defined;
|
|
||||||
/// @endcond
|
|
||||||
typedef implementation_defined type;
|
|
||||||
};
|
|
||||||
|
|
||||||
//! Derive a class from splay_set_base_hook in order to store objects in
|
|
||||||
//! in a splay_set/splay_multiset. splay_set_base_hook holds the data necessary to maintain
|
|
||||||
//! the splay_set/splay_multiset and provides an appropriate value_traits class for splay_set/splay_multiset.
|
|
||||||
//!
|
|
||||||
//! The hook admits the following options: \c tag<>, \c void_pointer<>,
|
|
||||||
//! \c link_mode<> and \c optimize_size<>.
|
|
||||||
//!
|
|
||||||
//! \c tag<> defines a tag to identify the node.
|
|
||||||
//! The same tag value can be used in different classes, but if a class is
|
|
||||||
//! derived from more than one \c list_base_hook, then each \c list_base_hook needs its
|
|
||||||
//! unique tag.
|
|
||||||
//!
|
|
||||||
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
|
||||||
//! and the the container configured to use this hook.
|
|
||||||
//!
|
|
||||||
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
|
|
||||||
//! \c auto_unlink or \c safe_link).
|
|
||||||
//!
|
|
||||||
//! <b>WARNING: </b> Deprecated class, use `bs_set_base_hook` instead.
|
|
||||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
|
||||||
template<class ...Options>
|
|
||||||
#else
|
|
||||||
template<class O1, class O2, class O3>
|
|
||||||
#endif
|
|
||||||
class splay_set_base_hook
|
|
||||||
: public make_splay_set_base_hook<
|
|
||||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
|
||||||
O1, O2, O3
|
|
||||||
#else
|
|
||||||
Options...
|
|
||||||
#endif
|
|
||||||
>::type
|
|
||||||
{
|
|
||||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
|
||||||
public:
|
|
||||||
//! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
|
|
||||||
//! initializes the node to an unlinked state.
|
|
||||||
//!
|
|
||||||
//! <b>Throws</b>: Nothing.
|
|
||||||
splay_set_base_hook();
|
|
||||||
|
|
||||||
//! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
|
|
||||||
//! initializes the node to an unlinked state. The argument is ignored.
|
|
||||||
//!
|
|
||||||
//! <b>Throws</b>: Nothing.
|
|
||||||
//!
|
|
||||||
//! <b>Rationale</b>: Providing a copy-constructor
|
|
||||||
//! makes classes using the hook STL-compliant without forcing the
|
|
||||||
//! user to do some additional work. \c swap can be used to emulate
|
|
||||||
//! move-semantics.
|
|
||||||
splay_set_base_hook(const splay_set_base_hook& );
|
|
||||||
|
|
||||||
//! <b>Effects</b>: Empty function. The argument is ignored.
|
|
||||||
//!
|
|
||||||
//! <b>Throws</b>: Nothing.
|
|
||||||
//!
|
|
||||||
//! <b>Rationale</b>: Providing an assignment operator
|
|
||||||
//! makes classes using the hook STL-compliant without forcing the
|
|
||||||
//! user to do some additional work. \c swap can be used to emulate
|
|
||||||
//! move-semantics.
|
|
||||||
splay_set_base_hook& operator=(const splay_set_base_hook& );
|
|
||||||
|
|
||||||
//! <b>Effects</b>: If link_mode is \c normal_link, the destructor does
|
|
||||||
//! nothing (ie. no code is generated). If link_mode is \c safe_link and the
|
|
||||||
//! object is stored in a set an assertion is raised. If link_mode is
|
|
||||||
//! \c auto_unlink and \c is_linked() is true, the node is unlinked.
|
|
||||||
//!
|
|
||||||
//! <b>Throws</b>: Nothing.
|
|
||||||
~splay_set_base_hook();
|
|
||||||
|
|
||||||
//! <b>Effects</b>: Swapping two nodes swaps the position of the elements
|
|
||||||
//! related to those nodes in one or two containers. That is, if the node
|
|
||||||
//! this is part of the element e1, the node x is part of the element e2
|
|
||||||
//! and both elements are included in the containers s1 and s2, then after
|
|
||||||
//! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1
|
|
||||||
//! at the position of e1. If one element is not in a container, then
|
|
||||||
//! after the swap-operation the other element is not in a container.
|
|
||||||
//! Iterators to e1 and e2 related to those nodes are invalidated.
|
|
||||||
//!
|
|
||||||
//! <b>Complexity</b>: Constant
|
|
||||||
//!
|
|
||||||
//! <b>Throws</b>: Nothing.
|
|
||||||
void swap_nodes(splay_set_base_hook &other);
|
|
||||||
|
|
||||||
//! <b>Precondition</b>: link_mode must be \c safe_link or \c auto_unlink.
|
|
||||||
//!
|
|
||||||
//! <b>Returns</b>: true, if the node belongs to a container, false
|
|
||||||
//! otherwise. This function can be used to test whether \c set::iterator_to
|
|
||||||
//! will return a valid iterator.
|
|
||||||
//!
|
|
||||||
//! <b>Complexity</b>: Constant
|
|
||||||
bool is_linked() const;
|
|
||||||
|
|
||||||
//! <b>Effects</b>: Removes the node if it's inserted in a container.
|
|
||||||
//! This function is only allowed if link_mode is \c auto_unlink.
|
|
||||||
//!
|
|
||||||
//! <b>Throws</b>: Nothing.
|
|
||||||
void unlink();
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
//! Helper metafunction to define a \c splay_set_member_hook that yields to the same
|
|
||||||
//! type when the same options (either explicitly or implicitly) are used.
|
|
||||||
//!
|
|
||||||
//! <b>WARNING: </b> Deprecated class, use `make_bs_set_member_hook` instead.
|
|
||||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
|
||||||
template<class ...Options>
|
|
||||||
#else
|
|
||||||
template<class O1 = void, class O2 = void, class O3 = void>
|
|
||||||
#endif
|
|
||||||
struct make_splay_set_member_hook
|
|
||||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
|
||||||
#if defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
|
||||||
: public make_bs_set_member_hook<Options...>
|
|
||||||
#else
|
|
||||||
: public make_bs_set_member_hook<O1, O2, O3>
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
typedef typename make_bs_set_member_hook
|
|
||||||
<
|
|
||||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
|
||||||
O1, O2, O3
|
|
||||||
#else
|
|
||||||
Options...
|
|
||||||
#endif
|
|
||||||
>::type implementation_defined;
|
|
||||||
/// @endcond
|
|
||||||
typedef implementation_defined type;
|
|
||||||
};
|
|
||||||
|
|
||||||
//! Put a public data member splay_set_member_hook in order to store objects of this
|
|
||||||
//! class in a splay_set/splay_multiset. splay_set_member_hook holds the data
|
|
||||||
//! necessary for maintaining the splay_set/splay_multiset and provides an appropriate
|
|
||||||
//! value_traits class for splay_set/splay_multiset.
|
|
||||||
//!
|
|
||||||
//! The hook admits the following options: \c void_pointer<>,
|
|
||||||
//! \c link_mode<> and \c optimize_size<>.
|
|
||||||
//!
|
|
||||||
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
|
||||||
//! and the the container configured to use this hook.
|
|
||||||
//!
|
|
||||||
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
|
|
||||||
//! \c auto_unlink or \c safe_link).
|
|
||||||
//!
|
|
||||||
//! <b>WARNING: </b> Deprecated class, use `bs_set_member_hook` instead.
|
|
||||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
|
||||||
template<class ...Options>
|
|
||||||
#else
|
|
||||||
template<class O1, class O2, class O3>
|
|
||||||
#endif
|
|
||||||
class splay_set_member_hook
|
|
||||||
: public make_splay_set_member_hook<
|
|
||||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
|
||||||
O1, O2, O3
|
|
||||||
#else
|
|
||||||
Options...
|
|
||||||
#endif
|
|
||||||
>::type
|
|
||||||
{
|
|
||||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
|
||||||
public:
|
|
||||||
//! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
|
|
||||||
//! initializes the node to an unlinked state.
|
|
||||||
//!
|
|
||||||
//! <b>Throws</b>: Nothing.
|
|
||||||
splay_set_member_hook();
|
|
||||||
|
|
||||||
//! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
|
|
||||||
//! initializes the node to an unlinked state. The argument is ignored.
|
|
||||||
//!
|
|
||||||
//! <b>Throws</b>: Nothing.
|
|
||||||
//!
|
|
||||||
//! <b>Rationale</b>: Providing a copy-constructor
|
|
||||||
//! makes classes using the hook STL-compliant without forcing the
|
|
||||||
//! user to do some additional work. \c swap can be used to emulate
|
|
||||||
//! move-semantics.
|
|
||||||
splay_set_member_hook(const splay_set_member_hook& );
|
|
||||||
|
|
||||||
//! <b>Effects</b>: Empty function. The argument is ignored.
|
|
||||||
//!
|
|
||||||
//! <b>Throws</b>: Nothing.
|
|
||||||
//!
|
|
||||||
//! <b>Rationale</b>: Providing an assignment operator
|
|
||||||
//! makes classes using the hook STL-compliant without forcing the
|
|
||||||
//! user to do some additional work. \c swap can be used to emulate
|
|
||||||
//! move-semantics.
|
|
||||||
splay_set_member_hook& operator=(const splay_set_member_hook& );
|
|
||||||
|
|
||||||
//! <b>Effects</b>: If link_mode is \c normal_link, the destructor does
|
|
||||||
//! nothing (ie. no code is generated). If link_mode is \c safe_link and the
|
|
||||||
//! object is stored in a set an assertion is raised. If link_mode is
|
|
||||||
//! \c auto_unlink and \c is_linked() is true, the node is unlinked.
|
|
||||||
//!
|
|
||||||
//! <b>Throws</b>: Nothing.
|
|
||||||
~splay_set_member_hook();
|
|
||||||
|
|
||||||
//! <b>Effects</b>: Swapping two nodes swaps the position of the elements
|
|
||||||
//! related to those nodes in one or two containers. That is, if the node
|
|
||||||
//! this is part of the element e1, the node x is part of the element e2
|
|
||||||
//! and both elements are included in the containers s1 and s2, then after
|
|
||||||
//! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1
|
|
||||||
//! at the position of e1. If one element is not in a container, then
|
|
||||||
//! after the swap-operation the other element is not in a container.
|
|
||||||
//! Iterators to e1 and e2 related to those nodes are invalidated.
|
|
||||||
//!
|
|
||||||
//! <b>Complexity</b>: Constant
|
|
||||||
//!
|
|
||||||
//! <b>Throws</b>: Nothing.
|
|
||||||
void swap_nodes(splay_set_member_hook &other);
|
|
||||||
|
|
||||||
//! <b>Precondition</b>: link_mode must be \c safe_link or \c auto_unlink.
|
|
||||||
//!
|
|
||||||
//! <b>Returns</b>: true, if the node belongs to a container, false
|
|
||||||
//! otherwise. This function can be used to test whether \c set::iterator_to
|
|
||||||
//! will return a valid iterator.
|
|
||||||
//!
|
|
||||||
//! <b>Complexity</b>: Constant
|
|
||||||
bool is_linked() const;
|
|
||||||
|
|
||||||
//! <b>Effects</b>: Removes the node if it's inserted in a container.
|
|
||||||
//! This function is only allowed if link_mode is \c auto_unlink.
|
|
||||||
//!
|
|
||||||
//! <b>Throws</b>: Nothing.
|
|
||||||
void unlink();
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
} //namespace intrusive
|
|
||||||
} //namespace boost
|
|
||||||
|
|
||||||
#include <boost/intrusive/detail/config_end.hpp>
|
|
||||||
|
|
||||||
#endif //BOOST_INTRUSIVE_SPLAY_SET_HOOK_HPP
|
|
@ -13,6 +13,7 @@
|
|||||||
#define BOOST_INTRUSIVE_SPLAYTREE_HPP
|
#define BOOST_INTRUSIVE_SPLAYTREE_HPP
|
||||||
|
|
||||||
#include <boost/intrusive/detail/config_begin.hpp>
|
#include <boost/intrusive/detail/config_begin.hpp>
|
||||||
|
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
@ -20,8 +21,6 @@
|
|||||||
|
|
||||||
#include <boost/intrusive/detail/assert.hpp>
|
#include <boost/intrusive/detail/assert.hpp>
|
||||||
#include <boost/static_assert.hpp>
|
#include <boost/static_assert.hpp>
|
||||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
|
||||||
#include <boost/intrusive/splay_set_hook.hpp>
|
|
||||||
#include <boost/intrusive/bstree.hpp>
|
#include <boost/intrusive/bstree.hpp>
|
||||||
#include <boost/intrusive/detail/tree_node.hpp>
|
#include <boost/intrusive/detail/tree_node.hpp>
|
||||||
#include <boost/intrusive/detail/ebo_functor_holder.hpp>
|
#include <boost/intrusive/detail/ebo_functor_holder.hpp>
|
||||||
@ -77,7 +76,6 @@ class splaytree_impl
|
|||||||
/// @cond
|
/// @cond
|
||||||
typedef bstree_impl< ValueTraits, VoidOrKeyComp, SizeType
|
typedef bstree_impl< ValueTraits, VoidOrKeyComp, SizeType
|
||||||
, ConstantTimeSize, SplayTreeAlgorithms> tree_type;
|
, ConstantTimeSize, SplayTreeAlgorithms> tree_type;
|
||||||
typedef typename tree_type::real_value_traits real_value_traits;
|
|
||||||
typedef tree_type implementation_defined;
|
typedef tree_type implementation_defined;
|
||||||
/// @endcond
|
/// @endcond
|
||||||
|
|
||||||
@ -267,7 +265,6 @@ class splaytree_impl
|
|||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyValueCompare)
|
//! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyValueCompare)
|
||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
|
|
||||||
size_type erase(const KeyType& key, KeyValueCompare comp);
|
size_type erase(const KeyType& key, KeyValueCompare comp);
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,Disposer)
|
//! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,Disposer)
|
||||||
@ -293,60 +290,32 @@ class splaytree_impl
|
|||||||
template<class Disposer>
|
template<class Disposer>
|
||||||
void clear_and_dispose(Disposer disposer);
|
void clear_and_dispose(Disposer disposer);
|
||||||
|
|
||||||
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::count(const_reference)const
|
//! @copydoc ::boost::intrusive::bstree::count(const_reference)const
|
||||||
//! Additional note: non-const function, splaying is performed for the first
|
//! Additional note: non-const function, splaying is performed.
|
||||||
//! element of the equal range of "value"
|
size_type count(const_reference value);
|
||||||
size_type count(const_reference value)
|
|
||||||
{ return this->count(value, this->value_comp()); }
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const
|
//! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const
|
||||||
//! Additional note: non-const function, splaying is performed for the first
|
//! Additional note: non-const function, splaying is performed.
|
||||||
//! element of the equal range of "key"
|
|
||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
size_type count(const KeyType &key, KeyValueCompare comp)
|
size_type count(const KeyType &key, KeyValueCompare comp);
|
||||||
{
|
|
||||||
std::pair<const_iterator, const_iterator> ret = this->equal_range(key, comp);
|
|
||||||
return std::distance(ret.first, ret.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::count(const_reference)const
|
//! @copydoc ::boost::intrusive::bstree::count(const_reference)const
|
||||||
//! Additional note: Deprecated function, use count const overload instead.
|
//! Additional note: const function, no splaying is performed
|
||||||
size_type count(const_reference value) const
|
size_type count(const_reference value) const;
|
||||||
{ return tree_type::count(value); }
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const
|
//! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const
|
||||||
//! Additional note: Deprecated function, use count const overload instead.
|
//! Additional note: const function, no splaying is performed
|
||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
size_type count(const KeyType &key, KeyValueCompare comp) const
|
size_type count(const KeyType &key, KeyValueCompare comp) const;
|
||||||
{ return tree_type::count(key, comp); }
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::count(const_reference)const
|
|
||||||
//! Additional note: Deprecated function, use count const overload instead.
|
|
||||||
size_type count_dont_splay(const_reference value) const
|
|
||||||
{ return tree_type::count(value); }
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const
|
|
||||||
//! Additional note: Deprecated function, use count const overload instead.
|
|
||||||
template<class KeyType, class KeyValueCompare>
|
|
||||||
size_type count_dont_splay(const KeyType &key, KeyValueCompare comp) const
|
|
||||||
{ return tree_type::count(key, comp); }
|
|
||||||
|
|
||||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)
|
//! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)
|
||||||
//! Additional note: non-const function, splaying is performed for the first
|
//! Additional note: non-const function, splaying is performed.
|
||||||
//! element of the equal range of "value"
|
|
||||||
iterator lower_bound(const_reference value);
|
iterator lower_bound(const_reference value);
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)const
|
//! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)const
|
||||||
//! Additional note: const function, no splaying is performed
|
//! Additional note: const function, no splaying is performed
|
||||||
const_iterator lower_bound(const_reference value) const;
|
const_iterator lower_bound(const_reference value) const;
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)const
|
|
||||||
//! Additional note: Deprecated function, use lower_bound const overload instead.
|
|
||||||
const_iterator lower_bound_dont_splay(const_reference value) const;
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)
|
//! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)
|
||||||
//! Additional note: non-const function, splaying is performed for the first
|
//! Additional note: non-const function, splaying is performed for the first
|
||||||
//! element of the equal range of "key"
|
//! element of the equal range of "key"
|
||||||
@ -358,11 +327,6 @@ class splaytree_impl
|
|||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
const_iterator lower_bound(const KeyType &key, KeyValueCompare comp) const;
|
const_iterator lower_bound(const KeyType &key, KeyValueCompare comp) const;
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)
|
|
||||||
//! Additional note: Deprecated function, use lower_bound const overload instead.
|
|
||||||
template<class KeyType, class KeyValueCompare>
|
|
||||||
iterator lower_bound_dont_splay(const KeyType &key, KeyValueCompare comp) const;
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)
|
//! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)
|
||||||
//! Additional note: non-const function, splaying is performed for the first
|
//! Additional note: non-const function, splaying is performed for the first
|
||||||
//! element of the equal range of "value"
|
//! element of the equal range of "value"
|
||||||
@ -372,10 +336,6 @@ class splaytree_impl
|
|||||||
//! Additional note: const function, no splaying is performed
|
//! Additional note: const function, no splaying is performed
|
||||||
const_iterator upper_bound(const_reference value) const;
|
const_iterator upper_bound(const_reference value) const;
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)const
|
|
||||||
//! Additional note: Deprecated function, use upper_bound const overload instead.
|
|
||||||
const_iterator upper_bound_dont_splay(const_reference value) const;
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)
|
//! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)
|
||||||
//! Additional note: non-const function, splaying is performed for the first
|
//! Additional note: non-const function, splaying is performed for the first
|
||||||
//! element of the equal range of "key"
|
//! element of the equal range of "key"
|
||||||
@ -387,11 +347,6 @@ class splaytree_impl
|
|||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
const_iterator upper_bound(const KeyType &key, KeyValueCompare comp) const;
|
const_iterator upper_bound(const KeyType &key, KeyValueCompare comp) const;
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)
|
|
||||||
//! Additional note: Deprecated function, use upper_bound const overload instead.
|
|
||||||
template<class KeyType, class KeyValueCompare>
|
|
||||||
const_iterator upper_bound_dont_splay(const KeyType &key, KeyValueCompare comp) const;
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::find(const_reference)
|
//! @copydoc ::boost::intrusive::bstree::find(const_reference)
|
||||||
//! Additional note: non-const function, splaying is performed for the first
|
//! Additional note: non-const function, splaying is performed for the first
|
||||||
//! element of the equal range of "value"
|
//! element of the equal range of "value"
|
||||||
@ -401,10 +356,6 @@ class splaytree_impl
|
|||||||
//! Additional note: const function, no splaying is performed
|
//! Additional note: const function, no splaying is performed
|
||||||
const_iterator find(const_reference value) const;
|
const_iterator find(const_reference value) const;
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::find(const_reference)const
|
|
||||||
//! Additional note: Deprecated function, use find const overload instead.
|
|
||||||
const_iterator find_dont_splay(const_reference value) const;
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)
|
//! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)
|
||||||
//! Additional note: non-const function, splaying is performed for the first
|
//! Additional note: non-const function, splaying is performed for the first
|
||||||
//! element of the equal range of "key"
|
//! element of the equal range of "key"
|
||||||
@ -416,11 +367,6 @@ class splaytree_impl
|
|||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
const_iterator find(const KeyType &key, KeyValueCompare comp) const;
|
const_iterator find(const KeyType &key, KeyValueCompare comp) const;
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)const
|
|
||||||
//! Additional note: Deprecated function, use find const overload instead.
|
|
||||||
template<class KeyType, class KeyValueCompare>
|
|
||||||
const_iterator find_dont_splay(const KeyType &key, KeyValueCompare comp) const;
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)
|
//! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)
|
||||||
//! Additional note: non-const function, splaying is performed for the first
|
//! Additional note: non-const function, splaying is performed for the first
|
||||||
//! element of the equal range of "value"
|
//! element of the equal range of "value"
|
||||||
@ -430,10 +376,6 @@ class splaytree_impl
|
|||||||
//! Additional note: const function, no splaying is performed
|
//! Additional note: const function, no splaying is performed
|
||||||
std::pair<const_iterator, const_iterator> equal_range(const_reference value) const;
|
std::pair<const_iterator, const_iterator> equal_range(const_reference value) const;
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)const
|
|
||||||
//! Additional note: Deprecated function, use equal_range const overload instead.
|
|
||||||
std::pair<const_iterator, const_iterator> equal_range_dont_splay(const_reference value) const;
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)
|
//! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)
|
||||||
//! Additional note: non-const function, splaying is performed for the first
|
//! Additional note: non-const function, splaying is performed for the first
|
||||||
//! element of the equal range of "key"
|
//! element of the equal range of "key"
|
||||||
@ -445,11 +387,6 @@ class splaytree_impl
|
|||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
std::pair<const_iterator, const_iterator> equal_range(const KeyType &key, KeyValueCompare comp) const;
|
std::pair<const_iterator, const_iterator> equal_range(const KeyType &key, KeyValueCompare comp) const;
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)
|
|
||||||
//! Additional note: Deprecated function, use equal_range const overload instead.
|
|
||||||
template<class KeyType, class KeyValueCompare>
|
|
||||||
std::pair<const_iterator, const_iterator> equal_range_dont_splay(const KeyType &key, KeyValueCompare comp) const;
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)
|
//! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)
|
||||||
std::pair<iterator,iterator> bounded_range
|
std::pair<iterator,iterator> bounded_range
|
||||||
(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
|
(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
|
||||||
@ -468,17 +405,6 @@ class splaytree_impl
|
|||||||
std::pair<const_iterator, const_iterator> bounded_range
|
std::pair<const_iterator, const_iterator> bounded_range
|
||||||
(const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
|
(const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)const
|
|
||||||
//! Additional note: Deprecated function, use bounded_range const overload instead.
|
|
||||||
std::pair<const_iterator, const_iterator> bounded_range_dont_splay
|
|
||||||
(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
|
|
||||||
//! Additional note: Deprecated function, use bounded_range const overload instead.
|
|
||||||
template<class KeyType, class KeyValueCompare>
|
|
||||||
std::pair<const_iterator, const_iterator> bounded_range_dont_splay
|
|
||||||
(const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::s_iterator_to(reference)
|
//! @copydoc ::boost::intrusive::bstree::s_iterator_to(reference)
|
||||||
static iterator s_iterator_to(reference value);
|
static iterator s_iterator_to(reference value);
|
||||||
|
|
||||||
@ -529,10 +455,10 @@ class splaytree_impl
|
|||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
iterator splay_down(const KeyType &key, KeyValueCompare comp)
|
iterator splay_down(const KeyType &key, KeyValueCompare comp)
|
||||||
{
|
{
|
||||||
detail::key_nodeptr_comp<value_compare, real_value_traits>
|
detail::key_nodeptr_comp<value_compare, value_traits>
|
||||||
key_node_comp(comp, &this->get_real_value_traits());
|
key_node_comp(comp, &this->get_value_traits());
|
||||||
node_ptr r = node_algorithms::splay_down(tree_type::header_ptr(), key, key_node_comp);
|
node_ptr r = node_algorithms::splay_down(tree_type::header_ptr(), key, key_node_comp);
|
||||||
return iterator(r, this->real_value_traits_ptr());
|
return iterator(r, this->value_traits_ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
//! <b>Effects</b>: Rearranges the container so that if *this stores an element
|
//! <b>Effects</b>: Rearranges the container so that if *this stores an element
|
||||||
@ -644,14 +570,13 @@ class splaytree
|
|||||||
public:
|
public:
|
||||||
typedef typename Base::value_compare value_compare;
|
typedef typename Base::value_compare value_compare;
|
||||||
typedef typename Base::value_traits value_traits;
|
typedef typename Base::value_traits value_traits;
|
||||||
typedef typename Base::real_value_traits real_value_traits;
|
|
||||||
typedef typename Base::iterator iterator;
|
typedef typename Base::iterator iterator;
|
||||||
typedef typename Base::const_iterator const_iterator;
|
typedef typename Base::const_iterator const_iterator;
|
||||||
typedef typename Base::reverse_iterator reverse_iterator;
|
typedef typename Base::reverse_iterator reverse_iterator;
|
||||||
typedef typename Base::const_reverse_iterator const_reverse_iterator;
|
typedef typename Base::const_reverse_iterator const_reverse_iterator;
|
||||||
|
|
||||||
//Assert if passed value traits are compatible with the type
|
//Assert if passed value traits are compatible with the type
|
||||||
BOOST_STATIC_ASSERT((detail::is_same<typename real_value_traits::value_type, T>::value));
|
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
|
||||||
|
|
||||||
explicit splaytree( const value_compare &cmp = value_compare()
|
explicit splaytree( const value_compare &cmp = value_compare()
|
||||||
, const value_traits &v_traits = value_traits())
|
, const value_traits &v_traits = value_traits())
|
||||||
|
@ -31,8 +31,8 @@
|
|||||||
#define BOOST_INTRUSIVE_SPLAYTREE_ALGORITHMS_HPP
|
#define BOOST_INTRUSIVE_SPLAYTREE_ALGORITHMS_HPP
|
||||||
|
|
||||||
#include <boost/intrusive/detail/config_begin.hpp>
|
#include <boost/intrusive/detail/config_begin.hpp>
|
||||||
#include <boost/intrusive/detail/assert.hpp>
|
|
||||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||||
|
#include <boost/intrusive/detail/assert.hpp>
|
||||||
#include <boost/intrusive/pointer_traits.hpp>
|
#include <boost/intrusive/pointer_traits.hpp>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <boost/intrusive/detail/utilities.hpp>
|
#include <boost/intrusive/detail/utilities.hpp>
|
||||||
@ -45,33 +45,70 @@ namespace intrusive {
|
|||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template<class NodeTraits>
|
template<class NodeTraits>
|
||||||
struct splaydown_rollback
|
struct splaydown_assemble_and_fix_header
|
||||||
{
|
{
|
||||||
typedef typename NodeTraits::node_ptr node_ptr;
|
typedef typename NodeTraits::node_ptr node_ptr;
|
||||||
splaydown_rollback( const node_ptr *pcur_subtree, const node_ptr & header
|
|
||||||
, const node_ptr & leftmost , const node_ptr & rightmost)
|
splaydown_assemble_and_fix_header(const node_ptr & t, const node_ptr & header, const node_ptr &leftmost, const node_ptr &rightmost)
|
||||||
: pcur_subtree_(pcur_subtree) , header_(header)
|
: t_(t)
|
||||||
, leftmost_(leftmost) , rightmost_(rightmost)
|
, null_node_(header)
|
||||||
|
, l_(null_node_)
|
||||||
|
, r_(null_node_)
|
||||||
|
, leftmost_(leftmost)
|
||||||
|
, rightmost_(rightmost)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void release()
|
~splaydown_assemble_and_fix_header()
|
||||||
{ pcur_subtree_ = 0; }
|
|
||||||
|
|
||||||
~splaydown_rollback()
|
|
||||||
{
|
{
|
||||||
if(pcur_subtree_){
|
this->assemble();
|
||||||
//Exception can only be thrown by comp, but
|
|
||||||
//tree invariants still hold. *pcur_subtree is the current root
|
//Now recover the original header except for the
|
||||||
//so link it to the header.
|
//splayed root node.
|
||||||
NodeTraits::set_parent(*pcur_subtree_, header_);
|
//"t_" is the current root and "null_node_" is the header node
|
||||||
NodeTraits::set_parent(header_, *pcur_subtree_);
|
NodeTraits::set_parent(null_node_, t_);
|
||||||
//Recover leftmost/rightmost pointers
|
NodeTraits::set_parent(t_, null_node_);
|
||||||
NodeTraits::set_left (header_, leftmost_);
|
//Recover leftmost/rightmost pointers
|
||||||
NodeTraits::set_right(header_, rightmost_);
|
NodeTraits::set_left (null_node_, leftmost_);
|
||||||
|
NodeTraits::set_right(null_node_, rightmost_);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void assemble()
|
||||||
|
{
|
||||||
|
//procedure assemble;
|
||||||
|
// left(r), right(l) := right(t), left(t);
|
||||||
|
// left(t), right(t) := right(null), left(null);
|
||||||
|
//end assemble;
|
||||||
|
{ // left(r), right(l) := right(t), left(t);
|
||||||
|
|
||||||
|
node_ptr const old_t_left = NodeTraits::get_left(t_);
|
||||||
|
node_ptr const old_t_right = NodeTraits::get_right(t_);
|
||||||
|
NodeTraits::set_right(l_, old_t_left);
|
||||||
|
NodeTraits::set_left (r_, old_t_right);
|
||||||
|
if(old_t_left){
|
||||||
|
NodeTraits::set_parent(old_t_left, l_);
|
||||||
|
}
|
||||||
|
if(old_t_right){
|
||||||
|
NodeTraits::set_parent(old_t_right, r_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{ // left(t), right(t) := right(null), left(null);
|
||||||
|
node_ptr const null_right = NodeTraits::get_right(null_node_);
|
||||||
|
node_ptr const null_left = NodeTraits::get_left(null_node_);
|
||||||
|
NodeTraits::set_left (t_, null_right);
|
||||||
|
NodeTraits::set_right(t_, null_left);
|
||||||
|
if(null_right){
|
||||||
|
NodeTraits::set_parent(null_right, t_);
|
||||||
|
}
|
||||||
|
if(null_left){
|
||||||
|
NodeTraits::set_parent(null_left, t_);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const node_ptr *pcur_subtree_;
|
|
||||||
node_ptr header_, leftmost_, rightmost_;
|
public:
|
||||||
|
node_ptr t_, null_node_, l_, r_, leftmost_, rightmost_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} //namespace detail {
|
} //namespace detail {
|
||||||
@ -184,32 +221,28 @@ class splaytree_algorithms
|
|||||||
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree_algorithms::erase(const node_ptr&,const node_ptr&)
|
//! @copydoc ::boost::intrusive::bstree_algorithms::erase(const node_ptr&,const node_ptr&)
|
||||||
//! Additional notes: the previous node of z is splayed. The "splay" parameter which indicated if splaying
|
//! Additional notes: the previous node of z is splayed to speed up range deletions.
|
||||||
//! should be performed, it's deprecated and will disappear in future versions.
|
static void erase(const node_ptr & header, const node_ptr & z)
|
||||||
static void erase(const node_ptr & header, const node_ptr & z, bool splay = true)
|
|
||||||
{
|
{
|
||||||
//posibility 1
|
//posibility 1
|
||||||
if(splay && NodeTraits::get_left(z)){
|
if(NodeTraits::get_left(z)){
|
||||||
splay_up(bstree_algo::prev_node(z), header);
|
splay_up(bstree_algo::prev_node(z), header);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
//possibility 2
|
//possibility 2
|
||||||
if(splay && NodeTraits::get_left(z)){
|
if(NodeTraits::get_left(z)){
|
||||||
node_ptr l = NodeTraits::get_left(z);
|
node_ptr l = NodeTraits::get_left(z);
|
||||||
splay_up(l, header);
|
splay_up(l, header);
|
||||||
}*//*
|
}*/
|
||||||
if(splay && NodeTraits::get_left(z)){
|
/*
|
||||||
|
if(NodeTraits::get_left(z)){
|
||||||
node_ptr l = bstree_algo::prev_node(z);
|
node_ptr l = bstree_algo::prev_node(z);
|
||||||
splay_up_impl(l, z);
|
splay_up_impl(l, z);
|
||||||
}*/
|
}*/
|
||||||
/*
|
/*
|
||||||
//possibility 4
|
//possibility 4
|
||||||
if(splay){
|
splay_up(z, header);
|
||||||
splay_up(z, header);
|
*/
|
||||||
}*/
|
|
||||||
|
|
||||||
//if(splay)
|
|
||||||
//splay_up(z, header);
|
|
||||||
bstree_algo::erase(header, z);
|
bstree_algo::erase(header, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,7 +258,7 @@ class splaytree_algorithms
|
|||||||
|
|
||||||
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
//! @copydoc ::boost::intrusive::bstree_algorithms::count(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
//! @copydoc ::boost::intrusive::bstree_algorithms::count(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
||||||
//! Additional notes: the first node of the range is splayed.
|
//! Additional notes: an element with key `key` is splayed.
|
||||||
template<class KeyType, class KeyNodePtrCompare>
|
template<class KeyType, class KeyNodePtrCompare>
|
||||||
static std::size_t count
|
static std::size_t count
|
||||||
(const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
(const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
||||||
@ -247,15 +280,14 @@ class splaytree_algorithms
|
|||||||
{ return bstree_algo::count(header, key, comp); }
|
{ return bstree_algo::count(header, key, comp); }
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
//! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
||||||
//! Additional notes: the first node of the range is splayed. The "splay" parameter which indicated if splaying
|
//! Additional notes: the first node of the range is splayed.
|
||||||
//! should be performed, it's deprecated and will disappear in future versions.
|
|
||||||
template<class KeyType, class KeyNodePtrCompare>
|
template<class KeyType, class KeyNodePtrCompare>
|
||||||
static node_ptr lower_bound
|
static node_ptr lower_bound
|
||||||
(const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp, bool splay = true)
|
(const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
||||||
{
|
{
|
||||||
//splay_down(detail::uncast(header), key, comp);
|
splay_down(detail::uncast(header), key, comp);
|
||||||
node_ptr y = bstree_algo::lower_bound(header, key, comp);
|
node_ptr y = bstree_algo::lower_bound(header, key, comp);
|
||||||
if(splay) splay_up(y, detail::uncast(header));
|
//splay_up(y, detail::uncast(header));
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,15 +299,14 @@ class splaytree_algorithms
|
|||||||
{ return bstree_algo::lower_bound(header, key, comp); }
|
{ return bstree_algo::lower_bound(header, key, comp); }
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
//! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
||||||
//! Additional notes: the first node of the range is splayed. The "splay" parameter which indicated if splaying
|
//! Additional notes: the first node of the range is splayed.
|
||||||
//! should be performed, it's deprecated and will disappear in future versions.
|
|
||||||
template<class KeyType, class KeyNodePtrCompare>
|
template<class KeyType, class KeyNodePtrCompare>
|
||||||
static node_ptr upper_bound
|
static node_ptr upper_bound
|
||||||
(const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp, bool splay = true)
|
(const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
||||||
{
|
{
|
||||||
//splay_down(detail::uncast(header), key, comp);
|
splay_down(detail::uncast(header), key, comp);
|
||||||
node_ptr y = bstree_algo::upper_bound(header, key, comp);
|
node_ptr y = bstree_algo::upper_bound(header, key, comp);
|
||||||
if(splay) splay_up(y, detail::uncast(header));
|
//splay_up(y, detail::uncast(header));
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,17 +318,13 @@ class splaytree_algorithms
|
|||||||
{ return bstree_algo::upper_bound(header, key, comp); }
|
{ return bstree_algo::upper_bound(header, key, comp); }
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree_algorithms::find(const const_node_ptr&, const KeyType&,KeyNodePtrCompare)
|
//! @copydoc ::boost::intrusive::bstree_algorithms::find(const const_node_ptr&, const KeyType&,KeyNodePtrCompare)
|
||||||
//! Additional notes: the found node of the lower bound is splayed. The "splay" parameter which indicated if splaying
|
//! Additional notes: the found node of the lower bound is splayed.
|
||||||
//! should be performed, it's deprecated and will disappear in future versions.
|
|
||||||
template<class KeyType, class KeyNodePtrCompare>
|
template<class KeyType, class KeyNodePtrCompare>
|
||||||
static node_ptr find
|
static node_ptr find
|
||||||
(const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp, bool splay = true)
|
(const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
||||||
{
|
{
|
||||||
if(splay) splay_down(detail::uncast(header), key, comp);
|
splay_down(detail::uncast(header), key, comp);
|
||||||
node_ptr end = detail::uncast(header);
|
return bstree_algo::find(header, key, comp);
|
||||||
node_ptr y = bstree_algo::lower_bound(header, key, comp);
|
|
||||||
node_ptr r = (y == end || comp(key, y)) ? end : y;
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree_algorithms::find(const const_node_ptr&, const KeyType&,KeyNodePtrCompare)
|
//! @copydoc ::boost::intrusive::bstree_algorithms::find(const const_node_ptr&, const KeyType&,KeyNodePtrCompare)
|
||||||
@ -308,15 +335,14 @@ class splaytree_algorithms
|
|||||||
{ return bstree_algo::find(header, key, comp); }
|
{ return bstree_algo::find(header, key, comp); }
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
//! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
||||||
//! Additional notes: the first node of the range is splayed. The "splay" parameter which indicated if splaying
|
//! Additional notes: the first node of the range is splayed.
|
||||||
//! should be performed, it's deprecated and will disappear in future versions.
|
|
||||||
template<class KeyType, class KeyNodePtrCompare>
|
template<class KeyType, class KeyNodePtrCompare>
|
||||||
static std::pair<node_ptr, node_ptr> equal_range
|
static std::pair<node_ptr, node_ptr> equal_range
|
||||||
(const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp, bool splay = true)
|
(const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
||||||
{
|
{
|
||||||
//splay_down(detail::uncast(header), key, comp);
|
splay_down(detail::uncast(header), key, comp);
|
||||||
std::pair<node_ptr, node_ptr> ret = bstree_algo::equal_range(header, key, comp);
|
std::pair<node_ptr, node_ptr> ret = bstree_algo::equal_range(header, key, comp);
|
||||||
if(splay) splay_up(ret.first, detail::uncast(header));
|
//splay_up(ret.first, detail::uncast(header));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,17 +353,36 @@ class splaytree_algorithms
|
|||||||
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
||||||
{ return bstree_algo::equal_range(header, key, comp); }
|
{ return bstree_algo::equal_range(header, key, comp); }
|
||||||
|
|
||||||
|
//! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound_range(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
||||||
|
//! Additional notes: the first node of the range is splayed.
|
||||||
|
template<class KeyType, class KeyNodePtrCompare>
|
||||||
|
static std::pair<node_ptr, node_ptr> lower_bound_range
|
||||||
|
(const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
||||||
|
{
|
||||||
|
splay_down(detail::uncast(header), key, comp);
|
||||||
|
std::pair<node_ptr, node_ptr> ret = bstree_algo::lower_bound_range(header, key, comp);
|
||||||
|
//splay_up(ret.first, detail::uncast(header));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound_range(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
||||||
|
//! Additional note: no splaying is performed
|
||||||
|
template<class KeyType, class KeyNodePtrCompare>
|
||||||
|
static std::pair<node_ptr, node_ptr> lower_bound_range
|
||||||
|
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
||||||
|
{ return bstree_algo::lower_bound_range(header, key, comp); }
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const const_node_ptr&,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool)
|
//! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const const_node_ptr&,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool)
|
||||||
//! Additional notes: the first node of the range is splayed. The "splay" parameter which indicated if splaying
|
//! Additional notes: the first node of the range is splayed.
|
||||||
//! should be performed, it's deprecated and will disappear in future versions.
|
|
||||||
template<class KeyType, class KeyNodePtrCompare>
|
template<class KeyType, class KeyNodePtrCompare>
|
||||||
static std::pair<node_ptr, node_ptr> bounded_range
|
static std::pair<node_ptr, node_ptr> bounded_range
|
||||||
(const node_ptr & header, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp
|
(const node_ptr & header, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp
|
||||||
, bool left_closed, bool right_closed, bool splay = true)
|
, bool left_closed, bool right_closed)
|
||||||
{
|
{
|
||||||
|
splay_down(detail::uncast(header), lower_key, comp);
|
||||||
std::pair<node_ptr, node_ptr> ret =
|
std::pair<node_ptr, node_ptr> ret =
|
||||||
bstree_algo::bounded_range(header, lower_key, upper_key, comp, left_closed, right_closed);
|
bstree_algo::bounded_range(header, lower_key, upper_key, comp, left_closed, right_closed);
|
||||||
if(splay) splay_up(ret.first, detail::uncast(header));
|
//splay_up(ret.first, detail::uncast(header));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -445,6 +490,20 @@ class splaytree_algorithms
|
|||||||
|
|
||||||
// bottom-up splay, use data_ as parent for n | complexity : logarithmic | exception : nothrow
|
// bottom-up splay, use data_ as parent for n | complexity : logarithmic | exception : nothrow
|
||||||
static void splay_up(const node_ptr & node, const node_ptr & header)
|
static void splay_up(const node_ptr & node, const node_ptr & header)
|
||||||
|
{ priv_splay_up<true>(node, header); }
|
||||||
|
|
||||||
|
// top-down splay | complexity : logarithmic | exception : strong, note A
|
||||||
|
template<class KeyType, class KeyNodePtrCompare>
|
||||||
|
static node_ptr splay_down(const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp, bool *pfound = 0)
|
||||||
|
{ return priv_splay_down<true>(header, key, comp, pfound); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/// @cond
|
||||||
|
|
||||||
|
// bottom-up splay, use data_ as parent for n | complexity : logarithmic | exception : nothrow
|
||||||
|
template<bool SimpleSplay>
|
||||||
|
static void priv_splay_up(const node_ptr & node, const node_ptr & header)
|
||||||
{
|
{
|
||||||
// If (node == header) do a splay for the right most node instead
|
// If (node == header) do a splay for the right most node instead
|
||||||
// this is to boost performance of equal_range/count on equivalent containers in the case
|
// this is to boost performance of equal_range/count on equivalent containers in the case
|
||||||
@ -470,20 +529,19 @@ class splaytree_algorithms
|
|||||||
rotate(p);
|
rotate(p);
|
||||||
rotate(n);
|
rotate(n);
|
||||||
}
|
}
|
||||||
else{
|
else {
|
||||||
// zig-zag
|
// zig-zag
|
||||||
rotate(n);
|
rotate(n);
|
||||||
rotate(n);
|
if(!SimpleSplay){
|
||||||
|
rotate(n);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// top-down splay | complexity : logarithmic | exception : strong, note A
|
template<bool SimpleSplay, class KeyType, class KeyNodePtrCompare>
|
||||||
template<class KeyType, class KeyNodePtrCompare>
|
static node_ptr priv_splay_down(const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp, bool *pfound = 0)
|
||||||
static node_ptr splay_down(const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
|
||||||
{
|
{
|
||||||
if(!NodeTraits::get_parent(header))
|
|
||||||
return header;
|
|
||||||
//Most splay tree implementations use a dummy/null node to implement.
|
//Most splay tree implementations use a dummy/null node to implement.
|
||||||
//this function. This has some problems for a generic library like Intrusive:
|
//this function. This has some problems for a generic library like Intrusive:
|
||||||
//
|
//
|
||||||
@ -494,118 +552,87 @@ class splaytree_algorithms
|
|||||||
//are not changed when splaying (because the invariants of the tree don't
|
//are not changed when splaying (because the invariants of the tree don't
|
||||||
//change) We can back up them, use the header as the null node and
|
//change) We can back up them, use the header as the null node and
|
||||||
//reassign old values after the function has been completed.
|
//reassign old values after the function has been completed.
|
||||||
node_ptr t = NodeTraits::get_parent(header);
|
node_ptr const old_root = NodeTraits::get_parent(header);
|
||||||
//Check if tree has a single node
|
node_ptr const leftmost = NodeTraits::get_left(header);
|
||||||
if(!NodeTraits::get_left(t) && !NodeTraits::get_right(t))
|
node_ptr const rightmost = NodeTraits::get_right(header);
|
||||||
return t;
|
if(leftmost == rightmost){ //Empty or unique node
|
||||||
//Backup leftmost/rightmost
|
if(pfound){
|
||||||
node_ptr leftmost (NodeTraits::get_left(header));
|
*pfound = old_root && !comp(key, old_root) && !comp(old_root, key);
|
||||||
node_ptr rightmost(NodeTraits::get_right(header));
|
}
|
||||||
{
|
return old_root ? old_root : header;
|
||||||
//Anti-exception rollback, recovers the original header node if an exception is thrown.
|
}
|
||||||
detail::splaydown_rollback<NodeTraits> rollback(&t, header, leftmost, rightmost);
|
else{
|
||||||
node_ptr null_node = header;
|
//Initialize "null node" (the header in our case)
|
||||||
node_ptr l = null_node;
|
NodeTraits::set_left (header, node_ptr());
|
||||||
node_ptr r = null_node;
|
NodeTraits::set_right(header, node_ptr());
|
||||||
|
//Class that will backup leftmost/rightmost from header, commit the assemble(),
|
||||||
|
//and will restore leftmost/rightmost to header even if "comp" throws
|
||||||
|
detail::splaydown_assemble_and_fix_header<NodeTraits> commit(old_root, header, leftmost, rightmost);
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
for( ;; ){
|
for( ;; ){
|
||||||
if(comp(key, t)){
|
if(comp(key, commit.t_)){
|
||||||
if(NodeTraits::get_left(t) == node_ptr() )
|
node_ptr const t_left = NodeTraits::get_left(commit.t_);
|
||||||
|
if(!t_left)
|
||||||
break;
|
break;
|
||||||
if(comp(key, NodeTraits::get_left(t))){
|
if(comp(key, t_left)){
|
||||||
t = bstree_algo::rotate_right(t);
|
bstree_algo::rotate_right_no_parent_fix(commit.t_, t_left);
|
||||||
|
commit.t_ = t_left;
|
||||||
if(NodeTraits::get_left(t) == node_ptr())
|
if( !NodeTraits::get_left(commit.t_) )
|
||||||
break;
|
break;
|
||||||
link_right(t, r);
|
link_right(commit.t_, commit.r_);
|
||||||
}
|
|
||||||
else if(comp(NodeTraits::get_left(t), key)){
|
|
||||||
link_right(t, r);
|
|
||||||
|
|
||||||
if(NodeTraits::get_right(t) == node_ptr() )
|
|
||||||
break;
|
|
||||||
link_left(t, l);
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
link_right(t, r);
|
link_right(commit.t_, commit.r_);
|
||||||
|
if(!SimpleSplay && comp(t_left, key)){
|
||||||
|
if( !NodeTraits::get_right(commit.t_) )
|
||||||
|
break;
|
||||||
|
link_left(commit.t_, commit.l_);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(comp(t, key)){
|
else if(comp(commit.t_, key)){
|
||||||
if(NodeTraits::get_right(t) == node_ptr() )
|
node_ptr const t_right = NodeTraits::get_right(commit.t_);
|
||||||
|
if(!t_right)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if(comp(NodeTraits::get_right(t), key)){
|
if(comp(t_right, key)){
|
||||||
t = bstree_algo::rotate_left( t );
|
bstree_algo::rotate_left_no_parent_fix(commit.t_, t_right);
|
||||||
|
commit.t_ = t_right;
|
||||||
if(NodeTraits::get_right(t) == node_ptr() )
|
if( !NodeTraits::get_right(commit.t_) )
|
||||||
break;
|
break;
|
||||||
link_left(t, l);
|
link_left(commit.t_, commit.l_);
|
||||||
}
|
|
||||||
else if(comp(key, NodeTraits::get_right(t))){
|
|
||||||
link_left(t, l);
|
|
||||||
|
|
||||||
if(NodeTraits::get_left(t) == node_ptr())
|
|
||||||
break;
|
|
||||||
|
|
||||||
link_right(t, r);
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
link_left(t, l);
|
link_left(commit.t_, commit.l_);
|
||||||
|
if(!SimpleSplay && comp(key, t_right)){
|
||||||
|
if( !NodeTraits::get_left(commit.t_) )
|
||||||
|
break;
|
||||||
|
link_right(commit.t_, commit.r_);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assemble(t, l, r, null_node);
|
//commit.~splaydown_assemble_and_fix_header<NodeTraits>() will first
|
||||||
rollback.release();
|
//"assemble()" + link the new root & recover header's leftmost & rightmost
|
||||||
}
|
if(pfound){
|
||||||
|
*pfound = found;
|
||||||
//Now recover the original header except for the
|
}
|
||||||
//splayed root node.
|
return commit.t_;
|
||||||
//t is the current root
|
|
||||||
NodeTraits::set_parent(header, t);
|
|
||||||
NodeTraits::set_parent(t, header);
|
|
||||||
//Recover leftmost/rightmost pointers
|
|
||||||
NodeTraits::set_left (header, leftmost);
|
|
||||||
NodeTraits::set_right(header, rightmost);
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
/// @cond
|
|
||||||
|
|
||||||
// assemble the three sub-trees into new tree pointed to by t | complexity : constant | exception : nothrow
|
|
||||||
static void assemble(const node_ptr &t, const node_ptr & l, const node_ptr & r, const const_node_ptr & null_node )
|
|
||||||
{
|
|
||||||
NodeTraits::set_right(l, NodeTraits::get_left(t));
|
|
||||||
NodeTraits::set_left(r, NodeTraits::get_right(t));
|
|
||||||
|
|
||||||
if(NodeTraits::get_right(l) != node_ptr()){
|
|
||||||
NodeTraits::set_parent(NodeTraits::get_right(l), l);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(NodeTraits::get_left(r) != node_ptr()){
|
|
||||||
NodeTraits::set_parent(NodeTraits::get_left(r), r);
|
|
||||||
}
|
|
||||||
|
|
||||||
NodeTraits::set_left (t, NodeTraits::get_right(null_node));
|
|
||||||
NodeTraits::set_right(t, NodeTraits::get_left(null_node));
|
|
||||||
|
|
||||||
if( NodeTraits::get_left(t) != node_ptr() ){
|
|
||||||
NodeTraits::set_parent(NodeTraits::get_left(t), t);
|
|
||||||
}
|
|
||||||
|
|
||||||
if( NodeTraits::get_right(t) ){
|
|
||||||
NodeTraits::set_parent(NodeTraits::get_right(t), t);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// break link to left child node and attach it to left tree pointed to by l | complexity : constant | exception : nothrow
|
// break link to left child node and attach it to left tree pointed to by l | complexity : constant | exception : nothrow
|
||||||
static void link_left(node_ptr & t, node_ptr & l)
|
static void link_left(node_ptr & t, node_ptr & l)
|
||||||
{
|
{
|
||||||
|
//procedure link_left;
|
||||||
|
// t, l, right(l) := right(t), t, t
|
||||||
|
//end link_left
|
||||||
NodeTraits::set_right(l, t);
|
NodeTraits::set_right(l, t);
|
||||||
NodeTraits::set_parent(t, l);
|
NodeTraits::set_parent(t, l);
|
||||||
l = t;
|
l = t;
|
||||||
@ -615,6 +642,9 @@ class splaytree_algorithms
|
|||||||
// break link to right child node and attach it to right tree pointed to by r | complexity : constant | exception : nothrow
|
// break link to right child node and attach it to right tree pointed to by r | complexity : constant | exception : nothrow
|
||||||
static void link_right(node_ptr & t, node_ptr & r)
|
static void link_right(node_ptr & t, node_ptr & r)
|
||||||
{
|
{
|
||||||
|
//procedure link_right;
|
||||||
|
// t, r, left(r) := left(t), t, t
|
||||||
|
//end link_right;
|
||||||
NodeTraits::set_left(r, t);
|
NodeTraits::set_left(r, t);
|
||||||
NodeTraits::set_parent(t, r);
|
NodeTraits::set_parent(t, r);
|
||||||
r = t;
|
r = t;
|
||||||
@ -624,6 +654,9 @@ class splaytree_algorithms
|
|||||||
// rotate n with its parent | complexity : constant | exception : nothrow
|
// rotate n with its parent | complexity : constant | exception : nothrow
|
||||||
static void rotate(const node_ptr & n)
|
static void rotate(const node_ptr & n)
|
||||||
{
|
{
|
||||||
|
//procedure rotate_left;
|
||||||
|
// t, right(t), left(right(t)) := right(t), left(right(t)), t
|
||||||
|
//end rotate_left;
|
||||||
node_ptr p = NodeTraits::get_parent(n);
|
node_ptr p = NodeTraits::get_parent(n);
|
||||||
node_ptr g = NodeTraits::get_parent(p);
|
node_ptr g = NodeTraits::get_parent(p);
|
||||||
//Test if g is header before breaking tree
|
//Test if g is header before breaking tree
|
||||||
@ -632,13 +665,13 @@ class splaytree_algorithms
|
|||||||
|
|
||||||
if(NodeTraits::get_left(p) == n){
|
if(NodeTraits::get_left(p) == n){
|
||||||
NodeTraits::set_left(p, NodeTraits::get_right(n));
|
NodeTraits::set_left(p, NodeTraits::get_right(n));
|
||||||
if(NodeTraits::get_left(p) != node_ptr())
|
if(NodeTraits::get_left(p))
|
||||||
NodeTraits::set_parent(NodeTraits::get_left(p), p);
|
NodeTraits::set_parent(NodeTraits::get_left(p), p);
|
||||||
NodeTraits::set_right(n, p);
|
NodeTraits::set_right(n, p);
|
||||||
}
|
}
|
||||||
else{ // must be ( p->right == n )
|
else{ // must be ( p->right == n )
|
||||||
NodeTraits::set_right(p, NodeTraits::get_left(n));
|
NodeTraits::set_right(p, NodeTraits::get_left(n));
|
||||||
if(NodeTraits::get_right(p) != node_ptr())
|
if(NodeTraits::get_right(p))
|
||||||
NodeTraits::set_parent(NodeTraits::get_right(p), p);
|
NodeTraits::set_parent(NodeTraits::get_right(p), p);
|
||||||
NodeTraits::set_left(n, p);
|
NodeTraits::set_left(n, p);
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#define BOOST_INTRUSIVE_TREAP_HPP
|
#define BOOST_INTRUSIVE_TREAP_HPP
|
||||||
|
|
||||||
#include <boost/intrusive/detail/config_begin.hpp>
|
#include <boost/intrusive/detail/config_begin.hpp>
|
||||||
|
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
@ -21,7 +22,6 @@
|
|||||||
|
|
||||||
#include <boost/intrusive/detail/assert.hpp>
|
#include <boost/intrusive/detail/assert.hpp>
|
||||||
#include <boost/static_assert.hpp>
|
#include <boost/static_assert.hpp>
|
||||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
|
||||||
#include <boost/intrusive/bs_set_hook.hpp>
|
#include <boost/intrusive/bs_set_hook.hpp>
|
||||||
#include <boost/intrusive/bstree.hpp>
|
#include <boost/intrusive/bstree.hpp>
|
||||||
#include <boost/intrusive/detail/tree_node.hpp>
|
#include <boost/intrusive/detail/tree_node.hpp>
|
||||||
@ -72,8 +72,8 @@ template<class ValueTraits, class VoidOrKeyComp, class VoidOrPrioComp, class Siz
|
|||||||
#endif
|
#endif
|
||||||
class treap_impl
|
class treap_impl
|
||||||
/// @cond
|
/// @cond
|
||||||
: public bstree_impl<ValueTraits, VoidOrKeyComp, SizeType, ConstantTimeSize, BsTreeAlgorithms>
|
: public bstree_impl<ValueTraits, VoidOrKeyComp, SizeType, ConstantTimeSize, BsTreeAlgorithms>
|
||||||
, public detail::ebo_functor_holder
|
, public detail::ebo_functor_holder
|
||||||
< typename get_prio
|
< typename get_prio
|
||||||
< VoidOrPrioComp
|
< VoidOrPrioComp
|
||||||
, typename bstree_impl
|
, typename bstree_impl
|
||||||
@ -87,7 +87,6 @@ class treap_impl
|
|||||||
typedef bstree_impl< ValueTraits, VoidOrKeyComp, SizeType
|
typedef bstree_impl< ValueTraits, VoidOrKeyComp, SizeType
|
||||||
, ConstantTimeSize, BsTreeAlgorithms> tree_type;
|
, ConstantTimeSize, BsTreeAlgorithms> tree_type;
|
||||||
typedef tree_type implementation_defined;
|
typedef tree_type implementation_defined;
|
||||||
typedef typename tree_type::real_value_traits real_value_traits;
|
|
||||||
typedef get_prio
|
typedef get_prio
|
||||||
< VoidOrPrioComp
|
< VoidOrPrioComp
|
||||||
, typename tree_type::value_type> get_prio_type;
|
, typename tree_type::value_type> get_prio_type;
|
||||||
@ -96,7 +95,7 @@ class treap_impl
|
|||||||
<typename get_prio_type::type> prio_base;
|
<typename get_prio_type::type> prio_base;
|
||||||
|
|
||||||
/// @endcond
|
/// @endcond
|
||||||
|
|
||||||
typedef typename implementation_defined::pointer pointer;
|
typedef typename implementation_defined::pointer pointer;
|
||||||
typedef typename implementation_defined::const_pointer const_pointer;
|
typedef typename implementation_defined::const_pointer const_pointer;
|
||||||
typedef typename implementation_defined::value_type value_type;
|
typedef typename implementation_defined::value_type value_type;
|
||||||
@ -120,7 +119,7 @@ class treap_impl
|
|||||||
|
|
||||||
static const bool constant_time_size = implementation_defined::constant_time_size;
|
static const bool constant_time_size = implementation_defined::constant_time_size;
|
||||||
static const bool stateful_value_traits = implementation_defined::stateful_value_traits;
|
static const bool stateful_value_traits = implementation_defined::stateful_value_traits;
|
||||||
static const bool safemode_or_autounlink = is_safe_autounlink<real_value_traits::link_mode>::value;
|
static const bool safemode_or_autounlink = is_safe_autounlink<value_traits::link_mode>::value;
|
||||||
|
|
||||||
/// @cond
|
/// @cond
|
||||||
private:
|
private:
|
||||||
@ -217,7 +216,7 @@ class treap_impl
|
|||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: Nothing.
|
//! <b>Throws</b>: Nothing.
|
||||||
iterator top()
|
iterator top()
|
||||||
{ return this->empty() ? this->end() : iterator(node_traits::get_parent(this->tree_type::header_ptr()), this); }
|
{ return this->tree_type::root(); }
|
||||||
|
|
||||||
//! <b>Effects</b>: Returns a const_iterator pointing to the highest priority object of the treap..
|
//! <b>Effects</b>: Returns a const_iterator pointing to the highest priority object of the treap..
|
||||||
//!
|
//!
|
||||||
@ -233,7 +232,7 @@ class treap_impl
|
|||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: Nothing.
|
//! <b>Throws</b>: Nothing.
|
||||||
const_iterator ctop() const
|
const_iterator ctop() const
|
||||||
{ return this->empty() ? this->cend() : const_iterator(node_traits::get_parent(this->tree_type::header_ptr()), this); }
|
{ return this->tree_type::root(); }
|
||||||
|
|
||||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
//! @copydoc ::boost::intrusive::bstree::rbegin()
|
//! @copydoc ::boost::intrusive::bstree::rbegin()
|
||||||
@ -363,15 +362,15 @@ class treap_impl
|
|||||||
//! No copy-constructors are called.
|
//! No copy-constructors are called.
|
||||||
iterator insert_equal(reference value)
|
iterator insert_equal(reference value)
|
||||||
{
|
{
|
||||||
detail::key_nodeptr_comp<value_compare, real_value_traits>
|
detail::key_nodeptr_comp<value_compare, value_traits>
|
||||||
key_node_comp(this->value_comp(), &this->get_real_value_traits());
|
key_node_comp(this->value_comp(), &this->get_value_traits());
|
||||||
detail::key_nodeptr_comp<priority_compare, real_value_traits>
|
detail::key_nodeptr_comp<priority_compare, value_traits>
|
||||||
key_node_pcomp(this->priv_pcomp(), &this->get_real_value_traits());
|
key_node_pcomp(this->priv_pcomp(), &this->get_value_traits());
|
||||||
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
|
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
|
||||||
if(safemode_or_autounlink)
|
if(safemode_or_autounlink)
|
||||||
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
|
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
|
||||||
iterator ret(node_algorithms::insert_equal_upper_bound
|
iterator ret(node_algorithms::insert_equal_upper_bound
|
||||||
(this->tree_type::header_ptr(), to_insert, key_node_comp, key_node_pcomp), this->real_value_traits_ptr());
|
(this->tree_type::header_ptr(), to_insert, key_node_comp, key_node_pcomp), this->value_traits_ptr());
|
||||||
this->tree_type::sz_traits().increment();
|
this->tree_type::sz_traits().increment();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -392,15 +391,15 @@ class treap_impl
|
|||||||
//! No copy-constructors are called.
|
//! No copy-constructors are called.
|
||||||
iterator insert_equal(const_iterator hint, reference value)
|
iterator insert_equal(const_iterator hint, reference value)
|
||||||
{
|
{
|
||||||
detail::key_nodeptr_comp<value_compare, real_value_traits>
|
detail::key_nodeptr_comp<value_compare, value_traits>
|
||||||
key_node_comp(this->value_comp(), &this->get_real_value_traits());
|
key_node_comp(this->value_comp(), &this->get_value_traits());
|
||||||
detail::key_nodeptr_comp<priority_compare, real_value_traits>
|
detail::key_nodeptr_comp<priority_compare, value_traits>
|
||||||
key_node_pcomp(this->priv_pcomp(), &this->get_real_value_traits());
|
key_node_pcomp(this->priv_pcomp(), &this->get_value_traits());
|
||||||
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
|
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
|
||||||
if(safemode_or_autounlink)
|
if(safemode_or_autounlink)
|
||||||
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
|
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
|
||||||
iterator ret (node_algorithms::insert_equal
|
iterator ret (node_algorithms::insert_equal
|
||||||
(this->tree_type::header_ptr(), hint.pointed_node(), to_insert, key_node_comp, key_node_pcomp), this->real_value_traits_ptr());
|
(this->tree_type::header_ptr(), hint.pointed_node(), to_insert, key_node_comp, key_node_pcomp), this->value_traits_ptr());
|
||||||
this->tree_type::sz_traits().increment();
|
this->tree_type::sz_traits().increment();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -540,14 +539,14 @@ class treap_impl
|
|||||||
( const KeyType &key, KeyValueCompare key_value_comp
|
( const KeyType &key, KeyValueCompare key_value_comp
|
||||||
, KeyValuePrioCompare key_value_pcomp, insert_commit_data &commit_data)
|
, KeyValuePrioCompare key_value_pcomp, insert_commit_data &commit_data)
|
||||||
{
|
{
|
||||||
detail::key_nodeptr_comp<KeyValueCompare, real_value_traits>
|
detail::key_nodeptr_comp<KeyValueCompare, value_traits>
|
||||||
ocomp(key_value_comp, &this->get_real_value_traits());
|
ocomp(key_value_comp, &this->get_value_traits());
|
||||||
detail::key_nodeptr_comp<KeyValuePrioCompare, real_value_traits>
|
detail::key_nodeptr_comp<KeyValuePrioCompare, value_traits>
|
||||||
pcomp(key_value_pcomp, &this->get_real_value_traits());
|
pcomp(key_value_pcomp, &this->get_value_traits());
|
||||||
std::pair<node_ptr, bool> ret =
|
std::pair<node_ptr, bool> ret =
|
||||||
(node_algorithms::insert_unique_check
|
(node_algorithms::insert_unique_check
|
||||||
(this->tree_type::header_ptr(), key, ocomp, pcomp, commit_data));
|
(this->tree_type::header_ptr(), key, ocomp, pcomp, commit_data));
|
||||||
return std::pair<iterator, bool>(iterator(ret.first, this->real_value_traits_ptr()), ret.second);
|
return std::pair<iterator, bool>(iterator(ret.first, this->value_traits_ptr()), ret.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! <b>Requires</b>: key_value_comp must be a comparison function that induces
|
//! <b>Requires</b>: key_value_comp must be a comparison function that induces
|
||||||
@ -592,14 +591,14 @@ class treap_impl
|
|||||||
, KeyValuePrioCompare key_value_pcomp
|
, KeyValuePrioCompare key_value_pcomp
|
||||||
, insert_commit_data &commit_data)
|
, insert_commit_data &commit_data)
|
||||||
{
|
{
|
||||||
detail::key_nodeptr_comp<KeyValueCompare, real_value_traits>
|
detail::key_nodeptr_comp<KeyValueCompare, value_traits>
|
||||||
ocomp(key_value_comp, &this->get_real_value_traits());
|
ocomp(key_value_comp, &this->get_value_traits());
|
||||||
detail::key_nodeptr_comp<KeyValuePrioCompare, real_value_traits>
|
detail::key_nodeptr_comp<KeyValuePrioCompare, value_traits>
|
||||||
pcomp(key_value_pcomp, &this->get_real_value_traits());
|
pcomp(key_value_pcomp, &this->get_value_traits());
|
||||||
std::pair<node_ptr, bool> ret =
|
std::pair<node_ptr, bool> ret =
|
||||||
(node_algorithms::insert_unique_check
|
(node_algorithms::insert_unique_check
|
||||||
(this->tree_type::header_ptr(), hint.pointed_node(), key, ocomp, pcomp, commit_data));
|
(this->tree_type::header_ptr(), hint.pointed_node(), key, ocomp, pcomp, commit_data));
|
||||||
return std::pair<iterator, bool>(iterator(ret.first, this->real_value_traits_ptr()), ret.second);
|
return std::pair<iterator, bool>(iterator(ret.first, this->value_traits_ptr()), ret.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! <b>Requires</b>: value must be an lvalue of type value_type. commit_data
|
//! <b>Requires</b>: value must be an lvalue of type value_type. commit_data
|
||||||
@ -621,12 +620,12 @@ class treap_impl
|
|||||||
//! erased between the "insert_check" and "insert_commit" calls.
|
//! erased between the "insert_check" and "insert_commit" calls.
|
||||||
iterator insert_unique_commit(reference value, const insert_commit_data &commit_data)
|
iterator insert_unique_commit(reference value, const insert_commit_data &commit_data)
|
||||||
{
|
{
|
||||||
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
|
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
|
||||||
if(safemode_or_autounlink)
|
if(safemode_or_autounlink)
|
||||||
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
|
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
|
||||||
node_algorithms::insert_unique_commit(this->tree_type::header_ptr(), to_insert, commit_data);
|
node_algorithms::insert_unique_commit(this->tree_type::header_ptr(), to_insert, commit_data);
|
||||||
this->tree_type::sz_traits().increment();
|
this->tree_type::sz_traits().increment();
|
||||||
return iterator(to_insert, this->real_value_traits_ptr());
|
return iterator(to_insert, this->value_traits_ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
//! <b>Requires</b>: value must be an lvalue, "pos" must be
|
//! <b>Requires</b>: value must be an lvalue, "pos" must be
|
||||||
@ -645,13 +644,13 @@ class treap_impl
|
|||||||
//! by advanced users.
|
//! by advanced users.
|
||||||
iterator insert_before(const_iterator pos, reference value)
|
iterator insert_before(const_iterator pos, reference value)
|
||||||
{
|
{
|
||||||
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
|
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
|
||||||
if(safemode_or_autounlink)
|
if(safemode_or_autounlink)
|
||||||
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
|
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
|
||||||
detail::key_nodeptr_comp<priority_compare, real_value_traits>
|
detail::key_nodeptr_comp<priority_compare, value_traits>
|
||||||
pcomp(this->priv_pcomp(), &this->get_real_value_traits());
|
pcomp(this->priv_pcomp(), &this->get_value_traits());
|
||||||
iterator ret (node_algorithms::insert_before
|
iterator ret (node_algorithms::insert_before
|
||||||
(this->tree_type::header_ptr(), pos.pointed_node(), to_insert, pcomp), this->real_value_traits_ptr());
|
(this->tree_type::header_ptr(), pos.pointed_node(), to_insert, pcomp), this->value_traits_ptr());
|
||||||
this->tree_type::sz_traits().increment();
|
this->tree_type::sz_traits().increment();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -672,11 +671,11 @@ class treap_impl
|
|||||||
//! by advanced users.
|
//! by advanced users.
|
||||||
void push_back(reference value)
|
void push_back(reference value)
|
||||||
{
|
{
|
||||||
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
|
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
|
||||||
if(safemode_or_autounlink)
|
if(safemode_or_autounlink)
|
||||||
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
|
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
|
||||||
detail::key_nodeptr_comp<priority_compare, real_value_traits>
|
detail::key_nodeptr_comp<priority_compare, value_traits>
|
||||||
pcomp(this->priv_pcomp(), &this->get_real_value_traits());
|
pcomp(this->priv_pcomp(), &this->get_value_traits());
|
||||||
node_algorithms::push_back(this->tree_type::header_ptr(), to_insert, pcomp);
|
node_algorithms::push_back(this->tree_type::header_ptr(), to_insert, pcomp);
|
||||||
this->tree_type::sz_traits().increment();
|
this->tree_type::sz_traits().increment();
|
||||||
}
|
}
|
||||||
@ -697,11 +696,11 @@ class treap_impl
|
|||||||
//! by advanced users.
|
//! by advanced users.
|
||||||
void push_front(reference value)
|
void push_front(reference value)
|
||||||
{
|
{
|
||||||
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
|
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
|
||||||
if(safemode_or_autounlink)
|
if(safemode_or_autounlink)
|
||||||
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
|
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
|
||||||
detail::key_nodeptr_comp<priority_compare, real_value_traits>
|
detail::key_nodeptr_comp<priority_compare, value_traits>
|
||||||
pcomp(this->priv_pcomp(), &this->get_real_value_traits());
|
pcomp(this->priv_pcomp(), &this->get_value_traits());
|
||||||
node_algorithms::push_front(this->tree_type::header_ptr(), to_insert, pcomp);
|
node_algorithms::push_front(this->tree_type::header_ptr(), to_insert, pcomp);
|
||||||
this->tree_type::sz_traits().increment();
|
this->tree_type::sz_traits().increment();
|
||||||
}
|
}
|
||||||
@ -721,8 +720,8 @@ class treap_impl
|
|||||||
node_ptr to_erase(i.pointed_node());
|
node_ptr to_erase(i.pointed_node());
|
||||||
if(safemode_or_autounlink)
|
if(safemode_or_autounlink)
|
||||||
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!node_algorithms::unique(to_erase));
|
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!node_algorithms::unique(to_erase));
|
||||||
detail::key_nodeptr_comp<priority_compare, real_value_traits>
|
detail::key_nodeptr_comp<priority_compare, value_traits>
|
||||||
key_node_pcomp(this->priv_pcomp(), &this->get_real_value_traits());
|
key_node_pcomp(this->priv_pcomp(), &this->get_value_traits());
|
||||||
node_algorithms::erase(this->tree_type::header_ptr(), to_erase, key_node_pcomp);
|
node_algorithms::erase(this->tree_type::header_ptr(), to_erase, key_node_pcomp);
|
||||||
this->tree_type::sz_traits().decrement();
|
this->tree_type::sz_traits().decrement();
|
||||||
if(safemode_or_autounlink)
|
if(safemode_or_autounlink)
|
||||||
@ -796,7 +795,7 @@ class treap_impl
|
|||||||
{
|
{
|
||||||
node_ptr to_erase(i.pointed_node());
|
node_ptr to_erase(i.pointed_node());
|
||||||
iterator ret(this->erase(i));
|
iterator ret(this->erase(i));
|
||||||
disposer(this->get_real_value_traits().to_value_ptr(to_erase));
|
disposer(this->get_value_traits().to_value_ptr(to_erase));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -898,7 +897,7 @@ class treap_impl
|
|||||||
void clear_and_dispose(Disposer disposer)
|
void clear_and_dispose(Disposer disposer)
|
||||||
{
|
{
|
||||||
node_algorithms::clear_and_dispose(this->tree_type::header_ptr()
|
node_algorithms::clear_and_dispose(this->tree_type::header_ptr()
|
||||||
, detail::node_disposer<Disposer, real_value_traits, TreapAlgorithms>(disposer, &this->get_real_value_traits()));
|
, detail::node_disposer<Disposer, value_traits, TreapAlgorithms>(disposer, &this->get_value_traits()));
|
||||||
node_algorithms::init_header(this->tree_type::header_ptr());
|
node_algorithms::init_header(this->tree_type::header_ptr());
|
||||||
this->tree_type::sz_traits().set_size(0);
|
this->tree_type::sz_traits().set_size(0);
|
||||||
}
|
}
|
||||||
@ -910,7 +909,7 @@ class treap_impl
|
|||||||
//! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const
|
//! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const
|
||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
size_type count(const KeyType& key, KeyValueCompare comp) const;
|
size_type count(const KeyType& key, KeyValueCompare comp) const;
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)
|
//! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)
|
||||||
iterator lower_bound(const_reference value);
|
iterator lower_bound(const_reference value);
|
||||||
|
|
||||||
@ -1120,14 +1119,13 @@ class treap
|
|||||||
typedef typename Base::value_compare value_compare;
|
typedef typename Base::value_compare value_compare;
|
||||||
typedef typename Base::priority_compare priority_compare;
|
typedef typename Base::priority_compare priority_compare;
|
||||||
typedef typename Base::value_traits value_traits;
|
typedef typename Base::value_traits value_traits;
|
||||||
typedef typename Base::real_value_traits real_value_traits;
|
|
||||||
typedef typename Base::iterator iterator;
|
typedef typename Base::iterator iterator;
|
||||||
typedef typename Base::const_iterator const_iterator;
|
typedef typename Base::const_iterator const_iterator;
|
||||||
typedef typename Base::reverse_iterator reverse_iterator;
|
typedef typename Base::reverse_iterator reverse_iterator;
|
||||||
typedef typename Base::const_reverse_iterator const_reverse_iterator;
|
typedef typename Base::const_reverse_iterator const_reverse_iterator;
|
||||||
|
|
||||||
//Assert if passed value traits are compatible with the type
|
//Assert if passed value traits are compatible with the type
|
||||||
BOOST_STATIC_ASSERT((detail::is_same<typename real_value_traits::value_type, T>::value));
|
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
|
||||||
|
|
||||||
explicit treap( const value_compare &cmp = value_compare()
|
explicit treap( const value_compare &cmp = value_compare()
|
||||||
, const priority_compare &pcmp = priority_compare()
|
, const priority_compare &pcmp = priority_compare()
|
||||||
|
@ -14,9 +14,9 @@
|
|||||||
#define BOOST_INTRUSIVE_TREAP_ALGORITHMS_HPP
|
#define BOOST_INTRUSIVE_TREAP_ALGORITHMS_HPP
|
||||||
|
|
||||||
#include <boost/intrusive/detail/config_begin.hpp>
|
#include <boost/intrusive/detail/config_begin.hpp>
|
||||||
|
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
|
||||||
|
|
||||||
#include <boost/intrusive/detail/assert.hpp>
|
#include <boost/intrusive/detail/assert.hpp>
|
||||||
#include <boost/intrusive/pointer_traits.hpp>
|
#include <boost/intrusive/pointer_traits.hpp>
|
||||||
@ -110,16 +110,17 @@ class treap_algorithms
|
|||||||
|
|
||||||
static void rotate_up_n(const node_ptr header, const node_ptr p, std::size_t n)
|
static void rotate_up_n(const node_ptr header, const node_ptr p, std::size_t n)
|
||||||
{
|
{
|
||||||
for( node_ptr p_parent = NodeTraits::get_parent(p)
|
node_ptr p_parent(NodeTraits::get_parent(p));
|
||||||
; n--
|
node_ptr p_grandparent(NodeTraits::get_parent(p_parent));
|
||||||
; p_parent = NodeTraits::get_parent(p)){
|
while(n--){
|
||||||
//Check if left child
|
if(p == NodeTraits::get_left(p_parent)){ //p is left child
|
||||||
if(p == NodeTraits::get_left(p_parent)){
|
bstree_algo::rotate_right(p_parent, p, p_grandparent, header);
|
||||||
bstree_algo::rotate_right(p_parent, header);
|
|
||||||
}
|
}
|
||||||
else{ //Right child
|
else{ //p is right child
|
||||||
bstree_algo::rotate_left(p_parent, header);
|
bstree_algo::rotate_left(p_parent, p, p_grandparent, header);
|
||||||
}
|
}
|
||||||
|
p_parent = p_grandparent;
|
||||||
|
p_grandparent = NodeTraits::get_parent(p_parent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,6 +249,7 @@ class treap_algorithms
|
|||||||
//! @copydoc ::boost::intrusive::bstree_algorithms::count(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
//! @copydoc ::boost::intrusive::bstree_algorithms::count(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
||||||
template<class KeyType, class KeyNodePtrCompare>
|
template<class KeyType, class KeyNodePtrCompare>
|
||||||
static std::size_t count(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp);
|
static std::size_t count(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp);
|
||||||
|
|
||||||
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
|
|
||||||
//! <b>Requires</b>: "h" must be the header node of a tree.
|
//! <b>Requires</b>: "h" must be the header node of a tree.
|
||||||
@ -525,7 +527,7 @@ class treap_algorithms
|
|||||||
(const node_ptr & header, const node_ptr & new_node, const insert_commit_data &commit_data)
|
(const node_ptr & header, const node_ptr & new_node, const insert_commit_data &commit_data)
|
||||||
{
|
{
|
||||||
bstree_algo::insert_unique_commit(header, new_node, commit_data);
|
bstree_algo::insert_unique_commit(header, new_node, commit_data);
|
||||||
rebalance_after_insertion_commit(header, new_node, commit_data.rotations);
|
rotate_up_n(header, new_node, commit_data.rotations);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
@ -546,11 +548,12 @@ class treap_algorithms
|
|||||||
node_ptr z_left = NodeTraits::get_left(z);
|
node_ptr z_left = NodeTraits::get_left(z);
|
||||||
node_ptr z_right = NodeTraits::get_right(z);
|
node_ptr z_right = NodeTraits::get_right(z);
|
||||||
while(z_left || z_right){
|
while(z_left || z_right){
|
||||||
|
const node_ptr z_parent(NodeTraits::get_parent(z));
|
||||||
if(!z_right || (z_left && pcomp(z_left, z_right))){
|
if(!z_right || (z_left && pcomp(z_left, z_right))){
|
||||||
bstree_algo::rotate_right(z, header);
|
bstree_algo::rotate_right(z, z_left, z_parent, header);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
bstree_algo::rotate_left(z, header);
|
bstree_algo::rotate_left(z, z_right, z_parent, header);
|
||||||
}
|
}
|
||||||
++n;
|
++n;
|
||||||
z_left = NodeTraits::get_left(z);
|
z_left = NodeTraits::get_left(z);
|
||||||
@ -566,10 +569,9 @@ class treap_algorithms
|
|||||||
rebalance_after_insertion_check(h, commit_data.node, new_node, pcomp, commit_data.rotations);
|
rebalance_after_insertion_check(h, commit_data.node, new_node, pcomp, commit_data.rotations);
|
||||||
//No-throw
|
//No-throw
|
||||||
bstree_algo::insert_unique_commit(h, new_node, commit_data);
|
bstree_algo::insert_unique_commit(h, new_node, commit_data);
|
||||||
rebalance_after_insertion_commit(h, new_node, commit_data.rotations);
|
rotate_up_n(h, new_node, commit_data.rotations);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Key, class KeyNodePriorityCompare>
|
template<class Key, class KeyNodePriorityCompare>
|
||||||
static void rebalance_after_insertion_check
|
static void rebalance_after_insertion_check
|
||||||
(const const_node_ptr &header, const const_node_ptr & up, const Key &k
|
(const const_node_ptr &header, const const_node_ptr & up, const Key &k
|
||||||
@ -586,22 +588,6 @@ class treap_algorithms
|
|||||||
num_rotations = n;
|
num_rotations = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rebalance_after_insertion_commit(const node_ptr & header, const node_ptr & p, std::size_t n)
|
|
||||||
{
|
|
||||||
// Now execute n rotations
|
|
||||||
for( node_ptr p_parent = NodeTraits::get_parent(p)
|
|
||||||
; n--
|
|
||||||
; p_parent = NodeTraits::get_parent(p)){
|
|
||||||
//Check if left child
|
|
||||||
if(p == NodeTraits::get_left(p_parent)){
|
|
||||||
bstree_algo::rotate_right(p_parent, header);
|
|
||||||
}
|
|
||||||
else{ //Right child
|
|
||||||
bstree_algo::rotate_left(p_parent, header);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class NodePtrPriorityCompare>
|
template<class NodePtrPriorityCompare>
|
||||||
static bool check_invariant(const const_node_ptr & header, NodePtrPriorityCompare pcomp)
|
static bool check_invariant(const const_node_ptr & header, NodePtrPriorityCompare pcomp)
|
||||||
{
|
{
|
||||||
|
@ -44,6 +44,7 @@ class treap_set_impl
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
/// @cond
|
/// @cond
|
||||||
|
public:
|
||||||
typedef treap_impl<ValueTraits, VoidOrKeyComp, VoidOrPrioComp, SizeType, ConstantTimeSize> tree_type;
|
typedef treap_impl<ValueTraits, VoidOrKeyComp, VoidOrPrioComp, SizeType, ConstantTimeSize> tree_type;
|
||||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(treap_set_impl)
|
BOOST_MOVABLE_BUT_NOT_COPYABLE(treap_set_impl)
|
||||||
|
|
||||||
@ -291,13 +292,19 @@ class treap_set_impl
|
|||||||
template<class Disposer>
|
template<class Disposer>
|
||||||
void clear_and_dispose(Disposer disposer);
|
void clear_and_dispose(Disposer disposer);
|
||||||
|
|
||||||
|
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::treap::count(const_reference)const
|
//! @copydoc ::boost::intrusive::treap::count(const_reference)const
|
||||||
size_type count(const_reference value) const;
|
size_type count(const_reference value) const
|
||||||
|
{ return static_cast<size_type>(this->tree_type::find(value) != this->tree_type::cend()); }
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::treap::count(const KeyType&,KeyValueCompare)const
|
//! @copydoc ::boost::intrusive::treap::count(const KeyType&,KeyValueCompare)const
|
||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
size_type count(const KeyType& key, KeyValueCompare comp) const;
|
size_type count(const KeyType& key, KeyValueCompare comp) const
|
||||||
|
{ return static_cast<size_type>(this->tree_type::find(key, comp) != this->tree_type::cend()); }
|
||||||
|
|
||||||
|
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::treap::lower_bound(const_reference)
|
//! @copydoc ::boost::intrusive::treap::lower_bound(const_reference)
|
||||||
iterator lower_bound(const_reference value);
|
iterator lower_bound(const_reference value);
|
||||||
|
|
||||||
@ -340,21 +347,29 @@ class treap_set_impl
|
|||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
const_iterator find(const KeyType& key, KeyValueCompare comp) const;
|
const_iterator find(const KeyType& key, KeyValueCompare comp) const;
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::treap::equal_range(const_reference)
|
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
std::pair<iterator,iterator> equal_range(const_reference value);
|
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::treap::equal_range(const KeyType&,KeyValueCompare)
|
//! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)
|
||||||
|
std::pair<iterator,iterator> equal_range(const_reference value)
|
||||||
|
{ return this->tree_type::lower_bound_range(value); }
|
||||||
|
|
||||||
|
//! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)
|
||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
|
std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp)
|
||||||
|
{ return this->tree_type::lower_bound_range(key, comp); }
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::treap::equal_range(const_reference)const
|
//! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)const
|
||||||
std::pair<const_iterator, const_iterator>
|
std::pair<const_iterator, const_iterator>
|
||||||
equal_range(const_reference value) const;
|
equal_range(const_reference value) const
|
||||||
|
{ return this->tree_type::lower_bound_range(value); }
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::treap::equal_range(const KeyType&,KeyValueCompare)const
|
//! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)const
|
||||||
template<class KeyType, class KeyValueCompare>
|
template<class KeyType, class KeyValueCompare>
|
||||||
std::pair<const_iterator, const_iterator>
|
std::pair<const_iterator, const_iterator>
|
||||||
equal_range(const KeyType& key, KeyValueCompare comp) const;
|
equal_range(const KeyType& key, KeyValueCompare comp) const
|
||||||
|
{ return this->tree_type::lower_bound_range(key, comp); }
|
||||||
|
|
||||||
|
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::treap::bounded_range(const_reference,const_reference,bool,bool)
|
//! @copydoc ::boost::intrusive::treap::bounded_range(const_reference,const_reference,bool,bool)
|
||||||
std::pair<iterator,iterator> bounded_range
|
std::pair<iterator,iterator> bounded_range
|
||||||
|
@ -13,6 +13,9 @@
|
|||||||
#ifndef BOOST_INTRUSIVE_TRIVIAL_VALUE_TRAITS_HPP
|
#ifndef BOOST_INTRUSIVE_TRIVIAL_VALUE_TRAITS_HPP
|
||||||
#define BOOST_INTRUSIVE_TRIVIAL_VALUE_TRAITS_HPP
|
#define BOOST_INTRUSIVE_TRIVIAL_VALUE_TRAITS_HPP
|
||||||
|
|
||||||
|
#include <boost/intrusive/detail/config_begin.hpp>
|
||||||
|
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||||
|
|
||||||
#include <boost/intrusive/link_mode.hpp>
|
#include <boost/intrusive/link_mode.hpp>
|
||||||
#include <boost/intrusive/pointer_traits.hpp>
|
#include <boost/intrusive/pointer_traits.hpp>
|
||||||
|
|
||||||
@ -22,7 +25,11 @@ namespace intrusive {
|
|||||||
//!This value traits template is used to create value traits
|
//!This value traits template is used to create value traits
|
||||||
//!from user defined node traits where value_traits::value_type and
|
//!from user defined node traits where value_traits::value_type and
|
||||||
//!node_traits::node should be equal
|
//!node_traits::node should be equal
|
||||||
template<class NodeTraits, link_mode_type LinkMode = normal_link>
|
template<class NodeTraits, link_mode_type LinkMode
|
||||||
|
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
|
= safe_link
|
||||||
|
#endif
|
||||||
|
>
|
||||||
struct trivial_value_traits
|
struct trivial_value_traits
|
||||||
{
|
{
|
||||||
typedef NodeTraits node_traits;
|
typedef NodeTraits node_traits;
|
||||||
@ -43,4 +50,6 @@ struct trivial_value_traits
|
|||||||
} //namespace intrusive
|
} //namespace intrusive
|
||||||
} //namespace boost
|
} //namespace boost
|
||||||
|
|
||||||
|
#include <boost/intrusive/detail/config_end.hpp>
|
||||||
|
|
||||||
#endif //BOOST_INTRUSIVE_TRIVIAL_VALUE_TRAITS_HPP
|
#endif //BOOST_INTRUSIVE_TRIVIAL_VALUE_TRAITS_HPP
|
||||||
|
@ -1029,15 +1029,15 @@ struct make_unordered_set
|
|||||||
typedef typename detail::get_value_traits
|
typedef typename detail::get_value_traits
|
||||||
<T, typename packed_options::proto_value_traits>::type value_traits;
|
<T, typename packed_options::proto_value_traits>::type value_traits;
|
||||||
|
|
||||||
typedef typename make_real_bucket_traits
|
typedef typename make_bucket_traits
|
||||||
<T, true, packed_options>::type real_bucket_traits;
|
<T, true, packed_options>::type bucket_traits;
|
||||||
|
|
||||||
typedef unordered_set_impl
|
typedef unordered_set_impl
|
||||||
< value_traits
|
< value_traits
|
||||||
, typename packed_options::hash
|
, typename packed_options::hash
|
||||||
, typename packed_options::equal
|
, typename packed_options::equal
|
||||||
, typename packed_options::size_type
|
, typename packed_options::size_type
|
||||||
, real_bucket_traits
|
, bucket_traits
|
||||||
, (std::size_t(true)*hash_bool_flags::unique_keys_pos)
|
, (std::size_t(true)*hash_bool_flags::unique_keys_pos)
|
||||||
| (std::size_t(packed_options::constant_time_size)*hash_bool_flags::constant_time_size_pos)
|
| (std::size_t(packed_options::constant_time_size)*hash_bool_flags::constant_time_size_pos)
|
||||||
| (std::size_t(packed_options::power_2_buckets)*hash_bool_flags::power_2_buckets_pos)
|
| (std::size_t(packed_options::power_2_buckets)*hash_bool_flags::power_2_buckets_pos)
|
||||||
@ -2066,15 +2066,15 @@ struct make_unordered_multiset
|
|||||||
typedef typename detail::get_value_traits
|
typedef typename detail::get_value_traits
|
||||||
<T, typename packed_options::proto_value_traits>::type value_traits;
|
<T, typename packed_options::proto_value_traits>::type value_traits;
|
||||||
|
|
||||||
typedef typename make_real_bucket_traits
|
typedef typename make_bucket_traits
|
||||||
<T, true, packed_options>::type real_bucket_traits;
|
<T, true, packed_options>::type bucket_traits;
|
||||||
|
|
||||||
typedef unordered_multiset_impl
|
typedef unordered_multiset_impl
|
||||||
< value_traits
|
< value_traits
|
||||||
, typename packed_options::hash
|
, typename packed_options::hash
|
||||||
, typename packed_options::equal
|
, typename packed_options::equal
|
||||||
, typename packed_options::size_type
|
, typename packed_options::size_type
|
||||||
, real_bucket_traits
|
, bucket_traits
|
||||||
, (std::size_t(false)*hash_bool_flags::unique_keys_pos)
|
, (std::size_t(false)*hash_bool_flags::unique_keys_pos)
|
||||||
| (std::size_t(packed_options::constant_time_size)*hash_bool_flags::constant_time_size_pos)
|
| (std::size_t(packed_options::constant_time_size)*hash_bool_flags::constant_time_size_pos)
|
||||||
| (std::size_t(packed_options::power_2_buckets)*hash_bool_flags::power_2_buckets_pos)
|
| (std::size_t(packed_options::power_2_buckets)*hash_bool_flags::power_2_buckets_pos)
|
||||||
|
@ -207,7 +207,7 @@ struct make_unordered_set_base_hook
|
|||||||
//! unique tag.
|
//! unique tag.
|
||||||
//!
|
//!
|
||||||
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
||||||
//! and the the container configured to use this hook.
|
//! and the container configured to use this hook.
|
||||||
//!
|
//!
|
||||||
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
|
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
|
||||||
//! \c auto_unlink or \c safe_link).
|
//! \c auto_unlink or \c safe_link).
|
||||||
@ -341,7 +341,7 @@ struct make_unordered_set_member_hook
|
|||||||
//! \c link_mode<> and \c store_hash<>.
|
//! \c link_mode<> and \c store_hash<>.
|
||||||
//!
|
//!
|
||||||
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
||||||
//! and the the container configured to use this hook.
|
//! and the container configured to use this hook.
|
||||||
//!
|
//!
|
||||||
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
|
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
|
||||||
//! \c auto_unlink or \c safe_link).
|
//! \c auto_unlink or \c safe_link).
|
||||||
|
@ -31,10 +31,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "custom_bucket_traits", "cus
|
|||||||
ProjectSection(ProjectDependencies) = postProject
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "external_value_traits", "external_value_traits\external_value_traits.vcproj", "{97B69A72-B9D3-7389-17FB-74612F4A9543}"
|
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "splay_multiset", "splay_multiset\splay_multiset.vcproj", "{01E70176-B6C5-BF47-2C91-A949077BA323}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "splay_multiset", "splay_multiset\splay_multiset.vcproj", "{01E70176-B6C5-BF47-2C91-A949077BA323}"
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
@ -115,6 +111,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scary_iterators", "scary_it
|
|||||||
ProjectSection(ProjectDependencies) = postProject
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pack_options", "pack_options\pack_options.vcproj", "{77F4139B-281B-F694-7CB1-3495467B4D35}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "container_size_test", "container_size_test\container_size_test.vcproj", "{9E721E26-45AF-192C-AD67-A4CC7D096497}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfiguration) = preSolution
|
GlobalSection(SolutionConfiguration) = preSolution
|
||||||
Debug = Debug
|
Debug = Debug
|
||||||
@ -155,10 +159,6 @@ Global
|
|||||||
{31C77B84-0B2C-9481-CB81-27A149F33825}.Debug.Build.0 = Debug|Win32
|
{31C77B84-0B2C-9481-CB81-27A149F33825}.Debug.Build.0 = Debug|Win32
|
||||||
{31C77B84-0B2C-9481-CB81-27A149F33825}.Release.ActiveCfg = Release|Win32
|
{31C77B84-0B2C-9481-CB81-27A149F33825}.Release.ActiveCfg = Release|Win32
|
||||||
{31C77B84-0B2C-9481-CB81-27A149F33825}.Release.Build.0 = Release|Win32
|
{31C77B84-0B2C-9481-CB81-27A149F33825}.Release.Build.0 = Release|Win32
|
||||||
{97B69A72-B9D3-7389-17FB-74612F4A9543}.Debug.ActiveCfg = Debug|Win32
|
|
||||||
{97B69A72-B9D3-7389-17FB-74612F4A9543}.Debug.Build.0 = Debug|Win32
|
|
||||||
{97B69A72-B9D3-7389-17FB-74612F4A9543}.Release.ActiveCfg = Release|Win32
|
|
||||||
{97B69A72-B9D3-7389-17FB-74612F4A9543}.Release.Build.0 = Release|Win32
|
|
||||||
{01E70176-B6C5-BF47-2C91-A949077BA323}.Debug.ActiveCfg = Debug|Win32
|
{01E70176-B6C5-BF47-2C91-A949077BA323}.Debug.ActiveCfg = Debug|Win32
|
||||||
{01E70176-B6C5-BF47-2C91-A949077BA323}.Debug.Build.0 = Debug|Win32
|
{01E70176-B6C5-BF47-2C91-A949077BA323}.Debug.Build.0 = Debug|Win32
|
||||||
{01E70176-B6C5-BF47-2C91-A949077BA323}.Release.ActiveCfg = Release|Win32
|
{01E70176-B6C5-BF47-2C91-A949077BA323}.Release.ActiveCfg = Release|Win32
|
||||||
@ -239,6 +239,14 @@ Global
|
|||||||
{7679B41B-C1C5-FA34-9614-3547B3140346}.Debug.Build.0 = Debug|Win32
|
{7679B41B-C1C5-FA34-9614-3547B3140346}.Debug.Build.0 = Debug|Win32
|
||||||
{7679B41B-C1C5-FA34-9614-3547B3140346}.Release.ActiveCfg = Release|Win32
|
{7679B41B-C1C5-FA34-9614-3547B3140346}.Release.ActiveCfg = Release|Win32
|
||||||
{7679B41B-C1C5-FA34-9614-3547B3140346}.Release.Build.0 = Release|Win32
|
{7679B41B-C1C5-FA34-9614-3547B3140346}.Release.Build.0 = Release|Win32
|
||||||
|
{77F4139B-281B-F694-7CB1-3495467B4D35}.Debug.ActiveCfg = Debug|Win32
|
||||||
|
{77F4139B-281B-F694-7CB1-3495467B4D35}.Debug.Build.0 = Debug|Win32
|
||||||
|
{77F4139B-281B-F694-7CB1-3495467B4D35}.Release.ActiveCfg = Release|Win32
|
||||||
|
{77F4139B-281B-F694-7CB1-3495467B4D35}.Release.Build.0 = Release|Win32
|
||||||
|
{9E721E26-45AF-192C-AD67-A4CC7D096497}.Debug.ActiveCfg = Debug|Win32
|
||||||
|
{9E721E26-45AF-192C-AD67-A4CC7D096497}.Debug.Build.0 = Debug|Win32
|
||||||
|
{9E721E26-45AF-192C-AD67-A4CC7D096497}.Release.ActiveCfg = Release|Win32
|
||||||
|
{9E721E26-45AF-192C-AD67-A4CC7D096497}.Release.Build.0 = Release|Win32
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
|
@ -157,6 +157,9 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\..\..\boost\intrusive\options.hpp">
|
RelativePath="..\..\..\..\..\boost\intrusive\options.hpp">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\..\..\boost\intrusive\pack_options.hpp">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\..\..\boost\intrusive\parent_from_member.hpp">
|
RelativePath="..\..\..\..\..\boost\intrusive\parent_from_member.hpp">
|
||||||
</File>
|
</File>
|
||||||
@ -361,9 +364,6 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\example\doc_erasing_and_disposing.cpp">
|
RelativePath="..\..\..\example\doc_erasing_and_disposing.cpp">
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\..\..\example\doc_external_value_traits.cpp">
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\example\doc_function_hooks.cpp">
|
RelativePath="..\..\..\example\doc_function_hooks.cpp">
|
||||||
</File>
|
</File>
|
||||||
|
@ -1,133 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="Windows-1252"?>
|
|
||||||
<VisualStudioProject
|
|
||||||
ProjectType="Visual C++"
|
|
||||||
Version="7.10"
|
|
||||||
Name="external_value_traits"
|
|
||||||
ProjectGUID="{97B69A72-B9D3-7389-17FB-74612F4A9543}"
|
|
||||||
RootNamespace="external_value_traits"
|
|
||||||
Keyword="Win32Proj">
|
|
||||||
<Platforms>
|
|
||||||
<Platform
|
|
||||||
Name="Win32"/>
|
|
||||||
</Platforms>
|
|
||||||
<Configurations>
|
|
||||||
<Configuration
|
|
||||||
Name="Debug|Win32"
|
|
||||||
OutputDirectory="Debug"
|
|
||||||
IntermediateDirectory="Debug"
|
|
||||||
ConfigurationType="1"
|
|
||||||
CharacterSet="2">
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
Optimization="0"
|
|
||||||
AdditionalIncludeDirectories="../../../../../"
|
|
||||||
PreprocessorDefinitions="BOOST_DATE_TIME_NO_LIB"
|
|
||||||
GeneratePreprocessedFile="0"
|
|
||||||
KeepComments="FALSE"
|
|
||||||
MinimalRebuild="TRUE"
|
|
||||||
BasicRuntimeChecks="3"
|
|
||||||
RuntimeLibrary="5"
|
|
||||||
DisableLanguageExtensions="FALSE"
|
|
||||||
TreatWChar_tAsBuiltInType="TRUE"
|
|
||||||
ForceConformanceInForLoopScope="TRUE"
|
|
||||||
UsePrecompiledHeader="0"
|
|
||||||
WarningLevel="4"
|
|
||||||
Detect64BitPortabilityProblems="TRUE"
|
|
||||||
DebugInformationFormat="4"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCustomBuildTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCLinkerTool"
|
|
||||||
OutputFile="$(OutDir)/external_value_traits.exe"
|
|
||||||
LinkIncremental="2"
|
|
||||||
GenerateDebugInformation="TRUE"
|
|
||||||
ProgramDatabaseFile="$(OutDir)/external_value_traits.pdb"
|
|
||||||
GenerateMapFile="TRUE"
|
|
||||||
SubSystem="1"
|
|
||||||
TargetMachine="1"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCMIDLTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPostBuildEventTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreBuildEventTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreLinkEventTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCResourceCompilerTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCWebServiceProxyGeneratorTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXMLDataGeneratorTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCWebDeploymentTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManagedWrapperGeneratorTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
|
||||||
</Configuration>
|
|
||||||
<Configuration
|
|
||||||
Name="Release|Win32"
|
|
||||||
OutputDirectory="Release"
|
|
||||||
IntermediateDirectory="Release"
|
|
||||||
ConfigurationType="1"
|
|
||||||
CharacterSet="2">
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
AdditionalIncludeDirectories="../../../../../"
|
|
||||||
PreprocessorDefinitions="BOOST_DATE_TIME_NO_LIB"
|
|
||||||
RuntimeLibrary="4"
|
|
||||||
DisableLanguageExtensions="FALSE"
|
|
||||||
ForceConformanceInForLoopScope="TRUE"
|
|
||||||
UsePrecompiledHeader="0"
|
|
||||||
WarningLevel="3"
|
|
||||||
Detect64BitPortabilityProblems="TRUE"
|
|
||||||
DebugInformationFormat="3"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCustomBuildTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCLinkerTool"
|
|
||||||
OutputFile="$(OutDir)/external_value_traits.exe"
|
|
||||||
LinkIncremental="1"
|
|
||||||
GenerateDebugInformation="TRUE"
|
|
||||||
SubSystem="1"
|
|
||||||
OptimizeReferences="2"
|
|
||||||
EnableCOMDATFolding="2"
|
|
||||||
TargetMachine="1"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCMIDLTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPostBuildEventTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreBuildEventTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreLinkEventTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCResourceCompilerTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCWebServiceProxyGeneratorTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXMLDataGeneratorTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCWebDeploymentTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManagedWrapperGeneratorTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
|
||||||
</Configuration>
|
|
||||||
</Configurations>
|
|
||||||
<References>
|
|
||||||
</References>
|
|
||||||
<Files>
|
|
||||||
<Filter
|
|
||||||
Name="Source Files"
|
|
||||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
|
||||||
UniqueIdentifier="{7FAFEA31-6364-FB35-16A6-77AF315C236A}">
|
|
||||||
<File
|
|
||||||
RelativePath="..\..\..\test\external_value_traits_test.cpp">
|
|
||||||
</File>
|
|
||||||
</Filter>
|
|
||||||
</Files>
|
|
||||||
<Globals>
|
|
||||||
</Globals>
|
|
||||||
</VisualStudioProject>
|
|
@ -21,6 +21,7 @@
|
|||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="../../../../../"
|
AdditionalIncludeDirectories="../../../../../"
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||||
|
GeneratePreprocessedFile="0"
|
||||||
MinimalRebuild="TRUE"
|
MinimalRebuild="TRUE"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="5"
|
RuntimeLibrary="5"
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
#include<boost/intrusive/detail/utilities.hpp>
|
#include<boost/intrusive/detail/utilities.hpp>
|
||||||
#include<boost/intrusive/detail/mpl.hpp>
|
#include<boost/intrusive/detail/mpl.hpp>
|
||||||
|
#include<boost/static_assert.hpp>
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
namespace intrusive {
|
namespace intrusive {
|
||||||
@ -28,7 +29,7 @@ class delete_disposer
|
|||||||
void operator()(Pointer p)
|
void operator()(Pointer p)
|
||||||
{
|
{
|
||||||
typedef typename std::iterator_traits<Pointer>::value_type value_type;
|
typedef typename std::iterator_traits<Pointer>::value_type value_type;
|
||||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(( detail::is_same<T, value_type>::value ));
|
BOOST_STATIC_ASSERT(( detail::is_same<T, value_type>::value ));
|
||||||
delete boost::intrusive::detail::to_raw_pointer(p);
|
delete boost::intrusive::detail::to_raw_pointer(p);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,241 +0,0 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// (C) Copyright Ion Gaztanaga 2007-2013
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
|
||||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// See http://www.boost.org/libs/intrusive for documentation.
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
#include <boost/intrusive/list.hpp>
|
|
||||||
#include <boost/intrusive/slist.hpp>
|
|
||||||
#include <boost/intrusive/rbtree.hpp>
|
|
||||||
#include <boost/intrusive/hashtable.hpp>
|
|
||||||
#include <boost/intrusive/pointer_traits.hpp>
|
|
||||||
#include <functional>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
using namespace boost::intrusive;
|
|
||||||
|
|
||||||
class MyClass
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
int int_;
|
|
||||||
|
|
||||||
MyClass(int i = 0)
|
|
||||||
: int_(i)
|
|
||||||
{}
|
|
||||||
friend bool operator > (const MyClass &l, const MyClass &r)
|
|
||||||
{ return l.int_ > r.int_; }
|
|
||||||
friend bool operator == (const MyClass &l, const MyClass &r)
|
|
||||||
{ return l.int_ == r.int_; }
|
|
||||||
friend std::size_t hash_value(const MyClass &v)
|
|
||||||
{ return boost::hash_value(v.int_); }
|
|
||||||
};
|
|
||||||
|
|
||||||
const int NumElements = 100;
|
|
||||||
|
|
||||||
template<class NodeTraits>
|
|
||||||
struct external_traits
|
|
||||||
{
|
|
||||||
typedef NodeTraits node_traits;
|
|
||||||
typedef typename node_traits::node node;
|
|
||||||
typedef typename node_traits::node_ptr node_ptr;
|
|
||||||
typedef typename node_traits::const_node_ptr const_node_ptr;
|
|
||||||
typedef MyClass value_type;
|
|
||||||
typedef typename pointer_traits<node_ptr>::
|
|
||||||
template rebind_pointer<MyClass>::type pointer;
|
|
||||||
typedef typename pointer_traits<node_ptr>::
|
|
||||||
template rebind_pointer
|
|
||||||
<const MyClass>::type const_pointer;
|
|
||||||
static const link_mode_type link_mode = normal_link;
|
|
||||||
|
|
||||||
external_traits(pointer values, std::size_t NumElem)
|
|
||||||
: values_(values), node_array_(NumElem)
|
|
||||||
{}
|
|
||||||
|
|
||||||
node_ptr to_node_ptr (value_type &value)
|
|
||||||
{ return (&node_array_[0]) + (&value - values_); }
|
|
||||||
|
|
||||||
const_node_ptr to_node_ptr (const value_type &value) const
|
|
||||||
{ return &node_array_[0] + (&value - values_); }
|
|
||||||
|
|
||||||
pointer to_value_ptr(node_ptr n)
|
|
||||||
{ return values_ + (n - &node_array_[0]); }
|
|
||||||
|
|
||||||
const_pointer to_value_ptr(const_node_ptr n) const
|
|
||||||
{ return values_ + (n - &node_array_[0]); }
|
|
||||||
|
|
||||||
pointer values_;
|
|
||||||
std::vector<node> node_array_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class NodeTraits>
|
|
||||||
struct value_traits_proxy;
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct traits_holder
|
|
||||||
: public T
|
|
||||||
{};
|
|
||||||
|
|
||||||
typedef value_traits_proxy<list_node_traits<void*> > list_value_traits_proxy;
|
|
||||||
typedef value_traits_proxy<slist_node_traits<void*> > slist_value_traits_proxy;
|
|
||||||
typedef value_traits_proxy<rbtree_node_traits<void*> > rbtree_value_traits_proxy;
|
|
||||||
typedef value_traits_proxy<traits_holder<slist_node_traits<void*> > > hash_value_traits_proxy;
|
|
||||||
|
|
||||||
struct uset_bucket_traits
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
typedef unordered_bucket<value_traits<external_traits
|
|
||||||
<traits_holder<slist_node_traits<void*> > > > >::type bucket_type;
|
|
||||||
|
|
||||||
//Non-copyable
|
|
||||||
uset_bucket_traits(const uset_bucket_traits &other);
|
|
||||||
uset_bucket_traits & operator=(const uset_bucket_traits &other);
|
|
||||||
|
|
||||||
public:
|
|
||||||
static const std::size_t NumBuckets = 100;
|
|
||||||
|
|
||||||
uset_bucket_traits(){}
|
|
||||||
|
|
||||||
bucket_type * bucket_begin() const
|
|
||||||
{ return buckets_; }
|
|
||||||
|
|
||||||
std::size_t bucket_count() const
|
|
||||||
{ return NumBuckets; }
|
|
||||||
|
|
||||||
mutable bucket_type buckets_[NumBuckets];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct bucket_traits_proxy
|
|
||||||
{
|
|
||||||
static const bool external_bucket_traits = true;
|
|
||||||
typedef uset_bucket_traits bucket_traits;
|
|
||||||
|
|
||||||
template<class Container>
|
|
||||||
bucket_traits &get_bucket_traits(Container &cont);
|
|
||||||
|
|
||||||
template<class Container>
|
|
||||||
const bucket_traits &get_bucket_traits(const Container &cont) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
//Define a list that will store MyClass using the external hook
|
|
||||||
typedef list<MyClass, value_traits<list_value_traits_proxy> > List;
|
|
||||||
//Define a slist that will store MyClass using the external hook
|
|
||||||
typedef slist<MyClass, value_traits<slist_value_traits_proxy> > Slist;
|
|
||||||
//Define a rbtree that will store MyClass using the external hook
|
|
||||||
typedef rbtree< MyClass
|
|
||||||
, value_traits<rbtree_value_traits_proxy>
|
|
||||||
, compare<std::greater<MyClass> > > Rbtree;
|
|
||||||
//Define a hashtable that will store MyClass using the external hook
|
|
||||||
|
|
||||||
typedef hashtable< MyClass
|
|
||||||
, value_traits<hash_value_traits_proxy>
|
|
||||||
, bucket_traits<bucket_traits_proxy>
|
|
||||||
> Hash;
|
|
||||||
|
|
||||||
template<class NodeTraits>
|
|
||||||
struct value_traits_proxy
|
|
||||||
{
|
|
||||||
static const bool external_value_traits = true;
|
|
||||||
typedef external_traits<NodeTraits> value_traits;
|
|
||||||
|
|
||||||
template<class Container>
|
|
||||||
const value_traits &get_value_traits(const Container &cont) const;
|
|
||||||
|
|
||||||
template<class Container>
|
|
||||||
value_traits &get_value_traits(Container &cont);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ContainerHolder
|
|
||||||
: public uset_bucket_traits
|
|
||||||
, public List
|
|
||||||
, public external_traits<list_node_traits<void*> >
|
|
||||||
, public Slist
|
|
||||||
, public external_traits<slist_node_traits<void*> >
|
|
||||||
, public Rbtree
|
|
||||||
, public external_traits<rbtree_node_traits<void*> >
|
|
||||||
, public Hash
|
|
||||||
, public external_traits<traits_holder<slist_node_traits<void*> > >
|
|
||||||
{
|
|
||||||
static const std::size_t NumBucket = 100;
|
|
||||||
ContainerHolder(MyClass *values, std::size_t num_elem)
|
|
||||||
: uset_bucket_traits()
|
|
||||||
, List()
|
|
||||||
, external_traits<list_node_traits<void*> >(values, num_elem)
|
|
||||||
, Slist()
|
|
||||||
, external_traits<slist_node_traits<void*> >(values, num_elem)
|
|
||||||
, Rbtree()
|
|
||||||
, external_traits<rbtree_node_traits<void*> >(values, num_elem)
|
|
||||||
, Hash(Hash::bucket_traits())
|
|
||||||
, external_traits<traits_holder<slist_node_traits<void*> > >(values, num_elem)
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class NodeTraits>
|
|
||||||
template<class Container>
|
|
||||||
typename value_traits_proxy<NodeTraits>::value_traits &
|
|
||||||
value_traits_proxy<NodeTraits>::get_value_traits(Container &cont)
|
|
||||||
{ return static_cast<value_traits&>(static_cast<ContainerHolder&>(cont)); }
|
|
||||||
|
|
||||||
template<class NodeTraits>
|
|
||||||
template<class Container>
|
|
||||||
const typename value_traits_proxy<NodeTraits>::value_traits &
|
|
||||||
value_traits_proxy<NodeTraits>::get_value_traits(const Container &cont) const
|
|
||||||
{ return static_cast<const value_traits&>(static_cast<const ContainerHolder&>(cont)); }
|
|
||||||
|
|
||||||
template<class Container>
|
|
||||||
typename bucket_traits_proxy::bucket_traits &
|
|
||||||
bucket_traits_proxy::get_bucket_traits(Container &cont)
|
|
||||||
{ return static_cast<bucket_traits&>(static_cast<ContainerHolder&>(cont)); }
|
|
||||||
|
|
||||||
template<class Container>
|
|
||||||
const typename bucket_traits_proxy::bucket_traits &
|
|
||||||
bucket_traits_proxy::get_bucket_traits(const Container &cont) const
|
|
||||||
{ return static_cast<const bucket_traits&>(static_cast<const ContainerHolder&>(cont)); }
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
MyClass values [NumElements];
|
|
||||||
//Create several MyClass objects, each one with a different value
|
|
||||||
for(int i = 0; i < NumElements; ++i)
|
|
||||||
values[i].int_ = i;
|
|
||||||
|
|
||||||
ContainerHolder cont_holder(values, NumElements);
|
|
||||||
List &my_list = static_cast<List &> (cont_holder);
|
|
||||||
Slist &my_slist = static_cast<Slist &> (cont_holder);
|
|
||||||
Rbtree &my_rbtree = static_cast<Rbtree &> (cont_holder);
|
|
||||||
Hash &my_hash = static_cast<Hash &> (cont_holder);
|
|
||||||
|
|
||||||
//Now insert them in containers
|
|
||||||
for(MyClass * it(&values[0]), *itend(&values[NumElements])
|
|
||||||
; it != itend; ++it){
|
|
||||||
my_list.push_front(*it);
|
|
||||||
my_slist.push_front(*it);
|
|
||||||
my_rbtree.insert_unique(*it);
|
|
||||||
my_hash.insert_unique(*it);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Now test containers
|
|
||||||
{
|
|
||||||
List::const_iterator list_it (my_list.cbegin());
|
|
||||||
Slist::const_iterator slist_it (my_slist.cbegin());
|
|
||||||
Rbtree::const_iterator rbtree_it (my_rbtree.cbegin());
|
|
||||||
Hash::const_iterator hash_it (my_hash.cbegin());
|
|
||||||
MyClass *it_val(&values[NumElements] - 1), *it_rbeg_val(&values[0]-1);
|
|
||||||
|
|
||||||
//Test inserted objects
|
|
||||||
for(; it_val != it_rbeg_val; --it_val, ++list_it, ++slist_it, ++rbtree_it){
|
|
||||||
if(&*list_it != &*it_val) return 1;
|
|
||||||
if(&*slist_it != &*it_val) return 1;
|
|
||||||
if(&*rbtree_it != &*it_val) return 1;
|
|
||||||
hash_it = my_hash.find(*it_val);
|
|
||||||
if(hash_it == my_hash.cend() || &*hash_it != &*it_val)
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -68,7 +68,7 @@ class has_member_function_named_func
|
|||||||
|
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
#if !defined(BOOST_CONTAINER_PERFECT_FORWARDING)
|
#if !defined(BOOST_INTRUSIVE_PERFECT_FORWARDING)
|
||||||
|
|
||||||
namespace boost{
|
namespace boost{
|
||||||
namespace intrusive{
|
namespace intrusive{
|
||||||
@ -147,7 +147,7 @@ class has_member_function_named_func
|
|||||||
<Fun, true , void , void , void>
|
<Fun, true , void , void , void>
|
||||||
{
|
{
|
||||||
template<class U>
|
template<class U>
|
||||||
static decltype(boost::move_detail::declval<Fun>().func(), has_member_function_callable_with::yes_type()) Test(Fun* f);
|
static decltype(boost::move_detail::declval<U>().func(), has_member_function_callable_with::yes_type()) Test(U* f);
|
||||||
|
|
||||||
template<class U>
|
template<class U>
|
||||||
static has_member_function_callable_with::no_type Test(...);
|
static has_member_function_callable_with::no_type Test(...);
|
||||||
@ -259,7 +259,7 @@ class has_member_function_named_func
|
|||||||
|
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
#else
|
#else //#if !defined(BOOST_INTRUSIVE_PERFECT_FORWARDING)
|
||||||
|
|
||||||
namespace boost{
|
namespace boost{
|
||||||
namespace intrusive{
|
namespace intrusive{
|
||||||
@ -283,6 +283,7 @@ class has_member_function_named_func
|
|||||||
namespace intrusive{
|
namespace intrusive{
|
||||||
namespace intrusive_detail{
|
namespace intrusive_detail{
|
||||||
|
|
||||||
|
#ifdef BOOST_NO_CXX11_DECLTYPE
|
||||||
template<class F, std::size_t N = sizeof(boost::move_detail::declval<F>().func(), 0)>
|
template<class F, std::size_t N = sizeof(boost::move_detail::declval<F>().func(), 0)>
|
||||||
struct zeroarg_checker_func
|
struct zeroarg_checker_func
|
||||||
{
|
{
|
||||||
@ -299,12 +300,19 @@ class has_member_function_named_func
|
|||||||
zeroarg_checker_func(int);
|
zeroarg_checker_func(int);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif //BOOST_NO_CXX11_DECLTYPE
|
||||||
|
|
||||||
template<typename Fun>
|
template<typename Fun>
|
||||||
struct has_member_function_callable_with_func_impl
|
struct has_member_function_callable_with_func_impl
|
||||||
<Fun, true>
|
<Fun, true>
|
||||||
{
|
{
|
||||||
template<class U>
|
#ifndef BOOST_NO_CXX11_DECLTYPE
|
||||||
static zeroarg_checker_func<U> Test(zeroarg_checker_func<U>*);
|
template<class U, class V = decltype(boost::move_detail::declval<U>().func()) >
|
||||||
|
static boost_intrusive_has_member_function_callable_with::yes_type Test(U*);
|
||||||
|
#else
|
||||||
|
template<class U>
|
||||||
|
static zeroarg_checker_func<U> Test(zeroarg_checker_func<U>*);
|
||||||
|
#endif
|
||||||
|
|
||||||
template <class U>
|
template <class U>
|
||||||
static has_member_function_callable_with::no_type Test(...);
|
static has_member_function_callable_with::no_type Test(...);
|
||||||
@ -356,7 +364,7 @@ class has_member_function_named_func
|
|||||||
|
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
#endif
|
#endif //#if !defined(BOOST_INTRUSIVE_PERFECT_FORWARDING)
|
||||||
|
|
||||||
struct functor
|
struct functor
|
||||||
{
|
{
|
||||||
|
@ -183,12 +183,6 @@ int main()
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(detail::is_same<make_splay_set_base_hook<void_pointer<void*>, link_mode<safe_link> >::type
|
|
||||||
,make_splay_set_base_hook<>::type
|
|
||||||
>::value == false){
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Check defined types and implicitly defined types are unequal
|
//Check defined types and implicitly defined types are unequal
|
||||||
if(detail::is_same<make_list_base_hook<void_pointer<void*>, link_mode<normal_link> >::type
|
if(detail::is_same<make_list_base_hook<void_pointer<void*>, link_mode<normal_link> >::type
|
||||||
,make_list_base_hook<>::type
|
,make_list_base_hook<>::type
|
||||||
@ -220,12 +214,6 @@ int main()
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(detail::is_same<make_splay_set_base_hook<void_pointer<void*>, link_mode<normal_link> >::type
|
|
||||||
,make_splay_set_base_hook<>::type
|
|
||||||
>::value == true){
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(detail::is_same<make_bs_set_base_hook<void_pointer<void*>, link_mode<normal_link> >::type
|
if(detail::is_same<make_bs_set_base_hook<void_pointer<void*>, link_mode<normal_link> >::type
|
||||||
,make_bs_set_base_hook<>::type
|
,make_bs_set_base_hook<>::type
|
||||||
>::value == true){
|
>::value == true){
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
#include <boost/pointer_cast.hpp>
|
#include <boost/pointer_cast.hpp>
|
||||||
#include <boost/intrusive/pointer_traits.hpp>
|
#include <boost/intrusive/pointer_traits.hpp>
|
||||||
|
|
||||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
#if (defined _MSC_VER)
|
||||||
# pragma once
|
# pragma once
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -77,15 +77,15 @@ struct my_tag;
|
|||||||
template<class VoidPointer>
|
template<class VoidPointer>
|
||||||
struct hooks
|
struct hooks
|
||||||
{
|
{
|
||||||
typedef splay_set_base_hook<void_pointer<VoidPointer> > base_hook_type;
|
typedef bs_set_base_hook<void_pointer<VoidPointer> > base_hook_type;
|
||||||
typedef splay_set_base_hook
|
typedef bs_set_base_hook
|
||||||
< link_mode<auto_unlink>
|
< link_mode<auto_unlink>
|
||||||
, void_pointer<VoidPointer>
|
, void_pointer<VoidPointer>
|
||||||
, tag<my_tag> > auto_base_hook_type;
|
, tag<my_tag> > auto_base_hook_type;
|
||||||
typedef splay_set_member_hook<void_pointer<VoidPointer> > member_hook_type;
|
typedef bs_set_member_hook<void_pointer<VoidPointer> > member_hook_type;
|
||||||
typedef splay_set_member_hook
|
typedef bs_set_member_hook
|
||||||
< link_mode<auto_unlink>
|
< link_mode<auto_unlink>
|
||||||
, void_pointer<VoidPointer> > auto_member_hook_type;
|
, void_pointer<VoidPointer> > auto_member_hook_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template< class ValueType
|
template< class ValueType
|
||||||
|
@ -74,15 +74,15 @@ struct my_tag;
|
|||||||
template<class VoidPointer>
|
template<class VoidPointer>
|
||||||
struct hooks
|
struct hooks
|
||||||
{
|
{
|
||||||
typedef splay_set_base_hook<void_pointer<VoidPointer> > base_hook_type;
|
typedef bs_set_base_hook<void_pointer<VoidPointer> > base_hook_type;
|
||||||
typedef splay_set_base_hook
|
typedef bs_set_base_hook
|
||||||
< link_mode<auto_unlink>
|
< link_mode<auto_unlink>
|
||||||
, void_pointer<VoidPointer>
|
, void_pointer<VoidPointer>
|
||||||
, tag<my_tag> > auto_base_hook_type;
|
, tag<my_tag> > auto_base_hook_type;
|
||||||
typedef splay_set_member_hook<void_pointer<VoidPointer> > member_hook_type;
|
typedef bs_set_member_hook<void_pointer<VoidPointer> > member_hook_type;
|
||||||
typedef splay_set_member_hook
|
typedef bs_set_member_hook
|
||||||
< link_mode<auto_unlink>
|
< link_mode<auto_unlink>
|
||||||
, void_pointer<VoidPointer> > auto_member_hook_type;
|
, void_pointer<VoidPointer> > auto_member_hook_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template< class ValueType
|
template< class ValueType
|
||||||
|
@ -219,7 +219,7 @@ void test_common_unordered_and_associative_container(Container & c, Data & d, bo
|
|||||||
|
|
||||||
c.erase(*da, c.key_comp());
|
c.erase(*da, c.key_comp());
|
||||||
BOOST_TEST( c.size() == old_size-1 );
|
BOOST_TEST( c.size() == old_size-1 );
|
||||||
//This should not eras anyone
|
//This should not erase any
|
||||||
size_type second_erase = c.erase_and_dispose( *da, c.key_comp(), detail::null_disposer() );
|
size_type second_erase = c.erase_and_dispose( *da, c.key_comp(), detail::null_disposer() );
|
||||||
BOOST_TEST( second_erase == 0 );
|
BOOST_TEST( second_erase == 0 );
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user