forked from boostorg/intrusive
Trailing whitespaces
[SVN r78516]
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
# Boost.Intrusive library documentation Jamfile
|
||||
#
|
||||
# Copyright Ion Gaztanaga 2006.
|
||||
# Copyright Ion Gaztanaga 2006.
|
||||
# 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)
|
||||
@ -46,9 +46,9 @@ doxygen autodoc
|
||||
;
|
||||
|
||||
xml intrusive : intrusive.qbk
|
||||
:
|
||||
:
|
||||
<include>../../../tools/auto_index/include
|
||||
;
|
||||
;
|
||||
|
||||
boostbook standalone
|
||||
:
|
||||
@ -61,26 +61,26 @@ boostbook standalone
|
||||
<dependency>autodoc
|
||||
|
||||
# Build requirements go here:
|
||||
|
||||
|
||||
# <auto-index>on (or off) one turns on (or off) indexing:
|
||||
<auto-index>on
|
||||
|
||||
|
||||
# Turns on (or off) auto-index-verbose for diagnostic info.
|
||||
# This is highly recommended until you have got all the many details correct!
|
||||
<auto-index-verbose>on
|
||||
|
||||
<auto-index-verbose>on
|
||||
|
||||
# Choose the indexing method (separately for html and PDF) - see manual.
|
||||
# Choose indexing method for PDFs:
|
||||
<format>pdf:<auto-index-internal>off
|
||||
|
||||
|
||||
# Choose indexing method for html:
|
||||
<format>html:<auto-index-internal>on
|
||||
|
||||
|
||||
# Set the name of the script file to use (index.idx is popular):
|
||||
<auto-index-script>index.idx
|
||||
# Commands in the script file should all use RELATIVE PATHS
|
||||
# otherwise the script will not be portable to other machines.
|
||||
# Relative paths are normally taken as relative to the location
|
||||
# Relative paths are normally taken as relative to the location
|
||||
# of the script file, but we can add a prefix to all
|
||||
# those relative paths using the <auto-index-prefix> feature.
|
||||
# The path specified by <auto-index-prefix> may be either relative or
|
||||
|
@ -1 +1 @@
|
||||
!scan-path "boost/intrusive" ".*.hpp" false
|
||||
!scan-path "boost/intrusive" ".*.hpp" false
|
||||
|
@ -26,7 +26,7 @@
|
||||
[*Boost.Intrusive] is a library presenting some intrusive containers to
|
||||
the world of C++. Intrusive containers are special containers
|
||||
that offer [link intrusive.performance better performance]
|
||||
and exception safety guarantees than non-intrusive containers (like STL containers).
|
||||
and exception safety guarantees than non-intrusive containers (like STL containers).
|
||||
|
||||
The performance benefits of intrusive containers makes them ideal as a building
|
||||
block to efficiently construct complex containers like multi-index containers or
|
||||
@ -88,7 +88,7 @@ next and previous node and the value itself. Something similar to:
|
||||
{
|
||||
list_node *next;
|
||||
list_node *previous;
|
||||
MyClass value;
|
||||
MyClass value;
|
||||
};
|
||||
|
||||
|
||||
@ -127,11 +127,11 @@ way to make user classes compatible with those containers.
|
||||
|
||||
[section:properties_of_intrusive Properties of Boost.Intrusive containers]
|
||||
|
||||
Semantically, a [*Boost.Intrusive] container is similar to a STL container
|
||||
Semantically, a [*Boost.Intrusive] container is similar to a STL container
|
||||
holding pointers to objects. That is, if you have an intrusive list holding
|
||||
objects of type `T`, then `std::list<T*>` would allow you to do quite the
|
||||
same operations (maintaining and navigating a set of objects of type T and
|
||||
types derived from it).
|
||||
types derived from it).
|
||||
|
||||
A non-intrusive container has some limitations:
|
||||
|
||||
@ -151,7 +151,7 @@ A non-intrusive container has some limitations:
|
||||
* It's not possible to store a derived object in a STL-container while
|
||||
retaining its original type.
|
||||
|
||||
Intrusive containers have some important advantages:
|
||||
Intrusive containers have some important advantages:
|
||||
|
||||
* Operating with intrusive containers doesn't invoke any memory management at all.
|
||||
The time and size overhead associated with dynamic memory can be minimized.
|
||||
@ -160,7 +160,7 @@ Intrusive containers have some important advantages:
|
||||
equivalent container of pointers: iteration is faster.
|
||||
|
||||
* Intrusive containers offer better exception guarantees than non-intrusive containers.
|
||||
In some situations intrusive containers offer a no-throw guarantee that can't be
|
||||
In some situations intrusive containers offer a no-throw guarantee that can't be
|
||||
achieved with non-intrusive containers.
|
||||
|
||||
* The computation of an iterator to an element from a pointer or reference to that element
|
||||
@ -174,16 +174,16 @@ Intrusive containers have some important advantages:
|
||||
|
||||
Intrusive containers have also downsides:
|
||||
|
||||
* Each type stored in an intrusive container needs additional memory holding the
|
||||
* Each type stored in an intrusive container needs additional memory holding the
|
||||
maintenance information needed by the container. Hence, whenever a certain type will
|
||||
be stored in an intrusive container [*you have to change the definition of that type]
|
||||
appropriately. Although this task is easy with [*Boost.Intrusive], touching the
|
||||
appropriately. Although this task is easy with [*Boost.Intrusive], touching the
|
||||
definition of a type is sometimes a crucial issue.
|
||||
|
||||
* In intrusive containers you don't store a copy of an object, [*but rather the original object
|
||||
is linked with other objects in the container]. Objects don't need copy-constructors or assignment
|
||||
operators to be stored in intrusive containers. But you have to take care of possible side effects,
|
||||
whenever you change the contents of an object (this is especially important for
|
||||
operators to be stored in intrusive containers. But you have to take care of possible side effects,
|
||||
whenever you change the contents of an object (this is especially important for
|
||||
associative containers).
|
||||
|
||||
* The user [*has to manage the lifetime of inserted objects] independently from the
|
||||
@ -230,9 +230,9 @@ For a performance comparison between Intrusive and Non-intrusive containers see
|
||||
|
||||
[section:usage How to use Boost.Intrusive]
|
||||
|
||||
If you plan to insert a class in an intrusive container, you have to make some decisions
|
||||
influencing the class definition itself. Each class that will be used in an intrusive
|
||||
container needs some appropriate data members storing the information needed by the
|
||||
If you plan to insert a class in an intrusive container, you have to make some decisions
|
||||
influencing the class definition itself. Each class that will be used in an intrusive
|
||||
container needs some appropriate data members storing the information needed by the
|
||||
container. We will take a simple intrusive container, the intrusive list
|
||||
([classref boost::intrusive::list boost::intrusive::list]), for the following
|
||||
examples, but all [*Boost.Intrusive] containers are very similar. To compile
|
||||
@ -246,14 +246,14 @@ just include:
|
||||
Every class to be inserted in an intrusive container, needs to contain a hook that
|
||||
will offer the necessary data and resources to be insertable in the container.
|
||||
With [*Boost.Intrusive] you just choose the hook to be a public base class or
|
||||
a public member of the class to be inserted. [*Boost.Intrusive] also offers
|
||||
a public member of the class to be inserted. [*Boost.Intrusive] also offers
|
||||
more flexible hooks for advanced users, as explained in the chapter
|
||||
[link intrusive.function_hooks Using function hooks], but usually base or member
|
||||
hooks are good enough for most users.
|
||||
|
||||
[section:usage_base_hook Using base hooks]
|
||||
|
||||
For [classref boost::intrusive::list list], you can publicly derive from
|
||||
For [classref boost::intrusive::list list], you can publicly derive from
|
||||
[classref boost::intrusive::list_base_hook list_base_hook].
|
||||
|
||||
[c++]
|
||||
@ -262,7 +262,7 @@ For [classref boost::intrusive::list list], you can publicly derive from
|
||||
class list_base_hook;
|
||||
|
||||
The class can take several options. [*Boost.Intrusive] classes receive arguments in the
|
||||
form `option_name<option_value>`. You can specify the following options:
|
||||
form `option_name<option_value>`. You can specify the following options:
|
||||
|
||||
* [*`tag<class Tag>`]: this argument serves as a tag, so you can derive from more than one
|
||||
[classref boost::intrusive::list_base_hook list_base_hook] and hence put an object in
|
||||
@ -307,11 +307,11 @@ After that, we can define the intrusive list:
|
||||
`list` receives the type to be inserted in the container (`T`) as the first parameter
|
||||
and optionally, the user can specify options. We have 3 option types:
|
||||
|
||||
* [*`base_hook<class Hook>`] / [*`member_hook<class T, class Hook, Hook T::* PtrToMember>`] /
|
||||
* [*`base_hook<class Hook>`] / [*`member_hook<class T, class Hook, Hook T::* PtrToMember>`] /
|
||||
[*`value_traits<class ValueTraits>`]: All these options specify the relationship
|
||||
between the type `T` to be inserted in the list and the hook (since we can
|
||||
have several hooks in the same `T` type). `member_hook` will be explained
|
||||
a bit later and `value_traits` will be explained in the
|
||||
a bit later and `value_traits` will be explained in the
|
||||
[link intrusive.value_traits Containers with custom ValueTraits] section.
|
||||
[*If no option is specified, the container will be configured to use the base
|
||||
hook with the default tag].
|
||||
@ -354,7 +354,7 @@ Remember that the user must specify the base hook if the base hook has no defaul
|
||||
#include <boost/intrusive/list.hpp>
|
||||
|
||||
using namespace boost::intrusive;
|
||||
|
||||
|
||||
struct my_tag;
|
||||
|
||||
typedef list_base_hook< tag<my_tag> > BaseHook;
|
||||
@ -397,10 +397,10 @@ Example:
|
||||
|
||||
#include <boost/intrusive/list.hpp>
|
||||
|
||||
class Foo
|
||||
class Foo
|
||||
{
|
||||
public:
|
||||
list_member_hook<> hook_;
|
||||
list_member_hook<> hook_;
|
||||
//...
|
||||
};
|
||||
|
||||
@ -431,7 +431,7 @@ Now we can use the container:
|
||||
|
||||
[section:usage_both_hooks Using both hooks]
|
||||
|
||||
You can insert the same object in several intrusive containers at the same time,
|
||||
You can insert the same object in several intrusive containers at the same time,
|
||||
using one hook per container. This is a full example using base and member hooks:
|
||||
|
||||
[import ../example/doc_how_to_use.cpp]
|
||||
@ -442,13 +442,13 @@ using one hook per container. This is a full example using base and member hooks
|
||||
[section:usage_lifetime Object lifetime]
|
||||
|
||||
Even if the interface of [classref boost::intrusive::list list] is similar to
|
||||
`std::list`, its usage is a bit different: You always have to keep in mind that
|
||||
you directly store objects in intrusive containers, not copies. The lifetime of a
|
||||
`std::list`, its usage is a bit different: You always have to keep in mind that
|
||||
you directly store objects in intrusive containers, not copies. The lifetime of a
|
||||
stored object is not bound to or managed by the container:
|
||||
|
||||
* When the container gets destroyed before the object, the object is not destroyed,
|
||||
so you have to be careful to avoid resource leaks.
|
||||
|
||||
|
||||
* When the object is destroyed before the container, your program is likely to crash,
|
||||
because the container contains a pointer to an non-existing object.
|
||||
|
||||
@ -470,7 +470,7 @@ issue and:
|
||||
* it's important to achieve a well-known worst-time system response.
|
||||
* localization of data (e.g. for cache hit optimization) leads to measurable effects.
|
||||
|
||||
The last point is important if you have a lot of containers over a set of elements. E.g. if
|
||||
The last point is important if you have a lot of containers over a set of elements. E.g. if
|
||||
you have a vector of objects (say, `std::vector<Object>`), and you also have a list
|
||||
storing a subset of those objects (`std::list<Object*>`), then operating on an Object
|
||||
from the list iterator (`std::list<Object*>::iterator`) requires two steps:
|
||||
@ -484,16 +484,16 @@ like a data block, list nodes may be dispersed in the heap memory.
|
||||
Hence depending on your system you might get a lot of cache misses. The same doesn't hold
|
||||
for an intrusive list. Indeed, dereferencing an iterator from an intrusive list is performed in
|
||||
the same two steps as described above. But the list node is already embedded in the Object, so
|
||||
the memory is directly tracked from the iterator to the Object.
|
||||
the memory is directly tracked from the iterator to the Object.
|
||||
|
||||
It's also possible to use intrusive containers when the objects to be stored can
|
||||
have different or unknown size. This allows storing base and derived objects
|
||||
in the same container, as shown in the following example:
|
||||
in the same container, as shown in the following example:
|
||||
|
||||
[import ../example/doc_window.cpp]
|
||||
[doc_window_code]
|
||||
|
||||
Due to certain properties of intrusive containers
|
||||
Due to certain properties of intrusive containers
|
||||
they are often more difficult to use than their STL-counterparts. That's why you
|
||||
should avoid them in public interfaces of libraries. Classes to be stored in intrusive
|
||||
containers must change their implementation to store the hook and this is not always
|
||||
@ -507,7 +507,7 @@ Here is a small summary of the basic concepts that will be used in the following
|
||||
chapters:
|
||||
|
||||
[variablelist Brief Concepts Summary
|
||||
[[Node Algorithms][A class containing typedefs and static functions that define
|
||||
[[Node Algorithms][A class containing typedefs and static functions that define
|
||||
basic operations that can be applied to a group of nodes. It's independent
|
||||
from the node definition and configured using a NodeTraits template
|
||||
parameter that describes the node.]]
|
||||
@ -543,7 +543,7 @@ chapters:
|
||||
Many operations have logarithmic time complexity.
|
||||
|
||||
* [*splay_set/splay_multiset/splaytree]: `std::set/std::multiset` like intrusive associative
|
||||
containers based on splay trees. Splay trees have no constant operations, but they
|
||||
containers based on splay trees. Splay trees have no constant operations, but they
|
||||
have some interesting caching properties.
|
||||
The size overhead is moderate for user classes (usually the size of three pointers).
|
||||
Many operations have logarithmic time complexity.
|
||||
@ -595,7 +595,7 @@ Apart from that, [*Boost.Intrusive] offers additional features:
|
||||
automatically and the user can safely unlink the object from the container without
|
||||
referring to the container.
|
||||
|
||||
* [*Non-raw pointers]: If the user wants to use smart pointers instead of raw pointers,
|
||||
* [*Non-raw pointers]: If the user wants to use smart pointers instead of raw pointers,
|
||||
[*Boost.Intrusive] hooks can
|
||||
be configured to use any type of pointer. This configuration information is also
|
||||
transmitted to the containers, so all the internal pointers used by intrusive containers
|
||||
@ -636,7 +636,7 @@ is actually inserted in a container without any external reference. Let's review
|
||||
|
||||
With these features, without any external reference the user can know if the object
|
||||
has been inserted in a container by calling the `is_linked()` member function.
|
||||
If the object is not actually inserted
|
||||
If the object is not actually inserted
|
||||
in a container, the hook is in the default state, and if it is inserted in a container, the
|
||||
hook is not in the default state.
|
||||
|
||||
@ -689,11 +689,11 @@ with the name of the file to include:
|
||||
These hooks have exactly the same size overhead as their analog non auto-unlinking
|
||||
hooks, but they have a restriction: they can only be used with
|
||||
[link intrusive.presenting_containers non-constant time containers].
|
||||
There is a reason for this:
|
||||
There is a reason for this:
|
||||
|
||||
* Auto-unlink hooks don't store any reference to the container where they are inserted.
|
||||
* Only containers with non constant-time `size()` allow removing an object from the container
|
||||
without referring to the container.
|
||||
without referring to the container.
|
||||
|
||||
This auto-unlink feature is useful in certain applications
|
||||
but it must be used [*very carefully]:
|
||||
@ -734,7 +734,7 @@ that have constant-time `size()`, so if you try to define such container with an
|
||||
auto-unlink hook's value_traits, you will get a static assertion:
|
||||
|
||||
[c++]
|
||||
|
||||
|
||||
#include <boost/intrusive/list.hpp>
|
||||
|
||||
using boost::intrusive;
|
||||
@ -776,7 +776,7 @@ in constant-time size containers.
|
||||
|
||||
[classref boost::intrusive::slist slist] is the simplest intrusive container of
|
||||
[*Boost.Intrusive]: a singly linked list. The memory overhead
|
||||
it imposes is 1 pointer per node. The size of an empty, non constant-time size
|
||||
it imposes is 1 pointer per node. The size of an empty, non constant-time size
|
||||
[classref boost::intrusive::slist slist] is the size of 1 pointer. This
|
||||
lightweight memory overhead comes with drawbacks, though: many operations have
|
||||
linear time complexity, even some that usually are constant time, like
|
||||
@ -810,7 +810,7 @@ Like the rest of [*Boost.Intrusive] containers,
|
||||
class slist_member_hook;
|
||||
|
||||
* [classref boost::intrusive::slist_member_hook slist_member_hook]:
|
||||
the user class contains a public
|
||||
the user class contains a public
|
||||
[classref boost::intrusive::slist_member_hook slist_member_hook] to make
|
||||
it [classref boost::intrusive::slist slist]-compatible.
|
||||
|
||||
@ -842,7 +842,7 @@ the section [link intrusive.usage How to use Boost.Intrusive]:
|
||||
[classref boost::intrusive::slist slist] receives the 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>`] /
|
||||
* [*`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].)
|
||||
@ -911,8 +911,8 @@ Like the rest of [*Boost.Intrusive] containers,
|
||||
template <class ...Options>
|
||||
class list_member_hook;
|
||||
|
||||
* [classref boost::intrusive::list_member_hook list_member_hook]:
|
||||
the user class contains a public
|
||||
* [classref boost::intrusive::list_member_hook list_member_hook]:
|
||||
the user class contains a public
|
||||
[classref boost::intrusive::list_member_hook list_member_hook] to make
|
||||
it [classref boost::intrusive::list list]-compatible.
|
||||
|
||||
@ -944,7 +944,7 @@ the same options explained in the section
|
||||
[classref boost::intrusive::list list] receives 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>`] /
|
||||
* [*`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].)
|
||||
@ -972,7 +972,7 @@ Now let's see a small example using both hooks:
|
||||
|
||||
[*Boost.Intrusive] also offers associative containers that can be very useful
|
||||
when creating more complex associative containers, like containers maintaining
|
||||
one or more indices with different sorting semantics. Boost.Intrusive associative
|
||||
one or more indices with different sorting semantics. Boost.Intrusive associative
|
||||
containers, like most STL associative container implementations are based on
|
||||
red-black trees.
|
||||
|
||||
@ -991,7 +991,7 @@ searches, insertions, erasures, etc. [classref boost::intrusive::set set] and
|
||||
[classref boost::intrusive::multiset multiset] are the
|
||||
intrusive equivalents of standard `std::set` and `std::multiset` containers.
|
||||
|
||||
[classref boost::intrusive::rbtree rbtree] is a superset of
|
||||
[classref boost::intrusive::rbtree rbtree] is a superset of
|
||||
[classref boost::intrusive::set set] and
|
||||
[classref boost::intrusive::multiset multiset] containers that offers
|
||||
functions to insert unique and multiple keys.
|
||||
@ -1068,7 +1068,7 @@ the same options explained in the section
|
||||
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>`] /
|
||||
* [*`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].)
|
||||
@ -1113,11 +1113,11 @@ load factor: that would require memory management and intrusive containers don't
|
||||
implement any memory management at all. However, the user can request an explicit
|
||||
rehashing passing a new bucket array.
|
||||
This also offers an additional guarantee over TR1 unordered associative containers:
|
||||
[*iterators are not invalidated when inserting an element] in the container.
|
||||
[*iterators are not invalidated when inserting an element] in the container.
|
||||
|
||||
As with TR1 unordered associative containers, rehashing invalidates iterators,
|
||||
changes ordering between elements and changes which buckets elements appear in,
|
||||
but does not invalidate pointers or references to elements.
|
||||
but does not invalidate pointers or references to elements.
|
||||
|
||||
Apart from expected hash and equality function objects, [*Boost.Intrusive] unordered
|
||||
associative containers' constructors take an argument specifying an auxiliary
|
||||
@ -1129,12 +1129,12 @@ The size overhead for a hashed container is moderate: 1 pointer per value plus
|
||||
a bucket array per container. The size of an element of the bucket array
|
||||
is usually one pointer. To obtain a good performance hashed container,
|
||||
the bucket length is usually the same as the number of elements that the
|
||||
container contains, so a well-balanced hashed container (`bucket_count()` is
|
||||
container contains, so a well-balanced hashed container (`bucket_count()` is
|
||||
equal to `size()` ) will have an equivalent overhead of two pointers per element.
|
||||
|
||||
An empty, non constant-time size [classref boost::intrusive::unordered_set unordered_set] or
|
||||
[classref boost::intrusive::unordered_multiset unordered_multiset]
|
||||
has also the size of `bucket_count()` pointers.
|
||||
has also the size of `bucket_count()` pointers.
|
||||
|
||||
Insertions, erasures, and searches, have amortized constant-time complexity in
|
||||
hashed containers. However, some worst-case guarantees are linear. See
|
||||
@ -1253,7 +1253,7 @@ is undefined.
|
||||
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>`] /
|
||||
* [*`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].)
|
||||
@ -1306,7 +1306,7 @@ And they also can receive additional options:
|
||||
|
||||
* [*`incremental<bool Enabled>`]: Activates incremental hashing (also known as Linear Hashing).
|
||||
This option implies `power_2_buckets<true>` and the container will require power of two buckets.
|
||||
For more information on incremental hashing, see
|
||||
For more information on incremental hashing, see
|
||||
[@http://en.wikipedia.org/wiki/Linear_hashing `Linear hash` on Wikipedia]
|
||||
Default: `incremental<false>`
|
||||
|
||||
@ -1339,7 +1339,7 @@ option. A user-defined bucket-traits must fulfill the following interface:
|
||||
|
||||
The following bucket traits just stores a pointer to the bucket
|
||||
array but the size is a compile-time constant. Note the use of the auxiliary
|
||||
[classref boost::intrusive::unordered_bucket unordered_bucket] and
|
||||
[classref boost::intrusive::unordered_bucket unordered_bucket] and
|
||||
[classref boost::intrusive::unordered_bucket_ptr unordered_bucket_ptr]
|
||||
utilities to obtain the type of the bucket and its pointer before defining
|
||||
the unordered container:
|
||||
@ -1454,7 +1454,7 @@ the same options explained in the section
|
||||
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>`] /
|
||||
* [*`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].)
|
||||
@ -1510,12 +1510,12 @@ containers:
|
||||
|
||||
[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.
|
||||
AVL trees are often compared with red-black trees because they support the same set of operations
|
||||
and because both take O(log n) time for basic operations.
|
||||
and because both take O(log n) time for basic operations.
|
||||
AVL trees are more rigidly balanced than Red-Black trees, leading to slower insertion and
|
||||
removal but faster retrieval, so AVL trees perform better
|
||||
than red-black trees for lookup-intensive applications.
|
||||
than red-black trees for lookup-intensive applications.
|
||||
|
||||
[*Boost.Intrusive] offers 3 containers based on avl trees:
|
||||
[classref boost::intrusive::avl_set avl_set],
|
||||
@ -1603,7 +1603,7 @@ the size of the node:
|
||||
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>`] /
|
||||
* [*`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].)
|
||||
@ -1753,7 +1753,7 @@ the same options explained in the section
|
||||
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>`] /
|
||||
* [*`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].)
|
||||
@ -1767,7 +1767,7 @@ And they also can receive additional options:
|
||||
in containers. The comparison functor must induce a strict weak ordering.
|
||||
Default: `compare< std::less<T> >`
|
||||
|
||||
* [*`floating_point<bool Enable>`]:
|
||||
* [*`floating_point<bool Enable>`]:
|
||||
When this option is deactivated, the scapegoat tree loses the ability to change
|
||||
the balance factor a at run-time, but the size of an empty container is reduced
|
||||
and no floating point operations are performed, normally increasing container
|
||||
@ -1796,7 +1796,7 @@ containers:
|
||||
The name ['treap] is a mixture of ['tree] and ['heap] indicating that Treaps exhibit the properties of both
|
||||
binary search trees and heaps. A treap is a binary search tree that orders the nodes
|
||||
by a key but also by a priority attribute. The nodes are ordered so that the keys form a binary search tree and
|
||||
the priorities obey the max heap order property.
|
||||
the priorities obey the max heap order property.
|
||||
|
||||
* If v is a left descendant of u, then key[v] < key[u];
|
||||
* If v is a right descendant of u, then key[v] > key[u];
|
||||
@ -1889,7 +1889,7 @@ the same options explained in the section
|
||||
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>`] /
|
||||
* [*`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].)
|
||||
@ -1972,7 +1972,7 @@ containers:
|
||||
[section:advanced_lookups Advanced lookups]
|
||||
|
||||
[*Boost.Intrusive] associative containers offer the same interface as STL associative
|
||||
containers. However, STL and TR1 ordered and unordered simple associative containers
|
||||
containers. However, STL and TR1 ordered and unordered simple associative containers
|
||||
(`std::set`, `std::multiset`, `std::tr1::unordered_set` and `std::tr1::unordered_multiset`)
|
||||
have some inefficiencies caused by the interface: the user can only operate with `value_type`
|
||||
objects. When using these containers we must use `iterator find(const value_type &value)`
|
||||
@ -1988,7 +1988,7 @@ However, sometimes the object to be searched is quite expensive to construct:
|
||||
`Expensive` has to construct a `std::string` using heap memory. Like
|
||||
`Expensive`, many times the only member taking part in ordering issues is just
|
||||
a small part of the class. For example, with `Expensive`, only the internal
|
||||
`std::string` is needed to compare the object.
|
||||
`std::string` is needed to compare the object.
|
||||
|
||||
In both containers, if we call `get_from_set/get_from_unordered_set` in a loop, we might get a performance penalty,
|
||||
because we are forced to create a whole `Expensive` object to be able to find an
|
||||
@ -2001,8 +2001,8 @@ to search `Expensive` in the container but constructing an `Expensive`
|
||||
might require more information that the user might not have.
|
||||
|
||||
To solve this, [classref boost::intrusive::set set]/[classref boost::intrusive::multiset multiset]
|
||||
offer alternative functions, which take any type comparable with the value and a
|
||||
functor that should be compatible with the
|
||||
offer alternative functions, which take any type comparable with the value and a
|
||||
functor that should be compatible with the
|
||||
ordering function of the associative container.
|
||||
[classref boost::intrusive::unordered_set unordered_set]/[classref boost::intrusive::unordered_multiset unordered_multiset]
|
||||
offers functions that take any key type and compatible hash and equality functions. Now, let's see the
|
||||
@ -2043,7 +2043,7 @@ For example, using the same `Expensive` class,
|
||||
this function can be inefficient:
|
||||
|
||||
[doc_assoc_optimized_code_normal_insert]
|
||||
|
||||
|
||||
If the object is already present, we are constructing an `Expensive` that
|
||||
will be discarded, and this is a waste of resources. Instead of that, let's use
|
||||
`insert_check` and `insert_commit` functions:
|
||||
@ -2069,7 +2069,7 @@ and [classref boost::intrusive::unordered_set unordered_set] reference for more
|
||||
`insert_check` and `insert_commit`.
|
||||
|
||||
With multiple ordered and unordered associative containers
|
||||
([classref boost::intrusive::multiset multiset] and
|
||||
([classref boost::intrusive::multiset multiset] and
|
||||
[classref boost::intrusive::unordered_multiset unordered_multiset]) there is
|
||||
no need for these advanced insertion functions, since insertions are always successful.
|
||||
|
||||
@ -2100,7 +2100,7 @@ Let's see an example:
|
||||
[endsect]
|
||||
|
||||
For more information about advanced lookup and insertion functions see
|
||||
associative containers' documentation (e.g.
|
||||
associative containers' documentation (e.g.
|
||||
[classref boost::intrusive::set set],
|
||||
[classref boost::intrusive::multiset multiset],
|
||||
[classref boost::intrusive::unordered_set unordered_set] and
|
||||
@ -2132,10 +2132,10 @@ object that will be called after the element has been erased from the container.
|
||||
void remove_and_dispose_if(Pred pred, Disposer disposer)
|
||||
|
||||
With this function the user can efficiently remove and destroy elements if the disposer
|
||||
function destroys an object: `remove_and_dispose_if`
|
||||
function destroys an object: `remove_and_dispose_if`
|
||||
will call the "disposer" function object for every removed element. [classref boost::intrusive::list list] offers
|
||||
more functions taking a disposer function object as argument, like `erase_and_dispose`, `clear_and_dispose`,
|
||||
`remove_and_dispose`, etc.
|
||||
`remove_and_dispose`, etc.
|
||||
|
||||
Note that the disposing function does not need to just destroy the object. It can
|
||||
implement any other operation like inserting the remove object in another container.
|
||||
@ -2169,7 +2169,7 @@ Apart from the container to be cloned, `clone_from` takes two function objects a
|
||||
|
||||
template <class Cloner, class Disposer>
|
||||
void clone_from(const list &src, Cloner cloner, Disposer disposer);
|
||||
|
||||
|
||||
This function will make `*this` a clone of `src`. Let's explain the arguments:
|
||||
|
||||
* The first parameter is the list to be cloned.
|
||||
@ -2178,7 +2178,7 @@ This function will make `*this` a clone of `src`. Let's explain the arguments:
|
||||
`pointer operator()(const value_type &)`.
|
||||
* The second parameter is a function object that will dispose `value_type` objects. It's used first
|
||||
to empty the container before cloning and to dispose the elements if an exception is thrown.
|
||||
|
||||
|
||||
The cloning function works as follows:
|
||||
|
||||
* First it clears and disposes all the elements from *this using the disposer function object.
|
||||
@ -2229,7 +2229,7 @@ in practice members or base classes of class data members. The inverse operation
|
||||
is a bit more complicated, but [*Boost.Intrusive] offers a bit of help with the function
|
||||
[funcref boost::intrusive::get_parent_from_member get_parent_from_member],
|
||||
which allows easy conversions from the address of a data member to the address of
|
||||
the parent holding that member. Let's see a little example of
|
||||
the parent holding that member. Let's see a little example of
|
||||
[classref boost::intrusive::function_hook function_hook]:
|
||||
|
||||
[import ../example/doc_function_hooks.cpp]
|
||||
@ -2251,7 +2251,7 @@ instantiation:
|
||||
|
||||
[c++]
|
||||
|
||||
//This leads to compilation error (Recursive is instantiated by
|
||||
//This leads to compilation error (Recursive is instantiated by
|
||||
//'list' to deduce hook properties (pointer type, tag, safe-mode...)
|
||||
class Recursive
|
||||
{ //...
|
||||
@ -2332,7 +2332,7 @@ The conversion from the smart pointer to a raw pointer will be implemented as a
|
||||
|
||||
[*Boost.Intrusive] offers another useful feature that's not present in STL
|
||||
containers: it's possible to obtain an iterator to a value from the value itself.
|
||||
This feature is implemented in [*Boost.Intrusive] containers by a
|
||||
This feature is implemented in [*Boost.Intrusive] containers by a
|
||||
function called `iterator_to`:
|
||||
|
||||
[c++]
|
||||
@ -2352,7 +2352,7 @@ For most [*Boost.Intrusive] containers
|
||||
([classref boost::intrusive::list list],
|
||||
[classref boost::intrusive::slist slist],
|
||||
[classref boost::intrusive::set set],
|
||||
[classref boost::intrusive::multiset multiset]) we have an alternative
|
||||
[classref boost::intrusive::multiset multiset]) we have an alternative
|
||||
static `s_iterator_to` function.
|
||||
|
||||
For unordered associative containers
|
||||
@ -2367,7 +2367,7 @@ explained in the [link intrusive.value_traits.stateful_value_traits Stateful val
|
||||
if the programmer uses hooks provided by [*Boost.Intrusive], those functions
|
||||
will be available.
|
||||
|
||||
Let's see a small function that shows the use of `iterator_to` and
|
||||
Let's see a small function that shows the use of `iterator_to` and
|
||||
`local_iterator_to`:
|
||||
|
||||
[import ../example/doc_iterator_from_value.cpp]
|
||||
@ -2452,7 +2452,7 @@ before explaining the customization options of [*Boost.Intrusive].
|
||||
}
|
||||
|
||||
// number of elements in the group of nodes containing "this_node"
|
||||
static std::size_t count(const_node_ptr this_node)
|
||||
static std::size_t count(const_node_ptr this_node)
|
||||
{
|
||||
std::size_t result = 0;
|
||||
const_node_ptr p = this_node;
|
||||
@ -2469,7 +2469,7 @@ before explaining the customization options of [*Boost.Intrusive].
|
||||
|
||||
* [*Node Traits]: A class that encapsulates the basic information and
|
||||
operations on a node within a group of nodes:
|
||||
the type of the node, a function to obtain the pointer to the next node, etc.
|
||||
the type of the node, a function to obtain the pointer to the next node, etc.
|
||||
[*Node Traits] specify the configuration information [*Node Algorithms]
|
||||
need. Each type of [*Node Algorithm] expects an interface that compatible
|
||||
[*Node Traits] classes must implement.
|
||||
@ -2484,18 +2484,18 @@ before explaining the customization options of [*Boost.Intrusive].
|
||||
struct node
|
||||
{
|
||||
node *next_;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
typedef node * node_ptr;
|
||||
typedef const node * const_node_ptr;
|
||||
|
||||
//A function to obtain a pointer to the next node
|
||||
static node_ptr get_next(const_node_ptr n)
|
||||
{ return n->next_; }
|
||||
{ return n->next_; }
|
||||
|
||||
//A function to set the pointer to the next node
|
||||
static void set_next(node_ptr n, node_ptr next)
|
||||
{ n->next_ = next; }
|
||||
{ n->next_ = next; }
|
||||
};
|
||||
|
||||
|
||||
@ -2544,7 +2544,7 @@ before explaining the customization options of [*Boost.Intrusive].
|
||||
value types that use different hooks. An intrusive container is also more elaborate
|
||||
than a group of nodes: it can store the number of elements to achieve constant-time
|
||||
size information, it can offer debugging facilities, etc.
|
||||
For example, an [classref boost::intrusive::slist slist] container
|
||||
For example, an [classref boost::intrusive::slist slist] container
|
||||
(intrusive singly linked list) should
|
||||
be able to hold `MyClass` objects that might have decided to store the hook
|
||||
as a base class or as a member. Internally, the container will use [*Node Algorithms]
|
||||
@ -2565,10 +2565,10 @@ before explaining the customization options of [*Boost.Intrusive].
|
||||
// ...
|
||||
|
||||
//Insert the value as the first element of the list
|
||||
void push_front (reference value)
|
||||
void push_front (reference value)
|
||||
{
|
||||
node_ptr to_insert(ValueTraits::to_node_ptr(value));
|
||||
circular_list_algorithms::link_after(to_insert, get_root_node());
|
||||
circular_list_algorithms::link_after(to_insert, get_root_node());
|
||||
}
|
||||
|
||||
// More operations
|
||||
@ -2584,7 +2584,7 @@ before explaining the customization options of [*Boost.Intrusive].
|
||||
that will be inserted in a group of nodes. [*Node Algorithms] just work
|
||||
with nodes and don't know anything about user classes. On the other
|
||||
hand, an intrusive container needs to know how to obtain a node from a user class,
|
||||
and also the inverse operation.
|
||||
and also the inverse operation.
|
||||
So we can define [*ValueTraits] as the glue between user classes and nodes
|
||||
required by [*Node Algorithms].
|
||||
Let's see a possible implementation of a value traits class that glues MyClass
|
||||
@ -2606,7 +2606,7 @@ before explaining the customization options of [*Boost.Intrusive].
|
||||
{ return static_cast<slist_base_hook &>(value).to_node_ptr(); }
|
||||
|
||||
//Converts a generic node into user's value
|
||||
static value_type *to_value_ptr(node_traits::node *n)
|
||||
static value_type *to_value_ptr(node_traits::node *n)
|
||||
{ static_cast<value_type*>(slist_base_hook::to_hook_ptr(n)); }
|
||||
|
||||
// More operations
|
||||
@ -2643,7 +2643,7 @@ members of the [classref boost::intrusive::circular_slist_algorithms circular_sl
|
||||
|
||||
An empty list is formed by a node whose pointer to the next node points
|
||||
to itself. [classref boost::intrusive::circular_slist_algorithms circular_slist_algorithms]
|
||||
is configured with a NodeTraits class, which encapsulates
|
||||
is configured with a NodeTraits class, which encapsulates
|
||||
the information about the node to be manipulated. NodeTraits must support the
|
||||
following interface:
|
||||
|
||||
@ -2686,7 +2686,7 @@ members of the [classref boost::intrusive::circular_list_algorithms circular_lis
|
||||
|
||||
An empty list is formed by a node whose pointer to the next node points
|
||||
to itself. [classref boost::intrusive::circular_list_algorithms circular_list_algorithms]
|
||||
is configured with a NodeTraits class, which encapsulates
|
||||
is configured with a NodeTraits class, which encapsulates
|
||||
the information about the node to be manipulated. NodeTraits must support the
|
||||
following interface:
|
||||
|
||||
@ -2737,7 +2737,7 @@ members of the [classref boost::intrusive::rbtree_algorithms rbtree_algorithms]
|
||||
An empty tree is formed by a node whose pointer to the parent node is null,
|
||||
the left and right node pointers point to itself, and whose color is red.
|
||||
[classref boost::intrusive::rbtree_algorithms rbtree_algorithms]
|
||||
is configured with a NodeTraits class, which encapsulates
|
||||
is configured with a NodeTraits class, which encapsulates
|
||||
the information about the node to be manipulated. NodeTraits must support the
|
||||
following interface:
|
||||
|
||||
@ -2808,7 +2808,7 @@ members of the [classref boost::intrusive::splaytree_algorithms splaytree_algori
|
||||
An empty tree is formed by a node whose pointer to the parent node is null,
|
||||
and whose left and right nodes pointers point to itself.
|
||||
[classref boost::intrusive::splaytree_algorithms splaytree_algorithms]
|
||||
is configured with a NodeTraits class, which encapsulates
|
||||
is configured with a NodeTraits class, which encapsulates
|
||||
the information about the node to be manipulated. NodeTraits must support the
|
||||
following interface:
|
||||
|
||||
@ -2862,7 +2862,7 @@ interface as [classref boost::intrusive::rbtree_algorithms rbtree_algorithms].
|
||||
struct avltree_algorithms;
|
||||
|
||||
[classref boost::intrusive::avltree_algorithms avltree_algorithms]
|
||||
is configured with a NodeTraits class, which encapsulates
|
||||
is configured with a NodeTraits class, which encapsulates
|
||||
the information about the node to be manipulated. NodeTraits must support the
|
||||
following interface:
|
||||
|
||||
@ -2934,7 +2934,7 @@ interface as [classref boost::intrusive::rbtree_algorithms rbtree_algorithms].
|
||||
struct treap_algorithms;
|
||||
|
||||
[classref boost::intrusive::treap_algorithms treap_algorithms]
|
||||
is configured with a NodeTraits class, which encapsulates
|
||||
is configured with a NodeTraits class, which encapsulates
|
||||
the information about the node to be manipulated. NodeTraits must support the
|
||||
following interface:
|
||||
|
||||
@ -2992,7 +2992,7 @@ For a complete list of functions see
|
||||
/ struct sgtree_algorithms;
|
||||
/
|
||||
/[classref boost::intrusive::sgtree_algorithms sgtree_algorithms]
|
||||
/is configured with a NodeTraits class, which encapsulates
|
||||
/is configured with a NodeTraits class, which encapsulates
|
||||
/the information about the node to be manipulated. NodeTraits must support the
|
||||
/following interface:
|
||||
/
|
||||
@ -3111,23 +3111,23 @@ Let's explain each type and function:
|
||||
* [*['node_ptr]]: A typedef for `node_traits::node_ptr`.
|
||||
|
||||
* [*['const_node_ptr]]: A typedef for `node_traits::const_node_ptr`.
|
||||
|
||||
|
||||
* [*['value_type]]: The type that the user wants to insert in the container. This type can be
|
||||
the same as `node_traits::node` but it can be different (for example, `node_traits::node`
|
||||
can be a member type of `value_type`). If `value_type` and `node_traits::node` are the
|
||||
same type, the `to_node_ptr` and `to_value_ptr` functions are trivial.
|
||||
|
||||
|
||||
* [*['pointer]]: The type of a pointer to a `value_type`. It must be the same pointer type
|
||||
as `node_ptr`: If `node_ptr` is `node*`, `pointer` must be `value_type*`. If
|
||||
`node_ptr` is `smart_ptr<node_traits::node>`, `pointer` must be `smart_ptr<value_type>`.
|
||||
This can be generically achieved using `boost::intrusive::pointer_traits` (portable implementation of C++11
|
||||
`std::pointer_traits`) or `boost::pointer_to_other` utility from [*Boost SmartPointers]
|
||||
defined in `<boost/pointer_to_other.hpp>`.
|
||||
|
||||
|
||||
* [*['const_pointer]]: The type of a pointer to a `const value_type`. It must be the same pointer type
|
||||
as `node_ptr`: If `node_ptr` is `node*`, `const_pointer` must be `const value_type*`. If
|
||||
`node_ptr` is `smart_ptr<node_traits::node>`, `const_pointer` must be `smart_ptr<const value_type>`.
|
||||
|
||||
|
||||
* [*['link_mode]]: Indicates that `value_traits` needs some additional work or checks from the
|
||||
container. The types are enumerations defined in the `link_mode.hpp` header.
|
||||
These are the possible types:
|
||||
@ -3138,7 +3138,7 @@ Let's explain each type and function:
|
||||
of the erased values to a default state. Containers also won't
|
||||
check that the hooks of the new values are default initialized.
|
||||
|
||||
* [*`safe_link`]: If this linking policy is specified as the link mode
|
||||
* [*`safe_link`]: If this linking policy is specified as the link mode
|
||||
in a `ValueTraits` class, containers
|
||||
configured with this `ValueTraits` will set the hooks
|
||||
of the erased values to a default state. Containers also will
|
||||
@ -3165,11 +3165,11 @@ Let's explain each type and function:
|
||||
[section:value_traits_example Custom ValueTraits example]
|
||||
|
||||
Let's define our own `value_traits` class to be able to use [*Boost.Intrusive]
|
||||
containers with an old C structure whose definition can't be changed.
|
||||
containers with an old C structure whose definition can't be changed.
|
||||
That legacy type has two pointers that can be used to build singly and doubly linked
|
||||
lists: in singly linked lists we only need a pointer, whereas in doubly
|
||||
linked lists, we need two pointers. Since we only have two pointers, we can't insert
|
||||
the object in both a singly and a doubly linked list at the same time.
|
||||
the object in both a singly and a doubly linked list at the same time.
|
||||
This is the definition of the old node:
|
||||
|
||||
[import ../example/doc_value_traits.cpp]
|
||||
@ -3181,20 +3181,20 @@ we'll define a ValueTraits class that will configure [*Boost.Intrusive] containe
|
||||
|
||||
[doc_value_traits_value_traits]
|
||||
|
||||
Defining a value traits class that simply defines `value_type` as
|
||||
Defining a value traits class that simply defines `value_type` as
|
||||
`legacy_node_traits::node` is a common approach when defining customized
|
||||
intrusive containers, so [*Boost.Intrusive] offers a templatized
|
||||
[classref boost::intrusive::trivial_value_traits trivial_value_traits] class
|
||||
that does exactly what we want:
|
||||
|
||||
[c++]
|
||||
|
||||
|
||||
#include <boost/intrusive/trivial_value_traits.hpp>
|
||||
|
||||
//Now we can define legacy_value_traits just with a single line
|
||||
using namespace boost::intrusive;
|
||||
typedef trivial_value_traits<legacy_node_traits, normal_link> legacy_value_traits;
|
||||
|
||||
|
||||
|
||||
Now we can just define the containers that will store the legacy abi objects and write
|
||||
a little test:
|
||||
@ -3211,7 +3211,7 @@ if the user does not want to use the provided [*Boost.Intrusive] facilities.
|
||||
In the previous example, `legacy_node_traits::node` type and
|
||||
`legacy_value_traits::value_type` are the same type, but this is not necessary. It's possible
|
||||
to have several `ValueTraits` defining the same `node_traits` type (and thus, the same `node_traits::node`).
|
||||
This reduces the number of node algorithm instantiations, but
|
||||
This reduces the number of node algorithm instantiations, but
|
||||
now `ValueTraits::to_node_ptr` and `ValueTraits::to_value_ptr` functions need to offer
|
||||
conversions between both types. Let's see a small example:
|
||||
|
||||
@ -3256,7 +3256,7 @@ class to define a value traits class with a value that stores the
|
||||
|
||||
using namespace boost::intrusive;
|
||||
|
||||
//Now define the needed value traits using
|
||||
//Now define the needed value traits using
|
||||
typedef derivation_value_traits<value_1, simple_node_traits, normal_link> ValueTraits1;
|
||||
typedef derivation_value_traits<value_2, simple_node_traits, normal_link> ValueTraits2;
|
||||
|
||||
@ -3279,7 +3279,7 @@ Until now all shown custom value traits are stateless, that is, [*the transforma
|
||||
and values is implemented in terms of static functions]. It's possible to use [*stateful] value traits
|
||||
so that we can separate nodes and values and [*avoid modifying types to insert nodes].
|
||||
[*Boost.Intrusive] differentiates between stateful and stateless value traits by checking if all
|
||||
Node <-> Value transformation functions are static or not (except for Visual 7.1, since overloaded
|
||||
Node <-> Value transformation functions are static or not (except for Visual 7.1, since overloaded
|
||||
static function detection is not possible, in this case the implementation checks if the class is empty):
|
||||
|
||||
* If all Node <-> Value transformation functions are static , a [*stateless]
|
||||
@ -3373,7 +3373,7 @@ has a couple of downsides:
|
||||
|
||||
//Implicitly specify constant-time size and size type
|
||||
typedef list<T> List2;
|
||||
|
||||
|
||||
* Option specifiers lead to long template symbols for classes and functions. Option specifiers themselves
|
||||
are verbose and without variadic templates, several default template parameters are assigned for
|
||||
non-specified options. Object and debugging information files can grow and compilation times
|
||||
@ -3413,7 +3413,7 @@ When designing [*Boost.Intrusive] the following guidelines have been taken into
|
||||
|
||||
[*Boost.Intrusive] should be a valuable tool in performance sensitive environments,
|
||||
and following this guideline, [*Boost.Intrusive] has been designed to offer well
|
||||
known complexity guarantees. Apart from that, some options, like optional
|
||||
known complexity guarantees. Apart from that, some options, like optional
|
||||
constant-time, have been designed to offer faster complexity guarantees in some
|
||||
functions, like `slist::splice`.
|
||||
|
||||
@ -3476,7 +3476,7 @@ primarily because:
|
||||
* They minimize memory allocation/deallocation calls.
|
||||
* They obtain better memory locality.
|
||||
|
||||
This section will show performance tests comparing some operations on
|
||||
This section will show performance tests comparing some operations on
|
||||
`boost::intrusive::list` and `std::list`:
|
||||
|
||||
* Insertions using `push_back` and container destruction will show the
|
||||
@ -3522,7 +3522,7 @@ and also derives from `test_class`.
|
||||
`func_ptr_adaptor` is just a functor adaptor to convert function objects taking
|
||||
`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 code in the
|
||||
[@../../libs/intrusive/perf/perf_list.cpp perf_list.cpp] source file.
|
||||
|
||||
[section:performance_results_push_back Back insertion and destruction]
|
||||
@ -3959,11 +3959,11 @@ all the objects to be inserted in intrusive containers in containers like `std::
|
||||
|
||||
[*Olaf Krzikalla] would like to thank:
|
||||
|
||||
* [*Markus Schaaf] for pointing out the possibility and the advantages of the derivation
|
||||
approach.
|
||||
* [*Markus Schaaf] for pointing out the possibility and the advantages of the derivation
|
||||
approach.
|
||||
|
||||
* [*Udo Steinbach] for encouragements to present this work for boost, a lot of fixes and
|
||||
helpful discussions.
|
||||
helpful discussions.
|
||||
|
||||
* [*Jaap Suter] for the initial hint, which eventually lead to the member value_traits.
|
||||
|
||||
|
@ -1,14 +1,14 @@
|
||||
# Boost Intrusive Library Example Jamfile
|
||||
|
||||
# (C) Copyright Ion Gaztanaga 2006-2007.
|
||||
# Use, modification and distribution are subject to the
|
||||
# Boost Software License, Version 1.0. (See accompanying file
|
||||
# Use, modification and distribution are subject to 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)
|
||||
|
||||
# Adapted from John Maddock's TR1 Jamfile.v2
|
||||
# Copyright John Maddock 2005.
|
||||
# Use, modification and distribution are subject to the
|
||||
# Boost Software License, Version 1.0. (See accompanying file
|
||||
# Use, modification and distribution are subject to 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)
|
||||
|
||||
# this rule enumerates through all the sources and invokes
|
||||
@ -27,7 +27,7 @@ rule test_all
|
||||
: # requirements
|
||||
<toolset>acc:<linkflags>-lrt
|
||||
<toolset>acc-pa_risc:<linkflags>-lrt
|
||||
<toolset>gcc-mingw:<linkflags>"-lole32 -loleaut32"
|
||||
<toolset>gcc-mingw:<linkflags>"-lole32 -loleaut32"
|
||||
<host-os>hpux,<toolset>gcc:<linkflags>"-Wl,+as,mpas"
|
||||
] ;
|
||||
}
|
||||
@ -35,4 +35,4 @@ rule test_all
|
||||
return $(all_rules) ;
|
||||
}
|
||||
|
||||
test-suite intrusive_example : [ test_all r ] : <threading>multi ;
|
||||
test-suite intrusive_example : [ test_all r ] : <threading>multi ;
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include <boost/intrusive/list.hpp>
|
||||
#include <vector>
|
||||
|
||||
//This is the node that will be used with algorithms.
|
||||
//This is the node that will be used with algorithms.
|
||||
struct simple_node
|
||||
{
|
||||
simple_node *prev_;
|
||||
@ -26,7 +26,7 @@ struct simple_node
|
||||
class base_1{};
|
||||
class base_2{};
|
||||
|
||||
struct value_1 : public base_1, public simple_node
|
||||
struct value_1 : public base_1, public simple_node
|
||||
{ int id_; };
|
||||
|
||||
struct value_2 : public base_1, public base_2, public simple_node
|
||||
@ -38,10 +38,10 @@ struct simple_node_traits
|
||||
typedef simple_node node;
|
||||
typedef node * node_ptr;
|
||||
typedef const node * const_node_ptr;
|
||||
static node *get_next(const node *n) { return n->next_; }
|
||||
static void set_next(node *n, node *next) { n->next_ = next; }
|
||||
static node *get_previous(const node *n) { return n->prev_; }
|
||||
static void set_previous(node *n, node *prev) { n->prev_ = prev; }
|
||||
static node *get_next(const node *n) { return n->next_; }
|
||||
static void set_next(node *n, node *next) { n->next_ = next; }
|
||||
static node *get_previous(const node *n) { return n->prev_; }
|
||||
static void set_previous(node *n, node *prev) { n->prev_ = prev; }
|
||||
};
|
||||
|
||||
//A templatized value traits for value_1 and value_2
|
||||
|
@ -26,17 +26,17 @@ struct simple_node_traits
|
||||
typedef simple_node node;
|
||||
typedef node * node_ptr;
|
||||
typedef const node * const_node_ptr;
|
||||
static node *get_next(const node *n) { return n->next_; }
|
||||
static void set_next(node *n, node *next) { n->next_ = next; }
|
||||
static node *get_previous(const node *n) { return n->prev_; }
|
||||
static void set_previous(node *n, node *prev) { n->prev_ = prev; }
|
||||
static node *get_next(const node *n) { return n->next_; }
|
||||
static void set_next(node *n, node *next) { n->next_ = next; }
|
||||
static node *get_previous(const node *n) { return n->prev_; }
|
||||
static void set_previous(node *n, node *prev) { n->prev_ = prev; }
|
||||
};
|
||||
|
||||
//[doc_advanced_value_traits2_value_traits
|
||||
class base_1{};
|
||||
class base_2{};
|
||||
|
||||
struct value_1 : public base_1, public simple_node
|
||||
struct value_1 : public base_1, public simple_node
|
||||
{
|
||||
int id_;
|
||||
simple_node node_;
|
||||
|
@ -20,7 +20,7 @@ using namespace boost::intrusive;
|
||||
struct StrHasher
|
||||
{
|
||||
std::size_t operator()(const char *str) const
|
||||
{
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
for(; *str; ++str) boost::hash_combine(seed, *str);
|
||||
return seed;
|
||||
@ -31,7 +31,7 @@ class Expensive : public set_base_hook<>, public unordered_set_base_hook<>
|
||||
{
|
||||
std::string key_;
|
||||
// Other members...
|
||||
|
||||
|
||||
public:
|
||||
Expensive(const char *key)
|
||||
: key_(key)
|
||||
|
@ -55,10 +55,10 @@ int main()
|
||||
|
||||
BaseSet baseset;
|
||||
MemberMultiset membermultiset;
|
||||
|
||||
//Check that size optimization is activated in the base hook
|
||||
|
||||
//Check that size optimization is activated in the base hook
|
||||
assert(sizeof(avl_set_base_hook<optimize_size<true> >) == 3*sizeof(void*));
|
||||
//Check that size optimization is deactivated in the member hook
|
||||
//Check that size optimization is deactivated in the member hook
|
||||
assert(sizeof(avl_set_member_hook<>) > 3*sizeof(void*));
|
||||
|
||||
//Now insert them in the sets
|
||||
|
@ -32,13 +32,13 @@ struct my_avltree_node_traits
|
||||
typedef const my_node * const_node_ptr;
|
||||
typedef int balance;
|
||||
|
||||
static node_ptr get_parent(const_node_ptr n) { return n->parent_; }
|
||||
static void set_parent(node_ptr n, node_ptr parent){ n->parent_ = parent; }
|
||||
static node_ptr get_left(const_node_ptr n) { return n->left_; }
|
||||
static void set_left(node_ptr n, node_ptr left) { n->left_ = left; }
|
||||
static node_ptr get_right(const_node_ptr n) { return n->right_; }
|
||||
static void set_right(node_ptr n, node_ptr right) { n->right_ = right; }
|
||||
static balance get_balance(const_node_ptr n) { return n->balance_; }
|
||||
static node_ptr get_parent(const_node_ptr n) { return n->parent_; }
|
||||
static void set_parent(node_ptr n, node_ptr parent){ n->parent_ = parent; }
|
||||
static node_ptr get_left(const_node_ptr n) { return n->left_; }
|
||||
static void set_left(node_ptr n, node_ptr left) { n->left_ = left; }
|
||||
static node_ptr get_right(const_node_ptr n) { return n->right_; }
|
||||
static void set_right(node_ptr n, node_ptr right) { n->right_ = right; }
|
||||
static balance get_balance(const_node_ptr n) { return n->balance_; }
|
||||
static void set_balance(node_ptr n, balance b) { n->balance_ = b; }
|
||||
static balance negative() { return -1; }
|
||||
static balance zero() { return 0; }
|
||||
@ -72,7 +72,7 @@ int main()
|
||||
|
||||
//Now go to the next node
|
||||
n = algo::next_node(n);
|
||||
assert(n == &three);
|
||||
assert(n == &three);
|
||||
|
||||
//Erase a node just using a pointer to it
|
||||
algo::unlink(&two);
|
||||
|
@ -38,14 +38,14 @@ entity::~entity()
|
||||
|
||||
//Function to insert a new "some_entity" in the global list
|
||||
void insert_some_entity()
|
||||
{ global_list.push_back (*new some_entity(/*...*/)); }
|
||||
{ global_list.push_back (*new some_entity(/*...*/)); }
|
||||
|
||||
//Function to clear an entity from the intrusive global list
|
||||
void clear_list ()
|
||||
{
|
||||
// entity's destructor removes itself from the global list implicitly
|
||||
while (!global_list.empty())
|
||||
delete &global_list.front();
|
||||
delete &global_list.front();
|
||||
}
|
||||
|
||||
int main()
|
||||
|
@ -33,8 +33,8 @@ class external_traits
|
||||
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;
|
||||
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)
|
||||
@ -63,7 +63,7 @@ class external_traits
|
||||
struct internal_traits
|
||||
{
|
||||
static const bool external_value_traits = true;
|
||||
typedef external_traits value_traits;
|
||||
typedef external_traits value_traits;
|
||||
|
||||
template<class Container>
|
||||
value_traits &get_value_traits(Container &cont);
|
||||
|
@ -33,7 +33,7 @@ typedef list<MyClass> BaseList;
|
||||
|
||||
//Define a list that will store MyClass using the public member hook
|
||||
typedef list< MyClass
|
||||
, member_hook< MyClass, list_member_hook<>, &MyClass::member_hook_>
|
||||
, member_hook< MyClass, list_member_hook<>, &MyClass::member_hook_>
|
||||
> MemberList;
|
||||
|
||||
int main()
|
||||
|
@ -25,10 +25,10 @@ struct my_list_node_traits
|
||||
typedef my_node node;
|
||||
typedef my_node * node_ptr;
|
||||
typedef const my_node * const_node_ptr;
|
||||
static node_ptr get_next(const_node_ptr n) { return n->next_; }
|
||||
static void set_next(node_ptr n, node_ptr next) { n->next_ = next; }
|
||||
static node *get_previous(const_node_ptr n) { return n->prev_; }
|
||||
static void set_previous(node_ptr n, node_ptr prev){ n->prev_ = prev; }
|
||||
static node_ptr get_next(const_node_ptr n) { return n->next_; }
|
||||
static void set_next(node_ptr n, node_ptr next) { n->next_ = next; }
|
||||
static node *get_previous(const_node_ptr n) { return n->prev_; }
|
||||
static void set_previous(node_ptr n, node_ptr prev){ n->prev_ = prev; }
|
||||
};
|
||||
|
||||
int main()
|
||||
|
@ -61,7 +61,7 @@ int main()
|
||||
const int ShmSize = 50000;
|
||||
const char *ShmName = get_shared_memory_name();
|
||||
{
|
||||
//Erase all old shared memory
|
||||
//Erase all old shared memory
|
||||
ip::shared_memory_object::remove(ShmName);
|
||||
ip::managed_shared_memory shm(ip::create_only, ShmName, ShmSize);
|
||||
|
||||
@ -72,7 +72,7 @@ int main()
|
||||
shm_allocator_t;
|
||||
typedef ip::vector<shared_memory_data, shm_allocator_t> shm_vector_t;
|
||||
shm_allocator_t shm_alloc(shm.get_segment_manager());
|
||||
shm_vector_t *pshm_vect =
|
||||
shm_vector_t *pshm_vect =
|
||||
shm.construct<shm_vector_t>(ip::anonymous_instance)(shm_alloc);
|
||||
pshm_vect->resize(MaxElem);
|
||||
|
||||
|
@ -31,13 +31,13 @@ struct my_rbtree_node_traits
|
||||
typedef my_node * node_ptr;
|
||||
typedef const my_node * const_node_ptr;
|
||||
typedef int color;
|
||||
static node_ptr get_parent(const_node_ptr n) { return n->parent_; }
|
||||
static void set_parent(node_ptr n, node_ptr parent){ n->parent_ = parent; }
|
||||
static node_ptr get_left(const_node_ptr n) { return n->left_; }
|
||||
static void set_left(node_ptr n, node_ptr left) { n->left_ = left; }
|
||||
static node_ptr get_right(const_node_ptr n) { return n->right_; }
|
||||
static void set_right(node_ptr n, node_ptr right) { n->right_ = right; }
|
||||
static color get_color(const_node_ptr n) { return n->color_; }
|
||||
static node_ptr get_parent(const_node_ptr n) { return n->parent_; }
|
||||
static void set_parent(node_ptr n, node_ptr parent){ n->parent_ = parent; }
|
||||
static node_ptr get_left(const_node_ptr n) { return n->left_; }
|
||||
static void set_left(node_ptr n, node_ptr left) { n->left_ = left; }
|
||||
static node_ptr get_right(const_node_ptr n) { return n->right_; }
|
||||
static void set_right(node_ptr n, node_ptr right) { n->right_ = right; }
|
||||
static color get_color(const_node_ptr n) { return n->color_; }
|
||||
static void set_color(node_ptr n, color c) { n->color_ = c; }
|
||||
static color black() { return color(0); }
|
||||
static color red() { return color(1); }
|
||||
@ -70,7 +70,7 @@ int main()
|
||||
|
||||
//Now go to the next node
|
||||
n = algo::next_node(n);
|
||||
assert(n == &three);
|
||||
assert(n == &three);
|
||||
|
||||
//Erase a node just using a pointer to it
|
||||
algo::unlink(&two);
|
||||
|
@ -55,10 +55,10 @@ int main()
|
||||
|
||||
BaseSet baseset;
|
||||
MemberMultiset membermultiset;
|
||||
|
||||
//Check that size optimization is activated in the base hook
|
||||
|
||||
//Check that size optimization is activated in the base hook
|
||||
assert(sizeof(set_base_hook<optimize_size<true> >) == 3*sizeof(void*));
|
||||
//Check that size optimization is deactivated in the member hook
|
||||
//Check that size optimization is deactivated in the member hook
|
||||
assert(sizeof(set_member_hook<>) > 3*sizeof(void*));
|
||||
|
||||
//Now insert them in the reverse order in the base hook set
|
||||
|
@ -56,7 +56,7 @@ int main()
|
||||
|
||||
BaseSet baseset;
|
||||
MemberMultiset membermultiset;
|
||||
|
||||
|
||||
//Now insert them in the reverse order in the base hook sg_set
|
||||
for(VectIt it(values.begin()), itend(values.end()); it != itend; ++it){
|
||||
baseset.insert(*it);
|
||||
|
@ -25,8 +25,8 @@ struct my_slist_node_traits
|
||||
typedef my_node node;
|
||||
typedef my_node * node_ptr;
|
||||
typedef const my_node * const_node_ptr;
|
||||
static node_ptr get_next(const_node_ptr n) { return n->next_; }
|
||||
static void set_next(node_ptr n, node_ptr next) { n->next_ = next; }
|
||||
static node_ptr get_next(const_node_ptr n) { return n->next_; }
|
||||
static void set_next(node_ptr n, node_ptr next) { n->next_ = next; }
|
||||
};
|
||||
|
||||
int main()
|
||||
|
@ -31,12 +31,12 @@ struct my_splaytree_node_traits
|
||||
typedef my_node * node_ptr;
|
||||
typedef const my_node * const_node_ptr;
|
||||
|
||||
static node_ptr get_parent(const_node_ptr n) { return n->parent_; }
|
||||
static void set_parent(node_ptr n, node_ptr parent){ n->parent_ = parent; }
|
||||
static node_ptr get_left(const_node_ptr n) { return n->left_; }
|
||||
static void set_left(node_ptr n, node_ptr left) { n->left_ = left; }
|
||||
static node_ptr get_right(const_node_ptr n) { return n->right_; }
|
||||
static void set_right(node_ptr n, node_ptr right) { n->right_ = right; }
|
||||
static node_ptr get_parent(const_node_ptr n) { return n->parent_; }
|
||||
static void set_parent(node_ptr n, node_ptr parent){ n->parent_ = parent; }
|
||||
static node_ptr get_left(const_node_ptr n) { return n->left_; }
|
||||
static void set_left(node_ptr n, node_ptr left) { n->left_ = left; }
|
||||
static node_ptr get_right(const_node_ptr n) { return n->right_; }
|
||||
static void set_right(node_ptr n, node_ptr right) { n->right_ = right; }
|
||||
};
|
||||
|
||||
struct node_ptr_compare
|
||||
@ -66,7 +66,7 @@ int main()
|
||||
|
||||
//Now go to the next node
|
||||
n = algo::next_node(n);
|
||||
assert(n == &three);
|
||||
assert(n == &three);
|
||||
|
||||
//Erase a node just using a pointer to it
|
||||
algo::unlink(&two);
|
||||
|
@ -20,7 +20,7 @@ using namespace boost::intrusive;
|
||||
class MyClass
|
||||
: public splay_set_base_hook<> //This is an splay tree base hook
|
||||
, public bs_set_base_hook<> //This is a binary search tree base hook
|
||||
|
||||
|
||||
{
|
||||
int int_;
|
||||
|
||||
|
@ -30,12 +30,12 @@ struct my_splaytree_node_traits
|
||||
typedef my_node * node_ptr;
|
||||
typedef const my_node * const_node_ptr;
|
||||
|
||||
static node_ptr get_parent(const_node_ptr n) { return n->parent_; }
|
||||
static void set_parent(node_ptr n, node_ptr parent){ n->parent_ = parent; }
|
||||
static node_ptr get_left(const_node_ptr n) { return n->left_; }
|
||||
static void set_left(node_ptr n, node_ptr left) { n->left_ = left; }
|
||||
static node_ptr get_right(const_node_ptr n) { return n->right_; }
|
||||
static void set_right(node_ptr n, node_ptr right) { n->right_ = right; }
|
||||
static node_ptr get_parent(const_node_ptr n) { return n->parent_; }
|
||||
static void set_parent(node_ptr n, node_ptr parent){ n->parent_ = parent; }
|
||||
static node_ptr get_left(const_node_ptr n) { return n->left_; }
|
||||
static void set_left(node_ptr n, node_ptr left) { n->left_ = left; }
|
||||
static node_ptr get_right(const_node_ptr n) { return n->right_; }
|
||||
static void set_right(node_ptr n, node_ptr right) { n->right_ = right; }
|
||||
};
|
||||
|
||||
struct node_ptr_compare
|
||||
@ -65,7 +65,7 @@ int main()
|
||||
|
||||
//Now go to the next node
|
||||
n = algo::next_node(n);
|
||||
assert(n == &three);
|
||||
assert(n == &three);
|
||||
|
||||
//Erase a node just using a pointer to it
|
||||
algo::unlink(&two);
|
||||
|
@ -27,8 +27,8 @@ struct stateful_value_traits
|
||||
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;
|
||||
typedef identifier_t * pointer;
|
||||
typedef const identifier_t * const_pointer;
|
||||
static const link_mode_type link_mode = normal_link;
|
||||
|
||||
stateful_value_traits(pointer ids, node_ptr node_array)
|
||||
|
@ -31,12 +31,12 @@ struct my_treap_node_traits
|
||||
typedef my_node * node_ptr;
|
||||
typedef const my_node * const_node_ptr;
|
||||
|
||||
static node_ptr get_parent(const_node_ptr n) { return n->parent_; }
|
||||
static void set_parent(node_ptr n, node_ptr parent){ n->parent_ = parent; }
|
||||
static node_ptr get_left(const_node_ptr n) { return n->left_; }
|
||||
static void set_left(node_ptr n, node_ptr left) { n->left_ = left; }
|
||||
static node_ptr get_right(const_node_ptr n) { return n->right_; }
|
||||
static void set_right(node_ptr n, node_ptr right) { n->right_ = right; }
|
||||
static node_ptr get_parent(const_node_ptr n) { return n->parent_; }
|
||||
static void set_parent(node_ptr n, node_ptr parent){ n->parent_ = parent; }
|
||||
static node_ptr get_left(const_node_ptr n) { return n->left_; }
|
||||
static void set_left(node_ptr n, node_ptr left) { n->left_ = left; }
|
||||
static node_ptr get_right(const_node_ptr n) { return n->right_; }
|
||||
static void set_right(node_ptr n, node_ptr right) { n->right_ = right; }
|
||||
};
|
||||
|
||||
struct node_ptr_compare
|
||||
@ -66,7 +66,7 @@ int main()
|
||||
|
||||
//Now go to the next node
|
||||
n = algo::next_node(n);
|
||||
assert(n == &three);
|
||||
assert(n == &three);
|
||||
|
||||
//Erase a node just using a pointer to it
|
||||
algo::unlink(&two, node_ptr_priority());
|
||||
|
@ -70,7 +70,7 @@ int main()
|
||||
|
||||
BaseSet baseset;
|
||||
MemberMultiset membermultiset;
|
||||
|
||||
|
||||
//Now insert them in the sets
|
||||
for(VectIt it(values.begin()), itend(values.end()); it != itend; ++it){
|
||||
baseset.insert(*it);
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
//This node is the legacy type we can't modify and we want to insert in
|
||||
//intrusive list and slist containers using only two pointers, since
|
||||
//we know the object will never be at the same time in both lists.
|
||||
//we know the object will never be at the same time in both lists.
|
||||
struct legacy_value
|
||||
{
|
||||
legacy_value *prev_;
|
||||
@ -39,14 +39,14 @@ struct legacy_node_traits
|
||||
typedef legacy_value * node_ptr;
|
||||
typedef const legacy_value * const_node_ptr;
|
||||
|
||||
static node *get_next(const node *n) { return n->next_; }
|
||||
static void set_next(node *n, node *next) { n->next_ = next; }
|
||||
static node *get_previous(const node *n) { return n->prev_; }
|
||||
static void set_previous(node *n, node *prev) { n->prev_ = prev; }
|
||||
static node *get_next(const node *n) { return n->next_; }
|
||||
static void set_next(node *n, node *next) { n->next_ = next; }
|
||||
static node *get_previous(const node *n) { return n->prev_; }
|
||||
static void set_previous(node *n, node *prev) { n->prev_ = prev; }
|
||||
};
|
||||
|
||||
//This ValueTraits will configure list and slist. In this case,
|
||||
//legacy_node_traits::node is the same as the
|
||||
//legacy_node_traits::node is the same as the
|
||||
//legacy_value_traits::value_type so to_node_ptr/to_value_ptr
|
||||
//functions are trivial.
|
||||
struct legacy_value_traits
|
||||
|
@ -27,7 +27,7 @@ class Window : public list_base_hook<>
|
||||
//Constructor. Includes this window in the list
|
||||
Window() { all_windows.push_back(*this); }
|
||||
//Destructor. Removes this node from the list
|
||||
virtual ~Window() { all_windows.erase(win_list::s_iterator_to(*this)); }
|
||||
virtual ~Window() { all_windows.erase(win_list::s_iterator_to(*this)); }
|
||||
//Pure virtual function to be implemented by derived classes
|
||||
virtual void Paint() = 0;
|
||||
};
|
||||
@ -75,7 +75,7 @@ int main()
|
||||
MainWindow window;
|
||||
|
||||
//Paint all the windows, sub-windows and so on
|
||||
paint_all_windows();
|
||||
paint_all_windows();
|
||||
|
||||
//All the windows are automatically unregistered in their destructors.
|
||||
return 0;
|
||||
|
@ -1,14 +1,14 @@
|
||||
# Boost Intrusive Library Performance test Jamfile
|
||||
|
||||
# (C) Copyright Ion Gaztanaga 2006-2007.
|
||||
# Use, modification and distribution are subject to the
|
||||
# Boost Software License, Version 1.0. (See accompanying file
|
||||
# Use, modification and distribution are subject to 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)
|
||||
|
||||
# Adapted from John Maddock's TR1 Jamfile.v2
|
||||
# Copyright John Maddock 2005.
|
||||
# Use, modification and distribution are subject to the
|
||||
# Boost Software License, Version 1.0. (See accompanying file
|
||||
# Use, modification and distribution are subject to 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)
|
||||
|
||||
# this rule enumerates through all the sources and invokes
|
||||
@ -21,7 +21,7 @@ rule test_all
|
||||
|
||||
for local fileb in [ glob *.cpp ]
|
||||
{
|
||||
all_rules += [ run $(fileb)
|
||||
all_rules += [ run $(fileb)
|
||||
: # additional args
|
||||
: # test-files
|
||||
: # requirements
|
||||
@ -31,4 +31,4 @@ rule test_all
|
||||
return $(all_rules) ;
|
||||
}
|
||||
|
||||
test-suite intrusive_perf : [ test_all r ] ;
|
||||
test-suite intrusive_perf : [ test_all r ] ;
|
||||
|
@ -28,6 +28,6 @@ For more information on hashing alternatives see the original standard hashing c
|
||||
|
||||
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1456.html
|
||||
|
||||
Now, intrusive containers don't allocate memory at all, so incremental rehashing must be trigered by the user using
|
||||
Now, intrusive containers don't allocate memory at all, so incremental rehashing must be trigered by the user using
|
||||
"incremental_rehash(bool)" (use an additional bucket, that is, incremental rehash) and "incremental_rehash(bucket_traits)" (to update the new bucket array with an array that should be twice/half the size of the previous one). I admit that this is not explained at all with an example, so I will note this issue in my to do list.
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
# Boost Intrusive Library Test Jamfile
|
||||
# (C) Copyright Ion Gaztanaga 2006.
|
||||
# Use, modification and distribution are subject to the
|
||||
# Boost Software License, Version 1.0. (See accompanying file
|
||||
# Use, modification and distribution are subject to 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)
|
||||
|
||||
# Adapted from John Maddock's TR1 Jamfile.v2
|
||||
# Copyright John Maddock 2005.
|
||||
# Use, modification and distribution are subject to the
|
||||
# Boost Software License, Version 1.0. (See accompanying file
|
||||
# Use, modification and distribution are subject to 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)
|
||||
|
||||
# this rule enumerates through all the sources and invokes
|
||||
@ -26,7 +26,7 @@ rule test_all
|
||||
: # requirements
|
||||
<toolset>acc:<linkflags>-lrt
|
||||
<toolset>acc-pa_risc:<linkflags>-lrt
|
||||
<toolset>gcc-mingw:<linkflags>"-lole32 -loleaut32"
|
||||
<toolset>gcc-mingw:<linkflags>"-lole32 -loleaut32"
|
||||
<host-os>hpux,<toolset>gcc:<linkflags>"-Wl,+as,mpas"
|
||||
] ;
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ template<class T, class O1, class O2, class O3, class O4>
|
||||
#else
|
||||
template<class T, class ...Options>
|
||||
#endif
|
||||
struct has_insert_before<boost::intrusive::avl_multiset<T,
|
||||
struct has_insert_before<boost::intrusive::avl_multiset<T,
|
||||
#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
O1, O2, O3, O4
|
||||
#else
|
||||
@ -146,7 +146,7 @@ class test_main_template<VoidPointer, false>
|
||||
}
|
||||
};
|
||||
|
||||
int main( int, char* [] )
|
||||
int main( int, char* [] )
|
||||
{
|
||||
test_main_template<void*, false>()();
|
||||
test_main_template<boost::intrusive::smart_ptr<void>, false>()();
|
||||
|
@ -23,7 +23,7 @@ template<class T, class O1, class O2, class O3, class O4>
|
||||
#else
|
||||
template<class T, class ...Options>
|
||||
#endif
|
||||
struct has_insert_before<boost::intrusive::avl_set<T,
|
||||
struct has_insert_before<boost::intrusive::avl_set<T,
|
||||
#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
O1, O2, O3, O4
|
||||
#else
|
||||
@ -147,7 +147,7 @@ class test_main_template<VoidPointer, false>
|
||||
}
|
||||
};
|
||||
|
||||
int main( int, char* [] )
|
||||
int main( int, char* [] )
|
||||
{
|
||||
test_main_template<void*, false>()();
|
||||
test_main_template<boost::intrusive::smart_ptr<void>, false>()();
|
||||
|
@ -29,7 +29,7 @@ class delete_disposer
|
||||
{
|
||||
typedef typename std::iterator_traits<Pointer>::value_type value_type;
|
||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(( detail::is_same<T, value_type>::value ));
|
||||
delete boost::intrusive::detail::to_raw_pointer(p);
|
||||
delete boost::intrusive::detail::to_raw_pointer(p);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -56,16 +56,16 @@ struct external_traits
|
||||
: values_(values), node_array_(NumElem)
|
||||
{}
|
||||
|
||||
node_ptr to_node_ptr (value_type &value)
|
||||
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
|
||||
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
|
||||
const_pointer to_value_ptr(const_node_ptr n) const
|
||||
{ return values_ + (n - &node_array_[0]); }
|
||||
|
||||
pointer values_;
|
||||
|
@ -42,7 +42,7 @@ struct has_insert_before
|
||||
};
|
||||
|
||||
template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner>
|
||||
struct test_generic_assoc
|
||||
struct test_generic_assoc
|
||||
{
|
||||
typedef typename ValueTraits::value_type value_type;
|
||||
static void test_all(std::vector<value_type>& values);
|
||||
@ -134,7 +134,7 @@ void test_generic_assoc<ValueTraits, ContainerDefiner>::test_insert_erase_burst(
|
||||
typedef typename std::vector<value_type>::const_iterator cvec_iterator;
|
||||
//Random erasure
|
||||
std::vector<cvec_iterator> it_vector;
|
||||
|
||||
|
||||
for(cvec_iterator it(values.begin()), itend(values.end())
|
||||
; it != itend
|
||||
; ++it){
|
||||
@ -396,7 +396,7 @@ void test_generic_assoc<ValueTraits, ContainerDefiner>::test_insert_before
|
||||
{
|
||||
assoc_type testset;
|
||||
typedef typename std::vector<value_type>::iterator vec_iterator;
|
||||
|
||||
|
||||
for(vec_iterator it(--values.end()); true; --it){
|
||||
testset.push_front(*it);
|
||||
if(it == values.begin()){
|
||||
|
@ -42,7 +42,7 @@ void test_generic_multiset<ValueTraits, ContainerDefiner>::test_all ()
|
||||
static const int random_init[6] = { 3, 2, 4, 1, 5, 2 };
|
||||
std::vector<value_type> values (6);
|
||||
for (int i = 0; i < 6; ++i)
|
||||
values[i].value_ = random_init[i];
|
||||
values[i].value_ = random_init[i];
|
||||
|
||||
typedef typename ContainerDefiner
|
||||
< value_type
|
||||
@ -77,7 +77,7 @@ void test_generic_multiset<ValueTraits, ContainerDefiner>::test_impl()
|
||||
typedef typename ValueTraits::value_type value_type;
|
||||
std::vector<value_type> values (5);
|
||||
for (int i = 0; i < 5; ++i)
|
||||
values[i].value_ = i;
|
||||
values[i].value_ = i;
|
||||
typedef typename ValueTraits::value_type value_type;
|
||||
typedef typename ContainerDefiner
|
||||
< value_type
|
||||
@ -92,7 +92,7 @@ void test_generic_multiset<ValueTraits, ContainerDefiner>::test_impl()
|
||||
testset.erase (testset.iterator_to (values[0]));
|
||||
testset.erase (testset.iterator_to (values[1]));
|
||||
testset.insert (values[1]);
|
||||
|
||||
|
||||
testset.erase (testset.iterator_to (values[2]));
|
||||
testset.erase (testset.iterator_to (values[3]));
|
||||
}
|
||||
@ -127,8 +127,8 @@ void test_generic_multiset<ValueTraits, ContainerDefiner>::test_sort(std::vector
|
||||
|
||||
BOOST_TEST (testset2.begin()->value_ == 2);
|
||||
BOOST_TEST (testset2.rbegin()->value_ == 5);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//test: insert, const_iterator, const_reverse_iterator, erase, iterator_to:
|
||||
template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner>
|
||||
void test_generic_multiset<ValueTraits, ContainerDefiner>::test_insert(std::vector<typename ValueTraits::value_type>& values)
|
||||
@ -165,7 +165,7 @@ void test_generic_multiset<ValueTraits, ContainerDefiner>::test_insert(std::vect
|
||||
|
||||
{ int init_values [] = { 1, 3, 5 };
|
||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset.begin() ); }
|
||||
}
|
||||
}
|
||||
|
||||
//test: insert (seq-version), swap, erase (seq-version), size:
|
||||
template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner>
|
||||
@ -191,7 +191,7 @@ void test_generic_multiset<ValueTraits, ContainerDefiner>::test_swap(std::vector
|
||||
testset1.erase (testset1.iterator_to(values[5]), testset1.end());
|
||||
BOOST_TEST (testset1.size() == 1);
|
||||
BOOST_TEST (&*testset1.begin() == &values[3]);
|
||||
}
|
||||
}
|
||||
|
||||
//test: find, equal_range (lower_bound, upper_bound):
|
||||
template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner>
|
||||
@ -213,14 +213,14 @@ void test_generic_multiset<ValueTraits, ContainerDefiner>::test_find(std::vector
|
||||
BOOST_TEST (i->value_ == 2);
|
||||
BOOST_TEST ((++i)->value_ == 2);
|
||||
std::pair<iterator,iterator> range = testset.equal_range (cmp_val);
|
||||
|
||||
|
||||
BOOST_TEST (range.first->value_ == 2);
|
||||
BOOST_TEST (range.second->value_ == 3);
|
||||
BOOST_TEST (std::distance (range.first, range.second) == 2);
|
||||
|
||||
cmp_val.value_ = 7;
|
||||
BOOST_TEST (testset.find (cmp_val) == testset.end());
|
||||
}
|
||||
}
|
||||
|
||||
}}} //namespace boost::intrusive::test
|
||||
|
||||
|
@ -30,7 +30,7 @@ struct is_treap
|
||||
};
|
||||
|
||||
template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner>
|
||||
struct test_generic_set
|
||||
struct test_generic_set
|
||||
{
|
||||
typedef typename ValueTraits::value_type value_type;
|
||||
static void test_all();
|
||||
@ -52,7 +52,7 @@ void test_generic_set<ValueTraits, ContainerDefiner>::test_all()
|
||||
static const int random_init[6] = { 3, 2, 4, 1, 5, 2 };
|
||||
std::vector<value_type> values (6);
|
||||
for (int i = 0; i < 6; ++i)
|
||||
values[i].value_ = random_init[i];
|
||||
values[i].value_ = random_init[i];
|
||||
|
||||
typedef typename ContainerDefiner
|
||||
< value_type
|
||||
@ -88,7 +88,7 @@ void test_generic_set<ValueTraits, ContainerDefiner>::test_impl()
|
||||
typedef typename ValueTraits::value_type value_type;
|
||||
std::vector<value_type> values (5);
|
||||
for (int i = 0; i < 5; ++i)
|
||||
values[i].value_ = i;
|
||||
values[i].value_ = i;
|
||||
|
||||
typedef typename ValueTraits::value_type value_type;
|
||||
typedef typename ContainerDefiner
|
||||
@ -103,7 +103,7 @@ void test_generic_set<ValueTraits, ContainerDefiner>::test_impl()
|
||||
testset.erase (testset.iterator_to (values[0]));
|
||||
testset.erase (testset.iterator_to (values[1]));
|
||||
testset.insert (values[1]);
|
||||
|
||||
|
||||
testset.erase (testset.iterator_to (values[2]));
|
||||
testset.erase (testset.iterator_to (values[3]));
|
||||
}
|
||||
@ -137,8 +137,8 @@ void test_generic_set<ValueTraits, ContainerDefiner>::test_sort(std::vector<type
|
||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset2.rbegin() ); }
|
||||
BOOST_TEST (testset2.begin()->value_ == 2);
|
||||
BOOST_TEST (testset2.rbegin()->value_ == 5);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//test: insert, const_iterator, const_reverse_iterator, erase, s_iterator_to:
|
||||
template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner>
|
||||
void test_generic_set<ValueTraits, ContainerDefiner>::test_insert(std::vector<typename ValueTraits::value_type>& values)
|
||||
@ -263,7 +263,7 @@ void test_generic_set<ValueTraits, ContainerDefiner>::test_swap(std::vector<type
|
||||
BOOST_TEST (testset1.size() == 1);
|
||||
// BOOST_TEST (&testset1.front() == &values[3]);
|
||||
BOOST_TEST (&*testset1.begin() == &values[3]);
|
||||
}
|
||||
}
|
||||
|
||||
//test: find, equal_range (lower_bound, upper_bound):
|
||||
template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner>
|
||||
@ -284,14 +284,14 @@ void test_generic_set<ValueTraits, ContainerDefiner>::test_find(std::vector<type
|
||||
BOOST_TEST (i->value_ == 2);
|
||||
BOOST_TEST ((++i)->value_ != 2);
|
||||
std::pair<iterator,iterator> range = testset.equal_range (cmp_val);
|
||||
|
||||
|
||||
BOOST_TEST (range.first->value_ == 2);
|
||||
BOOST_TEST (range.second->value_ == 3);
|
||||
BOOST_TEST (std::distance (range.first, range.second) == 1);
|
||||
|
||||
cmp_val.value_ = 7;
|
||||
BOOST_TEST (testset.find (cmp_val) == testset.end());
|
||||
}
|
||||
}
|
||||
|
||||
}}} //namespace boost::intrusive::test
|
||||
|
||||
|
@ -31,14 +31,14 @@ struct private_type
|
||||
private_type const &operator,(int) const;
|
||||
};
|
||||
|
||||
typedef char yes_type;
|
||||
typedef char yes_type;
|
||||
struct no_type{ char dummy[2]; };
|
||||
|
||||
template<typename T>
|
||||
no_type is_private_type(T const &);
|
||||
yes_type is_private_type(private_type const &);
|
||||
|
||||
}}}}
|
||||
}}}}
|
||||
|
||||
|
||||
namespace boost{
|
||||
@ -121,9 +121,9 @@ class has_member_function_named_func
|
||||
template<class U>
|
||||
static zeroarg_checker_func<U> Test(zeroarg_checker_func<U>*);
|
||||
|
||||
template <class U>
|
||||
template <class U>
|
||||
static has_member_function_callable_with::no_type Test(...);
|
||||
|
||||
|
||||
static const bool value
|
||||
= sizeof(Test< Fun >(0)) == sizeof(has_member_function_callable_with::yes_type);
|
||||
};
|
||||
@ -186,7 +186,7 @@ class has_member_function_named_func
|
||||
);
|
||||
};
|
||||
|
||||
}}}
|
||||
}}}
|
||||
|
||||
namespace boost{
|
||||
namespace intrusive{
|
||||
@ -216,7 +216,7 @@ class has_member_function_named_func
|
||||
)
|
||||
);
|
||||
};
|
||||
}}}
|
||||
}}}
|
||||
|
||||
namespace boost{
|
||||
namespace intrusive{
|
||||
@ -306,9 +306,9 @@ class has_member_function_named_func
|
||||
template<class U>
|
||||
static zeroarg_checker_func<U> Test(zeroarg_checker_func<U>*);
|
||||
|
||||
template <class U>
|
||||
template <class U>
|
||||
static has_member_function_callable_with::no_type Test(...);
|
||||
|
||||
|
||||
static const bool value = sizeof(Test< Fun >(0))
|
||||
== sizeof(has_member_function_callable_with::yes_type);
|
||||
};
|
||||
@ -460,7 +460,7 @@ int main()
|
||||
(void)check5;
|
||||
(void)check6;
|
||||
(void)check7;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -141,7 +141,7 @@ struct even_odd
|
||||
return v1.value_ < v2.value_;
|
||||
else
|
||||
return v2.value_ & 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct is_even
|
||||
@ -149,7 +149,7 @@ struct is_even
|
||||
template<class Hooks, bool constant_time_size>
|
||||
bool operator()
|
||||
(const testvalue<Hooks, constant_time_size>& v1) const
|
||||
{ return (v1.value_ & 1) == 0; }
|
||||
{ return (v1.value_ & 1) == 0; }
|
||||
};
|
||||
/*
|
||||
struct int_testvalue_comp
|
||||
|
@ -37,7 +37,7 @@ struct hooks
|
||||
};
|
||||
|
||||
template<class ValueTraits>
|
||||
struct test_list
|
||||
struct test_list
|
||||
{
|
||||
typedef typename ValueTraits::value_type value_type;
|
||||
static void test_all(std::vector<value_type>& values);
|
||||
@ -114,7 +114,7 @@ void test_list<ValueTraits>
|
||||
|
||||
testlist.pop_front();
|
||||
BOOST_TEST (testlist.empty());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//test: constructor, iterator, reverse_iterator, sort, reverse:
|
||||
@ -196,7 +196,7 @@ void test_list<ValueTraits>
|
||||
int init_values [] = { 1, 3, 4, 5 };
|
||||
TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() );
|
||||
}
|
||||
|
||||
|
||||
//test: assign, insert, const_iterator, const_reverse_iterator, erase, s_iterator_to:
|
||||
template<class ValueTraits>
|
||||
void test_list<ValueTraits>
|
||||
@ -281,7 +281,7 @@ void test_list<ValueTraits>
|
||||
testlist.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//test: insert (seq-version), swap, splice, erase (seq-version):
|
||||
template<class ValueTraits>
|
||||
@ -319,7 +319,7 @@ void test_list<ValueTraits>
|
||||
{ int init_values [] = { 1, 3, 5, 2 };
|
||||
TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() ); }
|
||||
|
||||
testlist1.splice (testlist1.end(), testlist2,
|
||||
testlist1.splice (testlist1.end(), testlist2,
|
||||
testlist2.begin(), ----testlist2.end());
|
||||
{ int init_values [] = { 4, 1, 3 };
|
||||
TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
|
||||
@ -414,7 +414,7 @@ class test_main_template
|
||||
typedef testvalue<hooks<VoidPointer>, constant_time_size> value_type;
|
||||
std::vector<value_type> data (5);
|
||||
for (int i = 0; i < 5; ++i)
|
||||
data[i].value_ = i + 1;
|
||||
data[i].value_ = i + 1;
|
||||
|
||||
test_list < typename detail::get_base_value_traits
|
||||
< value_type
|
||||
@ -442,7 +442,7 @@ class test_main_template<VoidPointer, false>
|
||||
typedef testvalue<hooks<VoidPointer>, false> value_type;
|
||||
std::vector<value_type> data (5);
|
||||
for (int i = 0; i < 5; ++i)
|
||||
data[i].value_ = i + 1;
|
||||
data[i].value_ = i + 1;
|
||||
|
||||
test_list < typename detail::get_base_value_traits
|
||||
< value_type
|
||||
@ -489,7 +489,7 @@ class test_main_template<VoidPointer, false>
|
||||
}
|
||||
};
|
||||
|
||||
int main( int, char* [] )
|
||||
int main( int, char* [] )
|
||||
{
|
||||
test_main_template<void*, false>()();
|
||||
test_main_template<smart_ptr<void>, false>()();
|
||||
|
@ -23,7 +23,7 @@ template<class T, class O1, class O2, class O3, class O4>
|
||||
#else
|
||||
template<class T, class ...Options>
|
||||
#endif
|
||||
struct has_insert_before<boost::intrusive::multiset<T,
|
||||
struct has_insert_before<boost::intrusive::multiset<T,
|
||||
#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
O1, O2, O3, O4
|
||||
#else
|
||||
@ -145,7 +145,7 @@ class test_main_template<VoidPointer, false>
|
||||
}
|
||||
};
|
||||
|
||||
int main( int, char* [] )
|
||||
int main( int, char* [] )
|
||||
{
|
||||
test_main_template<void*, false>()();
|
||||
test_main_template<boost::intrusive::smart_ptr<void>, false>()();
|
||||
|
@ -49,7 +49,7 @@ void instantiate()
|
||||
list< Foo, base_hook<ListBaseHook> > list_; list_.clear();
|
||||
slist< Foo, base_hook<SListBaseHook> > slist_; slist_.clear();
|
||||
set< Foo, base_hook<SetBaseHook> > set_; set_.clear();
|
||||
|
||||
|
||||
USet::bucket_type buckets[1];
|
||||
USet unordered_set_(USet::bucket_traits(buckets, 1)); unordered_set_.clear();
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ template<class T, class O1, class O2, class O3, class O4>
|
||||
#else
|
||||
template<class T, class ...Options>
|
||||
#endif
|
||||
struct has_insert_before<boost::intrusive::set<T,
|
||||
struct has_insert_before<boost::intrusive::set<T,
|
||||
#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
O1, O2, O3, O4
|
||||
#else
|
||||
@ -148,7 +148,7 @@ class test_main_template<VoidPointer, false>
|
||||
};
|
||||
|
||||
|
||||
int main( int, char* [] )
|
||||
int main( int, char* [] )
|
||||
{
|
||||
test_main_template<void*, false>()();
|
||||
test_main_template<boost::intrusive::smart_ptr<void>, false>()();
|
||||
|
@ -40,7 +40,7 @@ template<class T, class O1, class O2, class O3, class O4>
|
||||
#else
|
||||
template<class T, class ...Options>
|
||||
#endif
|
||||
struct has_insert_before<boost::intrusive::sg_multiset<T,
|
||||
struct has_insert_before<boost::intrusive::sg_multiset<T,
|
||||
#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
O1, O2, O3, O4
|
||||
#else
|
||||
@ -143,7 +143,7 @@ class test_main_template
|
||||
}
|
||||
};
|
||||
|
||||
int main( int, char* [] )
|
||||
int main( int, char* [] )
|
||||
{
|
||||
test_main_template<void*>()();
|
||||
test_main_template<boost::intrusive::smart_ptr<void> >()();
|
||||
|
@ -22,7 +22,7 @@ template<class T, class O1, class O2, class O3, class O4>
|
||||
#else
|
||||
template<class T, class ...Options>
|
||||
#endif
|
||||
struct has_rebalance<boost::intrusive::sg_set<T,
|
||||
struct has_rebalance<boost::intrusive::sg_set<T,
|
||||
#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
O1, O2, O3, O4
|
||||
#else
|
||||
@ -38,7 +38,7 @@ template<class T, class O1, class O2, class O3, class O4>
|
||||
#else
|
||||
template<class T, class ...Options>
|
||||
#endif
|
||||
struct has_insert_before<boost::intrusive::sg_set<T,
|
||||
struct has_insert_before<boost::intrusive::sg_set<T,
|
||||
#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
O1, O2, O3, O4
|
||||
#else
|
||||
@ -142,7 +142,7 @@ class test_main_template
|
||||
}
|
||||
};
|
||||
|
||||
int main( int, char* [] )
|
||||
int main( int, char* [] )
|
||||
{
|
||||
test_main_template<void*>()();
|
||||
test_main_template<boost::intrusive::smart_ptr<void> >()();
|
||||
|
@ -38,7 +38,7 @@ struct hooks
|
||||
};
|
||||
|
||||
template<class ValueTraits, bool Linear, bool CacheLast>
|
||||
struct test_slist
|
||||
struct test_slist
|
||||
{
|
||||
typedef typename ValueTraits::value_type value_type;
|
||||
static void test_all(std::vector<value_type>& values);
|
||||
@ -106,7 +106,7 @@ void test_slist<ValueTraits, Linear, CacheLast>
|
||||
> list_type;
|
||||
list_type testlist;
|
||||
BOOST_TEST (testlist.empty());
|
||||
|
||||
|
||||
testlist.push_front (values[0]);
|
||||
BOOST_TEST (testlist.size() == 1);
|
||||
BOOST_TEST (&testlist.front() == &values[0]);
|
||||
@ -114,11 +114,11 @@ void test_slist<ValueTraits, Linear, CacheLast>
|
||||
testlist.push_front (values[1]);
|
||||
BOOST_TEST (testlist.size() == 2);
|
||||
BOOST_TEST (&testlist.front() == &values[1]);
|
||||
|
||||
|
||||
testlist.pop_front();
|
||||
BOOST_TEST (testlist.size() == 1);
|
||||
BOOST_TEST (&testlist.front() == &values[0]);
|
||||
|
||||
|
||||
testlist.pop_front();
|
||||
BOOST_TEST (testlist.empty());
|
||||
}
|
||||
@ -241,8 +241,8 @@ void test_slist<ValueTraits, Linear, CacheLast>
|
||||
testlist.reverse();
|
||||
{ int init_values [] = { 5, 3, 1, 4, 2 };
|
||||
TEST_INTRUSIVE_SEQUENCE( init_values, testlist.begin() ); }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//test: assign, insert_after, const_iterator, erase_after, s_iterator_to, previous:
|
||||
template<class ValueTraits, bool Linear, bool CacheLast>
|
||||
void test_slist<ValueTraits, Linear, CacheLast>
|
||||
@ -374,7 +374,7 @@ void test_slist<ValueTraits, Linear, CacheLast>
|
||||
testlist.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//test: insert_after (seq-version), swap, splice_after:
|
||||
template<class ValueTraits, bool Linear, bool CacheLast>
|
||||
@ -410,7 +410,7 @@ void test_slist<ValueTraits, Linear, CacheLast>
|
||||
{ int init_values [] = { 1, 3, 5, 2 };
|
||||
TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() ); }
|
||||
|
||||
testlist1.splice_after (testlist1.begin(), testlist2,
|
||||
testlist1.splice_after (testlist1.begin(), testlist2,
|
||||
testlist2.before_begin(), ++++testlist2.begin());
|
||||
{ int init_values [] = { 4, 1, 3, 5 };
|
||||
TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
|
||||
@ -476,7 +476,7 @@ void test_slist<ValueTraits, Linear, CacheLast>
|
||||
{ int init_values [] = { 1 };
|
||||
TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class ValueTraits, bool Linear, bool CacheLast>
|
||||
void test_slist<ValueTraits, Linear, CacheLast>
|
||||
@ -529,7 +529,7 @@ class test_main_template
|
||||
typedef testvalue<hooks<VoidPointer> , constant_time_size> value_type;
|
||||
std::vector<value_type> data (5);
|
||||
for (int i = 0; i < 5; ++i)
|
||||
data[i].value_ = i + 1;
|
||||
data[i].value_ = i + 1;
|
||||
|
||||
test_slist < typename detail::get_base_value_traits
|
||||
< value_type
|
||||
@ -620,7 +620,7 @@ class test_main_template<VoidPointer, false>
|
||||
typedef testvalue<hooks<VoidPointer> , false> value_type;
|
||||
std::vector<value_type> data (5);
|
||||
for (int i = 0; i < 5; ++i)
|
||||
data[i].value_ = i + 1;
|
||||
data[i].value_ = i + 1;
|
||||
|
||||
test_slist < typename detail::get_base_value_traits
|
||||
< value_type
|
||||
@ -721,7 +721,7 @@ class test_main_template<VoidPointer, false>
|
||||
}
|
||||
};
|
||||
|
||||
int main(int, char* [])
|
||||
int main(int, char* [])
|
||||
{
|
||||
test_main_template<void*, false>()();
|
||||
test_main_template<smart_ptr<void>, false>()();
|
||||
|
@ -37,8 +37,8 @@ struct empty_type{};
|
||||
|
||||
template<class T>
|
||||
struct random_it
|
||||
: public boost::iterator<std::random_access_iterator_tag,
|
||||
T, std::ptrdiff_t, T*, T&>
|
||||
: public boost::iterator<std::random_access_iterator_tag,
|
||||
T, std::ptrdiff_t, T*, T&>
|
||||
{
|
||||
typedef const T* const_pointer;
|
||||
typedef const T& const_reference;
|
||||
@ -121,11 +121,11 @@ class smart_ptr
|
||||
|
||||
//!Constructor from other pointer. Never throws.
|
||||
template <class T>
|
||||
smart_ptr(T *ptr)
|
||||
smart_ptr(T *ptr)
|
||||
: m_ptr(ptr)
|
||||
{}
|
||||
*/
|
||||
//!Constructor from other smart_ptr
|
||||
//!Constructor from other smart_ptr
|
||||
smart_ptr(const smart_ptr& ptr)
|
||||
: m_ptr(ptr.m_ptr)
|
||||
{}
|
||||
@ -133,10 +133,10 @@ class smart_ptr
|
||||
static smart_ptr pointer_to(reference r)
|
||||
{ smart_ptr p; p.m_ptr = &r; return p; }
|
||||
|
||||
//!Constructor from other smart_ptr. If pointers of pointee types are
|
||||
//!Constructor from other smart_ptr. If pointers of pointee types are
|
||||
//!convertible, offset_ptrs will be convertibles. Never throws.
|
||||
template<class T2>
|
||||
smart_ptr(const smart_ptr<T2> &ptr)
|
||||
smart_ptr(const smart_ptr<T2> &ptr)
|
||||
: m_ptr(ptr.m_ptr)
|
||||
{}
|
||||
/*
|
||||
@ -169,16 +169,16 @@ class smart_ptr
|
||||
{ return m_ptr; }
|
||||
*/
|
||||
//!Pointer-like -> operator. It can return 0 pointer. Never throws.
|
||||
pointer operator->() const
|
||||
pointer operator->() const
|
||||
{ return m_ptr; }
|
||||
|
||||
//!Dereferencing operator, if it is a null smart_ptr behavior
|
||||
//!Dereferencing operator, if it is a null smart_ptr behavior
|
||||
//! is undefined. Never throws.
|
||||
reference operator* () const
|
||||
reference operator* () const
|
||||
{ return *m_ptr; }
|
||||
|
||||
//!Indexing operator. Never throws.
|
||||
reference operator[](std::ptrdiff_t idx) const
|
||||
reference operator[](std::ptrdiff_t idx) const
|
||||
{ return m_ptr[idx]; }
|
||||
/*
|
||||
//!Assignment from pointer (saves extra conversion). Never throws.
|
||||
@ -189,14 +189,14 @@ class smart_ptr
|
||||
smart_ptr& operator= (const smart_ptr & pt)
|
||||
{ m_ptr = pt.m_ptr; return *this; }
|
||||
|
||||
//!Assignment from related smart_ptr. If pointers of pointee types
|
||||
//!Assignment from related smart_ptr. If pointers of pointee types
|
||||
//! are assignable, offset_ptrs will be assignable. Never throws.
|
||||
template <class T2>
|
||||
smart_ptr& operator= (const smart_ptr<T2> & pt)
|
||||
{ m_ptr = pt.m_ptr; return *this; }
|
||||
|
||||
|
||||
//!smart_ptr + std::ptrdiff_t. Never throws.
|
||||
smart_ptr operator+ (std::ptrdiff_t offset) const
|
||||
smart_ptr operator+ (std::ptrdiff_t offset) const
|
||||
{ smart_ptr s; s.m_ptr = m_ptr + offset; return s; }
|
||||
|
||||
//!smart_ptr - std::ptrdiff_t. Never throws.
|
||||
@ -212,7 +212,7 @@ class smart_ptr
|
||||
{ m_ptr -= offset; return *this; }
|
||||
|
||||
//!++smart_ptr. Never throws.
|
||||
smart_ptr& operator++ (void)
|
||||
smart_ptr& operator++ (void)
|
||||
{ ++m_ptr; return *this; }
|
||||
|
||||
//!smart_ptr++. Never throws.
|
||||
@ -220,7 +220,7 @@ class smart_ptr
|
||||
{ smart_ptr temp(*this); ++*this; return temp; }
|
||||
|
||||
//!--smart_ptr. Never throws.
|
||||
smart_ptr& operator-- (void)
|
||||
smart_ptr& operator-- (void)
|
||||
{ --m_ptr; return *this; }
|
||||
|
||||
//!smart_ptr--. Never throws.
|
||||
@ -228,16 +228,16 @@ class smart_ptr
|
||||
{ smart_ptr temp(*this); --*this; return temp; }
|
||||
|
||||
//!safe bool conversion operator. Never throws.
|
||||
operator unspecified_bool_type() const
|
||||
operator unspecified_bool_type() const
|
||||
{ return m_ptr? &self_t::unspecified_bool_type_func : 0; }
|
||||
|
||||
//!Not operator. Not needed in theory, but improves portability.
|
||||
//!Not operator. Not needed in theory, but improves portability.
|
||||
//!Never throws.
|
||||
bool operator! () const
|
||||
{ return m_ptr == 0; }
|
||||
/*
|
||||
friend void swap (smart_ptr &pt, smart_ptr &pt2)
|
||||
{
|
||||
{
|
||||
value_type *ptr = pt.get();
|
||||
pt = pt2;
|
||||
pt2 = ptr;
|
||||
@ -247,102 +247,102 @@ class smart_ptr
|
||||
|
||||
//!smart_ptr<T1> == smart_ptr<T2>. Never throws.
|
||||
template<class T1, class T2>
|
||||
inline bool operator== (const smart_ptr<T1> &pt1,
|
||||
inline bool operator== (const smart_ptr<T1> &pt1,
|
||||
const smart_ptr<T2> &pt2)
|
||||
{ return pt1.operator->() == pt2.operator->(); }
|
||||
|
||||
//!smart_ptr<T1> != smart_ptr<T2>. Never throws.
|
||||
template<class T1, class T2>
|
||||
inline bool operator!= (const smart_ptr<T1> &pt1,
|
||||
inline bool operator!= (const smart_ptr<T1> &pt1,
|
||||
const smart_ptr<T2> &pt2)
|
||||
{ return pt1.operator->() != pt2.operator->(); }
|
||||
|
||||
//!smart_ptr<T1> < smart_ptr<T2>. Never throws.
|
||||
template<class T1, class T2>
|
||||
inline bool operator< (const smart_ptr<T1> &pt1,
|
||||
inline bool operator< (const smart_ptr<T1> &pt1,
|
||||
const smart_ptr<T2> &pt2)
|
||||
{ return pt1.operator->() < pt2.operator->(); }
|
||||
|
||||
//!smart_ptr<T1> <= smart_ptr<T2>. Never throws.
|
||||
template<class T1, class T2>
|
||||
inline bool operator<= (const smart_ptr<T1> &pt1,
|
||||
inline bool operator<= (const smart_ptr<T1> &pt1,
|
||||
const smart_ptr<T2> &pt2)
|
||||
{ return pt1.operator->() <= pt2.operator->(); }
|
||||
|
||||
//!smart_ptr<T1> > smart_ptr<T2>. Never throws.
|
||||
template<class T1, class T2>
|
||||
inline bool operator> (const smart_ptr<T1> &pt1,
|
||||
inline bool operator> (const smart_ptr<T1> &pt1,
|
||||
const smart_ptr<T2> &pt2)
|
||||
{ return pt1.operator->() > pt2.operator->(); }
|
||||
|
||||
//!smart_ptr<T1> >= smart_ptr<T2>. Never throws.
|
||||
template<class T1, class T2>
|
||||
inline bool operator>= (const smart_ptr<T1> &pt1,
|
||||
inline bool operator>= (const smart_ptr<T1> &pt1,
|
||||
const smart_ptr<T2> &pt2)
|
||||
{ return pt1.operator->() >= pt2.operator->(); }
|
||||
|
||||
//!operator<<
|
||||
template<class E, class T, class Y>
|
||||
inline std::basic_ostream<E, T> & operator<<
|
||||
//!operator<<
|
||||
template<class E, class T, class Y>
|
||||
inline std::basic_ostream<E, T> & operator<<
|
||||
(std::basic_ostream<E, T> & os, smart_ptr<Y> const & p)
|
||||
{ return os << p.operator->(); }
|
||||
|
||||
//!operator>>
|
||||
template<class E, class T, class Y>
|
||||
inline std::basic_istream<E, T> & operator>>
|
||||
//!operator>>
|
||||
template<class E, class T, class Y>
|
||||
inline std::basic_istream<E, T> & operator>>
|
||||
(std::basic_istream<E, T> & os, smart_ptr<Y> & p)
|
||||
{ Y * tmp; return os >> tmp; p = tmp; }
|
||||
|
||||
//!std::ptrdiff_t + smart_ptr
|
||||
//!std::ptrdiff_t + smart_ptr
|
||||
template<class T>
|
||||
inline smart_ptr<T> operator+(std::ptrdiff_t diff, const smart_ptr<T>& right)
|
||||
{ return right + diff; }
|
||||
|
||||
//!smart_ptr - smart_ptr
|
||||
//!smart_ptr - smart_ptr
|
||||
template<class T, class T2>
|
||||
inline std::ptrdiff_t operator- (const smart_ptr<T> &pt, const smart_ptr<T2> &pt2)
|
||||
{ return pt.operator->()- pt2.operator->(); }
|
||||
|
||||
//!swap specialization
|
||||
//!swap specialization
|
||||
template<class T>
|
||||
inline void swap (smart_ptr<T> &pt,
|
||||
inline void swap (smart_ptr<T> &pt,
|
||||
smart_ptr<T> &pt2)
|
||||
{
|
||||
{
|
||||
typename smart_ptr<T>::value_type *ptr = pt.operator->();
|
||||
pt = pt2;
|
||||
pt2 = ptr;
|
||||
}
|
||||
|
||||
//!Simulation of static_cast between pointers. Never throws.
|
||||
template<class T, class U>
|
||||
inline smart_ptr<T>
|
||||
template<class T, class U>
|
||||
inline smart_ptr<T>
|
||||
static_pointer_cast(const smart_ptr<U> & r)
|
||||
{
|
||||
return smart_ptr<T>(r, detail::static_cast_tag());
|
||||
{
|
||||
return smart_ptr<T>(r, detail::static_cast_tag());
|
||||
}
|
||||
|
||||
//!Simulation of const_cast between pointers. Never throws.
|
||||
template<class T, class U>
|
||||
template<class T, class U>
|
||||
inline smart_ptr<T>const_pointer_cast(smart_ptr<U> const & r)
|
||||
{
|
||||
return smart_ptr<T>(r, detail::const_cast_tag());
|
||||
{
|
||||
return smart_ptr<T>(r, detail::const_cast_tag());
|
||||
}
|
||||
|
||||
//!Simulation of dynamic_cast between pointers. Never throws.
|
||||
template<class T, class U>
|
||||
inline smart_ptr<T>
|
||||
template<class T, class U>
|
||||
inline smart_ptr<T>
|
||||
dynamic_pointer_cast(smart_ptr<U> const & r)
|
||||
{
|
||||
{
|
||||
return smart_ptr<T>
|
||||
(r, detail::dynamic_cast_tag());
|
||||
(r, detail::dynamic_cast_tag());
|
||||
}
|
||||
|
||||
//!Simulation of reinterpret_cast between pointers. Never throws.
|
||||
template<class T, class U>
|
||||
template<class T, class U>
|
||||
inline smart_ptr<T>
|
||||
reinterpret_pointer_cast(smart_ptr<U> const & r)
|
||||
{
|
||||
return smart_ptr<T>(r, detail::reinterpret_cast_tag());
|
||||
{
|
||||
return smart_ptr<T>(r, detail::reinterpret_cast_tag());
|
||||
}
|
||||
|
||||
} //namespace intrusive {
|
||||
|
@ -41,7 +41,7 @@ template<class T, class O1, class O2, class O3, class O4>
|
||||
#else
|
||||
template<class T, class ...Options>
|
||||
#endif
|
||||
struct has_splay<boost::intrusive::splay_multiset<T,
|
||||
struct has_splay<boost::intrusive::splay_multiset<T,
|
||||
#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
O1, O2, O3, O4
|
||||
#else
|
||||
@ -57,7 +57,7 @@ template<class T, class O1, class O2, class O3, class O4>
|
||||
#else
|
||||
template<class T, class ...Options>
|
||||
#endif
|
||||
struct has_rebalance<boost::intrusive::splay_multiset<T,
|
||||
struct has_rebalance<boost::intrusive::splay_multiset<T,
|
||||
#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
O1, O2, O3, O4
|
||||
#else
|
||||
@ -177,7 +177,7 @@ class test_main_template<VoidPointer, false>
|
||||
}
|
||||
};
|
||||
|
||||
int main( int, char* [] )
|
||||
int main( int, char* [] )
|
||||
{
|
||||
test_main_template<void*, false>()();
|
||||
test_main_template<boost::intrusive::smart_ptr<void>, false>()();
|
||||
|
@ -175,7 +175,7 @@ class test_main_template<VoidPointer, false>
|
||||
}
|
||||
};
|
||||
|
||||
int main( int, char* [] )
|
||||
int main( int, char* [] )
|
||||
{
|
||||
test_main_template<void*, false>()();
|
||||
test_main_template<boost::intrusive::smart_ptr<void>, false>()();
|
||||
|
@ -57,16 +57,16 @@ struct stateful_value_traits
|
||||
: values_(values), node_array_(node_array)
|
||||
{}
|
||||
|
||||
node_ptr to_node_ptr (value_type &value)
|
||||
node_ptr to_node_ptr (value_type &value)
|
||||
{ return node_array_ + (&value - values_); }
|
||||
|
||||
const_node_ptr to_node_ptr (const value_type &value) const
|
||||
const_node_ptr to_node_ptr (const value_type &value) const
|
||||
{ return node_array_ + (&value - values_); }
|
||||
|
||||
pointer to_value_ptr(node_ptr n)
|
||||
{ return values_ + (n - node_array_); }
|
||||
|
||||
const_pointer to_value_ptr(const_node_ptr n) const
|
||||
const_pointer to_value_ptr(const_node_ptr n) const
|
||||
{ return values_ + (n - node_array_); }
|
||||
|
||||
pointer values_;
|
||||
|
@ -247,7 +247,7 @@ void test_common_unordered_and_associative_container(Container & c, Data & d)
|
||||
{
|
||||
BOOST_TEST( c.find(*di) != c.end() );
|
||||
}
|
||||
|
||||
|
||||
typename Data::const_iterator db = d.begin();
|
||||
typename Data::const_iterator da = db++;
|
||||
|
||||
|
@ -24,7 +24,7 @@ template<class T, class O1, class O2, class O3, class O4>
|
||||
#else
|
||||
template<class T, class ...Options>
|
||||
#endif
|
||||
struct has_insert_before<boost::intrusive::treap_multiset<T,
|
||||
struct has_insert_before<boost::intrusive::treap_multiset<T,
|
||||
#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
O1, O2, O3, O4
|
||||
#else
|
||||
@ -143,7 +143,7 @@ class test_main_template<VoidPointer, false>
|
||||
}
|
||||
};
|
||||
|
||||
int main( int, char* [] )
|
||||
int main( int, char* [] )
|
||||
{
|
||||
test_main_template<void*, false>()();
|
||||
test_main_template<boost::intrusive::smart_ptr<void>, false>()();
|
||||
|
@ -22,7 +22,7 @@ template<class T, class O1, class O2, class O3, class O4>
|
||||
#else
|
||||
template<class T, class ...Options>
|
||||
#endif
|
||||
struct has_insert_before<boost::intrusive::treap_set<T,
|
||||
struct has_insert_before<boost::intrusive::treap_set<T,
|
||||
#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
O1, O2, O3, O4
|
||||
#else
|
||||
@ -38,7 +38,7 @@ template<class T, class O1, class O2, class O3, class O4>
|
||||
#else
|
||||
template<class T, class ...Options>
|
||||
#endif
|
||||
struct is_treap<boost::intrusive::treap_set<T,
|
||||
struct is_treap<boost::intrusive::treap_set<T,
|
||||
#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
O1, O2, O3, O4
|
||||
#else
|
||||
@ -159,7 +159,7 @@ class test_main_template<VoidPointer, false>
|
||||
}
|
||||
};
|
||||
|
||||
int main( int, char* [] )
|
||||
int main( int, char* [] )
|
||||
{
|
||||
test_main_template<void*, false>()();
|
||||
test_main_template<boost::intrusive::smart_ptr<void>, false>()();
|
||||
|
@ -144,7 +144,7 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>
|
||||
|
||||
std::vector<value_type> values (5);
|
||||
for (int i = 0; i < 5; ++i)
|
||||
values[i].value_ = i;
|
||||
values[i].value_ = i;
|
||||
|
||||
typename unordered_multiset_type::bucket_type buckets [BucketSize];
|
||||
unordered_multiset_type testset(bucket_traits(
|
||||
@ -157,7 +157,7 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>
|
||||
testset.erase (testset.iterator_to (values[0]));
|
||||
testset.erase (testset.iterator_to (values[1]));
|
||||
testset.insert (values[1]);
|
||||
|
||||
|
||||
testset.erase (testset.iterator_to (values[2]));
|
||||
testset.erase (testset.iterator_to (values[3]));
|
||||
}
|
||||
@ -194,7 +194,7 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>
|
||||
}
|
||||
testset1.clear();
|
||||
BOOST_TEST (testset1.empty());
|
||||
}
|
||||
}
|
||||
|
||||
//test: insert, const_iterator, const_reverse_iterator, erase, iterator_to:
|
||||
template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
|
||||
@ -231,7 +231,7 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>
|
||||
|
||||
i = testset.insert (values[0]);
|
||||
BOOST_TEST (&*i == &values[0]);
|
||||
|
||||
|
||||
i = testset.iterator_to (values[2]);
|
||||
BOOST_TEST (&*i == &values[2]);
|
||||
testset.erase(i);
|
||||
@ -275,7 +275,7 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>
|
||||
|
||||
i = testset.insert (values[0]);
|
||||
BOOST_TEST (&*i == &values[0]);
|
||||
|
||||
|
||||
i = testset.iterator_to (values[2]);
|
||||
BOOST_TEST (&*i == &values[2]);
|
||||
testset.erase(i);
|
||||
@ -317,7 +317,7 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>
|
||||
for(unsigned int i = 0, max = random_size; i != max; ++i){
|
||||
std::vector<typename ValueTraits::value_type> data (random_size);
|
||||
for (unsigned int j = 0; j < random_size; ++j)
|
||||
data[j].value_ = random_init[j];
|
||||
data[j].value_ = random_init[j];
|
||||
unordered_multiset_type testset_new(bucket_traits(
|
||||
pointer_traits<typename unordered_multiset_type::bucket_ptr>::
|
||||
pointer_to(single_bucket[0]), 1));
|
||||
@ -442,7 +442,7 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>:
|
||||
// BOOST_TEST (&testset1.front() == &values[3]);
|
||||
BOOST_TEST (&*testset1.begin() == &values[3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -651,7 +651,7 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>
|
||||
BOOST_TEST (testset1.size() == values.size());
|
||||
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||
}
|
||||
}
|
||||
|
||||
//test: find, equal_range (lower_bound, upper_bound):
|
||||
template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
|
||||
@ -682,14 +682,14 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>:
|
||||
BOOST_TEST (i->value_ == 2);
|
||||
BOOST_TEST ((++i)->value_ == 2);
|
||||
std::pair<iterator,iterator> range = testset.equal_range (cmp_val);
|
||||
|
||||
|
||||
BOOST_TEST (range.first->value_ == 2);
|
||||
BOOST_TEST (range.second->value_ == 3);
|
||||
BOOST_TEST (std::distance (range.first, range.second) == 2);
|
||||
|
||||
cmp_val.value_ = 7;
|
||||
BOOST_TEST (testset.find (cmp_val) == testset.end());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
|
||||
@ -781,7 +781,7 @@ class test_main_template
|
||||
static const int random_init[6] = { 3, 2, 4, 1, 5, 2 };
|
||||
std::vector<testvalue<hooks<VoidPointer> , constant_time_size> > data (6);
|
||||
for (int i = 0; i < 6; ++i)
|
||||
data[i].value_ = random_init[i];
|
||||
data[i].value_ = random_init[i];
|
||||
|
||||
test_unordered_multiset < typename detail::get_base_value_traits
|
||||
< value_type
|
||||
@ -817,7 +817,7 @@ class test_main_template<VoidPointer, false, Incremental>
|
||||
static const int random_init[6] = { 3, 2, 4, 1, 5, 2 };
|
||||
std::vector<testvalue<hooks<VoidPointer> , false> > data (6);
|
||||
for (int i = 0; i < 6; ++i)
|
||||
data[i].value_ = random_init[i];
|
||||
data[i].value_ = random_init[i];
|
||||
|
||||
test_unordered_multiset < typename detail::get_base_value_traits
|
||||
< value_type
|
||||
@ -864,7 +864,7 @@ class test_main_template<VoidPointer, false, Incremental>
|
||||
}
|
||||
};
|
||||
|
||||
int main( int, char* [] )
|
||||
int main( int, char* [] )
|
||||
{
|
||||
test_main_template<void*, false, true>()();
|
||||
test_main_template<smart_ptr<void>, false, true>()();
|
||||
|
@ -71,7 +71,7 @@ struct hooks
|
||||
static const std::size_t BucketSize = 8;
|
||||
|
||||
template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
|
||||
struct test_unordered_set
|
||||
struct test_unordered_set
|
||||
{
|
||||
typedef typename ValueTraits::value_type value_type;
|
||||
static void test_all(std::vector<value_type>& values);
|
||||
@ -142,7 +142,7 @@ void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::test
|
||||
|
||||
std::vector<value_type> values (5);
|
||||
for (int i = 0; i < 5; ++i)
|
||||
values[i].value_ = i;
|
||||
values[i].value_ = i;
|
||||
|
||||
typename unordered_set_type::bucket_type buckets [BucketSize];
|
||||
unordered_set_type testset(bucket_traits(
|
||||
@ -188,11 +188,11 @@ void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::
|
||||
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||
}
|
||||
|
||||
|
||||
testset1.clear();
|
||||
BOOST_TEST (testset1.empty());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//test: insert, const_iterator, const_reverse_iterator, erase, iterator_to:
|
||||
template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
|
||||
void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::
|
||||
@ -251,7 +251,7 @@ void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::
|
||||
{ int init_values [] = { 1, 3, 5 };
|
||||
TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//test: insert (seq-version), swap, erase (seq-version), size:
|
||||
template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
|
||||
@ -299,7 +299,7 @@ void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::
|
||||
BOOST_TEST (testset1.size() == 1);
|
||||
BOOST_TEST (&*testset1.begin() == &values[3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//test: rehash:
|
||||
template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
|
||||
@ -507,7 +507,7 @@ void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::
|
||||
BOOST_TEST (testset1.size() == values.size()-1);
|
||||
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//test: find, equal_range (lower_bound, upper_bound):
|
||||
@ -538,7 +538,7 @@ void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::
|
||||
BOOST_TEST (i->value_ == 2);
|
||||
BOOST_TEST ((++i)->value_ != 2);
|
||||
std::pair<iterator,iterator> range = testset.equal_range (cmp_val);
|
||||
|
||||
|
||||
BOOST_TEST (range.first->value_ == 2);
|
||||
BOOST_TEST (range.second->value_ == 3);
|
||||
BOOST_TEST (std::distance (range.first, range.second) == 1);
|
||||
@ -636,7 +636,7 @@ class test_main_template
|
||||
static const int random_init[6] = { 3, 2, 4, 1, 5, 2 };
|
||||
std::vector<testvalue<hooks<VoidPointer> , constant_time_size> > data (6);
|
||||
for (int i = 0; i < 6; ++i)
|
||||
data[i].value_ = random_init[i];
|
||||
data[i].value_ = random_init[i];
|
||||
|
||||
test_unordered_set < typename detail::get_base_value_traits
|
||||
< value_type
|
||||
@ -672,7 +672,7 @@ class test_main_template<VoidPointer, false, incremental>
|
||||
static const int random_init[6] = { 3, 2, 4, 1, 5, 2 };
|
||||
std::vector<testvalue<hooks<VoidPointer> , false> > data (6);
|
||||
for (int i = 0; i < 6; ++i)
|
||||
data[i].value_ = random_init[i];
|
||||
data[i].value_ = random_init[i];
|
||||
|
||||
test_unordered_set < typename detail::get_base_value_traits
|
||||
< value_type
|
||||
@ -719,7 +719,7 @@ class test_main_template<VoidPointer, false, incremental>
|
||||
}
|
||||
};
|
||||
|
||||
int main( int, char* [] )
|
||||
int main( int, char* [] )
|
||||
{
|
||||
test_main_template<void*, false, true>()();
|
||||
test_main_template<smart_ptr<void>, false, true>()();
|
||||
|
@ -78,7 +78,7 @@ int main()
|
||||
|
||||
//Test the objects inserted in the base hook list
|
||||
for(; vect_it != vect_itend; ++vect_it, ++list_it)
|
||||
if(&*list_it != &*vect_it)
|
||||
if(&*list_it != &*vect_it)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user