From 15de4da45112431575c8e27d13befed220aaa903 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Sun, 18 Nov 2007 10:44:56 +0000 Subject: [PATCH] Added scapegoat trees and an option to store the hash value in the hook for unordered containers [SVN r41196] --- doc/Jamfile.v2 | 3 + doc/intrusive.qbk | 210 +++++++- example/doc_avl_set.cpp | 8 +- example/doc_set.cpp | 8 +- example/doc_sg_set.cpp | 85 ++++ example/doc_splay_set.cpp | 37 +- proj/vc7ide/Intrusive.sln | 16 + .../vc7ide/_intrusivelib/_intrusivelib.vcproj | 24 + proj/vc7ide/avl_multiset/avl_multiset.vcproj | 3 +- proj/vc7ide/avl_set/avl_set.vcproj | 3 +- .../custom_bucket_traits.vcproj | 3 +- proj/vc7ide/default_hook/default_hook.vcproj | 3 +- .../external_value_traits.vcproj | 3 +- proj/vc7ide/list/list.vcproj | 3 +- .../make_functions/make_functions.vcproj | 3 +- proj/vc7ide/multiset/multiset.vcproj | 3 +- proj/vc7ide/perf_test/perf_test.vcproj | 3 +- proj/vc7ide/set/set.vcproj | 3 +- proj/vc7ide/sg_multiset/sg_multiset.vcproj | 128 +++++ proj/vc7ide/sg_set/sg_set.vcproj | 127 +++++ proj/vc7ide/slist/slist.vcproj | 3 +- .../splay_multiset/splay_multiset.vcproj | 3 +- proj/vc7ide/splay_set/splay_set.vcproj | 3 +- .../stateful_value_traits.vcproj | 3 +- proj/vc7ide/to-do.txt | 10 +- .../unordered_multiset.vcproj | 3 +- .../vc7ide/unordered_set/unordered_set.vcproj | 3 +- proj/vc7ide/virtual_base/virtual_base.vcproj | 3 +- test/avl_multiset_test.cpp | 408 +++------------ test/avl_set_test.cpp | 309 ++--------- test/external_value_traits_test.cpp | 7 +- test/generic_assoc_test.hpp | 328 ++++++++++++ test/generic_multiset_test.hpp | 227 +++++++++ test/generic_set_test.hpp | 225 ++++++++ test/itestvalue.hpp | 35 +- test/make_functions_test.cpp | 3 +- test/multiset_test.cpp | 326 ++---------- test/set_test.cpp | 292 ++--------- test/sg_multiset_test.cpp | 108 ++++ test/sg_set_test.cpp | 109 ++++ test/splay_multiset_test.cpp | 479 +++--------------- test/splay_set_test.cpp | 375 ++------------ test/stateful_value_traits_test.cpp | 3 +- test/test_container.hpp | 4 +- 44 files changed, 1987 insertions(+), 1958 deletions(-) create mode 100644 example/doc_sg_set.cpp create mode 100644 proj/vc7ide/sg_multiset/sg_multiset.vcproj create mode 100644 proj/vc7ide/sg_set/sg_set.vcproj create mode 100644 test/generic_assoc_test.hpp create mode 100644 test/generic_multiset_test.hpp create mode 100644 test/generic_set_test.hpp create mode 100644 test/sg_multiset_test.cpp create mode 100644 test/sg_set_test.cpp diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 index 2bb05df..823d326 100644 --- a/doc/Jamfile.v2 +++ b/doc/Jamfile.v2 @@ -33,6 +33,9 @@ doxygen autodoc "splay_set_impl=splay_set" \\ "splay_multiset_impl=splay_multiset" \\ "splaytree_impl=splaytree" \\ + "sg_set_impl=sg_set" \\ + "sg_multiset_impl=sg_multiset" \\ + "sgtree_impl=sgtree" \\ "avl_set_impl=avl_set" \\ "avl_multiset_impl=avl_multiset" \\ "avltree_impl=avltree"" diff --git a/doc/intrusive.qbk b/doc/intrusive.qbk index 59a10fc..6d9d140 100644 --- a/doc/intrusive.qbk +++ b/doc/intrusive.qbk @@ -1140,6 +1140,17 @@ the same options explained in the section internally in the hook and propagated to the container. Default: `void_pointer`. +Apart from them, these hooks offer additional options: + +* [*`store_hash`]: This option reserves additional space in + the hook to store the hash value of the object once it's introduced in the + container. When this option is used, the unordered container will store + the calculated hash value in the hook and rehashing operations won't need + to recalculate the hash of the value. + This option will improve the perfomance of unordered containers when + rehashing is frequent or hashing the value is a slow operation. + Default: `store_hash`. + [endsect] [section:unordered_set_unordered_multiset_containers unordered_set and unordered_multiset containers] @@ -1269,7 +1280,7 @@ structures that offer some advantages (and also disadvantages). Splay trees are self-adjusting binary search trees used tipically in caches, memory allocators and other applications, because splay trees have a "caching effect": recently accessed elements have better access times that elements accessed less frequently. -For more information on splay trees see [@http://en.wikipedia.org/wiki/Splay_tree Wikipedia]. +For more information on splay trees see [@http://en.wikipedia.org/wiki/Splay_tree Wikipedia entry]. [*Boost.Intrusive] offers 3 containers based on splay trees: [classref boost::intrusive::splay_set splay_set], @@ -1382,9 +1393,30 @@ And they also can receive an additional option: [endsect] +[section:splay_set_bst_hook Splay trees with BST hooks] + +Intrusive splay containers can also use plain binary search tree hooks +[classref boost::intrusive::bs_set_base_hook bs_set_base_hook] and +[classref boost::intrusive::bs_set_base_hook bs_set_base_hook]. +These hooks can be used by other intrusive containers like +intrusive scapegoat containers +[classref boost::intrusive::sg_set sg_set] and +[classref boost::intrusive::sg_multiset sg_multiset] so a programmer +might prefer using a binary search tree hook so that the same type +can be introduced in some situations in an splay container but that +can also be introduced in other compatible containers as well when +the hook is not being used in an splay container. + +[classref boost::intrusive::bs_set_base_hook bs_set_base_hook] and +[classref boost::intrusive::bs_set_base_hook bs_set_member_hook] admit +the same options as [classref boost::intrusive::splay_set_base_hook splay_set_base_hook]. + +[endsect] + [section:splay_set_multiset_example Example] -Now let's see an small example using both hooks and +Now let's see an small example using both splay hooks, +binary search tree hooks and [classref boost::intrusive::splay_set splay_set]/ [classref boost::intrusive::splay_multiset splay_multiset] containers: @@ -1396,7 +1428,6 @@ containers: [endsect] - [section:avl_set_multiset Intrusive avl tree based associative containers: avl_set, avl_multiset and avltree] Similar to red-black trees, AVL trees are balanced binary trees. @@ -1525,6 +1556,179 @@ containers: [endsect] +[section:sg_set_multiset Intrusive scapegoat tree based associative containers: sg_set, sg_multiset and sgtree] + +A scapegoat tree is a self-balancing binary search tree, that provides worst-case O(log n) +lookup time, and O(log n) amortized insertion and deletion time. +Unlike other self-balancing binary search trees that provide worst case O(log n) lookup +time, scapegoat trees have no additional per-node overhead compared to a regular binary +search tree. + +A binary search tree is said to be weight balanced if half the nodes are on the left +of the root, and half on the right. An α-height-balanced tree is defined with defined +with the following equation: + +[*['height(tree) <= log1/α(tree.size())]] + +* [*['α == 1]]: A tree forming a linked list is considered balanced. +* [*['α == 0.5]]: Only a perfectly balanced binary is considered balanced. + +Scapegoat trees are loosely ['α-height-balanced] so: + +[*['height(tree) <= log1/α(tree.size()) + 1]] + +Scapegoat trees support any α between 0.5 and 1. If α is higher, the tree is rebalanced +less often, obtaining quicker insertions but slower searches. Lower +α values improve search times. Scapegoat-trees implemented in [*Boost.Intrusive] offer the possibility of +[*changing α at run-time] taking advantage of the flexibility of scapegoat trees. +For more information on scapegoat trees see [@http://en.wikipedia.org/wiki/Scapegoat_tree Wikipedia entry]. + +Scapegoat trees also have downsides: + +* They need additional storage of data on the + root (the size of the tree, for example) to achieve logarithmic complexity operations + so it's not possible to offer `auto_unlink` hooks. The size of an empty scapegoat + tree is also considerably increased. + +* The operations needed to determine if the tree is unbalanced require floating-point + operations like ['log1/α]. If the system has no floating point operations (like some + embedded systems), scapegoat tree operations might become slow. + +[*Boost.Intrusive] offers 3 containers based on scapegoat trees: +[classref boost::intrusive::sg_set sg_set], +[classref boost::intrusive::sg_multiset sg_multiset] and +[classref boost::intrusive::sgtree sgtree]. The first two are similar to +[classref boost::intrusive::set set] or +[classref boost::intrusive::multiset multiset] and the latter is a generalization +that offers functions both to insert unique and multiple keys. + +The memory overhead of these containers with Boost.Intrusive hooks is 3 +pointers. + +An empty, [classref boost::intrusive::sg_set sg_set], +[classref boost::intrusive::sg_multiset sg_multiset] or +[classref boost::intrusive::sgtree sgtree] +has also the size of 3 pointers, two integers and two floating point values +(equivalent to the size of 7 pointers on most systems). + +[section:sg_set_multiset_hooks Using binary search tree hooks: bs_set_base_hook and bs_set_member_hook] + +[classref boost::intrusive::sg_set sg_set], +[classref boost::intrusive::sg_multiset sg_multiset] and +[classref boost::intrusive::sgtree sgtree] don't use their +own hooks but plain binary search tree hooks. This has many advantages +since binary search tree hooks can also be used to insert values in +splay containers. + +[c++] + + template + class bs_set_base_hook; + +* [classref boost::intrusive::bs_set_base_hook bs_set_base_hook]: + the user class derives publicly from this class to make + it compatible with scapegoat tree based containers. + +[c++] + + template + class bs_set_member_hook; + +* [classref boost::intrusive::set_member_hook set_member_hook]: + the user class contains a public member of this class to make + it compatible with scapegoat tree based containers. + +[classref boost::intrusive::bs_set_base_hook bs_set_base_hook] and +[classref boost::intrusive::bs_set_member_hook bs_set_member_hook] receive +the same options explained in the section +[link intrusive.usage How to use Boost.Intrusive] plus an option to optimize +the size of the node: + +* [*`tag`] (for base hooks only): This argument serves as a tag, + so you can derive from more than one base hook. + Default: `tag`. + +* [*`link_mode`]: The linking policy. + Default: `link_mode`. + +* [*`void_pointer`]: The pointer type to be used + internally in the hook and propagated to the container. + Default: `void_pointer`. + +[endsect] + +[section:sg_set_multiset_containers sg_set, sg_multiset and sgtree containers] + +[c++] + + template + class sg_set; + + template + class sg_multiset; + + template + class sgtree; + +These containers receive the same options explained in the section +[link intrusive.usage How to use Boost.Intrusive]: + +* [*`base_hook`] / [*`member_hook`] / + [*`value_traits`]: To specify the hook type or value traits used + to configure the container (to know about value traits go to the section + titled [link intrusive.value_traits Containers with custom ValueTraits]. + +* [*`size_type`]: To specify the type that will be used to store the size + of the container. Default: `size_type` + +And they also can receive additional options: + +* [*`compare`]: Comparison function for the objects to be inserted + in containers. The comparison functor must induce a strict weak ordering. + Default: `compare< std::less >` + +* [*`floating_point`]: + When this option is deactivated, the scapegoat tree loses the ability to change + the balance factor α at run-time, but the size of an empty container is reduced + and no floating point operations are performed, normally increasing container + performance. The fixed α factor that is used when this option is activated + is ['1/sqrt(2) ~ 0,70711]. Default: `floating_point` + +[endsect] + +[section:sg_set_multiset_example Example] + +Now let's see an small example using both hooks and +[classref boost::intrusive::sg_set sg_set]/ +[classref boost::intrusive::sg_multiset sg_multiset] +containers: + +[import ../example/doc_sg_set.cpp] +[doc_sg_set_code] + +[endsect] + +[endsect] + + + + + + + + + + + + + + + + + + + + [section:advanced_lookups_insertions Advanced lookup and insertion functions for associative containers] [section:advanced_lookups Advanced lookups] diff --git a/example/doc_avl_set.cpp b/example/doc_avl_set.cpp index 9e69975..33a061c 100644 --- a/example/doc_avl_set.cpp +++ b/example/doc_avl_set.cpp @@ -61,13 +61,11 @@ int main() //Check that size optimization is deactivated in the member hook assert(sizeof(avl_set_member_hook<>) > 3*sizeof(void*)); - //Now insert them in the reverse order in the base hook avl_set - for(VectIt it(values.begin()), itend(values.end()); it != itend; ++it) + //Now insert them in the sets + for(VectIt it(values.begin()), itend(values.end()); it != itend; ++it){ baseset.insert(*it); - - //Now insert them in the same order as in vector in the member hook avl_set - for(VectIt it(values.begin()), itend(values.end()); it != itend; ++it) membermultiset.insert(*it); + } //Now test avl_sets { diff --git a/example/doc_set.cpp b/example/doc_set.cpp index 7a4bcd6..d9d5d47 100644 --- a/example/doc_set.cpp +++ b/example/doc_set.cpp @@ -37,7 +37,7 @@ class MyClass : public set_base_hook > { return a.int_ < b.int_; } }; -//Define an set using the base hook that will store values in reverse order +//Define a set using the base hook that will store values in reverse order typedef set< MyClass, compare > > BaseSet; //Define an multiset using the member hook @@ -62,12 +62,10 @@ int main() assert(sizeof(set_member_hook<>) > 3*sizeof(void*)); //Now insert them in the reverse order in the base hook set - for(VectIt it(values.begin()), itend(values.end()); it != itend; ++it) + for(VectIt it(values.begin()), itend(values.end()); it != itend; ++it){ baseset.insert(*it); - - //Now insert them in the same order as in vector in the member hook set - for(VectIt it(values.begin()), itend(values.end()); it != itend; ++it) membermultiset.insert(*it); + } //Now test sets { diff --git a/example/doc_sg_set.cpp b/example/doc_sg_set.cpp new file mode 100644 index 0000000..2c6eec5 --- /dev/null +++ b/example/doc_sg_set.cpp @@ -0,0 +1,85 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2007 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// +//[doc_sg_set_code +#include +#include +#include +#include + +using namespace boost::intrusive; + +class MyClass : public bs_set_base_hook<> +{ + int int_; + + public: + //This is a member hook + bs_set_member_hook<> member_hook_; + + MyClass(int i) + : int_(i) + {} + friend bool operator< (const MyClass &a, const MyClass &b) + { return a.int_ < b.int_; } + friend bool operator> (const MyClass &a, const MyClass &b) + { return a.int_ > b.int_; } + friend bool operator== (const MyClass &a, const MyClass &b) + { return a.int_ < b.int_; } +}; + +//Define an sg_set using the base hook that will store values in reverse order +//and won't execute floating point operations. +typedef sg_set + < MyClass, compare >, floating_point > BaseSet; + +//Define an multiset using the member hook +typedef member_hook, &MyClass::member_hook_> MemberOption; +typedef sg_multiset< MyClass, MemberOption> MemberMultiset; + +int main() +{ + typedef std::vector::iterator VectIt; + typedef std::vector::reverse_iterator VectRit; + + //Create several MyClass objects, each one with a different value + std::vector values; + for(int i = 0; i < 100; ++i) values.push_back(MyClass(i)); + + BaseSet baseset; + MemberMultiset membermultiset; + + //Now insert them in the reverse order in the base hook sg_set + for(VectIt it(values.begin()), itend(values.end()); it != itend; ++it){ + baseset.insert(*it); + membermultiset.insert(*it); + } + + //Change balance factor + membermultiset.balance_factor(0.9f); + + //Now test sg_sets + { + BaseSet::reverse_iterator rbit(baseset.rbegin()), rbitend(baseset.rend()); + MemberMultiset::iterator mit(membermultiset.begin()), mitend(membermultiset.end()); + VectIt it(values.begin()), itend(values.end()); + + //Test the objects inserted in the base hook sg_set + for(; it != itend; ++it, ++rbit) + if(&*rbit != &*it) return 1; + + //Test the objects inserted in the member hook sg_set + for(it = values.begin(); it != itend; ++it, ++mit) + if(&*mit != &*it) return 1; + } + return 0; +} +//] diff --git a/example/doc_splay_set.cpp b/example/doc_splay_set.cpp index 0d347f4..b82f48a 100644 --- a/example/doc_splay_set.cpp +++ b/example/doc_splay_set.cpp @@ -11,13 +11,16 @@ ///////////////////////////////////////////////////////////////////////////// //[doc_splay_set_code #include +#include #include #include using namespace boost::intrusive; - //This is a base hook -class MyClass : public splay_set_base_hook<> +class MyClass + : public splay_set_base_hook<> //This is an splay tree base hook + , public bs_set_base_hook<> //This is a binary search tree base hook + { int int_; @@ -36,9 +39,12 @@ class MyClass : public splay_set_base_hook<> { return a.int_ < b.int_; } }; -//Define an set using the base hook that will store values in reverse order +//Define a set using the base hook that will store values in reverse order typedef splay_set< MyClass, compare > > BaseSplaySet; +//Define a set using the binary search tree hook +typedef splay_set< MyClass, base_hook > > BaseBsSplaySet; + //Define an multiset using the member hook typedef member_hook, &MyClass::member_hook_> MemberOption; typedef splay_multiset< MyClass, MemberOption> MemberSplayMultiset; @@ -52,30 +58,35 @@ int main() std::vector values; for(int i = 0; i < 100; ++i) values.push_back(MyClass(i)); - BaseSplaySet baseset; + BaseSplaySet baseset; + BaseBsSplaySet bsbaseset; MemberSplayMultiset membermultiset; - //Now insert them in the reverse order in the base hook set - for(VectIt it(values.begin()), itend(values.end()); it != itend; ++it) - baseset.insert(*it); - //Now insert them in the same order as in vector in the member hook set - for(VectIt it(values.begin()), itend(values.end()); it != itend; ++it) + //Insert values in the container + for(VectIt it(values.begin()), itend(values.end()); it != itend; ++it){ + baseset.insert(*it); + bsbaseset.insert(*it); membermultiset.insert(*it); + } //Now test sets { BaseSplaySet::reverse_iterator rbit(baseset.rbegin()), rbitend(baseset.rend()); + BaseBsSplaySet::iterator bsit(bsbaseset.begin()), bsitend(bsbaseset.end()); MemberSplayMultiset::iterator mit(membermultiset.begin()), mitend(membermultiset.end()); VectIt it(values.begin()), itend(values.end()); //Test the objects inserted in the base hook set - for(; it != itend; ++it, ++rbit) + for(; it != itend; ++it, ++rbit){ if(&*rbit != &*it) return 1; + } - //Test the objects inserted in the member hook set - for(it = values.begin(); it != itend; ++it, ++mit) - if(&*mit != &*it) return 1; + //Test the objects inserted in member and binary search hook sets + for(it = values.begin(); it != itend; ++it, ++bsit, ++mit){ + if(&*bsit != &*it) return 1; + if(&*mit != &*it) return 1; + } } return 0; } diff --git a/proj/vc7ide/Intrusive.sln b/proj/vc7ide/Intrusive.sln index 709f4d7..8767b1e 100644 --- a/proj/vc7ide/Intrusive.sln +++ b/proj/vc7ide/Intrusive.sln @@ -71,6 +71,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "avl_set", "avl_set\avl_set. ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sg_multiset", "sg_multiset\sg_multiset.vcproj", "{07022E76-6CB5-92C1-B47F-A10772A79B43}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sg_set", "sg_set\sg_set.vcproj", "{1690A9E7-DB57-971C-F24A-09B752A942F7}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug @@ -151,6 +159,14 @@ Global {16909EE7-24AF-97C1-C76B-204B971BA959}.Debug.Build.0 = Debug|Win32 {16909EE7-24AF-97C1-C76B-204B971BA959}.Release.ActiveCfg = Release|Win32 {16909EE7-24AF-97C1-C76B-204B971BA959}.Release.Build.0 = Release|Win32 + {07022E76-6CB5-92C1-B47F-A10772A79B43}.Debug.ActiveCfg = Debug|Win32 + {07022E76-6CB5-92C1-B47F-A10772A79B43}.Debug.Build.0 = Debug|Win32 + {07022E76-6CB5-92C1-B47F-A10772A79B43}.Release.ActiveCfg = Release|Win32 + {07022E76-6CB5-92C1-B47F-A10772A79B43}.Release.Build.0 = Release|Win32 + {1690A9E7-DB57-971C-F24A-09B752A942F7}.Debug.ActiveCfg = Debug|Win32 + {1690A9E7-DB57-971C-F24A-09B752A942F7}.Debug.Build.0 = Debug|Win32 + {1690A9E7-DB57-971C-F24A-09B752A942F7}.Release.ActiveCfg = Release|Win32 + {1690A9E7-DB57-971C-F24A-09B752A942F7}.Release.Build.0 = Release|Win32 EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection diff --git a/proj/vc7ide/_intrusivelib/_intrusivelib.vcproj b/proj/vc7ide/_intrusivelib/_intrusivelib.vcproj index 2a06564..cb19c41 100644 --- a/proj/vc7ide/_intrusivelib/_intrusivelib.vcproj +++ b/proj/vc7ide/_intrusivelib/_intrusivelib.vcproj @@ -117,6 +117,9 @@ + + @@ -165,6 +168,15 @@ + + + + + + @@ -267,6 +279,15 @@ + + + + + + @@ -343,6 +364,9 @@ + + diff --git a/proj/vc7ide/avl_multiset/avl_multiset.vcproj b/proj/vc7ide/avl_multiset/avl_multiset.vcproj index 760ce0c..a2d2cb1 100644 --- a/proj/vc7ide/avl_multiset/avl_multiset.vcproj +++ b/proj/vc7ide/avl_multiset/avl_multiset.vcproj @@ -26,9 +26,10 @@ BasicRuntimeChecks="3" RuntimeLibrary="5" DisableLanguageExtensions="TRUE" + TreatWChar_tAsBuiltInType="TRUE" ForceConformanceInForLoopScope="TRUE" UsePrecompiledHeader="0" - WarningLevel="3" + WarningLevel="4" Detect64BitPortabilityProblems="TRUE" DebugInformationFormat="4"/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/proj/vc7ide/sg_set/sg_set.vcproj b/proj/vc7ide/sg_set/sg_set.vcproj new file mode 100644 index 0000000..222fffc --- /dev/null +++ b/proj/vc7ide/sg_set/sg_set.vcproj @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/proj/vc7ide/slist/slist.vcproj b/proj/vc7ide/slist/slist.vcproj index 25411b5..d9138b2 100644 --- a/proj/vc7ide/slist/slist.vcproj +++ b/proj/vc7ide/slist/slist.vcproj @@ -25,9 +25,10 @@ BasicRuntimeChecks="3" RuntimeLibrary="5" DisableLanguageExtensions="TRUE" + TreatWChar_tAsBuiltInType="TRUE" ForceConformanceInForLoopScope="TRUE" UsePrecompiledHeader="0" - WarningLevel="3" + WarningLevel="4" Detect64BitPortabilityProblems="TRUE" DebugInformationFormat="4"/> to work with the same node and type traits as store_hash diff --git a/proj/vc7ide/unordered_multiset/unordered_multiset.vcproj b/proj/vc7ide/unordered_multiset/unordered_multiset.vcproj index 7a5cd30..2b9c6f3 100644 --- a/proj/vc7ide/unordered_multiset/unordered_multiset.vcproj +++ b/proj/vc7ide/unordered_multiset/unordered_multiset.vcproj @@ -26,9 +26,10 @@ BasicRuntimeChecks="3" RuntimeLibrary="5" DisableLanguageExtensions="TRUE" + TreatWChar_tAsBuiltInType="TRUE" ForceConformanceInForLoopScope="TRUE" UsePrecompiledHeader="0" - WarningLevel="3" + WarningLevel="4" Detect64BitPortabilityProblems="TRUE" DebugInformationFormat="4"/> #include "itestvalue.hpp" #include "smart_ptr.hpp" -#include "common_functors.hpp" -#include -#include -#include "test_macros.hpp" -#include "test_container.hpp" -#include +#include "generic_multiset_test.hpp" -namespace boost { namespace intrusive { namespace test { - -template -struct has_const_overloads > +template< class ValueType + , class Option1 = boost::intrusive::none + , class Option2 = boost::intrusive::none + , class Option3 = boost::intrusive::none + > +struct GetContainer { - static const bool value = false; + typedef boost::intrusive::avl_multiset + < ValueType + , Option1 + , Option2 + , Option3 + > type; }; -}}} - -using namespace boost::intrusive; -template -struct test_avl_multiset -{ - typedef typename ValueTraits::value_type value_type; - static void test_all (std::vector& values); - static void test_sort(std::vector& values); - static void test_insert(std::vector& values); - static void test_swap(std::vector& values); - static void test_find(std::vector& values); - static void test_impl(); - static void test_clone(std::vector& values); - static void test_container_from_end(std::vector& values); -}; - -template -void test_avl_multiset::test_all - (std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef avl_multiset - < value_type - , value_traits - , constant_time_size - > avl_multiset_type; - { - avl_multiset_type testset(values.begin(), values.end()); - test::test_container(testset); - testset.clear(); - testset.insert(values.begin(), values.end()); - test::test_common_unordered_and_associative_container(testset, values); - testset.clear(); - testset.insert(values.begin(), values.end()); - test::test_associative_container(testset, values); - testset.clear(); - testset.insert(values.begin(), values.end()); - test::test_non_unique_container(testset, values); - } - test_sort(values); - test_insert(values); - test_swap(values); - test_find(values); - test_impl(); - test_clone(values); - test_container_from_end(values); -} - -//test case due to an error in tree implementation: -template -void test_avl_multiset::test_impl() -{ - typedef typename ValueTraits::value_type value_type; - std::vector values (5); - for (int i = 0; i < 5; ++i) - values[i].value_ = i; - typedef typename ValueTraits::value_type value_type; - typedef avl_multiset - < value_type - , value_traits - , constant_time_size - > multiset_type; - - multiset_type testset; - for (int i = 0; i < 5; ++i) - testset.insert (values[i]); - - testset.erase (testset.iterator_to (values[0])); - testset.erase (testset.iterator_to (values[1])); - testset.insert (values[1]); - - testset.erase (testset.iterator_to (values[2])); - testset.erase (testset.iterator_to (values[3])); -} - -//test: constructor, iterator, clear, reverse_iterator, front, back, size: -template -void test_avl_multiset::test_sort -(std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef avl_multiset - < value_type - , value_traits - , constant_time_size - > multiset_type; - - multiset_type testset1 (values.begin(), values.end()); - { int init_values [] = { 1, 2, 2, 3, 4, 5 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); } - - testset1.clear(); - BOOST_TEST (testset1.empty()); - - typedef avl_multiset - - , value_traits - , constant_time_size - > multiset_type2; - multiset_type2 testset2 (&values[0], &values[0] + 6); - { int init_values [] = { 5, 3, 1, 4, 2, 2 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset2.rbegin() ); } - - BOOST_TEST (testset2.begin()->value_ == 2); - BOOST_TEST (testset2.rbegin()->value_ == 5); -} - -//test: insert, const_iterator, const_reverse_iterator, erase, iterator_to: -template -void test_avl_multiset::test_insert -(std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef avl_multiset - < value_type - , value_traits - , size_type - , constant_time_size - > multiset_type; - - multiset_type testset; - testset.insert(&values[0] + 2, &values[0] + 5); - { int init_values [] = { 1, 4, 5 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset.begin() ); } - - typename multiset_type::iterator i = testset.begin(); - BOOST_TEST (i->value_ == 1); - - i = testset.insert (i, values[0]); - BOOST_TEST (&*i == &values[0]); - - { int init_values [] = { 5, 4, 3, 1 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset.rbegin() ); } - - i = testset.iterator_to (values[2]); - BOOST_TEST (&*i == &values[2]); - - i = multiset_type::s_iterator_to (values[2]); - BOOST_TEST (&*i == &values[2]); - - testset.erase(i); - - { int init_values [] = { 1, 3, 5 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset.begin() ); } -} - -//test: insert (seq-version), swap, erase (seq-version), size: -template -void test_avl_multiset::test_swap -(std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef avl_multiset - < value_type - , value_traits - , size_type - , constant_time_size - > multiset_type; - multiset_type testset1 (&values[0], &values[0] + 2); - multiset_type testset2; - testset2.insert (&values[0] + 2, &values[0] + 6); - - { int init_values [] = { 1, 2, 4, 5 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset2.begin() ); } - { int init_values [] = { 2, 3 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); } - - testset1.swap (testset2); - - { int init_values [] = { 1, 2, 4, 5 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); } - { int init_values [] = { 2, 3 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset2.begin() ); } - - testset1.erase (testset1.iterator_to(values[5]), testset1.end()); - BOOST_TEST (testset1.size() == 1); - BOOST_TEST (&*testset1.begin() == &values[3]); -} - -//test: find, equal_range (lower_bound, upper_bound): -template -void test_avl_multiset::test_find -(std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef avl_multiset - < value_type - , value_traits - , size_type - , constant_time_size - > multiset_type; - multiset_type testset (values.begin(), values.end()); - typedef typename multiset_type::iterator iterator; - - value_type cmp_val; - cmp_val.value_ = 2; - iterator i = testset.find (cmp_val); - BOOST_TEST (i->value_ == 2); - BOOST_TEST ((++i)->value_ == 2); - std::pair range = testset.equal_range (cmp_val); - - BOOST_TEST (range.first->value_ == 2); - BOOST_TEST (range.second->value_ == 3); - BOOST_TEST (std::distance (range.first, range.second) == 2); - - cmp_val.value_ = 7; - BOOST_TEST (testset.find (cmp_val) == testset.end()); -} - -template -void test_avl_multiset::test_clone - (std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef avl_multiset - < value_type - , value_traits - , size_type - , constant_time_size - > multiset_type; - multiset_type testmultiset1 (&values[0], &values[0] + values.size()); - multiset_type testmultiset2; - - testmultiset2.clone_from(testmultiset1, test::new_cloner(), test::delete_disposer()); - BOOST_TEST (testmultiset2 == testmultiset1); - testmultiset2.clear_and_dispose(test::delete_disposer()); - BOOST_TEST (testmultiset2.empty()); -} - -template -void test_avl_multiset::test_container_from_end - (std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef avl_multiset - < value_type - , value_traits - , size_type - , constant_time_size - > multiset_type; - - multiset_type testmultiset (&values[0], &values[0] + values.size()); - BOOST_TEST (testmultiset == multiset_type::container_from_end_iterator(testmultiset.end())); - BOOST_TEST (testmultiset == multiset_type::container_from_end_iterator(testmultiset.cend())); -} - template class test_main_template { public: int operator()() { - for(int n = 0; n < 2; ++n){ - typedef testvalue value_type; - static const int random_init[6] = { 3, 2, 4, 1, 5, 2 }; - std::vector > data (6); - for (int i = 0; i < 6; ++i) - data[i].value_ = random_init[i]; + using namespace boost::intrusive; + typedef testvalue value_type; - test_avl_multiset < typename detail::get_base_value_traits - < value_type - , typename value_type::avl_set_base_hook_t - >::type - >::test_all(data); - test_avl_multiset < typename detail::get_member_value_traits - < value_type - , member_hook< value_type - , typename value_type::avl_set_member_hook_t - , &value_type::avl_set_node_ - > - >::type - >::test_all(data); - } + test::test_generic_multiset < typename detail::get_base_value_traits + < value_type + , typename value_type::avl_set_base_hook_t + >::type + , GetContainer + >::test_all(); + test::test_generic_multiset < typename detail::get_member_value_traits + < value_type + , member_hook< value_type + , typename value_type::avl_set_member_hook_t + , &value_type::avl_set_node_ + > + >::type + , GetContainer + >::test_all(); return 0; } }; @@ -315,80 +66,53 @@ class test_main_template public: int operator()() { - for(int n = 0; n < 2; ++n){ - typedef testvalue value_type; - static const int random_init[6] = { 3, 2, 4, 1, 5, 2 }; - std::vector > data (6); - for (int i = 0; i < 6; ++i) - data[i].value_ = random_init[i]; + using namespace boost::intrusive; + typedef testvalue value_type; - test_avl_multiset < typename detail::get_base_value_traits - < value_type - , typename value_type::avl_set_base_hook_t - >::type - >::test_all(data); + test::test_generic_multiset < typename detail::get_base_value_traits + < value_type + , typename value_type::avl_set_base_hook_t + >::type + , GetContainer + >::test_all(); - test_avl_multiset < typename detail::get_member_value_traits - < value_type - , member_hook< value_type - , typename value_type::avl_set_member_hook_t - , &value_type::avl_set_node_ - > - >::type - >::test_all(data); + test::test_generic_multiset < typename detail::get_member_value_traits + < value_type + , member_hook< value_type + , typename value_type::avl_set_member_hook_t + , &value_type::avl_set_node_ + > + >::type + , GetContainer + >::test_all(); - test_avl_multiset < typename detail::get_base_value_traits - < value_type - , typename value_type::avl_set_auto_base_hook_t - >::type - >::test_all(data); + test::test_generic_multiset < typename detail::get_base_value_traits + < value_type + , typename value_type::avl_set_auto_base_hook_t + >::type + , GetContainer + >::test_all(); - test_avl_multiset < typename detail::get_member_value_traits - < value_type - , member_hook< value_type - , typename value_type::avl_set_auto_member_hook_t - , &value_type::avl_set_auto_node_ - > - >::type - >::test_all(data); - } + test::test_generic_multiset < typename detail::get_member_value_traits + < value_type + , member_hook< value_type + , typename value_type::avl_set_auto_member_hook_t + , &value_type::avl_set_auto_node_ + > + >::type + , GetContainer + >::test_all(); return 0; } }; -//Explicit instantiations of non-counted classes -//template class multiset -// , false>; -//template class multiset -// , false>; -//template class multiset -// , false>; -//template class multiset -// , false>; -//template class multiset -// , false>; -//template class multiset -// , false>; -//template class multiset -// , false>; -//template class multiset -// , false>; - -//Explicit instantiation of counted classes -//template class multiset -// , true>; -//template class multiset -// , true>; -//template class multiset -// , true>; -//template class multiset -// , true>; - int main( int, char* [] ) { test_main_template()(); - test_main_template, false>()(); + test_main_template, false>()(); test_main_template()(); - test_main_template, true>()(); + test_main_template, true>()(); return boost::report_errors(); } + +#include diff --git a/test/avl_set_test.cpp b/test/avl_set_test.cpp index 2eedd77..1f7150e 100644 --- a/test/avl_set_test.cpp +++ b/test/avl_set_test.cpp @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2007. +// (C) Copyright Olaf Krzikalla 2004-2006. +// (C) Copyright Ion Gaztanaga 2006-2007. // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -11,284 +12,49 @@ ///////////////////////////////////////////////////////////////////////////// #include #include -#include #include "itestvalue.hpp" #include "smart_ptr.hpp" -#include "common_functors.hpp" -#include -#include -#include "test_macros.hpp" -#include "test_container.hpp" -#include +#include "generic_set_test.hpp" -namespace boost { namespace intrusive { namespace test { - -template -struct has_const_overloads > +template< class ValueType + , class Option1 = boost::intrusive::none + , class Option2 = boost::intrusive::none + , class Option3 = boost::intrusive::none + > +struct GetContainer { - static const bool value = false; + typedef boost::intrusive::avl_set + < ValueType + , Option1 + , Option2 + , Option3 + > type; }; -}}} - -using namespace boost::intrusive; - -template -struct test_avl_set -{ - typedef typename ValueTraits::value_type value_type; - static void test_all(std::vector& values); - static void test_sort(std::vector& values); - static void test_insert(std::vector& values); - static void test_swap(std::vector& values); - static void test_find(std::vector& values); - static void test_impl(); - static void test_clone(std::vector& values); - static void test_container_from_end(std::vector& values); -}; - -template -void test_avl_set::test_all(std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef avl_set - < value_type - , value_traits - , constant_time_size - > avl_set_type; - { - avl_set_type testset(values.begin(), values.end()); - test::test_container(testset); - testset.clear(); - testset.insert(values.begin(), values.end()); - test::test_common_unordered_and_associative_container(testset, values); - testset.clear(); - testset.insert(values.begin(), values.end()); - test::test_associative_container(testset, values); - testset.clear(); - testset.insert(values.begin(), values.end()); - test::test_unique_container(testset, values); - } - - test_sort(values); - test_insert(values); - test_swap(values); - test_find(values); - test_impl(); - test_clone(values); - test_container_from_end(values); -} - -//test case due to an error in tree implementation: -template -void test_avl_set::test_impl() -{ - typedef typename ValueTraits::value_type value_type; - std::vector values (5); - for (int i = 0; i < 5; ++i) - values[i].value_ = i; - - typedef typename ValueTraits::value_type value_type; - typedef avl_set - < value_type - , value_traits - , constant_time_size - > avl_set_type; - avl_set_type testset; - for (int i = 0; i < 5; ++i) - testset.insert (values[i]); - - testset.erase (testset.iterator_to (values[0])); - testset.erase (testset.iterator_to (values[1])); - testset.insert (values[1]); - - testset.erase (testset.iterator_to (values[2])); - testset.erase (testset.iterator_to (values[3])); -} - -//test: constructor, iterator, clear, reverse_iterator, front, back, size: -template -void test_avl_set::test_sort(std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef avl_set - < value_type - , value_traits - , constant_time_size - > avl_set_type; - avl_set_type testset1 (values.begin(), values.end()); - { int init_values [] = { 1, 2, 3, 4, 5 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); } - - testset1.clear(); - BOOST_TEST (testset1.empty()); - - typedef typename ValueTraits::value_type value_type; - typedef avl_set - < value_type - , compare - , value_traits - , constant_time_size - > set_type2; - set_type2 testset2 (&values[0], &values[0] + 6); - { int init_values [] = { 5, 3, 1, 4, 2 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset2.rbegin() ); } - BOOST_TEST (testset2.begin()->value_ == 2); - BOOST_TEST (testset2.rbegin()->value_ == 5); -} - -//test: insert, const_iterator, const_reverse_iterator, erase, s_iterator_to: -template -void test_avl_set::test_insert(std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef avl_set - < value_type - , value_traits - , constant_time_size - > avl_set_type; - avl_set_type testset; - testset.insert(&values[0] + 2, &values[0] + 5); - - const avl_set_type& const_testset = testset; - { int init_values [] = { 1, 4, 5 }; - TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); } - - typename avl_set_type::iterator i = testset.begin(); - BOOST_TEST (i->value_ == 1); - - i = testset.insert (i, values[0]); - BOOST_TEST (&*i == &values[0]); - - { int init_values [] = { 5, 4, 3, 1 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset.rbegin() ); } - - i = testset.iterator_to (values[2]); - BOOST_TEST (&*i == &values[2]); - - i = avl_set_type::s_iterator_to(values[2]); - BOOST_TEST (&*i == &values[2]); - - testset.erase (i); - { int init_values [] = { 1, 3, 5 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset.begin() ); } -} - -//test: insert (seq-version), swap, erase (seq-version), size: -template -void test_avl_set::test_swap(std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef avl_set - < value_type - , value_traits - , constant_time_size - > avl_set_type; - avl_set_type testset1 (&values[0], &values[0] + 2); - avl_set_type testset2; - testset2.insert (&values[0] + 2, &values[0] + 6); - testset1.swap (testset2); - - { int init_values [] = { 1, 2, 4, 5 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); } - - { int init_values [] = { 2, 3 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset2.begin() ); } - - testset1.erase (testset1.iterator_to(values[5]), testset1.end()); - BOOST_TEST (testset1.size() == 1); - // BOOST_TEST (&testset1.front() == &values[3]); - BOOST_TEST (&*testset1.begin() == &values[3]); -} - -//test: find, equal_range (lower_bound, upper_bound): -template -void test_avl_set::test_find(std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef avl_set - < value_type - , value_traits - , constant_time_size - > avl_set_type; - avl_set_type testset (values.begin(), values.end()); - typedef typename avl_set_type::iterator iterator; - - value_type cmp_val; - cmp_val.value_ = 2; - iterator i = testset.find (cmp_val); - BOOST_TEST (i->value_ == 2); - BOOST_TEST ((++i)->value_ != 2); - std::pair range = testset.equal_range (cmp_val); - - BOOST_TEST (range.first->value_ == 2); - BOOST_TEST (range.second->value_ == 3); - BOOST_TEST (std::distance (range.first, range.second) == 1); - - cmp_val.value_ = 7; - BOOST_TEST (testset.find (cmp_val) == testset.end()); -} - -template -void test_avl_set - ::test_clone(std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef avl_set - < value_type - , value_traits - , constant_time_size - > avl_set_type; - - avl_set_type testset1 (&values[0], &values[0] + values.size()); - avl_set_type testset2; - - testset2.clone_from(testset1, test::new_cloner(), test::delete_disposer()); - BOOST_TEST (testset2 == testset1); - testset2.clear_and_dispose(test::delete_disposer()); - BOOST_TEST (testset2.empty()); -} - -template -void test_avl_set - ::test_container_from_end(std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef avl_set - < value_type - , value_traits - , constant_time_size - > avl_set_type; - avl_set_type testset (&values[0], &values[0] + values.size()); - BOOST_TEST (testset == avl_set_type::container_from_end_iterator(testset.end())); - BOOST_TEST (testset == avl_set_type::container_from_end_iterator(testset.cend())); -} - template class test_main_template { public: int operator()() { + using namespace boost::intrusive; typedef testvalue value_type; - static const int random_init[6] = { 3, 2, 4, 1, 5, 2 }; - std::vector > data (6); - for (int i = 0; i < 6; ++i) - data[i].value_ = random_init[i]; - test_avl_set < typename detail::get_base_value_traits + test::test_generic_set < typename detail::get_base_value_traits < value_type , typename value_type::avl_set_base_hook_t >::type - >::test_all(data); - test_avl_set < typename detail::get_member_value_traits + , GetContainer + >::test_all(); + test::test_generic_set < typename detail::get_member_value_traits < value_type , member_hook< value_type , typename value_type::avl_set_member_hook_t , &value_type::avl_set_node_ > >::type - >::test_all(data); + , GetContainer + >::test_all(); return 0; } }; @@ -299,41 +65,42 @@ class test_main_template public: int operator()() { + using namespace boost::intrusive; typedef testvalue value_type; - static const int random_init[6] = { 3, 2, 4, 1, 5, 2 }; - std::vector > data (6); - for (int i = 0; i < 6; ++i) - data[i].value_ = random_init[i]; - test_avl_set < typename detail::get_base_value_traits + test::test_generic_set < typename detail::get_base_value_traits < value_type , typename value_type::avl_set_base_hook_t >::type - >::test_all(data); + , GetContainer + >::test_all(); - test_avl_set < typename detail::get_member_value_traits + test::test_generic_set < typename detail::get_member_value_traits < value_type , member_hook< value_type , typename value_type::avl_set_member_hook_t , &value_type::avl_set_node_ > >::type - >::test_all(data); + , GetContainer + >::test_all(); - test_avl_set < typename detail::get_base_value_traits + test::test_generic_set < typename detail::get_base_value_traits < value_type , typename value_type::avl_set_auto_base_hook_t >::type - >::test_all(data); + , GetContainer + >::test_all(); - test_avl_set < typename detail::get_member_value_traits + test::test_generic_set < typename detail::get_member_value_traits < value_type , member_hook< value_type , typename value_type::avl_set_auto_member_hook_t , &value_type::avl_set_auto_node_ > >::type - >::test_all(data); + , GetContainer + >::test_all(); return 0; } @@ -341,10 +108,12 @@ class test_main_template int main( int, char* [] ) { + test_main_template()(); - test_main_template, false>()(); + test_main_template, false>()(); test_main_template()(); - test_main_template, true>()(); + test_main_template, true>()(); return boost::report_errors(); } + #include diff --git a/test/external_value_traits_test.cpp b/test/external_value_traits_test.cpp index c27177a..fa380e2 100644 --- a/test/external_value_traits_test.cpp +++ b/test/external_value_traits_test.cpp @@ -207,8 +207,7 @@ int main() Rbtree &my_rbtree = static_cast (cont_holder); Hash &my_hash = static_cast (cont_holder); - //Now insert them in the reverse order - //in the base hook intrusive list + //Now insert them in containers for(MyClass * it(&values[0]), *itend(&values[NumElements]) ; it != itend; ++it){ my_list.push_front(*it); @@ -217,7 +216,7 @@ int main() my_hash.insert_unique(*it); } - //Now test lists + //Now test containers { List::const_iterator list_it (my_list.cbegin()); Slist::const_iterator slist_it (my_slist.cbegin()); @@ -225,7 +224,7 @@ int main() Hash::const_iterator hash_it (my_hash.cbegin()); MyClass *it_val(&values[NumElements] - 1), *it_rbeg_val(&values[0]-1); - //Test the objects inserted in the base hook list + //Test inserted objects for(; it_val != it_rbeg_val; --it_val, ++list_it, ++slist_it, ++rbtree_it){ if(&*list_it != &*it_val) return 1; if(&*slist_it != &*it_val) return 1; diff --git a/test/generic_assoc_test.hpp b/test/generic_assoc_test.hpp new file mode 100644 index 0000000..624fd60 --- /dev/null +++ b/test/generic_assoc_test.hpp @@ -0,0 +1,328 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Olaf Krzikalla 2004-2006. +// (C) Copyright Ion Gaztanaga 2006-2007. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// +#include //vector +#include //sort, random_shuffle +#include +#include "common_functors.hpp" +#include +#include +#include "test_macros.hpp" +#include "test_container.hpp" + +namespace boost{ +namespace intrusive{ +namespace test{ + +template +struct has_splay +{ + static const bool value = false; +}; + +template +struct has_rebalance +{ + static const bool value = false; +}; + +template class ContainerDefiner> +struct test_generic_assoc +{ + typedef typename ValueTraits::value_type value_type; + static void test_all(std::vector& values); + static void test_clone(std::vector& values); + static void test_insert_erase_burst(); + static void test_container_from_end(std::vector& values); + static void test_splay_up(std::vector& values); + static void test_splay_up(std::vector& values, boost::intrusive::detail::true_type); + static void test_splay_up(std::vector& values, boost::intrusive::detail::false_type); + static void test_splay_down(std::vector& values); + static void test_splay_down(std::vector& values, boost::intrusive::detail::true_type); + static void test_splay_down(std::vector& values, boost::intrusive::detail::false_type); + static void test_rebalance(std::vector& values); + static void test_rebalance(std::vector& values, boost::intrusive::detail::true_type); + static void test_rebalance(std::vector& values, boost::intrusive::detail::false_type); +}; + +template class ContainerDefiner> +void test_generic_assoc::test_insert_erase_burst() +{ + typedef typename ValueTraits::value_type value_type; + + std::vector values; + const int MaxValues = 100; + for(int i = 0; i != MaxValues; ++i){ + values.push_back(value_type(i)); + } + + typedef typename ContainerDefiner + < value_type + , value_traits + , constant_time_size + >::type assoc_type; + typedef typename assoc_type::iterator iterator; + + //First ordered insertions + assoc_type testset (&values[0], &values[0] + values.size()); + TEST_INTRUSIVE_SEQUENCE_EXPECTED(testset, testset.begin()); + + //Ordered erasure + iterator it(testset.begin()), itend(testset.end()); + for(int i = 0; it != itend; ++i){ + BOOST_TEST(&*it == &values[i]); + it = testset.erase(it); + } + + BOOST_TEST(testset.empty()); + + //Now random insertions + std::random_shuffle(values.begin(), values.end()); + testset.insert(&values[0], &values[0] + values.size()); + std::sort(values.begin(), values.end()); + TEST_INTRUSIVE_SEQUENCE_EXPECTED(testset, testset.begin()); + + //Random erasure + std::random_shuffle(values.begin(), values.end()); + for(int i = 0; i != MaxValues; ++i){ + it = testset.erase(testset.iterator_to(values[i])); + } + + BOOST_TEST(testset.empty()); +} + +template class ContainerDefiner> +void test_generic_assoc::test_all(std::vector& values) +{ + test_clone(values); + test_container_from_end(values); + test_splay_up(values); + test_splay_down(values); + test_rebalance(values); + test_insert_erase_burst(); +} + +template class ContainerDefiner> +void test_generic_assoc + ::test_clone(std::vector& values) +{ + typedef typename ValueTraits::value_type value_type; + typedef typename ContainerDefiner + < value_type + , value_traits + , constant_time_size + >::type assoc_type; + + assoc_type testset1 (&values[0], &values[0] + values.size()); + assoc_type testset2; + + testset2.clone_from(testset1, test::new_cloner(), test::delete_disposer()); + BOOST_TEST (testset2 == testset1); + testset2.clear_and_dispose(test::delete_disposer()); + BOOST_TEST (testset2.empty()); +} + +template class ContainerDefiner> +void test_generic_assoc + ::test_container_from_end(std::vector& values) +{ + typedef typename ValueTraits::value_type value_type; + typedef typename ContainerDefiner + < value_type + , value_traits + , constant_time_size + >::type assoc_type; + assoc_type testset (&values[0], &values[0] + values.size()); + BOOST_TEST (testset == assoc_type::container_from_end_iterator(testset.end())); + BOOST_TEST (testset == assoc_type::container_from_end_iterator(testset.cend())); +} + +template class ContainerDefiner> +void test_generic_assoc::test_splay_up +(std::vector& values, boost::intrusive::detail::true_type) +{ + typedef typename ValueTraits::value_type value_type; + typedef typename ContainerDefiner + < value_type + , value_traits + , constant_time_size + >::type assoc_type; + typedef typename assoc_type::iterator iterator; + typedef std::vector orig_set_t; + std::size_t num_values; + orig_set_t original_testset; + { + assoc_type testset (values.begin(), values.end()); + num_values = testset.size(); + original_testset.insert(original_testset.end(), testset.begin(), testset.end()); + } + + for(std::size_t i = 0; i != num_values; ++i){ + assoc_type testset (values.begin(), values.end()); + { + iterator it = testset.begin(); + for(std::size_t j = 0; j != i; ++j, ++it){} + testset.splay_up(it); + } + BOOST_TEST (testset.size() == num_values); + iterator it = testset.begin(); + for( typename orig_set_t::const_iterator origit = original_testset.begin() + , origitend = original_testset.end() + ; origit != origitend + ; ++origit, ++it){ + BOOST_TEST(*origit == *it); + } + } +} + +template class ContainerDefiner> +void test_generic_assoc::test_splay_up +(std::vector&, boost::intrusive::detail::false_type) +{} + +template class ContainerDefiner> +void test_generic_assoc::test_splay_up +(std::vector& values) +{ + typedef typename ContainerDefiner + < value_type + , value_traits + , constant_time_size + >::type assoc_type; + typedef typename detail::remove_const::type Type; + typedef detail::bool_::value> enabler; + test_splay_up(values, enabler()); +} + +template class ContainerDefiner> +void test_generic_assoc::test_splay_down +(std::vector& values, boost::intrusive::detail::true_type) +{ + typedef typename ValueTraits::value_type value_type; + typedef typename ContainerDefiner + < value_type + , value_traits + , constant_time_size + >::type assoc_type; + typedef typename assoc_type::iterator iterator; + typedef std::vector orig_set_t; + std::size_t num_values; + orig_set_t original_testset; + { + assoc_type testset (values.begin(), values.end()); + num_values = testset.size(); + original_testset.insert(original_testset.end(), testset.begin(), testset.end()); + } + + for(std::size_t i = 0; i != num_values; ++i){ + assoc_type testset (values.begin(), values.end()); + BOOST_TEST(testset.size() == num_values); + { + iterator it = testset.begin(); + for(std::size_t j = 0; j != i; ++j, ++it){} + BOOST_TEST(*it == *testset.splay_down(*it)); + } + BOOST_TEST (testset.size() == num_values); + iterator it = testset.begin(); + for( typename orig_set_t::const_iterator origit = original_testset.begin() + , origitend = original_testset.end() + ; origit != origitend + ; ++origit, ++it){ + BOOST_TEST(*origit == *it); + } + } +} + +template class ContainerDefiner> +void test_generic_assoc::test_splay_down +(std::vector&, boost::intrusive::detail::false_type) +{} + +template class ContainerDefiner> +void test_generic_assoc::test_splay_down +(std::vector& values) +{ + typedef typename ContainerDefiner + < value_type + , value_traits + , constant_time_size + >::type assoc_type; + typedef typename detail::remove_const::type Type; + typedef detail::bool_::value> enabler; + test_splay_down(values, enabler()); +} + +template class ContainerDefiner> +void test_generic_assoc::test_rebalance +(std::vector& values, boost::intrusive::detail::true_type) +{ + typedef typename ValueTraits::value_type value_type; + typedef typename ContainerDefiner + < value_type + , value_traits + , constant_time_size + >::type assoc_type; + typedef std::vector orig_set_t; + typedef typename orig_set_t::iterator iterator_t; + std::size_t num_values; + orig_set_t original_testset; + { + assoc_type testset (values.begin(), values.end()); + num_values = testset.size(); + original_testset.insert(original_testset.end(), testset.begin(), testset.end()); + } + { + assoc_type testset(values.begin(), values.end()); + testset.rebalance(); + iterator_t it = original_testset.begin(); + TEST_INTRUSIVE_SEQUENCE_EXPECTED(original_testset, testset.begin()); + } + + { + std::size_t numdata; + { + assoc_type testset(values.begin(), values.end()); + numdata = testset.size(); + } + + for(int i = 0; i != (int)numdata; ++i){ + assoc_type testset(values.begin(), values.end()); + typename assoc_type::iterator it = testset.begin(); + for(int j = 0; j != i; ++j) ++it; + testset.rebalance_subtree(it); + TEST_INTRUSIVE_SEQUENCE_EXPECTED(original_testset, testset.begin()); + } + } +} + +template class ContainerDefiner> +void test_generic_assoc::test_rebalance +(std::vector&, boost::intrusive::detail::false_type) +{} + +template class ContainerDefiner> +void test_generic_assoc::test_rebalance +(std::vector& values) +{ + typedef typename ContainerDefiner + < value_type + , value_traits + , constant_time_size + >::type assoc_type; + typedef typename detail::remove_const::type Type; + typedef detail::bool_::value> enabler; + test_rebalance(values, enabler()); +} + +}}} //namespace boost::intrusive::test + +#include diff --git a/test/generic_multiset_test.hpp b/test/generic_multiset_test.hpp new file mode 100644 index 0000000..0df4e72 --- /dev/null +++ b/test/generic_multiset_test.hpp @@ -0,0 +1,227 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Olaf Krzikalla 2004-2006. +// (C) Copyright Ion Gaztanaga 2006-2007. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// +#include +#include +#include "common_functors.hpp" +#include +#include +#include "test_macros.hpp" +#include "test_container.hpp" +#include "generic_assoc_test.hpp" + +namespace boost{ +namespace intrusive{ +namespace test{ + +template class ContainerDefiner> +struct test_generic_multiset +{ + typedef typename ValueTraits::value_type value_type; + static void test_all (); + static void test_sort(std::vector& values); + static void test_insert(std::vector& values); + static void test_swap(std::vector& values); + static void test_find(std::vector& values); + static void test_impl(); +}; + +template class ContainerDefiner> +void test_generic_multiset::test_all () +{ + typedef typename ValueTraits::value_type value_type; + static const int random_init[6] = { 3, 2, 4, 1, 5, 2 }; + std::vector values (6); + for (int i = 0; i < 6; ++i) + values[i].value_ = random_init[i]; + + typedef typename ContainerDefiner + < value_type + , value_traits + , constant_time_size + >::type multiset_type; + { + multiset_type testset(values.begin(), values.end()); + test::test_container(testset); + testset.clear(); + testset.insert(values.begin(), values.end()); + test::test_common_unordered_and_associative_container(testset, values); + testset.clear(); + testset.insert(values.begin(), values.end()); + test::test_associative_container(testset, values); + testset.clear(); + testset.insert(values.begin(), values.end()); + test::test_non_unique_container(testset, values); + } + test_sort(values); + test_insert(values); + test_swap(values); + test_find(values); + test_impl(); + test_generic_assoc::test_all(values); +} + +//test case due to an error in tree implementation: +template class ContainerDefiner> +void test_generic_multiset::test_impl() +{ + typedef typename ValueTraits::value_type value_type; + std::vector values (5); + for (int i = 0; i < 5; ++i) + values[i].value_ = i; + typedef typename ValueTraits::value_type value_type; + typedef typename ContainerDefiner + < value_type + , value_traits + , constant_time_size + >::type multiset_type; + + multiset_type testset; + for (int i = 0; i < 5; ++i) + testset.insert (values[i]); + + testset.erase (testset.iterator_to (values[0])); + testset.erase (testset.iterator_to (values[1])); + testset.insert (values[1]); + + testset.erase (testset.iterator_to (values[2])); + testset.erase (testset.iterator_to (values[3])); +} + +//test: constructor, iterator, clear, reverse_iterator, front, back, size: +template class ContainerDefiner> +void test_generic_multiset::test_sort(std::vector& values) +{ + typedef typename ValueTraits::value_type value_type; + typedef typename ContainerDefiner + < value_type + , value_traits + , constant_time_size + >::type multiset_type; + + multiset_type testset1 (values.begin(), values.end()); + { int init_values [] = { 1, 2, 2, 3, 4, 5 }; + TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); } + + testset1.clear(); + BOOST_TEST (testset1.empty()); + + typedef typename ContainerDefiner + + , value_traits + , constant_time_size + >::type multiset_type2; + multiset_type2 testset2 (&values[0], &values[0] + 6); + { int init_values [] = { 5, 3, 1, 4, 2, 2 }; + TEST_INTRUSIVE_SEQUENCE( init_values, testset2.rbegin() ); } + + BOOST_TEST (testset2.begin()->value_ == 2); + BOOST_TEST (testset2.rbegin()->value_ == 5); +} + +//test: insert, const_iterator, const_reverse_iterator, erase, iterator_to: +template class ContainerDefiner> +void test_generic_multiset::test_insert(std::vector& values) +{ + typedef typename ValueTraits::value_type value_type; + typedef typename ContainerDefiner + < value_type + , value_traits + , size_type + , constant_time_size + >::type multiset_type; + + multiset_type testset; + testset.insert(&values[0] + 2, &values[0] + 5); + { int init_values [] = { 1, 4, 5 }; + TEST_INTRUSIVE_SEQUENCE( init_values, testset.begin() ); } + + typename multiset_type::iterator i = testset.begin(); + BOOST_TEST (i->value_ == 1); + + i = testset.insert (i, values[0]); + BOOST_TEST (&*i == &values[0]); + + { int init_values [] = { 5, 4, 3, 1 }; + TEST_INTRUSIVE_SEQUENCE( init_values, testset.rbegin() ); } + + i = testset.iterator_to (values[2]); + BOOST_TEST (&*i == &values[2]); + + i = multiset_type::s_iterator_to (values[2]); + BOOST_TEST (&*i == &values[2]); + + testset.erase(i); + + { int init_values [] = { 1, 3, 5 }; + TEST_INTRUSIVE_SEQUENCE( init_values, testset.begin() ); } +} + +//test: insert (seq-version), swap, erase (seq-version), size: +template class ContainerDefiner> +void test_generic_multiset::test_swap(std::vector& values) +{ + typedef typename ValueTraits::value_type value_type; + typedef typename ContainerDefiner + < value_type + , value_traits + , size_type + , constant_time_size + >::type multiset_type; + multiset_type testset1 (&values[0], &values[0] + 2); + multiset_type testset2; + testset2.insert (&values[0] + 2, &values[0] + 6); + testset1.swap (testset2); + + { int init_values [] = { 1, 2, 4, 5 }; + TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); } + { int init_values [] = { 2, 3 }; + TEST_INTRUSIVE_SEQUENCE( init_values, testset2.begin() ); } + + testset1.erase (testset1.iterator_to(values[5]), testset1.end()); + BOOST_TEST (testset1.size() == 1); + BOOST_TEST (&*testset1.begin() == &values[3]); +} + +//test: find, equal_range (lower_bound, upper_bound): +template class ContainerDefiner> +void test_generic_multiset::test_find(std::vector& values) +{ + typedef typename ValueTraits::value_type value_type; + typedef typename ContainerDefiner + < value_type + , value_traits + , size_type + , constant_time_size + >::type multiset_type; + multiset_type testset (values.begin(), values.end()); + typedef typename multiset_type::iterator iterator; + + value_type cmp_val; + cmp_val.value_ = 2; + iterator i = testset.find (cmp_val); + BOOST_TEST (i->value_ == 2); + BOOST_TEST ((++i)->value_ == 2); + std::pair range = testset.equal_range (cmp_val); + + BOOST_TEST (range.first->value_ == 2); + BOOST_TEST (range.second->value_ == 3); + BOOST_TEST (std::distance (range.first, range.second) == 2); + + cmp_val.value_ = 7; + BOOST_TEST (testset.find (cmp_val) == testset.end()); +} + +}}} //namespace boost::intrusive::test + +#include diff --git a/test/generic_set_test.hpp b/test/generic_set_test.hpp new file mode 100644 index 0000000..db14008 --- /dev/null +++ b/test/generic_set_test.hpp @@ -0,0 +1,225 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Olaf Krzikalla 2004-2006. +// (C) Copyright Ion Gaztanaga 2006-2007. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// +#include +#include +#include "common_functors.hpp" +#include +#include +#include "test_macros.hpp" +#include "test_container.hpp" +#include "generic_assoc_test.hpp" + +namespace boost{ +namespace intrusive{ +namespace test{ + +template class ContainerDefiner> +struct test_generic_set +{ + typedef typename ValueTraits::value_type value_type; + static void test_all(); + static void test_sort(std::vector& values); + static void test_insert(std::vector& values); + static void test_swap(std::vector& values); + static void test_find(std::vector& values); + static void test_impl(); +}; + +template class ContainerDefiner> +void test_generic_set::test_all() +{ + typedef typename ValueTraits::value_type value_type; + static const int random_init[6] = { 3, 2, 4, 1, 5, 2 }; + std::vector values (6); + for (int i = 0; i < 6; ++i) + values[i].value_ = random_init[i]; + + typedef typename ContainerDefiner + < value_type + , value_traits + , constant_time_size + >::type set_type; + { + set_type testset(values.begin(), values.end()); + test::test_container(testset); + testset.clear(); + testset.insert(values.begin(), values.end()); + test::test_common_unordered_and_associative_container(testset, values); + testset.clear(); + testset.insert(values.begin(), values.end()); + test::test_associative_container(testset, values); + testset.clear(); + testset.insert(values.begin(), values.end()); + test::test_unique_container(testset, values); + } + test_sort(values); + test_insert(values); + test_swap(values); + test_find(values); + test_impl(); + test_generic_assoc::test_all(values); +} + +//test case due to an error in tree implementation: +template class ContainerDefiner> +void test_generic_set::test_impl() +{ + typedef typename ValueTraits::value_type value_type; + std::vector values (5); + for (int i = 0; i < 5; ++i) + values[i].value_ = i; + + typedef typename ValueTraits::value_type value_type; + typedef typename ContainerDefiner + < value_type + , value_traits + , constant_time_size + >::type set_type; + set_type testset; + for (int i = 0; i < 5; ++i) + testset.insert (values[i]); + + testset.erase (testset.iterator_to (values[0])); + testset.erase (testset.iterator_to (values[1])); + testset.insert (values[1]); + + testset.erase (testset.iterator_to (values[2])); + testset.erase (testset.iterator_to (values[3])); +} + +//test: constructor, iterator, clear, reverse_iterator, front, back, size: +template class ContainerDefiner> +void test_generic_set::test_sort(std::vector& values) +{ + typedef typename ValueTraits::value_type value_type; + typedef typename ContainerDefiner + < value_type + , value_traits + , constant_time_size + >::type set_type; + set_type testset1 (values.begin(), values.end()); + { int init_values [] = { 1, 2, 3, 4, 5 }; + TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); } + + testset1.clear(); + BOOST_TEST (testset1.empty()); + + typedef typename ValueTraits::value_type value_type; + typedef typename ContainerDefiner + < value_type + , compare + , value_traits + , constant_time_size + >::type set_type2; + set_type2 testset2 (&values[0], &values[0] + 6); + { int init_values [] = { 5, 3, 1, 4, 2 }; + TEST_INTRUSIVE_SEQUENCE( init_values, testset2.rbegin() ); } + BOOST_TEST (testset2.begin()->value_ == 2); + BOOST_TEST (testset2.rbegin()->value_ == 5); +} + +//test: insert, const_iterator, const_reverse_iterator, erase, s_iterator_to: +template class ContainerDefiner> +void test_generic_set::test_insert(std::vector& values) +{ + typedef typename ValueTraits::value_type value_type; + typedef typename ContainerDefiner + < value_type + , value_traits + , constant_time_size + >::type set_type; + set_type testset; + testset.insert(&values[0] + 2, &values[0] + 5); + + const set_type& const_testset = testset; + { int init_values [] = { 1, 4, 5 }; + TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); } + + typename set_type::iterator i = testset.begin(); + BOOST_TEST (i->value_ == 1); + + i = testset.insert (i, values[0]); + BOOST_TEST (&*i == &values[0]); + + { int init_values [] = { 5, 4, 3, 1 }; + TEST_INTRUSIVE_SEQUENCE( init_values, testset.rbegin() ); } + + i = testset.iterator_to (values[2]); + BOOST_TEST (&*i == &values[2]); + + i = set_type::s_iterator_to(values[2]); + BOOST_TEST (&*i == &values[2]); + + testset.erase (i); + { int init_values [] = { 1, 3, 5 }; + TEST_INTRUSIVE_SEQUENCE( init_values, testset.begin() ); } +} + +//test: insert (seq-version), swap, erase (seq-version), size: +template class ContainerDefiner> +void test_generic_set::test_swap(std::vector& values) +{ + typedef typename ValueTraits::value_type value_type; + typedef typename ContainerDefiner + < value_type + , value_traits + , constant_time_size + >::type set_type; + set_type testset1 (&values[0], &values[0] + 2); + set_type testset2; + testset2.insert (&values[0] + 2, &values[0] + 6); + testset1.swap (testset2); + + { int init_values [] = { 1, 2, 4, 5 }; + TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); } + + { int init_values [] = { 2, 3 }; + TEST_INTRUSIVE_SEQUENCE( init_values, testset2.begin() ); } + + testset1.erase (testset1.iterator_to(values[5]), testset1.end()); + BOOST_TEST (testset1.size() == 1); + // BOOST_TEST (&testset1.front() == &values[3]); + BOOST_TEST (&*testset1.begin() == &values[3]); +} + +//test: find, equal_range (lower_bound, upper_bound): +template class ContainerDefiner> +void test_generic_set::test_find(std::vector& values) +{ + typedef typename ValueTraits::value_type value_type; + typedef typename ContainerDefiner + < value_type + , value_traits + , constant_time_size + >::type set_type; + set_type testset (values.begin(), values.end()); + typedef typename set_type::iterator iterator; + + value_type cmp_val; + cmp_val.value_ = 2; + iterator i = testset.find (cmp_val); + BOOST_TEST (i->value_ == 2); + BOOST_TEST ((++i)->value_ != 2); + std::pair range = testset.equal_range (cmp_val); + + BOOST_TEST (range.first->value_ == 2); + BOOST_TEST (range.second->value_ == 3); + BOOST_TEST (std::distance (range.first, range.second) == 1); + + cmp_val.value_ = 7; + BOOST_TEST (testset.find (cmp_val) == testset.end()); +} + +}}} //namespace boost::intrusive::test + +#include diff --git a/test/itestvalue.hpp b/test/itestvalue.hpp index b7d92a4..6878158 100644 --- a/test/itestvalue.hpp +++ b/test/itestvalue.hpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include "smart_ptr.hpp" @@ -61,6 +62,14 @@ template struct splay_set_auto_member_hook_type { typedef splay_set_member_hook, void_pointer > type; }; +template +struct bs_set_base_hook_type +{ typedef bs_set_base_hook > type; }; + +template +struct bs_set_member_hook_type +{ typedef bs_set_member_hook > type; }; + template struct avl_set_base_hook_type { typedef avl_set_base_hook > type; }; @@ -115,7 +124,11 @@ struct uset_base_hook_type template struct uset_auto_base_hook_type -{ typedef unordered_set_base_hook, void_pointer, tag > type; }; +{ + typedef unordered_set_base_hook + < link_mode, void_pointer + , tag, store_hash > type; +}; template struct uset_member_hook_type @@ -123,7 +136,11 @@ struct uset_member_hook_type template struct uset_auto_member_hook_type -{ typedef unordered_set_member_hook, void_pointer > type; }; +{ + typedef unordered_set_member_hook + < link_mode, void_pointer + , store_hash > type; +}; template struct testvalue @@ -131,6 +148,7 @@ struct testvalue , set_auto_base_hook_type::type , splay_set_base_hook_type::type , splay_set_auto_base_hook_type::type + , bs_set_base_hook_type::type , avl_set_base_hook_type::type , avl_set_auto_base_hook_type::type , list_base_hook_type::type @@ -150,6 +168,9 @@ struct testvalue typedef typename splay_set_auto_member_hook_type::type splay_set_auto_member_hook_t; typedef typename splay_set_member_hook_type::type splay_set_member_hook_t; + typedef typename bs_set_base_hook_type::type bs_set_base_hook_t; + typedef typename bs_set_member_hook_type::type bs_set_member_hook_t; + typedef typename avl_set_auto_base_hook_type::type avl_set_auto_base_hook_t; typedef typename avl_set_base_hook_type::type avl_set_base_hook_t; typedef typename avl_set_auto_member_hook_type::type avl_set_auto_member_hook_t; @@ -178,6 +199,9 @@ struct testvalue splay_set_member_hook_t splay_set_node_; splay_set_auto_member_hook_t splay_set_auto_node_; + //ScapegoatSet members + bs_set_member_hook_t sg_set_node_; + //AvlSet members avl_set_member_hook_t avl_set_node_; avl_set_auto_member_hook_t avl_set_auto_node_; @@ -224,6 +248,9 @@ struct testvalue this->splay_set_node_ = src.splay_set_node_; this->splay_set_auto_node_ = src.splay_set_auto_node_; + bs_set_base_hook_t::operator=(src); + this->sg_set_node_ = src.sg_set_node_; + avl_set_base_hook_t::operator=(src); avl_set_auto_base_hook_t::operator=(src); this->avl_set_node_ = src.avl_set_node_; @@ -262,6 +289,10 @@ struct testvalue splay_set_node_.swap_nodes(other.splay_set_node_); splay_set_auto_node_.swap_nodes(other.splay_set_auto_node_); + //ScapeoatSet + bs_set_base_hook_t::swap_nodes(other); + sg_set_node_.swap_nodes(other.sg_set_node_); + //AvlSet avl_set_base_hook_t::swap_nodes(other); avl_set_auto_base_hook_t::swap_nodes(other); diff --git a/test/make_functions_test.cpp b/test/make_functions_test.cpp index 3c9b4a1..bf40afb 100644 --- a/test/make_functions_test.cpp +++ b/test/make_functions_test.cpp @@ -68,8 +68,7 @@ int main() Set my_set; USet my_uset(USet::bucket_traits(buckets, 100)); - //Now insert them in the reverse order - //in the base hook intrusive list + //Now insert them in containers for(VectIt it(values.begin()), itend(values.end()); it != itend; ++it){ my_list.push_front(*it); my_slist.push_front(*it); diff --git a/test/multiset_test.cpp b/test/multiset_test.cpp index 93c9d73..180ee62 100644 --- a/test/multiset_test.cpp +++ b/test/multiset_test.cpp @@ -10,278 +10,51 @@ // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// - #include #include -#include #include "itestvalue.hpp" #include "smart_ptr.hpp" -#include "common_functors.hpp" -#include -#include -#include "test_macros.hpp" -#include "test_container.hpp" +#include "generic_multiset_test.hpp" -using namespace boost::intrusive; -template -struct test_multiset +template< class ValueType + , class Option1 = boost::intrusive::none + , class Option2 = boost::intrusive::none + , class Option3 = boost::intrusive::none + > +struct GetContainer { - typedef typename ValueTraits::value_type value_type; - static void test_all (std::vector& values); - static void test_sort(std::vector& values); - static void test_insert(std::vector& values); - static void test_swap(std::vector& values); - static void test_find(std::vector& values); - static void test_impl(); - static void test_clone(std::vector& values); - static void test_container_from_end(std::vector& values); + typedef boost::intrusive::multiset + < ValueType + , Option1 + , Option2 + , Option3 + > type; }; -template -void test_multiset::test_all (std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef multiset - < value_type - , value_traits - , constant_time_size - > multiset_type; - { - multiset_type testset(values.begin(), values.end()); - test::test_container(testset); - testset.clear(); - testset.insert(values.begin(), values.end()); - test::test_common_unordered_and_associative_container(testset, values); - testset.clear(); - testset.insert(values.begin(), values.end()); - test::test_associative_container(testset, values); - testset.clear(); - testset.insert(values.begin(), values.end()); - test::test_non_unique_container(testset, values); - } - test_sort(values); - test_insert(values); - test_swap(values); - test_find(values); - test_impl(); - test_clone(values); - test_container_from_end(values); -} - -//test case due to an error in tree implementation: -template -void test_multiset::test_impl() -{ - typedef typename ValueTraits::value_type value_type; - std::vector values (5); - for (int i = 0; i < 5; ++i) - values[i].value_ = i; - typedef typename ValueTraits::value_type value_type; - typedef multiset - < value_type - , value_traits - , constant_time_size - > multiset_type; - - multiset_type testset; - for (int i = 0; i < 5; ++i) - testset.insert (values[i]); - - testset.erase (testset.iterator_to (values[0])); - testset.erase (testset.iterator_to (values[1])); - testset.insert (values[1]); - - testset.erase (testset.iterator_to (values[2])); - testset.erase (testset.iterator_to (values[3])); -} - -//test: constructor, iterator, clear, reverse_iterator, front, back, size: -template -void test_multiset::test_sort(std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef multiset - < value_type - , value_traits - , constant_time_size - > multiset_type; - - multiset_type testset1 (values.begin(), values.end()); - { int init_values [] = { 1, 2, 2, 3, 4, 5 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); } - - testset1.clear(); - BOOST_TEST (testset1.empty()); - - typedef multiset - - , value_traits - , constant_time_size - > multiset_type2; - multiset_type2 testset2 (&values[0], &values[0] + 6); - { int init_values [] = { 5, 3, 1, 4, 2, 2 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset2.rbegin() ); } - - BOOST_TEST (testset2.begin()->value_ == 2); - BOOST_TEST (testset2.rbegin()->value_ == 5); -} - -//test: insert, const_iterator, const_reverse_iterator, erase, iterator_to: -template -void test_multiset::test_insert(std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef multiset - < value_type - , value_traits - , size_type - , constant_time_size - > multiset_type; - - multiset_type testset; - testset.insert(&values[0] + 2, &values[0] + 5); - { int init_values [] = { 1, 4, 5 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset.begin() ); } - - typename multiset_type::iterator i = testset.begin(); - BOOST_TEST (i->value_ == 1); - - i = testset.insert (i, values[0]); - BOOST_TEST (&*i == &values[0]); - - { int init_values [] = { 5, 4, 3, 1 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset.rbegin() ); } - - i = testset.iterator_to (values[2]); - BOOST_TEST (&*i == &values[2]); - - i = multiset_type::s_iterator_to (values[2]); - BOOST_TEST (&*i == &values[2]); - - testset.erase(i); - - { int init_values [] = { 1, 3, 5 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset.begin() ); } -} - -//test: insert (seq-version), swap, erase (seq-version), size: -template -void test_multiset::test_swap(std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef multiset - < value_type - , value_traits - , size_type - , constant_time_size - > multiset_type; - multiset_type testset1 (&values[0], &values[0] + 2); - multiset_type testset2; - testset2.insert (&values[0] + 2, &values[0] + 6); - testset1.swap (testset2); - - { int init_values [] = { 1, 2, 4, 5 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); } - { int init_values [] = { 2, 3 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset2.begin() ); } - - testset1.erase (testset1.iterator_to(values[5]), testset1.end()); - BOOST_TEST (testset1.size() == 1); - BOOST_TEST (&*testset1.begin() == &values[3]); -} - -//test: find, equal_range (lower_bound, upper_bound): -template -void test_multiset::test_find(std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef multiset - < value_type - , value_traits - , size_type - , constant_time_size - > multiset_type; - multiset_type testset (values.begin(), values.end()); - typedef typename multiset_type::iterator iterator; - - value_type cmp_val; - cmp_val.value_ = 2; - iterator i = testset.find (cmp_val); - BOOST_TEST (i->value_ == 2); - BOOST_TEST ((++i)->value_ == 2); - std::pair range = testset.equal_range (cmp_val); - - BOOST_TEST (range.first->value_ == 2); - BOOST_TEST (range.second->value_ == 3); - BOOST_TEST (std::distance (range.first, range.second) == 2); - - cmp_val.value_ = 7; - BOOST_TEST (testset.find (cmp_val) == testset.end()); -} - -template -void test_multiset - ::test_clone(std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef multiset - < value_type - , value_traits - , size_type - , constant_time_size - > multiset_type; - multiset_type testmultiset1 (&values[0], &values[0] + values.size()); - multiset_type testmultiset2; - - testmultiset2.clone_from(testmultiset1, test::new_cloner(), test::delete_disposer()); - BOOST_TEST (testmultiset2 == testmultiset1); - testmultiset2.clear_and_dispose(test::delete_disposer()); - BOOST_TEST (testmultiset2.empty()); -} - -template -void test_multiset - ::test_container_from_end(std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef multiset - < value_type - , value_traits - , size_type - , constant_time_size - > multiset_type; - - multiset_type testmultiset (&values[0], &values[0] + values.size()); - BOOST_TEST (testmultiset == multiset_type::container_from_end_iterator(testmultiset.end())); - BOOST_TEST (testmultiset == multiset_type::container_from_end_iterator(testmultiset.cend())); -} - template class test_main_template { public: int operator()() { + using namespace boost::intrusive; typedef testvalue value_type; - static const int random_init[6] = { 3, 2, 4, 1, 5, 2 }; - std::vector > data (6); - for (int i = 0; i < 6; ++i) - data[i].value_ = random_init[i]; - test_multiset < typename detail::get_base_value_traits + test::test_generic_multiset < typename detail::get_base_value_traits < value_type , typename value_type::set_base_hook_t >::type - >::test_all(data); - test_multiset < typename detail::get_member_value_traits + , GetContainer + >::test_all(); + test::test_generic_multiset < typename detail::get_member_value_traits < value_type , member_hook< value_type , typename value_type::set_member_hook_t , &value_type::set_node_ > >::type - >::test_all(data); + , GetContainer + >::test_all(); return 0; } }; @@ -292,78 +65,53 @@ class test_main_template public: int operator()() { + using namespace boost::intrusive; typedef testvalue value_type; - static const int random_init[6] = { 3, 2, 4, 1, 5, 2 }; - std::vector > data (6); - for (int i = 0; i < 6; ++i) - data[i].value_ = random_init[i]; - test_multiset < typename detail::get_base_value_traits + test::test_generic_multiset < typename detail::get_base_value_traits < value_type , typename value_type::set_base_hook_t >::type - >::test_all(data); + , GetContainer + >::test_all(); - test_multiset < typename detail::get_member_value_traits + test::test_generic_multiset < typename detail::get_member_value_traits < value_type , member_hook< value_type , typename value_type::set_member_hook_t , &value_type::set_node_ > >::type - >::test_all(data); + , GetContainer + >::test_all(); - test_multiset < typename detail::get_base_value_traits + test::test_generic_multiset < typename detail::get_base_value_traits < value_type , typename value_type::set_auto_base_hook_t >::type - >::test_all(data); + , GetContainer + >::test_all(); - test_multiset < typename detail::get_member_value_traits + test::test_generic_multiset < typename detail::get_member_value_traits < value_type , member_hook< value_type , typename value_type::set_auto_member_hook_t , &value_type::set_auto_node_ > >::type - >::test_all(data); + , GetContainer + >::test_all(); return 0; } }; -//Explicit instantiations of non-counted classes -//template class multiset -// , false>; -//template class multiset -// , false>; -//template class multiset -// , false>; -//template class multiset -// , false>; -//template class multiset -// , false>; -//template class multiset -// , false>; -//template class multiset -// , false>; -//template class multiset -// , false>; - -//Explicit instantiation of counted classes -//template class multiset -// , true>; -//template class multiset -// , true>; -//template class multiset -// , true>; -//template class multiset -// , true>; - int main( int, char* [] ) { test_main_template()(); - test_main_template, false>()(); + test_main_template, false>()(); test_main_template()(); - test_main_template, true>()(); + test_main_template, true>()(); return boost::report_errors(); } + +#include diff --git a/test/set_test.cpp b/test/set_test.cpp index 15f8e7d..a6b214e 100644 --- a/test/set_test.cpp +++ b/test/set_test.cpp @@ -12,272 +12,49 @@ ///////////////////////////////////////////////////////////////////////////// #include #include -#include #include "itestvalue.hpp" #include "smart_ptr.hpp" -#include "common_functors.hpp" -#include -#include -#include "test_macros.hpp" -#include "test_container.hpp" +#include "generic_set_test.hpp" -using namespace boost::intrusive; - -template -struct test_set +template< class ValueType + , class Option1 = boost::intrusive::none + , class Option2 = boost::intrusive::none + , class Option3 = boost::intrusive::none + > +struct GetContainer { - typedef typename ValueTraits::value_type value_type; - static void test_all(std::vector& values); - static void test_sort(std::vector& values); - static void test_insert(std::vector& values); - static void test_swap(std::vector& values); - static void test_find(std::vector& values); - static void test_impl(); - static void test_clone(std::vector& values); - static void test_container_from_end(std::vector& values); + typedef boost::intrusive::set + < ValueType + , Option1 + , Option2 + , Option3 + > type; }; -template -void test_set::test_all(std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef set - < value_type - , value_traits - , constant_time_size - > set_type; - { - set_type testset(values.begin(), values.end()); - test::test_container(testset); - testset.clear(); - testset.insert(values.begin(), values.end()); - test::test_common_unordered_and_associative_container(testset, values); - testset.clear(); - testset.insert(values.begin(), values.end()); - test::test_associative_container(testset, values); - testset.clear(); - testset.insert(values.begin(), values.end()); - test::test_unique_container(testset, values); - } - test_sort(values); - test_insert(values); - test_swap(values); - test_find(values); - test_impl(); - test_clone(values); - test_container_from_end(values); -} - -//test case due to an error in tree implementation: -template -void test_set::test_impl() -{ - typedef typename ValueTraits::value_type value_type; - std::vector values (5); - for (int i = 0; i < 5; ++i) - values[i].value_ = i; - - typedef typename ValueTraits::value_type value_type; - typedef set - < value_type - , value_traits - , constant_time_size - > set_type; - set_type testset; - for (int i = 0; i < 5; ++i) - testset.insert (values[i]); - - testset.erase (testset.iterator_to (values[0])); - testset.erase (testset.iterator_to (values[1])); - testset.insert (values[1]); - - testset.erase (testset.iterator_to (values[2])); - testset.erase (testset.iterator_to (values[3])); -} - -//test: constructor, iterator, clear, reverse_iterator, front, back, size: -template -void test_set::test_sort(std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef set - < value_type - , value_traits - , constant_time_size - > set_type; - set_type testset1 (values.begin(), values.end()); - { int init_values [] = { 1, 2, 3, 4, 5 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); } - - testset1.clear(); - BOOST_TEST (testset1.empty()); - - typedef typename ValueTraits::value_type value_type; - typedef set - < value_type - , compare - , value_traits - , constant_time_size - > set_type2; - set_type2 testset2 (&values[0], &values[0] + 6); - { int init_values [] = { 5, 3, 1, 4, 2 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset2.rbegin() ); } - BOOST_TEST (testset2.begin()->value_ == 2); - BOOST_TEST (testset2.rbegin()->value_ == 5); -} - -//test: insert, const_iterator, const_reverse_iterator, erase, s_iterator_to: -template -void test_set::test_insert(std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef set - < value_type - , value_traits - , constant_time_size - > set_type; - set_type testset; - testset.insert(&values[0] + 2, &values[0] + 5); - - const set_type& const_testset = testset; - { int init_values [] = { 1, 4, 5 }; - TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); } - - typename set_type::iterator i = testset.begin(); - BOOST_TEST (i->value_ == 1); - - i = testset.insert (i, values[0]); - BOOST_TEST (&*i == &values[0]); - - { int init_values [] = { 5, 4, 3, 1 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset.rbegin() ); } - - i = testset.iterator_to (values[2]); - BOOST_TEST (&*i == &values[2]); - - i = set_type::s_iterator_to(values[2]); - BOOST_TEST (&*i == &values[2]); - - testset.erase (i); - { int init_values [] = { 1, 3, 5 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset.begin() ); } -} - -//test: insert (seq-version), swap, erase (seq-version), size: -template -void test_set::test_swap(std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef set - < value_type - , value_traits - , constant_time_size - > set_type; - set_type testset1 (&values[0], &values[0] + 2); - set_type testset2; - testset2.insert (&values[0] + 2, &values[0] + 6); - testset1.swap (testset2); - - { int init_values [] = { 1, 2, 4, 5 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); } - - { int init_values [] = { 2, 3 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset2.begin() ); } - - testset1.erase (testset1.iterator_to(values[5]), testset1.end()); - BOOST_TEST (testset1.size() == 1); - // BOOST_TEST (&testset1.front() == &values[3]); - BOOST_TEST (&*testset1.begin() == &values[3]); -} - -//test: find, equal_range (lower_bound, upper_bound): -template -void test_set::test_find(std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef set - < value_type - , value_traits - , constant_time_size - > set_type; - set_type testset (values.begin(), values.end()); - typedef typename set_type::iterator iterator; - - value_type cmp_val; - cmp_val.value_ = 2; - iterator i = testset.find (cmp_val); - BOOST_TEST (i->value_ == 2); - BOOST_TEST ((++i)->value_ != 2); - std::pair range = testset.equal_range (cmp_val); - - BOOST_TEST (range.first->value_ == 2); - BOOST_TEST (range.second->value_ == 3); - BOOST_TEST (std::distance (range.first, range.second) == 1); - - cmp_val.value_ = 7; - BOOST_TEST (testset.find (cmp_val) == testset.end()); -} - -template -void test_set - ::test_clone(std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef set - < value_type - , value_traits - , constant_time_size - > set_type; - - set_type testset1 (&values[0], &values[0] + values.size()); - set_type testset2; - - testset2.clone_from(testset1, test::new_cloner(), test::delete_disposer()); - BOOST_TEST (testset2 == testset1); - testset2.clear_and_dispose(test::delete_disposer()); - BOOST_TEST (testset2.empty()); -} - -template -void test_set - ::test_container_from_end(std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef set - < value_type - , value_traits - , constant_time_size - > set_type; - set_type testset (&values[0], &values[0] + values.size()); - BOOST_TEST (testset == set_type::container_from_end_iterator(testset.end())); - BOOST_TEST (testset == set_type::container_from_end_iterator(testset.cend())); -} - template class test_main_template { public: int operator()() { + using namespace boost::intrusive; typedef testvalue value_type; - static const int random_init[6] = { 3, 2, 4, 1, 5, 2 }; - std::vector > data (6); - for (int i = 0; i < 6; ++i) - data[i].value_ = random_init[i]; - test_set < typename detail::get_base_value_traits + test::test_generic_set < typename detail::get_base_value_traits < value_type , typename value_type::set_base_hook_t >::type - >::test_all(data); - test_set < typename detail::get_member_value_traits + , GetContainer + >::test_all(); + test::test_generic_set < typename detail::get_member_value_traits < value_type , member_hook< value_type , typename value_type::set_member_hook_t , &value_type::set_node_ > >::type - >::test_all(data); + , GetContainer + >::test_all(); return 0; } }; @@ -288,41 +65,42 @@ class test_main_template public: int operator()() { + using namespace boost::intrusive; typedef testvalue value_type; - static const int random_init[6] = { 3, 2, 4, 1, 5, 2 }; - std::vector > data (6); - for (int i = 0; i < 6; ++i) - data[i].value_ = random_init[i]; - test_set < typename detail::get_base_value_traits + test::test_generic_set < typename detail::get_base_value_traits < value_type , typename value_type::set_base_hook_t >::type - >::test_all(data); + , GetContainer + >::test_all(); - test_set < typename detail::get_member_value_traits + test::test_generic_set < typename detail::get_member_value_traits < value_type , member_hook< value_type , typename value_type::set_member_hook_t , &value_type::set_node_ > >::type - >::test_all(data); + , GetContainer + >::test_all(); - test_set < typename detail::get_base_value_traits + test::test_generic_set < typename detail::get_base_value_traits < value_type , typename value_type::set_auto_base_hook_t >::type - >::test_all(data); + , GetContainer + >::test_all(); - test_set < typename detail::get_member_value_traits + test::test_generic_set < typename detail::get_member_value_traits < value_type , member_hook< value_type , typename value_type::set_auto_member_hook_t , &value_type::set_auto_node_ > >::type - >::test_all(data); + , GetContainer + >::test_all(); return 0; } @@ -332,9 +110,9 @@ int main( int, char* [] ) { test_main_template()(); - test_main_template, false>()(); + test_main_template, false>()(); test_main_template()(); - test_main_template, true>()(); + test_main_template, true>()(); return boost::report_errors(); } #include diff --git a/test/sg_multiset_test.cpp b/test/sg_multiset_test.cpp new file mode 100644 index 0000000..48f15f4 --- /dev/null +++ b/test/sg_multiset_test.cpp @@ -0,0 +1,108 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Olaf Krzikalla 2004-2006. +// (C) Copyright Ion Gaztanaga 2006-2007. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// +#include +#include +#include "itestvalue.hpp" +#include "smart_ptr.hpp" +#include "generic_multiset_test.hpp" + +namespace boost { namespace intrusive { namespace test { + +template +struct has_rebalance > +{ + static const bool value = true; +}; + +}}} + +template< class ValueType + , class Option1 = boost::intrusive::none + , class Option2 = boost::intrusive::none + , class Option3 = boost::intrusive::none + > +struct GetContainer +{ + typedef boost::intrusive::sg_multiset + < ValueType + , Option1 + , Option2 + , Option3 + > type; +}; + +template< class ValueType + , class Option1 = boost::intrusive::none + , class Option2 = boost::intrusive::none + , class Option3 = boost::intrusive::none + > +struct GetContainerFixedAlpha +{ + typedef boost::intrusive::sg_multiset + < ValueType + , Option1 + , Option2 + , Option3 + , boost::intrusive::floating_point + > type; +}; + +template +class test_main_template +{ + public: + int operator()() + { + using namespace boost::intrusive; + typedef testvalue value_type; + + test::test_generic_multiset < typename detail::get_base_value_traits + < value_type + , typename value_type::bs_set_base_hook_t + >::type + , GetContainer + >::test_all(); + test::test_generic_multiset < typename detail::get_member_value_traits + < value_type + , member_hook< value_type + , typename value_type::bs_set_member_hook_t + , &value_type::sg_set_node_ + > + >::type + , GetContainer + >::test_all(); + test::test_generic_multiset < typename detail::get_base_value_traits + < value_type + , typename value_type::bs_set_base_hook_t + >::type + , GetContainerFixedAlpha + >::test_all(); + test::test_generic_multiset < typename detail::get_member_value_traits + < value_type + , member_hook< value_type + , typename value_type::bs_set_member_hook_t + , &value_type::sg_set_node_ + > + >::type + , GetContainerFixedAlpha + >::test_all(); + return 0; + } +}; + +int main( int, char* [] ) +{ + test_main_template()(); + test_main_template >()(); + return boost::report_errors(); +} diff --git a/test/sg_set_test.cpp b/test/sg_set_test.cpp new file mode 100644 index 0000000..9d85e32 --- /dev/null +++ b/test/sg_set_test.cpp @@ -0,0 +1,109 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2007. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// +#include +#include +#include "itestvalue.hpp" +#include "smart_ptr.hpp" +#include "generic_set_test.hpp" + +namespace boost { namespace intrusive { namespace test { + +template +struct has_rebalance > +{ + static const bool value = true; +}; + +}}} + +template< class ValueType + , class Option1 = boost::intrusive::none + , class Option2 = boost::intrusive::none + , class Option3 = boost::intrusive::none + > +struct GetContainer +{ + typedef boost::intrusive::sg_set + < ValueType + , Option1 + , Option2 + , Option3 + > type; +}; + +template< class ValueType + , class Option1 = boost::intrusive::none + , class Option2 = boost::intrusive::none + , class Option3 = boost::intrusive::none + > +struct GetContainerFixedAlpha +{ + typedef boost::intrusive::sg_set + < ValueType + , Option1 + , Option2 + , Option3 + , boost::intrusive::floating_point + > type; +}; + +template +class test_main_template +{ + public: + int operator()() + { + using namespace boost::intrusive; + typedef testvalue value_type; + + test::test_generic_set < typename detail::get_base_value_traits + < value_type + , typename value_type::bs_set_base_hook_t + >::type + , GetContainer + >::test_all(); + test::test_generic_set < typename detail::get_member_value_traits + < value_type + , member_hook< value_type + , typename value_type::bs_set_member_hook_t + , &value_type::sg_set_node_ + > + >::type + , GetContainer + >::test_all(); + + test::test_generic_set < typename detail::get_base_value_traits + < value_type + , typename value_type::bs_set_base_hook_t + >::type + , GetContainerFixedAlpha + >::test_all(); + test::test_generic_set < typename detail::get_member_value_traits + < value_type + , member_hook< value_type + , typename value_type::bs_set_member_hook_t + , &value_type::sg_set_node_ + > + >::type + , GetContainerFixedAlpha + >::test_all(); + return 0; + } +}; + +int main( int, char* [] ) +{ + test_main_template()(); + test_main_template >()(); + return boost::report_errors(); +} +#include diff --git a/test/splay_multiset_test.cpp b/test/splay_multiset_test.cpp index dd39787..a8601ac 100644 --- a/test/splay_multiset_test.cpp +++ b/test/splay_multiset_test.cpp @@ -10,18 +10,12 @@ // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// - #include #include #include #include "itestvalue.hpp" #include "smart_ptr.hpp" -#include "common_functors.hpp" -#include -#include -#include "test_macros.hpp" -#include "test_container.hpp" -#include +#include "generic_multiset_test.hpp" namespace boost { namespace intrusive { namespace test { @@ -31,327 +25,34 @@ struct has_const_overloads > static const bool value = false; }; -}}} - -using namespace boost::intrusive; -template -struct test_splay_multiset +template +struct has_splay > { - typedef typename ValueTraits::value_type value_type; - static void test_all (std::vector& values, bool splay); - static void test_sort(std::vector& values, bool splay); - static void test_insert(std::vector& values, bool splay); - static void test_swap(std::vector& values, bool splay); - static void test_find(std::vector& values, bool splay); - static void test_splay_up(std::vector& values); - static void test_splay_down(std::vector& values); - static void test_impl(bool splay); - static void test_clone(std::vector& values, bool splay); - static void test_container_from_end(std::vector& values, bool splay); + static const bool value = true; }; -template -void test_splay_multiset::test_all - (std::vector& values, bool splay) +template +struct has_rebalance > { - typedef typename ValueTraits::value_type value_type; - typedef splay_multiset - < value_type - , value_traits - , constant_time_size - > splay_multiset_type; - { - splay_multiset_type testset(values.begin(), values.end()); - test::test_container(testset); - testset.clear(); - testset.insert(values.begin(), values.end()); - test::test_common_unordered_and_associative_container(testset, values); - testset.clear(); - testset.insert(values.begin(), values.end()); - test::test_associative_container(testset, values); - testset.clear(); - testset.insert(values.begin(), values.end()); - test::test_non_unique_container(testset, values); - } - test_sort(values, splay); - test_insert(values, splay); - test_swap(values, splay); - test_find(values, splay); - test_splay_up(values); - test_splay_down(values); - test_impl(splay); - test_clone(values, splay); - test_container_from_end(values, splay); -} + static const bool value = true; +}; -//test case due to an error in tree implementation: -template -void test_splay_multiset::test_impl(bool splay) +}}} + +template< class ValueType + , class Option1 = boost::intrusive::none + , class Option2 = boost::intrusive::none + , class Option3 = boost::intrusive::none + > +struct GetContainer { - typedef typename ValueTraits::value_type value_type; - std::vector values (5); - for (int i = 0; i < 5; ++i) - values[i].value_ = i; - typedef typename ValueTraits::value_type value_type; - typedef splay_multiset - < value_type - , value_traits - , constant_time_size - > multiset_type; - - multiset_type testset; - for (int i = 0; i < 5; ++i) - testset.insert (values[i]); - - testset.erase (testset.iterator_to (values[0])); - testset.erase (testset.iterator_to (values[1])); - testset.insert (values[1]); - - testset.erase (testset.iterator_to (values[2])); - testset.erase (testset.iterator_to (values[3])); -} - -//test: constructor, iterator, clear, reverse_iterator, front, back, size: -template -void test_splay_multiset::test_sort -(std::vector& values, bool splay) -{ - typedef typename ValueTraits::value_type value_type; - typedef splay_multiset - < value_type - , value_traits - , constant_time_size - > multiset_type; - - multiset_type testset1 (values.begin(), values.end()); - { int init_values [] = { 1, 2, 2, 3, 4, 5 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); } - - testset1.clear(); - BOOST_TEST (testset1.empty()); - - typedef splay_multiset - - , value_traits - , constant_time_size - > multiset_type2; - multiset_type2 testset2 (&values[0], &values[0] + 6); - { int init_values [] = { 5, 3, 1, 4, 2, 2 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset2.rbegin() ); } - - BOOST_TEST (testset2.begin()->value_ == 2); - BOOST_TEST (testset2.rbegin()->value_ == 5); -} - -//test: insert, const_iterator, const_reverse_iterator, erase, iterator_to: -template -void test_splay_multiset::test_insert -(std::vector& values, bool splay) -{ - typedef typename ValueTraits::value_type value_type; - typedef splay_multiset - < value_type - , value_traits - , size_type - , constant_time_size - > multiset_type; - - multiset_type testset; - testset.insert(&values[0] + 2, &values[0] + 5); - { int init_values [] = { 1, 4, 5 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset.begin() ); } - - typename multiset_type::iterator i = testset.begin(); - BOOST_TEST (i->value_ == 1); - - i = testset.insert (i, values[0]); - BOOST_TEST (&*i == &values[0]); - - { int init_values [] = { 5, 4, 3, 1 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset.rbegin() ); } - - i = testset.iterator_to (values[2]); - BOOST_TEST (&*i == &values[2]); - - i = multiset_type::s_iterator_to (values[2]); - BOOST_TEST (&*i == &values[2]); - - testset.erase(i); - - { int init_values [] = { 1, 3, 5 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset.begin() ); } -} - -//test: insert (seq-version), swap, erase (seq-version), size: -template -void test_splay_multiset::test_swap -(std::vector& values, bool splay) -{ - typedef typename ValueTraits::value_type value_type; - typedef splay_multiset - < value_type - , value_traits - , size_type - , constant_time_size - > multiset_type; - multiset_type testset1 (&values[0], &values[0] + 2); - multiset_type testset2; - testset2.insert (&values[0] + 2, &values[0] + 6); - - { int init_values [] = { 1, 2, 4, 5 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset2.begin() ); } - { int init_values [] = { 2, 3 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); } - - testset1.swap (testset2); - - { int init_values [] = { 1, 2, 4, 5 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); } - { int init_values [] = { 2, 3 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset2.begin() ); } - - testset1.erase (testset1.iterator_to(values[5]), testset1.end()); - BOOST_TEST (testset1.size() == 1); - BOOST_TEST (&*testset1.begin() == &values[3]); -} - -template -void test_splay_multiset::test_splay_up -(std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef splay_multiset - < value_type - , value_traits - , size_type - , constant_time_size - > multiset_type; - typedef typename multiset_type::iterator iterator; - typedef std::multiset orig_multiset_t; - std::size_t num_values; - std::multiset original_testset (values.begin(), values.end()); - num_values = original_testset.size(); - - for(std::size_t i = 0; i != num_values; ++i){ - multiset_type testset (values.begin(), values.end()); - { - iterator it = testset.begin(); - for(std::size_t j = 0; j != i; ++j, ++it){} - testset.splay_up(it); - } - BOOST_TEST (testset.size() == num_values); - iterator it = testset.begin(); - for( typename orig_multiset_t::const_iterator origit = original_testset.begin() - , origitend = original_testset.end() - ; origit != origitend - ; ++origit, ++it){ - BOOST_TEST(*origit == *it); - } - } -} - -template -void test_splay_multiset::test_splay_down -(std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef splay_multiset - < value_type - , value_traits - , size_type - , constant_time_size - > multiset_type; - typedef typename multiset_type::iterator iterator; - typedef std::multiset orig_multiset_t; - std::size_t num_values; - std::multiset original_testset (values.begin(), values.end()); - num_values = original_testset.size(); - - for(std::size_t i = 0; i != num_values; ++i){ - multiset_type testset (values.begin(), values.end()); - { - iterator it = testset.begin(); - for(std::size_t j = 0; j != i; ++j, ++it){} - BOOST_TEST(*it == *testset.splay_down(*it)); - } - BOOST_TEST (testset.size() == num_values); - iterator it = testset.begin(); - for( typename orig_multiset_t::const_iterator origit = original_testset.begin() - , origitend = original_testset.end() - ; origit != origitend - ; ++origit, ++it){ - BOOST_TEST(*origit == *it); - } - } -} - -//test: find, equal_range (lower_bound, upper_bound): -template -void test_splay_multiset::test_find -(std::vector& values, bool splay) -{ - typedef typename ValueTraits::value_type value_type; - typedef splay_multiset - < value_type - , value_traits - , size_type - , constant_time_size - > multiset_type; - multiset_type testset (values.begin(), values.end()); - typedef typename multiset_type::iterator iterator; - - value_type cmp_val; - cmp_val.value_ = 2; - iterator i = testset.find (cmp_val); - BOOST_TEST (i->value_ == 2); - BOOST_TEST ((++i)->value_ == 2); - std::pair range = testset.equal_range (cmp_val); - - BOOST_TEST (range.first->value_ == 2); - BOOST_TEST (range.second->value_ == 3); - BOOST_TEST (std::distance (range.first, range.second) == 2); - - cmp_val.value_ = 7; - BOOST_TEST (testset.find (cmp_val) == testset.end()); -} - -template -void test_splay_multiset::test_clone - (std::vector& values, bool splay) -{ - typedef typename ValueTraits::value_type value_type; - typedef splay_multiset - < value_type - , value_traits - , size_type - , constant_time_size - > multiset_type; - multiset_type testmultiset1 (&values[0], &values[0] + values.size()); - multiset_type testmultiset2; - - testmultiset2.clone_from(testmultiset1, test::new_cloner(), test::delete_disposer()); - BOOST_TEST (testmultiset2 == testmultiset1); - testmultiset2.clear_and_dispose(test::delete_disposer()); - BOOST_TEST (testmultiset2.empty()); -} - -template -void test_splay_multiset::test_container_from_end - (std::vector& values, bool splay) -{ - typedef typename ValueTraits::value_type value_type; - typedef splay_multiset - < value_type - , value_traits - , size_type - , constant_time_size - > multiset_type; - - multiset_type testmultiset (&values[0], &values[0] + values.size()); - BOOST_TEST (testmultiset == multiset_type::container_from_end_iterator(testmultiset.end())); - BOOST_TEST (testmultiset == multiset_type::container_from_end_iterator(testmultiset.cend())); -} + typedef boost::intrusive::splay_multiset + < ValueType + , Option1 + , Option2 + , Option3 + > type; +}; template class test_main_template @@ -359,27 +60,24 @@ class test_main_template public: int operator()() { - for(int n = 0; n < 2; ++n){ - typedef testvalue value_type; - static const int random_init[6] = { 3, 2, 4, 1, 5, 2 }; - std::vector > data (6); - for (int i = 0; i < 6; ++i) - data[i].value_ = random_init[i]; + using namespace boost::intrusive; + typedef testvalue value_type; - test_splay_multiset < typename detail::get_base_value_traits - < value_type - , typename value_type::splay_set_base_hook_t - >::type - >::test_all(data, 0 != (n%2)); - test_splay_multiset < typename detail::get_member_value_traits - < value_type - , member_hook< value_type - , typename value_type::splay_set_member_hook_t - , &value_type::splay_set_node_ - > - >::type - >::test_all(data, 0 != (n%2)); - } + test::test_generic_multiset < typename detail::get_base_value_traits + < value_type + , typename value_type::splay_set_base_hook_t + >::type + , GetContainer + >::test_all(); + test::test_generic_multiset < typename detail::get_member_value_traits + < value_type + , member_hook< value_type + , typename value_type::splay_set_member_hook_t + , &value_type::splay_set_node_ + > + >::type + , GetContainer + >::test_all(); return 0; } }; @@ -390,80 +88,51 @@ class test_main_template public: int operator()() { - for(int n = 0; n < 2; ++n){ - typedef testvalue value_type; - static const int random_init[6] = { 3, 2, 4, 1, 5, 2 }; - std::vector > data (6); - for (int i = 0; i < 6; ++i) - data[i].value_ = random_init[i]; + using namespace boost::intrusive; + typedef testvalue value_type; - test_splay_multiset < typename detail::get_base_value_traits - < value_type - , typename value_type::splay_set_base_hook_t - >::type - >::test_all(data, 0 != (n%2)); + test::test_generic_multiset < typename detail::get_base_value_traits + < value_type + , typename value_type::splay_set_base_hook_t + >::type + , GetContainer + >::test_all(); - test_splay_multiset < typename detail::get_member_value_traits - < value_type - , member_hook< value_type - , typename value_type::splay_set_member_hook_t - , &value_type::splay_set_node_ - > - >::type - >::test_all(data, 0 != (n%2)); + test::test_generic_multiset < typename detail::get_member_value_traits + < value_type + , member_hook< value_type + , typename value_type::splay_set_member_hook_t + , &value_type::splay_set_node_ + > + >::type + , GetContainer + >::test_all(); - test_splay_multiset < typename detail::get_base_value_traits - < value_type - , typename value_type::splay_set_auto_base_hook_t - >::type - >::test_all(data, 0 != (n%2)); + test::test_generic_multiset < typename detail::get_base_value_traits + < value_type + , typename value_type::splay_set_auto_base_hook_t + >::type + , GetContainer + >::test_all(); - test_splay_multiset < typename detail::get_member_value_traits - < value_type - , member_hook< value_type - , typename value_type::splay_set_auto_member_hook_t - , &value_type::splay_set_auto_node_ - > - >::type - >::test_all(data, 0 != (n%2)); - } + test::test_generic_multiset < typename detail::get_member_value_traits + < value_type + , member_hook< value_type + , typename value_type::splay_set_auto_member_hook_t + , &value_type::splay_set_auto_node_ + > + >::type + , GetContainer + >::test_all(); return 0; } }; -//Explicit instantiations of non-counted classes -//template class multiset -// , false>; -//template class multiset -// , false>; -//template class multiset -// , false>; -//template class multiset -// , false>; -//template class multiset -// , false>; -//template class multiset -// , false>; -//template class multiset -// , false>; -//template class multiset -// , false>; - -//Explicit instantiation of counted classes -//template class multiset -// , true>; -//template class multiset -// , true>; -//template class multiset -// , true>; -//template class multiset -// , true>; - int main( int, char* [] ) { test_main_template()(); - test_main_template, false>()(); + test_main_template, false>()(); test_main_template()(); - test_main_template, true>()(); + test_main_template, true>()(); return boost::report_errors(); } diff --git a/test/splay_set_test.cpp b/test/splay_set_test.cpp index 3c7a53c..b18b4e7 100644 --- a/test/splay_set_test.cpp +++ b/test/splay_set_test.cpp @@ -11,15 +11,9 @@ ///////////////////////////////////////////////////////////////////////////// #include #include -#include #include "itestvalue.hpp" #include "smart_ptr.hpp" -#include "common_functors.hpp" -#include -#include -#include "test_macros.hpp" -#include "test_container.hpp" -#include +#include "generic_set_test.hpp" namespace boost { namespace intrusive { namespace test { @@ -29,315 +23,34 @@ struct has_const_overloads > static const bool value = false; }; -}}} - -using namespace boost::intrusive; - -template -struct test_splay_set +template +struct has_splay > { - typedef typename ValueTraits::value_type value_type; - static void test_all(std::vector& values); - static void test_sort(std::vector& values); - static void test_insert(std::vector& values); - static void test_swap(std::vector& values); - static void test_find(std::vector& values); - static void test_splay_up(std::vector& values); - static void test_splay_down(std::vector& values); - static void test_impl(); - static void test_clone(std::vector& values); - static void test_container_from_end(std::vector& values); + static const bool value = true; }; -template -void test_splay_set::test_all(std::vector& values) +template +struct has_rebalance > { - typedef typename ValueTraits::value_type value_type; - typedef splay_set - < value_type - , value_traits - , constant_time_size - > splay_set_type; - { - splay_set_type testset(values.begin(), values.end()); - test::test_container(testset); - testset.clear(); - testset.insert(values.begin(), values.end()); - test::test_common_unordered_and_associative_container(testset, values); - testset.clear(); - testset.insert(values.begin(), values.end()); - test::test_associative_container(testset, values); - testset.clear(); - testset.insert(values.begin(), values.end()); - test::test_unique_container(testset, values); - } + static const bool value = true; +}; - test_sort(values); - test_insert(values); - test_swap(values); - test_find(values); - test_splay_up(values); - test_splay_down(values); - test_impl(); - test_clone(values); - test_container_from_end(values); -} +}}} -//test case due to an error in tree implementation: -template -void test_splay_set::test_impl() +template< class ValueType + , class Option1 = boost::intrusive::none + , class Option2 = boost::intrusive::none + , class Option3 = boost::intrusive::none + > +struct GetContainer { - typedef typename ValueTraits::value_type value_type; - std::vector values (5); - for (int i = 0; i < 5; ++i) - values[i].value_ = i; - - typedef typename ValueTraits::value_type value_type; - typedef splay_set - < value_type - , value_traits - , constant_time_size - > splay_set_type; - splay_set_type testset; - for (int i = 0; i < 5; ++i) - testset.insert (values[i]); - - testset.erase (testset.iterator_to (values[0])); - testset.erase (testset.iterator_to (values[1])); - testset.insert (values[1]); - - testset.erase (testset.iterator_to (values[2])); - testset.erase (testset.iterator_to (values[3])); -} - -//test: constructor, iterator, clear, reverse_iterator, front, back, size: -template -void test_splay_set::test_sort(std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef splay_set - < value_type - , value_traits - , constant_time_size - > splay_set_type; - splay_set_type testset1 (values.begin(), values.end()); - { int init_values [] = { 1, 2, 3, 4, 5 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); } - - testset1.clear(); - BOOST_TEST (testset1.empty()); - - typedef typename ValueTraits::value_type value_type; - typedef splay_set - < value_type - , compare - , value_traits - , constant_time_size - > set_type2; - set_type2 testset2 (&values[0], &values[0] + 6); - { int init_values [] = { 5, 3, 1, 4, 2 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset2.rbegin() ); } - BOOST_TEST (testset2.begin()->value_ == 2); - BOOST_TEST (testset2.rbegin()->value_ == 5); -} - -//test: insert, const_iterator, const_reverse_iterator, erase, s_iterator_to: -template -void test_splay_set::test_insert(std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef splay_set - < value_type - , value_traits - , constant_time_size - > splay_set_type; - splay_set_type testset; - testset.insert(&values[0] + 2, &values[0] + 5); - - const splay_set_type& const_testset = testset; - { int init_values [] = { 1, 4, 5 }; - TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); } - - typename splay_set_type::iterator i = testset.begin(); - BOOST_TEST (i->value_ == 1); - - i = testset.insert (i, values[0]); - BOOST_TEST (&*i == &values[0]); - - { int init_values [] = { 5, 4, 3, 1 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset.rbegin() ); } - - i = testset.iterator_to (values[2]); - BOOST_TEST (&*i == &values[2]); - - i = splay_set_type::s_iterator_to(values[2]); - BOOST_TEST (&*i == &values[2]); - - testset.erase (i); - { int init_values [] = { 1, 3, 5 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset.begin() ); } -} - -//test: insert (seq-version), swap, erase (seq-version), size: -template -void test_splay_set::test_swap(std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef splay_set - < value_type - , value_traits - , constant_time_size - > splay_set_type; - splay_set_type testset1 (&values[0], &values[0] + 2); - splay_set_type testset2; - testset2.insert (&values[0] + 2, &values[0] + 6); - testset1.swap (testset2); - - { int init_values [] = { 1, 2, 4, 5 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); } - - { int init_values [] = { 2, 3 }; - TEST_INTRUSIVE_SEQUENCE( init_values, testset2.begin() ); } - - testset1.erase (testset1.iterator_to(values[5]), testset1.end()); - BOOST_TEST (testset1.size() == 1); - // BOOST_TEST (&testset1.front() == &values[3]); - BOOST_TEST (&*testset1.begin() == &values[3]); -} - -template -void test_splay_set::test_splay_up -(std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef splay_set - < value_type - , value_traits - , size_type - , constant_time_size - > set_type; - typedef typename set_type::iterator iterator; - typedef std::set orig_set_t; - std::size_t num_values; - std::set original_testset (values.begin(), values.end()); - num_values = original_testset.size(); - - for(std::size_t i = 0; i != num_values; ++i){ - set_type testset (values.begin(), values.end()); - { - iterator it = testset.begin(); - for(std::size_t j = 0; j != i; ++j, ++it){} - testset.splay_up(it); - } - BOOST_TEST (testset.size() == num_values); - iterator it = testset.begin(); - for( typename orig_set_t::const_iterator origit = original_testset.begin() - , origitend = original_testset.end() - ; origit != origitend - ; ++origit, ++it){ - BOOST_TEST(*origit == *it); - } - } -} - -template -void test_splay_set::test_splay_down -(std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef splay_set - < value_type - , value_traits - , size_type - , constant_time_size - > set_type; - typedef typename set_type::iterator iterator; - typedef std::set orig_set_t; - std::size_t num_values; - std::set original_testset (values.begin(), values.end()); - num_values = original_testset.size(); - - for(std::size_t i = 0; i != num_values; ++i){ - set_type testset (values.begin(), values.end()); - BOOST_TEST(testset.size() == num_values); - { - iterator it = testset.begin(); - for(std::size_t j = 0; j != i; ++j, ++it){} - BOOST_TEST(*it == *testset.splay_down(*it)); - } - BOOST_TEST (testset.size() == num_values); - iterator it = testset.begin(); - for( typename orig_set_t::const_iterator origit = original_testset.begin() - , origitend = original_testset.end() - ; origit != origitend - ; ++origit, ++it){ - BOOST_TEST(*origit == *it); - } - } -} - -//test: find, equal_range (lower_bound, upper_bound): -template -void test_splay_set::test_find(std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef splay_set - < value_type - , value_traits - , constant_time_size - > splay_set_type; - splay_set_type testset (values.begin(), values.end()); - typedef typename splay_set_type::iterator iterator; - - value_type cmp_val; - cmp_val.value_ = 2; - iterator i = testset.find (cmp_val); - BOOST_TEST (i->value_ == 2); - BOOST_TEST ((++i)->value_ != 2); - std::pair range = testset.equal_range (cmp_val); - - BOOST_TEST (range.first->value_ == 2); - BOOST_TEST (range.second->value_ == 3); - BOOST_TEST (std::distance (range.first, range.second) == 1); - - cmp_val.value_ = 7; - BOOST_TEST (testset.find (cmp_val) == testset.end()); -} - -template -void test_splay_set - ::test_clone(std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef splay_set - < value_type - , value_traits - , constant_time_size - > splay_set_type; - - splay_set_type testset1 (&values[0], &values[0] + values.size()); - splay_set_type testset2; - - testset2.clone_from(testset1, test::new_cloner(), test::delete_disposer()); - BOOST_TEST (testset2 == testset1); - testset2.clear_and_dispose(test::delete_disposer()); - BOOST_TEST (testset2.empty()); -} - -template -void test_splay_set - ::test_container_from_end(std::vector& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef splay_set - < value_type - , value_traits - , constant_time_size - > splay_set_type; - splay_set_type testset (&values[0], &values[0] + values.size()); - BOOST_TEST (testset == splay_set_type::container_from_end_iterator(testset.end())); - BOOST_TEST (testset == splay_set_type::container_from_end_iterator(testset.cend())); -} + typedef boost::intrusive::splay_set + < ValueType + , Option1 + , Option2 + , Option3 + > type; +}; template class test_main_template @@ -345,25 +58,24 @@ class test_main_template public: int operator()() { + using namespace boost::intrusive; typedef testvalue value_type; - static const int random_init[6] = { 3, 2, 4, 1, 5, 2 }; - std::vector > data (6); - for (int i = 0; i < 6; ++i) - data[i].value_ = random_init[i]; - test_splay_set < typename detail::get_base_value_traits + test::test_generic_set < typename detail::get_base_value_traits < value_type , typename value_type::splay_set_base_hook_t >::type - >::test_all(data); - test_splay_set < typename detail::get_member_value_traits + , GetContainer + >::test_all(); + test::test_generic_set < typename detail::get_member_value_traits < value_type , member_hook< value_type , typename value_type::splay_set_member_hook_t , &value_type::splay_set_node_ > >::type - >::test_all(data); + , GetContainer + >::test_all(); return 0; } }; @@ -374,41 +86,42 @@ class test_main_template public: int operator()() { + using namespace boost::intrusive; typedef testvalue value_type; - static const int random_init[6] = { 3, 2, 4, 1, 5, 2 }; - std::vector > data (6); - for (int i = 0; i < 6; ++i) - data[i].value_ = random_init[i]; - test_splay_set < typename detail::get_base_value_traits + test::test_generic_set < typename detail::get_base_value_traits < value_type , typename value_type::splay_set_base_hook_t >::type - >::test_all(data); + , GetContainer + >::test_all(); - test_splay_set < typename detail::get_member_value_traits + test::test_generic_set < typename detail::get_member_value_traits < value_type , member_hook< value_type , typename value_type::splay_set_member_hook_t , &value_type::splay_set_node_ > >::type - >::test_all(data); + , GetContainer + >::test_all(); - test_splay_set < typename detail::get_base_value_traits + test::test_generic_set < typename detail::get_base_value_traits < value_type , typename value_type::splay_set_auto_base_hook_t >::type - >::test_all(data); + , GetContainer + >::test_all(); - test_splay_set < typename detail::get_member_value_traits + test::test_generic_set < typename detail::get_member_value_traits < value_type , member_hook< value_type , typename value_type::splay_set_auto_member_hook_t , &value_type::splay_set_auto_node_ > >::type - >::test_all(data); + , GetContainer + >::test_all(); return 0; } @@ -417,9 +130,9 @@ class test_main_template int main( int, char* [] ) { test_main_template()(); - test_main_template, false>()(); + test_main_template, false>()(); test_main_template()(); - test_main_template, true>()(); + test_main_template, true>()(); return boost::report_errors(); } #include diff --git a/test/stateful_value_traits_test.cpp b/test/stateful_value_traits_test.cpp index d544ac0..aca8cb3 100644 --- a/test/stateful_value_traits_test.cpp +++ b/test/stateful_value_traits_test.cpp @@ -117,8 +117,7 @@ int main() , slist_traits(values, uset_hook_array) ); - //Now insert them in the reverse order - //in the base hook intrusive list + //Now insert them in containers for(MyClass * it(&values[0]), *itend(&values[NumElements]) ; it != itend ; ++it){ diff --git a/test/test_container.hpp b/test/test_container.hpp index 4e8c4ff..9ae000a 100644 --- a/test/test_container.hpp +++ b/test/test_container.hpp @@ -185,7 +185,7 @@ void test_associative_container_invariants(Container & c, Data & d, boost::intru } template< class Container, class Data > -void test_associative_container_invariants(Container & c, Data & d, boost::intrusive::detail::false_type) +void test_associative_container_invariants(Container &, Data &, boost::intrusive::detail::false_type) {} template< class Container, class Data > @@ -245,7 +245,7 @@ void test_unordered_associative_container_invariants(Container & c, Data & d, bo } template< class Container, class Data > -void test_unordered_associative_container_invariants(Container & c, Data & d, boost::intrusive::detail::false_type) +void test_unordered_associative_container_invariants(Container &, Data &, boost::intrusive::detail::false_type) {} template< class Container, class Data >