2 This file is a part of libcds - Concurrent Data Structures library
4 (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
6 Source code repo: http://github.com/khizmax/libcds/
7 Download: http://sourceforge.net/projects/libcds/files/
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions are met:
12 * Redistributions of source code must retain the above copyright notice, this
13 list of conditions and the following disclaimer.
15 * Redistributions in binary form must reproduce the above copyright notice,
16 this list of conditions and the following disclaimer in the documentation
17 and/or other materials provided with the distribution.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #ifndef CDSLIB_INTRUSIVE_STRIPED_SET_BOOST_UNORDERED_SET_ADAPTER_H
32 #define CDSLIB_INTRUSIVE_STRIPED_SET_BOOST_UNORDERED_SET_ADAPTER_H
34 #include <boost/intrusive/unordered_set.hpp>
35 #include <cds/intrusive/striped_set/adapter.h>
36 #include <cds/opt/buffer.h>
39 namespace cds { namespace intrusive { namespace striped_set {
42 template <class Set, typename... Options>
43 class adapt_boost_unordered_set
46 typedef Set container_type; ///< underlying intrusive container type
49 class adapted_container
52 typedef typename container_type::value_type value_type; ///< value type stored in the container
53 typedef typename container_type::iterator iterator; ///< container iterator
54 typedef typename container_type::const_iterator const_iterator; ///< container const iterator
56 typedef typename opt::value <
57 typename opt::find_option <
58 opt::buffer< opt::v::initialized_static_buffer< cds::any_type, 256 > >,
61 > ::buffer initial_buffer_type;
62 typedef typename initial_buffer_type::template rebind< typename container_type::bucket_type >::other buffer_type;
63 typedef cds::intrusive::striped_set::load_factor_resizing<256> default_resizing_policy;
66 template <typename Compare>
67 struct equal_from_compare
70 equal_from_compare( Compare& cmp )
74 equal_from_compare( equal_from_compare const& src )
78 template <typename A, typename B>
79 bool operator()( A& a, B& b ) const
81 return !m_cmp( a, b ) && !m_cmp( b, a );
84 template <typename A, typename B>
85 bool operator()( A& a, B& b )
87 return !m_cmp( a, b ) && !m_cmp( b, a );
91 buffer_type m_Buckets; // buffer should be declared first since it is used in m_Set ctor.
96 : m_Set( typename container_type::bucket_traits( m_Buckets.buffer(), m_Buckets.capacity()) )
99 container_type& base_container()
104 template <typename Func>
105 bool insert( value_type& val, Func f )
107 std::pair<iterator, bool> res = m_Set.insert( val );
113 template <typename Func>
114 std::pair<bool, bool> update( value_type& val, Func f, bool bAllowInsert )
116 if ( bAllowInsert ) {
117 std::pair<iterator, bool> res = m_Set.insert( val );
118 f( res.second, *res.first, val );
119 return std::make_pair( true, res.second );
122 auto it = m_Set.find( val );
123 if ( it == m_Set.end())
124 return std::make_pair( false, false );
125 f( false, *it, val );
126 return std::make_pair( true, false );
130 bool unlink( value_type& val )
132 iterator it = m_Set.find( value_type( val ));
133 if ( it == m_Set.end() || &(*it) != &val )
139 template <typename Q, typename Func>
140 value_type * erase( Q const& key, Func f )
142 iterator it = m_Set.find( key, typename container_type::hasher(), typename container_type::key_equal());
143 if ( it == m_Set.end())
145 value_type& val = *it;
151 template <typename Q, typename Less, typename Func>
152 value_type * erase( Q const& key, Less pred, Func f )
154 iterator it = m_Set.find( key, typename container_type::hasher(), equal_from_compare<Less>( pred ));
155 if ( it == m_Set.end())
157 value_type& val = *it;
163 template <typename Q, typename Func>
164 bool find( Q& key, Func f )
166 iterator it = m_Set.find( key, typename container_type::hasher(), typename container_type::key_equal());
167 if ( it == m_Set.end())
173 template <typename Q, typename Less, typename Func>
174 bool find( Q& key, Less pred, Func f )
176 iterator it = m_Set.find( key, typename container_type::hasher(), equal_from_compare<Less>( pred ));
177 if ( it == m_Set.end())
188 template <typename Disposer>
189 void clear( Disposer disposer )
191 m_Set.clear_and_dispose( disposer );
194 iterator begin() { return m_Set.begin(); }
195 const_iterator begin() const { return m_Set.begin(); }
196 iterator end() { return m_Set.end(); }
197 const_iterator end() const { return m_Set.end(); }
201 return (size_t)m_Set.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,
219 typename O1, typename O2, typename O3, typename O4, typename O5,
220 typename O6, typename O7, typename O8, typename O9, typename O10,
223 class adapt < boost::intrusive::unordered_set< T, O1, O2, O3, O4, O5, O6, O7, O8, O9, O10 >, Options... >
224 : public details::adapt_boost_unordered_set < boost::intrusive::unordered_set< T, O1, O2, O3, O4, O5, O6, O7, O8, O9, O10 >, Options... >
227 template <typename T, typename... BIOptons, typename... Options>
228 class adapt < boost::intrusive::unordered_set< T, BIOptons... >, Options... >
229 : public details::adapt_boost_unordered_set < boost::intrusive::unordered_set< T, BIOptons... >, Options... >
233 }}} // namespace cds::intrusive::striped_set
236 #endif // #ifndef CDSLIB_INTRUSIVE_STRIPED_SET_BOOST_UNORDERED_SET_ADAPTER_H