3 #ifndef __CDS_CONTAINER_DETAILS_MAKE_SKIP_LIST_MAP_H
4 #define __CDS_CONTAINER_DETAILS_MAKE_SKIP_LIST_MAP_H
6 #include <cds/container/skip_list_base.h>
7 #include <cds/details/binary_functor_wrapper.h>
10 namespace cds { namespace container { namespace details {
12 template <typename GC, typename K, typename T, typename Traits>
13 struct make_skip_list_map
17 typedef T mapped_type;
18 typedef std::pair< key_type const, mapped_type> value_type;
19 typedef Traits type_traits;
21 typedef cds::intrusive::skip_list::node< gc > intrusive_node_type;
22 struct node_type: public intrusive_node_type
24 typedef intrusive_node_type base_class;
25 typedef typename base_class::atomic_marked_ptr atomic_marked_ptr;
26 typedef value_type stored_value_type;
29 //atomic_marked_ptr m_arrTower[] ; // allocated together with node_type in single memory block
32 node_type( unsigned int nHeight, atomic_marked_ptr * pTower, Q const& key )
33 : m_Value( std::make_pair( key, mapped_type() ))
35 init_tower( nHeight, pTower );
38 template <typename Q, typename U>
39 node_type( unsigned int nHeight, atomic_marked_ptr * pTower, Q const& key, U const& val )
40 : m_Value( std::make_pair( key, val ))
42 init_tower( nHeight, pTower );
45 # ifdef CDS_EMPLACE_SUPPORT
46 template <typename Q, typename... Args>
47 node_type( unsigned int nHeight, atomic_marked_ptr * pTower, Q&& key, Args&&... args )
48 : m_Value( std::forward<Q>(key), std::move( mapped_type( std::forward<Args>(args)... )))
50 init_tower( nHeight, pTower );
55 node_type() ; // no default ctor
57 void init_tower( unsigned int nHeight, atomic_marked_ptr * pTower )
60 new (pTower) atomic_marked_ptr[ nHeight - 1 ];
61 base_class::make_tower( nHeight, pTower );
66 class node_allocator: public skip_list::details::node_allocator< node_type, type_traits>
68 typedef skip_list::details::node_allocator< node_type, type_traits> base_class;
71 node_type * New( unsigned int nHeight, Q const& key )
73 return base_class::New( nHeight, key );
75 template <typename Q, typename U>
76 node_type * New( unsigned int nHeight, Q const& key, U const& val )
78 unsigned char * pMem = base_class::alloc_space( nHeight );
81 nHeight > 1 ? reinterpret_cast<typename base_class::node_tower_item *>( pMem + base_class::c_nNodeSize ) : nullptr,
85 # ifdef CDS_EMPLACE_SUPPORT
86 template <typename... Args>
87 node_type * New( unsigned int nHeight, Args&&... args )
89 unsigned char * pMem = base_class::alloc_space( nHeight );
92 nHeight > 1 ? reinterpret_cast<typename base_class::node_tower_item *>( pMem + base_class::c_nNodeSize ) : nullptr,
93 std::forward<Args>(args)...
99 struct node_deallocator {
100 void operator ()( node_type * pNode )
102 node_allocator().Delete( pNode );
106 typedef skip_list::details::dummy_node_builder<intrusive_node_type> dummy_node_builder;
110 key_type const & operator()( node_type const& node ) const
112 return node.m_Value.first;
115 typedef typename opt::details::make_comparator< key_type, type_traits >::type key_comparator;
117 class intrusive_type_traits: public cds::intrusive::skip_list::make_traits<
118 cds::opt::type_traits< type_traits >
119 ,cds::intrusive::opt::hook< intrusive::skip_list::base_hook< cds::opt::gc< gc > > >
120 ,cds::intrusive::opt::disposer< node_deallocator >
121 ,cds::intrusive::skip_list::internal_node_builder< dummy_node_builder >
122 ,cds::opt::compare< cds::details::compare_wrapper< node_type, key_comparator, key_accessor > >
126 typedef cds::intrusive::SkipListSet< gc, node_type, intrusive_type_traits> type;
129 }}} // namespace cds::container::details
132 #endif // __CDS_CONTAINER_DETAILS_MAKE_SKIP_LIST_MAP_H