$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r75959 - trunk/libs/crc/test
From: dwalker07_at_[hidden]
Date: 2011-12-15 06:07:29
Author: dlwalker
Date: 2011-12-15 06:07:27 EST (Thu, 15 Dec 2011)
New Revision: 75959
URL: http://svn.boost.org/trac/boost/changeset/75959
Log:
Added modernized version of the Boost.CRC test as an unit-test.
Added:
   trunk/libs/crc/test/crc_test2.cpp   (contents, props changed)
Text files modified: 
   trunk/libs/crc/test/Jamfile.v2 |    21 ++++++++++++---------                   
   1 files changed, 12 insertions(+), 9 deletions(-)
Modified: trunk/libs/crc/test/Jamfile.v2
==============================================================================
--- trunk/libs/crc/test/Jamfile.v2	(original)
+++ trunk/libs/crc/test/Jamfile.v2	2011-12-15 06:07:27 EST (Thu, 15 Dec 2011)
@@ -1,14 +1,17 @@
-#~ Copyright Rene Rivera 2008
+#~ Copyright Rene Rivera 2008, Daryle Walker 2011
 #~ Distributed under the Boost Software License, Version 1.0.
 #~ (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
-project
-    :   requirements
-        <library>/boost/test//boost_test_exec_monitor/<link>static
-    ;
-
 import testing ;
 
