Merge branch 'dev' of github.com:khizmax/libcds into dev
[libcds.git] / tests / unit / map2 / std_hash_map.h
1 //$$CDS-header$$
2
3 #ifndef CDSUNIT_STD_HASH_MAP_GCC_H
4 #define CDSUNIT_STD_HASH_MAP_GCC_H
5
6 #include <mutex>    //unique_lock
7 #include <unordered_map>
8
9 namespace map2 {
10
11     template <typename Key, typename Value, typename Lock,
12         class Alloc = typename CDS_DEFAULT_ALLOCATOR::template rebind<std::pair<Key const, Value> >::other
13     >
14     class StdHashMap
15         : public std::unordered_map<
16             Key, Value
17             , std::hash<Key>
18             , std::equal_to<Key>
19             , Alloc
20         >
21     {
22     public:
23         Lock m_lock;
24         typedef std::unique_lock<Lock> scoped_lock;
25         typedef std::unordered_map<
26             Key, Value
27             , std::hash<Key>
28             , std::equal_to<Key>
29             , Alloc
30         >   base_class;
31     public:
32         typedef typename base_class::mapped_type value_type;
33         typedef size_t      item_counter;
34
35         StdHashMap()
36         {}
37
38         template <class Config>
39         StdHashMap( Config const& )
40         {}
41
42         bool contains( const Key& key )
43         {
44             scoped_lock al( m_lock );
45             return base_class::find( key ) != base_class::end();
46         }
47
48         bool insert( const Key& key, const Value& val )
49         {
50             scoped_lock al( m_lock );
51             return base_class::insert( typename base_class::value_type(key, val)).second;
52         }
53
54         template <typename T, typename Func>
55         bool insert( const Key& key, const T& val, Func func )
56         {
57             scoped_lock al( m_lock );
58             std::pair<typename base_class::iterator, bool> pRet = base_class::insert( typename base_class::value_type(key, Value() ));
59             if ( pRet.second ) {
60                 func( pRet.first->second, val );
61                 return true;
62             }
63             return false;
64         }
65
66         template <typename T, typename Func>
67         std::pair<bool, bool> update( const T& key, Func func, bool /*bAllowInsert*/ = true )
68         {
69             scoped_lock al( m_lock );
70             std::pair<typename base_class::iterator, bool> pRet = base_class::insert( typename base_class::value_type( key, Value() ));
71             if ( pRet.second ) {
72                 func( true, *pRet.first );
73                 return std::make_pair( true, true );
74             }
75             else {
76                 func( false, *pRet.first );
77                 return std::make_pair( true, false );
78             }
79         }
80
81         bool erase( const Key& key )
82         {
83             scoped_lock al( m_lock );
84             return base_class::erase( key ) != 0;
85         }
86
87         template <typename T, typename Func>
88         bool erase( const T& key, Func func )
89         {
90             scoped_lock al( m_lock );
91             typename base_class::iterator it = base_class::find( key );
92             if ( it != base_class::end() ) {
93                 func( *it );
94                 return base_class::erase( key ) != 0;
95             }
96             return false;
97         }
98
99         std::ostream& dump( std::ostream& stm ) { return stm; }
100
101
102         // for testing
103         static CDS_CONSTEXPR bool const c_bExtractSupported = false;
104         static CDS_CONSTEXPR bool const c_bLoadFactorDepended = false;
105         static CDS_CONSTEXPR bool const c_bEraseExactKey = false;
106     };
107 }   // namespace map2
108
109 #endif  // #ifndef CDSUNIT_STD_HASH_MAP_GCC_H