Merge branch 'mateidavid-test-nonhook-nodes' into develop

This commit is contained in:
Ion Gaztañaga
2014-05-01 10:23:38 +02:00
19 changed files with 296 additions and 1 deletions

View File

@@ -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/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/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/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. * Optimized tree rebalancing code to avoid redundant assignments.

View File

@@ -318,6 +318,9 @@
<File <File
RelativePath="..\..\..\test\Jamfile.v2"> RelativePath="..\..\..\test\Jamfile.v2">
</File> </File>
<File
RelativePath="..\..\..\test\nonhook_node.hpp">
</File>
<File <File
RelativePath="..\..\..\test\smart_ptr.hpp"> RelativePath="..\..\..\test\smart_ptr.hpp">
</File> </File>

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 typedef avl_set_member_hook
< link_mode<auto_unlink> < link_mode<auto_unlink>
, void_pointer<VoidPointer> > auto_member_hook_type; , 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 template< class ValueType
@@ -96,6 +99,13 @@ class test_main_template
>::type >::type
, GetContainer , GetContainer
>::test_all(); >::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; return 0;
} }
}; };

View File

@@ -55,6 +55,9 @@ struct hooks
typedef avl_set_member_hook typedef avl_set_member_hook
< link_mode<auto_unlink> < link_mode<auto_unlink>
, void_pointer<VoidPointer> > auto_member_hook_type; , 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 template< class ValueType
@@ -96,6 +99,13 @@ class test_main_template
>::type >::type
, GetContainer , GetContainer
>::test_all(); >::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; return 0;
} }
}; };

View File

@@ -16,6 +16,7 @@
#include <iostream> #include <iostream>
#include <boost/intrusive/options.hpp> #include <boost/intrusive/options.hpp>
#include <boost/functional/hash.hpp> #include <boost/functional/hash.hpp>
#include "nonhook_node.hpp"
namespace boost{ namespace boost{
namespace intrusive{ namespace intrusive{
@@ -33,6 +34,7 @@ struct testvalue
{ {
typename Hooks::member_hook_type node_; typename Hooks::member_hook_type node_;
typename Hooks::auto_member_hook_type auto_node_; typename Hooks::auto_member_hook_type auto_node_;
typename Hooks::nonhook_node_member_type nhn_member_;
int value_; int value_;
static const bool constant_time_size = ConstantTimeSize; 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)); Hooks::auto_base_hook_type::operator=(static_cast<const typename Hooks::auto_base_hook_type&>(src));
this->node_ = src.node_; this->node_ = src.node_;
this->auto_node_ = src.auto_node_; this->auto_node_ = src.auto_node_;
this->nhn_member_ = src.nhn_member_;
value_ = src.value_; value_ = src.value_;
return *this; return *this;
} }
@@ -66,6 +69,7 @@ struct testvalue
Hooks::auto_base_hook_type::swap_nodes(static_cast<typename Hooks::auto_base_hook_type&>(other)); Hooks::auto_base_hook_type::swap_nodes(static_cast<typename Hooks::auto_base_hook_type&>(other));
node_.swap_nodes(other.node_); node_.swap_nodes(other.node_);
auto_node_.swap_nodes(other.auto_node_); auto_node_.swap_nodes(other.auto_node_);
nhn_member_.swap_nodes(other.nhn_member_);
} }
bool is_linked() const bool is_linked() const
@@ -73,7 +77,8 @@ struct testvalue
return Hooks::base_hook_type::is_linked() || return Hooks::base_hook_type::is_linked() ||
Hooks::auto_base_hook_type::is_linked() || Hooks::auto_base_hook_type::is_linked() ||
node_.is_linked() || node_.is_linked() ||
auto_node_.is_linked(); auto_node_.is_linked() ||
nhn_member_.is_linked();
} }
~testvalue() ~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<void_pointer<VoidPointer>, tag<my_tag> > member_hook_type;
typedef list_member_hook< link_mode<auto_unlink> typedef list_member_hook< link_mode<auto_unlink>
, void_pointer<VoidPointer> > auto_member_hook_type; , 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> template<class ValueTraits>
@@ -436,6 +439,12 @@ class test_main_template
> >
>::type >::type
>::test_all(data); >::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; return 0;
} }
}; };

View File

@@ -54,6 +54,9 @@ struct hooks
<VoidPointer>, optimize_size<true> > member_hook_type; <VoidPointer>, optimize_size<true> > member_hook_type;
typedef set_member_hook typedef set_member_hook
<link_mode<auto_unlink>, void_pointer<VoidPointer> > auto_member_hook_type; <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 template< class ValueType
@@ -95,6 +98,13 @@ class test_main_template
>::type >::type
, GetContainer , GetContainer
>::test_all(); >::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; return 0;
} }
}; };

120
test/nonhook_node.hpp Normal file
View 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

View File

@@ -55,6 +55,9 @@ struct hooks
<VoidPointer>, optimize_size<true> > member_hook_type; <VoidPointer>, optimize_size<true> > member_hook_type;
typedef set_member_hook typedef set_member_hook
<link_mode<auto_unlink>, void_pointer<VoidPointer> > auto_member_hook_type; <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 template< class ValueType
@@ -96,6 +99,13 @@ class test_main_template
>::type >::type
, GetContainer , GetContainer
>::test_all(); >::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; return 0;
} }
}; };