-test-suite crc :
-    [ run crc_test.cpp ]
-    ;
+test-suite crc
+  :
+    [ run crc_test.cpp
+      :
+      :
+      : requirements <library>/boost/test//boost_test_exec_monitor/<link>static ]
+    [ unit-test crc_test2.cpp
+      :
+      :
+      : requirements <library>/boost/test//boost_unit_test_framework/<link>static ]
+  ;
Added: trunk/libs/crc/test/crc_test2.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/crc/test/crc_test2.cpp	2011-12-15 06:07:27 EST (Thu, 15 Dec 2011)
@@ -0,0 +1,566 @@
+//  Boost CRC unit test program file  ----------------------------------------//
+
+//  Copyright 2011 Daryle Walker.  Use, modification, and
+//  distribution are subject to the Boost Software License, Version 1.0.  (See
+//  accompanying file LICENSE_1_0.txt or a copy at
+//  <http://www.boost.org/LICENSE_1_0.txt>.)
+
+//  See <http://www.boost.org/libs/crc/> for the library's home page.
+
+#define BOOST_TEST_MODULE CRC Unit Test
+#include <boost/test/unit_test.hpp>
+#include <boost/test/test_case_template.hpp>
+#include <boost/crc.hpp>   // for boost::crc_basic,crc_optimal,augmented_crc,crc
+
+#include <boost/cstdint.hpp>         // for boost::uint16_t, uint32_t, uintmax_t
+#include <boost/detail/endian.hpp>                       // for BOOST_BIG_ENDIAN
+#include <boost/integer.hpp>                                // for boost::uint_t
+#include <boost/mpl/bool.hpp>                            // for boost::mpl:bool_
+#include <boost/mpl/integral_c.hpp>                // for boost::mpl::integral_c
+#include <boost/mpl/list.hpp>                            // for boost::mpl::list
+#include <boost/mpl/size_t.hpp>                        // for boost::mpl::size_t
+#include <boost/typeof/typeof.hpp>                             // for BOOST_AUTO
+#include <boost/random/linear_congruential.hpp>        // for boost::minstd_rand
+
+#include <algorithm>  // for std::generate_n, for_each
+#include <climits>    // for CHAR_BIT
+#include <cstddef>    // for std::size_t
+
+// Sanity check
+#if CHAR_BIT != 8
+#error The expected results assume octet-sized bytes.
+#endif
+
+
+// Common definitions  -------------------------------------------------------//
+
+namespace {
+
+// Many CRC configurations use the string "123456789" in ASCII as test data.
+unsigned char const  std_data[] = { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+                      0x38, 0x39 };
+std::size_t const    std_data_len = sizeof( std_data ) / sizeof( std_data[0] );
+
+// Checksums of the standard test data for common configurations
+boost::uint16_t const  std_crc_ccitt_result = 0x29B1u;
+boost::uint16_t const  std_crc_16_result = 0xBB3Du;
+boost::uint32_t const  std_crc_32_result = 0xCBF43926ul;
+
+// Conversion functions between native- and big-endian representations
+#ifdef BOOST_BIG_ENDIAN
+boost::uint32_t  native_to_big( boost::uint32_t x )  { return x; }
+boost::uint32_t  big_to_native( boost::uint32_t x )  { return x; }
+#else
+union endian_convert
+{
+    boost::uint32_t  w;
+    unsigned char    p[ 4 ];
+};
+
+boost::uint32_t  native_to_big( boost::uint32_t x )
+{
+    endian_convert  e;
+
+    e.p[ 0 ] = x >> 24;
+    e.p[ 1 ] = x >> 16;
+    e.p[ 2 ] = x >> 8;
+    e.p[ 3 ] = x;
+    return e.w;
+}
+
+boost::uint32_t  big_to_native( boost::uint32_t x )
+{
+    endian_convert  e;
+
+    e.w = x;
+    x = e.p[ 0 ];
+    x <<= 8;
+    x |= e.p[ 1 ];
+    x <<= 8;
+    x |= e.p[ 2 ];
+    x <<= 8;
+    x |= e.p[ 3 ];
+    return x;
+}
+#endif
+
+// Define CRC parameters inside traits classes.  Probably will use this in a
+// future version of the CRC libray!
+template < std::size_t Bits >
+class my_crc_rt_traits
+{
+public:
+    typedef boost::mpl::size_t<Bits>            register_length_c;
+    typedef typename boost::uint_t<Bits>::fast  register_type;
+    typedef boost::crc_basic<Bits>              computer_type;
+
+    register_type  divisor_polynominal;
+    register_type  initial_remainder;
+    bool           reflect_input_byte;
+    bool           reflect_output_remainder;
+    register_type  final_xor_mask;
+
+    computer_type  make_crc_basic() const
+    { return computer_type(divisor_polynominal, initial_remainder,
+     final_xor_mask, reflect_input_byte, reflect_output_remainder); }
+};
+
+template < std::size_t Bits, boost::uintmax_t DivisorPolynominal,
+           boost::uintmax_t InitialRemainder, bool ReflectInputBytes,
+           bool ReflectOutputRemainder, boost::uintmax_t FinalXorMask >
+class my_crc_ct_traits
+{
+public:
+    typedef my_crc_rt_traits<Bits>                           rt_adaptor_type;
+    typedef typename rt_adaptor_type::register_type            register_type;
+    typedef boost::crc_optimal<Bits, DivisorPolynominal, InitialRemainder,
+     FinalXorMask, ReflectInputBytes, ReflectOutputRemainder>  computer_type;
+
+    typedef boost::mpl::size_t<Bits>  register_length_c;
+    typedef boost::mpl::integral_c<register_type, DivisorPolynominal>
+      divisor_polynominal_c;
+    typedef boost::mpl::integral_c<register_type, InitialRemainder>
+      initial_remainder_c;
+    typedef boost::mpl::bool_<ReflectInputBytes>  reflect_input_byte_c;
+    typedef boost::mpl::bool_<ReflectOutputRemainder>
+      reflect_output_remainder_c;
+    typedef boost::mpl::integral_c<register_type, FinalXorMask>
+      final_xor_mask_c;
+
+    operator rt_adaptor_type() const
+    {
+        rt_adaptor_type const  result = { divisor_polynominal_c::value,
+         initial_remainder_c::value, reflect_input_byte_c::value,
+         reflect_output_remainder_c::value, final_xor_mask_c::value };
+
+        return result;
+    }
+
+    static  computer_type  make_crc_optimal()
+    { return boost::crc_optimal<register_length_c::value,
+     divisor_polynominal_c::value, initial_remainder_c::value,
+     final_xor_mask_c::value, reflect_input_byte_c::value,
+     reflect_output_remainder_c::value>(); }
+};
+
+template < std::size_t Bits, boost::uintmax_t DivisorPolynominal,
+           boost::uintmax_t InitialRemainder, bool ReflectInputBytes,
+           bool ReflectOutputRemainder, boost::uintmax_t FinalXorMask,
+           boost::uintmax_t StandardTestDataResult >
+class my_crc_test_traits
+{
+public:
+    typedef my_crc_ct_traits<Bits, DivisorPolynominal, InitialRemainder,
+     ReflectInputBytes, ReflectOutputRemainder, FinalXorMask>  ct_traits_type;
+    typedef my_crc_rt_traits<Bits>  rt_traits_type;
+
+    typedef typename rt_traits_type::register_type  register_type;
+
+    typedef boost::mpl::size_t<Bits>  register_length_c;
+    typedef boost::mpl::integral_c<register_type, DivisorPolynominal>
+      divisor_polynominal_c;
+    typedef boost::mpl::integral_c<register_type, InitialRemainder>
+      initial_remainder_c;
+    typedef boost::mpl::bool_<ReflectInputBytes>  reflect_input_byte_c;
+    typedef boost::mpl::bool_<ReflectOutputRemainder>
+      reflect_output_remainder_c;
+    typedef boost::mpl::integral_c<register_type, FinalXorMask>
+      final_xor_mask_c;
+    typedef boost::mpl::integral_c<register_type, StandardTestDataResult>
+      standard_test_data_CRC_c;
+
+    typedef typename ct_traits_type::computer_type  computer_ct_type;
+    typedef typename rt_traits_type::computer_type  computer_rt_type;
+
+    static  computer_ct_type  make_crc_optimal()
+    { return ct_traits_type::make_crc_optimal(); }
+    static  computer_rt_type  make_crc_basic()
+    { return ct_traits_type().operator rt_traits_type().make_crc_basic(); }
+};
+
+// Now make some example CRC profiles
+typedef my_crc_test_traits<16u, 0x8005u, 0u, true, true, 0u, std_crc_16_result>
+  my_crc_16_traits;
+typedef my_crc_test_traits<16u, 0x1021u, 0xFFFFu, false, false, 0u,
+ std_crc_ccitt_result>  my_crc_ccitt_traits;
+typedef my_crc_test_traits<32u, 0x04C11DB7ul, 0xFFFFFFFFul, true, true,
+ 0xFFFFFFFFul, std_crc_32_result>  my_crc_32_traits;
+
+typedef boost::mpl::list<my_crc_16_traits, my_crc_ccitt_traits,
+ my_crc_32_traits>  crc_test_policies;
+
+// Bit mask constants
+template < std::size_t BitIndex >
+struct high_bit_mask_c
+    : boost::mpl::integral_c<typename boost::uint_t< BitIndex + 1u >::fast,
+       ( UINTMAX_C(1) << BitIndex )>
+{};
+template < std::size_t BitCount >
+struct low_bits_mask_c
+    : boost::mpl::integral_c<typename boost::uint_t< BitCount >::fast,
+       ( BitCount ? (( (( UINTMAX_C(1) << (BitCount - 1u) ) - 1u) << 1 ) |
+       UINTMAX_C( 1 )) : 0u )>
+{};
+
+}  // anonymous namespace
+
+
+// Unit tests  ---------------------------------------------------------------//
+
+BOOST_AUTO_TEST_SUITE( unaugmented_octet_crc_tests )
+
+BOOST_AUTO_TEST_CASE_TEMPLATE( computation_comparison_test, CRCPolicy,
+ crc_test_policies )
+{
+    BOOST_AUTO( crc_f, CRCPolicy::make_crc_optimal() );
+    BOOST_AUTO( crc_s, CRCPolicy::make_crc_basic() );
+    typename CRCPolicy::register_type const  func_result
+     = boost::crc<CRCPolicy::register_length_c::value,
+        CRCPolicy::divisor_polynominal_c::value,
+        CRCPolicy::initial_remainder_c::value,
+        CRCPolicy::final_xor_mask_c::value,
+        CRCPolicy::reflect_input_byte_c::value,
+        CRCPolicy::reflect_output_remainder_c::value>( std_data, std_data_len );
+
+    crc_f.process_bytes( std_data, std_data_len );
+    crc_s.process_bytes( std_data, std_data_len );
+
+    BOOST_CHECK_EQUAL( crc_f.checksum(),
+     CRCPolicy::standard_test_data_CRC_c::value );
+    BOOST_CHECK_EQUAL( crc_s.checksum(),
+     CRCPolicy::standard_test_data_CRC_c::value );
+    BOOST_CHECK_EQUAL( CRCPolicy::standard_test_data_CRC_c::value,
+     func_result );
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE( accessor_and_split_run_test, CRCPolicy,
+ crc_test_policies )
+{
+    typedef typename CRCPolicy::computer_ct_type  optimal_crc_type;
+    typedef typename CRCPolicy::computer_rt_type    basic_crc_type;
+
+    // Test accessors
+    optimal_crc_type  faster_crc1;
+    basic_crc_type    slower_crc1( faster_crc1.get_truncated_polynominal(),
+     faster_crc1.get_initial_remainder(), faster_crc1.get_final_xor_value(),
+     faster_crc1.get_reflect_input(), faster_crc1.get_reflect_remainder() );
+
+    BOOST_CHECK_EQUAL( faster_crc1.get_interim_remainder(),
+     slower_crc1.get_initial_remainder() );
+
+    // Process the first half of the standard data
+    std::size_t const  mid_way = std_data_len / 2u;
+
+    faster_crc1.process_bytes( std_data, mid_way );
+    slower_crc1.process_bytes( std_data, mid_way );
+
+    BOOST_CHECK_EQUAL( faster_crc1.checksum(), slower_crc1.checksum() );
+
+    // Process the second half of the standard data, testing more accessors
+    unsigned char const * const  std_data_end = std_data + std_data_len;
+    boost::crc_optimal<optimal_crc_type::bit_count,
+     optimal_crc_type::truncated_polynominal,
+     optimal_crc_type::initial_remainder, optimal_crc_type::final_xor_value,
+     optimal_crc_type::reflect_input, optimal_crc_type::reflect_remainder>
+      faster_crc2( faster_crc1.get_interim_remainder() );
+    boost::crc_basic<basic_crc_type::bit_count>  slower_crc2(
+     slower_crc1.get_truncated_polynominal(),
+     slower_crc1.get_interim_remainder(), slower_crc1.get_final_xor_value(),
+     slower_crc1.get_reflect_input(), slower_crc1.get_reflect_remainder() );
+
+    faster_crc2.process_block( std_data + mid_way, std_data_end );
+    slower_crc2.process_block( std_data + mid_way, std_data_end );
+
+    BOOST_CHECK_EQUAL( slower_crc2.checksum(), faster_crc2.checksum() );
+    BOOST_CHECK_EQUAL( faster_crc2.checksum(),
+     CRCPolicy::standard_test_data_CRC_c::value );
+    BOOST_CHECK_EQUAL( CRCPolicy::standard_test_data_CRC_c::value,
+     slower_crc2.checksum() );
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE( reset_and_single_bit_error_test, CRCPolicy,
+ crc_test_policies )
+{
+    // A single-bit error in a CRC can be guaranteed to be detected if the
+    // modulo-2 polynomial divisor has at least two non-zero coefficients.  The
+    // implicit highest coefficient is always one, so that leaves an explicit
+    // coefficient, i.e. at least one of the polynomial's bits is set.
+    BOOST_REQUIRE( CRCPolicy::divisor_polynominal_c::value &
+     low_bits_mask_c<CRCPolicy::register_length_c::value>::value );
+
+    // Create a random block of data
+    boost::uint32_t    ran_data[ 256 ];
+    std::size_t const  ran_length = sizeof(ran_data) / sizeof(ran_data[0]);
+
+    std::generate_n( ran_data, ran_length, boost::minstd_rand() );
+
+    // Create computers and compute the checksum of the data
+    BOOST_AUTO( optimal_tester, CRCPolicy::make_crc_optimal() );
+    BOOST_AUTO( basic_tester, CRCPolicy::make_crc_basic() );
+
+    optimal_tester.process_bytes( ran_data, sizeof(ran_data) );
+    basic_tester.process_bytes( ran_data, sizeof(ran_data) );
+
+    BOOST_AUTO( const optimal_checksum, optimal_tester.checksum() );
+    BOOST_AUTO( const basic_checksum, basic_tester.checksum() );
+
+    BOOST_CHECK_EQUAL( optimal_checksum, basic_checksum );
+
+    // Do the checksum again, while testing the capability to reset the current
+    // remainder (to either a default or a given value)
+    optimal_tester.reset();
+    basic_tester.reset( CRCPolicy::initial_remainder_c::value );
+
+    optimal_tester.process_bytes( ran_data, sizeof(ran_data) );
+    basic_tester.process_bytes( ran_data, sizeof(ran_data) );
+
+    BOOST_CHECK_EQUAL( optimal_tester.checksum(), basic_tester.checksum() );
+    BOOST_CHECK_EQUAL( optimal_tester.checksum(), optimal_checksum );
+    BOOST_CHECK_EQUAL( basic_tester.checksum(), basic_checksum );
+
+    // Introduce a single-bit error
+    ran_data[ ran_data[0] % ran_length ] ^= ( 1u << (ran_data[ 1 ] % 32u) );
+
+    // Compute the checksum of the errorenous data, while continuing to test
+    // the remainder-resetting methods
+    optimal_tester.reset( CRCPolicy::initial_remainder_c::value );
+    basic_tester.reset();
+
+    optimal_tester.process_bytes( ran_data, sizeof(ran_data) );
+    basic_tester.process_bytes( ran_data, sizeof(ran_data) );
+
+    BOOST_CHECK_EQUAL( basic_tester.checksum(), optimal_tester.checksum() );
+    BOOST_CHECK_NE( optimal_checksum, optimal_tester.checksum() );
+    BOOST_CHECK_NE( basic_checksum, basic_tester.checksum() );
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+BOOST_AUTO_TEST_CASE( augmented_crc_test )
+{
+    using std::size_t;
+    using boost::uint32_t;
+    using boost::augmented_crc;
+
+    // Common CRC parameters, all others are zero/false
+    static  size_t const    bits = 32u;
+    static  uint32_t const  poly = 0x04C11DB7ul;
+
+    // Create a random block of data, with space at the end for a CRC
+    static  size_t const  data_length = 256u;
+    static  size_t const  run_length = data_length + 1u;
+
+    uint32_t      run_data[ run_length ];
+    uint32_t &    run_crc = run_data[ data_length ];
+    size_t const  data_size = sizeof( run_data ) - sizeof( run_crc );
+
+    std::generate_n( run_data, data_length, boost::minstd_rand() );
+    run_crc = 0u;
+
+    // The augmented-CRC routine needs to push an appropriate number of zero
+    // bits (the register size) through before the checksum can be extracted.
+    // The other CRC methods, which are un-augmented, don't need to do this.
+    uint32_t const  checksum = boost::crc<bits, poly, 0u, 0u, false, false>(
+     run_data, data_size );
+
+    BOOST_CHECK_EQUAL( (augmented_crc<bits, poly>)(run_data, sizeof( run_data
+     )), checksum );
+
+    // Now appending a message's CRC to the message should lead to a zero-value
+    // checksum.  Note that the CRC must be read from the largest byte on down,
+    // i.e. big-endian!
+    run_crc = native_to_big( checksum );
+    BOOST_CHECK_EQUAL( (augmented_crc<bits, poly>)(run_data, sizeof( run_data
+     )), 0u );
+
+    // Check again with the non-augmented methods
+    boost::crc_basic<bits>  crc_b( poly );
+
+    crc_b.process_bytes( run_data, data_size );
+    BOOST_CHECK_EQUAL( crc_b.checksum(), checksum );
+
+    // Introduce a single-bit error, now the checksum shouldn't match!
+    uint32_t const  affected_word_index = run_data[ 0 ] % data_length;
+    uint32_t const  affected_bit_index = run_data[ 1 ] % 32u;
+    uint32_t const  affecting_mask = 1ul << affected_bit_index;
+
+    run_data[ affected_word_index ] ^= affecting_mask;
+
+    crc_b.reset();
+    crc_b.process_bytes( run_data, data_size );
+    BOOST_CHECK_NE( crc_b.checksum(), checksum );
+
+    BOOST_CHECK_NE( (augmented_crc<bits, poly>)(run_data, sizeof( run_data )),
+     0u );
+
+    run_crc = 0u;
+    BOOST_CHECK_NE( (augmented_crc<bits, poly>)(run_data, sizeof( run_data )),
+     checksum );
+
+    // Now introduce the single error in the checksum instead
+    run_data[ affected_word_index ] ^= affecting_mask;
+    run_crc = native_to_big( checksum ) ^ affecting_mask;
+    BOOST_CHECK_NE( (augmented_crc<bits, poly>)(run_data, sizeof( run_data )),
+     0u );
+
+    // Repeat these tests with a non-zero initial remainder.  Before we can
+    // check the results against a non-augmented CRC computer, realize that they
+    // interpret the inital remainder differently.  However, the two standards
+    // can convert between each other.
+    // (checksum2 initial value is as a scratch pad.  So are the address and new
+    //  value of run_crc, but it's also useful for the next sub-step.)
+    // (TODO: getting the equivalent unaugmented-CRC initial-remainder given an
+    //  augmented-CRC initial-remainder is done by putting said augmented-CRC
+    //  initial-remainder through the augmented-CRC computation with a
+    //  zero-value message.  I don't know how to go the other way, yet.)
+    run_crc = 0u;
+    uint32_t        checksum2 = run_data[ run_data[2] % data_length ];
+    uint32_t const  initial_residue = checksum2 + !checksum2;  // ensure nonzero
+    uint32_t const  initial_residue_unaugmented = augmented_crc<bits, poly>(
+                     &run_crc, sizeof(run_crc), initial_residue );
+
+    BOOST_REQUIRE_NE( initial_residue, 0u );
+    crc_b.reset( initial_residue_unaugmented );
+    crc_b.process_bytes( run_data, data_size );
+    checksum2 = crc_b.checksum();
+
+    BOOST_REQUIRE_EQUAL( run_crc, 0u );
+    BOOST_CHECK_EQUAL( (augmented_crc<bits, poly>)(run_data, sizeof( run_data ),
+     initial_residue), checksum2 );
+    run_crc = native_to_big( checksum2 );
+    BOOST_CHECK_EQUAL( (augmented_crc<bits, poly>)(run_data, sizeof( run_data ),
+     initial_residue), 0u );
+
+    // Use the inital remainder argument to split a CRC-computing run
+    size_t const    split_index = data_length / 2u;
+    uint32_t const  intermediate = augmented_crc<bits, poly>( run_data,
+                     sizeof(run_crc) * split_index, initial_residue );
+
+    BOOST_CHECK_EQUAL( (augmented_crc<bits, poly>)(&run_data[ split_index ],
+     sizeof( run_data ) - sizeof( run_crc ) * split_index, intermediate), 0u );
+    run_crc = 0u;
+    BOOST_CHECK_EQUAL( (augmented_crc<bits, poly>)(&run_data[ split_index ],
+     sizeof( run_data ) - sizeof( run_crc ) * split_index, intermediate),
+     checksum2 );
+
+    // Repeat the single-bit error test, with a non-zero initial-remainder
+    run_data[ run_data[3] % data_length ] ^= ( 1ul << (run_data[4] % 32u) );
+    run_crc = native_to_big( checksum2 );
+    BOOST_CHECK_NE( (augmented_crc<bits, poly>)(run_data, sizeof( run_data ),
+     initial_residue), 0u );
+}
+
+BOOST_AUTO_TEST_SUITE ( sub_octet_crc_tests )
+
+BOOST_AUTO_TEST_CASE( sub_nybble_polynominal_test )
+{
+    // The CRC standard is a SDH/SONET Low Order LCAS control word with CRC-3
+    // taken from ITU-T G.707 (12/03) XIII.2.
+
+    // Four samples, each four bytes; should all have a CRC of zero
+    unsigned char const  samples[4][4]
+      = {
+            { 0x3Au, 0xC4u, 0x08u, 0x06u },
+            { 0x42u, 0xC5u, 0x0Au, 0x41u },
+            { 0x4Au, 0xC5u, 0x08u, 0x22u },
+            { 0x52u, 0xC4u, 0x08u, 0x05u }
+        };
+
+    // Basic computer
+    boost::crc_basic<3u>  crc_1( 0x03u );
+
+    crc_1.process_bytes( samples[0], 4u );
+    BOOST_CHECK_EQUAL( crc_1.checksum(), 0u );
+
+    crc_1.reset();
+    crc_1.process_bytes( samples[1], 4u );
+    BOOST_CHECK_EQUAL( crc_1.checksum(), 0u );
+
+    crc_1.reset();
+    crc_1.process_bytes( samples[2], 4u );
+    BOOST_CHECK_EQUAL( crc_1.checksum(), 0u );
+
+    crc_1.reset();
+    crc_1.process_bytes( samples[3], 4u );
+    BOOST_CHECK_EQUAL( crc_1.checksum(), 0u );
+
+    // Optimal computer, via the single-run function
+    BOOST_AUTO( crc_f, &(boost::crc<3u, 0x03u, 0u, 0u, false, false>) );
+
+    BOOST_CHECK_EQUAL( crc_f(samples[ 0 ], 4u), 0u );
+    BOOST_CHECK_EQUAL( crc_f(samples[ 1 ], 4u), 0u );
+    BOOST_CHECK_EQUAL( crc_f(samples[ 2 ], 4u), 0u );
+    BOOST_CHECK_EQUAL( crc_f(samples[ 3 ], 4u), 0u );
+
+    // TODO: do similar tests with boost::augmented_crc<3, 0x03>
+    // (Now I think that this can't be done right now, since that function reads
+    // byte-wise, so the register size needs to be a multiple of CHAR_BIT.)
+}
+
+BOOST_AUTO_TEST_CASE( sub_octet_polynominal_test )
+{
+    // The CRC standard is a SDH/SONET J0/J1/J2/N1/N2/TR TTI (trace message)
+    // with CRC-7, o.a. ITU-T G.707 Annex B, G.832 Annex A.
+
+    // Two samples, each sixteen bytes
+    // Sample 1 is '\x80' + ASCII("123456789ABCDEF")
+    // Sample 2 is '\x80' + ASCII("TTI UNAVAILABLE")
+    unsigned char const  samples[2][16]
+      = {
+            { 0x80u, 0x31u, 0x32u, 0x33u, 0x34u, 0x35u, 0x36u, 0x37u, 0x38u,
+              0x39u, 0x41u, 0x42u, 0x43u, 0x44u, 0x45u, 0x46u },
+            { 0x80u, 0x54u, 0x54u, 0x49u, 0x20u, 0x55u, 0x4Eu, 0x41u, 0x56u,
+              0x41u, 0x49u, 0x4Cu, 0x41u, 0x42u, 0x4Cu, 0x45u }
+        };
+    unsigned const       results[2] = { 0x62u, 0x23u };
+
+    // Basic computer
+    boost::crc_basic<7u>  crc_1( 0x09u );
+
+    crc_1.process_bytes( samples[0], 16u );
+    BOOST_CHECK_EQUAL( crc_1.checksum(), results[0] );
+
+    crc_1.reset();
+    crc_1.process_bytes( samples[1], 16u );
+    BOOST_CHECK_EQUAL( crc_1.checksum(), results[1] );
+
+    // Optimal computer, via the single-run function
+    BOOST_AUTO( crc_f, &(boost::crc<7u, 0x09u, 0u, 0u, false, false>) );
+
+    BOOST_CHECK_EQUAL( crc_f(samples[ 0 ], 16u), results[0] );
+    BOOST_CHECK_EQUAL( crc_f(samples[ 1 ], 16u), results[1] );
+
+    // TODO: do similar tests with boost::augmented_crc<7, 0x09>
+    // (Now I think that this can't be done right now, since that function reads
+    // byte-wise, so the register size needs to be a multiple of CHAR_BIT.)
+}
+
+BOOST_AUTO_TEST_CASE( one_bit_polynominal_test )
+{
+    // Try a CRC based on the (x + 1) polynominal, which is a factor in
+    // many real-life polynominals and doesn't fit evenly in a byte.
+    boost::crc_basic<1u>  crc_1( 1u );
+
+    crc_1.process_bytes( std_data, std_data_len );
+    BOOST_CHECK_EQUAL( crc_1.checksum(), 1u );
+
+    // Do it again, but using crc_optimal.  The real purpose of this is to test
+    // crc_optimal::process_byte, which doesn't get exercised anywhere else in
+    // this file (directly or indirectly).
+    boost::crc_optimal<1u, 1u, 0u, 0u, false, false>  crc_2;
+
+    for ( std::size_t  i = 0u ; i < std_data_len ; ++i )
+        crc_2.process_byte( std_data[i] );
+    BOOST_CHECK_EQUAL( crc_2.checksum(), 1u );
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+BOOST_AUTO_TEST_CASE_TEMPLATE( function_object_test, CRCPolicy,
+ crc_test_policies )
+{
+    typename CRCPolicy::computer_ct_type  crc_c;
+
+    crc_c = std::for_each( std_data, std_data + std_data_len, crc_c );
+    BOOST_CHECK_EQUAL( crc_c(), CRCPolicy::standard_test_data_CRC_c::value );
+}