3 #ifndef __CDS_CONTAINER_STRIPED_SET_BOOST_LIST_ADAPTER_H
4 #define __CDS_CONTAINER_STRIPED_SET_BOOST_LIST_ADAPTER_H
6 #include <boost/version.hpp>
7 #if BOOST_VERSION < 104800
8 # error "For boost::container::list you must use boost 1.48 or above"
11 #include <cds/container/striped_set/adapter.h>
13 #include <boost/container/list.hpp>
14 #include <algorithm> // std::lower_bound
17 namespace cds { namespace container {
18 namespace striped_set {
20 // Copy policy for boost::container::list
21 template <typename T, typename Alloc>
22 struct copy_item_policy< boost::container::list< T, Alloc > >
24 typedef boost::container::list< T, Alloc > list_type;
25 typedef typename list_type::iterator iterator;
27 void operator()( list_type& list, iterator itInsert, iterator itWhat )
29 itInsert = list.insert( itInsert, *itWhat );
33 // Swap policy for boost::container::list
34 template <typename T, typename Alloc>
35 struct swap_item_policy< boost::container::list< T, Alloc > >
37 typedef boost::container::list< T, Alloc > list_type;
38 typedef typename list_type::iterator iterator;
40 void operator()( list_type& list, iterator itInsert, iterator itWhat )
42 typename list_type::value_type newVal;
43 itInsert = list.insert( itInsert, newVal );
44 std::swap( *itWhat, *itInsert );
48 #ifdef CDS_MOVE_SEMANTICS_SUPPORT
49 // Move policy for boost::container::list
50 template <typename T, typename Alloc>
51 struct move_item_policy< boost::container::list< T, Alloc > >
53 typedef boost::container::list< T, Alloc > list_type;
54 typedef typename list_type::iterator iterator;
56 void operator()( list_type& list, iterator itInsert, iterator itWhat )
58 list.insert( itInsert, std::move( *itWhat ) );
62 } // namespace striped_set
63 }} // namespace cds::container
65 namespace cds { namespace intrusive { namespace striped_set {
67 /// boost::container::list adapter for hash set bucket
68 template <typename T, class Alloc, CDS_SPEC_OPTIONS>
69 class adapt< boost::container::list<T, Alloc>, CDS_OPTIONS >
72 typedef boost::container::list<T, Alloc> container_type ; ///< underlying container type
75 /// Adapted container type
76 class adapted_container: public cds::container::striped_set::adapted_sequential_container
79 typedef typename container_type::value_type value_type ; ///< value type stored in the container
80 typedef typename container_type::iterator iterator ; ///< container iterator
81 typedef typename container_type::const_iterator const_iterator ; ///< container const iterator
83 static bool const has_find_with = true;
84 static bool const has_erase_with = true;
88 typedef typename cds::opt::details::make_comparator_from_option_list< value_type, CDS_OPTIONS >::type key_comparator;
90 typedef typename cds::opt::select<
91 typename cds::opt::value<
92 typename cds::opt::find_option<
93 cds::opt::copy_policy< cds::container::striped_set::move_item >
97 , cds::container::striped_set::copy_item, cds::container::striped_set::copy_item_policy<container_type>
98 , cds::container::striped_set::swap_item, cds::container::striped_set::swap_item_policy<container_type>
99 #ifdef CDS_MOVE_SEMANTICS_SUPPORT
100 , cds::container::striped_set::move_item, cds::container::striped_set::move_item_policy<container_type>
104 struct find_predicate
106 bool operator()( value_type const& i1, value_type const& i2) const
108 return key_comparator()( i1, i2 ) < 0;
111 template <typename Q>
112 bool operator()( Q const& i1, value_type const& i2) const
114 return key_comparator()( i1, i2 ) < 0;
117 template <typename Q>
118 bool operator()( value_type const& i1, Q const& i2) const
120 return key_comparator()( i1, i2 ) < 0;
127 container_type m_List;
134 template <typename Q, typename Func>
135 bool insert( Q const& val, Func f )
137 iterator it = std::lower_bound( m_List.begin(), m_List.end(), val, find_predicate() );
138 if ( it == m_List.end() || key_comparator()( val, *it ) != 0 ) {
139 value_type newItem( val );
140 it = m_List.insert( it, newItem );
141 cds::unref( f )( *it );
146 // key already exists
150 # ifdef CDS_EMPLACE_SUPPORT
151 template <typename... Args>
152 bool emplace( Args&&... args )
154 value_type val( std::forward<Args>(args)... );
155 iterator it = std::lower_bound( m_List.begin(), m_List.end(), val, find_predicate() );
156 if ( it == m_List.end() || key_comparator()( val, *it ) != 0 ) {
157 m_List.emplace( it, std::move( val ) );
164 template <typename Q, typename Func>
165 std::pair<bool, bool> ensure( Q const& val, Func func )
167 iterator it = std::lower_bound( m_List.begin(), m_List.end(), val, find_predicate() );
168 if ( it == m_List.end() || key_comparator()( val, *it ) != 0 ) {
170 value_type newItem( val );
171 it = m_List.insert( it, newItem );
172 cds::unref( func )( true, *it, val );
173 return std::make_pair( true, true );
177 cds::unref( func )( false, *it, val );
178 return std::make_pair( true, false );
182 template <typename Q, typename Func>
183 bool erase( Q const& key, Func f )
185 iterator it = std::lower_bound( m_List.begin(), m_List.end(), key, find_predicate() );
186 if ( it == m_List.end() || key_comparator()( key, *it ) != 0 )
190 cds::unref( f )( *it );
196 template <typename Q, typename Less, typename Func>
197 bool erase( Q const& key, Less pred, Func f )
199 iterator it = std::lower_bound( m_List.begin(), m_List.end(), key, pred );
200 if ( it == m_List.end() || pred( key, *it ) || pred( *it, key ) )
204 cds::unref( f )( *it );
210 template <typename Q, typename Func>
211 bool find( Q& val, Func f )
213 iterator it = std::lower_bound( m_List.begin(), m_List.end(), val, find_predicate() );
214 if ( it == m_List.end() || key_comparator()( val, *it ) != 0 )
218 cds::unref( f )( *it, val );
222 template <typename Q, typename Less, typename Func>
223 bool find( Q& val, Less pred, Func f )
225 iterator it = std::lower_bound( m_List.begin(), m_List.end(), val, pred );
226 if ( it == m_List.end() || pred( val, *it ) || pred( *it, val ) )
230 cds::unref( f )( *it, val );
234 /// Clears the container
240 iterator begin() { return m_List.begin(); }
241 const_iterator begin() const { return m_List.begin(); }
242 iterator end() { return m_List.end(); }
243 const_iterator end() const { return m_List.end(); }
245 void move_item( adapted_container& /*from*/, iterator itWhat )
247 iterator it = std::lower_bound( m_List.begin(), m_List.end(), *itWhat, find_predicate() );
248 assert( it == m_List.end() || key_comparator()( *itWhat, *it ) != 0 );
250 copy_item()( m_List, it, itWhat );
255 return m_List.size();
260 typedef adapted_container type ; ///< Result of \p adapt metafunction
263 }}} // namespace cds::intrsive::striped_set
266 #endif // #ifndef __CDS_CONTAINER_STRIPED_SET_BOOST_LIST_ADAPTER_H