3 #ifndef CDSLIB_INTRUSIVE_STRIPED_SET_BOOST_SLIST_ADAPTER_H
4 #define CDSLIB_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> update( value_type& val, Func f, bool bAllowInsert )
116 std::pair< iterator, bool > pos = find_prev_item( val );
120 return std::make_pair( false, false );
122 m_List.insert_after( pos.first, val );
124 return std::make_pair( true, true );
128 f( false, *(++pos.first), val );
129 return std::make_pair( true, false );
133 bool unlink( value_type& val )
135 std::pair< iterator, bool > pos = find_prev_item( val );
140 if ( &(*pos.first) != &val )
143 m_List.erase( pos.first );
147 template <typename Q, typename Func>
148 value_type * erase( Q const& key, Func f )
150 return erase_( key, key_comparator(), f );
153 template <typename Q, typename Less, typename Func>
154 value_type * erase( Q const& key, Less /*pred*/, Func f )
156 return erase_( key, cds::opt::details::make_comparator_from_less<Less>(), f );
159 template <typename Q, typename Func>
160 bool find( Q& key, Func f )
162 std::pair< iterator, bool > pos = find_prev_item( key );
167 f( *(++pos.first), key );
171 template <typename Q, typename Less, typename Func>
172 bool find( Q& key, Less pred, Func f )
174 std::pair< iterator, bool > pos = find_prev_item( key, pred );
179 f( *(++pos.first), key );
188 template <typename Disposer>
189 void clear( Disposer disposer )
191 m_List.clear_and_dispose( disposer );
194 iterator begin() { return m_List.begin(); }
195 const_iterator begin() const { return m_List.begin(); }
196 iterator end() { return m_List.end(); }
197 const_iterator end() const { return m_List.end(); }
201 return (size_t)m_List.size();
204 void move_item( adapted_container& from, iterator itWhat )
206 value_type& val = *itWhat;
207 from.base_container().erase( itWhat );
208 insert( val, []( value_type& ) {} );
213 typedef adapted_container type; ///< Result of the metafunction
215 } // namespace details
217 #if CDS_COMPILER == CDS_COMPILER_INTEL && CDS_COMPILER_VERSION <= 1500
218 template <typename T, typename P1, typename P2, typename P3, typename P4, typename P5, typename... Options>
219 class adapt< boost::intrusive::slist< T, P1, P2, P3, P4, P5 >, Options... >
220 : public details::adapt_boost_slist< boost::intrusive::slist< T, P1, P2, P3, P4, P5 >, Options... >
223 template <typename T, typename... BIOptions, typename... Options>
224 class adapt< boost::intrusive::slist< T, BIOptions... >, Options... >
225 : public details::adapt_boost_slist< boost::intrusive::slist< T, BIOptions... >, Options... >
229 }}} // namespace cds::intrusive::striped_set
232 #endif // #ifndef CDSLIB_INTRUSIVE_STRIPED_SET_BOOST_SLIST_ADAPTER_H