Replace cds::ref/boost::ref with std::ref, remove cds::unref and cds/ref.h header
[libcds.git] / cds / container / striped_set / boost_vector.h
1 //$$CDS-header$$
2
3 #ifndef __CDS_CONTAINER_STRIPED_SET_BOOST_VECTOR_ADAPTER_H
4 #define __CDS_CONTAINER_STRIPED_SET_BOOST_VECTOR_ADAPTER_H
5
6 #include <boost/version.hpp>
7 #if BOOST_VERSION < 104800
8 #   error "For boost::container::vector you must use boost 1.48 or above"
9 #endif
10
11 #include <functional>   // ref
12 #include <algorithm>    // std::lower_bound
13 #include <utility>      // std::pair
14 #include <cds/container/striped_set/adapter.h>     // lower_bound
15 #include <boost/container/vector.hpp>
16
17 //@cond
18 namespace cds { namespace container {
19     namespace striped_set {
20
21         // Copy policy for boost::container::vector
22         template <typename T, typename Alloc>
23         struct copy_item_policy< boost::container::vector< T, Alloc > >
24         {
25             typedef boost::container::vector< T, Alloc > vector_type;
26             typedef typename vector_type::iterator iterator;
27
28             void operator()( vector_type& vec, iterator itInsert, iterator itWhat )
29             {
30                 vec.insert( itInsert, *itWhat );
31             }
32         };
33
34         // Swap policy for boost::container::vector
35         template <typename T, typename Alloc>
36         struct swap_item_policy< boost::container::vector< T, Alloc > >
37         {
38             typedef boost::container::vector< T, Alloc > vector_type;
39             typedef typename vector_type::iterator iterator;
40
41             void operator()( vector_type& vec, iterator itInsert, iterator itWhat )
42             {
43                 typename vector_type::value_type newVal;
44                 itInsert = vec.insert( itInsert, newVal );
45                 std::swap( *itInsert, *itWhat );
46             }
47         };
48
49         // Move policy for boost::container::vector
50         template <typename T, typename Alloc>
51         struct move_item_policy< boost::container::vector< T, Alloc > >
52         {
53             typedef boost::container::vector< T, Alloc > vector_type;
54             typedef typename vector_type::iterator iterator;
55
56             void operator()( vector_type& vec, iterator itInsert, iterator itWhat )
57             {
58                 vec.insert( itInsert, std::move( *itWhat ));
59             }
60         };
61     }   // namespace striped_set
62 }} // namespace cds::container
63
64 namespace cds { namespace intrusive { namespace striped_set {
65
66     /// boost::container::vector adapter for hash set bucket
67     template <typename T, class Alloc, typename... Options>
68     class adapt< boost::container::vector<T, Alloc>, Options... >
69     {
70     public:
71         typedef boost::container::vector<T, Alloc>     container_type          ;   ///< underlying container type
72
73     private:
74         /// Adapted container type
75         class adapted_container: public cds::container::striped_set::adapted_sequential_container
76         {
77         public:
78             typedef typename container_type::value_type value_type  ;   ///< value type stored in the container
79             typedef typename container_type::iterator      iterator ;   ///< container iterator
80             typedef typename container_type::const_iterator const_iterator ;    ///< container const iterator
81
82             static bool const has_find_with = true;
83             static bool const has_erase_with = true;
84
85         private:
86             //@cond
87             typedef typename cds::opt::details::make_comparator_from_option_list< value_type, Options... >::type key_comparator;
88
89             typedef typename cds::opt::select<
90                 typename cds::opt::value<
91                     typename cds::opt::find_option<
92                         cds::opt::copy_policy< cds::container::striped_set::move_item >
93                         , Options...
94                     >::type
95                 >::copy_policy
96                 , cds::container::striped_set::copy_item, cds::container::striped_set::copy_item_policy<container_type>
97                 , cds::container::striped_set::swap_item, cds::container::striped_set::swap_item_policy<container_type>
98                 , cds::container::striped_set::move_item, cds::container::striped_set::move_item_policy<container_type>
99             >::type copy_item;
100
101             struct find_predicate
102             {
103                 bool operator()( value_type const& i1, value_type const& i2) const
104                 {
105                     return key_comparator()( i1, i2 ) < 0;
106                 }
107
108                 template <typename Q>
109                 bool operator()( Q const& i1, value_type const& i2) const
110                 {
111                     return key_comparator()( i1, i2 ) < 0;
112                 }
113
114                 template <typename Q>
115                 bool operator()( value_type const& i1, Q const& i2) const
116                 {
117                     return key_comparator()( i1, i2 ) < 0;
118                 }
119             };
120             //@endcond
121
122         private:
123             //@cond
124             container_type  m_Vector;
125             //@endcond
126
127         public:
128             template <typename Q, typename Func>
129             bool insert( const Q& val, Func f )
130             {
131                 iterator it = std::lower_bound( m_Vector.begin(), m_Vector.end(), val, find_predicate() );
132                 if ( it == m_Vector.end() || key_comparator()( val, *it ) != 0 ) {
133                     value_type newItem( val );
134                     it = m_Vector.insert( it, newItem );
135                     f( *it );
136                     return true;
137                 }
138                 return false;
139             }
140
141             template <typename... Args>
142             bool emplace( Args&&... args )
143             {
144                 value_type val( std::forward<Args>(args)... );
145                 iterator it = std::lower_bound( m_Vector.begin(), m_Vector.end(), val, find_predicate() );
146                 if ( it == m_Vector.end() || key_comparator()( val, *it ) != 0 ) {
147                     it = m_Vector.emplace( it, std::move( val ) );
148                     return true;
149                 }
150                 return false;
151             }
152
153             template <typename Q, typename Func>
154             std::pair<bool, bool> ensure( const Q& val, Func func )
155             {
156                 iterator it = std::lower_bound( m_Vector.begin(), m_Vector.end(), val, find_predicate() );
157                 if ( it == m_Vector.end() || key_comparator()( val, *it ) != 0 ) {
158                     // insert new
159                     value_type newItem( val );
160                     it = m_Vector.insert( it, newItem );
161                     func( true, *it, val );
162                     return std::make_pair( true, true );
163                 }
164                 else {
165                     // already exists
166                     func( false, *it, val );
167                     return std::make_pair( true, false );
168                 }
169             }
170
171             template <typename Q, typename Func>
172             bool erase( const Q& key, Func f )
173             {
174                 iterator it = std::lower_bound( m_Vector.begin(), m_Vector.end(), key, find_predicate() );
175                 if ( it == m_Vector.end() || key_comparator()( key, *it ) != 0 )
176                     return false;
177
178                 // key exists
179                 f( *it );
180                 m_Vector.erase( it );
181                 return true;
182             }
183
184             template <typename Q, typename Less, typename Func>
185             bool erase( Q const& key, Less pred, Func f )
186             {
187                 iterator it = std::lower_bound( m_Vector.begin(), m_Vector.end(), key, pred );
188                 if ( it == m_Vector.end() || pred( key, *it ) || pred( *it, key ) )
189                     return false;
190
191                 // key exists
192                 f( *it );
193                 m_Vector.erase( it );
194                 return true;
195             }
196
197             template <typename Q, typename Func>
198             bool find( Q& val, Func f )
199             {
200                 iterator it = std::lower_bound( m_Vector.begin(), m_Vector.end(), val, find_predicate() );
201                 if ( it == m_Vector.end() || key_comparator()( val, *it ) != 0 )
202                     return false;
203
204                 // key exists
205                 f( *it, val );
206                 return true;
207             }
208
209             template <typename Q, typename Less, typename Func>
210             bool find( Q& val, Less pred, Func f )
211             {
212                 iterator it = std::lower_bound( m_Vector.begin(), m_Vector.end(), val, pred );
213                 if ( it == m_Vector.end() || pred( val, *it ) || pred( *it, val ) )
214                     return false;
215
216                 // key exists
217                 f( *it, val );
218                 return true;
219             }
220
221             /// Clears the container
222             void clear()
223             {
224                 m_Vector.clear();
225             }
226
227             iterator begin()                { return m_Vector.begin(); }
228             const_iterator begin() const    { return m_Vector.begin(); }
229             iterator end()                  { return m_Vector.end(); }
230             const_iterator end() const      { return m_Vector.end(); }
231
232             void move_item( adapted_container& /*from*/, iterator itWhat )
233             {
234                 iterator it = std::lower_bound( m_Vector.begin(), m_Vector.end(), *itWhat, find_predicate() );
235                 assert( it == m_Vector.end() || key_comparator()( *itWhat, *it ) != 0 );
236
237                 copy_item()( m_Vector, it, itWhat );
238             }
239
240             size_t size() const
241             {
242                 return m_Vector.size();
243             }
244         };
245
246     public:
247         typedef adapted_container type ; ///< Result of \p adapt metafunction
248
249     };
250 }}} // namespace cds::intrusive::striped_set
251
252
253 //@endcond
254
255 #endif // #ifndef __CDS_CONTAINER_STRIPED_SET_BOOST_VECTOR_ADAPTER_H