3 #ifndef __CDS_CONTAINER_STRIPED_SET_BOOST_SLIST_ADAPTER_H
4 #define __CDS_CONTAINER_STRIPED_SET_BOOST_SLIST_ADAPTER_H
6 #include <cds/container/striped_set/adapter.h>
8 #include <boost/container/slist.hpp>
11 namespace cds { namespace container {
12 namespace striped_set {
14 // Copy policy for boost::container::slist
15 template <typename T, typename Alloc>
16 struct copy_item_policy< boost::container::slist< T, Alloc > >
18 typedef boost::container::slist< T, Alloc > list_type;
19 typedef typename list_type::iterator iterator;
21 void operator()( list_type& list, iterator itInsert, iterator itWhat )
23 list.insert_after( itInsert, *itWhat );
27 // Swap policy for boost::container::slist
28 template <typename T, typename Alloc>
29 struct swap_item_policy< boost::container::slist< T, Alloc > >
31 typedef boost::container::slist< T, Alloc > list_type;
32 typedef typename list_type::iterator iterator;
34 void operator()( list_type& list, iterator itInsert, iterator itWhat )
37 itInsert = list.insert_after( itInsert, newVal );
38 std::swap( *itInsert, *itWhat );
42 #ifdef CDS_MOVE_SEMANTICS_SUPPORT
43 // Move policy for boost::container::slist
44 template <typename T, typename Alloc>
45 struct move_item_policy< boost::container::slist< T, Alloc > >
47 typedef boost::container::slist< T, Alloc > list_type;
48 typedef typename list_type::iterator iterator;
50 void operator()( list_type& list, iterator itInsert, iterator itWhat )
52 list.insert_after( itInsert, std::move( *itWhat ) );
57 } // namespace striped_set
58 }} // namespace cds::container
60 namespace cds { namespace intrusive { namespace striped_set {
62 /// boost::container::slist adapter for hash set bucket
63 template <typename T, class Alloc, CDS_SPEC_OPTIONS>
64 class adapt< boost::container::slist<T, Alloc>, CDS_OPTIONS >
67 typedef boost::container::slist<T, Alloc> container_type ; ///< underlying container type
70 /// Adapted container type
71 class adapted_container: public cds::container::striped_set::adapted_sequential_container
74 typedef typename container_type::value_type value_type ; ///< value type stored in the container
75 typedef typename container_type::iterator iterator ; ///< container iterator
76 typedef typename container_type::const_iterator const_iterator ; ///< container const iterator
78 static bool const has_find_with = true;
79 static bool const has_erase_with = true;
83 typedef typename cds::opt::details::make_comparator_from_option_list< value_type, CDS_OPTIONS >::type key_comparator;
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 #ifdef CDS_MOVE_SEMANTICS_SUPPORT
95 , cds::container::striped_set::move_item, cds::container::striped_set::move_item_policy<container_type>
100 std::pair< iterator, bool > find_prev_item( Q const& key )
102 iterator itPrev = m_List.before_begin();
103 iterator itEnd = m_List.end();
104 for ( iterator it = m_List.begin(); it != itEnd; ++it ) {
105 int nCmp = key_comparator()( key, *it );
111 return std::make_pair( itPrev, true );
113 return std::make_pair( itPrev, false );
116 template <typename Q, typename Less>
117 std::pair< iterator, bool > find_prev_item( Q const& key, Less pred )
119 iterator itPrev = m_List.before_begin();
120 iterator itEnd = m_List.end();
121 for ( iterator it = m_List.begin(); it != itEnd; ++it ) {
122 if ( pred( key, *it ))
124 else if ( pred( *it, key ) )
127 return std::make_pair( itPrev, true );
129 return std::make_pair( itPrev, false );
136 container_type m_List;
143 template <typename Q, typename Func>
144 bool insert( const Q& val, Func f )
146 std::pair< iterator, bool > pos = find_prev_item( val );
148 value_type newItem( val );
149 pos.first = m_List.insert_after( pos.first, newItem );
150 cds::unref( f )( *pos.first );
154 // key already exists
158 # ifdef CDS_EMPLACE_SUPPORT
159 template <typename... Args>
160 bool emplace( Args&&... args )
162 value_type val( std::forward<Args>(args)... );
163 std::pair< iterator, bool > pos = find_prev_item( val );
165 m_List.emplace_after( pos.first, std::move( val ) );
172 template <typename Q, typename Func>
173 std::pair<bool, bool> ensure( const Q& val, Func func )
175 std::pair< iterator, bool > pos = find_prev_item( val );
178 value_type newItem( val );
179 pos.first = m_List.insert_after( pos.first, newItem );
180 cds::unref( func )( true, *pos.first, val );
181 return std::make_pair( true, true );
185 cds::unref( func )( false, *(++pos.first), val );
186 return std::make_pair( true, false );
190 template <typename Q, typename Func>
191 bool erase( Q const& key, Func f )
193 std::pair< iterator, bool > pos = find_prev_item( key );
198 iterator it = pos.first;
199 cds::unref( f )( *(++it) );
200 m_List.erase_after( pos.first );
205 template <typename Q, typename Less, typename Func>
206 bool erase( Q const& key, Less pred, Func f )
208 std::pair< iterator, bool > pos = find_prev_item( key, pred );
213 iterator it = pos.first;
214 cds::unref( f )( *(++it) );
215 m_List.erase_after( pos.first );
220 template <typename Q, typename Func>
221 bool find( Q& val, Func f )
223 std::pair< iterator, bool > pos = find_prev_item( val );
228 cds::unref( f )( *(++pos.first), val );
232 template <typename Q, typename Less, typename Func>
233 bool find( Q& val, Less pred, Func f )
235 std::pair< iterator, bool > pos = find_prev_item( val, pred );
240 cds::unref( f )( *(++pos.first), val );
249 iterator begin() { return m_List.begin(); }
250 const_iterator begin() const { return m_List.begin(); }
251 iterator end() { return m_List.end(); }
252 const_iterator end() const { return m_List.end(); }
254 void move_item( adapted_container& /*from*/, iterator itWhat )
256 std::pair< iterator, bool > pos = find_prev_item( *itWhat );
257 assert( !pos.second );
259 copy_item()( m_List, pos.first, itWhat );
264 return m_List.size();
269 typedef adapted_container type ; ///< Result of \p adapt metafunction
272 }}} // namespace cds::intrusive::striped_set
277 #endif // #ifndef __CDS_CONTAINER_STRIPED_SET_BOOST_SLIST_ADAPTER_H