3 #ifndef CDSLIB_CONTAINER_STRIPED_SET_BOOST_SLIST_ADAPTER_H
4 #define CDSLIB_CONTAINER_STRIPED_SET_BOOST_SLIST_ADAPTER_H
6 #include <functional> // ref
7 #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 // Move policy for boost::container::slist
43 template <typename T, typename Alloc>
44 struct move_item_policy< boost::container::slist< T, Alloc > >
46 typedef boost::container::slist< T, Alloc > list_type;
47 typedef typename list_type::iterator iterator;
49 void operator()( list_type& list, iterator itInsert, iterator itWhat )
51 list.insert_after( itInsert, std::move( *itWhat ) );
55 } // namespace striped_set
56 }} // namespace cds::container
58 namespace cds { namespace intrusive { namespace striped_set {
60 /// boost::container::slist adapter for hash set bucket
61 template <typename T, class Alloc, typename... Options>
62 class adapt< boost::container::slist<T, Alloc>, Options... >
65 typedef boost::container::slist<T, Alloc> container_type ; ///< underlying container type
68 /// Adapted container type
69 class adapted_container: public cds::container::striped_set::adapted_sequential_container
72 typedef typename container_type::value_type value_type ; ///< value type stored in the container
73 typedef typename container_type::iterator iterator ; ///< container iterator
74 typedef typename container_type::const_iterator const_iterator ; ///< container const iterator
76 static bool const has_find_with = true;
77 static bool const has_erase_with = true;
81 typedef typename cds::opt::details::make_comparator_from_option_list< value_type, Options... >::type key_comparator;
83 typedef typename cds::opt::select<
84 typename cds::opt::value<
85 typename cds::opt::find_option<
86 cds::opt::copy_policy< cds::container::striped_set::move_item >
90 , cds::container::striped_set::copy_item, cds::container::striped_set::copy_item_policy<container_type>
91 , cds::container::striped_set::swap_item, cds::container::striped_set::swap_item_policy<container_type>
92 , cds::container::striped_set::move_item, cds::container::striped_set::move_item_policy<container_type>
96 std::pair< iterator, bool > find_prev_item( Q const& key )
98 iterator itPrev = m_List.before_begin();
99 iterator itEnd = m_List.end();
100 for ( iterator it = m_List.begin(); it != itEnd; ++it ) {
101 int nCmp = key_comparator()( key, *it );
107 return std::make_pair( itPrev, true );
109 return std::make_pair( itPrev, false );
112 template <typename Q, typename Less>
113 std::pair< iterator, bool > find_prev_item( Q const& key, Less pred )
115 iterator itPrev = m_List.before_begin();
116 iterator itEnd = m_List.end();
117 for ( iterator it = m_List.begin(); it != itEnd; ++it ) {
118 if ( pred( key, *it ))
120 else if ( pred( *it, key ) )
123 return std::make_pair( itPrev, true );
125 return std::make_pair( itPrev, false );
132 container_type m_List;
139 template <typename Q, typename Func>
140 bool insert( const Q& val, Func f )
142 std::pair< iterator, bool > pos = find_prev_item( val );
144 value_type newItem( val );
145 pos.first = m_List.insert_after( pos.first, newItem );
150 // key already exists
154 template <typename... Args>
155 bool emplace( Args&&... args )
157 value_type val( std::forward<Args>(args)... );
158 std::pair< iterator, bool > pos = find_prev_item( val );
160 m_List.emplace_after( pos.first, std::move( val ) );
166 template <typename Q, typename Func>
167 std::pair<bool, bool> update( const Q& val, Func func, bool bAllowInsert )
169 std::pair< iterator, bool > pos = find_prev_item( val );
173 return std::make_pair( false, false );
175 value_type newItem( val );
176 pos.first = m_List.insert_after( pos.first, newItem );
177 func( true, *pos.first, val );
178 return std::make_pair( true, true );
182 func( false, *(++pos.first), val );
183 return std::make_pair( true, false );
187 template <typename Q, typename Func>
188 bool erase( Q const& key, Func f )
190 std::pair< iterator, bool > pos = find_prev_item( key );
195 iterator it = pos.first;
197 m_List.erase_after( pos.first );
202 template <typename Q, typename Less, typename Func>
203 bool erase( Q const& key, Less pred, Func f )
205 std::pair< iterator, bool > pos = find_prev_item( key, pred );
210 iterator it = pos.first;
212 m_List.erase_after( pos.first );
217 template <typename Q, typename Func>
218 bool find( Q& val, Func f )
220 std::pair< iterator, bool > pos = find_prev_item( val );
225 f( *(++pos.first), val );
229 template <typename Q, typename Less, typename Func>
230 bool find( Q& val, Less pred, Func f )
232 std::pair< iterator, bool > pos = find_prev_item( val, pred );
237 f( *(++pos.first), val );
246 iterator begin() { return m_List.begin(); }
247 const_iterator begin() const { return m_List.begin(); }
248 iterator end() { return m_List.end(); }
249 const_iterator end() const { return m_List.end(); }
251 void move_item( adapted_container& /*from*/, iterator itWhat )
253 std::pair< iterator, bool > pos = find_prev_item( *itWhat );
254 assert( !pos.second );
256 copy_item()( m_List, pos.first, itWhat );
261 return m_List.size();
266 typedef adapted_container type ; ///< Result of \p adapt metafunction
269 }}} // namespace cds::intrusive::striped_set
274 #endif // #ifndef CDSLIB_CONTAINER_STRIPED_SET_BOOST_SLIST_ADAPTER_H