From 19cf6211cadb3a5864a35274f70f5da55eefbdf8 Mon Sep 17 00:00:00 2001 From: Matei David Date: Thu, 15 May 2014 13:10:51 -0400 Subject: [PATCH 01/14] lib: new "header_holder_type" container option --- include/boost/intrusive/options.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/boost/intrusive/options.hpp b/include/boost/intrusive/options.hpp index 7652f9a..dafd91f 100644 --- a/include/boost/intrusive/options.hpp +++ b/include/boost/intrusive/options.hpp @@ -182,6 +182,9 @@ struct get_node_traits //!obtain constant-time size() member. BOOST_INTRUSIVE_OPTION_CONSTANT(constant_time_size, bool, Enabled, constant_time_size) +//!This option setter specifies a container header holder type +BOOST_INTRUSIVE_OPTION_TYPE(header_holder_type, Header_Holder, Header_Holder, header_holder_type) + //!This option setter specifies the type that //!the container will use to store its size. BOOST_INTRUSIVE_OPTION_TYPE(size_type, SizeType, SizeType, size_type) From 11ec15f45a372d70bf935d32b2ab0f0e7a5f1755 Mon Sep 17 00:00:00 2001 From: Matei David Date: Thu, 15 May 2014 13:25:58 -0400 Subject: [PATCH 02/14] lib: default option for header_holder_type --- include/boost/intrusive/avltree.hpp | 1 + include/boost/intrusive/bstree.hpp | 1 + include/boost/intrusive/list.hpp | 1 + include/boost/intrusive/rbtree.hpp | 1 + include/boost/intrusive/sgtree.hpp | 1 + include/boost/intrusive/slist.hpp | 1 + include/boost/intrusive/splaytree.hpp | 1 + include/boost/intrusive/treap.hpp | 1 + 8 files changed, 8 insertions(+) diff --git a/include/boost/intrusive/avltree.hpp b/include/boost/intrusive/avltree.hpp index 7a53b39..c8e54b3 100644 --- a/include/boost/intrusive/avltree.hpp +++ b/include/boost/intrusive/avltree.hpp @@ -47,6 +47,7 @@ struct avltree_defaults static const bool constant_time_size = true; typedef std::size_t size_type; typedef void compare; + typedef void header_holder_type; }; /// @endcond diff --git a/include/boost/intrusive/bstree.hpp b/include/boost/intrusive/bstree.hpp index 950fa78..76d8da1 100644 --- a/include/boost/intrusive/bstree.hpp +++ b/include/boost/intrusive/bstree.hpp @@ -49,6 +49,7 @@ struct bstree_defaults typedef void compare; static const bool floating_point = true; //For sgtree typedef void priority; //For treap + typedef void header_holder_type; }; template diff --git a/include/boost/intrusive/list.hpp b/include/boost/intrusive/list.hpp index 36c29e7..a16b14d 100644 --- a/include/boost/intrusive/list.hpp +++ b/include/boost/intrusive/list.hpp @@ -42,6 +42,7 @@ struct list_defaults typedef detail::default_list_hook proto_value_traits; static const bool constant_time_size = true; typedef std::size_t size_type; + typedef void header_holder_type; }; /// @endcond diff --git a/include/boost/intrusive/rbtree.hpp b/include/boost/intrusive/rbtree.hpp index c4ff5f4..58dfe11 100644 --- a/include/boost/intrusive/rbtree.hpp +++ b/include/boost/intrusive/rbtree.hpp @@ -45,6 +45,7 @@ struct rbtree_defaults static const bool constant_time_size = true; typedef std::size_t size_type; typedef void compare; + typedef void header_holder_type; }; /// @endcond diff --git a/include/boost/intrusive/sgtree.hpp b/include/boost/intrusive/sgtree.hpp index 8cb2b5c..4d3b205 100644 --- a/include/boost/intrusive/sgtree.hpp +++ b/include/boost/intrusive/sgtree.hpp @@ -192,6 +192,7 @@ struct sgtree_defaults typedef std::size_t size_type; typedef void compare; static const bool floating_point = true; + typedef void header_holder_type; }; /// @endcond diff --git a/include/boost/intrusive/slist.hpp b/include/boost/intrusive/slist.hpp index a50838a..fd5c860 100644 --- a/include/boost/intrusive/slist.hpp +++ b/include/boost/intrusive/slist.hpp @@ -57,6 +57,7 @@ struct slist_defaults static const bool linear = false; typedef std::size_t size_type; static const bool cache_last = false; + typedef void header_holder_type; }; struct slist_bool_flags diff --git a/include/boost/intrusive/splaytree.hpp b/include/boost/intrusive/splaytree.hpp index 24e4c74..3747ed4 100644 --- a/include/boost/intrusive/splaytree.hpp +++ b/include/boost/intrusive/splaytree.hpp @@ -44,6 +44,7 @@ struct splaytree_defaults static const bool constant_time_size = true; typedef std::size_t size_type; typedef void compare; + typedef void header_holder_type; }; /// @endcond diff --git a/include/boost/intrusive/treap.hpp b/include/boost/intrusive/treap.hpp index 3bda6db..6cc90be 100644 --- a/include/boost/intrusive/treap.hpp +++ b/include/boost/intrusive/treap.hpp @@ -48,6 +48,7 @@ struct treap_defaults typedef std::size_t size_type; typedef void compare; typedef void priority; + typedef void header_holder_type; }; /// @endcond From 3af2654edacf5d9800f9eeb4e1f7cd20450b67f7 Mon Sep 17 00:00:00 2001 From: Matei David Date: Thu, 15 May 2014 13:54:53 -0400 Subject: [PATCH 03/14] lib: extra template parameter to containers & makers, not used yet --- include/boost/intrusive/avl_set.hpp | 22 ++++++++++++---------- include/boost/intrusive/avltree.hpp | 11 ++++++----- include/boost/intrusive/bs_set.hpp | 22 ++++++++++++---------- include/boost/intrusive/bstree.hpp | 11 ++++++----- include/boost/intrusive/intrusive_fwd.hpp | 20 ++++++++++++++++++++ include/boost/intrusive/list.hpp | 10 +++++----- include/boost/intrusive/rbtree.hpp | 11 ++++++----- include/boost/intrusive/set.hpp | 22 ++++++++++++---------- include/boost/intrusive/sg_set.hpp | 22 ++++++++++++---------- include/boost/intrusive/sgtree.hpp | 11 ++++++----- include/boost/intrusive/slist.hpp | 10 +++++----- include/boost/intrusive/splay_set.hpp | 22 ++++++++++++---------- include/boost/intrusive/splaytree.hpp | 11 ++++++----- include/boost/intrusive/treap.hpp | 11 ++++++----- include/boost/intrusive/treap_set.hpp | 22 ++++++++++++---------- 15 files changed, 138 insertions(+), 100 deletions(-) diff --git a/include/boost/intrusive/avl_set.hpp b/include/boost/intrusive/avl_set.hpp index ce2d178..f125785 100644 --- a/include/boost/intrusive/avl_set.hpp +++ b/include/boost/intrusive/avl_set.hpp @@ -397,7 +397,8 @@ void swap(avl_set_impl &x, avl_set_impl &y); template #else template + , class O3 = void, class O4 = void + , class O5 = void> #endif struct make_avl_set { @@ -405,7 +406,7 @@ struct make_avl_set typedef typename pack_options < avltree_defaults, #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) - O1, O2, O3, O4 + O1, O2, O3, O4, O5 #else Options... #endif @@ -426,14 +427,14 @@ struct make_avl_set #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) -template +template #else template #endif class avl_set : public make_avl_set &x, avl_multiset_impl template #else template + , class O3 = void, class O4 = void + , class O5 = void> #endif struct make_avl_multiset { @@ -842,7 +844,7 @@ struct make_avl_multiset typedef typename pack_options < avltree_defaults, #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) - O1, O2, O3, O4 + O1, O2, O3, O4, O5 #else Options... #endif @@ -864,14 +866,14 @@ struct make_avl_multiset #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) -template +template #else template #endif class avl_multiset : public make_avl_multiset &x, avltree_impl &y); template #else template + , class O3 = void, class O4 = void + , class O5 = void> #endif struct make_avltree { @@ -439,7 +440,7 @@ struct make_avltree typedef typename pack_options < avltree_defaults, #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) - O1, O2, O3, O4 + O1, O2, O3, O4, O5 #else Options... #endif @@ -462,14 +463,14 @@ struct make_avltree #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) -template +template #else template #endif class avltree : public make_avltree &x, bs_set_impl &y); template #else template + , class O3 = void, class O4 = void + , class O5 = void> #endif struct make_bs_set { @@ -403,7 +404,7 @@ struct make_bs_set typedef typename pack_options < bstree_defaults, #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) - O1, O2, O3, O4 + O1, O2, O3, O4, O5 #else Options... #endif @@ -424,14 +425,14 @@ struct make_bs_set #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) -template +template #else template #endif class bs_set : public make_bs_set &x, bs_multiset_impl &y template #else template + , class O3 = void, class O4 = void + , class O5 = void> #endif struct make_bs_multiset { @@ -840,7 +842,7 @@ struct make_bs_multiset typedef typename pack_options < bstree_defaults, #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) - O1, O2, O3, O4 + O1, O2, O3, O4, O5 #else Options... #endif @@ -862,14 +864,14 @@ struct make_bs_multiset #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) -template +template #else template #endif class bs_multiset : public make_bs_multiset #else template + , class O3 = void, class O4 = void + , class O5 = void> #endif struct make_bstree { @@ -2010,7 +2011,7 @@ struct make_bstree typedef typename pack_options < bstree_defaults, #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) - O1, O2, O3, O4 + O1, O2, O3, O4, O5 #else Options... #endif @@ -2034,14 +2035,14 @@ struct make_bstree #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) -template +template #else template #endif class bstree : public make_bstree #else template @@ -137,6 +138,7 @@ template , class O1 = void , class O2 = void , class O3 = void + , class O4 = void > #else template @@ -173,6 +175,7 @@ template , class O2 = void , class O3 = void , class O4 = void + , class O5 = void > #else template @@ -186,6 +189,7 @@ template , class O2 = void , class O3 = void , class O4 = void + , class O5 = void > #else template @@ -199,6 +203,7 @@ template , class O2 = void , class O3 = void , class O4 = void + , class O5 = void > #else template @@ -237,6 +242,7 @@ template , class O2 = void , class O3 = void , class O4 = void + , class O5 = void > #else template @@ -250,6 +256,7 @@ template , class O2 = void , class O3 = void , class O4 = void + , class O5 = void > #else template @@ -263,6 +270,7 @@ template , class O2 = void , class O3 = void , class O4 = void + , class O5 = void > #else template @@ -277,6 +285,7 @@ template , class O2 = void , class O3 = void , class O4 = void + , class O5 = void > #else template @@ -290,6 +299,7 @@ template , class O2 = void , class O3 = void , class O4 = void + , class O5 = void > #else template @@ -303,6 +313,7 @@ template , class O2 = void , class O3 = void , class O4 = void + , class O5 = void > #else template @@ -342,6 +353,7 @@ template , class O2 = void , class O3 = void , class O4 = void + , class O5 = void > #else template @@ -355,6 +367,7 @@ template , class O2 = void , class O3 = void , class O4 = void + , class O5 = void > #else template @@ -368,6 +381,7 @@ template , class O2 = void , class O3 = void , class O4 = void + , class O5 = void > #else template @@ -382,6 +396,7 @@ template , class O2 = void , class O3 = void , class O4 = void + , class O5 = void > #else template @@ -395,6 +410,7 @@ template , class O2 = void , class O3 = void , class O4 = void + , class O5 = void > #else template @@ -408,6 +424,7 @@ template , class O2 = void , class O3 = void , class O4 = void + , class O5 = void > #else template @@ -421,6 +438,7 @@ template , class O2 = void , class O3 = void , class O4 = void + , class O5 = void > #else template @@ -434,6 +452,7 @@ template , class O2 = void , class O3 = void , class O4 = void + , class O5 = void > #else template @@ -447,6 +466,7 @@ template , class O2 = void , class O3 = void , class O4 = void + , class O5 = void > #else template diff --git a/include/boost/intrusive/list.hpp b/include/boost/intrusive/list.hpp index a16b14d..16bff16 100644 --- a/include/boost/intrusive/list.hpp +++ b/include/boost/intrusive/list.hpp @@ -1387,7 +1387,7 @@ inline void swap #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template #else -template +template #endif struct make_list { @@ -1395,7 +1395,7 @@ struct make_list typedef typename pack_options < list_defaults, #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) - O1, O2, O3 + O1, O2, O3, O4 #else Options... #endif @@ -1418,14 +1418,14 @@ struct make_list #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) -template +template #else template #endif class list : public make_list &x, rbtree_impl &y); template #else template + , class O3 = void, class O4 = void + , class O5 = void> #endif struct make_rbtree { @@ -435,7 +436,7 @@ struct make_rbtree typedef typename pack_options < rbtree_defaults, #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) - O1, O2, O3, O4 + O1, O2, O3, O4, O5 #else Options... #endif @@ -458,14 +459,14 @@ struct make_rbtree #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) -template +template #else template #endif class rbtree : public make_rbtree &x, set_impl &y); template #else template + , class O3 = void, class O4 = void + , class O5 = void> #endif struct make_set { @@ -405,7 +406,7 @@ struct make_set typedef typename pack_options < rbtree_defaults, #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) - O1, O2, O3, O4 + O1, O2, O3, O4, O5 #else Options... #endif @@ -426,14 +427,14 @@ struct make_set #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) -template +template #else template #endif class set : public make_set &x, multiset_impl &y); template #else template + , class O3 = void, class O4 = void + , class O5 = void> #endif struct make_multiset { @@ -842,7 +844,7 @@ struct make_multiset typedef typename pack_options < rbtree_defaults, #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) - O1, O2, O3, O4 + O1, O2, O3, O4, O5 #else Options... #endif @@ -864,14 +866,14 @@ struct make_multiset #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) -template +template #else template #endif class multiset : public make_multiset &x, sg_set_impl &y); template #else template + , class O3 = void, class O4 = void + , class O5 = void> #endif struct make_sg_set { @@ -416,7 +417,7 @@ struct make_sg_set typedef typename pack_options < sgtree_defaults, #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) - O1, O2, O3, O4 + O1, O2, O3, O4, O5 #else Options... #endif @@ -437,14 +438,14 @@ struct make_sg_set #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) -template +template #else template #endif class sg_set : public make_sg_set &x, sg_multiset_impl &y template #else template + , class O3 = void, class O4 = void + , class O5 = void> #endif struct make_sg_multiset { @@ -866,7 +868,7 @@ struct make_sg_multiset typedef typename pack_options < sgtree_defaults, #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) - O1, O2, O3, O4 + O1, O2, O3, O4, O5 #else Options... #endif @@ -888,14 +890,14 @@ struct make_sg_multiset #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) -template +template #else template #endif class sg_multiset : public make_sg_multiset &x, sgtree_impl &y); template #else template + , class O3 = void, class O4 = void + , class O5 = void> #endif struct make_sgtree { @@ -881,7 +882,7 @@ struct make_sgtree typedef typename pack_options < sgtree_defaults, #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) - O1, O2, O3, O4 + O1, O2, O3, O4, O5 #else Options... #endif @@ -904,14 +905,14 @@ struct make_sgtree #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) -template +template #else template #endif class sgtree : public make_sgtree #else -template +template #endif struct make_slist { @@ -2106,7 +2106,7 @@ struct make_slist typedef typename pack_options < slist_defaults, #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) - O1, O2, O3, O4, O5 + O1, O2, O3, O4, O5, O6 #else Options... #endif @@ -2128,14 +2128,14 @@ struct make_slist #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) -template +template #else template #endif class slist : public make_slist &x, splay_set_impl &y); template #else template + , class O3 = void, class O4 = void + , class O5 = void> #endif struct make_splay_set { @@ -426,7 +427,7 @@ struct make_splay_set typedef typename pack_options < splaytree_defaults, #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) - O1, O2, O3, O4 + O1, O2, O3, O4, O5 #else Options... #endif @@ -447,14 +448,14 @@ struct make_splay_set #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) -template +template #else template #endif class splay_set : public make_splay_set &x, splay_multiset_impl #else template + , class O3 = void, class O4 = void + , class O5 = void> #endif struct make_splay_multiset { @@ -879,7 +881,7 @@ struct make_splay_multiset typedef typename pack_options < splaytree_defaults, #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) - O1, O2, O3, O4 + O1, O2, O3, O4, O5 #else Options... #endif @@ -901,14 +903,14 @@ struct make_splay_multiset #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) -template +template #else template #endif class splay_multiset : public make_splay_multiset &x, splaytree_impl &y); template #else template + , class O3 = void, class O4 = void + , class O5 = void> #endif struct make_splaytree { @@ -522,7 +523,7 @@ struct make_splaytree typedef typename pack_options < splaytree_defaults, #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) - O1, O2, O3, O4 + O1, O2, O3, O4, O5 #else Options... #endif @@ -545,14 +546,14 @@ struct make_splaytree #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) -template +template #else template #endif class splaytree : public make_splaytree &x, treap_impl &y); template #else template + , class O3 = void, class O4 = void + , class O5 = void> #endif struct make_treap { typedef typename pack_options < treap_defaults, #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) - O1, O2, O3, O4 + O1, O2, O3, O4, O5 #else Options... #endif @@ -1093,14 +1094,14 @@ struct make_treap #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) -template +template #else template #endif class treap : public make_treap #else template + , class O3 = void, class O4 = void + , class O5 = void> #endif struct make_treap_set { typedef typename pack_options < treap_defaults, #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) - O1, O2, O3, O4 + O1, O2, O3, O4, O5 #else Options... #endif @@ -453,14 +454,14 @@ struct make_treap_set #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) -template +template #else template #endif class treap_set : public make_treap_set #else template + , class O3 = void, class O4 = void + , class O5 = void> #endif struct make_treap_multiset { typedef typename pack_options < treap_defaults, #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) - O1, O2, O3, O4 + O1, O2, O3, O4, O5 #else Options... #endif @@ -919,14 +921,14 @@ struct make_treap_multiset #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) -template +template #else template #endif class treap_multiset : public make_treap_multiset Date: Thu, 15 May 2014 16:08:25 -0400 Subject: [PATCH 04/14] lib: new utility structs default_holder: default header node holder get_header_holder_type: type function producing header_holder_type --- include/boost/intrusive/detail/utilities.hpp | 30 ++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/include/boost/intrusive/detail/utilities.hpp b/include/boost/intrusive/detail/utilities.hpp index 31bb6e2..a454822 100644 --- a/include/boost/intrusive/detail/utilities.hpp +++ b/include/boost/intrusive/detail/utilities.hpp @@ -894,6 +894,36 @@ static typename uncast_types::non_const_pointer return uncast_types::non_const_traits::const_cast_from(ptr); } +// trivial header node holder +template < typename Node_Traits > +struct default_holder : public Node_Traits::node +{ + typedef Node_Traits node_traits; + typedef typename node_traits::node node; + typedef typename node_traits::node_ptr node_ptr; + typedef typename node_traits::const_node_ptr const_node_ptr; + + default_holder() : node() {} + + const_node_ptr get_header_node() const + { return pointer_traits< const_node_ptr >::pointer_to(*static_cast< const node* >(this)); } + node_ptr get_header_node() + { return pointer_traits< node_ptr >::pointer_to(*static_cast< node* >(this)); } +}; + +// type function producing the header node holder +template < typename Value_Traits, typename Header_Holder > +struct get_header_holder_type +{ + typedef Header_Holder type; +}; +template < typename Value_Traits > +struct get_header_holder_type< Value_Traits, void > +{ + typedef default_holder< typename Value_Traits::node_traits > type; +}; + + } //namespace detail template From cdf32597acfc1c9a1cf498d8c3914a3da4f3116a Mon Sep 17 00:00:00 2001 From: Matei David Date: Thu, 15 May 2014 16:10:22 -0400 Subject: [PATCH 05/14] lib: extra template parameter propagated to impl bases, not used yet --- include/boost/intrusive/avl_set.hpp | 18 ++++-- include/boost/intrusive/avltree.hpp | 10 +++- include/boost/intrusive/bs_set.hpp | 18 ++++-- include/boost/intrusive/bstree.hpp | 85 ++++++++++++++------------- include/boost/intrusive/list.hpp | 37 ++++++------ include/boost/intrusive/rbtree.hpp | 10 +++- include/boost/intrusive/set.hpp | 18 ++++-- include/boost/intrusive/sg_set.hpp | 18 ++++-- include/boost/intrusive/sgtree.hpp | 9 ++- include/boost/intrusive/slist.hpp | 49 +++++++-------- include/boost/intrusive/splay_set.hpp | 18 ++++-- include/boost/intrusive/splaytree.hpp | 10 +++- include/boost/intrusive/treap.hpp | 12 ++-- include/boost/intrusive/treap_set.hpp | 18 ++++-- 14 files changed, 197 insertions(+), 133 deletions(-) diff --git a/include/boost/intrusive/avl_set.hpp b/include/boost/intrusive/avl_set.hpp index f125785..d968a14 100644 --- a/include/boost/intrusive/avl_set.hpp +++ b/include/boost/intrusive/avl_set.hpp @@ -36,15 +36,15 @@ namespace intrusive { #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif class avl_set_impl #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED - : public bstree_impl + : public bstree_impl #endif { /// @cond - typedef bstree_impl tree_type; + typedef bstree_impl tree_type; BOOST_MOVABLE_BUT_NOT_COPYABLE(avl_set_impl) typedef tree_type implementation_defined; @@ -414,12 +414,15 @@ struct make_avl_set typedef typename detail::get_value_traits ::type value_traits; + typedef typename detail::get_header_holder_type + < value_traits, typename packed_options::header_holder_type >::type header_holder_type; typedef avl_set_impl < value_traits , typename packed_options::compare , typename packed_options::size_type , packed_options::constant_time_size + , header_holder_type > implementation_defined; /// @endcond typedef implementation_defined type; @@ -507,15 +510,15 @@ class avl_set #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif class avl_multiset_impl #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED - : public bstree_impl + : public bstree_impl #endif { /// @cond - typedef bstree_impl tree_type; + typedef bstree_impl tree_type; BOOST_MOVABLE_BUT_NOT_COPYABLE(avl_multiset_impl) typedef tree_type implementation_defined; @@ -852,12 +855,15 @@ struct make_avl_multiset typedef typename detail::get_value_traits ::type value_traits; + typedef typename detail::get_header_holder_type + < value_traits, typename packed_options::header_holder_type >::type header_holder_type; typedef avl_multiset_impl < value_traits , typename packed_options::compare , typename packed_options::size_type , packed_options::constant_time_size + , header_holder_type > implementation_defined; /// @endcond typedef implementation_defined type; diff --git a/include/boost/intrusive/avltree.hpp b/include/boost/intrusive/avltree.hpp index df63ed0..787fa76 100644 --- a/include/boost/intrusive/avltree.hpp +++ b/include/boost/intrusive/avltree.hpp @@ -68,18 +68,19 @@ struct avltree_defaults #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif class avltree_impl /// @cond - : public bstree_impl + : public bstree_impl /// @endcond { public: typedef ValueTraits value_traits; /// @cond typedef bstree_impl< ValueTraits, VoidOrKeyComp, SizeType - , ConstantTimeSize, AvlTreeAlgorithms> tree_type; + , ConstantTimeSize, AvlTreeAlgorithms + , Header_Holder> tree_type; typedef tree_type implementation_defined; /// @endcond @@ -448,12 +449,15 @@ struct make_avltree typedef typename detail::get_value_traits ::type value_traits; + typedef typename detail::get_header_holder_type + < value_traits, typename packed_options::header_holder_type >::type header_holder_type; typedef avltree_impl < value_traits , typename packed_options::compare , typename packed_options::size_type , packed_options::constant_time_size + , header_holder_type > implementation_defined; /// @endcond typedef implementation_defined type; diff --git a/include/boost/intrusive/bs_set.hpp b/include/boost/intrusive/bs_set.hpp index 577b881..7ee125d 100644 --- a/include/boost/intrusive/bs_set.hpp +++ b/include/boost/intrusive/bs_set.hpp @@ -36,15 +36,15 @@ namespace intrusive { #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif class bs_set_impl #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED - : public bstree_impl + : public bstree_impl #endif { /// @cond - typedef bstree_impl tree_type; + typedef bstree_impl tree_type; BOOST_MOVABLE_BUT_NOT_COPYABLE(bs_set_impl) typedef tree_type implementation_defined; @@ -412,12 +412,15 @@ struct make_bs_set typedef typename detail::get_value_traits ::type value_traits; + typedef typename detail::get_header_holder_type + < value_traits, typename packed_options::header_holder_type >::type header_holder_type; typedef bs_set_impl < value_traits , typename packed_options::compare , typename packed_options::size_type , packed_options::constant_time_size + , header_holder_type > implementation_defined; /// @endcond typedef implementation_defined type; @@ -505,15 +508,15 @@ class bs_set #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif class bs_multiset_impl #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED - : public bstree_impl + : public bstree_impl #endif { /// @cond - typedef bstree_impl tree_type; + typedef bstree_impl tree_type; BOOST_MOVABLE_BUT_NOT_COPYABLE(bs_multiset_impl) typedef tree_type implementation_defined; @@ -850,12 +853,15 @@ struct make_bs_multiset typedef typename detail::get_value_traits ::type value_traits; + typedef typename detail::get_header_holder_type + < value_traits, typename packed_options::header_holder_type >::type header_holder_type; typedef bs_multiset_impl < value_traits , typename packed_options::compare , typename packed_options::size_type , packed_options::constant_time_size + , header_holder_type > implementation_defined; /// @endcond typedef implementation_defined type; diff --git a/include/boost/intrusive/bstree.hpp b/include/boost/intrusive/bstree.hpp index 0700203..1e1fe86 100644 --- a/include/boost/intrusive/bstree.hpp +++ b/include/boost/intrusive/bstree.hpp @@ -52,7 +52,7 @@ struct bstree_defaults typedef void header_holder_type; }; -template +template struct bstbase3 { typedef ValueTraits value_traits; @@ -198,15 +198,15 @@ struct bstbase3 }; -template +template struct bstbase2 //Put the (possibly empty) functor in the first position to get EBO in MSVC : public detail::ebo_functor_holder::type> - , public bstbase3 + , public bstbase3 { - typedef bstbase3 treeheader_t; + typedef bstbase3 treeheader_t; typedef typename treeheader_t::value_traits value_traits; typedef typename treeheader_t::node_algorithms node_algorithms; typedef typename get_less @@ -444,12 +444,12 @@ struct bstbase2 //Due to MSVC's EBO implementation, to save space and maintain the ABI, we must put the non-empty size member //in the first position, but if size is not going to be stored then we'll use an specialization //that doesn't inherit from size_holder -template +template struct bstbase_hack : public detail::size_holder - , public bstbase2 < ValueTraits, VoidOrKeyComp, AlgoType> + , public bstbase2 < ValueTraits, VoidOrKeyComp, AlgoType, Header_Holder> { - typedef bstbase2< ValueTraits, VoidOrKeyComp, AlgoType> base_type; + typedef bstbase2< ValueTraits, VoidOrKeyComp, AlgoType, Header_Holder> base_type; typedef typename base_type::value_compare value_compare; typedef SizeType size_type; typedef typename base_type::node_traits node_traits; @@ -472,11 +472,11 @@ struct bstbase_hack }; //Specialization for ConstantTimeSize == false -template -struct bstbase_hack - : public bstbase2 < ValueTraits, VoidOrKeyComp, AlgoType> +template +struct bstbase_hack + : public bstbase2 < ValueTraits, VoidOrKeyComp, AlgoType, Header_Holder> { - typedef bstbase2< ValueTraits, VoidOrKeyComp, AlgoType> base_type; + typedef bstbase2< ValueTraits, VoidOrKeyComp, AlgoType, Header_Holder> base_type; typedef typename base_type::value_compare value_compare; bstbase_hack(const value_compare & comp, const ValueTraits &vtraits) : base_type(comp, vtraits) @@ -493,15 +493,15 @@ struct bstbase_hack static size_traits s_size_traits; }; -template -detail::size_holder bstbase_hack::s_size_traits; +template +detail::size_holder bstbase_hack::s_size_traits; //This class will -template +template struct bstbase - : public bstbase_hack< ValueTraits, VoidOrKeyComp, ConstantTimeSize, SizeType, AlgoType> + : public bstbase_hack< ValueTraits, VoidOrKeyComp, ConstantTimeSize, SizeType, AlgoType, Header_Holder> { - typedef bstbase_hack< ValueTraits, VoidOrKeyComp, ConstantTimeSize, SizeType, AlgoType> base_type; + typedef bstbase_hack< ValueTraits, VoidOrKeyComp, ConstantTimeSize, SizeType, AlgoType, Header_Holder> base_type; typedef ValueTraits value_traits; typedef typename base_type::value_compare value_compare; typedef value_compare key_compare; @@ -553,14 +553,14 @@ struct bstbase #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif class bstree_impl - : public bstbase + : public bstbase { public: /// @cond - typedef bstbase data_type; + typedef bstbase data_type; typedef tree_iterator iterator_type; typedef tree_iterator const_iterator_type; /// @endcond @@ -1876,31 +1876,31 @@ class bstree_impl #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif inline bool operator< #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) (const bstree_impl &x, const bstree_impl &y) #else -( const bstree_impl &x -, const bstree_impl &y) +( const bstree_impl &x +, const bstree_impl &y) #endif { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif bool operator== #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) (const bstree_impl &x, const bstree_impl &y) #else -( const bstree_impl &x -, const bstree_impl &y) +( const bstree_impl &x +, const bstree_impl &y) #endif { - typedef bstree_impl tree_type; + typedef bstree_impl tree_type; typedef typename tree_type::const_iterator const_iterator; if(tree_type::constant_time_size && x.size() != y.size()){ @@ -1929,70 +1929,70 @@ bool operator== #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif inline bool operator!= #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) (const bstree_impl &x, const bstree_impl &y) #else -( const bstree_impl &x -, const bstree_impl &y) +( const bstree_impl &x +, const bstree_impl &y) #endif { return !(x == y); } #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif inline bool operator> #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) (const bstree_impl &x, const bstree_impl &y) #else -( const bstree_impl &x -, const bstree_impl &y) +( const bstree_impl &x +, const bstree_impl &y) #endif { return y < x; } #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif inline bool operator<= #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) (const bstree_impl &x, const bstree_impl &y) #else -( const bstree_impl &x -, const bstree_impl &y) +( const bstree_impl &x +, const bstree_impl &y) #endif { return !(y < x); } #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif inline bool operator>= #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) (const bstree_impl &x, const bstree_impl &y) #else -( const bstree_impl &x -, const bstree_impl &y) +( const bstree_impl &x +, const bstree_impl &y) #endif { return !(x < y); } #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif inline void swap #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) (bstree_impl &x, bstree_impl &y) #else -( bstree_impl &x -, bstree_impl &y) +( bstree_impl &x +, bstree_impl &y) #endif { x.swap(y); } @@ -2019,6 +2019,8 @@ struct make_bstree typedef typename detail::get_value_traits ::type value_traits; + typedef typename detail::get_header_holder_type + < value_traits, typename packed_options::header_holder_type >::type header_holder_type; typedef bstree_impl < value_traits @@ -2026,6 +2028,7 @@ struct make_bstree , typename packed_options::size_type , packed_options::constant_time_size , BsTreeAlgorithms + , header_holder_type > implementation_defined; /// @endcond typedef implementation_defined type; diff --git a/include/boost/intrusive/list.hpp b/include/boost/intrusive/list.hpp index 16bff16..b2dfa4e 100644 --- a/include/boost/intrusive/list.hpp +++ b/include/boost/intrusive/list.hpp @@ -60,7 +60,7 @@ struct list_defaults #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif class list_impl { @@ -1268,29 +1268,29 @@ class list_impl #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif inline bool operator< #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) (const list_impl &x, const list_impl &y) #else -(const list_impl &x, const list_impl &y) +(const list_impl &x, const list_impl &y) #endif { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif bool operator== #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) (const list_impl &x, const list_impl &y) #else -(const list_impl &x, const list_impl &y) +(const list_impl &x, const list_impl &y) #endif { - typedef list_impl list_type; + typedef list_impl list_type; typedef typename list_type::const_iterator const_iterator; const bool C = list_type::constant_time_size; if(C && x.size() != y.size()){ @@ -1320,65 +1320,65 @@ bool operator== #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif inline bool operator!= #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) (const list_impl &x, const list_impl &y) #else -(const list_impl &x, const list_impl &y) +(const list_impl &x, const list_impl &y) #endif { return !(x == y); } #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif inline bool operator> #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) (const list_impl &x, const list_impl &y) #else -(const list_impl &x, const list_impl &y) +(const list_impl &x, const list_impl &y) #endif { return y < x; } #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif inline bool operator<= #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) (const list_impl &x, const list_impl &y) #else -(const list_impl &x, const list_impl &y) +(const list_impl &x, const list_impl &y) #endif { return !(y < x); } #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif inline bool operator>= #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) (const list_impl &x, const list_impl &y) #else -(const list_impl &x, const list_impl &y) +(const list_impl &x, const list_impl &y) #endif { return !(x < y); } #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif inline void swap #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) (list_impl &x, list_impl &y) #else -(list_impl &x, list_impl &y) +(list_impl &x, list_impl &y) #endif { x.swap(y); } @@ -1403,12 +1403,15 @@ struct make_list typedef typename detail::get_value_traits ::type value_traits; + typedef typename detail::get_header_holder_type + < value_traits, typename packed_options::header_holder_type >::type header_holder_type; typedef list_impl < value_traits, typename packed_options::size_type, - packed_options::constant_time_size + packed_options::constant_time_size, + header_holder_type > implementation_defined; /// @endcond typedef implementation_defined type; diff --git a/include/boost/intrusive/rbtree.hpp b/include/boost/intrusive/rbtree.hpp index 187d4f9..d15ea45 100644 --- a/include/boost/intrusive/rbtree.hpp +++ b/include/boost/intrusive/rbtree.hpp @@ -66,18 +66,19 @@ struct rbtree_defaults #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif class rbtree_impl /// @cond - : public bstree_impl + : public bstree_impl /// @endcond { public: typedef ValueTraits value_traits; /// @cond typedef bstree_impl< ValueTraits, VoidOrKeyComp, SizeType - , ConstantTimeSize, RbTreeAlgorithms> tree_type; + , ConstantTimeSize, RbTreeAlgorithms + , Header_Holder> tree_type; typedef tree_type implementation_defined; /// @endcond @@ -444,12 +445,15 @@ struct make_rbtree typedef typename detail::get_value_traits ::type value_traits; + typedef typename detail::get_header_holder_type + < value_traits, typename packed_options::header_holder_type >::type header_holder_type; typedef rbtree_impl < value_traits , typename packed_options::compare , typename packed_options::size_type , packed_options::constant_time_size + , header_holder_type > implementation_defined; /// @endcond typedef implementation_defined type; diff --git a/include/boost/intrusive/set.hpp b/include/boost/intrusive/set.hpp index b7ca954..5ab0834 100644 --- a/include/boost/intrusive/set.hpp +++ b/include/boost/intrusive/set.hpp @@ -38,15 +38,15 @@ namespace intrusive { #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif class set_impl #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED - : public bstree_impl + : public bstree_impl #endif { /// @cond - typedef bstree_impl tree_type; + typedef bstree_impl tree_type; BOOST_MOVABLE_BUT_NOT_COPYABLE(set_impl) typedef tree_type implementation_defined; @@ -414,12 +414,15 @@ struct make_set typedef typename detail::get_value_traits ::type value_traits; + typedef typename detail::get_header_holder_type + < value_traits, typename packed_options::header_holder_type >::type header_holder_type; typedef set_impl < value_traits , typename packed_options::compare , typename packed_options::size_type , packed_options::constant_time_size + , header_holder_type > implementation_defined; /// @endcond typedef implementation_defined type; @@ -507,15 +510,15 @@ class set #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif class multiset_impl #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED - : public bstree_impl + : public bstree_impl #endif { /// @cond - typedef bstree_impl tree_type; + typedef bstree_impl tree_type; BOOST_MOVABLE_BUT_NOT_COPYABLE(multiset_impl) typedef tree_type implementation_defined; @@ -852,12 +855,15 @@ struct make_multiset typedef typename detail::get_value_traits ::type value_traits; + typedef typename detail::get_header_holder_type + < value_traits, typename packed_options::header_holder_type >::type header_holder_type; typedef multiset_impl < value_traits , typename packed_options::compare , typename packed_options::size_type , packed_options::constant_time_size + , header_holder_type > implementation_defined; /// @endcond typedef implementation_defined type; diff --git a/include/boost/intrusive/sg_set.hpp b/include/boost/intrusive/sg_set.hpp index 2c62b5c..3e8fa5e 100644 --- a/include/boost/intrusive/sg_set.hpp +++ b/include/boost/intrusive/sg_set.hpp @@ -36,15 +36,15 @@ namespace intrusive { #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif class sg_set_impl #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED - : public sgtree_impl + : public sgtree_impl #endif { /// @cond - typedef sgtree_impl tree_type; + typedef sgtree_impl tree_type; BOOST_MOVABLE_BUT_NOT_COPYABLE(sg_set_impl) typedef tree_type implementation_defined; @@ -425,12 +425,15 @@ struct make_sg_set typedef typename detail::get_value_traits ::type value_traits; + typedef typename detail::get_header_holder_type + < value_traits, typename packed_options::header_holder_type >::type header_holder_type; typedef sg_set_impl < value_traits , typename packed_options::compare , typename packed_options::size_type , packed_options::floating_point + , header_holder_type > implementation_defined; /// @endcond typedef implementation_defined type; @@ -518,15 +521,15 @@ class sg_set #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif class sg_multiset_impl #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED - : public sgtree_impl + : public sgtree_impl #endif { /// @cond - typedef sgtree_impl tree_type; + typedef sgtree_impl tree_type; BOOST_MOVABLE_BUT_NOT_COPYABLE(sg_multiset_impl) typedef tree_type implementation_defined; @@ -876,12 +879,15 @@ struct make_sg_multiset typedef typename detail::get_value_traits ::type value_traits; + typedef typename detail::get_header_holder_type + < value_traits, typename packed_options::header_holder_type >::type header_holder_type; typedef sg_multiset_impl < value_traits , typename packed_options::compare , typename packed_options::size_type , packed_options::floating_point + , header_holder_type > implementation_defined; /// @endcond typedef implementation_defined type; diff --git a/include/boost/intrusive/sgtree.hpp b/include/boost/intrusive/sgtree.hpp index c7f6d8b..400c2bb 100644 --- a/include/boost/intrusive/sgtree.hpp +++ b/include/boost/intrusive/sgtree.hpp @@ -213,11 +213,11 @@ struct sgtree_defaults #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif class sgtree_impl /// @cond - : public bstree_impl + : public bstree_impl , public detail::alpha_holder /// @endcond { @@ -225,7 +225,7 @@ class sgtree_impl typedef ValueTraits value_traits; /// @cond typedef bstree_impl< ValueTraits, VoidOrKeyComp, SizeType - , true, SgTreeAlgorithms> tree_type; + , true, SgTreeAlgorithms, Header_Holder> tree_type; typedef tree_type implementation_defined; /// @endcond @@ -890,12 +890,15 @@ struct make_sgtree typedef typename detail::get_value_traits ::type value_traits; + typedef typename detail::get_header_holder_type + < value_traits, typename packed_options::header_holder_type >::type header_holder_type; typedef sgtree_impl < value_traits , typename packed_options::compare , typename packed_options::size_type , packed_options::floating_point + , header_holder_type > implementation_defined; /// @endcond typedef implementation_defined type; diff --git a/include/boost/intrusive/slist.hpp b/include/boost/intrusive/slist.hpp index af8e4ce..8970340 100644 --- a/include/boost/intrusive/slist.hpp +++ b/include/boost/intrusive/slist.hpp @@ -96,7 +96,7 @@ struct slist_bool_flags #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif class slist_impl { @@ -1972,31 +1972,31 @@ class slist_impl #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif inline bool operator< #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) (const slist_impl &x, const slist_impl &y) #else -( const slist_impl &x -, const slist_impl &y) +( const slist_impl &x +, const slist_impl &y) #endif { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif bool operator== #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) (const slist_impl &x, const slist_impl &y) #else -( const slist_impl &x -, const slist_impl &y) +( const slist_impl &x +, const slist_impl &y) #endif { - typedef slist_impl slist_type; + typedef slist_impl slist_type; typedef typename slist_type::const_iterator const_iterator; const bool C = slist_type::constant_time_size; if(C && x.size() != y.size()){ @@ -2026,70 +2026,70 @@ bool operator== #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif inline bool operator!= #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) (const slist_impl &x, const slist_impl &y) #else -( const slist_impl &x -, const slist_impl &y) +( const slist_impl &x +, const slist_impl &y) #endif { return !(x == y); } #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif inline bool operator> #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) (const slist_impl &x, const slist_impl &y) #else -( const slist_impl &x -, const slist_impl &y) +( const slist_impl &x +, const slist_impl &y) #endif { return y < x; } #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif inline bool operator<= #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) (const slist_impl &x, const slist_impl &y) #else -( const slist_impl &x -, const slist_impl &y) +( const slist_impl &x +, const slist_impl &y) #endif { return !(y < x); } #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif inline bool operator>= #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) (const slist_impl &x, const slist_impl &y) #else -( const slist_impl &x -, const slist_impl &y) +( const slist_impl &x +, const slist_impl &y) #endif { return !(x < y); } #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif inline void swap #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) (slist_impl &x, slist_impl &y) #else -( slist_impl &x -, slist_impl &y) +( slist_impl &x +, slist_impl &y) #endif { x.swap(y); } @@ -2113,12 +2113,15 @@ struct make_slist >::type packed_options; typedef typename detail::get_value_traits ::type value_traits; + typedef typename detail::get_header_holder_type + < value_traits, typename packed_options::header_holder_type >::type header_holder_type; typedef slist_impl < value_traits , typename packed_options::size_type , (std::size_t(packed_options::linear)*slist_bool_flags::linear_pos) |(std::size_t(packed_options::constant_time_size)*slist_bool_flags::constant_time_size_pos) |(std::size_t(packed_options::cache_last)*slist_bool_flags::cache_last_pos) + , header_holder_type > implementation_defined; /// @endcond typedef implementation_defined type; diff --git a/include/boost/intrusive/splay_set.hpp b/include/boost/intrusive/splay_set.hpp index f90050c..c53ac7e 100644 --- a/include/boost/intrusive/splay_set.hpp +++ b/include/boost/intrusive/splay_set.hpp @@ -36,15 +36,15 @@ namespace intrusive { #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif class splay_set_impl #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED - : public splaytree_impl + : public splaytree_impl #endif { /// @cond - typedef splaytree_impl tree_type; + typedef splaytree_impl tree_type; BOOST_MOVABLE_BUT_NOT_COPYABLE(splay_set_impl) typedef tree_type implementation_defined; @@ -435,12 +435,15 @@ struct make_splay_set typedef typename detail::get_value_traits ::type value_traits; + typedef typename detail::get_header_holder_type + < value_traits, typename packed_options::header_holder_type >::type header_holder_type; typedef splay_set_impl < value_traits , typename packed_options::compare , typename packed_options::size_type , packed_options::constant_time_size + , header_holder_type > implementation_defined; /// @endcond typedef implementation_defined type; @@ -528,15 +531,15 @@ class splay_set #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif class splay_multiset_impl #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED - : public splaytree_impl + : public splaytree_impl #endif { /// @cond - typedef splaytree_impl tree_type; + typedef splaytree_impl tree_type; BOOST_MOVABLE_BUT_NOT_COPYABLE(splay_multiset_impl) typedef tree_type implementation_defined; @@ -889,12 +892,15 @@ struct make_splay_multiset typedef typename detail::get_value_traits ::type value_traits; + typedef typename detail::get_header_holder_type + < value_traits, typename packed_options::header_holder_type >::type header_holder_type; typedef splay_multiset_impl < value_traits , typename packed_options::compare , typename packed_options::size_type , packed_options::constant_time_size + , header_holder_type > implementation_defined; /// @endcond typedef implementation_defined type; diff --git a/include/boost/intrusive/splaytree.hpp b/include/boost/intrusive/splaytree.hpp index 1790264..d20fbf8 100644 --- a/include/boost/intrusive/splaytree.hpp +++ b/include/boost/intrusive/splaytree.hpp @@ -65,18 +65,19 @@ struct splaytree_defaults #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif class splaytree_impl /// @cond - : public bstree_impl + : public bstree_impl /// @endcond { public: typedef ValueTraits value_traits; /// @cond typedef bstree_impl< ValueTraits, VoidOrKeyComp, SizeType - , ConstantTimeSize, SplayTreeAlgorithms> tree_type; + , ConstantTimeSize, SplayTreeAlgorithms + , Header_Holder> tree_type; typedef tree_type implementation_defined; /// @endcond @@ -531,12 +532,15 @@ struct make_splaytree typedef typename detail::get_value_traits ::type value_traits; + typedef typename detail::get_header_holder_type + < value_traits, typename packed_options::header_holder_type >::type header_holder_type; typedef splaytree_impl < value_traits , typename packed_options::compare , typename packed_options::size_type , packed_options::constant_time_size + , header_holder_type > implementation_defined; /// @endcond typedef implementation_defined type; diff --git a/include/boost/intrusive/treap.hpp b/include/boost/intrusive/treap.hpp index e7d8ada..3d656c6 100644 --- a/include/boost/intrusive/treap.hpp +++ b/include/boost/intrusive/treap.hpp @@ -69,16 +69,16 @@ struct treap_defaults #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif class treap_impl /// @cond - : public bstree_impl + : public bstree_impl , public detail::ebo_functor_holder < typename get_prio < VoidOrPrioComp , typename bstree_impl - ::value_type>::type + ::value_type>::type > /// @endcond { @@ -86,7 +86,8 @@ class treap_impl typedef ValueTraits value_traits; /// @cond typedef bstree_impl< ValueTraits, VoidOrKeyComp, SizeType - , ConstantTimeSize, BsTreeAlgorithms> tree_type; + , ConstantTimeSize, BsTreeAlgorithms + , Header_Holder> tree_type; typedef tree_type implementation_defined; typedef get_prio < VoidOrPrioComp @@ -1079,6 +1080,8 @@ struct make_treap typedef typename detail::get_value_traits ::type value_traits; + typedef typename detail::get_header_holder_type + < value_traits, typename packed_options::header_holder_type >::type header_holder_type; typedef treap_impl < value_traits @@ -1086,6 +1089,7 @@ struct make_treap , typename packed_options::priority , typename packed_options::size_type , packed_options::constant_time_size + , header_holder_type > implementation_defined; /// @endcond typedef implementation_defined type; diff --git a/include/boost/intrusive/treap_set.hpp b/include/boost/intrusive/treap_set.hpp index 10fe46d..7869463 100644 --- a/include/boost/intrusive/treap_set.hpp +++ b/include/boost/intrusive/treap_set.hpp @@ -36,16 +36,16 @@ namespace intrusive { #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif class treap_set_impl #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED - : public treap_impl + : public treap_impl #endif { /// @cond public: - typedef treap_impl tree_type; + typedef treap_impl tree_type; BOOST_MOVABLE_BUT_NOT_COPYABLE(treap_set_impl) typedef tree_type implementation_defined; @@ -439,6 +439,8 @@ struct make_treap_set typedef typename detail::get_value_traits ::type value_traits; + typedef typename detail::get_header_holder_type + < value_traits, typename packed_options::header_holder_type >::type header_holder_type; typedef treap_set_impl < value_traits @@ -446,6 +448,7 @@ struct make_treap_set , typename packed_options::priority , typename packed_options::size_type , packed_options::constant_time_size + , header_holder_type > implementation_defined; /// @endcond typedef implementation_defined type; @@ -537,15 +540,15 @@ class treap_set #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif class treap_multiset_impl #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED - : public treap_impl + : public treap_impl #endif { /// @cond - typedef treap_impl tree_type; + typedef treap_impl tree_type; BOOST_MOVABLE_BUT_NOT_COPYABLE(treap_multiset_impl) typedef tree_type implementation_defined; @@ -906,6 +909,8 @@ struct make_treap_multiset typedef typename detail::get_value_traits ::type value_traits; + typedef typename detail::get_header_holder_type + < value_traits, typename packed_options::header_holder_type >::type header_holder_type; typedef treap_multiset_impl < value_traits @@ -913,6 +918,7 @@ struct make_treap_multiset , typename packed_options::priority , typename packed_options::size_type , packed_options::constant_time_size + , header_holder_type > implementation_defined; /// @endcond typedef implementation_defined type; From 81e994ff07ae9c4c331417de9d10d8a25200e239 Mon Sep 17 00:00:00 2001 From: Matei David Date: Thu, 15 May 2014 18:54:22 -0400 Subject: [PATCH 06/14] lib: renamed struct: default_holder -> default_header_holder renamed holder methods: get_header_node -> get_node TTI checks not working --- include/boost/intrusive/detail/utilities.hpp | 22 ++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/include/boost/intrusive/detail/utilities.hpp b/include/boost/intrusive/detail/utilities.hpp index a454822..b11c89c 100644 --- a/include/boost/intrusive/detail/utilities.hpp +++ b/include/boost/intrusive/detail/utilities.hpp @@ -31,6 +31,7 @@ #include #include #include +#include namespace boost { namespace intrusive { @@ -896,34 +897,43 @@ static typename uncast_types::non_const_pointer // trivial header node holder template < typename Node_Traits > -struct default_holder : public Node_Traits::node +struct default_header_holder : public Node_Traits::node { typedef Node_Traits node_traits; typedef typename node_traits::node node; typedef typename node_traits::node_ptr node_ptr; typedef typename node_traits::const_node_ptr const_node_ptr; - default_holder() : node() {} + default_header_holder() : node() {} - const_node_ptr get_header_node() const + const_node_ptr get_node() const { return pointer_traits< const_node_ptr >::pointer_to(*static_cast< const node* >(this)); } - node_ptr get_header_node() + node_ptr get_node() { return pointer_traits< node_ptr >::pointer_to(*static_cast< node* >(this)); } + + // (unsafe) downcast used to implement container-from-iterator + static default_header_holder* get_holder(node_ptr p) + { return static_cast< default_header_holder* >(boost::intrusive::detail::to_raw_pointer(p)); } }; +//BOOST_TTI_HAS_MEMBER_FUNCTION(get_node) + // type function producing the header node holder template < typename Value_Traits, typename Header_Holder > struct get_header_holder_type { + //typedef typename Value_Traits::node_ptr node_ptr; + //typedef typename Value_Traits::const_node_ptr const_node_ptr; + //BOOST_STATIC_ASSERT((has_member_function_get_node< Header_Holder, node_ptr () >::value)); + //BOOST_STATIC_ASSERT((has_member_function_get_node< Header_Holder, const_node_ptr () const>::value)); typedef Header_Holder type; }; template < typename Value_Traits > struct get_header_holder_type< Value_Traits, void > { - typedef default_holder< typename Value_Traits::node_traits > type; + typedef default_header_holder< typename Value_Traits::node_traits > type; }; - } //namespace detail template From 7be8c2521b49745149e9bab34540605ed1d6c761 Mon Sep 17 00:00:00 2001 From: Matei David Date: Thu, 15 May 2014 18:55:56 -0400 Subject: [PATCH 07/14] lib: core implementation of header_holder in list_impl --- include/boost/intrusive/list.hpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/include/boost/intrusive/list.hpp b/include/boost/intrusive/list.hpp index b2dfa4e..a32f53a 100644 --- a/include/boost/intrusive/list.hpp +++ b/include/boost/intrusive/list.hpp @@ -83,9 +83,12 @@ class list_impl typedef typename node_traits::node_ptr node_ptr; typedef typename node_traits::const_node_ptr const_node_ptr; typedef circular_list_algorithms node_algorithms; + typedef Header_Holder header_holder_type; static const bool constant_time_size = ConstantTimeSize; static const bool stateful_value_traits = detail::is_stateful_value_traits::value; + static const bool has_container_from_iterator = + boost::is_same< header_holder_type, detail::default_header_holder< node_traits > >::value; /// @cond @@ -103,15 +106,13 @@ class list_impl )); node_ptr get_root_node() - { return pointer_traits::pointer_to(data_.root_plus_size_.root_); } + { return data_.root_plus_size_.get_node(); } const_node_ptr get_root_node() const - { return pointer_traits::pointer_to(data_.root_plus_size_.root_); } + { return data_.root_plus_size_.get_node(); } - struct root_plus_size : public size_traits - { - node root_; - }; + struct root_plus_size : public header_holder_type, public size_traits + { }; struct data_t : public value_traits { @@ -1255,8 +1256,10 @@ class list_impl private: static list_impl &priv_container_from_end_iterator(const const_iterator &end_iterator) { - root_plus_size *r = detail::parent_from_member - ( boost::intrusive::detail::to_raw_pointer(end_iterator.pointed_node()), &root_plus_size::root_); + BOOST_STATIC_ASSERT((has_container_from_iterator)); + node_ptr p = end_iterator.pointed_node(); + header_holder_type* h = header_holder_type::get_holder(p); + root_plus_size* r = static_cast< root_plus_size* >(h); data_t *d = detail::parent_from_member ( r, &data_t::root_plus_size_); list_impl *s = detail::parent_from_member(d, &list_impl::data_); From bb975d1bb7a96e18b64e73de3893bfda92893c67 Mon Sep 17 00:00:00 2001 From: Matei David Date: Fri, 16 May 2014 10:13:54 -0400 Subject: [PATCH 08/14] lib: removed some unused methods --- include/boost/intrusive/slist.hpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/include/boost/intrusive/slist.hpp b/include/boost/intrusive/slist.hpp index 8970340..18242af 100644 --- a/include/boost/intrusive/slist.hpp +++ b/include/boost/intrusive/slist.hpp @@ -226,16 +226,6 @@ class slist_impl value_traits &priv_value_traits() { return data_; } - protected: - node &prot_root_node() - { return data_.root_plus_size_.root_; } - - node const &prot_root_node() const - { return data_.root_plus_size_.root_; } - - void prot_set_size(size_type s) - { data_.root_plus_size_.set_size(s); } - public: typedef typename pointer_traits::template From e9b63d291fb78a45cf351075a195e6a5f8d3f4f6 Mon Sep 17 00:00:00 2001 From: Matei David Date: Fri, 16 May 2014 10:14:38 -0400 Subject: [PATCH 09/14] lib: core implementation of header_holder in slist_impl --- include/boost/intrusive/slist.hpp | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/include/boost/intrusive/slist.hpp b/include/boost/intrusive/slist.hpp index 18242af..491dd01 100644 --- a/include/boost/intrusive/slist.hpp +++ b/include/boost/intrusive/slist.hpp @@ -37,17 +37,17 @@ namespace intrusive { /// @cond -template -struct root_plus_last +template +struct header_holder_plus_last { - Node root_; + Header_Holder header_holder_; NodePtr last_; }; -template -struct root_plus_last +template +struct header_holder_plus_last { - Node root_; + Header_Holder header_holder_; }; struct slist_defaults @@ -116,11 +116,14 @@ class slist_impl typedef typename node_traits::node node; typedef typename node_traits::node_ptr node_ptr; typedef typename node_traits::const_node_ptr const_node_ptr; + typedef Header_Holder header_holder_type; static const bool constant_time_size = 0 != (BoolFlags & slist_bool_flags::constant_time_size_pos); static const bool stateful_value_traits = detail::is_stateful_value_traits::value; static const bool linear = 0 != (BoolFlags & slist_bool_flags::linear_pos); static const bool cache_last = 0 != (BoolFlags & slist_bool_flags::cache_last_pos); + static const bool has_container_from_iterator = + boost::is_same< header_holder_type, detail::default_header_holder< node_traits > >::value; typedef typename detail::if_c < linear @@ -153,10 +156,10 @@ class slist_impl (linear ? const_node_ptr() : this->get_root_node()); } node_ptr get_root_node() - { return pointer_traits::pointer_to(data_.root_plus_size_.root_); } + { return data_.root_plus_size_.header_holder_.get_node(); } const_node_ptr get_root_node() const - { return pointer_traits::pointer_to(data_.root_plus_size_.root_); } + { return data_.root_plus_size_.header_holder_.get_node(); } node_ptr get_last_node() { return this->get_last_node(detail::bool_()); } @@ -198,9 +201,10 @@ class slist_impl } } + typedef header_holder_plus_last header_holder_plus_last_t; struct root_plus_size : public size_traits - , public root_plus_last + , public header_holder_plus_last_t {}; struct data_t @@ -1950,8 +1954,12 @@ class slist_impl //Obtaining the container from the end iterator is not possible with linear //singly linked lists (because "end" is represented by the null pointer) BOOST_STATIC_ASSERT(!linear); - root_plus_size *r = detail::parent_from_member - ( boost::intrusive::detail::to_raw_pointer(end_iterator.pointed_node()), (&root_plus_size::root_)); + BOOST_STATIC_ASSERT((has_container_from_iterator)); + node_ptr p = end_iterator.pointed_node(); + header_holder_type* h = header_holder_type::get_holder(p); + header_holder_plus_last_t* hpl = detail::parent_from_member< header_holder_plus_last_t, header_holder_type> + (h, &header_holder_plus_last_t::header_holder_); + root_plus_size* r = static_cast< root_plus_size* >(hpl); data_t *d = detail::parent_from_member ( r, &data_t::root_plus_size_); slist_impl *s = detail::parent_from_member(d, &slist_impl::data_); From 64f880c2d64de16ba3dcd4ea3bf25c2795d18ddd Mon Sep 17 00:00:00 2001 From: Matei David Date: Fri, 16 May 2014 10:25:09 -0400 Subject: [PATCH 10/14] lib: removed some unused method bstbase3::priv_container_from_end_iterator --- include/boost/intrusive/bstree.hpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/include/boost/intrusive/bstree.hpp b/include/boost/intrusive/bstree.hpp index 1e1fe86..172598a 100644 --- a/include/boost/intrusive/bstree.hpp +++ b/include/boost/intrusive/bstree.hpp @@ -1864,13 +1864,6 @@ class bstree_impl return b.unconst(); } /// @endcond - - private: - static bstree_impl &priv_container_from_end_iterator(const const_iterator &end_iterator) - { - return *static_cast - (boost::intrusive::detail::to_raw_pointer(end_iterator.pointed_node())); - } }; #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) From 80b509ee2dcf01354d85ed089d61859be13b0372 Mon Sep 17 00:00:00 2001 From: Matei David Date: Fri, 16 May 2014 10:58:20 -0400 Subject: [PATCH 11/14] lib: fix proxy-reference-unfriendly method in node_cloner --- include/boost/intrusive/detail/utilities.hpp | 13 +- test/generic_assoc_test.hpp | 186 ++++++++++++------- test/generic_multiset_test.hpp | 70 +++---- test/generic_set_test.hpp | 92 ++++----- test/multiset_test.cpp | 112 +++++++++-- test/set_test.cpp | 111 +++++++++-- test/test_container.hpp | 18 +- 7 files changed, 430 insertions(+), 172 deletions(-) diff --git a/include/boost/intrusive/detail/utilities.hpp b/include/boost/intrusive/detail/utilities.hpp index b11c89c..86e3c7c 100644 --- a/include/boost/intrusive/detail/utilities.hpp +++ b/include/boost/intrusive/detail/utilities.hpp @@ -239,14 +239,25 @@ struct node_cloner typedef typename real_value_traits::pointer pointer; typedef typename node_traits::node node; typedef typename real_value_traits::const_node_ptr const_node_ptr; + typedef typename real_value_traits::reference reference; + typedef typename real_value_traits::const_reference const_reference; node_cloner(F f, const RealValueTraits *traits) : base_t(f), traits_(traits) {} + // tree-based containers use this method, which is proxy-reference friendly node_ptr operator()(const node_ptr & p) - { return this->operator()(*p); } + { + const_reference v = *traits_->to_value_ptr(p); + node_ptr n = traits_->to_node_ptr(*base_t::get()(v)); + //Cloned node must be in default mode if the linking mode requires it + if(safemode_or_autounlink) + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(n)); + return n; + } + // hashtables use this method, which is proxy-reference unfriendly node_ptr operator()(const node &to_clone) { const value_type &v = diff --git a/test/generic_assoc_test.hpp b/test/generic_assoc_test.hpp index 6b01749..6dbae8a 100644 --- a/test/generic_assoc_test.hpp +++ b/test/generic_assoc_test.hpp @@ -75,35 +75,41 @@ template& values); - static void test_clone(std::vector& values); + typedef typename Value_Container< value_type >::type value_cont_type; + typedef typename ValueTraits::reference reference; + typedef typename ValueTraits::const_reference const_reference; + static void test_all(value_cont_type& values); + static void test_clone(value_cont_type& values); static void test_insert_erase_burst(); - static void test_container_from_end(std::vector& values); - static void test_splay_up(std::vector& values); - static void test_splay_up(std::vector& values, boost::intrusive::detail::true_type); - static void test_splay_up(std::vector& values, boost::intrusive::detail::false_type); - static void test_splay_down(std::vector& values); - static void test_splay_down(std::vector& values, boost::intrusive::detail::true_type); - static void test_splay_down(std::vector& values, boost::intrusive::detail::false_type); - static void test_rebalance(std::vector& values); - static void test_rebalance(std::vector& values, boost::intrusive::detail::true_type); - static void test_rebalance(std::vector& values, boost::intrusive::detail::false_type); - static void test_insert_before(std::vector& values); - static void test_insert_before(std::vector& values, boost::intrusive::detail::true_type); - static void test_insert_before(std::vector& values, boost::intrusive::detail::false_type); - static void test_container_from_iterator(std::vector& values); + static void test_container_from_end(value_cont_type& values); + static void test_splay_up(value_cont_type& values); + static void test_splay_up(value_cont_type& values, boost::intrusive::detail::true_type); + static void test_splay_up(value_cont_type& values, boost::intrusive::detail::false_type); + static void test_splay_down(value_cont_type& values); + static void test_splay_down(value_cont_type& values, boost::intrusive::detail::true_type); + static void test_splay_down(value_cont_type& values, boost::intrusive::detail::false_type); + static void test_rebalance(value_cont_type& values); + static void test_rebalance(value_cont_type& values, boost::intrusive::detail::true_type); + static void test_rebalance(value_cont_type& values, boost::intrusive::detail::false_type); + static void test_insert_before(value_cont_type& values); + static void test_insert_before(value_cont_type& values, boost::intrusive::detail::true_type); + static void test_insert_before(value_cont_type& values, boost::intrusive::detail::false_type); + static void test_container_from_iterator(value_cont_type& values); }; -template class ContainerDefiner> -void test_generic_assoc:: - test_container_from_iterator(std::vector& values) +template < bool Has_Container_From_Iterator, typename assoc_type, typename Value_Container > +struct test_container_from_iterator_impl +{ + void operator () (Value_Container&) + { + std::clog << "skipping test_container_from_iterator\n"; + } +}; +template < typename assoc_type, typename Value_Container > +struct test_container_from_iterator_impl< true, assoc_type, Value_Container > +{ + void operator () (Value_Container& values) { - typedef typename ContainerDefiner - < value_type - , value_traits - , constant_time_size - >::type assoc_type; - assoc_type testset(values.begin(), values.end()); typedef typename assoc_type::iterator it_type; typedef typename assoc_type::const_iterator cit_type; @@ -121,16 +127,30 @@ void test_generic_assoc:: BOOST_TEST(testset.size() == sz); } } +}; + +template class ContainerDefiner> +void test_generic_assoc:: + test_container_from_iterator(value_cont_type& values) +{ + typedef typename ContainerDefiner + < value_type + , value_traits + , constant_time_size + >::type assoc_type; + test_container_from_iterator_impl< assoc_type::has_container_from_iterator, assoc_type, value_cont_type >()(values); +} template class ContainerDefiner> void test_generic_assoc::test_insert_erase_burst() { typedef typename ValueTraits::value_type value_type; - std::vector values; + //value_cont_type values; const int MaxValues = 100; + value_cont_type values(MaxValues); for(int i = 0; i != MaxValues; ++i){ - values.push_back(value_type(i)); + (&values[i])->value_ = i; } typedef typename ContainerDefiner @@ -141,7 +161,7 @@ void test_generic_assoc::test_insert_erase_burst( typedef typename assoc_type::iterator iterator; //First ordered insertions - assoc_type testset (&values[0], &values[0] + values.size()); + assoc_type testset (values.begin(), values.begin() + values.size()); TEST_INTRUSIVE_SEQUENCE_EXPECTED(testset, testset.begin()); //Ordered erasure @@ -157,13 +177,11 @@ void test_generic_assoc::test_insert_erase_burst( //Now random insertions std::random_shuffle(values.begin(), values.end()); - testset.insert(&values[0], &values[0] + values.size()); - std::vector values_ordered(values); - std::sort(values_ordered.begin(), values_ordered.end()); + testset.insert(values.begin(), values.begin() + values.size()); TEST_INTRUSIVE_SEQUENCE_EXPECTED(testset, testset.begin()); { - typedef typename std::vector::const_iterator cvec_iterator; + typedef typename value_cont_type::const_iterator cvec_iterator; //Random erasure std::vector it_vector; @@ -182,7 +200,7 @@ void test_generic_assoc::test_insert_erase_burst( } template class ContainerDefiner> -void test_generic_assoc::test_all(std::vector& values) +void test_generic_assoc::test_all(value_cont_type& values) { test_clone(values); test_container_from_end(values); @@ -194,18 +212,28 @@ void test_generic_assoc::test_all(std::vector class ContainerDefiner> -void test_generic_assoc - ::test_clone(std::vector& values) +template < bool Has_Value_Allocator, typename assoc_type, typename value_cont_type > +struct test_clone_impl { - typedef typename ValueTraits::value_type value_type; - typedef typename ContainerDefiner - < value_type - , value_traits - , constant_time_size - >::type assoc_type; +void operator () (value_cont_type& values) +{ + assoc_type testset1 (values.begin(), values.begin() + values.size()); + assoc_type testset2; - assoc_type testset1 (&values[0], &values[0] + values.size()); + testset2.clone_from(testset1); + BOOST_TEST (testset2 == testset1); + testset2.clear_and_dispose(); + BOOST_TEST (testset2.empty()); +} +}; + +template < typename assoc_type, typename value_cont_type > +struct test_clone_impl< false, assoc_type, value_cont_type > +{ +void operator () (value_cont_type& values) +{ + typedef typename assoc_type::value_type value_type; + assoc_type testset1 (values.begin(), values.begin() + values.size()); assoc_type testset2; testset2.clone_from(testset1, test::new_cloner(), test::delete_disposer()); @@ -213,10 +241,11 @@ void test_generic_assoc testset2.clear_and_dispose(test::delete_disposer()); BOOST_TEST (testset2.empty()); } +}; template class ContainerDefiner> void test_generic_assoc - ::test_container_from_end(std::vector& values) + ::test_clone(value_cont_type& values) { typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -224,14 +253,45 @@ void test_generic_assoc , value_traits , constant_time_size >::type assoc_type; - assoc_type testset (&values[0], &values[0] + values.size()); + + test_clone_impl< assoc_type::has_value_allocator, assoc_type, value_cont_type >()(values); +} + +template < bool Has_Container_From_Iterator, typename assoc_type, typename value_cont_type > +struct test_container_from_end_impl +{ + void operator () (value_cont_type&) + { + std::clog << "skipping test_container_from_end\n"; + } +}; +template < typename assoc_type, typename value_cont_type > +struct test_container_from_end_impl< true, assoc_type, value_cont_type > +{ + void operator () (value_cont_type& values) +{ + assoc_type testset (values.begin(), values.begin() + values.size()); BOOST_TEST (testset == assoc_type::container_from_end_iterator(testset.end())); BOOST_TEST (testset == assoc_type::container_from_end_iterator(testset.cend())); } +}; + +template class ContainerDefiner> +void test_generic_assoc + ::test_container_from_end(value_cont_type& values) +{ + typedef typename ValueTraits::value_type value_type; + typedef typename ContainerDefiner + < value_type + , value_traits + , constant_time_size + >::type assoc_type; + test_container_from_end_impl< assoc_type::has_container_from_iterator, assoc_type, value_cont_type >()(values); +} template class ContainerDefiner> void test_generic_assoc::test_splay_up -(std::vector& values, boost::intrusive::detail::true_type) +(value_cont_type& values, boost::intrusive::detail::true_type) { typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -240,7 +300,7 @@ void test_generic_assoc::test_splay_up , constant_time_size >::type assoc_type; typedef typename assoc_type::iterator iterator; - typedef std::vector orig_set_t; + typedef value_cont_type orig_set_t; std::size_t num_values; orig_set_t original_testset; { @@ -269,12 +329,12 @@ void test_generic_assoc::test_splay_up template class ContainerDefiner> void test_generic_assoc::test_splay_up -(std::vector&, boost::intrusive::detail::false_type) +(value_cont_type&, boost::intrusive::detail::false_type) {} template class ContainerDefiner> void test_generic_assoc::test_splay_up -(std::vector& values) +(value_cont_type& values) { typedef typename ContainerDefiner < value_type @@ -288,7 +348,7 @@ void test_generic_assoc::test_splay_up template class ContainerDefiner> void test_generic_assoc::test_splay_down -(std::vector& values, boost::intrusive::detail::true_type) +(value_cont_type& values, boost::intrusive::detail::true_type) { typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -297,7 +357,7 @@ void test_generic_assoc::test_splay_down , constant_time_size >::type assoc_type; typedef typename assoc_type::iterator iterator; - typedef std::vector orig_set_t; + typedef value_cont_type orig_set_t; std::size_t num_values; orig_set_t original_testset; { @@ -327,12 +387,12 @@ void test_generic_assoc::test_splay_down template class ContainerDefiner> void test_generic_assoc::test_splay_down -(std::vector&, boost::intrusive::detail::false_type) +(value_cont_type&, boost::intrusive::detail::false_type) {} template class ContainerDefiner> void test_generic_assoc::test_splay_down -(std::vector& values) +(value_cont_type& values) { typedef typename ContainerDefiner < value_type @@ -346,7 +406,7 @@ void test_generic_assoc::test_splay_down template class ContainerDefiner> void test_generic_assoc::test_rebalance -(std::vector& values, boost::intrusive::detail::true_type) +(value_cont_type& values, boost::intrusive::detail::true_type) { typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -354,7 +414,7 @@ void test_generic_assoc::test_rebalance , value_traits , constant_time_size >::type assoc_type; - typedef std::vector orig_set_t; + typedef value_cont_type orig_set_t; orig_set_t original_testset; { assoc_type testset (values.begin(), values.end()); @@ -385,12 +445,12 @@ void test_generic_assoc::test_rebalance template class ContainerDefiner> void test_generic_assoc::test_rebalance -(std::vector&, boost::intrusive::detail::false_type) +(value_cont_type&, boost::intrusive::detail::false_type) {} template class ContainerDefiner> void test_generic_assoc::test_rebalance -(std::vector& values) +(value_cont_type& values) { typedef typename ContainerDefiner < value_type @@ -404,7 +464,7 @@ void test_generic_assoc::test_rebalance template class ContainerDefiner> void test_generic_assoc::test_insert_before -(std::vector& values, boost::intrusive::detail::true_type) +(value_cont_type& values, boost::intrusive::detail::true_type) { typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -414,7 +474,7 @@ void test_generic_assoc::test_insert_before >::type assoc_type; { assoc_type testset; - typedef typename std::vector::iterator vec_iterator; + typedef typename value_cont_type::iterator vec_iterator; for(vec_iterator it(values.begin()), itend(values.end()) ; it != itend ; ++it){ @@ -425,7 +485,7 @@ void test_generic_assoc::test_insert_before } { assoc_type testset; - typedef typename std::vector::iterator vec_iterator; + typedef typename value_cont_type::iterator vec_iterator; for(vec_iterator it(--values.end()); true; --it){ testset.push_front(*it); @@ -438,7 +498,7 @@ void test_generic_assoc::test_insert_before } { assoc_type testset; - typedef typename std::vector::iterator vec_iterator; + typedef typename value_cont_type::iterator vec_iterator; typename assoc_type::iterator it_pos = testset.insert_before(testset.end(), *values.rbegin()); testset.insert_before(testset.begin(), *values.begin()); @@ -454,12 +514,12 @@ void test_generic_assoc::test_insert_before template class ContainerDefiner> void test_generic_assoc::test_insert_before -(std::vector&, boost::intrusive::detail::false_type) +(value_cont_type&, boost::intrusive::detail::false_type) {} template class ContainerDefiner> void test_generic_assoc::test_insert_before -(std::vector& values) +(value_cont_type& values) { typedef typename ContainerDefiner < value_type diff --git a/test/generic_multiset_test.hpp b/test/generic_multiset_test.hpp index 81a0c27..fe3800d 100644 --- a/test/generic_multiset_test.hpp +++ b/test/generic_multiset_test.hpp @@ -27,11 +27,14 @@ template::type value_cont_type; + typedef typename ValueTraits::reference reference; + typedef typename ValueTraits::const_reference const_reference; static void test_all (); - static void test_sort(std::vector& values); - static void test_insert(std::vector& values); - static void test_swap(std::vector& values); - static void test_find(std::vector& values); + static void test_sort(value_cont_type& values); + static void test_insert(value_cont_type& values); + static void test_swap(value_cont_type& values); + static void test_find(value_cont_type& values); static void test_impl(); }; @@ -40,9 +43,9 @@ void test_generic_multiset::test_all () { typedef typename ValueTraits::value_type value_type; static const int random_init[6] = { 3, 2, 4, 1, 5, 2 }; - std::vector values (6); + value_cont_type values (6); for (int i = 0; i < 6; ++i) - values[i].value_ = random_init[i]; + (&values[i])->value_ = random_init[i]; typedef typename ContainerDefiner < value_type @@ -75,9 +78,9 @@ template::test_impl() { typedef typename ValueTraits::value_type value_type; - std::vector values (5); + value_cont_type values (5); for (int i = 0; i < 5; ++i) - values[i].value_ = i; + (&values[i])->value_ = i; typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner < value_type @@ -99,7 +102,7 @@ void test_generic_multiset::test_impl() //test: constructor, iterator, clear, reverse_iterator, front, back, size: template class ContainerDefiner> -void test_generic_multiset::test_sort(std::vector& values) +void test_generic_multiset::test_sort(value_cont_type& values) { typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -121,7 +124,7 @@ void test_generic_multiset::test_sort(std::vector , value_traits , constant_time_size >::type multiset_type2; - multiset_type2 testset2 (&values[0], &values[0] + 6); + multiset_type2 testset2 (values.begin(), values.begin() + 6); { int init_values [] = { 5, 3, 1, 4, 2, 2 }; TEST_INTRUSIVE_SEQUENCE( init_values, testset2.rbegin() ); } @@ -131,7 +134,7 @@ void test_generic_multiset::test_sort(std::vector //test: insert, const_iterator, const_reverse_iterator, erase, iterator_to: template class ContainerDefiner> -void test_generic_multiset::test_insert(std::vector& values) +void test_generic_multiset::test_insert(value_cont_type& values) { typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -142,7 +145,7 @@ void test_generic_multiset::test_insert(std::vect >::type multiset_type; multiset_type testset; - testset.insert(&values[0] + 2, &values[0] + 5); + testset.insert(values.begin() + 2, values.begin() + 5); { int init_values [] = { 1, 4, 5 }; TEST_INTRUSIVE_SEQUENCE( init_values, testset.begin() ); } @@ -169,7 +172,7 @@ void test_generic_multiset::test_insert(std::vect //test: insert (seq-version), swap, erase (seq-version), size: template class ContainerDefiner> -void test_generic_multiset::test_swap(std::vector& values) +void test_generic_multiset::test_swap(value_cont_type& values) { typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -178,9 +181,9 @@ void test_generic_multiset::test_swap(std::vector , size_type , constant_time_size >::type multiset_type; - multiset_type testset1 (&values[0], &values[0] + 2); + multiset_type testset1 (values.begin(), values.begin() + 2); multiset_type testset2; - testset2.insert (&values[0] + 2, &values[0] + 6); + testset2.insert (values.begin() + 2, values.begin() + 6); testset1.swap (testset2); { int init_values [] = { 1, 2, 4, 5 }; @@ -195,7 +198,7 @@ void test_generic_multiset::test_swap(std::vector //test: find, equal_range (lower_bound, upper_bound): template class ContainerDefiner> -void test_generic_multiset::test_find(std::vector& values) +void test_generic_multiset::test_find(value_cont_type& values) { typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -208,8 +211,9 @@ void test_generic_multiset::test_find(std::vector typedef typename multiset_type::iterator iterator; { - value_type cmp_val; - cmp_val.value_ = 2; + value_cont_type cmp_val_cont(1); + reference cmp_val = cmp_val_cont.front(); + (&cmp_val)->value_ = 2; iterator i = testset.find (cmp_val); BOOST_TEST (i->value_ == 2); BOOST_TEST ((++i)->value_ == 2); @@ -219,7 +223,7 @@ void test_generic_multiset::test_find(std::vector BOOST_TEST (range.second->value_ == 3); BOOST_TEST (std::distance (range.first, range.second) == 2); - cmp_val.value_ = 7; + (&cmp_val)->value_ = 7; BOOST_TEST (testset.find (cmp_val) == testset.end()); } { //1, 2, 2, 3, 4, 5 @@ -227,10 +231,12 @@ void test_generic_multiset::test_find(std::vector std::pair range; std::pair::type ,typename search_const_iterator::type> const_range; - value_type cmp_val_lower, cmp_val_upper; + value_cont_type cmp_val_cont(2); + reference cmp_val_lower = cmp_val_cont.front(); + reference cmp_val_upper = cmp_val_cont.back(); { - cmp_val_lower.value_ = 1; - cmp_val_upper.value_ = 2; + (&cmp_val_lower)->value_ = 1; + (&cmp_val_upper)->value_ = 2; //left-closed, right-closed range = testset.bounded_range (cmp_val_lower, cmp_val_upper, true, true); BOOST_TEST (range.first->value_ == 1); @@ -238,39 +244,39 @@ void test_generic_multiset::test_find(std::vector BOOST_TEST (std::distance (range.first, range.second) == 3); } { - cmp_val_lower.value_ = 1; - cmp_val_upper.value_ = 2; + (&cmp_val_lower)->value_ = 1; + (&cmp_val_upper)->value_ = 2; const_range = const_testset.bounded_range (cmp_val_lower, cmp_val_upper, true, false); BOOST_TEST (const_range.first->value_ == 1); BOOST_TEST (const_range.second->value_ == 2); BOOST_TEST (std::distance (const_range.first, const_range.second) == 1); - cmp_val_lower.value_ = 1; - cmp_val_upper.value_ = 3; + (&cmp_val_lower)->value_ = 1; + (&cmp_val_upper)->value_ = 3; range = testset.bounded_range (cmp_val_lower, cmp_val_upper, true, false); BOOST_TEST (range.first->value_ == 1); BOOST_TEST (range.second->value_ == 3); BOOST_TEST (std::distance (range.first, range.second) == 3); } { - cmp_val_lower.value_ = 1; - cmp_val_upper.value_ = 2; + (&cmp_val_lower)->value_ = 1; + (&cmp_val_upper)->value_ = 2; const_range = const_testset.bounded_range (cmp_val_lower, cmp_val_upper, false, true); BOOST_TEST (const_range.first->value_ == 2); BOOST_TEST (const_range.second->value_ == 3); BOOST_TEST (std::distance (const_range.first, const_range.second) == 2); } { - cmp_val_lower.value_ = 1; - cmp_val_upper.value_ = 2; + (&cmp_val_lower)->value_ = 1; + (&cmp_val_upper)->value_ = 2; range = testset.bounded_range (cmp_val_lower, cmp_val_upper, false, false); BOOST_TEST (range.first->value_ == 2); BOOST_TEST (range.second->value_ == 2); BOOST_TEST (std::distance (range.first, range.second) == 0); } { - cmp_val_lower.value_ = 5; - cmp_val_upper.value_ = 6; + (&cmp_val_lower)->value_ = 5; + (&cmp_val_upper)->value_ = 6; const_range = const_testset.bounded_range (cmp_val_lower, cmp_val_upper, true, false); BOOST_TEST (const_range.first->value_ == 5); BOOST_TEST (const_range.second == const_testset.end()); diff --git a/test/generic_set_test.hpp b/test/generic_set_test.hpp index 2a46ba9..cf132a2 100644 --- a/test/generic_set_test.hpp +++ b/test/generic_set_test.hpp @@ -33,14 +33,17 @@ template::type value_cont_type; + typedef typename ValueTraits::reference reference; + typedef typename ValueTraits::const_reference const_reference; static void test_all(); - static void test_sort(std::vector& values); - static void test_insert(std::vector& values); - static void test_insert_advanced(std::vector& values, boost::intrusive::detail::true_type); - static void test_insert_advanced(std::vector& values, boost::intrusive::detail::false_type); - static void test_insert_advanced(std::vector& values); - static void test_swap(std::vector& values); - static void test_find(std::vector& values); + static void test_sort(value_cont_type& values); + static void test_insert(value_cont_type& values); + static void test_insert_advanced(value_cont_type& values, boost::intrusive::detail::true_type); + static void test_insert_advanced(value_cont_type& values, boost::intrusive::detail::false_type); + static void test_insert_advanced(value_cont_type& values); + static void test_swap(value_cont_type& values); + static void test_find(value_cont_type& values); static void test_impl(); }; @@ -50,9 +53,9 @@ void test_generic_set::test_all() { typedef typename ValueTraits::value_type value_type; static const int random_init[6] = { 3, 2, 4, 1, 5, 2 }; - std::vector values (6); + value_cont_type values(6); for (int i = 0; i < 6; ++i) - values[i].value_ = random_init[i]; + (&values[i])->value_ = random_init[i]; typedef typename ContainerDefiner < value_type @@ -86,9 +89,9 @@ template::test_impl() { typedef typename ValueTraits::value_type value_type; - std::vector values (5); + value_cont_type values (5); for (int i = 0; i < 5; ++i) - values[i].value_ = i; + (&values[i])->value_ = i; typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -110,7 +113,7 @@ void test_generic_set::test_impl() //test: constructor, iterator, clear, reverse_iterator, front, back, size: template class ContainerDefiner> -void test_generic_set::test_sort(std::vector& values) +void test_generic_set::test_sort(value_cont_type& values) { typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -132,7 +135,7 @@ void test_generic_set::test_sort(std::vector , constant_time_size >::type set_type2; - set_type2 testset2 (&values[0], &values[0] + 6); + set_type2 testset2 (values.begin(), values.begin() + 6); { int init_values [] = { 5, 3, 1, 4, 2 }; TEST_INTRUSIVE_SEQUENCE( init_values, testset2.rbegin() ); } BOOST_TEST (testset2.begin()->value_ == 2); @@ -141,7 +144,7 @@ void test_generic_set::test_sort(std::vector class ContainerDefiner> -void test_generic_set::test_insert(std::vector& values) +void test_generic_set::test_insert(value_cont_type& values) { typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -151,7 +154,7 @@ void test_generic_set::test_insert(std::vector::type set_type; { set_type testset; - testset.insert(&values[0] + 2, &values[0] + 5); + testset.insert(values.begin() + 2, values.begin() + 5); const set_type& const_testset = testset; { int init_values [] = { 1, 4, 5 }; @@ -173,9 +176,9 @@ void test_generic_set::test_insert(std::vector(values[2])); + ic = testset.iterator_to (static_cast< const_reference >(values[2])); BOOST_TEST (&*ic == &values[2]); - ic = set_type::s_iterator_to (const_cast(values[2])); + ic = set_type::s_iterator_to (static_cast< const_reference >(values[2])); BOOST_TEST (&*ic == &values[2]); testset.erase (i); @@ -186,7 +189,7 @@ void test_generic_set::test_insert(std::vector class ContainerDefiner> void test_generic_set::test_insert_advanced -(std::vector& values, boost::intrusive::detail::true_type) +(value_cont_type& values, boost::intrusive::detail::true_type) { typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -196,7 +199,7 @@ void test_generic_set::test_insert_advanced >::type set_type; { set_type testset; - testset.insert(&values[0], &values[0] + values.size()); + testset.insert(values.begin(), values.begin() + values.size()); value_type v(1); typename set_type::insert_commit_data data; BOOST_TEST (!testset.insert_check(v, testset.value_comp(), testset.priority_comp(), data).second); @@ -207,7 +210,7 @@ void test_generic_set::test_insert_advanced template class ContainerDefiner> void test_generic_set::test_insert_advanced -(std::vector& values) +(value_cont_type& values) { typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -224,7 +227,7 @@ void test_generic_set::test_insert_advanced //test: insert, const_iterator, const_reverse_iterator, erase, s_iterator_to: template class ContainerDefiner> void test_generic_set::test_insert_advanced - ( std::vector& values + ( value_cont_type& values , boost::intrusive::detail::false_type) { typedef typename ValueTraits::value_type value_type; @@ -235,7 +238,7 @@ void test_generic_set::test_insert_advanced >::type set_type; { set_type testset; - testset.insert(&values[0], &values[0] + values.size()); + testset.insert(values.begin(), values.begin() + values.size()); value_type v(1); typename set_type::insert_commit_data data; BOOST_TEST (!testset.insert_check(v, testset.value_comp(), data).second); @@ -246,7 +249,7 @@ void test_generic_set::test_insert_advanced //test: insert (seq-version), swap, erase (seq-version), size: template class ContainerDefiner> -void test_generic_set::test_swap(std::vector& values) +void test_generic_set::test_swap(value_cont_type& values) { typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -254,9 +257,9 @@ void test_generic_set::test_swap(std::vector , constant_time_size >::type set_type; - set_type testset1 (&values[0], &values[0] + 2); + set_type testset1 (values.begin(), values.begin() + 2); set_type testset2; - testset2.insert (&values[0] + 2, &values[0] + 6); + testset2.insert (values.begin() + 2, values.begin() + 6); testset1.swap (testset2); { int init_values [] = { 1, 2, 4, 5 }; @@ -273,7 +276,7 @@ void test_generic_set::test_swap(std::vector class ContainerDefiner> -void test_generic_set::test_find(std::vector& values) +void test_generic_set::test_find(value_cont_type& values) { typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -285,8 +288,10 @@ void test_generic_set::test_find(std::vectorvalue_ = 2; iterator i = testset.find (cmp_val); BOOST_TEST (i->value_ == 2); BOOST_TEST ((++i)->value_ != 2); @@ -296,7 +301,7 @@ void test_generic_set::test_find(std::vectorvalue_ == 3); BOOST_TEST (std::distance (range.first, range.second) == 1); - cmp_val.value_ = 7; + (&cmp_val)->value_ = 7; BOOST_TEST (testset.find (cmp_val) == testset.end()); } @@ -305,10 +310,13 @@ void test_generic_set::test_find(std::vector range; std::pair::type ,typename search_const_iterator::type> const_range; - value_type cmp_val_lower, cmp_val_upper; + //value_type cmp_val_lower, cmp_val_upper; + value_cont_type cmp_val_cont(2); + reference cmp_val_lower = cmp_val_cont.front(); + reference cmp_val_upper = cmp_val_cont.back(); { - cmp_val_lower.value_ = 1; - cmp_val_upper.value_ = 2; + (&cmp_val_lower)->value_ = 1; + (&cmp_val_upper)->value_ = 2; //left-closed, right-closed range = testset.bounded_range (cmp_val_lower, cmp_val_upper, true, true); BOOST_TEST (range.first->value_ == 1); @@ -316,39 +324,39 @@ void test_generic_set::test_find(std::vectorvalue_ = 1; + (&cmp_val_upper)->value_ = 2; const_range = const_testset.bounded_range (cmp_val_lower, cmp_val_upper, true, false); BOOST_TEST (const_range.first->value_ == 1); BOOST_TEST (const_range.second->value_ == 2); BOOST_TEST (std::distance (const_range.first, const_range.second) == 1); - cmp_val_lower.value_ = 1; - cmp_val_upper.value_ = 3; + (&cmp_val_lower)->value_ = 1; + (&cmp_val_upper)->value_ = 3; range = testset.bounded_range (cmp_val_lower, cmp_val_upper, true, false); BOOST_TEST (range.first->value_ == 1); BOOST_TEST (range.second->value_ == 3); BOOST_TEST (std::distance (range.first, range.second) == 2); } { - cmp_val_lower.value_ = 1; - cmp_val_upper.value_ = 2; + (&cmp_val_lower)->value_ = 1; + (&cmp_val_upper)->value_ = 2; const_range = const_testset.bounded_range (cmp_val_lower, cmp_val_upper, false, true); BOOST_TEST (const_range.first->value_ == 2); BOOST_TEST (const_range.second->value_ == 3); BOOST_TEST (std::distance (const_range.first, const_range.second) == 1); } { - cmp_val_lower.value_ = 1; - cmp_val_upper.value_ = 2; + (&cmp_val_lower)->value_ = 1; + (&cmp_val_upper)->value_ = 2; range = testset.bounded_range (cmp_val_lower, cmp_val_upper, false, false); BOOST_TEST (range.first->value_ == 2); BOOST_TEST (range.second->value_ == 2); BOOST_TEST (std::distance (range.first, range.second) == 0); } { - cmp_val_lower.value_ = 5; - cmp_val_upper.value_ = 6; + (&cmp_val_lower)->value_ = 5; + (&cmp_val_upper)->value_ = 6; const_range = const_testset.bounded_range (cmp_val_lower, cmp_val_upper, true, false); BOOST_TEST (const_range.first->value_ == 5); BOOST_TEST (const_range.second == const_testset.end()); diff --git a/test/multiset_test.cpp b/test/multiset_test.cpp index dd52cfe..2a38dcd 100644 --- a/test/multiset_test.cpp +++ b/test/multiset_test.cpp @@ -13,6 +13,7 @@ #include #include #include "itestvalue.hpp" +#include "bptr_value.hpp" #include "smart_ptr.hpp" #include "generic_multiset_test.hpp" @@ -59,6 +60,10 @@ struct hooks > nonhook_node_member_type; }; +// container generator with void node allocator +template < bool Void_Allocator > +struct GetContainer_With_Allocator +{ template< class ValueType , class Option1 =void , class Option2 =void @@ -73,8 +78,36 @@ struct GetContainer , Option3 > type; }; +}; -template +// container generator with standard (non-void) node allocator +template <> +struct GetContainer_With_Allocator< false > +{ +template< class ValueType + , class Option1 =void + , class Option2 =void + , class Option3 =void + > +struct GetContainer +{ + // extract node type through options->value_traits->node_traits->node + typedef typename pack_options< rbtree_defaults, Option1, Option2, Option3 >::type packed_options; + typedef typename detail::get_value_traits< ValueType, typename packed_options::proto_value_traits>::type value_traits; + typedef typename value_traits::node_traits::node node; + + typedef boost::intrusive::multiset + < ValueType + , Option1 + , Option2 + , Option3 + , node_allocator_type< std::allocator< node > > + > type; +}; +}; + + +template class test_main_template { public: @@ -87,7 +120,7 @@ class test_main_template < value_type , typename hooks::base_hook_type >::type - , GetContainer + , GetContainer_With_Allocator< Void_Allocator >::template GetContainer >::test_all(); test::test_generic_multiset < typename detail::get_member_value_traits < value_type @@ -96,21 +129,21 @@ class test_main_template , &value_type::node_ > >::type - , GetContainer + , GetContainer_With_Allocator< Void_Allocator >::template GetContainer >::test_all(); test::test_generic_multiset < nonhook_node_member_value_traits< value_type, typename hooks::nonhook_node_member_type, &value_type::nhn_member_, safe_link >, - GetContainer + GetContainer_With_Allocator< Void_Allocator >::template GetContainer >::test_all(); return 0; } }; -template -class test_main_template +template +class test_main_template { public: int operator()() @@ -122,7 +155,7 @@ class test_main_template < value_type , typename hooks::base_hook_type >::type - , GetContainer + , GetContainer_With_Allocator< Void_Allocator >::template GetContainer >::test_all(); test::test_generic_multiset < typename detail::get_member_value_traits @@ -132,14 +165,14 @@ class test_main_template , &value_type::node_ > >::type - , GetContainer + , GetContainer_With_Allocator< Void_Allocator >::template GetContainer >::test_all(); test::test_generic_multiset < typename detail::get_base_value_traits < value_type , typename hooks::auto_base_hook_type >::type - , GetContainer + , GetContainer_With_Allocator< Void_Allocator >::template GetContainer >::test_all(); test::test_generic_multiset < typename detail::get_member_value_traits @@ -149,18 +182,69 @@ class test_main_template , &value_type::auto_node_ > >::type - , GetContainer + , GetContainer_With_Allocator< Void_Allocator >::template GetContainer >::test_all(); return 0; } }; +// container generator which ignores further parametrization, except for compare option +template < typename Value_Traits, bool Constant_Time_Size, typename Allocator > +struct Get_Preset_Container +{ + template < class + , class Option1 = void + , class Option2 = void + , class Option3 = void + > + struct GetContainer + { + // ignore further paramatrization except for the compare option + // notably ignore the size option (use preset) + typedef typename pack_options< rbtree_defaults, Option1, Option2, Option3 >::type packed_options; + typedef typename packed_options::compare compare_option; + + typedef boost::intrusive::multiset< typename Value_Traits::value_type, + value_traits< Value_Traits >, + constant_time_size< Constant_Time_Size >, + compare< compare_option >, + node_allocator_type< Allocator > + > type; + }; +}; + +template < bool Constant_Time_Size > +struct test_main_template_bptr +{ + void operator () () + { + typedef BPtr_Value value_type; + typedef BPtr_Value_Traits< RBTree_BPtr_Node_Traits > value_traits; + typedef Bounded_Allocator< value_type > allocator_type; + + allocator_type::init(); + test::test_generic_multiset< value_traits, + Get_Preset_Container< value_traits, Constant_Time_Size, allocator_type >::template GetContainer + >::test_all(); + assert(allocator_type::is_clear()); + allocator_type::destroy(); + } +}; + int main( int, char* [] ) { - test_main_template()(); - test_main_template, false>()(); - test_main_template()(); - test_main_template, true>()(); + // test (plain/smart pointers) x (nonconst/const size) x (void node allocator) + test_main_template()(); + test_main_template, false, true>()(); + test_main_template()(); + test_main_template, true, true>()(); + // test (plain pointers) x (nonconst/const size) x (standard node allocator) + test_main_template()(); + test_main_template()(); + // test (bounded pointers) x ((nonconst/const size) x (special node allocator) + test_main_template_bptr< true >()(); + test_main_template_bptr< false >()(); + return boost::report_errors(); } diff --git a/test/set_test.cpp b/test/set_test.cpp index 8d5c490..8a2c3c6 100644 --- a/test/set_test.cpp +++ b/test/set_test.cpp @@ -14,6 +14,7 @@ #include #include "itestvalue.hpp" +#include "bptr_value.hpp" #include "smart_ptr.hpp" #include "generic_set_test.hpp" @@ -60,6 +61,10 @@ struct hooks > nonhook_node_member_type; }; +// container generator with void node allocator +template < bool Void_Allocator > +struct GetContainer_With_Allocator +{ template< class ValueType , class Option1 =void , class Option2 =void @@ -74,8 +79,36 @@ struct GetContainer , Option3 > type; }; +}; -template +// container generator with standard (non-void) node allocator +template <> +struct GetContainer_With_Allocator< false > +{ +template< class ValueType + , class Option1 =void + , class Option2 =void + , class Option3 =void + > +struct GetContainer +{ + // extract node type through options->value_traits->node_traits->node + typedef typename pack_options< rbtree_defaults, Option1, Option2, Option3 >::type packed_options; + typedef typename detail::get_value_traits< ValueType, typename packed_options::proto_value_traits>::type value_traits; + typedef typename value_traits::node_traits::node node; + + typedef boost::intrusive::set + < ValueType + , Option1 + , Option2 + , Option3 + , node_allocator_type< std::allocator< node > > + > type; +}; +}; + + +template class test_main_template { public: @@ -88,7 +121,7 @@ class test_main_template < value_type , typename hooks::base_hook_type >::type - , GetContainer + , GetContainer_With_Allocator< Void_Allocator >::template GetContainer >::test_all(); test::test_generic_set < typename detail::get_member_value_traits < value_type @@ -97,21 +130,21 @@ class test_main_template , &value_type::node_ > >::type - , GetContainer + , GetContainer_With_Allocator< Void_Allocator >::template GetContainer >::test_all(); test::test_generic_set < nonhook_node_member_value_traits< value_type, typename hooks::nonhook_node_member_type, &value_type::nhn_member_, safe_link >, - GetContainer + GetContainer_With_Allocator< Void_Allocator >::template GetContainer >::test_all(); return 0; } }; -template -class test_main_template +template +class test_main_template { public: int operator()() @@ -123,7 +156,7 @@ class test_main_template < value_type , typename hooks::base_hook_type >::type - , GetContainer + , GetContainer_With_Allocator< Void_Allocator >::template GetContainer >::test_all(); test::test_generic_set < typename detail::get_member_value_traits @@ -133,14 +166,14 @@ class test_main_template , &value_type::node_ > >::type - , GetContainer + , GetContainer_With_Allocator< Void_Allocator >::template GetContainer >::test_all(); test::test_generic_set < typename detail::get_base_value_traits < value_type , typename hooks::auto_base_hook_type >::type - , GetContainer + , GetContainer_With_Allocator< Void_Allocator >::template GetContainer >::test_all(); test::test_generic_set < typename detail::get_member_value_traits @@ -150,20 +183,70 @@ class test_main_template , &value_type::auto_node_ > >::type - , GetContainer + , GetContainer_With_Allocator< Void_Allocator >::template GetContainer >::test_all(); return 0; } }; +// container generator which ignores further parametrization, except for compare option +template < typename Value_Traits, bool Constant_Time_Size, typename Allocator > +struct Get_Preset_Container +{ + template < class + , class Option1 = void + , class Option2 = void + , class Option3 = void + > + struct GetContainer + { + // ignore further paramatrization except for the compare option + // notably ignore the size option (use preset) + typedef typename pack_options< rbtree_defaults, Option1, Option2, Option3 >::type packed_options; + typedef typename packed_options::compare compare_option; + + typedef boost::intrusive::set< typename Value_Traits::value_type, + value_traits< Value_Traits >, + constant_time_size< Constant_Time_Size >, + compare< compare_option >, + node_allocator_type< Allocator > + > type; + }; +}; + +template < bool Constant_Time_Size > +struct test_main_template_bptr +{ + void operator () () + { + typedef BPtr_Value value_type; + typedef BPtr_Value_Traits< RBTree_BPtr_Node_Traits > value_traits; + typedef Bounded_Allocator< value_type > allocator_type; + + allocator_type::init(); + test::test_generic_set< value_traits, + Get_Preset_Container< value_traits, Constant_Time_Size, allocator_type >::template GetContainer + >::test_all(); + assert(allocator_type::is_clear()); + allocator_type::destroy(); + } +}; int main( int, char* [] ) { - test_main_template()(); - test_main_template, false>()(); - test_main_template()(); - test_main_template, true>()(); + // test (plain/smart pointers) x (nonconst/const size) x (void node allocator) + test_main_template()(); + test_main_template, false, true>()(); + test_main_template()(); + test_main_template, true, true>()(); + // test (plain pointers) x (nonconst/const size) x (standard node allocator) + test_main_template()(); + test_main_template()(); + // test (bounded pointers) x ((nonconst/const size) x (special node allocator) + test_main_template_bptr< true >()(); + test_main_template_bptr< false >()(); + return boost::report_errors(); } diff --git a/test/test_container.hpp b/test/test_container.hpp index 2bacb16..fbddaec 100644 --- a/test/test_container.hpp +++ b/test/test_container.hpp @@ -428,12 +428,15 @@ void test_unordered_associative_container(Container & c, Data & d) template< class Container, class Data > void test_unique_container(Container & c, Data & d) { - typedef typename Container::value_type value_type; + //typedef typename Container::value_type value_type; c.clear(); c.insert(d.begin(),d.end()); typename Container::size_type old_size = c.size(); - value_type v(*d.begin()); - c.insert(v); + //value_type v(*d.begin()); + //c.insert(v); + Data d2(1); + (&d2.front())->value_ = (&d.front())->value_; + c.insert(d2.front()); BOOST_TEST( c.size() == old_size ); c.clear(); } @@ -441,12 +444,15 @@ void test_unique_container(Container & c, Data & d) template< class Container, class Data > void test_non_unique_container(Container & c, Data & d) { - typedef typename Container::value_type value_type; + //typedef typename Container::value_type value_type; c.clear(); c.insert(d.begin(),d.end()); typename Container::size_type old_size = c.size(); - value_type v(*d.begin()); - c.insert(v); + //value_type v(*d.begin()); + //c.insert(v); + Data d2(1); + (&d2.front())->value_ = (&d.front())->value_; + c.insert(d2.front()); BOOST_TEST( c.size() == (old_size+1) ); c.clear(); } From 54e9befe5f0f528060bd39f35b5dc9bbc2d1d451 Mon Sep 17 00:00:00 2001 From: Matei David Date: Fri, 16 May 2014 10:59:29 -0400 Subject: [PATCH 12/14] lib: core implementation of header_holder in bstbase3 --- include/boost/intrusive/bstree.hpp | 48 +++++++++++++++++------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/include/boost/intrusive/bstree.hpp b/include/boost/intrusive/bstree.hpp index 172598a..8720b05 100644 --- a/include/boost/intrusive/bstree.hpp +++ b/include/boost/intrusive/bstree.hpp @@ -61,18 +61,38 @@ struct bstbase3 typedef typename get_algo::type node_algorithms; typedef typename node_traits::node_ptr node_ptr; typedef typename node_traits::const_node_ptr const_node_ptr; + typedef tree_iterator iterator; + typedef tree_iterator const_iterator; + typedef boost::intrusive::detail::reverse_iterator reverse_iterator; + typedef boost::intrusive::detail::reverse_iterator const_reverse_iterator; + typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::pointer) pointer; + typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::const_pointer) const_pointer; + typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::element_type) value_type; + typedef BOOST_INTRUSIVE_IMPDEF(value_type) key_type; + typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::reference) reference; + typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::reference) const_reference; + typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::difference_type) difference_type; + typedef Header_Holder header_holder_type; + + static const bool safemode_or_autounlink = is_safe_autounlink::value; + static const bool stateful_value_traits = detail::is_stateful_value_traits::value; + static const bool has_container_from_iterator = + boost::is_same< header_holder_type, detail::default_header_holder< node_traits > >::value; struct holder_t : public ValueTraits { explicit holder_t(const ValueTraits &vtraits) : ValueTraits(vtraits) {} - node_type root; + header_holder_type root; } holder; - static bstbase3 &get_tree_base_from_root(node_type &root) + static bstbase3 &get_tree_base_from_end_iterator(const const_iterator &end_iterator) { - holder_t *holder = get_parent_from_member(&root, &holder_t::root); + BOOST_STATIC_ASSERT(has_container_from_iterator); + node_ptr p = end_iterator.pointed_node(); + header_holder_type* h = header_holder_type::get_holder(p); + holder_t *holder = get_parent_from_member(h, &holder_t::root); bstbase3 *base = get_parent_from_member (holder, &bstbase3::holder); return *base; } @@ -84,10 +104,10 @@ struct bstbase3 } node_ptr header_ptr() - { return pointer_traits::pointer_to(this->holder.root); } + { return holder.root.get_node(); } const_node_ptr header_ptr() const - { return pointer_traits::pointer_to(this->holder.root); } + { return holder.root.get_node(); } const value_traits &get_value_traits() const { return this->holder; } @@ -101,20 +121,6 @@ struct bstbase3 const_value_traits_ptr value_traits_ptr() const { return pointer_traits::pointer_to(this->get_value_traits()); } - typedef tree_iterator iterator; - typedef tree_iterator const_iterator; - typedef boost::intrusive::detail::reverse_iterator reverse_iterator; - typedef boost::intrusive::detail::reverse_iterator const_reverse_iterator; - typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::pointer) pointer; - typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::const_pointer) const_pointer; - typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::element_type) value_type; - typedef BOOST_INTRUSIVE_IMPDEF(value_type) key_type; - typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::reference) reference; - typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::reference) const_reference; - typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::difference_type) difference_type; - static const bool safemode_or_autounlink = is_safe_autounlink::value; - static const bool stateful_value_traits = detail::is_stateful_value_traits::value; - iterator begin() { return iterator(node_algorithms::begin_node(this->header_ptr()), this->value_traits_ptr()); } @@ -776,7 +782,7 @@ class bstree_impl static bstree_impl &container_from_end_iterator(iterator end_iterator) { return static_cast - (data_type::get_tree_base_from_root(*boost::intrusive::detail::to_raw_pointer(end_iterator.pointed_node()))); + (data_type::get_tree_base_from_end_iterator(end_iterator)); } //! Precondition: end_iterator must be a valid end const_iterator @@ -790,7 +796,7 @@ class bstree_impl static const bstree_impl &container_from_end_iterator(const_iterator end_iterator) { return static_cast - (data_type::get_tree_base_from_root(*boost::intrusive::detail::to_raw_pointer(end_iterator.pointed_node()))); + (data_type::get_tree_base_from_end_iterator(end_iterator)); } //! Precondition: it must be a valid iterator From b79d3cfdec8db26c82319a4839a6cf4b00fe8b6e Mon Sep 17 00:00:00 2001 From: Matei David Date: Fri, 16 May 2014 12:03:36 -0400 Subject: [PATCH 13/14] tests: bounded pointers tests for slist, list, (rb/avl) x (set/multiset) --- test/avl_multiset_test.cpp | 112 +++++++- test/avl_set_test.cpp | 111 +++++++- test/bounded_pointer.hpp | 355 ++++++++++++++++++++++++ test/bptr_value.hpp | 240 ++++++++++++++++ test/container_size_test.cpp | 31 +++ test/generic_assoc_test.hpp | 43 +-- test/itestvalue.hpp | 55 +++- test/list_test.cpp | 421 +++++++++++++++------------- test/multiset_test.cpp | 35 +-- test/set_test.cpp | 36 +-- test/slist_test.cpp | 522 +++++++++++++++++++---------------- 11 files changed, 1427 insertions(+), 534 deletions(-) create mode 100644 test/bounded_pointer.hpp create mode 100644 test/bptr_value.hpp diff --git a/test/avl_multiset_test.cpp b/test/avl_multiset_test.cpp index be6d3c2..c02f961 100644 --- a/test/avl_multiset_test.cpp +++ b/test/avl_multiset_test.cpp @@ -14,6 +14,7 @@ #include #include #include "itestvalue.hpp" +#include "bptr_value.hpp" #include "smart_ptr.hpp" #include "generic_multiset_test.hpp" @@ -60,6 +61,10 @@ struct hooks > nonhook_node_member_type; }; +// container generator with void node allocator +template < bool Default_Holder > +struct GetContainer_With_Holder +{ template< class ValueType , class Option1 =void , class Option2 =void @@ -74,8 +79,35 @@ struct GetContainer , Option3 > type; }; +}; -template +// container generator with standard (non-void) node allocator +template <> +struct GetContainer_With_Holder< false > +{ +template< class ValueType + , class Option1 =void + , class Option2 =void + , class Option3 =void + > +struct GetContainer +{ + // extract node type through options->value_traits->node_traits->node + typedef typename pack_options< avltree_defaults, Option1, Option2, Option3 >::type packed_options; + typedef typename detail::get_value_traits< ValueType, typename packed_options::proto_value_traits>::type value_traits; + typedef typename value_traits::node_traits::node node; + + typedef boost::intrusive::avl_multiset + < ValueType + , Option1 + , Option2 + , Option3 + , header_holder_type< pointer_holder< node > > + > type; +}; +}; + +template class test_main_template { public: @@ -88,7 +120,7 @@ class test_main_template < value_type , typename hooks::base_hook_type >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_multiset < typename detail::get_member_value_traits < value_type @@ -97,21 +129,21 @@ class test_main_template , &value_type::node_ > >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_multiset < nonhook_node_member_value_traits< value_type, typename hooks::nonhook_node_member_type, &value_type::nhn_member_, safe_link >, - GetContainer + GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); return 0; } }; -template -class test_main_template +template +class test_main_template { public: int operator()() @@ -123,7 +155,7 @@ class test_main_template < value_type , typename hooks::base_hook_type >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_multiset < typename detail::get_member_value_traits @@ -133,14 +165,14 @@ class test_main_template , &value_type::node_ > >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_multiset < typename detail::get_base_value_traits < value_type , typename hooks::auto_base_hook_type >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_multiset < typename detail::get_member_value_traits @@ -150,18 +182,70 @@ class test_main_template , &value_type::auto_node_ > >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); return 0; } }; +// container generator which ignores further parametrization, except for compare option +template < typename Value_Traits, bool Constant_Time_Size, typename Header_Holder > +struct Get_Preset_Container +{ + template < class + , class Option1 = void + , class Option2 = void + , class Option3 = void + > + struct GetContainer + { + // ignore further paramatrization except for the compare option + // notably ignore the size option (use preset) + typedef typename pack_options< avltree_defaults, Option1, Option2, Option3 >::type packed_options; + typedef typename packed_options::compare compare_option; + + typedef boost::intrusive::avl_multiset< typename Value_Traits::value_type, + value_traits< Value_Traits >, + constant_time_size< Constant_Time_Size >, + compare< compare_option >, + header_holder_type< Header_Holder > + > type; + }; +}; + +template < bool Constant_Time_Size > +struct test_main_template_bptr +{ + void operator () () + { + typedef BPtr_Value value_type; + typedef BPtr_Value_Traits< AVLTree_BPtr_Node_Traits > value_traits; + typedef Bounded_Allocator< value_type > allocator_type; + + allocator_type::init(); + test::test_generic_multiset< value_traits, + Get_Preset_Container< value_traits, Constant_Time_Size, + Bounded_Pointer_Holder< value_type > >::template GetContainer + >::test_all(); + assert(allocator_type::is_clear()); + allocator_type::destroy(); + } +}; + int main( int, char* [] ) { - test_main_template()(); - test_main_template, false>()(); - test_main_template()(); - test_main_template, true>()(); + // test (plain/smart pointers) x (nonconst/const size) x (void node allocator) + test_main_template()(); + test_main_template, false, true>()(); + test_main_template()(); + test_main_template, true, true>()(); + // test (plain pointers) x (nonconst/const size) x (standard node allocator) + test_main_template()(); + test_main_template()(); + // test (bounded pointers) x ((nonconst/const size) x (special node allocator) + test_main_template_bptr< true >()(); + test_main_template_bptr< false >()(); + return boost::report_errors(); } diff --git a/test/avl_set_test.cpp b/test/avl_set_test.cpp index 36d0731..18d5b9d 100644 --- a/test/avl_set_test.cpp +++ b/test/avl_set_test.cpp @@ -13,6 +13,7 @@ #include #include #include "itestvalue.hpp" +#include "bptr_value.hpp" #include "smart_ptr.hpp" #include "generic_set_test.hpp" @@ -60,6 +61,10 @@ struct hooks > nonhook_node_member_type; }; +// container generator with void node allocator +template < bool Default_Holder > +struct GetContainer_With_Holder +{ template< class ValueType , class Option1 =void , class Option2 =void @@ -74,8 +79,35 @@ struct GetContainer , Option3 > type; }; +}; -template +// container generator with standard (non-void) node allocator +template <> +struct GetContainer_With_Holder< false > +{ +template< class ValueType + , class Option1 =void + , class Option2 =void + , class Option3 =void + > +struct GetContainer +{ + // extract node type through options->value_traits->node_traits->node + typedef typename pack_options< avltree_defaults, Option1, Option2, Option3 >::type packed_options; + typedef typename detail::get_value_traits< ValueType, typename packed_options::proto_value_traits>::type value_traits; + typedef typename value_traits::node_traits::node node; + + typedef boost::intrusive::avl_set + < ValueType + , Option1 + , Option2 + , Option3 + , header_holder_type< pointer_holder< node > > + > type; +}; +}; + +template class test_main_template { public: @@ -88,7 +120,7 @@ class test_main_template < value_type , typename hooks::base_hook_type >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_set < typename detail::get_member_value_traits < value_type @@ -97,21 +129,21 @@ class test_main_template , &value_type::node_ > >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_set < nonhook_node_member_value_traits< value_type, typename hooks::nonhook_node_member_type, &value_type::nhn_member_, safe_link >, - GetContainer + GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); return 0; } }; -template -class test_main_template +template +class test_main_template { public: int operator()() @@ -123,7 +155,7 @@ class test_main_template < value_type , typename hooks::base_hook_type >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_set < typename detail::get_member_value_traits @@ -133,14 +165,14 @@ class test_main_template , &value_type::node_ > >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_set < typename detail::get_base_value_traits < value_type , typename hooks::auto_base_hook_type >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_set < typename detail::get_member_value_traits @@ -150,19 +182,70 @@ class test_main_template , &value_type::auto_node_ > >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); return 0; } }; +// container generator which ignores further parametrization, except for compare option +template < typename Value_Traits, bool Constant_Time_Size, typename Header_Holder > +struct Get_Preset_Container +{ + template < class + , class Option1 = void + , class Option2 = void + , class Option3 = void + > + struct GetContainer + { + // ignore further paramatrization except for the compare option + // notably ignore the size option (use preset) + typedef typename pack_options< avltree_defaults, Option1, Option2, Option3 >::type packed_options; + typedef typename packed_options::compare compare_option; + + typedef boost::intrusive::avl_set< typename Value_Traits::value_type, + value_traits< Value_Traits >, + constant_time_size< Constant_Time_Size >, + compare< compare_option >, + header_holder_type< Header_Holder > + > type; + }; +}; + +template < bool Constant_Time_Size > +struct test_main_template_bptr +{ + void operator () () + { + typedef BPtr_Value value_type; + typedef BPtr_Value_Traits< AVLTree_BPtr_Node_Traits > value_traits; + typedef Bounded_Allocator< value_type > allocator_type; + + allocator_type::init(); + test::test_generic_set< value_traits, + Get_Preset_Container< value_traits, Constant_Time_Size, + Bounded_Pointer_Holder< value_type > >::template GetContainer + >::test_all(); + assert(allocator_type::is_clear()); + allocator_type::destroy(); + } +}; + int main( int, char* [] ) { - test_main_template()(); - test_main_template, false>()(); - test_main_template()(); - test_main_template, true>()(); + // test (plain/smart pointers) x (nonconst/const size) x (void node allocator) + test_main_template()(); + test_main_template, false, true>()(); + test_main_template()(); + test_main_template, true, true>()(); + // test (plain pointers) x (nonconst/const size) x (standard node allocator) + test_main_template()(); + test_main_template()(); + // test (bounded pointers) x ((nonconst/const size) x (special node allocator) + test_main_template_bptr< true >()(); + test_main_template_bptr< false >()(); return boost::report_errors(); } diff --git a/test/bounded_pointer.hpp b/test/bounded_pointer.hpp new file mode 100644 index 0000000..75828cc --- /dev/null +++ b/test/bounded_pointer.hpp @@ -0,0 +1,355 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Matei David 2014 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOUNDED_POINTER_HPP +#define BOUNDED_POINTER_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CONST_CONVERSIONS(_type, _t) \ + operator const _type< typename boost::add_const< _t >::type >& () const \ + { return *reinterpret_cast< const _type< typename boost::add_const< _t >::type >* >(this); } \ + operator _type< typename boost::add_const< _t >::type >& () \ + { return *reinterpret_cast< _type< typename boost::add_const< _t >::type >* >(this); } \ + \ + const _type< typename boost::remove_const< _t >::type >& unconst() const \ + { return *reinterpret_cast< const _type< typename boost::remove_const< _t >::type >* >(this); } \ + _type< typename boost::remove_const< _t >::type >& unconst() \ + { return *reinterpret_cast< _type< typename boost::remove_const< _t >::type >* >(this); } + + +template < typename T > +class Bounded_Pointer; +template < typename T > +class Bounded_Reference; +template < typename T > +class Bounded_Allocator; + + +template < typename T > +class Bounded_Pointer +{ +public: + typedef typename boost::remove_const< T >::type mut_val_t; + typedef const mut_val_t const_val_t; + + template + struct rebind + { + typedef typename boost::mpl::if_< + boost::is_same< + typename boost::remove_const< U >::type, + typename boost::remove_const< T >::type >, + Bounded_Pointer< U >, + U* + >::type type; + }; + + Bounded_Pointer() : _offset(255) {} + Bounded_Pointer(const Bounded_Pointer& other) : _offset(other._offset) {} + Bounded_Pointer& operator = (const Bounded_Pointer& other) { _offset = other._offset; return *this; } + CONST_CONVERSIONS(Bounded_Pointer, T) + + static mut_val_t* base() + { + assert(Bounded_Allocator< mut_val_t >::inited()); + return &Bounded_Allocator< mut_val_t >::_base[0]; + } + + operator bool() const { return _offset != 255; } + + T* raw() const { return base() + _offset; } + Bounded_Reference< T > operator * () const { return Bounded_Reference< T >(*this); } + T* operator -> () const { return raw(); } + Bounded_Pointer& operator ++ () { ++_offset; return *this; } + Bounded_Pointer operator ++ (int) { Bounded_Pointer res(*this); ++(*this); return res; } + + template < typename U > + // typename boost::enable_if< boost::is_same< typename boost::remove_const< U >::type, + // typename boost::remove_const< T >::type >, int >::type = 42 > + bool operator == (const Bounded_Pointer< U >& rhs) const + { + return _offset == rhs._offset; + } + template < typename U > + // typename boost::enable_if< boost::is_same< typename boost::remove_const< U >::type, + // typename boost::remove_const< T >::type >, int >::type = 42 > + bool operator < (const Bounded_Pointer< U >& rhs) const + { + return _offset < rhs._offset; + } + + friend std::ostream& operator << (std::ostream& os, const Bounded_Pointer< T >& ptr) + { + os << static_cast< int >(ptr._offset); + return os; + } +private: + template friend class Bounded_Pointer; + friend class Bounded_Reference< T >; + friend class Bounded_Allocator< T >; + + uint8_t _offset; +}; // class Bounded_Pointer + +template < typename T > +class Bounded_Reference +{ +public: + typedef typename boost::remove_const< T >::type mut_val_t; + typedef const mut_val_t const_val_t; + + Bounded_Reference() : _offset(255) {} + Bounded_Reference(const Bounded_Reference& other) : _offset(other._offset) {} + CONST_CONVERSIONS(Bounded_Reference, T) + + T& raw() const { assert(_offset != 255); return *(Bounded_Pointer< T >::base() + _offset); } + operator T& () const { assert(_offset != 255); return raw(); } + Bounded_Pointer< T > operator & () const { assert(_offset != 255); Bounded_Pointer< T > res; res._offset = _offset; return res; } + + Bounded_Reference& operator = (const T& rhs) { assert(_offset != 255); raw() = rhs; return *this; } + Bounded_Reference& operator = (const Bounded_Reference& rhs) { assert(_offset != 255); raw() = rhs.raw(); return *this; } + + friend std::ostream& operator << (std::ostream& os, const Bounded_Reference< T >& ref) + { + os << "[bptr=" << static_cast< int >(ref._offset) << ",deref=" << ref.raw() << "]"; + return os; + } + + // the copy asop is shallow; we need swap overload to shuffle a vector of references + friend void swap(Bounded_Reference& lhs, Bounded_Reference& rhs) + { + std::swap(lhs._offset, rhs._offset); + } + +private: + friend class Bounded_Pointer< T >; + Bounded_Reference(Bounded_Pointer< T > bptr) : _offset(bptr._offset) { assert(_offset != 255); } + + uint8_t _offset; +}; // class Bounded_Reference + +template < typename T > +class Bounded_Allocator +{ +public: + typedef T value_type; + typedef Bounded_Pointer< T > pointer; + + pointer allocate(size_t n) + { + assert(inited()); + assert(n == 1); + pointer p; + uint8_t i; + for (i = 0; i < 255 and _in_use[i]; ++i); + assert(i < 255); + p._offset = i; + _in_use[p._offset] = true; + //std::clog << "allocating node " << static_cast< int >(p._offset) << "\n"; + return p; + } + void deallocate(pointer p, size_t n) + { + assert(inited()); + assert(n == 1); + assert(_in_use[p._offset]); + //std::clog << "deallocating node " << static_cast< int >(p._offset) << "\n"; + _in_use[p._offset] = false; + } + + // static methods + static void init() + { + assert(_in_use.empty()); + _in_use = std::vector< bool >(255, false); + // allocate non-constructed storage + _base = static_cast< T* >(::operator new [] (255 * sizeof(T))); + } + static bool inited() + { + return _in_use.size() == 255; + } + static bool is_clear() + { + assert(inited()); + for (uint8_t i = 0; i < 255; ++i) + { + if (_in_use[i]) + { + return false; + } + } + return true; + } + static void destroy() + { + // deallocate storage without destructors + ::operator delete [] (_base); + _in_use.clear(); + } + +private: + friend class Bounded_Pointer< T >; + friend class Bounded_Pointer< const T >; + static T* _base; + static std::vector< bool > _in_use; +}; // class Bounded_Allocator + +template < typename T > +T* Bounded_Allocator< T >::_base = NULL; + +template < typename T > +std::vector< bool > Bounded_Allocator< T >::_in_use; + + +template < typename T > +class Bounded_Reference_Cont + : public std::vector< Bounded_Reference< T > > +{ +private: + typedef T value_type; + typedef std::vector< Bounded_Reference< T > > Base; + typedef Bounded_Allocator< T > allocator_type; + typedef Bounded_Pointer< T > pointer; + +public: + Bounded_Reference_Cont(size_t n = 0) : Base(), _allocator() + { + for (size_t i = 0; i < n; ++i) + { + pointer p = _allocator.allocate(1); + new (p.raw()) value_type(); + Base::push_back(*p); + } + } + Bounded_Reference_Cont(const Bounded_Reference_Cont& other) : Base(), _allocator(other._allocator) + { + //std::clog << "copying values container\n"; + for (typename Base::const_iterator it = other.begin(); it != other.end(); ++it) + { + pointer p = _allocator.allocate(1); + new (p.raw()) value_type(*it); + Base::push_back(*p); + } + } + ~Bounded_Reference_Cont() + { + while (not Base::empty()) + { + pointer p = &Base::back(); + p->~value_type(); + _allocator.deallocate(p, 1); + Base::pop_back(); + } + } + +private: + allocator_type _allocator; +}; // class Bounded_Reference_Cont + +template < typename T > +class Bounded_Pointer_Holder +{ +public: + typedef T value_type; + typedef Bounded_Pointer< value_type > pointer; + typedef Bounded_Pointer< const value_type > const_pointer; + typedef Bounded_Allocator< value_type > allocator_type; + + Bounded_Pointer_Holder() : _ptr(allocator_type().allocate(1)) + { + new (_ptr.raw()) value_type(); + } + ~Bounded_Pointer_Holder() + { + _ptr->~value_type(); + allocator_type().deallocate(_ptr, 1); + } + + const_pointer get_node () const { return _ptr; } + pointer get_node () { return _ptr; } + +private: + const pointer _ptr; +}; // class Bounded_Pointer_Holder + + +namespace boost +{ +namespace intrusive +{ + +template < typename T > +struct pointer_traits< Bounded_Pointer< T > > +{ + typedef T element_type; + typedef Bounded_Pointer< T > pointer; + typedef Bounded_Pointer< const T > const_pointer; + typedef ptrdiff_t difference_type; + typedef Bounded_Reference< T > reference; + + template + struct rebind_pointer + { + typedef typename Bounded_Pointer< T >::template rebind< U >::type type; + }; + + static pointer pointer_to(reference r) { return &r; } + static pointer const_cast_from(const_pointer cptr) { return cptr.unconst(); } +}; + +} // namespace intrusive +} // namespace boost + +template < typename T, typename U > +// typename boost::enable_if< boost::is_same< typename boost::remove_const< T >::type, +// typename boost::remove_const< U >::type >, int >::type = 42 > +bool operator != (const Bounded_Pointer< T >& lhs, const Bounded_Pointer< U >& rhs) +{ + return !(lhs == rhs); +} +template < typename T > +bool operator == (const Bounded_Pointer< T >& lhs, const void* p) +{ + assert(!p); + return lhs == Bounded_Pointer< T >(); +} +template < typename T > +bool operator == (const void* p, const Bounded_Pointer< T >& rhs) +{ + assert(!p); + return Bounded_Pointer< T >() == rhs; +} +template < typename T > +bool operator != (const Bounded_Pointer< T >& lhs, const void* p) +{ + assert(!p); + return lhs != Bounded_Pointer< T >(); +} +template < typename T > +bool operator != (const void* p, const Bounded_Pointer< T >& rhs) +{ + assert(!p); + return Bounded_Pointer< T >() != rhs; +} + + +#endif diff --git a/test/bptr_value.hpp b/test/bptr_value.hpp new file mode 100644 index 0000000..e930cf2 --- /dev/null +++ b/test/bptr_value.hpp @@ -0,0 +1,240 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Matei David 2014 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_BPTR_VALUE_HPP +#define BOOST_INTRUSIVE_BPTR_VALUE_HPP + +#include +#include +#include "bounded_pointer.hpp" +#include "common_functors.hpp" + + +namespace boost +{ +namespace intrusive +{ + +struct BPtr_Value +{ + static const bool constant_time_size = true; + + BPtr_Value(int value = 42) : value_(value) {} + //BPtr_Value(const BPtr_Value& rhs) = delete; + BPtr_Value(const BPtr_Value& rhs) : value_(rhs.value_) {} + //BPtr_Value(BPtr_Value&&) = delete; + ~BPtr_Value() + { + if (is_linked()) + { + std::cerr << "BPtr_Value dtor: destructing linked value: &=" << (void*)this << "\n"; + assert(false); + } + } + + // testvalue is used in std::vector and thus prev and next + // have to be handled appropriately when copied: + BPtr_Value& operator = (const BPtr_Value& src) + { + if (is_linked()) + { + std::cerr << "BPtr_Value asop: assigning to linked value: &=" << (void*)this << ", src=" << (void*)&src << "\n"; + assert(false); + } + value_ = src.value_; + //_previous = src._previous; + //_next = src._next; + return *this; + } + + // value + int value_; + + // list node hooks + Bounded_Pointer< BPtr_Value > _previous; + Bounded_Pointer< BPtr_Value > _next; + // tree node hooks + Bounded_Pointer< BPtr_Value > _parent; + Bounded_Pointer< BPtr_Value > _l_child; + Bounded_Pointer< BPtr_Value > _r_child; + char _extra; + + bool is_linked() const { return _previous or _next or _parent or _l_child or _r_child; } + + friend bool operator< (const BPtr_Value &other1, const BPtr_Value &other2) + { return other1.value_ < other2.value_; } + + friend bool operator< (int other1, const BPtr_Value &other2) + { return other1 < other2.value_; } + + friend bool operator< (const BPtr_Value &other1, int other2) + { return other1.value_ < other2; } + + friend bool operator== (const BPtr_Value &other1, const BPtr_Value &other2) + { return other1.value_ == other2.value_; } + + friend bool operator== (int other1, const BPtr_Value &other2) + { return other1 == other2.value_; } + + friend bool operator== (const BPtr_Value &other1, int other2) + { return other1.value_ == other2; } + + friend bool operator!= (const BPtr_Value &other1, const BPtr_Value &other2) + { return !(other1 == other2); } + + friend bool operator!= (int other1, const BPtr_Value &other2) + { return !(other1 == other2.value_); } + + friend bool operator!= (const BPtr_Value &other1, int other2) + { return !(other1.value_ == other2); } + + friend std::ostream& operator << (std::ostream& os, const BPtr_Value& v) + { + os << v.value_; + return os; + } +}; // class BPtr_Value + +template < typename Node_Algorithms > +void swap_nodes(Bounded_Reference< BPtr_Value > lhs, + Bounded_Reference< BPtr_Value > rhs) +{ + Node_Algorithms::swap_nodes( + boost::intrusive::pointer_traits< Bounded_Pointer< BPtr_Value > >::pointer_to(lhs), + boost::intrusive::pointer_traits< Bounded_Pointer< BPtr_Value > >::pointer_to(rhs)); +} + +struct List_BPtr_Node_Traits +{ + typedef BPtr_Value val_t; + typedef val_t node; + typedef Bounded_Pointer< val_t > node_ptr; + typedef Bounded_Pointer< const val_t > const_node_ptr; + + static node_ptr get_previous(const_node_ptr p) { return p->_previous; } + static void set_previous(node_ptr p, node_ptr prev) { p->_previous = prev; } + static node_ptr get_next(const_node_ptr p) { return p->_next; } + static void set_next(node_ptr p, node_ptr next) { p->_next = next; } +}; + +struct RBTree_BPtr_Node_Traits +{ + typedef BPtr_Value val_t; + typedef val_t node; + typedef Bounded_Pointer< val_t > node_ptr; + typedef Bounded_Pointer< const val_t > const_node_ptr; + typedef char color; + + static node_ptr get_parent(const_node_ptr p) { return p->_parent; } + static void set_parent(node_ptr p, node_ptr parent) { p->_parent = parent; } + static node_ptr get_left(const_node_ptr p) { return p->_l_child; } + static void set_left(node_ptr p, node_ptr l_child) { p->_l_child = l_child; } + static node_ptr get_right(const_node_ptr p) { return p->_r_child; } + static void set_right(node_ptr p, node_ptr r_child) { p->_r_child = r_child; } + static color get_color(const_node_ptr p) { return p->_extra; } + static void set_color(node_ptr p, color c) { p->_extra = c; } + static color black() { return 0; } + static color red() { return 1; } +}; + +struct AVLTree_BPtr_Node_Traits +{ + typedef BPtr_Value val_t; + typedef val_t node; + typedef Bounded_Pointer< val_t > node_ptr; + typedef Bounded_Pointer< const val_t > const_node_ptr; + typedef char balance; + + static node_ptr get_parent(const_node_ptr p) { return p->_parent; } + static void set_parent(node_ptr p, node_ptr parent) { p->_parent = parent; } + static node_ptr get_left(const_node_ptr p) { return p->_l_child; } + static void set_left(node_ptr p, node_ptr l_child) { p->_l_child = l_child; } + static node_ptr get_right(const_node_ptr p) { return p->_r_child; } + static void set_right(node_ptr p, node_ptr r_child) { p->_r_child = r_child; } + static balance get_balance(const_node_ptr p) { return p->_extra; } + static void set_balance(node_ptr p, balance b) { p->_extra = b; } + static balance negative() { return -1; } + static balance zero() { return 0; } + static balance positive() { return 1; } +}; + +template < typename Node_Traits > +struct BPtr_Value_Traits +{ + typedef Node_Traits node_traits; + typedef typename node_traits::val_t value_type; + typedef typename node_traits::node_ptr node_ptr; + typedef typename node_traits::const_node_ptr const_node_ptr; + typedef node_ptr pointer; + typedef const_node_ptr const_pointer; + typedef Bounded_Reference< value_type > reference; + typedef Bounded_Reference< const value_type > const_reference; + + static const boost::intrusive::link_mode_type link_mode = boost::intrusive::safe_link; + + static const_node_ptr to_node_ptr(const_reference v) { return &v; } + static node_ptr to_node_ptr(reference v) { return &v; } + static const_pointer to_value_ptr(const_node_ptr p) { return p; } + static pointer to_value_ptr(node_ptr p) { return p; } +}; + +template < typename > +struct Value_Container; + +template <> +struct Value_Container< BPtr_Value > +{ + typedef Bounded_Reference_Cont< BPtr_Value > type; +}; + +namespace test +{ + +template <> +class new_cloner< BPtr_Value > +{ +public: + typedef BPtr_Value value_type; + typedef Bounded_Pointer< value_type > pointer; + typedef Bounded_Reference< const value_type > const_reference; + typedef Bounded_Allocator< value_type > allocator_type; + + pointer operator () (const_reference r) + { + pointer p = allocator_type().allocate(1); + new (p.raw()) value_type(r); + return p; + } +}; + +template <> +class delete_disposer< BPtr_Value > +{ +public: + typedef BPtr_Value value_type; + typedef Bounded_Pointer< value_type > pointer; + typedef Bounded_Allocator< value_type > allocator_type; + + void operator () (pointer p) + { + p->~value_type(); + allocator_type().deallocate(p, 1); + } +}; + +} // namespace test + +} // namespace intrusive +} // namespace boost + + +#endif diff --git a/test/container_size_test.cpp b/test/container_size_test.cpp index d95cee5..00ad27f 100644 --- a/test/container_size_test.cpp +++ b/test/container_size_test.cpp @@ -23,6 +23,7 @@ #include #include #include +#include "itestvalue.hpp" using namespace boost::intrusive; @@ -71,6 +72,16 @@ void test_sizes(boolean, std::size_t wordsize) BOOST_TEST_EQ(sizeof(c), wordsize*2); test_iterator_sizes(c, wordsize); } + { + list< node< list_base_hook<> >, header_holder_type< pointer_holder< list_node > > > c; + BOOST_TEST_EQ(sizeof(c), wordsize*2); + test_iterator_sizes(c, wordsize); + } + { + list< node< list_base_hook<> >, constant_time_size, header_holder_type< pointer_holder< list_node > > > c; + BOOST_TEST_EQ(sizeof(c), wordsize*1); + test_iterator_sizes(c, wordsize); + } { //slist slist > > > c; BOOST_TEST_EQ(sizeof(c), wordsize*2); @@ -101,6 +112,16 @@ void test_sizes(boolean, std::size_t wordsize) BOOST_TEST_EQ(sizeof(c), wordsize*3); test_iterator_sizes(c, wordsize); } + { + set< node< set_base_hook<> >, header_holder_type< pointer_holder< rbtree_node > > > c; + BOOST_TEST_EQ(sizeof(c), wordsize*2); + test_iterator_sizes(c, wordsize); + } + { + set< node< set_base_hook<> >, constant_time_size, header_holder_type< pointer_holder< rbtree_node > > > c; + BOOST_TEST_EQ(sizeof(c), wordsize*1); + test_iterator_sizes(c, wordsize); + } { //avl avl_set > > > c; BOOST_TEST_EQ(sizeof(c), wordsize*5); @@ -116,6 +137,16 @@ void test_sizes(boolean, std::size_t wordsize) BOOST_TEST_EQ(sizeof(c), wordsize*3); test_iterator_sizes(c, wordsize); } + { + avl_set< node< avl_set_base_hook<> >, header_holder_type< pointer_holder< avltree_node > > > c; + BOOST_TEST_EQ(sizeof(c), wordsize*2); + test_iterator_sizes(c, wordsize); + } + { + avl_set< node< avl_set_base_hook<> >, constant_time_size, header_holder_type< pointer_holder< avltree_node > > > c; + BOOST_TEST_EQ(sizeof(c), wordsize*1); + test_iterator_sizes(c, wordsize); + } { //splay splay_set > > > c; BOOST_TEST_EQ(sizeof(c), wordsize*4); diff --git a/test/generic_assoc_test.hpp b/test/generic_assoc_test.hpp index 6dbae8a..5854df0 100644 --- a/test/generic_assoc_test.hpp +++ b/test/generic_assoc_test.hpp @@ -212,27 +212,15 @@ void test_generic_assoc::test_all(value_cont_type test_container_from_iterator(values); } -template < bool Has_Value_Allocator, typename assoc_type, typename value_cont_type > -struct test_clone_impl +template class ContainerDefiner> +void test_generic_assoc + ::test_clone(value_cont_type& values) { -void operator () (value_cont_type& values) -{ - assoc_type testset1 (values.begin(), values.begin() + values.size()); - assoc_type testset2; - - testset2.clone_from(testset1); - BOOST_TEST (testset2 == testset1); - testset2.clear_and_dispose(); - BOOST_TEST (testset2.empty()); -} -}; - -template < typename assoc_type, typename value_cont_type > -struct test_clone_impl< false, assoc_type, value_cont_type > -{ -void operator () (value_cont_type& values) -{ - typedef typename assoc_type::value_type value_type; + typedef typename ContainerDefiner + < value_type + , value_traits + , constant_time_size + >::type assoc_type; assoc_type testset1 (values.begin(), values.begin() + values.size()); assoc_type testset2; @@ -241,21 +229,6 @@ void operator () (value_cont_type& values) testset2.clear_and_dispose(test::delete_disposer()); BOOST_TEST (testset2.empty()); } -}; - -template class ContainerDefiner> -void test_generic_assoc - ::test_clone(value_cont_type& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef typename ContainerDefiner - < value_type - , value_traits - , constant_time_size - >::type assoc_type; - - test_clone_impl< assoc_type::has_value_allocator, assoc_type, value_cont_type >()(values); -} template < bool Has_Container_From_Iterator, typename assoc_type, typename value_cont_type > struct test_container_from_end_impl diff --git a/test/itestvalue.hpp b/test/itestvalue.hpp index 4168501..43ffc5e 100644 --- a/test/itestvalue.hpp +++ b/test/itestvalue.hpp @@ -112,6 +112,12 @@ struct testvalue { return other1.value_ != other2; } }; +template < typename Node_Algorithms, class Hooks, bool ConstantTimeSize > +void swap_nodes(testvalue< Hooks, ConstantTimeSize >& lhs, testvalue< Hooks, ConstantTimeSize >& rhs) +{ + lhs.swap_nodes(rhs); +} + template std::size_t hash_value(const testvalue &t) { @@ -137,25 +143,56 @@ std::ostream& operator<< struct even_odd { - template + template < typename value_type_1, typename value_type_2 > bool operator() - (const testvalue& v1 - ,const testvalue& v2) const + (const value_type_1& v1 + ,const value_type_2& v2) const { - if ((v1.value_ & 1) == (v2.value_ & 1)) - return v1.value_ < v2.value_; + if (((&v1)->value_ & 1) == ((&v2)->value_ & 1)) + return (&v1)->value_ < (&v2)->value_; else - return v2.value_ & 1; + return (&v2)->value_ & 1; } }; struct is_even { - template + template bool operator() - (const testvalue& v1) const - { return (v1.value_ & 1) == 0; } + (const value_type& v1) const + { return ((&v1)->value_ & 1) == 0; } }; + +template +struct Value_Container; + +template < class Hooks, bool ConstantTimeSize > +struct Value_Container< testvalue< Hooks, ConstantTimeSize > > +{ + typedef std::vector< testvalue< Hooks, ConstantTimeSize > > type; +}; + +template < typename T > +class pointer_holder +{ +public: + pointer_holder() : _ptr(new T()) + { + //std::clog << "constructing holder pointing to &=" << (void*)_ptr << "\n"; + } + ~pointer_holder() + { + //std::clog << "destructing holder pointing to &=" << (void*)_ptr << "\n"; + delete _ptr; + } + + const T* get_node() const { return _ptr; } + T* get_node() { return _ptr; } + +private: + T* const _ptr; +}; + /* struct int_testvalue_comp { diff --git a/test/list_test.cpp b/test/list_test.cpp index 7301dcf..06f8eb9 100644 --- a/test/list_test.cpp +++ b/test/list_test.cpp @@ -14,12 +14,15 @@ #include #include #include "itestvalue.hpp" +#include "bptr_value.hpp" #include "smart_ptr.hpp" #include "common_functors.hpp" #include #include #include "test_macros.hpp" #include "test_container.hpp" +#include +#include using namespace boost::intrusive; @@ -39,32 +42,41 @@ struct hooks > nonhook_node_member_type; }; -template + +template < typename List_Type, typename Value_Container > struct test_list { - typedef typename ValueTraits::value_type value_type; - static void test_all(std::vector& values); - static void test_front_back(std::vector& values); - static void test_sort(std::vector& values); - static void test_merge(std::vector& values); - static void test_remove_unique(std::vector& values); - static void test_insert(std::vector& values); - static void test_shift(std::vector& values); - static void test_swap(std::vector& values); - static void test_clone(std::vector& values); - static void test_container_from_end(std::vector& values); + typedef List_Type list_type; + typedef typename list_type::value_traits value_traits; + typedef typename value_traits::value_type value_type; + typedef typename list_type::node_algorithms node_algorithms; + + static void test_all(Value_Container& values); + static void test_front_back(Value_Container& values); + static void test_sort(Value_Container& values); + static void test_merge(Value_Container& values); + static void test_remove_unique(Value_Container& values); + static void test_insert(Value_Container& values); + static void test_shift(Value_Container& values); + static void test_swap(Value_Container& values); + static void test_clone(Value_Container& values); + static void test_container_from_end(Value_Container& values); }; -template -void test_list::test_all(std::vector& values) +template < typename List_Type, typename Value_Container > +void test_list< List_Type, Value_Container >::test_all(Value_Container& values) { - typedef typename ValueTraits::value_type value_type; - typedef list - < value_type - , value_traits - , size_type - , constant_time_size - > list_type; + std::clog << "testing list with:\n" + << " value_type = " << typeid(value_type).name() << "\n" + << " sizeof(value_type) = " << sizeof(value_type) << "\n" + << " link_mode = " << value_traits::link_mode << "\n" + << " node = " << typeid(typename list_type::node).name() << "\n" + << " sizeof(node) = " << sizeof(typename list_type::node) << "\n" + << " node_ptr = " << typeid(typename list_type::node_ptr).name() << "\n" + << " sizeof(node_ptr) = " << sizeof(typename list_type::node_ptr) << "\n" + << " constant_time_size = " << list_type::constant_time_size << "\n" + << " has_container_from_iterator = " << list_type::has_container_from_iterator << "\n" + << " sizeof(list_type) = " << sizeof(list_type) << "\n"; { list_type list(values.begin(), values.end()); test::test_container(list); @@ -85,17 +97,10 @@ void test_list::test_all(std::vector -void test_list - ::test_front_back(std::vector& values) +template < class List_Type, typename Value_Container > +void test_list< List_Type, Value_Container > + ::test_front_back(Value_Container& values) { - typedef typename ValueTraits::value_type value_type; - typedef list - < value_type - , value_traits - , size_type - , constant_time_size - > list_type; list_type testlist; BOOST_TEST (testlist.empty()); @@ -119,19 +124,11 @@ void test_list BOOST_TEST (testlist.empty()); } - //test: constructor, iterator, reverse_iterator, sort, reverse: -template -void test_list - ::test_sort(std::vector& values) +template < class List_Type, typename Value_Container > +void test_list< List_Type, Value_Container > + ::test_sort(Value_Container& values) { - typedef typename ValueTraits::value_type value_type; - typedef list - < value_type - , value_traits - , size_type - , constant_time_size - > list_type; list_type testlist(values.begin(), values.end()); { int init_values [] = { 1, 2, 3, 4, 5 }; @@ -147,17 +144,10 @@ void test_list } //test: merge due to error in merge implementation: -template -void test_list - ::test_remove_unique (std::vector& values) +template < class List_Type, typename Value_Container > +void test_list< List_Type, Value_Container > + ::test_remove_unique (Value_Container& values) { - typedef typename ValueTraits::value_type value_type; - typedef list - < value_type - , value_traits - , size_type - , constant_time_size - > list_type; { list_type list(values.begin(), values.end()); list.remove_if(is_even()); @@ -165,7 +155,7 @@ void test_list TEST_INTRUSIVE_SEQUENCE( init_values, list.begin() ); } { - std::vector values2(values); + Value_Container values2(values); // NOTE: problematic copy of value container list_type list(values.begin(), values.end()); list.insert(list.end(), values2.begin(), values2.end()); list.sort(); @@ -178,17 +168,10 @@ void test_list } //test: merge due to error in merge implementation: -template -void test_list - ::test_merge (std::vector& values) +template < class List_Type, typename Value_Container > +void test_list< List_Type, Value_Container > + ::test_merge (Value_Container& values) { - typedef typename ValueTraits::value_type value_type; - typedef list - < value_type - , value_traits - , size_type - , constant_time_size - > list_type; list_type testlist1, testlist2; testlist1.push_front (values[0]); testlist2.push_front (values[4]); @@ -201,19 +184,12 @@ void test_list } //test: assign, insert, const_iterator, const_reverse_iterator, erase, s_iterator_to: -template -void test_list - ::test_insert(std::vector& values) +template < class List_Type, typename Value_Container > +void test_list< List_Type, Value_Container > + ::test_insert(Value_Container& values) { - typedef typename ValueTraits::value_type value_type; - typedef list - < value_type - , value_traits - , size_type - , constant_time_size - > list_type; list_type testlist; - testlist.assign (&values[0] + 2, &values[0] + 5); + testlist.assign (values.begin() + 2, values.begin() + 5); const list_type& const_testlist = testlist; { int init_values [] = { 3, 4, 5 }; @@ -238,10 +214,10 @@ void test_list BOOST_TEST (&*i == &values[4]); typename list_type::const_iterator ic; - ic = testlist.iterator_to (const_cast(values[4])); + ic = testlist.iterator_to (static_cast< typename list_type::const_reference >(values[4])); BOOST_TEST (&*ic == &values[4]); - ic = list_type::s_iterator_to (const_cast(values[4])); + ic = list_type::s_iterator_to (static_cast< typename list_type::const_reference >(values[4])); BOOST_TEST (&*ic == &values[4]); i = testlist.erase (i); @@ -251,18 +227,10 @@ void test_list TEST_INTRUSIVE_SEQUENCE( init_values, const_testlist.begin() ); } } - -template -void test_list - ::test_shift(std::vector& values) +template < class List_Type, typename Value_Container > +void test_list< List_Type, Value_Container > + ::test_shift(Value_Container& values) { - typedef typename ValueTraits::value_type value_type; - typedef list - < value_type - , value_traits - , size_type - , constant_time_size - > list_type; list_type testlist; const int num_values = (int)values.size(); std::vector expected_values(num_values); @@ -271,7 +239,7 @@ void test_list expected_values.resize(s); //Shift forward all possible positions 3 times for(int i = 0; i < s*3; ++i){ - testlist.insert(testlist.begin(), &values[0], &values[0] + s); + testlist.insert(testlist.begin(), values.begin(), values.begin() + s); testlist.shift_forward(i); for(int j = 0; j < s; ++j){ expected_values[(j + s - i%s) % s] = (j + 1); @@ -282,7 +250,7 @@ void test_list //Shift backwards all possible positions for(int i = 0; i < s*3; ++i){ - testlist.insert(testlist.begin(), &values[0], &values[0] + s); + testlist.insert(testlist.begin(), values.begin(), values.begin() + s); testlist.shift_backwards(i); for(int j = 0; j < s; ++j){ expected_values[(j + i) % s] = (j + 1); @@ -294,21 +262,14 @@ void test_list } //test: insert (seq-version), swap, splice, erase (seq-version): -template -void test_list - ::test_swap(std::vector& values) +template < class List_Type, typename Value_Container > +void test_list< List_Type, Value_Container > + ::test_swap(Value_Container& values) { - typedef typename ValueTraits::value_type value_type; - typedef list - < value_type - , value_traits - , size_type - , constant_time_size - > list_type; { - list_type testlist1 (&values[0], &values[0] + 2); + list_type testlist1 (values.begin(), values.begin() + 2); list_type testlist2; - testlist2.insert (testlist2.end(), &values[0] + 2, &values[0] + 5); + testlist2.insert (testlist2.end(), values.begin() + 2, values.begin() + 5); testlist1.swap (testlist2); { int init_values [] = { 3, 4, 5 }; @@ -341,72 +302,75 @@ void test_list BOOST_TEST (&testlist1.front() == &values[3]); } { - list_type testlist1 (&values[0], &values[0] + 2); - list_type testlist2 (&values[0] + 3, &values[0] + 5); + list_type testlist1 (values.begin(), values.begin() + 2); + list_type testlist2 (values.begin() + 3, values.begin() + 5); - values[0].swap_nodes(values[2]); + swap_nodes< node_algorithms >(values[0], values[2]); { int init_values [] = { 3, 2 }; TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); } - values[2].swap_nodes(values[4]); + swap_nodes< node_algorithms >(values[2], values[4]); { int init_values [] = { 5, 2 }; TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); } { int init_values [] = { 4, 3 }; TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() ); } } { - list_type testlist1 (&values[0], &values[1]); + list_type testlist1 (values.begin(), values.begin() + 1); { int init_values [] = { 1 }; TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); } - values[1].swap_nodes(values[2]); + swap_nodes< node_algorithms >(values[1], values[2]); { int init_values [] = { 1 }; TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); } - values[0].swap_nodes(values[2]); + swap_nodes< node_algorithms >(values[0], values[2]); { int init_values [] = { 3 }; TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); } - values[0].swap_nodes(values[2]); + swap_nodes< node_algorithms >(values[0], values[2]); { int init_values [] = { 1 }; TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); } } - } -template -void test_list - ::test_container_from_end(std::vector& values) +template < class List_Type, typename Value_Container, bool > +struct test_container_from_end_impl { - typedef typename ValueTraits::value_type value_type; - typedef list - < value_type - , value_traits - , size_type - , constant_time_size - > list_type; - list_type testlist1 (&values[0], &values[0] + values.size()); + void operator () (Value_Container&) + { + std::clog << "skipping test_container_from_end\n"; + } +}; + +template < class List_Type, typename Value_Container > +struct test_container_from_end_impl< List_Type, Value_Container, true > +{ + void operator () (Value_Container& values) +{ + typedef List_Type list_type; + list_type testlist1 (values.begin(), values.begin() + values.size()); BOOST_TEST (testlist1 == list_type::container_from_end_iterator(testlist1.end())); BOOST_TEST (testlist1 == list_type::container_from_end_iterator(testlist1.cend())); } +}; - -template -void test_list - ::test_clone(std::vector& values) +template < class List_Type, typename Value_Container > +void test_list< List_Type, Value_Container > + ::test_container_from_end(Value_Container& values) { - typedef typename ValueTraits::value_type value_type; - typedef list - < value_type - , value_traits - , size_type - , constant_time_size - > list_type; - list_type testlist1 (&values[0], &values[0] + values.size()); + test_container_from_end_impl< List_Type, Value_Container, List_Type::has_container_from_iterator >()(values); +} + +template < class List_Type, typename Value_Container > +void test_list< List_Type, Value_Container > + ::test_clone(Value_Container& values) +{ + list_type testlist1 (values.begin(), values.begin() + values.size()); list_type testlist2; testlist2.clone_from(testlist1, test::new_cloner(), test::delete_disposer()); @@ -415,42 +379,74 @@ void test_list BOOST_TEST (testlist2.empty()); } -template +template < typename Value_Traits, bool Constant_Time_Size, bool Default_Holder, typename Value_Container > +struct make_and_test_list + : test_list< list< typename Value_Traits::value_type, + value_traits< Value_Traits >, + size_type< std::size_t >, + constant_time_size< Constant_Time_Size > + >, + Value_Container + > +{}; + +template < typename Value_Traits, bool Constant_Time_Size, typename Value_Container > +struct make_and_test_list< Value_Traits, Constant_Time_Size, false, Value_Container > + : test_list< list< typename Value_Traits::value_type, + value_traits< Value_Traits >, + size_type< std::size_t >, + constant_time_size< Constant_Time_Size >, + header_holder_type< pointer_holder< typename Value_Traits::node_traits::node > > + >, + Value_Container + > +{}; + + +template < class VoidPointer, bool ConstantTimeSize, bool Default_Holder > class test_main_template { public: int operator()() { - typedef testvalue, constant_time_size> value_type; + typedef testvalue, ConstantTimeSize> value_type; std::vector data (5); for (int i = 0; i < 5; ++i) data[i].value_ = i + 1; - test_list < typename detail::get_base_value_traits - < value_type - , typename hooks::base_hook_type - >::type - >::test_all(data); - test_list < typename detail::get_member_value_traits - < value_type - , member_hook< value_type - , typename hooks::member_hook_type - , &value_type::node_ - > - >::type - >::test_all(data); - test_list < nonhook_node_member_value_traits< value_type, - typename hooks::nonhook_node_member_type, - &value_type::nhn_member_, - safe_link - > - >::test_all(data); + make_and_test_list < typename detail::get_base_value_traits < + value_type, + typename hooks::base_hook_type + >::type, + ConstantTimeSize, + Default_Holder, + std::vector< value_type > + >::test_all(data); + make_and_test_list < typename detail::get_member_value_traits < + value_type, + member_hook< value_type, typename hooks::member_hook_type, &value_type::node_> + >::type, + ConstantTimeSize, + Default_Holder, + std::vector< value_type > + >::test_all(data); + make_and_test_list< nonhook_node_member_value_traits < + value_type, + typename hooks::nonhook_node_member_type, + &value_type::nhn_member_, + safe_link + >, + ConstantTimeSize, + Default_Holder, + std::vector< value_type > + >::test_all(data); + return 0; } }; -template -class test_main_template +template < class VoidPointer, bool Default_Holder > +class test_main_template< VoidPointer, false, Default_Holder > { public: int operator()() @@ -460,40 +456,45 @@ class test_main_template for (int i = 0; i < 5; ++i) data[i].value_ = i + 1; - test_list < typename detail::get_base_value_traits - < value_type - , typename hooks::base_hook_type - >::type - >::test_all(data); - - test_list < typename detail::get_member_value_traits - < value_type - , member_hook< value_type - , typename hooks::member_hook_type - , &value_type::node_ - > - >::type - >::test_all(data); + make_and_test_list < typename detail::get_base_value_traits < + value_type, + typename hooks::base_hook_type + >::type, + false, + Default_Holder, + std::vector< value_type > + >::test_all(data); + make_and_test_list < typename detail::get_member_value_traits < + value_type, + member_hook< value_type, typename hooks::member_hook_type, &value_type::node_> + >::type, + false, + Default_Holder, + std::vector< value_type > + >::test_all(data); // test_list // , safe_link> // >::test_all(data); - test_list < typename detail::get_base_value_traits - < value_type - , typename hooks::auto_base_hook_type - >::type - >::test_all(data); - test_list < typename detail::get_member_value_traits - < value_type - , member_hook< value_type - , typename hooks::auto_member_hook_type - , &value_type::auto_node_ - > - >::type - >::test_all(data); + make_and_test_list < typename detail::get_base_value_traits < + value_type, + typename hooks::auto_base_hook_type + >::type, + false, + Default_Holder, + std::vector< value_type > + >::test_all(data); + make_and_test_list < typename detail::get_member_value_traits < + value_type, + member_hook< value_type, typename hooks::auto_member_hook_type, &value_type::auto_node_> + >::type, + false, + Default_Holder, + std::vector< value_type > + >::test_all(data); // test_list } }; +template < bool Constant_Time_Size > +struct test_main_template_bptr +{ + int operator()() + { + typedef BPtr_Value value_type; + typedef BPtr_Value_Traits< List_BPtr_Node_Traits > list_value_traits; + typedef typename list_value_traits::node_ptr node_ptr; + typedef Bounded_Allocator< value_type > allocator_type; + + allocator_type::init(); + allocator_type allocator; + + { + Bounded_Reference_Cont< value_type > ref_cont; + for (int i = 0; i < 5; ++i) + { + node_ptr tmp = allocator.allocate(1); + new (tmp.raw()) value_type(i + 1); + ref_cont.push_back(*tmp); + } + + test_list < list < value_type, + value_traits< list_value_traits >, + size_type< std::size_t >, + constant_time_size< Constant_Time_Size >, + header_holder_type< Bounded_Pointer_Holder< value_type > > + >, + Bounded_Reference_Cont< value_type > + >::test_all(ref_cont); + } + + assert(allocator_type::is_clear()); + allocator_type::destroy(); + return 0; + } +}; + int main( int, char* [] ) { - test_main_template()(); - test_main_template, false>()(); - test_main_template()(); - test_main_template, true>()(); + // test combinations of (regular/smart)_ptr x (const/nonconst)_size x (default/non-default)_header_holder + // skip smart_ptr with non-default header_holder + test_main_template()(); + test_main_template, false, true>()(); + test_main_template()(); + test_main_template, true, true>()(); + test_main_template()(); + test_main_template()(); + // test bounded pointers with const/non_const size (always with non-default header_holder) + test_main_template_bptr< true >()(); + test_main_template_bptr< false >()(); + return boost::report_errors(); } diff --git a/test/multiset_test.cpp b/test/multiset_test.cpp index 2a38dcd..b96e206 100644 --- a/test/multiset_test.cpp +++ b/test/multiset_test.cpp @@ -61,8 +61,8 @@ struct hooks }; // container generator with void node allocator -template < bool Void_Allocator > -struct GetContainer_With_Allocator +template < bool Default_Holder > +struct GetContainer_With_Holder { template< class ValueType , class Option1 =void @@ -82,7 +82,7 @@ struct GetContainer // container generator with standard (non-void) node allocator template <> -struct GetContainer_With_Allocator< false > +struct GetContainer_With_Holder< false > { template< class ValueType , class Option1 =void @@ -101,13 +101,13 @@ struct GetContainer , Option1 , Option2 , Option3 - , node_allocator_type< std::allocator< node > > + , header_holder_type< pointer_holder< node > > > type; }; }; -template +template class test_main_template { public: @@ -120,7 +120,7 @@ class test_main_template < value_type , typename hooks::base_hook_type >::type - , GetContainer_With_Allocator< Void_Allocator >::template GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_multiset < typename detail::get_member_value_traits < value_type @@ -129,21 +129,21 @@ class test_main_template , &value_type::node_ > >::type - , GetContainer_With_Allocator< Void_Allocator >::template GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_multiset < nonhook_node_member_value_traits< value_type, typename hooks::nonhook_node_member_type, &value_type::nhn_member_, safe_link >, - GetContainer_With_Allocator< Void_Allocator >::template GetContainer + GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); return 0; } }; -template -class test_main_template +template +class test_main_template { public: int operator()() @@ -155,7 +155,7 @@ class test_main_template < value_type , typename hooks::base_hook_type >::type - , GetContainer_With_Allocator< Void_Allocator >::template GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_multiset < typename detail::get_member_value_traits @@ -165,14 +165,14 @@ class test_main_template , &value_type::node_ > >::type - , GetContainer_With_Allocator< Void_Allocator >::template GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_multiset < typename detail::get_base_value_traits < value_type , typename hooks::auto_base_hook_type >::type - , GetContainer_With_Allocator< Void_Allocator >::template GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_multiset < typename detail::get_member_value_traits @@ -182,14 +182,14 @@ class test_main_template , &value_type::auto_node_ > >::type - , GetContainer_With_Allocator< Void_Allocator >::template GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); return 0; } }; // container generator which ignores further parametrization, except for compare option -template < typename Value_Traits, bool Constant_Time_Size, typename Allocator > +template < typename Value_Traits, bool Constant_Time_Size, typename Header_Holder > struct Get_Preset_Container { template < class @@ -208,7 +208,7 @@ struct Get_Preset_Container value_traits< Value_Traits >, constant_time_size< Constant_Time_Size >, compare< compare_option >, - node_allocator_type< Allocator > + header_holder_type< Header_Holder > > type; }; }; @@ -224,7 +224,8 @@ struct test_main_template_bptr allocator_type::init(); test::test_generic_multiset< value_traits, - Get_Preset_Container< value_traits, Constant_Time_Size, allocator_type >::template GetContainer + Get_Preset_Container< value_traits, Constant_Time_Size, + Bounded_Pointer_Holder< value_type > >::template GetContainer >::test_all(); assert(allocator_type::is_clear()); allocator_type::destroy(); diff --git a/test/set_test.cpp b/test/set_test.cpp index 8a2c3c6..537335c 100644 --- a/test/set_test.cpp +++ b/test/set_test.cpp @@ -62,8 +62,8 @@ struct hooks }; // container generator with void node allocator -template < bool Void_Allocator > -struct GetContainer_With_Allocator +template < bool Default_Holder > +struct GetContainer_With_Holder { template< class ValueType , class Option1 =void @@ -83,7 +83,7 @@ struct GetContainer // container generator with standard (non-void) node allocator template <> -struct GetContainer_With_Allocator< false > +struct GetContainer_With_Holder< false > { template< class ValueType , class Option1 =void @@ -102,13 +102,13 @@ struct GetContainer , Option1 , Option2 , Option3 - , node_allocator_type< std::allocator< node > > + , header_holder_type< pointer_holder< node > > > type; }; }; -template +template class test_main_template { public: @@ -121,7 +121,7 @@ class test_main_template < value_type , typename hooks::base_hook_type >::type - , GetContainer_With_Allocator< Void_Allocator >::template GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_set < typename detail::get_member_value_traits < value_type @@ -130,21 +130,21 @@ class test_main_template , &value_type::node_ > >::type - , GetContainer_With_Allocator< Void_Allocator >::template GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_set < nonhook_node_member_value_traits< value_type, typename hooks::nonhook_node_member_type, &value_type::nhn_member_, safe_link >, - GetContainer_With_Allocator< Void_Allocator >::template GetContainer + GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); return 0; } }; -template -class test_main_template +template +class test_main_template { public: int operator()() @@ -156,7 +156,7 @@ class test_main_template < value_type , typename hooks::base_hook_type >::type - , GetContainer_With_Allocator< Void_Allocator >::template GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_set < typename detail::get_member_value_traits @@ -166,14 +166,14 @@ class test_main_template , &value_type::node_ > >::type - , GetContainer_With_Allocator< Void_Allocator >::template GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_set < typename detail::get_base_value_traits < value_type , typename hooks::auto_base_hook_type >::type - , GetContainer_With_Allocator< Void_Allocator >::template GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_set < typename detail::get_member_value_traits @@ -183,7 +183,7 @@ class test_main_template , &value_type::auto_node_ > >::type - , GetContainer_With_Allocator< Void_Allocator >::template GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); return 0; @@ -191,7 +191,7 @@ class test_main_template }; // container generator which ignores further parametrization, except for compare option -template < typename Value_Traits, bool Constant_Time_Size, typename Allocator > +template < typename Value_Traits, bool Constant_Time_Size, typename Header_Holder > struct Get_Preset_Container { template < class @@ -210,7 +210,7 @@ struct Get_Preset_Container value_traits< Value_Traits >, constant_time_size< Constant_Time_Size >, compare< compare_option >, - node_allocator_type< Allocator > + header_holder_type< Header_Holder > > type; }; }; @@ -226,7 +226,9 @@ struct test_main_template_bptr allocator_type::init(); test::test_generic_set< value_traits, - Get_Preset_Container< value_traits, Constant_Time_Size, allocator_type >::template GetContainer + Get_Preset_Container< value_traits, Constant_Time_Size, + Bounded_Pointer_Holder< value_type > + >::template GetContainer >::test_all(); assert(allocator_type::is_clear()); allocator_type::destroy(); diff --git a/test/slist_test.cpp b/test/slist_test.cpp index cde9a31..e6c544d 100644 --- a/test/slist_test.cpp +++ b/test/slist_test.cpp @@ -15,12 +15,14 @@ #include #include #include "itestvalue.hpp" +#include "bptr_value.hpp" #include "smart_ptr.hpp" #include "common_functors.hpp" #include #include #include "test_macros.hpp" #include "test_container.hpp" +#include using namespace boost::intrusive; @@ -40,39 +42,47 @@ struct hooks > nonhook_node_member_type; }; -template +template < typename List_Type, typename Value_Container > struct test_slist { - typedef typename ValueTraits::value_type value_type; - static void test_all(std::vector& values); - static void test_front(std::vector& values); - static void test_back(std::vector& values, detail::bool_); - static void test_back(std::vector& values, detail::bool_); - static void test_sort(std::vector& values); - static void test_merge(std::vector& values); - static void test_remove_unique(std::vector& values); - static void test_insert(std::vector& values); - static void test_shift(std::vector& values); - static void test_swap(std::vector& values); - static void test_slow_insert(std::vector& values); - static void test_clone(std::vector& values); - static void test_container_from_end(std::vector &, detail::bool_){} - static void test_container_from_end(std::vector &values, detail::bool_); + typedef List_Type list_type; + typedef typename list_type::value_traits value_traits; + typedef typename value_traits::value_type value_type; + typedef typename list_type::node_algorithms node_algorithms; + + static void test_all(Value_Container& values); + static void test_front(Value_Container& values); + static void test_back(Value_Container& values, detail::bool_); + static void test_back(Value_Container& values, detail::bool_); + static void test_sort(Value_Container& values); + static void test_merge(Value_Container& values); + static void test_remove_unique(Value_Container& values); + static void test_insert(Value_Container& values); + static void test_shift(Value_Container& values); + static void test_swap(Value_Container& values); + static void test_slow_insert(Value_Container& values); + static void test_clone(Value_Container& values); + static void test_container_from_end(Value_Container &, detail::bool_){} + static void test_container_from_end(Value_Container &values, detail::bool_); }; -template -void test_slist - ::test_all (std::vector& values) +template < typename List_Type, typename Value_Container > +void test_slist< List_Type, Value_Container > + ::test_all (Value_Container& values) { - typedef typename ValueTraits::value_type value_type; - typedef slist - < value_type - , value_traits - , size_type - , constant_time_size - , linear - , cache_last - > list_type; + std::clog << "testing slist with:\n" + << " value_type = " << typeid(value_type).name() << "\n" + << " sizeof(value_type) = " << sizeof(value_type) << "\n" + << " link_mode = " << value_traits::link_mode << "\n" + << " node = " << typeid(typename list_type::node).name() << "\n" + << " sizeof(node) = " << sizeof(typename list_type::node) << "\n" + << " node_ptr = " << typeid(typename list_type::node_ptr).name() << "\n" + << " sizeof(node_ptr) = " << sizeof(typename list_type::node_ptr) << "\n" + << " constant_time_size = " << list_type::constant_time_size << "\n" + << " linear = " << list_type::linear << "\n" + << " cache_last = " << list_type::cache_last << "\n" + << " has_container_from_iterator = " << list_type::has_container_from_iterator << "\n" + << " sizeof(list_type) = " << sizeof(list_type) << "\n"; { list_type list(values.begin(), values.end()); test::test_container(list); @@ -81,7 +91,7 @@ void test_slist test::test_sequence_container(list, values); } test_front(values); - test_back(values, detail::bool_()); + test_back(values, detail::bool_()); test_sort(values); test_merge (values); test_remove_unique(values); @@ -90,23 +100,14 @@ void test_slist test_slow_insert (values); test_swap(values); test_clone(values); - test_container_from_end(values, detail::bool_()); + test_container_from_end(values, detail::bool_()); } //test: push_front, pop_front, front, size, empty: -template -void test_slist - ::test_front(std::vector& values) +template < typename List_Type, typename Value_Container > +void test_slist< List_Type, Value_Container > + ::test_front(Value_Container& values) { - typedef typename ValueTraits::value_type value_type; - typedef slist - < value_type - , value_traits - , size_type - , constant_time_size - , linear - , cache_last - > list_type; list_type testlist; BOOST_TEST (testlist.empty()); @@ -127,19 +128,10 @@ void test_slist } //test: push_front, pop_front, front, size, empty: -template -void test_slist - ::test_back(std::vector& values, detail::bool_) +template < typename List_Type, typename Value_Container > +void test_slist< List_Type, Value_Container > + ::test_back(Value_Container& values, detail::bool_) { - typedef typename ValueTraits::value_type value_type; - typedef slist - < value_type - , value_traits - , size_type - , constant_time_size - , linear - , cache_last - > list_type; list_type testlist; BOOST_TEST (testlist.empty()); @@ -154,26 +146,17 @@ void test_slist } //test: push_front, pop_front, front, size, empty: -template -void test_slist - ::test_back(std::vector&, detail::bool_) +template < typename List_Type, typename Value_Container > +void test_slist< List_Type, Value_Container > + ::test_back(Value_Container&, detail::bool_) {} //test: merge due to error in merge implementation: -template -void test_slist - ::test_merge (std::vector& values) +template < typename List_Type, typename Value_Container > +void test_slist< List_Type, Value_Container > + ::test_merge (Value_Container& values) { - typedef typename ValueTraits::value_type value_type; - typedef slist - < value_type - , value_traits - , size_type - , constant_time_size - , linear - , cache_last - > list_type; list_type testlist1, testlist2; testlist1.push_front (values[0]); testlist2.push_front (values[4]); @@ -186,19 +169,10 @@ void test_slist } //test: merge due to error in merge implementation: -template -void test_slist - ::test_remove_unique (std::vector& values) +template < typename List_Type, typename Value_Container > +void test_slist< List_Type, Value_Container > + ::test_remove_unique (Value_Container& values) { - typedef typename ValueTraits::value_type value_type; - typedef slist - < value_type - , value_traits - , size_type - , constant_time_size - , linear - , cache_last - > list_type; { list_type list(values.begin(), values.end()); list.remove_if(is_even()); @@ -206,7 +180,7 @@ void test_slist TEST_INTRUSIVE_SEQUENCE( init_values, list.begin() ); } { - std::vector values2(values); + Value_Container values2(values); list_type list(values.begin(), values.end()); list.insert_after(list.before_begin(), values2.begin(), values2.end()); list.sort(); @@ -219,19 +193,10 @@ void test_slist } //test: constructor, iterator, sort, reverse: -template -void test_slist - ::test_sort(std::vector& values) +template < typename List_Type, typename Value_Container > +void test_slist< List_Type, Value_Container > + ::test_sort(Value_Container& values) { - typedef typename ValueTraits::value_type value_type; - typedef slist - < value_type - , value_traits - , size_type - , constant_time_size - , linear - , cache_last - > list_type; list_type testlist (values.begin(), values.end()); { int init_values [] = { 1, 2, 3, 4, 5 }; @@ -247,21 +212,12 @@ void test_slist } //test: assign, insert_after, const_iterator, erase_after, s_iterator_to, previous: -template -void test_slist - ::test_insert(std::vector& values) +template < typename List_Type, typename Value_Container > +void test_slist< List_Type, Value_Container > + ::test_insert(Value_Container& values) { - typedef typename ValueTraits::value_type value_type; - typedef slist - < value_type - , value_traits - , size_type - , constant_time_size - , linear - , cache_last - > list_type; list_type testlist; - testlist.assign (&values[0] + 2, &values[0] + 5); + testlist.assign (values.begin() + 2, values.begin() + 5); const list_type& const_testlist = testlist; { int init_values [] = { 3, 4, 5 }; @@ -280,9 +236,9 @@ void test_slist BOOST_TEST (&*i == &values[4]); typename list_type::const_iterator ic; - ic = testlist.iterator_to (const_cast(values[4])); + ic = testlist.iterator_to (static_cast< typename list_type::const_reference >(values[4])); BOOST_TEST (&*ic == &values[4]); - ic = list_type::s_iterator_to (const_cast(values[4])); + ic = list_type::s_iterator_to (static_cast< typename list_type::const_reference >(values[4])); BOOST_TEST (&*ic == &values[4]); i = testlist.previous (i); @@ -295,22 +251,13 @@ void test_slist } //test: insert, const_iterator, erase, siterator_to: -template -void test_slist - ::test_slow_insert (std::vector& values) +template < typename List_Type, typename Value_Container > +void test_slist< List_Type, Value_Container > + ::test_slow_insert (Value_Container& values) { - typedef typename ValueTraits::value_type value_type; - typedef slist - < value_type - , value_traits - , size_type - , constant_time_size - , linear - , cache_last - > list_type; list_type testlist; testlist.push_front (values[4]); - testlist.insert (testlist.begin(), &values[0] + 2, &values[0] + 4); + testlist.insert (testlist.begin(), values.begin() + 2, values.begin() + 4); const list_type& const_testlist = testlist; { int init_values [] = { 3, 4, 5 }; @@ -337,24 +284,14 @@ void test_slist testlist.erase (++testlist.begin(), testlist.end()); BOOST_TEST (testlist.size() == 1); - BOOST_TEST (testlist.front().value_ == 3); + BOOST_TEST (testlist.begin()->value_ == 3); } -template -void test_slist - ::test_shift(std::vector& values) +template < typename List_Type, typename Value_Container > +void test_slist< List_Type, Value_Container > + ::test_shift(Value_Container& values) { - typedef typename ValueTraits::value_type value_type; - typedef slist - < value_type - , value_traits - , size_type - , constant_time_size - , linear - , cache_last - > list_type; list_type testlist; - const int num_values = (int)values.size(); std::vector expected_values(num_values); @@ -362,7 +299,7 @@ void test_slist for(int s = 1; s <= num_values; ++s){ expected_values.resize(s); for(int i = 0; i < s*3; ++i){ - testlist.insert_after(testlist.before_begin(), &values[0], &values[0] + s); + testlist.insert_after(testlist.before_begin(), values.begin(), values.begin() + s); testlist.shift_forward(i); for(int j = 0; j < s; ++j){ expected_values[(j + s - i%s) % s] = (j + 1); @@ -374,7 +311,7 @@ void test_slist //Shift backwards all possible positions for(int i = 0; i < s*3; ++i){ - testlist.insert_after(testlist.before_begin(), &values[0], &values[0] + s); + testlist.insert_after(testlist.before_begin(), values.begin(), values.begin() + s); testlist.shift_backwards(i); for(int j = 0; j < s; ++j){ expected_values[(j + i) % s] = (j + 1); @@ -387,23 +324,14 @@ void test_slist } //test: insert_after (seq-version), swap, splice_after: -template -void test_slist - ::test_swap(std::vector& values) +template < typename List_Type, typename Value_Container > +void test_slist< List_Type, Value_Container > + ::test_swap(Value_Container& values) { - typedef typename ValueTraits::value_type value_type; - typedef slist - < value_type - , value_traits - , size_type - , constant_time_size - , linear - , cache_last - > list_type; { - list_type testlist1 (&values[0], &values[0] + 2); + list_type testlist1 (values.begin(), values.begin() + 2); list_type testlist2; - testlist2.insert_after (testlist2.before_begin(), &values[0] + 2, &values[0] + 5); + testlist2.insert_after (testlist2.before_begin(), values.begin() + 2, values.begin() + 5); testlist1.swap(testlist2); { int init_values [] = { 3, 4, 5 }; TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); } @@ -428,7 +356,7 @@ void test_slist TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() ); } } { //Now test swap when testlist2 is empty - list_type testlist1 (&values[0], &values[0] + 2); + list_type testlist1 (values.begin(), values.begin() + 2); list_type testlist2; testlist1.swap(testlist2); BOOST_TEST (testlist1.empty()); @@ -436,7 +364,7 @@ void test_slist TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() ); } } { //Now test swap when testlist1 is empty - list_type testlist2 (&values[0], &values[0] + 2); + list_type testlist2 (values.begin(), values.begin() + 2); list_type testlist1; testlist1.swap(testlist2); BOOST_TEST (testlist2.empty()); @@ -451,14 +379,14 @@ void test_slist if(!list_type::linear) { - list_type testlist1 (&values[0], &values[0] + 2); - list_type testlist2 (&values[0] + 3, &values[0] + 5); + list_type testlist1 (values.begin(), values.begin() + 2); + list_type testlist2 (values.begin() + 3, values.begin() + 5); - values[0].swap_nodes(values[2]); + swap_nodes< node_algorithms >(values[0], values[2]); { int init_values [] = { 3, 2 }; TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); } - values[2].swap_nodes(values[4]); + swap_nodes< node_algorithms >(values[2], values[4]); { int init_values [] = { 5, 2 }; TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); } { int init_values [] = { 4, 3 }; @@ -466,52 +394,42 @@ void test_slist } if(!list_type::linear) { - list_type testlist1 (&values[0], &values[0]+1); + list_type testlist1 (values.begin(), values.begin()+1); if(testlist1.size() != 1){ abort(); } { int init_values [] = { 1 }; TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); } - values[1].swap_nodes(values[2]); + swap_nodes< node_algorithms >(values[1], values[2]); BOOST_TEST(testlist1.size() == 1); - BOOST_TEST(!values[1].is_linked()); - BOOST_TEST(!values[2].is_linked()); + BOOST_TEST(!(&values[1])->is_linked()); + BOOST_TEST(!(&values[2])->is_linked()); { int init_values [] = { 1 }; TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); } - values[0].swap_nodes(values[2]); + swap_nodes< node_algorithms >(values[0], values[2]); BOOST_TEST(testlist1.size() == 1); - BOOST_TEST(values[2].is_linked()); - BOOST_TEST(!values[0].is_linked()); + BOOST_TEST((&values[2])->is_linked()); + BOOST_TEST(!(&values[0])->is_linked()); { int init_values [] = { 3 }; TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); } - values[0].swap_nodes(values[2]); + swap_nodes< node_algorithms >(values[0], values[2]); BOOST_TEST(testlist1.size() == 1); - BOOST_TEST(!values[2].is_linked()); - BOOST_TEST(values[0].is_linked()); + BOOST_TEST(!(&values[2])->is_linked()); + BOOST_TEST((&values[0])->is_linked()); { int init_values [] = { 1 }; TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); } } } -template -void test_slist - ::test_clone(std::vector& values) +template < typename List_Type, typename Value_Container > +void test_slist< List_Type, Value_Container > + ::test_clone(Value_Container& values) { - typedef typename ValueTraits::value_type value_type; - typedef slist - < value_type - , value_traits - , size_type - , constant_time_size - , linear - , cache_last - > list_type; - - list_type testlist1 (&values[0], &values[0] + values.size()); + list_type testlist1 (values.begin(), values.begin() + values.size()); list_type testlist2; testlist2.clone_from(testlist1, test::new_cloner(), test::delete_disposer()); @@ -520,144 +438,193 @@ void test_slist BOOST_TEST (testlist2.empty()); } -template -void test_slist - ::test_container_from_end(std::vector& values +template < typename List_Type, typename Value_Container > +void test_slist< List_Type, Value_Container > + ::test_container_from_end(Value_Container& values ,detail::bool_) { - typedef typename ValueTraits::value_type value_type; - typedef slist - < value_type - , value_traits - , size_type - , constant_time_size - , linear - , cache_last - > list_type; - list_type testlist1 (&values[0], &values[0] + values.size()); + + list_type testlist1 (values.begin(), values.begin() + values.size()); BOOST_TEST (testlist1 == list_type::container_from_end_iterator(testlist1.end())); BOOST_TEST (testlist1 == list_type::container_from_end_iterator(testlist1.cend())); } -template +template < typename Value_Traits, bool Constant_Time_Size, bool Linear, bool CacheLast, bool Default_Holder, typename Value_Container > +struct make_and_test_slist + : test_slist< slist< typename Value_Traits::value_type, + value_traits< Value_Traits >, + size_type< std::size_t >, + constant_time_size< Constant_Time_Size >, + linear, + cache_last + >, + Value_Container + > +{}; + +template < typename Value_Traits, bool Constant_Time_Size, bool Linear, bool CacheLast, typename Value_Container > +struct make_and_test_slist< Value_Traits, Constant_Time_Size, Linear, CacheLast, false, Value_Container > + : test_slist< slist< typename Value_Traits::value_type, + value_traits< Value_Traits >, + size_type< std::size_t >, + constant_time_size< Constant_Time_Size >, + linear, + cache_last, + header_holder_type< pointer_holder< typename Value_Traits::node_traits::node > > + >, + Value_Container + > +{}; + +template class test_main_template { public: int operator()() { typedef testvalue , constant_time_size> value_type; - std::vector data (5); + std::vector< value_type > data (5); for (int i = 0; i < 5; ++i) data[i].value_ = i + 1; - test_slist < typename detail::get_base_value_traits + make_and_test_slist < typename detail::get_base_value_traits < value_type , typename hooks::base_hook_type >::type + , constant_time_size , false , false + , Default_Holder + , std::vector< value_type > >::test_all(data); - test_slist < typename detail::get_member_value_traits + make_and_test_slist < typename detail::get_member_value_traits < value_type , member_hook< value_type , typename hooks::member_hook_type , &value_type::node_ > >::type + , constant_time_size , false , false + , Default_Holder + , std::vector< value_type > >::test_all(data); - test_slist < nonhook_node_member_value_traits< value_type, + make_and_test_slist < nonhook_node_member_value_traits< value_type, typename hooks::nonhook_node_member_type, &value_type::nhn_member_, safe_link - >, - false, - false + > + , constant_time_size + , false + , false + , Default_Holder + , std::vector< value_type > >::test_all(data); //Now linear slists - test_slist < typename detail::get_base_value_traits + make_and_test_slist < typename detail::get_base_value_traits < value_type , typename hooks::base_hook_type >::type + , constant_time_size , true , false + , Default_Holder + , std::vector< value_type > >::test_all(data); - test_slist < typename detail::get_member_value_traits + make_and_test_slist < typename detail::get_member_value_traits < value_type , member_hook< value_type , typename hooks::member_hook_type , &value_type::node_ > >::type + , constant_time_size , true , false + , Default_Holder + , std::vector< value_type > >::test_all(data); //Now the same but caching the last node - test_slist < typename detail::get_base_value_traits + make_and_test_slist < typename detail::get_base_value_traits < value_type , typename hooks::base_hook_type >::type + , constant_time_size , false , true + , Default_Holder + , std::vector< value_type > >::test_all(data); - test_slist < typename detail::get_member_value_traits + make_and_test_slist < typename detail::get_member_value_traits < value_type , member_hook< value_type , typename hooks::member_hook_type , &value_type::node_ > >::type + , constant_time_size , false , true + , Default_Holder + , std::vector< value_type > >::test_all(data); //Now linear slists - test_slist < typename detail::get_base_value_traits + make_and_test_slist < typename detail::get_base_value_traits < value_type , typename hooks::base_hook_type >::type + , constant_time_size , true , true + , Default_Holder + , std::vector< value_type > >::test_all(data); - test_slist < typename detail::get_member_value_traits + make_and_test_slist < typename detail::get_member_value_traits < value_type , member_hook< value_type , typename hooks::member_hook_type , &value_type::node_ > >::type + , constant_time_size , true , true + , Default_Holder + , std::vector< value_type > >::test_all(data); return 0; } }; -template -class test_main_template +template +class test_main_template { public: int operator()() { typedef testvalue , false> value_type; - std::vector data (5); + std::vector< value_type > data (5); for (int i = 0; i < 5; ++i) data[i].value_ = i + 1; - test_slist < typename detail::get_base_value_traits + make_and_test_slist < typename detail::get_base_value_traits < value_type , typename hooks::base_hook_type >::type , false , false + , false + , Default_Holder + , std::vector< value_type > >::test_all(data); - test_slist < typename detail::get_member_value_traits + make_and_test_slist < typename detail::get_member_value_traits < value_type , member_hook< value_type , typename hooks::member_hook_type @@ -666,17 +633,23 @@ class test_main_template >::type , false , false + , false + , Default_Holder + , std::vector< value_type > >::test_all(data); - test_slist < typename detail::get_base_value_traits + make_and_test_slist < typename detail::get_base_value_traits < value_type , typename hooks::auto_base_hook_type >::type , false , false + , false + , Default_Holder + , std::vector< value_type > >::test_all(data); - test_slist < typename detail::get_member_value_traits + make_and_test_slist < typename detail::get_member_value_traits < value_type , member_hook< value_type , typename hooks::auto_member_hook_type @@ -685,37 +658,74 @@ class test_main_template >::type , false , false + , false + , Default_Holder + , std::vector< value_type > >::test_all(data); - test_slist < typename detail::get_base_value_traits + make_and_test_slist < typename detail::get_base_value_traits < value_type , typename hooks::base_hook_type >::type + , false , true , false + , Default_Holder + , std::vector< value_type > >::test_all(data); - test_slist < typename detail::get_member_value_traits + make_and_test_slist < typename detail::get_member_value_traits < value_type , member_hook< value_type , typename hooks::member_hook_type , &value_type::node_ > >::type + , false , true , false + , Default_Holder + , std::vector< value_type > >::test_all(data); //Now cache last - test_slist < typename detail::get_base_value_traits + make_and_test_slist < typename detail::get_base_value_traits + < value_type + , typename hooks::base_hook_type + >::type + , false + , false + , true + , Default_Holder + , std::vector< value_type > + >::test_all(data); + + make_and_test_slist < typename detail::get_member_value_traits + < value_type + , member_hook< value_type + , typename hooks::member_hook_type + , &value_type::node_ + > + >::type + , false + , false + , true + , Default_Holder + , std::vector< value_type > + >::test_all(data); + + make_and_test_slist < typename detail::get_base_value_traits < value_type , typename hooks::base_hook_type >::type , false , true + , true + , Default_Holder + , std::vector< value_type > >::test_all(data); - test_slist < typename detail::get_member_value_traits + make_and_test_slist < typename detail::get_member_value_traits < value_type , member_hook< value_type , typename hooks::member_hook_type @@ -724,36 +734,66 @@ class test_main_template >::type , false , true + , true + , Default_Holder + , std::vector< value_type > >::test_all(data); + return 0; + } +}; - test_slist < typename detail::get_base_value_traits - < value_type - , typename hooks::base_hook_type - >::type - , true - , true - >::test_all(data); +template < bool Constant_Time_Size > +struct test_main_template_bptr +{ + int operator()() + { + typedef BPtr_Value value_type; + typedef BPtr_Value_Traits< List_BPtr_Node_Traits > list_value_traits; + typedef typename list_value_traits::node_ptr node_ptr; + typedef Bounded_Allocator< value_type > allocator_type; - test_slist < typename detail::get_member_value_traits - < value_type - , member_hook< value_type - , typename hooks::member_hook_type - , &value_type::node_ - > - >::type - , true - , true - >::test_all(data); + allocator_type::init(); + allocator_type allocator; + + { + Bounded_Reference_Cont< value_type > ref_cont; + for (int i = 0; i < 5; ++i) + { + node_ptr tmp = allocator.allocate(1); + new (tmp.raw()) value_type(i + 1); + ref_cont.push_back(*tmp); + } + + test_slist < slist < value_type, + value_traits< list_value_traits >, + size_type< std::size_t >, + constant_time_size< Constant_Time_Size >, + header_holder_type< Bounded_Pointer_Holder< value_type > > + >, + Bounded_Reference_Cont< value_type > + >::test_all(ref_cont); + } + + assert(allocator_type::is_clear()); + allocator_type::destroy(); return 0; } }; int main(int, char* []) { - test_main_template()(); - test_main_template, false>()(); - test_main_template()(); - test_main_template, true>()(); + // test combinations of (regular/smart)_ptr x (const/nonconst)_size x (default/non-default)_header_holder + // skip smart_ptr with non-default header_holder + test_main_template()(); + test_main_template, false, true>()(); + test_main_template()(); + test_main_template, true, true>()(); + test_main_template()(); + test_main_template()(); + // test bounded pointers with const/non_const size (always with non-default header_holder) + test_main_template_bptr< true >()(); + test_main_template_bptr< false >()(); + return boost::report_errors(); } #include From f4eb5831aa5e3696ede50c79ead384034f047a02 Mon Sep 17 00:00:00 2001 From: Matei David Date: Tue, 20 May 2014 16:42:56 -0400 Subject: [PATCH 14/14] tests: bounded pointers tests for (splay/sg/treap)x(set/multiset) --- test/avl_multiset_test.cpp | 6 +- test/avl_set_test.cpp | 6 +- test/bounded_pointer.hpp | 60 +++++++++- test/bptr_value.hpp | 15 +++ test/generic_assoc_test.hpp | 197 ++++++++------------------------- test/generic_multiset_test.hpp | 27 ++++- test/generic_set_test.hpp | 57 +++++----- test/itestvalue.hpp | 11 +- test/list_test.cpp | 58 ++++------ test/multiset_test.cpp | 6 +- test/set_test.cpp | 6 +- test/sg_multiset_test.cpp | 174 ++++++++++++++++++++++++++--- test/sg_set_test.cpp | 169 ++++++++++++++++++++++++++-- test/slist_test.cpp | 58 +++++----- test/splay_multiset_test.cpp | 124 +++++++++++++++++---- test/splay_set_test.cpp | 124 +++++++++++++++++---- test/treap_multiset_test.cpp | 116 ++++++++++++++++--- test/treap_set_test.cpp | 120 +++++++++++++++++--- 18 files changed, 956 insertions(+), 378 deletions(-) diff --git a/test/avl_multiset_test.cpp b/test/avl_multiset_test.cpp index c02f961..1238950 100644 --- a/test/avl_multiset_test.cpp +++ b/test/avl_multiset_test.cpp @@ -21,13 +21,13 @@ namespace boost { namespace intrusive { namespace test { #if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES) -template +template #else template #endif struct has_insert_before()(); test_main_template()(); - // test (bounded pointers) x ((nonconst/const size) x (special node allocator) + // test (bounded pointers) x (nonconst/const size) x (special node allocator) test_main_template_bptr< true >()(); test_main_template_bptr< false >()(); diff --git a/test/avl_set_test.cpp b/test/avl_set_test.cpp index 18d5b9d..26f66d9 100644 --- a/test/avl_set_test.cpp +++ b/test/avl_set_test.cpp @@ -20,13 +20,13 @@ namespace boost { namespace intrusive { namespace test { #if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES) -template +template #else template #endif struct has_insert_before()(); test_main_template()(); - // test (bounded pointers) x ((nonconst/const size) x (special node allocator) + // test (bounded pointers) x (nonconst/const size) x (special node allocator) test_main_template_bptr< true >()(); test_main_template_bptr< false >()(); diff --git a/test/bounded_pointer.hpp b/test/bounded_pointer.hpp index 75828cc..7dcf8d8 100644 --- a/test/bounded_pointer.hpp +++ b/test/bounded_pointer.hpp @@ -222,44 +222,92 @@ std::vector< bool > Bounded_Allocator< T >::_in_use; template < typename T > class Bounded_Reference_Cont - : public std::vector< Bounded_Reference< T > > + : private std::vector< Bounded_Reference< T > > { private: - typedef T value_type; + typedef T val_type; typedef std::vector< Bounded_Reference< T > > Base; typedef Bounded_Allocator< T > allocator_type; typedef Bounded_Pointer< T > pointer; public: + typedef typename Base::value_type value_type; + typedef typename Base::iterator iterator; + typedef typename Base::const_iterator const_iterator; + typedef typename Base::reference reference; + typedef typename Base::const_reference const_reference; + typedef typename Base::reverse_iterator reverse_iterator; + typedef typename Base::const_reverse_iterator const_reverse_iterator; + + iterator begin() { return Base::begin(); } + iterator end() { return Base::end(); } + const_iterator begin() const { return Base::begin(); } + const_iterator end() const { return Base::end(); } + reverse_iterator rbegin() { return Base::rbegin(); } + reverse_iterator rend() { return Base::rend(); } + const_reverse_iterator rbegin() const { return Base::rbegin(); } + const_reverse_iterator rend() const { return Base::rend(); } + reference front() { return Base::front(); } + const_reference front() const { return Base::front(); } + reference back() { return Base::back(); } + const_reference back() const { return Base::back(); } + size_t size() const { return Base::size(); } + reference operator [] (size_t i) { return Base::operator [] (i); } + const_reference operator [] (size_t i) const { return Base::operator [] (i); } + void push_back(const value_type& v) { Base::push_back(v); } + Bounded_Reference_Cont(size_t n = 0) : Base(), _allocator() { for (size_t i = 0; i < n; ++i) { pointer p = _allocator.allocate(1); - new (p.raw()) value_type(); + new (p.raw()) val_type(); Base::push_back(*p); } } Bounded_Reference_Cont(const Bounded_Reference_Cont& other) : Base(), _allocator(other._allocator) { //std::clog << "copying values container\n"; - for (typename Base::const_iterator it = other.begin(); it != other.end(); ++it) + *this = other; + } + template < typename InputIterator > + Bounded_Reference_Cont(InputIterator it_start, InputIterator it_end) : Base(), _allocator() + { + for (InputIterator it = it_start; it != it_end; ++it) { pointer p = _allocator.allocate(1); - new (p.raw()) value_type(*it); + new (p.raw()) val_type(*it); Base::push_back(*p); } } ~Bounded_Reference_Cont() + { + clear(); + } + void clear() { while (not Base::empty()) { pointer p = &Base::back(); - p->~value_type(); + p->~val_type(); _allocator.deallocate(p, 1); Base::pop_back(); } } + Bounded_Reference_Cont& operator = (const Bounded_Reference_Cont& other) + { + if (&other != this) + { + clear(); + for (typename Base::const_iterator it = other.begin(); it != other.end(); ++it) + { + pointer p = _allocator.allocate(1); + new (p.raw()) val_type(*it); + Base::push_back(*p); + } + } + return *this; + } private: allocator_type _allocator; diff --git a/test/bptr_value.hpp b/test/bptr_value.hpp index e930cf2..daec91f 100644 --- a/test/bptr_value.hpp +++ b/test/bptr_value.hpp @@ -167,6 +167,21 @@ struct AVLTree_BPtr_Node_Traits static balance positive() { return 1; } }; +struct Tree_BPtr_Node_Traits +{ + typedef BPtr_Value val_t; + typedef val_t node; + typedef Bounded_Pointer< val_t > node_ptr; + typedef Bounded_Pointer< const val_t > const_node_ptr; + + static node_ptr get_parent(const_node_ptr p) { return p->_parent; } + static void set_parent(node_ptr p, node_ptr parent) { p->_parent = parent; } + static node_ptr get_left(const_node_ptr p) { return p->_l_child; } + static void set_left(node_ptr p, node_ptr l_child) { p->_l_child = l_child; } + static node_ptr get_right(const_node_ptr p) { return p->_r_child; } + static void set_right(node_ptr p, node_ptr r_child) { p->_r_child = r_child; } +}; + template < typename Node_Traits > struct BPtr_Value_Traits { diff --git a/test/generic_assoc_test.hpp b/test/generic_assoc_test.hpp index 5854df0..45b861e 100644 --- a/test/generic_assoc_test.hpp +++ b/test/generic_assoc_test.hpp @@ -78,38 +78,32 @@ struct test_generic_assoc typedef typename Value_Container< value_type >::type value_cont_type; typedef typename ValueTraits::reference reference; typedef typename ValueTraits::const_reference const_reference; - static void test_all(value_cont_type& values); - static void test_clone(value_cont_type& values); + static void test_all(value_cont_type&); + static void test_clone(value_cont_type&); static void test_insert_erase_burst(); - static void test_container_from_end(value_cont_type& values); - static void test_splay_up(value_cont_type& values); - static void test_splay_up(value_cont_type& values, boost::intrusive::detail::true_type); - static void test_splay_up(value_cont_type& values, boost::intrusive::detail::false_type); - static void test_splay_down(value_cont_type& values); - static void test_splay_down(value_cont_type& values, boost::intrusive::detail::true_type); - static void test_splay_down(value_cont_type& values, boost::intrusive::detail::false_type); - static void test_rebalance(value_cont_type& values); - static void test_rebalance(value_cont_type& values, boost::intrusive::detail::true_type); - static void test_rebalance(value_cont_type& values, boost::intrusive::detail::false_type); - static void test_insert_before(value_cont_type& values); - static void test_insert_before(value_cont_type& values, boost::intrusive::detail::true_type); - static void test_insert_before(value_cont_type& values, boost::intrusive::detail::false_type); - static void test_container_from_iterator(value_cont_type& values); + static void test_container_from_end(value_cont_type&, detail::true_type); + static void test_container_from_end(value_cont_type&, detail::false_type) {} + static void test_splay_up(value_cont_type&, detail::true_type); + static void test_splay_up(value_cont_type&, detail::false_type) {} + static void test_splay_down(value_cont_type&, detail::true_type); + static void test_splay_down(value_cont_type&, detail::false_type) {} + static void test_rebalance(value_cont_type&, detail::true_type); + static void test_rebalance(value_cont_type&, detail::false_type) {} + static void test_insert_before(value_cont_type&, detail::true_type); + static void test_insert_before(value_cont_type&, detail::false_type) {} + static void test_container_from_iterator(value_cont_type&, detail::true_type); + static void test_container_from_iterator(value_cont_type&, detail::false_type) {} }; -template < bool Has_Container_From_Iterator, typename assoc_type, typename Value_Container > -struct test_container_from_iterator_impl -{ - void operator () (Value_Container&) - { - std::clog << "skipping test_container_from_iterator\n"; - } -}; -template < typename assoc_type, typename Value_Container > -struct test_container_from_iterator_impl< true, assoc_type, Value_Container > -{ - void operator () (Value_Container& values) +template class ContainerDefiner> +void test_generic_assoc:: + test_container_from_iterator(value_cont_type& values, detail::true_type) { + typedef typename ContainerDefiner + < value_type + , value_traits + , constant_time_size + >::type assoc_type; assoc_type testset(values.begin(), values.end()); typedef typename assoc_type::iterator it_type; typedef typename assoc_type::const_iterator cit_type; @@ -127,19 +121,6 @@ struct test_container_from_iterator_impl< true, assoc_type, Value_Container > BOOST_TEST(testset.size() == sz); } } -}; - -template class ContainerDefiner> -void test_generic_assoc:: - test_container_from_iterator(value_cont_type& values) -{ - typedef typename ContainerDefiner - < value_type - , value_traits - , constant_time_size - >::type assoc_type; - test_container_from_iterator_impl< assoc_type::has_container_from_iterator, assoc_type, value_cont_type >()(values); -} template class ContainerDefiner> void test_generic_assoc::test_insert_erase_burst() @@ -202,14 +183,20 @@ void test_generic_assoc::test_insert_erase_burst( template class ContainerDefiner> void test_generic_assoc::test_all(value_cont_type& values) { + typedef typename ContainerDefiner + < value_type + , value_traits + , constant_time_size + >::type assoc_type; + test_clone(values); - test_container_from_end(values); - test_splay_up(values); - test_splay_down(values); - test_rebalance(values); - test_insert_before(values); + test_container_from_end(values, detail::bool_< assoc_type::has_container_from_iterator >()); + test_splay_up(values, detail::bool_< has_splay< assoc_type >::value >()); + test_splay_down(values, detail::bool_< has_splay< assoc_type >::value >()); + test_rebalance(values, detail::bool_< has_rebalance< assoc_type >::value >()); + test_insert_before(values, detail::bool_< has_insert_before< assoc_type >::value >()); test_insert_erase_burst(); - test_container_from_iterator(values); + test_container_from_iterator(values, detail::bool_< assoc_type::has_container_from_iterator >()); } template class ContainerDefiner> @@ -230,28 +217,9 @@ void test_generic_assoc BOOST_TEST (testset2.empty()); } -template < bool Has_Container_From_Iterator, typename assoc_type, typename value_cont_type > -struct test_container_from_end_impl -{ - void operator () (value_cont_type&) - { - std::clog << "skipping test_container_from_end\n"; - } -}; -template < typename assoc_type, typename value_cont_type > -struct test_container_from_end_impl< true, assoc_type, value_cont_type > -{ - void operator () (value_cont_type& values) -{ - assoc_type testset (values.begin(), values.begin() + values.size()); - BOOST_TEST (testset == assoc_type::container_from_end_iterator(testset.end())); - BOOST_TEST (testset == assoc_type::container_from_end_iterator(testset.cend())); -} -}; - template class ContainerDefiner> void test_generic_assoc - ::test_container_from_end(value_cont_type& values) + ::test_container_from_end(value_cont_type& values, detail::true_type) { typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -259,12 +227,14 @@ void test_generic_assoc , value_traits , constant_time_size >::type assoc_type; - test_container_from_end_impl< assoc_type::has_container_from_iterator, assoc_type, value_cont_type >()(values); + assoc_type testset (values.begin(), values.begin() + values.size()); + BOOST_TEST (testset == assoc_type::container_from_end_iterator(testset.end())); + BOOST_TEST (testset == assoc_type::container_from_end_iterator(testset.cend())); } template class ContainerDefiner> void test_generic_assoc::test_splay_up -(value_cont_type& values, boost::intrusive::detail::true_type) +(value_cont_type& values, detail::true_type) { typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -279,7 +249,7 @@ void test_generic_assoc::test_splay_up { assoc_type testset (values.begin(), values.end()); num_values = testset.size(); - original_testset.insert(original_testset.end(), testset.begin(), testset.end()); + original_testset = value_cont_type(testset.begin(), testset.end()); } for(std::size_t i = 0; i != num_values; ++i){ @@ -300,28 +270,9 @@ void test_generic_assoc::test_splay_up } } -template class ContainerDefiner> -void test_generic_assoc::test_splay_up -(value_cont_type&, boost::intrusive::detail::false_type) -{} - -template class ContainerDefiner> -void test_generic_assoc::test_splay_up -(value_cont_type& values) -{ - typedef typename ContainerDefiner - < value_type - , value_traits - , constant_time_size - >::type assoc_type; - typedef typename detail::remove_const::type Type; - typedef detail::bool_::value> enabler; - test_splay_up(values, enabler()); -} - template class ContainerDefiner> void test_generic_assoc::test_splay_down -(value_cont_type& values, boost::intrusive::detail::true_type) +(value_cont_type& values, detail::true_type) { typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -336,7 +287,7 @@ void test_generic_assoc::test_splay_down { assoc_type testset (values.begin(), values.end()); num_values = testset.size(); - original_testset.insert(original_testset.end(), testset.begin(), testset.end()); + original_testset = value_cont_type(testset.begin(), testset.end()); } for(std::size_t i = 0; i != num_values; ++i){ @@ -358,28 +309,9 @@ void test_generic_assoc::test_splay_down } } -template class ContainerDefiner> -void test_generic_assoc::test_splay_down -(value_cont_type&, boost::intrusive::detail::false_type) -{} - -template class ContainerDefiner> -void test_generic_assoc::test_splay_down -(value_cont_type& values) -{ - typedef typename ContainerDefiner - < value_type - , value_traits - , constant_time_size - >::type assoc_type; - typedef typename detail::remove_const::type Type; - typedef detail::bool_::value> enabler; - test_splay_down(values, enabler()); -} - template class ContainerDefiner> void test_generic_assoc::test_rebalance -(value_cont_type& values, boost::intrusive::detail::true_type) +(value_cont_type& values, detail::true_type) { typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -391,7 +323,8 @@ void test_generic_assoc::test_rebalance orig_set_t original_testset; { assoc_type testset (values.begin(), values.end()); - original_testset.insert(original_testset.end(), testset.begin(), testset.end()); + //original_testset.insert(original_testset.end(), testset.begin(), testset.end()); + original_testset = value_cont_type(testset.begin(), testset.end()); } { assoc_type testset(values.begin(), values.end()); @@ -416,28 +349,9 @@ void test_generic_assoc::test_rebalance } } -template class ContainerDefiner> -void test_generic_assoc::test_rebalance -(value_cont_type&, boost::intrusive::detail::false_type) -{} - -template class ContainerDefiner> -void test_generic_assoc::test_rebalance -(value_cont_type& values) -{ - typedef typename ContainerDefiner - < value_type - , value_traits - , constant_time_size - >::type assoc_type; - typedef typename detail::remove_const::type Type; - typedef detail::bool_::value> enabler; - test_rebalance(values, enabler()); -} - template class ContainerDefiner> void test_generic_assoc::test_insert_before -(value_cont_type& values, boost::intrusive::detail::true_type) +(value_cont_type& values, detail::true_type) { typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -485,25 +399,6 @@ void test_generic_assoc::test_insert_before } } -template class ContainerDefiner> -void test_generic_assoc::test_insert_before -(value_cont_type&, boost::intrusive::detail::false_type) -{} - -template class ContainerDefiner> -void test_generic_assoc::test_insert_before -(value_cont_type& values) -{ - typedef typename ContainerDefiner - < value_type - , value_traits - , constant_time_size - >::type assoc_type; - typedef typename detail::remove_const::type Type; - typedef detail::bool_::value> enabler; - test_insert_before(values, enabler()); -} - }}} //namespace boost::intrusive::test #include diff --git a/test/generic_multiset_test.hpp b/test/generic_multiset_test.hpp index fe3800d..82aa6cc 100644 --- a/test/generic_multiset_test.hpp +++ b/test/generic_multiset_test.hpp @@ -18,6 +18,7 @@ #include "test_macros.hpp" #include "test_container.hpp" #include "generic_assoc_test.hpp" +#include namespace boost{ namespace intrusive{ @@ -30,11 +31,11 @@ struct test_generic_multiset typedef typename Value_Container< value_type >::type value_cont_type; typedef typename ValueTraits::reference reference; typedef typename ValueTraits::const_reference const_reference; - static void test_all (); - static void test_sort(value_cont_type& values); - static void test_insert(value_cont_type& values); - static void test_swap(value_cont_type& values); - static void test_find(value_cont_type& values); + static void test_all(); + static void test_sort(value_cont_type&); + static void test_insert(value_cont_type&); + static void test_swap(value_cont_type&); + static void test_find(value_cont_type&); static void test_impl(); }; @@ -52,6 +53,22 @@ void test_generic_multiset::test_all () , value_traits , constant_time_size >::type multiset_type; +#ifdef PRINT_TESTS + std::clog << "testing multiset with:\n" + << " value_type = " << typeid(value_type).name() << "\n" + << " sizeof(value_type) = " << sizeof(value_type) << "\n" + << " link_mode = " << ValueTraits::link_mode << "\n" + << " node = " << typeid(typename multiset_type::node).name() << "\n" + << " sizeof(node) = " << sizeof(typename multiset_type::node) << "\n" + << " node_ptr = " << typeid(typename multiset_type::node_ptr).name() << "\n" + << " sizeof(node_ptr) = " << sizeof(typename multiset_type::node_ptr) << "\n" + << " constant_time_size = " << multiset_type::constant_time_size << "\n" + << " has_container_from_iterator = " << multiset_type::has_container_from_iterator << "\n" + << " has_splay = " << has_splay< multiset_type >::value << "\n" + << " has_rebalance = " << has_rebalance< multiset_type >::value << "\n" + << " has_insert_before = " << has_insert_before< multiset_type >::value << "\n" + << " sizeof(multiset_type) = " << sizeof(multiset_type) << "\n"; +#endif { multiset_type testset(values.begin(), values.end()); test::test_container(testset); diff --git a/test/generic_set_test.hpp b/test/generic_set_test.hpp index cf132a2..86bea8b 100644 --- a/test/generic_set_test.hpp +++ b/test/generic_set_test.hpp @@ -18,6 +18,7 @@ #include "test_macros.hpp" #include "test_container.hpp" #include "generic_assoc_test.hpp" +#include namespace boost{ namespace intrusive{ @@ -37,13 +38,12 @@ struct test_generic_set typedef typename ValueTraits::reference reference; typedef typename ValueTraits::const_reference const_reference; static void test_all(); - static void test_sort(value_cont_type& values); - static void test_insert(value_cont_type& values); - static void test_insert_advanced(value_cont_type& values, boost::intrusive::detail::true_type); - static void test_insert_advanced(value_cont_type& values, boost::intrusive::detail::false_type); - static void test_insert_advanced(value_cont_type& values); - static void test_swap(value_cont_type& values); - static void test_find(value_cont_type& values); + static void test_sort(value_cont_type&); + static void test_insert(value_cont_type&); + static void test_insert_advanced(value_cont_type&, detail::true_type); + static void test_insert_advanced(value_cont_type&, detail::false_type); + static void test_swap(value_cont_type&); + static void test_find(value_cont_type&); static void test_impl(); }; @@ -62,6 +62,23 @@ void test_generic_set::test_all() , value_traits , constant_time_size >::type set_type; +#ifdef PRINT_TESTS + std::clog << "testing set with:\n" + << " value_type = " << typeid(value_type).name() << "\n" + << " sizeof(value_type) = " << sizeof(value_type) << "\n" + << " link_mode = " << ValueTraits::link_mode << "\n" + << " node = " << typeid(typename set_type::node).name() << "\n" + << " sizeof(node) = " << sizeof(typename set_type::node) << "\n" + << " node_ptr = " << typeid(typename set_type::node_ptr).name() << "\n" + << " sizeof(node_ptr) = " << sizeof(typename set_type::node_ptr) << "\n" + << " constant_time_size = " << set_type::constant_time_size << "\n" + << " has_container_from_iterator = " << set_type::has_container_from_iterator << "\n" + << " is_treap = " << is_treap< set_type >::value << "\n" + << " has_splay = " << has_splay< set_type >::value << "\n" + << " has_rebalance = " << has_rebalance< set_type >::value << "\n" + << " has_insert_before = " << has_insert_before< set_type >::value << "\n" + << " sizeof(set_type) = " << sizeof(set_type) << "\n"; +#endif { set_type testset(values.begin(), values.end()); test::test_container(testset); @@ -77,7 +94,7 @@ void test_generic_set::test_all() } test_sort(values); test_insert(values); - test_insert_advanced(values); + test_insert_advanced(values, detail::bool_< is_treap< set_type >::value >()); test_swap(values); test_find(values); test_impl(); @@ -187,9 +204,10 @@ void test_generic_set::test_insert(value_cont_typ } } +// treap version template class ContainerDefiner> void test_generic_set::test_insert_advanced -(value_cont_type& values, boost::intrusive::detail::true_type) +(value_cont_type& values, detail::true_type) { typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -207,28 +225,10 @@ void test_generic_set::test_insert_advanced } } - -template class ContainerDefiner> -void test_generic_set::test_insert_advanced -(value_cont_type& values) -{ - typedef typename ValueTraits::value_type value_type; - typedef typename ContainerDefiner - < value_type - , value_traits - , constant_time_size - >::type set_type; - typedef typename detail::remove_const::type Type; - typedef detail::bool_::value> enabler; - test_insert_advanced(values, enabler()); -} - - //test: insert, const_iterator, const_reverse_iterator, erase, s_iterator_to: template class ContainerDefiner> void test_generic_set::test_insert_advanced - ( value_cont_type& values - , boost::intrusive::detail::false_type) +(value_cont_type& values, detail::false_type) { typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -246,7 +246,6 @@ void test_generic_set::test_insert_advanced } } - //test: insert (seq-version), swap, erase (seq-version), size: template class ContainerDefiner> void test_generic_set::test_swap(value_cont_type& values) diff --git a/test/itestvalue.hpp b/test/itestvalue.hpp index 43ffc5e..b10a520 100644 --- a/test/itestvalue.hpp +++ b/test/itestvalue.hpp @@ -118,16 +118,15 @@ void swap_nodes(testvalue< Hooks, ConstantTimeSize >& lhs, testvalue< Hooks, Con lhs.swap_nodes(rhs); } -template -std::size_t hash_value(const testvalue &t) +template < typename Value_Type > +std::size_t hash_value(const Value_Type& t) { boost::hash hasher; - return hasher(t.value_); + return hasher((&t)->value_); } -template -bool priority_order( const testvalue &t1 - , const testvalue &t2) +template < typename Value_Type > +bool priority_order(const Value_Type& t1, const Value_Type& t2) { std::size_t hash1 = hash_value(t1); boost::hash_combine(hash1, &t1); diff --git a/test/list_test.cpp b/test/list_test.cpp index 06f8eb9..3e58f64 100644 --- a/test/list_test.cpp +++ b/test/list_test.cpp @@ -51,21 +51,23 @@ struct test_list typedef typename value_traits::value_type value_type; typedef typename list_type::node_algorithms node_algorithms; - static void test_all(Value_Container& values); - static void test_front_back(Value_Container& values); - static void test_sort(Value_Container& values); - static void test_merge(Value_Container& values); - static void test_remove_unique(Value_Container& values); - static void test_insert(Value_Container& values); - static void test_shift(Value_Container& values); - static void test_swap(Value_Container& values); - static void test_clone(Value_Container& values); - static void test_container_from_end(Value_Container& values); + static void test_all(Value_Container&); + static void test_front_back(Value_Container&); + static void test_sort(Value_Container&); + static void test_merge(Value_Container&); + static void test_remove_unique(Value_Container&); + static void test_insert(Value_Container&); + static void test_shift(Value_Container&); + static void test_swap(Value_Container&); + static void test_clone(Value_Container&); + static void test_container_from_end(Value_Container&, detail::true_type); + static void test_container_from_end(Value_Container&, detail::false_type) {} }; template < typename List_Type, typename Value_Container > void test_list< List_Type, Value_Container >::test_all(Value_Container& values) { +#ifdef PRINT_TESTS std::clog << "testing list with:\n" << " value_type = " << typeid(value_type).name() << "\n" << " sizeof(value_type) = " << sizeof(value_type) << "\n" @@ -77,6 +79,7 @@ void test_list< List_Type, Value_Container >::test_all(Value_Container& values) << " constant_time_size = " << list_type::constant_time_size << "\n" << " has_container_from_iterator = " << list_type::has_container_from_iterator << "\n" << " sizeof(list_type) = " << sizeof(list_type) << "\n"; +#endif { list_type list(values.begin(), values.end()); test::test_container(list); @@ -93,7 +96,7 @@ void test_list< List_Type, Value_Container >::test_all(Value_Container& values) test_shift(values); test_swap(values); test_clone(values); - test_container_from_end(values); + test_container_from_end(values, detail::bool_< List_Type::has_container_from_iterator >()); } //test: push_front, pop_front, push_back, pop_back, front, back, size, empty: @@ -338,33 +341,14 @@ void test_list< List_Type, Value_Container > } } -template < class List_Type, typename Value_Container, bool > -struct test_container_from_end_impl -{ - void operator () (Value_Container&) - { - std::clog << "skipping test_container_from_end\n"; - } -}; - template < class List_Type, typename Value_Container > -struct test_container_from_end_impl< List_Type, Value_Container, true > +void test_list< List_Type, Value_Container > + ::test_container_from_end(Value_Container& values, detail::true_type) { - void operator () (Value_Container& values) -{ - typedef List_Type list_type; list_type testlist1 (values.begin(), values.begin() + values.size()); BOOST_TEST (testlist1 == list_type::container_from_end_iterator(testlist1.end())); BOOST_TEST (testlist1 == list_type::container_from_end_iterator(testlist1.cend())); } -}; - -template < class List_Type, typename Value_Container > -void test_list< List_Type, Value_Container > - ::test_container_from_end(Value_Container& values) -{ - test_container_from_end_impl< List_Type, Value_Container, List_Type::has_container_from_iterator >()(values); -} template < class List_Type, typename Value_Container > void test_list< List_Type, Value_Container > @@ -546,15 +530,15 @@ struct test_main_template_bptr int main( int, char* [] ) { - // test combinations of (regular/smart)_ptr x (const/nonconst)_size x (default/non-default)_header_holder - // skip smart_ptr with non-default header_holder + // test (plain/smart pointers) x (nonconst/const size) x (void node allocator) test_main_template()(); - test_main_template, false, true>()(); + test_main_template, false, true>()(); test_main_template()(); - test_main_template, true, true>()(); + test_main_template, true, true>()(); + // test (plain pointers) x (nonconst/const size) x (standard node allocator) test_main_template()(); test_main_template()(); - // test bounded pointers with const/non_const size (always with non-default header_holder) + // test (bounded pointers) x ((nonconst/const size) x (special node allocator) test_main_template_bptr< true >()(); test_main_template_bptr< false >()(); diff --git a/test/multiset_test.cpp b/test/multiset_test.cpp index b96e206..2c65244 100644 --- a/test/multiset_test.cpp +++ b/test/multiset_test.cpp @@ -20,13 +20,13 @@ namespace boost { namespace intrusive { namespace test { #if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES) -template +template #else template #endif struct has_insert_before()(); test_main_template()(); - // test (bounded pointers) x ((nonconst/const size) x (special node allocator) + // test (bounded pointers) x (nonconst/const size) x (special node allocator) test_main_template_bptr< true >()(); test_main_template_bptr< false >()(); diff --git a/test/set_test.cpp b/test/set_test.cpp index 537335c..d633773 100644 --- a/test/set_test.cpp +++ b/test/set_test.cpp @@ -21,13 +21,13 @@ namespace boost { namespace intrusive { namespace test { #if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES) -template +template #else template #endif struct has_insert_before()(); test_main_template()(); - // test (bounded pointers) x ((nonconst/const size) x (special node allocator) + // test (bounded pointers) x (nonconst/const size) x (special node allocator) test_main_template_bptr< true >()(); test_main_template_bptr< false >()(); diff --git a/test/sg_multiset_test.cpp b/test/sg_multiset_test.cpp index 4eee56c..f2665f0 100644 --- a/test/sg_multiset_test.cpp +++ b/test/sg_multiset_test.cpp @@ -13,19 +13,20 @@ #include #include #include "itestvalue.hpp" +#include "bptr_value.hpp" #include "smart_ptr.hpp" #include "generic_multiset_test.hpp" namespace boost { namespace intrusive { namespace test { #if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES) -template +template #else template #endif struct has_rebalance +template #else template #endif struct has_insert_before struct GetContainer { - typedef boost::intrusive::sg_multiset + typedef boost::intrusive::sg_set < ValueType , Option1 , Option2 @@ -94,7 +95,7 @@ template< class ValueType > struct GetContainerFixedAlpha { - typedef boost::intrusive::sg_multiset + typedef boost::intrusive::sg_set < ValueType , Option1 , Option2 @@ -103,7 +104,101 @@ struct GetContainerFixedAlpha > type; }; -template +// container generator with void node allocator +template < bool Default_Holder > +struct GetContainer_With_Holder +{ +template< class ValueType + , class Option1 =void + , class Option2 =void + , class Option3 =void + > +struct GetContainer +{ + typedef boost::intrusive::sg_multiset + < ValueType + , Option1 + , Option2 + , Option3 + > type; +}; +}; + +// container generator with standard (non-void) node allocator +template <> +struct GetContainer_With_Holder< false > +{ +template< class ValueType + , class Option1 =void + , class Option2 =void + , class Option3 =void + > +struct GetContainer +{ + // extract node type through options->value_traits->node_traits->node + typedef typename pack_options< sgtree_defaults, Option1, Option2, Option3 >::type packed_options; + typedef typename detail::get_value_traits< ValueType, typename packed_options::proto_value_traits>::type value_traits; + typedef typename value_traits::node_traits::node node; + + typedef boost::intrusive::sg_multiset + < ValueType + , Option1 + , Option2 + , Option3 + , header_holder_type< pointer_holder< node > > + > type; +}; +}; + +// container generator with void node allocator +template < bool Default_Holder > +struct GetContainerFixedAlpha_With_Holder +{ +template< class ValueType + , class Option1 =void + , class Option2 =void + , class Option3 =void + > +struct GetContainerFixedAlpha +{ + typedef boost::intrusive::sg_multiset + < ValueType + , Option1 + , Option2 + , Option3 + > type; +}; +}; + +// container generator with standard (non-void) node allocator +template <> +struct GetContainerFixedAlpha_With_Holder< false > +{ +template< class ValueType + , class Option1 =void + , class Option2 =void + , class Option3 =void + > +struct GetContainerFixedAlpha +{ + // extract node type through options->value_traits->node_traits->node + typedef typename pack_options< sgtree_defaults, Option1, Option2, Option3 >::type packed_options; + typedef typename detail::get_value_traits< ValueType, typename packed_options::proto_value_traits>::type value_traits; + typedef typename value_traits::node_traits::node node; + + typedef boost::intrusive::sg_multiset + < ValueType + , Option1 + , Option2 + , Option3 + , boost::intrusive::floating_point + , header_holder_type< pointer_holder< node > > + > type; +}; +}; + + +template class test_main_template { public: @@ -116,7 +211,7 @@ class test_main_template < value_type , typename hooks::base_hook_type >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_multiset < typename detail::get_member_value_traits < value_type @@ -125,13 +220,13 @@ class test_main_template , &value_type::node_ > >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_multiset < typename detail::get_base_value_traits < value_type , typename hooks::base_hook_type >::type - , GetContainerFixedAlpha + , GetContainerFixedAlpha_With_Holder< Default_Holder >::template GetContainerFixedAlpha >::test_all(); test::test_generic_multiset < typename detail::get_member_value_traits < value_type @@ -140,22 +235,73 @@ class test_main_template , &value_type::node_ > >::type - , GetContainerFixedAlpha + , GetContainerFixedAlpha_With_Holder< Default_Holder >::template GetContainerFixedAlpha >::test_all(); test::test_generic_multiset < nonhook_node_member_value_traits< value_type, typename hooks::nonhook_node_member_type, &value_type::nhn_member_, safe_link >, - GetContainerFixedAlpha + GetContainerFixedAlpha_With_Holder< Default_Holder >::template GetContainerFixedAlpha >::test_all(); return 0; } }; +// container generator which ignores further parametrization, except for compare option +template < typename Value_Traits, bool Constant_Time_Size, typename Header_Holder > +struct Get_Preset_Container +{ + template < class + , class Option1 = void + , class Option2 = void + , class Option3 = void + > + struct GetContainer + { + // ignore further paramatrization except for the compare option + // notably ignore the size option (use preset) + typedef typename pack_options< sgtree_defaults, Option1, Option2, Option3 >::type packed_options; + typedef typename packed_options::compare compare_option; + + typedef boost::intrusive::sg_multiset< typename Value_Traits::value_type, + value_traits< Value_Traits >, + constant_time_size< Constant_Time_Size >, + compare< compare_option >, + header_holder_type< Header_Holder > + > type; + }; +}; + +template < bool Constant_Time_Size > +struct test_main_template_bptr +{ + void operator () () + { + typedef BPtr_Value value_type; + typedef BPtr_Value_Traits< Tree_BPtr_Node_Traits > value_traits; + typedef Bounded_Allocator< value_type > allocator_type; + + allocator_type::init(); + test::test_generic_multiset< value_traits, + Get_Preset_Container< value_traits, Constant_Time_Size, + Bounded_Pointer_Holder< value_type > >::template GetContainer + >::test_all(); + assert(allocator_type::is_clear()); + allocator_type::destroy(); + } +}; + int main( int, char* [] ) { - test_main_template()(); - test_main_template >()(); + // test (plain/smart pointers) x (const size) x (void node allocator) + test_main_template()(); + test_main_template, true >()(); + // test (plain pointers) x (const size) x (standard node allocator) + test_main_template()(); + // test (bounded pointers) x (nonconst/const size) x (special node allocator) + test_main_template_bptr< true >()(); + test_main_template_bptr< false >()(); + return boost::report_errors(); } diff --git a/test/sg_set_test.cpp b/test/sg_set_test.cpp index 00926e1..ad5a9db 100644 --- a/test/sg_set_test.cpp +++ b/test/sg_set_test.cpp @@ -12,19 +12,20 @@ #include #include #include "itestvalue.hpp" +#include "bptr_value.hpp" #include "smart_ptr.hpp" #include "generic_set_test.hpp" namespace boost { namespace intrusive { namespace test { #if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES) -template +template #else template #endif struct has_rebalance +template #else template #endif struct has_insert_before type; }; -template +// container generator with void node allocator +template < bool Default_Holder > +struct GetContainer_With_Holder +{ +template< class ValueType + , class Option1 =void + , class Option2 =void + , class Option3 =void + > +struct GetContainer +{ + typedef boost::intrusive::sg_set + < ValueType + , Option1 + , Option2 + , Option3 + > type; +}; +}; + +// container generator with standard (non-void) node allocator +template <> +struct GetContainer_With_Holder< false > +{ +template< class ValueType + , class Option1 =void + , class Option2 =void + , class Option3 =void + > +struct GetContainer +{ + // extract node type through options->value_traits->node_traits->node + typedef typename pack_options< sgtree_defaults, Option1, Option2, Option3 >::type packed_options; + typedef typename detail::get_value_traits< ValueType, typename packed_options::proto_value_traits>::type value_traits; + typedef typename value_traits::node_traits::node node; + + typedef boost::intrusive::sg_set + < ValueType + , Option1 + , Option2 + , Option3 + , header_holder_type< pointer_holder< node > > + > type; +}; +}; + +// container generator with void node allocator +template < bool Default_Holder > +struct GetContainerFixedAlpha_With_Holder +{ +template< class ValueType + , class Option1 =void + , class Option2 =void + , class Option3 =void + > +struct GetContainerFixedAlpha +{ + typedef boost::intrusive::sg_set + < ValueType + , Option1 + , Option2 + , Option3 + > type; +}; +}; + +// container generator with standard (non-void) node allocator +template <> +struct GetContainerFixedAlpha_With_Holder< false > +{ +template< class ValueType + , class Option1 =void + , class Option2 =void + , class Option3 =void + > +struct GetContainerFixedAlpha +{ + // extract node type through options->value_traits->node_traits->node + typedef typename pack_options< sgtree_defaults, Option1, Option2, Option3 >::type packed_options; + typedef typename detail::get_value_traits< ValueType, typename packed_options::proto_value_traits>::type value_traits; + typedef typename value_traits::node_traits::node node; + + typedef boost::intrusive::sg_set + < ValueType + , Option1 + , Option2 + , Option3 + , boost::intrusive::floating_point + , header_holder_type< pointer_holder< node > > + > type; +}; +}; + +template class test_main_template { public: @@ -114,7 +208,7 @@ class test_main_template < value_type , typename hooks::base_hook_type >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_set < typename detail::get_member_value_traits < value_type @@ -123,14 +217,14 @@ class test_main_template , &value_type::node_ > >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_set < typename detail::get_base_value_traits < value_type , typename hooks::base_hook_type >::type - , GetContainerFixedAlpha + , GetContainerFixedAlpha_With_Holder< Default_Holder >::template GetContainerFixedAlpha >::test_all(); test::test_generic_set < typename detail::get_member_value_traits < value_type @@ -139,23 +233,74 @@ class test_main_template , &value_type::node_ > >::type - , GetContainerFixedAlpha + , GetContainerFixedAlpha_With_Holder< Default_Holder >::template GetContainerFixedAlpha >::test_all(); test::test_generic_set < nonhook_node_member_value_traits< value_type, typename hooks::nonhook_node_member_type, &value_type::nhn_member_, safe_link >, - GetContainerFixedAlpha + GetContainerFixedAlpha_With_Holder< Default_Holder >::template GetContainerFixedAlpha >::test_all(); return 0; } }; +// container generator which ignores further parametrization, except for compare option +template < typename Value_Traits, bool Constant_Time_Size, typename Header_Holder > +struct Get_Preset_Container +{ + template < class + , class Option1 = void + , class Option2 = void + , class Option3 = void + > + struct GetContainer + { + // ignore further paramatrization except for the compare option + // notably ignore the size option (use preset) + typedef typename pack_options< sgtree_defaults, Option1, Option2, Option3 >::type packed_options; + typedef typename packed_options::compare compare_option; + + typedef boost::intrusive::sg_set< typename Value_Traits::value_type, + value_traits< Value_Traits >, + constant_time_size< Constant_Time_Size >, + compare< compare_option >, + header_holder_type< Header_Holder > + > type; + }; +}; + +template < bool Constant_Time_Size > +struct test_main_template_bptr +{ + void operator () () + { + typedef BPtr_Value value_type; + typedef BPtr_Value_Traits< Tree_BPtr_Node_Traits > value_traits; + typedef Bounded_Allocator< value_type > allocator_type; + + allocator_type::init(); + test::test_generic_set< value_traits, + Get_Preset_Container< value_traits, Constant_Time_Size, + Bounded_Pointer_Holder< value_type > >::template GetContainer + >::test_all(); + assert(allocator_type::is_clear()); + allocator_type::destroy(); + } +}; + int main( int, char* [] ) { - test_main_template()(); - test_main_template >()(); + // test (plain/smart pointers) x (const size) x (void node allocator) + test_main_template()(); + test_main_template, true >()(); + // test (plain pointers) x (const size) x (standard node allocator) + test_main_template()(); + // test (bounded pointers) x (nonconst/const size) x (special node allocator) + test_main_template_bptr< true >()(); + test_main_template_bptr< false >()(); + return boost::report_errors(); } #include diff --git a/test/slist_test.cpp b/test/slist_test.cpp index e6c544d..457b71d 100644 --- a/test/slist_test.cpp +++ b/test/slist_test.cpp @@ -50,26 +50,27 @@ struct test_slist typedef typename value_traits::value_type value_type; typedef typename list_type::node_algorithms node_algorithms; - static void test_all(Value_Container& values); - static void test_front(Value_Container& values); - static void test_back(Value_Container& values, detail::bool_); - static void test_back(Value_Container& values, detail::bool_); - static void test_sort(Value_Container& values); - static void test_merge(Value_Container& values); - static void test_remove_unique(Value_Container& values); - static void test_insert(Value_Container& values); - static void test_shift(Value_Container& values); - static void test_swap(Value_Container& values); - static void test_slow_insert(Value_Container& values); - static void test_clone(Value_Container& values); - static void test_container_from_end(Value_Container &, detail::bool_){} - static void test_container_from_end(Value_Container &values, detail::bool_); + static void test_all(Value_Container&); + static void test_front(Value_Container&); + static void test_back(Value_Container&, detail::true_type); + static void test_back(Value_Container&, detail::false_type) {} + static void test_sort(Value_Container&); + static void test_merge(Value_Container&); + static void test_remove_unique(Value_Container&); + static void test_insert(Value_Container&); + static void test_shift(Value_Container&); + static void test_swap(Value_Container&); + static void test_slow_insert(Value_Container&); + static void test_clone(Value_Container&); + static void test_container_from_end(Value_Container&, detail::true_type); + static void test_container_from_end(Value_Container&, detail::false_type) {} }; template < typename List_Type, typename Value_Container > void test_slist< List_Type, Value_Container > ::test_all (Value_Container& values) { +#ifdef PRINT_TESTS std::clog << "testing slist with:\n" << " value_type = " << typeid(value_type).name() << "\n" << " sizeof(value_type) = " << sizeof(value_type) << "\n" @@ -83,6 +84,7 @@ void test_slist< List_Type, Value_Container > << " cache_last = " << list_type::cache_last << "\n" << " has_container_from_iterator = " << list_type::has_container_from_iterator << "\n" << " sizeof(list_type) = " << sizeof(list_type) << "\n"; +#endif { list_type list(values.begin(), values.end()); test::test_container(list); @@ -91,7 +93,7 @@ void test_slist< List_Type, Value_Container > test::test_sequence_container(list, values); } test_front(values); - test_back(values, detail::bool_()); + test_back(values, detail::bool_< list_type::cache_last >()); test_sort(values); test_merge (values); test_remove_unique(values); @@ -100,7 +102,7 @@ void test_slist< List_Type, Value_Container > test_slow_insert (values); test_swap(values); test_clone(values); - test_container_from_end(values, detail::bool_()); + test_container_from_end(values, detail::bool_< not list_type::linear and list_type::has_container_from_iterator >()); } //test: push_front, pop_front, front, size, empty: @@ -130,7 +132,7 @@ void test_slist< List_Type, Value_Container > //test: push_front, pop_front, front, size, empty: template < typename List_Type, typename Value_Container > void test_slist< List_Type, Value_Container > - ::test_back(Value_Container& values, detail::bool_) + ::test_back(Value_Container& values, detail::true_type) { list_type testlist; BOOST_TEST (testlist.empty()); @@ -145,13 +147,6 @@ void test_slist< List_Type, Value_Container > BOOST_TEST (&testlist.back() == &values[1]); } -//test: push_front, pop_front, front, size, empty: -template < typename List_Type, typename Value_Container > -void test_slist< List_Type, Value_Container > - ::test_back(Value_Container&, detail::bool_) -{} - - //test: merge due to error in merge implementation: template < typename List_Type, typename Value_Container > void test_slist< List_Type, Value_Container > @@ -440,10 +435,8 @@ void test_slist< List_Type, Value_Container > template < typename List_Type, typename Value_Container > void test_slist< List_Type, Value_Container > - ::test_container_from_end(Value_Container& values - ,detail::bool_) + ::test_container_from_end(Value_Container& values, detail::true_type) { - list_type testlist1 (values.begin(), values.begin() + values.size()); BOOST_TEST (testlist1 == list_type::container_from_end_iterator(testlist1.end())); BOOST_TEST (testlist1 == list_type::container_from_end_iterator(testlist1.cend())); @@ -782,18 +775,19 @@ struct test_main_template_bptr int main(int, char* []) { - // test combinations of (regular/smart)_ptr x (const/nonconst)_size x (default/non-default)_header_holder - // skip smart_ptr with non-default header_holder + // test (plain/smart pointers) x (nonconst/const size) x (void node allocator) test_main_template()(); - test_main_template, false, true>()(); + test_main_template, false, true>()(); test_main_template()(); - test_main_template, true, true>()(); + test_main_template, true, true>()(); + // test (plain pointers) x (nonconst/const size) x (standard node allocator) test_main_template()(); test_main_template()(); - // test bounded pointers with const/non_const size (always with non-default header_holder) + // test (bounded pointers) x ((nonconst/const size) x (special node allocator) test_main_template_bptr< true >()(); test_main_template_bptr< false >()(); + return boost::report_errors(); } #include diff --git a/test/splay_multiset_test.cpp b/test/splay_multiset_test.cpp index c22706e..9c2bc13 100644 --- a/test/splay_multiset_test.cpp +++ b/test/splay_multiset_test.cpp @@ -14,19 +14,20 @@ #include #include #include "itestvalue.hpp" +#include "bptr_value.hpp" #include "smart_ptr.hpp" #include "generic_multiset_test.hpp" namespace boost { namespace intrusive { namespace test { #if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES) -template +template #else template #endif struct has_splay +template #else template #endif struct has_rebalance +template #else template #endif struct has_const_searches nonhook_node_member_type; }; +// container generator with void node allocator +template < bool Default_Holder > +struct GetContainer_With_Holder +{ template< class ValueType , class Option1 =void , class Option2 =void @@ -105,8 +110,35 @@ struct GetContainer , Option3 > type; }; +}; -template +// container generator with standard (non-void) node allocator +template <> +struct GetContainer_With_Holder< false > +{ +template< class ValueType + , class Option1 =void + , class Option2 =void + , class Option3 =void + > +struct GetContainer +{ + // extract node type through options->value_traits->node_traits->node + typedef typename pack_options< splaytree_defaults, Option1, Option2, Option3 >::type packed_options; + typedef typename detail::get_value_traits< ValueType, typename packed_options::proto_value_traits>::type value_traits; + typedef typename value_traits::node_traits::node node; + + typedef boost::intrusive::splay_multiset + < ValueType + , Option1 + , Option2 + , Option3 + , header_holder_type< pointer_holder< node > > + > type; +}; +}; + +template class test_main_template { public: @@ -119,7 +151,7 @@ class test_main_template < value_type , typename hooks::base_hook_type >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_multiset < typename detail::get_member_value_traits < value_type @@ -128,22 +160,22 @@ class test_main_template , &value_type::node_ > >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_multiset < nonhook_node_member_value_traits< value_type, typename hooks::nonhook_node_member_type, &value_type::nhn_member_, safe_link >, - GetContainer + GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); return 0; } }; -template -class test_main_template +template +class test_main_template { public: int operator()() @@ -155,7 +187,7 @@ class test_main_template < value_type , typename hooks::base_hook_type >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_multiset < typename detail::get_member_value_traits @@ -165,14 +197,14 @@ class test_main_template , &value_type::node_ > >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_multiset < typename detail::get_base_value_traits < value_type , typename hooks::auto_base_hook_type >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_multiset < typename detail::get_member_value_traits @@ -182,17 +214,69 @@ class test_main_template , &value_type::auto_node_ > >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); return 0; } }; +// container generator which ignores further parametrization, except for compare option +template < typename Value_Traits, bool Constant_Time_Size, typename Header_Holder > +struct Get_Preset_Container +{ + template < class + , class Option1 = void + , class Option2 = void + , class Option3 = void + > + struct GetContainer + { + // ignore further paramatrization except for the compare option + // notably ignore the size option (use preset) + typedef typename pack_options< splaytree_defaults, Option1, Option2, Option3 >::type packed_options; + typedef typename packed_options::compare compare_option; + + typedef boost::intrusive::splay_multiset< typename Value_Traits::value_type, + value_traits< Value_Traits >, + constant_time_size< Constant_Time_Size >, + compare< compare_option >, + header_holder_type< Header_Holder > + > type; + }; +}; + +template < bool Constant_Time_Size > +struct test_main_template_bptr +{ + void operator () () + { + typedef BPtr_Value value_type; + typedef BPtr_Value_Traits< Tree_BPtr_Node_Traits > value_traits; + typedef Bounded_Allocator< value_type > allocator_type; + + allocator_type::init(); + test::test_generic_multiset< value_traits, + Get_Preset_Container< value_traits, Constant_Time_Size, + Bounded_Pointer_Holder< value_type > >::template GetContainer + >::test_all(); + assert(allocator_type::is_clear()); + allocator_type::destroy(); + } +}; + int main( int, char* [] ) { - test_main_template()(); - test_main_template, false>()(); - test_main_template()(); - test_main_template, true>()(); + // test (plain/smart pointers) x (nonconst/const size) x (void node allocator) + test_main_template()(); + test_main_template, false, true>()(); + test_main_template()(); + test_main_template, true, true>()(); + // test (plain pointers) x (nonconst/const size) x (standard node allocator) + test_main_template()(); + test_main_template()(); + // test (bounded pointers) x (nonconst/const size) x (special node allocator) + test_main_template_bptr< true >()(); + test_main_template_bptr< false >()(); + return boost::report_errors(); } diff --git a/test/splay_set_test.cpp b/test/splay_set_test.cpp index 7fc3fce..9ac14fe 100644 --- a/test/splay_set_test.cpp +++ b/test/splay_set_test.cpp @@ -12,19 +12,20 @@ #include #include #include "itestvalue.hpp" +#include "bptr_value.hpp" #include "smart_ptr.hpp" #include "generic_set_test.hpp" namespace boost { namespace intrusive { namespace test { #if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES) -template +template #else template #endif struct has_splay +template #else template #endif struct has_rebalance +template #else template #endif struct has_const_searches nonhook_node_member_type; }; +// container generator with void node allocator +template < bool Default_Holder > +struct GetContainer_With_Holder +{ template< class ValueType , class Option1 =void , class Option2 =void @@ -102,8 +107,35 @@ struct GetContainer , Option3 > type; }; +}; -template +// container generator with standard (non-void) node allocator +template <> +struct GetContainer_With_Holder< false > +{ +template< class ValueType + , class Option1 =void + , class Option2 =void + , class Option3 =void + > +struct GetContainer +{ + // extract node type through options->value_traits->node_traits->node + typedef typename pack_options< splaytree_defaults, Option1, Option2, Option3 >::type packed_options; + typedef typename detail::get_value_traits< ValueType, typename packed_options::proto_value_traits>::type value_traits; + typedef typename value_traits::node_traits::node node; + + typedef boost::intrusive::splay_set + < ValueType + , Option1 + , Option2 + , Option3 + , header_holder_type< pointer_holder< node > > + > type; +}; +}; + +template class test_main_template { public: @@ -116,7 +148,7 @@ class test_main_template < value_type , typename hooks::base_hook_type >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_set < typename detail::get_member_value_traits < value_type @@ -125,21 +157,21 @@ class test_main_template , &value_type::node_ > >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_set < nonhook_node_member_value_traits< value_type, typename hooks::nonhook_node_member_type, &value_type::nhn_member_, safe_link >, - GetContainer + GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); return 0; } }; -template -class test_main_template +template +class test_main_template { public: int operator()() @@ -151,7 +183,7 @@ class test_main_template < value_type , typename hooks::base_hook_type >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_set < typename detail::get_member_value_traits @@ -161,14 +193,14 @@ class test_main_template , &value_type::node_ > >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_set < typename detail::get_base_value_traits < value_type , typename hooks::auto_base_hook_type >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_set < typename detail::get_member_value_traits @@ -178,19 +210,71 @@ class test_main_template , &value_type::auto_node_ > >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); return 0; } }; +// container generator which ignores further parametrization, except for compare option +template < typename Value_Traits, bool Constant_Time_Size, typename Header_Holder > +struct Get_Preset_Container +{ + template < class + , class Option1 = void + , class Option2 = void + , class Option3 = void + > + struct GetContainer + { + // ignore further paramatrization except for the compare option + // notably ignore the size option (use preset) + typedef typename pack_options< splaytree_defaults, Option1, Option2, Option3 >::type packed_options; + typedef typename packed_options::compare compare_option; + + typedef boost::intrusive::splay_set< typename Value_Traits::value_type, + value_traits< Value_Traits >, + constant_time_size< Constant_Time_Size >, + compare< compare_option >, + header_holder_type< Header_Holder > + > type; + }; +}; + +template < bool Constant_Time_Size > +struct test_main_template_bptr +{ + void operator () () + { + typedef BPtr_Value value_type; + typedef BPtr_Value_Traits< Tree_BPtr_Node_Traits > value_traits; + typedef Bounded_Allocator< value_type > allocator_type; + + allocator_type::init(); + test::test_generic_set< value_traits, + Get_Preset_Container< value_traits, Constant_Time_Size, + Bounded_Pointer_Holder< value_type > >::template GetContainer + >::test_all(); + assert(allocator_type::is_clear()); + allocator_type::destroy(); + } +}; + int main( int, char* [] ) { - test_main_template()(); - test_main_template, false>()(); - test_main_template()(); - test_main_template, true>()(); + // test (plain/smart pointers) x (nonconst/const size) x (void node allocator) + test_main_template()(); + test_main_template, false, true>()(); + test_main_template()(); + test_main_template, true, true>()(); + // test (plain pointers) x (nonconst/const size) x (standard node allocator) + test_main_template()(); + test_main_template()(); + // test (bounded pointers) x (nonconst/const size) x (special node allocator) + test_main_template_bptr< true >()(); + test_main_template_bptr< false >()(); + return boost::report_errors(); } #include diff --git a/test/treap_multiset_test.cpp b/test/treap_multiset_test.cpp index 7918082..0b68455 100644 --- a/test/treap_multiset_test.cpp +++ b/test/treap_multiset_test.cpp @@ -14,19 +14,20 @@ #include #include #include "itestvalue.hpp" +#include "bptr_value.hpp" #include "smart_ptr.hpp" #include "generic_multiset_test.hpp" namespace boost { namespace intrusive { namespace test { #if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES) -template +template #else template #endif struct has_insert_before nonhook_node_member_type; }; +// container generator with void node allocator +template < bool Default_Holder > +struct GetContainer_With_Holder +{ template< class ValueType , class Option1 =void , class Option2 =void @@ -71,8 +76,35 @@ struct GetContainer , Option3 > type; }; +}; -template +// container generator with standard (non-void) node allocator +template <> +struct GetContainer_With_Holder< false > +{ +template< class ValueType + , class Option1 =void + , class Option2 =void + , class Option3 =void + > +struct GetContainer +{ + // extract node type through options->value_traits->node_traits->node + typedef typename pack_options< treap_defaults, Option1, Option2, Option3 >::type packed_options; + typedef typename detail::get_value_traits< ValueType, typename packed_options::proto_value_traits>::type value_traits; + typedef typename value_traits::node_traits::node node; + + typedef boost::intrusive::treap_multiset + < ValueType + , Option1 + , Option2 + , Option3 + , header_holder_type< pointer_holder< node > > + > type; +}; +}; + +template class test_main_template { public: @@ -85,7 +117,7 @@ class test_main_template < value_type , typename hooks::base_hook_type >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_multiset < typename detail::get_member_value_traits < value_type @@ -94,21 +126,21 @@ class test_main_template , &value_type::node_ > >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_multiset < nonhook_node_member_value_traits< value_type, typename hooks::nonhook_node_member_type, &value_type::nhn_member_, safe_link >, - GetContainer + GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); return 0; } }; -template -class test_main_template +template +class test_main_template { public: int operator()() @@ -120,7 +152,7 @@ class test_main_template < value_type , typename hooks::base_hook_type >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_multiset < typename detail::get_member_value_traits @@ -130,14 +162,14 @@ class test_main_template , &value_type::node_ > >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_multiset < typename detail::get_base_value_traits < value_type , typename hooks::auto_base_hook_type >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_multiset < typename detail::get_member_value_traits @@ -147,18 +179,70 @@ class test_main_template , &value_type::auto_node_ > >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); return 0; } }; +// container generator which ignores further parametrization, except for compare option +template < typename Value_Traits, bool Constant_Time_Size, typename Header_Holder > +struct Get_Preset_Container +{ + template < class + , class Option1 = void + , class Option2 = void + , class Option3 = void + > + struct GetContainer + { + // ignore further paramatrization except for the compare option + // notably ignore the size option (use preset) + typedef typename pack_options< treap_defaults, Option1, Option2, Option3 >::type packed_options; + typedef typename packed_options::compare compare_option; + + typedef boost::intrusive::treap_multiset< typename Value_Traits::value_type, + value_traits< Value_Traits >, + constant_time_size< Constant_Time_Size >, + compare< compare_option >, + header_holder_type< Header_Holder > + > type; + }; +}; + +template < bool Constant_Time_Size > +struct test_main_template_bptr +{ + void operator () () + { + typedef BPtr_Value value_type; + typedef BPtr_Value_Traits< Tree_BPtr_Node_Traits > value_traits; + typedef Bounded_Allocator< value_type > allocator_type; + + allocator_type::init(); + test::test_generic_multiset< value_traits, + Get_Preset_Container< value_traits, Constant_Time_Size, + Bounded_Pointer_Holder< value_type > >::template GetContainer + >::test_all(); + assert(allocator_type::is_clear()); + allocator_type::destroy(); + } +}; + int main( int, char* [] ) { - test_main_template()(); - test_main_template, false>()(); - test_main_template()(); - test_main_template, true>()(); + // test (plain/smart pointers) x (nonconst/const size) x (void node allocator) + test_main_template()(); + test_main_template, false, true>()(); + test_main_template()(); + test_main_template, true, true>()(); + // test (plain pointers) x (nonconst/const size) x (standard node allocator) + test_main_template()(); + test_main_template()(); + // test (bounded pointers) x (nonconst/const size) x (special node allocator) + test_main_template_bptr< true >()(); + test_main_template_bptr< false >()(); + return boost::report_errors(); } diff --git a/test/treap_set_test.cpp b/test/treap_set_test.cpp index 8d1cd49..3edd829 100644 --- a/test/treap_set_test.cpp +++ b/test/treap_set_test.cpp @@ -12,19 +12,20 @@ #include #include #include "itestvalue.hpp" +#include "bptr_value.hpp" #include "smart_ptr.hpp" #include "generic_set_test.hpp" namespace boost { namespace intrusive { namespace test { #if !defined (BOOST_INTRUSIVE_VARIADIC_TEMPLATES) -template +template #else template #endif struct has_insert_before +template #else template #endif struct is_treap nonhook_node_member_type; }; +// container generator with void node allocator +template < bool Default_Holder > +struct GetContainer_With_Holder +{ template< class ValueType , class Option1 =void , class Option2 =void @@ -86,8 +91,35 @@ struct GetContainer , Option3 > type; }; +}; -template +// container generator with standard (non-void) node allocator +template <> +struct GetContainer_With_Holder< false > +{ +template< class ValueType + , class Option1 =void + , class Option2 =void + , class Option3 =void + > +struct GetContainer +{ + // extract node type through options->value_traits->node_traits->node + typedef typename pack_options< treap_defaults, Option1, Option2, Option3 >::type packed_options; + typedef typename detail::get_value_traits< ValueType, typename packed_options::proto_value_traits>::type value_traits; + typedef typename value_traits::node_traits::node node; + + typedef boost::intrusive::treap_set + < ValueType + , Option1 + , Option2 + , Option3 + , header_holder_type< pointer_holder< node > > + > type; +}; +}; + +template class test_main_template { public: @@ -100,7 +132,7 @@ class test_main_template < value_type , typename hooks::base_hook_type >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_set < typename detail::get_member_value_traits < value_type @@ -109,21 +141,21 @@ class test_main_template , &value_type::node_ > >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_set < nonhook_node_member_value_traits< value_type, typename hooks::nonhook_node_member_type, &value_type::nhn_member_, safe_link >, - GetContainer + GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); return 0; } }; -template -class test_main_template +template +class test_main_template { public: int operator()() @@ -135,7 +167,7 @@ class test_main_template < value_type , typename hooks::base_hook_type >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_set < typename detail::get_member_value_traits @@ -145,14 +177,14 @@ class test_main_template , &value_type::node_ > >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_set < typename detail::get_base_value_traits < value_type , typename hooks::auto_base_hook_type >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); test::test_generic_set < typename detail::get_member_value_traits @@ -162,19 +194,71 @@ class test_main_template , &value_type::auto_node_ > >::type - , GetContainer + , GetContainer_With_Holder< Default_Holder >::template GetContainer >::test_all(); return 0; } }; +// container generator which ignores further parametrization, except for compare option +template < typename Value_Traits, bool Constant_Time_Size, typename Header_Holder > +struct Get_Preset_Container +{ + template < class + , class Option1 = void + , class Option2 = void + , class Option3 = void + > + struct GetContainer + { + // ignore further paramatrization except for the compare option + // notably ignore the size option (use preset) + typedef typename pack_options< treap_defaults, Option1, Option2, Option3 >::type packed_options; + typedef typename packed_options::compare compare_option; + + typedef boost::intrusive::treap_set< typename Value_Traits::value_type, + value_traits< Value_Traits >, + constant_time_size< Constant_Time_Size >, + compare< compare_option >, + header_holder_type< Header_Holder > + > type; + }; +}; + +template < bool Constant_Time_Size > +struct test_main_template_bptr +{ + void operator () () + { + typedef BPtr_Value value_type; + typedef BPtr_Value_Traits< Tree_BPtr_Node_Traits > value_traits; + typedef Bounded_Allocator< value_type > allocator_type; + + allocator_type::init(); + test::test_generic_set< value_traits, + Get_Preset_Container< value_traits, Constant_Time_Size, + Bounded_Pointer_Holder< value_type > >::template GetContainer + >::test_all(); + assert(allocator_type::is_clear()); + allocator_type::destroy(); + } +}; + int main( int, char* [] ) { - test_main_template()(); - test_main_template, false>()(); - test_main_template()(); - test_main_template, true>()(); + // test (plain/smart pointers) x (nonconst/const size) x (void node allocator) + test_main_template()(); + test_main_template, false, true>()(); + test_main_template()(); + test_main_template, true, true>()(); + // test (plain pointers) x (nonconst/const size) x (standard node allocator) + test_main_template()(); + test_main_template()(); + // test (bounded pointers) x (nonconst/const size) x (special node allocator) + test_main_template_bptr< true >()(); + test_main_template_bptr< false >()(); + return boost::report_errors(); }