Small fixes in split_bitstring algo
authorkhizmax <libcds.dev@gmail.com>
Wed, 5 Aug 2015 19:46:23 +0000 (22:46 +0300)
committerkhizmax <libcds.dev@gmail.com>
Wed, 5 Aug 2015 19:46:23 +0000 (22:46 +0300)
improving split_bitstring test

cds/algo/split_bitstring.h
tests/test-hdr/misc/split_bitstring.cpp

index 51590e2f1915f691632818b89358da8108051f2f..19c183fdfd053d2ede65cdefd82db413af054e6d 100644 (file)
@@ -70,7 +70,7 @@ namespace cds { namespace algo {
 #   endif
             uint_type result;
 
-            size_t const nRest = c_nBitPerInt - m_pos % c_nBitPerInt;
+            uint_type const nRest = c_nBitPerInt - m_pos % c_nBitPerInt;
             m_pos += nBits;
             if ( nBits < nRest ) {
                 result = *m_ptr << ( nRest - nBits );
@@ -81,7 +81,7 @@ namespace cds { namespace algo {
                 ++m_ptr;
             }
             else {
-                size_t const lsb = *m_ptr >> ( c_nBitPerInt - nRest );
+                uint_type const lsb = *m_ptr >> ( c_nBitPerInt - nRest );
                 nBits -= nRest;
                 ++m_ptr;
 
index af304536784507bda9478cfb8f8ad26591df9c96..3597cd257bd6cd9948d8aff81b05eccd745aa339 100644 (file)
@@ -6,9 +6,8 @@
 
 class Split_bitstrig : public CppUnitMini::TestCase
 {
-protected:
-
-    void cut_uint()
+private:
+    bool is_big_endian()
     {
         union {
             uint32_t ui;
@@ -16,11 +15,24 @@ protected:
         } byte_order;
         byte_order.ui = 0xFF000001;
 
-        if ( byte_order.ch == 0x01 )
-            cut_uint_le();
-        else
+        return byte_order.ch != 0x01;
+    }
+protected:
+
+    void cut_uint()
+    {
+        if ( is_big_endian() )
             cut_uint_be();
+        else
+            cut_uint_le();
+    }
 
+    void cut_uint16()
+    {
+        if ( is_big_endian() )
+            cut_small_be<uint16_t>();
+        else
+            cut_small_le<uint16_t>();
     }
 
     void cut_uint_le()
@@ -171,8 +183,122 @@ protected:
         }
     }
 
+
+private:
+    template <typename PartUInt>
+    void cut_small_le()
+    {
+        CPPUNIT_MSG("little-endian byte order");
+        typedef PartUInt part_uint;
+
+        typedef cds::algo::split_bitstring< uint64_t, part_uint > split_bitstring;
+
+        uint64_t src = 0xFEDCBA9876543210;
+        split_bitstring splitter(src);
+        uint64_t res;
+
+        // Cut each hex digit
+        splitter.reset();
+        for ( size_t i = 0; i < sizeof(size_t) * 2; ++i ) {
+            CPPUNIT_ASSERT( !splitter.eos() );
+            CPPUNIT_ASSERT( splitter );
+            CPPUNIT_ASSERT( static_cast<size_t>(splitter.cut( 4 )) == i );
+        }
+        CPPUNIT_ASSERT( splitter.eos() );
+        CPPUNIT_ASSERT( !splitter );
+
+        // by one bit
+        {
+            splitter.reset();
+            res = 0;
+            for ( size_t i = 0; i < sizeof(size_t) * 8; ++i ) {
+                CPPUNIT_ASSERT( !splitter.eos() );
+                CPPUNIT_ASSERT( splitter );
+                res = res + ( static_cast<uint64_t>(splitter.cut( 1 )) << i);
+            }
+            CPPUNIT_ASSERT( splitter.eos() );
+            CPPUNIT_ASSERT( !splitter );
+            CPPUNIT_ASSERT( res == src );
+        }
+
+        // random cut
+        {
+            for ( size_t k = 0; k < 100; ++k ) {
+                splitter.reset();
+                res = 0;
+                size_t shift = 0;
+                while ( splitter ) {
+                    CPPUNIT_ASSERT( !splitter.eos() );
+                    CPPUNIT_ASSERT( splitter );
+                    int bits = rand() % 16;
+                    res = res + ( static_cast<uint64_t>(splitter.safe_cut( bits )) << shift );
+                    shift += bits;
+                }
+                CPPUNIT_ASSERT( splitter.eos() );
+                CPPUNIT_ASSERT( !splitter );
+                CPPUNIT_ASSERT( res == src );
+            }
+        }
+    }
+
+    template <typename PartUInt>
+    void cut_small_be()
+    {
+        CPPUNIT_MSG("big-endian byte order");
+        typedef PartUInt part_uint;
+
+        typedef cds::algo::split_bitstring< uint64_t, part_uint > split_bitstring;
+
+        uint64_t src = 0xFEDCBA9876543210;
+        split_bitstring splitter(src);
+        uint64_t res;
+
+        // Cut each hex digit
+        splitter.reset();
+        for ( size_t i = 0; i < sizeof(size_t) * 2; ++i ) {
+            CPPUNIT_ASSERT( !splitter.eos() );
+            CPPUNIT_ASSERT( splitter );
+            CPPUNIT_ASSERT( splitter.cut( 4 ) == 0x0F - i );
+        }
+        CPPUNIT_ASSERT( splitter.eos() );
+        CPPUNIT_ASSERT( !splitter );
+
+        // by one bit
+        {
+            splitter.reset();
+            res = 0;
+            for ( size_t i = 0; i < sizeof(size_t) * 8; ++i ) {
+                CPPUNIT_ASSERT( !splitter.eos() );
+                CPPUNIT_ASSERT( splitter );
+                res = (res << 1) + splitter.cut( 1 );
+            }
+            CPPUNIT_ASSERT( splitter.eos() );
+            CPPUNIT_ASSERT( !splitter );
+            CPPUNIT_ASSERT( res == src );
+        }
+
+        // random cut
+        {
+            for ( size_t k = 0; k < 100; ++k ) {
+                splitter.reset();
+                res = 0;
+                while ( splitter ) {
+                    CPPUNIT_ASSERT( !splitter.eos() );
+                    CPPUNIT_ASSERT( splitter );
+                    int bits = rand() % 16;
+                    res = (res << bits) + splitter.safe_cut( bits );
+                }
+                CPPUNIT_ASSERT( splitter.eos() );
+                CPPUNIT_ASSERT( !splitter );
+                CPPUNIT_ASSERT( res == src );
+            }
+        }
+    }
+
+
     CPPUNIT_TEST_SUITE(Split_bitstrig);
         CPPUNIT_TEST(cut_uint)
+        CPPUNIT_TEST(cut_uint16)
     CPPUNIT_TEST_SUITE_END();
 };