3 #ifndef __CDS_INTRUSIVE_DETAILS_NODE_TRAITS_H
4 #define __CDS_INTRUSIVE_DETAILS_NODE_TRAITS_H
6 #include <cds/intrusive/options.h>
8 namespace cds { namespace intrusive {
10 #ifdef CDS_DOXYGEN_INVOKED
11 /// Container's node traits
12 /** @ingroup cds_intrusive_helper
13 This traits is intended for converting between type \p T of value stored in the intrusive container
14 and container's node type \p NodeType.
16 There are separate specializations for each \p Hook type.
18 template <typename T, typename NodeType, typename Hook>
21 typedef T value_type ; ///< Value type
22 typedef NodeType node_type ; ///< Node type
24 /// Convert value reference to node pointer
25 static node_type * to_node_ptr( value_type& v );
27 /// Convert value pointer to node pointer
28 static node_type * to_node_ptr( value_type * v );
30 /// Convert value reference to node pointer (const version)
31 static const node_type * to_node_ptr( value_type const& v );
33 /// Convert value pointer to node pointer (const version)
34 static const node_type * to_node_ptr( value_type const * v );
36 /// Convert node refernce to value pointer
37 static value_type * to_value_ptr( node_type& n );
39 /// Convert node pointer to value pointer
40 static value_type * to_value_ptr( node_type * n );
42 /// Convert node reference to value pointer (const version)
43 static const value_type * to_value_ptr( node_type const & n );
45 /// Convert node pointer to value pointer (const version)
46 static const value_type * to_value_ptr( node_type const * n );
50 template <typename T, typename NodeType, class Hook, typename HookType>
55 template <typename T, typename NodeType, class Hook>
56 struct node_traits<T, NodeType, Hook, opt::base_hook_tag>
59 typedef NodeType node_type;
61 static node_type * to_node_ptr( value_type& v )
63 return static_cast<node_type *>( &v );
65 static node_type * to_node_ptr( value_type * v )
67 return v ? static_cast<node_type *>(v) : nullptr;
69 static const node_type * to_node_ptr( const value_type& v )
71 return static_cast<const node_type *>( &v );
73 static const node_type * to_node_ptr( const value_type * v )
75 return v ? static_cast<const node_type *>(v) : nullptr;
77 static value_type * to_value_ptr( node_type& n )
79 return static_cast<value_type *>( &n );
81 static value_type * to_value_ptr( node_type * n )
83 return n ? static_cast<value_type *>(n) : nullptr;
85 static const value_type * to_value_ptr( const node_type& n )
87 return static_cast<const value_type *>( &n );
89 static const value_type * to_value_ptr( const node_type * n )
91 return n ? static_cast<const value_type *>(n) : nullptr;
95 template <typename T, typename NodeType, class Hook>
96 struct node_traits<T, NodeType, Hook, opt::member_hook_tag>
99 typedef NodeType node_type;
101 static node_type * to_node_ptr( value_type& v )
103 return reinterpret_cast<node_type *>( reinterpret_cast<char *>(&v) + Hook::c_nMemberOffset );
105 static node_type * to_node_ptr( value_type * v )
107 return v ? to_node_ptr( *v ) : nullptr;
109 static const node_type * to_node_ptr( const value_type& v )
111 return reinterpret_cast<const node_type *>( reinterpret_cast<const char *>(&v) + Hook::c_nMemberOffset );
113 static const node_type * to_node_ptr( const value_type * v )
115 return v ? to_node_ptr( *v ) : nullptr;
117 static value_type * to_value_ptr( node_type& n )
119 return reinterpret_cast<value_type *>( reinterpret_cast<char *>(&n) - Hook::c_nMemberOffset );
121 static value_type * to_value_ptr( node_type * n )
123 return n ? to_value_ptr( *n ) : nullptr;
125 static const value_type * to_value_ptr( const node_type& n )
127 return reinterpret_cast<const value_type *>( reinterpret_cast<const char *>(&n) - Hook::c_nMemberOffset );
129 static const value_type * to_value_ptr( const node_type * n )
131 return n ? to_value_ptr( *n ) : nullptr;
135 template <typename T, typename NodeType, class Hook>
136 struct node_traits<T, NodeType, Hook, opt::traits_hook_tag>: public Hook::node_traits
140 /// Node traits selector metafunction
141 /** @ingroup cds_intrusive_helper
142 The metafunction selects appropriate \ref node_traits specialization based on value type \p T, node type \p NodeType, and hook type \p Hook.
144 template <typename T, typename NodeType, class Hook>
145 struct get_node_traits
148 typedef node_traits<T, NodeType, Hook, typename Hook::hook_type> type;
153 /// Functor converting container's node type to value type
154 template <class Container>
155 struct node_to_value {
156 typename Container::value_type * operator()( typename Container::node_type * p ) const
158 typedef typename Container::node_traits node_traits;
159 return node_traits::to_value_ptr( p );
164 }} // namespace cds::intrusuve
166 #endif // #ifndef __CDS_INTRUSIVE_DETAILS_NODE_TRAITS_H