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/details/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 \p gc::nogc)
14 /** @ingroup cds_nonintrusive_set
15 \anchor cds_nonintrusive_SplitListSet_nogc
17 This specialization is so-called append-only container 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 @warning Many member functions return an iterator pointing to an item.
23 The iterator can be used to set up field of the item,
24 but you should provide an exclusive access to it,
25 see \ref cds_intrusive_item_creating "insert item troubleshooting".
29 #ifdef CDS_DOXYGEN_INVOKED
30 class Traits = split_list::traits
35 class SplitListSet< cds::gc::nogc, T, Traits>
36 #ifdef CDS_DOXYGEN_INVOKED
37 :protected intrusive::SplitListSet<cds::gc::nogc, typename Traits::ordered_list, Traits>
39 :protected details::make_split_list_set< cds::gc::nogc, T, typename Traits::ordered_list, split_list::details::wrap_set_traits<T, Traits> >::type
44 typedef details::make_split_list_set< cds::gc::nogc, T, typename Traits::ordered_list, split_list::details::wrap_set_traits<T, Traits> > maker;
45 typedef typename maker::type base_class;
49 typedef cds::gc::nogc gc; ///< Garbage collector
50 typedef T value_type; ///< type of value to be stored in the list
51 typedef Traits traits; ///< List traits
53 typedef typename maker::ordered_list ordered_list; ///< Underlying ordered list class
54 typedef typename base_class::key_comparator key_comparator; ///< key comparison functor
56 /// Hash functor for \ref value_type and all its derivatives that you use
57 typedef typename base_class::hash hash;
58 typedef typename base_class::item_counter item_counter; ///< Item counter type
62 typedef typename maker::cxx_node_allocator cxx_node_allocator;
63 typedef typename maker::node_type node_type;
66 static node_type * alloc_node(Q const& v )
68 return cxx_node_allocator().New( v );
71 template <typename... Args>
72 static node_type * alloc_node( Args&&... args )
74 return cxx_node_allocator().MoveNew( std::forward<Args>(args)...);
77 static void free_node( node_type * pNode )
79 cxx_node_allocator().Delete( pNode );
82 struct node_disposer {
83 void operator()( node_type * pNode )
88 typedef std::unique_ptr< node_type, node_disposer > scoped_node_ptr;
92 /// Initialize split-ordered list of default capacity
94 The default capacity is defined in bucket table constructor.
95 See \p intrusive::split_list::expandable_bucket_table, \p intrusive::split_list::static_bucket_table
96 which selects by \p split_list::dynamic_bucket_table option.
102 /// Initialize split-ordered list
104 size_t nItemCount ///< estimated average of item count
105 , size_t nLoadFactor = 1 ///< load factor - average item count per bucket. Small integer up to 10, default is 1.
107 : base_class( nItemCount, nLoadFactor )
113 \p IsConst - constness boolean flag
115 The forward iterator has the following features:
116 - it has no post-increment operator
117 - it depends on underlying ordered list iterator
119 template <bool IsConst>
120 class iterator_type: protected base_class::template iterator_type<IsConst>
123 typedef typename base_class::template iterator_type<IsConst> iterator_base_class;
124 friend class SplitListSet;
127 /// Value pointer type (const for const iterator)
128 typedef typename cds::details::make_const_type<value_type, IsConst>::pointer value_ptr;
129 /// Value reference type (const for const iterator)
130 typedef typename cds::details::make_const_type<value_type, IsConst>::reference value_ref;
138 iterator_type( iterator_type const& src )
139 : iterator_base_class( src )
144 explicit iterator_type( iterator_base_class const& src )
145 : iterator_base_class( src )
150 /// Dereference operator
151 value_ptr operator ->() const
153 return &(iterator_base_class::operator->()->m_Value);
156 /// Dereference operator
157 value_ref operator *() const
159 return iterator_base_class::operator*().m_Value;
163 iterator_type& operator ++()
165 iterator_base_class::operator++();
169 /// Assignment operator
170 iterator_type& operator = (iterator_type const& src)
172 iterator_base_class::operator=(src);
176 /// Equality operator
178 bool operator ==(iterator_type<C> const& i ) const
180 return iterator_base_class::operator==(i);
183 /// Equality operator
185 bool operator !=(iterator_type<C> const& i ) const
187 return iterator_base_class::operator!=(i);
193 typedef iterator_type<false> iterator;
195 /// Const forward iterator
196 typedef iterator_type<true> const_iterator;
198 /// Returns a forward iterator addressing the first element in a set
200 For empty set \code begin() == end() \endcode
204 return iterator( base_class::begin() );
207 /// Returns an iterator that addresses the location succeeding the last element in a set
209 Do not use the value returned by <tt>end</tt> function to access any item.
210 The returned value can be used only to control reaching the end of the set.
211 For empty set \code begin() == end() \endcode
215 return iterator( base_class::end() );
218 /// Returns a forward const iterator addressing the first element in a set
219 const_iterator begin() const
221 return const_iterator( base_class::begin() );
224 /// Returns an const iterator that addresses the location succeeding the last element in a set
225 const_iterator end() const
227 return const_iterator( base_class::end() );
232 iterator insert_node( node_type * pNode )
234 assert( pNode != nullptr );
235 scoped_node_ptr p(pNode);
237 iterator it( base_class::insert_( *pNode ));
250 The function inserts \p val in the set if it does not contain
251 an item with key equal to \p val.
252 The \p value_type should be constructible from a value of type \p Q.
254 Return an iterator pointing to inserted item if success \p end() otherwise
256 template <typename Q>
257 iterator insert( const Q& val )
259 return insert_node( alloc_node( val ) );
262 /// Inserts data of type \p value_type created from \p args
264 Return an iterator pointing to inserted item if success \p end() otherwise
266 template <typename... Args>
267 iterator emplace( Args&&... args )
269 return insert_node( alloc_node( std::forward<Args>(args)... ) );
272 /// Ensures that the item \p val exists in the set
274 The operation inserts new item created from \p val if the key \p val is not found in the set.
275 Otherwise, the function returns an iterator that points to item found.
276 The \p value_type should be constructible from a value of type \p Q.
278 Returns <tt> std::pair<iterator, bool> </tt> where \p first is an iterator pointing to
279 item found or inserted, \p second is true if new item has been added or \p false if the item
280 already is in the set.
282 template <typename Q>
283 std::pair<iterator, bool> ensure( const Q& val )
285 scoped_node_ptr pNode( alloc_node( val ));
287 std::pair<typename base_class::iterator, bool> ret = base_class::ensure_( *pNode, [](bool /*bNew*/, node_type& /*item*/, node_type& /*val*/){} );
288 if ( ret.first != base_class::end() && ret.second ) {
290 return std::make_pair( iterator(ret.first), ret.second );
293 return std::make_pair( iterator(ret.first), ret.second );
296 /// Find the key \p key
297 /** \anchor cds_nonintrusive_SplitListSet_nogc_find
299 The function searches the item with key equal to \p key
300 and returns an iterator pointed to item found if the key is found,
301 and \ref end() otherwise.
303 template <typename Q>
304 iterator find( Q const& key )
306 return iterator( base_class::find_( key ));
309 /// Finds the key \p key using \p pred predicate for searching
311 The function is an analog of \ref cds_nonintrusive_SplitListSet_nogc_find "find(Q const&)"
312 but \p pred is used for key comparing.
313 \p Less functor has the interface like \p std::less.
314 \p Less must imply the same element order as the comparator used for building the set.
316 template <typename Q, typename Less>
317 iterator find_with( Q const& key, Less pred )
319 return iterator( base_class::find_with_( key, typename maker::template predicate_wrapper<Less>::type() ));
322 /// Checks if the set is empty
324 Emptiness is checked by item counting: if item count is zero then the set is empty.
325 Thus, the correct item counting feature is an important part of split-list set implementation.
329 return base_class::empty();
332 /// Returns item count in the set
335 return base_class::size();
339 }} // namespace cds::container
341 #endif // #ifndef __CDS_CONTAINER_SPLIT_LIST_SET_NOGC_H