diff --git a/doc/intrusive.qbk b/doc/intrusive.qbk
index a0cf973..4d47228 100644
--- a/doc/intrusive.qbk
+++ b/doc/intrusive.qbk
@@ -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.
diff --git a/proj/vc7ide/_intrusivelib/_intrusivelib.vcproj b/proj/vc7ide/_intrusivelib/_intrusivelib.vcproj
index fc4e758..cfa6a7a 100644
--- a/proj/vc7ide/_intrusivelib/_intrusivelib.vcproj
+++ b/proj/vc7ide/_intrusivelib/_intrusivelib.vcproj
@@ -318,6 +318,9 @@
+
+
diff --git a/test/nonhook_node.hpp b/test/nonhook_node.hpp
index 0297140..06ba155 100644
--- a/test/nonhook_node.hpp
+++ b/test/nonhook_node.hpp
@@ -1,106 +1,117 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (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
-#include
#include
#include
+#include
+#include
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 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;
+ 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;
- }
- ~nonhook_node_member()
- {
- if (is_linked())
- {
- std::cerr << "nonhook_node_member dtor of linked: &=" << (void*)this << std::endl;
- }
- node_algorithms::init(pointer_traits::pointer_to(static_cast< node& >(*this)));
- }
+ nonhook_node_member()
+ {
+ node_algorithms::init(pointer_traits::pointer_to(static_cast< node& >(*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)));
- }
+ 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::pointer_to(static_cast< node& >(*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;
+ 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 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));
- }
+ BOOST_STATIC_ASSERT((Link_Mode == safe_link || Link_Mode == auto_unlink));
- 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 node_ptr to_node_ptr(reference value)
+ {
+ return pointer_traits::pointer_to(static_cast(value.*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));
- }
+ 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));
+ }
};
}