Merge branch 'check' into dev
[libcds.git] / cds / container / michael_kvlist_nogc.h
index 01c2da0750a1756c1bb097a4190bf9ccbc3ae17b..15a14dfa1488718bd72349841d6331814da5c56b 100644 (file)
@@ -4,10 +4,9 @@
 #define __CDS_CONTAINER_MICHAEL_KVLIST_NOGC_H
 
 #include <memory>
-#include <cds/container/michael_list_base.h>
+#include <cds/container/details/michael_list_base.h>
 #include <cds/intrusive/michael_list_nogc.h>
 #include <cds/container/details/make_michael_kvlist.h>
-#include <cds/details/functor_wrapper.h>
 
 namespace cds { namespace container {
 
@@ -20,12 +19,12 @@ namespace cds { namespace container {
             typedef make_michael_kvlist<cds::gc::nogc, K, T, Traits>  base_maker;
             typedef typename base_maker::node_type node_type;
 
-            struct type_traits: public base_maker::type_traits
+            struct intrusive_traits: public base_maker::intrusive_traits
             {
                 typedef typename base_maker::node_deallocator    disposer;
             };
 
-            typedef intrusive::MichaelList<cds::gc::nogc, node_type, type_traits>  type;
+            typedef intrusive::MichaelList<cds::gc::nogc, node_type, intrusive_traits>  type;
         };
 
     }   // namespace details
@@ -33,6 +32,7 @@ namespace cds { namespace container {
 
     /// Michael's ordered list (key-value pair, template specialization for gc::nogc)
     /** @ingroup cds_nonintrusive_list
+        @anchor cds_nonintrusive_MichaelKVList_nogc
 
         This specialization is intended for so-called persistent usage when no item
         reclamation may be performed. The class does not support deleting of list item.
@@ -48,7 +48,7 @@ namespace cds { namespace container {
         typename Key,
         typename Value,
 #ifdef CDS_DOXYGEN_INVOKED
-        typename Traits = michael_list::type_traits
+        typename Traits = michael_list::traits
 #else
         typename Traits
 #endif
@@ -61,73 +61,40 @@ namespace cds { namespace container {
 #endif
     {
         //@cond
-        typedef details::make_michael_kvlist_nogc< Key, Value, Traits > options;
-        typedef typename options::type  base_class;
+        typedef details::make_michael_kvlist_nogc< Key, Value, Traits > maker;
+        typedef typename maker::type  base_class;
         //@endcond
 
     public:
+        typedef cds::gc::nogc gc;         ///< Garbage collector used
+        typedef Traits        traits;     ///< List traits
+
 #ifdef CDS_DOXYGEN_INVOKED
         typedef Key                                 key_type        ;   ///< Key type
         typedef Value                               mapped_type     ;   ///< Type of value stored in the list
         typedef std::pair<key_type const, mapped_type> value_type   ;   ///< key/value pair stored in the list
 #else
-        typedef typename options::key_type          key_type;
-        typedef typename options::value_type        mapped_type;
-        typedef typename options::pair_type         value_type;
+        typedef typename maker::key_type          key_type;
+        typedef typename maker::value_type        mapped_type;
+        typedef typename maker::pair_type         value_type;
 #endif
 
-        typedef typename base_class::gc             gc              ;   ///< Garbage collector used
-        typedef typename base_class::back_off       back_off        ;   ///< Back-off strategy used
-        typedef typename options::allocator_type    allocator_type  ;   ///< Allocator type used for allocate/deallocate the nodes
-        typedef typename base_class::item_counter   item_counter    ;   ///< Item counting policy used
-        typedef typename options::key_comparator    key_comparator  ;   ///< key comparison functor
-        typedef typename base_class::memory_model   memory_model    ;   ///< Memory ordering. See cds::opt::memory_model option
+        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
+        typedef typename base_class::item_counter item_counter;   ///< Item counting policy used
+        typedef typename maker::key_comparator    key_comparator; ///< key comparison functor
+        typedef typename base_class::memory_model memory_model;   ///< Memory ordering. See cds::opt::memory_model option
 
     protected:
         //@cond
-        typedef typename base_class::value_type     node_type;
-        typedef typename options::cxx_allocator     cxx_allocator;
-        typedef typename options::node_deallocator  node_deallocator;
-        typedef typename options::type_traits::compare  intrusive_key_comparator;
+        typedef typename base_class::value_type   node_type;
+        typedef typename maker::cxx_allocator     cxx_allocator;
+        typedef typename maker::node_deallocator  node_deallocator;
+        typedef typename maker::intrusive_traits::compare  intrusive_key_comparator;
 
         typedef typename base_class::atomic_node_ptr head_type;
         //@endcond
 
-    private:
-        //@cond
-#   ifndef CDS_CXX11_LAMBDA_SUPPORT
-        struct ensure_functor
-        {
-            node_type * m_pItemFound;
-
-            ensure_functor()
-                : m_pItemFound( nullptr )
-            {}
-
-            void operator ()(bool, node_type& item, node_type& )
-            {
-                m_pItemFound = &item;
-            }
-        };
-
-        template <typename Func>
-        class find_functor: protected cds::details::functor_wrapper<Func>
-        {
-            typedef cds::details::functor_wrapper<Func> base_class;
-        public:
-            find_functor( Func f )
-                : base_class(f)
-            {}
-
-            template <typename Q>
-            void operator ()( node_type& node, Q&  )
-            {
-                base_class::get()( node.m_Data );
-            }
-        };
-#   endif
-        //@endcond
-
     protected:
         //@cond
         template <typename K>
@@ -142,13 +109,11 @@ namespace cds { namespace container {
             return cxx_allocator().New( key, val );
         }
 
-#ifdef CDS_EMPLACE_SUPPORT
         template <typename K, typename... Args>
         static node_type * alloc_node( K&& key, Args&&... args )
         {
             return cxx_allocator().MoveNew( std::forward<K>(key), std::forward<Args>(args)... );
         }
-#endif
 
         static void free_node( node_type * pNode )
         {
@@ -296,7 +261,7 @@ namespace cds { namespace container {
         /// Returns an iterator that addresses the location succeeding the last element in a list
         /**
             Do not use the value returned by <tt>end</tt> function to access any item.
-            Internally, <tt>end</tt> returning value equals to <tt>NULL</tt>.
+            Internally, <tt>end</tt> returning value equals to \p nullptr.
 
             The returned value can be used only to control reaching the end of the list.
             For empty list \code begin() == end() \endcode
@@ -312,7 +277,7 @@ namespace cds { namespace container {
         {
             return const_iterator( head() );
         }
-        const_iterator cbegin()
+        const_iterator cbegin() const
         {
             return const_iterator( head() );
         }
@@ -324,7 +289,7 @@ namespace cds { namespace container {
         {
             return const_iterator();
         }
-        const_iterator cend()
+        const_iterator cend() const
         {
             return const_iterator();
         }
@@ -407,8 +372,6 @@ namespace cds { namespace container {
             to the list's item inserted. <tt>item.second</tt> is a reference to item's value that may be changed.
             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 <tt>boost::ref</tt>
-            and it is called only if the inserting is successful.
 
             The key_type should be constructible from value of type \p K.
 
@@ -444,20 +407,15 @@ namespace cds { namespace container {
             return std::make_pair( node_to_iterator( ret.first ), ret.second );
         }
 
-#   ifdef CDS_EMPLACE_SUPPORT
         /// Inserts data of type \ref mapped_type constructed with <tt>std::forward<Args>(args)...</tt>
         /**
             Returns an iterator pointed to inserted value, or \p end() if inserting is failed
-
-            This function is available only for compiler that supports
-            variadic template and move semantics
         */
         template <typename K, typename... Args>
         iterator emplace( K&& key, Args&&... args )
         {
             return node_to_iterator( emplace_at( head(), std::forward<K>(key), std::forward<Args>(args)... ));
         }
-#   endif
 
         /// Find the key \p key
         /** \anchor cds_nonintrusive_MichaelKVList_nogc_find
@@ -472,7 +430,7 @@ namespace cds { namespace container {
             return node_to_iterator( find_at( head(), key, intrusive_key_comparator() ) );
         }
 
-        /// Finds the key \p val using \p pred predicate for searching
+        /// Finds the key \p key using \p pred predicate for searching
         /**
             The function is an analog of \ref cds_nonintrusive_MichaelKVList_nogc_find "find(Q const&)"
             but \p pred is used for key comparing.
@@ -482,7 +440,8 @@ namespace cds { namespace container {
         template <typename Q, typename Less>
         iterator find_with( Q const& key, Less pred )
         {
-            return node_to_iterator( find_at( head(), key, typename options::template less_wrapper<Less>::type() ) );
+            CDS_UNUSED( pred );
+            return node_to_iterator( find_at( head(), key, typename maker::template less_wrapper<Less>::type() ) );
         }
 
         /// Check if the list is empty
@@ -493,11 +452,11 @@ namespace cds { namespace container {
 
         /// Returns list's item count
         /**
-            The value returned depends on opt::item_counter option. For atomicity::empty_item_counter,
+            The value returned depends on item counter provided by \p Traits. For \p atomicity::empty_item_counter,
             this function always returns 0.
 
-            <b>Warning</b>: even if you use real item counter and it returns 0, this fact is not mean that the list
-            is empty. To check list emptyness use \ref empty() method.
+            @note Even if you use real item counter and it returns 0, this fact does not mean that the list
+            is empty. To check list emptyness use \p empty() method.
         */
         size_t size() const
         {
@@ -505,9 +464,6 @@ namespace cds { namespace container {
         }
 
         /// Clears the list
-        /**
-            Post-condition: the list is empty
-        */
         void clear()
         {
             base_class::clear();
@@ -542,7 +498,7 @@ namespace cds { namespace container {
             scoped_node_ptr pNode( alloc_node( key ));
 
             if ( base_class::insert_at( refHead, *pNode )) {
-                cds::unref(f)( pNode->m_Data );
+                f( pNode->m_Data );
                 return pNode.release();
             }
             return nullptr;
@@ -554,13 +510,7 @@ namespace cds { namespace container {
             scoped_node_ptr pNode( alloc_node( key ));
             node_type * pItemFound = nullptr;
 
-#       ifdef CDS_CXX11_LAMBDA_SUPPORT
             std::pair<bool, bool> ret = base_class::ensure_at( refHead, *pNode, [&pItemFound](bool, node_type& item, node_type&){ pItemFound = &item; });
-#       else
-            ensure_functor func;
-            std::pair<bool, bool> ret = base_class::ensure_at( refHead, *pNode, boost::ref(func) );
-            pItemFound = func.m_pItemFound;
-#       endif
             assert( pItemFound != nullptr );
 
             if ( ret.first && ret.second )
@@ -568,32 +518,17 @@ namespace cds { namespace container {
             return std::make_pair( pItemFound, ret.second );
         }
 
-#   ifdef CDS_EMPLACE_SUPPORT
         template <typename K, typename... Args>
         node_type * emplace_at( head_type& refHead, K&& key, Args&&... args )
         {
             return insert_node_at( refHead, alloc_node( std::forward<K>(key), std::forward<Args>(args)... ));
         }
-#endif
 
         template <typename K, typename Compare>
         node_type * find_at( head_type& refHead, K const& key, Compare cmp )
         {
             return base_class::find_at( refHead, key, cmp );
         }
-
-        /*
-        template <typename K, typename Compare typename Func>
-        bool find_at( head_type& refHead, K& key, Compare cmp, Func f )
-        {
-#       ifdef CDS_CXX11_LAMBDA_SUPPORT
-            return base_class::find_at( refHead, key, cmp, [&f]( node_type& node, K const& ){ cds::unref(f)( node.m_Data ); });
-#       else
-            find_functor<Func>  wrapper( f );
-            return base_class::find_at( refHead, key, cmp, cds::ref(wrapper) );
-#       endif
-        }
-        */
         //@endcond
     };