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 container_type m_List;
93 container_type& base_container()
98 template <typename Func>
99 bool insert( value_type& val, Func f )
101 std::pair< iterator, bool > pos = find_prev_item( val );
103 m_List.insert_after( pos.first, val );
104 cds::unref( f )( val );
108 // key already exists
112 template <typename Func>
113 std::pair<bool, bool> ensure( value_type& val, Func f )
115 std::pair< iterator, bool > pos = find_prev_item( val );
118 m_List.insert_after( pos.first, val );
119 cds::unref( f )( true, val, val );
120 return std::make_pair( true, true );
124 cds::unref( f )( false, *(++pos.first), val );
125 return std::make_pair( true, false );
129 bool unlink( value_type& val )
131 std::pair< iterator, bool > pos = find_prev_item( val );
136 if ( &(*pos.first) != &val )
139 m_List.erase( pos.first );
143 template <typename Q, typename Func>
144 value_type * erase( Q const& key, Func f )
146 return erase_( key, key_comparator(), f );
149 template <typename Q, typename Less, typename Func>
150 value_type * erase( Q const& key, Less pred, Func f )
152 return erase_( key, cds::opt::details::make_comparator_from_less<Less>(), f );
155 template <typename Q, typename Func>
156 bool find( Q& key, Func f )
158 std::pair< iterator, bool > pos = find_prev_item( key );
163 cds::unref( f )( *(++pos.first), key );
167 template <typename Q, typename Less, typename Func>
168 bool find( Q& key, Less pred, Func f )
170 std::pair< iterator, bool > pos = find_prev_item( key, pred );
175 cds::unref( f )( *(++pos.first), key );
184 template <typename Disposer>
185 void clear( Disposer disposer )
187 m_List.clear_and_dispose( disposer );
190 iterator begin() { return m_List.begin(); }
191 const_iterator begin() const { return m_List.begin(); }
192 iterator end() { return m_List.end(); }
193 const_iterator end() const { return m_List.end(); }
197 return (size_t) m_List.size();
200 void move_item( adapted_container& from, iterator itWhat )
202 value_type& val = *itWhat;
203 from.base_container().erase( itWhat );
204 insert( val, []( value_type& ) {} );
209 typedef adapted_container type ; ///< Result of the metafunction
211 }}} // namespace cds::intrusive::striped_set
214 #endif // #ifndef __CDS_INTRUSIVE_STRIPED_SET_BOOST_SLIST_ADAPTER_H