More changes for Boost 1.45

[SVN r64984]
This commit is contained in:
Ion Gaztañaga
2010-08-24 17:13:19 +00:00
parent ba311e69cf
commit 94a5c533f9
35 changed files with 893 additions and 64 deletions

View File

@@ -1,5 +1,5 @@
[/ [/
/ Copyright (c) 2007-2009 Ion Gaztanaga / Copyright (c) 2007-2010 Ion Gaztanaga
/ /
/ Distributed under the Boost Software License, Version 1.0. (See accompanying / 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) / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -8,7 +8,7 @@
[library Boost.Intrusive [library Boost.Intrusive
[quickbook 1.4] [quickbook 1.4]
[authors [Krzikalla, Olaf], [Gaztanaga, Ion]] [authors [Krzikalla, Olaf], [Gaztanaga, Ion]]
[copyright 2005 Olaf Krzikalla, 2006-2009 Ion Gaztanaga] [copyright 2005 Olaf Krzikalla, 2006-2010 Ion Gaztanaga]
[id intrusive] [id intrusive]
[dirname intrusive] [dirname intrusive]
[purpose Intrusive containers] [purpose Intrusive containers]
@@ -198,7 +198,7 @@ Intrusive containers have also downsides:
swapping can be used to implement move capabilities. To ease the implementation of swapping can be used to implement move capabilities. To ease the implementation of
copy constructors and assignment operators of classes storing [*Boost.Intrusive] copy constructors and assignment operators of classes storing [*Boost.Intrusive]
containers, [*Boost.Intrusive] offers special cloning functions. See containers, [*Boost.Intrusive] offers special cloning functions. See
[link intrusive.clone_from Cloning [*Boost.Intrusive] containers] section for more information. [link intrusive.clone_from Cloning Boost.Intrusive containers] section for more information.
* Analyzing the thread safety of a program that uses containers is harder with intrusive containers, because * Analyzing the thread safety of a program that uses containers is harder with intrusive containers, because
the container might be modified indirectly without an explicit call to a container member. the container might be modified indirectly without an explicit call to a container member.
@@ -246,7 +246,10 @@ just include:
Every class to be inserted in an intrusive container, needs to contain a hook that Every class to be inserted in an intrusive container, needs to contain a hook that
will offer the necessary data and resources to be insertable in the container. will offer the necessary data and resources to be insertable in the container.
With [*Boost.Intrusive] you just choose the hook to be a public base class or With [*Boost.Intrusive] you just choose the hook to be a public base class or
a public member of the class to be inserted. a public member of the class to be inserted. [*Boost.Intrusive] also offers
more flexible hooks for advanced users, as explained in the chapter
[link intrusive.function_hooks Using function hooks], but usually base or member
hooks are good enough for most users.
[section:usage_base_hook Using base hooks] [section:usage_base_hook Using base hooks]
@@ -451,6 +454,7 @@ stored object is not bound to or managed by the container:
[endsect] [endsect]
[endsect] [endsect]
[section:usage_when When to use?] [section:usage_when When to use?]
@@ -2147,7 +2151,7 @@ that erase an element from the container.
[endsect] [endsect]
[section:clone_from Cloning [*Boost.Intrusive] containers] [section:clone_from Cloning Boost.Intrusive containers]
As previously mentioned, [*Boost.Intrusive] containers are [*non-copyable and non-assignable], because As previously mentioned, [*Boost.Intrusive] containers are [*non-copyable and non-assignable], because
intrusive containers don't allocate memory at all. To implement a copy-constructor or assignment operator, intrusive containers don't allocate memory at all. To implement a copy-constructor or assignment operator,
@@ -2190,6 +2194,105 @@ Here is an example of `clone_from`:
[endsect] [endsect]
[section:function_hooks Using function hooks]
A programmer might find that base or member hooks are not flexible enough in some situations.
In some applications it would be optimal to put a hook deep inside a member of a class or just outside the class.
[*Boost.Intrusive] has an easy option to allow such cases: [classref boost::intrusive::function_hook function_hook].
This option is similar to [classref boost::intrusive::member_hook member_hook] or
[classref boost::intrusive::base_hook base_hook], but the programmer can specify a function
object that tells the container how to obtain a hook from a value and vice versa.
The programmer just needs to define the following function object:
[c++]
//This functor converts between value_type and a hook_type
struct Functor
{
//Required types
typedef /*impl-defined*/ hook_type;
typedef /*impl-defined*/ hook_ptr;
typedef /*impl-defined*/ const_hook_ptr;
typedef /*impl-defined*/ value_type;
typedef /*impl-defined*/ pointer;
typedef /*impl-defined*/ const_pointer;
//Required static functions
static hook_ptr to_hook_ptr (value_type &value);
static const_hook_ptr to_hook_ptr(const value_type &value);
static pointer to_value_ptr(hook_ptr n);
static const_pointer to_value_ptr(const_hook_ptr n);
};
Converting from values to hooks is generally easy, since most hooks are
in practice members or base classes of class data members. The inverse operation
is a bit more complicated, but [*Boost.Intrusive] offers a bit of help with the function
[funcref boost::intrusive::get_parent_from_member get_parent_from_member],
which allows easy conversions from the address of a data member to the address of
the parent holding that member. Let's see a little example of
[classref boost::intrusive::function_hook function_hook]:
[import ../example/doc_function_hooks.cpp]
[doc_function_hooks]
[endsect]
[section:recursive Recursive Boost.Intrusive containers]
[*Boost.Intrusive] containers can be used to define recursive structures very easily,
allowing complex data structures with very low overhead. Let's see an example:
[import ../example/doc_recursive.cpp]
[doc_recursive]
Recursive data structures using [*Boost.Intrusive] containers must avoid using hook deduction to avoid early type
instantiation:
[c++]
//This leads to compilation error (Recursive is instantiated by
//'list' to deduce hook properties (pointer type, tag, safe-mode...)
class Recursive
{ //...
list< Recursive > l;
//...
};
//Ok, programmer must specify the hook type to avoid early Recursive instantiation
class Recursive
{ //...
list< Recursive, base_hook<BaseHook> > l;
//...
};
Member hooks are not suitable for recursive structures:
[c++]
class Recursive
{
private:
Recursive(const Recursive&);
Recursive & operator=(const Recursive&);
public:
list_member_hook<> memhook;
list< Recursive, member_hook<Recursive, list_member_hook<>, &Recursive::memhook> > children;
};
Specifying `&Recursive::memhook` (that is, the offset between memhook and Recursive) provokes an early
instantiation of `Recursive`. To define recursive structures using member hooks, a programmer should use
[classref ::boost::interprocess::function_hook function_hook]:
[import ../example/doc_recursive_member.cpp]
[doc_recursive_member]
[endsect]
[section:using_smart_pointers Using smart pointers with Boost.Intrusive containers] [section:using_smart_pointers Using smart pointers with Boost.Intrusive containers]
[*Boost.Intrusive] hooks can be configured to use other pointers than raw pointers. [*Boost.Intrusive] hooks can be configured to use other pointers than raw pointers.
@@ -3313,7 +3416,7 @@ If you are concerned with file sizes and compilation times, this option is your
When designing [*Boost.Intrusive] the following guidelines have been taken into account: When designing [*Boost.Intrusive] the following guidelines have been taken into account:
[section: Boost.Intrusive in performance sensitive environments] [section:performance_sensitive Boost.Intrusive in performance sensitive environments]
[*Boost.Intrusive] should be a valuable tool in performance sensitive environments, [*Boost.Intrusive] should be a valuable tool in performance sensitive environments,
and following this guideline, [*Boost.Intrusive] has been designed to offer well and following this guideline, [*Boost.Intrusive] has been designed to offer well
@@ -3327,7 +3430,7 @@ constructions.
[endsect] [endsect]
[section: Boost.Intrusive in space constrained environments] [section:space_constrained Boost.Intrusive in space constrained environments]
[*Boost.Intrusive] should be useful in space constrained environments, [*Boost.Intrusive] should be useful in space constrained environments,
and following this guideline [*Boost.Intrusive] separates node algorithms and following this guideline [*Boost.Intrusive] separates node algorithms
@@ -3344,7 +3447,7 @@ when the container is empty or contains few values.
[endsect] [endsect]
[section: Boost.Intrusive as a basic building block] [section:basic_building_block Boost.Intrusive as a basic building block]
[*Boost.Intrusive] can be a basic building block to build more complex containers [*Boost.Intrusive] can be a basic building block to build more complex containers
and this potential has motivated many design decisions. For example, the ability and this potential has motivated many design decisions. For example, the ability
@@ -3358,7 +3461,7 @@ functions come in handy when implementing non-intrusive containers
[endsect] [endsect]
[section: Extending Boost.Intrusive] [section:extending_intrusive Extending Boost.Intrusive]
[*Boost.Intrusive] offers a wide range of containers but also allows the [*Boost.Intrusive] offers a wide range of containers but also allows the
construction of custom containers reusing [*Boost.Intrusive] elements. construction of custom containers reusing [*Boost.Intrusive] elements.
@@ -3728,6 +3831,28 @@ all the objects to be inserted in intrusive containers in containers like `std::
[section:release_notes Release Notes] [section:release_notes Release Notes]
[section:release_notes_boost_1_45_00 Boost 1.45 Release]
* Added `function_hook` option.
* Fixed bugs
[@https://svn.boost.org/trac/boost/ticket/3668 #3668],
[@https://svn.boost.org/trac/boost/ticket/3339 #3688],
[@https://svn.boost.org/trac/boost/ticket/3698 #3698],
[@https://svn.boost.org/trac/boost/ticket/3706 #3706],
[@https://svn.boost.org/trac/boost/ticket/3721 #3721].
[@https://svn.boost.org/trac/boost/ticket/3729 #3729],
[@https://svn.boost.org/trac/boost/ticket/3746 #3746],
[@https://svn.boost.org/trac/boost/ticket/3781 #3781],
[@https://svn.boost.org/trac/boost/ticket/3829 #3829],
[@https://svn.boost.org/trac/boost/ticket/3840 #3840],
[@https://svn.boost.org/trac/boost/ticket/3339 #3339],
[@https://svn.boost.org/trac/boost/ticket/3419 #3419],
[@https://svn.boost.org/trac/boost/ticket/3431 #3431],
[@https://svn.boost.org/trac/boost/ticket/4021 #4021],
[endsect]
[section:release_notes_boost_1_40_00 Boost 1.40 Release] [section:release_notes_boost_1_40_00 Boost 1.40 Release]
* Code cleanup in tree_algorithms.hpp and avl_tree_algorithms.hpp * Code cleanup in tree_algorithms.hpp and avl_tree_algorithms.hpp
@@ -3849,29 +3974,4 @@ helpful discussions.
[endsect] [endsect]
[xinclude autodoc.xml] [xinclude autodoc.xml]
[section:license_notices License notices]
Most of the internal implementation of red-black trees is based on that of SGI STL stl_tree.h file:
['Copyright (c) 1996,1997 Silicon Graphics Computer Systems, Inc.
Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. Silicon Graphics makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty.]
['Copyright (c) 1994 Hewlett-Packard Company
Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. Hewlett-Packard Company makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty.]
The tree destruction algorithm is based on Julienne Walker and The EC Team code:
['This code is in the public domain. Anyone may
use it or change it in any way that they see
fit. The author assumes no responsibility for
damages incurred through use of the original
code or any variations thereof.]
['It is requested, but not required, that due
credit is given to the original author and
anyone who has modified the code through
a header comment, such as this one.]
[endsect]

View File

@@ -0,0 +1,76 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2010-2010
//
// 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/detail/config_begin.hpp>
//[doc_function_hooks
#include <boost/intrusive/list.hpp>
#include <boost/intrusive/parent_from_member.hpp>
using namespace boost::intrusive;
struct MyClass
{
int dummy;
//This internal type has a member hook
struct InnerNode
{
int dummy;
list_member_hook<> hook;
} inner;
};
//This functor converts between MyClass and InnerNode's member hook
struct Functor
{
//Required types
typedef list_member_hook<> hook_type;
typedef hook_type* hook_ptr;
typedef const hook_type* const_hook_ptr;
typedef MyClass value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
//Required static functions
static hook_ptr to_hook_ptr (value_type &value)
{ return &value.inner.hook; }
static const_hook_ptr to_hook_ptr(const value_type &value)
{ return &value.inner.hook; }
static pointer to_value_ptr(hook_ptr n)
{
return get_parent_from_member<MyClass>
(get_parent_from_member<MyClass::InnerNode>(n, &MyClass::InnerNode::hook)
,&MyClass::inner
);
}
static const_pointer to_value_ptr(const_hook_ptr n)
{
return get_parent_from_member<MyClass>
(get_parent_from_member<MyClass::InnerNode>(n, &MyClass::InnerNode::hook)
,&MyClass::inner
);
}
};
//Define a list that will use the hook accessed through the function object
typedef list< MyClass, function_hook< Functor> > List;
int main()
{
MyClass n;
List l;
//Insert the node in both lists
l.insert(l.begin(), n);
assert(l.size() == 1);
return 0;
}
//]
#include <boost/intrusive/detail/config_end.hpp>

53
example/doc_recursive.cpp Normal file
View File

@@ -0,0 +1,53 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2009
//
// 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_recursive
#include <boost/intrusive/list.hpp>
#include <cassert>
using namespace boost::intrusive;
typedef list_base_hook<> BaseHook;
//A recursive class
class Recursive : public BaseHook
{
private:
Recursive(const Recursive&);
Recursive & operator=(const Recursive&);
public:
Recursive() : BaseHook(), children(){}
list< Recursive, base_hook<BaseHook> > children;
};
int main()
{
Recursive f, f2;
//A recursive list of Recursive
list< Recursive, base_hook<BaseHook> > l;
//Insert a node in parent list
l.insert(l.begin(), f);
//Insert a node in child list
l.begin()->children.insert(l.begin()->children.begin(), f2);
//Objects properly inserted
assert(l.size() == l.begin()->children.size());
assert(l.size() == 1);
//Clear both lists
l.begin()->children.clear();
l.clear();
return 0;
}
//]

View File

@@ -0,0 +1,86 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2010-2010
//
// 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/detail/config_begin.hpp>
//[doc_recursive_member
#include <boost/intrusive/list.hpp>
#include <boost/intrusive/parent_from_member.hpp>
using namespace boost::intrusive;
class Recursive;
//Declaration of the functor that converts betwen the Recursive
//class and the hook
struct Functor
{
//Required types
typedef list_member_hook<> hook_type;
typedef hook_type* hook_ptr;
typedef const hook_type* const_hook_ptr;
typedef Recursive value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
//Required static functions
static hook_ptr to_hook_ptr (value_type &value);
static const_hook_ptr to_hook_ptr(const value_type &value);
static pointer to_value_ptr(hook_ptr n);
static const_pointer to_value_ptr(const_hook_ptr n);
};
//Define the recursive class
class Recursive
{
private:
Recursive(const Recursive&);
Recursive & operator=(const Recursive&);
public:
Recursive() : hook(), children() {}
list_member_hook<> hook;
list< Recursive, function_hook< Functor> > children;
};
//Definition of Functor functions
inline Functor::hook_ptr Functor::to_hook_ptr (Functor::value_type &value)
{ return &value.hook; }
inline Functor::const_hook_ptr Functor::to_hook_ptr(const Functor::value_type &value)
{ return &value.hook; }
inline Functor::pointer Functor::to_value_ptr(Functor::hook_ptr n)
{ return get_parent_from_member<Recursive>(n, &Recursive::hook); }
inline Functor::const_pointer Functor::to_value_ptr(Functor::const_hook_ptr n)
{ return get_parent_from_member<Recursive>(n, &Recursive::hook); }
int main()
{
Recursive f, f2;
//A recursive list of Recursive
list< Recursive, function_hook< Functor> > l;
//Insert a node in parent list
l.insert(l.begin(), f);
//Insert a node in child list
l.begin()->children.insert(l.begin()->children.begin(), f2);
//Objects properly inserted
assert(l.size() == l.begin()->children.size());
assert(l.size() == 1);
//Clear both lists
l.begin()->children.clear();
l.clear();
return 0;
}
//]
#include <boost/intrusive/detail/config_end.hpp>

View File

@@ -91,13 +91,19 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "treap_multiset", "treap_mul
ProjectSection(ProjectDependencies) = postProject ProjectSection(ProjectDependencies) = postProject
EndProjectSection EndProjectSection
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "recursive", "recursive\recursive.vcproj", "{7679B41B-F2B4-9176-CB81-35449467B435}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "function_hook", "function_hook\function_hook.vcproj", "{761A79B4-9968-CB81-F02B-2A4497345475}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global Global
GlobalSection(SolutionConfiguration) = preSolution GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug Debug = Debug
Release = Release Release = Release
EndGlobalSection EndGlobalSection
GlobalSection(ProjectDependencies) = postSolution
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution GlobalSection(ProjectConfiguration) = postSolution
{977B61B4-9968-497C-9F0B-24A8145473B8}.Debug.ActiveCfg = Debug|Win32 {977B61B4-9968-497C-9F0B-24A8145473B8}.Debug.ActiveCfg = Debug|Win32
{977B61B4-9968-497C-9F0B-24A8145473B8}.Debug.Build.0 = Debug|Win32 {977B61B4-9968-497C-9F0B-24A8145473B8}.Debug.Build.0 = Debug|Win32
@@ -191,6 +197,14 @@ Global
{16E09E95-F4A2-C971-BC76-9BA407191C59}.Debug.Build.0 = Debug|Win32 {16E09E95-F4A2-C971-BC76-9BA407191C59}.Debug.Build.0 = Debug|Win32
{16E09E95-F4A2-C971-BC76-9BA407191C59}.Release.ActiveCfg = Release|Win32 {16E09E95-F4A2-C971-BC76-9BA407191C59}.Release.ActiveCfg = Release|Win32
{16E09E95-F4A2-C971-BC76-9BA407191C59}.Release.Build.0 = Release|Win32 {16E09E95-F4A2-C971-BC76-9BA407191C59}.Release.Build.0 = Release|Win32
{7679B41B-F2B4-9176-CB81-35449467B435}.Debug.ActiveCfg = Debug|Win32
{7679B41B-F2B4-9176-CB81-35449467B435}.Debug.Build.0 = Debug|Win32
{7679B41B-F2B4-9176-CB81-35449467B435}.Release.ActiveCfg = Release|Win32
{7679B41B-F2B4-9176-CB81-35449467B435}.Release.Build.0 = Release|Win32
{761A79B4-9968-CB81-F02B-2A4497345475}.Debug.ActiveCfg = Debug|Win32
{761A79B4-9968-CB81-F02B-2A4497345475}.Debug.Build.0 = Debug|Win32
{761A79B4-9968-CB81-F02B-2A4497345475}.Release.ActiveCfg = Release|Win32
{761A79B4-9968-CB81-F02B-2A4497345475}.Release.Build.0 = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection EndGlobalSection

View File

@@ -156,6 +156,9 @@
<File <File
RelativePath="..\..\..\..\..\boost\intrusive\options.hpp"> RelativePath="..\..\..\..\..\boost\intrusive\options.hpp">
</File> </File>
<File
RelativePath="..\..\..\..\..\boost\intrusive\parent_from_member.hpp">
</File>
<File <File
RelativePath="..\..\..\..\..\boost\intrusive\pointer_plus_bits.hpp"> RelativePath="..\..\..\..\..\boost\intrusive\pointer_plus_bits.hpp">
</File> </File>
@@ -373,6 +376,9 @@
<File <File
RelativePath="..\..\..\example\doc_external_value_traits.cpp"> RelativePath="..\..\..\example\doc_external_value_traits.cpp">
</File> </File>
<File
RelativePath="..\..\..\example\doc_function_hooks.cpp">
</File>
<File <File
RelativePath="..\..\..\example\doc_how_to_use.cpp"> RelativePath="..\..\..\example\doc_how_to_use.cpp">
</File> </File>
@@ -394,6 +400,12 @@
<File <File
RelativePath="..\..\..\example\doc_rbtree_algorithms.cpp"> RelativePath="..\..\..\example\doc_rbtree_algorithms.cpp">
</File> </File>
<File
RelativePath="..\..\..\example\doc_recursive.cpp">
</File>
<File
RelativePath="..\..\..\example\doc_recursive_member.cpp">
</File>
<File <File
RelativePath="..\..\..\example\doc_set.cpp"> RelativePath="..\..\..\example\doc_set.cpp">
</File> </File>

View File

@@ -27,7 +27,7 @@
MinimalRebuild="TRUE" MinimalRebuild="TRUE"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="5" RuntimeLibrary="5"
DisableLanguageExtensions="TRUE" DisableLanguageExtensions="FALSE"
TreatWChar_tAsBuiltInType="TRUE" TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE" ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"

View File

@@ -25,7 +25,7 @@
MinimalRebuild="TRUE" MinimalRebuild="TRUE"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="5" RuntimeLibrary="5"
DisableLanguageExtensions="TRUE" DisableLanguageExtensions="FALSE"
TreatWChar_tAsBuiltInType="TRUE" TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE" ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"

View File

@@ -24,7 +24,7 @@
MinimalRebuild="TRUE" MinimalRebuild="TRUE"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="5" RuntimeLibrary="5"
DisableLanguageExtensions="TRUE" DisableLanguageExtensions="FALSE"
TreatWChar_tAsBuiltInType="TRUE" TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE" ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"

View File

@@ -27,7 +27,7 @@
MinimalRebuild="TRUE" MinimalRebuild="TRUE"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="5" RuntimeLibrary="5"
DisableLanguageExtensions="TRUE" DisableLanguageExtensions="FALSE"
TreatWChar_tAsBuiltInType="TRUE" TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE" ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"

View File

@@ -27,7 +27,7 @@
MinimalRebuild="TRUE" MinimalRebuild="TRUE"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="5" RuntimeLibrary="5"
DisableLanguageExtensions="TRUE" DisableLanguageExtensions="FALSE"
TreatWChar_tAsBuiltInType="TRUE" TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE" ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"

View File

@@ -27,7 +27,7 @@
MinimalRebuild="TRUE" MinimalRebuild="TRUE"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="5" RuntimeLibrary="5"
DisableLanguageExtensions="TRUE" DisableLanguageExtensions="FALSE"
TreatWChar_tAsBuiltInType="TRUE" TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE" ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"

View File

@@ -0,0 +1,133 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="function_hook"
ProjectGUID="{761A79B4-9968-CB81-F02B-2A4497345475}"
RootNamespace="function_hook"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../../../"
PreprocessorDefinitions="BOOST_DATE_TIME_NO_LIB"
GeneratePreprocessedFile="0"
KeepComments="FALSE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
DisableLanguageExtensions="FALSE"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/function_hook.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/function_hook.pdb"
GenerateMapFile="TRUE"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../../../"
PreprocessorDefinitions="BOOST_DATE_TIME_NO_LIB"
RuntimeLibrary="4"
DisableLanguageExtensions="FALSE"
ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/function_hook.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="{4C737FF1-7AB5-3764-A066-252B75A372FF}">
<File
RelativePath="..\..\..\test\function_hook_test.cpp">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -27,7 +27,7 @@
MinimalRebuild="TRUE" MinimalRebuild="TRUE"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="5" RuntimeLibrary="5"
DisableLanguageExtensions="TRUE" DisableLanguageExtensions="FALSE"
TreatWChar_tAsBuiltInType="TRUE" TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE" ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"

View File

@@ -27,7 +27,7 @@
MinimalRebuild="TRUE" MinimalRebuild="TRUE"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="5" RuntimeLibrary="5"
DisableLanguageExtensions="TRUE" DisableLanguageExtensions="FALSE"
TreatWChar_tAsBuiltInType="TRUE" TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE" ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"

View File

@@ -24,7 +24,7 @@
MinimalRebuild="TRUE" MinimalRebuild="TRUE"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="5" RuntimeLibrary="5"
DisableLanguageExtensions="TRUE" DisableLanguageExtensions="FALSE"
TreatWChar_tAsBuiltInType="TRUE" TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE" ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"

View File

@@ -0,0 +1,133 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="recursive"
ProjectGUID="{7679B41B-F2B4-9176-CB81-35449467B435}"
RootNamespace="recursive"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../../../"
PreprocessorDefinitions="BOOST_DATE_TIME_NO_LIB"
GeneratePreprocessedFile="0"
KeepComments="FALSE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
DisableLanguageExtensions="FALSE"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/recursive.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/recursive.pdb"
GenerateMapFile="TRUE"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../../../"
PreprocessorDefinitions="BOOST_DATE_TIME_NO_LIB"
RuntimeLibrary="4"
DisableLanguageExtensions="FALSE"
ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/recursive.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="{4F537F31-AB85-7644-A616-25727F35FA5F}">
<File
RelativePath="..\..\..\test\recursive_test.cpp">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -24,7 +24,7 @@
MinimalRebuild="TRUE" MinimalRebuild="TRUE"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="5" RuntimeLibrary="5"
DisableLanguageExtensions="TRUE" DisableLanguageExtensions="FALSE"
TreatWChar_tAsBuiltInType="TRUE" TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE" ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"

View File

@@ -25,7 +25,7 @@
MinimalRebuild="TRUE" MinimalRebuild="TRUE"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="5" RuntimeLibrary="5"
DisableLanguageExtensions="TRUE" DisableLanguageExtensions="FALSE"
TreatWChar_tAsBuiltInType="TRUE" TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE" ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"

View File

@@ -24,7 +24,7 @@
MinimalRebuild="TRUE" MinimalRebuild="TRUE"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="5" RuntimeLibrary="5"
DisableLanguageExtensions="TRUE" DisableLanguageExtensions="FALSE"
TreatWChar_tAsBuiltInType="TRUE" TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE" ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"

View File

@@ -24,7 +24,7 @@
MinimalRebuild="TRUE" MinimalRebuild="TRUE"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="5" RuntimeLibrary="5"
DisableLanguageExtensions="TRUE" DisableLanguageExtensions="FALSE"
TreatWChar_tAsBuiltInType="TRUE" TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE" ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"

View File

@@ -25,7 +25,7 @@
MinimalRebuild="TRUE" MinimalRebuild="TRUE"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="5" RuntimeLibrary="5"
DisableLanguageExtensions="TRUE" DisableLanguageExtensions="FALSE"
TreatWChar_tAsBuiltInType="TRUE" TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE" ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"

View File

@@ -24,7 +24,7 @@
MinimalRebuild="TRUE" MinimalRebuild="TRUE"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="5" RuntimeLibrary="5"
DisableLanguageExtensions="TRUE" DisableLanguageExtensions="FALSE"
TreatWChar_tAsBuiltInType="TRUE" TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE" ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"

View File

@@ -27,7 +27,7 @@
MinimalRebuild="TRUE" MinimalRebuild="TRUE"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="5" RuntimeLibrary="5"
DisableLanguageExtensions="TRUE" DisableLanguageExtensions="FALSE"
TreatWChar_tAsBuiltInType="TRUE" TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE" ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"

View File

@@ -14,3 +14,4 @@
-> Non-array buckets -> Non-array buckets
-> Document incremental<> option better -> Document incremental<> option better
-> Assure stable order for optimize_multikey and inverse order otherwise -> Assure stable order for optimize_multikey and inverse order otherwise
-> add an option to unordered containers to get O(1) traversal and begin()/end() even with very low load factors

View File

@@ -24,7 +24,7 @@
MinimalRebuild="TRUE" MinimalRebuild="TRUE"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="5" RuntimeLibrary="5"
DisableLanguageExtensions="TRUE" DisableLanguageExtensions="FALSE"
TreatWChar_tAsBuiltInType="TRUE" TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE" ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"

View File

@@ -24,7 +24,7 @@
MinimalRebuild="TRUE" MinimalRebuild="TRUE"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="5" RuntimeLibrary="5"
DisableLanguageExtensions="TRUE" DisableLanguageExtensions="FALSE"
TreatWChar_tAsBuiltInType="TRUE" TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE" ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"

View File

@@ -25,7 +25,7 @@
MinimalRebuild="TRUE" MinimalRebuild="TRUE"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="5" RuntimeLibrary="5"
DisableLanguageExtensions="TRUE" DisableLanguageExtensions="FALSE"
TreatWChar_tAsBuiltInType="TRUE" TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE" ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"

View File

@@ -25,7 +25,7 @@
MinimalRebuild="TRUE" MinimalRebuild="TRUE"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="5" RuntimeLibrary="5"
DisableLanguageExtensions="TRUE" DisableLanguageExtensions="FALSE"
TreatWChar_tAsBuiltInType="TRUE" TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE" ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"

View File

@@ -27,7 +27,7 @@
MinimalRebuild="TRUE" MinimalRebuild="TRUE"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="5" RuntimeLibrary="5"
DisableLanguageExtensions="TRUE" DisableLanguageExtensions="FALSE"
TreatWChar_tAsBuiltInType="TRUE" TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE" ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"

152
test/function_hook_test.cpp Normal file
View File

@@ -0,0 +1,152 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2010-2010
//
// 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/detail/config_begin.hpp>
#include <boost/intrusive/parent_from_member.hpp>
#include <boost/intrusive/list.hpp>
#include <boost/intrusive/slist.hpp>
#include <boost/intrusive/set.hpp>
#include <boost/intrusive/unordered_set.hpp>
#include <boost/functional/hash.hpp>
using namespace boost::intrusive;
struct MyClass
{
MyClass() : order(0) {}
int order;
//This internal type has two hooks
struct InnerNode : public list_base_hook<>, public slist_base_hook<>
, public set_base_hook<>, public unordered_set_base_hook<>
{
list_member_hook<> listhook;
slist_member_hook<> slisthook;
set_member_hook<> sethook;
unordered_set_member_hook<> usethook;
} inner;
friend bool operator < (const MyClass &l, const MyClass &r)
{ return l.order < r.order; }
friend bool operator == (const MyClass &l, const MyClass &r)
{ return l.order == r.order; }
friend std::size_t hash_value(const MyClass &value)
{ return std::size_t(value.order); }
};
//This functor converts between MyClass and the InnerNode member hook
#define InnerMemberHook(TAG, HOOKTYPE, MEMBERNAME)\
struct InnerMemberHookFunctor##TAG \
{\
typedef HOOKTYPE hook_type;\
typedef hook_type* hook_ptr;\
typedef const hook_type* const_hook_ptr;\
typedef MyClass value_type;\
typedef value_type* pointer;\
typedef const value_type* const_pointer;\
\
static hook_ptr to_hook_ptr (value_type &value)\
{ return &value.inner.MEMBERNAME; }\
static const_hook_ptr to_hook_ptr(const value_type &value)\
{ return &value.inner.MEMBERNAME; }\
static pointer to_value_ptr(hook_ptr n)\
{\
return get_parent_from_member<MyClass>\
(get_parent_from_member<MyClass::InnerNode>(n, &MyClass::InnerNode::MEMBERNAME)\
,&MyClass::inner\
);\
}\
static const_pointer to_value_ptr(const_hook_ptr n)\
{\
return get_parent_from_member<MyClass>\
(get_parent_from_member<MyClass::InnerNode>(n, &MyClass::InnerNode::MEMBERNAME)\
,&MyClass::inner\
);\
}\
};\
//
//This functor converts between MyClass and the InnerNode base hook
#define InnerBaseHook(TAG, HOOKTYPE)\
struct InnerBaseHookFunctor##TAG \
{\
typedef HOOKTYPE hook_type;\
typedef hook_type* hook_ptr;\
typedef const hook_type* const_hook_ptr;\
typedef MyClass value_type;\
typedef value_type* pointer;\
typedef const value_type* const_pointer;\
\
static hook_ptr to_hook_ptr (value_type &value)\
{ return &value.inner; }\
static const_hook_ptr to_hook_ptr(const value_type &value)\
{ return &value.inner; }\
static pointer to_value_ptr(hook_ptr n)\
{\
return get_parent_from_member<MyClass>(static_cast<MyClass::InnerNode*>(n),&MyClass::inner);\
}\
static const_pointer to_value_ptr(const_hook_ptr n)\
{\
return get_parent_from_member<MyClass>(static_cast<const MyClass::InnerNode*>(n),&MyClass::inner);\
}\
};\
//
//List
InnerMemberHook(List, list_member_hook<>, listhook)
InnerBaseHook(List, list_base_hook<>)
//Slist
InnerMemberHook(Slist, slist_member_hook<>, slisthook)
InnerBaseHook(Slist, slist_base_hook<>)
//Set
InnerMemberHook(Set, set_member_hook<>, sethook)
InnerBaseHook(Set, set_base_hook<>)
//Unordered Set
InnerMemberHook(USet, unordered_set_member_hook<>, usethook)
InnerBaseHook(USet, unordered_set_base_hook<>)
//Define containers
typedef list < MyClass, function_hook< InnerMemberHookFunctorList> > CustomListMember;
typedef list < MyClass, function_hook< InnerBaseHookFunctorList > > CustomListBase;
typedef slist< MyClass, function_hook< InnerMemberHookFunctorSlist> > CustomSlistMember;
typedef slist< MyClass, function_hook< InnerBaseHookFunctorSlist > > CustomSlistBase;
typedef set < MyClass, function_hook< InnerMemberHookFunctorSet> > CustomSetMember;
typedef set < MyClass, function_hook< InnerBaseHookFunctorSet > > CustomSetBase;
typedef unordered_set< MyClass, function_hook< InnerMemberHookFunctorUSet> > CustomUSetMember;
typedef unordered_set< MyClass, function_hook< InnerBaseHookFunctorUSet > > CustomUSetBase;
int main()
{
MyClass n;
CustomListBase listbase;
CustomListMember listmember;
CustomSlistBase slistbase;
CustomSlistMember slistmember;
CustomSetBase setbase;
CustomSetMember setmember;
CustomUSetBase::bucket_type buckets[1];
CustomUSetBase usetbase(CustomUSetBase::bucket_traits(buckets, 1));
CustomUSetMember usetmember(CustomUSetMember::bucket_traits(buckets, 1));
listbase.insert(listbase.begin(), n);
listmember.insert(listmember.begin(), n);
slistbase.insert(slistbase.begin(), n);
slistmember.insert(slistmember.begin(), n);
setbase.insert(n);
setmember.insert(n);
usetbase.insert(n);
usetmember.insert(n);
return 0;
}
#include <boost/intrusive/detail/config_end.hpp>

View File

@@ -402,9 +402,9 @@ void test_generic_assoc<ValueTraits, ContainerDefiner>::test_insert_before
for(vec_iterator it(--values.end()); true; --it){ for(vec_iterator it(--values.end()); true; --it){
testset.push_front(*it); testset.push_front(*it);
if(it == values.begin()){ if(it == values.begin()){
break; break;
} }
} }
BOOST_TEST(testset.size() == values.size()); BOOST_TEST(testset.size() == values.size());
TEST_INTRUSIVE_SEQUENCE_EXPECTED(values, testset.begin()); TEST_INTRUSIVE_SEQUENCE_EXPECTED(values, testset.begin());

View File

@@ -10,10 +10,8 @@
// See http://www.boost.org/libs/intrusive for documentation. // See http://www.boost.org/libs/intrusive for documentation.
// //
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
#include <boost/intrusive/detail/config_begin.hpp> #include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/list.hpp> #include <boost/intrusive/list.hpp>
#include <boost/intrusive/detail/pointer_to_other.hpp> #include <boost/intrusive/detail/pointer_to_other.hpp>
#include "itestvalue.hpp" #include "itestvalue.hpp"
#include "smart_ptr.hpp" #include "smart_ptr.hpp"
@@ -500,4 +498,3 @@ int main( int, char* [] )
return boost::report_errors(); return boost::report_errors();
} }
#include <boost/intrusive/detail/config_end.hpp>

71
test/recursive_test.cpp Normal file
View File

@@ -0,0 +1,71 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2010
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#include <boost/intrusive/list.hpp>
#include <boost/intrusive/slist.hpp>
#include <boost/intrusive/set.hpp>
#include <boost/intrusive/unordered_set.hpp>
#include <boost/intrusive/avl_set.hpp>
#include <boost/intrusive/sg_set.hpp>
#include <boost/intrusive/splay_set.hpp>
#include <boost/intrusive/treap_set.hpp>
#include <cassert>
using namespace boost::intrusive;
typedef list_base_hook<> ListBaseHook;
typedef slist_base_hook<> SListBaseHook;
typedef set_base_hook<> SetBaseHook;
typedef unordered_set_base_hook<> USetBaseHook;
class Foo;
typedef unordered_set<Foo, base_hook<USetBaseHook> > USet;
class Foo : public ListBaseHook, public SListBaseHook, public SetBaseHook, public USetBaseHook
{
USet::bucket_type buckets[1];
Foo(const Foo &);
Foo & operator=(const Foo &);
public:
Foo() : uset_children(USet::bucket_traits(buckets, 1))
{}
list <Foo, base_hook<ListBaseHook> > list_children;
slist<Foo, base_hook<SListBaseHook> > slist_children;
set <Foo, base_hook<SetBaseHook> > set_children;
USet uset_children;
};
void instantiate()
{
list< Foo, base_hook<ListBaseHook> > list_; list_.clear();
slist< Foo, base_hook<SListBaseHook> > slist_; slist_.clear();
set< Foo, base_hook<SetBaseHook> > set_; set_.clear();
USet::bucket_type buckets[1];
USet unordered_set_(USet::bucket_traits(buckets, 1)); unordered_set_.clear();
}
int main()
{
instantiate();
//A small test with list
{
Foo f, f2;
list< Foo, base_hook<ListBaseHook> > l;
l.insert(l.begin(), f);
l.begin()->list_children.insert(l.begin()->list_children.begin(), f2);
assert(l.size() == l.begin()->list_children.size());
l.begin()->list_children.clear();
l.clear();
}
return 0;
}

View File

@@ -13,6 +13,7 @@
#include <boost/iterator.hpp> #include <boost/iterator.hpp>
#include <boost/intrusive/pointer_plus_bits.hpp> #include <boost/intrusive/pointer_plus_bits.hpp>
#include <boost/pointer_cast.hpp>
#if (defined _MSC_VER) && (_MSC_VER >= 1200) #if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once # pragma once
@@ -312,7 +313,7 @@ inline T* boost_intrusive_get_pointer(const smart_ptr<T> & p)
//!Simulation of static_cast between pointers. Never throws. //!Simulation of static_cast between pointers. Never throws.
template<class T, class U> template<class T, class U>
inline smart_ptr<T> inline smart_ptr<T>
static_pointer_cast(smart_ptr<U> const & r) static_pointer_cast(const smart_ptr<U> & r)
{ {
return smart_ptr<T>(r, detail::static_cast_tag()); return smart_ptr<T>(r, detail::static_cast_tag());
} }