First inclusion

[SVN r37593]
This commit is contained in:
Ion Gaztañaga
2007-05-04 21:30:54 +00:00
parent fe23901b24
commit b039088719
60 changed files with 10043 additions and 0 deletions

40
doc/Jamfile.v2 Normal file
View File

@@ -0,0 +1,40 @@
# Boost.Intrusive library documentation Jamfile
#
# Copyright Ion Gazta<74>aga 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)
#
# See http://www.boost.org/libs/intrusive for documentation.
project boost/intrusive/libs/doc ;
import doxygen ;
import quickbook ;
doxygen intrusive_doxygen
:
[ glob ../../../boost/intrusive/*.hpp ]
:
<doxygen:param>HIDE_UNDOC_MEMBERS=YES
<doxygen:param>HIDE_UNDOC_CLASSES=YES
<doxygen:param>EXTRACT_PRIVATE=NO
<doxygen:param>ENABLE_PREPROCESSING=YES
<doxygen:param>MACRO_EXPANSION=YES
<doxygen:param>EXPAND_ONLY_PREDEF=YES
<doxygen:param>SEARCH_INCLUDES=YES
;
xml intrusive_xml : intrusive.qbk ;
boostbook standalone
:
intrusive_xml
intrusive_doxygen
:
<xsl:param>boost.root=../../../..
<xsl:param>boost.libraries=../../../../libs/libraries.htm
<xsl:param>generate.section.toc.level=3
<xsl:param>chunk.first.sections=1
;

538
doc/html/boostbook.css Normal file
View File

@@ -0,0 +1,538 @@
/*=============================================================================
Copyright (c) 2004 Joel de Guzman
http://spirit.sourceforge.net/
Use, modification and distribution is 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)
=============================================================================*/
/*=============================================================================
Body defaults
=============================================================================*/
body
{
margin: 1em;
font-family: sans-serif;
}
/*=============================================================================
Paragraphs
=============================================================================*/
p
{
text-align: left;
font-size: 10pt;
line-height: 1.15;
}
/*=============================================================================
Program listings
=============================================================================*/
/* Code on paragraphs */
p tt.computeroutput
{
font-size: 10pt;
}
pre.synopsis
{
font-size: 10pt;
margin: 1pc 4% 0pc 4%;
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
}
.programlisting,
.screen
{
font-size: 10pt;
display: block;
margin: 1pc 4% 0pc 4%;
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
}
/*=============================================================================
Headings
=============================================================================*/
h1, h2, h3, h4, h5, h6
{
text-align: left;
margin: 1em 0em 0.5em 0em;
font-weight: bold;
}
h1 { font: 140% }
h2 { font: bold 140% }
h3 { font: bold 130% }
h4 { font: bold 120% }
h5 { font: italic 110% }
h6 { font: italic 100% }
/* Top page titles */
title,
h1.title,
h2.title
h3.title,
h4.title,
h5.title,
h6.title,
.refentrytitle
{
font-weight: bold;
margin-bottom: 1pc;
}
h1.title { font-size: 140% }
h2.title { font-size: 140% }
h3.title { font-size: 130% }
h4.title { font-size: 120% }
h5.title { font-size: 110% }
h6.title { font-size: 100% }
.section h1
{
margin: 0em 0em 0.5em 0em;
font-size: 140%;
}
.section h2 { font-size: 140% }
.section h3 { font-size: 130% }
.section h4 { font-size: 120% }
.section h5 { font-size: 110% }
.section h6 { font-size: 100% }
/* Code on titles */
h1 tt.computeroutput { font-size: 140% }
h2 tt.computeroutput { font-size: 140% }
h3 tt.computeroutput { font-size: 130% }
h4 tt.computeroutput { font-size: 120% }
h5 tt.computeroutput { font-size: 110% }
h6 tt.computeroutput { font-size: 100% }
/*=============================================================================
Author
=============================================================================*/
h3.author
{
font-size: 100%
}
/*=============================================================================
Lists
=============================================================================*/
li
{
font-size: 10pt;
line-height: 1.3;
}
/* Unordered lists */
ul
{
text-align: left;
}
/* Ordered lists */
ol
{
text-align: left;
}
/*=============================================================================
Links
=============================================================================*/
a
{
text-decoration: none; /* no underline */
}
a:hover
{
text-decoration: underline;
}
/*=============================================================================
Spirit style navigation
=============================================================================*/
.spirit-nav
{
text-align: right;
}
.spirit-nav a
{
color: white;
padding-left: 0.5em;
}
.spirit-nav img
{
border-width: 0px;
}
/*=============================================================================
Table of contents
=============================================================================*/
.toc
{
margin: 1pc 4% 0pc 4%;
padding: 0.1pc 1pc 0.1pc 1pc;
font-size: 10pt;
line-height: 1.15;
}
.toc-main
{
width: 600;
text-align: center;
margin: 1pc 1pc 1pc 10%;
padding: 2pc 1pc 3pc 1pc;
line-height: 0.1;
}
.boost-toc
{
float: right;
padding: 0.5pc;
}
/*=============================================================================
Tables
=============================================================================*/
.table-title,
div.table p.title
{
margin-left: 4%;
padding-right: 0.5em;
padding-left: 0.5em;
}
.informaltable table,
.table table
{
width: 92%;
margin-left: 4%;
margin-right: 4%;
}
div.informaltable table,
div.table table
{
padding: 4px;
}
/* Table Cells */
div.informaltable table tr td,
div.table table tr td
{
padding: 0.5em;
text-align: left;
}
div.informaltable table tr th,
div.table table tr th
{
padding: 0.5em 0.5em 0.5em 0.5em;
border: 1pt solid white;
font-size: 120%;
}
/*=============================================================================
Blurbs
=============================================================================*/
div.note,
div.tip,
div.important,
div.caution,
div.warning,
p.blurb
{
font-size: 10pt;
line-height: 1.2;
display: block;
margin: 1pc 4% 0pc 4%;
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
}
p.blurb img
{
padding: 1pt;
}
/*=============================================================================
Variable Lists
=============================================================================*/
span.term
{
font-weight: bold;
font-size: 10pt;
}
div.variablelist table tbody tr td
{
text-align: left;
vertical-align: top;
padding: 0em 2em 0em 0em;
font-size: 10pt;
}
div.variablelist table tbody tr td p
{
margin: 0em 0em 0.5em 0em;
}
/* Make the terms in definition lists bold */
div.variablelist dl dt
{
font-weight: bold;
font-size: 10pt;
}
div.variablelist dl dd
{
margin: 1em 0em 1em 2em;
font-size: 10pt;
}
/*=============================================================================
Misc
=============================================================================*/
/* Title of books and articles in bibliographies */
span.title
{
font-style: italic;
}
span.underline
{
text-decoration: underline;
}
span.strikethrough
{
text-decoration: line-through;
}
/* Copyright, Legal Notice */
div div.legalnotice p
{
font-size: 8pt;
text-align: left
}
/*=============================================================================
Colors
=============================================================================*/
@media screen
{
/* Links */
a
{
color: #0C7445;
}
a:visited
{
color: #663974;
}
h1 a, h2 a, h3 a, h4 a, h5 a, h6 a,
h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover,
h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited
{
text-decoration: none; /* no underline */
color: #000000;
}
/* Syntax Highlighting */
.keyword { color: #0000AA; }
.identifier { color: #000000; }
.special { color: #707070; }
.preprocessor { color: #402080; }
.char { color: teal; }
.comment { color: #800000; }
.string { color: teal; }
.number { color: teal; }
.white_bkd { background-color: #E8FBE9; }
.dk_grey_bkd { background-color: #A0DAAC; }
/* Copyright, Legal Notice */
.copyright
{
color: #666666;
font-size: small;
}
div div.legalnotice p
{
color: #666666;
}
/* Program listing */
pre.synopsis
{
border: 1px solid #DCDCDC;
border-bottom: 3px solid #9D9D9D;
border-right: 3px solid #9D9D9D;
background-color: #FAFFFB;
}
.programlisting,
.screen
{
border: 1px solid #DCDCDC;
border-bottom: 3px solid #9D9D9D;
border-right: 3px solid #9D9D9D;
background-color: #FAFFFB;
}
/* Blurbs */
div.note,
div.tip,
div.important,
div.caution,
div.warning,
p.blurb
{
border: 1px solid #DCDCDC;
border-bottom: 3px solid #9D9D9D;
border-right: 3px solid #9D9D9D;
background-color: #FAFFFB;
}
/* Table of contents */
.toc
{
border: 1px solid #DCDCDC;
border-bottom: 3px solid #9D9D9D;
border-right: 3px solid #9D9D9D;
background-color: #FAFFFB;
}
/* Table of contents */
.toc-main
{
border: 1px solid #DCDCDC;
border-bottom: 3px solid #9D9D9D;
border-right: 3px solid #9D9D9D;
background-color: #FAFFFB;
}
/* Tables */
div.informaltable table tr td,
div.table table tr td
{
border: 1px solid #DCDCDC;
background-color: #FAFFFB;
}
div.informaltable table tr th,
div.table table tr th
{
background-color: #E3F9E4;
border: 1px solid #DCDCDC;
}
/* Misc */
span.highlight
{
color: #00A000;
}
}
@media print
{
/* Links */
a
{
color: black;
}
a:visited
{
color: black;
}
.spirit-nav
{
display: none;
}
/* Program listing */
pre.synopsis
{
border: 1px solid gray;
background-color: #FAFFFB;
}
.programlisting,
.screen
{
border: 1px solid gray;
background-color: #FAFFFB;
}
/* Table of contents */
.toc
{
border: 1px solid #DCDCDC;
border-bottom: 3px solid #9D9D9D;
border-right: 3px solid #9D9D9D;
background-color: #FAFFFB;
}
/* Table of contents */
.toc-main
{
border: 1px solid #DCDCDC;
border-bottom: 3px solid #9D9D9D;
border-right: 3px solid #9D9D9D;
background-color: #FAFFFB;
}
.informaltable table,
.table table
{
border: 1px solid #DCDCDC;
border-bottom: 3px solid #9D9D9D;
border-right: 3px solid #9D9D9D;
border-collapse: collapse;
background-color: #FAFFFB;
}
/* Tables */
div.informaltable table tr td,
div.table table tr td
{
border: 1px solid #DCDCDC;
background-color: #FAFFFB;
}
div.informaltable table tr th,
div.table table tr th
{
border: 1px solid #DCDCDC;
background-color: #FAFFFB;
}
/* Misc */
span.highlight
{
font-weight: bold;
}
}

BIN
doc/html/images/blank.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 374 B

BIN
doc/html/images/caution.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
doc/html/images/draft.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
doc/html/images/home.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 358 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 722 B

BIN
doc/html/images/next.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 336 B

BIN
doc/html/images/note.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 490 B

BIN
doc/html/images/prev.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 334 B

BIN
doc/html/images/tip.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 449 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 B

BIN
doc/html/images/up.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 370 B

BIN
doc/html/images/warning.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

5
doc/html/reference.css Normal file
View File

@@ -0,0 +1,5 @@
PRE.synopsis {
background-color: #e0ffff;
border: thin solid blue;
padding: 1em
}

2440
doc/intrusive.qbk Normal file

File diff suppressed because it is too large Load Diff

34
example/Jamfile.v2 Normal file
View File

@@ -0,0 +1,34 @@
# Boost Intrusive Library Documentation test Jamfile
# (C) Copyright Ion Gazta<74>aga 2006-2007.
# 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
# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# this rule enumerates through all the sources and invokes
# the run rule for each source, the result is a list of all
# the run rules, which we can pass on to the test_suite rule:
rule test_all
{
local all_rules = ;
for local fileb in [ glob *.cpp ]
{
all_rules += [ run $(fileb)
: # additional args
: # test-files
: # requirements
] ;
}
return $(all_rules) ;
}
test-suite intrusive_doc : [ test_all r ] ;

View File

@@ -0,0 +1,103 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gazta<74>aga 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.
//
/////////////////////////////////////////////////////////////////////////////
//[doc_advanced_value_traits_code
#include <boost/intrusive/linking_policy.hpp>
#include <boost/intrusive/list.hpp>
#include <vector>
//This is the node that will be used with algorithms.
struct simple_node
{
simple_node *prev_;
simple_node *next_;
};
//]
//[doc_advanced_value_traits_value_traits
class base_1{};
class base_2{};
struct value_1 : public base_1, public simple_node
{ int id_; };
struct value_2 : public base_1, public base_2, public simple_node
{ float id_; };
//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; }
};
//A templatized value traits for value_1 and value_2
template<class ValueType>
struct value_traits
{
typedef simple_node_traits node_traits;
typedef node_traits::node_ptr node_ptr;
typedef node_traits::const_node_ptr const_node_ptr;
typedef ValueType value_type;
typedef ValueType * pointer;
typedef const ValueType * const_pointer;
enum { linking_policy = boost::intrusive::normal_link };
static node_ptr to_node_ptr (value_type &value) { return node_ptr(&value); }
static const_node_ptr to_node_ptr (const value_type &value) { return const_node_ptr(&value); }
static pointer to_value_ptr(node_ptr n) { return static_cast<value_type*>(n); }
static const_pointer to_value_ptr(const_node_ptr n) { return static_cast<const value_type*>(n); }
};
//]
//[doc_advanced_value_traits_containers
//Now define two intrusive lists. Both lists will use the same algorithms:
// circular_list_algorithms<simple_node_traits>
typedef boost::intrusive::list <value_traits<value_1> > Value1List;
typedef boost::intrusive::list <value_traits<value_2> > Value2List;
//]
//[doc_advanced_value_traits_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;
}
//]

View File

@@ -0,0 +1,270 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gazta<74>aga 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.
//
/////////////////////////////////////////////////////////////////////////////
//[doc_assoc_optimized_code_normal_find
#include <boost/intrusive/set.hpp>
#include <boost/intrusive/unordered_set.hpp>
#include <cstring>
using namespace boost::intrusive;
// Hash function for strings
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;
}
};
class Expensive : public set_base_hook<>, public unordered_set_base_hook<>
{
std::string key_;
// Other members...
public:
Expensive(const char *key)
: key_(key)
{} //other expensive initializations...
const std::string & get_key() const
{ return key_; }
friend bool operator < (const Expensive &a, const Expensive &b)
{ return a.key_ < b.key_; }
friend bool operator == (const Expensive &a, const Expensive &b)
{ return a.key_ == b.key_; }
friend std::size_t hash_value(const Expensive &object)
{ return StrHasher()(object.get_key().c_str()); }
};
// A set and unordered_set that store Expensive objects
typedef set<set_base_hook<>::value_traits<Expensive> > Set;
typedef unordered_set<unordered_set_base_hook<>::
value_traits<Expensive> > UnorderedSet;
// Search functions
Expensive *get_from_set(const char* key, Set &set)
{
Set::iterator it = set.find(Expensive(key));
if( it == set.end() ) return 0;
return &*it;
}
Expensive *get_from_unordered_set
(const char* key, UnorderedSet &unordered_set)
{
UnorderedSet::iterator it =
unordered_set.find(Expensive (key));
if( it == unordered_set.end() ) return 0;
return &*it;
}
//]
//[doc_assoc_optimized_code_optimized_find
// These compare Expensive and a c-string
struct StrExpComp
{
bool operator()(const char *str, const Expensive &c) const
{ return std::strcmp(str, c.get_key().c_str()) < 0; }
bool operator()(const Expensive &c, const char *str) const
{ return std::strcmp(c.get_key().c_str(), str) < 0; }
};
struct StrExpEqual
{
bool operator()(const char *str, const Expensive &c) const
{ return std::strcmp(str, c.get_key().c_str()) == 0; }
bool operator()(const Expensive &c, const char *str) const
{ return std::strcmp(c.get_key().c_str(), str) == 0; }
};
// Optimized search functions
Expensive *get_from_set_optimized(const char* key, Set &set)
{
Set::iterator it = set.find(key, StrExpComp());
if( it == set.end() ) return 0;
return &*it;
}
Expensive *get_from_unordered_set_optimized
(const char* key, UnorderedSet &unordered_set)
{
UnorderedSet::iterator it =
unordered_set.find(key, StrHasher(), StrExpEqual());
if( it == unordered_set.end() ) return 0;
return &*it;
}
//]
//[doc_assoc_optimized_code_normal_insert
// Insertion functions
bool insert_to_set(const char* key, Set &set)
{
Expensive *pobject = new Expensive(key);
bool success = set.insert(*pobject).second;
if(!success) delete pobject;
return success;
}
bool insert_to_unordered_set
(const char* key, UnorderedSet &unordered_set)
{
Expensive *pobject = new Expensive(key);
bool success = unordered_set.insert(*pobject).second;
if(!success) delete pobject;
return success;
}
//]
//[doc_assoc_optimized_code_optimized_insert
// Optimized insertion functions
bool insert_to_set_optimized(const char* key, Set &set)
{
Set::insert_commit_data insert_data;
bool success = set.insert_check
(key, StrExpComp(), insert_data).second;
if(success)
set.insert_commit(*new Expensive(key), insert_data);
return success;
}
bool insert_to_unordered_set_optimized
(const char* key, UnorderedSet &unordered_set)
{
UnorderedSet::insert_commit_data insert_data;
bool success = unordered_set.insert_check
(key, StrHasher(), StrExpEqual(), insert_data).second;
if(success)
unordered_set.insert_commit(*new Expensive(key), insert_data);
return success;
}
//]
int main()
{
Set set;
UnorderedSet::bucket_type buckets[10];
UnorderedSet unordered_set(buckets, 10);
const char * const expensive_key
= "A long string that avoids small string optimization";
Expensive value(expensive_key);
if(get_from_set(expensive_key, set)){
return 1;
}
if(get_from_unordered_set(expensive_key, unordered_set)){
return 1;
}
if(get_from_set_optimized(expensive_key, set)){
return 1;
}
if(get_from_unordered_set_optimized(expensive_key, unordered_set)){
return 1;
}
Set::iterator setit = set.insert(value).first;
UnorderedSet::iterator unordered_setit = unordered_set.insert(value).first;
if(!get_from_set(expensive_key, set)){
return 1;
}
if(!get_from_unordered_set(expensive_key, unordered_set)){
return 1;
}
if(!get_from_set_optimized(expensive_key, set)){
return 1;
}
if(!get_from_unordered_set_optimized(expensive_key, unordered_set)){
return 1;
}
set.erase(setit);
unordered_set.erase(unordered_setit);
if(!insert_to_set(expensive_key, set)){
return 1;
}
if(!insert_to_unordered_set(expensive_key, unordered_set)){
return 1;
}
{
Expensive *ptr = &*set.begin();
set.clear();
delete ptr;
}
{
Expensive *ptr = &*unordered_set.begin();
unordered_set.clear();
delete ptr;
}
if(!insert_to_set_optimized(expensive_key, set)){
return 1;
}
if(!insert_to_unordered_set_optimized(expensive_key, unordered_set)){
return 1;
}
{
Expensive *ptr = &*set.begin();
set.clear();
delete ptr;
}
{
Expensive *ptr = &*unordered_set.begin();
unordered_set.clear();
delete ptr;
}
setit = set.insert(value).first;
unordered_setit = unordered_set.insert(value).first;
if(insert_to_set(expensive_key, set)){
return 1;
}
if(insert_to_unordered_set(expensive_key, unordered_set)){
return 1;
}
if(insert_to_set_optimized(expensive_key, set)){
return 1;
}
if(insert_to_unordered_set_optimized(expensive_key, unordered_set)){
return 1;
}
set.erase(value);
unordered_set.erase(value);
return 0;
}

View File

@@ -0,0 +1,83 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gazta<74>aga 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.
//
/////////////////////////////////////////////////////////////////////////////
//[doc_auto_unlink_code
#include <boost/intrusive/list.hpp>
#include <cassert>
using namespace boost::intrusive;
class MyClass : public list_base_hook<tag, auto_unlink>
//This hook removes the node in the destructor
{
int int_;
public:
MyClass(int i = 0) : int_(i) {}
void unlink() { list_base_hook<tag, auto_unlink>::unlink(); }
bool is_linked() { return list_base_hook<tag, auto_unlink>::is_linked(); }
int get() const { return int_; }
};
//Define a list that will store MyClass
//using the public base hook
//The list can't have constant-time size!
typedef list< list_base_hook<tag, auto_unlink>::
value_traits<MyClass>, false > List;
int main()
{
//Create the list
List list;
{
//Create myclass and check it's linked
MyClass myclass;
assert(myclass.is_linked() == false);
//Insert the object
list.push_back(myclass);
//Check that we have inserted the object
assert(list.empty() == false);
assert(&list.front() == &myclass);
assert(myclass.is_linked() == true);
//Now myclass' destructor will unlink it
//automatically
}
//Check auto-unlink has been executed
assert(list.empty() == true);
{
//Now test the unlink() function
//Create myclass and check it's linked
MyClass myclass;
assert(myclass.is_linked() == false);
//Insert the object
list.push_back(myclass);
//Check that we have inserted the object
assert(list.empty() == false);
assert(&list.front() == &myclass);
assert(myclass.is_linked() == true);
//Now unlink the node
myclass.unlink();
//Check auto-unlink has been executed
assert(list.empty() == true);
}
return 0;
}
//]

View File

@@ -0,0 +1,78 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gazta<74>aga 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.
//
/////////////////////////////////////////////////////////////////////////////
//[doc_clone_from
#include <boost/intrusive/list.hpp>
#include <iostream>
#include <vector>
//A class that can be inserted in an intrusive list
class my_class
: public boost::intrusive::list_base_hook<>
{
public:
friend bool operator==(const my_class &a, const my_class &b)
{ return a.int_ == b.int_; }
int int_;
//...
};
//Definition of the intrusive list
typedef boost::intrusive::list< my_class::value_traits<my_class> > my_class_list;
//Cloner object function
class new_cloner
{
public:
my_class *operator()(const my_class &clone_this)
{ return new my_class(clone_this); }
};
//The destroyer object function
class delete_destroyer
{
public:
void operator()(my_class *delete_this)
{ delete delete_this; }
};
int main()
{
const int MaxElem = 100;
std::vector<my_class> nodes(MaxElem);
//Fill all the nodes and insert them in the list
my_class_list list;
for(int i = 0; i < MaxElem; ++i){
nodes[i].int_ = i;
}
list.insert(list.end(), nodes.begin(), nodes.end());
//Now clone "list" using "new" and "delete" object functions
my_class_list cloned_list;
cloned_list.clone_from(list, new_cloner(), delete_destroyer());
//Test that both are equal
if(cloned_list != list){
std::cout << "Both lists are different" << std::endl;
}
else{
std::cout << "Both lists are equal" << std::endl;
}
//Don't forget to free the memory from the second list
cloned_list.clear_and_destroy(delete_destroyer());
return 0;
}
//]

59
example/doc_entity.cpp Normal file
View File

@@ -0,0 +1,59 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gazta<74>aga 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.
//
/////////////////////////////////////////////////////////////////////////////
//[doc_entity_code
#include <boost/intrusive/list.hpp>
//A class that can be inserted in an intrusive list
class entity
: public boost::intrusive::list_base_hook<>
{
public:
virtual ~entity();
//...
};
//"some_entity" derives from "entity"
class some_entity : public entity
{/**/};
//Definition of the intrusive list
typedef boost::intrusive::list< entity::value_traits<entity> > entity_list;
//A global list
entity_list list;
//The destructor removes itself from the list
entity::~entity()
{ list.erase(entity_list::iterator_to(*this)); }
//Function to insert a new "some_entity" in the list
void insert_some_entity()
{ list.push_back (*new some_entity(/*...*/)); }
//Function to clear an entity from the intrusive list
void clear_list ()
{
// entity's destructor removes itself from the list implicitly
while (!list.empty())
delete &list.front();
}
int main()
{
//Insert some new entities
insert_some_entity();
insert_some_entity();
//list's destructor will free objects
return 0;
}
//]

View File

@@ -0,0 +1,73 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gazta<74>aga 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.
//
/////////////////////////////////////////////////////////////////////////////
//[doc_erasing_and_destroying
#include <boost/intrusive/list.hpp>
//A class that can be inserted in an intrusive list
class my_class
: public boost::intrusive::list_base_hook<>
{
public:
my_class(int i)
: int_(i)
{}
int int_;
//...
};
//Definition of the intrusive list
typedef boost::intrusive::list< my_class::value_traits<my_class> > my_class_list;
//The predicate function
class is_even
{
public:
bool operator()(const my_class &c) const
{ return 0 == (c.int_ % 2); }
};
//The destroyer object function
class delete_destroyer
{
public:
void operator()(my_class *delete_this)
{ delete delete_this; }
};
int main()
{
const int MaxElem = 100;
//Fill all the nodes and insert them in the list
my_class_list list;
try{
//Insert new objects in the container
for(int i = 0; i < MaxElem; ++i){
list.push_back(*new my_class(i));
}
//Now use remove_and_destroy_if to erase and delete the objects
list.remove_and_destroy_if(is_even(), delete_destroyer());
}
catch(...){
//If something throws, make sure that all the memory is freed
list.clear_and_destroy(delete_destroyer());
throw;
}
//Destroy remaining elements
list.erase_and_destroy(list.begin(), list.end(), delete_destroyer());
return 0;
}
//]

View File

@@ -0,0 +1,86 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gazta<74>aga 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.
//
/////////////////////////////////////////////////////////////////////////////
//[doc_how_to_use_code
#include <boost/intrusive/list.hpp>
#include <vector>
using namespace boost::intrusive;
class MyClass : public list_base_hook<>
{
int int_;
public:
list_member_hook<> member_hook_;
MyClass(int i) : int_(i) {}
int get() const { return int_; }
};
//Define a list that will store MyClass using the base hook
typedef list< list_base_hook<>::value_traits<MyClass> >
BaseList;
//Define a list that will store MyClass using the member hook
typedef list< list_member_hook<>::
value_traits<MyClass, &MyClass::member_hook_>
> MemberList;
int main()
{
typedef std::vector<MyClass> Vect;
typedef Vect::iterator VectIt;
typedef Vect::reverse_iterator VectRit;
//Create several MyClass objects, each one
//with a different internal number
Vect myclassvector;
for(int i = 0; i < 100; ++i)
myclassvector.push_back(MyClass(i));
BaseList baselist;
MemberList memberlist;
//Now insert them in the reverse order
//in the base hook intrusive list
for(VectIt it(myclassvector.begin()), itend(myclassvector.end())
; it != itend ; ++it){
baselist.push_front(*it);
}
//Now insert them in the same order as in vector in the
//member hook intrusive list
for(VectIt it(myclassvector.begin()), itend(myclassvector.end())
; it != itend; ++it){
memberlist.push_back(*it);
}
//Now test lists
{
BaseList::reverse_iterator rbit(baselist.rbegin()), rbitend(baselist.rend());
MemberList::iterator mit(memberlist.begin()), mitend(memberlist.end());
VectIt it(myclassvector.begin()), itend(myclassvector.end());
//Test the objects inserted in the base hook list
for(; it != itend; ++it, ++rbit){
if(&*rbit != &*it) return 1;
}
//Test the objects inserted in the member hook list
for(it = myclassvector.begin(); it != itend; ++it, ++mit){
if(&*mit != &*it) return 1;
}
}
return 0;
}
//]

View File

@@ -0,0 +1,94 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gazta<74>aga 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.
//
/////////////////////////////////////////////////////////////////////////////
//[doc_iterator_from_value
#include <boost/intrusive/list.hpp>
#include <boost/intrusive/unordered_set.hpp>
#include <boost/functional/hash.hpp>
#include <vector>
class intrusive_data
{
int data_id_;
public:
int get() const { return data_id_; }
void set(int id) { data_id_ = id; }
//This class can be inserted in an intrusive list
typedef boost::intrusive::
list_member_hook<> list_member_hook_t;
list_member_hook_t list_hook_;
//This class can be inserted in an intrusive unordered_set
typedef boost::intrusive::
unordered_set_member_hook<> unordered_set_member_hook_t;
unordered_set_member_hook_t unordered_set_hook_;
//Comparison operators
friend bool operator==(const intrusive_data &a, const intrusive_data &b)
{ return a.get() == b.get(); }
friend bool operator!=(const intrusive_data &a, const intrusive_data &b)
{ return a.get() != b.get(); }
};
//The hash function
std::size_t hash_value(const intrusive_data &i)
{ return boost::hash<int>()(i.get()); }
//Definition of the intrusive list that will hold intrusive_data
typedef boost::intrusive::list< intrusive_data::list_member_hook_t::
value_traits<intrusive_data, &intrusive_data::list_hook_> > list_t;
//Definition of the intrusive unordered_set that will hold intrusive_data
typedef boost::intrusive::unordered_set< intrusive_data::unordered_set_member_hook_t::
value_traits<intrusive_data, &intrusive_data::unordered_set_hook_> > unordered_set_t;
int main()
{
//Create MaxElem objects
const int MaxElem = 100;
std::vector<intrusive_data> nodes(MaxElem);
//Declare the intrusive containers
list_t list;
unordered_set_t::bucket_type buckets[MaxElem];
unordered_set_t unordered_set(buckets, MaxElem);
//Initialize all the nodes
for(int i = 0; i < MaxElem; ++i)
nodes[i].set(i);
//Now insert them in both intrusive containers
list.insert(list.end(), nodes.begin(), nodes.end());
unordered_set.insert(nodes.begin(), nodes.end());
//Now check list::iterator_to
//which is an static member function
list_t::iterator list_it(list.begin());
for(int i = 0; i < MaxElem; ++i, ++list_it)
if(list_t::iterator_to(nodes[i]) != list_it)
return 1;
//Now check unordered_set::iterator_to (which is a member function)
//and unordered_set::local_current (which is an static member function)
unordered_set_t::iterator unordered_set_it(unordered_set.begin());
for(int i = 0; i < MaxElem; ++i, ++unordered_set_it){
if(unordered_set.iterator_to(nodes[i]) != unordered_set.find(nodes[i]))
return 1;
if(*unordered_set_t::local_iterator_to(nodes[i]) != *unordered_set.find(nodes[i]))
return 1;
}
return 0;
}
//]

90
example/doc_list.cpp Normal file
View File

@@ -0,0 +1,90 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gazta<74>aga 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.
//
/////////////////////////////////////////////////////////////////////////////
//[doc_list_code
#include <boost/intrusive/list.hpp>
#include <vector>
using namespace boost::intrusive;
class MyClass : public list_base_hook<> //This is a derivation hook
{
int int_;
public:
//This is a member hook
list_member_hook<> member_hook_;
MyClass(int i)
: int_(i)
{}
int get() const
{ return int_; }
};
//Define a list that will store MyClass using the public base hook
typedef list< list_base_hook<>::value_traits<MyClass> > BaseList;
//Define a list that will store MyClass using the public member hook
typedef list< list_member_hook<>::value_traits<MyClass, &MyClass::member_hook_> > MemberList;
int main()
{
typedef std::vector<MyClass> Vect;
typedef Vect::iterator VectIt;
typedef Vect::reverse_iterator VectRit;
//Create several MyClass objects, each one
//with a different internal number
Vect myclassvector;
for(int i = 0; i < 100; ++i)
myclassvector.push_back(MyClass(i));
BaseList baselist;
MemberList memberlist;
//Now insert them in the reverse order
//in the base hook intrusive list
for(VectIt it(myclassvector.begin()), itend(myclassvector.end())
; it != itend
; ++it){
baselist.push_front(*it);
}
//Now insert them in the same order as in vector in the
//member hook intrusive list
for(VectIt it(myclassvector.begin()), itend(myclassvector.end())
; it != itend
; ++it){
memberlist.push_back(*it);
}
//Now test lists
{
BaseList::reverse_iterator rbit(baselist.rbegin()), rbitend(baselist.rend());
MemberList::iterator mit(memberlist.begin()), mitend(memberlist.end());
VectIt it(myclassvector.begin()), itend(myclassvector.end());
//Test the objects inserted in the base hook list
for(; it != itend; ++it, ++rbit){
if(&*rbit != &*it) return 1;
}
//Test the objects inserted in the member hook list
for(it = myclassvector.begin(); it != itend; ++it, ++mit){
if(&*mit != &*it) return 1;
}
}
return 0;
}
//]

View File

@@ -0,0 +1,66 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gazta<74>aga 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.
//
/////////////////////////////////////////////////////////////////////////////
//[doc_list_algorithms_code
#include <boost/intrusive/circular_list_algorithms.hpp>
#include <cassert>
struct my_node
{
my_node *next_, *prev_;
//other members...
};
//Define our own list_node_traits
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; }
};
int main()
{
typedef boost::intrusive::circular_list_algorithms<my_list_node_traits> algo;
my_node one, two, three;
//Create an empty doubly linked list container:
//"one" will be the first node of the container
algo::init(&one);
assert(algo::count(&one) == 1);
//Now add a new node before "one"
algo::link_before(&one, &two);
assert(algo::count(&one) == 2);
//Now add a new node after "two"
algo::link_after(&two, &three);
assert(algo::count(&one) == 3);
//Now unlink the node after one
algo::unlink(&three);
assert(algo::count(&one) == 2);
//Now unlink two
algo::unlink(&two);
assert(algo::count(&one) == 1);
//Now unlink one
algo::unlink(&one);
assert(algo::count(&one) == 1);
return 0;
}
//]

View File

@@ -0,0 +1,90 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gazta<74>aga 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.
//
/////////////////////////////////////////////////////////////////////////////
//[doc_offset_ptr_0
#include <boost/intrusive/list.hpp>
#include <boost/interprocess/offset_ptr.hpp>
class shared_memory_data
{
int data_id_;
public:
int get() const { return data_id_; }
void set(int id) { data_id_ = id; }
//Declare the hook with an offset_ptr from Boost.Interprocess
//to make this class compatible with shared memory
typedef boost::intrusive::list_member_hook
< boost::intrusive::safe_link
, boost::interprocess::offset_ptr<void> > member_hook_t;
member_hook_t list_hook_;
};
//]
//[doc_offset_ptr_1
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/vector.hpp>
//Definition of the shared memory friendly intrusive list
typedef boost::intrusive::list< shared_memory_data::member_hook_t::
value_traits<shared_memory_data, &shared_memory_data::list_hook_> > shm_list_t;
int main()
{
//Now create an intrusive list in shared memory:
//nodes and the container itself must be created in shared memory
const int MaxElem = 100;
const int ShmSize = 50000;
const char *ShmName = "MySharedMemory";
using namespace boost::interprocess;
//Erase all old shared memory
shared_memory_object::remove(ShmName);
managed_shared_memory shm(create_only, ShmName, ShmSize);
//Create all nodes in shared memory using a shared memory vector
//See Boost.Interprocess documentation for more information on this
typedef allocator< shared_memory_data
, managed_shared_memory::segment_manager> shm_allocator_t;
typedef 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.construct<shm_vector_t>(anonymous_instance)(shm_alloc);
pshm_vect->resize(MaxElem);
//Initialize all the nodes
for(int i = 0; i < MaxElem; ++i){
(*pshm_vect)[i].set(i);
}
//Now create the shared memory intrusive list
shm_list_t *plist = shm.construct<shm_list_t>(anonymous_instance)();
plist->insert(plist->end(), pshm_vect->begin(), pshm_vect->end());
//Check all the inserted nodes
int checker = 0;
for( shm_list_t::const_iterator it = plist->begin(), itend(plist->end())
; it != itend
; ++it, ++checker){
if(it->get() != checker){
return false;
}
}
//Now delete the list and after that, the nodes
shm.destroy_ptr(plist);
shm.destroy_ptr(pshm_vect);
return 0;
}
//]

View File

@@ -0,0 +1,82 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gazta<74>aga 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.
//
/////////////////////////////////////////////////////////////////////////////
//[doc_rbtree_algorithms_code
#include <boost/intrusive/rbtree_algorithms.hpp>
#include <cassert>
struct my_node
{
my_node(int i = 0)
: int_(i)
{}
my_node *parent_, *left_, *right_;
int color_;
//other members
int int_;
};
//Define our own rbtree_node_traits
struct my_rbtree_node_traits
{
typedef my_node node;
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 void set_color(node_ptr n, color c) { n->color_ = c; }
static color black() { return color(0); }
static color red() { return color(1); }
};
struct node_ptr_compare
{
bool operator()(my_node *a, my_node *b)
{ return a->int_ < b->int_; }
};
int main()
{
typedef boost::intrusive::rbtree_algorithms<my_rbtree_node_traits> algo;
my_node header, two(2), three(3);
//Create an empty rbtree container:
//"header" will be the header node of the tree
algo::init_header(&header);
//Now insert node "two" in the tree using the sorting functor
algo::insert_equal_upper_bound(&header, &two, node_ptr_compare());
//Now insert node "three" in the tree using the sorting functor
algo::insert_equal_lower_bound(&header, &three, node_ptr_compare());
//Now take the first node (the left node of the header)
my_node *n = header.left_;
assert(n == &two);
//Now go to the next node
n = algo::next_node(n);
assert(n == &three);
//Erase a node just using a pointer to it
algo::unlink_and_rebalance(n);
//Erase a node using also the header (faster)
algo::erase(&header, n);
return 0;
}
//]

95
example/doc_set.cpp Normal file
View File

@@ -0,0 +1,95 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gazta<74>aga 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.
//
/////////////////////////////////////////////////////////////////////////////
//[doc_set_code
#include <boost/intrusive/set.hpp>
#include <vector>
#include <algorithm>
using namespace boost::intrusive;
//This is a base hook
class MyClass : public set_base_hook<>
{
int int_;
public:
//This is a member hook
set_member_hook<> member_hook_;
MyClass(int i)
: int_(i)
{}
int get() const
{ return int_; }
friend bool operator< (const MyClass &a, const MyClass &b)
{ return a.get() < b.get(); }
friend bool operator> (const MyClass &a, const MyClass &b)
{ return a.get() > b.get(); }
};
//Define an set that will store MyClass
//in reverse order using the public base hook
typedef set< set_base_hook<>::value_traits<MyClass>
, std::greater<MyClass> > BaseSet;
//Define an multiset that will store MyClass
//using the public member hook
typedef multiset< set_member_hook<>::
value_traits<MyClass, &MyClass::member_hook_>
, std::less<MyClass> > MemberIMultiset;
int main()
{
typedef std::vector<MyClass> Vect;
typedef Vect::iterator VectIt;
typedef Vect::reverse_iterator VectRit;
//Create several MyClass objects, each one
//with a different internal number
Vect myclassvector;
for(int i = 0; i < 100; ++i)
myclassvector.push_back(MyClass(i));
BaseSet baseset;
MemberIMultiset membermultiset;
//Now insert them in the reverse order
//in the base hook intrusive set
for(VectIt it(myclassvector.begin()), itend(myclassvector.end())
; it != itend; ++it)
baseset.insert(*it);
//Now insert them in the same order as in vector in the
//member hook intrusive set
for(VectIt it(myclassvector.begin()), itend(myclassvector.end())
; it != itend; ++it)
membermultiset.insert(*it);
//Now test sets
{
BaseSet::reverse_iterator rbit(baseset.rbegin()), rbitend(baseset.rend());
MemberIMultiset::iterator mit(membermultiset.begin()), mitend(membermultiset.end());
VectIt it(myclassvector.begin()), itend(myclassvector.end());
//Test the objects inserted in the base hook set
for(; it != itend; ++it, ++rbit){
if(&*rbit != &*it) return 1;
}
//Test the objects inserted in the member hook set
for(it = myclassvector.begin(); it != itend; ++it, ++mit){
if(&*mit != &*it) return 1;
}
}
return 0;
}
//]

92
example/doc_slist.cpp Normal file
View File

@@ -0,0 +1,92 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gazta<74>aga 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.
//
/////////////////////////////////////////////////////////////////////////////
//[doc_slist_code
#include <boost/intrusive/slist.hpp>
#include <vector>
using namespace boost::intrusive;
//This is a base hook
class MyClass : public slist_base_hook<>
{
int int_;
public:
//This is a member hook
slist_member_hook<> member_hook_;
MyClass(int i)
: int_(i)
{}
int get() const
{ return int_; }
};
//Define an slist that will store MyClass using the public base hook
typedef slist< slist_base_hook<>::value_traits<MyClass> > BaseList;
//Define an slist that will store MyClass using the public member hook
typedef slist< slist_member_hook<>::value_traits<MyClass, &MyClass::member_hook_> > MemberList;
int main()
{
typedef std::vector<MyClass> Vect;
typedef Vect::iterator VectIt;
typedef Vect::reverse_iterator VectRit;
//Create several MyClass objects, each one
//with a different internal number
Vect myclassvector;
for(int i = 0; i < 100; ++i)
myclassvector.push_back(MyClass(i));
BaseList baselist;
MemberList memberlist;
//Now insert them in the reverse order
//in the base hook intrusive list
for(VectIt it(myclassvector.begin()), itend(myclassvector.end())
; it != itend
; ++it){
baselist.push_front(*it);
}
//Now insert them in the same order as in vector in the
//member hook intrusive list
for(BaseList::iterator it(baselist.begin()), itend(baselist.end())
; it != itend
; ++it){
memberlist.push_front(*it);
}
//Now test lists
{
BaseList::iterator bit(baselist.begin()), bitend(baselist.end());
MemberList::iterator mit(memberlist.begin()), mitend(memberlist.end());
VectRit rit(myclassvector.rbegin()), ritend(myclassvector.rend());
VectIt it(myclassvector.begin()), itend(myclassvector.end());
//Test the objects inserted in the base hook list
for(; rit != ritend; ++rit, ++bit){
if(&*bit != &*rit) return 1;
}
//Test the objects inserted in the member hook list
for(; it != itend; ++it, ++mit){
if(&*mit != &*it) return 1;
}
}
return 0;
}
//]

View File

@@ -0,0 +1,60 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gazta<74>aga 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.
//
/////////////////////////////////////////////////////////////////////////////
//[doc_slist_algorithms_code
#include <boost/intrusive/circular_slist_algorithms.hpp>
#include <cassert>
struct my_node
{
my_node *next_;
//other members...
};
//Define our own slist_node_traits
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; }
};
int main()
{
typedef boost::intrusive::circular_slist_algorithms<my_slist_node_traits> algo;
my_node one, two, three;
//Create an empty singly linked list container:
//"one" will be the first node of the container
algo::init(&one);
assert(algo::count(&one) == 1);
//Now add a new node
algo::link_after(&one, &two);
assert(algo::count(&one) == 2);
//Now add a new node after "one"
algo::link_after(&one, &three);
assert(algo::count(&one) == 3);
//Now unlink the node after one
algo::unlink_after(&one);
assert(algo::count(&one) == 2);
//Now unlink two
algo::unlink(&two);
assert(algo::count(&one) == 1);
return 0;
}
//]

