From 9169db7f5742f87058ed535f07aea9fc312ea595 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Thu, 1 May 2014 10:21:40 +0200 Subject: [PATCH] Fixed #9961: tests for hooks not derived frorm generic_hook --- doc/intrusive.qbk | 1 + .../vc7ide/_intrusivelib/_intrusivelib.vcproj | 3 + test/nonhook_node.hpp | 167 ++++++++++-------- 3 files changed, 93 insertions(+), 78 deletions(-) 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)); + } }; }