Major merge from 'dev'
[libcds.git] / cds / container / michael_list_rcu.h
index 740f0d86cd6ac97bf19dcf6787d6fa7f8b57d94c..cc53b77351ed8b7f39d284448966b14184caff41 100644 (file)
@@ -1,7 +1,7 @@
 //$$CDS-header$$
 
-#ifndef __CDS_CONTAINER_MICHAEL_LIST_RCU_H
-#define __CDS_CONTAINER_MICHAEL_LIST_RCU_H
+#ifndef CDSLIB_CONTAINER_MICHAEL_LIST_RCU_H
+#define CDSLIB_CONTAINER_MICHAEL_LIST_RCU_H
 
 #include <memory>
 #include <cds/container/details/michael_list_base.h>
@@ -111,9 +111,9 @@ namespace cds { namespace container {
         //@endcond
 
     public:
-        typedef cds::urcu::gc<RCU> gc;          ///< RCU 
+        typedef cds::urcu::gc<RCU> gc;          ///< RCU
         typedef T                  value_type;  ///< Type of value stored in the list
-        typedef Traits             traits;      /// List traits
+        typedef Traits             traits;      ///< List traits
 
         typedef typename base_class::back_off     back_off;       ///< Back-off strategy used
         typedef typename maker::allocator_type    allocator_type; ///< Allocator type used for allocate/deallocate the nodes
@@ -136,7 +136,7 @@ namespace cds { namespace container {
         //@endcond
 
     public:
-        typedef cds::urcu::exempt_ptr< gc, node_type, value_type, typename maker::intrusive_traits::disposer > exempt_ptr; ///< pointer to extracted node
+        using exempt_ptr = cds::urcu::exempt_ptr< gc, node_type, value_type, typename maker::intrusive_traits::disposer >; ///< pointer to extracted node
 
     private:
         //@cond
@@ -278,7 +278,7 @@ namespace cds { namespace container {
         {
             return const_iterator( head() );
         }
-        const_iterator cbegin()
+        const_iterator cbegin() const
         {
             return const_iterator( head() );
         }
@@ -290,7 +290,7 @@ namespace cds { namespace container {
         {
             return const_iterator();
         }
-        const_iterator cend()
+        const_iterator cend() const
         {
             return const_iterator();
         }
@@ -341,8 +341,6 @@ namespace cds { namespace container {
             The argument \p itemValue of user-defined functor \p func is the reference
             to the list's item inserted. User-defined functor \p func should guarantee that during changing
             item's value no any other changes could be made on this list's item by concurrent threads.
-            The user-defined functor can be passed by reference using \p std::ref
-            and it is called only if the inserting is success.
 
             The type \p Q should contain the complete key of the node.
             The object of \ref value_type should be constructible from \p key of type \p Q.
@@ -356,6 +354,8 @@ namespace cds { namespace container {
             it is preferable that the initialization should be completed only if inserting is successful.
 
             The function makes RCU lock internally.
+
+            @warning See \ref cds_intrusive_item_creating "insert item troubleshooting"
         */
         template <typename Q, typename Func>
         bool insert( Q const& key, Func func )
@@ -393,6 +393,8 @@ namespace cds { namespace container {
             Returns <tt> std::pair<bool, bool> </tt> where \p first is true if operation is successfull,
             \p second is true if new item has been added or \p false if the item with \p key
             already is in the list.
+
+            @warning See \ref cds_intrusive_item_creating "insert item troubleshooting"
         */
         template <typename Q, typename Func>
         std::pair<bool, bool> ensure( Q const& key, Func f )
@@ -416,7 +418,7 @@ namespace cds { namespace container {
         /** \anchor cds_nonintrusive_MichealList_rcu_erase_val
             Since the key of MichaelList's item type \p value_type is not explicitly specified,
             template parameter \p Q defines the key type searching in the list.
-            The list item comparator should be able to compare values of the type \p value_type 
+            The list item comparator should be able to compare values of the type \p value_type
             and \p Q in any order.
 
             RCU \p synchronize method can be called. RCU should not be locked.
@@ -439,6 +441,7 @@ namespace cds { namespace container {
         template <typename Q, typename Less>
         bool erase_with( Q const& key, Less pred )
         {
+            CDS_UNUSED( pred );
             return erase_at( head(), key, typename maker::template less_wrapper<Less>::type(), [](value_type const&){} );
         }
 
@@ -479,6 +482,7 @@ namespace cds { namespace container {
         template <typename Q, typename Less, typename Func>
         bool erase_with( Q const& key, Less pred, Func f )
         {
+            CDS_UNUSED( pred );
             return erase_at( head(), key, typename maker::template less_wrapper<Less>::type(), f );
         }
 
@@ -486,8 +490,8 @@ namespace cds { namespace container {
         /**
         @anchor cds_nonintrusive_MichaelList_rcu_extract
             The function searches an item with key equal to \p key in the list,
-            unlinks it from the list, and returns pointer to an item found in \p dest argument.
-            If the item with the key equal to \p key is not found the function returns \p false.
+            unlinks it from the list, and returns \ref cds::urcu::exempt_ptr "exempt_ptr" pointer to the item found.
+            If the item with the key equal to \p key is not found the function returns an empty \p exempt_ptr.
 
             @note The function does NOT call RCU read-side lock or synchronization,
             and does NOT dispose the item found. It just excludes the item from the list
@@ -511,7 +515,8 @@ namespace cds { namespace container {
 
                 // Now, you can apply extract function
                 // Note that you must not delete the item found inside the RCU lock
-                if ( theList.extract( p, 10 )) {
+                p = theList.extract( 10 )
+                if ( p ) {
                     // do something with p
                     ...
                 }
@@ -522,25 +527,24 @@ namespace cds { namespace container {
             \endcode
         */
         template <typename Q>
-        bool extract( exempt_ptr& dest, Q const& key )
+        exempt_ptr extract( Q const& key )
         {
-            dest = extract_at( head(), key, intrusive_key_comparator() );
-            return !dest.empty();
+            return exempt_ptr( extract_at( head(), key, intrusive_key_comparator() ));
         }
 
         /// Extracts an item from the list using \p pred predicate for searching
         /**
-            This function is the analog for \ref cds_nonintrusive_MichaelList_rcu_extract "extract(exempt_ptr&, Q const&)".
+            This function is the analog for \p extract(Q const&).
 
             The \p pred is a predicate used for key comparing.
             \p Less has the interface like \p std::less.
             \p pred must imply the same element order as \ref key_comparator.
         */
         template <typename Q, typename Less>
-        bool extract_with( exempt_ptr& dest, Q const& key, Less pred )
+        exempt_ptr extract_with( Q const& key, Less pred )
         {
-            dest = extract_at( head(), key, typename maker::template less_wrapper<Less>::type() );
-            return !dest.empty();
+            CDS_UNUSED( pred );
+            return exempt_ptr( extract_at( head(), key, typename maker::template less_wrapper<Less>::type() ));
         }
 
         /// Finds the key \p key
@@ -566,6 +570,7 @@ namespace cds { namespace container {
         template <typename Q, typename Less>
         bool find_with( Q const& key, Less pred ) const
         {
+            CDS_UNUSED( pred );
             return find_at( head(), key, typename maker::template less_wrapper<Less>::type() );
         }
 
@@ -594,6 +599,13 @@ namespace cds { namespace container {
         {
             return find_at( head(), key, intrusive_key_comparator(), f );
         }
+        //@cond
+        template <typename Q, typename Func>
+        bool find( Q const& key, Func f ) const
+        {
+            return find_at( head(), key, intrusive_key_comparator(), f );
+        }
+        //@endcond
 
         /// Finds the key \p key using \p pred predicate for searching
         /**
@@ -605,8 +617,17 @@ namespace cds { namespace container {
         template <typename Q, typename Less, typename Func>
         bool find_with( Q& key, Less pred, Func f ) const
         {
+            CDS_UNUSED( pred );
             return find_at( head(), key, typename maker::template less_wrapper<Less>::type(), f );
         }
+        //@cond
+        template <typename Q, typename Less, typename Func>
+        bool find_with( Q const& key, Less pred, Func f ) const
+        {
+            CDS_UNUSED( pred );
+            return find_at( head(), key, typename maker::template less_wrapper<Less>::type(), f );
+        }
+        //@endcond
 
         /// Finds the key \p key and return the item found
         /** \anchor cds_nonintrusive_MichaelList_rcu_get
@@ -653,6 +674,7 @@ namespace cds { namespace container {
         template <typename Q, typename Less>
         value_type * get_with( Q const& key, Less pred ) const
         {
+            CDS_UNUSED( pred );
             return get_at( head(), key, typename maker::template less_wrapper<Less>::type());
         }
 
@@ -768,4 +790,4 @@ namespace cds { namespace container {
 
 }}  // namespace cds::container
 
-#endif  // #ifndef __CDS_CONTAINER_MICHAEL_LIST_RCU_H
+#endif  // #ifndef CDSLIB_CONTAINER_MICHAEL_LIST_RCU_H