View File

@@ -0,0 +1,110 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gazta<74>aga 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.
//
/////////////////////////////////////////////////////////////////////////////
//[doc_unordered_set_code
#include <boost/intrusive/unordered_set.hpp>
#include <vector>
#include <algorithm>
#include <boost/functional/hash.hpp>
using namespace boost::intrusive;
//This is a derivation hook
class MyClass : public unordered_set_base_hook<>
{
int int_;
public:
//This is a member hook
unordered_set_member_hook<> member_hook_;
MyClass(int i)
: int_(i)
{}
int get() const
{ return int_; }
friend bool operator== (const MyClass &a, const MyClass &b)
{ return a.get() == b.get(); }
friend bool operator> (const MyClass &a, const MyClass &b)
{ return a.get() > b.get(); }
};
std::size_t hash_value(const MyClass &value)
{ return std::size_t(value.get()); }
//Define an unordered_set that will store MyClass
//in reverse order using the public base hook
typedef unordered_set< unordered_set_base_hook<>::
value_traits<MyClass> > BaseSet;
//Define an unordered_multiset that will store MyClass
//using the public member hook
typedef unordered_multiset< unordered_set_member_hook<>::
value_traits<MyClass, &MyClass::member_hook_> > MemberMultiSet;
int main()
{
typedef std::vector<MyClass> Vect;
typedef Vect::iterator VectIt;
typedef Vect::reverse_iterator VectRit;
//Create a vector with 100 different MyClass objects,
//each one with a different internal number
Vect myclassvector;
for(int i = 0; i < 100; ++i)
myclassvector.push_back(MyClass(i));
//Create a copy of the vector
Vect myclassvector2(myclassvector);
//Create a bucket array for base_set
BaseSet::bucket_type base_buckets[100];
//Create a bucket array for member_multi_set
MemberMultiSet::bucket_type member_buckets[200];
//Create a the unordered_set and unordered_multiset,
//taking buckets as arguments
BaseSet base_set(base_buckets, 100);
MemberMultiSet member_multi_set(member_buckets, 200);
//Now insert myclassvector's elements in the unordered_set
for(VectIt it(myclassvector.begin()), itend(myclassvector.end())
; it != itend; ++it){
base_set.insert(*it);
}
//Now insert myclassvector's and myclassvector2's elements in the unordered_multiset
for(VectIt it(myclassvector.begin()), itend(myclassvector.end()),
it2(myclassvector2.begin()),itend2(myclassvector2.end())
; it != itend; ++it, ++it2){
member_multi_set.insert(*it);
member_multi_set.insert(*it2);
}
//Now find every element
{
VectIt it(myclassvector.begin()), itend(myclassvector.end());
for(; it != itend; ++it){
//base_set should contain one element for each key
if(base_set.count(*it) != 1) return 1;
//member_multi_set should contain two elements for each key
if(member_multi_set.count(*it) != 2) return 1;
}
}
return 0;
}
//]

