Fixed Clang build
[libcds.git] / cds / intrusive / impl / iterable_list.h
index ccc50be6d1f7ea0f97d5a53373f3da31517ac3e8..fe85cc98ff13a56f2021ba79143039681f7eda28 100644 (file)
@@ -5,7 +5,7 @@
 
     Source code repo: http://github.com/khizmax/libcds/
     Download: http://sourceforge.net/projects/libcds/files/
-    
+
     Redistribution and use in source and binary forms, with or without
     modification, are permitted provided that the following conditions are met:
 
@@ -160,6 +160,7 @@ namespace cds { namespace intrusive {
         //@endcond
 
     protected:
+        //@cond
         typedef atomics::atomic< node_type* > atomic_node_ptr;  ///< Atomic node pointer
         typedef atomic_node_ptr               auxiliary_head;   ///< Auxiliary head type (for split-list support)
 
@@ -167,7 +168,6 @@ namespace cds { namespace intrusive {
         item_counter    m_ItemCounter;  ///< Item counter
         mutable stat    m_Stat;         ///< Internal statistics
 
-        //@cond
         typedef cds::details::Allocator< node_type, node_allocator > cxx_node_allocator;
 
         /// Position pointer for item search
@@ -190,35 +190,32 @@ namespace cds { namespace intrusive {
 
         protected:
             node_type*  m_pNode;
-            value_type* m_pVal;
-            typename gc::Guard  m_Guard; // for m_pVal
+            typename gc::Guard  m_Guard; // data guard
 
             void next()
             {
                 while ( m_pNode ) {
-                    m_pNode = m_pNode->next.load( memory_model::memory_order_relaxed );
-                    if ( !m_pNode )
+                    m_pNode = m_pNode->next.load( memory_model::memory_order_acquire );
+                    if ( !m_pNode ) {
+                        m_Guard.clear();
                         break;
-                    m_pVal = m_Guard.protect( m_pNode->data );
-                    if ( m_pVal )
+                    }
+                    if ( m_Guard.protect( m_pNode->data ))
                         break;
                 }
             }
 
             explicit iterator_type( atomic_node_ptr const& pNode )
-                : m_pNode( pNode.load( memory_model::memory_order_relaxed ))
-                , m_pVal( nullptr )
+                : m_pNode( pNode.load( memory_model::memory_order_acquire ))
             {
                 if ( m_pNode ) {
-                    m_pVal = m_Guard.protect( m_pNode->data );
-                    if ( !m_pVal )
+                    if ( !m_Guard.protect( m_pNode->data ))
                         next();
                 }
             }
 
             iterator_type( node_type* pNode, value_type* pVal )
                 : m_pNode( pNode )
-                , m_pVal( pVal )
             {
                 if ( m_pNode ) {
                     assert( pVal != nullptr );
@@ -232,25 +229,23 @@ namespace cds { namespace intrusive {
 
             iterator_type()
                 : m_pNode( nullptr )
-                , m_pVal( nullptr )
             {}
 
             iterator_type( iterator_type const& src )
                 : m_pNode( src.m_pNode )
-                , m_pVal( src.m_pVal )
             {
-                m_Guard.assign( m_pVal );
+                m_Guard.copy( src.m_Guard );
             }
 
             value_ptr operator ->() const
             {
-                return m_pVal;
+                return m_Guard.template get<value_type>();
             }
 
             value_ref operator *() const
             {
-                assert( m_pVal != nullptr );
-                return *m_pVal;
+                assert( m_Guard.get_native() != nullptr );
+                return *m_Guard.template get<value_type>();
             }
 
             /// Pre-increment
@@ -263,8 +258,7 @@ namespace cds { namespace intrusive {
             iterator_type& operator = (iterator_type const& src)
             {
                 m_pNode = src.m_pNode;
-                m_pVal = src.m_pVal;
-                m_Guard.assign( m_pVal );
+                m_Guard.copy( src.m_Guard );
                 return *this;
             }
 
@@ -276,7 +270,7 @@ namespace cds { namespace intrusive {
             template <bool C>
             bool operator !=(iterator_type<C> const& i ) const
             {
-                return m_pNode != i.m_pNode;
+                return !( *this == i );
             }
         };
         //@endcond
@@ -591,7 +585,7 @@ namespace cds { namespace intrusive {
             ord_list theList;
             // ...
             {
-                ord_list::guarded_ptr gp(theList.extract( 5 ));
+                ord_list::guarded_ptr gp( theList.extract( 5 ));
                 if ( gp ) {
                     // Deal with gp
                     // ...
@@ -603,9 +597,7 @@ namespace cds { namespace intrusive {
         template <typename Q>
         guarded_ptr extract( Q const& key )
         {
-            guarded_ptr gp;
-            extract_at( m_pHead, gp.guard(), key, key_comparator());
-            return gp;
+            return extract_at( m_pHead, key, key_comparator());
         }
 
         /// Extracts the item using compare functor \p pred
@@ -621,9 +613,7 @@ namespace cds { namespace intrusive {
         guarded_ptr extract_with( Q const& key, Less pred )
         {
             CDS_UNUSED( pred );
-            guarded_ptr gp;
-            extract_at( m_pHead, gp.guard(), key, cds::opt::details::make_comparator_from_less<Less>());
-            return gp;
+            return extract_at( m_pHead, key, cds::opt::details::make_comparator_from_less<Less>());
         }
 
         /// Finds \p key in the list
@@ -760,9 +750,7 @@ namespace cds { namespace intrusive {
         template <typename Q>
         guarded_ptr get( Q const& key ) const
         {
-            guarded_ptr gp;
-            get_at( m_pHead, gp.guard(), key, key_comparator());
-            return gp;
+            return get_at( m_pHead, key, key_comparator());
         }
 
         /// Finds the \p key and return the item found
@@ -778,9 +766,7 @@ namespace cds { namespace intrusive {
         guarded_ptr get_with( Q const& key, Less pred ) const
         {
             CDS_UNUSED( pred );
-            guarded_ptr gp;
-            get_at( m_pHead, gp.guard(), key, cds::opt::details::make_comparator_from_less<Less>());
-            return gp;
+            return get_at( m_pHead, key, cds::opt::details::make_comparator_from_less<Less>());
         }
 
         /// Clears the list (thread safe, not atomic)
@@ -995,16 +981,16 @@ namespace cds { namespace intrusive {
         }
 
         template <typename Q, typename Compare>
-        bool extract_at( atomic_node_ptr& refHead, typename guarded_ptr::native_guard& dest, Q const& val, Compare cmp )
+        guarded_ptr extract_at( atomic_node_ptr& refHead, Q const& val, Compare cmp )
         {
             position pos;
             back_off bkoff;
             while ( search( refHead, val, pos, cmp )) {
                 if ( unlink_node( pos )) {
-                    dest.set( pos.pFound );
                     --m_ItemCounter;
                     m_Stat.onEraseSuccess();
-                    return true;
+                    assert( pos.pFound != nullptr );
+                    return guarded_ptr( std::move( pos.guard ));
                 }
                 else
                     bkoff();
@@ -1013,7 +999,7 @@ namespace cds { namespace intrusive {
             }
 
             m_Stat.onEraseFailed();
-            return false;
+            return guarded_ptr();
         }
 
         template <typename Q, typename Compare>
@@ -1060,17 +1046,16 @@ namespace cds { namespace intrusive {
         }
 
         template <typename Q, typename Compare>
-        bool get_at( atomic_node_ptr const& refHead, typename guarded_ptr::native_guard& guard, Q const& val, Compare cmp ) const
+        guarded_ptr get_at( atomic_node_ptr const& refHead, Q const& val, Compare cmp ) const
         {
             position pos;
             if ( search( refHead, val, pos, cmp )) {
-                guard.set( pos.pFound );
                 m_Stat.onFindSuccess();
-                return true;
+                return guarded_ptr( std::move( pos.guard ));
             }
 
             m_Stat.onFindFailed();
-            return false;
+            return guarded_ptr();
         }
         //@endcond