2 This file is a part of libcds - Concurrent Data Structures library
4 (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
6 Source code repo: http://github.com/khizmax/libcds/
7 Download: http://sourceforge.net/projects/libcds/files/
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions are met:
12 * Redistributions of source code must retain the above copyright notice, this
13 list of conditions and the following disclaimer.
15 * Redistributions in binary form must reproduce the above copyright notice,
16 this list of conditions and the following disclaimer in the documentation
17 and/or other materials provided with the distribution.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #ifndef CDSLIB_INTRUSIVE_DETAILS_NODE_TRAITS_H
32 #define CDSLIB_INTRUSIVE_DETAILS_NODE_TRAITS_H
34 #include <cds/intrusive/options.h>
36 namespace cds { namespace intrusive {
38 #ifdef CDS_DOXYGEN_INVOKED
39 /// Container's node traits
40 /** @ingroup cds_intrusive_helper
41 This traits is intended for converting between type \p T of value stored in the intrusive container
42 and container's node type \p NodeType.
44 There are separate specializations for each \p Hook type.
46 template <typename T, typename NodeType, typename Hook>
49 typedef T value_type ; ///< Value type
50 typedef NodeType node_type ; ///< Node type
52 /// Convert value reference to node pointer
53 static node_type * to_node_ptr( value_type& v );
55 /// Convert value pointer to node pointer
56 static node_type * to_node_ptr( value_type * v );
58 /// Convert value reference to node pointer (const version)
59 static const node_type * to_node_ptr( value_type const& v );
61 /// Convert value pointer to node pointer (const version)
62 static const node_type * to_node_ptr( value_type const * v );
64 /// Convert node refernce to value pointer
65 static value_type * to_value_ptr( node_type& n );
67 /// Convert node pointer to value pointer
68 static value_type * to_value_ptr( node_type * n );
70 /// Convert node reference to value pointer (const version)
71 static const value_type * to_value_ptr( node_type const & n );
73 /// Convert node pointer to value pointer (const version)
74 static const value_type * to_value_ptr( node_type const * n );
78 template <typename T, typename NodeType, class Hook, typename HookType>
83 template <typename T, typename NodeType, class Hook>
84 struct node_traits<T, NodeType, Hook, opt::base_hook_tag>
87 typedef NodeType node_type;
89 static node_type * to_node_ptr( value_type& v )
91 return static_cast<node_type *>( &v );
93 static node_type * to_node_ptr( value_type * v )
95 return v ? static_cast<node_type *>(v) : nullptr;
97 static const node_type * to_node_ptr( const value_type& v )
99 return static_cast<const node_type *>( &v );
101 static const node_type * to_node_ptr( const value_type * v )
103 return v ? static_cast<const node_type *>(v) : nullptr;
105 static value_type * to_value_ptr( node_type& n )
107 return static_cast<value_type *>( &n );
109 static value_type * to_value_ptr( node_type * n )
111 return n ? static_cast<value_type *>(n) : nullptr;
113 static const value_type * to_value_ptr( const node_type& n )
115 return static_cast<const value_type *>( &n );
117 static const value_type * to_value_ptr( const node_type * n )
119 return n ? static_cast<const value_type *>(n) : nullptr;
123 template <typename T, typename NodeType, class Hook>
124 struct node_traits<T, NodeType, Hook, opt::member_hook_tag>
126 typedef T value_type;
127 typedef NodeType node_type;
129 static node_type * to_node_ptr( value_type& v )
131 return reinterpret_cast<node_type *>( reinterpret_cast<char *>(&v) + Hook::c_nMemberOffset );
133 static node_type * to_node_ptr( value_type * v )
135 return v ? to_node_ptr( *v ) : nullptr;
137 static const node_type * to_node_ptr( const value_type& v )
139 return reinterpret_cast<const node_type *>( reinterpret_cast<const char *>(&v) + Hook::c_nMemberOffset );
141 static const node_type * to_node_ptr( const value_type * v )
143 return v ? to_node_ptr( *v ) : nullptr;
145 static value_type * to_value_ptr( node_type& n )
147 return reinterpret_cast<value_type *>( reinterpret_cast<char *>(&n) - Hook::c_nMemberOffset );
149 static value_type * to_value_ptr( node_type * n )
151 return n ? to_value_ptr( *n ) : nullptr;
153 static const value_type * to_value_ptr( const node_type& n )
155 return reinterpret_cast<const value_type *>( reinterpret_cast<const char *>(&n) - Hook::c_nMemberOffset );
157 static const value_type * to_value_ptr( const node_type * n )
159 return n ? to_value_ptr( *n ) : nullptr;
163 template <typename T, typename NodeType, class Hook>
164 struct node_traits<T, NodeType, Hook, opt::traits_hook_tag>: public Hook::node_traits
168 /// Node traits selector metafunction
169 /** @ingroup cds_intrusive_helper
170 The metafunction selects appropriate \ref node_traits specialization based on value type \p T, node type \p NodeType, and hook type \p Hook.
172 template <typename T, typename NodeType, class Hook>
173 struct get_node_traits
176 typedef node_traits<T, NodeType, Hook, typename Hook::hook_type> type;
181 /// Functor converting container's node type to value type
183 template <class Container>
184 struct node_to_value {
185 typename Container::value_type * operator()( typename Container::node_type * p ) const
187 typedef typename Container::node_traits node_traits;
188 return node_traits::to_value_ptr( p );
193 }} // namespace cds::intrusuve
195 #endif // #ifndef CDSLIB_INTRUSIVE_DETAILS_NODE_TRAITS_H