mirror of
https://github.com/boostorg/intrusive.git
synced 2025-08-03 22:44:43 +02:00
Changes for 1.49
[SVN r76183]
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
[/
|
[/
|
||||||
/ Copyright (c) 2007-2010 Ion Gaztanaga
|
/ Copyright (c) 2006-2011 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-2010 Ion Gaztanaga]
|
[copyright 2005 Olaf Krzikalla, 2006-2011 Ion Gaztanaga]
|
||||||
[id intrusive]
|
[id intrusive]
|
||||||
[dirname intrusive]
|
[dirname intrusive]
|
||||||
[purpose Intrusive containers]
|
[purpose Intrusive containers]
|
||||||
@@ -2313,24 +2313,16 @@ and [*Boost.Intrusive]:
|
|||||||
|
|
||||||
[section:smart_pointers_requirements Requirements for smart pointers compatible with Boost.Intrusive]
|
[section:smart_pointers_requirements Requirements for smart pointers compatible with Boost.Intrusive]
|
||||||
|
|
||||||
Not every smart pointer is compatible with [*Boost.Intrusive]; the smart pointer must
|
Not every smart pointer is compatible with [*Boost.Intrusive]:
|
||||||
have the following features:
|
|
||||||
|
|
||||||
* It must support the same operations as a raw pointer, except casting.
|
* It must be compatible with C++11 [@http://en.cppreference.com/w/cpp/memory/pointer_traits `std::pointer_traits`]
|
||||||
* It must be convertible to a raw pointer and constructible from a raw pointer.
|
requirements. [*Boost.Intrusive] uses its own [classref boost::intrusive::pointer_traits pointer_traits]
|
||||||
|
class to implement those features in both C++11 and C++03 compilers.
|
||||||
* It must have the same ownership semantics as a raw pointer. This means that
|
* It must have the same ownership semantics as a raw pointer. This means that
|
||||||
resource management smart pointers (like `boost::shared_ptr`) can't be used.
|
resource management smart pointers (like `boost::shared_ptr`) can't be used.
|
||||||
|
|
||||||
The conversion from the smart pointer to a raw pointer must be implemented following
|
The conversion from the smart pointer to a raw pointer will be implemented as a recursive call to
|
||||||
Boost smart pointer `detail::get_pointer()` function. This function will be found using
|
`operator->()` until the function returns a raw pointer.
|
||||||
ADL. For example, for `boost::interprocess::offset_ptr`, `detail::get_pointer` is defined
|
|
||||||
as follows:
|
|
||||||
|
|
||||||
[c++]
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
T * detail::get_pointer(boost::interprocess::offset_ptr<T> const & p)
|
|
||||||
{ return p.get(); }
|
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
@@ -3072,7 +3064,7 @@ achieve this using [*Boost.Intrusive] predefined hooks. Now, instead of using
|
|||||||
|
|
||||||
[c++]
|
[c++]
|
||||||
|
|
||||||
#include <boost/pointer_to_other.hpp>
|
#include <boost/intrusive/pointer_traits.hpp>
|
||||||
#include <boost/intrusive/link_mode.hpp>
|
#include <boost/intrusive/link_mode.hpp>
|
||||||
|
|
||||||
struct my_value_traits
|
struct my_value_traits
|
||||||
@@ -3081,8 +3073,10 @@ achieve this using [*Boost.Intrusive] predefined hooks. Now, instead of using
|
|||||||
typedef implementation_defined value_type;
|
typedef implementation_defined value_type;
|
||||||
typedef node_traits::node_ptr node_ptr;
|
typedef node_traits::node_ptr node_ptr;
|
||||||
typedef node_traits::const_node_ptr const_node_ptr;
|
typedef node_traits::const_node_ptr const_node_ptr;
|
||||||
typedef boost::pointer_to_other<node_ptr, value_type>::type pointer;
|
typedef boost::intrusive::pointer_traits<node_ptr>::rebind_traits
|
||||||
typedef boost::pointer_to_other<node_ptr, const value_type>::type const_pointer;
|
<value_type>::type::pointer pointer;
|
||||||
|
typedef boost::intrusive::pointer_traits<node_ptr>::rebind_traits
|
||||||
|
<const value_type>::type::pointer const_pointer;
|
||||||
|
|
||||||
static const link_mode_type link_mode = some_linking_policy;
|
static const link_mode_type link_mode = some_linking_policy;
|
||||||
|
|
||||||
@@ -3126,14 +3120,13 @@ Let's explain each type and function:
|
|||||||
* [*['pointer]]: The type of a pointer to a `value_type`. It must be the same pointer type
|
* [*['pointer]]: The type of a pointer to a `value_type`. It must be the same pointer type
|
||||||
as `node_ptr`: If `node_ptr` is `node*`, `pointer` must be `value_type*`. If
|
as `node_ptr`: If `node_ptr` is `node*`, `pointer` must be `value_type*`. If
|
||||||
`node_ptr` is `smart_ptr<node_traits::node>`, `pointer` must be `smart_ptr<value_type>`.
|
`node_ptr` is `smart_ptr<node_traits::node>`, `pointer` must be `smart_ptr<value_type>`.
|
||||||
This can be generically achieved using `boost::pointer_to_other` utility from [*Boost SmartPointers]
|
This can be generically achieved using `boost::intrusive::pointer_traits` (portable implementation of C++11
|
||||||
|
`std::pointer_traits`) or `boost::pointer_to_other` utility from [*Boost SmartPointers]
|
||||||
defined in `<boost/pointer_to_other.hpp>`.
|
defined in `<boost/pointer_to_other.hpp>`.
|
||||||
|
|
||||||
* [*['const_pointer]]: The type of a pointer to a `const value_type`. It must be the same pointer type
|
* [*['const_pointer]]: The type of a pointer to a `const value_type`. It must be the same pointer type
|
||||||
as `node_ptr`: If `node_ptr` is `node*`, `const_pointer` must be `const value_type*`. If
|
as `node_ptr`: If `node_ptr` is `node*`, `const_pointer` must be `const value_type*`. If
|
||||||
`node_ptr` is `smart_ptr<node_traits::node>`, `const_pointer` must be `smart_ptr<const value_type>`
|
`node_ptr` is `smart_ptr<node_traits::node>`, `const_pointer` must be `smart_ptr<const value_type>`.
|
||||||
This can be generically achieved using `boost::pointer_to_other` utility from [*Boost SmartPointers]
|
|
||||||
defined in `<boost/pointer_to_other.hpp>`.
|
|
||||||
|
|
||||||
* [*['link_mode]]: Indicates that `value_traits` needs some additional work or checks from the
|
* [*['link_mode]]: Indicates that `value_traits` needs some additional work or checks from the
|
||||||
container. The types are enumerations defined in the `link_mode.hpp` header.
|
container. The types are enumerations defined in the `link_mode.hpp` header.
|
||||||
@@ -3568,7 +3561,7 @@ These are the times in microseconds for each case, and the normalized time:
|
|||||||
[[`normal_link` intrusive list] [5000 / 22500] [1 / 1]]
|
[[`normal_link` intrusive list] [5000 / 22500] [1 / 1]]
|
||||||
[[`safe_link` intrusive list] [7812 / 32187] [1.56 / 1.43]]
|
[[`safe_link` intrusive list] [7812 / 32187] [1.56 / 1.43]]
|
||||||
[[`auto_unlink` intrusive list] [10156 / 41562] [2.03 / 1.84]]
|
[[`auto_unlink` intrusive list] [10156 / 41562] [2.03 / 1.84]]
|
||||||
[[Standard list] [76875 / 97500] [5.37 / 4.33]]
|
[[Standard list] [26875 / 97500] [5.37 / 4.33]]
|
||||||
[[Standard compact pointer list] [76406 / 86718] [15.28 / 3.85]]
|
[[Standard compact pointer list] [76406 / 86718] [15.28 / 3.85]]
|
||||||
[[Standard disperse pointer list] [146562 / 175625] [29.31 / 7.80]]
|
[[Standard disperse pointer list] [146562 / 175625] [29.31 / 7.80]]
|
||||||
]
|
]
|
||||||
@@ -3831,6 +3824,15 @@ 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_49_00 Boost 1.49 Release]
|
||||||
|
|
||||||
|
* Fixed bugs
|
||||||
|
[@https://svn.boost.org/trac/boost/ticket/6223 #6223],
|
||||||
|
[@https://svn.boost.org/trac/boost/ticket/6153 #6153].
|
||||||
|
|
||||||
|
|
||||||
|
[endsect]
|
||||||
|
|
||||||
[section:release_notes_boost_1_48_00 Boost 1.48 Release]
|
[section:release_notes_boost_1_48_00 Boost 1.48 Release]
|
||||||
|
|
||||||
* Fixed bugs
|
* Fixed bugs
|
||||||
@@ -3934,15 +3936,9 @@ all the objects to be inserted in intrusive containers in containers like `std::
|
|||||||
|
|
||||||
[*Boost.Intrusive] has been tested on the following compilers/platforms:
|
[*Boost.Intrusive] has been tested on the following compilers/platforms:
|
||||||
|
|
||||||
* Visual 7.1/WinXP
|
* Visual >= 7.1
|
||||||
* Visual 8.0/WinXP
|
* GCC >= 4.1
|
||||||
* Visual 9.0/WinXP
|
* Intel 11
|
||||||
* GCC 4.1.1/MinGW
|
|
||||||
* GCC 3.4.4/Cygwin
|
|
||||||
* Intel 9.1/WinXP
|
|
||||||
* GCC 4.1.2/Linux
|
|
||||||
* GCC 3.4.3/Solaris 11
|
|
||||||
* GCC 4.0/Mac Os 10.4.1
|
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
|
BIN
proj/vc7ide/Intrusive.ncb
Normal file
BIN
proj/vc7ide/Intrusive.ncb
Normal file
Binary file not shown.
@@ -1,24 +1,4 @@
|
|||||||
Microsoft Visual Studio Solution File, Format Version 8.00
|
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}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unordered_set", "unordered_set\unordered_set.vcproj", "{90E701E6-2C91-F4A7-BA6C-A9F3B0949279}"
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
@@ -99,32 +79,42 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "function_hook", "function_h
|
|||||||
ProjectSection(ProjectDependencies) = postProject
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pointer_traits", "pointer_traits\pointer_traits.vcproj", "{7679B41B-F2B4-9176-CB81-35449467B435}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
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}") = "has_member_function_callable_with", "has_member_function_callable_with\has_member_function_callable_with.vcproj", "{3579B1A4-02AB-5489-CB81-957B14032465}"
|
||||||
|
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.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.ActiveCfg = Debug|Win32
|
||||||
{90E701E6-2C91-F4A7-BA6C-A9F3B0949279}.Debug.Build.0 = 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.ActiveCfg = Release|Win32
|
||||||
@@ -205,6 +195,34 @@ Global
|
|||||||
{761A79B4-9968-CB81-F02B-2A4497345475}.Debug.Build.0 = 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.ActiveCfg = Release|Win32
|
||||||
{761A79B4-9968-CB81-F02B-2A4497345475}.Release.Build.0 = Release|Win32
|
{761A79B4-9968-CB81-F02B-2A4497345475}.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
|
||||||
|
{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
|
||||||
|
{3579B1A4-02AB-5489-CB81-957B14032465}.Debug.ActiveCfg = Debug|Win32
|
||||||
|
{3579B1A4-02AB-5489-CB81-957B14032465}.Debug.Build.0 = Debug|Win32
|
||||||
|
{3579B1A4-02AB-5489-CB81-957B14032465}.Release.ActiveCfg = Release|Win32
|
||||||
|
{3579B1A4-02AB-5489-CB81-957B14032465}.Release.Build.0 = Release|Win32
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
|
@@ -154,6 +154,9 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\..\..\boost\intrusive\pointer_plus_bits.hpp">
|
RelativePath="..\..\..\..\..\boost\intrusive\pointer_plus_bits.hpp">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\..\..\boost\intrusive\pointer_traits.hpp">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\..\..\boost\intrusive\rbtree.hpp">
|
RelativePath="..\..\..\..\..\boost\intrusive\rbtree.hpp">
|
||||||
</File>
|
</File>
|
||||||
@@ -244,6 +247,9 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\..\..\boost\intrusive\detail\generic_hook.hpp">
|
RelativePath="..\..\..\..\..\boost\intrusive\detail\generic_hook.hpp">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\..\..\boost\intrusive\detail\has_member_function_callable_with.hpp">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\..\..\boost\intrusive\detail\hashtable_node.hpp">
|
RelativePath="..\..\..\..\..\boost\intrusive\detail\hashtable_node.hpp">
|
||||||
</File>
|
</File>
|
||||||
@@ -253,6 +259,9 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\..\..\boost\intrusive\detail\list_node.hpp">
|
RelativePath="..\..\..\..\..\boost\intrusive\detail\list_node.hpp">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\..\..\boost\intrusive\detail\memory_util.hpp">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\..\..\boost\intrusive\detail\mpl.hpp">
|
RelativePath="..\..\..\..\..\boost\intrusive\detail\mpl.hpp">
|
||||||
</File>
|
</File>
|
||||||
@@ -260,7 +269,7 @@
|
|||||||
RelativePath="..\..\..\..\..\boost\intrusive\detail\parent_from_member.hpp">
|
RelativePath="..\..\..\..\..\boost\intrusive\detail\parent_from_member.hpp">
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\..\..\boost\intrusive\detail\pointer_to_other.hpp">
|
RelativePath="..\..\..\..\..\boost\intrusive\detail\preprocessor.hpp">
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\..\..\boost\intrusive\detail\rbtree_node.hpp">
|
RelativePath="..\..\..\..\..\boost\intrusive\detail\rbtree_node.hpp">
|
||||||
|
@@ -0,0 +1,133 @@
|
|||||||
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="7.10"
|
||||||
|
Name="has_member_function_callable_with"
|
||||||
|
ProjectGUID="{3579B1A4-02AB-5489-CB81-957B14032465}"
|
||||||
|
RootNamespace="virtual_base"
|
||||||
|
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)/has_member_function_callable_with.exe"
|
||||||
|
LinkIncremental="2"
|
||||||
|
GenerateDebugInformation="TRUE"
|
||||||
|
ProgramDatabaseFile="$(OutDir)/has_member_function_callable_with.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)/has_member_function_callable_with.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="{77B513CF-A736-6476-7AB5-D4AB7228A73C}">
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\test\has_member_function_callable_with.cpp">
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
133
proj/vc7ide/pointer_traits/pointer_traits.vcproj
Normal file
133
proj/vc7ide/pointer_traits/pointer_traits.vcproj
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="7.10"
|
||||||
|
Name="pointer_traits"
|
||||||
|
ProjectGUID="{7679B41B-F2B4-9176-CB81-35449467B435}"
|
||||||
|
RootNamespace="pointer_traits"
|
||||||
|
Keyword="Win32Proj">
|
||||||
|
<Platforms>
|
||||||
|
<Platform
|
||||||
|
Name="Win32"/>
|
||||||
|
</Platforms>
|
||||||
|
<Configurations>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
OutputDirectory="Debug"
|
||||||
|
IntermediateDirectory="Debug"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="2">
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="../../../../../"
|
||||||
|
PreprocessorDefinitions="BOOST_DATE_TIME_NO_LIB"
|
||||||
|
GeneratePreprocessedFile="0"
|
||||||
|
KeepComments="FALSE"
|
||||||
|
MinimalRebuild="TRUE"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="5"
|
||||||
|
DisableLanguageExtensions="FALSE"
|
||||||
|
TreatWChar_tAsBuiltInType="TRUE"
|
||||||
|
ForceConformanceInForLoopScope="TRUE"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="4"
|
||||||
|
Detect64BitPortabilityProblems="TRUE"
|
||||||
|
DebugInformationFormat="4"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
OutputFile="$(OutDir)/pointer_traits.exe"
|
||||||
|
LinkIncremental="2"
|
||||||
|
GenerateDebugInformation="TRUE"
|
||||||
|
ProgramDatabaseFile="$(OutDir)/pointer_traits.pdb"
|
||||||
|
GenerateMapFile="TRUE"
|
||||||
|
SubSystem="1"
|
||||||
|
TargetMachine="1"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebDeploymentTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedWrapperGeneratorTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|Win32"
|
||||||
|
OutputDirectory="Release"
|
||||||
|
IntermediateDirectory="Release"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="2">
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalIncludeDirectories="../../../../../"
|
||||||
|
PreprocessorDefinitions="BOOST_DATE_TIME_NO_LIB"
|
||||||
|
RuntimeLibrary="4"
|
||||||
|
DisableLanguageExtensions="FALSE"
|
||||||
|
ForceConformanceInForLoopScope="TRUE"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
Detect64BitPortabilityProblems="TRUE"
|
||||||
|
DebugInformationFormat="3"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
OutputFile="$(OutDir)/pointer_traits.exe"
|
||||||
|
LinkIncremental="1"
|
||||||
|
GenerateDebugInformation="TRUE"
|
||||||
|
SubSystem="1"
|
||||||
|
OptimizeReferences="2"
|
||||||
|
EnableCOMDATFolding="2"
|
||||||
|
TargetMachine="1"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebDeploymentTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedWrapperGeneratorTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
<References>
|
||||||
|
</References>
|
||||||
|
<Files>
|
||||||
|
<Filter
|
||||||
|
Name="Source Files"
|
||||||
|
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||||
|
UniqueIdentifier="{4F537F31-AB85-7644-A616-25727F35FA5F}">
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\test\pointer_traits_test.cpp">
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
@@ -15,6 +15,9 @@
|
|||||||
-> 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
|
-> add an option to unordered containers to get O(1) traversal and begin()/end() even with very low load factors
|
||||||
|
-> Take all pointers by const reference to optimize shared memory pointers
|
||||||
|
-> Return pointers by const reference if node traits return them by const reference to optimize shared memory pointers
|
||||||
|
-> Detect call signatures by has_member_function_callable_with instead of exact match to allow taking by const reference
|
||||||
|
|
||||||
|
|
||||||
The article explains it quite well: Linear Hashing The cost of hash table expansion is spread out across each hash table insertion operation, as opposed to being incurred all at once. Linear hashing is therefore well suited for interactive applications.
|
The article explains it quite well: Linear Hashing The cost of hash table expansion is spread out across each hash table insertion operation, as opposed to being incurred all at once. Linear hashing is therefore well suited for interactive applications.
|
||||||
@@ -27,3 +30,4 @@ http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1456.html
|
|||||||
|
|
||||||
Now, intrusive containers don't allocate memory at all, so incremental rehashing must be trigered by the user using
|
Now, intrusive containers don't allocate memory at all, so incremental rehashing must be trigered by the user using
|
||||||
"incremental_rehash(bool)" (use an additional bucket, that is, incremental rehash) and "incremental_rehash(bucket_traits)" (to update the new bucket array with an array that should be twice/half the size of the previous one). I admit that this is not explained at all with an example, so I will note this issue in my to do list.
|
"incremental_rehash(bool)" (use an additional bucket, that is, incremental rehash) and "incremental_rehash(bucket_traits)" (to update the new bucket array with an array that should be twice/half the size of the previous one). I admit that this is not explained at all with an example, so I will note this issue in my to do list.
|
||||||
|
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
#include <boost/intrusive/detail/config_begin.hpp>
|
#include <boost/intrusive/detail/config_begin.hpp>
|
||||||
#include <boost/intrusive/avl_set.hpp>
|
#include <boost/intrusive/avl_set.hpp>
|
||||||
#include <boost/intrusive/detail/pointer_to_other.hpp>
|
#include <boost/intrusive/pointer_traits.hpp>
|
||||||
#include "itestvalue.hpp"
|
#include "itestvalue.hpp"
|
||||||
#include "smart_ptr.hpp"
|
#include "smart_ptr.hpp"
|
||||||
#include "generic_multiset_test.hpp"
|
#include "generic_multiset_test.hpp"
|
||||||
|
@@ -29,7 +29,7 @@ class delete_disposer
|
|||||||
{
|
{
|
||||||
typedef typename std::iterator_traits<Pointer>::value_type value_type;
|
typedef typename std::iterator_traits<Pointer>::value_type value_type;
|
||||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(( detail::is_same<T, value_type>::value ));
|
BOOST_INTRUSIVE_INVARIANT_ASSERT(( detail::is_same<T, value_type>::value ));
|
||||||
delete detail::boost_intrusive_get_pointer(p);
|
delete boost::intrusive::detail::to_raw_pointer(p);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
#include <boost/intrusive/splay_set.hpp>
|
#include <boost/intrusive/splay_set.hpp>
|
||||||
#include <boost/intrusive/avl_set.hpp>
|
#include <boost/intrusive/avl_set.hpp>
|
||||||
#include <boost/intrusive/sg_set.hpp>
|
#include <boost/intrusive/sg_set.hpp>
|
||||||
|
#include <boost/intrusive/pointer_traits.hpp>
|
||||||
#include "smart_ptr.hpp"
|
#include "smart_ptr.hpp"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -78,7 +79,8 @@ int main()
|
|||||||
List my_list;
|
List my_list;
|
||||||
Slist my_slist;
|
Slist my_slist;
|
||||||
Set my_set;
|
Set my_set;
|
||||||
USet my_uset(USet::bucket_traits(buckets, 100));
|
USet my_uset(USet::bucket_traits(pointer_traits<USet::bucket_ptr>::pointer_to(*buckets), 100));
|
||||||
|
|
||||||
AvlSet my_avlset;
|
AvlSet my_avlset;
|
||||||
SplaySet my_splayset;
|
SplaySet my_splayset;
|
||||||
SgSet my_sgset;
|
SgSet my_sgset;
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
#include <boost/intrusive/slist.hpp>
|
#include <boost/intrusive/slist.hpp>
|
||||||
#include <boost/intrusive/rbtree.hpp>
|
#include <boost/intrusive/rbtree.hpp>
|
||||||
#include <boost/intrusive/hashtable.hpp>
|
#include <boost/intrusive/hashtable.hpp>
|
||||||
#include <boost/pointer_to_other.hpp>
|
#include <boost/intrusive/pointer_traits.hpp>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -45,10 +45,11 @@ struct external_traits
|
|||||||
typedef typename node_traits::node_ptr node_ptr;
|
typedef typename node_traits::node_ptr node_ptr;
|
||||||
typedef typename node_traits::const_node_ptr const_node_ptr;
|
typedef typename node_traits::const_node_ptr const_node_ptr;
|
||||||
typedef MyClass value_type;
|
typedef MyClass value_type;
|
||||||
typedef typename boost::pointer_to_other
|
typedef typename pointer_traits<node_ptr>::
|
||||||
<node_ptr, MyClass>::type pointer;
|
template rebind_pointer<MyClass>::type pointer;
|
||||||
typedef typename boost::pointer_to_other
|
typedef typename pointer_traits<node_ptr>::
|
||||||
<node_ptr, const MyClass>::type const_pointer;
|
template rebind_pointer
|
||||||
|
<const MyClass>::type const_pointer;
|
||||||
static const link_mode_type link_mode = normal_link;
|
static const link_mode_type link_mode = normal_link;
|
||||||
|
|
||||||
external_traits(pointer values, std::size_t NumElem)
|
external_traits(pointer values, std::size_t NumElem)
|
||||||
|
@@ -325,17 +325,14 @@ void test_generic_assoc<ValueTraits, ContainerDefiner>::test_rebalance
|
|||||||
>::type assoc_type;
|
>::type assoc_type;
|
||||||
typedef std::vector<value_type> orig_set_t;
|
typedef std::vector<value_type> orig_set_t;
|
||||||
typedef typename orig_set_t::iterator iterator_t;
|
typedef typename orig_set_t::iterator iterator_t;
|
||||||
std::size_t num_values;
|
|
||||||
orig_set_t original_testset;
|
orig_set_t original_testset;
|
||||||
{
|
{
|
||||||
assoc_type testset (values.begin(), values.end());
|
assoc_type testset (values.begin(), values.end());
|
||||||
num_values = testset.size();
|
|
||||||
original_testset.insert(original_testset.end(), testset.begin(), testset.end());
|
original_testset.insert(original_testset.end(), testset.begin(), testset.end());
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
assoc_type testset(values.begin(), values.end());
|
assoc_type testset(values.begin(), values.end());
|
||||||
testset.rebalance();
|
testset.rebalance();
|
||||||
iterator_t it = original_testset.begin();
|
|
||||||
TEST_INTRUSIVE_SEQUENCE_EXPECTED(original_testset, testset.begin());
|
TEST_INTRUSIVE_SEQUENCE_EXPECTED(original_testset, testset.begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
450
test/has_member_function_callable_with.cpp
Normal file
450
test/has_member_function_callable_with.cpp
Normal file
@@ -0,0 +1,450 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// (C) Copyright Ion Gaztanaga 2011-2011. 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/detail/workaround.hpp>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <boost/move/move.hpp>
|
||||||
|
|
||||||
|
namespace boost{
|
||||||
|
namespace intrusive{
|
||||||
|
namespace intrusive_detail{
|
||||||
|
namespace has_member_function_callable_with {
|
||||||
|
|
||||||
|
struct dont_care
|
||||||
|
{
|
||||||
|
dont_care(...);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct private_type
|
||||||
|
{
|
||||||
|
static private_type p;
|
||||||
|
private_type const &operator,(int) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef char yes_type;
|
||||||
|
struct no_type{ char dummy[2]; };
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
no_type is_private_type(T const &);
|
||||||
|
yes_type is_private_type(private_type const &);
|
||||||
|
|
||||||
|
}}}}
|
||||||
|
|
||||||
|
|
||||||
|
namespace boost{
|
||||||
|
namespace intrusive{
|
||||||
|
namespace intrusive_detail{
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
class has_member_function_named_func
|
||||||
|
{
|
||||||
|
struct BaseMixin
|
||||||
|
{
|
||||||
|
void func();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Base : public Type, public BaseMixin {};
|
||||||
|
template <typename T, T t> class Helper{};
|
||||||
|
|
||||||
|
template <typename U>
|
||||||
|
static has_member_function_callable_with::no_type deduce
|
||||||
|
(U*, Helper<void (BaseMixin::*)(), &U::func>* = 0);
|
||||||
|
static has_member_function_callable_with::yes_type deduce(...);
|
||||||
|
|
||||||
|
public:
|
||||||
|
static const bool value =
|
||||||
|
sizeof(has_member_function_callable_with::yes_type) == sizeof(deduce((Base*)(0)));
|
||||||
|
};
|
||||||
|
|
||||||
|
}}}
|
||||||
|
|
||||||
|
#if !defined(BOOST_CONTAINER_PERFECT_FORWARDING)
|
||||||
|
|
||||||
|
namespace boost{
|
||||||
|
namespace intrusive{
|
||||||
|
namespace intrusive_detail{
|
||||||
|
|
||||||
|
template<typename Fun, bool HasFunc
|
||||||
|
, class P0 = void , class P1 = void , class P2 = void>
|
||||||
|
struct has_member_function_callable_with_func_impl;
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Fun , class P0 , class P1 , class P2>
|
||||||
|
struct has_member_function_callable_with_func_impl
|
||||||
|
<Fun, false , P0 , P1 , P2>
|
||||||
|
{
|
||||||
|
static const bool value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}}}
|
||||||
|
|
||||||
|
|
||||||
|
namespace boost{
|
||||||
|
namespace intrusive{
|
||||||
|
namespace intrusive_detail{
|
||||||
|
|
||||||
|
#if !defined(_MSC_VER) || (_MSC_VER != 1600)
|
||||||
|
|
||||||
|
template<class F, std::size_t N = sizeof(boost::move_detail::declval<F>().func(), 0)>
|
||||||
|
struct zeroarg_checker_func
|
||||||
|
{
|
||||||
|
has_member_function_callable_with::yes_type dummy;
|
||||||
|
zeroarg_checker_func(int);
|
||||||
|
};
|
||||||
|
|
||||||
|
//For buggy compilers like MSVC 7.1, ((F*)0)->func() does not
|
||||||
|
//fail but sizeof yields to 0.
|
||||||
|
template<class F>
|
||||||
|
struct zeroarg_checker_func<F, 0>
|
||||||
|
{
|
||||||
|
has_member_function_callable_with::no_type dummy;
|
||||||
|
zeroarg_checker_func(int);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Fun>
|
||||||
|
struct has_member_function_callable_with_func_impl
|
||||||
|
<Fun, true , void , void , void>
|
||||||
|
{
|
||||||
|
template<class U>
|
||||||
|
static zeroarg_checker_func<U> Test(zeroarg_checker_func<U>*);
|
||||||
|
|
||||||
|
template <class U>
|
||||||
|
static has_member_function_callable_with::no_type Test(...);
|
||||||
|
|
||||||
|
static const bool value = sizeof(Test< Fun >(0))
|
||||||
|
== sizeof(has_member_function_callable_with::yes_type);
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
template<typename Fun>
|
||||||
|
struct has_member_function_callable_with_func_impl
|
||||||
|
<Fun, true , void , void , void>
|
||||||
|
{
|
||||||
|
template<class U>
|
||||||
|
static decltype(boost::move_detail::declval<Fun>().func(), has_member_function_callable_with::yes_type()) Test(Fun* f);
|
||||||
|
|
||||||
|
template<class U>
|
||||||
|
static has_member_function_callable_with::no_type Test(...);
|
||||||
|
static const bool value = sizeof(Test<Fun>((Fun*)0)) == sizeof(has_member_function_callable_with::yes_type);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}}}
|
||||||
|
|
||||||
|
|
||||||
|
namespace boost{
|
||||||
|
namespace intrusive{
|
||||||
|
namespace intrusive_detail{
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Fun>
|
||||||
|
struct funwrap1_func : Fun
|
||||||
|
{
|
||||||
|
using Fun::func;
|
||||||
|
has_member_function_callable_with::private_type
|
||||||
|
func( has_member_function_callable_with::dont_care) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Fun , class P0>
|
||||||
|
struct has_member_function_callable_with_func_impl
|
||||||
|
<Fun, true , P0 , void , void>
|
||||||
|
{
|
||||||
|
|
||||||
|
typedef funwrap1_func<Fun> FunWrap;
|
||||||
|
|
||||||
|
static bool const value = (sizeof(has_member_function_callable_with::no_type) ==
|
||||||
|
sizeof(has_member_function_callable_with::is_private_type
|
||||||
|
( (::boost::move_detail::declval< FunWrap >().func( ::boost::move_detail::declval<P0>() ), 0) )
|
||||||
|
)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
}}}
|
||||||
|
|
||||||
|
namespace boost{
|
||||||
|
namespace intrusive{
|
||||||
|
namespace intrusive_detail{
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Fun>
|
||||||
|
struct funwrap2_func: Fun
|
||||||
|
{
|
||||||
|
using Fun::func;
|
||||||
|
has_member_function_callable_with::private_type
|
||||||
|
func( has_member_function_callable_with::dont_care , has_member_function_callable_with::dont_care) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Fun , class P0 , class P1>
|
||||||
|
struct has_member_function_callable_with_func_impl
|
||||||
|
<Fun, true , P0 , P1 , void>
|
||||||
|
{
|
||||||
|
typedef funwrap2_func<Fun> FunWrap;
|
||||||
|
|
||||||
|
static bool const value = (sizeof(has_member_function_callable_with::no_type) ==
|
||||||
|
sizeof(has_member_function_callable_with::is_private_type
|
||||||
|
( (::boost::move_detail::declval< FunWrap >().
|
||||||
|
func( ::boost::move_detail::declval<P0>()
|
||||||
|
, ::boost::move_detail::declval<P1>() )
|
||||||
|
, 0) )
|
||||||
|
)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}}}
|
||||||
|
|
||||||
|
namespace boost{
|
||||||
|
namespace intrusive{
|
||||||
|
namespace intrusive_detail{
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Fun>
|
||||||
|
struct funwrap3_func: Fun
|
||||||
|
{
|
||||||
|
using Fun::func;
|
||||||
|
has_member_function_callable_with::private_type
|
||||||
|
func( has_member_function_callable_with::dont_care
|
||||||
|
, has_member_function_callable_with::dont_care
|
||||||
|
, has_member_function_callable_with::dont_care) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Fun , class P0 , class P1 , class P2>
|
||||||
|
struct has_member_function_callable_with_func_impl
|
||||||
|
<Fun, true , P0 , P1 , P2 >
|
||||||
|
{
|
||||||
|
typedef funwrap3_func<Fun> FunWrap;
|
||||||
|
|
||||||
|
static bool const value = (sizeof(has_member_function_callable_with::no_type) ==
|
||||||
|
sizeof(has_member_function_callable_with::is_private_type
|
||||||
|
( (::boost::move_detail::declval< FunWrap >().
|
||||||
|
func( ::boost::move_detail::declval<P0>()
|
||||||
|
, ::boost::move_detail::declval<P1>()
|
||||||
|
, ::boost::move_detail::declval<P2>() )
|
||||||
|
, 0) )
|
||||||
|
)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Fun
|
||||||
|
, class P0 = void , class P1 = void, typename P2 = void>
|
||||||
|
struct has_member_function_callable_with_func
|
||||||
|
: public has_member_function_callable_with_func_impl
|
||||||
|
<Fun, has_member_function_named_func<Fun>::value, P0 , P1 , P2 >
|
||||||
|
{};
|
||||||
|
|
||||||
|
}}}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
namespace boost{
|
||||||
|
namespace intrusive{
|
||||||
|
namespace intrusive_detail{
|
||||||
|
|
||||||
|
template<typename Fun, bool HasFunc, class ...Args>
|
||||||
|
struct has_member_function_callable_with_func_impl;
|
||||||
|
|
||||||
|
template<typename Fun, class ...Args>
|
||||||
|
struct has_member_function_callable_with_func_impl
|
||||||
|
<Fun, false, Args...>
|
||||||
|
{
|
||||||
|
static const bool value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}}}
|
||||||
|
|
||||||
|
|
||||||
|
namespace boost{
|
||||||
|
namespace intrusive{
|
||||||
|
namespace intrusive_detail{
|
||||||
|
|
||||||
|
template<class F, std::size_t N = sizeof(boost::move_detail::declval<F>().func(), 0)>
|
||||||
|
struct zeroarg_checker_func
|
||||||
|
{
|
||||||
|
has_member_function_callable_with::yes_type dummy;
|
||||||
|
zeroarg_checker_func(int);
|
||||||
|
};
|
||||||
|
|
||||||
|
//For buggy compilers like MSVC 7.1, ((F*)0)->func() does not
|
||||||
|
//fail but sizeof yields to 0.
|
||||||
|
template<class F>
|
||||||
|
struct zeroarg_checker_func<F, 0>
|
||||||
|
{
|
||||||
|
has_member_function_callable_with::no_type dummy;
|
||||||
|
zeroarg_checker_func(int);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Fun>
|
||||||
|
struct has_member_function_callable_with_func_impl
|
||||||
|
<Fun, true>
|
||||||
|
{
|
||||||
|
template<class U>
|
||||||
|
static zeroarg_checker_func<U> Test(zeroarg_checker_func<U>*);
|
||||||
|
|
||||||
|
template <class U>
|
||||||
|
static has_member_function_callable_with::no_type Test(...);
|
||||||
|
|
||||||
|
static const bool value = sizeof(Test< Fun >(0))
|
||||||
|
== sizeof(has_member_function_callable_with::yes_type);
|
||||||
|
};
|
||||||
|
|
||||||
|
}}}
|
||||||
|
|
||||||
|
|
||||||
|
namespace boost{
|
||||||
|
namespace intrusive{
|
||||||
|
namespace intrusive_detail{
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Fun, class ...DontCares>
|
||||||
|
struct funwrap_func : Fun
|
||||||
|
{
|
||||||
|
using Fun::func;
|
||||||
|
has_member_function_callable_with::private_type
|
||||||
|
func(DontCares...) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Fun, class ...Args>
|
||||||
|
struct has_member_function_callable_with_func_impl
|
||||||
|
<Fun, true , Args...>
|
||||||
|
{
|
||||||
|
template<class T>
|
||||||
|
struct make_dontcare
|
||||||
|
{
|
||||||
|
typedef has_member_function_callable_with::dont_care type;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef funwrap_func<Fun, typename make_dontcare<Args>::type...> FunWrap;
|
||||||
|
|
||||||
|
static bool const value = (sizeof(has_member_function_callable_with::no_type) ==
|
||||||
|
sizeof(has_member_function_callable_with::is_private_type
|
||||||
|
( (::boost::move_detail::declval< FunWrap >().func( ::boost::move_detail::declval<Args>()... ), 0) )
|
||||||
|
)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Fun, class ...Args>
|
||||||
|
struct has_member_function_callable_with_func
|
||||||
|
: public has_member_function_callable_with_func_impl
|
||||||
|
<Fun, has_member_function_named_func<Fun>::value, Args... >
|
||||||
|
{};
|
||||||
|
|
||||||
|
}}}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct functor
|
||||||
|
{
|
||||||
|
void func();
|
||||||
|
void func(const int&);
|
||||||
|
void func(const int&, const int&);
|
||||||
|
void func(const int&, const int&, const int&);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct functor2
|
||||||
|
{
|
||||||
|
void func(char*);
|
||||||
|
void func(int, char*);
|
||||||
|
void func(int, char*, double);
|
||||||
|
void func(const int&, char*, void *);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct functor3
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct functor4
|
||||||
|
{
|
||||||
|
void func(...);
|
||||||
|
template<class T>
|
||||||
|
void func(int, const T &);
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void func(const T &);
|
||||||
|
|
||||||
|
template<class T, class U>
|
||||||
|
void func(int, const T &, const U &);
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
using namespace boost::intrusive::intrusive_detail;
|
||||||
|
|
||||||
|
{
|
||||||
|
int check1[ has_member_function_callable_with_func<functor>::value ? 1 : -1];
|
||||||
|
int check2[!has_member_function_callable_with_func<functor2>::value ? 1 : -1];
|
||||||
|
int check3[!has_member_function_callable_with_func<functor3>::value ? 1 : -1];
|
||||||
|
int check4[ has_member_function_callable_with_func<functor4>::value ? 1 : -1];
|
||||||
|
(void)check1;
|
||||||
|
(void)check2;
|
||||||
|
(void)check3;
|
||||||
|
(void)check4;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int check1[ has_member_function_callable_with_func<functor, int>::value ? 1 : -1];
|
||||||
|
int check2[!has_member_function_callable_with_func<functor, char*>::value ? 1 : -1];
|
||||||
|
int check3[!has_member_function_callable_with_func<functor2, int>::value ? 1 : -1];
|
||||||
|
int check4[ has_member_function_callable_with_func<functor2, char*>::value ? 1 : -1];
|
||||||
|
int check5[!has_member_function_callable_with_func<functor3, int>::value ? 1 : -1];
|
||||||
|
int check6[!has_member_function_callable_with_func<functor3, char*>::value ? 1 : -1];
|
||||||
|
int check7[ has_member_function_callable_with_func<functor4, int>::value ? 1 : -1];
|
||||||
|
int check8[ has_member_function_callable_with_func<functor4, char*>::value ? 1 : -1];
|
||||||
|
(void)check1;
|
||||||
|
(void)check2;
|
||||||
|
(void)check3;
|
||||||
|
(void)check4;
|
||||||
|
(void)check5;
|
||||||
|
(void)check6;
|
||||||
|
(void)check7;
|
||||||
|
(void)check8;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int check1[ has_member_function_callable_with_func<functor, int, int>::value ? 1 : -1];
|
||||||
|
int check2[!has_member_function_callable_with_func<functor, int, char*>::value ? 1 : -1];
|
||||||
|
int check3[!has_member_function_callable_with_func<functor2, int, int>::value ? 1 : -1];
|
||||||
|
int check4[ has_member_function_callable_with_func<functor2, int, char*>::value ? 1 : -1];
|
||||||
|
int check5[!has_member_function_callable_with_func<functor3, int, int>::value ? 1 : -1];
|
||||||
|
int check6[!has_member_function_callable_with_func<functor3, int, char*>::value ? 1 : -1];
|
||||||
|
int check7[ has_member_function_callable_with_func<functor4, int, char*>::value ? 1 : -1];
|
||||||
|
(void)check1;
|
||||||
|
(void)check2;
|
||||||
|
(void)check3;
|
||||||
|
(void)check4;
|
||||||
|
(void)check5;
|
||||||
|
(void)check6;
|
||||||
|
(void)check7;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int check1[ has_member_function_callable_with_func<functor, int, int, int>::value ? 1 : -1];
|
||||||
|
int check2[!has_member_function_callable_with_func<functor, int, char*, int>::value ? 1 : -1];
|
||||||
|
int check3[!has_member_function_callable_with_func<functor2, int, int, int>::value ? 1 : -1];
|
||||||
|
int check4[ has_member_function_callable_with_func<functor2, int, char*, void*>::value ? 1 : -1];
|
||||||
|
int check5[!has_member_function_callable_with_func<functor3, int, int, int>::value ? 1 : -1];
|
||||||
|
int check6[!has_member_function_callable_with_func<functor3, int, char*, void*>::value ? 1 : -1];
|
||||||
|
int check7[ has_member_function_callable_with_func<functor4, int, char*, int>::value ? 1 : -1];
|
||||||
|
(void)check1;
|
||||||
|
(void)check2;
|
||||||
|
(void)check3;
|
||||||
|
(void)check4;
|
||||||
|
(void)check5;
|
||||||
|
(void)check6;
|
||||||
|
(void)check7;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
#include <boost/intrusive/detail/config_end.hpp>
|
@@ -12,7 +12,7 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
#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/pointer_traits.hpp>
|
||||||
#include "itestvalue.hpp"
|
#include "itestvalue.hpp"
|
||||||
#include "smart_ptr.hpp"
|
#include "smart_ptr.hpp"
|
||||||
#include "common_functors.hpp"
|
#include "common_functors.hpp"
|
||||||
@@ -221,7 +221,7 @@ void test_list<ValueTraits>
|
|||||||
|
|
||||||
{
|
{
|
||||||
typename list_type::const_iterator ci = typename list_type::iterator();
|
typename list_type::const_iterator ci = typename list_type::iterator();
|
||||||
//typename list_type::iterator i = typename list_type::const_iterator();
|
(void)ci;
|
||||||
}
|
}
|
||||||
|
|
||||||
testlist.insert (i, values[0]);
|
testlist.insert (i, values[0]);
|
||||||
@@ -495,6 +495,5 @@ int main( int, char* [] )
|
|||||||
test_main_template<smart_ptr<void>, false>()();
|
test_main_template<smart_ptr<void>, false>()();
|
||||||
test_main_template<void*, true>()();
|
test_main_template<void*, true>()();
|
||||||
test_main_template<smart_ptr<void>, true>()();
|
test_main_template<smart_ptr<void>, true>()();
|
||||||
|
|
||||||
return boost::report_errors();
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
@@ -18,6 +18,7 @@
|
|||||||
#include <boost/intrusive/splay_set.hpp>
|
#include <boost/intrusive/splay_set.hpp>
|
||||||
#include <boost/intrusive/treap_set.hpp>
|
#include <boost/intrusive/treap_set.hpp>
|
||||||
#include <boost/intrusive/detail/mpl.hpp>
|
#include <boost/intrusive/detail/mpl.hpp>
|
||||||
|
#include <boost/intrusive/pointer_traits.hpp>
|
||||||
#include "smart_ptr.hpp"
|
#include "smart_ptr.hpp"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -92,7 +93,8 @@ int main()
|
|||||||
List my_list;
|
List my_list;
|
||||||
Slist my_slist;
|
Slist my_slist;
|
||||||
Set my_set;
|
Set my_set;
|
||||||
USet my_uset(USet::bucket_traits(buckets, 100));
|
USet my_uset(USet::bucket_traits
|
||||||
|
(pointer_traits<USet::bucket_ptr>::pointer_to(buckets[0]), 100));
|
||||||
|
|
||||||
AvlSet my_avlset;
|
AvlSet my_avlset;
|
||||||
SplaySet my_splayset;
|
SplaySet my_splayset;
|
||||||
|
201
test/pointer_traits_test.cpp
Normal file
201
test/pointer_traits_test.cpp
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// (C) Copyright Ion Gaztanaga 2011-2011. 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/type_traits/is_same.hpp>
|
||||||
|
#include <boost/static_assert.hpp>
|
||||||
|
#include <boost/intrusive/pointer_traits.hpp>
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class CompleteSmartPtr
|
||||||
|
{
|
||||||
|
template <class U>
|
||||||
|
friend class CompleteSmartPtr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_TEMPLATE_ALIASES)
|
||||||
|
template <class U> using rebind = CompleteSmartPtr<U>;
|
||||||
|
#else
|
||||||
|
template <class U> struct rebind
|
||||||
|
{ typedef CompleteSmartPtr<U> other; };
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef char difference_type;
|
||||||
|
typedef T element_type;
|
||||||
|
|
||||||
|
CompleteSmartPtr()
|
||||||
|
: ptr_(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
explicit CompleteSmartPtr(T &p)
|
||||||
|
: ptr_(&p)
|
||||||
|
{}
|
||||||
|
|
||||||
|
CompleteSmartPtr(const CompleteSmartPtr &c)
|
||||||
|
{ this->ptr_ = c.ptr_; }
|
||||||
|
|
||||||
|
CompleteSmartPtr & operator=(const CompleteSmartPtr &c)
|
||||||
|
{ this->ptr_ = c.ptr_; }
|
||||||
|
|
||||||
|
static CompleteSmartPtr pointer_to(T &r)
|
||||||
|
{ return CompleteSmartPtr(r); }
|
||||||
|
|
||||||
|
T * operator->() const
|
||||||
|
{ return ptr_; }
|
||||||
|
|
||||||
|
T & operator *() const
|
||||||
|
{ return *ptr_; }
|
||||||
|
|
||||||
|
template<class U>
|
||||||
|
static CompleteSmartPtr static_cast_from(const CompleteSmartPtr<U> &uptr)
|
||||||
|
{ return CompleteSmartPtr(*static_cast<element_type*>(uptr.ptr_)); }
|
||||||
|
|
||||||
|
template<class U>
|
||||||
|
static CompleteSmartPtr const_cast_from(const CompleteSmartPtr<U> &uptr)
|
||||||
|
{ return CompleteSmartPtr(*const_cast<element_type*>(uptr.ptr_)); }
|
||||||
|
|
||||||
|
template<class U>
|
||||||
|
static CompleteSmartPtr dynamic_cast_from(const CompleteSmartPtr<U> &uptr)
|
||||||
|
{ return CompleteSmartPtr(*dynamic_cast<element_type*>(uptr.ptr_)); }
|
||||||
|
|
||||||
|
friend bool operator ==(const CompleteSmartPtr &l, const CompleteSmartPtr &r)
|
||||||
|
{ return l.ptr_ == r.ptr_; }
|
||||||
|
|
||||||
|
friend bool operator !=(const CompleteSmartPtr &l, const CompleteSmartPtr &r)
|
||||||
|
{ return l.ptr_ != r.ptr_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
T *ptr_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class SimpleSmartPtr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
SimpleSmartPtr()
|
||||||
|
: ptr_(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
explicit SimpleSmartPtr(T *p)
|
||||||
|
: ptr_(p)
|
||||||
|
{}
|
||||||
|
|
||||||
|
SimpleSmartPtr(const SimpleSmartPtr &c)
|
||||||
|
{ this->ptr_ = c.ptr_; }
|
||||||
|
|
||||||
|
SimpleSmartPtr & operator=(const SimpleSmartPtr &c)
|
||||||
|
{ this->ptr_ = c.ptr_; }
|
||||||
|
|
||||||
|
friend bool operator ==(const SimpleSmartPtr &l, const SimpleSmartPtr &r)
|
||||||
|
{ return l.ptr_ == r.ptr_; }
|
||||||
|
|
||||||
|
friend bool operator !=(const SimpleSmartPtr &l, const SimpleSmartPtr &r)
|
||||||
|
{ return l.ptr_ != r.ptr_; }
|
||||||
|
|
||||||
|
T* operator->() const
|
||||||
|
{ return ptr_; }
|
||||||
|
|
||||||
|
T & operator *() const
|
||||||
|
{ return *ptr_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
T *ptr_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class B{ public: virtual ~B(){} };
|
||||||
|
class D : public B {};
|
||||||
|
class DD : public virtual B {};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int dummy;
|
||||||
|
|
||||||
|
//Raw pointer
|
||||||
|
BOOST_STATIC_ASSERT(( boost::is_same<boost::intrusive::pointer_traits
|
||||||
|
<int*>::element_type, int>::value ));
|
||||||
|
BOOST_STATIC_ASSERT(( boost::is_same<boost::intrusive::pointer_traits
|
||||||
|
<int*>::pointer, int*>::value ));
|
||||||
|
BOOST_STATIC_ASSERT(( boost::is_same<boost::intrusive::pointer_traits
|
||||||
|
<int*>::difference_type, std::ptrdiff_t>::value ));
|
||||||
|
BOOST_STATIC_ASSERT(( boost::is_same<boost::intrusive::pointer_traits
|
||||||
|
<int*>::rebind_pointer<double>::type
|
||||||
|
, double*>::value ));
|
||||||
|
if(boost::intrusive::pointer_traits<int*>::pointer_to(dummy) != &dummy){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(boost::intrusive::pointer_traits<D*>::static_cast_from((B*)0)){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(boost::intrusive::pointer_traits<D*>::const_cast_from((const D*)0)){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(boost::intrusive::pointer_traits<DD*>::dynamic_cast_from((B*)0)){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Complete smart pointer
|
||||||
|
BOOST_STATIC_ASSERT(( boost::is_same<boost::intrusive::pointer_traits
|
||||||
|
< CompleteSmartPtr<int> >::element_type, int>::value ));
|
||||||
|
BOOST_STATIC_ASSERT(( boost::is_same<boost::intrusive::pointer_traits
|
||||||
|
< CompleteSmartPtr<int> >::pointer, CompleteSmartPtr<int> >::value ));
|
||||||
|
BOOST_STATIC_ASSERT(( boost::is_same<boost::intrusive::pointer_traits
|
||||||
|
< CompleteSmartPtr<int> >::difference_type, char>::value ));
|
||||||
|
BOOST_STATIC_ASSERT(( boost::is_same<boost::intrusive::pointer_traits
|
||||||
|
< CompleteSmartPtr<int> >::rebind_pointer<double>::type
|
||||||
|
, CompleteSmartPtr<double> >::value ));
|
||||||
|
if(boost::intrusive::pointer_traits< CompleteSmartPtr<int> >
|
||||||
|
::pointer_to(dummy) != CompleteSmartPtr<int>(dummy)){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(boost::intrusive::pointer_traits< CompleteSmartPtr<D> >::
|
||||||
|
static_cast_from(CompleteSmartPtr<B>()) != CompleteSmartPtr<D>()){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(boost::intrusive::pointer_traits< CompleteSmartPtr<D> >::
|
||||||
|
const_cast_from(CompleteSmartPtr<const D>()) != CompleteSmartPtr<D>()){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(boost::intrusive::pointer_traits< CompleteSmartPtr<DD> >::
|
||||||
|
dynamic_cast_from(CompleteSmartPtr<B>()) != CompleteSmartPtr<DD>()){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Simple smart pointer
|
||||||
|
BOOST_STATIC_ASSERT(( boost::is_same<boost::intrusive::pointer_traits
|
||||||
|
< SimpleSmartPtr<int> >::element_type, int>::value ));
|
||||||
|
BOOST_STATIC_ASSERT(( boost::is_same<boost::intrusive::pointer_traits
|
||||||
|
< SimpleSmartPtr<int> >::pointer, SimpleSmartPtr<int> >::value ));
|
||||||
|
BOOST_STATIC_ASSERT(( boost::is_same<boost::intrusive::pointer_traits
|
||||||
|
< SimpleSmartPtr<int> >::difference_type, std::ptrdiff_t>::value ));
|
||||||
|
BOOST_STATIC_ASSERT(( boost::is_same<boost::intrusive::pointer_traits
|
||||||
|
< SimpleSmartPtr<int> >::rebind_pointer<double>::type
|
||||||
|
, SimpleSmartPtr<double> >::value ));
|
||||||
|
if(boost::intrusive::pointer_traits< SimpleSmartPtr<int> >
|
||||||
|
::pointer_to(dummy) != SimpleSmartPtr<int>(&dummy)){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(boost::intrusive::pointer_traits< SimpleSmartPtr<D> >::
|
||||||
|
static_cast_from(SimpleSmartPtr<B>()) != SimpleSmartPtr<D>()){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(boost::intrusive::pointer_traits< SimpleSmartPtr<D> >::
|
||||||
|
const_cast_from(SimpleSmartPtr<const D>()) != SimpleSmartPtr<D>()){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(boost::intrusive::pointer_traits< SimpleSmartPtr<DD> >::
|
||||||
|
dynamic_cast_from(SimpleSmartPtr<B>()) != SimpleSmartPtr<DD>()){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <boost/intrusive/detail/config_end.hpp>
|
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
#include <boost/intrusive/detail/config_begin.hpp>
|
#include <boost/intrusive/detail/config_begin.hpp>
|
||||||
#include <boost/intrusive/slist.hpp>
|
#include <boost/intrusive/slist.hpp>
|
||||||
#include <boost/intrusive/detail/pointer_to_other.hpp>
|
#include <boost/intrusive/pointer_traits.hpp>
|
||||||
#include "itestvalue.hpp"
|
#include "itestvalue.hpp"
|
||||||
#include "smart_ptr.hpp"
|
#include "smart_ptr.hpp"
|
||||||
#include "common_functors.hpp"
|
#include "common_functors.hpp"
|
||||||
|
@@ -14,6 +14,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>
|
#include <boost/pointer_cast.hpp>
|
||||||
|
#include <boost/intrusive/pointer_traits.hpp>
|
||||||
|
|
||||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||||
# pragma once
|
# pragma once
|
||||||
@@ -108,6 +109,11 @@ class smart_ptr
|
|||||||
|
|
||||||
public: //Public Functions
|
public: //Public Functions
|
||||||
|
|
||||||
|
smart_ptr()
|
||||||
|
: m_ptr(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/*
|
||||||
//!Constructor from raw pointer (allows "0" pointer conversion). Never throws.
|
//!Constructor from raw pointer (allows "0" pointer conversion). Never throws.
|
||||||
explicit smart_ptr(pointer ptr = 0)
|
explicit smart_ptr(pointer ptr = 0)
|
||||||
: m_ptr(ptr)
|
: m_ptr(ptr)
|
||||||
@@ -118,64 +124,67 @@ class smart_ptr
|
|||||||
smart_ptr(T *ptr)
|
smart_ptr(T *ptr)
|
||||||
: m_ptr(ptr)
|
: m_ptr(ptr)
|
||||||
{}
|
{}
|
||||||
|
*/
|
||||||
//!Constructor from other smart_ptr
|
//!Constructor from other smart_ptr
|
||||||
smart_ptr(const smart_ptr& ptr)
|
smart_ptr(const smart_ptr& ptr)
|
||||||
: m_ptr(ptr.m_ptr)
|
: m_ptr(ptr.m_ptr)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
static smart_ptr pointer_to(reference r)
|
||||||
|
{ smart_ptr p; p.m_ptr = &r; return p; }
|
||||||
|
|
||||||
//!Constructor from other smart_ptr. If pointers of pointee types are
|
//!Constructor from other smart_ptr. If pointers of pointee types are
|
||||||
//!convertible, offset_ptrs will be convertibles. Never throws.
|
//!convertible, offset_ptrs will be convertibles. Never throws.
|
||||||
template<class T2>
|
template<class T2>
|
||||||
smart_ptr(const smart_ptr<T2> &ptr)
|
smart_ptr(const smart_ptr<T2> &ptr)
|
||||||
: m_ptr(ptr.m_ptr)
|
: m_ptr(ptr.m_ptr)
|
||||||
{}
|
{}
|
||||||
|
/*
|
||||||
//!Emulates static_cast operator. Never throws.
|
//!Emulates static_cast operator. Never throws.
|
||||||
template<class Y>
|
template<class Y>
|
||||||
smart_ptr(const smart_ptr<Y> & r, detail::static_cast_tag)
|
smart_ptr(const smart_ptr<Y> & r, detail::static_cast_tag)
|
||||||
: m_ptr(static_cast<PointedType*>(r.get()))
|
: m_ptr(static_cast<PointedType*>(r.m_ptr))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//!Emulates const_cast operator. Never throws.
|
//!Emulates const_cast operator. Never throws.
|
||||||
template<class Y>
|
template<class Y>
|
||||||
smart_ptr(const smart_ptr<Y> & r, detail::const_cast_tag)
|
smart_ptr(const smart_ptr<Y> & r, detail::const_cast_tag)
|
||||||
: m_ptr(const_cast<PointedType*>(r.get()))
|
: m_ptr(const_cast<PointedType*>(r.m_ptr))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//!Emulates dynamic_cast operator. Never throws.
|
//!Emulates dynamic_cast operator. Never throws.
|
||||||
template<class Y>
|
template<class Y>
|
||||||
smart_ptr(const smart_ptr<Y> & r, detail::dynamic_cast_tag)
|
smart_ptr(const smart_ptr<Y> & r, detail::dynamic_cast_tag)
|
||||||
: m_ptr(dynamic_cast<PointedType*>(r.get()))
|
: m_ptr(dynamic_cast<PointedType*>(r.m_ptr))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//!Emulates reinterpret_cast operator. Never throws.
|
//!Emulates reinterpret_cast operator. Never throws.
|
||||||
template<class Y>
|
template<class Y>
|
||||||
smart_ptr(const smart_ptr<Y> & r, detail::reinterpret_cast_tag)
|
smart_ptr(const smart_ptr<Y> & r, detail::reinterpret_cast_tag)
|
||||||
: m_ptr(reinterpret_cast<PointedType*>(r.get()))
|
: m_ptr(reinterpret_cast<PointedType*>(r.m_ptr))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//!Obtains raw pointer from offset. Never throws.
|
//!Obtains raw pointer from offset. Never throws.
|
||||||
pointer get() const
|
pointer get() const
|
||||||
{ return m_ptr; }
|
{ return m_ptr; }
|
||||||
|
*/
|
||||||
//!Pointer-like -> operator. It can return 0 pointer. Never throws.
|
//!Pointer-like -> operator. It can return 0 pointer. Never throws.
|
||||||
pointer operator->() const
|
pointer operator->() const
|
||||||
{ return this->get(); }
|
{ return m_ptr; }
|
||||||
|
|
||||||
//!Dereferencing operator, if it is a null smart_ptr behavior
|
//!Dereferencing operator, if it is a null smart_ptr behavior
|
||||||
//! is undefined. Never throws.
|
//! is undefined. Never throws.
|
||||||
reference operator* () const
|
reference operator* () const
|
||||||
{ return *(this->get()); }
|
{ return *m_ptr; }
|
||||||
|
|
||||||
//!Indexing operator. Never throws.
|
//!Indexing operator. Never throws.
|
||||||
reference operator[](std::ptrdiff_t idx) const
|
reference operator[](std::ptrdiff_t idx) const
|
||||||
{ return this->get()[idx]; }
|
{ return m_ptr[idx]; }
|
||||||
|
/*
|
||||||
//!Assignment from pointer (saves extra conversion). Never throws.
|
//!Assignment from pointer (saves extra conversion). Never throws.
|
||||||
smart_ptr& operator= (pointer from)
|
smart_ptr& operator= (pointer from)
|
||||||
{ m_ptr = from; return *this; }
|
{ m_ptr = from; return *this; }
|
||||||
|
*/
|
||||||
//!Assignment from other smart_ptr. Never throws.
|
//!Assignment from other smart_ptr. Never throws.
|
||||||
smart_ptr& operator= (const smart_ptr & pt)
|
smart_ptr& operator= (const smart_ptr & pt)
|
||||||
{ m_ptr = pt.m_ptr; return *this; }
|
{ m_ptr = pt.m_ptr; return *this; }
|
||||||
@@ -188,11 +197,11 @@ class smart_ptr
|
|||||||
|
|
||||||
//!smart_ptr + std::ptrdiff_t. Never throws.
|
//!smart_ptr + std::ptrdiff_t. Never throws.
|
||||||
smart_ptr operator+ (std::ptrdiff_t offset) const
|
smart_ptr operator+ (std::ptrdiff_t offset) const
|
||||||
{ return smart_ptr(this->get()+offset); }
|
{ smart_ptr s; s.m_ptr = m_ptr + offset; return s; }
|
||||||
|
|
||||||
//!smart_ptr - std::ptrdiff_t. Never throws.
|
//!smart_ptr - std::ptrdiff_t. Never throws.
|
||||||
smart_ptr operator- (std::ptrdiff_t offset) const
|
smart_ptr operator- (std::ptrdiff_t offset) const
|
||||||
{ return smart_ptr(this->get()-offset); }
|
{ smart_ptr s; s.m_ptr = m_ptr - offset; return s; }
|
||||||
|
|
||||||
//!smart_ptr += std::ptrdiff_t. Never throws.
|
//!smart_ptr += std::ptrdiff_t. Never throws.
|
||||||
smart_ptr &operator+= (std::ptrdiff_t offset)
|
smart_ptr &operator+= (std::ptrdiff_t offset)
|
||||||
@@ -220,12 +229,12 @@ class smart_ptr
|
|||||||
|
|
||||||
//!safe bool conversion operator. Never throws.
|
//!safe bool conversion operator. Never throws.
|
||||||
operator unspecified_bool_type() const
|
operator unspecified_bool_type() const
|
||||||
{ return this->get()? &self_t::unspecified_bool_type_func : 0; }
|
{ return m_ptr? &self_t::unspecified_bool_type_func : 0; }
|
||||||
|
|
||||||
//!Not operator. Not needed in theory, but improves portability.
|
//!Not operator. Not needed in theory, but improves portability.
|
||||||
//!Never throws.
|
//!Never throws.
|
||||||
bool operator! () const
|
bool operator! () const
|
||||||
{ return this->get() == 0; }
|
{ return m_ptr == 0; }
|
||||||
/*
|
/*
|
||||||
friend void swap (smart_ptr &pt, smart_ptr &pt2)
|
friend void swap (smart_ptr &pt, smart_ptr &pt2)
|
||||||
{
|
{
|
||||||
@@ -240,43 +249,43 @@ class smart_ptr
|
|||||||
template<class T1, class T2>
|
template<class T1, class T2>
|
||||||
inline bool operator== (const smart_ptr<T1> &pt1,
|
inline bool operator== (const smart_ptr<T1> &pt1,
|
||||||
const smart_ptr<T2> &pt2)
|
const smart_ptr<T2> &pt2)
|
||||||
{ return pt1.get() == pt2.get(); }
|
{ return pt1.operator->() == pt2.operator->(); }
|
||||||
|
|
||||||
//!smart_ptr<T1> != smart_ptr<T2>. Never throws.
|
//!smart_ptr<T1> != smart_ptr<T2>. Never throws.
|
||||||
template<class T1, class T2>
|
template<class T1, class T2>
|
||||||
inline bool operator!= (const smart_ptr<T1> &pt1,
|
inline bool operator!= (const smart_ptr<T1> &pt1,
|
||||||
const smart_ptr<T2> &pt2)
|
const smart_ptr<T2> &pt2)
|
||||||
{ return pt1.get() != pt2.get(); }
|
{ return pt1.operator->() != pt2.operator->(); }
|
||||||
|
|
||||||
//!smart_ptr<T1> < smart_ptr<T2>. Never throws.
|
//!smart_ptr<T1> < smart_ptr<T2>. Never throws.
|
||||||
template<class T1, class T2>
|
template<class T1, class T2>
|
||||||
inline bool operator< (const smart_ptr<T1> &pt1,
|
inline bool operator< (const smart_ptr<T1> &pt1,
|
||||||
const smart_ptr<T2> &pt2)
|
const smart_ptr<T2> &pt2)
|
||||||
{ return pt1.get() < pt2.get(); }
|
{ return pt1.operator->() < pt2.operator->(); }
|
||||||
|
|
||||||
//!smart_ptr<T1> <= smart_ptr<T2>. Never throws.
|
//!smart_ptr<T1> <= smart_ptr<T2>. Never throws.
|
||||||
template<class T1, class T2>
|
template<class T1, class T2>
|
||||||
inline bool operator<= (const smart_ptr<T1> &pt1,
|
inline bool operator<= (const smart_ptr<T1> &pt1,
|
||||||
const smart_ptr<T2> &pt2)
|
const smart_ptr<T2> &pt2)
|
||||||
{ return pt1.get() <= pt2.get(); }
|
{ return pt1.operator->() <= pt2.operator->(); }
|
||||||
|
|
||||||
//!smart_ptr<T1> > smart_ptr<T2>. Never throws.
|
//!smart_ptr<T1> > smart_ptr<T2>. Never throws.
|
||||||
template<class T1, class T2>
|
template<class T1, class T2>
|
||||||
inline bool operator> (const smart_ptr<T1> &pt1,
|
inline bool operator> (const smart_ptr<T1> &pt1,
|
||||||
const smart_ptr<T2> &pt2)
|
const smart_ptr<T2> &pt2)
|
||||||
{ return pt1.get() > pt2.get(); }
|
{ return pt1.operator->() > pt2.operator->(); }
|
||||||
|
|
||||||
//!smart_ptr<T1> >= smart_ptr<T2>. Never throws.
|
//!smart_ptr<T1> >= smart_ptr<T2>. Never throws.
|
||||||
template<class T1, class T2>
|
template<class T1, class T2>
|
||||||
inline bool operator>= (const smart_ptr<T1> &pt1,
|
inline bool operator>= (const smart_ptr<T1> &pt1,
|
||||||
const smart_ptr<T2> &pt2)
|
const smart_ptr<T2> &pt2)
|
||||||
{ return pt1.get() >= pt2.get(); }
|
{ return pt1.operator->() >= pt2.operator->(); }
|
||||||
|
|
||||||
//!operator<<
|
//!operator<<
|
||||||
template<class E, class T, class Y>
|
template<class E, class T, class Y>
|
||||||
inline std::basic_ostream<E, T> & operator<<
|
inline std::basic_ostream<E, T> & operator<<
|
||||||
(std::basic_ostream<E, T> & os, smart_ptr<Y> const & p)
|
(std::basic_ostream<E, T> & os, smart_ptr<Y> const & p)
|
||||||
{ return os << p.get(); }
|
{ return os << p.operator->(); }
|
||||||
|
|
||||||
//!operator>>
|
//!operator>>
|
||||||
template<class E, class T, class Y>
|
template<class E, class T, class Y>
|
||||||
@@ -292,24 +301,18 @@ inline smart_ptr<T> operator+(std::ptrdiff_t diff, const smart_ptr<T>& right)
|
|||||||
//!smart_ptr - smart_ptr
|
//!smart_ptr - smart_ptr
|
||||||
template<class T, class T2>
|
template<class T, class T2>
|
||||||
inline std::ptrdiff_t operator- (const smart_ptr<T> &pt, const smart_ptr<T2> &pt2)
|
inline std::ptrdiff_t operator- (const smart_ptr<T> &pt, const smart_ptr<T2> &pt2)
|
||||||
{ return pt.get()- pt2.get(); }
|
{ return pt.operator->()- pt2.operator->(); }
|
||||||
|
|
||||||
//!swap specialization
|
//!swap specialization
|
||||||
template<class T>
|
template<class T>
|
||||||
inline void swap (smart_ptr<T> &pt,
|
inline void swap (smart_ptr<T> &pt,
|
||||||
smart_ptr<T> &pt2)
|
smart_ptr<T> &pt2)
|
||||||
{
|
{
|
||||||
typename smart_ptr<T>::value_type *ptr = pt.get();
|
typename smart_ptr<T>::value_type *ptr = pt.operator->();
|
||||||
pt = pt2;
|
pt = pt2;
|
||||||
pt2 = ptr;
|
pt2 = ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
//!detail::boost_intrusive_get_pointer() enables boost::mem_fn to recognize smart_ptr.
|
|
||||||
//!Never throws.
|
|
||||||
template<class T>
|
|
||||||
inline T* boost_intrusive_get_pointer(const smart_ptr<T> & p)
|
|
||||||
{ return p.get(); }
|
|
||||||
|
|
||||||
//!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>
|
||||||
@@ -363,23 +366,26 @@ struct pointer_plus_bits<smart_ptr<T>, NumBits>
|
|||||||
typedef smart_ptr<T> pointer;
|
typedef smart_ptr<T> pointer;
|
||||||
|
|
||||||
static pointer get_pointer(const pointer &n)
|
static pointer get_pointer(const pointer &n)
|
||||||
{ return pointer_plus_bits<T*, NumBits>::get_pointer(n.get()); }
|
{
|
||||||
|
return pointer_traits<pointer>::pointer_to
|
||||||
|
(*pointer_plus_bits<T*, NumBits>::get_pointer(n.operator->()));
|
||||||
|
}
|
||||||
|
|
||||||
static void set_pointer(pointer &n, pointer p)
|
static void set_pointer(pointer &n, pointer p)
|
||||||
{
|
{
|
||||||
T *raw_n = n.get();
|
T *raw_n = n.operator->();
|
||||||
pointer_plus_bits<T*, NumBits>::set_pointer(raw_n, p.get());
|
pointer_plus_bits<T*, NumBits>::set_pointer(raw_n, p.operator->());
|
||||||
n = raw_n;
|
n = pointer_traits<pointer>::pointer_to(*raw_n);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::size_t get_bits(const pointer &n)
|
static std::size_t get_bits(const pointer &n)
|
||||||
{ return pointer_plus_bits<T*, NumBits>::get_bits(n.get()); }
|
{ return pointer_plus_bits<T*, NumBits>::get_bits(n.operator->()); }
|
||||||
|
|
||||||
static void set_bits(pointer &n, std::size_t c)
|
static void set_bits(pointer &n, std::size_t c)
|
||||||
{
|
{
|
||||||
T *raw_n = n.get();
|
T *raw_n = n.operator->();
|
||||||
pointer_plus_bits<T*, NumBits>::set_bits(raw_n, c);
|
pointer_plus_bits<T*, NumBits>::set_bits(raw_n, c);
|
||||||
n = raw_n;
|
n = pointer_traits<pointer>::pointer_to(*raw_n);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
#include <boost/intrusive/detail/config_begin.hpp>
|
#include <boost/intrusive/detail/config_begin.hpp>
|
||||||
#include <boost/intrusive/splay_set.hpp>
|
#include <boost/intrusive/splay_set.hpp>
|
||||||
#include <boost/intrusive/detail/pointer_to_other.hpp>
|
#include <boost/intrusive/pointer_traits.hpp>
|
||||||
#include "itestvalue.hpp"
|
#include "itestvalue.hpp"
|
||||||
#include "smart_ptr.hpp"
|
#include "smart_ptr.hpp"
|
||||||
#include "generic_multiset_test.hpp"
|
#include "generic_multiset_test.hpp"
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
#include <boost/intrusive/set.hpp>
|
#include <boost/intrusive/set.hpp>
|
||||||
#include <boost/intrusive/unordered_set.hpp>
|
#include <boost/intrusive/unordered_set.hpp>
|
||||||
#include <boost/functional/hash.hpp>
|
#include <boost/functional/hash.hpp>
|
||||||
#include <boost/pointer_to_other.hpp>
|
#include <boost/intrusive/pointer_traits.hpp>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
using namespace boost::intrusive;
|
using namespace boost::intrusive;
|
||||||
@@ -46,10 +46,11 @@ struct stateful_value_traits
|
|||||||
typedef typename node_traits::node_ptr node_ptr;
|
typedef typename node_traits::node_ptr node_ptr;
|
||||||
typedef typename node_traits::const_node_ptr const_node_ptr;
|
typedef typename node_traits::const_node_ptr const_node_ptr;
|
||||||
typedef T value_type;
|
typedef T value_type;
|
||||||
typedef typename boost::pointer_to_other
|
typedef typename pointer_traits<node_ptr>::
|
||||||
<node_ptr, T>::type pointer;
|
template rebind_pointer<T>::type pointer;
|
||||||
typedef typename boost::pointer_to_other
|
typedef typename pointer_traits<node_ptr>::
|
||||||
<node_ptr, const T>::type const_pointer;
|
template rebind_pointer<const T>::type const_pointer;
|
||||||
|
|
||||||
static const link_mode_type link_mode = normal_link;
|
static const link_mode_type link_mode = normal_link;
|
||||||
|
|
||||||
stateful_value_traits(pointer values, node_ptr node_array)
|
stateful_value_traits(pointer values, node_ptr node_array)
|
||||||
|
@@ -91,7 +91,6 @@ void test_sequence_container(Container & c, Data & d)
|
|||||||
c.insert( c.begin(), *i );
|
c.insert( c.begin(), *i );
|
||||||
c.insert( c.end(), *(++i) );
|
c.insert( c.end(), *(++i) );
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_TEST( c.size() == 2 );
|
BOOST_TEST( c.size() == 2 );
|
||||||
BOOST_TEST( !c.empty() );
|
BOOST_TEST( !c.empty() );
|
||||||
|
|
||||||
@@ -99,6 +98,17 @@ void test_sequence_container(Container & c, Data & d)
|
|||||||
i = c.erase( c.begin() );
|
i = c.erase( c.begin() );
|
||||||
|
|
||||||
BOOST_TEST( c.size() == 1 );
|
BOOST_TEST( c.size() == 1 );
|
||||||
|
BOOST_TEST( !c.empty() );
|
||||||
|
|
||||||
|
i = c.erase( c.begin() );
|
||||||
|
|
||||||
|
BOOST_TEST( c.size() == 0 );
|
||||||
|
BOOST_TEST( c.empty() );
|
||||||
|
|
||||||
|
c.insert( c.begin(), *d.begin() );
|
||||||
|
|
||||||
|
BOOST_TEST( c.size() == 1 );
|
||||||
|
BOOST_TEST( !c.empty() );
|
||||||
|
|
||||||
{
|
{
|
||||||
typename Data::iterator i = d.begin();
|
typename Data::iterator i = d.begin();
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
#include <boost/intrusive/detail/config_begin.hpp>
|
#include <boost/intrusive/detail/config_begin.hpp>
|
||||||
#include <boost/intrusive/unordered_set.hpp>
|
#include <boost/intrusive/unordered_set.hpp>
|
||||||
#include <boost/intrusive/detail/pointer_to_other.hpp>
|
#include <boost/intrusive/pointer_traits.hpp>
|
||||||
#include "itestvalue.hpp"
|
#include "itestvalue.hpp"
|
||||||
#include "smart_ptr.hpp"
|
#include "smart_ptr.hpp"
|
||||||
#include "common_functors.hpp"
|
#include "common_functors.hpp"
|
||||||
@@ -102,7 +102,9 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>:
|
|||||||
{
|
{
|
||||||
typedef typename unordered_multiset_type::bucket_traits bucket_traits;
|
typedef typename unordered_multiset_type::bucket_traits bucket_traits;
|
||||||
typename unordered_multiset_type::bucket_type buckets [BucketSize];
|
typename unordered_multiset_type::bucket_type buckets [BucketSize];
|
||||||
unordered_multiset_type testset(bucket_traits(buckets, BucketSize));
|
unordered_multiset_type testset
|
||||||
|
(bucket_traits(pointer_traits<typename unordered_multiset_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets[0]), BucketSize));
|
||||||
testset.insert(values.begin(), values.end());
|
testset.insert(values.begin(), values.end());
|
||||||
test::test_container(testset);
|
test::test_container(testset);
|
||||||
testset.clear();
|
testset.clear();
|
||||||
@@ -145,7 +147,9 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>
|
|||||||
values[i].value_ = i;
|
values[i].value_ = i;
|
||||||
|
|
||||||
typename unordered_multiset_type::bucket_type buckets [BucketSize];
|
typename unordered_multiset_type::bucket_type buckets [BucketSize];
|
||||||
unordered_multiset_type testset(bucket_traits(buckets, BucketSize));
|
unordered_multiset_type testset(bucket_traits(
|
||||||
|
pointer_traits<typename unordered_multiset_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets[0]), BucketSize));
|
||||||
|
|
||||||
for (int i = 0; i < 5; ++i)
|
for (int i = 0; i < 5; ++i)
|
||||||
testset.insert (values[i]);
|
testset.insert (values[i]);
|
||||||
@@ -175,7 +179,10 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>
|
|||||||
typedef typename unordered_multiset_type::bucket_traits bucket_traits;
|
typedef typename unordered_multiset_type::bucket_traits bucket_traits;
|
||||||
|
|
||||||
typename unordered_multiset_type::bucket_type buckets [BucketSize];
|
typename unordered_multiset_type::bucket_type buckets [BucketSize];
|
||||||
unordered_multiset_type testset1(values.begin(), values.end(), bucket_traits(buckets, BucketSize));
|
unordered_multiset_type testset1
|
||||||
|
(values.begin(), values.end(), bucket_traits
|
||||||
|
(pointer_traits<typename unordered_multiset_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets[0]), BucketSize));
|
||||||
|
|
||||||
if(Incremental){
|
if(Incremental){
|
||||||
{ int init_values [] = { 4, 5, 1, 2, 2, 3 };
|
{ int init_values [] = { 4, 5, 1, 2, 2, 3 };
|
||||||
@@ -206,7 +213,9 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>
|
|||||||
typedef typename unordered_multiset_type::bucket_traits bucket_traits;
|
typedef typename unordered_multiset_type::bucket_traits bucket_traits;
|
||||||
typedef typename unordered_multiset_type::iterator iterator;
|
typedef typename unordered_multiset_type::iterator iterator;
|
||||||
typename unordered_multiset_type::bucket_type buckets [BucketSize];
|
typename unordered_multiset_type::bucket_type buckets [BucketSize];
|
||||||
unordered_multiset_type testset(bucket_traits(buckets, BucketSize));
|
unordered_multiset_type testset(bucket_traits(
|
||||||
|
pointer_traits<typename unordered_multiset_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets[0]), BucketSize));
|
||||||
|
|
||||||
testset.insert(&values[0] + 2, &values[0] + 5);
|
testset.insert(&values[0] + 2, &values[0] + 5);
|
||||||
|
|
||||||
@@ -244,7 +253,9 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>
|
|||||||
|
|
||||||
//Now with a single bucket
|
//Now with a single bucket
|
||||||
typename unordered_multiset_type::bucket_type single_bucket[1];
|
typename unordered_multiset_type::bucket_type single_bucket[1];
|
||||||
unordered_multiset_type testset2(bucket_traits(single_bucket, 1));
|
unordered_multiset_type testset2(bucket_traits(
|
||||||
|
pointer_traits<typename unordered_multiset_type::bucket_ptr>::
|
||||||
|
pointer_to(single_bucket[0]), 1));
|
||||||
testset2.insert(&values[0], &values[0] + values.size());
|
testset2.insert(&values[0], &values[0] + values.size());
|
||||||
BOOST_TEST (testset2.erase(5) == 1);
|
BOOST_TEST (testset2.erase(5) == 1);
|
||||||
BOOST_TEST (testset2.erase(2) == 2);
|
BOOST_TEST (testset2.erase(2) == 2);
|
||||||
@@ -286,7 +297,9 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>
|
|||||||
|
|
||||||
//Now with a single bucket
|
//Now with a single bucket
|
||||||
typename unordered_multiset_type::bucket_type single_bucket[1];
|
typename unordered_multiset_type::bucket_type single_bucket[1];
|
||||||
unordered_multiset_type testset2(bucket_traits(single_bucket, 1));
|
unordered_multiset_type testset2(bucket_traits(
|
||||||
|
pointer_traits<typename unordered_multiset_type::bucket_ptr>::
|
||||||
|
pointer_to(single_bucket[0]), 1));
|
||||||
testset2.insert(&values[0], &values[0] + values.size());
|
testset2.insert(&values[0], &values[0] + values.size());
|
||||||
BOOST_TEST (testset2.erase(5) == 1);
|
BOOST_TEST (testset2.erase(5) == 1);
|
||||||
BOOST_TEST (testset2.erase(2) == 2);
|
BOOST_TEST (testset2.erase(2) == 2);
|
||||||
@@ -305,7 +318,9 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>
|
|||||||
std::vector<typename ValueTraits::value_type> data (random_size);
|
std::vector<typename ValueTraits::value_type> data (random_size);
|
||||||
for (unsigned int j = 0; j < random_size; ++j)
|
for (unsigned int j = 0; j < random_size; ++j)
|
||||||
data[j].value_ = random_init[j];
|
data[j].value_ = random_init[j];
|
||||||
unordered_multiset_type testset_new(bucket_traits(single_bucket, 1));
|
unordered_multiset_type testset_new(bucket_traits(
|
||||||
|
pointer_traits<typename unordered_multiset_type::bucket_ptr>::
|
||||||
|
pointer_to(single_bucket[0]), 1));
|
||||||
testset_new.insert(&data[0], &data[0]+max);
|
testset_new.insert(&data[0], &data[0]+max);
|
||||||
testset_new.erase(testset_new.iterator_to(data[i]));
|
testset_new.erase(testset_new.iterator_to(data[i]));
|
||||||
BOOST_TEST (testset_new.size() == (max -1));
|
BOOST_TEST (testset_new.size() == (max -1));
|
||||||
@@ -332,7 +347,8 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>
|
|||||||
unordered_multiset_type testset
|
unordered_multiset_type testset
|
||||||
( &random_init[0]
|
( &random_init[0]
|
||||||
, &random_init[0] + random_init.size()
|
, &random_init[0] + random_init.size()
|
||||||
, bucket_traits(buckets, NumBucketSize));
|
, bucket_traits(pointer_traits<typename unordered_multiset_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets[0]), NumBucketSize));
|
||||||
|
|
||||||
BOOST_TEST (testset.size() == random_init.size());
|
BOOST_TEST (testset.size() == random_init.size());
|
||||||
|
|
||||||
@@ -394,8 +410,12 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>:
|
|||||||
typename unordered_multiset_type::bucket_type buckets [BucketSize];
|
typename unordered_multiset_type::bucket_type buckets [BucketSize];
|
||||||
|
|
||||||
typename unordered_multiset_type::bucket_type buckets2 [BucketSize];
|
typename unordered_multiset_type::bucket_type buckets2 [BucketSize];
|
||||||
unordered_multiset_type testset1(&values[0], &values[0] + 2, bucket_traits(buckets, BucketSize));
|
unordered_multiset_type testset1(&values[0], &values[0] + 2,
|
||||||
unordered_multiset_type testset2(bucket_traits(buckets2, BucketSize));
|
bucket_traits(pointer_traits<typename unordered_multiset_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets[0]), BucketSize));
|
||||||
|
unordered_multiset_type testset2(bucket_traits(
|
||||||
|
pointer_traits<typename unordered_multiset_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets2[0]), BucketSize));
|
||||||
|
|
||||||
testset2.insert (&values[0] + 2, &values[0] + 6);
|
testset2.insert (&values[0] + 2, &values[0] + 6);
|
||||||
testset1.swap (testset2);
|
testset1.swap (testset2);
|
||||||
@@ -445,7 +465,9 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>
|
|||||||
//Build a uset
|
//Build a uset
|
||||||
typename unordered_multiset_type::bucket_type buckets1 [BucketSize];
|
typename unordered_multiset_type::bucket_type buckets1 [BucketSize];
|
||||||
typename unordered_multiset_type::bucket_type buckets2 [BucketSize*2];
|
typename unordered_multiset_type::bucket_type buckets2 [BucketSize*2];
|
||||||
unordered_multiset_type testset1(&values[0], &values[0] + values.size(), bucket_traits(buckets1, BucketSize));
|
unordered_multiset_type testset1(&values[0], &values[0] + values.size(),
|
||||||
|
bucket_traits(pointer_traits<typename unordered_multiset_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets1[0]), BucketSize));
|
||||||
//Test current state
|
//Test current state
|
||||||
BOOST_TEST(testset1.split_count() == BucketSize/2);
|
BOOST_TEST(testset1.split_count() == BucketSize/2);
|
||||||
{ int init_values [] = { 4, 5, 1, 2, 2, 3 };
|
{ int init_values [] = { 4, 5, 1, 2, 2, 3 };
|
||||||
@@ -472,21 +494,27 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>
|
|||||||
//Try incremental hashing specifying a new bucket traits pointing to the same array
|
//Try incremental hashing specifying a new bucket traits pointing to the same array
|
||||||
//
|
//
|
||||||
//This incremental rehash should fail because the new size is not twice the original
|
//This incremental rehash should fail because the new size is not twice the original
|
||||||
BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets1, BucketSize)) == false);
|
BOOST_TEST(testset1.incremental_rehash(bucket_traits(
|
||||||
|
pointer_traits<typename unordered_multiset_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets1[0]), BucketSize)) == false);
|
||||||
BOOST_TEST(testset1.split_count() == BucketSize);
|
BOOST_TEST(testset1.split_count() == BucketSize);
|
||||||
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
//This incremental rehash should success because the new size is twice the original
|
//This incremental rehash should success because the new size is twice the original
|
||||||
//and split_count is the same as the old bucket count
|
//and split_count is the same as the old bucket count
|
||||||
BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets1, BucketSize*2)) == true);
|
BOOST_TEST(testset1.incremental_rehash(bucket_traits(
|
||||||
|
pointer_traits<typename unordered_multiset_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets1[0]), BucketSize*2)) == true);
|
||||||
BOOST_TEST(testset1.split_count() == BucketSize);
|
BOOST_TEST(testset1.split_count() == BucketSize);
|
||||||
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
//This incremental rehash should also success because the new size is half the original
|
//This incremental rehash should also success because the new size is half the original
|
||||||
//and split_count is the same as the new bucket count
|
//and split_count is the same as the new bucket count
|
||||||
BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets1, BucketSize)) == true);
|
BOOST_TEST(testset1.incremental_rehash(bucket_traits(
|
||||||
|
pointer_traits<typename unordered_multiset_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets1[0]), BucketSize)) == true);
|
||||||
BOOST_TEST(testset1.split_count() == BucketSize);
|
BOOST_TEST(testset1.split_count() == BucketSize);
|
||||||
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
@@ -495,39 +523,51 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>
|
|||||||
//Try incremental hashing specifying a new bucket traits pointing to the same array
|
//Try incremental hashing specifying a new bucket traits pointing to the same array
|
||||||
//
|
//
|
||||||
//This incremental rehash should fail because the new size is not twice the original
|
//This incremental rehash should fail because the new size is not twice the original
|
||||||
BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets2, BucketSize)) == false);
|
BOOST_TEST(testset1.incremental_rehash(bucket_traits(
|
||||||
|
pointer_traits<typename unordered_multiset_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets2[0]), BucketSize)) == false);
|
||||||
BOOST_TEST(testset1.split_count() == BucketSize);
|
BOOST_TEST(testset1.split_count() == BucketSize);
|
||||||
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
//This incremental rehash should success because the new size is twice the original
|
//This incremental rehash should success because the new size is twice the original
|
||||||
//and split_count is the same as the old bucket count
|
//and split_count is the same as the old bucket count
|
||||||
BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets2, BucketSize*2)) == true);
|
BOOST_TEST(testset1.incremental_rehash(bucket_traits(
|
||||||
|
pointer_traits<typename unordered_multiset_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets2[0]), BucketSize*2)) == true);
|
||||||
BOOST_TEST(testset1.split_count() == BucketSize);
|
BOOST_TEST(testset1.split_count() == BucketSize);
|
||||||
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
//This incremental rehash should also success because the new size is half the original
|
//This incremental rehash should also success because the new size is half the original
|
||||||
//and split_count is the same as the new bucket count
|
//and split_count is the same as the new bucket count
|
||||||
BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets1, BucketSize)) == true);
|
BOOST_TEST(testset1.incremental_rehash(bucket_traits(
|
||||||
|
pointer_traits<typename unordered_multiset_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets1[0]), BucketSize)) == true);
|
||||||
BOOST_TEST(testset1.split_count() == BucketSize);
|
BOOST_TEST(testset1.split_count() == BucketSize);
|
||||||
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
//Full shrink rehash
|
//Full shrink rehash
|
||||||
testset1.rehash(bucket_traits(buckets1, 4));
|
testset1.rehash(bucket_traits(
|
||||||
|
pointer_traits<typename unordered_multiset_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets1[0]), 4));
|
||||||
BOOST_TEST (testset1.size() == values.size());
|
BOOST_TEST (testset1.size() == values.size());
|
||||||
BOOST_TEST (testset1.incremental_rehash() == false);
|
BOOST_TEST (testset1.incremental_rehash() == false);
|
||||||
{ int init_values [] = { 4, 5, 1, 2, 2, 3 };
|
{ int init_values [] = { 4, 5, 1, 2, 2, 3 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
//Full shrink rehash again
|
//Full shrink rehash again
|
||||||
testset1.rehash(bucket_traits(buckets1, 2));
|
testset1.rehash(bucket_traits(
|
||||||
|
pointer_traits<typename unordered_multiset_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets1[0]), 2));
|
||||||
BOOST_TEST (testset1.size() == values.size());
|
BOOST_TEST (testset1.size() == values.size());
|
||||||
BOOST_TEST (testset1.incremental_rehash() == false);
|
BOOST_TEST (testset1.incremental_rehash() == false);
|
||||||
{ int init_values [] = { 2, 2, 4, 3, 5, 1 };
|
{ int init_values [] = { 2, 2, 4, 3, 5, 1 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
//Full growing rehash
|
//Full growing rehash
|
||||||
testset1.rehash(bucket_traits(buckets1, BucketSize));
|
testset1.rehash(bucket_traits(
|
||||||
|
pointer_traits<typename unordered_multiset_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets1[0]), BucketSize));
|
||||||
BOOST_TEST (testset1.size() == values.size());
|
BOOST_TEST (testset1.size() == values.size());
|
||||||
BOOST_TEST (testset1.incremental_rehash() == false);
|
BOOST_TEST (testset1.incremental_rehash() == false);
|
||||||
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
||||||
@@ -575,29 +615,39 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>
|
|||||||
typename unordered_multiset_type::bucket_type buckets2 [2];
|
typename unordered_multiset_type::bucket_type buckets2 [2];
|
||||||
typename unordered_multiset_type::bucket_type buckets3 [BucketSize*2];
|
typename unordered_multiset_type::bucket_type buckets3 [BucketSize*2];
|
||||||
|
|
||||||
unordered_multiset_type testset1(&values[0], &values[0] + 6, bucket_traits(buckets1, BucketSize));
|
unordered_multiset_type testset1(&values[0], &values[0] + 6, bucket_traits(
|
||||||
|
pointer_traits<typename unordered_multiset_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets1[0]), BucketSize));
|
||||||
BOOST_TEST (testset1.size() == values.size());
|
BOOST_TEST (testset1.size() == values.size());
|
||||||
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
testset1.rehash(bucket_traits(buckets2, 2));
|
testset1.rehash(bucket_traits(
|
||||||
|
pointer_traits<typename unordered_multiset_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets2[0]), 2));
|
||||||
BOOST_TEST (testset1.size() == values.size());
|
BOOST_TEST (testset1.size() == values.size());
|
||||||
{ int init_values [] = { 4, 2, 2, 5, 3, 1 };
|
{ int init_values [] = { 4, 2, 2, 5, 3, 1 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
testset1.rehash(bucket_traits(buckets3, BucketSize*2));
|
testset1.rehash(bucket_traits(
|
||||||
|
pointer_traits<typename unordered_multiset_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets3[0]), BucketSize*2));
|
||||||
BOOST_TEST (testset1.size() == values.size());
|
BOOST_TEST (testset1.size() == values.size());
|
||||||
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
//Now rehash reducing the buckets
|
//Now rehash reducing the buckets
|
||||||
testset1.rehash(bucket_traits(buckets3, 2));
|
testset1.rehash(bucket_traits(
|
||||||
|
pointer_traits<typename unordered_multiset_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets3[0]), 2));
|
||||||
BOOST_TEST (testset1.size() == values.size());
|
BOOST_TEST (testset1.size() == values.size());
|
||||||
{ int init_values [] = { 4, 2, 2, 5, 3, 1 };
|
{ int init_values [] = { 4, 2, 2, 5, 3, 1 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
//Now rehash increasing the buckets
|
//Now rehash increasing the buckets
|
||||||
testset1.rehash(bucket_traits(buckets3, BucketSize*2));
|
testset1.rehash(bucket_traits(
|
||||||
|
pointer_traits<typename unordered_multiset_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets3[0]), BucketSize*2));
|
||||||
BOOST_TEST (testset1.size() == values.size());
|
BOOST_TEST (testset1.size() == values.size());
|
||||||
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
@@ -620,7 +670,9 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>:
|
|||||||
typedef typename unordered_multiset_type::bucket_traits bucket_traits;
|
typedef typename unordered_multiset_type::bucket_traits bucket_traits;
|
||||||
|
|
||||||
typename unordered_multiset_type::bucket_type buckets[BucketSize];
|
typename unordered_multiset_type::bucket_type buckets[BucketSize];
|
||||||
unordered_multiset_type testset(values.begin(), values.end(), bucket_traits(buckets, BucketSize));
|
unordered_multiset_type testset(values.begin(), values.end(), bucket_traits(
|
||||||
|
pointer_traits<typename unordered_multiset_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets[0]), BucketSize));
|
||||||
|
|
||||||
typedef typename unordered_multiset_type::iterator iterator;
|
typedef typename unordered_multiset_type::iterator iterator;
|
||||||
|
|
||||||
@@ -658,8 +710,12 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>
|
|||||||
//Test with equal bucket arrays
|
//Test with equal bucket arrays
|
||||||
typename unordered_multiset_type::bucket_type buckets1 [BucketSize];
|
typename unordered_multiset_type::bucket_type buckets1 [BucketSize];
|
||||||
typename unordered_multiset_type::bucket_type buckets2 [BucketSize];
|
typename unordered_multiset_type::bucket_type buckets2 [BucketSize];
|
||||||
unordered_multiset_type testset1 (values.begin(), values.end(), bucket_traits(buckets1, BucketSize));
|
unordered_multiset_type testset1 (values.begin(), values.end(), bucket_traits(
|
||||||
unordered_multiset_type testset2 (bucket_traits(buckets2, BucketSize));
|
pointer_traits<typename unordered_multiset_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets1[0]), BucketSize));
|
||||||
|
unordered_multiset_type testset2 (bucket_traits(
|
||||||
|
pointer_traits<typename unordered_multiset_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets2[0]), BucketSize));
|
||||||
|
|
||||||
testset2.clone_from(testset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>());
|
testset2.clone_from(testset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>());
|
||||||
//Ordering is not guarantee in the cloning so insert data in a set and test
|
//Ordering is not guarantee in the cloning so insert data in a set and test
|
||||||
@@ -675,8 +731,12 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>
|
|||||||
//Test with bigger source bucket arrays
|
//Test with bigger source bucket arrays
|
||||||
typename unordered_multiset_type::bucket_type buckets1 [BucketSize*2];
|
typename unordered_multiset_type::bucket_type buckets1 [BucketSize*2];
|
||||||
typename unordered_multiset_type::bucket_type buckets2 [BucketSize];
|
typename unordered_multiset_type::bucket_type buckets2 [BucketSize];
|
||||||
unordered_multiset_type testset1 (values.begin(), values.end(), bucket_traits(buckets1, BucketSize*2));
|
unordered_multiset_type testset1 (values.begin(), values.end(), bucket_traits(
|
||||||
unordered_multiset_type testset2 (bucket_traits(buckets2, BucketSize));
|
pointer_traits<typename unordered_multiset_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets1[0]), BucketSize*2));
|
||||||
|
unordered_multiset_type testset2 (bucket_traits(
|
||||||
|
pointer_traits<typename unordered_multiset_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets2[0]), BucketSize));
|
||||||
|
|
||||||
testset2.clone_from(testset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>());
|
testset2.clone_from(testset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>());
|
||||||
//Ordering is not guarantee in the cloning so insert data in a set and test
|
//Ordering is not guarantee in the cloning so insert data in a set and test
|
||||||
@@ -692,8 +752,12 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>
|
|||||||
//Test with smaller source bucket arrays
|
//Test with smaller source bucket arrays
|
||||||
typename unordered_multiset_type::bucket_type buckets1 [BucketSize];
|
typename unordered_multiset_type::bucket_type buckets1 [BucketSize];
|
||||||
typename unordered_multiset_type::bucket_type buckets2 [BucketSize*2];
|
typename unordered_multiset_type::bucket_type buckets2 [BucketSize*2];
|
||||||
unordered_multiset_type testset1 (values.begin(), values.end(), bucket_traits(buckets1, BucketSize));
|
unordered_multiset_type testset1 (values.begin(), values.end(), bucket_traits(
|
||||||
unordered_multiset_type testset2 (bucket_traits(buckets2, BucketSize*2));
|
pointer_traits<typename unordered_multiset_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets1[0]), BucketSize));
|
||||||
|
unordered_multiset_type testset2 (bucket_traits(
|
||||||
|
pointer_traits<typename unordered_multiset_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets2[0]), BucketSize*2));
|
||||||
|
|
||||||
testset2.clone_from(testset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>());
|
testset2.clone_from(testset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>());
|
||||||
//Ordering is not guaranteed in the cloning so insert data in a set and test
|
//Ordering is not guaranteed in the cloning so insert data in a set and test
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
#include <boost/intrusive/detail/config_begin.hpp>
|
#include <boost/intrusive/detail/config_begin.hpp>
|
||||||
#include <boost/intrusive/unordered_set.hpp>
|
#include <boost/intrusive/unordered_set.hpp>
|
||||||
#include <boost/intrusive/detail/pointer_to_other.hpp>
|
#include <boost/intrusive/pointer_traits.hpp>
|
||||||
#include "itestvalue.hpp"
|
#include "itestvalue.hpp"
|
||||||
#include "smart_ptr.hpp"
|
#include "smart_ptr.hpp"
|
||||||
#include "common_functors.hpp"
|
#include "common_functors.hpp"
|
||||||
@@ -101,7 +101,9 @@ void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::
|
|||||||
typedef typename unordered_set_type::bucket_traits bucket_traits;
|
typedef typename unordered_set_type::bucket_traits bucket_traits;
|
||||||
{
|
{
|
||||||
typename unordered_set_type::bucket_type buckets [BucketSize];
|
typename unordered_set_type::bucket_type buckets [BucketSize];
|
||||||
unordered_set_type testset(bucket_traits(buckets, BucketSize));
|
unordered_set_type testset(bucket_traits(
|
||||||
|
pointer_traits<typename unordered_set_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets[0]), BucketSize));
|
||||||
testset.insert(values.begin(), values.end());
|
testset.insert(values.begin(), values.end());
|
||||||
test::test_container(testset);
|
test::test_container(testset);
|
||||||
testset.clear();
|
testset.clear();
|
||||||
@@ -143,7 +145,9 @@ void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::test
|
|||||||
values[i].value_ = i;
|
values[i].value_ = i;
|
||||||
|
|
||||||
typename unordered_set_type::bucket_type buckets [BucketSize];
|
typename unordered_set_type::bucket_type buckets [BucketSize];
|
||||||
unordered_set_type testset(bucket_traits(buckets, BucketSize));
|
unordered_set_type testset(bucket_traits(
|
||||||
|
pointer_traits<typename unordered_set_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets[0]), BucketSize));
|
||||||
for (int i = 0; i < 5; ++i)
|
for (int i = 0; i < 5; ++i)
|
||||||
testset.insert (values[i]);
|
testset.insert (values[i]);
|
||||||
|
|
||||||
@@ -171,7 +175,9 @@ void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::
|
|||||||
typedef typename unordered_set_type::bucket_traits bucket_traits;
|
typedef typename unordered_set_type::bucket_traits bucket_traits;
|
||||||
|
|
||||||
typename unordered_set_type::bucket_type buckets [BucketSize];
|
typename unordered_set_type::bucket_type buckets [BucketSize];
|
||||||
unordered_set_type testset1(values.begin(), values.end(), bucket_traits(buckets, BucketSize));
|
unordered_set_type testset1(values.begin(), values.end(), bucket_traits(
|
||||||
|
pointer_traits<typename unordered_set_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets[0]), BucketSize));
|
||||||
BOOST_TEST (5 == std::distance(testset1.begin(), testset1.end()));
|
BOOST_TEST (5 == std::distance(testset1.begin(), testset1.end()));
|
||||||
|
|
||||||
if(Incremental){
|
if(Incremental){
|
||||||
@@ -204,7 +210,9 @@ void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::
|
|||||||
typedef typename unordered_set_type::bucket_traits bucket_traits;
|
typedef typename unordered_set_type::bucket_traits bucket_traits;
|
||||||
|
|
||||||
typename unordered_set_type::bucket_type buckets [BucketSize];
|
typename unordered_set_type::bucket_type buckets [BucketSize];
|
||||||
unordered_set_type testset(bucket_traits(buckets, BucketSize));
|
unordered_set_type testset(bucket_traits(
|
||||||
|
pointer_traits<typename unordered_set_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets[0]), BucketSize));
|
||||||
testset.insert(&values[0] + 2, &values[0] + 5);
|
testset.insert(&values[0] + 2, &values[0] + 5);
|
||||||
|
|
||||||
const unordered_set_type& const_testset = testset;
|
const unordered_set_type& const_testset = testset;
|
||||||
@@ -263,8 +271,12 @@ void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::
|
|||||||
|
|
||||||
typename unordered_set_type::bucket_type buckets1 [BucketSize];
|
typename unordered_set_type::bucket_type buckets1 [BucketSize];
|
||||||
typename unordered_set_type::bucket_type buckets2 [BucketSize];
|
typename unordered_set_type::bucket_type buckets2 [BucketSize];
|
||||||
unordered_set_type testset1(&values[0], &values[0] + 2, bucket_traits(buckets1, BucketSize));
|
unordered_set_type testset1(&values[0], &values[0] + 2, bucket_traits(
|
||||||
unordered_set_type testset2(bucket_traits(buckets2, BucketSize));
|
pointer_traits<typename unordered_set_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets1[0]), BucketSize));
|
||||||
|
unordered_set_type testset2(bucket_traits(
|
||||||
|
pointer_traits<typename unordered_set_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets2[0]), BucketSize));
|
||||||
|
|
||||||
testset2.insert (&values[0] + 2, &values[0] + 6);
|
testset2.insert (&values[0] + 2, &values[0] + 6);
|
||||||
testset1.swap (testset2);
|
testset1.swap (testset2);
|
||||||
@@ -307,7 +319,9 @@ void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::
|
|||||||
//Build a uset
|
//Build a uset
|
||||||
typename unordered_set_type::bucket_type buckets1 [BucketSize];
|
typename unordered_set_type::bucket_type buckets1 [BucketSize];
|
||||||
typename unordered_set_type::bucket_type buckets2 [BucketSize*2];
|
typename unordered_set_type::bucket_type buckets2 [BucketSize*2];
|
||||||
unordered_set_type testset1(&values[0], &values[0] + 6, bucket_traits(buckets1, BucketSize));
|
unordered_set_type testset1(&values[0], &values[0] + 6, bucket_traits(
|
||||||
|
pointer_traits<typename unordered_set_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets1[0]), BucketSize));
|
||||||
//Test current state
|
//Test current state
|
||||||
BOOST_TEST(testset1.split_count() == BucketSize/2);
|
BOOST_TEST(testset1.split_count() == BucketSize/2);
|
||||||
{ int init_values [] = { 4, 5, 1, 2, 3 };
|
{ int init_values [] = { 4, 5, 1, 2, 3 };
|
||||||
@@ -334,21 +348,27 @@ void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::
|
|||||||
//Try incremental hashing specifying a new bucket traits pointing to the same array
|
//Try incremental hashing specifying a new bucket traits pointing to the same array
|
||||||
//
|
//
|
||||||
//This incremental rehash should fail because the new size is not twice the original
|
//This incremental rehash should fail because the new size is not twice the original
|
||||||
BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets1, BucketSize)) == false);
|
BOOST_TEST(testset1.incremental_rehash(bucket_traits(
|
||||||
|
pointer_traits<typename unordered_set_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets1[0]), BucketSize)) == false);
|
||||||
BOOST_TEST(testset1.split_count() == BucketSize);
|
BOOST_TEST(testset1.split_count() == BucketSize);
|
||||||
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
//This incremental rehash should success because the new size is twice the original
|
//This incremental rehash should success because the new size is twice the original
|
||||||
//and split_count is the same as the old bucket count
|
//and split_count is the same as the old bucket count
|
||||||
BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets1, BucketSize*2)) == true);
|
BOOST_TEST(testset1.incremental_rehash(bucket_traits(
|
||||||
|
pointer_traits<typename unordered_set_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets1[0]), BucketSize*2)) == true);
|
||||||
BOOST_TEST(testset1.split_count() == BucketSize);
|
BOOST_TEST(testset1.split_count() == BucketSize);
|
||||||
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
//This incremental rehash should also success because the new size is half the original
|
//This incremental rehash should also success because the new size is half the original
|
||||||
//and split_count is the same as the new bucket count
|
//and split_count is the same as the new bucket count
|
||||||
BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets1, BucketSize)) == true);
|
BOOST_TEST(testset1.incremental_rehash(bucket_traits(
|
||||||
|
pointer_traits<typename unordered_set_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets1[0]), BucketSize)) == true);
|
||||||
BOOST_TEST(testset1.split_count() == BucketSize);
|
BOOST_TEST(testset1.split_count() == BucketSize);
|
||||||
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
@@ -357,39 +377,51 @@ void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::
|
|||||||
//Try incremental hashing specifying a new bucket traits pointing to the same array
|
//Try incremental hashing specifying a new bucket traits pointing to the same array
|
||||||
//
|
//
|
||||||
//This incremental rehash should fail because the new size is not twice the original
|
//This incremental rehash should fail because the new size is not twice the original
|
||||||
BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets2, BucketSize)) == false);
|
BOOST_TEST(testset1.incremental_rehash(bucket_traits(
|
||||||
|
pointer_traits<typename unordered_set_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets2[0]), BucketSize)) == false);
|
||||||
BOOST_TEST(testset1.split_count() == BucketSize);
|
BOOST_TEST(testset1.split_count() == BucketSize);
|
||||||
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
//This incremental rehash should success because the new size is twice the original
|
//This incremental rehash should success because the new size is twice the original
|
||||||
//and split_count is the same as the old bucket count
|
//and split_count is the same as the old bucket count
|
||||||
BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets2, BucketSize*2)) == true);
|
BOOST_TEST(testset1.incremental_rehash(bucket_traits(
|
||||||
|
pointer_traits<typename unordered_set_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets2[0]), BucketSize*2)) == true);
|
||||||
BOOST_TEST(testset1.split_count() == BucketSize);
|
BOOST_TEST(testset1.split_count() == BucketSize);
|
||||||
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
//This incremental rehash should also success because the new size is half the original
|
//This incremental rehash should also success because the new size is half the original
|
||||||
//and split_count is the same as the new bucket count
|
//and split_count is the same as the new bucket count
|
||||||
BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets1, BucketSize)) == true);
|
BOOST_TEST(testset1.incremental_rehash(bucket_traits(
|
||||||
|
pointer_traits<typename unordered_set_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets1[0]), BucketSize)) == true);
|
||||||
BOOST_TEST(testset1.split_count() == BucketSize);
|
BOOST_TEST(testset1.split_count() == BucketSize);
|
||||||
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
//Full shrink rehash
|
//Full shrink rehash
|
||||||
testset1.rehash(bucket_traits(buckets1, 4));
|
testset1.rehash(bucket_traits(
|
||||||
|
pointer_traits<typename unordered_set_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets1[0]), 4));
|
||||||
BOOST_TEST (testset1.size() == values.size()-1);
|
BOOST_TEST (testset1.size() == values.size()-1);
|
||||||
BOOST_TEST (testset1.incremental_rehash() == false);
|
BOOST_TEST (testset1.incremental_rehash() == false);
|
||||||
{ int init_values [] = { 4, 5, 1, 2, 3 };
|
{ int init_values [] = { 4, 5, 1, 2, 3 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
//Full shrink rehash again
|
//Full shrink rehash again
|
||||||
testset1.rehash(bucket_traits(buckets1, 2));
|
testset1.rehash(bucket_traits(
|
||||||
|
pointer_traits<typename unordered_set_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets1[0]), 2));
|
||||||
BOOST_TEST (testset1.size() == values.size()-1);
|
BOOST_TEST (testset1.size() == values.size()-1);
|
||||||
BOOST_TEST (testset1.incremental_rehash() == false);
|
BOOST_TEST (testset1.incremental_rehash() == false);
|
||||||
{ int init_values [] = { 2, 4, 3, 5, 1 };
|
{ int init_values [] = { 2, 4, 3, 5, 1 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
//Full growing rehash
|
//Full growing rehash
|
||||||
testset1.rehash(bucket_traits(buckets1, BucketSize));
|
testset1.rehash(bucket_traits(
|
||||||
|
pointer_traits<typename unordered_set_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets1[0]), BucketSize));
|
||||||
BOOST_TEST (testset1.size() == values.size()-1);
|
BOOST_TEST (testset1.size() == values.size()-1);
|
||||||
BOOST_TEST (testset1.incremental_rehash() == false);
|
BOOST_TEST (testset1.incremental_rehash() == false);
|
||||||
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
||||||
@@ -439,29 +471,39 @@ void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::
|
|||||||
typename unordered_set_type::bucket_type buckets2 [2];
|
typename unordered_set_type::bucket_type buckets2 [2];
|
||||||
typename unordered_set_type::bucket_type buckets3 [BucketSize*2];
|
typename unordered_set_type::bucket_type buckets3 [BucketSize*2];
|
||||||
|
|
||||||
unordered_set_type testset1(&values[0], &values[0] + 6, bucket_traits(buckets1, BucketSize));
|
unordered_set_type testset1(&values[0], &values[0] + 6, bucket_traits(
|
||||||
|
pointer_traits<typename unordered_set_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets1[0]), BucketSize));
|
||||||
BOOST_TEST (testset1.size() == values.size()-1);
|
BOOST_TEST (testset1.size() == values.size()-1);
|
||||||
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
testset1.rehash(bucket_traits(buckets2, 2));
|
testset1.rehash(bucket_traits(
|
||||||
|
pointer_traits<typename unordered_set_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets2[0]), 2));
|
||||||
BOOST_TEST (testset1.size() == values.size()-1);
|
BOOST_TEST (testset1.size() == values.size()-1);
|
||||||
{ int init_values [] = { 4, 2, 5, 3, 1 };
|
{ int init_values [] = { 4, 2, 5, 3, 1 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
testset1.rehash(bucket_traits(buckets3, BucketSize*2));
|
testset1.rehash(bucket_traits(
|
||||||
|
pointer_traits<typename unordered_set_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets3[0]), BucketSize*2));
|
||||||
BOOST_TEST (testset1.size() == values.size()-1);
|
BOOST_TEST (testset1.size() == values.size()-1);
|
||||||
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
//Now rehash reducing the buckets
|
//Now rehash reducing the buckets
|
||||||
testset1.rehash(bucket_traits(buckets3, 2));
|
testset1.rehash(bucket_traits(
|
||||||
|
pointer_traits<typename unordered_set_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets3[0]), 2));
|
||||||
BOOST_TEST (testset1.size() == values.size()-1);
|
BOOST_TEST (testset1.size() == values.size()-1);
|
||||||
{ int init_values [] = { 4, 2, 5, 3, 1 };
|
{ int init_values [] = { 4, 2, 5, 3, 1 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
//Now rehash increasing the buckets
|
//Now rehash increasing the buckets
|
||||||
testset1.rehash(bucket_traits(buckets3, BucketSize*2));
|
testset1.rehash(bucket_traits(
|
||||||
|
pointer_traits<typename unordered_set_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets3[0]), BucketSize*2));
|
||||||
BOOST_TEST (testset1.size() == values.size()-1);
|
BOOST_TEST (testset1.size() == values.size()-1);
|
||||||
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
@@ -485,7 +527,9 @@ void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::
|
|||||||
typedef typename unordered_set_type::bucket_traits bucket_traits;
|
typedef typename unordered_set_type::bucket_traits bucket_traits;
|
||||||
|
|
||||||
typename unordered_set_type::bucket_type buckets [BucketSize];
|
typename unordered_set_type::bucket_type buckets [BucketSize];
|
||||||
unordered_set_type testset (values.begin(), values.end(), bucket_traits(buckets, BucketSize));
|
unordered_set_type testset (values.begin(), values.end(), bucket_traits(
|
||||||
|
pointer_traits<typename unordered_set_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets[0]), BucketSize));
|
||||||
typedef typename unordered_set_type::iterator iterator;
|
typedef typename unordered_set_type::iterator iterator;
|
||||||
|
|
||||||
value_type cmp_val;
|
value_type cmp_val;
|
||||||
@@ -521,8 +565,12 @@ void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>
|
|||||||
//Test with equal bucket arrays
|
//Test with equal bucket arrays
|
||||||
typename unordered_set_type::bucket_type buckets1 [BucketSize];
|
typename unordered_set_type::bucket_type buckets1 [BucketSize];
|
||||||
typename unordered_set_type::bucket_type buckets2 [BucketSize];
|
typename unordered_set_type::bucket_type buckets2 [BucketSize];
|
||||||
unordered_set_type testset1 (values.begin(), values.end(), bucket_traits(buckets1, BucketSize));
|
unordered_set_type testset1 (values.begin(), values.end(), bucket_traits(
|
||||||
unordered_set_type testset2 (bucket_traits(buckets2, BucketSize));
|
pointer_traits<typename unordered_set_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets1[0]), BucketSize));
|
||||||
|
unordered_set_type testset2 (bucket_traits(
|
||||||
|
pointer_traits<typename unordered_set_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets2[0]), BucketSize));
|
||||||
|
|
||||||
testset2.clone_from(testset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>());
|
testset2.clone_from(testset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>());
|
||||||
//Ordering is not guarantee in the cloning so insert data in a set and test
|
//Ordering is not guarantee in the cloning so insert data in a set and test
|
||||||
@@ -538,8 +586,12 @@ void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>
|
|||||||
//Test with bigger source bucket arrays
|
//Test with bigger source bucket arrays
|
||||||
typename unordered_set_type::bucket_type buckets1 [BucketSize*2];
|
typename unordered_set_type::bucket_type buckets1 [BucketSize*2];
|
||||||
typename unordered_set_type::bucket_type buckets2 [BucketSize];
|
typename unordered_set_type::bucket_type buckets2 [BucketSize];
|
||||||
unordered_set_type testset1 (values.begin(), values.end(), bucket_traits(buckets1, BucketSize*2));
|
unordered_set_type testset1 (values.begin(), values.end(), bucket_traits(
|
||||||
unordered_set_type testset2 (bucket_traits(buckets2, BucketSize));
|
pointer_traits<typename unordered_set_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets1[0]), BucketSize*2));
|
||||||
|
unordered_set_type testset2 (bucket_traits(
|
||||||
|
pointer_traits<typename unordered_set_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets2[0]), BucketSize));
|
||||||
|
|
||||||
testset2.clone_from(testset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>());
|
testset2.clone_from(testset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>());
|
||||||
//Ordering is not guaranteed in the cloning so insert data in a set and test
|
//Ordering is not guaranteed in the cloning so insert data in a set and test
|
||||||
@@ -555,8 +607,12 @@ void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>
|
|||||||
//Test with smaller source bucket arrays
|
//Test with smaller source bucket arrays
|
||||||
typename unordered_set_type::bucket_type buckets1 [BucketSize];
|
typename unordered_set_type::bucket_type buckets1 [BucketSize];
|
||||||
typename unordered_set_type::bucket_type buckets2 [BucketSize*2];
|
typename unordered_set_type::bucket_type buckets2 [BucketSize*2];
|
||||||
unordered_set_type testset1 (values.begin(), values.end(), bucket_traits(buckets1, BucketSize));
|
unordered_set_type testset1 (values.begin(), values.end(), bucket_traits(
|
||||||
unordered_set_type testset2 (bucket_traits(buckets2, BucketSize*2));
|
pointer_traits<typename unordered_set_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets1[0]), BucketSize));
|
||||||
|
unordered_set_type testset2 (bucket_traits(
|
||||||
|
pointer_traits<typename unordered_set_type::bucket_ptr>::
|
||||||
|
pointer_to(buckets2[0]), BucketSize*2));
|
||||||
|
|
||||||
testset2.clone_from(testset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>());
|
testset2.clone_from(testset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>());
|
||||||
//Ordering is not guarantee in the cloning so insert data in a set and test
|
//Ordering is not guarantee in the cloning so insert data in a set and test
|
||||||
|
@@ -78,7 +78,8 @@ int main()
|
|||||||
|
|
||||||
//Test the objects inserted in the base hook list
|
//Test the objects inserted in the base hook list
|
||||||
for(; vect_it != vect_itend; ++vect_it, ++list_it)
|
for(; vect_it != vect_itend; ++vect_it, ++list_it)
|
||||||
if(&*list_it != &*vect_it) return 1;
|
if(&*list_it != &*vect_it)
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Reference in New Issue
Block a user