Replace NULL with nullptr
[libcds.git] / cds / intrusive / node_traits.h
1 //$$CDS-header$$
2
3 #ifndef __CDS_INTRUSIVE_NODE_TRAITS_H
4 #define __CDS_INTRUSIVE_NODE_TRAITS_H
5
6 #include <cds/intrusive/options.h>
7
8 namespace cds { namespace intrusive {
9
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.
15
16         There are separate specializations for each \p Hook type.
17     */
18     template <typename T, typename NodeType, typename Hook>
19     struct node_traits
20     {
21         typedef T        value_type ;  ///< Value type
22         typedef NodeType node_type  ;  ///< Node type
23
24         /// Convert value reference to node pointer
25         static node_type * to_node_ptr( value_type& v );
26
27         /// Convert value pointer to node pointer
28         static node_type * to_node_ptr( value_type * v );
29
30         /// Convert value reference to node pointer (const version)
31         static const node_type * to_node_ptr( value_type const& v );
32
33         /// Convert value pointer to node pointer (const version)
34         static const node_type * to_node_ptr( value_type const * v );
35
36         /// Convert node refernce to value pointer
37         static value_type * to_value_ptr( node_type&  n );
38
39         /// Convert node pointer to value pointer
40         static value_type * to_value_ptr( node_type *  n );
41
42         /// Convert node reference to value pointer (const version)
43         static const value_type * to_value_ptr( node_type const & n );
44
45         /// Convert node pointer to value pointer (const version)
46         static const value_type * to_value_ptr( node_type const * n );
47     };
48
49 #else
50     template <typename T, typename NodeType, class Hook, typename HookType>
51     struct node_traits;
52 #endif
53
54     //@cond
55     template <typename T, typename NodeType, class Hook>
56     struct node_traits<T, NodeType, Hook, opt::base_hook_tag>
57     {
58         typedef T        value_type;
59         typedef NodeType node_type;
60
61         static node_type * to_node_ptr( value_type& v )
62         {
63             return static_cast<node_type *>( &v );
64         }
65         static node_type * to_node_ptr( value_type * v )
66         {
67             return v ? static_cast<node_type *>(v) : nullptr;
68         }
69         static const node_type * to_node_ptr( const value_type& v )
70         {
71             return static_cast<const node_type *>( &v );
72         }
73         static const node_type * to_node_ptr( const value_type * v )
74         {
75             return v ? static_cast<const node_type *>(v) : nullptr;
76         }
77         static value_type * to_value_ptr( node_type&  n )
78         {
79             return static_cast<value_type *>( &n );
80         }
81         static value_type * to_value_ptr( node_type *  n )
82         {
83             return n ? static_cast<value_type *>(n) : nullptr;
84         }
85         static const value_type * to_value_ptr( const node_type& n )
86         {
87             return static_cast<const value_type *>( &n );
88         }
89         static const value_type * to_value_ptr( const node_type * n )
90         {
91             return n ? static_cast<const value_type *>(n) : nullptr;
92         }
93     };
94
95     template <typename T, typename NodeType, class Hook>
96     struct node_traits<T, NodeType, Hook, opt::member_hook_tag>
97     {
98         typedef T        value_type;
99         typedef NodeType node_type;
100
101         static node_type * to_node_ptr( value_type& v )
102         {
103             return reinterpret_cast<node_type *>( reinterpret_cast<char *>(&v) + Hook::c_nMemberOffset );
104         }
105         static node_type * to_node_ptr( value_type * v )
106         {
107             return v ? to_node_ptr( *v ) : nullptr;
108         }
109         static const node_type * to_node_ptr( const value_type& v )
110         {
111             return reinterpret_cast<const node_type *>( reinterpret_cast<const char *>(&v) + Hook::c_nMemberOffset );
112         }
113         static const node_type * to_node_ptr( const value_type * v )
114         {
115             return v ? to_node_ptr( *v ) : nullptr;
116         }
117         static value_type * to_value_ptr( node_type& n )
118         {
119             return reinterpret_cast<value_type *>( reinterpret_cast<char *>(&n) - Hook::c_nMemberOffset );
120         }
121         static value_type * to_value_ptr( node_type * n )
122         {
123             return n ? to_value_ptr( *n ) : nullptr;
124         }
125         static const value_type * to_value_ptr( const node_type& n )
126         {
127             return reinterpret_cast<const value_type *>( reinterpret_cast<const char *>(&n) - Hook::c_nMemberOffset );
128         }
129         static const value_type * to_value_ptr( const node_type * n )
130         {
131             return n ? to_value_ptr( *n ) : nullptr;
132         }
133     };
134
135     template <typename T, typename NodeType, class Hook>
136     struct node_traits<T, NodeType, Hook, opt::traits_hook_tag>: public Hook::node_traits
137     {};
138     //@endcond
139
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.
143     */
144     template <typename T, typename NodeType, class Hook>
145     struct get_node_traits
146     {
147         //@cond
148         typedef node_traits<T, NodeType, Hook, typename Hook::hook_type> type;
149         //@endcond
150     };
151
152     //@cond
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 )
157         {
158             typedef typename Container::node_traits node_traits;
159             return node_traits::to_value_ptr( p );
160         }
161     };
162     //@endcond
163
164 }} // namespace cds::intrusuve
165
166 #endif  // #ifndef __CDS_INTRUSIVE_NODE_TRAITS_H