View File

@@ -0,0 +1,99 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gazta<74>aga 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.
//
/////////////////////////////////////////////////////////////////////////////
//[doc_value_traits_code_legacy
#include <boost/intrusive/linking_policy.hpp>
#include <boost/intrusive/list.hpp>
#include <boost/intrusive/slist.hpp>
#include <vector>
//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.
struct legacy_value
{
legacy_value *prev_;
legacy_value *next_;
int id_;
};
//]
//[doc_value_traits_value_traits
//Define our own NodeTraits that will configure singly and doubly linked
//list algorithms. Note that this node traits is compatible with
//circular_slist_algorithms and circular_list_algorithms.
struct legacy_node_traits
{
typedef legacy_value node;
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; }
};
//This ValueTraits will configure list and slist. In this case,
//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
{
typedef legacy_node_traits node_traits;
typedef node_traits::node_ptr node_ptr;
typedef node_traits::const_node_ptr const_node_ptr;
typedef legacy_value value_type;
typedef legacy_value * pointer;
typedef const legacy_value * const_pointer;
enum { linking_policy = boost::intrusive::normal_link };
static node_ptr to_node_ptr (value_type &value) { return node_ptr(&value); }
static const_node_ptr to_node_ptr (const value_type &value) { return const_node_ptr(&value); }
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); }
};
//]
//[doc_value_traits_test
//Now define an intrusive list and slist that will store legacy_value objects
typedef boost::intrusive::list <legacy_value_traits> LegacyAbiList;
typedef boost::intrusive::slist<legacy_value_traits> LegacyAbiSlist;
template<class List>
bool test_list()
{
typedef std::vector<legacy_value> Vect;
//Create legacy_value objects, with a different internal number
Vect legacy_vector;
for(int i = 0; i < 100; ++i){
legacy_value value; value.id_ = i; legacy_vector.push_back(value);
}
//Create the list with the objects
List mylist(legacy_vector.begin(), legacy_vector.end());
//Now test both lists
typename List::const_iterator bit(mylist.begin()), bitend(mylist.end());
typename Vect::const_iterator it(legacy_vector.begin()), itend(legacy_vector.end());
//Test the objects inserted in our list
for(; it != itend; ++it, ++bit){
if(&*bit != &*it) return false;
}
return true;
}
int main()
{
return test_list<LegacyAbiList>() && test_list<LegacyAbiSlist>() ? 0 : 1;
}
//]

85
example/doc_window.cpp Normal file
View File

@@ -0,0 +1,85 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gazta<74>aga 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.
//
/////////////////////////////////////////////////////////////////////////////
//[doc_window_code
#include <boost/intrusive/list.hpp>
using namespace boost::intrusive;
//An abstract class that can be inserted in an intrusive list
class Window : public list_base_hook<>
{
public:
//This is a container those value is an abstract class: you can't do this with std::list.
typedef list< list_base_hook<>::value_traits<Window> > win_list;
//An static intrusive list declaration
static win_list all_windows;
//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::iterator_to(*this)); }
//Pure virtual function to be implemented by derived classes
virtual void Paint() = 0;
};
//The static intrusive list declaration
Window::win_list Window::all_windows;
//Some Window derived classes
class FrameWindow : public Window
{ void Paint(){/**/} };
class EditWindow : public Window
{ void Paint(){/**/} };
class CanvasWindow : public Window
{ void Paint(){/**/} };
//A function that prints all windows stored in the intrusive list
void paint_all_windows()
{
for(Window::win_list::iterator i(Window::all_windows.begin())
, e(Window::all_windows.end())
; i != e; ++i)
i->Paint();
}
//...
//A class derived from Window
class MainWindow : public Window
{
FrameWindow frame_; //these are derived from Window too
EditWindow edit_;
CanvasWindow canvas_;
public:
void Paint(){/**/}
//...
};
//Main function
int main()
{
//When each Window class is created, is
//automatically registered in the global list
MainWindow window;
//Paint all the windows, sub-windows and so on
paint_all_windows();
//All the windows are automatically unregistered
//in their destructors.
return 0;
}
//]

34
perf/Jamfile.v2 Normal file
View File

@@ -0,0 +1,34 @@
# Boost Intrusive Library Performance test Jamfile
# (C) Copyright Ion Gazta<74>aga 2006-2007.
# 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
# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# this rule enumerates through all the sources and invokes
# the run rule for each source, the result is a list of all
# the run rules, which we can pass on to the test_suite rule:
rule test_all
{
local all_rules = ;
for local fileb in [ glob *.cpp ]
{
all_rules += [ run $(fileb)
: # additional args
: # test-files
: # requirements
] ;
}
return $(all_rules) ;
}
test-suite intrusive_perf : [ test_all r ] ;

534
perf/perf_list.cpp Normal file
View File

@@ -0,0 +1,534 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gazta<74>aga 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.
//
/////////////////////////////////////////////////////////////////////////////
//Includes for tests
#include <list>
#include <functional>
#include <iostream>
#include <boost/intrusive/list.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
using namespace boost::posix_time;
//[perf_list_value_type
//Iteration and element count defines
const int NumIter = 100;
const int NumElements = 100000;
using namespace boost::intrusive;
template<bool BigSize>
struct filler { int dummy[10]; };
template <>
struct filler<false> {};
template<bool BigSize> //The object for non-intrusive containers
struct test_class : private filler<BigSize>
{
int i_;
test_class() {}
test_class(int i) : i_(i) {}
friend bool operator <(const test_class &l, const test_class &r) { return l.i_ < r.i_; }
friend bool operator >(const test_class &l, const test_class &r) { return l.i_ > r.i_; }
};
template <bool BigSize, linking_policy Policy> //The object for intrusive containers
struct itest_class : public list_base_hook<tag, Policy>, public test_class<BigSize>
{
itest_class() {}
itest_class(int i) : test_class<BigSize>(i) {}
};
template<class FuncObj> //Adapts functors taking values to functors taking pointers
struct func_ptr_adaptor : public FuncObj
{
typedef typename FuncObj::first_argument_type* first_argument_type;
typedef typename FuncObj::second_argument_type* second_argument_type;
typedef typename FuncObj::result_type result_type;
result_type operator()(first_argument_type a, second_argument_type b) const
{ return FuncObj::operator()(*a, *b); }
};
//]
template <bool BigSize, linking_policy Policy>
struct get_ilist //Helps to define an intrusive list from a policy
{
typedef list_base_hook<tag, Policy> hook;
typedef list<typename hook::template value_traits<itest_class<BigSize, Policy> >, false> type;
};
template <bool BigSize> //Helps to define an std list
struct get_list { typedef std::list<test_class<BigSize> > type; };
template <bool BigSize> //Helps to define an std pointer list
struct get_ptrlist { typedef std::list<test_class<BigSize>*> type; };
////////////////////////////////////////////////////////////////////////
//
// PUSH_BACK
//
////////////////////////////////////////////////////////////////////////
template <bool BigSize, linking_policy Policy>
void test_intrusive_list_push_back()
{
typedef typename get_ilist<BigSize, Policy>::type ilist;
ptime tini = microsec_clock::universal_time();
for(int i = 0; i < NumIter; ++i){
//First create the elements and insert them in the intrusive list
//[perf_list_push_back_intrusive
std::vector<typename ilist::value_type> objects(NumElements);
ilist l;
for(int i = 0; i < NumElements; ++i)
l.push_back(objects[i]);
//Elements are unlinked in ilist's destructor
//Elements are destroyed in vector's destructor
//]
}
ptime tend = microsec_clock::universal_time();
std::cout << "usecs/iteration: " << (tend-tini).total_microseconds()/NumIter << std::endl;
}
template <bool BigSize>
void test_std_list_push_back()
{
typedef typename get_list<BigSize>::type stdlist;
ptime tini = microsec_clock::universal_time();
for(int i = 0; i < NumIter; ++i){
//Now create the std list and insert
//[perf_list_push_back_stdlist
stdlist l;
for(int i = 0; i < NumElements; ++i)
l.push_back(typename stdlist::value_type(i));
//Elements unlinked and destroyed in stdlist's destructor
//]
}
ptime tend = microsec_clock::universal_time();
std::cout << "usecs/iteration: " << (tend-tini).total_microseconds()/NumIter << std::endl;
}
template <bool BigSize>
void test_compact_std_ptrlist_push_back()
{
typedef typename get_list<BigSize>::type stdlist;
typedef typename get_ptrlist<BigSize>::type stdptrlist;
//Now measure insertion time, including element creation
ptime tini = microsec_clock::universal_time();
for(int i = 0; i < NumIter; ++i){
//Create elements and insert their pointer in the list
//[perf_list_push_back_stdptrlist
std::vector<typename stdlist::value_type> objects(NumElements);
stdptrlist l;
for(int i = 0; i < NumElements; ++i)
l.push_back(&objects[i]);
//Pointers to elements unlinked and destroyed in stdptrlist's destructor
//Elements destroyed in vector's destructor
//]
}
ptime tend = microsec_clock::universal_time();
std::cout << "usecs/iteration: " << (tend-tini).total_microseconds()/NumIter << std::endl;
}
template <bool BigSize>
void test_disperse_std_ptrlist_push_back()
{
typedef typename get_list<BigSize>::type stdlist;
typedef typename get_ptrlist<BigSize>::type stdptrlist;
//Now measure insertion time, including element creation
ptime tini = microsec_clock::universal_time();
for(int i = 0; i < NumIter; ++i){
//Create elements and insert their pointer in the list
//[perf_list_push_back_disperse_stdptrlist
stdlist objects; stdptrlist l;
for(int i = 0; i < NumElements; ++i){
objects.push_back(typename stdlist::value_type(i));
l.push_back(&objects.back());
}
//Pointers to elements unlinked and destroyed in stdptrlist's destructor
//Elements unlinked and destroyed in stdlist's destructor
//]
}
ptime tend = microsec_clock::universal_time();
std::cout << "usecs/iteration: " << (tend-tini).total_microseconds()/NumIter << std::endl;
}
////////////////////////////////////////////////////////////////////////
//
// REVERSE
//
////////////////////////////////////////////////////////////////////////
//[perf_list_reverse
template <bool BigSize, linking_policy Policy>
void test_intrusive_list_reverse()
{
typedef typename get_ilist<BigSize, Policy>::type ilist;
//First create the elements
std::vector<typename ilist::value_type> objects(NumElements);
//Now create the intrusive list and insert data
ilist l(objects.begin(), objects.end());
//Now measure sorting time
ptime tini = microsec_clock::universal_time();
for(int i = 0; i < NumIter; ++i){
l.reverse();
}
ptime tend = microsec_clock::universal_time();
std::cout << "usecs/iteration: " << (tend-tini).total_microseconds()/NumIter << std::endl;
}
template <bool BigSize>
void test_std_list_reverse()
{
typedef typename get_list<BigSize>::type stdlist;
//Create the list and insert values
stdlist l;
for(int i = 0; i < NumElements; ++i)
l.push_back(typename stdlist::value_type());
//Now measure sorting time
ptime tini = microsec_clock::universal_time();
for(int i = 0; i < NumIter; ++i){
l.reverse();
}
ptime tend = microsec_clock::universal_time();
std::cout << "usecs/iteration: " << (tend-tini).total_microseconds()/NumIter << std::endl;
}
template <bool BigSize>
void test_compact_std_ptrlist_reverse()
{
typedef typename get_list<BigSize>::type stdlist;
typedef typename get_ptrlist<BigSize>::type stdptrlist;
//First create the elements
std::vector<typename stdlist::value_type> objects(NumElements);
//Now create the std list and insert
stdptrlist l;
for(int i = 0; i < NumElements; ++i)
l.push_back(&objects[i]);
//Now measure sorting time
ptime tini = microsec_clock::universal_time();
for(int i = 0; i < NumIter; ++i){
l.reverse();
}
ptime tend = microsec_clock::universal_time();
std::cout << "usecs/iteration: " << (tend-tini).total_microseconds()/NumIter << std::endl;
}
template <bool BigSize>
void test_disperse_std_ptrlist_reverse()
{
typedef typename get_list<BigSize>::type stdlist;
typedef typename get_ptrlist<BigSize>::type stdptrlist;
//First create the elements
std::list<typename stdlist::value_type> objects;
//Now create the std list and insert
stdptrlist l;
for(int i = 0; i < NumElements; ++i){
objects.push_back(typename stdlist::value_type());
l.push_back(&objects.back());
}
//Now measure sorting time
ptime tini = microsec_clock::universal_time();
for(int i = 0; i < NumIter; ++i){
l.reverse();
}
ptime tend = microsec_clock::universal_time();
std::cout << "usecs/iteration: " << (tend-tini).total_microseconds()/NumIter << std::endl;
}
//]
////////////////////////////////////////////////////////////////////////
//
// SORT
//
////////////////////////////////////////////////////////////////////////
//[perf_list_sort
template <bool BigSize, linking_policy Policy>
void test_intrusive_list_sort()
{
typedef typename get_ilist<BigSize, Policy>::type ilist;
//First create the elements
std::vector<typename ilist::value_type> objects(NumElements);
for(int i = 0; i < NumElements; ++i)
objects[i].i_ = i;
//Now create the intrusive list and insert data
ilist l(objects.begin(), objects.end());
//Now measure sorting time
ptime tini = microsec_clock::universal_time();
for(int i = 0; i < NumIter; ++i){
if(!(i % 2)){
l.sort(std::greater<typename ilist::value_type>());
}
else{
l.sort(std::less<typename ilist::value_type>());
}
}
ptime tend = microsec_clock::universal_time();
std::cout << "usecs/iteration: " << (tend-tini).total_microseconds()/NumIter << std::endl;
}
template <bool BigSize>
void test_std_list_sort()
{
typedef typename get_list<BigSize>::type stdlist;
//Create the list and insert values
stdlist l;
for(int i = 0; i < NumElements; ++i)
l.push_back(typename stdlist::value_type(i));
//Now measure sorting time
ptime tini = microsec_clock::universal_time();
for(int i = 0; i < NumIter; ++i){
if(!(i % 2)){
l.sort(std::greater<typename stdlist::value_type>());
}
else{
l.sort(std::less<typename stdlist::value_type>());
}
}
ptime tend = microsec_clock::universal_time();
std::cout << "usecs/iteration: " << (tend-tini).total_microseconds()/NumIter << std::endl;
}
template <bool BigSize>
void test_compact_std_ptrlist_sort()
{
typedef typename get_list<BigSize>::type stdlist;
typedef typename get_ptrlist<BigSize>::type stdptrlist;
//First create the elements
std::vector<typename stdlist::value_type> objects(NumElements);
for(int i = 0; i < NumElements; ++i)
objects[i].i_ = i;
//Now create the std list and insert
stdptrlist l;
for(int i = 0; i < NumElements; ++i)
l.push_back(&objects[i]);
//Now measure sorting time
ptime tini = microsec_clock::universal_time();
for(int i = 0; i < NumIter; ++i){
if(!(i % 2)){
l.sort(func_ptr_adaptor<std::greater<typename stdlist::value_type> >());
}
else{
l.sort(func_ptr_adaptor<std::less<typename stdlist::value_type> >());
}
}
ptime tend = microsec_clock::universal_time();
std::cout << "usecs/iteration: " << (tend-tini).total_microseconds()/NumIter << std::endl;
}
template <bool BigSize>
void test_disperse_std_ptrlist_sort()
{
typedef typename get_list<BigSize>::type stdlist;
typedef typename get_ptrlist<BigSize>::type stdptrlist;
//First create the elements and the list
std::list<typename stdlist::value_type> objects;
stdptrlist l;
for(int i = 0; i < NumElements; ++i){
objects.push_back(typename stdlist::value_type(i));
l.push_back(&objects.back());
}
//Now measure sorting time
ptime tini = microsec_clock::universal_time();
for(int i = 0; i < NumIter; ++i){
if(!(i % 2)){
l.sort(func_ptr_adaptor<std::greater<typename stdlist::value_type> >());
}
else{
l.sort(func_ptr_adaptor<std::less<typename stdlist::value_type> >());
}
}
ptime tend = microsec_clock::universal_time();
std::cout << "usecs/iteration: " << (tend-tini).total_microseconds()/NumIter << std::endl;
}
//]
////////////////////////////////////////////////////////////////////////
//
// WRITE ACCESS
//
////////////////////////////////////////////////////////////////////////
//[perf_list_write_access
template <bool BigSize, linking_policy Policy>
void test_intrusive_list_write_access()
{
typedef typename get_ilist<BigSize, Policy>::type ilist;
//First create the elements
std::vector<typename ilist::value_type> objects(NumElements);
for(int i = 0; i < NumElements; ++i){
objects[i].i_ = i;
}
//Now create the intrusive list and insert data
ilist l(objects.begin(), objects.end());
//Now measure access time to the value type
ptime tini = microsec_clock::universal_time();
for(int i = 0; i < NumIter; ++i){
typename ilist::iterator it(l.begin()), end(l.end());
for(; it != end; ++it){
++(it->i_);
}
}
ptime tend = microsec_clock::universal_time();
std::cout << "usecs/iteration: " << (tend-tini).total_microseconds()/NumIter << std::endl;
}
template <bool BigSize>
void test_std_list_write_access()
{
typedef typename get_list<BigSize>::type stdlist;
//Create the list and insert values
stdlist l;
for(int i = 0; i < NumElements; ++i)
l.push_back(typename stdlist::value_type(i));
//Now measure access time to the value type
ptime tini = microsec_clock::universal_time();
for(int i = 0; i < NumIter; ++i){
typename stdlist::iterator it(l.begin()), end(l.end());
for(; it != end; ++it){
++(it->i_);
}
}
ptime tend = microsec_clock::universal_time();
std::cout << "usecs/iteration: " << (tend-tini).total_microseconds()/NumIter << std::endl;
}
template <bool BigSize>
void test_compact_std_ptrlist_write_access()
{
typedef typename get_list<BigSize>::type stdlist;
typedef typename get_ptrlist<BigSize>::type stdptrlist;
//First create the elements
std::vector<typename stdlist::value_type> objects(NumElements);
for(int i = 0; i < NumElements; ++i){
objects[i].i_ = i;
}
//Now create the std list and insert
stdptrlist l;
for(int i = 0; i < NumElements; ++i)
l.push_back(&objects[i]);
//Now measure access time to the value type
ptime tini = microsec_clock::universal_time();
for(int i = 0; i < NumIter; ++i){
typename stdptrlist::iterator it(l.begin()), end(l.end());
for(; it != end; ++it){
++((*it)->i_);
}
}
ptime tend = microsec_clock::universal_time();
std::cout << "usecs/iteration: " << (tend-tini).total_microseconds()/NumIter << std::endl;
}
template <bool BigSize>
void test_disperse_std_ptrlist_write_access()
{
typedef typename get_list<BigSize>::type stdlist;
typedef typename get_ptrlist<BigSize>::type stdptrlist;
//First create the elements
std::list<typename stdlist::value_type> objects;
//Now create the std list and insert
stdptrlist l;
for(int i = 0; i < NumElements; ++i){
objects.push_back(typename stdlist::value_type(i));
l.push_back(&objects.back());
}
//Now measure access time to the value type
ptime tini = microsec_clock::universal_time();
for(int i = 0; i < NumIter; ++i){
typename stdptrlist::iterator it(l.begin()), end(l.end());
for(; it != end; ++it){
++((*it)->i_);
}
}
ptime tend = microsec_clock::universal_time();
std::cout << "usecs/iteration: " << (tend-tini).total_microseconds()/NumIter << std::endl;
}
//]
////////////////////////////////////////////////////////////////////////
//
// ALL TESTS
//
////////////////////////////////////////////////////////////////////////
template<bool BigSize>
void do_all_tests()
{
std::cout << "Testing push back() with BigSize:" << BigSize << std::endl;
test_intrusive_list_push_back<BigSize, normal_link>();
test_intrusive_list_push_back<BigSize, safe_link>();
test_intrusive_list_push_back<BigSize, auto_unlink>();
test_std_list_push_back<BigSize> ();
test_compact_std_ptrlist_push_back<BigSize>();
test_disperse_std_ptrlist_push_back<BigSize>();
//reverse
std::cout << "Testing reverse() with BigSize:" << BigSize << std::endl;
test_intrusive_list_reverse<BigSize, normal_link>();
test_intrusive_list_reverse<BigSize, safe_link>();
test_intrusive_list_reverse<BigSize, auto_unlink>();
test_std_list_reverse<BigSize>();
test_compact_std_ptrlist_reverse<BigSize>();
test_disperse_std_ptrlist_reverse<BigSize>();
//sort
std::cout << "Testing sort() with BigSize:" << BigSize << std::endl;
test_intrusive_list_sort<BigSize, normal_link>();
test_intrusive_list_sort<BigSize, safe_link>();
test_intrusive_list_sort<BigSize, auto_unlink>();
test_std_list_sort<BigSize>();
test_compact_std_ptrlist_sort<BigSize>();
test_disperse_std_ptrlist_sort<BigSize>();
//write_access
std::cout << "Testing write_access() with BigSize:" << BigSize << std::endl;
test_intrusive_list_write_access<BigSize, normal_link>();
test_intrusive_list_write_access<BigSize, safe_link>();
test_intrusive_list_write_access<BigSize, auto_unlink>();
test_std_list_write_access<BigSize>();
test_compact_std_ptrlist_write_access<BigSize>();
test_disperse_std_ptrlist_write_access<BigSize>();
}
int main()
{
//First pass the tests with a small size class
do_all_tests<false>();
//Now pass the tests with a big size class
do_all_tests<true>();
return 0;
}

