From e9cdb500d6e825b71dddfd487f50f16a114f1a1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Sat, 21 Jun 2008 09:06:15 +0000 Subject: [PATCH] gcc 4.3 fixes for normal and -std=c++0x modes [SVN r46573] --- doc/intrusive.qbk | 100 ++++++++++++++---- proj/vc7ide/Intrusive.sln | 8 ++ .../vc7ide/_intrusivelib/_intrusivelib.vcproj | 9 ++ proj/vc7ide/list/list.vcproj | 10 -- proj/vc7ide/multiset/multiset.vcproj | 10 -- proj/vc7ide/perf_test/perf_test.vcproj | 10 -- proj/vc7ide/set/set.vcproj | 10 -- proj/vc7ide/slist/slist.vcproj | 10 -- proj/vc7ide/to-do.txt | 43 ++++++-- .../unordered_multiset.vcproj | 10 -- .../vc7ide/unordered_set/unordered_set.vcproj | 10 -- test/common_functors.hpp | 8 ++ test/list_test.cpp | 1 + test/slist_test.cpp | 2 +- test/unordered_multiset_test.cpp | 48 ++++++--- test/unordered_set_test.cpp | 48 ++++++--- 16 files changed, 201 insertions(+), 136 deletions(-) diff --git a/doc/intrusive.qbk b/doc/intrusive.qbk index cf1f5e6..2b410ed 100644 --- a/doc/intrusive.qbk +++ b/doc/intrusive.qbk @@ -127,7 +127,7 @@ way to make user classes compatible with those containers. [section:properties_of_intrusive Properties of Boost.Intrusive containers] -Semantically, a [*Boost.Intrusive] container is similar to an STL container +Semantically, a [*Boost.Intrusive] container is similar to a STL container holding pointers to objects. That is, if you have an intrusive list holding objects of type `T`, then `std::list` would allow you to do quite the same operations (maintaining and navigating a set of objects of type T and @@ -584,7 +584,7 @@ Apart from that, [*Boost.Intrusive] offers additional features: safe state and intrusive containers check that state before inserting a value in the container. When erasing an element from the container, the container puts the hook in the safe state again. This allows a safer use mode and it can be used to detect - programming errors. It implies an slight performance overhead in some operations + programming errors. It implies a slight performance overhead in some operations and can convert some constant time operations to linear time operations. * [*Auto-unlink hooks]: The hook destructor removes the object from the container @@ -596,7 +596,7 @@ Apart from that, [*Boost.Intrusive] offers additional features: be configured to use any type of pointer. This configuration information is also transmitted to the containers, so all the internal pointers used by intrusive containers configured with these hooks will be smart pointers. As an example, - [*Boost.Interprocess] defines an smart pointer compatible with shared memory, + [*Boost.Interprocess] defines an mart pointer compatible with shared memory, called `offset_ptr`. [*Boost.Intrusive] can be configured to use this smart pointer to allow shared memory intrusive containers. @@ -718,7 +718,7 @@ Let's see an example of an auto-unlink hook: As explained, [*Boost.Intrusive] auto-unlink hooks are incompatible with containers that have constant-time `size()`, so if you try to define such container with an -auto-unlink hook's value_traits, you will get an static assertion: +auto-unlink hook's value_traits, you will get a static assertion: [c++] @@ -860,7 +860,7 @@ assertion will be raised. [section:slist_example Example] -Now let's see an small example using both hooks: +Now let's see a small example using both hooks: [import ../example/doc_slist.cpp] [doc_slist_code] @@ -946,7 +946,7 @@ the section [link intrusive.usage How to use Boost.Intrusive]: [section:list_example Example] -Now let's see an small example using both hooks: +Now let's see a small example using both hooks: [import ../example/doc_list.cpp] [doc_list_code] @@ -1075,7 +1075,7 @@ And they also can receive an additional option: [section:set_multiset_example Example] -Now let's see an small example using both hooks and both containers: +Now let's see a small example using both hooks and both containers: [import ../example/doc_set.cpp] [doc_set_code] @@ -1277,11 +1277,22 @@ And they also can receive additional options: of the first element. This imposes the overhead of one pointer to the size of the container. Default: `cache_begin`. +* [*`compare_hash`]: + [*Note: this option requires `store_hash` option in the hook]. + When the comparison function is expensive, + (e.g. strings with a long common predicate) sometimes (specially when the + load factor is high or we have many equivalent elements in an + [classref boost::intrusive::unordered_multiset unordered_multiset] and + no `optimize_multikey<>` is activatedin the hook) + the equality function is a performance problem. Two equal values must have + equal hashes, so comparing the hash values of two elements before using the + comparison functor can speed up some implementations. + [endsect] [section:unordered_set_unordered_multiset_example Example] -Now let's see an small example using both hooks and both containers: +Now let's see a small example using both hooks and both containers: [import ../example/doc_unordered_set.cpp] [doc_unordered_set_code] @@ -1450,9 +1461,9 @@ intrusive scapegoat containers [classref boost::intrusive::sg_set sg_set] and [classref boost::intrusive::sg_multiset sg_multiset]. A programmer might prefer using a binary search tree hook so that the same type -can be inserted in some situations in an splay container but +can be inserted in some situations in a splay container but also inserted in other compatible containers when -the hook is not being used in an splay container. +the hook is not being used in a 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 @@ -1462,7 +1473,7 @@ the same options as [classref boost::intrusive::splay_set_base_hook splay_set_ba [section:splay_set_multiset_example Example] -Now let's see an small example using both splay hooks, +Now let's see a 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] @@ -1590,7 +1601,7 @@ And they also can receive an additional option: [section:avl_set_multiset_example Example] -Now let's see an small example using both hooks and +Now let's see a small example using both hooks and [classref boost::intrusive::avl_set avl_set]/ [classref boost::intrusive::avl_multiset avl_multiset] containers: @@ -1745,7 +1756,7 @@ And they also can receive additional options: [section:sg_set_multiset_example Example] -Now let's see an small example using both hooks and +Now let's see a small example using both hooks and [classref boost::intrusive::sg_set sg_set]/ [classref boost::intrusive::sg_multiset sg_multiset] containers: @@ -1923,7 +1934,7 @@ more functions taking a disposer function object as argument, like `erase_and_di Note that the disposing function does not need to just destroy the object. It can implement any other operation like inserting the remove object in another container. -Let's see an small example: +Let's see a small example: [import ../example/doc_erasing_and_disposing.cpp] [doc_erasing_and_disposing] @@ -1940,11 +1951,11 @@ that erase an element from the container. As previously mentioned, [*Boost.Intrusive] containers are [*non-copyable and non-assignable], because intrusive containers don't allocate memory at all. To implement a copy-constructor or assignment operator, the user must clone one by one all the elements of the container and insert them in another intrusive container. -However, cloning by hand is usually more inefficient than a member cloning function and an specialized cloning +However, cloning by hand is usually more inefficient than a member cloning function and a specialized cloning function can offer more guarantees than the manual cloning (better exception safety guarantees, for example). To ease the implementation of copy constructors and assignment operators of classes containing [*Boost.Intrusive] -containers, all [*Boost.Intrusive] containers offer an special cloning function called `clone_from`. +containers, all [*Boost.Intrusive] containers offer a special cloning function called `clone_from`. Apart from the container to be cloned, `clone_from` takes two function objects as arguments. For example, consider the `clone_from` member function of [classref boost::intrusive::list list]: @@ -1981,9 +1992,9 @@ Here's an example of `clone_from`: [section:using_smart_pointers Using smart pointers with Boost.Intrusive containers] [*Boost.Intrusive] hooks can be configured to use other pointers than raw pointers. -When a [*Boost.Intrusive] hook is configured with an smart pointer as an argument, +When a [*Boost.Intrusive] hook is configured with a smart pointer as an argument, this pointer configuration is passed to the containers. For example, if the following -hook is configured with an smart pointer (for example, an offset pointer from +hook is configured with a smart pointer (for example, an offset pointer from [*Boost.Interprocess]): [import ../example/doc_offset_ptr.cpp] @@ -2060,7 +2071,7 @@ explained in the [link intrusive.value_traits.stateful_value_traits Stateful val if the programmer uses hooks provided by [*Boost.Intrusive], those functions will be available. -Let's see an small function that shows the use of `iterator_to` and +Let's see a small function that shows the use of `iterator_to` and `local_iterator_to`: [import ../example/doc_iterator_from_value.cpp] @@ -2068,6 +2079,51 @@ Let's see an small function that shows the use of `iterator_to` and [endsect] +[section:any_hooks Any Hooks: A single hook for any Intrusive container] + +Sometimes, a class programmer wants to place a class in several intrusive +containers but no at the same time. In this case, the programmer might +decide to insert two hooks in the same class. + +[c++] + + class MyClass + : public list_base_hook<>, public slist_base_hook<> //... + {}; + +However, there is a more size-efficient alternative in [*Boost.Intrusive]: "any" hooks +([classref boost::intrusive::any_base_hook any_base_hook] and +[classref boost::intrusive::any_member_hook any_member_hook]. +These hooks can be used to store a type in several containers +offered by [*Boost.Intrusive] minimizing the size of the class. + +These hooks support these options: + +* [*`tag`] (for base hooks only): This argument serves as a tag, + so you can derive from more than one slist hook. + Default: `tag`. + +* [*`link_mode`]: The linking policy. + `link_mode` is [*not] supported and `link_mode` + might offer weaker error detection in any hooks than in other hooks. + Default: `link_mode`. + +* [*`void_pointer`]: The pointer type to be used + internally in the hook and propagated to the container. + Default: `void_pointer`. + +`auto_unlink` can't be supported because the hook does not know in which type of might +be inserted container. Additionally, these hooks don't support `unlink()` and +`swap_nodes()` operations for the same reason. + +Here's an example that creates a class with two any hooks, and uses one to insert the +class in a [classref slist] and the other one in a [classref list]. + +[import ../example/doc_any_hook.cpp] +[doc_any_hook] + +[endsect] + [section:concepts Concepts explained] This section will expand the explanation of previously presented basic concepts @@ -2187,7 +2243,7 @@ before explaining the customization options of [*Boost.Intrusive]. int value_; }; -* [*Intrusive Container]: A container that offers an STL-like interface to store +* [*Intrusive Container]: A container that offers a STL-like interface to store user objects. An intrusive container can be templatized to store different value types that use different hooks. An intrusive container is also more elaborate than a group of nodes: it can store the number of elements to achieve constant-time @@ -2642,7 +2698,7 @@ used in node algorithms, since these types can be different. Apart from this, Instead of using [*Boost.Intrusive] predefined hooks a user might want to develop customized containers, for example, using nodes that are -optimized for an specific +optimized for a specific application or that are compatible with a a legacy ABI. A user might want to have only two additional pointers in his class and insert the class in a doubly linked list sometimes and in a singly linked list in other situations. You can't @@ -2804,7 +2860,7 @@ In the previous example, `legacy_node_traits::node` type and to have several `ValueTraits` defining the same `node_traits` type (and thus, the same `node_traits::node`). This reduces the number of node algorithm instantiations, but now `ValueTraits::to_node_ptr` and `ValueTraits::to_value_ptr` functions need to offer -conversions between both types. Let's see an small example: +conversions between both types. Let's see a small example: First, we'll define the node to be used in the algorithms. For a linked list, we just need a node that stores two pointers: diff --git a/proj/vc7ide/Intrusive.sln b/proj/vc7ide/Intrusive.sln index 4fb0638..0b105c0 100644 --- a/proj/vc7ide/Intrusive.sln +++ b/proj/vc7ide/Intrusive.sln @@ -79,6 +79,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sg_set", "sg_set\sg_set.vcp ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "any_hook", "any_test\any_test.vcproj", "{97B61B24-4C97-9681-50BF-243175A813B6}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug @@ -167,6 +171,10 @@ Global {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 + {97B61B24-4C97-9681-50BF-243175A813B6}.Debug.ActiveCfg = Debug|Win32 + {97B61B24-4C97-9681-50BF-243175A813B6}.Debug.Build.0 = Debug|Win32 + {97B61B24-4C97-9681-50BF-243175A813B6}.Release.ActiveCfg = Release|Win32 + {97B61B24-4C97-9681-50BF-243175A813B6}.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 6dd0c3f..b42d957 100644 --- a/proj/vc7ide/_intrusivelib/_intrusivelib.vcproj +++ b/proj/vc7ide/_intrusivelib/_intrusivelib.vcproj @@ -105,6 +105,9 @@ Name="Header Files" Filter="h;hpp;hxx;hm;inl;inc;xsd" UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"> + + @@ -207,6 +210,9 @@ + + @@ -316,6 +322,9 @@ + + diff --git a/proj/vc7ide/list/list.vcproj b/proj/vc7ide/list/list.vcproj index 17c3b6a..e5e510b 100644 --- a/proj/vc7ide/list/list.vcproj +++ b/proj/vc7ide/list/list.vcproj @@ -127,16 +127,6 @@ RelativePath="..\..\..\test\list_test.cpp"> - - - - diff --git a/proj/vc7ide/multiset/multiset.vcproj b/proj/vc7ide/multiset/multiset.vcproj index 4303b0c..8828607 100644 --- a/proj/vc7ide/multiset/multiset.vcproj +++ b/proj/vc7ide/multiset/multiset.vcproj @@ -121,16 +121,6 @@ RelativePath="..\..\..\test\multiset_test.cpp"> - - - - diff --git a/proj/vc7ide/perf_test/perf_test.vcproj b/proj/vc7ide/perf_test/perf_test.vcproj index e94844d..5e410b1 100644 --- a/proj/vc7ide/perf_test/perf_test.vcproj +++ b/proj/vc7ide/perf_test/perf_test.vcproj @@ -122,16 +122,6 @@ RelativePath="..\..\..\perf\perf_list.cpp"> - - - - diff --git a/proj/vc7ide/set/set.vcproj b/proj/vc7ide/set/set.vcproj index 6e96cd2..85dff59 100644 --- a/proj/vc7ide/set/set.vcproj +++ b/proj/vc7ide/set/set.vcproj @@ -121,16 +121,6 @@ RelativePath="..\..\..\test\set_test.cpp"> - - - - diff --git a/proj/vc7ide/slist/slist.vcproj b/proj/vc7ide/slist/slist.vcproj index d9138b2..3d118f5 100644 --- a/proj/vc7ide/slist/slist.vcproj +++ b/proj/vc7ide/slist/slist.vcproj @@ -121,16 +121,6 @@ RelativePath="..\..\..\test\slist_test.cpp"> - - - - diff --git a/proj/vc7ide/to-do.txt b/proj/vc7ide/to-do.txt index 3428e61..747f679 100644 --- a/proj/vc7ide/to-do.txt +++ b/proj/vc7ide/to-do.txt @@ -1,12 +1,37 @@ -Add resize() to list -Implement incremental hashing -Add invariants to slist and test them after every operation -Create a generic hook that will work with all containers -Take advantage of store_hash in lookups: Instead of comparing objects, just - compare hashes. This will improve equality for expensive objects. +Implement incremental hashing: -Improve the use of cache_begin to unordered containers: --> Speed up rehash +bucket_len is power of two +cur_idx is always at least, half of bucket_len + +find bucket from value: + size_type bucket_num = hash(val) &(bucket_len - 1); + if (bucket_num >= cur_idx) + bucket_num -= bucket_len/2; + +incremental_rehash: + + iterator _Plist, _Where; + if (load_factor > LoadFactorLimit) + { // too dense, need to grow hash table + if (cur_idx >= (bucket_len - 1)) + { // table full, request doubling + return false; + } + else if (cur_idx >= bucket_len) + bucket_len*=2; + + size_type bucket_num = cur_idx - bucket_len/2; + // rehash elements from bucket_num + ++cur_idx; + } + +insert from value: + + size_type bucket_num = hash(val) & (bucket_len - 1); + if (bucket_num >= cur_idx) + bucket_num -= bucket_len/2; + insert in bucket + +rehash: -Add erase(iterator, iterator, difference_type) to lists to obtain constant-time erase. diff --git a/proj/vc7ide/unordered_multiset/unordered_multiset.vcproj b/proj/vc7ide/unordered_multiset/unordered_multiset.vcproj index 2b9c6f3..2559e0c 100644 --- a/proj/vc7ide/unordered_multiset/unordered_multiset.vcproj +++ b/proj/vc7ide/unordered_multiset/unordered_multiset.vcproj @@ -122,16 +122,6 @@ RelativePath="..\..\..\test\unordered_multiset_test.cpp"> - - - - diff --git a/proj/vc7ide/unordered_set/unordered_set.vcproj b/proj/vc7ide/unordered_set/unordered_set.vcproj index 33c95ac..b7e9681 100644 --- a/proj/vc7ide/unordered_set/unordered_set.vcproj +++ b/proj/vc7ide/unordered_set/unordered_set.vcproj @@ -121,16 +121,6 @@ RelativePath="..\..\..\test\unordered_set_test.cpp"> - - - - diff --git a/test/common_functors.hpp b/test/common_functors.hpp index 7a6d500..d3bc3fa 100644 --- a/test/common_functors.hpp +++ b/test/common_functors.hpp @@ -41,6 +41,14 @@ class new_cloner { return new T(t); } }; +template +class new_default_factory +{ + public: + T *operator()() + { return new T(); } +}; + } //namespace test { } //namespace intrusive { } //namespace boost { diff --git a/test/list_test.cpp b/test/list_test.cpp index 3a000a9..37998be 100644 --- a/test/list_test.cpp +++ b/test/list_test.cpp @@ -229,6 +229,7 @@ void test_list TEST_INTRUSIVE_SEQUENCE( init_values, const_testlist.begin() ); } } + template void test_list ::test_shift(std::vector& values) diff --git a/test/slist_test.cpp b/test/slist_test.cpp index c8055c1..7ca0afc 100644 --- a/test/slist_test.cpp +++ b/test/slist_test.cpp @@ -315,7 +315,7 @@ void test_slist testlist.erase (++testlist.begin(), testlist.end()); BOOST_TEST (testlist.size() == 1); BOOST_TEST (testlist.front().value_ == 3); -} +} template void test_slist diff --git a/test/unordered_multiset_test.cpp b/test/unordered_multiset_test.cpp index dda1ad3..e10efd2 100644 --- a/test/unordered_multiset_test.cpp +++ b/test/unordered_multiset_test.cpp @@ -27,7 +27,7 @@ using namespace boost::intrusive; static const std::size_t BucketSize = 11; -template +template struct test_unordered_multiset { typedef typename ValueTraits::value_type value_type; @@ -41,8 +41,8 @@ struct test_unordered_multiset static void test_clone(std::vector& values); }; -template -void test_unordered_multiset::test_all (std::vector& values) +template +void test_unordered_multiset::test_all (std::vector& values) { typedef typename ValueTraits::value_type value_type; typedef unordered_multiset @@ -50,6 +50,7 @@ void test_unordered_multiset::test_all (std::vector , constant_time_size , cache_begin + , compare_hash > unordered_multiset_type; { typedef typename unordered_multiset_type::bucket_traits bucket_traits; @@ -77,8 +78,8 @@ void test_unordered_multiset::test_all (std::vector -void test_unordered_multiset::test_impl() +template +void test_unordered_multiset::test_impl() { typedef typename ValueTraits::value_type value_type; typedef unordered_multiset @@ -86,6 +87,7 @@ void test_unordered_multiset::test_impl() , value_traits , constant_time_size , cache_begin + , compare_hash > unordered_multiset_type; typedef typename unordered_multiset_type::bucket_traits bucket_traits; @@ -108,8 +110,8 @@ void test_unordered_multiset::test_impl() } //test: constructor, iterator, clear, reverse_iterator, front, back, size: -template -void test_unordered_multiset::test_sort(std::vector& values) +template +void test_unordered_multiset::test_sort(std::vector& values) { typedef typename ValueTraits::value_type value_type; typedef unordered_multiset @@ -117,6 +119,7 @@ void test_unordered_multiset::test_sort(std::vector , constant_time_size , cache_begin + , compare_hash > unordered_multiset_type; typedef typename unordered_multiset_type::bucket_traits bucket_traits; @@ -130,8 +133,8 @@ void test_unordered_multiset::test_sort(std::vector -void test_unordered_multiset::test_insert(std::vector& values) +template +void test_unordered_multiset::test_insert(std::vector& values) { typedef typename ValueTraits::value_type value_type; typedef unordered_multiset @@ -139,6 +142,7 @@ void test_unordered_multiset::test_insert(std::vector , constant_time_size , cache_begin + , compare_hash > unordered_multiset_type; typedef typename unordered_multiset_type::bucket_traits bucket_traits; typedef typename unordered_multiset_type::iterator iterator; @@ -269,8 +273,8 @@ void test_unordered_multiset::test_insert(std::vector -void test_unordered_multiset::test_swap(std::vector& values) +template +void test_unordered_multiset::test_swap(std::vector& values) { typedef typename ValueTraits::value_type value_type; typedef unordered_multiset @@ -278,6 +282,7 @@ void test_unordered_multiset::test_swap(std::vector , constant_time_size , cache_begin + , compare_hash > unordered_multiset_type; typedef typename unordered_multiset_type::bucket_traits bucket_traits; typename unordered_multiset_type::bucket_type buckets [BucketSize]; @@ -302,8 +307,8 @@ void test_unordered_multiset::test_swap(std::vector -void test_unordered_multiset::test_rehash(std::vector& values) +template +void test_unordered_multiset::test_rehash(std::vector& values) { typedef typename ValueTraits::value_type value_type; typedef unordered_multiset @@ -311,6 +316,7 @@ void test_unordered_multiset::test_rehash(std::vector , constant_time_size , cache_begin + , compare_hash > unordered_multiset_type; typedef typename unordered_multiset_type::bucket_traits bucket_traits; @@ -347,8 +353,8 @@ void test_unordered_multiset::test_rehash(std::vector -void test_unordered_multiset::test_find(std::vector& values) +template +void test_unordered_multiset::test_find(std::vector& values) { typedef typename ValueTraits::value_type value_type; typedef unordered_multiset @@ -356,6 +362,7 @@ void test_unordered_multiset::test_find(std::vector , constant_time_size , cache_begin + , compare_hash > unordered_multiset_type; typedef typename unordered_multiset_type::bucket_traits bucket_traits; @@ -380,8 +387,8 @@ void test_unordered_multiset::test_find(std::vector -void test_unordered_multiset +template +void test_unordered_multiset ::test_clone(std::vector& values) { typedef typename ValueTraits::value_type value_type; @@ -390,6 +397,7 @@ void test_unordered_multiset , value_traits , constant_time_size , cache_begin + , compare_hash > unordered_multiset_type; typedef typename unordered_multiset_type::bucket_traits bucket_traits; { @@ -462,6 +470,7 @@ class test_main_template , typename value_type::unordered_set_base_hook_t >::type , true + , false >::test_all(data); test_unordered_multiset < typename detail::get_member_value_traits @@ -472,6 +481,7 @@ class test_main_template > >::type , false + , false >::test_all(data); return 0; @@ -495,6 +505,7 @@ class test_main_template , typename value_type::unordered_set_base_hook_t >::type , true + , false >::test_all(data); test_unordered_multiset < typename detail::get_member_value_traits @@ -505,6 +516,7 @@ class test_main_template > >::type , false + , false >::test_all(data); test_unordered_multiset < typename detail::get_base_value_traits @@ -512,6 +524,7 @@ class test_main_template , typename value_type::unordered_set_auto_base_hook_t >::type , true + , true >::test_all(data); test_unordered_multiset < typename detail::get_member_value_traits @@ -522,6 +535,7 @@ class test_main_template > >::type , false + , true >::test_all(data); return 0; } diff --git a/test/unordered_set_test.cpp b/test/unordered_set_test.cpp index 6fcff90..7702a2e 100644 --- a/test/unordered_set_test.cpp +++ b/test/unordered_set_test.cpp @@ -26,7 +26,7 @@ using namespace boost::intrusive; static const std::size_t BucketSize = 11; -template +template struct test_unordered_set { typedef typename ValueTraits::value_type value_type; @@ -40,8 +40,8 @@ struct test_unordered_set static void test_clone(std::vector& values); }; -template -void test_unordered_set::test_all(std::vector& values) +template +void test_unordered_set::test_all(std::vector& values) { typedef typename ValueTraits::value_type value_type; typedef unordered_set @@ -49,6 +49,7 @@ void test_unordered_set::test_all(std::vector , constant_time_size , cache_begin + , compare_hash > unordered_set_type; typedef typename unordered_set_type::bucket_traits bucket_traits; { @@ -76,8 +77,8 @@ void test_unordered_set::test_all(std::vector -void test_unordered_set::test_impl() +template +void test_unordered_set::test_impl() { typedef typename ValueTraits::value_type value_type; typedef unordered_set @@ -85,6 +86,7 @@ void test_unordered_set::test_impl() , value_traits , constant_time_size , cache_begin + , compare_hash > unordered_set_type; typedef typename unordered_set_type::bucket_traits bucket_traits; @@ -105,8 +107,8 @@ void test_unordered_set::test_impl() } //test: constructor, iterator, clear, reverse_iterator, front, back, size: -template -void test_unordered_set::test_sort(std::vector& values) +template +void test_unordered_set::test_sort(std::vector& values) { typedef typename ValueTraits::value_type value_type; typedef unordered_set @@ -114,6 +116,7 @@ void test_unordered_set::test_sort(std::vector , constant_time_size , cache_begin + , compare_hash > unordered_set_type; typedef typename unordered_set_type::bucket_traits bucket_traits; @@ -129,8 +132,8 @@ void test_unordered_set::test_sort(std::vector -void test_unordered_set::test_insert(std::vector& values) +template +void test_unordered_set::test_insert(std::vector& values) { typedef typename ValueTraits::value_type value_type; typedef unordered_set @@ -138,6 +141,7 @@ void test_unordered_set::test_insert(std::vector , constant_time_size , cache_begin + , compare_hash > unordered_set_type; typedef typename unordered_set_type::bucket_traits bucket_traits; @@ -165,8 +169,8 @@ void test_unordered_set::test_insert(std::vector -void test_unordered_set::test_swap(std::vector& values) +template +void test_unordered_set::test_swap(std::vector& values) { typedef typename ValueTraits::value_type value_type; typedef unordered_set @@ -174,6 +178,7 @@ void test_unordered_set::test_swap(std::vector , constant_time_size , cache_begin + , compare_hash > unordered_set_type; typedef typename unordered_set_type::bucket_traits bucket_traits; @@ -197,8 +202,8 @@ void test_unordered_set::test_swap(std::vector -void test_unordered_set::test_rehash(std::vector& values) +template +void test_unordered_set::test_rehash(std::vector& values) { typedef typename ValueTraits::value_type value_type; typedef unordered_set @@ -206,6 +211,7 @@ void test_unordered_set::test_rehash(std::vector , constant_time_size , cache_begin + , compare_hash > unordered_set_type; typedef typename unordered_set_type::bucket_traits bucket_traits; @@ -243,8 +249,8 @@ void test_unordered_set::test_rehash(std::vector -void test_unordered_set::test_find(std::vector& values) +template +void test_unordered_set::test_find(std::vector& values) { typedef typename ValueTraits::value_type value_type; typedef unordered_set @@ -252,6 +258,7 @@ void test_unordered_set::test_find(std::vector , constant_time_size , cache_begin + , compare_hash > unordered_set_type; typedef typename unordered_set_type::bucket_traits bucket_traits; @@ -274,8 +281,8 @@ void test_unordered_set::test_find(std::vector -void test_unordered_set +template +void test_unordered_set ::test_clone(std::vector& values) { typedef typename ValueTraits::value_type value_type; @@ -284,6 +291,7 @@ void test_unordered_set , value_traits , constant_time_size , cache_begin + , compare_hash > unordered_set_type; typedef typename unordered_set_type::bucket_traits bucket_traits; { @@ -356,6 +364,7 @@ class test_main_template , typename value_type::unordered_set_base_hook_t >::type , true + , false >::test_all(data); test_unordered_set < typename detail::get_member_value_traits < value_type @@ -365,6 +374,7 @@ class test_main_template > >::type , false + , false >::test_all(data); return 0; @@ -388,6 +398,7 @@ class test_main_template , typename value_type::unordered_set_base_hook_t >::type , true + , false >::test_all(data); test_unordered_set < typename detail::get_member_value_traits @@ -398,6 +409,7 @@ class test_main_template > >::type , false + , false >::test_all(data); test_unordered_set < typename detail::get_base_value_traits @@ -405,6 +417,7 @@ class test_main_template , typename value_type::unordered_set_auto_base_hook_t >::type , true + , true >::test_all(data); test_unordered_set < typename detail::get_member_value_traits @@ -415,6 +428,7 @@ class test_main_template > >::type , false + , true >::test_all(data); return 0; }