forked from boostorg/intrusive
New Intrusive version
[SVN r38273]
This commit is contained in:
@@ -8,12 +8,10 @@
|
|||||||
# See http://www.boost.org/libs/intrusive for documentation.
|
# See http://www.boost.org/libs/intrusive for documentation.
|
||||||
|
|
||||||
|
|
||||||
project boost/intrusive/doc ;
|
import doxygen ;
|
||||||
|
|
||||||
import boostbook : boostbook ;
|
|
||||||
import quickbook ;
|
import quickbook ;
|
||||||
|
|
||||||
doxygen intrusive_doxygen
|
doxygen autodoc
|
||||||
:
|
:
|
||||||
[ glob ../../../boost/intrusive/*.hpp ]
|
[ glob ../../../boost/intrusive/*.hpp ]
|
||||||
:
|
:
|
||||||
@@ -26,15 +24,15 @@ doxygen intrusive_doxygen
|
|||||||
<doxygen:param>SEARCH_INCLUDES=YES
|
<doxygen:param>SEARCH_INCLUDES=YES
|
||||||
;
|
;
|
||||||
|
|
||||||
xml intrusive_xml : intrusive.qbk ;
|
xml intrusive : intrusive.qbk ;
|
||||||
|
|
||||||
boostbook intrusive
|
boostbook standalone
|
||||||
:
|
:
|
||||||
intrusive_xml
|
intrusive
|
||||||
intrusive_doxygen
|
|
||||||
:
|
:
|
||||||
<xsl:param>boost.root=../../../..
|
<xsl:param>boost.root=../../../..
|
||||||
<xsl:param>boost.libraries=../../../../libs/libraries.htm
|
<xsl:param>boost.libraries=../../../../libs/libraries.htm
|
||||||
<xsl:param>generate.section.toc.level=3
|
<xsl:param>generate.section.toc.level=3
|
||||||
<xsl:param>chunk.first.sections=1
|
<xsl:param>chunk.first.sections=1
|
||||||
|
<dependency>autodoc
|
||||||
;
|
;
|
||||||
|
@@ -1,8 +1,16 @@
|
|||||||
|
[/
|
||||||
|
/ Copyright (c) 2007 Ion Gaztanaga
|
||||||
|
/
|
||||||
|
/ 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)
|
||||||
|
/]
|
||||||
|
|
||||||
[library Boost.Intrusive
|
[library Boost.Intrusive
|
||||||
[quickbook 1.3]
|
[quickbook 1.3]
|
||||||
[version 2007-06-23]
|
|
||||||
[authors [Krzikalla, Olaf], [Gaztañaga, Ion]]
|
[authors [Krzikalla, Olaf], [Gaztañaga, Ion]]
|
||||||
[copyright 2005 Olaf Krzikalla, 2006-2007 Ion Gaztañaga]
|
[copyright 2005 Olaf Krzikalla, 2006-2007 Ion Gaztañaga]
|
||||||
|
[id intrusive]
|
||||||
|
[dirname intrusive]
|
||||||
[purpose Intrusive containers]
|
[purpose Intrusive containers]
|
||||||
[license
|
[license
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
Distributed under the Boost Software License, Version 1.0.
|
||||||
@@ -17,7 +25,7 @@
|
|||||||
|
|
||||||
[*Boost.Intrusive] is a library presenting some intrusive containers to
|
[*Boost.Intrusive] is a library presenting some intrusive containers to
|
||||||
the world of C++. Intrusive containers are special containers
|
the world of C++. Intrusive containers are special containers
|
||||||
that offer [link boost_intrusive.performance better performance]
|
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
|
The performance benefits of intrusive containers makes them ideal as a building
|
||||||
@@ -190,7 +198,7 @@ Intrusive containers have also downsides:
|
|||||||
swapping can be used to implement move-capabilities. To ease the implementation of
|
swapping can be used to implement move-capabilities. To ease the implementation of
|
||||||
copy constructors and assignment operators of classes storing [*Boost.Intrusive]
|
copy constructors and assignment operators of classes storing [*Boost.Intrusive]
|
||||||
containers, [*Boost.Intrusive] offers special cloning functions. See
|
containers, [*Boost.Intrusive] offers special cloning functions. See
|
||||||
[link boost_intrusive.clone_from Cloning [*Boost.Intrusive] containers] section for more information.
|
[link intrusive.clone_from Cloning [*Boost.Intrusive] containers] section for more information.
|
||||||
|
|
||||||
* Analyzing thread-safety of a program that uses containers is harder with intrusive containers, becuase
|
* Analyzing thread-safety of a program that uses containers is harder with intrusive containers, becuase
|
||||||
the container might be modified indirectly without an explicitly call to a container member.
|
the container might be modified indirectly without an explicitly call to a container member.
|
||||||
@@ -214,7 +222,7 @@ Intrusive containers have also downsides:
|
|||||||
]
|
]
|
||||||
|
|
||||||
For a performance comparison between Intrusive and Non-intrusive containers see
|
For a performance comparison between Intrusive and Non-intrusive containers see
|
||||||
[link boost_intrusive.performance Performance] section.
|
[link intrusive.performance Performance] section.
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
@@ -259,11 +267,11 @@ three template arguments:
|
|||||||
|
|
||||||
* The second template argument controls the linking policy. [*Boost.Intrusive] currently supports
|
* The second template argument controls the linking policy. [*Boost.Intrusive] currently supports
|
||||||
3 policies: `normal_link`, `safe_link`, `auto_unlink`. More about these in the sections
|
3 policies: `normal_link`, `safe_link`, `auto_unlink`. More about these in the sections
|
||||||
[link boost_intrusive.safe_hook Safe hooks] and [link boost_intrusive.auto_unlink_hooks Auto-unlink hooks]
|
[link intrusive.safe_hook Safe hooks] and [link intrusive.auto_unlink_hooks Auto-unlink hooks]
|
||||||
|
|
||||||
* The third template argument is the pointer type to be used internally in the hook.
|
* The third template argument is the pointer type to be used internally in the hook.
|
||||||
The default value is `void *`, which means that raw pointers will be used in the hook.
|
The default value is `void *`, which means that raw pointers will be used in the hook.
|
||||||
More about this in the section titled [link boost_intrusive.using_smart_pointers Using smart pointers with Boost.Intrusive containers]
|
More about this in the section titled [link intrusive.using_smart_pointers Using smart pointers with Boost.Intrusive containers]
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
@@ -591,13 +599,13 @@ the user. See [@http://www.boost.org/libs/utility/assert.html] for more
|
|||||||
information about `BOOST_ASSERT`.
|
information about `BOOST_ASSERT`.
|
||||||
|
|
||||||
`BOOST_ASSERT` is globally configured for all the libraries, so the user might
|
`BOOST_ASSERT` is globally configured for all the libraries, so the user might
|
||||||
want to redefine safe-mode assertions without modifying `BOOST_ASSERT`. This can
|
want to redefine intrusive safe-mode assertions without modifying the global
|
||||||
be achieved redefining the following macros:
|
`BOOST_ASSERT`. This can be achieved redefining the following macros:
|
||||||
|
|
||||||
* `BOOST_INTRUSIVE_SAFE_MODE_CONTAINER_INSERTION_ASSERT`: This assertion will be
|
* `BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT`: This assertion will be
|
||||||
used in insertion functions of the intrusive containers to check that
|
used in insertion functions of the intrusive containers to check that
|
||||||
the hook of the value to be inserted is default constructed.
|
the hook of the value to be inserted is default constructed.
|
||||||
* `BOOST_INTRUSIVE_SAFE_MODE_HOOK_DESTRUCTOR_ASSERT`: This assertion will be
|
* `BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT`: This assertion will be
|
||||||
used in hooks' destructors to check that the hook is in a default state.
|
used in hooks' destructors to check that the hook is in a default state.
|
||||||
|
|
||||||
If any of these macros is not redefined, it will be defaulted to `BOOST_ASSERT`.
|
If any of these macros is not redefined, it will be defaulted to `BOOST_ASSERT`.
|
||||||
@@ -620,7 +628,7 @@ If any of these macros is not redefined, it will be defaulted to `BOOST_ASSERT`.
|
|||||||
|
|
||||||
These hooks have exactly the same size overhead as their analogue non auto-unlinking
|
These hooks have exactly the same size overhead as their analogue non auto-unlinking
|
||||||
hooks, but they have a restriction: they can only be used with
|
hooks, but they have a restriction: they can only be used with
|
||||||
[link boost_intrusive.presenting_containers non-constant time containers].
|
[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.
|
* Auto-unlink hooks don't store any reference to the container where they are inserted.
|
||||||
@@ -1594,7 +1602,7 @@ before explaining the customization options of [*Boost.Intrusive].
|
|||||||
|
|
||||||
[section:node_algorithms Node algorithms with custom NodeTraits]
|
[section:node_algorithms Node algorithms with custom NodeTraits]
|
||||||
|
|
||||||
As explained in the [link boost_intrusive.concepts Concepts] section, [*Boost.Intrusive]
|
As explained in the [link intrusive.concepts Concepts] section, [*Boost.Intrusive]
|
||||||
containers are implemented using node algorithms that work on generic nodes.
|
containers are implemented using node algorithms that work on generic nodes.
|
||||||
|
|
||||||
Sometimes, the use of intrusive containers is expensive for some environments
|
Sometimes, the use of intrusive containers is expensive for some environments
|
||||||
@@ -1775,7 +1783,7 @@ For a complete rbtree of functions see
|
|||||||
|
|
||||||
[section:value_traits Containers with custom ValueTraits]
|
[section:value_traits Containers with custom ValueTraits]
|
||||||
|
|
||||||
As explained in the [link boost_intrusive.concepts Concepts] section, [*Boost.Intrusive]
|
As explained in the [link intrusive.concepts Concepts] section, [*Boost.Intrusive]
|
||||||
containers are templatized using a `ValueTraits` parameter. This parameter contains
|
containers are templatized using a `ValueTraits` parameter. This parameter contains
|
||||||
all the information to glue the `value_type` of the containers and the node to be
|
all the information to glue the `value_type` of the containers and the node to be
|
||||||
used in node algorithms, since these types can be different. Apart from this,
|
used in node algorithms, since these types can be different. Apart from this,
|
||||||
@@ -1819,7 +1827,7 @@ Let's explain each type and function:
|
|||||||
|
|
||||||
* ['node_traits]: The node configuration that it's needed by node algorithms.
|
* ['node_traits]: The node configuration that it's needed by node algorithms.
|
||||||
These node traits and algorithms are
|
These node traits and algorithms are
|
||||||
described in the previous chapter: [link boost_intrusive.node_algorithms Nodes Algorithms].
|
described in the previous chapter: [link intrusive.node_algorithms Nodes Algorithms].
|
||||||
|
|
||||||
* If my_value_traits is meant to be used with [classref boost::intrusive::slist slist],
|
* If my_value_traits is meant to be used with [classref boost::intrusive::slist slist],
|
||||||
`node_traits` should follow
|
`node_traits` should follow
|
||||||
@@ -1912,6 +1920,21 @@ we'll define a ValueTraits class that will configure [*Boost.Intrusive] containe
|
|||||||
|
|
||||||
[doc_value_traits_value_traits]
|
[doc_value_traits_value_traits]
|
||||||
|
|
||||||
|
Defining a value traits class that just 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
|
Now we can just define the containers that will store the legacy abi objects and write
|
||||||
a little test:
|
a little test:
|
||||||
|
|
||||||
@@ -1955,6 +1978,40 @@ share the same list algorithms.
|
|||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
|
[section:simplifying_value_traits Simplifying value traits definition]
|
||||||
|
|
||||||
|
The previous example can be further simplified using
|
||||||
|
[classref boost::intrusive::derivation_value_traits derivation_value_traits]
|
||||||
|
class to define a value traits class with a value that stores the
|
||||||
|
`simple_node` as a base class:
|
||||||
|
|
||||||
|
[c++]
|
||||||
|
|
||||||
|
#include <boost/intrusive/derivation_value_traits.hpp>
|
||||||
|
|
||||||
|
//value_1, value_2, simple_node and simple_node_traits are defined
|
||||||
|
//as in the previous example...
|
||||||
|
//...
|
||||||
|
|
||||||
|
using namespace boost::intrusive;
|
||||||
|
|
||||||
|
//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;
|
||||||
|
|
||||||
|
//Now define the containers
|
||||||
|
typedef list <ValueTraits1> Value1List;
|
||||||
|
typedef list <ValueTraits2> Value2List;
|
||||||
|
|
||||||
|
We can even choose to store `simple_node` as a member of `value_1` and `value_2`
|
||||||
|
classes and use [classref boost::intrusive::member_value_traits member_value_traits]
|
||||||
|
to define the needed value traits classes:
|
||||||
|
|
||||||
|
[import ../example/doc_advanced_value_traits2.cpp]
|
||||||
|
[doc_advanced_value_traits2_value_traits]
|
||||||
|
|
||||||
|
[endsect]
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
[section:thread_safety Thread safety guarantees]
|
[section:thread_safety Thread safety guarantees]
|
||||||
@@ -2108,7 +2165,7 @@ and also derives from `test_class`.
|
|||||||
You can find the full test code code in the
|
You can find the full test code code in the
|
||||||
[@../../perf/perf_list.cpp perf_list.cpp] source file.
|
[@../../perf/perf_list.cpp perf_list.cpp] source file.
|
||||||
|
|
||||||
[section:performance_results_push_back Back insertions and destruction]
|
[section:performance_results_push_back Back insertion and destruction]
|
||||||
|
|
||||||
The first test will measure the benefits we can obtain with intrusive containers
|
The first test will measure the benefits we can obtain with intrusive containers
|
||||||
avoiding memory allocations and deallocations . All the objects to be
|
avoiding memory allocations and deallocations . All the objects to be
|
||||||
@@ -2171,7 +2228,7 @@ These are the times in microseconds for each case, and the normalized time:
|
|||||||
|
|
||||||
The results are logical: intrusive lists just need one allocation. The destruction
|
The results are logical: intrusive lists just need one allocation. The destruction
|
||||||
time of the `normal_link` intrusive container is trivial (complexity: `O(1)`),
|
time of the `normal_link` intrusive container is trivial (complexity: `O(1)`),
|
||||||
whereas `safe_link` and `auto_unlink` intrusive containers need to the hook of
|
whereas `safe_link` and `auto_unlink` intrusive containers need to put the hook of
|
||||||
erased values' in the default state (complexity: `O(NumElements)`). That's why
|
erased values' in the default state (complexity: `O(NumElements)`). That's why
|
||||||
`normal_link` intrusive list shines in this test.
|
`normal_link` intrusive list shines in this test.
|
||||||
|
|
||||||
@@ -2187,7 +2244,7 @@ a good operating system memory allocator is the reason for this good results.
|
|||||||
|
|
||||||
[section:performance_results_reversing Reversing]
|
[section:performance_results_reversing Reversing]
|
||||||
|
|
||||||
The next test measures the time needed to complete calss to the member function `reverse()`.
|
The next test measures the time needed to complete calls to the member function `reverse()`.
|
||||||
Values (`test_class` and `itest_class`) and lists are created like explained in the
|
Values (`test_class` and `itest_class`) and lists are created like explained in the
|
||||||
previous section.
|
previous section.
|
||||||
|
|
||||||
@@ -2405,6 +2462,21 @@ all the objects to be inserted in intrusive containers in containers like `std::
|
|||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
|
[section:disabling_exceptions Disabling exceptions support]
|
||||||
|
|
||||||
|
[*Boost.Intrusive] might be useful in environments where exceptions are not available
|
||||||
|
or recommendable (like embedded or real-time systems). [*Boost.Intrusive] uses the
|
||||||
|
global Boost mechanism to disable exception handling, so that if the compiler
|
||||||
|
configuration disables exceptions, `BOOST_NO_EXCEPTIONS` is defined and exception
|
||||||
|
handling is disabled.
|
||||||
|
|
||||||
|
This mechanism is a global mechanism to disable exceptions. If for any reason,
|
||||||
|
the user wants to disable exception handling [*only] in [*Boost.Intrusive],
|
||||||
|
`BOOST_INTRUSIVE_DISABLE_EXCEPTION_HANDLING` can be defined to disable
|
||||||
|
exception handling in the library.
|
||||||
|
|
||||||
|
[endsect]
|
||||||
|
|
||||||
[section:tested_compilers Tested compilers]
|
[section:tested_compilers Tested compilers]
|
||||||
|
|
||||||
[*Boost.Intrusive] has been tested in the following compilers/platforms:
|
[*Boost.Intrusive] has been tested in the following compilers/platforms:
|
||||||
@@ -2418,6 +2490,7 @@ all the objects to be inserted in intrusive containers in containers like `std::
|
|||||||
* Codewarrior 9.4/WinXP
|
* Codewarrior 9.4/WinXP
|
||||||
* GCC 3.4.3/Solaris 11
|
* GCC 3.4.3/Solaris 11
|
||||||
* GCC 4.0/Mac Os 10.4.1
|
* GCC 4.0/Mac Os 10.4.1
|
||||||
|
* SunCC 5.8/Solaris 11
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
@@ -2448,7 +2521,7 @@ helpful discussions.
|
|||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
[xinclude intrusive_doxygen.xml]
|
[xinclude autodoc.xml]
|
||||||
|
|
||||||
[section:license_notices License notices]
|
[section:license_notices License notices]
|
||||||
|
|
||||||
|
95
example/doc_advanced_value_traits2.cpp
Normal file
95
example/doc_advanced_value_traits2.cpp
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// (C) Copyright Ion Gaztanaga 2006-2007
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
// See http://www.boost.org/libs/intrusive for documentation.
|
||||||
|
//
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
#include <boost/intrusive/linking_policy.hpp>
|
||||||
|
#include <boost/intrusive/list.hpp>
|
||||||
|
#include <boost/intrusive/member_value_traits.hpp>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
struct simple_node
|
||||||
|
{
|
||||||
|
simple_node *prev_;
|
||||||
|
simple_node *next_;
|
||||||
|
};
|
||||||
|
|
||||||
|
//Define the node traits. A single node_traits will be enough.
|
||||||
|
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; }
|
||||||
|
};
|
||||||
|
|
||||||
|
//[doc_advanced_value_traits2_value_traits
|
||||||
|
class base_1{};
|
||||||
|
class base_2{};
|
||||||
|
|
||||||
|
struct value_1 : public base_1, public simple_node
|
||||||
|
{
|
||||||
|
int id_;
|
||||||
|
simple_node node_;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct value_2 : public base_1, public base_2, public simple_node
|
||||||
|
{
|
||||||
|
simple_node node_;
|
||||||
|
float id_;
|
||||||
|
};
|
||||||
|
|
||||||
|
using namespace boost::intrusive;
|
||||||
|
|
||||||
|
typedef member_value_traits
|
||||||
|
<value_1, simple_node_traits, &value_1::node_, normal_link> ValueTraits1;
|
||||||
|
typedef member_value_traits
|
||||||
|
<value_2, simple_node_traits, &value_2::node_, normal_link> ValueTraits2;
|
||||||
|
|
||||||
|
//Now define two intrusive lists. Both lists will use the same algorithms:
|
||||||
|
// circular_list_algorithms<simple_node_traits>
|
||||||
|
typedef boost::intrusive::list <ValueTraits1> Value1List;
|
||||||
|
typedef boost::intrusive::list <ValueTraits2> Value2List;
|
||||||
|
//]
|
||||||
|
|
||||||
|
//[doc_advanced_value_traits2_test
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
typedef std::vector<value_1> Vect1;
|
||||||
|
typedef std::vector<value_2> Vect2;
|
||||||
|
|
||||||
|
//Create values, with a different internal number
|
||||||
|
Vect1 values1;
|
||||||
|
Vect2 values2;
|
||||||
|
for(int i = 0; i < 100; ++i){
|
||||||
|
value_1 v1; v1.id_ = i; values1.push_back(v1);
|
||||||
|
value_2 v2; v2.id_ = (float)i; values2.push_back(v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Create the lists with the objects
|
||||||
|
Value1List list1(values1.begin(), values1.end());
|
||||||
|
Value2List list2(values2.begin(), values2.end());
|
||||||
|
|
||||||
|
//Now test both lists
|
||||||
|
Value1List::const_iterator bit1(list1.begin()), bitend1(list1.end());
|
||||||
|
Value2List::const_iterator bit2(list2.begin()), bitend2(list2.end());
|
||||||
|
|
||||||
|
Vect1::const_iterator it1(values1.begin()), itend1(values1.end());
|
||||||
|
Vect2::const_iterator it2(values2.begin()), itend2(values2.end());
|
||||||
|
|
||||||
|
//Test the objects inserted in our lists
|
||||||
|
for(; it1 != itend1; ++it1, ++bit1, ++it2, ++bit2){
|
||||||
|
if(&*bit1 != &*it1 || &*bit2 != &*it2) return false;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//]
|
@@ -45,7 +45,7 @@ int main()
|
|||||||
//nodes and the container itself must be created in shared memory
|
//nodes and the container itself must be created in shared memory
|
||||||
const int MaxElem = 100;
|
const int MaxElem = 100;
|
||||||
const int ShmSize = 50000;
|
const int ShmSize = 50000;
|
||||||
const char *ShmName = "MySharedMemory";
|
const char *ShmName = "SharedMemoryName";
|
||||||
|
|
||||||
using namespace boost::interprocess;
|
using namespace boost::interprocess;
|
||||||
|
|
||||||
|
@@ -60,6 +60,7 @@ struct legacy_value_traits
|
|||||||
static pointer to_value_ptr(node_ptr n) { return pointer(n); }
|
static pointer to_value_ptr(node_ptr n) { return pointer(n); }
|
||||||
static const_pointer to_value_ptr(const_node_ptr n) { return const_pointer(n); }
|
static const_pointer to_value_ptr(const_node_ptr n) { return const_pointer(n); }
|
||||||
};
|
};
|
||||||
|
|
||||||
//]
|
//]
|
||||||
|
|
||||||
//[doc_value_traits_test
|
//[doc_value_traits_test
|
||||||
|
@@ -111,6 +111,9 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\..\..\boost\intrusive\circular_slist_algorithms.hpp">
|
RelativePath="..\..\..\..\..\boost\intrusive\circular_slist_algorithms.hpp">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\..\..\boost\intrusive\derivation_value_traits.hpp">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\..\..\boost\intrusive\hashtable.hpp">
|
RelativePath="..\..\..\..\..\boost\intrusive\hashtable.hpp">
|
||||||
</File>
|
</File>
|
||||||
@@ -126,6 +129,9 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\..\..\boost\intrusive\list_hook.hpp">
|
RelativePath="..\..\..\..\..\boost\intrusive\list_hook.hpp">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\..\..\boost\intrusive\member_value_traits.hpp">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\..\..\boost\intrusive\pointer_plus_bit.hpp">
|
RelativePath="..\..\..\..\..\boost\intrusive\pointer_plus_bit.hpp">
|
||||||
</File>
|
</File>
|
||||||
@@ -150,6 +156,9 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\..\..\boost\intrusive\tag.hpp">
|
RelativePath="..\..\..\..\..\boost\intrusive\tag.hpp">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\..\..\boost\intrusive\trivial_value_traits.hpp">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\..\..\boost\intrusive\unordered_set.hpp">
|
RelativePath="..\..\..\..\..\boost\intrusive\unordered_set.hpp">
|
||||||
</File>
|
</File>
|
||||||
@@ -169,7 +178,7 @@
|
|||||||
RelativePath="..\..\..\..\..\boost\intrusive\detail\config_end.hpp">
|
RelativePath="..\..\..\..\..\boost\intrusive\detail\config_end.hpp">
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\..\..\boost\intrusive\detail\ebo_holder.hpp">
|
RelativePath="..\..\..\..\..\boost\intrusive\detail\ebo_functor_holder.hpp">
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\..\..\boost\intrusive\detail\hashtable_node.hpp">
|
RelativePath="..\..\..\..\..\boost\intrusive\detail\hashtable_node.hpp">
|
||||||
@@ -186,9 +195,6 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\..\..\boost\intrusive\detail\pointer_to_other.hpp">
|
RelativePath="..\..\..\..\..\boost\intrusive\detail\pointer_to_other.hpp">
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\..\..\..\..\boost\intrusive\detail\pointer_type.hpp">
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\..\..\boost\intrusive\detail\rbtree_node.hpp">
|
RelativePath="..\..\..\..\..\boost\intrusive\detail\rbtree_node.hpp">
|
||||||
</File>
|
</File>
|
||||||
@@ -225,6 +231,9 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\test\test_container.hpp">
|
RelativePath="..\..\..\test\test_container.hpp">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\test\testvalue.hpp">
|
||||||
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="example"
|
Name="example"
|
||||||
|
@@ -27,6 +27,8 @@
|
|||||||
MinimalRebuild="TRUE"
|
MinimalRebuild="TRUE"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="5"
|
RuntimeLibrary="5"
|
||||||
|
DisableLanguageExtensions="TRUE"
|
||||||
|
ForceConformanceInForLoopScope="TRUE"
|
||||||
UsePrecompiledHeader="0"
|
UsePrecompiledHeader="0"
|
||||||
WarningLevel="3"
|
WarningLevel="3"
|
||||||
Detect64BitPortabilityProblems="TRUE"
|
Detect64BitPortabilityProblems="TRUE"
|
||||||
|
@@ -24,6 +24,8 @@
|
|||||||
MinimalRebuild="TRUE"
|
MinimalRebuild="TRUE"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="5"
|
RuntimeLibrary="5"
|
||||||
|
DisableLanguageExtensions="TRUE"
|
||||||
|
ForceConformanceInForLoopScope="TRUE"
|
||||||
UsePrecompiledHeader="0"
|
UsePrecompiledHeader="0"
|
||||||
WarningLevel="3"
|
WarningLevel="3"
|
||||||
Detect64BitPortabilityProblems="TRUE"
|
Detect64BitPortabilityProblems="TRUE"
|
||||||
|
@@ -24,6 +24,8 @@
|
|||||||
MinimalRebuild="TRUE"
|
MinimalRebuild="TRUE"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="5"
|
RuntimeLibrary="5"
|
||||||
|
DisableLanguageExtensions="TRUE"
|
||||||
|
ForceConformanceInForLoopScope="TRUE"
|
||||||
UsePrecompiledHeader="0"
|
UsePrecompiledHeader="0"
|
||||||
WarningLevel="3"
|
WarningLevel="3"
|
||||||
Detect64BitPortabilityProblems="TRUE"
|
Detect64BitPortabilityProblems="TRUE"
|
||||||
|
@@ -24,6 +24,8 @@
|
|||||||
MinimalRebuild="TRUE"
|
MinimalRebuild="TRUE"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="5"
|
RuntimeLibrary="5"
|
||||||
|
DisableLanguageExtensions="TRUE"
|
||||||
|
ForceConformanceInForLoopScope="TRUE"
|
||||||
UsePrecompiledHeader="0"
|
UsePrecompiledHeader="0"
|
||||||
WarningLevel="3"
|
WarningLevel="3"
|
||||||
Detect64BitPortabilityProblems="TRUE"
|
Detect64BitPortabilityProblems="TRUE"
|
||||||
|
@@ -25,6 +25,8 @@
|
|||||||
MinimalRebuild="TRUE"
|
MinimalRebuild="TRUE"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="5"
|
RuntimeLibrary="5"
|
||||||
|
DisableLanguageExtensions="TRUE"
|
||||||
|
ForceConformanceInForLoopScope="TRUE"
|
||||||
UsePrecompiledHeader="0"
|
UsePrecompiledHeader="0"
|
||||||
WarningLevel="3"
|
WarningLevel="3"
|
||||||
Detect64BitPortabilityProblems="TRUE"
|
Detect64BitPortabilityProblems="TRUE"
|
||||||
|
@@ -24,6 +24,8 @@
|
|||||||
MinimalRebuild="TRUE"
|
MinimalRebuild="TRUE"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="5"
|
RuntimeLibrary="5"
|
||||||
|
DisableLanguageExtensions="TRUE"
|
||||||
|
ForceConformanceInForLoopScope="TRUE"
|
||||||
UsePrecompiledHeader="0"
|
UsePrecompiledHeader="0"
|
||||||
WarningLevel="3"
|
WarningLevel="3"
|
||||||
Detect64BitPortabilityProblems="TRUE"
|
Detect64BitPortabilityProblems="TRUE"
|
||||||
|
@@ -20,6 +20,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <boost/detail/lightweight_test.hpp>
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
#include "test_macros.hpp"
|
#include "test_macros.hpp"
|
||||||
|
#include "test_container.hpp"
|
||||||
|
|
||||||
using namespace boost::intrusive;
|
using namespace boost::intrusive;
|
||||||
|
|
||||||
@@ -39,6 +40,20 @@ struct test_list
|
|||||||
template<class ValueTraits>
|
template<class ValueTraits>
|
||||||
void test_list<ValueTraits>::test_all(std::vector<typename ValueTraits::value_type>& values)
|
void test_list<ValueTraits>::test_all(std::vector<typename ValueTraits::value_type>& values)
|
||||||
{
|
{
|
||||||
|
typedef boost::intrusive::list
|
||||||
|
< ValueTraits
|
||||||
|
, ValueTraits::value_type::constant_time_size
|
||||||
|
, std::size_t
|
||||||
|
> list_type;
|
||||||
|
|
||||||
|
{
|
||||||
|
list_type list(values.begin(), values.end());
|
||||||
|
test::test_container(list);
|
||||||
|
list.clear();
|
||||||
|
list.insert(list.end(), values.begin(), values.end());
|
||||||
|
test::test_sequence_container(list, values);
|
||||||
|
}
|
||||||
|
|
||||||
test_front_back(values);
|
test_front_back(values);
|
||||||
test_sort(values);
|
test_sort(values);
|
||||||
test_insert(values);
|
test_insert(values);
|
||||||
@@ -46,11 +61,6 @@ void test_list<ValueTraits>::test_all(std::vector<typename ValueTraits::value_ty
|
|||||||
test_swap(values);
|
test_swap(values);
|
||||||
test_clone(values);
|
test_clone(values);
|
||||||
|
|
||||||
typedef boost::intrusive::list
|
|
||||||
< ValueTraits
|
|
||||||
, ValueTraits::value_type::constant_time_size
|
|
||||||
, std::size_t
|
|
||||||
> list_type;
|
|
||||||
list_type testlist(values.begin(), values.end());
|
list_type testlist(values.begin(), values.end());
|
||||||
list_type testlist2;
|
list_type testlist2;
|
||||||
}
|
}
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <boost/detail/lightweight_test.hpp>
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
#include "test_macros.hpp"
|
#include "test_macros.hpp"
|
||||||
|
#include "test_container.hpp"
|
||||||
|
|
||||||
using namespace boost::intrusive;
|
using namespace boost::intrusive;
|
||||||
|
|
||||||
@@ -38,6 +39,24 @@ struct test_multiset
|
|||||||
template<class ValueTraits>
|
template<class ValueTraits>
|
||||||
void test_multiset<ValueTraits>::test_all (std::vector<typename ValueTraits::value_type>& values)
|
void test_multiset<ValueTraits>::test_all (std::vector<typename ValueTraits::value_type>& values)
|
||||||
{
|
{
|
||||||
|
typedef multiset
|
||||||
|
<ValueTraits
|
||||||
|
,std::less<typename ValueTraits::value_type>
|
||||||
|
,ValueTraits::value_type::constant_time_size, std::size_t
|
||||||
|
> multiset_type;
|
||||||
|
{
|
||||||
|
multiset_type testset(values.begin(), values.end());
|
||||||
|
test::test_container(testset);
|
||||||
|
testset.clear();
|
||||||
|
testset.insert(values.begin(), values.end());
|
||||||
|
test::test_common_unordered_and_associative_container(testset, values);
|
||||||
|
testset.clear();
|
||||||
|
testset.insert(values.begin(), values.end());
|
||||||
|
test::test_associative_container(testset, values);
|
||||||
|
testset.clear();
|
||||||
|
testset.insert(values.begin(), values.end());
|
||||||
|
test::test_non_unique_container(testset, values);
|
||||||
|
}
|
||||||
test_sort(values);
|
test_sort(values);
|
||||||
test_insert(values);
|
test_insert(values);
|
||||||
test_swap(values);
|
test_swap(values);
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <boost/detail/lightweight_test.hpp>
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
#include "test_macros.hpp"
|
#include "test_macros.hpp"
|
||||||
|
#include "test_container.hpp"
|
||||||
|
|
||||||
using namespace boost::intrusive;
|
using namespace boost::intrusive;
|
||||||
|
|
||||||
@@ -38,6 +39,24 @@ struct test_set
|
|||||||
template<class ValueTraits>
|
template<class ValueTraits>
|
||||||
void test_set<ValueTraits>::test_all(std::vector<typename ValueTraits::value_type>& values)
|
void test_set<ValueTraits>::test_all(std::vector<typename ValueTraits::value_type>& values)
|
||||||
{
|
{
|
||||||
|
typedef boost::intrusive::set
|
||||||
|
<ValueTraits
|
||||||
|
,std::less<typename ValueTraits::value_type>
|
||||||
|
,ValueTraits::value_type::constant_time_size, std::size_t
|
||||||
|
> set_type;
|
||||||
|
{
|
||||||
|
set_type testset(values.begin(), values.end());
|
||||||
|
test::test_container(testset);
|
||||||
|
testset.clear();
|
||||||
|
testset.insert(values.begin(), values.end());
|
||||||
|
test::test_common_unordered_and_associative_container(testset, values);
|
||||||
|
testset.clear();
|
||||||
|
testset.insert(values.begin(), values.end());
|
||||||
|
test::test_associative_container(testset, values);
|
||||||
|
testset.clear();
|
||||||
|
testset.insert(values.begin(), values.end());
|
||||||
|
test::test_unique_container(testset, values);
|
||||||
|
}
|
||||||
test_sort(values);
|
test_sort(values);
|
||||||
test_insert(values);
|
test_insert(values);
|
||||||
test_swap(values);
|
test_swap(values);
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <boost/detail/lightweight_test.hpp>
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
#include "test_macros.hpp"
|
#include "test_macros.hpp"
|
||||||
|
#include "test_container.hpp"
|
||||||
|
|
||||||
using namespace boost::intrusive;
|
using namespace boost::intrusive;
|
||||||
|
|
||||||
@@ -41,6 +42,17 @@ template<class ValueTraits>
|
|||||||
void test_slist<ValueTraits>
|
void test_slist<ValueTraits>
|
||||||
::test_all (std::vector<typename ValueTraits::value_type>& values)
|
::test_all (std::vector<typename ValueTraits::value_type>& values)
|
||||||
{
|
{
|
||||||
|
typedef boost::intrusive::slist
|
||||||
|
<ValueTraits
|
||||||
|
,ValueTraits::value_type::constant_time_size, std::size_t
|
||||||
|
> list_type;
|
||||||
|
{
|
||||||
|
list_type list(values.begin(), values.end());
|
||||||
|
test::test_container(list);
|
||||||
|
list.clear();
|
||||||
|
list.insert(list.end(), values.begin(), values.end());
|
||||||
|
test::test_sequence_container(list, values);
|
||||||
|
}
|
||||||
test_front_back (values);
|
test_front_back (values);
|
||||||
test_sort(values);
|
test_sort(values);
|
||||||
test_merge (values);
|
test_merge (values);
|
||||||
|
@@ -1,119 +1,24 @@
|
|||||||
//////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Copyright (c) 2006 Matias Capeletto
|
// (C) Copyright Ion Gaztanaga 2007
|
||||||
// Copyright (c) 2007 Ion Gaztanaga
|
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
// See http://www.boost.org/libs/intrusive for documentation.
|
||||||
|
//
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#ifndef BOOST_INTRUSIVE_TEST_TEST_CONTAINER_HPP
|
#ifndef BOOST_INTRUSIVE_TEST_CONTAINER_HPP
|
||||||
#define BOOST_INTRUSIVE_TEST_TEST_CONTAINER_HPP
|
#define BOOST_INTRUSIVE_TEST_CONTAINER_HPP
|
||||||
|
|
||||||
// std
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
#include <cassert>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <vector>
|
|
||||||
// Boost.Test
|
|
||||||
//#include "boost/test/included/test_exec_monitor.hpp"
|
|
||||||
|
|
||||||
namespace boost{
|
namespace boost {
|
||||||
namespace intrusive{
|
namespace intrusive {
|
||||||
namespace test {
|
namespace test {
|
||||||
|
|
||||||
const int NumElem = 5;
|
|
||||||
|
|
||||||
/*
|
|
||||||
Beginning of range a.begin() iterator if a is mutable, const_iterator otherwise [4] [7]
|
|
||||||
End of range a.end() iterator if a is mutable, const_iterator otherwise [4]
|
|
||||||
Size a.size() size_type
|
|
||||||
Maximum size a.max_size() size_type
|
|
||||||
Empty container a.empty() Convertible to bool
|
|
||||||
Swap a.swap(b) void
|
|
||||||
|
|
||||||
Expression semantics
|
|
||||||
Semantics of an expression is defined only where it differs from, or is not defined in, Assignable, Equality Comparable, or LessThan Comparable Name Expression Precondition Semantics Postcondition
|
|
||||||
Move constructor X(a) X().size() == a.size(). X() contains a copy of each of a's elements.
|
|
||||||
Move constructor X b(a); b.size() == a.size(). b contains a copy of each of a's elements.
|
|
||||||
Move Assignment operator b = a b.size() == a.size(). b contains a copy of each of a's elements.
|
|
||||||
Destructor a.~X() Each of a's elements is disposed, and memory allocated for them (if any) is deallocated.
|
|
||||||
Beginning of range a.begin() Returns an iterator pointing to the first element in the container. [7] a.begin() is either dereferenceable or past-the-end. It is past-the-end if and only if a.size() == 0.
|
|
||||||
End of range a.end() Returns an iterator pointing one past the last element in the container. a.end() is past-the-end.
|
|
||||||
Size a.size() Returns the size of the container, that is, its number of elements. [8] a.size() >= 0 && a.size() <= max_size()
|
|
||||||
Maximum size a.max_size() Returns the largest size that this container can ever have. [8] a.max_size() >= 0 && a.max_size() >= a.size()
|
|
||||||
Empty container a.empty() Equivalent to a.size() == 0. (But possibly faster.)
|
|
||||||
Swap a.swap(b) Equivalent to swap(a,b) [9]
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
expression return type operational assertion/note complexity
|
|
||||||
semantics pre/post-condition
|
|
||||||
|
|
||||||
|
|
||||||
X::value_type T T is
|
|
||||||
CopyConstructible
|
|
||||||
compile time
|
|
||||||
X::reference lvalue of T compile time
|
|
||||||
X::const_-
|
|
||||||
reference
|
|
||||||
const lvalue of T compile time
|
|
||||||
X::iterator iterator type
|
|
||||||
whose value
|
|
||||||
type is T
|
|
||||||
any iterator category
|
|
||||||
except output iterator.
|
|
||||||
convertible to
|
|
||||||
X::const_iterator.
|
|
||||||
compile time
|
|
||||||
X::const_-
|
|
||||||
iterator
|
|
||||||
constant iterator
|
|
||||||
type whose
|
|
||||||
value type is T
|
|
||||||
any iterator category
|
|
||||||
except output iterator
|
|
||||||
compile time
|
|
||||||
X::difference_
|
|
||||||
type
|
|
||||||
signed integral
|
|
||||||
type
|
|
||||||
is identical to the
|
|
||||||
difference type of
|
|
||||||
X::iterator and
|
|
||||||
X::const_iterator
|
|
||||||
compile time
|
|
||||||
X::size_type unsigned
|
|
||||||
integral type
|
|
||||||
size_type can
|
|
||||||
represent any
|
|
||||||
non-negative value of
|
|
||||||
compile time
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
X u; post: u.size() == 0 constant
|
|
||||||
X(); X().size() == 0 constant
|
|
||||||
X(a); a == X(a). linear
|
|
||||||
X u(a); post: u == a linear
|
|
||||||
X u = a; Equivalent to: X u; u
|
|
||||||
= a;
|
|
||||||
(&a)->X(); void note: the destructor is
|
|
||||||
applied to every
|
|
||||||
element of a; all the
|
|
||||||
memory is deallocated.
|
|
||||||
linear
|
|
||||||
a.begin(); iterator;
|
|
||||||
const_-
|
|
||||||
iterator for
|
|
||||||
constant a
|
|
||||||
constant
|
|
||||||
*/
|
|
||||||
|
|
||||||
template< class Container >
|
template< class Container >
|
||||||
void test_container( Container & c )
|
void test_container( Container & c )
|
||||||
{
|
{
|
||||||
@@ -126,102 +31,231 @@ void test_container( Container & c )
|
|||||||
typedef typename Container::const_pointer const_pointer;
|
typedef typename Container::const_pointer const_pointer;
|
||||||
typedef typename Container::difference_type difference_type;
|
typedef typename Container::difference_type difference_type;
|
||||||
typedef typename Container::size_type size_type;
|
typedef typename Container::size_type size_type;
|
||||||
|
typedef typename Container::difference_type difference_type;
|
||||||
|
typedef typename Container::size_type size_type;
|
||||||
|
typedef typename Container::value_traits value_traits;
|
||||||
|
|
||||||
const size_type num_elem = c.size();
|
const size_type num_elem = c.size();
|
||||||
BOOST_CHECK( c.empty() == (num_elem == 0) );
|
BOOST_TEST( c.empty() == (num_elem == 0) );
|
||||||
{
|
{
|
||||||
iterator it(c.begin()), itend(c.end());
|
iterator it(c.begin()), itend(c.end());
|
||||||
size_type i;
|
size_type i;
|
||||||
for(i = 0; i < num_elem; ++i){
|
for(i = 0; i < num_elem; ++i){
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
BOOST_CHECK( it == c.end() );
|
BOOST_TEST( it == c.end() );
|
||||||
BOOST_CHECK( c.size() == i );
|
BOOST_TEST( c.size() == i );
|
||||||
}
|
}
|
||||||
|
|
||||||
//Check iterator conversion
|
//Check iterator conversion
|
||||||
BOOST_CHECK( const_iterator(c.begin()) == c.cbegin() );
|
BOOST_TEST( const_iterator(c.begin()) == c.cbegin() );
|
||||||
{
|
{
|
||||||
const_iterator it(c.cbegin()), itend(c.cend());
|
const_iterator it(c.cbegin()), itend(c.cend());
|
||||||
size_type i;
|
size_type i;
|
||||||
for(i = 0; i < num_elem; ++i){
|
for(i = 0; i < num_elem; ++i){
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
BOOST_CHECK( it == c.cend() );
|
BOOST_TEST( it == c.cend() );
|
||||||
BOOST_CHECK( c.size() == i );
|
BOOST_TEST( c.size() == i );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
template< class Container >
|
|
||||||
void test_container
|
template< class Container, class Data >
|
||||||
( Container & c, typename Container::size_type num_elem
|
void test_sequence_container(Container & c, Data & d)
|
||||||
, Container & c2, typename Container::size_type num_elem2)
|
|
||||||
{
|
{
|
||||||
typedef typename Container::value_type value_type;
|
assert( d.size() > 2 );
|
||||||
typedef typename Container::iterator iterator;
|
|
||||||
typedef typename Container::const_iterator const_iterator;
|
|
||||||
typedef typename Container::reference reference;
|
|
||||||
typedef typename Container::const_reference const_reference;
|
|
||||||
typedef typename Container::pointer pointer;
|
|
||||||
typedef typename Container::const_pointer const_pointer;
|
|
||||||
typedef typename Container::difference_type difference_type;
|
|
||||||
typedef typename Container::size_type size_type;
|
|
||||||
|
|
||||||
//For the future:
|
c.clear();
|
||||||
//
|
|
||||||
//move-copy constructor
|
|
||||||
//move-assignment
|
|
||||||
|
|
||||||
test_container_helper(c, num_elem);
|
BOOST_TEST( c.size() == 0 );
|
||||||
test_container_helper(c2, num_elem2);
|
BOOST_TEST( c.empty() );
|
||||||
|
|
||||||
//Test swap and test again
|
c.insert( c.begin(), *d.begin() );
|
||||||
c.swap(c2);
|
c.insert( c.end(), *(++d.begin()) );
|
||||||
test_container_helper(c, num_elem2);
|
|
||||||
test_container_helper(c2, num_elem);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
template< class Sequence >
|
BOOST_TEST( c.size() == 2 );
|
||||||
void test_sequence( Sequence & seq )
|
BOOST_TEST( !c.empty() );
|
||||||
{
|
|
||||||
//First the container requirements
|
|
||||||
test_container(seq);
|
|
||||||
typedef Sequence::value_type value_type;
|
|
||||||
typedef Sequence::iterator iterator;
|
|
||||||
|
|
||||||
Sequence::size_type old_size(seq.size());
|
c.erase( c.begin() );
|
||||||
|
|
||||||
//Now test sequence requirements
|
BOOST_TEST( c.size() == 1 );
|
||||||
//insert(p, t)
|
|
||||||
Sequence::value_type one(1);
|
|
||||||
iterator one_pos = seq.insert(seq.begin(), one);
|
|
||||||
BOOST_CHECK( &*seq.begin() == &one );
|
|
||||||
BOOST_CHECK( seq.size() == (old_size + 1) );
|
|
||||||
|
|
||||||
//insert(p, i, j)
|
c.insert( c.begin(), *(++++d.begin()) );
|
||||||
value_type range[2] = { value_type(2), value_type(3) };
|
|
||||||
iterator range_it = one_pos; ++range_it;
|
|
||||||
seq.insert(range_it, &range[0], &range[2]);
|
|
||||||
BOOST_CHECK( seq.size() == (old_size + 3) );
|
|
||||||
range_it = ++seq.begin();
|
|
||||||
BOOST_CHECK( &*range_it == &range[0] );
|
|
||||||
++range_it;
|
|
||||||
BOOST_CHECK( &*range_it == &range[1] );
|
|
||||||
|
|
||||||
//erase(q)
|
c.erase( c.begin(), c.end() );
|
||||||
iterator it_from_erase = seq.erase(seq.begin());
|
|
||||||
BOOST_CHECK( seq.size() == (old_size + 2) );
|
|
||||||
BOOST_CHECK( &*it_from_erase == &range[0] );
|
|
||||||
|
|
||||||
//erase(q1, q2)
|
BOOST_TEST( c.empty() );
|
||||||
iterator q1(it_from_erase), q2(it_from_erase);
|
|
||||||
++++q2;
|
c.insert( c.begin(), *d.begin() );
|
||||||
it_from_erase = seq.erase(q1, q2);
|
|
||||||
BOOST_CHECK( seq.size() == old_size );
|
BOOST_TEST( c.size() == 1 );
|
||||||
//clear(), assign()???
|
|
||||||
|
BOOST_TEST( c.begin() != c.end() );
|
||||||
|
|
||||||
|
c.erase( c.begin() );
|
||||||
|
|
||||||
|
c.assign(d.begin(), d.end());
|
||||||
|
|
||||||
|
BOOST_TEST( c.size() == d.size() );
|
||||||
|
|
||||||
|
c.clear();
|
||||||
|
|
||||||
|
BOOST_TEST( c.size() == 0 );
|
||||||
|
BOOST_TEST( c.empty() );
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace test{
|
template< class Container, class Data >
|
||||||
} // namespace intrusive{
|
void test_common_unordered_and_associative_container(Container & c, Data & d)
|
||||||
} // namespace boost{
|
{
|
||||||
|
typedef typename Container::size_type size_type;
|
||||||
|
|
||||||
#endif // BOOST_INTRUSIVE_TEST_TEST_CONTAINER_HPP
|
assert( d.size() > 2 );
|
||||||
|
|
||||||
|
c.clear();
|
||||||
|
c.insert(d.begin(), d.end());
|
||||||
|
|
||||||
|
for( typename Data::const_iterator di = d.begin(), de = d.end();
|
||||||
|
di != de; ++di )
|
||||||
|
{
|
||||||
|
BOOST_TEST( c.find(*di) != c.end() );
|
||||||
|
}
|
||||||
|
|
||||||
|
typename Data::const_iterator da = d.begin();
|
||||||
|
typename Data::const_iterator db = ++d.begin();
|
||||||
|
|
||||||
|
size_type old_size = c.size();
|
||||||
|
|
||||||
|
c.erase(*da);
|
||||||
|
|
||||||
|
BOOST_TEST( c.size() == old_size-1 );
|
||||||
|
|
||||||
|
BOOST_TEST( c.count(*da) == 0 );
|
||||||
|
BOOST_TEST( c.count(*db) != 0 );
|
||||||
|
|
||||||
|
BOOST_TEST( c.find(*da) == c.end() );
|
||||||
|
BOOST_TEST( c.find(*db) != c.end() );
|
||||||
|
|
||||||
|
BOOST_TEST( c.equal_range(*db).first != c.end() );
|
||||||
|
|
||||||
|
c.clear();
|
||||||
|
|
||||||
|
BOOST_TEST( c.equal_range(*da).first == c.end() );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class Container, class Data >
|
||||||
|
void test_associative_container_invariants(Container & c, Data & d)
|
||||||
|
{
|
||||||
|
typedef typename Container::const_iterator const_iterator;
|
||||||
|
for( typename Data::const_iterator di = d.begin(), de = d.end();
|
||||||
|
di != de; ++di)
|
||||||
|
{
|
||||||
|
const_iterator ci = c.find(*di);
|
||||||
|
BOOST_TEST( ci != c.end() );
|
||||||
|
BOOST_TEST( ! c.value_comp()(*ci, *di) );
|
||||||
|
const_iterator cil = c.lower_bound(*di);
|
||||||
|
const_iterator ciu = c.upper_bound(*di);
|
||||||
|
std::pair<const_iterator, const_iterator> er = c.equal_range(*di);
|
||||||
|
BOOST_TEST( cil == er.first );
|
||||||
|
BOOST_TEST( ciu == er.second );
|
||||||
|
if(ciu != c.end()){
|
||||||
|
BOOST_TEST( c.value_comp()(*cil, *ciu) );
|
||||||
|
}
|
||||||
|
if(c.count(*di) > 1){
|
||||||
|
const_iterator ci_next = cil; ++ci_next;
|
||||||
|
for( ; ci_next != ciu; ++cil, ++ci_next){
|
||||||
|
BOOST_TEST( !c.value_comp()(*ci_next, *cil) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class Container, class Data >
|
||||||
|
void test_associative_container(Container & c, Data & d)
|
||||||
|
{
|
||||||
|
typedef typename Container::const_iterator const_iterator;
|
||||||
|
assert( d.size() > 2 );
|
||||||
|
|
||||||
|
c.clear();
|
||||||
|
c.insert(d.begin(),d.end());
|
||||||
|
|
||||||
|
test_associative_container_invariants(c, d);
|
||||||
|
|
||||||
|
const Container & cr = c;
|
||||||
|
|
||||||
|
test_associative_container_invariants(cr, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class Container, class Data >
|
||||||
|
void test_unordered_associative_container_invariants(Container & c, Data & d)
|
||||||
|
{
|
||||||
|
typedef typename Container::size_type size_type;
|
||||||
|
typedef typename Container::const_iterator const_iterator;
|
||||||
|
|
||||||
|
for( typename Data::const_iterator di = d.begin(), de = d.end() ;
|
||||||
|
di != de ; ++di ){
|
||||||
|
const_iterator i = c.find(*di);
|
||||||
|
size_type nb = c.bucket(*i);
|
||||||
|
size_type bucket_elem = std::distance(c.begin(nb), c.end(nb));
|
||||||
|
BOOST_TEST( bucket_elem == c.bucket_size(nb) );
|
||||||
|
BOOST_TEST( &*c.local_iterator_to(*c.find(*di)) == &*i );
|
||||||
|
std::pair<const_iterator, const_iterator> er = c.equal_range(*di);
|
||||||
|
size_type cnt = std::distance(er.first, er.second);
|
||||||
|
BOOST_TEST( cnt == c.count(*di));
|
||||||
|
if(cnt > 1)
|
||||||
|
for(const_iterator n = er.first, i = n++, e = er.second; n != e; ++i, ++n){
|
||||||
|
BOOST_TEST( c.key_eq()(*i, *n) );
|
||||||
|
BOOST_TEST( c.hash_function()(*i) == c.hash_function()(*n) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_type blen = c.bucket_count();
|
||||||
|
size_type total_objects = 0;
|
||||||
|
for(size_type i = 0; i < blen; ++i){
|
||||||
|
total_objects += c.bucket_size(i);
|
||||||
|
}
|
||||||
|
BOOST_TEST( total_objects == c.size() );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class Container, class Data >
|
||||||
|
void test_unordered_associative_container(Container & c, Data & d)
|
||||||
|
{
|
||||||
|
c.clear();
|
||||||
|
c.insert( d.begin(), d.end() );
|
||||||
|
|
||||||
|
test_unordered_associative_container_invariants(c, d);
|
||||||
|
|
||||||
|
const Container & cr = c;
|
||||||
|
|
||||||
|
test_unordered_associative_container_invariants(cr, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class Container, class Data >
|
||||||
|
void test_unique_container(Container & c, Data & d)
|
||||||
|
{
|
||||||
|
typedef typename Container::value_type value_type;
|
||||||
|
c.clear();
|
||||||
|
c.insert(d.begin(),d.end());
|
||||||
|
typename Container::size_type old_size = c.size();
|
||||||
|
value_type v(*d.begin());
|
||||||
|
c.insert(v);
|
||||||
|
BOOST_TEST( c.size() == old_size );
|
||||||
|
c.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class Container, class Data >
|
||||||
|
void test_non_unique_container(Container & c, Data & d)
|
||||||
|
{
|
||||||
|
typedef typename Container::value_type value_type;
|
||||||
|
c.clear();
|
||||||
|
c.insert(d.begin(),d.end());
|
||||||
|
typename Container::size_type old_size = c.size();
|
||||||
|
value_type v(*d.begin());
|
||||||
|
c.insert(v);
|
||||||
|
BOOST_TEST( c.size() == (old_size+1) );
|
||||||
|
c.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
}}}
|
||||||
|
|
||||||
|
#endif //#ifndef BOOST_INTRUSIVE_TEST_CONTAINER_HPP
|
||||||
|
0
test/test_intrusive_associative_container.hpp
Normal file
0
test/test_intrusive_associative_container.hpp
Normal file
0
test/test_intrusive_sequence_container.hpp
Normal file
0
test/test_intrusive_sequence_container.hpp
Normal file
0
test/test_intrusive_unordered_container.hpp
Normal file
0
test/test_intrusive_unordered_container.hpp
Normal file
@@ -21,6 +21,7 @@
|
|||||||
#include <set>
|
#include <set>
|
||||||
#include <boost/detail/lightweight_test.hpp>
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
#include "test_macros.hpp"
|
#include "test_macros.hpp"
|
||||||
|
#include "test_container.hpp"
|
||||||
|
|
||||||
using namespace boost::intrusive;
|
using namespace boost::intrusive;
|
||||||
|
|
||||||
@@ -43,6 +44,27 @@ struct test_unordered_multiset
|
|||||||
template<class ValueTraits>
|
template<class ValueTraits>
|
||||||
void test_unordered_multiset<ValueTraits>::test_all (std::vector<typename ValueTraits::value_type>& values)
|
void test_unordered_multiset<ValueTraits>::test_all (std::vector<typename ValueTraits::value_type>& values)
|
||||||
{
|
{
|
||||||
|
typedef boost::intrusive::unordered_multiset
|
||||||
|
<ValueTraits
|
||||||
|
,boost::hash<typename ValueTraits::value_type>
|
||||||
|
,std::equal_to<typename ValueTraits::value_type>
|
||||||
|
,ValueTraits::value_type::constant_time_size, std::size_t
|
||||||
|
> unordered_multiset_type;
|
||||||
|
{
|
||||||
|
typename unordered_multiset_type::bucket_type buckets [BucketSize];
|
||||||
|
unordered_multiset_type testset(buckets, BucketSize);
|
||||||
|
testset.insert(values.begin(), values.end());
|
||||||
|
test::test_container(testset);
|
||||||
|
testset.clear();
|
||||||
|
testset.insert(values.begin(), values.end());
|
||||||
|
test::test_common_unordered_and_associative_container(testset, values);
|
||||||
|
testset.clear();
|
||||||
|
testset.insert(values.begin(), values.end());
|
||||||
|
test::test_unordered_associative_container(testset, values);
|
||||||
|
testset.clear();
|
||||||
|
testset.insert(values.begin(), values.end());
|
||||||
|
test::test_non_unique_container(testset, values);
|
||||||
|
}
|
||||||
test_sort(values);
|
test_sort(values);
|
||||||
test_insert(values);
|
test_insert(values);
|
||||||
test_swap(values);
|
test_swap(values);
|
||||||
|
@@ -20,6 +20,7 @@
|
|||||||
#include <set>
|
#include <set>
|
||||||
#include <boost/detail/lightweight_test.hpp>
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
#include "test_macros.hpp"
|
#include "test_macros.hpp"
|
||||||
|
#include "test_container.hpp"
|
||||||
|
|
||||||
using namespace boost::intrusive;
|
using namespace boost::intrusive;
|
||||||
|
|
||||||
@@ -42,6 +43,27 @@ struct test_unordered_set
|
|||||||
template<class ValueTraits>
|
template<class ValueTraits>
|
||||||
void test_unordered_set<ValueTraits>::test_all(std::vector<typename ValueTraits::value_type>& values)
|
void test_unordered_set<ValueTraits>::test_all(std::vector<typename ValueTraits::value_type>& values)
|
||||||
{
|
{
|
||||||
|
typedef boost::intrusive::unordered_set
|
||||||
|
<ValueTraits
|
||||||
|
,boost::hash<typename ValueTraits::value_type>
|
||||||
|
,std::equal_to<typename ValueTraits::value_type>
|
||||||
|
,ValueTraits::value_type::constant_time_size, std::size_t
|
||||||
|
> unordered_set_type;
|
||||||
|
{
|
||||||
|
typename unordered_set_type::bucket_type buckets [BucketSize];
|
||||||
|
unordered_set_type testset(buckets, BucketSize);
|
||||||
|
testset.insert(values.begin(), values.end());
|
||||||
|
test::test_container(testset);
|
||||||
|
testset.clear();
|
||||||
|
testset.insert(values.begin(), values.end());
|
||||||
|
test::test_common_unordered_and_associative_container(testset, values);
|
||||||
|
testset.clear();
|
||||||
|
testset.insert(values.begin(), values.end());
|
||||||
|
test::test_unordered_associative_container(testset, values);
|
||||||
|
testset.clear();
|
||||||
|
testset.insert(values.begin(), values.end());
|
||||||
|
test::test_unique_container(testset, values);
|
||||||
|
}
|
||||||
test_sort(values);
|
test_sort(values);
|
||||||
test_insert(values);
|
test_insert(values);
|
||||||
test_swap(values);
|
test_swap(values);
|
||||||
|
Reference in New Issue
Block a user