71
proj/vc7ide/Intrusive.sln Normal file
View File

@@ -0,0 +1,71 @@
Microsoft Visual Studio Solution File, Format Version 8.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "list", "list\list.vcproj", "{977B61B4-9968-497C-9F0B-24A8145473B8}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "slist", "slist\slist.vcproj", "{5A02061D-3728-4C49-AFC8-0130C1F161C0}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "multiset", "multiset\multiset.vcproj", "{961F0E06-C092-4AF7-ABC5-2A49999F3B79}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_intrusivelib", "_intrusivelib\_intrusivelib.vcproj", "{90F3C5BD-8E6C-4629-BC71-A1009EC88059}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "set", "set\set.vcproj", "{960E01F6-92C1-F74A-BCA5-2A9F3B994979}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unordered_set", "unordered_set\unordered_set.vcproj", "{90E701E6-2C91-F4A7-BA6C-A9F3B0949279}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unordered_multiset", "unordered_multiset\unordered_multiset.vcproj", "{9101EE76-BB6C-2C91-F4B7-A9F3B9490279}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
Release = Release
EndGlobalSection
GlobalSection(ProjectDependencies) = postSolution
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{977B61B4-9968-497C-9F0B-24A8145473B8}.Debug.ActiveCfg = Debug|Win32
{977B61B4-9968-497C-9F0B-24A8145473B8}.Debug.Build.0 = Debug|Win32
{977B61B4-9968-497C-9F0B-24A8145473B8}.Release.ActiveCfg = Release|Win32
{977B61B4-9968-497C-9F0B-24A8145473B8}.Release.Build.0 = Release|Win32
{5A02061D-3728-4C49-AFC8-0130C1F161C0}.Debug.ActiveCfg = Debug|Win32
{5A02061D-3728-4C49-AFC8-0130C1F161C0}.Debug.Build.0 = Debug|Win32
{5A02061D-3728-4C49-AFC8-0130C1F161C0}.Release.ActiveCfg = Release|Win32
{5A02061D-3728-4C49-AFC8-0130C1F161C0}.Release.Build.0 = Release|Win32
{961F0E06-C092-4AF7-ABC5-2A49999F3B79}.Debug.ActiveCfg = Debug|Win32
{961F0E06-C092-4AF7-ABC5-2A49999F3B79}.Debug.Build.0 = Debug|Win32
{961F0E06-C092-4AF7-ABC5-2A49999F3B79}.Release.ActiveCfg = Release|Win32
{961F0E06-C092-4AF7-ABC5-2A49999F3B79}.Release.Build.0 = Release|Win32
{90F3C5BD-8E6C-4629-BC71-A1009EC88059}.Debug.ActiveCfg = Debug|Win32
{90F3C5BD-8E6C-4629-BC71-A1009EC88059}.Debug.Build.0 = Debug|Win32
{90F3C5BD-8E6C-4629-BC71-A1009EC88059}.Release.ActiveCfg = Release|Win32
{90F3C5BD-8E6C-4629-BC71-A1009EC88059}.Release.Build.0 = Release|Win32
{960E01F6-92C1-F74A-BCA5-2A9F3B994979}.Debug.ActiveCfg = Debug|Win32
{960E01F6-92C1-F74A-BCA5-2A9F3B994979}.Debug.Build.0 = Debug|Win32
{960E01F6-92C1-F74A-BCA5-2A9F3B994979}.Release.ActiveCfg = Release|Win32
{960E01F6-92C1-F74A-BCA5-2A9F3B994979}.Release.Build.0 = Release|Win32
{90E701E6-2C91-F4A7-BA6C-A9F3B0949279}.Debug.ActiveCfg = Debug|Win32
{90E701E6-2C91-F4A7-BA6C-A9F3B0949279}.Debug.Build.0 = Debug|Win32
{90E701E6-2C91-F4A7-BA6C-A9F3B0949279}.Release.ActiveCfg = Release|Win32
{90E701E6-2C91-F4A7-BA6C-A9F3B0949279}.Release.Build.0 = Release|Win32
{9101EE76-BB6C-2C91-F4B7-A9F3B9490279}.Debug.ActiveCfg = Debug|Win32
{9101EE76-BB6C-2C91-F4B7-A9F3B9490279}.Debug.Build.0 = Debug|Win32
{9101EE76-BB6C-2C91-F4B7-A9F3B9490279}.Release.ActiveCfg = Release|Win32
{9101EE76-BB6C-2C91-F4B7-A9F3B9490279}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,129 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="list"
ProjectGUID="{B1F70826-C6CF-47EF-B7C9-FC9C8BB63A79}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/Intrusive.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/Intrusive.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="4"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/Intrusive.exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,294 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="_intrusivelib"
ProjectGUID="{90F3C5BD-8E6C-4629-BC71-A1009EC88059}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="4"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/_intrusivelib.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="4"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="4"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/_intrusivelib.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Jamfile"
Filter=""
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath="..\..\..\test\Jamfile.v2">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
<File
RelativePath="..\..\..\..\..\boost\intrusive\circular_list_algorithms.hpp">
</File>
<File
RelativePath="..\..\..\..\..\boost\intrusive\circular_slist_algorithms.hpp">
</File>
<File
RelativePath="..\..\..\..\..\boost\intrusive\hashtable.hpp">
</File>
<File
RelativePath="..\..\..\..\..\boost\intrusive\intrusive_fwd.hpp">
</File>
<File
RelativePath="..\..\..\..\..\boost\intrusive\linking_policy.hpp">
</File>
<File
RelativePath="..\..\..\..\..\boost\intrusive\list.hpp">
</File>
<File
RelativePath="..\..\..\..\..\boost\intrusive\list_hook.hpp">
</File>
<File
RelativePath="..\..\..\..\..\boost\intrusive\pointer_plus_bit.hpp">
</File>
<File
RelativePath="..\..\..\..\..\boost\intrusive\rbtree.hpp">
</File>
<File
RelativePath="..\..\..\..\..\boost\intrusive\rbtree_algorithms.hpp">
</File>
<File
RelativePath="..\..\..\..\..\boost\intrusive\set.hpp">
</File>
<File
RelativePath="..\..\..\..\..\boost\intrusive\set_hook.hpp">
</File>
<File
RelativePath="..\..\..\..\..\boost\intrusive\slist.hpp">
</File>
<File
RelativePath="..\..\..\..\..\boost\intrusive\slist_hook.hpp">
</File>
<File
RelativePath="..\..\..\..\..\boost\intrusive\tag.hpp">
</File>
<File
RelativePath="..\..\..\..\..\boost\intrusive\unordered_set.hpp">
</File>
<File
RelativePath="..\..\..\..\..\boost\intrusive\unordered_set_hook.hpp">
</File>
<Filter
Name="detail"
Filter="">
<File
RelativePath="..\..\..\..\..\boost\intrusive\detail\config_begin.hpp">
</File>
<File
RelativePath="..\..\..\..\..\boost\intrusive\detail\config_end.hpp">
</File>
<File
RelativePath="..\..\..\..\..\boost\intrusive\detail\ebo_holder.hpp">
</File>
<File
RelativePath="..\..\..\..\..\boost\intrusive\detail\hashtable_node.hpp">
</File>
<File
RelativePath="..\..\..\..\..\boost\intrusive\detail\pointed_node.hpp">
</File>
<File
RelativePath="..\..\..\..\..\boost\intrusive\detail\parent_from_member.hpp">
</File>
<File
RelativePath="..\..\..\..\..\boost\intrusive\detail\pointer_to_other.hpp">
</File>
<File
RelativePath="..\..\..\..\..\boost\intrusive\detail\pointer_type.hpp">
</File>
<File
RelativePath="..\..\..\..\..\boost\intrusive\detail\rbtree_node.hpp">
</File>
<File
RelativePath="..\..\..\..\..\boost\intrusive\detail\slist_node.hpp">
</File>
<File
RelativePath="..\..\..\..\..\boost\intrusive\detail\utilities.hpp">
</File>
</Filter>
</Filter>
<Filter
Name="doc"
Filter="">
<File
RelativePath="..\..\..\doc\intrusive.qbk">
</File>
<File
RelativePath="..\..\..\doc\Jamfile.v2">
</File>
</Filter>
<Filter
Name="Test headers"
Filter="">
<File
RelativePath="..\..\..\test\common_functors.hpp">
</File>
<File
RelativePath="..\..\..\test\itestvalue.hpp">
</File>
<File
RelativePath="..\..\..\test\smart_ptr.hpp">
</File>
<File
RelativePath="..\..\..\test\test_container.hpp">
</File>
</Filter>
<Filter
Name="example"
Filter="">
<File
RelativePath="..\..\..\example\doc_advanced_value_traits.cpp">
</File>
<File
RelativePath="..\..\..\example\doc_assoc_optimized_code.cpp">
</File>
<File
RelativePath="..\..\..\example\doc_auto_unlink.cpp">
</File>
<File
RelativePath="..\..\..\example\doc_clone_from.cpp">
</File>
<File
RelativePath="..\..\..\example\doc_entity.cpp">
</File>
<File
RelativePath="..\..\..\example\doc_erasing_and_destroying.cpp">
</File>
<File
RelativePath="..\..\..\example\doc_how_to_use.cpp">
</File>
<File
RelativePath="..\..\..\example\doc_iterator_from_value.cpp">
</File>
<File
RelativePath="..\..\..\example\doc_list.cpp">
</File>
<File
RelativePath="..\..\..\example\doc_list_algorithms.cpp">
</File>
<File
RelativePath="..\..\..\example\doc_offset_ptr.cpp">
</File>
<File
RelativePath="..\..\..\example\doc_rbtree_algorithms.cpp">
</File>
<File
RelativePath="..\..\..\example\doc_set.cpp">
</File>
<File
RelativePath="..\..\..\example\doc_slist.cpp">
</File>
<File
RelativePath="..\..\..\example\doc_slist_algorithms.cpp">
</File>
<File
RelativePath="..\..\..\example\doc_unordered_set.cpp">
</File>
<File
RelativePath="..\..\..\example\doc_value_traits.cpp">
</File>
<File
RelativePath="..\..\..\example\doc_window.cpp">
</File>
</Filter>
<Filter
Name="perf"
Filter="">
<File
RelativePath="..\..\..\perf\perf_list.cpp">
</File>
</Filter>
<File
RelativePath="..\to-do.txt">
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,135 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="list"
ProjectGUID="{977B61B4-9968-497C-9F0B-24A8145473B8}"
RootNamespace="list"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../../../"
PreprocessorDefinitions="BOOST_DATE_TIME_NO_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/list.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/list.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../../../"
PreprocessorDefinitions="BOOST_DATE_TIME_NO_LIB"
RuntimeLibrary="4"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/list.exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath="..\..\..\test\list_test.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,134 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="multiset"
ProjectGUID="{961F0E06-C092-4AF7-ABC5-2A49999F3B79}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../../../"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/multiset.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/multiset.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../../../"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
RuntimeLibrary="4"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/multiset.exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath="..\..\..\test\multiset_test.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

134
proj/vc7ide/set/set.vcproj Normal file
View File

@@ -0,0 +1,134 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="set"
ProjectGUID="{960E01F6-92C1-F74A-BCA5-2A9F3B994979}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../../../"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/set.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/set.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../../../"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="4"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/set.exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4F73C7F1-C745-4726-06A6-2D752AA322FF}">
<File
RelativePath="..\..\..\test\set_test.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{68007AB6-FDA6800-084c-B78A-8121AA3BBD01}">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,134 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="slist"
ProjectGUID="{5A02061D-3728-4C49-AFC8-0130C1F161C0}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../../../"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/slist.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/slist.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../../../"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="4"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/slist.exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath="..\..\..\test\slist_test.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,134 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="unordered_multiset"
ProjectGUID="{9101EE76-BB6C-2C91-F4B7-A9F3B9490279}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../../../"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/unordered_multiset.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/unordered_multiset.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../../../"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="4"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/unordered_multiset.exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4F3C77F1-B78A-C745-4726-2D752AA322FF}">
<File
RelativePath="..\..\..\test\unordered_multiset_test.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{99954380-9C8D-084c-4b04-62E52E6FBBFB}">
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{6A181B76-FDA6800-8E8B-0A66-813A3BB1AD01}">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,134 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="unordered_set"
ProjectGUID="{90E701E6-2C91-F4A7-BA6C-A9F3B0949279}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../../../"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/unordered_set.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/unordered_set.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../../../"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="4"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/unordered_set.exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4F3C77F1-B78A-C745-4726-2D752AA322FF}">
<File
RelativePath="..\..\..\test\unordered_set_test.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{68AB0076-FDA6800-084c-06A6-8121AA3BBD01}">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

34
test/Jamfile.v2 Normal file
View File

@@ -0,0 +1,34 @@
# Boost Intrusive Library Test Jamfile
# (C) Copyright Ion Gazta<74>aga 2006.
# 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
# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# this rule enumerates through all the sources and invokes
# the run rule for each source, the result is a list of all
# the run rules, which we can pass on to the test_suite rule:
rule test_all
{
local all_rules = ;
for local fileb in [ glob *.cpp ]
{
all_rules += [ run $(fileb)
: # additional args
: # test-files
: # requirements
] ;
}
return $(all_rules) ;
}
test-suite intrusive_test : [ test_all r ] ;

43
test/common_functors.hpp Normal file
View File

@@ -0,0 +1,43 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gazta<74>aga 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.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_TEST_COMMON_FUNCTORS_HPP
#define BOOST_INTRUSIVE_TEST_COMMON_FUNCTORS_HPP
namespace boost {
namespace intrusive {
namespace test {
class delete_destroyer
{
public:
template <class Pointer>
void operator()(Pointer p)
{
using boost::get_pointer;
delete get_pointer(p);
}
};
class new_cloner
{
public:
template<class Type>
Type *operator()(const Type &t)
{ return new Type(t); }
};
} //namespace test {
} //namespace intrusive {
} //namespace boost {
#endif

338
test/itestvalue.hpp Normal file
View File

@@ -0,0 +1,338 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gazta<74>aga 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.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_ITESTVALUE
#define BOOST_INTRUSIVE_ITESTVALUE
#ifdef _MSC_VER
//#pragma warning(disable : 4584)
#endif
#include <iostream>
#include <boost/intrusive/set.hpp>
#include <boost/intrusive/list.hpp>
#include <boost/intrusive/slist.hpp>
#include <boost/intrusive/unordered_set.hpp>
#include <boost/intrusive/detail/pointer_to_other.hpp>
#include <boost/functional/hash.hpp>
#include "smart_ptr.hpp"
namespace boost{
namespace intrusive{
template<class VoidPointer, bool ConstantTimeSize>
struct testvalue
: set_base_hook<tag, safe_link, VoidPointer>
, set_base_hook<tag, auto_unlink, VoidPointer>
, unordered_set_base_hook<tag, safe_link, VoidPointer>
, unordered_set_base_hook<tag, auto_unlink, VoidPointer>
, list_base_hook<tag, safe_link, VoidPointer>
, list_base_hook<tag, auto_unlink, VoidPointer>
, slist_base_hook<tag, safe_link, VoidPointer>
, slist_base_hook<tag, auto_unlink, VoidPointer>
{
typedef set_base_hook<tag, auto_unlink, VoidPointer> set_auto_base_hook;
typedef set_base_hook<tag, safe_link, VoidPointer>set_base_hook;
typedef set_member_hook<auto_unlink, VoidPointer> set_auto_member_hook;
typedef set_member_hook<safe_link, VoidPointer> set_member_hook;
typedef unordered_set_base_hook<tag, auto_unlink, VoidPointer> unordered_set_auto_base_hook;
typedef unordered_set_base_hook<tag, safe_link, VoidPointer> unordered_set_base_hook;
typedef unordered_set_member_hook<auto_unlink, VoidPointer> unordered_set_auto_member_hook;
typedef unordered_set_member_hook<safe_link, VoidPointer> unordered_set_member_hook;
typedef list_base_hook<tag, auto_unlink, VoidPointer> list_auto_base_hook;
typedef list_base_hook<tag, safe_link, VoidPointer> list_base_hook;
typedef list_member_hook<auto_unlink, VoidPointer> list_auto_member_hook;
typedef list_member_hook<safe_link, VoidPointer> list_member_hook;
typedef slist_base_hook<tag, auto_unlink, VoidPointer> slist_auto_base_hook;
typedef slist_base_hook<tag, safe_link, VoidPointer> slist_base_hook;
typedef slist_member_hook<auto_unlink, VoidPointer> slist_auto_member_hook;
typedef slist_member_hook<safe_link, VoidPointer> slist_member_hook;
typedef typename boost::pointer_to_other
<VoidPointer, testvalue>::type pointer;
//Set members
//pointer set_parent_, set_left_, set_right_;
//int set_color_;
set_member_hook set_node_;
set_auto_member_hook set_auto_node_;
unordered_set_member_hook unordered_set_node_;
unordered_set_auto_member_hook unordered_set_auto_node_;
//List members
//pointer list_next_, list_prev_;
list_member_hook list_node_;
list_auto_member_hook list_auto_node_;
//Slist members
//pointer slist_next_;
slist_member_hook slist_node_;
slist_auto_member_hook slist_auto_node_;
int value_;
enum{ constant_time_size = ConstantTimeSize };
testvalue()
{}
testvalue(int i)
: value_(i)
{}
testvalue (const testvalue& src)
: value_ (src.value_)
{}
// testvalue is used in std::vector and thus prev and next
// have to be handled appropriately when copied:
testvalue & operator= (const testvalue& src)
{
set_base_hook::operator=(src);
this->set_node_ = src.set_node_;
set_auto_base_hook::operator=(src);
this->set_auto_node_ = src.set_auto_node_;
unordered_set_base_hook::operator=(src);
this->unordered_set_node_ = src.unordered_set_node_;
unordered_set_auto_base_hook::operator=(src);
this->unordered_set_auto_node_ = src.unordered_set_auto_node_;
list_base_hook::operator=(src);
this->list_node_ = src.list_node_;
list_auto_base_hook::operator=(src);
this->list_auto_node_ = src.list_auto_node_;
slist_base_hook::operator=(src);
this->slist_node_ = src.slist_node_;
slist_auto_base_hook::operator=(src);
this->slist_auto_node_ = src.slist_auto_node_;
value_ = src.value_;
return *this;
}
void swap_nodes(testvalue &other)
{
//Set has no swapping
//...
//List
list_base_hook::swap_nodes(other);
list_node_.swap_nodes(other.list_node_);
list_auto_base_hook::swap_nodes(other);
list_auto_node_.swap_nodes(other.list_auto_node_);
//Slist
slist_base_hook::swap_nodes(other);
slist_node_.swap_nodes(other.slist_node_);
slist_auto_base_hook::swap_nodes(other);
slist_auto_node_.swap_nodes(other.slist_auto_node_);
}
~testvalue()
{}
bool operator< (const testvalue &other) const
{ return value_ < other.value_; }
bool operator==(const testvalue &other) const
{ return value_ == other.value_; }
};
template<class VoidPointer, bool ConstantTimeSize>
std::size_t hash_value(const testvalue<VoidPointer, ConstantTimeSize> &t)
{
boost::hash<int> hasher;
return hasher(t.value_);
}
template<class VoidPointer, bool constant_time_size>
std::ostream& operator<<
(std::ostream& s, const testvalue<VoidPointer, constant_time_size>& t)
{ return s << t.value_; }
struct even_odd
{
template<class VoidPointer, bool constant_time_size>
bool operator()
(const testvalue<VoidPointer, constant_time_size>& v1
,const testvalue<VoidPointer, constant_time_size>& v2) const
{
if ((v1.value_ & 1) == (v2.value_ & 1))
return v1.value_ < v2.value_;
else
return v2.value_ & 1;
}
};
typedef testvalue<void *, false> value_r_f;
typedef testvalue<smart_ptr<void>, false> value_s_f;
typedef testvalue<void *, true> value_r_t;
typedef testvalue<smart_ptr<void>, true> value_s_t;
//Typedefs
typedef value_r_f::set_base_hook::
value_traits<value_r_f > set_base_raw;
typedef value_r_f::set_member_hook::
value_traits<value_r_f, &value_r_f::set_node_> set_member_raw;
typedef value_r_f::set_auto_base_hook::
value_traits<value_r_f> set_auto_base_raw;
typedef value_r_f::set_auto_member_hook::
value_traits<value_r_f, &value_r_f::set_auto_node_> set_auto_member_raw;
typedef value_s_f::set_base_hook::
value_traits<value_s_f > set_base_smart;
typedef value_s_f::set_member_hook::
value_traits<value_s_f, &value_s_f::set_node_> set_member_smart;
typedef value_s_f::set_auto_base_hook::
value_traits<value_s_f> set_auto_base_smart;
typedef value_s_f::set_auto_member_hook::
value_traits<value_s_f, &value_s_f::set_auto_node_> set_auto_member_smart;
typedef value_r_t::set_base_hook::
value_traits<value_r_t > set_base_raw_t;
typedef value_r_t::set_member_hook::
value_traits<value_r_t, &value_r_t::set_node_> set_member_raw_t;
typedef value_s_t::set_base_hook::
value_traits<value_s_t > set_base_smart_t;
typedef value_s_t::set_member_hook::
value_traits<value_s_t, &value_s_t::set_node_> set_member_smart_t;
//Typedefs
typedef value_r_f::unordered_set_base_hook::
value_traits<value_r_f > unordered_set_base_raw;
typedef value_r_f::unordered_set_member_hook::
value_traits<value_r_f, &value_r_f::unordered_set_node_> unordered_set_member_raw;
typedef value_r_f::unordered_set_auto_base_hook::
value_traits<value_r_f> unordered_set_auto_base_raw;
typedef value_r_f::unordered_set_auto_member_hook::
value_traits<value_r_f, &value_r_f::unordered_set_auto_node_> unordered_set_auto_member_raw;
typedef value_s_f::unordered_set_base_hook::
value_traits<value_s_f > unordered_set_base_smart;
typedef value_s_f::unordered_set_member_hook::
value_traits<value_s_f, &value_s_f::unordered_set_node_> unordered_set_member_smart;
typedef value_s_f::unordered_set_auto_base_hook::
value_traits<value_s_f> unordered_set_auto_base_smart;
typedef value_s_f::unordered_set_auto_member_hook::
value_traits<value_s_f, &value_s_f::unordered_set_auto_node_> unordered_set_auto_member_smart;
typedef value_r_t::unordered_set_base_hook::
value_traits<value_r_t > unordered_set_base_raw_t;
typedef value_r_t::unordered_set_member_hook::
value_traits<value_r_t, &value_r_t::unordered_set_node_> unordered_set_member_raw_t;
typedef value_s_t::unordered_set_base_hook::
value_traits<value_s_t > unordered_set_base_smart_t;
typedef value_s_t::unordered_set_member_hook::
value_traits<value_s_t, &value_s_t::unordered_set_node_> unordered_set_member_smart_t;
//Explicit instantiations
typedef value_r_f::list_base_hook::
value_traits<value_r_f> list_base_raw;
typedef value_r_f::list_member_hook::
value_traits<value_r_f, &value_r_f::list_node_> list_member_raw;
typedef value_r_f::list_auto_base_hook::
value_traits<value_r_f> list_auto_base_raw;
typedef value_r_f::list_auto_member_hook::
value_traits<value_r_f, &value_r_f::list_auto_node_> list_auto_member_raw;
typedef value_s_f::list_base_hook::
value_traits<value_s_f> list_base_smart;
typedef value_s_f::list_member_hook::
value_traits<value_s_f, &value_s_f::list_node_> list_member_smart;
typedef value_s_f::list_auto_base_hook::
value_traits<value_s_f> list_auto_base_smart;
typedef value_s_f::list_auto_member_hook::
value_traits<value_s_f, &value_s_f::list_auto_node_> list_auto_member_smart;
typedef value_r_t::list_base_hook::
value_traits<value_r_t> list_base_raw_t;
typedef value_r_t::list_member_hook::
value_traits<value_r_t, &value_r_t::list_node_> list_member_raw_t;
typedef value_s_t::list_base_hook::
value_traits<value_s_t> list_base_smart_t;
typedef value_s_t::list_member_hook::
value_traits<value_s_t, &value_s_t::list_node_> list_member_smart_t;
typedef value_r_f::slist_base_hook::
value_traits<value_r_f> slist_base_raw;
typedef value_r_f::slist_member_hook::
value_traits<value_r_f, &value_r_f::slist_node_> slist_member_raw;
typedef value_r_f::slist_auto_base_hook::
value_traits<value_r_f> slist_auto_base_raw;
typedef value_r_f::slist_auto_member_hook::
value_traits<value_r_f, &value_r_f::slist_auto_node_> slist_auto_member_raw;
typedef value_s_f::slist_base_hook::
value_traits<value_s_f> slist_base_smart;
typedef value_s_f::slist_member_hook::
value_traits<value_s_f, &value_s_f::slist_node_> slist_member_smart;
typedef value_s_f::slist_auto_base_hook::
value_traits<value_s_f> slist_auto_base_smart;
typedef value_s_f::slist_auto_member_hook::
value_traits<value_s_f, &value_s_f::slist_auto_node_> slist_auto_member_smart;
typedef value_r_t::slist_base_hook::
value_traits<value_r_t> slist_base_raw_t;
typedef value_r_t::slist_member_hook::
value_traits<value_r_t, &value_r_t::slist_node_> slist_member_raw_t;
typedef value_s_t::slist_base_hook::
value_traits<value_s_t> slist_base_smart_t;
typedef value_s_t::slist_member_hook::
value_traits<value_s_t, &value_s_t::slist_node_> slist_member_smart_t;
} //namespace boost{
} //namespace intrusive{
#endif

