fix make_distrib
[libcds.git] / cds / intrusive / moir_queue.h
index 29e081215b6e684585e7e5e90a49b55ee2f1a0d2..0d2d62a852f8ee5ffcbd93fb7b99c3b7245e05f6 100644 (file)
@@ -12,7 +12,7 @@ namespace cds { namespace intrusive {
         This is slightly optimized Michael & Scott's queue algorithm that overloads \ref dequeue function.
 
         Source:
-            \li [2000] Simon Doherty, Lindsay Groves, Victor Luchangco, Mark Moir
+            - [2000] Simon Doherty, Lindsay Groves, Victor Luchangco, Mark Moir
                 "Formal Verification of a practical lock-free queue algorithm"
 
         Cite from this work about difference from Michael & Scott algo:
@@ -23,8 +23,6 @@ namespace cds { namespace intrusive {
         frequently, our modification will reduce the number of accesses to global memory. This modification, however,
         introduces the possibility of \p Head and \p Tail \93crossing\94."
 
-        Type of node: \ref single_link::node
-
         Explanation of template arguments see intrusive::MSQueue.
 
         \par Examples
@@ -36,7 +34,7 @@ namespace cds { namespace intrusive {
         typedef cds::gc::HP hp_gc;
 
         // MoirQueue with Hazard Pointer garbage collector, base hook + item disposer:
-        struct Foo: public ci::single_link::node< hp_gc >
+        struct Foo: public ci::msqueue::node< hp_gc >
         {
             // Your data
             ...
@@ -53,10 +51,12 @@ namespace cds { namespace intrusive {
         typedef ci::MoirQueue<
             hp_gc
             ,Foo
-            ,ci::opt::hook<
-                ci::single_link::base_hook< ci::opt::gc<hp_gc> >
-            >
-            ,ci::opt::disposer< fooDisposer >
+            typename ci::msqueue::make_traits<
+                ,ci::opt::hook<
+                    ci::msqueue::base_hook< ci::opt::gc<hp_gc> >
+                >
+                ,ci::opt::disposer< fooDisposer >
+            >::type
         > fooQueue;
 
         // MoirQueue with Hazard Pointer garbage collector,
@@ -66,30 +66,24 @@ namespace cds { namespace intrusive {
         {
             // Your data
             ...
-            ci::single_link::node< hp_gc > hMember;
+            ci::msqueue::node< hp_gc > hMember;
         };
 
-        typedef ci::MoirQueue<
-            hp_gc
-            ,Foo
-            ,ci::opt::hook<
-                ci::single_link::member_hook<
-                    offsetof(Bar, hMember)
-                    ,ci::opt::gc<hp_gc>
-                >
-            >
-            ,ci::opt::disposer< fooDisposer >
-            ,cds::opt::item_counter< cds::atomicity::item_counter >
-            ,cds::opt::alignment< cds::opt::no_special_alignment >
-        > barQueue;
-
+        struct barQueueTraits: public ci::msqueue::traits
+        {
+            typedef ci::msqueue::member_hook< offsetof(Bar, hMember), ,ci::opt::gc<hp_gc> > hook;
+            typedef fooDisposer disposer;
+            typedef cds::atomicity::item_counter item_counter;
+            enum { aligment = cds::opt::no_special_alignment alignment };
+        };
+        typedef ci::MoirQueue< hp_gc, Bar, barQueueTraits > barQueue;
         \endcode
     */
-    template <typename GC, typename T, CDS_DECL_OPTIONS9>
-    class MoirQueue: public MSQueue< GC, T, CDS_OPTIONS9 >
+    template <typename GC, typename T, typename Traits = cds::intrusive::msqueue::traits>
+    class MoirQueue: public MSQueue< GC, T, Traits >
     {
         //@cond
-        typedef MSQueue< GC, T, CDS_OPTIONS9 > base_class;
+        typedef MSQueue< GC, T, Traits > base_class;
         typedef typename base_class::node_type node_type;
         //@endcond
 
@@ -103,9 +97,9 @@ namespace cds { namespace intrusive {
         //@endcond
 
         /// Rebind template arguments
-        template <typename GC2, typename T2, CDS_DECL_OTHER_OPTIONS9>
+        template < typename GC2, typename T2, typename Traits2 >
         struct rebind {
-            typedef MoirQueue< GC2, T2, CDS_OTHER_OPTIONS9> other   ;   ///< Rebinding result
+            typedef MoirQueue< GC2, T2, Traits2> other   ;   ///< Rebinding result
         };
 
     protected:
@@ -123,13 +117,13 @@ namespace cds { namespace intrusive {
                 h = res.guards.protect( 0, base_class::m_pHead, node_to_value() );
                 pNext = res.guards.protect( 1, h->m_pNext, node_to_value() );
 
-                if ( pNext == null_ptr<node_type *>() )
+                if ( pNext == nullptr )
                     return false    ;    // queue is empty
 
-                if ( base_class::m_pHead.compare_exchange_strong( h, pNext, memory_model::memory_order_release, CDS_ATOMIC::memory_order_relaxed )) {
+                if ( base_class::m_pHead.compare_exchange_strong( h, pNext, memory_model::memory_order_release, atomics::memory_order_relaxed )) {
                     node_type * t = base_class::m_pTail.load(memory_model::memory_order_acquire);
                     if ( h == t )
-                        base_class::m_pTail.compare_exchange_strong( t, pNext, memory_model::memory_order_release, CDS_ATOMIC::memory_order_relaxed );
+                        base_class::m_pTail.compare_exchange_strong( t, pNext, memory_model::memory_order_release, atomics::memory_order_relaxed );
                     break;
                 }
 
@@ -149,7 +143,7 @@ namespace cds { namespace intrusive {
     public:
         /// Dequeues a value from the queue
         /** @anchor cds_intrusive_MoirQueue_dequeue
-            See warning about item disposing in \ref MSQueue::dequeue.
+            See warning about item disposing in \p MSQueue::dequeue.
         */
         value_type * dequeue()
         {
@@ -158,7 +152,7 @@ namespace cds { namespace intrusive {
                 base_class::dispose_result( res );
                 return node_traits::to_value_ptr( *res.pNext );
             }
-            return null_ptr<value_type *>();
+            return nullptr;
         }
 
         /// Synonym for \ref cds_intrusive_MoirQueue_dequeue "dequeue" function