3 #ifndef CDSLIB_INTRUSIVE_DETAILS_SINGLE_LINK_STRUCT_H
4 #define CDSLIB_INTRUSIVE_DETAILS_SINGLE_LINK_STRUCT_H
6 #include <cds/intrusive/details/base.h>
7 #include <cds/gc/default_gc.h>
8 #include <cds/algo/atomic.h>
10 namespace cds { namespace intrusive {
12 /// Definitions common for single-linked data structures
13 /** @ingroup cds_intrusive_helper
15 namespace single_link {
20 - GC - garbage collector used
21 - Tag - a tag used to distinguish between different implementation
23 template <class GC, typename Tag = opt::none>
26 typedef GC gc ; ///< Garbage collector
27 typedef Tag tag ; ///< tag
29 typedef typename gc::template atomic_ref<node> atomic_node_ptr ; ///< atomic pointer
31 /// Rebind node for other template parameters
32 template <class GC2, typename Tag2 = tag>
34 typedef node<GC2, Tag2> other ; ///< Rebinding result
37 atomic_node_ptr m_pNext ; ///< pointer to the next node in the container
41 m_pNext.store( nullptr, atomics::memory_order_release );
47 typedef cds::gc::default_gc gc;
48 typedef opt::none tag;
53 template < typename HookType, typename... Options>
56 typedef typename opt::make_options< default_hook, Options...>::type options;
57 typedef typename options::gc gc;
58 typedef typename options::tag tag;
59 typedef node<gc, tag> node_type;
60 typedef HookType hook_type;
67 - opt::gc - garbage collector used.
70 template < typename... Options >
71 struct base_hook: public hook< opt::base_hook_tag, Options... >
76 \p MemberOffset defines offset in bytes of \ref node member into your structure.
77 Use \p offsetof macro to define \p MemberOffset
80 - opt::gc - garbage collector used.
83 template < size_t MemberOffset, typename... Options >
84 struct member_hook: public hook< opt::member_hook_tag, Options... >
87 static const size_t c_nMemberOffset = MemberOffset;
93 \p NodeTraits defines type traits for node.
94 See \ref node_traits for \p NodeTraits interface description
97 - opt::gc - garbage collector used.
100 template <typename NodeTraits, typename... Options >
101 struct traits_hook: public hook< opt::traits_hook_tag, Options... >
104 typedef NodeTraits node_traits;
109 template <typename Node>
110 struct link_checker {
112 typedef Node node_type;
115 /// Checks if the link field of node \p pNode is \p nullptr
117 An asserting is generated if \p pNode link field is not \p nullptr
119 static void is_empty( const node_type * pNode )
121 assert( pNode->m_pNext.load( atomics::memory_order_relaxed ) == nullptr );
127 template <class GC, typename Node, opt::link_check_type LinkType >
128 struct link_checker_selector;
130 template <typename GC, typename Node>
131 struct link_checker_selector< GC, Node, opt::never_check_link >
133 typedef intrusive::opt::v::empty_link_checker<Node> type;
136 template <typename GC, typename Node>
137 struct link_checker_selector< GC, Node, opt::debug_check_link >
140 typedef link_checker<Node> type;
142 typedef intrusive::opt::v::empty_link_checker<Node> type;
146 template <typename GC, typename Node>
147 struct link_checker_selector< GC, Node, opt::always_check_link >
149 typedef link_checker<Node> type;
153 /// Metafunction for selecting appropriate link checking policy
154 template < typename Node, opt::link_check_type LinkType >
155 struct get_link_checker
158 typedef typename link_checker_selector< typename Node::gc, Node, LinkType>::type type;
162 } // namespace single_link
164 }} // namespace cds::intrusive
168 #endif // #ifndef CDSLIB_INTRUSIVE_DETAILS_SINGLE_LINK_STRUCT_H