TreiberStack bugfix
[libcds.git] / cds / intrusive / tsigas_cycle_queue.h
index 73131d3434a4e2093cd46ddf065019b04e057267..f9bbb360a74ee097be6f59b30ca2486168d49779 100644 (file)
@@ -3,11 +3,11 @@
 #ifndef __CDS_INTRUSIVE_TSIGAS_CYCLE_QUEUE_H
 #define __CDS_INTRUSIVE_TSIGAS_CYCLE_QUEUE_H
 
-#include <cds/intrusive/base.h>
+#include <functional>   // ref
+#include <cds/intrusive/details/base.h>
 #include <cds/cxx11_atomic.h>
 #include <cds/details/bounded_container.h>
 #include <cds/opt/buffer.h>
-#include <cds/ref.h>
 
 namespace cds { namespace intrusive {
 
@@ -60,7 +60,7 @@ namespace cds { namespace intrusive {
         dynamic_queue    dynQueue( 1024 );
         \endcode
     */
-    template <typename T, CDS_DECL_OPTIONS7>
+    template <typename T, typename... Options>
     class TsigasCycleQueue: public cds::bounded_container
     {
         //@cond
@@ -77,16 +77,16 @@ namespace cds { namespace intrusive {
     public:
         //@cond
         typedef typename opt::make_options<
-            typename cds::opt::find_type_traits< default_options, CDS_OPTIONS7>::type
-            ,CDS_OPTIONS7
+            typename cds::opt::find_type_traits< default_options, Options...>::type
+            ,Options...
         >::type   options;
         //@endcond
 
     public:
         /// Rebind template arguments
-        template <typename T2, CDS_DECL_OTHER_OPTIONS7>
+        template <typename T2, typename... Options2>
         struct rebind {
-            typedef TsigasCycleQueue< T2, CDS_OTHER_OPTIONS7> other   ;   ///< Rebinding result
+            typedef TsigasCycleQueue< T2, Options2...> other   ;   ///< Rebinding result
         };
 
     public:
@@ -98,10 +98,10 @@ namespace cds { namespace intrusive {
 
     protected:
         //@cond
-        typedef typename options::buffer::template rebind< CDS_ATOMIC::atomic<value_type *> >::other buffer;
+        typedef typename options::buffer::template rebind< atomics::atomic<value_type *> >::other buffer;
         typedef typename opt::details::alignment_setter< buffer, options::alignment >::type aligned_buffer;
         typedef size_t index_type;
-        typedef typename opt::details::alignment_setter< CDS_ATOMIC::atomic<index_type>, options::alignment >::type aligned_index;
+        typedef typename opt::details::alignment_setter< atomics::atomic<index_type>, options::alignment >::type aligned_index;
         //@endcond
 
     protected:
@@ -116,7 +116,7 @@ namespace cds { namespace intrusive {
         //@cond
         static CDS_CONSTEXPR value_type * free0() CDS_NOEXCEPT
         {
-            return null_ptr<value_type *>();
+            return nullptr;
         }
         static CDS_CONSTEXPR value_type * free1() CDS_NOEXCEPT
         {
@@ -216,7 +216,7 @@ namespace cds { namespace intrusive {
                     }
 
                     // help the dequeue to update head
-                    m_nHead.compare_exchange_strong( temp, ate, memory_model::memory_order_release, CDS_ATOMIC::memory_order_relaxed );
+                    m_nHead.compare_exchange_strong( temp, ate, memory_model::memory_order_release, atomics::memory_order_relaxed );
                     continue;
                 }
 
@@ -226,9 +226,9 @@ namespace cds { namespace intrusive {
                     continue;
 
                 // get actual tail and try to enqueue new node
-                if ( m_buffer[ate].compare_exchange_strong( tt, pNewNode, memory_model::memory_order_release, CDS_ATOMIC::memory_order_relaxed ) ) {
+                if ( m_buffer[ate].compare_exchange_strong( tt, pNewNode, memory_model::memory_order_release, atomics::memory_order_relaxed ) ) {
                     if ( temp % 2 == 0 )
-                        m_nTail.compare_exchange_strong( te, temp, memory_model::memory_order_release, CDS_ATOMIC::memory_order_relaxed );
+                        m_nTail.compare_exchange_strong( te, temp, memory_model::memory_order_release, atomics::memory_order_relaxed );
                     ++m_ItemCounter;
                     return true;
                 }
@@ -241,7 +241,7 @@ namespace cds { namespace intrusive {
 
         /// Dequeues item from the queue
         /** @anchor cds_intrusive_TsigasQueue_dequeue
-            If the queue is empty the function returns \a NULL
+            If the queue is empty the function returns \p nullptr
 
             Dequeue does not call value disposer. You can manually dispose returned value if it is needed.
         */
@@ -261,9 +261,9 @@ namespace cds { namespace intrusive {
                     if ( th != m_nHead.load(memory_model::memory_order_relaxed) )
                         goto TryAgain;
 
-                    // two consecutive NULL means queue empty
+                    // two consecutive nullptr means queue empty
                     if ( temp == m_nTail.load(memory_model::memory_order_acquire) )
-                        return NULL;
+                        return nullptr;
 
                     temp = ( temp + 1 ) & nModulo;
                     tt = m_buffer[ temp ].load(memory_model::memory_order_relaxed);
@@ -275,7 +275,7 @@ namespace cds { namespace intrusive {
                 // check whether the queue is empty
                 if ( temp == m_nTail.load(memory_model::memory_order_acquire) ) {
                     // help the enqueue to update end
-                    m_nTail.compare_exchange_strong( temp, (temp + 1) & nModulo, memory_model::memory_order_release, CDS_ATOMIC::memory_order_relaxed );
+                    m_nTail.compare_exchange_strong( temp, (temp + 1) & nModulo, memory_model::memory_order_release, atomics::memory_order_relaxed );
                     continue;
                 }
 
@@ -285,9 +285,9 @@ namespace cds { namespace intrusive {
                     continue;
 
                 // Get the actual head, null means empty
-                if ( m_buffer[temp].compare_exchange_strong( tt, pNull, memory_model::memory_order_release, CDS_ATOMIC::memory_order_relaxed )) {
+                if ( m_buffer[temp].compare_exchange_strong( tt, pNull, memory_model::memory_order_release, atomics::memory_order_relaxed )) {
                     if ( temp % 2 == 0 )
-                        m_nHead.compare_exchange_strong( th, temp, memory_model::memory_order_release, CDS_ATOMIC::memory_order_relaxed );
+                        m_nHead.compare_exchange_strong( th, temp, memory_model::memory_order_release, atomics::memory_order_relaxed );
                     --m_ItemCounter;
                     return reinterpret_cast<value_type *>(reinterpret_cast<intptr_t>( tt ) & ~intptr_t(1));
                 }
@@ -296,7 +296,7 @@ namespace cds { namespace intrusive {
             } while ( bkoff(), true );
 
             // No control path reaches this line!
-            return null_ptr<value_type *>();
+            return nullptr;
         }
 
         /// Synonym of \ref cds_intrusive_TsigasQueue_enqueue "enqueue"
@@ -325,7 +325,7 @@ namespace cds { namespace intrusive {
             while ( is_free( tt ) ) {
                 if ( th != m_nHead.load(memory_model::memory_order_relaxed) )
                     goto TryAgain;
-                // two consecutive NULL means queue empty
+                // two consecutive nullptr means queue empty
                 if ( temp == m_nTail.load(memory_model::memory_order_relaxed) )
                     return true;
                 temp = ( temp + 1 ) & nModulo;
@@ -343,15 +343,15 @@ namespace cds { namespace intrusive {
                 void operator ()( T * val );
             };
             \endcode
-            You can pass \p disposer by reference using \p boost::ref.
+            You can pass \p disposer by reference using \p std::ref.
             The disposer will be called immediately for each item.
         */
         template <typename Disposer>
         void clear( Disposer f )
         {
             value_type * pv;
-            while ( (pv = pop()) != null_ptr<value_type *>() ) {
-                unref(f)( pv );
+            while ( (pv = pop()) != nullptr ) {
+                f( pv );
             }
         }