376
test/list_test.cpp Normal file
View File

@@ -0,0 +1,376 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gazta<74>aga 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/list.hpp>
#include <boost/intrusive/detail/pointer_to_other.hpp>
#include "itestvalue.hpp"
#include "smart_ptr.hpp"
#include "common_functors.hpp"
#include <vector>
#include <boost/intrusive/linking_policy.hpp>
// Boost.Test
#include "boost/test/included/test_exec_monitor.hpp"
using namespace boost::intrusive;
template<class ValueTraits>
struct test_list
{
typedef typename ValueTraits::value_type value_type;
static void test_all(std::vector<value_type>& values);
static void test_front_back(std::vector<value_type>& values);
static void test_sort(std::vector<value_type>& values);
static void test_insert(std::vector<value_type>& values);
static void test_shift(std::vector<value_type>& values);
static void test_swap(std::vector<value_type>& values);
static void test_clone(std::vector<value_type>& values);
};
template<class ValueTraits>
void test_list<ValueTraits>::test_all(std::vector<typename ValueTraits::value_type>& values)
{
test_front_back(values);
test_sort(values);
test_insert(values);
test_shift(values);
test_swap(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 testlist2;
}
//test: push_front, pop_front, push_back, pop_back, front, back, size, empty:
template<class ValueTraits>
void test_list<ValueTraits>
::test_front_back(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 testlist;
BOOST_CHECK (testlist.empty());
testlist.push_back (values[0]);
BOOST_CHECK (testlist.size() == 1);
BOOST_CHECK (&testlist.front() == &values[0]);
BOOST_CHECK (&testlist.back() == &values[0]);
testlist.push_front (values[1]);
BOOST_CHECK (testlist.size() == 2);
BOOST_CHECK (&testlist.front() == &values[1]);
BOOST_CHECK (&testlist.back() == &values[0]);
testlist.pop_back();
BOOST_CHECK (testlist.size() == 1);
const list_type &const_testlist = testlist;
BOOST_CHECK (&const_testlist.front() == &values[1]);
BOOST_CHECK (&const_testlist.back() == &values[1]);
testlist.pop_front();
BOOST_CHECK (testlist.empty());
}
//test: constructor, iterator, reverse_iterator, sort, reverse:
template<class ValueTraits>
void test_list<ValueTraits>
::test_sort(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type testvalue_t;
boost::test_tools::output_test_stream test_seq;
typedef boost::intrusive::list
< ValueTraits
, ValueTraits::value_type::constant_time_size
, std::size_t
> list_type;
list_type testlist(values.begin(), values.end());
std::copy (testlist.begin(), testlist.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("12345"));
testlist.sort (even_odd());
std::copy (testlist.rbegin(), testlist.rend(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("53142"));
testlist.reverse();
//test postincrement:
for (BOOST_DEDUCED_TYPENAME list_type::iterator i =
testlist.begin(), e = testlist.end(); i != e; i++)
test_seq << *i;
BOOST_CHECK (test_seq.is_equal ("53142"));
}
//test: assign, insert, const_iterator, const_reverse_iterator, erase, iterator_to:
template<class ValueTraits>
void test_list<ValueTraits>
::test_insert(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type testvalue_t;
boost::test_tools::output_test_stream test_seq;
typedef boost::intrusive::list
< ValueTraits
, ValueTraits::value_type::constant_time_size
, std::size_t
> list_type;
list_type testlist;
testlist.assign (&values[0] + 2, &values[0] + 5);
const list_type& const_testlist = testlist;
std::copy (const_testlist.begin(), const_testlist.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("345"));
BOOST_DEDUCED_TYPENAME list_type::iterator i = ++testlist.begin();
BOOST_CHECK (i->value_ == 4);
testlist.insert (i, values[0]);
std::copy (const_testlist.rbegin(), const_testlist.rend(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("5413"));
i = testlist.iterator_to (values[4]);
BOOST_CHECK (&*i == &values[4]);
i = testlist.erase (i);
BOOST_CHECK (i == testlist.end());
//test postincrement:
for (BOOST_DEDUCED_TYPENAME list_type::const_iterator i =
const_testlist.begin(), e = const_testlist.end(); i != e; i++)
test_seq << *i;
BOOST_CHECK (test_seq.is_equal ("314"));
}
template<class ValueTraits>
void test_list<ValueTraits>
::test_shift(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type testvalue_t;
boost::test_tools::output_test_stream test_seq;
typedef boost::intrusive::list
< ValueTraits
, ValueTraits::value_type::constant_time_size
, std::size_t
> list_type;
list_type testlist;
const int num_values = (int)values.size();
std::vector<int> expected_values(num_values);
//Shift forward all possible positions 3 times
for(int i = 0; i < num_values*3; ++i){
testlist.assign(values.begin(), values.end());
testlist.shift_forward(i);
for(int j = 0; j < num_values; ++j){
expected_values[(j + num_values - i%num_values) % num_values] = (j + 1);
}
std::copy (testlist.begin(), testlist.end(),
std::ostream_iterator<testvalue_t> (test_seq));
std::stringstream stream;
std::copy (expected_values.begin(), expected_values.end(),
std::ostream_iterator<testvalue_t> (stream));
stream << std::ends;
BOOST_CHECK (test_seq.is_equal (stream.str().c_str()));
testlist.clear();
}
//Shift backwards all possible positions
for(int i = 0; i < num_values*3; ++i){
testlist.assign(values.begin(), values.end());
testlist.shift_backwards(i);
for(int j = 0; j < num_values; ++j){
expected_values[(j + i) % num_values] = (j + 1);
}
std::copy (testlist.begin(), testlist.end(),
std::ostream_iterator<testvalue_t> (test_seq));
std::stringstream stream;
std::copy (expected_values.begin(), expected_values.end(),
std::ostream_iterator<testvalue_t> (stream));
stream << std::ends;
BOOST_CHECK (test_seq.is_equal (stream.str().c_str()));
testlist.clear();
}
}
//test: insert (seq-version), swap, splice, erase (seq-version):
template<class ValueTraits>
void test_list<ValueTraits>
::test_swap(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type testvalue_t;
boost::test_tools::output_test_stream test_seq;
typedef boost::intrusive::list
<ValueTraits
,ValueTraits::value_type::constant_time_size, std::size_t
> list_type;
{
list_type testlist1 (&values[0], &values[0] + 2);
list_type testlist2;
testlist2.insert (testlist2.end(), &values[0] + 2, &values[0] + 5);
testlist1.swap (testlist2);
std::copy (testlist1.begin(), testlist1.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("345"));
std::copy (testlist2.begin(), testlist2.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("12"));
testlist2.splice (++testlist2.begin(), testlist1);
std::copy (testlist2.begin(), testlist2.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("13452"));
BOOST_CHECK (testlist1.empty());
testlist1.splice (testlist1.end(), testlist2, ++(++testlist2.begin()));
std::copy (testlist1.begin(), testlist1.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("4"));
std::copy (testlist2.begin(), testlist2.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("1352"));
testlist1.splice (testlist1.end(), testlist2,
testlist2.begin(), ----testlist2.end());
std::copy (testlist1.begin(), testlist1.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("413"));
std::copy (testlist2.begin(), testlist2.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("52"));
testlist1.erase (testlist1.iterator_to(values[0]), testlist1.end());
BOOST_CHECK (testlist1.size() == 1);
BOOST_CHECK (&testlist1.front() == &values[3]);
}
{
boost::test_tools::output_test_stream test_seq;
list_type testlist1 (&values[0], &values[0] + 2);
list_type testlist2 (&values[0] + 3, &values[0] + 5);
values[0].swap_nodes(values[2]);
std::copy (testlist1.begin(), testlist1.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("32"));
values[2].swap_nodes(values[4]);
std::copy (testlist1.begin(), testlist1.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("52"));
std::copy (testlist2.begin(), testlist2.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("43"));
}
}
template<class ValueTraits>
void test_list<ValueTraits>
::test_clone(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type testvalue_t;
boost::test_tools::output_test_stream test_seq;
typedef boost::intrusive::list
<ValueTraits
,ValueTraits::value_type::constant_time_size, std::size_t
> list_type;
list_type testlist1 (&values[0], &values[0] + values.size());
list_type testlist2;
testlist2.clone_from(testlist1, test::new_cloner(), test::delete_destroyer());
BOOST_CHECK (testlist2 == testlist1);
testlist2.clear_and_destroy(test::delete_destroyer());
BOOST_CHECK (testlist2.empty());
}
template<class VoidPointer, bool constant_time_size>
class test_main_template
{
public:
int operator()()
{
typedef testvalue<VoidPointer, constant_time_size> testvalue_t;
std::vector<testvalue_t> data (5);
for (int i = 0; i < 5; ++i)
data[i].value_ = i + 1;
test_list <typename testvalue_t::list_base_hook::template
value_traits<testvalue_t> >::test_all(data);
test_list <typename testvalue_t::list_member_hook::template
value_traits<testvalue_t, &testvalue_t::list_node_> >::test_all(data);
return 0;
}
};
template<class VoidPointer>
class test_main_template<VoidPointer, false>
{
public:
int operator()()
{
typedef testvalue<VoidPointer, false> testvalue_t;
std::vector<testvalue_t> data (5);
for (int i = 0; i < 5; ++i)
data[i].value_ = i + 1;
test_list <typename testvalue_t::list_base_hook::template
value_traits<testvalue_t> >::test_all(data);
test_list <typename testvalue_t::list_member_hook::template
value_traits<testvalue_t, &testvalue_t::list_node_> >::test_all(data);
test_list <typename testvalue_t::list_auto_base_hook::template
value_traits<testvalue_t> >::test_all(data);
test_list <typename testvalue_t::list_auto_member_hook::template
value_traits<testvalue_t, &testvalue_t::list_auto_node_> >::test_all(data);
return 0;
}
};
//Explicit instantiations of non-counted classes
template class boost::intrusive::list<list_base_raw, false>;
template class boost::intrusive::list<list_member_raw, false>;
template class boost::intrusive::list<list_auto_base_raw, false>;
template class boost::intrusive::list<list_auto_member_raw, false>;
template class boost::intrusive::list<list_base_smart, false>;
template class boost::intrusive::list<list_member_smart, false>;
template class boost::intrusive::list<list_auto_base_smart, false>;
template class boost::intrusive::list<list_auto_member_smart, false>;
//Explicit instantiation of counted classes
template class boost::intrusive::list<list_base_raw_t, true>;
template class boost::intrusive::list<list_member_raw_t, true>;
template class boost::intrusive::list<list_base_smart_t, true>;
template class boost::intrusive::list<list_member_smart_t, true>;
int test_main( int, char* [] )
{
test_main_template<void*, false>()();
test_main_template<boost::intrusive::smart_ptr<void>, false>()();
test_main_template<void*, true>()();
test_main_template<boost::intrusive::smart_ptr<void>, true>()();
return 0;
}

317
test/multiset_test.cpp Normal file
View File

@@ -0,0 +1,317 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gazta<74>aga 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/set.hpp>
#include <boost/intrusive/detail/pointer_to_other.hpp>
#include "itestvalue.hpp"
#include "smart_ptr.hpp"
#include "common_functors.hpp"
#include <vector>
// Boost.Test
#include "boost/test/included/test_exec_monitor.hpp"
using namespace boost::intrusive;
template<class ValueTraits>
struct test_multiset
{
typedef typename ValueTraits::value_type value_type;
static void test_all (std::vector<value_type>& values);
static void test_sort(std::vector<value_type>& values);
static void test_insert(std::vector<value_type>& values);
static void test_swap(std::vector<value_type>& values);
static void test_find(std::vector<value_type>& values);
static void test_impl();
static void test_clone(std::vector<value_type>& values);
};
template<class ValueTraits>
void test_multiset<ValueTraits>::test_all (std::vector<typename ValueTraits::value_type>& values)
{
test_sort(values);
test_insert(values);
test_swap(values);
test_find(values);
test_impl();
test_clone(values);
}
//test case due to an error in tree implementation:
template<class ValueTraits>
void test_multiset<ValueTraits>::test_impl()
{
typedef typename ValueTraits::value_type testvalue_t;
std::vector<testvalue_t> values (5);
for (int i = 0; i < 5; ++i)
values[i].value_ = i;
typedef multiset
<ValueTraits
,std::less<typename ValueTraits::value_type>
,ValueTraits::value_type::constant_time_size, std::size_t
> multiset_type;
multiset_type testset;
for (int i = 0; i < 5; ++i)
testset.insert (values[i]);
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]));
}
//test: constructor, iterator, clear, reverse_iterator, front, back, size:
template<class ValueTraits>
void test_multiset<ValueTraits>::test_sort(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type testvalue_t;
boost::test_tools::output_test_stream test_seq;
typedef multiset
<ValueTraits
,std::less<typename ValueTraits::value_type>
,ValueTraits::value_type::constant_time_size, std::size_t
> multiset_type;
multiset_type testset1 (values.begin(), values.end());
std::copy (testset1.begin(), testset1.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("122345"));
testset1.clear();
BOOST_CHECK (testset1.empty());
typedef multiset
<ValueTraits
,even_odd
,ValueTraits::value_type::constant_time_size, std::size_t
> multiset_type2;
multiset_type2 testset2 (&values[0], &values[0] + 6);
std::copy (testset2.rbegin(), testset2.rend(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("531422"));
BOOST_CHECK (testset2.begin()->value_ == 2);
BOOST_CHECK (testset2.rbegin()->value_ == 5);
}
//test: insert, const_iterator, const_reverse_iterator, erase, iterator_to:
template<class ValueTraits>
void test_multiset<ValueTraits>::test_insert(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type testvalue_t;
boost::test_tools::output_test_stream test_seq;
typedef multiset
<ValueTraits
,std::less<typename ValueTraits::value_type>
,ValueTraits::value_type::constant_time_size, std::size_t
> multiset_type;
multiset_type testset;
testset.insert(&values[0] + 2, &values[0] + 5);
const multiset_type& const_testset = testset;
std::copy (const_testset.begin(), const_testset.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("145"));
BOOST_DEDUCED_TYPENAME multiset_type::iterator i = testset.begin();
BOOST_CHECK (i->value_ == 1);
i = testset.insert (i, values[0]);
BOOST_CHECK (&*i == &values[0]);
std::copy (const_testset.rbegin(), const_testset.rend(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("5431"));
i = testset.iterator_to (values[2]);
BOOST_CHECK (&*i == &values[2]);
testset.erase(i);
//test post-increment:
for (BOOST_DEDUCED_TYPENAME multiset_type::const_iterator i = const_testset.begin(),
e = const_testset.end(); i != e; i++)
test_seq << *i;
BOOST_CHECK (test_seq.is_equal ("135"));
}
//test: insert (seq-version), swap, erase (seq-version), size:
template<class ValueTraits>
void test_multiset<ValueTraits>::test_swap(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type testvalue_t;
boost::test_tools::output_test_stream test_seq;
typedef multiset
<ValueTraits
,std::less<typename ValueTraits::value_type>
,ValueTraits::value_type::constant_time_size, std::size_t
> multiset_type;
multiset_type testset1 (&values[0], &values[0] + 2);
multiset_type testset2;
testset2.insert (&values[0] + 2, &values[0] + 6);
testset1.swap (testset2);
std::copy (testset1.begin(), testset1.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("1245"));
//test post-increment:
for (BOOST_DEDUCED_TYPENAME multiset_type::iterator i = testset2.begin(),
e = testset2.end(); i != e; i++)
test_seq << *i;
BOOST_CHECK (test_seq.is_equal ("23"));
testset1.erase (testset1.iterator_to(values[5]), testset1.end());
BOOST_CHECK (testset1.size() == 1);
BOOST_CHECK (&*testset1.begin() == &values[3]);
}
//test: find, equal_range (lower_bound, upper_bound):
template<class ValueTraits>
void test_multiset<ValueTraits>::test_find(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type testvalue_t;
boost::test_tools::output_test_stream test_seq;
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());
typedef BOOST_DEDUCED_TYPENAME multiset_type::iterator iterator;
testvalue_t cmp_val;
cmp_val.value_ = 2;
iterator i = testset.find (cmp_val);
BOOST_CHECK (i->value_ == 2);
BOOST_CHECK ((++i)->value_ == 2);
std::pair<iterator,iterator> range = testset.equal_range (cmp_val);
BOOST_CHECK (range.first->value_ == 2);
BOOST_CHECK (range.second->value_ == 3);
BOOST_CHECK (std::distance (range.first, range.second) == 2);
cmp_val.value_ = 7;
BOOST_CHECK (testset.find (cmp_val) == testset.end());
}
template<class ValueTraits>
void test_multiset<ValueTraits>
::test_clone(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type testvalue_t;
typedef multiset
<ValueTraits
,std::less<typename ValueTraits::value_type>
,ValueTraits::value_type::constant_time_size, std::size_t
> multiset_type;
multiset_type testmultiset1 (&values[0], &values[0] + values.size());
multiset_type testmultiset2;
testmultiset2.clone_from(testmultiset1, test::new_cloner(), test::delete_destroyer());
BOOST_CHECK (testmultiset2 == testmultiset1);
testmultiset2.clear_and_destroy(test::delete_destroyer());
BOOST_CHECK (testmultiset2.empty());
}
template<class VoidPointer, bool constant_time_size>
class test_main_template
{
public:
int operator()()
{
typedef testvalue<VoidPointer, constant_time_size> testvalue_t;
static const int random_init[6] = { 3, 2, 4, 1, 5, 2 };
std::vector<testvalue<VoidPointer, constant_time_size> > data (6);
for (int i = 0; i < 6; ++i)
data[i].value_ = random_init[i];
test_multiset <typename testvalue_t::set_base_hook::template
value_traits<testvalue_t> >::test_all(data);
test_multiset <typename testvalue_t::set_member_hook::template
value_traits<testvalue_t, &testvalue_t::set_node_> >::test_all(data);
return 0;
}
};
template<class VoidPointer>
class test_main_template<VoidPointer, false>
{
public:
int operator()()
{
typedef testvalue<VoidPointer, false> testvalue_t;
static const int random_init[6] = { 3, 2, 4, 1, 5, 2 };
std::vector<testvalue<VoidPointer, false> > data (6);
for (int i = 0; i < 6; ++i)
data[i].value_ = random_init[i];
test_multiset <typename testvalue_t::set_base_hook::template
value_traits<testvalue_t> >::test_all(data);
test_multiset <typename testvalue_t::set_member_hook::template
value_traits<testvalue_t, &testvalue_t::set_node_> >::test_all(data);
test_multiset <typename testvalue_t::set_auto_base_hook::template
value_traits<testvalue_t> >::test_all(data);
test_multiset <typename testvalue_t::set_auto_member_hook::template
value_traits<testvalue_t, &testvalue_t::set_auto_node_> >::test_all(data);
return 0;
}
};
//Explicit instantiations of non-counted classes
template class multiset
<set_base_raw, std::less<set_base_raw::value_type>, false>;
template class multiset
<set_member_raw, std::less<set_member_raw::value_type>, false>;
template class multiset
<set_auto_base_raw, std::less<set_auto_base_raw::value_type>, false>;
template class multiset
<set_auto_member_raw, std::less<set_auto_member_raw::value_type>, false>;
template class multiset
<set_base_smart, std::less<set_base_smart::value_type>, false>;
template class multiset
<set_member_smart, std::less<set_member_smart::value_type>, false>;
template class multiset
<set_auto_base_smart, std::less<set_auto_base_smart::value_type>, false>;
template class multiset
<set_auto_member_smart, std::less<set_auto_member_smart::value_type>, false>;
//Explicit instantiation of counted classes
template class multiset
<set_base_raw_t, std::less<set_base_raw_t::value_type>, true>;
template class multiset
<set_member_raw_t, std::less<set_member_raw_t::value_type>, true>;
template class multiset
<set_base_smart_t, std::less<set_base_smart_t::value_type>, true>;
template class multiset
<set_member_smart_t, std::less<set_member_smart_t::value_type>, true>;
int test_main( int, char* [] )
{
test_main_template<void*, false>()();
test_main_template<smart_ptr<void>, false>()();
test_main_template<void*, true>()();
test_main_template<smart_ptr<void>, true>()();
return 0;
}

315
test/set_test.cpp Normal file
View File

@@ -0,0 +1,315 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gazta<74>aga 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/set.hpp>
#include <boost/intrusive/detail/pointer_to_other.hpp>
#include "itestvalue.hpp"
#include "smart_ptr.hpp"
#include "common_functors.hpp"
#include <vector>
// Boost.Test
#include "boost/test/included/test_exec_monitor.hpp"
using namespace boost::intrusive;
template<class ValueTraits>
struct test_set
{
typedef typename ValueTraits::value_type value_type;
static void test_all(std::vector<value_type>& values);
static void test_sort(std::vector<value_type>& values);
static void test_insert(std::vector<value_type>& values);
static void test_swap(std::vector<value_type>& values);
static void test_find(std::vector<value_type>& values);
static void test_impl();
static void test_clone(std::vector<value_type>& values);
};
template<class ValueTraits>
void test_set<ValueTraits>::test_all(std::vector<typename ValueTraits::value_type>& values)
{
test_sort(values);
test_insert(values);
test_swap(values);
test_find(values);
test_impl();
test_clone(values);
}
//test case due to an error in tree implementation:
template<class ValueTraits>
void test_set<ValueTraits>::test_impl()
{
typedef typename ValueTraits::value_type testvalue_t;
std::vector<testvalue_t> values (5);
for (int i = 0; i < 5; ++i)
values[i].value_ = i;
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;
for (int i = 0; i < 5; ++i)
testset.insert (values[i]);
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]));
}
//test: constructor, iterator, clear, reverse_iterator, front, back, size:
template<class ValueTraits>
void test_set<ValueTraits>::test_sort(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type testvalue_t;
boost::test_tools::output_test_stream test_seq;
typedef boost::intrusive::set
<ValueTraits
,std::less<typename ValueTraits::value_type>
,ValueTraits::value_type::constant_time_size, std::size_t
> set_type;
set_type testset1 (values.begin(), values.end());
std::copy (testset1.begin(), testset1.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("12345"));
testset1.clear();
BOOST_CHECK (testset1.empty());
typedef boost::intrusive::set
<ValueTraits
,even_odd
,ValueTraits::value_type::constant_time_size, std::size_t
> set_type2;
set_type2 testset2 (&values[0], &values[0] + 6);
std::copy (testset2.rbegin(), testset2.rend(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("53142"));
BOOST_CHECK (testset2.begin()->value_ == 2);
BOOST_CHECK (testset2.rbegin()->value_ == 5);
}
//test: insert, const_iterator, const_reverse_iterator, erase, iterator_to:
template<class ValueTraits>
void test_set<ValueTraits>::test_insert(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type testvalue_t;
boost::test_tools::output_test_stream test_seq;
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;
testset.insert(&values[0] + 2, &values[0] + 5);
const set_type& const_testset = testset;
std::copy (const_testset.begin(), const_testset.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("145"));
BOOST_DEDUCED_TYPENAME set_type::iterator i = testset.begin();
BOOST_CHECK (i->value_ == 1);
i = testset.insert (i, values[0]);
BOOST_CHECK (&*i == &values[0]);
std::copy (const_testset.rbegin(), const_testset.rend(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("5431"));
i = testset.iterator_to (values[2]);
BOOST_CHECK (&*i == &values[2]);
testset.erase (i);
//test post-increment:
for (BOOST_DEDUCED_TYPENAME set_type::const_iterator i = const_testset.begin(),
e = const_testset.end(); i != e; i++)
test_seq << *i;
BOOST_CHECK (test_seq.is_equal ("135"));
}
//test: insert (seq-version), swap, erase (seq-version), size:
template<class ValueTraits>
void test_set<ValueTraits>::test_swap(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type testvalue_t;
boost::test_tools::output_test_stream test_seq;
typedef boost::intrusive::set
<ValueTraits
,std::less<typename ValueTraits::value_type>
,ValueTraits::value_type::constant_time_size, std::size_t
> set_type;
set_type testset1 (&values[0], &values[0] + 2);
set_type testset2;
testset2.insert (&values[0] + 2, &values[0] + 6);
testset1.swap (testset2);
std::copy (testset1.begin(), testset1.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("1245"));
//test post-increment:
for (BOOST_DEDUCED_TYPENAME set_type::iterator i = testset2.begin(),
e = testset2.end(); i != e; i++)
test_seq << *i;
BOOST_CHECK (test_seq.is_equal ("23"));
testset1.erase (testset1.iterator_to(values[5]), testset1.end());
BOOST_CHECK (testset1.size() == 1);
// BOOST_CHECK (&testset1.front() == &values[3]);
BOOST_CHECK (&*testset1.begin() == &values[3]);
}
//test: find, equal_range (lower_bound, upper_bound):
template<class ValueTraits>
void test_set<ValueTraits>::test_find(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type testvalue_t;
boost::test_tools::output_test_stream test_seq;
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());
typedef BOOST_DEDUCED_TYPENAME set_type::iterator iterator;
testvalue_t cmp_val;
cmp_val.value_ = 2;
iterator i = testset.find (cmp_val);
BOOST_CHECK (i->value_ == 2);
BOOST_CHECK ((++i)->value_ != 2);
std::pair<iterator,iterator> range = testset.equal_range (cmp_val);
BOOST_CHECK (range.first->value_ == 2);
BOOST_CHECK (range.second->value_ == 3);
BOOST_CHECK (std::distance (range.first, range.second) == 1);
cmp_val.value_ = 7;
BOOST_CHECK (testset.find (cmp_val) == testset.end());
}
template<class ValueTraits>
void test_set<ValueTraits>
::test_clone(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type testvalue_t;
typedef boost::intrusive::set
<ValueTraits
,std::less<typename ValueTraits::value_type>
,ValueTraits::value_type::constant_time_size, std::size_t
> set_type;
set_type testset1 (&values[0], &values[0] + values.size());
set_type testset2;
testset2.clone_from(testset1, test::new_cloner(), test::delete_destroyer());
BOOST_CHECK (testset2 == testset1);
testset2.clear_and_destroy(test::delete_destroyer());
BOOST_CHECK (testset2.empty());
}
template<class VoidPointer, bool constant_time_size>
class test_main_template
{
public:
int operator()()
{
typedef testvalue<VoidPointer, constant_time_size> testvalue_t;
static const int random_init[6] = { 3, 2, 4, 1, 5, 2 };
std::vector<testvalue<VoidPointer, constant_time_size> > data (6);
for (int i = 0; i < 6; ++i)
data[i].value_ = random_init[i];
test_set <typename testvalue_t::set_base_hook::template
value_traits<testvalue_t> >::test_all(data);
test_set <typename testvalue_t::set_member_hook::template
value_traits<testvalue_t, &testvalue_t::set_node_> >::test_all(data);
return 0;
}
};
template<class VoidPointer>
class test_main_template<VoidPointer, false>
{
public:
int operator()()
{
typedef testvalue<VoidPointer, false> testvalue_t;
static const int random_init[6] = { 3, 2, 4, 1, 5, 2 };
std::vector<testvalue<VoidPointer, false> > data (6);
for (int i = 0; i < 6; ++i)
data[i].value_ = random_init[i];
test_set <typename testvalue_t::set_base_hook::template
value_traits<testvalue_t> >::test_all(data);
test_set <typename testvalue_t::set_member_hook::template
value_traits<testvalue_t, &testvalue_t::set_node_> >::test_all(data);
test_set <typename testvalue_t::set_auto_base_hook::template
value_traits<testvalue_t> >::test_all(data);
test_set <typename testvalue_t::set_auto_member_hook::template
value_traits<testvalue_t, &testvalue_t::set_auto_node_> >::test_all(data);
return 0;
}
};
//Explicit instantiations of non-counted classes
template class boost::intrusive::set
<set_base_raw, std::less<set_base_raw::value_type>, false>;
template class boost::intrusive::set
<set_member_raw, std::less<set_member_raw::value_type>, false>;
template class boost::intrusive::set
<set_auto_base_raw, std::less<set_auto_base_raw::value_type>, false>;
template class boost::intrusive::set
<set_auto_member_raw, std::less<set_auto_member_raw::value_type>, false>;
template class boost::intrusive::set
<set_base_smart, std::less<set_base_smart::value_type>, false>;
template class boost::intrusive::set
<set_member_smart, std::less<set_member_smart::value_type>, false>;
template class boost::intrusive::set
<set_auto_base_smart, std::less<set_auto_base_smart::value_type>, false>;
template class boost::intrusive::set
<set_auto_member_smart, std::less<set_auto_member_smart::value_type>, false>;
//Explicit instantiation of counted classes
template class boost::intrusive::set
<set_base_raw_t, std::less<set_base_raw_t::value_type>, true>;
template class boost::intrusive::set
<set_member_raw_t, std::less<set_member_raw_t::value_type>, true>;
template class boost::intrusive::set
<set_base_smart_t, std::less<set_base_smart_t::value_type>, true>;
template class boost::intrusive::set
<set_member_smart_t, std::less<set_member_smart_t::value_type>, true>;
int test_main( int, char* [] )
{
test_main_template<void*, false>()();
test_main_template<boost::intrusive::smart_ptr<void>, false>()();
test_main_template<void*, true>()();
test_main_template<boost::intrusive::smart_ptr<void>, true>()();
return 0;
}

433
test/slist_test.cpp Normal file
View File

@@ -0,0 +1,433 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gazta<74>aga 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/slist.hpp>
#include <boost/intrusive/detail/pointer_to_other.hpp>
#include "itestvalue.hpp"
#include "smart_ptr.hpp"
#include "common_functors.hpp"
#include <vector>
#include <sstream>
// Boost.Test
#include "boost/test/included/test_exec_monitor.hpp"
using namespace boost::intrusive;
template<class ValueTraits>
struct test_slist
{
typedef typename ValueTraits::value_type value_type;
static void test_all (std::vector<value_type>& values);
static void test_front_back (std::vector<value_type>& values);
static void test_sort(std::vector<value_type>& values);
static void test_merge (std::vector<value_type>& values);
static void test_insert(std::vector<value_type>& values);
static void test_shift(std::vector<value_type>& values);
static void test_swap(std::vector<value_type>& values);
static void test_slow_insert (std::vector<value_type>& values);
static void test_clone (std::vector<value_type>& values);
};
template<class ValueTraits>
void test_slist<ValueTraits>
::test_all (std::vector<typename ValueTraits::value_type>& values)
{
test_front_back (values);
test_sort(values);
test_merge (values);
test_insert(values);
test_shift(values);
test_slow_insert (values);
test_swap(values);
test_clone(values);
}
//test: push_front, pop_front, front, size, empty:
template<class ValueTraits>
void test_slist<ValueTraits>
::test_front_back (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 testlist;
BOOST_CHECK (testlist.empty());
testlist.push_front (values[0]);
BOOST_CHECK (testlist.size() == 1);
BOOST_CHECK (&testlist.front() == &values[0]);
testlist.push_front (values[1]);
BOOST_CHECK (testlist.size() == 2);
BOOST_CHECK (&testlist.front() == &values[1]);
testlist.pop_front();
BOOST_CHECK (testlist.size() == 1);
BOOST_CHECK (&testlist.front() == &values[0]);
testlist.pop_front();
BOOST_CHECK (testlist.empty());
}
//test: merge due to error in merge implementation:
template<class ValueTraits>
void test_slist<ValueTraits>
::test_merge (std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type testvalue_t;
boost::test_tools::output_test_stream test_seq;
typedef boost::intrusive::slist
<ValueTraits
,ValueTraits::value_type::constant_time_size, std::size_t
> list_type;
list_type testlist1, testlist2;
testlist1.push_front (values[0]);
testlist2.push_front (values[4]);
testlist2.push_front (values[3]);
testlist2.push_front (values[2]);
testlist1.merge (testlist2);
std::copy (testlist1.begin(), testlist1.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("1345"));
}
//test: constructor, iterator, sort, reverse:
template<class ValueTraits>
void test_slist<ValueTraits>
::test_sort(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type testvalue_t;
boost::test_tools::output_test_stream test_seq;
typedef boost::intrusive::slist
<ValueTraits
,ValueTraits::value_type::constant_time_size, std::size_t
> list_type;
list_type testlist (values.begin(), values.end());
std::copy (testlist.begin(), testlist.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("12345"));
testlist.sort (even_odd());
for (BOOST_DEDUCED_TYPENAME list_type::iterator i = testlist.begin(),
e = testlist.end(); i != e; i++) //test postincrement
test_seq << *i;
BOOST_CHECK (test_seq.is_equal ("24135"));
testlist.reverse();
std::copy (testlist.begin(), testlist.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("53142"));
}
//test: assign, insert_after, const_iterator, erase_after, iterator_to, previous:
template<class ValueTraits>
void test_slist<ValueTraits>
::test_insert(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type testvalue_t;
boost::test_tools::output_test_stream test_seq;
typedef boost::intrusive::slist
<ValueTraits
,ValueTraits::value_type::constant_time_size, std::size_t
> list_type;
list_type testlist;
testlist.assign (&values[0] + 2, &values[0] + 5);
const list_type& const_testlist = testlist;
std::copy (const_testlist.begin(), const_testlist.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("345"));
BOOST_DEDUCED_TYPENAME list_type::iterator i = ++testlist.begin();
BOOST_CHECK (i->value_ == 4);
testlist.insert_after (i, values[0]);
for (BOOST_DEDUCED_TYPENAME list_type::const_iterator i2 = const_testlist.begin(),
e = const_testlist.end(); i2 != e; i2++) //test postincrement
test_seq << *i2;
BOOST_CHECK (test_seq.is_equal ("3415"));
i = testlist.iterator_to (values[4]);
BOOST_CHECK (&*i == &values[4]);
i = testlist.previous (i);
BOOST_CHECK (&*i == &values[0]);
testlist.erase_after (i);
BOOST_CHECK (&*i == &values[0]);
std::copy (const_testlist.begin(), const_testlist.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("341"));
}
//test: insert, const_iterator, erase, iterator_to:
template<class ValueTraits>
void test_slist<ValueTraits>
::test_slow_insert (std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type testvalue_t;
boost::test_tools::output_test_stream test_seq;
typedef boost::intrusive::slist
<ValueTraits
,ValueTraits::value_type::constant_time_size, std::size_t
> list_type;
list_type testlist;
testlist.push_front (values[4]);
testlist.insert (testlist.begin(), &values[0] + 2, &values[0] + 4);
const list_type& const_testlist = testlist;
std::copy (const_testlist.begin(), const_testlist.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("345"));
BOOST_DEDUCED_TYPENAME list_type::iterator i = ++testlist.begin();
BOOST_CHECK (i->value_ == 4);
testlist.insert (i, values[0]);
std::copy (const_testlist.begin(), const_testlist.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("3145"));
i = testlist.iterator_to (values[4]);
BOOST_CHECK (&*i == &values[4]);
i = testlist.erase (i);
BOOST_CHECK (i == testlist.end());
//test postincrement:
for (BOOST_DEDUCED_TYPENAME list_type::const_iterator i =
const_testlist.begin(), e = const_testlist.end(); i != e; i++)
test_seq << *i;
BOOST_CHECK (test_seq.is_equal ("314"));
testlist.erase (++testlist.begin(), testlist.end());
BOOST_CHECK (testlist.size() == 1);
BOOST_CHECK (testlist.front().value_ == 3);
}
template<class ValueTraits>
void test_slist<ValueTraits>
::test_shift(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type testvalue_t;
boost::test_tools::output_test_stream test_seq;
typedef boost::intrusive::slist
<ValueTraits
,ValueTraits::value_type::constant_time_size, std::size_t
> list_type;
list_type testlist;
const int num_values = (int)values.size();
std::vector<int> expected_values(num_values);
//Shift forward all possible positions 3 times
for(int i = 0; i < num_values*3; ++i){
testlist.assign(values.begin(), values.end());
testlist.shift_forward(i);
for(int j = 0; j < num_values; ++j){
expected_values[(j + num_values - i%num_values) % num_values] = (j + 1);
}
std::copy (testlist.begin(), testlist.end(),
std::ostream_iterator<testvalue_t> (test_seq));
std::stringstream stream;
std::copy (expected_values.begin(), expected_values.end(),
std::ostream_iterator<testvalue_t> (stream));
stream << std::ends;
BOOST_CHECK (test_seq.is_equal (stream.str().c_str()));
testlist.clear();
}
//Shift backwards all possible positions
for(int i = 0; i < num_values*3; ++i){
testlist.assign(values.begin(), values.end());
testlist.shift_backwards(i);
for(int j = 0; j < num_values; ++j){
expected_values[(j + i) % num_values] = (j + 1);
}
std::copy (testlist.begin(), testlist.end(),
std::ostream_iterator<testvalue_t> (test_seq));
std::stringstream stream2;
std::copy (testlist.begin(), testlist.end(),
std::ostream_iterator<testvalue_t> (stream2));
stream2 << std::ends;
std::stringstream stream;
std::copy (expected_values.begin(), expected_values.end(),
std::ostream_iterator<testvalue_t> (stream));
stream << std::ends;
BOOST_CHECK (test_seq.is_equal (stream.str().c_str()));
testlist.clear();
}
}
//test: insert_after (seq-version), swap, splice_after:
template<class ValueTraits>
void test_slist<ValueTraits>
::test_swap(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type testvalue_t;
boost::test_tools::output_test_stream test_seq;
typedef boost::intrusive::slist
<ValueTraits
,ValueTraits::value_type::constant_time_size, std::size_t
> list_type;
{
list_type testlist1 (&values[0], &values[0] + 2);
list_type testlist2;
testlist2.insert_after (testlist2.end(), &values[0] + 2, &values[0] + 5);
testlist1.swap(testlist2);
std::copy (testlist1.begin(), testlist1.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("345"));
std::copy (testlist2.begin(), testlist2.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("12"));
testlist2.splice_after (testlist2.begin(), testlist1);
std::copy (testlist2.begin(), testlist2.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("13452"));
BOOST_CHECK (testlist1.empty());
testlist1.splice_after (testlist1.end(), testlist2, ++testlist2.begin());
std::copy (testlist1.begin(), testlist1.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("4"));
std::copy (testlist2.begin(), testlist2.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("1352"));
testlist1.splice_after (testlist1.begin(), testlist2,
testlist2.end(), ++++testlist2.begin());
std::copy (testlist1.begin(), testlist1.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("4135"));
std::copy (testlist2.begin(), testlist2.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("2"));
}
{
boost::test_tools::output_test_stream test_seq;
list_type testlist1 (&values[0], &values[0] + 2);
list_type testlist2 (&values[0] + 3, &values[0] + 5);
values[0].swap_nodes(values[2]);
std::copy (testlist1.begin(), testlist1.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("32"));
values[2].swap_nodes(values[4]);
std::copy (testlist1.begin(), testlist1.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("52"));
std::copy (testlist2.begin(), testlist2.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("43"));
}
}
template<class ValueTraits>
void test_slist<ValueTraits>
::test_clone(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type testvalue_t;
boost::test_tools::output_test_stream test_seq;
typedef boost::intrusive::slist
<ValueTraits
,ValueTraits::value_type::constant_time_size, std::size_t
> list_type;
list_type testlist1 (&values[0], &values[0] + values.size());
list_type testlist2;
testlist2.clone_from(testlist1, test::new_cloner(), test::delete_destroyer());
BOOST_CHECK (testlist2 == testlist1);
testlist2.clear_and_destroy(test::delete_destroyer());
BOOST_CHECK (testlist2.empty());
}
template<class VoidPointer, bool constant_time_size>
class test_main_template
{
public:
int operator()()
{
typedef testvalue<VoidPointer, constant_time_size> testvalue_t;
std::vector<testvalue_t> data (5);
for (int i = 0; i < 5; ++i)
data[i].value_ = i + 1;
test_slist <typename testvalue_t::slist_base_hook::template
value_traits<testvalue_t> >::test_all(data);
test_slist <typename testvalue_t::slist_member_hook::template
value_traits<testvalue_t, &testvalue_t::slist_node_> >::test_all(data);
return 0;
}
};
template<class VoidPointer>
class test_main_template<VoidPointer, false>
{
public:
int operator()()
{
typedef testvalue<VoidPointer, false> testvalue_t;
std::vector<testvalue_t> data (5);
for (int i = 0; i < 5; ++i)
data[i].value_ = i + 1;
test_slist <typename testvalue_t::slist_base_hook::template
value_traits<testvalue_t> >::test_all(data);
test_slist <typename testvalue_t::slist_member_hook::template
value_traits<testvalue_t, &testvalue_t::slist_node_> >::test_all(data);
test_slist <typename testvalue_t::slist_auto_base_hook::template
value_traits<testvalue_t> >::test_all(data);
test_slist <typename testvalue_t::slist_auto_member_hook::template
value_traits<testvalue_t, &testvalue_t::slist_auto_node_> >::test_all(data);
return 0;
}
};
//Explicit instantiations of non-counted classes
template class boost::intrusive::slist<slist_base_raw, false>;
template class boost::intrusive::slist<slist_member_raw, false>;
template class boost::intrusive::slist<slist_auto_base_raw, false>;
template class boost::intrusive::slist<slist_auto_member_raw, false>;
template class boost::intrusive::slist<slist_base_smart, false>;
template class boost::intrusive::slist<slist_member_smart, false>;
template class boost::intrusive::slist<slist_auto_base_smart, false>;
template class boost::intrusive::slist<slist_auto_member_smart, false>;
//Explicit instantiation of counted classes
template class boost::intrusive::slist<slist_base_raw_t, true>;
template class boost::intrusive::slist<slist_member_raw_t, true>;
template class boost::intrusive::slist<slist_base_smart_t, true>;
template class boost::intrusive::slist<slist_member_smart_t, true>;
int test_main(int, char* [])
{
test_main_template<void*, false>()();
test_main_template<boost::intrusive::smart_ptr<void>, false>()();
test_main_template<void*, true>()();
test_main_template<boost::intrusive::smart_ptr<void>, true>()();
return 0;
}

355
test/smart_ptr.hpp Normal file
View File

@@ -0,0 +1,355 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gazta<74>aga 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)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_SMART_PTR_HPP
#define BOOST_INTRUSIVE_SMART_PTR_HPP
#include <boost/iterator.hpp>
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
namespace boost{
namespace intrusive{
namespace detail {
struct static_cast_tag {};
struct const_cast_tag {};
struct dynamic_cast_tag {};
struct reinterpret_cast_tag {};
} //namespace detail {
//Empty class
struct empty_type{};
template<class T>
struct random_it
: public boost::iterator<std::random_access_iterator_tag,
T, std::ptrdiff_t, T*, T&>
{
typedef const T* const_pointer;
typedef const T& const_reference;
};
template<> struct random_it<void>
{
typedef void * pointer;
typedef const void * const_pointer;
typedef empty_type& reference;
typedef const empty_type& const_reference;
typedef void value_type;
typedef empty_type difference_type;
typedef empty_type iterator_category;
};
template<> struct random_it<const void>
{
typedef const void * pointer;
typedef const void * const_pointer;
typedef const empty_type & reference;
typedef const empty_type & const_reference;
typedef const void value_type;
typedef empty_type difference_type;
typedef empty_type iterator_category;
};
template<> struct random_it<volatile void>
{
typedef volatile void * pointer;
typedef const volatile void * const_pointer;
typedef empty_type& reference;
typedef const empty_type& const_reference;
typedef volatile void value_type;
typedef empty_type difference_type;
typedef empty_type iterator_category;
};
template<> struct random_it<const volatile void>
{
typedef const volatile void * pointer;
typedef const volatile void * const_pointer;
typedef const empty_type & reference;
typedef const empty_type & const_reference;
typedef const volatile void value_type;
typedef empty_type difference_type;
typedef empty_type iterator_category;
};
} //namespace intrusive {
} //namespace boost {
namespace boost {
namespace intrusive {
template <class PointedType>
class smart_ptr
{
typedef random_it<PointedType> random_it_t;
typedef smart_ptr<PointedType> self_t;
typedef typename random_it_t::const_pointer const_pointer_t;
typedef typename random_it_t::const_reference const_reference_t;
void unspecified_bool_type_func() const {}
typedef void (self_t::*unspecified_bool_type)() const;
public:
typedef typename random_it_t::pointer pointer;
typedef typename random_it_t::reference reference;
typedef typename random_it_t::value_type value_type;
typedef typename random_it_t::difference_type difference_type;
typedef typename random_it_t::iterator_category iterator_category;
PointedType *m_ptr;
public: //Public Functions
/*!Constructor from raw pointer (allows "0" pointer conversion). Never throws.*/
smart_ptr(pointer ptr = 0)
: m_ptr(ptr)
{}
/*!Constructor from other pointer. Never throws.*/
template <class T>
smart_ptr(T *ptr)
: m_ptr(ptr)
{}
/*!Constructor from other smart_ptr */
smart_ptr(const smart_ptr& ptr)
: m_ptr(ptr.m_ptr)
{}
/*!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)
: m_ptr(ptr.m_ptr)
{}
/*!Emulates static_cast operator. Never throws. */
template<class Y>
smart_ptr(const smart_ptr<Y> & r, detail::static_cast_tag)
: m_ptr(static_cast<PointedType*>(r.get()))
{}
/*!Emulates const_cast operator. Never throws.*/
template<class Y>
smart_ptr(const smart_ptr<Y> & r, detail::const_cast_tag)
: m_ptr(const_cast<PointedType*>(r.get()))
{}
/*!Emulates dynamic_cast operator. Never throws.*/
template<class Y>
smart_ptr(const smart_ptr<Y> & r, detail::dynamic_cast_tag)
: m_ptr(dynamic_cast<PointedType*>(r.get()))
{}
/*!Emulates reinterpret_cast operator. Never throws.*/
template<class Y>
smart_ptr(const smart_ptr<Y> & r, detail::reinterpret_cast_tag)
: m_ptr(reinterpret_cast<PointedType*>(r.get()))
{}
/*!Obtains raw pointer from offset. Never throws.*/
pointer get()const
{ return m_ptr; }
/*!Pointer-like -> operator. It can return 0 pointer. Never throws.*/
pointer operator->() const
{ return this->get(); }
/*!Dereferencing operator, if it is a null smart_ptr behavior
is undefined. Never throws.*/
reference operator* () const
{ return *(this->get()); }
/*!Indexing operator. Never throws.*/
reference operator[](std::ptrdiff_t idx) const
{ return this->get()[idx]; }
/*!Assignment from pointer (saves extra conversion). Never throws.*/
smart_ptr& operator= (pointer from)
{ m_ptr = from; return *this; }
/*!Assignment from other smart_ptr. Never throws.*/
smart_ptr& operator= (const smart_ptr & pt)
{ m_ptr = pt.m_ptr; return *this; }
/*!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
{ return smart_ptr(this->get()+offset); }
/*!smart_ptr - std::ptrdiff_t. Never throws.*/
smart_ptr operator- (std::ptrdiff_t offset) const
{ return smart_ptr(this->get()-offset); }
/*!smart_ptr += std::ptrdiff_t. Never throws.*/
smart_ptr &operator+= (std::ptrdiff_t offset)
{ m_ptr += offset; return *this; }
/*!smart_ptr -= std::ptrdiff_t. Never throws.*/
smart_ptr &operator-= (std::ptrdiff_t offset)
{ m_ptr -= offset; return *this; }
/*!++smart_ptr. Never throws.*/
smart_ptr& operator++ (void)
{ ++m_ptr; return *this; }
/*!smart_ptr++. Never throws.*/
smart_ptr operator++ (int)
{ smart_ptr temp(*this); ++*this; return temp; }
/*!--smart_ptr. Never throws.*/
smart_ptr& operator-- (void)
{ --m_ptr; return *this; }
/*!smart_ptr--. Never throws.*/
smart_ptr operator-- (int)
{ smart_ptr temp(*this); --*this; return temp; }
/*!safe bool conversion operator. Never throws.*/
operator unspecified_bool_type() const
{ return this->get()? &self_t::unspecified_bool_type_func : 0; }
/*!Not operator. Not needed in theory, but improves portability.
Never throws.*/
bool operator! () const
{ return this->get() == 0; }
/*
friend void swap (smart_ptr &pt, smart_ptr &pt2)
{
value_type *ptr = pt.get();
pt = pt2;
pt2 = ptr;
}
*/
};
/*!smart_ptr<T1> == smart_ptr<T2>. Never throws.*/
template<class T1, class T2>
inline bool operator== (const smart_ptr<T1> &pt1,
const smart_ptr<T2> &pt2)
{ return pt1.get() == pt2.get(); }
/*!smart_ptr<T1> != smart_ptr<T2>. Never throws.*/
template<class T1, class T2>
inline bool operator!= (const smart_ptr<T1> &pt1,
const smart_ptr<T2> &pt2)
{ return pt1.get() != pt2.get(); }
/*!smart_ptr<T1> < smart_ptr<T2>. Never throws.*/
template<class T1, class T2>
inline bool operator< (const smart_ptr<T1> &pt1,
const smart_ptr<T2> &pt2)
{ return pt1.get() < pt2.get(); }
/*!smart_ptr<T1> <= smart_ptr<T2>. Never throws.*/
template<class T1, class T2>
inline bool operator<= (const smart_ptr<T1> &pt1,
const smart_ptr<T2> &pt2)
{ return pt1.get() <= pt2.get(); }
/*!smart_ptr<T1> > smart_ptr<T2>. Never throws.*/
template<class T1, class T2>
inline bool operator> (const smart_ptr<T1> &pt1,
const smart_ptr<T2> &pt2)
{ return pt1.get() > pt2.get(); }
/*!smart_ptr<T1> >= smart_ptr<T2>. Never throws.*/
template<class T1, class T2>
inline bool operator>= (const smart_ptr<T1> &pt1,
const smart_ptr<T2> &pt2)
{ return pt1.get() >= pt2.get(); }
/*!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.get(); }
/*!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 */
template<class T>
inline smart_ptr<T> operator+(std::ptrdiff_t diff, const smart_ptr<T>& right)
{ return right + diff; }
/*!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.get()- pt2.get(); }
/*!swap specialization */
template<class T>
inline void swap (smart_ptr<T> &pt,
smart_ptr<T> &pt2)
{
typename smart_ptr<T>::value_type *ptr = pt.get();
pt = pt2;
pt2 = ptr;
}
/*!get_pointer() enables boost::mem_fn to recognize smart_ptr.
Never throws.*/
template<class T>
inline T * get_pointer(smart_ptr<T> const & p)
{ return p.get(); }
/*!Simulation of static_cast between pointers. Never throws.*/
template<class T, class U>
inline smart_ptr<T>
static_pointer_cast(smart_ptr<U> const & r)
{
return smart_ptr<T>(r, detail::static_cast_tag());
}
/*!Simulation of const_cast between pointers. Never throws.*/
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());
}
/*!Simulation of dynamic_cast between pointers. Never throws.*/
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());
}
/*!Simulation of reinterpret_cast between pointers. Never throws.*/
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());
}
} //namespace intrusive {
} //namespace boost {
#endif //#ifndef BOOST_INTRUSIVE_SMART_PTR_HPP

