1 ///////////////////////////////////////////////////////////////////////////// 2 // 3 // (C) Copyright Matei David 2014-2014. 4 // (C) Copyright Ion Gaztanaga 2014-2014. 5 // 6 // Distributed under the Boost Software License, Version 1.0. 7 // (See accompanying file LICENSE_1_0.txt or copy at 8 // http://www.boost.org/LICENSE_1_0.txt) 9 // 10 // See http://www.boost.org/libs/intrusive for documentation. 11 // 12 ///////////////////////////////////////////////////////////////////////////// 13 #ifndef BOOST_INTRUSIVE_DETAIL_NONHOOK_NODE_HPP 14 #define BOOST_INTRUSIVE_DETAIL_NONHOOK_NODE_HPP 15 16 #include <boost/intrusive/detail/config_begin.hpp> 17 #include <boost/intrusive/pointer_traits.hpp> 18 #include <boost/intrusive/detail/parent_from_member.hpp> 19 20 #include <boost/move/detail/to_raw_pointer.hpp> 21 22 #include <boost/static_assert.hpp> 23 #include <boost/detail/lightweight_test.hpp> 24 25 namespace boost{ 26 namespace intrusive{ 27 28 //This node will only be used in safe or auto unlink modes 29 //so test it's been properly released 30 template < typename NodeTraits, template <typename> class Node_Algorithms > 31 struct nonhook_node_member : public NodeTraits::node 32 { 33 typedef NodeTraits node_traits; 34 typedef typename node_traits::node node; 35 typedef typename node_traits::node_ptr node_ptr; 36 typedef typename node_traits::const_node_ptr const_node_ptr; 37 typedef Node_Algorithms< node_traits > node_algorithms; 38 nonhook_node_memberboost::intrusive::nonhook_node_member39 nonhook_node_member() 40 { 41 node_algorithms::init(pointer_traits<node_ptr>::pointer_to(static_cast< node& >(*this))); 42 } 43 nonhook_node_memberboost::intrusive::nonhook_node_member44 nonhook_node_member(const nonhook_node_member& rhs) 45 { 46 BOOST_TEST(!rhs.is_linked()); 47 node_algorithms::init(pointer_traits<node_ptr>::pointer_to(static_cast< node& >(*this))); 48 } 49 operator =boost::intrusive::nonhook_node_member50 nonhook_node_member& operator = (const nonhook_node_member& rhs) 51 { 52 BOOST_TEST(!this->is_linked() && !rhs.is_linked()); 53 return *this; 54 } 55 ~nonhook_node_memberboost::intrusive::nonhook_node_member56 ~nonhook_node_member() 57 { 58 BOOST_TEST(!this->is_linked()); 59 node_algorithms::init(pointer_traits<node_ptr>::pointer_to(static_cast< node& >(*this))); 60 } 61 swap_nodesboost::intrusive::nonhook_node_member62 void swap_nodes(nonhook_node_member& other) 63 { 64 node_algorithms::swap_nodes(pointer_traits<node_ptr>::pointer_to(static_cast< node& >(*this)), 65 pointer_traits<node_ptr>::pointer_to(static_cast< node& >(other))); 66 } 67 is_linkedboost::intrusive::nonhook_node_member68 bool is_linked() const 69 { 70 return !node_algorithms::unique(pointer_traits<const_node_ptr>::pointer_to(static_cast< const node& >(*this))); 71 } 72 }; 73 74 template < typename T, typename NonHook_Member, NonHook_Member T::* P, link_mode_type Link_Mode > 75 struct nonhook_node_member_value_traits 76 { 77 typedef T value_type; 78 typedef typename NonHook_Member::node_traits node_traits; 79 typedef typename node_traits::node node; 80 typedef typename node_traits::node_ptr node_ptr; 81 typedef typename node_traits::const_node_ptr const_node_ptr; 82 typedef typename pointer_traits<node_ptr>:: 83 template rebind_pointer<T>::type pointer; 84 typedef typename pointer_traits<node_ptr>:: 85 template rebind_pointer<const T>::type const_pointer; 86 typedef T & reference; 87 typedef const T & const_reference; 88 89 static const link_mode_type link_mode = Link_Mode; 90 91 BOOST_STATIC_ASSERT((Link_Mode == safe_link || Link_Mode == auto_unlink)); 92 to_node_ptrboost::intrusive::nonhook_node_member_value_traits93 static node_ptr to_node_ptr(reference value) 94 { 95 return pointer_traits<node_ptr>::pointer_to(static_cast<node&>(value.*P)); 96 } 97 to_node_ptrboost::intrusive::nonhook_node_member_value_traits98 static const_node_ptr to_node_ptr(const_reference value) 99 { 100 return pointer_traits<const_node_ptr>::pointer_to(static_cast<const node&>(value.*P)); 101 } 102 to_value_ptrboost::intrusive::nonhook_node_member_value_traits103 static pointer to_value_ptr(node_ptr n) 104 { 105 return pointer_traits<pointer>::pointer_to 106 (*detail::parent_from_member<T, NonHook_Member> 107 (static_cast<NonHook_Member*>(boost::movelib::to_raw_pointer(n)), P)); 108 } 109 to_value_ptrboost::intrusive::nonhook_node_member_value_traits110 static const_pointer to_value_ptr(const_node_ptr n) 111 { 112 return pointer_traits<const_pointer>::pointer_to 113 (*detail::parent_from_member<T, NonHook_Member> 114 (static_cast<const NonHook_Member*>(boost::movelib::to_raw_pointer(n)), P)); 115 } 116 }; 117 118 } 119 } 120 121 #endif 122