intrusive MSQueue refactoring (not tested)
[libcds.git] / cds / intrusive / skip_list_nogc.h
index 112e1b278d5afc99631b559c2fc4e6bc7855dd20..ba4ce74658afdbbc7718b9d42e239e6120dd8522 100644 (file)
@@ -5,10 +5,10 @@
 
 #include <type_traits>
 #include <memory>
+#include <functional>   // ref
 #include <cds/gc/nogc.h>
-#include <cds/intrusive/skip_list_base.h>
+#include <cds/intrusive/details/skip_list_base.h>
 #include <cds/opt/compare.h>
-#include <cds/ref.h>
 #include <cds/details/binary_functor_wrapper.h>
 
 namespace cds { namespace intrusive {
@@ -22,13 +22,13 @@ namespace cds { namespace intrusive {
             typedef cds::gc::nogc   gc          ;   ///< Garbage collector
             typedef Tag             tag         ;   ///< tag
 
-            typedef CDS_ATOMIC::atomic<node * > atomic_ptr;
+            typedef atomics::atomic<node * > atomic_ptr;
             typedef atomic_ptr                  tower_item_type;
 
         protected:
             atomic_ptr      m_pNext     ;   ///< Next item in bottom-list (list at level 0)
             unsigned int    m_nHeight   ;   ///< Node height (size of m_arrNext array). For node at level 0 the height is 1.
-            atomic_ptr *    m_arrNext   ;   ///< Array of next items for levels 1 .. m_nHeight - 1. For node at level 0 \p m_arrNext is \p NULL
+            atomic_ptr *    m_arrNext   ;   ///< Array of next items for levels 1 .. m_nHeight - 1. For node at level 0 \p m_arrNext is \p nullptr
 
         public:
             /// Constructs a node of height 1 (a bottom-list node)
@@ -103,12 +103,12 @@ namespace cds { namespace intrusive {
             void clear()
             {
                 assert( m_arrNext == nullptr );
-                m_pNext.store( nullptr, CDS_ATOMIC::memory_order_release );
+                m_pNext.store( nullptr, atomics::memory_order_release );
             }
 
             bool is_cleared() const
             {
-                return m_pNext.load( CDS_ATOMIC::memory_order_relaxed ) == nullptr
+                return m_pNext.load( atomics::memory_order_relaxed ) == nullptr
                     && m_arrNext == nullptr
                     && m_nHeight <= 1
 ;
@@ -137,7 +137,7 @@ namespace cds { namespace intrusive {
 
         public: // for internal use only!!!
             iterator( node_type& refHead )
-                : m_pNode( refHead[0].load( CDS_ATOMIC::memory_order_relaxed ) )
+                : m_pNode( refHead[0].load( atomics::memory_order_relaxed ) )
             {}
 
             static iterator from_node( node_type * pNode )
@@ -176,7 +176,7 @@ namespace cds { namespace intrusive {
             iterator& operator ++()
             {
                 if ( m_pNode )
-                    m_pNode = m_pNode->next(0).load( CDS_ATOMIC::memory_order_relaxed );
+                    m_pNode = m_pNode->next(0).load( atomics::memory_order_relaxed );
                 return *this;
             }
 
@@ -264,7 +264,7 @@ namespace cds { namespace intrusive {
             bool operator !=(iterator const& i ) const;
         };
         \endcode
-        Note, the iterator object returned by \ref end, \p cend member functions points to \p NULL and should not be dereferenced.
+        Note, the iterator object returned by \ref end, \p cend member functions points to \p nullptr and should not be dereferenced.
 
         <b>How to use</b>
 
@@ -410,31 +410,6 @@ namespace cds { namespace intrusive {
             node_type *   pCur;
         };
 
-#   ifndef CDS_CXX11_LAMBDA_SUPPORT
-        struct empty_insert_functor {
-            void operator()( value_type& )
-            {}
-        };
-
-        struct empty_find_functor {
-            template <typename Q>
-            void operator()( value_type& item, Q& val )
-            {}
-        };
-
-        template <typename Func>
-        struct insert_at_ensure_functor {
-            Func m_func;
-            insert_at_ensure_functor( Func f ) : m_func(f) {}
-
-            void operator()( value_type& item )
-            {
-                cds::unref( m_func)( true, item, item );
-            }
-        };
-
-#   endif // ifndef CDS_CXX11_LAMBDA_SUPPORT
-
         class head_node: public node_type
         {
             typename node_type::atomic_ptr   m_Tower[c_nMaxHeight];
@@ -443,7 +418,7 @@ namespace cds { namespace intrusive {
             head_node( unsigned int nHeight )
             {
                 for ( size_t i = 0; i < sizeof(m_Tower) / sizeof(m_Tower[0]); ++i )
-                    m_Tower[i].store( nullptr, CDS_ATOMIC::memory_order_relaxed );
+                    m_Tower[i].store( nullptr, atomics::memory_order_relaxed );
 
                 node_type::make_tower( nHeight, m_Tower );
             }
@@ -456,8 +431,8 @@ namespace cds { namespace intrusive {
             void clear()
             {
                 for (unsigned int i = 0; i < sizeof(m_Tower) / sizeof(m_Tower[0]); ++i )
-                    m_Tower[i].store( nullptr, CDS_ATOMIC::memory_order_relaxed );
-                node_type::m_pNext.store( nullptr, CDS_ATOMIC::memory_order_relaxed );
+                    m_Tower[i].store( nullptr, atomics::memory_order_relaxed );
+                node_type::m_pNext.store( nullptr, atomics::memory_order_relaxed );
             }
         };
         //@endcond
@@ -467,7 +442,7 @@ namespace cds { namespace intrusive {
 
         item_counter                m_ItemCounter       ;   ///< item counter
         random_level_generator      m_RandomLevelGen    ;   ///< random level generator instance
-        CDS_ATOMIC::atomic<unsigned int>    m_nHeight   ;   ///< estimated high level
+        atomics::atomic<unsigned int>    m_nHeight   ;   ///< estimated high level
         mutable stat                m_Stat              ;   ///< internal statistics
 
     protected:
@@ -559,7 +534,7 @@ namespace cds { namespace intrusive {
                 if ( !pos.pPrev[0]->next(0).compare_exchange_strong( p, pNode, memory_model::memory_order_release, memory_model::memory_order_relaxed ) ) {
                     return false;
                 }
-                cds::unref( f )( val );
+                f( val );
             }
 
             for ( unsigned int nLevel = 1; nLevel < nHeight; ++nLevel ) {
@@ -587,7 +562,7 @@ namespace cds { namespace intrusive {
             if ( find_position( val, pos, cmp, true, false )) {
                 assert( cmp( *node_traits::to_value_ptr( pos.pCur ), val ) == 0 );
 
-                cds::unref(f)( *node_traits::to_value_ptr( pos.pCur ), val );
+                f( *node_traits::to_value_ptr( pos.pCur ), val );
 
                 m_Stat.onFindFastSuccess();
                 return pos.pCur;
@@ -601,7 +576,7 @@ namespace cds { namespace intrusive {
         void increase_height( unsigned int nHeight )
         {
             unsigned int nCur = m_nHeight.load( memory_model::memory_order_relaxed );
-            while ( nCur < nHeight && !m_nHeight.compare_exchange_weak( nCur, nHeight, memory_model::memory_order_acquire, CDS_ATOMIC::memory_order_relaxed ) );
+            while ( nCur < nHeight && !m_nHeight.compare_exchange_weak( nCur, nHeight, memory_model::memory_order_acquire, atomics::memory_order_relaxed ) );
         }
         //@endcond
 
@@ -618,7 +593,7 @@ namespace cds { namespace intrusive {
             static_assert( (std::is_same< gc, typename node_type::gc >::value), "GC and node_type::gc must be the same type" );
 
             // Barrier for head node
-            CDS_ATOMIC::atomic_thread_fence( memory_model::memory_order_release );
+            atomics::atomic_thread_fence( memory_model::memory_order_release );
         }
 
         /// Clears and destructs the skip-list
@@ -714,12 +689,7 @@ namespace cds { namespace intrusive {
                         bTowerOk = true;
                 }
 
-#       ifndef CDS_CXX11_LAMBDA_SUPPORT
-                if ( !insert_at_position( val, pNode, pos, empty_insert_functor() ))
-#       else
-                if ( !insert_at_position( val, pNode, pos, []( value_type& ) {} ))
-#       endif
-                {
+                if ( !insert_at_position( val, pNode, pos, []( value_type& ) {} )) {
                     m_Stat.onInsertRetry();
                     continue;
                 }
@@ -753,7 +723,7 @@ namespace cds { namespace intrusive {
             The functor can change non-key fields of the \p item; however, \p func must guarantee
             that during changing no any other modifications could be made on this item by concurrent threads.
 
-            You can pass \p func argument by value or by reference using <tt>boost::ref</tt> or cds::ref.
+            You can pass \p func argument by value or by reference using \p std::ref.
 
             Returns std::pair<bool, bool> where \p first is \p true if operation is successfull,
             \p second is \p true if new item has been added or \p false if the item with \p key
@@ -768,10 +738,6 @@ namespace cds { namespace intrusive {
             bool bTowerOk = nHeight > 1 && pNode->get_tower() != nullptr;
             bool bTowerMade = false;
 
-#       ifndef CDS_CXX11_LAMBDA_SUPPORT
-            insert_at_ensure_functor<Func> wrapper( func );
-#       endif
-
             position pos;
             while ( true )
             {
@@ -781,7 +747,7 @@ namespace cds { namespace intrusive {
                     if ( !bTowerMade )
                         scp.release();
 
-                    cds::unref(func)( false, *node_traits::to_value_ptr(pos.pCur), val );
+                    func( false, *node_traits::to_value_ptr(pos.pCur), val );
                     m_Stat.onEnsureExist();
                     return std::make_pair( true, false );
                 }
@@ -793,12 +759,7 @@ namespace cds { namespace intrusive {
                         bTowerOk = true;
                 }
 
-#       ifdef CDS_CXX11_LAMBDA_SUPPORT
-                if ( !insert_at_position( val, pNode, pos, [&func]( value_type& item ) { cds::unref(func)( true, item, item ); }))
-#       else
-                if ( !insert_at_position( val, pNode, pos, cds::ref(wrapper) ))
-#       endif
-                {
+                if ( !insert_at_position( val, pNode, pos, [&func]( value_type& item ) { func( true, item, item ); })) {
                     m_Stat.onInsertRetry();
                     continue;
                 }
@@ -823,7 +784,7 @@ namespace cds { namespace intrusive {
             \endcode
             where \p item is the item found, \p val is the <tt>find</tt> function argument.
 
-            You can pass \p f argument by value or by reference using <tt>boost::ref</tt> or cds::ref.
+            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.
@@ -868,7 +829,7 @@ namespace cds { namespace intrusive {
             \endcode
             where \p item is the item found, \p val is the <tt>find</tt> function argument.
 
-            You can pass \p f argument by value or by reference using <tt>boost::ref</tt> or cds::ref.
+            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.
@@ -910,12 +871,7 @@ namespace cds { namespace intrusive {
         template <typename Q>
         value_type * find( Q const& val ) const
         {
-            node_type * pNode =
-#       ifdef CDS_CXX11_LAMBDA_SUPPORT
-                find_with_( val, key_comparator(), [](value_type& , Q const& ) {} );
-#       else
-                find_with_( val, key_comparator(), empty_find_functor() );
-#       endif
+            node_type * pNode = find_with_( val, key_comparator(), [](value_type& , Q const& ) {} );
             if ( pNode )
                 return node_traits::to_value_ptr( pNode );
             return nullptr;
@@ -931,12 +887,7 @@ namespace cds { namespace intrusive {
         template <typename Q, typename Less>
         value_type * find_with( Q const& val, Less pred ) const
         {
-            node_type * pNode =
-#       ifdef CDS_CXX11_LAMBDA_SUPPORT
-                find_with_( val, cds::opt::details::make_comparator_from_less<Less>(), [](value_type& , Q const& ) {} );
-#       else
-                find_with_( val, cds::opt::details::make_comparator_from_less<Less>(), empty_find_functor() );
-#       endif
+            node_type * pNode = find_with_( val, cds::opt::details::make_comparator_from_less<Less>(), [](value_type& , Q const& ) {} );
             if ( pNode )
                 return node_traits::to_value_ptr( pNode );
             return nullptr;
@@ -944,7 +895,7 @@ namespace cds { namespace intrusive {
 
         /// Gets minimum key from the set
         /**
-            If the set is empty the function returns \p NULL
+            If the set is empty the function returns \p nullptr
         */
         value_type * get_min() const
         {
@@ -953,7 +904,7 @@ namespace cds { namespace intrusive {
 
         /// Gets maximum key from the set
         /**
-            The function returns \p NULL if the set is empty
+            The function returns \p nullptr if the set is empty
         */
         value_type * get_max() const
         {