3 #ifndef __CDS_INTRUSIVE_STRIPED_SET_BOOST_SLIST_ADAPTER_H
4 #define __CDS_INTRUSIVE_STRIPED_SET_BOOST_SLIST_ADAPTER_H
6 #include <boost/intrusive/slist.hpp>
7 #include <cds/intrusive/striped_set/adapter.h>
10 namespace cds { namespace intrusive { namespace striped_set {
12 template <typename T, typename... BIOptons, typename... Options>
13 class adapt< boost::intrusive::slist< T, BIOptons... >, Options... >
16 typedef boost::intrusive::slist< T, BIOptons... > container_type ; ///< underlying intrusive container type
19 /// Adapted intrusive container
20 class adapted_container: public cds::intrusive::striped_set::adapted_sequential_container
23 typedef typename container_type::value_type value_type ; ///< value type stored in the container
24 typedef typename container_type::iterator iterator ; ///< container iterator
25 typedef typename container_type::const_iterator const_iterator ; ///< container const iterator
27 typedef typename cds::opt::details::make_comparator_from_option_list< value_type, Options... >::type key_comparator;
31 template <typename Q, typename Less>
32 std::pair< iterator, bool > find_prev_item( Q const& key, Less pred )
34 iterator itPrev = m_List.before_begin();
35 iterator itEnd = m_List.end();
36 for ( iterator it = m_List.begin(); it != itEnd; ++it ) {
37 if ( pred( key, *it ) )
39 else if ( pred( *it, key ) )
42 return std::make_pair( itPrev, true );
44 return std::make_pair( itPrev, false );
48 std::pair< iterator, bool > find_prev_item( Q const& key )
50 return find_prev_item_cmp( key, key_comparator() );
53 template <typename Q, typename Compare>
54 std::pair< iterator, bool > find_prev_item_cmp( Q const& key, Compare cmp )
56 iterator itPrev = m_List.before_begin();
57 iterator itEnd = m_List.end();
58 for ( iterator it = m_List.begin(); it != itEnd; ++it ) {
59 int nCmp = cmp( key, *it );
65 return std::make_pair( itPrev, true );
67 return std::make_pair( itPrev, false );
70 template <typename Q, typename Compare, typename Func>
71 value_type * erase_( Q const& key, Compare cmp, Func f )
73 std::pair< iterator, bool > pos = find_prev_item_cmp( key, cmp );
78 iterator it = pos.first;
79 value_type& val = *(++it);
80 cds::unref( f )( val );
81 m_List.erase_after( pos.first );
87 # ifndef CDS_CXX11_LAMBDA_SUPPORT
88 struct empty_insert_functor {
89 void operator()( value_type& )
95 container_type m_List;
101 container_type& base_container()
106 template <typename Func>
107 bool insert( value_type& val, Func f )
109 std::pair< iterator, bool > pos = find_prev_item( val );
111 m_List.insert_after( pos.first, val );
112 cds::unref( f )( val );
116 // key already exists
120 template <typename Func>
121 std::pair<bool, bool> ensure( value_type& val, Func f )
123 std::pair< iterator, bool > pos = find_prev_item( val );
126 m_List.insert_after( pos.first, val );
127 cds::unref( f )( true, val, val );
128 return std::make_pair( true, true );
132 cds::unref( f )( false, *(++pos.first), val );
133 return std::make_pair( true, false );
137 bool unlink( value_type& val )
139 std::pair< iterator, bool > pos = find_prev_item( val );
144 if ( &(*pos.first) != &val )
147 m_List.erase( pos.first );
151 template <typename Q, typename Func>
152 value_type * erase( Q const& key, Func f )
154 return erase_( key, key_comparator(), f );
157 template <typename Q, typename Less, typename Func>
158 value_type * erase( Q const& key, Less pred, Func f )
160 return erase_( key, cds::opt::details::make_comparator_from_less<Less>(), f );
163 template <typename Q, typename Func>
164 bool find( Q& key, Func f )
166 std::pair< iterator, bool > pos = find_prev_item( key );
171 cds::unref( f )( *(++pos.first), key );
175 template <typename Q, typename Less, typename Func>
176 bool find( Q& key, Less pred, Func f )
178 std::pair< iterator, bool > pos = find_prev_item( key, pred );
183 cds::unref( f )( *(++pos.first), key );
192 template <typename Disposer>
193 void clear( Disposer disposer )
195 m_List.clear_and_dispose( disposer );
198 iterator begin() { return m_List.begin(); }
199 const_iterator begin() const { return m_List.begin(); }
200 iterator end() { return m_List.end(); }
201 const_iterator end() const { return m_List.end(); }
205 return (size_t) m_List.size();
208 void move_item( adapted_container& from, iterator itWhat )
210 value_type& val = *itWhat;
211 from.base_container().erase( itWhat );
212 # ifdef CDS_CXX11_LAMBDA_SUPPORT
213 insert( val, []( value_type& ) {} );
215 insert( val, empty_insert_functor() );
221 typedef adapted_container type ; ///< Result of the metafunction
223 }}} // namespace cds::intrusive::striped_set
226 #endif // #ifndef __CDS_INTRUSIVE_STRIPED_SET_BOOST_SLIST_ADAPTER_H