Merge branch 'ldionne-ldionne-cmake' into dev
[libcds.git] / test / unit / misc / split_bitstring.cpp
index 360fd3d2bf1322305bf7c1dae12e21bf05e8818c..23e97e6dd7ca1e792fd1de2d665cba6aaab83955 100644 (file)
@@ -29,7 +29,7 @@
 */
 
 #include <cds/algo/split_bitstring.h>
-#include <gtest/gtest.h>
+#include <cds_test/ext_gtest.h>
 
 namespace {
     bool is_big_endian()
@@ -55,24 +55,24 @@ namespace {
             size_t res;
 
             // Trivial case
-            ASSERT_FALSE( splitter.eos() );
+            ASSERT_FALSE( splitter.eos());
             ASSERT_FALSE( !splitter );
             res = splitter.cut( sizeof( src ) * 8 );
             EXPECT_EQ( res, src );
-            ASSERT_TRUE( splitter.eos() );
+            ASSERT_TRUE( splitter.eos());
             ASSERT_TRUE( !splitter );
             EXPECT_EQ( splitter.safe_cut( sizeof( src ) * 8 ), 0u );
-            ASSERT_TRUE( splitter.eos() );
+            ASSERT_TRUE( splitter.eos());
             ASSERT_TRUE( !splitter );
             splitter.reset();
-            ASSERT_FALSE( splitter.eos() );
+            ASSERT_FALSE( splitter.eos());
             ASSERT_FALSE( !splitter );
             res = splitter.cut( sizeof( src ) * 8 );
             EXPECT_EQ( res, src );
-            ASSERT_TRUE( splitter.eos() );
+            ASSERT_TRUE( splitter.eos());
             ASSERT_TRUE( !splitter );
             EXPECT_EQ( splitter.safe_cut( sizeof( src ) * 8 ), 0u );
-            ASSERT_TRUE( splitter.eos() );
+            ASSERT_TRUE( splitter.eos());
             ASSERT_TRUE( !splitter );
 
             EXPECT_EQ( *splitter.source(), src );
@@ -154,24 +154,24 @@ namespace {
             size_t res;
 
             // Trivial case
-            ASSERT_FALSE( splitter.eos() );
+            ASSERT_FALSE( splitter.eos());
             ASSERT_FALSE( !splitter );
             res = splitter.cut( sizeof( src ) * 8 );
             ASSERT_EQ( res, src );
-            ASSERT_TRUE( splitter.eos() );
+            ASSERT_TRUE( splitter.eos());
             ASSERT_TRUE( !splitter );
             EXPECT_EQ( splitter.safe_cut( sizeof( src ) * 8 ), 0u );
-            ASSERT_TRUE( splitter.eos() );
+            ASSERT_TRUE( splitter.eos());
             ASSERT_TRUE( !splitter );
             splitter.reset();
-            ASSERT_FALSE( splitter.eos() );
+            ASSERT_FALSE( splitter.eos());
             ASSERT_FALSE( !splitter );
             res = splitter.cut( sizeof( src ) * 8 );
             EXPECT_EQ( res, src );
-            ASSERT_TRUE( splitter.eos() );
+            ASSERT_TRUE( splitter.eos());
             ASSERT_TRUE( !splitter );
             EXPECT_EQ( splitter.safe_cut( sizeof( src ) * 8 ), 0u );
-            ASSERT_TRUE( splitter.eos() );
+            ASSERT_TRUE( splitter.eos());
             ASSERT_TRUE( !splitter );
 
             EXPECT_EQ( *splitter.source(), src );
@@ -183,7 +183,14 @@ namespace {
             for ( size_t i = 0; i < sizeof(size_t) * 2; ++i ) {
                 ASSERT_FALSE( splitter.eos());
                 ASSERT_FALSE( !splitter );
-                EXPECT_EQ( splitter.cut( 4 ), 0x0F - i );
+                if ( i % 2 == 0 ) {
+                    // even - least half-byte
+                    EXPECT_EQ( splitter.cut( 4 ), 0x0E - i ) << "i=" << i;
+                }
+                else {
+                    // odd - most half-byte
+                    EXPECT_EQ( splitter.cut( 4 ), 0x0F - i + 1 ) << "i=" << i;
+                }
             }
             ASSERT_TRUE( splitter.eos());
             ASSERT_TRUE( !splitter );
@@ -203,7 +210,9 @@ namespace {
                 for ( size_t i = 0; i < sizeof(size_t) * 8; ++i ) {
                     ASSERT_FALSE( splitter.eos());
                     ASSERT_FALSE( !splitter );
-                    res = ( res << 1 ) | ( splitter.cut( 1 ) );
+                    if ( i % 8 == 0 )
+                        res = res << 8;
+                    res |= ( splitter.cut( 1 )) << ( i % 8 );
                 }
                 ASSERT_TRUE( splitter.eos());
                 ASSERT_TRUE( !splitter );
@@ -216,6 +225,7 @@ namespace {
             }
 
             // random cut
+            /*
             {
                 for ( size_t k = 0; k < 100; ++k ) {
                     splitter.reset();
@@ -243,6 +253,7 @@ namespace {
                     EXPECT_EQ( splitter.bit_offset(), sizeof( src ) * 8 );
                 }
             }
+            */
         }
 
         template <typename PartUInt>
@@ -344,7 +355,12 @@ namespace {
             for ( size_t i = 0; i < sizeof(size_t) * 2; ++i ) {
                 ASSERT_FALSE( splitter.eos());
                 ASSERT_FALSE( !splitter );
-                EXPECT_EQ( splitter.cut( 4 ), 0x0F - i );
+                if ( i % 2 == 0 ) {
+                    EXPECT_EQ( splitter.cut( 4 ), 0x0E - i );
+                }
+                else {
+                    EXPECT_EQ( splitter.cut( 4 ), 0x0F - i + 1 );
+                }
             }
             ASSERT_TRUE( splitter.eos());
             ASSERT_TRUE( !splitter );
@@ -360,7 +376,9 @@ namespace {
                 for ( size_t i = 0; i < sizeof(size_t) * 8; ++i ) {
                     ASSERT_FALSE( splitter.eos());
                     ASSERT_FALSE( !splitter );
-                    res = (res << 1) + splitter.cut( 1 );
+                    if ( i % 8 == 0 )
+                        res = res << 8;
+                    res |= ( splitter.cut( 1 )) << ( i % 8 );
                 }
                 ASSERT_TRUE( splitter.eos());
                 ASSERT_TRUE( !splitter );
@@ -372,6 +390,7 @@ namespace {
             }
 
             // random cut
+            /*
             {
                 for ( size_t k = 0; k < 100; ++k ) {
                     splitter.reset();
@@ -398,16 +417,18 @@ namespace {
                     EXPECT_EQ( splitter.bit_offset(), sizeof( src ) * 8 );
                 }
             }
+            */
         }
 
         struct int48 {
             uint32_t    n32;
             uint16_t    n16;
-
+#if 0
             friend bool operator ==( int48 lhs, int48 rhs )
             {
                 return lhs.n32 == rhs.n32 && lhs.n16 == rhs.n16;
             }
+#endif
 
             uint64_t to64() const
             {
@@ -428,71 +449,77 @@ namespace {
 
             uint64_t res;
 
+#if CDS_BUILD_BITS == 64
             {
                 typedef cds::algo::split_bitstring< int48, int48_size, size_t > split_bitstring;
                 split_bitstring splitter( src );
 
                 // Trivial case
-                ASSERT_FALSE( splitter.eos() );
+                ASSERT_FALSE( splitter.eos());
                 ASSERT_FALSE( !splitter );
                 res = splitter.cut( int48_size * 8 );
-                EXPECT_EQ( res, src.to64() );
-                ASSERT_TRUE( splitter.eos() );
+                EXPECT_EQ( res, src.to64());
+                ASSERT_TRUE( splitter.eos());
                 ASSERT_TRUE( !splitter );
                 EXPECT_EQ( splitter.safe_cut( int48_size * 8 ), 0u );
-                ASSERT_TRUE( splitter.eos() );
+                ASSERT_TRUE( splitter.eos());
                 ASSERT_TRUE( !splitter );
                 splitter.reset();
-                ASSERT_FALSE( splitter.eos() );
+                ASSERT_FALSE( splitter.eos());
                 ASSERT_FALSE( !splitter );
                 res = splitter.cut( int48_size * 8 );
-                EXPECT_EQ( res, src.to64() );
-                ASSERT_TRUE( splitter.eos() );
+                EXPECT_EQ( res, src.to64());
+                ASSERT_TRUE( splitter.eos());
                 ASSERT_TRUE( !splitter );
                 EXPECT_EQ( splitter.safe_cut( int48_size * 8 ), 0u );
-                ASSERT_TRUE( splitter.eos() );
+                ASSERT_TRUE( splitter.eos());
                 ASSERT_TRUE( !splitter );
             }
+#endif
 
             typedef cds::algo::split_bitstring< int48, int48_size, size_t > split_bitstring;
             split_bitstring splitter( src );
 
-            EXPECT_EQ( splitter.source()->to64(), src.to64() );
+            EXPECT_EQ( splitter.source()->to64(), src.to64());
             EXPECT_EQ( splitter.rest_count(), int48_size * 8 );
             EXPECT_EQ( splitter.bit_offset(), 0u );
 
             // Cut each hex digit
             splitter.reset();
             for ( size_t i = 0; i < int48_size * 2; ++i ) {
-                ASSERT_FALSE( splitter.eos() );
+                ASSERT_FALSE( splitter.eos());
                 ASSERT_FALSE( !splitter );
                 ASSERT_EQ( splitter.cut( 4 ), i );
             }
-            ASSERT_TRUE( splitter.eos() );
+            ASSERT_TRUE( splitter.eos());
             ASSERT_FALSE( splitter );
             EXPECT_EQ( splitter.safe_cut( 8 ), 0u );
-            EXPECT_EQ( splitter.source()->to64(), src.to64() );
+            EXPECT_EQ( splitter.source()->to64(), src.to64());
             EXPECT_EQ( splitter.rest_count(), 0u );
             EXPECT_EQ( splitter.bit_offset(), int48_size * 8 );
 
             // by one bit
             {
                 splitter.reset();
-                EXPECT_EQ( splitter.source()->to64(), src.to64() );
+                EXPECT_EQ( splitter.source()->to64(), src.to64());
                 EXPECT_EQ( splitter.rest_count(), int48_size * 8 );
                 EXPECT_EQ( splitter.bit_offset(), 0u );
 
                 res = 0;
                 for ( size_t i = 0; i < int48_size * 8; ++i ) {
-                    ASSERT_FALSE( splitter.eos() );
+                    ASSERT_FALSE( splitter.eos());
                     ASSERT_FALSE( !splitter );
+#if CDS_BUILD_BITS == 64
                     res |= splitter.cut( 1 ) << i;
+#else
+                    res |= static_cast<decltype(res)>( splitter.cut( 1 )) << i;
+#endif
                 }
-                ASSERT_TRUE( splitter.eos() );
+                ASSERT_TRUE( splitter.eos());
                 ASSERT_TRUE( !splitter );
-                EXPECT_EQ( res, src.to64() );
+                EXPECT_EQ( res, src.to64());
                 EXPECT_EQ( splitter.safe_cut( 8 ), 0u );
-                EXPECT_EQ( splitter.source()->to64(), src.to64() );
+                EXPECT_EQ( splitter.source()->to64(), src.to64());
                 EXPECT_EQ( splitter.rest_count(), 0u );
                 EXPECT_EQ( splitter.bit_offset(), int48_size * 8 );
             }
@@ -501,24 +528,28 @@ namespace {
             {
                 for ( size_t k = 0; k < 100; ++k ) {
                     splitter.reset();
-                    EXPECT_EQ( splitter.source()->to64(), src.to64() );
+                    EXPECT_EQ( splitter.source()->to64(), src.to64());
                     EXPECT_EQ( splitter.rest_count(), int48_size * 8 );
                     EXPECT_EQ( splitter.bit_offset(), 0u );
 
                     res = 0;
                     size_t shift = 0;
                     while ( splitter ) {
-                        ASSERT_FALSE( splitter.eos() );
+                        ASSERT_FALSE( splitter.eos());
                         ASSERT_FALSE( !splitter );
                         int bits = std::rand() % 16;
+#if CDS_BUILD_BITS == 64
                         res |= splitter.safe_cut( bits ) << shift;
+#else
+                        res |= static_cast<decltype(res)>( splitter.safe_cut( bits )) << shift;
+#endif
                         shift += bits;
                     }
-                    ASSERT_TRUE( splitter.eos() );
+                    ASSERT_TRUE( splitter.eos());
                     ASSERT_TRUE( !splitter );
-                    EXPECT_EQ( res, src.to64() );
+                    EXPECT_EQ( res, src.to64());
                     EXPECT_EQ( splitter.safe_cut( 8 ), 0u );
-                    EXPECT_EQ( splitter.source()->to64(), src.to64() );
+                    EXPECT_EQ( splitter.source()->to64(), src.to64());
                     EXPECT_EQ( splitter.rest_count(), 0u );
                     EXPECT_EQ( splitter.bit_offset(), int48_size * 8 );
                 }
@@ -533,102 +564,121 @@ namespace {
 
             uint64_t res;
 
+#if CDS_BUILD_BITS == 64
             {
                 typedef cds::algo::split_bitstring< int48, int48_size, size_t > split_bitstring;
                 split_bitstring splitter( src );
 
                 // Trivial case
-                ASSERT_FALSE( splitter.eos() );
+                ASSERT_FALSE( splitter.eos());
                 ASSERT_FALSE( !splitter );
                 res = splitter.cut( int48_size * 8 );
-                ASSERT_EQ( res, src.to64() );
-                ASSERT_TRUE( splitter.eos() );
+                ASSERT_EQ( res, src.to64());
+                ASSERT_TRUE( splitter.eos());
                 ASSERT_TRUE( !splitter );
                 EXPECT_EQ( splitter.safe_cut( int48_size * 8 ), 0u );
-                ASSERT_TRUE( splitter.eos() );
+                ASSERT_TRUE( splitter.eos());
                 ASSERT_TRUE( !splitter );
                 splitter.reset();
-                ASSERT_FALSE( splitter.eos() );
+                ASSERT_FALSE( splitter.eos());
                 ASSERT_FALSE( !splitter );
                 res = splitter.cut( int48_size * 8 );
-                EXPECT_EQ( res, src.to64() );
-                ASSERT_TRUE( splitter.eos() );
+                EXPECT_EQ( res, src.to64());
+                ASSERT_TRUE( splitter.eos());
                 ASSERT_TRUE( !splitter );
                 EXPECT_EQ( splitter.safe_cut( int48_size * 8 ), 0u );
-                ASSERT_TRUE( splitter.eos() );
+                ASSERT_TRUE( splitter.eos());
                 ASSERT_TRUE( !splitter );
             }
+#endif
 
             typedef cds::algo::split_bitstring< int48, int48_size, size_t > split_bitstring;
             split_bitstring splitter( src );
 
-            EXPECT_EQ( splitter.source()->to64(), src.to64() );
+            EXPECT_EQ( splitter.source()->to64(), src.to64());
             EXPECT_EQ( splitter.rest_count(), int48_size * 8 );
             EXPECT_EQ( splitter.bit_offset(), 0u );
 
             // Cut each hex digit
             splitter.reset();
             for ( size_t i = 0; i < int48_size * 2; ++i ) {
-                ASSERT_FALSE( splitter.eos() );
+                ASSERT_FALSE( splitter.eos());
                 ASSERT_FALSE( !splitter );
-                EXPECT_EQ( splitter.cut( 4 ), 0x0B - i );
+                if ( i % 2 == 0 ) {
+                    EXPECT_EQ( splitter.cut( 4 ), 0x0A - i );
+                }
+                else {
+                    EXPECT_EQ( splitter.cut( 4 ), 0x0B - i + 1 );
+                }
             }
-            ASSERT_TRUE( splitter.eos() );
+            ASSERT_TRUE( splitter.eos());
             ASSERT_TRUE( !splitter );
             EXPECT_EQ( splitter.safe_cut( 8 ), 0u );
-            EXPECT_EQ( splitter.source()->to64(), src.to64() );
+            EXPECT_EQ( splitter.source()->to64(), src.to64());
             EXPECT_EQ( splitter.rest_count(), 0u );
             EXPECT_EQ( splitter.bit_offset(), int48_size * 8 );
 
             // by one bit
             {
                 splitter.reset();
-                EXPECT_EQ( splitter.source()->to64(), src.to64() );
+                EXPECT_EQ( splitter.source()->to64(), src.to64());
                 EXPECT_EQ( splitter.rest_count(), int48_size * 8 );
                 EXPECT_EQ( splitter.bit_offset(), 0u );
 
                 res = 0;
                 for ( size_t i = 0; i < int48_size * 8; ++i ) {
-                    ASSERT_FALSE( splitter.eos() );
+                    ASSERT_FALSE( splitter.eos());
                     ASSERT_FALSE( !splitter );
-                    res = ( res << 1 ) | ( splitter.cut( 1 ) );
+#if CDS_BUILD_BITS == 64
+                    if ( i % 8 == 0 )
+                        res = res << 8;
+                    res |= ( splitter.cut( 1 )) << ( i % 8 );
+#else
+                    res = ( res << 1 ) | static_cast<decltype(res)>( splitter.cut( 1 ));
+#endif
                 }
-                ASSERT_TRUE( splitter.eos() );
+                ASSERT_TRUE( splitter.eos());
                 ASSERT_TRUE( !splitter );
-                EXPECT_EQ( res, src.to64() );
+                EXPECT_EQ( res, src.to64());
                 EXPECT_EQ( splitter.safe_cut( 8 ), 0u );
-                EXPECT_EQ( splitter.source()->to64(), src.to64() );
+                EXPECT_EQ( splitter.source()->to64(), src.to64());
                 EXPECT_EQ( splitter.rest_count(), 0u );
                 EXPECT_EQ( splitter.bit_offset(), int48_size * 8 );
             }
 
             // random cut
+            /*
             {
                 for ( size_t k = 0; k < 100; ++k ) {
                     splitter.reset();
-                    EXPECT_EQ( splitter.source()->to64(), src.to64() );
+                    EXPECT_EQ( splitter.source()->to64(), src.to64());
                     EXPECT_EQ( splitter.rest_count(), int48_size * 8 );
                     EXPECT_EQ( splitter.bit_offset(), 0u );
 
                     res = 0;
                     while ( splitter ) {
-                        ASSERT_FALSE( splitter.eos() );
+                        ASSERT_FALSE( splitter.eos());
                         ASSERT_FALSE( !splitter );
                         unsigned bits = std::rand() % 16;
                         size_t shift = splitter.rest_count();
                         if ( shift > bits )
                             shift = bits;
+#if CDS_BUILD_BITS == 64
                         res = ( res << shift ) | splitter.safe_cut( bits );
+#else
+                        res = ( res << shift ) | static_cast<decltype(res)>( splitter.safe_cut( bits ));
+#endif
                     }
-                    ASSERT_TRUE( splitter.eos() );
+                    ASSERT_TRUE( splitter.eos());
                     ASSERT_TRUE( !splitter );
-                    EXPECT_EQ( res, src.to64() );
+                    EXPECT_EQ( res, src.to64());
                     EXPECT_EQ( splitter.safe_cut( 8 ), 0u );
-                    EXPECT_EQ( splitter.source()->to64(), src.to64() );
+                    EXPECT_EQ( splitter.source()->to64(), src.to64());
                     EXPECT_EQ( splitter.rest_count(), 0u );
                     EXPECT_EQ( splitter.bit_offset(), int48_size * 8 );
                 }
             }
+            */
         }
 
         void cut_byte_le()
@@ -638,12 +688,12 @@ namespace {
             typedef cds::algo::byte_splitter< size_t > splitter_type;
             splitter_type splitter( src );
 
-            ASSERT_TRUE( !splitter.eos() );
+            ASSERT_TRUE( !splitter.eos());
             EXPECT_EQ( *splitter.source(), src );
             EXPECT_EQ( splitter.rest_count(), sizeof( src ) * 8 );
             EXPECT_EQ( splitter.bit_offset(), 0u );
-            EXPECT_TRUE( splitter.is_correct( 8 ) );
-            EXPECT_FALSE( splitter.is_correct( 4 ) );
+            EXPECT_TRUE( splitter.is_correct( 8 ));
+            EXPECT_FALSE( splitter.is_correct( 4 ));
 
             unsigned expected = 0x10;
             for ( unsigned i = 0; i < splitter_type::c_bitstring_size; ++i ) {
@@ -652,7 +702,7 @@ namespace {
                 expected += 0x22;
             }
 
-            ASSERT_TRUE( splitter.eos() );
+            ASSERT_TRUE( splitter.eos());
             EXPECT_EQ( splitter.safe_cut( 8 ), 0u );
             EXPECT_EQ( *splitter.source(), src );
             EXPECT_EQ( splitter.rest_count(), 0u );
@@ -666,12 +716,12 @@ namespace {
             typedef cds::algo::byte_splitter< size_t > splitter_type;
             splitter_type splitter( src );
 
-            ASSERT_TRUE( !splitter.eos() );
+            ASSERT_TRUE( !splitter.eos());
             EXPECT_EQ( *splitter.source(), src );
             EXPECT_EQ( splitter.rest_count(), sizeof( src ) * 8 );
             EXPECT_EQ( splitter.bit_offset(), 0u );
-            EXPECT_TRUE( splitter.is_correct( 8 ) );
-            EXPECT_FALSE( splitter.is_correct( 4 ) );
+            EXPECT_TRUE( splitter.is_correct( 8 ));
+            EXPECT_FALSE( splitter.is_correct( 4 ));
 
             unsigned expected = 0xFE;
             for ( unsigned i = 0; i < splitter_type::c_bitstring_size; ++i ) {
@@ -680,7 +730,7 @@ namespace {
                 expected -= 0x22;
             }
 
-            ASSERT_TRUE( splitter.eos() );
+            ASSERT_TRUE( splitter.eos());
             EXPECT_EQ( splitter.safe_cut( 8 ), 0u );
             EXPECT_EQ( *splitter.source(), src );
             EXPECT_EQ( splitter.rest_count(), 0u );
@@ -749,7 +799,7 @@ namespace {
 
     TEST_F( Split_bitstrig, cut_int48 )
     {
-        if ( is_big_endian() )
+        if ( is_big_endian())
             cut_int48_be();
         else
             cut_int48_le();
@@ -757,7 +807,7 @@ namespace {
 
     TEST_F( Split_bitstrig, cut_byte )
     {
-        if ( is_big_endian() )
+        if ( is_big_endian())
             cut_byte_be();
         else
             cut_byte_le();