Replace cds::ref/boost::ref with std::ref, remove cds::unref and cds/ref.h header
[libcds.git] / cds / container / striped_set / std_hash_set_std.h
1 //$$CDS-header$$
2
3 #ifndef __CDS_CONTAINER_STRIPED_SET_STD_HASH_SET_STD_ADAPTER_H
4 #define __CDS_CONTAINER_STRIPED_SET_STD_HASH_SET_STD_ADAPTER_H
5
6 #ifndef __CDS_CONTAINER_STRIPED_SET_STD_HASH_SET_ADAPTER_H
7 #   error <cds/container/striped_set/std_hash_set.h> must be included instead of <cds/container/striped_set/std_hash_set_std.h> header
8 #endif
9
10 #include <cds/container/striped_set/adapter.h>
11 #include <unordered_set>
12
13 //@cond
14 namespace cds { namespace container {
15     namespace striped_set {
16
17         // Copy policy for std::unordered_set
18         template <typename T, typename Hash, typename Pred, typename Alloc>
19         struct copy_item_policy< std::unordered_set< T, Hash, Pred, Alloc > >
20         {
21             typedef std::unordered_set< T, Hash, Pred, Alloc > set_type;
22             typedef typename set_type::iterator iterator;
23
24             void operator()( set_type& set, iterator itWhat )
25             {
26                 set.insert( *itWhat );
27             }
28         };
29
30         template <typename T, typename Hash, typename Pred, typename Alloc>
31         struct swap_item_policy< std::unordered_set< T, Hash, Pred, Alloc > >: public copy_item_policy< std::unordered_set< T, Hash, Pred, Alloc > >
32         {};
33
34         // Move policy for std::unordered_set
35         template <typename T, typename Hash, typename Pred, typename Alloc>
36         struct move_item_policy< std::unordered_set< T, Hash, Pred, Alloc > >
37         {
38             typedef std::unordered_set< T, Hash, Pred, Alloc > set_type;
39             typedef typename set_type::iterator iterator;
40
41             void operator()( set_type& set, iterator itWhat )
42             {
43                 set.insert( std::move( *itWhat ) );
44             }
45         };
46
47     }   // namespace striped_set
48 }} // namespace cds::container
49
50 namespace cds { namespace intrusive { namespace striped_set {
51     /// std::unordered_set  adapter for hash set bucket
52     template <typename T, class Hash, class Pred, class Alloc, typename... Options>
53     class adapt< std::unordered_set<T, Hash, Pred, Alloc>, Options... >
54     {
55     public:
56         typedef std::unordered_set<T, Hash, Pred, Alloc>  container_type  ;   ///< underlying container type
57
58     private:
59         /// Adapted container type
60         class adapted_container: public cds::container::striped_set::adapted_container
61         {
62         public:
63             typedef typename container_type::value_type value_type  ;   ///< value type stored in the container
64             typedef typename container_type::iterator      iterator ;   ///< container iterator
65             typedef typename container_type::const_iterator const_iterator ;    ///< container const iterator
66
67             static bool const has_find_with = false;
68             static bool const has_erase_with = false;
69
70         private:
71             //@cond
72             typedef typename cds::opt::select<
73                 typename cds::opt::value<
74                     typename cds::opt::find_option<
75                         cds::opt::copy_policy< cds::container::striped_set::move_item >
76                         , Options...
77                     >::type
78                 >::copy_policy
79                 , cds::container::striped_set::copy_item, cds::container::striped_set::copy_item_policy<container_type>
80                 , cds::container::striped_set::swap_item, cds::container::striped_set::swap_item_policy<container_type> // not defined
81                 , cds::container::striped_set::move_item, cds::container::striped_set::move_item_policy<container_type>
82             >::type copy_item;
83             //@endcond
84
85         private:
86             //@cond
87             container_type  m_Set;
88             //@endcond
89
90         public:
91             template <typename Q, typename Func>
92             bool insert( const Q& val, Func f )
93             {
94                 std::pair<iterator, bool> res = m_Set.insert( value_type(val) );
95                 if ( res.second )
96                     ::f( const_cast<value_type&>(*res.first) );
97                 return res.second;
98             }
99
100             template <typename... Args>
101             bool emplace( Args&&... args )
102             {
103                 std::pair<iterator, bool> res = m_Set.emplace( std::forward<Args>(args)... );
104                 return res.second;
105             }
106
107             template <typename Q, typename Func>
108             std::pair<bool, bool> ensure( const Q& val, Func func )
109             {
110                 std::pair<iterator, bool> res = m_Set.insert( value_type(val) );
111                 func( res.second, const_cast<value_type&>(*res.first), val );
112                 return std::make_pair( true, res.second );
113             }
114
115             template <typename Q, typename Func>
116             bool erase( const Q& key, Func f )
117             {
118                 const_iterator it = m_Set.find( value_type(key) );
119                 if ( it == m_Set.end() )
120                     return false;
121                 f( const_cast<value_type&>(*it) );
122                 m_Set.erase( it );
123                 return true;
124             }
125
126             template <typename Q, typename Func>
127             bool find( Q& val, Func f )
128             {
129                 iterator it = m_Set.find( value_type(val) );
130                 if ( it == m_Set.end() )
131                     return false;
132                 f( const_cast<value_type&>(*it), val );
133                 return true;
134             }
135
136             /// Clears the container
137             void clear()
138             {
139                 m_Set.clear();
140             }
141
142             iterator begin()                { return m_Set.begin(); }
143             const_iterator begin() const    { return m_Set.begin(); }
144             iterator end()                  { return m_Set.end(); }
145             const_iterator end() const      { return m_Set.end(); }
146
147             void move_item( adapted_container& /*from*/, iterator itWhat )
148             {
149                 assert( m_Set.find( *itWhat ) == m_Set.end() );
150                 copy_item()( m_Set, itWhat );
151             }
152
153             size_t size() const
154             {
155                 return m_Set.size();
156             }
157         };
158
159     public:
160         typedef adapted_container type ; ///< Result of \p adapt metafunction
161     };
162 }}} // namespace cds::intrusive::striped_set
163
164
165 //@endcond
166
167 #endif  // #ifndef __CDS_CONTAINER_STRIPED_SET_STD_HASH_SET_STD_ADAPTER_H