227
test/test_container.hpp Normal file
View File

@@ -0,0 +1,227 @@
//////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2006 Matias Capeletto
// Copyright (c) 2007 Ion Gazta<74>aga
//
// 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)
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_TEST_TEST_CONTAINER_HPP
#define BOOST_INTRUSIVE_TEST_TEST_CONTAINER_HPP
// std
#include <cassert>
#include <algorithm>
#include <vector>
// Boost.Test
//#include "boost/test/included/test_exec_monitor.hpp"
namespace boost{
namespace intrusive{
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 destroyed, 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 >
void test_container( Container & c )
{
typedef typename Container::value_type value_type;
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;
const size_type num_elem = c.size();
BOOST_CHECK( c.empty() == (num_elem == 0) );
{
iterator it(c.begin()), itend(c.end());
size_type i;
for(i = 0; i < num_elem; ++i){
++it;
}
BOOST_CHECK( it == c.end() );
BOOST_CHECK( c.size() == i );
}
//Check iterator conversion
BOOST_CHECK( const_iterator(c.begin()) == c.cbegin() );
{
const_iterator it(c.cbegin()), itend(c.cend());
size_type i;
for(i = 0; i < num_elem; ++i){
++it;
}
BOOST_CHECK( it == c.cend() );
BOOST_CHECK( c.size() == i );
}
}
/*
template< class Container >
void test_container
( Container & c, typename Container::size_type num_elem
, Container & c2, typename Container::size_type num_elem2)
{
typedef typename Container::value_type value_type;
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:
//
//move-copy constructor
//move-assignment
test_container_helper(c, num_elem);
test_container_helper(c2, num_elem2);
//Test swap and test again
c.swap(c2);
test_container_helper(c, num_elem2);
test_container_helper(c2, num_elem);
}*/
template< class Sequence >
void test_sequence( Sequence & seq )
{
//First the container requirements
test_container(seq);
typedef Sequence::value_type value_type;
typedef Sequence::iterator iterator;
Sequence::size_type old_size(seq.size());
//Now test sequence requirements
//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)
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)
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)
iterator q1(it_from_erase), q2(it_from_erase);
++++q2;
it_from_erase = seq.erase(q1, q2);
BOOST_CHECK( seq.size() == old_size );
//clear(), assign()???
}
} // namespace test{
} // namespace intrusive{
} // namespace boost{
#endif // BOOST_INTRUSIVE_TEST_TEST_CONTAINER_HPP

