added tests for intrusive hooks not derived from the default hooks

This commit is contained in:
Matei David
2014-04-28 20:08:24 -04:00
parent fc6d3cca5f
commit 60c6f40336
17 changed files with 273 additions and 1 deletions

21
test/Makefile Normal file
View File

@@ -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)

View File

@@ -55,6 +55,9 @@ struct hooks
typedef avl_set_member_hook
< link_mode<auto_unlink>
, void_pointer<VoidPointer> > auto_member_hook_type;
typedef nonhook_node_member< avltree_node_traits<VoidPointer, false >,
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<VoidPointer>::nonhook_node_member_type,
&value_type::nhn_member_,
safe_link
>,
GetContainer
>::test_all();
return 0;
}
};

View File

@@ -55,6 +55,9 @@ struct hooks
typedef avl_set_member_hook
< link_mode<auto_unlink>
, void_pointer<VoidPointer> > auto_member_hook_type;
typedef nonhook_node_member< avltree_node_traits<VoidPointer, false >,
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<VoidPointer>::nonhook_node_member_type,
&value_type::nhn_member_,
safe_link
>,
GetContainer
>::test_all();
return 0;
}
};

View File

@@ -16,6 +16,7 @@
#include <iostream>
#include <boost/intrusive/options.hpp>
#include <boost/functional/hash.hpp>
#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<const typename Hooks::auto_base_hook_type&>(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<typename Hooks::auto_base_hook_type&>(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()

View File

@@ -34,6 +34,9 @@ struct hooks
typedef list_member_hook<void_pointer<VoidPointer>, tag<my_tag> > member_hook_type;
typedef list_member_hook< link_mode<auto_unlink>
, void_pointer<VoidPointer> > auto_member_hook_type;
typedef nonhook_node_member< list_node_traits< VoidPointer >,
circular_list_algorithms
> nonhook_node_member_type;
};
template<class ValueTraits>
@@ -436,6 +439,12 @@ class test_main_template
>
>::type
>::test_all(data);
test_list < nonhook_node_member_value_traits< value_type,
typename hooks<VoidPointer>::nonhook_node_member_type,
&value_type::nhn_member_,
safe_link
>
>::test_all(data);
return 0;
}
};

View File

@@ -54,6 +54,9 @@ struct hooks
<VoidPointer>, optimize_size<true> > member_hook_type;
typedef set_member_hook
<link_mode<auto_unlink>, void_pointer<VoidPointer> > auto_member_hook_type;
typedef nonhook_node_member< rbtree_node_traits <VoidPointer, false >,
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<VoidPointer>::nonhook_node_member_type,
&value_type::nhn_member_,
safe_link
>,
GetContainer
>::test_all();
return 0;
}
};

101
test/nonhook_node.hpp Normal file
View File

@@ -0,0 +1,101 @@
#ifndef BOOST_INTRUSIVE_DETAIL_NONHOOK_NODE_HPP
#define BOOST_INTRUSIVE_DETAIL_NONHOOK_NODE_HPP
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/list.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/detail/utilities.hpp>
namespace boost{
namespace intrusive{
template < typename Node_Traits, template <typename> 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<node_ptr>::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<node_ptr>::pointer_to(static_cast< node& >(*this)),
pointer_traits<node_ptr>::pointer_to(static_cast< node& >(other)));
}
bool is_linked() const
{
return !node_algorithms::unique(pointer_traits<const_node_ptr>::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<node_ptr>::
template rebind_pointer<T>::type pointer;
typedef typename pointer_traits<node_ptr>::
template rebind_pointer<const T>::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<node_ptr>::pointer_to(static_cast<node&>(value.*P));
}
static const_node_ptr to_node_ptr(const_reference value)
{
return pointer_traits<const_node_ptr>::pointer_to(static_cast<const node&>(value.*P));
}
static pointer to_value_ptr(node_ptr n)
{
return pointer_traits<pointer>::pointer_to
(*detail::parent_from_member<T, NonHook_Member>
(static_cast<NonHook_Member*>(boost::intrusive::detail::to_raw_pointer(n)), P));
}
static const_pointer to_value_ptr(const_node_ptr n)
{
return pointer_traits<const_pointer>::pointer_to
(*detail::parent_from_member<T, NonHook_Member>
(static_cast<const NonHook_Member*>(boost::intrusive::detail::to_raw_pointer(n)), P));
}
};
}
}
#endif

