3 #ifndef __CDS_CONTAINER_STRIPED_SET_STD_VECTOR_ADAPTER_H
4 #define __CDS_CONTAINER_STRIPED_SET_STD_VECTOR_ADAPTER_H
6 #include <cds/container/striped_set/adapter.h> // lower_bound
9 #include <algorithm> // std::lower_bound
10 #include <utility> // std::pair
13 namespace cds { namespace container {
14 namespace striped_set {
16 // Copy policy for std::vector
17 template <typename T, typename Alloc>
18 struct copy_item_policy< std::vector< T, Alloc > >
20 typedef std::vector< T, Alloc > vector_type;
21 typedef typename vector_type::iterator iterator;
23 void operator()( vector_type& vec, iterator itInsert, iterator itWhat )
25 vec.insert( itInsert, *itWhat );
29 // Swap policy for std::vector
30 template <typename T, typename Alloc>
31 struct swap_item_policy< std::vector< T, Alloc > >
33 typedef std::vector< T, Alloc > vector_type;
34 typedef typename vector_type::iterator iterator;
36 void operator()( vector_type& vec, iterator itInsert, iterator itWhat )
38 typename vector_type::value_type newVal;
39 itInsert = vec.insert( itInsert, newVal );
40 std::swap( *itInsert, *itWhat );
44 #ifdef CDS_MOVE_SEMANTICS_SUPPORT
45 // Move policy for std::vector
46 template <typename T, typename Alloc>
47 struct move_item_policy< std::vector< T, Alloc > >
49 typedef std::vector< T, Alloc > vector_type;
50 typedef typename vector_type::iterator iterator;
52 void operator()( vector_type& vec, iterator itInsert, iterator itWhat )
54 vec.insert( itInsert, std::move( *itWhat ));
59 } // namespace striped_set
60 }} // namespace cds::container
62 namespace cds { namespace intrusive { namespace striped_set {
64 /// std::vector adapter for hash set bucket
65 template <typename T, class Alloc, CDS_SPEC_OPTIONS>
66 class adapt< std::vector<T, Alloc>, CDS_OPTIONS >
69 typedef std::vector<T, Alloc> container_type ; ///< underlying container type
72 /// Adapted container type
73 class adapted_container: public cds::container::striped_set::adapted_sequential_container
76 typedef typename container_type::value_type value_type ; ///< value type stored in the container
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 = true;
81 static bool const has_erase_with = true;
85 typedef typename cds::opt::details::make_comparator_from_option_list< value_type, CDS_OPTIONS >::type key_comparator;
87 typedef typename cds::opt::select<
88 typename cds::opt::value<
89 typename cds::opt::find_option<
90 cds::opt::copy_policy< cds::container::striped_set::move_item >
94 , cds::container::striped_set::copy_item, cds::container::striped_set::copy_item_policy<container_type>
95 , cds::container::striped_set::swap_item, cds::container::striped_set::swap_item_policy<container_type>
96 #ifdef CDS_MOVE_SEMANTICS_SUPPORT
97 , 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;
129 template <typename Q, typename Func>
130 bool insert( const Q& val, Func f )
132 iterator it = std::lower_bound( m_Vector.begin(), m_Vector.end(), val, find_predicate() );
133 if ( it == m_Vector.end() || key_comparator()( val, *it ) != 0 ) {
134 value_type newItem( val );
135 it = m_Vector.insert( it, newItem );
136 cds::unref( f )( *it );
142 # ifdef CDS_EMPLACE_SUPPORT
143 template <typename... Args>
144 bool emplace( Args&&... args )
146 #if CDS_COMPILER == CDS_COMPILER_MSVC && CDS_COMPILER_VERSION == CDS_COMPILER_MSVC12
147 // MS VC++ 2013 internal compiler error
148 // Use assignment workaround, see http://connect.microsoft.com/VisualStudio/feedback/details/804941/visual-studio-2013-rc-c-internal-compiler-error-with-std-forward
149 value_type val = value_type(std::forward<Args>(args)...);
151 value_type val( std::forward<Args>(args)... );
153 iterator it = std::lower_bound( m_Vector.begin(), m_Vector.end(), val, find_predicate() );
154 if ( it == m_Vector.end() || key_comparator()( val, *it ) != 0 ) {
155 it = m_Vector.emplace( it, std::move( val ) );
162 template <typename Q, typename Func>
163 std::pair<bool, bool> ensure( const Q& val, Func func )
165 iterator it = std::lower_bound( m_Vector.begin(), m_Vector.end(), val, find_predicate() );
166 if ( it == m_Vector.end() || key_comparator()( val, *it ) != 0 ) {
168 value_type newItem( val );
169 it = m_Vector.insert( it, newItem );
170 cds::unref( func )( true, *it, val );
171 return std::make_pair( true, true );
175 cds::unref( func )( false, *it, val );
176 return std::make_pair( true, false );
180 template <typename Q, typename Func>
181 bool erase( const Q& key, Func f )
183 iterator it = std::lower_bound( m_Vector.begin(), m_Vector.end(), key, find_predicate() );
184 if ( it == m_Vector.end() || key_comparator()( key, *it ) != 0 )
188 cds::unref( f )( *it );
189 m_Vector.erase( it );
193 template <typename Q, typename Less, typename Func>
194 bool erase( const Q& key, Less pred, Func f )
196 iterator it = std::lower_bound( m_Vector.begin(), m_Vector.end(), key, pred );
197 if ( it == m_Vector.end() || pred( key, *it ) || pred( *it, key ) )
201 cds::unref( f )( *it );
202 m_Vector.erase( it );
206 template <typename Q, typename Func>
207 bool find( Q& val, Func f )
209 iterator it = std::lower_bound( m_Vector.begin(), m_Vector.end(), val, find_predicate() );
210 if ( it == m_Vector.end() || key_comparator()( val, *it ) != 0 )
214 cds::unref( f )( *it, val );
218 template <typename Q, typename Less, typename Func>
219 bool find( Q& val, Less pred, Func f )
221 iterator it = std::lower_bound( m_Vector.begin(), m_Vector.end(), val, pred );
222 if ( it == m_Vector.end() || pred( val, *it ) || pred( *it, val ) )
226 cds::unref( f )( *it, val );
236 iterator begin() { return m_Vector.begin(); }
237 const_iterator begin() const { return m_Vector.begin(); }
238 iterator end() { return m_Vector.end(); }
239 const_iterator end() const { return m_Vector.end(); }
241 void move_item( adapted_container& /*from*/, iterator itWhat )
243 iterator it = std::lower_bound( m_Vector.begin(), m_Vector.end(), *itWhat, find_predicate() );
244 assert( it == m_Vector.end() || key_comparator()( *itWhat, *it ) != 0 );
246 copy_item()( m_Vector, it, itWhat );
251 return m_Vector.size();
256 typedef adapted_container type ; ///< Result of \p adapt metafunction
259 }}} // namespace cds::intrusive::striped_set
263 #endif // #ifndef __CDS_CONTAINER_STRIPED_SET_STD_VECTOR_ADAPTER_H