65
test/test_templates.hpp Normal file
View File

@@ -0,0 +1,65 @@
#ifndef BOOST_INTRUSIVE_TEST_TEST_TEMPLATES_HPP
#define BOOST_INTRUSIVE_TEST_TEST_TEMPLATES_HPP
#include <vector>
namespace boost {
namespace intrusive {
namespace test {
template<class Container>
void test_shift()
{
typedef typename ValueTraits::value_type testvalue_t;
boost::test_tools::output_test_stream test_seq;
Container test_cont;
const int NumElem = 6;
std::vector<typename Container::value_type> values(NumElem);
for(int i = 0; i < NumElem; ++i){
values[i] = i+1;
}
const int num_values = (int)values.size();
std::vector<int> expected_values(num_values);
//Shift forward all possible positions 3 times
for(int i = 0; i < num_values*3; ++i){
test_cont.assign(values.begin(), values.end());
test_cont.shift_forward(i);
for(int j = 0; j < num_values; ++j){
expected_values[(j + num_values - i%num_values) % num_values] = (j + 1);
}
std::copy (test_cont.begin(), test_cont.end(),
std::ostream_iterator<testvalue_t> (test_seq));
std::stringstream stream;
std::copy (expected_values.begin(), expected_values.end(),
std::ostream_iterator<testvalue_t> (stream));
stream << std::ends;
BOOST_CHECK (test_seq.is_equal (stream.str().c_str()));
test_cont.clear();
}
//Shift backwards all possible positions
for(int i = 0; i < num_values*2; ++i){
test_cont.assign(values.begin(), values.end());
test_cont.shift_backwards(i);
for(int j = 0; j < num_values; ++j){
expected_values[(j + i) % num_values] = (j + 1);
}
std::copy (test_cont.begin(), test_cont.end(),
std::ostream_iterator<testvalue_t> (test_seq));
std::stringstream stream;
std::copy (expected_values.begin(), expected_values.end(),
std::ostream_iterator<testvalue_t> (stream));
stream << std::ends;
BOOST_CHECK (test_seq.is_equal (stream.str().c_str()));
test_cont.clear();
}
}
} //namespace test {
} //namespace intrusive {
} //namespace boost {
#endif //#ifndef BOOST_INTRUSIVE_TEST_TEST_TEMPLATES_HPP

View File