View File

@@ -66,6 +66,9 @@ struct hooks
struct auto_base_hook_type struct auto_base_hook_type
: bs_set_base_hook<void_pointer<VoidPointer>, tag<my_tag> > : 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 >::type
, GetContainerFixedAlpha , GetContainerFixedAlpha
>::test_all(); >::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; return 0;
} }
}; };

View File

@@ -65,6 +65,9 @@ struct hooks
struct auto_base_hook_type struct auto_base_hook_type
: bs_set_base_hook<void_pointer<VoidPointer>, tag<my_tag> > : 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 template< class ValueType
@@ -138,6 +141,13 @@ class test_main_template
>::type >::type
, GetContainerFixedAlpha , GetContainerFixedAlpha
>::test_all(); >::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; 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<void_pointer<VoidPointer>, tag<my_tag> > member_hook_type;
typedef slist_member_hook< link_mode<auto_unlink> typedef slist_member_hook< link_mode<auto_unlink>
, void_pointer<VoidPointer> > auto_member_hook_type; , 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> template<class ValueTraits, bool Linear, bool CacheLast>
@@ -564,6 +567,14 @@ class test_main_template
, false , false
, false , false
>::test_all(data); >::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 //Now linear slists
test_slist < typename detail::get_base_value_traits test_slist < typename detail::get_base_value_traits

View File

@@ -86,6 +86,9 @@ struct hooks
typedef bs_set_member_hook typedef bs_set_member_hook
< link_mode<auto_unlink> < link_mode<auto_unlink>
, void_pointer<VoidPointer> > auto_member_hook_type; , void_pointer<VoidPointer> > auto_member_hook_type;
typedef nonhook_node_member< tree_node_traits< VoidPointer >,
splaytree_algorithms
> nonhook_node_member_type;
}; };
template< class ValueType template< class ValueType
@@ -127,6 +130,14 @@ class test_main_template
>::type >::type
, GetContainer , GetContainer
>::test_all(); >::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; return 0;
} }
}; };

View File

@@ -83,6 +83,9 @@ struct hooks
typedef bs_set_member_hook typedef bs_set_member_hook
< link_mode<auto_unlink> < link_mode<auto_unlink>
, void_pointer<VoidPointer> > auto_member_hook_type; , void_pointer<VoidPointer> > auto_member_hook_type;
typedef nonhook_node_member< tree_node_traits< VoidPointer >,
splaytree_algorithms
> nonhook_node_member_type;
}; };
template< class ValueType template< class ValueType
@@ -124,6 +127,13 @@ class test_main_template
>::type >::type
, GetContainer , GetContainer
>::test_all(); >::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; return 0;
} }
}; };

View File

@@ -52,6 +52,9 @@ struct hooks
< void_pointer<VoidPointer> > member_hook_type; < void_pointer<VoidPointer> > member_hook_type;
typedef bs_set_member_hook typedef bs_set_member_hook
< void_pointer<VoidPointer> > auto_member_hook_type; < void_pointer<VoidPointer> > auto_member_hook_type;
typedef nonhook_node_member< tree_node_traits< VoidPointer >,
treap_algorithms
> nonhook_node_member_type;
}; };
template< class ValueType template< class ValueType
@@ -93,6 +96,13 @@ class test_main_template
>::type >::type
, GetContainer , GetContainer
>::test_all(); >::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; return 0;
} }
}; };

View File

@@ -67,6 +67,9 @@ struct hooks
< void_pointer<VoidPointer> > member_hook_type; < void_pointer<VoidPointer> > member_hook_type;
typedef bs_set_member_hook typedef bs_set_member_hook
< void_pointer<VoidPointer> > auto_member_hook_type; < void_pointer<VoidPointer> > auto_member_hook_type;
typedef nonhook_node_member< tree_node_traits< VoidPointer >,
treap_algorithms
> nonhook_node_member_type;
}; };
template< class ValueType template< class ValueType
@@ -108,6 +111,13 @@ class test_main_template
>::type >::type
, GetContainer , GetContainer
>::test_all(); >::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; return 0;
} }
}; };

View File

@@ -67,6 +67,9 @@ struct hooks
, store_hash<true> , store_hash<true>
, optimize_multikey<true> , optimize_multikey<true>
> auto_member_hook_type; > 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; static const std::size_t BucketSize = 8;
@@ -805,6 +808,15 @@ class test_main_template
, false , false
, Incremental , Incremental
>::test_all(data); >::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; return 0;
} }
}; };

View File

@@ -66,6 +66,9 @@ struct hooks
, store_hash<true> , store_hash<true>
, optimize_multikey<true> , optimize_multikey<true>
> auto_member_hook_type; > 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; static const std::size_t BucketSize = 8;
@@ -657,6 +660,15 @@ class test_main_template
, false , false
, incremental , incremental
>::test_all(data); >::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; return 0;
} }