forked from boostorg/intrusive
Merge branch 'mateidavid-test-nonhook-nodes' into develop
This commit is contained in:
@@ -3800,6 +3800,7 @@ to be inserted in intrusive containers are allocated using `std::vector` or `std
|
||||
* [@https://svn.boost.org/trac/boost/ticket/9746 #9746: Modern Sun CC compiler detects error in intrusive library header]
|
||||
* [@https://svn.boost.org/trac/boost/ticket/9940 #9940: bad bug in intrusive list with safe_link (or auto_unlink) hooks]
|
||||
* [@https://svn.boost.org/trac/boost/ticket/9949 #9949: clear header node hooks upon intrusive container destruction]
|
||||
* [@https://svn.boost.org/trac/boost/ticket/9961 #9961: tests for hooks not derived frorm generic_hook]
|
||||
|
||||
* Optimized tree rebalancing code to avoid redundant assignments.
|
||||
|
||||
|
@@ -318,6 +318,9 @@
|
||||
<File
|
||||
RelativePath="..\..\..\test\Jamfile.v2">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\test\nonhook_node.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\test\smart_ptr.hpp">
|
||||
</File>
|
||||
|
21
test/Makefile
Normal file
21
test/Makefile
Normal 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)
|
@@ -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;
|
||||
}
|
||||
};
|
||||
|
@@ -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;
|
||||
}
|
||||
};
|
||||
|
@@ -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()
|
||||
|
@@ -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;
|
||||
}
|
||||
};
|
||||
|
@@ -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;
|
||||
}
|
||||
};
|
||||
|
120
test/nonhook_node.hpp
Normal file
120
test/nonhook_node.hpp
Normal file
@@ -0,0 +1,120 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Matei David 2014-2014.
|
||||
// (C) Copyright Ion Gaztanaga 2014-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_DETAIL_NONHOOK_NODE_HPP
|
||||
#define BOOST_INTRUSIVE_DETAIL_NONHOOK_NODE_HPP
|
||||
|
||||
#include <boost/intrusive/detail/config_begin.hpp>
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
#include <boost/intrusive/detail/utilities.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
|
||||
namespace boost{
|
||||
namespace intrusive{
|
||||
|
||||
//This node will only be used in safe or auto unlink modes
|
||||
//so test it's been properly released
|
||||
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)
|
||||
{
|
||||
BOOST_TEST(!rhs.is_linked());
|
||||
*this = rhs;
|
||||
}
|
||||
|
||||
nonhook_node_member& operator = (const nonhook_node_member& rhs)
|
||||
{
|
||||
BOOST_TEST(!this->is_linked() && !rhs.is_linked());
|
||||
static_cast< node& >(*this) = rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
~nonhook_node_member()
|
||||
{
|
||||
BOOST_TEST(!this->is_linked());
|
||||
node_algorithms::init(pointer_traits<node_ptr>::pointer_to(static_cast< node& >(*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;
|
||||
|
||||
BOOST_STATIC_ASSERT((Link_Mode == safe_link || Link_Mode == auto_unlink));
|
||||
|
||||
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
|
@@ -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;
|
||||
}
|
||||
};
|
||||
|
@@ -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;
|
||||
}
|
||||
};
|
||||
|
@@ -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;
|
||||
}
|
||||
};
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
}
|
||||
};
|
||||
|
@@ -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;
|
||||
}
|
||||
};
|
||||
|
@@ -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;
|
||||
}
|
||||
};
|
||||
|
@@ -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;
|
||||
}
|
||||
};
|
||||
|
@@ -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;
|
||||
}
|
||||
};
|
||||
|
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user