@@ -0,0 +1,463 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gazta<74>aga 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/unordered_set.hpp>
#include <boost/intrusive/detail/pointer_to_other.hpp>
#include "itestvalue.hpp"
#include "smart_ptr.hpp"
#include "common_functors.hpp"
#include <vector>
// Boost.Test
#include "boost/test/included/test_exec_monitor.hpp"
using namespace boost::intrusive;
static const std::size_t BucketSize = 11;
template<class ValueTraits>
struct test_unordered_multiset
{
typedef typename ValueTraits::value_type value_type;
static void test_all (std::vector<value_type>& values);
static void test_sort(std::vector<value_type>& values);
static void test_insert(std::vector<value_type>& values);
static void test_swap(std::vector<value_type>& values);
static void test_rehash(std::vector<value_type>& values);
static void test_find(std::vector<value_type>& values);
static void test_impl();
static void test_clone(std::vector<value_type>& values);
};
template<class ValueTraits>
void test_unordered_multiset<ValueTraits>::test_all (std::vector<typename ValueTraits::value_type>& values)
{
test_sort(values);
test_insert(values);
test_swap(values);
test_rehash(values);
test_find(values);
test_impl();
test_clone(values);
}
//test case due to an error in tree implementation:
template<class ValueTraits>
void test_unordered_multiset<ValueTraits>::test_impl()
{
typedef typename ValueTraits::value_type testvalue_t;
std::vector<testvalue_t> values (5);
for (int i = 0; i < 5; ++i)
values[i].value_ = i;
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);
for (int i = 0; i < 5; ++i)
testset.insert (values[i]);
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]));
}
//test: constructor, iterator, clear, reverse_iterator, front, back, size:
template<class ValueTraits>
void test_unordered_multiset<ValueTraits>::test_sort(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type testvalue_t;
boost::test_tools::output_test_stream test_seq;
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 testset1(buckets, BucketSize, values.begin(), values.end());
std::copy (testset1.begin(), testset1.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("122345"));
testset1.clear();
BOOST_CHECK (testset1.empty());
}
//test: insert, const_iterator, const_reverse_iterator, erase, iterator_to:
template<class ValueTraits>
void test_unordered_multiset<ValueTraits>::test_insert(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type testvalue_t;
boost::test_tools::output_test_stream test_seq;
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);
typedef typename unordered_multiset_type::value_type value_type;
testset.insert(&values[0] + 2, &values[0] + 5);
const unordered_multiset_type& const_testset = testset;
std::copy (const_testset.begin(), const_testset.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("145"));
BOOST_DEDUCED_TYPENAME unordered_multiset_type::iterator i = testset.begin();
BOOST_CHECK (i->value_ == 1);
i = testset.insert (values[0]);
BOOST_CHECK (&*i == &values[0]);
i = testset.iterator_to (values[2]);
BOOST_CHECK (&*i == &values[2]);
testset.erase(i);
//test post-increment:
for (BOOST_DEDUCED_TYPENAME unordered_multiset_type::const_iterator i = const_testset.begin(),
e = const_testset.end(); i != e; i++)
test_seq << *i;
BOOST_CHECK (test_seq.is_equal ("135"));
testset.clear();
testset.insert(&values[0], &values[0] + values.size());
test_seq.clear();
for (BOOST_DEDUCED_TYPENAME unordered_multiset_type::const_iterator i = const_testset.begin(),
e = const_testset.end(); i != e; i++)
test_seq << *i;
BOOST_CHECK (test_seq.is_equal ("122345"));
BOOST_CHECK (testset.erase(1) == 1);
BOOST_CHECK (testset.erase(2) == 2);
BOOST_CHECK (testset.erase(3) == 1);
BOOST_CHECK (testset.erase(4) == 1);
BOOST_CHECK (testset.erase(5) == 1);
BOOST_CHECK (testset.empty() == true);
//Now with a single bucket
typename unordered_multiset_type::bucket_type single_bucket[1];
unordered_multiset_type testset2(single_bucket, 1);
testset2.insert(&values[0], &values[0] + values.size());
BOOST_CHECK (testset2.erase(5) == 1);
BOOST_CHECK (testset2.erase(2) == 2);
BOOST_CHECK (testset2.erase(1) == 1);
BOOST_CHECK (testset2.erase(4) == 1);
BOOST_CHECK (testset2.erase(3) == 1);
BOOST_CHECK (testset2.empty() == true);
}
//test: insert (seq-version), swap, erase (seq-version), size:
template<class ValueTraits>
void test_unordered_multiset<ValueTraits>::test_swap(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type testvalue_t;
boost::test_tools::output_test_stream test_seq;
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 testset1(buckets, BucketSize, &values[0], &values[0] + 2);
typename unordered_multiset_type::bucket_type buckets2 [BucketSize];
unordered_multiset_type testset2(buckets2, BucketSize);
testset2.insert (&values[0] + 2, &values[0] + 6);
testset1.swap (testset2);
std::copy (testset1.begin(), testset1.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("1245"));
//test post-increment:
for (BOOST_DEDUCED_TYPENAME unordered_multiset_type::iterator i = testset2.begin(),
e = testset2.end(); i != e; i++)
test_seq << *i;
BOOST_CHECK (test_seq.is_equal ("23"));
testset1.erase (testset1.iterator_to(values[5]), testset1.end());
BOOST_CHECK (testset1.size() == 1);
// BOOST_CHECK (&testset1.front() == &values[3]);
BOOST_CHECK (&*testset1.begin() == &values[3]);
}
//test: rehash:
template<class ValueTraits>
void test_unordered_multiset<ValueTraits>::test_rehash(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type testvalue_t;
boost::test_tools::output_test_stream test_seq;
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 buckets1 [BucketSize];
unordered_multiset_type testset1(buckets1, BucketSize, &values[0], &values[0] + 6);
BOOST_CHECK (testset1.size() == 6);
std::copy (testset1.begin(), testset1.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("122345"));
typename unordered_multiset_type::bucket_type buckets2 [2];
testset1.rehash(buckets2, 2);
BOOST_CHECK (testset1.size() == 6);
std::copy (testset1.begin(), testset1.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("422531"));
typename unordered_multiset_type::bucket_type buckets3 [BucketSize*2];
testset1.rehash(buckets3, BucketSize*2);
BOOST_CHECK (testset1.size() == 6);
std::copy (testset1.begin(), testset1.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("122345"));
//Now rehash reducing the buckets
testset1.rehash(buckets3, 2);
BOOST_CHECK (testset1.size() == 6);
std::copy (testset1.begin(), testset1.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("422531"));
//Now rehash increasing the buckets
testset1.rehash(buckets3, BucketSize*2);
BOOST_CHECK (testset1.size() == 6);
std::copy (testset1.begin(), testset1.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("122345"));
}
//test: find, equal_range (lower_bound, upper_bound):
template<class ValueTraits>
void test_unordered_multiset<ValueTraits>::test_find(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type testvalue_t;
boost::test_tools::output_test_stream test_seq;
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, values.begin(), values.end());
typedef BOOST_DEDUCED_TYPENAME unordered_multiset_type::iterator iterator;
testvalue_t cmp_val;
cmp_val.value_ = 2;
iterator i = testset.find (cmp_val);
BOOST_CHECK (i->value_ == 2);
BOOST_CHECK ((++i)->value_ == 2);
std::pair<iterator,iterator> range = testset.equal_range (cmp_val);
BOOST_CHECK (range.first->value_ == 2);
BOOST_CHECK (range.second->value_ == 3);
BOOST_CHECK (std::distance (range.first, range.second) == 2);
cmp_val.value_ = 7;
BOOST_CHECK (testset.find (cmp_val) == testset.end());
}
template<class ValueTraits>
void test_unordered_multiset<ValueTraits>
::test_clone(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;
{
//Test with equal bucket arrays
typename unordered_multiset_type::bucket_type buckets1 [BucketSize];
typename unordered_multiset_type::bucket_type buckets2 [BucketSize];
unordered_multiset_type testset1 (buckets1, BucketSize, values.begin(), values.end());
unordered_multiset_type testset2 (buckets2, BucketSize);
testset2.clone_from(testset1, test::new_cloner(), test::delete_destroyer());
//Ordering is not guarantee in the cloning so insert data in a set and test
std::multiset<typename ValueTraits::value_type>
src(testset1.begin(), testset1.end());
std::multiset<typename ValueTraits::value_type>
dst(testset2.begin(), testset2.end());
BOOST_CHECK (src == dst);
testset2.clear_and_destroy(test::delete_destroyer());
BOOST_CHECK (testset2.empty());
}
{
//Test with bigger source bucket arrays
typename unordered_multiset_type::bucket_type buckets1 [BucketSize*2];
typename unordered_multiset_type::bucket_type buckets2 [BucketSize];
unordered_multiset_type testset1 (buckets1, BucketSize*2, values.begin(), values.end());
unordered_multiset_type testset2 (buckets2, BucketSize);
testset2.clone_from(testset1, test::new_cloner(), test::delete_destroyer());
//Ordering is not guarantee in the cloning so insert data in a set and test
std::multiset<typename ValueTraits::value_type>
src(testset1.begin(), testset1.end());
std::multiset<typename ValueTraits::value_type>
dst(testset2.begin(), testset2.end());
BOOST_CHECK (src == dst);
testset2.clear_and_destroy(test::delete_destroyer());
BOOST_CHECK (testset2.empty());
}
{
//Test with smaller source bucket arrays
typename unordered_multiset_type::bucket_type buckets1 [BucketSize];
typename unordered_multiset_type::bucket_type buckets2 [BucketSize*2];
unordered_multiset_type testset1 (buckets1, BucketSize, values.begin(), values.end());
unordered_multiset_type testset2 (buckets2, BucketSize*2);
testset2.clone_from(testset1, test::new_cloner(), test::delete_destroyer());
//Ordering is not guarantee in the cloning so insert data in a set and test
std::multiset<typename ValueTraits::value_type>
src(testset1.begin(), testset1.end());
std::multiset<typename ValueTraits::value_type>
dst(testset2.begin(), testset2.end());
BOOST_CHECK (src == dst);
testset2.clear_and_destroy(test::delete_destroyer());
BOOST_CHECK (testset2.empty());
}
}
template<class VoidPointer, bool constant_time_size>
class test_main_template
{
public:
int operator()()
{
typedef testvalue<VoidPointer, constant_time_size> testvalue_t;
static const int random_init[6] = { 3, 2, 4, 1, 5, 2 };
std::vector<testvalue<VoidPointer, constant_time_size> > data (6);
for (int i = 0; i < 6; ++i)
data[i].value_ = random_init[i];
test_unordered_multiset <typename testvalue_t::unordered_set_base_hook::template
value_traits<testvalue_t> >::test_all(data);
test_unordered_multiset <typename testvalue_t::unordered_set_member_hook::template
value_traits<testvalue_t, &testvalue_t::unordered_set_node_> >::test_all(data);
return 0;
}
};
template<class VoidPointer>
class test_main_template<VoidPointer, false>
{
public:
int operator()()
{
typedef testvalue<VoidPointer, false> testvalue_t;
static const int random_init[6] = { 3, 2, 4, 1, 5, 2 };
std::vector<testvalue<VoidPointer, false> > data (6);
for (int i = 0; i < 6; ++i)
data[i].value_ = random_init[i];
test_unordered_multiset <typename testvalue_t::unordered_set_base_hook::template
value_traits<testvalue_t> >::test_all(data);
test_unordered_multiset <typename testvalue_t::unordered_set_member_hook::template
value_traits<testvalue_t, &testvalue_t::unordered_set_node_> >::test_all(data);
test_unordered_multiset <typename testvalue_t::unordered_set_auto_base_hook::template
value_traits<testvalue_t> >::test_all(data);
test_unordered_multiset <typename testvalue_t::unordered_set_auto_member_hook::template
value_traits<testvalue_t, &testvalue_t::unordered_set_auto_node_> >::test_all(data);
return 0;
}
};
//Explicit instantiations of non-counted classes
template class boost::intrusive::unordered_multiset
< unordered_set_base_raw_t
, boost::hash<unordered_set_base_raw_t::value_type>
, std::equal_to<unordered_set_base_raw_t::value_type>, false>;
template class boost::intrusive::unordered_multiset
< unordered_set_member_raw_t
, boost::hash<unordered_set_member_raw_t::value_type>
, std::equal_to<unordered_set_member_raw_t::value_type>, false>;
template class boost::intrusive::unordered_multiset
< unordered_set_auto_base_raw
, boost::hash<unordered_set_auto_base_raw::value_type>
, std::equal_to<unordered_set_auto_base_raw::value_type>, false>;
template class boost::intrusive::unordered_multiset
< unordered_set_auto_member_raw
, boost::hash<unordered_set_auto_member_raw::value_type>
, std::equal_to<unordered_set_auto_member_raw::value_type>, false>;
template class boost::intrusive::unordered_multiset
< unordered_set_base_smart
, boost::hash<unordered_set_base_smart::value_type>
, std::equal_to<unordered_set_base_smart::value_type>, false>;
template class boost::intrusive::unordered_multiset
< unordered_set_member_smart
, boost::hash<unordered_set_member_smart::value_type>
, std::equal_to<unordered_set_member_smart::value_type>, false>;
template class boost::intrusive::unordered_multiset
< unordered_set_auto_base_smart
, boost::hash<unordered_set_auto_base_smart::value_type>
, std::equal_to<unordered_set_auto_base_smart::value_type>, false>;
template class boost::intrusive::unordered_multiset
< unordered_set_auto_member_smart
, boost::hash<unordered_set_auto_member_smart::value_type>
, std::equal_to<unordered_set_auto_member_smart::value_type>, false>;
//Explicit instantiation of counted classes
template class boost::intrusive::unordered_multiset
< unordered_set_base_raw_t
, boost::hash<unordered_set_base_raw_t::value_type>
, std::equal_to<unordered_set_base_raw_t::value_type>, true>;
template class boost::intrusive::unordered_multiset
< unordered_set_member_raw_t
, boost::hash<unordered_set_base_raw_t::value_type>
, std::equal_to<unordered_set_member_raw_t::value_type>, true>;
template class boost::intrusive::unordered_multiset
< unordered_set_base_smart_t
, boost::hash<unordered_set_base_smart_t::value_type>
, std::equal_to<unordered_set_base_smart_t::value_type>, true>;
template class boost::intrusive::unordered_multiset
< unordered_set_member_smart_t
, boost::hash<unordered_set_member_smart_t::value_type>
, std::equal_to<unordered_set_member_smart_t::value_type>, true>;
int test_main( int, char* [] )
{
test_main_template<void*, false>()();
test_main_template<boost::intrusive::smart_ptr<void>, false>()();
test_main_template<void*, true>()();
test_main_template<boost::intrusive::smart_ptr<void>, true>()();
return 0;
}

438
test/unordered_set_test.cpp Normal file
View File

@@ -0,0 +1,438 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gazta<74>aga 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/unordered_set.hpp>
#include <boost/intrusive/detail/pointer_to_other.hpp>
#include "itestvalue.hpp"
#include "smart_ptr.hpp"
#include "common_functors.hpp"
#include <vector>
#include <set>
// Boost.Test
#include "boost/test/included/test_exec_monitor.hpp"
using namespace boost::intrusive;
static const std::size_t BucketSize = 11;
template<class ValueTraits>
struct test_unordered_set
{
typedef typename ValueTraits::value_type value_type;
static void test_all(std::vector<value_type>& values);
static void test_sort(std::vector<value_type>& values);
static void test_insert(std::vector<value_type>& values);
static void test_swap(std::vector<value_type>& values);
static void test_rehash(std::vector<value_type>& values);
static void test_find(std::vector<value_type>& values);
static void test_impl();
static void test_clone(std::vector<value_type>& values);
};
template<class ValueTraits>
void test_unordered_set<ValueTraits>::test_all(std::vector<typename ValueTraits::value_type>& values)
{
test_sort(values);
test_insert(values);
test_swap(values);
test_rehash(values);
test_find(values);
test_impl();
test_clone(values);
}
//test case due to an error in tree implementation:
template<class ValueTraits>
void test_unordered_set<ValueTraits>::test_impl()
{
typedef typename ValueTraits::value_type testvalue_t;
std::vector<testvalue_t> values (5);
for (int i = 0; i < 5; ++i)
values[i].value_ = i;
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);
for (int i = 0; i < 5; ++i)
testset.insert (values[i]);
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]));
}
//test: constructor, iterator, clear, reverse_iterator, front, back, size:
template<class ValueTraits>
void test_unordered_set<ValueTraits>::test_sort(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type testvalue_t;
boost::test_tools::output_test_stream test_seq;
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 testset1(buckets, BucketSize, values.begin(), values.end());
BOOST_CHECK (5 == std::distance(testset1.begin(), testset1.end()));
std::copy (testset1.begin(), testset1.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("12345"));
testset1.clear();
BOOST_CHECK (testset1.empty());
}
//test: insert, const_iterator, const_reverse_iterator, erase, iterator_to:
template<class ValueTraits>
void test_unordered_set<ValueTraits>::test_insert(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type testvalue_t;
boost::test_tools::output_test_stream test_seq;
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[0] + 2, &values[0] + 5);
const unordered_set_type& const_testset = testset;
std::copy (const_testset.begin(), const_testset.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("145"));
BOOST_DEDUCED_TYPENAME unordered_set_type::iterator i = testset.begin();
BOOST_CHECK (i->value_ == 1);
i = testset.insert(values[0]).first;
BOOST_CHECK (&*i == &values[0]);
i = testset.iterator_to (values[2]);
BOOST_CHECK (&*i == &values[2]);
testset.erase (i);
//test post-increment:
for (BOOST_DEDUCED_TYPENAME unordered_set_type::const_iterator i = const_testset.begin(),
e = const_testset.end(); i != e; i++)
test_seq << *i;
BOOST_CHECK (test_seq.is_equal ("135"));
}
//test: insert (seq-version), swap, erase (seq-version), size:
template<class ValueTraits>
void test_unordered_set<ValueTraits>::test_swap(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type testvalue_t;
boost::test_tools::output_test_stream test_seq;
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 buckets1 [BucketSize];
unordered_set_type testset1(buckets1, BucketSize, &values[0], &values[0] + 2);
typename unordered_set_type::bucket_type buckets2 [BucketSize];
unordered_set_type testset2(buckets2, BucketSize);
testset2.insert (&values[0] + 2, &values[0] + 6);
testset1.swap (testset2);
std::copy (testset1.begin(), testset1.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("1245"));
//test post-increment:
for (BOOST_DEDUCED_TYPENAME unordered_set_type::iterator i = testset2.begin(),
e = testset2.end(); i != e; i++)
test_seq << *i;
BOOST_CHECK (test_seq.is_equal ("23"));
testset1.erase (testset1.iterator_to(values[5]), testset1.end());
BOOST_CHECK (testset1.size() == 1);
// BOOST_CHECK (&testset1.front() == &values[3]);
BOOST_CHECK (&*testset1.begin() == &values[3]);
}
//test: rehash:
template<class ValueTraits>
void test_unordered_set<ValueTraits>::test_rehash(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type testvalue_t;
boost::test_tools::output_test_stream test_seq;
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 buckets1 [BucketSize];
unordered_set_type testset1(buckets1, BucketSize, &values[0], &values[0] + 6);
BOOST_CHECK (testset1.size() == 5);
std::copy (testset1.begin(), testset1.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("12345"));
typename unordered_set_type::bucket_type buckets2 [2];
testset1.rehash(buckets2, 2);
BOOST_CHECK (testset1.size() == 5);
std::copy (testset1.begin(), testset1.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("42531"));
typename unordered_set_type::bucket_type buckets3 [BucketSize*2];
testset1.rehash(buckets3, BucketSize*2);
BOOST_CHECK (testset1.size() == 5);
std::copy (testset1.begin(), testset1.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("12345"));
//Now rehash reducing the buckets
testset1.rehash(buckets3, 2);
BOOST_CHECK (testset1.size() == 5);
std::copy (testset1.begin(), testset1.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("42531"));
//Now rehash increasing the buckets
testset1.rehash(buckets3, BucketSize*2);
BOOST_CHECK (testset1.size() == 5);
std::copy (testset1.begin(), testset1.end(),
std::ostream_iterator<testvalue_t> (test_seq));
BOOST_CHECK (test_seq.is_equal ("12345"));
}
//test: find, equal_range (lower_bound, upper_bound):
template<class ValueTraits>
void test_unordered_set<ValueTraits>::test_find(std::vector<typename ValueTraits::value_type>& values)
{
typedef typename ValueTraits::value_type testvalue_t;
boost::test_tools::output_test_stream test_seq;
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, values.begin(), values.end());
typedef BOOST_DEDUCED_TYPENAME unordered_set_type::iterator iterator;
testvalue_t cmp_val;
cmp_val.value_ = 2;
iterator i = testset.find (cmp_val);
BOOST_CHECK (i->value_ == 2);
BOOST_CHECK ((++i)->value_ != 2);
std::pair<iterator,iterator> range = testset.equal_range (cmp_val);
BOOST_CHECK (range.first->value_ == 2);
BOOST_CHECK (range.second->value_ == 3);
BOOST_CHECK (std::distance (range.first, range.second) == 1);
cmp_val.value_ = 7;
BOOST_CHECK (testset.find (cmp_val) == testset.end());
}
template<class ValueTraits>
void test_unordered_set<ValueTraits>
::test_clone(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;
{
//Test with equal bucket arrays
typename unordered_set_type::bucket_type buckets1 [BucketSize];
typename unordered_set_type::bucket_type buckets2 [BucketSize];
unordered_set_type testset1 (buckets1, BucketSize, values.begin(), values.end());
unordered_set_type testset2 (buckets2, BucketSize);
testset2.clone_from(testset1, test::new_cloner(), test::delete_destroyer());
//Ordering is not guarantee in the cloning so insert data in a set and test
std::set<typename ValueTraits::value_type>
src(testset1.begin(), testset1.end());
std::set<typename ValueTraits::value_type>
dst(testset2.begin(), testset2.end());
BOOST_CHECK (src == dst );
testset2.clear_and_destroy(test::delete_destroyer());
BOOST_CHECK (testset2.empty());
}
{
//Test with bigger source bucket arrays
typename unordered_set_type::bucket_type buckets1 [BucketSize*2];
typename unordered_set_type::bucket_type buckets2 [BucketSize];
unordered_set_type testset1 (buckets1, BucketSize*2, values.begin(), values.end());
unordered_set_type testset2 (buckets2, BucketSize);
testset2.clone_from(testset1, test::new_cloner(), test::delete_destroyer());
//Ordering is not guarantee in the cloning so insert data in a set and test
std::set<typename ValueTraits::value_type>
src(testset1.begin(), testset1.end());
std::set<typename ValueTraits::value_type>
dst(testset2.begin(), testset2.end());
BOOST_CHECK (src == dst );
testset2.clear_and_destroy(test::delete_destroyer());
BOOST_CHECK (testset2.empty());
}
{
//Test with smaller source bucket arrays
typename unordered_set_type::bucket_type buckets1 [BucketSize];
typename unordered_set_type::bucket_type buckets2 [BucketSize*2];
unordered_set_type testset1 (buckets1, BucketSize, values.begin(), values.end());
unordered_set_type testset2 (buckets2, BucketSize*2);
testset2.clone_from(testset1, test::new_cloner(), test::delete_destroyer());
//Ordering is not guarantee in the cloning so insert data in a set and test
std::set<typename ValueTraits::value_type>
src(testset1.begin(), testset1.end());
std::set<typename ValueTraits::value_type>
dst(testset2.begin(), testset2.end());
BOOST_CHECK (src == dst );
testset2.clear_and_destroy(test::delete_destroyer());
BOOST_CHECK (testset2.empty());
}
}
template<class VoidPointer, bool constant_time_size>
class test_main_template
{
public:
int operator()()
{
typedef testvalue<VoidPointer, constant_time_size> testvalue_t;
static const int random_init[6] = { 3, 2, 4, 1, 5, 2 };
std::vector<testvalue<VoidPointer, constant_time_size> > data (6);
for (int i = 0; i < 6; ++i)
data[i].value_ = random_init[i];
test_unordered_set <typename testvalue_t::unordered_set_base_hook::template
value_traits<testvalue_t> >::test_all(data);
test_unordered_set <typename testvalue_t::unordered_set_member_hook::template
value_traits<testvalue_t, &testvalue_t::unordered_set_node_> >::test_all(data);
return 0;
}
};
template<class VoidPointer>
class test_main_template<VoidPointer, false>
{
public:
int operator()()
{
typedef testvalue<VoidPointer, false> testvalue_t;
static const int random_init[6] = { 3, 2, 4, 1, 5, 2 };
std::vector<testvalue<VoidPointer, false> > data (6);
for (int i = 0; i < 6; ++i)
data[i].value_ = random_init[i];
test_unordered_set <typename testvalue_t::unordered_set_base_hook::template
value_traits<testvalue_t> >::test_all(data);
test_unordered_set <typename testvalue_t::unordered_set_member_hook::template
value_traits<testvalue_t, &testvalue_t::unordered_set_node_> >::test_all(data);
test_unordered_set <typename testvalue_t::unordered_set_auto_base_hook::template
value_traits<testvalue_t> >::test_all(data);
test_unordered_set <typename testvalue_t::unordered_set_auto_member_hook::template
value_traits<testvalue_t, &testvalue_t::unordered_set_auto_node_> >::test_all(data);
return 0;
}
};
template class boost::intrusive::unordered_set
< unordered_set_base_raw_t
, boost::hash<unordered_set_base_raw_t::value_type>
, std::equal_to<unordered_set_base_raw_t::value_type>, false>;
template class boost::intrusive::unordered_set
< unordered_set_member_raw_t
, boost::hash<unordered_set_member_raw_t::value_type>
, std::equal_to<unordered_set_member_raw_t::value_type>, false>;
template class boost::intrusive::unordered_set
< unordered_set_auto_base_raw
, boost::hash<unordered_set_auto_base_raw::value_type>
, std::equal_to<unordered_set_auto_base_raw::value_type>, false>;
template class boost::intrusive::unordered_set
< unordered_set_auto_member_raw
, boost::hash<unordered_set_auto_member_raw::value_type>
, std::equal_to<unordered_set_auto_member_raw::value_type>, false>;
template class boost::intrusive::unordered_set
< unordered_set_base_smart
, boost::hash<unordered_set_base_smart::value_type>
, std::equal_to<unordered_set_base_smart::value_type>, false>;
template class boost::intrusive::unordered_set
< unordered_set_member_smart
, boost::hash<unordered_set_member_smart::value_type>
, std::equal_to<unordered_set_member_smart::value_type>, false>;
template class boost::intrusive::unordered_set
< unordered_set_auto_base_smart
, boost::hash<unordered_set_auto_base_smart::value_type>
, std::equal_to<unordered_set_auto_base_smart::value_type>, false>;
template class boost::intrusive::unordered_set
< unordered_set_auto_member_smart
, boost::hash<unordered_set_auto_member_smart::value_type>
, std::equal_to<unordered_set_auto_member_smart::value_type>, false>;
//Explicit instantiation of counted classes
template class boost::intrusive::unordered_set
< unordered_set_base_raw_t
, boost::hash<unordered_set_base_raw_t::value_type>
, std::equal_to<unordered_set_base_raw_t::value_type>, true>;
template class boost::intrusive::unordered_set
< unordered_set_member_raw_t
, boost::hash<unordered_set_base_raw_t::value_type>
, std::equal_to<unordered_set_member_raw_t::value_type>, true>;
template class boost::intrusive::unordered_set
< unordered_set_base_smart_t
, boost::hash<unordered_set_base_smart_t::value_type>
, std::equal_to<unordered_set_base_smart_t::value_type>, true>;
template class boost::intrusive::unordered_set
< unordered_set_member_smart_t
, boost::hash<unordered_set_member_smart_t::value_type>
, std::equal_to<unordered_set_member_smart_t::value_type>, true>;
int test_main( int, char* [] )
{
test_main_template<void*, false>()();
test_main_template<boost::intrusive::smart_ptr<void>, false>()();
test_main_template<void*, true>()();
test_main_template<boost::intrusive::smart_ptr<void>, true>()();
return 0;
}