3 #ifndef CDSLIB_CONTAINER_STRIPED_MAP_STD_HASH_MAP_ADAPTER_H
4 #define CDSLIB_CONTAINER_STRIPED_MAP_STD_HASH_MAP_ADAPTER_H
6 #include <cds/container/striped_set/adapter.h>
7 #include <unordered_map>
10 namespace cds { namespace container {
11 namespace striped_set {
13 // Copy policy for map
14 template <typename Key, typename T, typename Hash, typename Pred, typename Alloc>
15 struct copy_item_policy< std::unordered_map< Key, T, Hash, Pred, Alloc > >
17 typedef std::unordered_map< Key, T, Hash, Pred, Alloc > map_type;
18 typedef typename map_type::value_type pair_type;
19 typedef typename map_type::iterator iterator;
21 void operator()( map_type& map, iterator itWhat )
23 map.insert( *itWhat );
27 // Swap policy for map
28 template <typename Key, typename T, typename Hash, typename Pred, typename Alloc>
29 struct swap_item_policy< std::unordered_map< Key, T, Hash, Pred, Alloc > >
31 typedef std::unordered_map< Key, T, Hash, Pred, Alloc > map_type;
32 typedef typename map_type::value_type pair_type;
33 typedef typename map_type::iterator iterator;
35 void operator()( map_type& map, iterator itWhat )
37 pair_type pair( itWhat->first, typename pair_type::second_type() );
38 std::pair<iterator, bool> res = map.insert( pair );
40 std::swap( res.first->second, itWhat->second );
44 // Move policy for map
45 template <typename Key, typename T, typename Hash, typename Pred, typename Alloc>
46 struct move_item_policy< std::unordered_map< Key, T, Hash, Pred, Alloc > >
48 typedef std::unordered_map< Key, T, Hash, Pred, Alloc > map_type;
49 typedef typename map_type::value_type pair_type;
50 typedef typename map_type::iterator iterator;
52 void operator()( map_type& map, iterator itWhat )
54 map.insert( std::move( *itWhat ) );
57 } // namespace striped_set
58 }} // namespace cds::container
60 namespace cds { namespace intrusive { namespace striped_set {
62 /// std::unordered_map adapter for hash map bucket
63 template <typename Key, typename T, class Hash, class Pred, class Alloc, typename... Options>
64 class adapt< std::unordered_map< Key, T, Hash, Pred, Alloc>, Options... >
67 typedef std::unordered_map< Key, T, Hash, Pred, Alloc> container_type ; ///< underlying container type
70 /// Adapted container type
71 class adapted_container: public cds::container::striped_set::adapted_container
74 typedef typename container_type::value_type value_type ; ///< value type stored in the container
75 typedef typename container_type::key_type key_type;
76 typedef typename container_type::mapped_type mapped_type;
77 typedef typename container_type::iterator iterator ; ///< container iterator
78 typedef typename container_type::const_iterator const_iterator ; ///< container const iterator
80 static bool const has_find_with = false;
81 static bool const has_erase_with = false;
85 typedef typename cds::opt::select<
86 typename cds::opt::value<
87 typename cds::opt::find_option<
88 cds::opt::copy_policy< cds::container::striped_set::move_item >
92 , cds::container::striped_set::copy_item, cds::container::striped_set::copy_item_policy<container_type>
93 , cds::container::striped_set::swap_item, cds::container::striped_set::swap_item_policy<container_type>
94 , cds::container::striped_set::move_item, cds::container::striped_set::move_item_policy<container_type>
100 container_type m_Map;
104 template <typename Q, typename Func>
105 bool insert( const Q& key, Func f )
107 std::pair<iterator, bool> res = m_Map.insert( value_type( key, mapped_type() ));
109 f( const_cast<value_type&>(*res.first) );
113 template <typename Q, typename... Args>
114 bool emplace( Q&& key, Args&&... args )
116 std::pair<iterator, bool> res = m_Map.emplace( std::forward<Q>(key), std::move( mapped_type(std::forward<Args>(args)...)) );
120 template <typename Q, typename Func>
121 std::pair<bool, bool> ensure( const Q& key, Func func )
123 std::pair<iterator, bool> res = m_Map.insert( value_type( key, mapped_type() ) );
124 func( res.second, const_cast<value_type&>(*res.first));
125 return std::make_pair( true, res.second );
128 template <typename Q, typename Func>
129 bool erase( const Q& key, Func f )
131 iterator it = m_Map.find( key_type(key) );
132 if ( it == m_Map.end() )
134 f( const_cast<value_type&>(*it) );
139 template <typename Q, typename Func>
140 bool find( Q& val, Func f )
142 iterator it = m_Map.find( key_type(val) );
143 if ( it == m_Map.end() )
145 f( const_cast<value_type&>(*it), val );
154 iterator begin() { return m_Map.begin(); }
155 const_iterator begin() const { return m_Map.begin(); }
156 iterator end() { return m_Map.end(); }
157 const_iterator end() const { return m_Map.end(); }
159 void move_item( adapted_container& /*from*/, iterator itWhat )
161 assert( m_Map.find( itWhat->first ) == m_Map.end() );
162 copy_item()( m_Map, itWhat );
172 typedef adapted_container type ; ///< Result of \p adapt metafunction
175 }}} // namespace cds::intrusive::striped_set
180 #endif // #ifndef CDSLIB_CONTAINER_STRIPED_MAP_STD_HASH_MAP_ADAPTER_H