Merge branch 'master' into dev
[libcds.git] / test / unit / intrusive-list / test_intrusive_iterable_list.h
index 1db06f9c52c2a119ac95c7acf5d1977f73df73dc..6c49b305e7dcdf415de9d078dc9f6d3fcdd71f02 100644 (file)
@@ -1,11 +1,11 @@
 /*
     This file is a part of libcds - Concurrent Data Structures library
 
-    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
 
     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:
 
@@ -25,7 +25,7 @@
     SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.     
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 #ifndef CDSUNIT_LIST_TEST_INTRUSIVE_ITERABLE_LIST_H
 #define CDSUNIT_LIST_TEST_INTRUSIVE_ITERABLE_LIST_H
@@ -62,7 +62,7 @@ namespace cds_test {
 
             stat& operator =( const stat& s )
             {
-                memcpy( this, &s, sizeof( s ) );
+                memcpy( this, &s, sizeof( s ));
                 return *this;
             }
         };
@@ -150,7 +150,7 @@ namespace cds_test {
         struct cmp {
             int operator ()( const T& v1, const T& v2 ) const
             {
-                if ( v1.key() < v2.key() )
+                if ( v1.key() < v2.key())
                     return -1;
                 return v1.key() > v2.key() ? 1 : 0;
             }
@@ -166,7 +166,7 @@ namespace cds_test {
             template <typename Q>
             int operator ()( const Q& v1, const T& v2 ) const
             {
-                if ( v1 < v2.key() )
+                if ( v1 < v2.key())
                     return -1;
                 return v1 > v2.key() ? 1 : 0;
             }
@@ -232,7 +232,7 @@ namespace cds_test {
             shuffle( arr, arr + nSize );
             shuffle( arr2, arr2 + nSize );
 
-            ASSERT_TRUE( l.empty() );
+            ASSERT_TRUE( l.empty());
             ASSERT_CONTAINER_SIZE( l, 0 );
 
             typedef typename List::iterator iterator;
@@ -242,6 +242,7 @@ namespace cds_test {
                 EXPECT_FALSE( l.contains( i.nKey ));
                 EXPECT_FALSE( l.contains( other_item( i.nKey ), other_less()));
                 EXPECT_FALSE( l.find( i.nKey, []( value_type& item, int ) { ++item.s.nFindCall; } ));
+                EXPECT_TRUE( l.find( i.nKey ) == l.end());
                 EXPECT_EQ( i.s.nFindCall, 0 );
                 EXPECT_FALSE( l.find_with( other_item( i.nKey ), other_less(), []( value_type& item, other_item const& ) { ++item.s.nFindCall; } ));
                 EXPECT_EQ( i.s.nFindCall, 0 );
@@ -252,24 +253,24 @@ namespace cds_test {
                     break;
                 case 1:
                     EXPECT_EQ( i.s.nInsertCall, 0 );
-                    EXPECT_TRUE( l.insert( i, []( value_type& i ) { ++i.s.nInsertCall; } ));
+                    EXPECT_TRUE( l.insert( i, []( value_type& v ) { ++v.s.nInsertCall; } ));
                     EXPECT_EQ( i.s.nInsertCall, 1 );
                     break;
                 case 2:
                     {
-                        std::pair<bool, bool> ret = l.update( i, []( value_type& i, value_type * old ) {
+                        std::pair<bool, bool> ret = l.update( i, []( value_type& v, value_type * old ) {
                             EXPECT_TRUE( old == nullptr );
-                            EXPECT_EQ( i.s.nUpdateNewCall, 0 );
-                            ++i.s.nUpdateNewCall;
+                            EXPECT_EQ( v.s.nUpdateNewCall, 0 );
+                            ++v.s.nUpdateNewCall;
                         }, false );
                         EXPECT_EQ( i.s.nUpdateNewCall, 0 );
                         EXPECT_EQ( ret.first, false );
                         EXPECT_EQ( ret.second, false );
 
-                        ret = l.update( i, []( value_type& i, value_type * old ) {
+                        ret = l.update( i, []( value_type& v, value_type * old ) {
                             EXPECT_TRUE( old == nullptr );
-                            EXPECT_EQ( i.s.nUpdateNewCall, 0 );
-                            ++i.s.nUpdateNewCall;
+                            EXPECT_EQ( v.s.nUpdateNewCall, 0 );
+                            ++v.s.nUpdateNewCall;
                         }, true );
                         EXPECT_EQ( i.s.nUpdateNewCall, 1 );
                         EXPECT_EQ( ret.first, true );
@@ -292,6 +293,7 @@ namespace cds_test {
                 EXPECT_TRUE( l.contains( i.nKey ));
                 EXPECT_TRUE( l.contains( i ));
                 EXPECT_TRUE( l.contains( other_item( i.nKey ), other_less()));
+                EXPECT_FALSE( l.find( i.nKey ) == l.end());
                 EXPECT_TRUE( l.find( i.nKey, []( value_type& item, int ) { ++item.s.nFindCall; } ));
                 EXPECT_EQ( i.s.nFindCall, 1 );
                 EXPECT_TRUE( l.find( i, []( value_type& item, value_type const& ) { ++item.s.nFindCall; } ));
@@ -299,27 +301,27 @@ namespace cds_test {
                 EXPECT_TRUE( l.find_with( other_item( i.nKey ), other_less(), []( value_type& item, other_item const& ) { ++item.s.nFindCall; } ));
                 EXPECT_EQ( i.s.nFindCall, 3 );
 
-                EXPECT_FALSE( l.insert( i ) );
-                ASSERT_FALSE( l.empty() );
+                EXPECT_FALSE( l.insert( i ));
+                ASSERT_FALSE( l.empty());
 
                 int const ckey = i.nKey;
                 iterator it = l.find( ckey );
-                ASSERT_FALSE( it == l.end() );
+                ASSERT_FALSE( it == l.end());
                 EXPECT_EQ( it->nKey, i.nKey );
                 EXPECT_EQ( (*it).nVal, i.nVal );
-                check_ordered( it, l.end() );
+                check_ordered( it, l.end());
 
                 it = l.find( i.nKey );
-                ASSERT_FALSE( it == l.end() );
+                ASSERT_FALSE( it == l.end());
                 EXPECT_EQ( it->nKey, i.nKey );
                 EXPECT_EQ( (*it).nVal, i.nVal );
-                check_ordered( it, l.end() );
+                check_ordered( it, l.end());
 
-                it = l.find_with( other_item( i.nKey ), other_less() );
-                ASSERT_FALSE( it == l.end() );
+                it = l.find_with( other_item( i.nKey ), other_less());
+                ASSERT_FALSE( it == l.end());
                 EXPECT_EQ( it->nKey, i.nKey );
                 EXPECT_EQ( it->nVal, i.nVal );
-                check_ordered( it, l.end() );
+                check_ordered( it, l.end());
 
             }
             ASSERT_CONTAINER_SIZE( l, nSize );
@@ -336,13 +338,13 @@ namespace cds_test {
                 EXPECT_TRUE( l.find_with( other_item( i.nKey ), other_less(), []( value_type& item, other_item const& ) { ++item.s.nFindCall; } ));
                 EXPECT_EQ( i.s.nFindCall, 6 );
             }
-            ASSERT_FALSE( l.empty() );
+            ASSERT_FALSE( l.empty());
             ASSERT_CONTAINER_SIZE( l, nSize );
 
             // update existing test
             for ( auto& i : arr2 ) {
                 EXPECT_EQ( i.s.nUpdateExistsCall, 0 );
-                std::pair<bool, bool> ret = l.update( i, update_functor() );
+                std::pair<bool, bool> ret = l.update( i, update_functor());
                 EXPECT_TRUE( ret.first );
                 EXPECT_FALSE( ret.second );
                 EXPECT_EQ( i.s.nUpdateExistsCall, 1 );
@@ -351,7 +353,7 @@ namespace cds_test {
             // update with the same value must be empty - no functor is called
             for ( auto& i : arr2 ) {
                 EXPECT_EQ( i.s.nUpdateExistsCall, 1 );
-                std::pair<bool, bool> ret = l.update( i, update_functor() );
+                std::pair<bool, bool> ret = l.update( i, update_functor());
                 EXPECT_TRUE( ret.first );
                 EXPECT_FALSE( ret.second );
                 EXPECT_EQ( i.s.nUpdateExistsCall, 1 );
@@ -362,10 +364,10 @@ namespace cds_test {
 
             for ( auto& i : arr ) {
                 EXPECT_EQ( i.s.nUpdateExistsCall, 0 );
-                std::pair<bool, bool> ret = l.update( i, []( value_type& i, value_type * old ) {
+                std::pair<bool, bool> ret = l.update( i, []( value_type& v, value_type * old ) {
                     EXPECT_FALSE( old == nullptr );
-                    EXPECT_EQ( i.s.nUpdateExistsCall, 0 );
-                    ++i.s.nUpdateExistsCall;
+                    EXPECT_EQ( v.s.nUpdateExistsCall, 0 );
+                    ++v.s.nUpdateExistsCall;
                 });
                 EXPECT_TRUE( ret.first );
                 EXPECT_FALSE( ret.second );
@@ -377,11 +379,11 @@ namespace cds_test {
                 if ( i.nKey & 1 )
                     EXPECT_TRUE( l.erase( i.nKey ));
                 else
-                    EXPECT_TRUE( l.erase_with( other_item( i.nKey ), other_less() ));
+                    EXPECT_TRUE( l.erase_with( other_item( i.nKey ), other_less()));
 
                 EXPECT_FALSE( l.contains( i ));
             }
-            EXPECT_TRUE( l.empty() );
+            EXPECT_TRUE( l.empty());
             EXPECT_CONTAINER_SIZE( l, 0 );
 
             // Apply retired pointer to clean links
@@ -405,7 +407,7 @@ namespace cds_test {
                 EXPECT_TRUE( ret.second );
                 EXPECT_EQ( i.s.nUpdateNewCall, updateNewCall + 1 );
             }
-            EXPECT_FALSE( l.empty() );
+            EXPECT_FALSE( l.empty());
             EXPECT_CONTAINER_SIZE( l, nSize );
 
             for ( auto const& i : arr ) {
@@ -421,7 +423,7 @@ namespace cds_test {
                 EXPECT_EQ( i.s.nEraseCall, 1 );
                 EXPECT_FALSE( l.contains( i.nKey ));
             }
-            EXPECT_TRUE( l.empty() );
+            EXPECT_TRUE( l.empty());
             EXPECT_CONTAINER_SIZE( l, 0 );
 
             // Apply retired pointer to clean links
@@ -434,12 +436,12 @@ namespace cds_test {
             for ( auto& i : arr )
                 EXPECT_TRUE( l.insert( i ));
 
-            EXPECT_FALSE( l.empty() );
+            EXPECT_FALSE( l.empty());
             EXPECT_CONTAINER_SIZE( l, nSize );
 
             l.clear();
 
-            EXPECT_TRUE( l.empty() );
+            EXPECT_TRUE( l.empty());
             EXPECT_CONTAINER_SIZE( l, 0 );
 
             // Apply retired pointer to clean links
@@ -451,24 +453,24 @@ namespace cds_test {
 
             // unlink test
             for ( auto& i : arr )
-                EXPECT_TRUE( l.insert( i ) );
+                EXPECT_TRUE( l.insert( i ));
             for ( auto& i : arr ) {
                 value_type val( i );
                 EXPECT_TRUE( l.contains( val ));
                 EXPECT_FALSE( l.unlink( val ));
-                EXPECT_TRUE( l.contains( val ) );
+                EXPECT_TRUE( l.contains( val ));
                 EXPECT_TRUE( l.unlink( i ));
                 EXPECT_FALSE( l.unlink( i ));
-                EXPECT_FALSE( l.contains( i ) );
+                EXPECT_FALSE( l.contains( i ));
             }
-            EXPECT_TRUE( l.empty() );
+            EXPECT_TRUE( l.empty());
             EXPECT_CONTAINER_SIZE( l, 0 );
 
             // Apply retired pointer to clean links
             List::gc::force_dispose();
             for ( auto const& i : arr ) {
                 EXPECT_EQ( i.s.nDisposeCount, 5 );
-                EXPECT_FALSE( l.contains( i ) );
+                EXPECT_FALSE( l.contains( i ));
             }
 
             // Iterators on empty list
@@ -507,11 +509,11 @@ namespace cds_test {
             }
             shuffle( arr, arr + nSize );
 
-            ASSERT_TRUE( l.empty() );
+            ASSERT_TRUE( l.empty());
             ASSERT_CONTAINER_SIZE( l, 0 );
 
             for ( auto& i : arr )
-                EXPECT_TRUE( l.insert( i ) );
+                EXPECT_TRUE( l.insert( i ));
 
             int key = 0;
             for ( auto it = l.begin(); it != l.end(); ++it ) {
@@ -527,11 +529,27 @@ namespace cds_test {
                 ++key;
             }
 
-            l.clear();
+            // Erase by iterator
+            key = 0;
+            for ( auto it = l.begin(); it != l.end(); ++it ) {
+                EXPECT_EQ( it->nKey, key );
+                EXPECT_EQ( ( *it ).nKey, key );
+
+                EXPECT_TRUE( l.erase_at( it ));
+
+                EXPECT_EQ( it->nKey, key );
+                EXPECT_EQ( ( *it ).nKey, key );
+
+                EXPECT_FALSE( l.erase_at( it ));
+                ++key;
+            }
+            EXPECT_TRUE( l.empty());
+            EXPECT_CONTAINER_SIZE( l, 0 );
+
             List::gc::force_dispose();
             for ( auto const& i : arr ) {
                 EXPECT_EQ( i.s.nDisposeCount, 1 );
-                EXPECT_FALSE( l.contains( i ) );
+                EXPECT_FALSE( l.contains( i ));
             }
         }
 
@@ -551,4 +569,4 @@ namespace cds_test {
 
 } // namespace cds_test
 
-#endif // CDSUNIT_LIST_TEST_INTRUSIVE_ITERABLE_LIST_H 
+#endif // CDSUNIT_LIST_TEST_INTRUSIVE_ITERABLE_LIST_H