forked from boostorg/intrusive
Changes and fixes for Boost 1.37
[SVN r49277]
This commit is contained in:
@@ -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
|
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
|
transmitted to the containers, so all the internal pointers used by intrusive containers
|
||||||
configured with these hooks will be smart pointers. As an example,
|
configured with these hooks will be smart pointers. As an example,
|
||||||
[*Boost.Interprocess] defines an mart pointer compatible with shared memory,
|
[*Boost.Interprocess] defines a smart pointer compatible with shared memory,
|
||||||
called `offset_ptr`. [*Boost.Intrusive] can be configured to use this smart pointer
|
called `offset_ptr`. [*Boost.Intrusive] can be configured to use this smart pointer
|
||||||
to allow shared memory intrusive containers.
|
to allow shared memory intrusive containers.
|
||||||
|
|
||||||
@@ -656,6 +656,15 @@ want to redefine intrusive safe-mode assertions without modifying the global
|
|||||||
used in hooks' destructors to check that the hook is in a default state.
|
used in hooks' destructors to check that the hook is in a default state.
|
||||||
|
|
||||||
If any of these macros is not redefined, the assertion will default to `BOOST_ASSERT`.
|
If any of these macros is not redefined, the assertion will default to `BOOST_ASSERT`.
|
||||||
|
If `BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT` or `BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT`
|
||||||
|
is defined and the programmer needs to include a file to configure that assertion, it can define
|
||||||
|
`BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT_INCLUDE` or `BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT_INCLUDE`
|
||||||
|
with the name of the file to include:
|
||||||
|
|
||||||
|
[c++]
|
||||||
|
|
||||||
|
#define BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT MYASSERT
|
||||||
|
#define BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT_INCLUDE <myassert.h>
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
@@ -1032,8 +1041,9 @@ the same options explained in the section
|
|||||||
* [*`optimize_size<bool Enable>`]: The hook will be optimized for size
|
* [*`optimize_size<bool Enable>`]: The hook will be optimized for size
|
||||||
instead of speed. The hook will embed the color bit of the red-black
|
instead of speed. The hook will embed the color bit of the red-black
|
||||||
tree node in the parent pointer if pointer alignment is even.
|
tree node in the parent pointer if pointer alignment is even.
|
||||||
Optimizing the size will reduce speed performance a bit since masking
|
In some platforms, optimizing the size might reduce speed performance a bit
|
||||||
operations will be needed to access parent pointer and color attributes.
|
since masking operations will be needed to access parent pointer and color attributes,
|
||||||
|
in other platforms this option improves performance due to improved memory locality.
|
||||||
Default: `optimize_size<false>`.
|
Default: `optimize_size<false>`.
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
@@ -1283,11 +1293,17 @@ And they also can receive additional options:
|
|||||||
(e.g. strings with a long common predicate) sometimes (specially when the
|
(e.g. strings with a long common predicate) sometimes (specially when the
|
||||||
load factor is high or we have many equivalent elements in an
|
load factor is high or we have many equivalent elements in an
|
||||||
[classref boost::intrusive::unordered_multiset unordered_multiset] and
|
[classref boost::intrusive::unordered_multiset unordered_multiset] and
|
||||||
no `optimize_multikey<>` is activatedin the hook)
|
no `optimize_multikey<>` is activated in the hook)
|
||||||
the equality function is a performance problem. Two equal values must have
|
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
|
equal hashes, so comparing the hash values of two elements before using the
|
||||||
comparison functor can speed up some implementations.
|
comparison functor can speed up some implementations.
|
||||||
|
|
||||||
|
* [*`incremental<bool Enabled>`]: Activates incremental hashing (also known as Linear Hashing).
|
||||||
|
This option implies `power_2_buckets<true>` and the container will require power of two buckets.
|
||||||
|
For more information on incremental hashing, see
|
||||||
|
[@http://en.wikipedia.org/wiki/Linear_hashing `Linear hash` on Wikipedia]
|
||||||
|
Default: `incremental<false>`
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
[section:unordered_set_unordered_multiset_example Example]
|
[section:unordered_set_unordered_multiset_example Example]
|
||||||
@@ -1558,8 +1574,9 @@ the size of the node:
|
|||||||
* [*`optimize_size<bool Enable>`]: The hook will be optimized for size
|
* [*`optimize_size<bool Enable>`]: The hook will be optimized for size
|
||||||
instead of speed. The hook will embed the balance bits of the AVL
|
instead of speed. The hook will embed the balance bits of the AVL
|
||||||
tree node in the parent pointer if pointer alignment is multiple of 4.
|
tree node in the parent pointer if pointer alignment is multiple of 4.
|
||||||
Optimizing the size will reduce speed performance a bit since masking
|
In some platforms, optimizing the size might reduce speed performance a bit
|
||||||
operations will be needed to access parent pointer and balance factor attributes.
|
since masking operations will be needed to access parent pointer and balance factor attributes,
|
||||||
|
in other platforms this option improves performance due to improved memory locality.
|
||||||
Default: `optimize_size<false>`.
|
Default: `optimize_size<false>`.
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
@@ -1890,7 +1907,7 @@ and [classref boost::intrusive::unordered_set unordered_set] reference for more
|
|||||||
|
|
||||||
With multiple ordered and unordered associative containers
|
With multiple ordered and unordered associative containers
|
||||||
([classref boost::intrusive::multiset multiset] and
|
([classref boost::intrusive::multiset multiset] and
|
||||||
[classref boost::intrusive::unordered_multiset unordered_multiset]) there's
|
[classref boost::intrusive::unordered_multiset unordered_multiset]) there is
|
||||||
no need for these advanced insertion functions, since insertions are always succesful.
|
no need for these advanced insertion functions, since insertions are always succesful.
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
@@ -1982,7 +1999,7 @@ The cloning function works as follows:
|
|||||||
all the constructed elements are disposed using the disposer function object.
|
all the constructed elements are disposed using the disposer function object.
|
||||||
|
|
||||||
|
|
||||||
Here's an example of `clone_from`:
|
Here is an example of `clone_from`:
|
||||||
|
|
||||||
[import ../example/doc_clone_from.cpp]
|
[import ../example/doc_clone_from.cpp]
|
||||||
[doc_clone_from]
|
[doc_clone_from]
|
||||||
@@ -2116,7 +2133,7 @@ These hooks support these options:
|
|||||||
be inserted container. Additionally, these hooks don't support `unlink()` and
|
be inserted container. Additionally, these hooks don't support `unlink()` and
|
||||||
`swap_nodes()` operations for the same reason.
|
`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
|
Here is 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].
|
class in a [classref slist] and the other one in a [classref list].
|
||||||
|
|
||||||
[import ../example/doc_any_hook.cpp]
|
[import ../example/doc_any_hook.cpp]
|
||||||
@@ -2699,7 +2716,7 @@ used in node algorithms, since these types can be different. Apart from this,
|
|||||||
Instead of using [*Boost.Intrusive] predefined hooks
|
Instead of using [*Boost.Intrusive] predefined hooks
|
||||||
a user might want to develop customized containers, for example, using nodes that are
|
a user might want to develop customized containers, for example, using nodes that are
|
||||||
optimized for a specific
|
optimized for a specific
|
||||||
application or that are compatible with a a legacy ABI. A user might want
|
application or that are compatible with a legacy ABI. A user might want
|
||||||
to have only two additional pointers in his class and insert the class in a doubly
|
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
|
linked list sometimes and in a singly linked list in other situations. You can't
|
||||||
achieve this using [*Boost.Intrusive] predefined hooks. Now, instead of using
|
achieve this using [*Boost.Intrusive] predefined hooks. Now, instead of using
|
||||||
@@ -3459,7 +3476,7 @@ The disperse list is again the slowest.
|
|||||||
|
|
||||||
[section:performance_results_conclusions Conclusions]
|
[section:performance_results_conclusions Conclusions]
|
||||||
|
|
||||||
Intrusive containers can offer performance benefits that can not be achieved with
|
Intrusive containers can offer performance benefits that cannot be achieved with
|
||||||
equivalent non-intrusive containers. Memory locality improvements are noticeable
|
equivalent non-intrusive containers. Memory locality improvements are noticeable
|
||||||
when the objects to be inserted are small. Minimizing memory allocation/deallocation calls is also
|
when the objects to be inserted are small. Minimizing memory allocation/deallocation calls is also
|
||||||
an important factor and intrusive containers make this simple if the user allocates
|
an important factor and intrusive containers make this simple if the user allocates
|
||||||
@@ -3471,6 +3488,17 @@ all the objects to be inserted in intrusive containers in containers like `std::
|
|||||||
|
|
||||||
[section:release_notes Release Notes]
|
[section:release_notes Release Notes]
|
||||||
|
|
||||||
|
[section:release_notes_boost_1_37_00 Boost 1.37 Release]
|
||||||
|
|
||||||
|
* Intrusive now takes advantage of compilers with variadic templates.
|
||||||
|
* `clone_from` functions now copy predicates and hash functions of associative containers.
|
||||||
|
* Added incremental hashing to unordered containers via `incremental<>` option.
|
||||||
|
* Update some function parameters from `iterator` to `const_iterator` in containers
|
||||||
|
to keep up with the draft of the next standard.
|
||||||
|
* Added an option to specify include files for intrusive configurable assertion macros.
|
||||||
|
|
||||||
|
[endsect]
|
||||||
|
|
||||||
[section:release_notes_boost_1_36_00 Boost 1.36 Release]
|
[section:release_notes_boost_1_36_00 Boost 1.36 Release]
|
||||||
|
|
||||||
* Added `linear<>` and `cache_last<>` options to singly linked lists.
|
* Added `linear<>` and `cache_last<>` options to singly linked lists.
|
||||||
@@ -3512,7 +3540,7 @@ all the objects to be inserted in intrusive containers in containers like `std::
|
|||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
[section:acknowledgments Acknowledgements]
|
[section:acknowledgements Acknowledegements]
|
||||||
|
|
||||||
[*Olaf Krzikalla] would like to thank:
|
[*Olaf Krzikalla] would like to thank:
|
||||||
|
|
||||||
|
@@ -21,7 +21,7 @@ class Window : public list_base_hook<>
|
|||||||
//This is a container those value is an abstract class: you can't do this with std::list.
|
//This is a container those value is an abstract class: you can't do this with std::list.
|
||||||
typedef list<Window> win_list;
|
typedef list<Window> win_list;
|
||||||
|
|
||||||
//An static intrusive list declaration
|
//A static intrusive list declaration
|
||||||
static win_list all_windows;
|
static win_list all_windows;
|
||||||
|
|
||||||
//Constructor. Includes this window in the list
|
//Constructor. Includes this window in the list
|
||||||
|
@@ -267,6 +267,9 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\..\..\boost\intrusive\detail\utilities.hpp">
|
RelativePath="..\..\..\..\..\boost\intrusive\detail\utilities.hpp">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\..\..\boost\intrusive\detail\workaround.hpp">
|
||||||
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
|
3
proj/vc7ide/to-do.txt
Normal file
3
proj/vc7ide/to-do.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
-> Implement C++0x features (variadic templates & rvalue references)
|
||||||
|
-> Offer bidirectional iterator for hashtables
|
||||||
|
-> Non-array buckets
|
@@ -3,7 +3,7 @@
|
|||||||
ProjectType="Visual C++"
|
ProjectType="Visual C++"
|
||||||
Version="7.10"
|
Version="7.10"
|
||||||
Name="unordered_set"
|
Name="unordered_set"
|
||||||
ProjectGUID="{90E701E6-2C91-F4A7-BA6C-A9F3B0949279}"
|
ProjectGUID="{9101EE76-BB6C-2C91-F4B7-A27B94908F19}"
|
||||||
Keyword="Win32Proj">
|
Keyword="Win32Proj">
|
||||||
<Platforms>
|
<Platforms>
|
||||||
<Platform
|
<Platform
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="../../../../../"
|
AdditionalIncludeDirectories="../../../../../"
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||||
|
GeneratePreprocessedFile="0"
|
||||||
MinimalRebuild="TRUE"
|
MinimalRebuild="TRUE"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="5"
|
RuntimeLibrary="5"
|
||||||
@@ -116,7 +117,7 @@
|
|||||||
<Filter
|
<Filter
|
||||||
Name="Source Files"
|
Name="Source Files"
|
||||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||||
UniqueIdentifier="{4F3C77F1-B78A-C745-4726-2D752AA322FF}">
|
UniqueIdentifier="{4F3C77F1-B78A-C745-4726-252AD75C322E}">
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\test\unordered_set_test.cpp">
|
RelativePath="..\..\..\test\unordered_set_test.cpp">
|
||||||
</File>
|
</File>
|
||||||
|
@@ -13,6 +13,9 @@
|
|||||||
#include <boost/intrusive/slist.hpp>
|
#include <boost/intrusive/slist.hpp>
|
||||||
#include <boost/intrusive/set.hpp>
|
#include <boost/intrusive/set.hpp>
|
||||||
#include <boost/intrusive/unordered_set.hpp>
|
#include <boost/intrusive/unordered_set.hpp>
|
||||||
|
#include <boost/intrusive/splay_set.hpp>
|
||||||
|
#include <boost/intrusive/avl_set.hpp>
|
||||||
|
#include <boost/intrusive/sg_set.hpp>
|
||||||
#include "smart_ptr.hpp"
|
#include "smart_ptr.hpp"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -28,6 +31,12 @@ class MyClass
|
|||||||
< void_pointer<smart_ptr<void> >, link_mode<normal_link> >
|
< void_pointer<smart_ptr<void> >, link_mode<normal_link> >
|
||||||
, public unordered_set_base_hook
|
, public unordered_set_base_hook
|
||||||
< void_pointer<smart_ptr<void> >, link_mode<normal_link> >
|
< void_pointer<smart_ptr<void> >, link_mode<normal_link> >
|
||||||
|
, public avl_set_base_hook
|
||||||
|
< void_pointer<smart_ptr<void> >, link_mode<normal_link> >
|
||||||
|
, public splay_set_base_hook
|
||||||
|
< void_pointer<smart_ptr<void> >, link_mode<normal_link> >
|
||||||
|
, public bs_set_base_hook
|
||||||
|
< void_pointer<smart_ptr<void> >, link_mode<normal_link> >
|
||||||
{
|
{
|
||||||
int int_;
|
int int_;
|
||||||
|
|
||||||
@@ -51,6 +60,9 @@ typedef list<MyClass> List;
|
|||||||
typedef slist<MyClass> Slist;
|
typedef slist<MyClass> Slist;
|
||||||
typedef set<MyClass> Set;
|
typedef set<MyClass> Set;
|
||||||
typedef unordered_set<MyClass> USet;
|
typedef unordered_set<MyClass> USet;
|
||||||
|
typedef avl_set<MyClass> AvlSet;
|
||||||
|
typedef splay_set<MyClass> SplaySet;
|
||||||
|
typedef sg_set<MyClass> SgSet;
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
@@ -67,6 +79,9 @@ int main()
|
|||||||
Slist my_slist;
|
Slist my_slist;
|
||||||
Set my_set;
|
Set my_set;
|
||||||
USet my_uset(USet::bucket_traits(buckets, 100));
|
USet my_uset(USet::bucket_traits(buckets, 100));
|
||||||
|
AvlSet my_avlset;
|
||||||
|
SplaySet my_splayset;
|
||||||
|
SgSet my_sgset;
|
||||||
|
|
||||||
//Now insert them in the reverse order
|
//Now insert them in the reverse order
|
||||||
//in the base hook intrusive list
|
//in the base hook intrusive list
|
||||||
@@ -75,6 +90,9 @@ int main()
|
|||||||
my_slist.push_front(*it);
|
my_slist.push_front(*it);
|
||||||
my_set.insert(*it);
|
my_set.insert(*it);
|
||||||
my_uset.insert(*it);
|
my_uset.insert(*it);
|
||||||
|
my_avlset.insert(*it);
|
||||||
|
my_splayset.insert(*it);
|
||||||
|
my_sgset.insert(*it);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Now test lists
|
//Now test lists
|
||||||
@@ -82,13 +100,24 @@ int main()
|
|||||||
List::const_iterator list_it(my_list.cbegin());
|
List::const_iterator list_it(my_list.cbegin());
|
||||||
Slist::const_iterator slist_it(my_slist.cbegin());
|
Slist::const_iterator slist_it(my_slist.cbegin());
|
||||||
Set::const_reverse_iterator set_rit(my_set.crbegin());
|
Set::const_reverse_iterator set_rit(my_set.crbegin());
|
||||||
|
AvlSet::const_reverse_iterator avl_set_rit(my_avlset.crbegin());
|
||||||
|
SplaySet::const_reverse_iterator splay_set_rit(my_splayset.crbegin());
|
||||||
|
SgSet::const_reverse_iterator sg_set_rit(my_sgset.crbegin());
|
||||||
|
|
||||||
VectRit vect_it(values.rbegin()), vect_itend(values.rend());
|
VectRit vect_it(values.rbegin()), vect_itend(values.rend());
|
||||||
|
|
||||||
//Test the objects inserted in the base hook list
|
//Test the objects inserted in the base hook list
|
||||||
for(; vect_it != vect_itend; ++vect_it, ++list_it, ++slist_it, ++set_rit){
|
for(; vect_it != vect_itend
|
||||||
if(&*list_it != &*vect_it) return 1;
|
; ++vect_it, ++list_it
|
||||||
if(&*slist_it != &*vect_it) return 1;
|
, ++slist_it, ++set_rit
|
||||||
if(&*set_rit != &*vect_it) return 1;
|
, ++avl_set_rit, ++splay_set_rit
|
||||||
|
, ++sg_set_rit){
|
||||||
|
if(&*list_it != &*vect_it) return 1;
|
||||||
|
if(&*slist_it != &*vect_it) return 1;
|
||||||
|
if(&*set_rit != &*vect_it) return 1;
|
||||||
|
if(&*avl_set_rit != &*vect_it) return 1;
|
||||||
|
if(&*splay_set_rit != &*vect_it)return 1;
|
||||||
|
if(&*sg_set_rit != &*vect_it) return 1;
|
||||||
if(my_uset.find(*set_rit) == my_uset.cend()) return 1;
|
if(my_uset.find(*set_rit) == my_uset.cend()) return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include <boost/intrusive/detail/config_begin.hpp>
|
#include <boost/intrusive/detail/config_begin.hpp>
|
||||||
#include <boost/intrusive/list.hpp>
|
#include <boost/intrusive/list.hpp>
|
||||||
|
|
||||||
#include <boost/intrusive/detail/pointer_to_other.hpp>
|
#include <boost/intrusive/detail/pointer_to_other.hpp>
|
||||||
#include "itestvalue.hpp"
|
#include "itestvalue.hpp"
|
||||||
#include "smart_ptr.hpp"
|
#include "smart_ptr.hpp"
|
||||||
@@ -446,13 +447,12 @@ class test_main_template<VoidPointer, false>
|
|||||||
>
|
>
|
||||||
>::type
|
>::type
|
||||||
>::test_all(data);
|
>::test_all(data);
|
||||||
/*
|
|
||||||
test_list<stateful_value_traits
|
// test_list<stateful_value_traits
|
||||||
< value_type
|
// < value_type
|
||||||
, list_node_traits<VoidPointer>
|
// , list_node_traits<VoidPointer>
|
||||||
, safe_link>
|
// , safe_link>
|
||||||
>::test_all(data);
|
// >::test_all(data);
|
||||||
*/
|
|
||||||
test_list < typename detail::get_base_value_traits
|
test_list < typename detail::get_base_value_traits
|
||||||
< value_type
|
< value_type
|
||||||
, typename value_type::list_auto_base_hook_t
|
, typename value_type::list_auto_base_hook_t
|
||||||
@@ -467,13 +467,13 @@ class test_main_template<VoidPointer, false>
|
|||||||
>
|
>
|
||||||
>::type
|
>::type
|
||||||
>::test_all(data);
|
>::test_all(data);
|
||||||
/*
|
|
||||||
test_list<stateful_value_traits
|
// test_list<stateful_value_traits
|
||||||
< value_type
|
// < value_type
|
||||||
, list_node_traits<VoidPointer>
|
// , list_node_traits<VoidPointer>
|
||||||
, auto_unlink>
|
// , auto_unlink>
|
||||||
>::test_all(data);
|
// >::test_all(data);
|
||||||
*/
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -488,3 +488,285 @@ int main( int, char* [] )
|
|||||||
return boost::report_errors();
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
#include <boost/intrusive/detail/config_end.hpp>
|
#include <boost/intrusive/detail/config_end.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////
|
||||||
|
// Builds an index_tuple<0, 1, 2, ..., Num-1>, that will
|
||||||
|
// be used to "unpack" into comma-separated values
|
||||||
|
// in a function call.
|
||||||
|
////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<int... Indexes>
|
||||||
|
struct index_tuple{};
|
||||||
|
|
||||||
|
template<std::size_t Num, typename Tuple = index_tuple<> >
|
||||||
|
struct build_number_seq;
|
||||||
|
|
||||||
|
template<std::size_t Num, int... Indexes>
|
||||||
|
struct build_number_seq<Num, index_tuple<Indexes...> >
|
||||||
|
: build_number_seq<Num - 1, index_tuple<Indexes..., sizeof...(Indexes)> >
|
||||||
|
{};
|
||||||
|
|
||||||
|
template<int... Indexes>
|
||||||
|
struct build_number_seq<0, index_tuple<Indexes...> >
|
||||||
|
{ typedef index_tuple<Indexes...> type; };
|
||||||
|
|
||||||
|
template<class ...Types>
|
||||||
|
struct typelist
|
||||||
|
{};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct invert_typelist;
|
||||||
|
|
||||||
|
template<int I, typename Tuple>
|
||||||
|
struct typelist_element;
|
||||||
|
|
||||||
|
template<int I, typename Head, typename... Tail>
|
||||||
|
struct typelist_element<I, typelist<Head, Tail...> >
|
||||||
|
{
|
||||||
|
typedef typename typelist_element<I-1, typelist<Tail...> >::type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Head, typename... Tail>
|
||||||
|
struct typelist_element<0, typelist<Head, Tail...> >
|
||||||
|
{
|
||||||
|
typedef Head type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<int ...Ints, class ...Types>
|
||||||
|
typelist<typename typelist_element<(sizeof...(Types) - 1) - Ints, typelist<Types...> >::type...>
|
||||||
|
inverted_typelist(index_tuple<Ints...>, typelist<Types...>)
|
||||||
|
{
|
||||||
|
return typelist<typename typelist_element<(sizeof...(Types) - 1) - Ints, typelist<Types...> >::type...>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Typelist>
|
||||||
|
struct sizeof_typelist;
|
||||||
|
|
||||||
|
template<class ...Types>
|
||||||
|
struct sizeof_typelist< typelist<Types...> >
|
||||||
|
{
|
||||||
|
static const std::size_t value = sizeof...(Types);
|
||||||
|
};
|
||||||
|
|
||||||
|
//invert_typelist_impl
|
||||||
|
template<class Typelist, class Indexes>
|
||||||
|
struct invert_typelist_impl;
|
||||||
|
|
||||||
|
|
||||||
|
template<class Typelist, int ...Ints>
|
||||||
|
struct invert_typelist_impl< Typelist, index_tuple<Ints...> >
|
||||||
|
{
|
||||||
|
static const std::size_t last_idx = sizeof_typelist<Typelist>::value - 1;
|
||||||
|
typedef typelist
|
||||||
|
<typename typelist_element<last_idx - Ints, Typelist>::type...> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Typelist, int Int>
|
||||||
|
struct invert_typelist_impl< Typelist, index_tuple<Int> >
|
||||||
|
{
|
||||||
|
typedef Typelist type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Typelist>
|
||||||
|
struct invert_typelist_impl< Typelist, index_tuple<> >
|
||||||
|
{
|
||||||
|
typedef Typelist type;
|
||||||
|
};
|
||||||
|
|
||||||
|
//invert_typelist
|
||||||
|
template<class Typelist>
|
||||||
|
struct invert_typelist;
|
||||||
|
|
||||||
|
template<class ...Types>
|
||||||
|
struct invert_typelist< typelist<Types...> >
|
||||||
|
{
|
||||||
|
typedef typelist<Types...> typelist_t;
|
||||||
|
typedef typename build_number_seq<sizeof...(Types)>::type indexes_t;
|
||||||
|
typedef typename invert_typelist_impl<typelist_t, indexes_t>::type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct none
|
||||||
|
{
|
||||||
|
template<class Base>
|
||||||
|
struct pack : Base
|
||||||
|
{ };
|
||||||
|
};
|
||||||
|
|
||||||
|
//!This option setter specifies the type of
|
||||||
|
//!a void pointer. This will instruct the hook
|
||||||
|
//!to use this type of pointer instead of the
|
||||||
|
//!default one
|
||||||
|
template<class VoidPointer>
|
||||||
|
struct void_pointer
|
||||||
|
{
|
||||||
|
/// @cond
|
||||||
|
template<class Base>
|
||||||
|
struct pack : Base
|
||||||
|
{
|
||||||
|
typedef VoidPointer void_pointer;
|
||||||
|
};
|
||||||
|
/// @endcond
|
||||||
|
};
|
||||||
|
|
||||||
|
//!This option setter specifies the type of
|
||||||
|
//!the tag of a base hook. A type cannot have two
|
||||||
|
//!base hooks of the same type, so a tag can be used
|
||||||
|
//!to differentiate two base hooks with otherwise same type
|
||||||
|
template<class Tag>
|
||||||
|
struct tag
|
||||||
|
{
|
||||||
|
/// @cond
|
||||||
|
template<class Base>
|
||||||
|
struct pack : Base
|
||||||
|
{
|
||||||
|
typedef Tag tag;
|
||||||
|
};
|
||||||
|
/// @endcond
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//!This option setter specifies if the hook
|
||||||
|
//!should be optimized for size instead of for speed.
|
||||||
|
template<bool Enabled>
|
||||||
|
struct optimize_size
|
||||||
|
{
|
||||||
|
/// @cond
|
||||||
|
template<class Base>
|
||||||
|
struct pack : Base
|
||||||
|
{
|
||||||
|
static const bool optimize_size = Enabled;
|
||||||
|
};
|
||||||
|
/// @endcond
|
||||||
|
};
|
||||||
|
|
||||||
|
//!This option setter specifies if the list container should
|
||||||
|
//!use a linear implementation instead of a circular one.
|
||||||
|
template<bool Enabled>
|
||||||
|
struct linear
|
||||||
|
{
|
||||||
|
/// @cond
|
||||||
|
template<class Base>
|
||||||
|
struct pack : Base
|
||||||
|
{
|
||||||
|
static const bool linear = Enabled;
|
||||||
|
};
|
||||||
|
/// @endcond
|
||||||
|
};
|
||||||
|
|
||||||
|
//!This option setter specifies if the list container should
|
||||||
|
//!use a linear implementation instead of a circular one.
|
||||||
|
template<bool Enabled>
|
||||||
|
struct cache_last
|
||||||
|
{
|
||||||
|
/// @cond
|
||||||
|
template<class Base>
|
||||||
|
struct pack : Base
|
||||||
|
{
|
||||||
|
static const bool cache_last = Enabled;
|
||||||
|
};
|
||||||
|
/// @endcond
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class Typelist>
|
||||||
|
struct do_pack;
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct do_pack<typelist<> >;
|
||||||
|
|
||||||
|
template<class Prev>
|
||||||
|
struct do_pack<typelist<Prev> >
|
||||||
|
{
|
||||||
|
typedef Prev type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Prev, class Last>
|
||||||
|
struct do_pack<typelist<Prev, Last> >
|
||||||
|
{
|
||||||
|
typedef typename Prev::template pack<Last> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Prev, class ...Others>
|
||||||
|
struct do_pack<typelist<Prev, Others...> >
|
||||||
|
{
|
||||||
|
typedef typename Prev::template pack
|
||||||
|
<typename do_pack<typelist<Others...>>::type> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<class ...Options>
|
||||||
|
struct pack_options
|
||||||
|
{
|
||||||
|
typedef typelist<Options...> typelist_t;
|
||||||
|
typedef typename invert_typelist<typelist_t>::type inverted_typelist;
|
||||||
|
typedef typename do_pack<inverted_typelist>::type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct hook_defaults
|
||||||
|
: public pack_options
|
||||||
|
< none
|
||||||
|
, void_pointer<void*>
|
||||||
|
, tag<int>
|
||||||
|
, optimize_size<false>
|
||||||
|
, linear<false>
|
||||||
|
>::type
|
||||||
|
{};
|
||||||
|
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <typeinfo>
|
||||||
|
|
||||||
|
struct S
|
||||||
|
{};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
typedef typelist<int, float, double> typelist_t;
|
||||||
|
typedef invert_typelist<typelist_t>::type inverted_typelist;
|
||||||
|
std::cout << "original: " << typeid(typelist_t).name() << std::endl;
|
||||||
|
std::cout << "inverted: " << typeid(inverted_typelist).name() << std::endl;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
typedef typelist<int> typelist_t;
|
||||||
|
typedef invert_typelist<typelist_t>::type inverted_typelist;
|
||||||
|
std::cout << "original: " << typeid(typelist_t).name() << std::endl;
|
||||||
|
std::cout << "inverted: " << typeid(inverted_typelist).name() << std::endl;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
typedef typelist<> typelist_t;
|
||||||
|
typedef invert_typelist<typelist_t>::type inverted_typelist;
|
||||||
|
std::cout << "original: " << typeid(typelist_t).name() << std::endl;
|
||||||
|
std::cout << "inverted: " << typeid(inverted_typelist).name() << std::endl;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
typedef pack_options<S, none>::type options_t;
|
||||||
|
std::cout << "options_t " << typeid(options_t).name() << std::endl;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
typedef pack_options<S, none, none>::type options_t;
|
||||||
|
std::cout << "options_t " << typeid(options_t).name() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
hook_defaults h;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
*/
|
@@ -108,7 +108,6 @@ class test_main_template<VoidPointer, false>
|
|||||||
|
|
||||||
int main( int, char* [] )
|
int main( int, char* [] )
|
||||||
{
|
{
|
||||||
|
|
||||||
test_main_template<void*, false>()();
|
test_main_template<void*, false>()();
|
||||||
test_main_template<boost::intrusive::smart_ptr<void>, false>()();
|
test_main_template<boost::intrusive::smart_ptr<void>, false>()();
|
||||||
test_main_template<void*, true>()();
|
test_main_template<void*, true>()();
|
||||||
|
@@ -18,8 +18,18 @@
|
|||||||
|
|
||||||
namespace boost { namespace intrusive { namespace test {
|
namespace boost { namespace intrusive { namespace test {
|
||||||
|
|
||||||
|
#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template<class T, class O1, class O2, class O3, class O4>
|
template<class T, class O1, class O2, class O3, class O4>
|
||||||
struct has_rebalance<boost::intrusive::sg_multiset<T, O1, O2, O3, O4> >
|
#else
|
||||||
|
template<class T, class ...Options>
|
||||||
|
#endif
|
||||||
|
struct has_rebalance<boost::intrusive::sg_multiset<T,
|
||||||
|
#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
|
O1, O2, O3, O4
|
||||||
|
#else
|
||||||
|
Options...
|
||||||
|
#endif
|
||||||
|
> >
|
||||||
{
|
{
|
||||||
static const bool value = true;
|
static const bool value = true;
|
||||||
};
|
};
|
||||||
|
@@ -17,8 +17,18 @@
|
|||||||
|
|
||||||
namespace boost { namespace intrusive { namespace test {
|
namespace boost { namespace intrusive { namespace test {
|
||||||
|
|
||||||
|
#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template<class T, class O1, class O2, class O3, class O4>
|
template<class T, class O1, class O2, class O3, class O4>
|
||||||
struct has_rebalance<boost::intrusive::sg_set<T, O1, O2, O3, O4> >
|
#else
|
||||||
|
template<class T, class ...Options>
|
||||||
|
#endif
|
||||||
|
struct has_rebalance<boost::intrusive::sg_set<T,
|
||||||
|
#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
|
O1, O2, O3, O4
|
||||||
|
#else
|
||||||
|
Options...
|
||||||
|
#endif
|
||||||
|
> >
|
||||||
{
|
{
|
||||||
static const bool value = true;
|
static const bool value = true;
|
||||||
};
|
};
|
||||||
|
@@ -19,20 +19,51 @@
|
|||||||
|
|
||||||
namespace boost { namespace intrusive { namespace test {
|
namespace boost { namespace intrusive { namespace test {
|
||||||
|
|
||||||
|
#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template<class T, class O1, class O2, class O3, class O4>
|
template<class T, class O1, class O2, class O3, class O4>
|
||||||
struct has_const_overloads<boost::intrusive::splay_multiset<T, O1, O2, O3, O4> >
|
#else
|
||||||
|
template<class T, class ...Options>
|
||||||
|
#endif
|
||||||
|
struct has_const_overloads<boost::intrusive::splay_multiset<
|
||||||
|
#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
|
T, O1, O2, O3, O4
|
||||||
|
#else
|
||||||
|
T, Options...
|
||||||
|
#endif
|
||||||
|
>
|
||||||
|
>
|
||||||
{
|
{
|
||||||
static const bool value = false;
|
static const bool value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template<class T, class O1, class O2, class O3, class O4>
|
template<class T, class O1, class O2, class O3, class O4>
|
||||||
struct has_splay<boost::intrusive::splay_multiset<T, O1, O2, O3, O4> >
|
#else
|
||||||
|
template<class T, class ...Options>
|
||||||
|
#endif
|
||||||
|
struct has_splay<boost::intrusive::splay_multiset<T,
|
||||||
|
#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
|
O1, O2, O3, O4
|
||||||
|
#else
|
||||||
|
Options...
|
||||||
|
#endif
|
||||||
|
> >
|
||||||
{
|
{
|
||||||
static const bool value = true;
|
static const bool value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template<class T, class O1, class O2, class O3, class O4>
|
template<class T, class O1, class O2, class O3, class O4>
|
||||||
struct has_rebalance<boost::intrusive::splay_multiset<T, O1, O2, O3, O4> >
|
#else
|
||||||
|
template<class T, class ...Options>
|
||||||
|
#endif
|
||||||
|
struct has_rebalance<boost::intrusive::splay_multiset<T,
|
||||||
|
#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
|
O1, O2, O3, O4
|
||||||
|
#else
|
||||||
|
Options...
|
||||||
|
#endif
|
||||||
|
> >
|
||||||
{
|
{
|
||||||
static const bool value = true;
|
static const bool value = true;
|
||||||
};
|
};
|
||||||
|
@@ -17,20 +17,50 @@
|
|||||||
|
|
||||||
namespace boost { namespace intrusive { namespace test {
|
namespace boost { namespace intrusive { namespace test {
|
||||||
|
|
||||||
|
#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template<class T, class O1, class O2, class O3, class O4>
|
template<class T, class O1, class O2, class O3, class O4>
|
||||||
struct has_const_overloads<boost::intrusive::splay_set<T, O1, O2, O3, O4> >
|
#else
|
||||||
|
template<class T, class ...Options>
|
||||||
|
#endif
|
||||||
|
struct has_const_overloads<boost::intrusive::splay_set<T,
|
||||||
|
#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
|
O1, O2, O3, O4
|
||||||
|
#else
|
||||||
|
Options...
|
||||||
|
#endif
|
||||||
|
> >
|
||||||
{
|
{
|
||||||
static const bool value = false;
|
static const bool value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template<class T, class O1, class O2, class O3, class O4>
|
template<class T, class O1, class O2, class O3, class O4>
|
||||||
struct has_splay<boost::intrusive::splay_set<T, O1, O2, O3, O4> >
|
#else
|
||||||
|
template<class T, class ...Options>
|
||||||
|
#endif
|
||||||
|
struct has_splay<boost::intrusive::splay_set<T,
|
||||||
|
#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
|
O1, O2, O3, O4
|
||||||
|
#else
|
||||||
|
Options...
|
||||||
|
#endif
|
||||||
|
> >
|
||||||
{
|
{
|
||||||
static const bool value = true;
|
static const bool value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
template<class T, class O1, class O2, class O3, class O4>
|
template<class T, class O1, class O2, class O3, class O4>
|
||||||
struct has_rebalance<boost::intrusive::splay_set<T, O1, O2, O3, O4> >
|
#else
|
||||||
|
template<class T, class ...Options>
|
||||||
|
#endif
|
||||||
|
struct has_rebalance<boost::intrusive::splay_set<T,
|
||||||
|
#if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
|
O1, O2, O3, O4
|
||||||
|
#else
|
||||||
|
Options...
|
||||||
|
#endif
|
||||||
|
> >
|
||||||
{
|
{
|
||||||
static const bool value = true;
|
static const bool value = true;
|
||||||
};
|
};
|
||||||
|
@@ -15,10 +15,7 @@
|
|||||||
|
|
||||||
#define TEST_INTRUSIVE_SEQUENCE( INTVALUES, ITERATOR )\
|
#define TEST_INTRUSIVE_SEQUENCE( INTVALUES, ITERATOR )\
|
||||||
{ \
|
{ \
|
||||||
const int init_values_size = sizeof(INTVALUES)/sizeof(INTVALUES[0]); \
|
BOOST_TEST (std::equal(&INTVALUES[0], &INTVALUES[0] + sizeof(INTVALUES)/sizeof(INTVALUES[0]), ITERATOR) ); \
|
||||||
std::vector<int> expected; \
|
|
||||||
expected.assign(&INTVALUES[0], &INTVALUES[0] + init_values_size); \
|
|
||||||
BOOST_TEST (std::equal(expected.begin(), expected.end(), ITERATOR) ); \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TEST_INTRUSIVE_SEQUENCE_EXPECTED( EXPECTEDVECTOR, ITERATOR )\
|
#define TEST_INTRUSIVE_SEQUENCE_EXPECTED( EXPECTEDVECTOR, ITERATOR )\
|
||||||
|
@@ -25,9 +25,9 @@
|
|||||||
|
|
||||||
using namespace boost::intrusive;
|
using namespace boost::intrusive;
|
||||||
|
|
||||||
static const std::size_t BucketSize = 11;
|
static const std::size_t BucketSize = 8;
|
||||||
|
|
||||||
template<class ValueTraits, bool CacheBegin, bool CompareHash>
|
template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
|
||||||
struct test_unordered_multiset
|
struct test_unordered_multiset
|
||||||
{
|
{
|
||||||
typedef typename ValueTraits::value_type value_type;
|
typedef typename ValueTraits::value_type value_type;
|
||||||
@@ -35,14 +35,16 @@ struct test_unordered_multiset
|
|||||||
static void test_sort(std::vector<value_type>& values);
|
static void test_sort(std::vector<value_type>& values);
|
||||||
static void test_insert(std::vector<value_type>& values);
|
static void test_insert(std::vector<value_type>& values);
|
||||||
static void test_swap(std::vector<value_type>& values);
|
static void test_swap(std::vector<value_type>& values);
|
||||||
static void test_rehash(std::vector<value_type>& values);
|
static void test_rehash(std::vector<value_type>& values, detail::true_);
|
||||||
|
static void test_rehash(std::vector<value_type>& values, detail::false_);
|
||||||
static void test_find(std::vector<value_type>& values);
|
static void test_find(std::vector<value_type>& values);
|
||||||
static void test_impl();
|
static void test_impl();
|
||||||
static void test_clone(std::vector<value_type>& values);
|
static void test_clone(std::vector<value_type>& values);
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class ValueTraits, bool CacheBegin, bool CompareHash>
|
template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
|
||||||
void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash>::test_all (std::vector<typename ValueTraits::value_type>& values)
|
void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>::
|
||||||
|
test_all (std::vector<typename ValueTraits::value_type>& values)
|
||||||
{
|
{
|
||||||
typedef typename ValueTraits::value_type value_type;
|
typedef typename ValueTraits::value_type value_type;
|
||||||
typedef unordered_multiset
|
typedef unordered_multiset
|
||||||
@@ -51,6 +53,7 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash>::test_all (st
|
|||||||
, constant_time_size<value_type::constant_time_size>
|
, constant_time_size<value_type::constant_time_size>
|
||||||
, cache_begin<CacheBegin>
|
, cache_begin<CacheBegin>
|
||||||
, compare_hash<CompareHash>
|
, compare_hash<CompareHash>
|
||||||
|
, incremental<Incremental>
|
||||||
> unordered_multiset_type;
|
> unordered_multiset_type;
|
||||||
{
|
{
|
||||||
typedef typename unordered_multiset_type::bucket_traits bucket_traits;
|
typedef typename unordered_multiset_type::bucket_traits bucket_traits;
|
||||||
@@ -71,15 +74,16 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash>::test_all (st
|
|||||||
test_sort(values);
|
test_sort(values);
|
||||||
test_insert(values);
|
test_insert(values);
|
||||||
test_swap(values);
|
test_swap(values);
|
||||||
test_rehash(values);
|
test_rehash(values, detail::bool_<Incremental>());
|
||||||
test_find(values);
|
test_find(values);
|
||||||
test_impl();
|
test_impl();
|
||||||
test_clone(values);
|
test_clone(values);
|
||||||
}
|
}
|
||||||
|
|
||||||
//test case due to an error in tree implementation:
|
//test case due to an error in tree implementation:
|
||||||
template<class ValueTraits, bool CacheBegin, bool CompareHash>
|
template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
|
||||||
void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash>::test_impl()
|
void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>
|
||||||
|
::test_impl()
|
||||||
{
|
{
|
||||||
typedef typename ValueTraits::value_type value_type;
|
typedef typename ValueTraits::value_type value_type;
|
||||||
typedef unordered_multiset
|
typedef unordered_multiset
|
||||||
@@ -88,6 +92,7 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash>::test_impl()
|
|||||||
, constant_time_size<value_type::constant_time_size>
|
, constant_time_size<value_type::constant_time_size>
|
||||||
, cache_begin<CacheBegin>
|
, cache_begin<CacheBegin>
|
||||||
, compare_hash<CompareHash>
|
, compare_hash<CompareHash>
|
||||||
|
, incremental<Incremental>
|
||||||
> unordered_multiset_type;
|
> unordered_multiset_type;
|
||||||
typedef typename unordered_multiset_type::bucket_traits bucket_traits;
|
typedef typename unordered_multiset_type::bucket_traits bucket_traits;
|
||||||
|
|
||||||
@@ -110,8 +115,9 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash>::test_impl()
|
|||||||
}
|
}
|
||||||
|
|
||||||
//test: constructor, iterator, clear, reverse_iterator, front, back, size:
|
//test: constructor, iterator, clear, reverse_iterator, front, back, size:
|
||||||
template<class ValueTraits, bool CacheBegin, bool CompareHash>
|
template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
|
||||||
void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash>::test_sort(std::vector<typename ValueTraits::value_type>& values)
|
void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>
|
||||||
|
::test_sort(std::vector<typename ValueTraits::value_type>& values)
|
||||||
{
|
{
|
||||||
typedef typename ValueTraits::value_type value_type;
|
typedef typename ValueTraits::value_type value_type;
|
||||||
typedef unordered_multiset
|
typedef unordered_multiset
|
||||||
@@ -120,21 +126,29 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash>::test_sort(st
|
|||||||
, constant_time_size<value_type::constant_time_size>
|
, constant_time_size<value_type::constant_time_size>
|
||||||
, cache_begin<CacheBegin>
|
, cache_begin<CacheBegin>
|
||||||
, compare_hash<CompareHash>
|
, compare_hash<CompareHash>
|
||||||
|
, incremental<Incremental>
|
||||||
> unordered_multiset_type;
|
> unordered_multiset_type;
|
||||||
typedef typename unordered_multiset_type::bucket_traits bucket_traits;
|
typedef typename unordered_multiset_type::bucket_traits bucket_traits;
|
||||||
|
|
||||||
typename unordered_multiset_type::bucket_type buckets [BucketSize];
|
typename unordered_multiset_type::bucket_type buckets [BucketSize];
|
||||||
unordered_multiset_type testset1(values.begin(), values.end(), bucket_traits(buckets, BucketSize));
|
unordered_multiset_type testset1(values.begin(), values.end(), bucket_traits(buckets, BucketSize));
|
||||||
|
|
||||||
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
if(Incremental){
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
{ int init_values [] = { 4, 5, 1, 2, 2, 3 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
}
|
||||||
testset1.clear();
|
testset1.clear();
|
||||||
BOOST_TEST (testset1.empty());
|
BOOST_TEST (testset1.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
//test: insert, const_iterator, const_reverse_iterator, erase, iterator_to:
|
//test: insert, const_iterator, const_reverse_iterator, erase, iterator_to:
|
||||||
template<class ValueTraits, bool CacheBegin, bool CompareHash>
|
template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
|
||||||
void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash>::test_insert(std::vector<typename ValueTraits::value_type>& values)
|
void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>
|
||||||
|
::test_insert(std::vector<typename ValueTraits::value_type>& values)
|
||||||
{
|
{
|
||||||
typedef typename ValueTraits::value_type value_type;
|
typedef typename ValueTraits::value_type value_type;
|
||||||
typedef unordered_multiset
|
typedef unordered_multiset
|
||||||
@@ -143,54 +157,100 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash>::test_insert(
|
|||||||
, constant_time_size<value_type::constant_time_size>
|
, constant_time_size<value_type::constant_time_size>
|
||||||
, cache_begin<CacheBegin>
|
, cache_begin<CacheBegin>
|
||||||
, compare_hash<CompareHash>
|
, compare_hash<CompareHash>
|
||||||
|
, incremental<Incremental>
|
||||||
> unordered_multiset_type;
|
> unordered_multiset_type;
|
||||||
typedef typename unordered_multiset_type::bucket_traits bucket_traits;
|
typedef typename unordered_multiset_type::bucket_traits bucket_traits;
|
||||||
typedef typename unordered_multiset_type::iterator iterator;
|
typedef typename unordered_multiset_type::iterator iterator;
|
||||||
{
|
typename unordered_multiset_type::bucket_type buckets [BucketSize];
|
||||||
typename unordered_multiset_type::bucket_type buckets [BucketSize];
|
unordered_multiset_type testset(bucket_traits(buckets, BucketSize));
|
||||||
unordered_multiset_type testset(bucket_traits(buckets, BucketSize));
|
|
||||||
|
|
||||||
testset.insert(&values[0] + 2, &values[0] + 5);
|
testset.insert(&values[0] + 2, &values[0] + 5);
|
||||||
|
|
||||||
const unordered_multiset_type& const_testset = testset;
|
const unordered_multiset_type& const_testset = testset;
|
||||||
{ int init_values [] = { 1, 4, 5 };
|
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
|
|
||||||
|
|
||||||
typename unordered_multiset_type::iterator i = testset.begin();
|
if(Incremental){
|
||||||
BOOST_TEST (i->value_ == 1);
|
{
|
||||||
|
{ int init_values [] = { 4, 5, 1 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
|
||||||
|
|
||||||
i = testset.insert (values[0]);
|
typename unordered_multiset_type::iterator i = testset.begin();
|
||||||
BOOST_TEST (&*i == &values[0]);
|
BOOST_TEST (i->value_ == 4);
|
||||||
|
|
||||||
i = testset.iterator_to (values[2]);
|
|
||||||
BOOST_TEST (&*i == &values[2]);
|
|
||||||
testset.erase(i);
|
|
||||||
|
|
||||||
{ int init_values [] = { 1, 3, 5 };
|
i = testset.insert (values[0]);
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
|
BOOST_TEST (&*i == &values[0]);
|
||||||
testset.clear();
|
|
||||||
testset.insert(&values[0], &values[0] + values.size());
|
i = testset.iterator_to (values[2]);
|
||||||
|
BOOST_TEST (&*i == &values[2]);
|
||||||
|
testset.erase(i);
|
||||||
|
|
||||||
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
{ int init_values [] = { 5, 1, 3 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
|
||||||
|
testset.clear();
|
||||||
|
testset.insert(&values[0], &values[0] + values.size());
|
||||||
|
|
||||||
BOOST_TEST (testset.erase(1) == 1);
|
{ int init_values [] = { 4, 5, 1, 2, 2, 3 };
|
||||||
BOOST_TEST (testset.erase(2) == 2);
|
TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
|
||||||
BOOST_TEST (testset.erase(3) == 1);
|
|
||||||
BOOST_TEST (testset.erase(4) == 1);
|
|
||||||
BOOST_TEST (testset.erase(5) == 1);
|
|
||||||
BOOST_TEST (testset.empty() == true);
|
|
||||||
|
|
||||||
//Now with a single bucket
|
BOOST_TEST (testset.erase(1) == 1);
|
||||||
typename unordered_multiset_type::bucket_type single_bucket[1];
|
BOOST_TEST (testset.erase(2) == 2);
|
||||||
unordered_multiset_type testset2(bucket_traits(single_bucket, 1));
|
BOOST_TEST (testset.erase(3) == 1);
|
||||||
testset2.insert(&values[0], &values[0] + values.size());
|
BOOST_TEST (testset.erase(4) == 1);
|
||||||
BOOST_TEST (testset2.erase(5) == 1);
|
BOOST_TEST (testset.erase(5) == 1);
|
||||||
BOOST_TEST (testset2.erase(2) == 2);
|
BOOST_TEST (testset.empty() == true);
|
||||||
BOOST_TEST (testset2.erase(1) == 1);
|
|
||||||
BOOST_TEST (testset2.erase(4) == 1);
|
//Now with a single bucket
|
||||||
BOOST_TEST (testset2.erase(3) == 1);
|
typename unordered_multiset_type::bucket_type single_bucket[1];
|
||||||
BOOST_TEST (testset2.empty() == true);
|
unordered_multiset_type testset2(bucket_traits(single_bucket, 1));
|
||||||
|
testset2.insert(&values[0], &values[0] + values.size());
|
||||||
|
BOOST_TEST (testset2.erase(5) == 1);
|
||||||
|
BOOST_TEST (testset2.erase(2) == 2);
|
||||||
|
BOOST_TEST (testset2.erase(1) == 1);
|
||||||
|
BOOST_TEST (testset2.erase(4) == 1);
|
||||||
|
BOOST_TEST (testset2.erase(3) == 1);
|
||||||
|
BOOST_TEST (testset2.empty() == true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
{
|
||||||
|
{ int init_values [] = { 1, 4, 5 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
|
||||||
|
|
||||||
|
typename unordered_multiset_type::iterator i = testset.begin();
|
||||||
|
BOOST_TEST (i->value_ == 1);
|
||||||
|
|
||||||
|
i = testset.insert (values[0]);
|
||||||
|
BOOST_TEST (&*i == &values[0]);
|
||||||
|
|
||||||
|
i = testset.iterator_to (values[2]);
|
||||||
|
BOOST_TEST (&*i == &values[2]);
|
||||||
|
testset.erase(i);
|
||||||
|
|
||||||
|
{ int init_values [] = { 1, 3, 5 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
|
||||||
|
testset.clear();
|
||||||
|
testset.insert(&values[0], &values[0] + values.size());
|
||||||
|
|
||||||
|
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
|
||||||
|
|
||||||
|
BOOST_TEST (testset.erase(1) == 1);
|
||||||
|
BOOST_TEST (testset.erase(2) == 2);
|
||||||
|
BOOST_TEST (testset.erase(3) == 1);
|
||||||
|
BOOST_TEST (testset.erase(4) == 1);
|
||||||
|
BOOST_TEST (testset.erase(5) == 1);
|
||||||
|
BOOST_TEST (testset.empty() == true);
|
||||||
|
|
||||||
|
//Now with a single bucket
|
||||||
|
typename unordered_multiset_type::bucket_type single_bucket[1];
|
||||||
|
unordered_multiset_type testset2(bucket_traits(single_bucket, 1));
|
||||||
|
testset2.insert(&values[0], &values[0] + values.size());
|
||||||
|
BOOST_TEST (testset2.erase(5) == 1);
|
||||||
|
BOOST_TEST (testset2.erase(2) == 2);
|
||||||
|
BOOST_TEST (testset2.erase(1) == 1);
|
||||||
|
BOOST_TEST (testset2.erase(4) == 1);
|
||||||
|
BOOST_TEST (testset2.erase(3) == 1);
|
||||||
|
BOOST_TEST (testset2.empty() == true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
//Now erase just one per loop
|
//Now erase just one per loop
|
||||||
@@ -270,11 +330,12 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash>::test_insert(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//test: insert (seq-version), swap, erase (seq-version), size:
|
//test: insert (seq-version), swap, erase (seq-version), size:
|
||||||
template<class ValueTraits, bool CacheBegin, bool CompareHash>
|
template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
|
||||||
void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash>::test_swap(std::vector<typename ValueTraits::value_type>& values)
|
void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>::
|
||||||
|
test_swap(std::vector<typename ValueTraits::value_type>& values)
|
||||||
{
|
{
|
||||||
typedef typename ValueTraits::value_type value_type;
|
typedef typename ValueTraits::value_type value_type;
|
||||||
typedef unordered_multiset
|
typedef unordered_multiset
|
||||||
@@ -283,17 +344,30 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash>::test_swap(st
|
|||||||
, constant_time_size<value_type::constant_time_size>
|
, constant_time_size<value_type::constant_time_size>
|
||||||
, cache_begin<CacheBegin>
|
, cache_begin<CacheBegin>
|
||||||
, compare_hash<CompareHash>
|
, compare_hash<CompareHash>
|
||||||
|
, incremental<Incremental>
|
||||||
> unordered_multiset_type;
|
> unordered_multiset_type;
|
||||||
typedef typename unordered_multiset_type::bucket_traits bucket_traits;
|
typedef typename unordered_multiset_type::bucket_traits bucket_traits;
|
||||||
typename unordered_multiset_type::bucket_type buckets [BucketSize];
|
typename unordered_multiset_type::bucket_type buckets [BucketSize];
|
||||||
{
|
|
||||||
typename unordered_multiset_type::bucket_type buckets2 [BucketSize];
|
|
||||||
unordered_multiset_type testset1(&values[0], &values[0] + 2, bucket_traits(buckets, BucketSize));
|
|
||||||
unordered_multiset_type testset2(bucket_traits(buckets2, BucketSize));
|
|
||||||
|
|
||||||
testset2.insert (&values[0] + 2, &values[0] + 6);
|
typename unordered_multiset_type::bucket_type buckets2 [BucketSize];
|
||||||
testset1.swap (testset2);
|
unordered_multiset_type testset1(&values[0], &values[0] + 2, bucket_traits(buckets, BucketSize));
|
||||||
|
unordered_multiset_type testset2(bucket_traits(buckets2, BucketSize));
|
||||||
|
|
||||||
|
testset2.insert (&values[0] + 2, &values[0] + 6);
|
||||||
|
testset1.swap (testset2);
|
||||||
|
|
||||||
|
if(Incremental){
|
||||||
|
{ int init_values [] = { 4, 5, 1, 2 };
|
||||||
|
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[4]), testset1.end());
|
||||||
|
BOOST_TEST (testset1.size() == 1);
|
||||||
|
// BOOST_TEST (&testset1.front() == &values[3]);
|
||||||
|
BOOST_TEST (&*testset1.begin() == &values[2]);
|
||||||
|
}
|
||||||
|
else{
|
||||||
{ int init_values [] = { 1, 2, 4, 5 };
|
{ int init_values [] = { 1, 2, 4, 5 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
@@ -306,9 +380,13 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash>::test_swap(st
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//test: rehash:
|
//test: rehash:
|
||||||
template<class ValueTraits, bool CacheBegin, bool CompareHash>
|
|
||||||
void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash>::test_rehash(std::vector<typename ValueTraits::value_type>& values)
|
template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
|
||||||
|
void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>
|
||||||
|
::test_rehash(std::vector<typename ValueTraits::value_type>& values, detail::true_)
|
||||||
{
|
{
|
||||||
typedef typename ValueTraits::value_type value_type;
|
typedef typename ValueTraits::value_type value_type;
|
||||||
typedef unordered_multiset
|
typedef unordered_multiset
|
||||||
@@ -317,6 +395,135 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash>::test_rehash(
|
|||||||
, constant_time_size<value_type::constant_time_size>
|
, constant_time_size<value_type::constant_time_size>
|
||||||
, cache_begin<CacheBegin>
|
, cache_begin<CacheBegin>
|
||||||
, compare_hash<CompareHash>
|
, compare_hash<CompareHash>
|
||||||
|
, incremental<Incremental>
|
||||||
|
> unordered_multiset_type;
|
||||||
|
typedef typename unordered_multiset_type::bucket_traits bucket_traits;
|
||||||
|
//Build a uset
|
||||||
|
typename unordered_multiset_type::bucket_type buckets1 [BucketSize];
|
||||||
|
typename unordered_multiset_type::bucket_type buckets2 [BucketSize*2];
|
||||||
|
unordered_multiset_type testset1(&values[0], &values[0] + values.size(), bucket_traits(buckets1, BucketSize));
|
||||||
|
//Test current state
|
||||||
|
BOOST_TEST(testset1.split_count() == BucketSize/2);
|
||||||
|
{ int init_values [] = { 4, 5, 1, 2, 2, 3 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
//Incremental rehash step
|
||||||
|
BOOST_TEST (testset1.incremental_rehash() == true);
|
||||||
|
BOOST_TEST(testset1.split_count() == (BucketSize/2+1));
|
||||||
|
{ int init_values [] = { 5, 1, 2, 2, 3, 4 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
//Rest of incremental rehashes should lead to the same sequence
|
||||||
|
for(std::size_t split_bucket = testset1.split_count(); split_bucket != BucketSize; ++split_bucket){
|
||||||
|
BOOST_TEST (testset1.incremental_rehash() == true);
|
||||||
|
BOOST_TEST(testset1.split_count() == (split_bucket+1));
|
||||||
|
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
}
|
||||||
|
//This incremental rehash should fail because we've reached the end of the bucket array
|
||||||
|
BOOST_TEST (testset1.incremental_rehash() == false);
|
||||||
|
BOOST_TEST(testset1.split_count() == BucketSize);
|
||||||
|
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
|
//
|
||||||
|
//Try incremental hashing specifying a new bucket traits pointing to the same array
|
||||||
|
//
|
||||||
|
//This incremental rehash should fail because the new size is not twice the original
|
||||||
|
BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets1, BucketSize)) == false);
|
||||||
|
BOOST_TEST(testset1.split_count() == BucketSize);
|
||||||
|
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
|
//This incremental rehash should success because the new size is twice the original
|
||||||
|
//and split_count is the same as the old bucket count
|
||||||
|
BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets1, BucketSize*2)) == true);
|
||||||
|
BOOST_TEST(testset1.split_count() == BucketSize);
|
||||||
|
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
|
//This incremental rehash should also success because the new size is half the original
|
||||||
|
//and split_count is the same as the new bucket count
|
||||||
|
BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets1, BucketSize)) == true);
|
||||||
|
BOOST_TEST(testset1.split_count() == BucketSize);
|
||||||
|
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
|
//
|
||||||
|
//Try incremental hashing specifying a new bucket traits pointing to the same array
|
||||||
|
//
|
||||||
|
//This incremental rehash should fail because the new size is not twice the original
|
||||||
|
BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets2, BucketSize)) == false);
|
||||||
|
BOOST_TEST(testset1.split_count() == BucketSize);
|
||||||
|
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
|
//This incremental rehash should success because the new size is twice the original
|
||||||
|
//and split_count is the same as the old bucket count
|
||||||
|
BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets2, BucketSize*2)) == true);
|
||||||
|
BOOST_TEST(testset1.split_count() == BucketSize);
|
||||||
|
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
|
//This incremental rehash should also success because the new size is half the original
|
||||||
|
//and split_count is the same as the new bucket count
|
||||||
|
BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets1, BucketSize)) == true);
|
||||||
|
BOOST_TEST(testset1.split_count() == BucketSize);
|
||||||
|
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
|
//Full shrink rehash
|
||||||
|
testset1.rehash(bucket_traits(buckets1, 4));
|
||||||
|
BOOST_TEST (testset1.size() == values.size());
|
||||||
|
BOOST_TEST (testset1.incremental_rehash() == false);
|
||||||
|
{ int init_values [] = { 4, 5, 1, 2, 2, 3 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
//Full shrink rehash again
|
||||||
|
testset1.rehash(bucket_traits(buckets1, 2));
|
||||||
|
BOOST_TEST (testset1.size() == values.size());
|
||||||
|
BOOST_TEST (testset1.incremental_rehash() == false);
|
||||||
|
{ int init_values [] = { 2, 2, 4, 3, 5, 1 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
//Full growing rehash
|
||||||
|
testset1.rehash(bucket_traits(buckets1, BucketSize));
|
||||||
|
BOOST_TEST (testset1.size() == values.size());
|
||||||
|
BOOST_TEST (testset1.incremental_rehash() == false);
|
||||||
|
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
//Incremental rehash shrinking
|
||||||
|
//First incremental rehashes should lead to the same sequence
|
||||||
|
for(std::size_t split_bucket = testset1.split_count(); split_bucket > 6; --split_bucket){
|
||||||
|
BOOST_TEST (testset1.incremental_rehash(false) == true);
|
||||||
|
BOOST_TEST(testset1.split_count() == (split_bucket-1));
|
||||||
|
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
}
|
||||||
|
//Incremental rehash step
|
||||||
|
BOOST_TEST (testset1.incremental_rehash(false) == true);
|
||||||
|
BOOST_TEST(testset1.split_count() == (BucketSize/2+1));
|
||||||
|
{ int init_values [] = { 5, 1, 2, 2, 3, 4 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
//Incremental rehash step 2
|
||||||
|
BOOST_TEST (testset1.incremental_rehash(false) == true);
|
||||||
|
BOOST_TEST(testset1.split_count() == (BucketSize/2));
|
||||||
|
{ int init_values [] = { 4, 5, 1, 2, 2, 3 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
//This incremental rehash should fail because we've reached the half of the bucket array
|
||||||
|
BOOST_TEST(testset1.incremental_rehash(false) == false);
|
||||||
|
BOOST_TEST(testset1.split_count() == BucketSize/2);
|
||||||
|
{ int init_values [] = { 4, 5, 1, 2, 2, 3 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
}
|
||||||
|
template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
|
||||||
|
void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>
|
||||||
|
::test_rehash(std::vector<typename ValueTraits::value_type>& values, detail::false_)
|
||||||
|
{
|
||||||
|
typedef typename ValueTraits::value_type value_type;
|
||||||
|
typedef unordered_multiset
|
||||||
|
<value_type
|
||||||
|
, value_traits<ValueTraits>
|
||||||
|
, constant_time_size<value_type::constant_time_size>
|
||||||
|
, cache_begin<CacheBegin>
|
||||||
|
, compare_hash<CompareHash>
|
||||||
|
, incremental<Incremental>
|
||||||
> unordered_multiset_type;
|
> unordered_multiset_type;
|
||||||
typedef typename unordered_multiset_type::bucket_traits bucket_traits;
|
typedef typename unordered_multiset_type::bucket_traits bucket_traits;
|
||||||
|
|
||||||
@@ -325,36 +532,37 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash>::test_rehash(
|
|||||||
typename unordered_multiset_type::bucket_type buckets3 [BucketSize*2];
|
typename unordered_multiset_type::bucket_type buckets3 [BucketSize*2];
|
||||||
|
|
||||||
unordered_multiset_type testset1(&values[0], &values[0] + 6, bucket_traits(buckets1, BucketSize));
|
unordered_multiset_type testset1(&values[0], &values[0] + 6, bucket_traits(buckets1, BucketSize));
|
||||||
BOOST_TEST (testset1.size() == 6);
|
BOOST_TEST (testset1.size() == values.size());
|
||||||
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
testset1.rehash(bucket_traits(buckets2, 2));
|
testset1.rehash(bucket_traits(buckets2, 2));
|
||||||
BOOST_TEST (testset1.size() == 6);
|
BOOST_TEST (testset1.size() == values.size());
|
||||||
{ int init_values [] = { 4, 2, 2, 5, 3, 1 };
|
{ int init_values [] = { 4, 2, 2, 5, 3, 1 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
testset1.rehash(bucket_traits(buckets3, BucketSize*2));
|
testset1.rehash(bucket_traits(buckets3, BucketSize*2));
|
||||||
BOOST_TEST (testset1.size() == 6);
|
BOOST_TEST (testset1.size() == values.size());
|
||||||
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
//Now rehash reducing the buckets
|
//Now rehash reducing the buckets
|
||||||
testset1.rehash(bucket_traits(buckets3, 2));
|
testset1.rehash(bucket_traits(buckets3, 2));
|
||||||
BOOST_TEST (testset1.size() == 6);
|
BOOST_TEST (testset1.size() == values.size());
|
||||||
{ int init_values [] = { 4, 2, 2, 5, 3, 1 };
|
{ int init_values [] = { 4, 2, 2, 5, 3, 1 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
//Now rehash increasing the buckets
|
//Now rehash increasing the buckets
|
||||||
testset1.rehash(bucket_traits(buckets3, BucketSize*2));
|
testset1.rehash(bucket_traits(buckets3, BucketSize*2));
|
||||||
BOOST_TEST (testset1.size() == 6);
|
BOOST_TEST (testset1.size() == values.size());
|
||||||
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
}
|
}
|
||||||
|
|
||||||
//test: find, equal_range (lower_bound, upper_bound):
|
//test: find, equal_range (lower_bound, upper_bound):
|
||||||
template<class ValueTraits, bool CacheBegin, bool CompareHash>
|
template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
|
||||||
void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash>::test_find(std::vector<typename ValueTraits::value_type>& values)
|
void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>::
|
||||||
|
test_find(std::vector<typename ValueTraits::value_type>& values)
|
||||||
{
|
{
|
||||||
typedef typename ValueTraits::value_type value_type;
|
typedef typename ValueTraits::value_type value_type;
|
||||||
typedef unordered_multiset
|
typedef unordered_multiset
|
||||||
@@ -363,6 +571,7 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash>::test_find(st
|
|||||||
, constant_time_size<value_type::constant_time_size>
|
, constant_time_size<value_type::constant_time_size>
|
||||||
, cache_begin<CacheBegin>
|
, cache_begin<CacheBegin>
|
||||||
, compare_hash<CompareHash>
|
, compare_hash<CompareHash>
|
||||||
|
, incremental<Incremental>
|
||||||
> unordered_multiset_type;
|
> unordered_multiset_type;
|
||||||
typedef typename unordered_multiset_type::bucket_traits bucket_traits;
|
typedef typename unordered_multiset_type::bucket_traits bucket_traits;
|
||||||
|
|
||||||
@@ -387,8 +596,8 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash>::test_find(st
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class ValueTraits, bool CacheBegin, bool CompareHash>
|
template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
|
||||||
void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash>
|
void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash, Incremental>
|
||||||
::test_clone(std::vector<typename ValueTraits::value_type>& values)
|
::test_clone(std::vector<typename ValueTraits::value_type>& values)
|
||||||
{
|
{
|
||||||
typedef typename ValueTraits::value_type value_type;
|
typedef typename ValueTraits::value_type value_type;
|
||||||
@@ -398,6 +607,7 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash>
|
|||||||
, constant_time_size<value_type::constant_time_size>
|
, constant_time_size<value_type::constant_time_size>
|
||||||
, cache_begin<CacheBegin>
|
, cache_begin<CacheBegin>
|
||||||
, compare_hash<CompareHash>
|
, compare_hash<CompareHash>
|
||||||
|
, incremental<Incremental>
|
||||||
> unordered_multiset_type;
|
> unordered_multiset_type;
|
||||||
typedef typename unordered_multiset_type::bucket_traits bucket_traits;
|
typedef typename unordered_multiset_type::bucket_traits bucket_traits;
|
||||||
{
|
{
|
||||||
@@ -442,7 +652,7 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash>
|
|||||||
unordered_multiset_type testset2 (bucket_traits(buckets2, BucketSize*2));
|
unordered_multiset_type testset2 (bucket_traits(buckets2, BucketSize*2));
|
||||||
|
|
||||||
testset2.clone_from(testset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>());
|
testset2.clone_from(testset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>());
|
||||||
//Ordering is not guarantee in the cloning so insert data in a set and test
|
//Ordering is not guaranteed in the cloning so insert data in a set and test
|
||||||
std::multiset<typename ValueTraits::value_type>
|
std::multiset<typename ValueTraits::value_type>
|
||||||
src(testset1.begin(), testset1.end());
|
src(testset1.begin(), testset1.end());
|
||||||
std::multiset<typename ValueTraits::value_type>
|
std::multiset<typename ValueTraits::value_type>
|
||||||
@@ -453,7 +663,7 @@ void test_unordered_multiset<ValueTraits, CacheBegin, CompareHash>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class VoidPointer, bool constant_time_size>
|
template<class VoidPointer, bool constant_time_size, bool Incremental>
|
||||||
class test_main_template
|
class test_main_template
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -471,6 +681,7 @@ class test_main_template
|
|||||||
>::type
|
>::type
|
||||||
, true
|
, true
|
||||||
, false
|
, false
|
||||||
|
, Incremental
|
||||||
>::test_all(data);
|
>::test_all(data);
|
||||||
|
|
||||||
test_unordered_multiset < typename detail::get_member_value_traits
|
test_unordered_multiset < typename detail::get_member_value_traits
|
||||||
@@ -482,14 +693,15 @@ class test_main_template
|
|||||||
>::type
|
>::type
|
||||||
, false
|
, false
|
||||||
, false
|
, false
|
||||||
|
, Incremental
|
||||||
>::test_all(data);
|
>::test_all(data);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class VoidPointer>
|
template<class VoidPointer, bool Incremental>
|
||||||
class test_main_template<VoidPointer, false>
|
class test_main_template<VoidPointer, false, Incremental>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
int operator()()
|
int operator()()
|
||||||
@@ -506,6 +718,7 @@ class test_main_template<VoidPointer, false>
|
|||||||
>::type
|
>::type
|
||||||
, true
|
, true
|
||||||
, false
|
, false
|
||||||
|
, Incremental
|
||||||
>::test_all(data);
|
>::test_all(data);
|
||||||
|
|
||||||
test_unordered_multiset < typename detail::get_member_value_traits
|
test_unordered_multiset < typename detail::get_member_value_traits
|
||||||
@@ -517,6 +730,7 @@ class test_main_template<VoidPointer, false>
|
|||||||
>::type
|
>::type
|
||||||
, false
|
, false
|
||||||
, false
|
, false
|
||||||
|
, Incremental
|
||||||
>::test_all(data);
|
>::test_all(data);
|
||||||
|
|
||||||
test_unordered_multiset < typename detail::get_base_value_traits
|
test_unordered_multiset < typename detail::get_base_value_traits
|
||||||
@@ -525,6 +739,7 @@ class test_main_template<VoidPointer, false>
|
|||||||
>::type
|
>::type
|
||||||
, true
|
, true
|
||||||
, true
|
, true
|
||||||
|
, Incremental
|
||||||
>::test_all(data);
|
>::test_all(data);
|
||||||
|
|
||||||
test_unordered_multiset < typename detail::get_member_value_traits
|
test_unordered_multiset < typename detail::get_member_value_traits
|
||||||
@@ -536,6 +751,7 @@ class test_main_template<VoidPointer, false>
|
|||||||
>::type
|
>::type
|
||||||
, false
|
, false
|
||||||
, true
|
, true
|
||||||
|
, Incremental
|
||||||
>::test_all(data);
|
>::test_all(data);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -543,10 +759,14 @@ class test_main_template<VoidPointer, false>
|
|||||||
|
|
||||||
int main( int, char* [] )
|
int main( int, char* [] )
|
||||||
{
|
{
|
||||||
test_main_template<void*, false>()();
|
test_main_template<void*, false, true>()();
|
||||||
test_main_template<smart_ptr<void>, false>()();
|
test_main_template<smart_ptr<void>, false, true>()();
|
||||||
test_main_template<void*, true>()();
|
test_main_template<void*, true, true>()();
|
||||||
test_main_template<smart_ptr<void>, true>()();
|
test_main_template<smart_ptr<void>, true, true>()();
|
||||||
|
test_main_template<void*, false, false>()();
|
||||||
|
test_main_template<smart_ptr<void>, false, false>()();
|
||||||
|
test_main_template<void*, true, true>()();
|
||||||
|
test_main_template<smart_ptr<void>, true, false>()();
|
||||||
return boost::report_errors();
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -24,9 +24,9 @@
|
|||||||
|
|
||||||
using namespace boost::intrusive;
|
using namespace boost::intrusive;
|
||||||
|
|
||||||
static const std::size_t BucketSize = 11;
|
static const std::size_t BucketSize = 8;
|
||||||
|
|
||||||
template<class ValueTraits, bool CacheBegin, bool CompareHash>
|
template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
|
||||||
struct test_unordered_set
|
struct test_unordered_set
|
||||||
{
|
{
|
||||||
typedef typename ValueTraits::value_type value_type;
|
typedef typename ValueTraits::value_type value_type;
|
||||||
@@ -34,14 +34,16 @@ struct test_unordered_set
|
|||||||
static void test_sort(std::vector<value_type>& values);
|
static void test_sort(std::vector<value_type>& values);
|
||||||
static void test_insert(std::vector<value_type>& values);
|
static void test_insert(std::vector<value_type>& values);
|
||||||
static void test_swap(std::vector<value_type>& values);
|
static void test_swap(std::vector<value_type>& values);
|
||||||
static void test_rehash(std::vector<value_type>& values);
|
static void test_rehash(std::vector<value_type>& values, detail::true_);
|
||||||
|
static void test_rehash(std::vector<value_type>& values, detail::false_);
|
||||||
static void test_find(std::vector<value_type>& values);
|
static void test_find(std::vector<value_type>& values);
|
||||||
static void test_impl();
|
static void test_impl();
|
||||||
static void test_clone(std::vector<value_type>& values);
|
static void test_clone(std::vector<value_type>& values);
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class ValueTraits, bool CacheBegin, bool CompareHash>
|
template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
|
||||||
void test_unordered_set<ValueTraits, CacheBegin, CompareHash>::test_all(std::vector<typename ValueTraits::value_type>& values)
|
void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::
|
||||||
|
test_all(std::vector<typename ValueTraits::value_type>& values)
|
||||||
{
|
{
|
||||||
typedef typename ValueTraits::value_type value_type;
|
typedef typename ValueTraits::value_type value_type;
|
||||||
typedef unordered_set
|
typedef unordered_set
|
||||||
@@ -50,6 +52,7 @@ void test_unordered_set<ValueTraits, CacheBegin, CompareHash>::test_all(std::vec
|
|||||||
, constant_time_size<value_type::constant_time_size>
|
, constant_time_size<value_type::constant_time_size>
|
||||||
, cache_begin<CacheBegin>
|
, cache_begin<CacheBegin>
|
||||||
, compare_hash<CompareHash>
|
, compare_hash<CompareHash>
|
||||||
|
, incremental<Incremental>
|
||||||
> unordered_set_type;
|
> unordered_set_type;
|
||||||
typedef typename unordered_set_type::bucket_traits bucket_traits;
|
typedef typename unordered_set_type::bucket_traits bucket_traits;
|
||||||
{
|
{
|
||||||
@@ -70,15 +73,15 @@ void test_unordered_set<ValueTraits, CacheBegin, CompareHash>::test_all(std::vec
|
|||||||
test_sort(values);
|
test_sort(values);
|
||||||
test_insert(values);
|
test_insert(values);
|
||||||
test_swap(values);
|
test_swap(values);
|
||||||
test_rehash(values);
|
test_rehash(values, detail::bool_<Incremental>());
|
||||||
test_find(values);
|
test_find(values);
|
||||||
test_impl();
|
test_impl();
|
||||||
test_clone(values);
|
test_clone(values);
|
||||||
}
|
}
|
||||||
|
|
||||||
//test case due to an error in tree implementation:
|
//test case due to an error in tree implementation:
|
||||||
template<class ValueTraits, bool CacheBegin, bool CompareHash>
|
template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
|
||||||
void test_unordered_set<ValueTraits, CacheBegin, CompareHash>::test_impl()
|
void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::test_impl()
|
||||||
{
|
{
|
||||||
typedef typename ValueTraits::value_type value_type;
|
typedef typename ValueTraits::value_type value_type;
|
||||||
typedef unordered_set
|
typedef unordered_set
|
||||||
@@ -87,6 +90,7 @@ void test_unordered_set<ValueTraits, CacheBegin, CompareHash>::test_impl()
|
|||||||
, constant_time_size<value_type::constant_time_size>
|
, constant_time_size<value_type::constant_time_size>
|
||||||
, cache_begin<CacheBegin>
|
, cache_begin<CacheBegin>
|
||||||
, compare_hash<CompareHash>
|
, compare_hash<CompareHash>
|
||||||
|
, incremental<Incremental>
|
||||||
> unordered_set_type;
|
> unordered_set_type;
|
||||||
typedef typename unordered_set_type::bucket_traits bucket_traits;
|
typedef typename unordered_set_type::bucket_traits bucket_traits;
|
||||||
|
|
||||||
@@ -107,8 +111,9 @@ void test_unordered_set<ValueTraits, CacheBegin, CompareHash>::test_impl()
|
|||||||
}
|
}
|
||||||
|
|
||||||
//test: constructor, iterator, clear, reverse_iterator, front, back, size:
|
//test: constructor, iterator, clear, reverse_iterator, front, back, size:
|
||||||
template<class ValueTraits, bool CacheBegin, bool CompareHash>
|
template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
|
||||||
void test_unordered_set<ValueTraits, CacheBegin, CompareHash>::test_sort(std::vector<typename ValueTraits::value_type>& values)
|
void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::
|
||||||
|
test_sort(std::vector<typename ValueTraits::value_type>& values)
|
||||||
{
|
{
|
||||||
typedef typename ValueTraits::value_type value_type;
|
typedef typename ValueTraits::value_type value_type;
|
||||||
typedef unordered_set
|
typedef unordered_set
|
||||||
@@ -117,23 +122,31 @@ void test_unordered_set<ValueTraits, CacheBegin, CompareHash>::test_sort(std::ve
|
|||||||
, constant_time_size<value_type::constant_time_size>
|
, constant_time_size<value_type::constant_time_size>
|
||||||
, cache_begin<CacheBegin>
|
, cache_begin<CacheBegin>
|
||||||
, compare_hash<CompareHash>
|
, compare_hash<CompareHash>
|
||||||
|
, incremental<Incremental>
|
||||||
> unordered_set_type;
|
> unordered_set_type;
|
||||||
typedef typename unordered_set_type::bucket_traits bucket_traits;
|
typedef typename unordered_set_type::bucket_traits bucket_traits;
|
||||||
|
|
||||||
typename unordered_set_type::bucket_type buckets [BucketSize];
|
typename unordered_set_type::bucket_type buckets [BucketSize];
|
||||||
unordered_set_type testset1(values.begin(), values.end(), bucket_traits(buckets, BucketSize));
|
unordered_set_type testset1(values.begin(), values.end(), bucket_traits(buckets, BucketSize));
|
||||||
|
|
||||||
BOOST_TEST (5 == std::distance(testset1.begin(), testset1.end()));
|
BOOST_TEST (5 == std::distance(testset1.begin(), testset1.end()));
|
||||||
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
if(Incremental){
|
||||||
|
{ int init_values [] = { 4, 5, 1, 2, 3 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
}
|
||||||
|
|
||||||
testset1.clear();
|
testset1.clear();
|
||||||
BOOST_TEST (testset1.empty());
|
BOOST_TEST (testset1.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
//test: insert, const_iterator, const_reverse_iterator, erase, iterator_to:
|
//test: insert, const_iterator, const_reverse_iterator, erase, iterator_to:
|
||||||
template<class ValueTraits, bool CacheBegin, bool CompareHash>
|
template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
|
||||||
void test_unordered_set<ValueTraits, CacheBegin, CompareHash>::test_insert(std::vector<typename ValueTraits::value_type>& values)
|
void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::
|
||||||
|
test_insert(std::vector<typename ValueTraits::value_type>& values)
|
||||||
{
|
{
|
||||||
typedef typename ValueTraits::value_type value_type;
|
typedef typename ValueTraits::value_type value_type;
|
||||||
typedef unordered_set
|
typedef unordered_set
|
||||||
@@ -142,6 +155,7 @@ void test_unordered_set<ValueTraits, CacheBegin, CompareHash>::test_insert(std::
|
|||||||
, constant_time_size<value_type::constant_time_size>
|
, constant_time_size<value_type::constant_time_size>
|
||||||
, cache_begin<CacheBegin>
|
, cache_begin<CacheBegin>
|
||||||
, compare_hash<CompareHash>
|
, compare_hash<CompareHash>
|
||||||
|
, incremental<Incremental>
|
||||||
> unordered_set_type;
|
> unordered_set_type;
|
||||||
typedef typename unordered_set_type::bucket_traits bucket_traits;
|
typedef typename unordered_set_type::bucket_traits bucket_traits;
|
||||||
|
|
||||||
@@ -150,27 +164,47 @@ void test_unordered_set<ValueTraits, CacheBegin, CompareHash>::test_insert(std::
|
|||||||
testset.insert(&values[0] + 2, &values[0] + 5);
|
testset.insert(&values[0] + 2, &values[0] + 5);
|
||||||
|
|
||||||
const unordered_set_type& const_testset = testset;
|
const unordered_set_type& const_testset = testset;
|
||||||
{ int init_values [] = { 1, 4, 5 };
|
if(Incremental)
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
|
{
|
||||||
|
{ int init_values [] = { 4, 5, 1 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
|
||||||
|
typename unordered_set_type::iterator i = testset.begin();
|
||||||
|
BOOST_TEST (i->value_ == 4);
|
||||||
|
|
||||||
typename unordered_set_type::iterator i = testset.begin();
|
i = testset.insert(values[0]).first;
|
||||||
BOOST_TEST (i->value_ == 1);
|
BOOST_TEST (&*i == &values[0]);
|
||||||
|
|
||||||
i = testset.insert(values[0]).first;
|
i = testset.iterator_to (values[2]);
|
||||||
BOOST_TEST (&*i == &values[0]);
|
BOOST_TEST (&*i == &values[2]);
|
||||||
|
|
||||||
i = testset.iterator_to (values[2]);
|
testset.erase (i);
|
||||||
BOOST_TEST (&*i == &values[2]);
|
|
||||||
|
|
||||||
testset.erase (i);
|
{ int init_values [] = { 5, 1, 3 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
{ int init_values [] = { 1, 4, 5 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
|
||||||
|
typename unordered_set_type::iterator i = testset.begin();
|
||||||
|
BOOST_TEST (i->value_ == 1);
|
||||||
|
|
||||||
{ int init_values [] = { 1, 3, 5 };
|
i = testset.insert(values[0]).first;
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
|
BOOST_TEST (&*i == &values[0]);
|
||||||
|
|
||||||
|
i = testset.iterator_to (values[2]);
|
||||||
|
BOOST_TEST (&*i == &values[2]);
|
||||||
|
|
||||||
|
testset.erase (i);
|
||||||
|
|
||||||
|
{ int init_values [] = { 1, 3, 5 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//test: insert (seq-version), swap, erase (seq-version), size:
|
//test: insert (seq-version), swap, erase (seq-version), size:
|
||||||
template<class ValueTraits, bool CacheBegin, bool CompareHash>
|
template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
|
||||||
void test_unordered_set<ValueTraits, CacheBegin, CompareHash>::test_swap(std::vector<typename ValueTraits::value_type>& values)
|
void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::
|
||||||
|
test_swap(std::vector<typename ValueTraits::value_type>& values)
|
||||||
{
|
{
|
||||||
typedef typename ValueTraits::value_type value_type;
|
typedef typename ValueTraits::value_type value_type;
|
||||||
typedef unordered_set
|
typedef unordered_set
|
||||||
@@ -179,6 +213,7 @@ void test_unordered_set<ValueTraits, CacheBegin, CompareHash>::test_swap(std::ve
|
|||||||
, constant_time_size<value_type::constant_time_size>
|
, constant_time_size<value_type::constant_time_size>
|
||||||
, cache_begin<CacheBegin>
|
, cache_begin<CacheBegin>
|
||||||
, compare_hash<CompareHash>
|
, compare_hash<CompareHash>
|
||||||
|
, incremental<Incremental>
|
||||||
> unordered_set_type;
|
> unordered_set_type;
|
||||||
typedef typename unordered_set_type::bucket_traits bucket_traits;
|
typedef typename unordered_set_type::bucket_traits bucket_traits;
|
||||||
|
|
||||||
@@ -190,20 +225,30 @@ void test_unordered_set<ValueTraits, CacheBegin, CompareHash>::test_swap(std::ve
|
|||||||
testset2.insert (&values[0] + 2, &values[0] + 6);
|
testset2.insert (&values[0] + 2, &values[0] + 6);
|
||||||
testset1.swap (testset2);
|
testset1.swap (testset2);
|
||||||
|
|
||||||
{ int init_values [] = { 1, 2, 4, 5 };
|
if(Incremental){
|
||||||
|
{ int init_values [] = { 4, 5, 1, 2 };
|
||||||
|
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[4]), testset1.end());
|
||||||
|
BOOST_TEST (testset1.size() == 1);
|
||||||
|
BOOST_TEST (&*testset1.begin() == &values[2]);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
{ int init_values [] = { 1, 2, 4, 5 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
{ int init_values [] = { 2, 3 };
|
{ int init_values [] = { 2, 3 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset2.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset2.begin() ); }
|
||||||
|
testset1.erase (testset1.iterator_to(values[5]), testset1.end());
|
||||||
testset1.erase (testset1.iterator_to(values[5]), testset1.end());
|
BOOST_TEST (testset1.size() == 1);
|
||||||
BOOST_TEST (testset1.size() == 1);
|
BOOST_TEST (&*testset1.begin() == &values[3]);
|
||||||
// BOOST_TEST (&testset1.front() == &values[3]);
|
}
|
||||||
BOOST_TEST (&*testset1.begin() == &values[3]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//test: rehash:
|
//test: rehash:
|
||||||
template<class ValueTraits, bool CacheBegin, bool CompareHash>
|
template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
|
||||||
void test_unordered_set<ValueTraits, CacheBegin, CompareHash>::test_rehash(std::vector<typename ValueTraits::value_type>& values)
|
void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::
|
||||||
|
test_rehash(std::vector<typename ValueTraits::value_type>& values, detail::true_)
|
||||||
{
|
{
|
||||||
typedef typename ValueTraits::value_type value_type;
|
typedef typename ValueTraits::value_type value_type;
|
||||||
typedef unordered_set
|
typedef unordered_set
|
||||||
@@ -212,6 +257,137 @@ void test_unordered_set<ValueTraits, CacheBegin, CompareHash>::test_rehash(std::
|
|||||||
, constant_time_size<value_type::constant_time_size>
|
, constant_time_size<value_type::constant_time_size>
|
||||||
, cache_begin<CacheBegin>
|
, cache_begin<CacheBegin>
|
||||||
, compare_hash<CompareHash>
|
, compare_hash<CompareHash>
|
||||||
|
, incremental<Incremental>
|
||||||
|
> unordered_set_type;
|
||||||
|
typedef typename unordered_set_type::bucket_traits bucket_traits;
|
||||||
|
//Build a uset
|
||||||
|
typename unordered_set_type::bucket_type buckets1 [BucketSize];
|
||||||
|
typename unordered_set_type::bucket_type buckets2 [BucketSize*2];
|
||||||
|
unordered_set_type testset1(&values[0], &values[0] + 6, bucket_traits(buckets1, BucketSize));
|
||||||
|
//Test current state
|
||||||
|
BOOST_TEST(testset1.split_count() == BucketSize/2);
|
||||||
|
{ int init_values [] = { 4, 5, 1, 2, 3 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
//Incremental rehash step
|
||||||
|
BOOST_TEST (testset1.incremental_rehash() == true);
|
||||||
|
BOOST_TEST(testset1.split_count() == (BucketSize/2+1));
|
||||||
|
{ int init_values [] = { 5, 1, 2, 3, 4 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
//Rest of incremental rehashes should lead to the same sequence
|
||||||
|
for(std::size_t split_bucket = testset1.split_count(); split_bucket != BucketSize; ++split_bucket){
|
||||||
|
BOOST_TEST (testset1.incremental_rehash() == true);
|
||||||
|
BOOST_TEST(testset1.split_count() == (split_bucket+1));
|
||||||
|
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
}
|
||||||
|
//This incremental rehash should fail because we've reached the end of the bucket array
|
||||||
|
BOOST_TEST(testset1.incremental_rehash() == false);
|
||||||
|
BOOST_TEST(testset1.split_count() == BucketSize);
|
||||||
|
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
|
//
|
||||||
|
//Try incremental hashing specifying a new bucket traits pointing to the same array
|
||||||
|
//
|
||||||
|
//This incremental rehash should fail because the new size is not twice the original
|
||||||
|
BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets1, BucketSize)) == false);
|
||||||
|
BOOST_TEST(testset1.split_count() == BucketSize);
|
||||||
|
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
|
//This incremental rehash should success because the new size is twice the original
|
||||||
|
//and split_count is the same as the old bucket count
|
||||||
|
BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets1, BucketSize*2)) == true);
|
||||||
|
BOOST_TEST(testset1.split_count() == BucketSize);
|
||||||
|
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
|
//This incremental rehash should also success because the new size is half the original
|
||||||
|
//and split_count is the same as the new bucket count
|
||||||
|
BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets1, BucketSize)) == true);
|
||||||
|
BOOST_TEST(testset1.split_count() == BucketSize);
|
||||||
|
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
|
//
|
||||||
|
//Try incremental hashing specifying a new bucket traits pointing to the same array
|
||||||
|
//
|
||||||
|
//This incremental rehash should fail because the new size is not twice the original
|
||||||
|
BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets2, BucketSize)) == false);
|
||||||
|
BOOST_TEST(testset1.split_count() == BucketSize);
|
||||||
|
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
|
//This incremental rehash should success because the new size is twice the original
|
||||||
|
//and split_count is the same as the old bucket count
|
||||||
|
BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets2, BucketSize*2)) == true);
|
||||||
|
BOOST_TEST(testset1.split_count() == BucketSize);
|
||||||
|
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
|
//This incremental rehash should also success because the new size is half the original
|
||||||
|
//and split_count is the same as the new bucket count
|
||||||
|
BOOST_TEST(testset1.incremental_rehash(bucket_traits(buckets1, BucketSize)) == true);
|
||||||
|
BOOST_TEST(testset1.split_count() == BucketSize);
|
||||||
|
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
|
//Full shrink rehash
|
||||||
|
testset1.rehash(bucket_traits(buckets1, 4));
|
||||||
|
BOOST_TEST (testset1.size() == values.size()-1);
|
||||||
|
BOOST_TEST (testset1.incremental_rehash() == false);
|
||||||
|
{ int init_values [] = { 4, 5, 1, 2, 3 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
//Full shrink rehash again
|
||||||
|
testset1.rehash(bucket_traits(buckets1, 2));
|
||||||
|
BOOST_TEST (testset1.size() == values.size()-1);
|
||||||
|
BOOST_TEST (testset1.incremental_rehash() == false);
|
||||||
|
{ int init_values [] = { 2, 4, 3, 5, 1 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
//Full growing rehash
|
||||||
|
testset1.rehash(bucket_traits(buckets1, BucketSize));
|
||||||
|
BOOST_TEST (testset1.size() == values.size()-1);
|
||||||
|
BOOST_TEST (testset1.incremental_rehash() == false);
|
||||||
|
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
//Incremental rehash shrinking
|
||||||
|
//First incremental rehashes should lead to the same sequence
|
||||||
|
for(std::size_t split_bucket = testset1.split_count(); split_bucket > 6; --split_bucket){
|
||||||
|
BOOST_TEST (testset1.incremental_rehash(false) == true);
|
||||||
|
BOOST_TEST(testset1.split_count() == (split_bucket-1));
|
||||||
|
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
}
|
||||||
|
//Incremental rehash step
|
||||||
|
BOOST_TEST (testset1.incremental_rehash(false) == true);
|
||||||
|
BOOST_TEST(testset1.split_count() == (BucketSize/2+1));
|
||||||
|
{ int init_values [] = { 5, 1, 2, 3, 4 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
//Incremental rehash step 2
|
||||||
|
BOOST_TEST (testset1.incremental_rehash(false) == true);
|
||||||
|
BOOST_TEST(testset1.split_count() == (BucketSize/2));
|
||||||
|
{ int init_values [] = { 4, 5, 1, 2, 3 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
//This incremental rehash should fail because we've reached the half of the bucket array
|
||||||
|
BOOST_TEST(testset1.incremental_rehash(false) == false);
|
||||||
|
BOOST_TEST(testset1.split_count() == BucketSize/2);
|
||||||
|
{ int init_values [] = { 4, 5, 1, 2, 3 };
|
||||||
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
}
|
||||||
|
|
||||||
|
//test: rehash:
|
||||||
|
template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
|
||||||
|
void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::
|
||||||
|
test_rehash(std::vector<typename ValueTraits::value_type>& values, detail::false_)
|
||||||
|
{
|
||||||
|
typedef typename ValueTraits::value_type value_type;
|
||||||
|
typedef unordered_set
|
||||||
|
<value_type
|
||||||
|
, value_traits<ValueTraits>
|
||||||
|
, constant_time_size<value_type::constant_time_size>
|
||||||
|
, cache_begin<CacheBegin>
|
||||||
|
, compare_hash<CompareHash>
|
||||||
|
, incremental<Incremental>
|
||||||
> unordered_set_type;
|
> unordered_set_type;
|
||||||
typedef typename unordered_set_type::bucket_traits bucket_traits;
|
typedef typename unordered_set_type::bucket_traits bucket_traits;
|
||||||
|
|
||||||
@@ -220,37 +396,38 @@ void test_unordered_set<ValueTraits, CacheBegin, CompareHash>::test_rehash(std::
|
|||||||
typename unordered_set_type::bucket_type buckets3 [BucketSize*2];
|
typename unordered_set_type::bucket_type buckets3 [BucketSize*2];
|
||||||
|
|
||||||
unordered_set_type testset1(&values[0], &values[0] + 6, bucket_traits(buckets1, BucketSize));
|
unordered_set_type testset1(&values[0], &values[0] + 6, bucket_traits(buckets1, BucketSize));
|
||||||
BOOST_TEST (testset1.size() == 5);
|
BOOST_TEST (testset1.size() == values.size()-1);
|
||||||
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
testset1.rehash(bucket_traits(buckets2, 2));
|
testset1.rehash(bucket_traits(buckets2, 2));
|
||||||
BOOST_TEST (testset1.size() == 5);
|
BOOST_TEST (testset1.size() == values.size()-1);
|
||||||
{ int init_values [] = { 4, 2, 5, 3, 1 };
|
{ int init_values [] = { 4, 2, 5, 3, 1 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
testset1.rehash(bucket_traits(buckets3, BucketSize*2));
|
testset1.rehash(bucket_traits(buckets3, BucketSize*2));
|
||||||
BOOST_TEST (testset1.size() == 5);
|
BOOST_TEST (testset1.size() == values.size()-1);
|
||||||
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
//Now rehash reducing the buckets
|
//Now rehash reducing the buckets
|
||||||
testset1.rehash(bucket_traits(buckets3, 2));
|
testset1.rehash(bucket_traits(buckets3, 2));
|
||||||
BOOST_TEST (testset1.size() == 5);
|
BOOST_TEST (testset1.size() == values.size()-1);
|
||||||
{ int init_values [] = { 4, 2, 5, 3, 1 };
|
{ int init_values [] = { 4, 2, 5, 3, 1 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
|
|
||||||
//Now rehash increasing the buckets
|
//Now rehash increasing the buckets
|
||||||
testset1.rehash(bucket_traits(buckets3, BucketSize*2));
|
testset1.rehash(bucket_traits(buckets3, BucketSize*2));
|
||||||
BOOST_TEST (testset1.size() == 5);
|
BOOST_TEST (testset1.size() == values.size()-1);
|
||||||
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
{ int init_values [] = { 1, 2, 3, 4, 5 };
|
||||||
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//test: find, equal_range (lower_bound, upper_bound):
|
//test: find, equal_range (lower_bound, upper_bound):
|
||||||
template<class ValueTraits, bool CacheBegin, bool CompareHash>
|
template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
|
||||||
void test_unordered_set<ValueTraits, CacheBegin, CompareHash>::test_find(std::vector<typename ValueTraits::value_type>& values)
|
void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::
|
||||||
|
test_find(std::vector<typename ValueTraits::value_type>& values)
|
||||||
{
|
{
|
||||||
typedef typename ValueTraits::value_type value_type;
|
typedef typename ValueTraits::value_type value_type;
|
||||||
typedef unordered_set
|
typedef unordered_set
|
||||||
@@ -259,6 +436,7 @@ void test_unordered_set<ValueTraits, CacheBegin, CompareHash>::test_find(std::ve
|
|||||||
, constant_time_size<value_type::constant_time_size>
|
, constant_time_size<value_type::constant_time_size>
|
||||||
, cache_begin<CacheBegin>
|
, cache_begin<CacheBegin>
|
||||||
, compare_hash<CompareHash>
|
, compare_hash<CompareHash>
|
||||||
|
, incremental<Incremental>
|
||||||
> unordered_set_type;
|
> unordered_set_type;
|
||||||
typedef typename unordered_set_type::bucket_traits bucket_traits;
|
typedef typename unordered_set_type::bucket_traits bucket_traits;
|
||||||
|
|
||||||
@@ -281,8 +459,8 @@ void test_unordered_set<ValueTraits, CacheBegin, CompareHash>::test_find(std::ve
|
|||||||
BOOST_TEST (testset.find (cmp_val) == testset.end());
|
BOOST_TEST (testset.find (cmp_val) == testset.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class ValueTraits, bool CacheBegin, bool CompareHash>
|
template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>
|
||||||
void test_unordered_set<ValueTraits, CacheBegin, CompareHash>
|
void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>
|
||||||
::test_clone(std::vector<typename ValueTraits::value_type>& values)
|
::test_clone(std::vector<typename ValueTraits::value_type>& values)
|
||||||
{
|
{
|
||||||
typedef typename ValueTraits::value_type value_type;
|
typedef typename ValueTraits::value_type value_type;
|
||||||
@@ -292,6 +470,7 @@ void test_unordered_set<ValueTraits, CacheBegin, CompareHash>
|
|||||||
, constant_time_size<value_type::constant_time_size>
|
, constant_time_size<value_type::constant_time_size>
|
||||||
, cache_begin<CacheBegin>
|
, cache_begin<CacheBegin>
|
||||||
, compare_hash<CompareHash>
|
, compare_hash<CompareHash>
|
||||||
|
, incremental<Incremental>
|
||||||
> unordered_set_type;
|
> unordered_set_type;
|
||||||
typedef typename unordered_set_type::bucket_traits bucket_traits;
|
typedef typename unordered_set_type::bucket_traits bucket_traits;
|
||||||
{
|
{
|
||||||
@@ -319,7 +498,7 @@ void test_unordered_set<ValueTraits, CacheBegin, CompareHash>
|
|||||||
unordered_set_type testset2 (bucket_traits(buckets2, BucketSize));
|
unordered_set_type testset2 (bucket_traits(buckets2, BucketSize));
|
||||||
|
|
||||||
testset2.clone_from(testset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>());
|
testset2.clone_from(testset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>());
|
||||||
//Ordering is not guarantee in the cloning so insert data in a set and test
|
//Ordering is not guaranteed in the cloning so insert data in a set and test
|
||||||
std::set<typename ValueTraits::value_type>
|
std::set<typename ValueTraits::value_type>
|
||||||
src(testset1.begin(), testset1.end());
|
src(testset1.begin(), testset1.end());
|
||||||
std::set<typename ValueTraits::value_type>
|
std::set<typename ValueTraits::value_type>
|
||||||
@@ -347,7 +526,7 @@ void test_unordered_set<ValueTraits, CacheBegin, CompareHash>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class VoidPointer, bool constant_time_size>
|
template<class VoidPointer, bool constant_time_size, bool incremental>
|
||||||
class test_main_template
|
class test_main_template
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -365,6 +544,7 @@ class test_main_template
|
|||||||
>::type
|
>::type
|
||||||
, true
|
, true
|
||||||
, false
|
, false
|
||||||
|
, incremental
|
||||||
>::test_all(data);
|
>::test_all(data);
|
||||||
test_unordered_set < typename detail::get_member_value_traits
|
test_unordered_set < typename detail::get_member_value_traits
|
||||||
< value_type
|
< value_type
|
||||||
@@ -375,14 +555,15 @@ class test_main_template
|
|||||||
>::type
|
>::type
|
||||||
, false
|
, false
|
||||||
, false
|
, false
|
||||||
|
, incremental
|
||||||
>::test_all(data);
|
>::test_all(data);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class VoidPointer>
|
template<class VoidPointer, bool incremental>
|
||||||
class test_main_template<VoidPointer, false>
|
class test_main_template<VoidPointer, false, incremental>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
int operator()()
|
int operator()()
|
||||||
@@ -399,6 +580,7 @@ class test_main_template<VoidPointer, false>
|
|||||||
>::type
|
>::type
|
||||||
, true
|
, true
|
||||||
, false
|
, false
|
||||||
|
, incremental
|
||||||
>::test_all(data);
|
>::test_all(data);
|
||||||
|
|
||||||
test_unordered_set < typename detail::get_member_value_traits
|
test_unordered_set < typename detail::get_member_value_traits
|
||||||
@@ -410,6 +592,7 @@ class test_main_template<VoidPointer, false>
|
|||||||
>::type
|
>::type
|
||||||
, false
|
, false
|
||||||
, false
|
, false
|
||||||
|
, incremental
|
||||||
>::test_all(data);
|
>::test_all(data);
|
||||||
|
|
||||||
test_unordered_set < typename detail::get_base_value_traits
|
test_unordered_set < typename detail::get_base_value_traits
|
||||||
@@ -418,6 +601,7 @@ class test_main_template<VoidPointer, false>
|
|||||||
>::type
|
>::type
|
||||||
, true
|
, true
|
||||||
, true
|
, true
|
||||||
|
, incremental
|
||||||
>::test_all(data);
|
>::test_all(data);
|
||||||
|
|
||||||
test_unordered_set < typename detail::get_member_value_traits
|
test_unordered_set < typename detail::get_member_value_traits
|
||||||
@@ -429,6 +613,7 @@ class test_main_template<VoidPointer, false>
|
|||||||
>::type
|
>::type
|
||||||
, false
|
, false
|
||||||
, true
|
, true
|
||||||
|
, incremental
|
||||||
>::test_all(data);
|
>::test_all(data);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -436,10 +621,14 @@ class test_main_template<VoidPointer, false>
|
|||||||
|
|
||||||
int main( int, char* [] )
|
int main( int, char* [] )
|
||||||
{
|
{
|
||||||
test_main_template<void*, false>()();
|
test_main_template<void*, false, true>()();
|
||||||
test_main_template<smart_ptr<void>, false>()();
|
test_main_template<smart_ptr<void>, false, true>()();
|
||||||
test_main_template<void*, true>()();
|
test_main_template<void*, true, true>()();
|
||||||
test_main_template<smart_ptr<void>, true>()();
|
test_main_template<smart_ptr<void>, true, true>()();
|
||||||
|
test_main_template<void*, false, false>()();
|
||||||
|
test_main_template<smart_ptr<void>, false, false>()();
|
||||||
|
test_main_template<void*, true, true>()();
|
||||||
|
test_main_template<smart_ptr<void>, true, false>()();
|
||||||
return boost::report_errors();
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
#include <boost/intrusive/detail/config_end.hpp>
|
#include <boost/intrusive/detail/config_end.hpp>
|
||||||
|
Reference in New Issue
Block a user