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 {
13 template <class List, typename... Options>
14 class adapt_boost_slist
17 typedef List container_type; ///< underlying intrusive container type
20 /// Adapted intrusive container
21 class adapted_container : public cds::intrusive::striped_set::adapted_sequential_container
24 typedef typename container_type::value_type value_type; ///< value type stored in the container
25 typedef typename container_type::iterator iterator; ///< container iterator
26 typedef typename container_type::const_iterator const_iterator; ///< container const iterator
28 typedef typename cds::opt::details::make_comparator_from_option_list< value_type, Options... >::type key_comparator;
32 template <typename Q, typename Less>
33 std::pair< iterator, bool > find_prev_item( Q const& key, Less pred )
35 iterator itPrev = m_List.before_begin();
36 iterator itEnd = m_List.end();
37 for ( iterator it = m_List.begin(); it != itEnd; ++it ) {
38 if ( pred( key, *it ) )
40 else if ( pred( *it, key ) )
43 return std::make_pair( itPrev, true );
45 return std::make_pair( itPrev, false );
49 std::pair< iterator, bool > find_prev_item( Q const& key )
51 return find_prev_item_cmp( key, key_comparator() );
54 template <typename Q, typename Compare>
55 std::pair< iterator, bool > find_prev_item_cmp( Q const& key, Compare cmp )
57 iterator itPrev = m_List.before_begin();
58 iterator itEnd = m_List.end();
59 for ( iterator it = m_List.begin(); it != itEnd; ++it ) {
60 int nCmp = cmp( key, *it );
66 return std::make_pair( itPrev, true );
68 return std::make_pair( itPrev, false );
71 template <typename Q, typename Compare, typename Func>
72 value_type * erase_( Q const& key, Compare cmp, Func f )
74 std::pair< iterator, bool > pos = find_prev_item_cmp( key, cmp );
79 iterator it = pos.first;
80 value_type& val = *(++it);
82 m_List.erase_after( pos.first );
88 container_type m_List;
94 container_type& base_container()
99 template <typename Func>
100 bool insert( value_type& val, Func f )
102 std::pair< iterator, bool > pos = find_prev_item( val );
104 m_List.insert_after( pos.first, val );
109 // key already exists
113 template <typename Func>
114 std::pair<bool, bool> ensure( value_type& val, Func f )
116 std::pair< iterator, bool > pos = find_prev_item( val );
119 m_List.insert_after( pos.first, val );
121 return std::make_pair( true, true );
125 f( false, *(++pos.first), val );
126 return std::make_pair( true, false );
130 bool unlink( value_type& val )
132 std::pair< iterator, bool > pos = find_prev_item( val );
137 if ( &(*pos.first) != &val )
140 m_List.erase( pos.first );
144 template <typename Q, typename Func>
145 value_type * erase( Q const& key, Func f )
147 return erase_( key, key_comparator(), f );
150 template <typename Q, typename Less, typename Func>
151 value_type * erase( Q const& key, Less pred, Func f )
153 return erase_( key, cds::opt::details::make_comparator_from_less<Less>(), f );
156 template <typename Q, typename Func>
157 bool find( Q& key, Func f )
159 std::pair< iterator, bool > pos = find_prev_item( key );
164 f( *(++pos.first), key );
168 template <typename Q, typename Less, typename Func>
169 bool find( Q& key, Less pred, Func f )
171 std::pair< iterator, bool > pos = find_prev_item( key, pred );
176 f( *(++pos.first), key );
185 template <typename Disposer>
186 void clear( Disposer disposer )
188 m_List.clear_and_dispose( disposer );
191 iterator begin() { return m_List.begin(); }
192 const_iterator begin() const { return m_List.begin(); }
193 iterator end() { return m_List.end(); }
194 const_iterator end() const { return m_List.end(); }
198 return (size_t)m_List.size();
201 void move_item( adapted_container& from, iterator itWhat )
203 value_type& val = *itWhat;
204 from.base_container().erase( itWhat );
205 insert( val, []( value_type& ) {} );
210 typedef adapted_container type; ///< Result of the metafunction
212 } // namespace details
214 #if CDS_COMPILER == CDS_COMPILER_INTEL && CDS_COMPILER_VERSION <= 1500
215 template <typename T, typename P1, typename P2, typename P3, typename P4, typename P5, typename... Options>
216 class adapt< boost::intrusive::slist< T, P1, P2, P3, P4, P5 >, Options... >
217 : public details::adapt_boost_slist< boost::intrusive::slist< T, P1, P2, P3, P4, P5 >, Options... >
220 template <typename T, typename... BIOptions, typename... Options>
221 class adapt< boost::intrusive::slist< T, BIOptions... >, Options... >
222 : public details::adapt_boost_slist< boost::intrusive::slist< T, BIOptions... >, Options... >
226 }}} // namespace cds::intrusive::striped_set
229 #endif // #ifndef __CDS_INTRUSIVE_STRIPED_SET_BOOST_SLIST_ADAPTER_H