From 60c6f40336f5a9d918c5461f816997c2bbaebbcd Mon Sep 17 00:00:00 2001 From: Matei David Date: Mon, 28 Apr 2014 20:08:24 -0400 Subject: [PATCH] added tests for intrusive hooks not derived from the default hooks --- test/Makefile | 21 +++++++ test/avl_multiset_test.cpp | 10 +++ test/avl_set_test.cpp | 10 +++ test/itestvalue.hpp | 7 ++- test/list_test.cpp | 9 +++ test/multiset_test.cpp | 10 +++ test/nonhook_node.hpp | 101 +++++++++++++++++++++++++++++++ test/set_test.cpp | 10 +++ test/sg_multiset_test.cpp | 10 +++ test/sg_set_test.cpp | 10 +++ test/slist_test.cpp | 11 ++++ test/splay_multiset_test.cpp | 11 ++++ test/splay_set_test.cpp | 10 +++ test/treap_multiset_test.cpp | 10 +++ test/treap_set_test.cpp | 10 +++ test/unordered_multiset_test.cpp | 12 ++++ test/unordered_set_test.cpp | 12 ++++ 17 files changed, 273 insertions(+), 1 deletion(-) create mode 100644 test/Makefile create mode 100644 test/nonhook_node.hpp diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000..a889a98 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,21 @@ +SRC_LIST = $(wildcard *.cpp) +TGT_LIST = $(basename $(SRC_LIST)) + +CPPFLAGS = -I${BOOST_INTRUSIVE}/include -I${BOOST}/include +CXXFLAGS = -Wall -Wextra -pedantic -Wno-ignored-qualifiers -Wno-long-long -g3 -O0 + +.PHONY: all run clean + +all: $(TGT_LIST) + +%: %.cpp + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $< -o $@ + +run: $(TGT_LIST) + for f in $^; do \ + echo "===== running: $$f"; \ + ./$$f || break; \ + done + +clean: + rm -f $(TGT_LIST) diff --git a/test/avl_multiset_test.cpp b/test/avl_multiset_test.cpp index ecad395..be6d3c2 100644 --- a/test/avl_multiset_test.cpp +++ b/test/avl_multiset_test.cpp @@ -55,6 +55,9 @@ struct hooks typedef avl_set_member_hook < link_mode , void_pointer > auto_member_hook_type; + typedef nonhook_node_member< avltree_node_traits, + avltree_algorithms + > nonhook_node_member_type; }; template< class ValueType @@ -96,6 +99,13 @@ class test_main_template >::type , 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 + >::test_all(); return 0; } }; diff --git a/test/avl_set_test.cpp b/test/avl_set_test.cpp index 8c04e46..36d0731 100644 --- a/test/avl_set_test.cpp +++ b/test/avl_set_test.cpp @@ -55,6 +55,9 @@ struct hooks typedef avl_set_member_hook < link_mode , void_pointer > auto_member_hook_type; + typedef nonhook_node_member< avltree_node_traits, + avltree_algorithms + > nonhook_node_member_type; }; template< class ValueType @@ -96,6 +99,13 @@ class test_main_template >::type , 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 + >::test_all(); return 0; } }; diff --git a/test/itestvalue.hpp b/test/itestvalue.hpp index 91bd182..4168501 100644 --- a/test/itestvalue.hpp +++ b/test/itestvalue.hpp @@ -16,6 +16,7 @@ #include #include #include +#include "nonhook_node.hpp" namespace boost{ namespace intrusive{ @@ -33,6 +34,7 @@ struct testvalue { typename Hooks::member_hook_type node_; typename Hooks::auto_member_hook_type auto_node_; + typename Hooks::nonhook_node_member_type nhn_member_; int value_; static const bool constant_time_size = ConstantTimeSize; @@ -56,6 +58,7 @@ struct testvalue Hooks::auto_base_hook_type::operator=(static_cast(src)); this->node_ = src.node_; this->auto_node_ = src.auto_node_; + this->nhn_member_ = src.nhn_member_; value_ = src.value_; return *this; } @@ -66,6 +69,7 @@ struct testvalue Hooks::auto_base_hook_type::swap_nodes(static_cast(other)); node_.swap_nodes(other.node_); auto_node_.swap_nodes(other.auto_node_); + nhn_member_.swap_nodes(other.nhn_member_); } bool is_linked() const @@ -73,7 +77,8 @@ struct testvalue return Hooks::base_hook_type::is_linked() || Hooks::auto_base_hook_type::is_linked() || node_.is_linked() || - auto_node_.is_linked(); + auto_node_.is_linked() || + nhn_member_.is_linked(); } ~testvalue() diff --git a/test/list_test.cpp b/test/list_test.cpp index 54d3061..7301dcf 100644 --- a/test/list_test.cpp +++ b/test/list_test.cpp @@ -34,6 +34,9 @@ struct hooks typedef list_member_hook, tag > member_hook_type; typedef list_member_hook< link_mode , void_pointer > auto_member_hook_type; + typedef nonhook_node_member< list_node_traits< VoidPointer >, + circular_list_algorithms + > nonhook_node_member_type; }; template @@ -436,6 +439,12 @@ class test_main_template > >::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); return 0; } }; diff --git a/test/multiset_test.cpp b/test/multiset_test.cpp index ba503a2..dd52cfe 100644 --- a/test/multiset_test.cpp +++ b/test/multiset_test.cpp @@ -54,6 +54,9 @@ struct hooks , optimize_size > member_hook_type; typedef set_member_hook , void_pointer > auto_member_hook_type; + typedef nonhook_node_member< rbtree_node_traits , + rbtree_algorithms + > nonhook_node_member_type; }; template< class ValueType @@ -95,6 +98,13 @@ class test_main_template >::type , 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 + >::test_all(); return 0; } }; diff --git a/test/nonhook_node.hpp b/test/nonhook_node.hpp new file mode 100644 index 0000000..ef5494b --- /dev/null +++ b/test/nonhook_node.hpp @@ -0,0 +1,101 @@ +#ifndef BOOST_INTRUSIVE_DETAIL_NONHOOK_NODE_HPP +#define BOOST_INTRUSIVE_DETAIL_NONHOOK_NODE_HPP + +#include +#include +#include +#include + + +namespace boost{ +namespace intrusive{ + + +template < typename Node_Traits, template class Node_Algorithms > +struct nonhook_node_member : 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; + typedef Node_Algorithms< node_traits > node_algorithms; + + nonhook_node_member() + { + node_algorithms::init(pointer_traits::pointer_to(static_cast< node& >(*this))); + } + nonhook_node_member(const nonhook_node_member& rhs) + { + if (rhs.is_linked()) + { + std::cerr << "nonhook_node_member copy ctor from linked: &=" << (void*)this << ", rhs=" << (void*)&rhs << std::endl; + } + *this = rhs; + } + nonhook_node_member& operator = (const nonhook_node_member& rhs) + { + if (is_linked() or rhs.is_linked()) + { + std::cerr << "nonhook_node_member copy asop to/from linked: &=" << (void*)this << ", rhs=" << (void*)&rhs << std::endl; + } + static_cast< node& >(*this) = rhs; + return *this; + } + + void swap_nodes(nonhook_node_member& other) + { + node_algorithms::swap_nodes(pointer_traits::pointer_to(static_cast< node& >(*this)), + pointer_traits::pointer_to(static_cast< node& >(other))); + } + bool is_linked() const + { + return !node_algorithms::unique(pointer_traits::pointer_to(static_cast< const node& >(*this))); + } +}; + +template < typename T, typename NonHook_Member, NonHook_Member T::* P, link_mode_type Link_Mode > +struct nonhook_node_member_value_traits +{ + typedef T value_type; + typedef typename NonHook_Member::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; + typedef typename pointer_traits:: + template rebind_pointer::type pointer; + typedef typename pointer_traits:: + template rebind_pointer::type const_pointer; + typedef T & reference; + typedef const T & const_reference; + + static const link_mode_type link_mode = Link_Mode; + + static node_ptr to_node_ptr(reference value) + { + return pointer_traits::pointer_to(static_cast(value.*P)); + } + + static const_node_ptr to_node_ptr(const_reference value) + { + return pointer_traits::pointer_to(static_cast(value.*P)); + } + + static pointer to_value_ptr(node_ptr n) + { + return pointer_traits::pointer_to + (*detail::parent_from_member + (static_cast(boost::intrusive::detail::to_raw_pointer(n)), P)); + } + + static const_pointer to_value_ptr(const_node_ptr n) + { + return pointer_traits::pointer_to + (*detail::parent_from_member + (static_cast(boost::intrusive::detail::to_raw_pointer(n)), P)); + } +}; + +} +} + +#endif diff --git a/test/set_test.cpp b/test/set_test.cpp index 4e4e91d..8d5c490 100644 --- a/test/set_test.cpp +++ b/test/set_test.cpp @@ -55,6 +55,9 @@ struct hooks , optimize_size > member_hook_type; typedef set_member_hook , void_pointer > auto_member_hook_type; + typedef nonhook_node_member< rbtree_node_traits , + rbtree_algorithms + > nonhook_node_member_type; }; template< class ValueType @@ -96,6 +99,13 @@ class test_main_template >::type , 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 + >::test_all(); return 0; } }; diff --git a/test/sg_multiset_test.cpp b/test/sg_multiset_test.cpp index 5accea7..4eee56c 100644 --- a/test/sg_multiset_test.cpp +++ b/test/sg_multiset_test.cpp @@ -66,6 +66,9 @@ struct hooks struct auto_base_hook_type : bs_set_base_hook, tag > {}; + typedef nonhook_node_member< tree_node_traits < VoidPointer >, + sgtree_algorithms + > nonhook_node_member_type; }; @@ -139,6 +142,13 @@ class test_main_template >::type , 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 + >::test_all(); return 0; } }; diff --git a/test/sg_set_test.cpp b/test/sg_set_test.cpp index f447425..00926e1 100644 --- a/test/sg_set_test.cpp +++ b/test/sg_set_test.cpp @@ -65,6 +65,9 @@ struct hooks struct auto_base_hook_type : bs_set_base_hook, tag > {}; + typedef nonhook_node_member< tree_node_traits < VoidPointer >, + sgtree_algorithms + > nonhook_node_member_type; }; template< class ValueType @@ -138,6 +141,13 @@ class test_main_template >::type , 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 + >::test_all(); return 0; } }; diff --git a/test/slist_test.cpp b/test/slist_test.cpp index 0ea0c2b..cde9a31 100644 --- a/test/slist_test.cpp +++ b/test/slist_test.cpp @@ -35,6 +35,9 @@ struct hooks typedef slist_member_hook, tag > member_hook_type; typedef slist_member_hook< link_mode , void_pointer > auto_member_hook_type; + typedef nonhook_node_member< slist_node_traits< VoidPointer >, + circular_slist_algorithms + > nonhook_node_member_type; }; template @@ -564,6 +567,14 @@ class test_main_template , false , false >::test_all(data); + test_slist < nonhook_node_member_value_traits< value_type, + typename hooks::nonhook_node_member_type, + &value_type::nhn_member_, + safe_link + >, + false, + false + >::test_all(data); //Now linear slists test_slist < typename detail::get_base_value_traits diff --git a/test/splay_multiset_test.cpp b/test/splay_multiset_test.cpp index 7a21f07..c22706e 100644 --- a/test/splay_multiset_test.cpp +++ b/test/splay_multiset_test.cpp @@ -86,6 +86,9 @@ struct hooks typedef bs_set_member_hook < link_mode , void_pointer > auto_member_hook_type; + typedef nonhook_node_member< tree_node_traits< VoidPointer >, + splaytree_algorithms + > nonhook_node_member_type; }; template< class ValueType @@ -127,6 +130,14 @@ class test_main_template >::type , 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 + >::test_all(); + return 0; } }; diff --git a/test/splay_set_test.cpp b/test/splay_set_test.cpp index 8e62f2c..7fc3fce 100644 --- a/test/splay_set_test.cpp +++ b/test/splay_set_test.cpp @@ -83,6 +83,9 @@ struct hooks typedef bs_set_member_hook < link_mode , void_pointer > auto_member_hook_type; + typedef nonhook_node_member< tree_node_traits< VoidPointer >, + splaytree_algorithms + > nonhook_node_member_type; }; template< class ValueType @@ -124,6 +127,13 @@ class test_main_template >::type , 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 + >::test_all(); return 0; } }; diff --git a/test/treap_multiset_test.cpp b/test/treap_multiset_test.cpp index 1982397..7918082 100644 --- a/test/treap_multiset_test.cpp +++ b/test/treap_multiset_test.cpp @@ -52,6 +52,9 @@ struct hooks < void_pointer > member_hook_type; typedef bs_set_member_hook < void_pointer > auto_member_hook_type; + typedef nonhook_node_member< tree_node_traits< VoidPointer >, + treap_algorithms + > nonhook_node_member_type; }; template< class ValueType @@ -93,6 +96,13 @@ class test_main_template >::type , 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 + >::test_all(); return 0; } }; diff --git a/test/treap_set_test.cpp b/test/treap_set_test.cpp index f0deb47..8d1cd49 100644 --- a/test/treap_set_test.cpp +++ b/test/treap_set_test.cpp @@ -67,6 +67,9 @@ struct hooks < void_pointer > member_hook_type; typedef bs_set_member_hook < void_pointer > auto_member_hook_type; + typedef nonhook_node_member< tree_node_traits< VoidPointer >, + treap_algorithms + > nonhook_node_member_type; }; template< class ValueType @@ -108,6 +111,13 @@ class test_main_template >::type , 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 + >::test_all(); return 0; } }; diff --git a/test/unordered_multiset_test.cpp b/test/unordered_multiset_test.cpp index a4da129..f0e8373 100644 --- a/test/unordered_multiset_test.cpp +++ b/test/unordered_multiset_test.cpp @@ -67,6 +67,9 @@ struct hooks , store_hash , optimize_multikey > auto_member_hook_type; + typedef nonhook_node_member< unordered_node_traits< VoidPointer, true, true >, + unordered_algorithms + > nonhook_node_member_type; }; static const std::size_t BucketSize = 8; @@ -805,6 +808,15 @@ class test_main_template , false , Incremental >::test_all(data); + test_unordered_multiset < nonhook_node_member_value_traits< value_type, + typename hooks::nonhook_node_member_type, + &value_type::nhn_member_, + safe_link + >, + false, + false, + Incremental + >::test_all(data); return 0; } }; diff --git a/test/unordered_set_test.cpp b/test/unordered_set_test.cpp index 4555405..0a60c5f 100644 --- a/test/unordered_set_test.cpp +++ b/test/unordered_set_test.cpp @@ -66,6 +66,9 @@ struct hooks , store_hash , optimize_multikey > auto_member_hook_type; + typedef nonhook_node_member< unordered_node_traits< VoidPointer, true, true >, + unordered_algorithms + > nonhook_node_member_type; }; static const std::size_t BucketSize = 8; @@ -657,6 +660,15 @@ class test_main_template , false , incremental >::test_all(data); + test_unordered_set < nonhook_node_member_value_traits< value_type, + typename hooks::nonhook_node_member_type, + &value_type::nhn_member_, + safe_link + >, + false, + false, + incremental + >::test_all(data); return 0; }