3 #ifndef __CDS_CONTAINER_SPLIT_LIST_SET_NOGC_H
4 #define __CDS_CONTAINER_SPLIT_LIST_SET_NOGC_H
6 #include <cds/intrusive/split_list_nogc.h>
7 #include <cds/container/split_list_base.h>
8 #include <cds/gc/nogc.h>
9 #include <cds/container/details/make_split_list_set.h>
11 namespace cds { namespace container {
13 /// Split-ordered list set (template specialization for gc::nogc)
14 /** @ingroup cds_nonintrusive_set
15 \anchor cds_nonintrusive_SplitListSet_nogc
17 This specialization is intended for so-called persistent usage when no item
18 reclamation may be performed. The class does not support deleting of list item.
20 See \ref cds_nonintrusive_SplitListSet_hp "SplitListSet" for description of template parameters.
22 The interface of the specialization is a slightly different.
26 #ifdef CDS_DOXYGEN_INVOKED
27 class Traits = split_list::type_traits
32 class SplitListSet< cds::gc::nogc, T, Traits>
33 #ifdef CDS_DOXYGEN_INVOKED
34 :protected intrusive::SplitListSet<cds::gc::nogc, typename Traits::ordered_list, Traits>
36 :protected details::make_split_list_set< cds::gc::nogc, T, typename Traits::ordered_list, split_list::details::wrap_set_traits<T, Traits> >::type
41 typedef details::make_split_list_set< cds::gc::nogc, T, typename Traits::ordered_list, split_list::details::wrap_set_traits<T, Traits> > options;
42 typedef typename options::type base_class;
46 typedef typename options::gc gc ; ///< Garbage collector
47 typedef typename options::value_type value_type ; ///< type of value stored in the list
48 typedef typename options::ordered_list ordered_list ; ///< Underlying ordered list class
49 typedef typename base_class::key_comparator key_comparator ; ///< key comparison functor
51 /// Hash functor for \ref value_type and all its derivatives that you use
52 typedef typename base_class::hash hash;
53 typedef typename base_class::item_counter item_counter ; ///< Item counter type
57 typedef typename options::cxx_node_allocator cxx_node_allocator;
58 typedef typename options::node_type node_type;
61 static node_type * alloc_node(Q const& v )
63 return cxx_node_allocator().New( v );
66 template <typename... Args>
67 static node_type * alloc_node( Args&&... args )
69 return cxx_node_allocator().MoveNew( std::forward<Args>(args)...);
72 static void free_node( node_type * pNode )
74 cxx_node_allocator().Delete( pNode );
77 struct node_disposer {
78 void operator()( node_type * pNode )
83 typedef std::unique_ptr< node_type, node_disposer > scoped_node_ptr;
89 # ifndef CDS_CXX11_LAMBDA_SUPPORT
90 struct empty_ensure_functor
92 void operator()( bool /*bNew*/, node_type& /*item*/, node_type& /*val*/ )
100 /// Initialize split-ordered list of default capacity
102 The default capacity is defined in bucket table constructor.
103 See intrusive::split_list::expandable_bucket_table, intrusive::split_list::static_ducket_table
104 which selects by intrusive::split_list::dynamic_bucket_table option.
110 /// Initialize split-ordered list
112 size_t nItemCount ///< estimate average of item count
113 , size_t nLoadFactor = 1 ///< load factor - average item count per bucket. Small integer up to 10, default is 1.
115 : base_class( nItemCount, nLoadFactor )
121 \p IsConst - constness boolean flag
123 The forward iterator has the following features:
124 - it has no post-increment operator
125 - it depends on underlying ordered list iterator
127 template <bool IsConst>
128 class iterator_type: protected base_class::template iterator_type<IsConst>
131 typedef typename base_class::template iterator_type<IsConst> iterator_base_class;
132 friend class SplitListSet;
135 /// Value pointer type (const for const iterator)
136 typedef typename cds::details::make_const_type<value_type, IsConst>::pointer value_ptr;
137 /// Value reference type (const for const iterator)
138 typedef typename cds::details::make_const_type<value_type, IsConst>::reference value_ref;
146 iterator_type( iterator_type const& src )
147 : iterator_base_class( src )
152 explicit iterator_type( iterator_base_class const& src )
153 : iterator_base_class( src )
158 /// Dereference operator
159 value_ptr operator ->() const
161 return &(iterator_base_class::operator->()->m_Value);
164 /// Dereference operator
165 value_ref operator *() const
167 return iterator_base_class::operator*().m_Value;
171 iterator_type& operator ++()
173 iterator_base_class::operator++();
177 /// Assignment operator
178 iterator_type& operator = (iterator_type const& src)
180 iterator_base_class::operator=(src);
184 /// Equality operator
186 bool operator ==(iterator_type<C> const& i ) const
188 return iterator_base_class::operator==(i);
191 /// Equality operator
193 bool operator !=(iterator_type<C> const& i ) const
195 return iterator_base_class::operator!=(i);
201 typedef iterator_type<false> iterator;
203 /// Const forward iterator
204 typedef iterator_type<true> const_iterator;
206 /// Returns a forward iterator addressing the first element in a set
208 For empty set \code begin() == end() \endcode
212 return iterator( base_class::begin() );
215 /// Returns an iterator that addresses the location succeeding the last element in a set
217 Do not use the value returned by <tt>end</tt> function to access any item.
218 The returned value can be used only to control reaching the end of the set.
219 For empty set \code begin() == end() \endcode
223 return iterator( base_class::end() );
226 /// Returns a forward const iterator addressing the first element in a set
227 const_iterator begin() const
229 return const_iterator( base_class::begin() );
232 /// Returns an const iterator that addresses the location succeeding the last element in a set
233 const_iterator end() const
235 return const_iterator( base_class::end() );
240 iterator insert_node( node_type * pNode )
242 assert( pNode != nullptr );
243 scoped_node_ptr p(pNode);
245 iterator it( base_class::insert_( *pNode ));
258 The function inserts \p val in the set if it does not contain
259 an item with key equal to \p val.
260 The \ref value_type should be constructible from a value of type \p Q.
262 Return an iterator pointing to inserted item if success \ref end() otherwise
264 template <typename Q>
265 iterator insert( const Q& val )
267 return insert_node( alloc_node( val ) );
270 /// Inserts data of type \ref value_type constructed with <tt>std::forward<Args>(args)...</tt>
272 Return an iterator pointing to inserted item if success \ref end() otherwise
274 template <typename... Args>
275 iterator emplace( Args&&... args )
277 return insert_node( alloc_node( std::forward<Args>(args)... ) );
280 /// Ensures that the item \p val exists in the set
282 The operation inserts new item created from \p val if the key \p val is not found in the set.
283 Otherwise, the function returns an iterator that points to item found.
284 The \p value_type should be constructible from a value of type \p Q.
286 Returns <tt> std::pair<iterator, bool> </tt> where \p first is an iterator pointing to
287 item found or inserted, \p second is true if new item has been added or \p false if the item
288 already is in the set.
290 template <typename Q>
291 std::pair<iterator, bool> ensure( const Q& val )
293 scoped_node_ptr pNode( alloc_node( val ));
295 # ifdef CDS_CXX11_LAMBDA_SUPPORT
296 std::pair<typename base_class::iterator, bool> ret = base_class::ensure_( *pNode, [](bool /*bNew*/, node_type& /*item*/, node_type& /*val*/){} );
298 std::pair<typename base_class::iterator, bool> ret = base_class::ensure_( *pNode, empty_ensure_functor() );
300 if ( ret.first != base_class::end() && ret.second ) {
302 return std::make_pair( iterator(ret.first), ret.second );
305 return std::make_pair( iterator(ret.first), ret.second );
308 /// Find the key \p val
309 /** \anchor cds_nonintrusive_SplitListSet_nogc_find
311 The function searches the item with key equal to \p key
312 and returns an iterator pointed to item found if the key is found,
313 and \ref end() otherwise
315 template <typename Q>
316 iterator find( Q const& key )
318 return iterator( base_class::find_( key ));
321 /// Finds the key \p val using \p pred predicate for searching
323 The function is an analog of \ref cds_nonintrusive_SplitListSet_nogc_find "find(Q const&)"
324 but \p pred is used for key comparing.
325 \p Less functor has the interface like \p std::less.
326 \p Less must imply the same element order as the comparator used for building the set.
328 template <typename Q, typename Less>
329 iterator find_with( Q const& key, Less pred )
331 return iterator( base_class::find_with_( key, typename options::template predicate_wrapper<Less>::type() ));
334 /// Checks if the set is empty
336 Emptiness is checked by item counting: if item count is zero then the set is empty.
337 Thus, the correct item counting feature is an important part of split-list set implementation.
341 return base_class::empty();
344 /// Returns item count in the set
347 return base_class::size();
351 }} // namespace cds::container
353 #endif // #ifndef __CDS_CONTAINER_SPLIT_LIST_SET_NOGC_H