View File

@@ -55,6 +55,9 @@ struct hooks
<VoidPointer>, optimize_size<true> > member_hook_type;
typedef set_member_hook
<link_mode<auto_unlink>, void_pointer<VoidPointer> > auto_member_hook_type;
typedef nonhook_node_member< rbtree_node_traits <VoidPointer, false >,
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<VoidPointer>::nonhook_node_member_type,
&value_type::nhn_member_,
safe_link
>,
GetContainer
>::test_all();
return 0;
}
};

View File

@@ -66,6 +66,9 @@ struct hooks
struct auto_base_hook_type
: bs_set_base_hook<void_pointer<VoidPointer>, tag<my_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<VoidPointer>::nonhook_node_member_type,
&value_type::nhn_member_,
safe_link
>,
GetContainerFixedAlpha
>::test_all();
return 0;
}
};

View File

@@ -65,6 +65,9 @@ struct hooks
struct auto_base_hook_type
: bs_set_base_hook<void_pointer<VoidPointer>, tag<my_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<VoidPointer>::nonhook_node_member_type,
&value_type::nhn_member_,
safe_link
>,
GetContainerFixedAlpha
>::test_all();
return 0;
}
};

View File

@@ -35,6 +35,9 @@ struct hooks
typedef slist_member_hook<void_pointer<VoidPointer>, tag<my_tag> > member_hook_type;
typedef slist_member_hook< link_mode<auto_unlink>
, void_pointer<VoidPointer> > auto_member_hook_type;
typedef nonhook_node_member< slist_node_traits< VoidPointer >,
circular_slist_algorithms
> nonhook_node_member_type;
};
template<class ValueTraits, bool Linear, bool CacheLast>
@@ -564,6 +567,14 @@ class test_main_template
, false
, false
>::test_all(data);
test_slist < nonhook_node_member_value_traits< value_type,
typename hooks<VoidPointer>::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

View File

@@ -86,6 +86,9 @@ struct hooks
typedef bs_set_member_hook
< link_mode<auto_unlink>
, void_pointer<VoidPointer> > 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<VoidPointer>::nonhook_node_member_type,
&value_type::nhn_member_,
safe_link
>,
GetContainer
>::test_all();
return 0;
}
};

View File

@@ -83,6 +83,9 @@ struct hooks
typedef bs_set_member_hook
< link_mode<auto_unlink>
, void_pointer<VoidPointer> > 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<VoidPointer>::nonhook_node_member_type,
&value_type::nhn_member_,
safe_link
>,
GetContainer
>::test_all();
return 0;
}
};

View File

@@ -52,6 +52,9 @@ struct hooks
< void_pointer<VoidPointer> > member_hook_type;
typedef bs_set_member_hook
< void_pointer<VoidPointer> > 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<VoidPointer>::nonhook_node_member_type,
&value_type::nhn_member_,
safe_link
>,
GetContainer
>::test_all();
return 0;
}
};

View File

@@ -67,6 +67,9 @@ struct hooks
< void_pointer<VoidPointer> > member_hook_type;
typedef bs_set_member_hook
< void_pointer<VoidPointer> > 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<VoidPointer>::nonhook_node_member_type,
&value_type::nhn_member_,
safe_link
>,
GetContainer
>::test_all();
return 0;
}
};

View File

@@ -67,6 +67,9 @@ struct hooks
, store_hash<true>
, optimize_multikey<true>
> 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<VoidPointer>::nonhook_node_member_type,
&value_type::nhn_member_,
safe_link
>,
false,
false,
Incremental
>::test_all(data);
return 0;
}
};

View File

@@ -66,6 +66,9 @@ struct hooks
, store_hash<true>
, optimize_multikey<true>
> 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<VoidPointer>::nonhook_node_member_type,
&value_type::nhn_member_,
safe_link
>,
false,
false,
incremental
>::test_all(data);
return 0;
}