a65aa37c21b7e5762d9100d5383c2326ebd2e633
[libcds.git] / cds / container / details / make_skip_list_set.h
1 //$$CDS-header$$
2
3 #ifndef __CDS_CONTAINER_DETAILS_MAKE_SKIP_LIST_SET_H
4 #define __CDS_CONTAINER_DETAILS_MAKE_SKIP_LIST_SET_H
5
6 #include <cds/container/details/skip_list_base.h>
7 #include <cds/details/binary_functor_wrapper.h>
8
9 //@cond
10 namespace cds { namespace container { namespace details {
11
12     template <typename GC, typename T, typename Traits>
13     struct make_skip_list_set
14     {
15         typedef GC      gc;
16         typedef T       value_type;
17         typedef Traits  traits;
18
19         typedef cds::intrusive::skip_list::node< gc >   intrusive_node_type;
20         struct node_type: public intrusive_node_type
21         {
22             typedef intrusive_node_type                     base_class;
23             typedef typename base_class::atomic_marked_ptr  atomic_marked_ptr;
24             typedef value_type                              stored_value_type;
25
26             value_type m_Value;
27             //atomic_marked_ptr m_arrTower[] ;  // allocated together with node_type in single memory block
28
29             template <typename Q>
30             node_type( unsigned int nHeight, atomic_marked_ptr * pTower, Q const& v )
31                 : m_Value(v)
32             {
33                 if ( nHeight > 1 ) {
34                     new (pTower) atomic_marked_ptr[ nHeight - 1 ];
35                     base_class::make_tower( nHeight, pTower );
36                 }
37             }
38
39             template <typename Q, typename... Args>
40             node_type( unsigned int nHeight, atomic_marked_ptr * pTower, Q&& q, Args&&... args )
41                 : m_Value( std::forward<Q>(q), std::forward<Args>(args)... )
42             {
43                 if ( nHeight > 1 ) {
44                     new (pTower) atomic_marked_ptr[ nHeight - 1 ];
45                     base_class::make_tower( nHeight, pTower );
46                 }
47             }
48
49         private:
50             node_type() ;   // no default ctor
51         };
52
53         typedef skip_list::details::node_allocator< node_type, traits> node_allocator;
54
55         struct node_deallocator {
56             void operator ()( node_type * pNode )
57             {
58                 node_allocator().Delete( pNode );
59             }
60         };
61
62         typedef skip_list::details::dummy_node_builder<intrusive_node_type> dummy_node_builder;
63
64         struct value_accessor
65         {
66             value_type const& operator()( node_type const& node ) const
67             {
68                 return node.m_Value;
69             }
70         };
71         typedef typename opt::details::make_comparator< value_type, traits >::type key_comparator;
72
73         template <typename Less>
74         struct less_wrapper {
75             typedef cds::details::compare_wrapper< node_type, cds::opt::details::make_comparator_from_less<Less>, value_accessor >    type;
76         };
77
78         class intrusive_traits: public cds::intrusive::skip_list::make_traits<
79             cds::opt::type_traits< traits >
80             ,cds::intrusive::opt::hook< intrusive::skip_list::base_hook< cds::opt::gc< gc > > >
81             ,cds::intrusive::opt::disposer< node_deallocator >
82             ,cds::intrusive::skip_list::internal_node_builder< dummy_node_builder >
83             ,cds::opt::compare< cds::details::compare_wrapper< node_type, key_comparator, value_accessor > >
84         >::type
85         {};
86
87         typedef cds::intrusive::SkipListSet< gc, node_type, intrusive_traits>   type;
88     };
89 }}} // namespace cds::container::details
90 //@endcond
91
92 #endif //#ifndef __CDS_CONTAINER_DETAILS_MAKE_SKIP_LIST_SET_H