Fixed EllenBinTree<RCU>
[libcds.git] / cds / intrusive / split_list.h
index 5aa0efce73abc9133c0b2f47342f02f7e76dc62a..4f7125fc56da808d598d5014a43d4132a9d3f22d 100644 (file)
@@ -197,7 +197,7 @@ namespace cds { namespace intrusive {
 
     protected:
         //@cond
-        typedef split_list::details::rebind_list_options<OrderedList, traits> wrapped_ordered_list;
+        typedef split_list::details::rebind_list_traits<OrderedList, traits> wrapped_ordered_list;
         //@endcond
 
     public:
@@ -298,7 +298,7 @@ namespace cds { namespace intrusive {
             }
 
             template <typename Q, typename Compare>
-            bool extract_at( dummy_node_type * pHead, typename gc::Guard& guard, split_list::details::search_value_type<Q> const& val, Compare cmp )
+            bool extract_at( dummy_node_type * pHead, typename guarded_ptr::native_guard& guard, split_list::details::search_value_type<Q> const& val, Compare cmp )
             {
                 assert( pHead != nullptr );
                 bucket_head_type h(pHead);
@@ -322,7 +322,7 @@ namespace cds { namespace intrusive {
             }
 
             template <typename Q, typename Compare>
-            bool get_at( dummy_node_type * pHead, typename gc::Guard& guard, split_list::details::search_value_type<Q> const& val, Compare cmp )
+            bool get_at( dummy_node_type * pHead, typename guarded_ptr::native_guard& guard, split_list::details::search_value_type<Q> const& val, Compare cmp )
             {
                 assert( pHead != nullptr );
                 bucket_head_type h(pHead);
@@ -439,10 +439,11 @@ namespace cds { namespace intrusive {
         void init()
         {
             // GC and OrderedList::gc must be the same
-            static_assert(( std::is_same<gc, typename ordered_list::gc>::value ), "GC and OrderedList::gc must be the same");
+            static_assert( std::is_same<gc, typename ordered_list::gc>::value, "GC and OrderedList::gc must be the same");
 
             // atomicity::empty_item_counter is not allowed as a item counter
-            static_assert(( !std::is_same<item_counter, atomicity::empty_item_counter>::value ), "atomicity::empty_item_counter is not allowed as a item counter");
+            static_assert( !std::is_same<item_counter, cds::atomicity::empty_item_counter>::value,
+                           "cds::atomicity::empty_item_counter is not allowed as a item counter");
 
             // Initialize bucket 0
             dummy_node_type * pNode = alloc_dummy_node( 0 /*split_list::dummy_hash(0)*/ );
@@ -470,7 +471,7 @@ namespace cds { namespace intrusive {
             dummy_node_type * pHead = get_bucket( nHash );
             assert( pHead != nullptr );
 
-            return m_Stat.onFind( 
+            return m_Stat.onFind(
                 m_List.find_at( pHead, sv, cmp,
                     [&f](value_type& item, split_list::details::search_value_type<Q>& val){ f(item, val.val ); })
             );
@@ -488,7 +489,7 @@ namespace cds { namespace intrusive {
         }
 
         template <typename Q, typename Compare>
-        bool get_( typename gc::Guard& guard, Q const& val, Compare cmp )
+        bool get_( typename guarded_ptr::native_guard& guard, Q const& val, Compare cmp )
         {
             size_t nHash = hash_value( val );
             split_list::details::search_value_type<Q const>  sv( val, split_list::regular_hash( nHash ));
@@ -499,13 +500,13 @@ namespace cds { namespace intrusive {
         }
 
         template <typename Q>
-        bool get_( typename gc::Guard& guard, Q const& key)
+        bool get_( typename guarded_ptr::native_guard& guard, Q const& key )
         {
             return get_( guard, key, key_comparator());
         }
 
         template <typename Q, typename Less>
-        bool get_with_( typename gc::Guard& guard, Q const& key, Less )
+        bool get_with_( typename guarded_ptr::native_guard& guard, Q const& key, Less )
         {
             return get_( guard, key, typename wrapped_ordered_list::template make_compare_from_less<Less>());
         }
@@ -545,10 +546,10 @@ namespace cds { namespace intrusive {
         }
 
         template <typename Q, typename Compare>
-        bool extract_( typename gc::Guard& guard, Q const& val, Compare cmp )
+        bool extract_( typename guarded_ptr::native_guard& guard, Q const& val, Compare cmp )
         {
             size_t nHash = hash_value( val );
-            split_list::details::search_value_type<Q const>  sv( val, split_list::regular_hash( nHash ));
+            split_list::details::search_value_type<Q const> sv( val, split_list::regular_hash( nHash ));
             dummy_node_type * pHead = get_bucket( nHash );
             assert( pHead != nullptr );
 
@@ -562,17 +563,16 @@ namespace cds { namespace intrusive {
         }
 
         template <typename Q>
-        bool extract_( typename gc::Guard& guard, Q const& key)
+        bool extract_( typename guarded_ptr::native_guard& guard, Q const& key )
         {
             return extract_( guard, key, key_comparator());
         }
 
         template <typename Q, typename Less>
-        bool extract_with_( typename gc::Guard& guard, Q const& key, Less )
+        bool extract_with_( typename guarded_ptr::native_guard& guard, Q const& key, Less )
         {
             return extract_( guard, key, typename wrapped_ordered_list::template make_compare_from_less<Less>() );
         }
-
         //@endcond
 
     public:
@@ -765,6 +765,7 @@ namespace cds { namespace intrusive {
         template <typename Q, typename Less>
         bool erase_with( const Q& key, Less pred )
         {
+            CDS_UNUSED( pred );
             return erase_( key, typename wrapped_ordered_list::template make_compare_from_less<Less>() );
         }
 
@@ -781,7 +782,6 @@ namespace cds { namespace intrusive {
                 void operator()( value_type const& item );
             };
             \endcode
-            The functor can be passed by reference with <tt>boost:ref</tt>
 
             If the item with key equal to \p key is not found the function return \p false.
 
@@ -803,19 +803,20 @@ namespace cds { namespace intrusive {
         template <typename Q, typename Less, typename Func>
         bool erase_with( Q const& key, Less pred, Func f )
         {
+            CDS_UNUSED( pred );
             return erase_( key, typename wrapped_ordered_list::template make_compare_from_less<Less>(), f );
         }
 
         /// Extracts the item with specified \p key
         /** \anchor cds_intrusive_SplitListSet_hp_extract
             The function searches an item with key equal to \p key,
-            unlinks it from the set, and returns it in \p dest parameter.
-            If the item with key equal to \p key is not found the function returns \p false.
+            unlinks it from the set, and returns it as \p guarded_ptr.
+            If \p key is not found the function returns an empty guarded pointer.
 
             Note the compare functor should accept a parameter of type \p Q that may be not the same as \p value_type.
 
-            The \ref disposer specified in \p OrderedList class' template parameter is called automatically
-            by garbage collector \p GC when returned \ref guarded_ptr object will be destroyed or released.
+            The \p disposer specified in \p OrderedList class' template parameter is called automatically
+            by garbage collector \p GC when returned \p guarded_ptr object will be destroyed or released.
             @note Each \p guarded_ptr object uses the GC's guard that can be limited resource.
 
             Usage:
@@ -824,24 +825,26 @@ namespace cds { namespace intrusive {
             splitlist_set theSet;
             // ...
             {
-                splitlist_set::guarded_ptr gp;
-                theSet.extract( gp, 5 );
-                // Deal with gp
-                // ...
-
+                splitlist_set::guarded_ptr gp( theSet.extract( 5 ));
+                if ( gp) {
+                    // Deal with gp
+                    // ...
+                }
                 // Destructor of gp releases internal HP guard
             }
             \endcode
         */
         template <typename Q>
-        bool extract( guarded_ptr& dest, Q const& key )
+        guarded_ptr extract( Q const& key )
         {
-            return extract_( dest.guard(), key );
+            guarded_ptr gp;
+            extract_( gp.guard(), key );
+            return gp;
         }
 
         /// Extracts the item using compare functor \p pred
         /**
-            The function is an analog of \ref cds_intrusive_SplitListSet_hp_extract "extract(guarded_ptr&, Q const&)"
+            The function is an analog of \ref cds_intrusive_SplitListSet_hp_extract "extract(Q const&)"
             but \p pred predicate is used for key comparing.
 
             \p Less functor has the semantics like \p std::less but should take arguments of type \ref value_type and \p Q
@@ -849,9 +852,11 @@ namespace cds { namespace intrusive {
             \p pred must imply the same element order as the comparator used for building the set.
         */
         template <typename Q, typename Less>
-        bool extract_with( guarded_ptr& dest, Q const& key, Less pred )
+        guarded_ptr extract_with( Q const& key, Less pred )
         {
-            return extract_with_( dest.guard(), key, pred );
+            guarded_ptr gp;
+            extract_with_( gp.guard(), key, pred );
+            return gp;
         }
 
         /// Finds the key \p key
@@ -865,8 +870,6 @@ namespace cds { namespace intrusive {
             \endcode
             where \p item is the item found, \p key is the <tt>find</tt> function argument.
 
-            You can pass \p f argument by value or by reference using \p std::ref.
-
             The functor can change non-key fields of \p item. Note that the functor is only guarantee
             that \p item cannot be disposed during functor is executing.
             The functor does not serialize simultaneous access to the set \p item. If such access is
@@ -882,6 +885,13 @@ namespace cds { namespace intrusive {
         {
             return find_( key, key_comparator(), f );
         }
+        //@cond
+        template <typename Q, typename Func>
+        bool find( Q const& key, Func f )
+        {
+            return find_( key, key_comparator(), f );
+        }
+        //@endcond
 
         /// Finds the key \p key with \p pred predicate for comparing
         /**
@@ -893,8 +903,17 @@ namespace cds { namespace intrusive {
         template <typename Q, typename Less, typename Func>
         bool find_with( Q& key, Less pred, Func f )
         {
+            CDS_UNUSED( pred );
             return find_( key, typename wrapped_ordered_list::template make_compare_from_less<Less>(), f );
         }
+        //@cond
+        template <typename Q, typename Less, typename Func>
+        bool find_with( Q const& key, Less pred, Func f )
+        {
+            CDS_UNUSED( pred );
+            return find_( key, typename wrapped_ordered_list::template make_compare_from_less<Less>(), f );
+        }
+        //@endcond
 
         /// Finds the key \p key
         /** \anchor cds_intrusive_SplitListSet_hp_find_val
@@ -921,18 +940,18 @@ namespace cds { namespace intrusive {
         template <typename Q, typename Less>
         bool find_with( Q const& key, Less pred )
         {
+            CDS_UNUSED( pred );
             return find_( key, typename wrapped_ordered_list::template make_compare_from_less<Less>() );
         }
 
         /// Finds the key \p key and return the item found
         /** \anchor cds_intrusive_SplitListSet_hp_get
             The function searches the item with key equal to \p key
-            and assigns the item found to guarded pointer \p ptr.
-            The function returns \p true if \p key is found, and \p false otherwise.
-            If \p key is not found the \p ptr parameter is not changed.
+            and returns the item found as \p guarded_ptr.
+            If \p key is not found the function returns an empty guarded pointer.
 
-            The \ref disposer specified in \p OrderedList class' template parameter is called
-            by garbage collector \p GC automatically when returned \ref guarded_ptr object
+            The \p disposer specified in \p OrderedList class' template parameter is called
+            by garbage collector \p GC automatically when returned \p guarded_ptr object
             will be destroyed or released.
             @note Each \p guarded_ptr object uses one GC's guard which can be limited resource.
 
@@ -942,8 +961,8 @@ namespace cds { namespace intrusive {
             splitlist_set theSet;
             // ...
             {
-                splitlist_set::guarded_ptr gp;
-                if ( theSet.get( gp, 5 )) {
+                splitlist_set::guarded_ptr gp = theSet.get( 5 );
+                if ( gp ) {
                     // Deal with gp
                     //...
                 }
@@ -955,14 +974,16 @@ namespace cds { namespace intrusive {
             should accept a parameter of type \p Q that can be not the same as \p value_type.
         */
         template <typename Q>
-        bool get( guarded_ptr& ptr, Q const& key )
+        guarded_ptr get( Q const& key )
         {
-            return get_( ptr.guard(), key );
+            guarded_ptr gp;
+            get_( gp.guard(), key );
+            return gp;
         }
 
         /// Finds the key \p key and return the item found
         /**
-            The function is an analog of \ref cds_intrusive_SplitListSet_hp_get "get( guarded_ptr& ptr, Q const&)"
+            The function is an analog of \ref cds_intrusive_SplitListSet_hp_get "get( Q const&)"
             but \p pred is used for comparing the keys.
 
             \p Less functor has the semantics like \p std::less but should take arguments of type \ref value_type and \p Q
@@ -970,9 +991,11 @@ namespace cds { namespace intrusive {
             \p pred must imply the same element order as the comparator used for building the set.
         */
         template <typename Q, typename Less>
-        bool get_with( guarded_ptr& ptr, Q const& key, Less pred )
+        guarded_ptr get_with( Q const& key, Less pred )
         {
-            return get_with_( ptr.guard(), key, pred );
+            guarded_ptr gp;
+            get_with_( gp.guard(), key, pred );
+            return gp;
         }
 
         /// Returns item count in the set
@@ -1009,6 +1032,12 @@ namespace cds { namespace intrusive {
             }
         }
 
+        /// Returns internal statistics
+        stat const& statistics() const
+        {
+            return m_Stat;
+        }
+
     protected:
         //@cond
         template <bool IsConst>
@@ -1076,13 +1105,23 @@ namespace cds { namespace intrusive {
         /// Returns a forward const iterator addressing the first element in a split-list
         const_iterator begin() const
         {
-            return const_iterator( m_List.begin(), m_List.end() );
+            return cbegin();
+        }
+        /// Returns a forward const iterator addressing the first element in a split-list
+        const_iterator cbegin() const
+        {
+            return const_iterator( m_List.cbegin(), m_List.cend() );
         }
 
         /// Returns an const iterator that addresses the location succeeding the last element in a split-list
         const_iterator end() const
         {
-            return const_iterator( m_List.end(), m_List.end() );
+            return cend();
+        }
+        /// Returns an const iterator that addresses the location succeeding the last element in a split-list
+        const_iterator cend() const
+        {
+            return const_iterator( m_List.cend(), m_List.cend() );
         }
 
     };