3 #ifndef __CDS_CONTAINER_STRIPED_SET_BOOST_VECTOR_ADAPTER_H
4 #define __CDS_CONTAINER_STRIPED_SET_BOOST_VECTOR_ADAPTER_H
6 #include <boost/version.hpp>
7 #if BOOST_VERSION < 104800
8 # error "For boost::container::vector you must use boost 1.48 or above"
11 #include <cds/container/striped_set/adapter.h> // lower_bound
13 #include <boost/container/vector.hpp>
14 #include <algorithm> // std::lower_bound
15 #include <utility> // std::pair
18 namespace cds { namespace container {
19 namespace striped_set {
21 // Copy policy for boost::container::vector
22 template <typename T, typename Alloc>
23 struct copy_item_policy< boost::container::vector< T, Alloc > >
25 typedef boost::container::vector< T, Alloc > vector_type;
26 typedef typename vector_type::iterator iterator;
28 void operator()( vector_type& vec, iterator itInsert, iterator itWhat )
30 vec.insert( itInsert, *itWhat );
34 // Swap policy for boost::container::vector
35 template <typename T, typename Alloc>
36 struct swap_item_policy< boost::container::vector< T, Alloc > >
38 typedef boost::container::vector< T, Alloc > vector_type;
39 typedef typename vector_type::iterator iterator;
41 void operator()( vector_type& vec, iterator itInsert, iterator itWhat )
43 typename vector_type::value_type newVal;
44 itInsert = vec.insert( itInsert, newVal );
45 std::swap( *itInsert, *itWhat );
49 // Move policy for boost::container::vector
50 template <typename T, typename Alloc>
51 struct move_item_policy< boost::container::vector< T, Alloc > >
53 typedef boost::container::vector< T, Alloc > vector_type;
54 typedef typename vector_type::iterator iterator;
56 void operator()( vector_type& vec, iterator itInsert, iterator itWhat )
58 vec.insert( itInsert, std::move( *itWhat ));
61 } // namespace striped_set
62 }} // namespace cds::container
64 namespace cds { namespace intrusive { namespace striped_set {
66 /// boost::container::vector adapter for hash set bucket
67 template <typename T, class Alloc, CDS_SPEC_OPTIONS>
68 class adapt< boost::container::vector<T, Alloc>, CDS_OPTIONS >
71 typedef boost::container::vector<T, Alloc> container_type ; ///< underlying container type
74 /// Adapted container type
75 class adapted_container: public cds::container::striped_set::adapted_sequential_container
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
82 static bool const has_find_with = true;
83 static bool const has_erase_with = true;
87 typedef typename cds::opt::details::make_comparator_from_option_list< value_type, CDS_OPTIONS >::type key_comparator;
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 >
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>
101 struct find_predicate
103 bool operator()( value_type const& i1, value_type const& i2) const
105 return key_comparator()( i1, i2 ) < 0;
108 template <typename Q>
109 bool operator()( Q const& i1, value_type const& i2) const
111 return key_comparator()( i1, i2 ) < 0;
114 template <typename Q>
115 bool operator()( value_type const& i1, Q const& i2) const
117 return key_comparator()( i1, i2 ) < 0;
124 container_type m_Vector;
128 template <typename Q, typename Func>
129 bool insert( const Q& val, Func f )
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 cds::unref( f )( *it );
141 # ifdef CDS_EMPLACE_SUPPORT
142 template <typename... Args>
143 bool emplace( Args&&... args )
145 value_type val( std::forward<Args>(args)... );
146 iterator it = std::lower_bound( m_Vector.begin(), m_Vector.end(), val, find_predicate() );
147 if ( it == m_Vector.end() || key_comparator()( val, *it ) != 0 ) {
148 it = m_Vector.emplace( it, std::move( val ) );
155 template <typename Q, typename Func>
156 std::pair<bool, bool> ensure( const Q& val, Func func )
158 iterator it = std::lower_bound( m_Vector.begin(), m_Vector.end(), val, find_predicate() );
159 if ( it == m_Vector.end() || key_comparator()( val, *it ) != 0 ) {
161 value_type newItem( val );
162 it = m_Vector.insert( it, newItem );
163 cds::unref( func )( true, *it, val );
164 return std::make_pair( true, true );
168 cds::unref( func )( false, *it, val );
169 return std::make_pair( true, false );
173 template <typename Q, typename Func>
174 bool erase( const Q& key, Func f )
176 iterator it = std::lower_bound( m_Vector.begin(), m_Vector.end(), key, find_predicate() );
177 if ( it == m_Vector.end() || key_comparator()( key, *it ) != 0 )
181 cds::unref( f )( *it );
182 m_Vector.erase( it );
186 template <typename Q, typename Less, typename Func>
187 bool erase( Q const& key, Less pred, Func f )
189 iterator it = std::lower_bound( m_Vector.begin(), m_Vector.end(), key, pred );
190 if ( it == m_Vector.end() || pred( key, *it ) || pred( *it, key ) )
194 cds::unref( f )( *it );
195 m_Vector.erase( it );
199 template <typename Q, typename Func>
200 bool find( Q& val, Func f )
202 iterator it = std::lower_bound( m_Vector.begin(), m_Vector.end(), val, find_predicate() );
203 if ( it == m_Vector.end() || key_comparator()( val, *it ) != 0 )
207 cds::unref( f )( *it, val );
211 template <typename Q, typename Less, typename Func>
212 bool find( Q& val, Less pred, Func f )
214 iterator it = std::lower_bound( m_Vector.begin(), m_Vector.end(), val, pred );
215 if ( it == m_Vector.end() || pred( val, *it ) || pred( *it, val ) )
219 cds::unref( f )( *it, val );
223 /// Clears the container
229 iterator begin() { return m_Vector.begin(); }
230 const_iterator begin() const { return m_Vector.begin(); }
231 iterator end() { return m_Vector.end(); }
232 const_iterator end() const { return m_Vector.end(); }
234 void move_item( adapted_container& /*from*/, iterator itWhat )
236 iterator it = std::lower_bound( m_Vector.begin(), m_Vector.end(), *itWhat, find_predicate() );
237 assert( it == m_Vector.end() || key_comparator()( *itWhat, *it ) != 0 );
239 copy_item()( m_Vector, it, itWhat );
244 return m_Vector.size();
249 typedef adapted_container type ; ///< Result of \p adapt metafunction
252 }}} // namespace cds::intrusive::striped_set
257 #endif // #ifndef __CDS_CONTAINER_STRIPED_SET_BOOST_VECTOR_ADAPTER_H