Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-09 08:28:41

0001 //  Boost CRC library crc.hpp header file  -----------------------------------//
0002 
0003 //  Copyright 2001, 2004, 2011 Daryle Walker.
0004 //  Distributed under the Boost Software License, Version 1.0.  (See the
0005 //  accompanying file LICENSE_1_0.txt or a copy at
0006 //  <http://www.boost.org/LICENSE_1_0.txt>.)
0007 
0008 //  See <http://www.boost.org/libs/crc/> for the library's home page.
0009 
0010 /** \file
0011     \brief  A collection of function templates and class templates that compute
0012       various forms of Cyclic Redundancy Codes (CRCs).
0013 
0014     \author  Daryle Walker
0015 
0016     \version  1.5
0017 
0018     \copyright  Boost Software License, version 1.0
0019 
0020     Contains the declarations (and definitions) of various kinds of CRC
0021     computation functions, function object types, and encapsulated policy types.
0022 
0023     \warning  The sample CRC-computer types were just checked against the
0024       <a href="http://regregex.bbcmicro.net/crc-catalogue.htm">Catalogue of
0025       parametrised CRC algorithms</a>.  New type aliases were added where I got
0026       a standard wrong.  However, the mistaken <code>typedef</code>s are still
0027       there for backwards compatibility.
0028     \note  There are references to the <i>Rocksoft&trade; Model CRC
0029       Algorithm</i>, as described within \"A Painless Guide to CRC Error
0030       Detection Algorithms,\" linked from \"<a
0031       href="http://www.ross.net/crc/crcpaper.html">CRC: A Paper On CRCs</a>\" by
0032       Ross Williams.  It will be abbreviated \"RMCA\" in other documentation
0033       blocks.
0034  */
0035 
0036 #ifndef BOOST_CRC_HPP
0037 #define BOOST_CRC_HPP
0038 
0039 #include <array>        // for std::array
0040 #include <climits>      // for CHAR_BIT, etc.
0041 #include <cstddef>      // for std::size_t
0042 #include <cstdint>      // for UINTMAX_C, std::uintmax_t
0043 #include <limits>       // for std::numeric_limits
0044 #include <type_traits>  // for std::conditional, std::integral_constant
0045 
0046 // Local reimplementation of boost::uint_t, to avoid dependency on Integer
0047 
0048 namespace boost {
0049 namespace crc_detail {
0050 
0051 struct uint_t_8
0052 {
0053     typedef std::uint_least8_t least;
0054     typedef std::uint_fast8_t fast;
0055 };
0056 
0057 struct uint_t_16
0058 {
0059     typedef std::uint_least16_t least;
0060     typedef std::uint_fast16_t fast;
0061 };
0062 
0063 struct uint_t_32
0064 {
0065     typedef std::uint_least32_t least;
0066     typedef std::uint_fast32_t fast;
0067 };
0068 
0069 struct uint_t_64
0070 {
0071     typedef std::uint_least64_t least;
0072     typedef std::uint_fast64_t fast;
0073 };
0074 
0075 struct uint_t_none
0076 {
0077 };
0078 
0079 template<int Bits> struct uint_t:
0080     std::conditional< (Bits <=  8), uint_t_8,
0081     typename std::conditional< (Bits <= 16), uint_t_16,
0082     typename std::conditional< (Bits <= 32), uint_t_32,
0083     typename std::conditional< (Bits <= 64), uint_t_64,
0084     uint_t_none>::type>::type>::type>::type
0085 {
0086 };
0087 
0088 } // namespace crc_detail
0089 } // namespace boost
0090 
0091 // The type of CRC parameters that can go in a template should be related
0092 // on the CRC's bit count.  This macro expresses that type in a compact
0093 // form.
0094 #define BOOST_CRC_PARM_TYPE  typename ::boost::crc_detail::uint_t<Bits>::fast
0095 
0096 namespace boost
0097 {
0098 
0099 
0100 //  Forward declarations  ----------------------------------------------------//
0101 
0102 //! Bit-wise CRC computer
0103 template < std::size_t Bits >
0104     class crc_basic;
0105 
0106 //! Table-driven CRC computer, usable as a function object
0107 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly = 0u,
0108            BOOST_CRC_PARM_TYPE InitRem = 0u,
0109            BOOST_CRC_PARM_TYPE FinalXor = 0u, bool ReflectIn = false,
0110            bool ReflectRem = false >
0111     class crc_optimal;
0112 
0113 //! Compute the (unaugmented) CRC of a memory block
0114 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
0115            BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
0116            bool ReflectIn, bool ReflectRem >
0117     typename crc_detail::uint_t<Bits>::fast  crc( void const *buffer,
0118      std::size_t byte_count);
0119 
0120 //! Compute the CRC of a memory block, with any augmentation provided by user
0121 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly >
0122     typename crc_detail::uint_t<Bits>::fast  augmented_crc( void const *buffer,
0123      std::size_t byte_count,
0124      typename crc_detail::uint_t<Bits>::fast initial_remainder = 0u);
0125 
0126 //! Computation type for ARC|CRC-16|CRC-IBM|CRC-16/ARC|CRC-16/LHA standard
0127 typedef crc_optimal<16, 0x8005, 0, 0, true, true>         crc_16_type;
0128 //! Computation type for CRC-16/CCITT-FALSE standard
0129 typedef crc_optimal<16, 0x1021, 0xFFFF, 0, false, false>  crc_ccitt_false_t;
0130 //! Computation type for the CRC mistakenly called the CCITT standard
0131 typedef crc_ccitt_false_t                                 crc_ccitt_type;
0132 //! Computation type for the actual
0133 //! KERMIT|CRC-16/CCITT|CRC-16/CCITT-TRUE|CRC-CCITT standard
0134 typedef crc_optimal<16, 0x1021, 0, 0, true, true>         crc_ccitt_true_t;
0135 //! Computation type that I mistakenly called the XMODEM standard; it inverts
0136 //! both reflection parameters and reflects the truncated divisor (Don't use?!)
0137 typedef crc_optimal<16, 0x8408, 0, 0, true, true>         crc_xmodem_type;
0138 //! Computation type for the actual XMODEM|ZMODEM|CRC-16/ACORN standard
0139 typedef crc_optimal<16, 0x1021, 0, 0, false, false>       crc_xmodem_t;
0140 
0141 //! Computation type for CRC-32|CRC-32/ADCCP|PKZIP standard
0142 typedef crc_optimal<32, 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, true, true>
0143   crc_32_type;
0144 
0145 
0146 //  Forward declarations for implementation detail stuff  --------------------//
0147 //  (Just for the stuff that will be needed for the next two sections)
0148 
0149 //! \cond
0150 namespace detail
0151 {
0152     //! Mix-in class to add a possibly-reflecting member function
0153     template < int BitLength, bool DoIt, int Id = 0 >
0154         class possible_reflector;
0155 
0156     //! Mix-in class for byte-fed, table-driven CRC algorithms
0157     template < int Order, std::uintmax_t TruncatedPolynomial, bool Reflect,
0158      int Id = 0 >
0159     class crc_driver;
0160 
0161 }  // namespace detail
0162 //! \endcond
0163 
0164 
0165 //  Simple cyclic redundancy code (CRC) class declaration  -------------------//
0166 
0167 /** Objects of this type compute the CRC checksum of submitted data, where said
0168     data can be entered piecemeal through several different kinds of groupings.
0169     Modulo-2 polynomial division steps are always performed bit-wise, without
0170     the use of pre-computation tables.  Said division uses the altered
0171     algorithm, so any data has to be unaugmented.
0172 
0173     \pre  0 \< \a Bits \<= \c std\::numeric_limits\<uintmax_t\>\::digits
0174 
0175     \tparam Bits  The order of the modulo-2 polynomial divisor.  (\e Width from
0176       the RMCA)
0177  */
0178 template < std::size_t Bits >
0179 class crc_basic
0180 {
0181 public:
0182     // Type
0183     /** \brief  The register type used for computations
0184 
0185         This type is used for CRC calculations and is the type for any returned
0186         checksums and returned or submitted remainders, (truncated) divisors, or
0187         XOR masks.  It is a built-in unsigned integer type.
0188      */
0189     typedef typename boost::crc_detail::uint_t<Bits>::fast  value_type;
0190 
0191     // Constant for the template parameter
0192     //! A copy of \a Bits provided for meta-programming purposes
0193     static const std::size_t bit_count = Bits;
0194 
0195     // Constructor (use the automatic copy-ctr, move-ctr, and dtr)
0196     //! Create a computer, separately listing each needed parameter
0197     explicit  crc_basic( value_type truncated_polynomial,
0198                value_type initial_remainder = 0, value_type final_xor_value = 0,
0199                bool reflect_input = false, bool reflect_remainder = false );
0200 
0201     // Internal Operations
0202     //! Return the (truncated) polynomial divisor
0203     value_type  get_truncated_polynominal() const;
0204     //! Return what the polynomial remainder was set to during construction
0205     value_type  get_initial_remainder() const;
0206     //! Return the XOR-mask used during output processing
0207     value_type  get_final_xor_value() const;
0208     //! Check if input-bytes will be reflected before processing
0209     bool        get_reflect_input() const;
0210     //! Check if the remainder will be reflected during output processing
0211     bool        get_reflect_remainder() const;
0212 
0213     //! Return the remainder based from already-processed bits
0214     value_type  get_interim_remainder() const;
0215     //! Change the interim remainder to a new value
0216     void        reset( value_type new_rem );
0217     //! Change the interim remainder back to the initial value
0218     void        reset();
0219 
0220     // External Operations
0221     //! Submit a single bit for input processing
0222     void  process_bit( bool bit );
0223     //! Submit the lowest \a bit_length bits of a byte for input processing
0224     void  process_bits( unsigned char bits, std::size_t bit_length );
0225     //! Submit a single byte for input processing
0226     void  process_byte( unsigned char byte );
0227     //! Submit a memory block for input processing, iterator-pair style
0228     void  process_block( void const *bytes_begin, void const *bytes_end );
0229     //! Submit a memory block for input processing, pointer-and-size style
0230     void  process_bytes( void const *buffer, std::size_t byte_count );
0231 
0232     //! Return the checksum of the already-processed bits
0233     value_type  checksum() const;
0234 
0235 private:
0236     // Member data
0237     value_type  rem_;
0238     value_type  poly_, init_, final_;  // non-const to allow assignability
0239     bool        rft_in_, rft_out_;     // non-const to allow assignability
0240 
0241 };  // boost::crc_basic
0242 
0243 
0244 //  Optimized cyclic redundancy code (CRC) class declaration  ----------------//
0245 
0246 /** Objects of this type compute the CRC checksum of submitted data, where said
0247     data can be entered piecemeal through several different kinds of groupings.
0248     Modulo-2 polynomial division steps are performed byte-wise, aided by the use
0249     of pre-computation tables.  Said division uses the altered algorithm, so any
0250     data has to be unaugmented.
0251 
0252     \pre  0 \< \a Bits \<= \c std\::numeric_limits\<uintmax_t\>\::digits
0253 
0254     \tparam Bits  The order of the modulo-2 polynomial divisor.  (\e Width from
0255       the RMCA)
0256     \tparam TruncPoly  The lowest coefficients of the divisor polynomial.  The
0257       highest-order coefficient is omitted and always assumed to be 1.  Defaults
0258       to \c 0, i.e. the only non-zero term is the implicit one for
0259       x<sup><var>Bits</var></sup>.  (\e Poly from the RMCA)
0260     \tparam InitRem  The (unaugmented) initial state of the polynomial
0261       remainder.  Defaults to \c 0 if omitted.  (\e Init from the RMCA)
0262     \tparam FinalXor  The (XOR) bit-mask to be applied to the output remainder,
0263       after possible reflection but before returning.  Defaults to \c 0 (i.e. no
0264       bit changes) if omitted.  (\e XorOut from the RMCA)
0265     \tparam ReflectIn  If \c true, input bytes are read lowest-order bit first,
0266       otherwise highest-order bit first.  Defaults to \c false if omitted.
0267       (\e RefIn from the RMCA)
0268     \tparam ReflectRem  If \c true, the output remainder is reflected before the
0269       XOR-mask.  Defaults to \c false if omitted.  (\e RefOut from the RMCA)
0270 
0271     \todo  Get rid of the default value for \a TruncPoly.  Choosing a divisor is
0272       an important decision with many factors, so a default is never useful,
0273       especially a bad one.
0274  */
0275 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
0276            BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
0277            bool ReflectIn, bool ReflectRem >
0278 class crc_optimal
0279 {
0280 public:
0281     // Type
0282     //! \copydoc  boost::crc_basic::value_type
0283     typedef typename boost::crc_detail::uint_t<Bits>::fast  value_type;
0284 
0285     // Constants for the template parameters
0286     //! \copydoc  boost::crc_basic::bit_count
0287     static const std::size_t bit_count = Bits;
0288     //! A copy of \a TruncPoly provided for meta-programming purposes
0289     static const value_type truncated_polynominal = TruncPoly;
0290     //! A copy of \a InitRem provided for meta-programming purposes
0291     static const value_type initial_remainder = InitRem;
0292     //! A copy of \a FinalXor provided for meta-programming purposes
0293     static const value_type final_xor_value = FinalXor;
0294     //! A copy of \a ReflectIn provided for meta-programming purposes
0295     static const bool reflect_input = ReflectIn;
0296     //! A copy of \a ReflectRem provided for meta-programming purposes
0297     static const bool reflect_remainder = ReflectRem;
0298 
0299     // Constructor (use the automatic copy-ctr, move-ctr, and dtr)
0300     //! Create a computer, giving an initial remainder if desired
0301     explicit  crc_optimal( value_type init_rem = initial_remainder );
0302 
0303     // Internal Operations
0304     //! \copybrief  boost::crc_basic::get_truncated_polynominal
0305     value_type  get_truncated_polynominal() const;
0306     //! \copybrief  boost::crc_basic::get_initial_remainder
0307     value_type  get_initial_remainder() const;
0308     //! \copybrief  boost::crc_basic::get_final_xor_value
0309     value_type  get_final_xor_value() const;
0310     //! \copybrief  boost::crc_basic::get_reflect_input
0311     bool        get_reflect_input() const;
0312     //! \copybrief  boost::crc_basic::get_reflect_remainder
0313     bool        get_reflect_remainder() const;
0314 
0315     //! \copybrief  boost::crc_basic::get_interim_remainder
0316     value_type  get_interim_remainder() const;
0317     //! Change the interim remainder to either a given value or the initial one
0318     void        reset( value_type new_rem = initial_remainder );
0319 
0320     // External Operations
0321     //! \copybrief  boost::crc_basic::process_byte
0322     void  process_byte( unsigned char byte );
0323     //! \copybrief  boost::crc_basic::process_block
0324     void  process_block( void const *bytes_begin, void const *bytes_end );
0325     //! \copybrief  boost::crc_basic::process_bytes
0326     void  process_bytes( void const *buffer, std::size_t byte_count );
0327 
0328     //! \copybrief  boost::crc_basic::checksum
0329     value_type  checksum() const;
0330 
0331     // Operators
0332     //! Submit a single byte for input processing, suitable for the STL
0333     void        operator ()( unsigned char byte );
0334     //! Return the checksum of the already-processed bits, suitable for the STL
0335     value_type  operator ()() const;
0336 
0337 private:
0338     // Implementation types
0339     // (Processing for reflected input gives reflected remainders, so you only
0340     // have to apply output-reflection if Reflect-Remainder doesn't match
0341     // Reflect-Input.)
0342     typedef detail::possible_reflector<Bits, ReflectIn>     reflect_i_type;
0343     typedef detail::crc_driver<Bits, TruncPoly, ReflectIn>  crc_table_type;
0344     typedef detail::possible_reflector<Bits, ReflectRem != ReflectIn>
0345       reflect_o_type;
0346 
0347     // Member data
0348     value_type  rem_;
0349 
0350 };  // boost::crc_optimal
0351 
0352 
0353 //  Implementation detail stuff  ---------------------------------------------//
0354 
0355 //! \cond
0356 namespace detail
0357 {
0358     /** \brief  Meta-programming integral constant for a single-bit bit-mask
0359 
0360         Generates a compile-time constant for a bit-mask that affects a single
0361         bit.  The \c value will be 2<sup><var>BitIndex</var></sup>.  The \c type
0362         will be the smallest built-in unsigned integer type that can contain the
0363         value, unless there's a built-in type that the system can handle easier,
0364         then the \c type will be smallest fast-handled unsigned integer type.
0365 
0366         \pre  0 \<= BitIndex \< \c std\::numeric_limits\<uintmax_t\>\::digits
0367 
0368         \tparam BitIndex  The place of the sole set bit.
0369      */
0370     template < int BitIndex >
0371     struct high_bit_mask_c
0372         : std::integral_constant<typename boost::crc_detail::uint_t< BitIndex + 1 >::fast,
0373            ( UINTMAX_C(1) << BitIndex )>
0374     {};
0375 
0376     /** \brief  Meta-programming integral constant for a lowest-bits bit-mask
0377 
0378         Generates a compile-time constant for a bit-mask that affects the lowest
0379         bits.  The \c value will be 2<sup><var>BitCount</var></sup> - 1.  The
0380         \c type will be the smallest built-in unsigned integer type that can
0381         contain the value, unless there's a built-in type that the system can
0382         handle easier, then the \c type will be smallest fast-handled unsigned
0383         integer type.
0384 
0385         \pre  0 \<= BitCount \<= \c std\::numeric_limits\<uintmax_t\>\::digits
0386 
0387         \tparam BitCount  The number of lowest-placed bits set.
0388      */
0389     template < int BitCount >
0390     struct low_bits_mask_c
0391         : std::integral_constant<typename boost::crc_detail::uint_t< BitCount >::fast, (
0392            BitCount ? (( (( UINTMAX_C(1) << (BitCount - 1) ) - 1u) << 1 ) |
0393            UINTMAX_C( 1 )) : 0u )>
0394     {};
0395 
0396     /** \brief  Reflects the bits of a number
0397 
0398         Reverses the order of the given number of bits within a value.  For
0399         instance, if the given reflect count is 5, then the bit values for the
0400         16- and 1-place will switch and the 8- and 2-place will switch, leaving
0401         the other bits alone.  (The 4-place bit is in the middle, so it wouldn't
0402         change.)
0403 
0404         \pre  \a Unsigned is a built-in unsigned integer type
0405         \pre  0 \< word_length \<= \c std\::numeric_limits\<Unsigned\>\::digits
0406 
0407         \tparam Unsigned  The type of \a x.
0408 
0409         \param x  The value to be (partially) reflected.
0410         \param word_length  The number of low-order bits to reflect.  Defaults
0411           to the total number of value bits in \a Unsigned.
0412 
0413         \return  The (partially) reflected value.
0414 
0415         \todo  Check if this is the fastest way.
0416      */
0417     template < typename Unsigned >
0418     Unsigned  reflect_unsigned( Unsigned x, int word_length
0419      = std::numeric_limits<Unsigned>::digits )
0420     {
0421         for ( Unsigned  l = 1u, h = static_cast<Unsigned>(l << (word_length - 1)) ; h > l ; h >>= 1, l
0422          <<= 1 )
0423         {
0424             Unsigned const  m = h | l, t = x & m;
0425 
0426             if ( (t == h) || (t == l) )
0427                 x ^= m;
0428         }
0429 
0430         return x;
0431     }
0432 
0433     /** \brief  Make a byte-to-byte-reflection map
0434 
0435         Creates a mapping array so the results can be cached.  Uses
0436         #reflect_unsigned to generate the element values.
0437 
0438         \return  An array <var>a</var> such that, for a given byte value
0439           <var>i</var>, <code><var>a</var>[ <var>i</var> ]</code> resolves to
0440           the reflected value of <var>i</var>.
0441      */
0442     std::array< unsigned char, (UINTMAX_C( 1 ) << CHAR_BIT) >
0443     inline make_byte_reflection_table()
0444     {
0445         std::array<unsigned char, ( UINTMAX_C(1) << CHAR_BIT )>  result;
0446         unsigned char                                              i = 0u;
0447 
0448         do
0449             result[ i ] = reflect_unsigned( i );
0450         while ( ++i );
0451         return result;
0452     }
0453 
0454     /** \brief  Reflects the bits of a single byte
0455 
0456         Reverses the order of all the bits within a value.  For instance, the
0457         bit values for the 2<sup><code>CHAR_BIT</code> - 1</sup>- and 1-place
0458         will switch and the 2<sup><code>CHAR_BIT</code> - 2</sup>- and 2-place
0459         will switch, etc.
0460 
0461         \param x  The byte value to be reflected.
0462 
0463         \return  The reflected value.
0464 
0465         \note  Since this could be the most common type of reflection, and the
0466           number of states is relatively small, the implementation pre-computes
0467           and uses a table of all the results.
0468      */
0469     inline unsigned char  reflect_byte( unsigned char x )
0470     {
0471         static  std::array<unsigned char, ( UINTMAX_C(1) << CHAR_BIT )> const
0472           table = make_byte_reflection_table();
0473 
0474         return table[ x ];
0475     }
0476 
0477     /** \brief  Reflects some bits within a single byte
0478 
0479         Like #reflect_unsigned, except it takes advantage of any (long-term)
0480         speed gains #reflect_byte may bring.
0481 
0482         \pre  0 \< \a word_length \<= \c CHAR_BIT
0483 
0484         \param x  The value to be (partially) reflected.
0485         \param word_length  The number of low-order bits to reflect.
0486 
0487         \return  The (partially) reflected value.
0488      */
0489     inline  unsigned char  reflect_sub_byte( unsigned char x, int word_length )
0490     { return reflect_byte(x) >> (CHAR_BIT - word_length); }
0491 
0492     /** \brief  Possibly reflects the bits of a number
0493 
0494         Reverses the order of the given number of bits within a value.  For
0495         instance, if the given reflect count is 5, then the bit values for the
0496         16- and 1-place will switch and the 8- and 2-place will switch, leaving
0497         the other bits alone.  (The 4-place bit is in the middle, so it wouldn't
0498         change.)  This variant function allows the reflection be controlled by
0499         an extra parameter, in case the decision to use reflection is made at
0500         run-time.
0501 
0502         \pre  \a Unsigned is a built-in unsigned integer type
0503         \pre  0 \< word_length \<= \c std\::numeric_limits\<Unsigned\>\::digits
0504 
0505         \tparam Unsigned  The type of \a x.
0506 
0507         \param x  The value to be (partially) reflected.
0508         \param reflect  Controls whether \a x is actually reflected (\c true) or
0509           left alone (\c false).
0510         \param word_length  The number of low-order bits to reflect.  Defaults
0511           to the total number of value bits in \a Unsigned.
0512 
0513         \return  The possibly (partially) reflected value.
0514      */
0515     template < typename Unsigned >
0516     inline
0517     Unsigned  reflect_optionally( Unsigned x, bool reflect, int word_length
0518      = std::numeric_limits<Unsigned>::digits )
0519     { return reflect ? reflect_unsigned(x, word_length) : x; }
0520 
0521     /** \brief  Possibly reflects the bits of a single byte
0522 
0523         Uses #reflect_byte (if \a reflect is \c true).
0524 
0525         \param x  The byte value to be (possibly) reflected.
0526         \param reflect  Whether (\c true) or not (\c false) \a x is reflected.
0527 
0528         \return  <code><var>reflect</var> ? reflect_byte(<var>x</var>) :
0529           <var>x</var></code>
0530      */
0531     inline
0532     unsigned char  reflect_byte_optionally( unsigned char x, bool reflect )
0533     { return reflect ? reflect_byte(x) : x; }
0534 
0535     /** \brief  Update a CRC remainder by several bits, assuming a non-augmented
0536           message
0537 
0538         Performs several steps of division required by the CRC algorithm, giving
0539         a new remainder polynomial based on the divisor polynomial and the
0540         synthesized dividend polynomial (from the old remainder and the
0541         newly-provided input).  The computations assume that the CRC is directly
0542         exposed from the remainder, without any zero-valued bits augmented to
0543         the message bits.
0544 
0545         \pre  \a Register and \a Word are both built-in unsigned integer types
0546         \pre  0 \< \a register_length \<= std\::numeric_limits\<\a Register\>
0547           \::digits
0548         \pre  0 \< \a word_length \<= std\::numeric_limits\<\a Word\>\::digits
0549 
0550         \tparam Register  The type used for representing the remainder and
0551           divisor modulo-2 polynomials.  The bit at <code>2<sup>i</sup></code>
0552           is used as the coefficient of <i>x<sup>i</sup></i>.
0553         \tparam Word  The type used for storing the incoming terms of the
0554           dividend modulo-2 polynomial.  The bit at <code>2<sup>i</sup></code>
0555           is used as the coefficient of <i>x<sup>i</sup></i> when \a reflect is
0556           \c false, and the coefficient of <i>x<sup><var>word_length</var> - 1 -
0557           i</sup></i> otherwise.
0558 
0559         \param[in]     register_length  The number of significant low-order bits
0560           to be used from \a Register values.  It is the order of the modulo-2
0561           polynomial remainder and one less than the divisor's order.
0562         \param[in,out] remainder  The upper part of the dividend polynomial
0563           before division, and the remainder polynomial after.
0564         \param[in]     new_dividend_bits  The coefficients for the next
0565           \a word_length lowest terms of the dividend polynomial.
0566         \param[in]     truncated_divisor  The lowest coefficients of the divisor
0567           polynomial.  The highest-order coefficient is omitted and always
0568           assumed to be 1.
0569         \param[in]     word_length  The number of lowest-order bits to read from
0570           \a new_dividend_bits.
0571         \param[in]     reflect  If \c false, read from the highest-order marked
0572           bit from \a new_dividend_bits and go down, as normal.  Otherwise,
0573           proceed from the lowest-order bit and go up.
0574 
0575         \note  This routine performs a modulo-2 polynomial division variant.
0576           The exclusive-or operations are applied in a different order, since
0577           that kind of operation is commutative and associative.  It also
0578           assumes that the zero-valued augment string was applied before this
0579           step, which means that the updated remainder can be directly used as
0580           the final CRC.
0581      */
0582     template < typename Register, typename Word >
0583     void  crc_modulo_word_update( int register_length, Register &remainder, Word
0584      new_dividend_bits, Register truncated_divisor, int word_length, bool
0585      reflect )
0586     {
0587         // Create this masking constant outside the loop.
0588         Register const  high_bit_mask = UINTMAX_C(1) << (register_length - 1);
0589 
0590         // The natural reading order for division is highest digit/bit first.
0591         // The "reflect" parameter switches this.  However, building a bit mask
0592         // for the lowest bit is the easiest....
0593         new_dividend_bits = reflect_optionally( new_dividend_bits, !reflect,
0594          word_length );
0595 
0596         // Perform modulo-2 division for each new dividend input bit
0597         for ( int  i = word_length ; i ; --i, new_dividend_bits >>= 1 )
0598         {
0599             // compare the new bit with the remainder's highest
0600             remainder ^= ( new_dividend_bits & 1u ) ? high_bit_mask : 0u;
0601 
0602             // perform modulo-2 division
0603             bool const  quotient = (remainder & high_bit_mask) != 0;
0604 
0605             remainder <<= 1;
0606             remainder ^= quotient ? truncated_divisor : 0u;
0607 
0608             // The quotient isn't used for anything, so don't keep it.
0609         }
0610 
0611         // Clear overflowed bits
0612         remainder &= (std::numeric_limits<Register>::max)() >> (std::numeric_limits<Register>::digits - register_length);
0613     }
0614 
0615     /** \brief  Update a CRC remainder by a single bit, assuming a non-augmented
0616           message
0617 
0618         Performs the next step of division required by the CRC algorithm, giving
0619         a new remainder polynomial based on the divisor polynomial and the
0620         synthesized dividend polynomial (from the old remainder and the
0621         newly-provided input).  The computations assume that the CRC is directly
0622         exposed from the remainder, without any zero-valued bits augmented to
0623         the message bits.
0624 
0625         \pre  \a Register is a built-in unsigned integer type
0626         \pre  0 \< \a register_length \<= std\::numeric_limits\<\a Register\>
0627           \::digits
0628 
0629         \tparam Register  The type used for representing the remainder and
0630           divisor modulo-2 polynomials.  The bit at <code>2<sup>i</sup></code>
0631           is used as the coefficient of <i>x<sup>i</sup></i>.
0632 
0633         \param[in]     register_length  The number of significant low-order bits
0634           to be used from \a Register values.  It is the order of the modulo-2
0635           polynomial remainder and one less than the divisor's order.
0636         \param[in,out] remainder  The upper part of the dividend polynomial
0637           before division, and the remainder polynomial after.
0638         \param[in]     new_dividend_bit  The coefficient for the constant term
0639           of the dividend polynomial.
0640         \param[in]     truncated_divisor  The lowest coefficients of the divisor
0641           polynomial.  The highest-order coefficient is omitted and always
0642           assumed to be 1.
0643 
0644         \note  This routine performs a modulo-2 polynomial division variant.
0645           The exclusive-or operations are applied in a different order, since
0646           that kind of operation is commutative and associative.  It also
0647           assumes that the zero-valued augment string was applied before this
0648           step, which means that the updated remainder can be directly used as
0649           the final CRC.
0650      */
0651     template < typename Register >
0652     inline  void  crc_modulo_update( int register_length, Register &remainder,
0653      bool new_dividend_bit, Register truncated_divisor )
0654     {
0655         crc_modulo_word_update( register_length, remainder,
0656          static_cast<unsigned>(new_dividend_bit), truncated_divisor, 1, false );
0657     }
0658 
0659     /** \brief  Update a CRC remainder by several bits, assuming an augmented
0660           message
0661 
0662         Performs several steps of division required by the CRC algorithm, giving
0663         a new remainder polynomial based on the divisor polynomial and the
0664         synthesized dividend polynomial (from the old remainder and the
0665         newly-provided input).  The computations assume that a zero-valued
0666         string of bits will be appended to the message before extracting the
0667         CRC.
0668 
0669         \pre  \a Register and \a Word are both built-in unsigned integer types
0670         \pre  0 \< \a register_length \<= std\::numeric_limits\<\a Register\>
0671           \::digits
0672         \pre  0 \< \a word_length \<= std\::numeric_limits\<\a Word\>\::digits
0673 
0674         \tparam Register  The type used for representing the remainder and
0675           divisor modulo-2 polynomials.  The bit at <code>2<sup>i</sup></code>
0676           is used as the coefficient of <i>x<sup>i</sup></i>.
0677         \tparam Word  The type used for storing the incoming terms of the
0678           dividend modulo-2 polynomial.  The bit at <code>2<sup>i</sup></code>
0679           is used as the coefficient of <i>x<sup>i</sup></i> when \a reflect is
0680           \c false, and the coefficient of <i>x<sup><var>word_length</var> - 1 -
0681           i</sup></i> otherwise.
0682 
0683         \param[in]     register_length  The number of significant low-order bits
0684           to be used from \a Register values.  It is the order of the modulo-2
0685           polynomial remainder and one less than the divisor's order.
0686         \param[in,out] remainder  The upper part of the dividend polynomial
0687           before division, and the remainder polynomial after.
0688         \param[in]     new_dividend_bits  The coefficients for the next
0689           \a word_length lowest terms of the dividend polynomial.
0690         \param[in]     truncated_divisor  The lowest coefficients of the divisor
0691           polynomial.  The highest-order coefficient is omitted and always
0692           assumed to be 1.
0693         \param[in]     word_length  The number of lowest-order bits to read from
0694           \a new_dividend_bits.
0695         \param[in]     reflect  If \c false, read from the highest-order marked
0696           bit from \a new_dividend_bits and go down, as normal.  Otherwise,
0697           proceed from the lowest-order bit and go up.
0698 
0699         \note  This routine performs straight-forward modulo-2 polynomial
0700           division.  It assumes that an augment string will be processed at the
0701           end of the message bits before doing CRC analysis.
0702         \todo  Use this function somewhere so I can test it.
0703      */
0704     template < typename Register, typename Word >
0705     void  augmented_crc_modulo_word_update( int register_length, Register
0706      &remainder, Word new_dividend_bits, Register truncated_divisor, int
0707      word_length, bool reflect )
0708     {
0709         // Create this masking constant outside the loop.
0710         Register const  high_bit_mask = UINTMAX_C(1) << (register_length - 1);
0711 
0712         // The natural reading order for division is highest digit/bit first.
0713         // The "reflect" parameter switches this.  However, building a bit mask
0714         // for the lowest bit is the easiest....
0715         new_dividend_bits = reflect_optionally( new_dividend_bits, !reflect,
0716          word_length );
0717 
0718         // Perform modulo-2 division for each new dividend input bit
0719         for ( int  i = word_length ; i ; --i, new_dividend_bits >>= 1 )
0720         {
0721             bool const  quotient = (remainder & high_bit_mask) != 0;
0722 
0723             remainder <<= 1;
0724             remainder |= new_dividend_bits & 1u;
0725             remainder ^= quotient ? truncated_divisor : 0u;
0726 
0727             // The quotient isn't used for anything, so don't keep it.
0728         }
0729     }
0730 
0731     /** \brief  Update a CRC remainder by a single bit, assuming an augmented
0732           message
0733 
0734         Performs the next step of division required by the CRC algorithm, giving
0735         a new remainder polynomial based on the divisor polynomial and the
0736         synthesized dividend polynomial (from the old remainder and the
0737         newly-provided input).  The computations assume that a zero-valued
0738         string of bits will be appended to the message before extracting the
0739         CRC.
0740 
0741         \pre  \a Register is a built-in unsigned integer type
0742         \pre  0 \< \a register_length \<= std\::numeric_limits\<\a Register\>
0743           \::digits
0744 
0745         \tparam Register  The type used for representing the remainder and
0746           divisor modulo-2 polynomials.  The bit at <code>2<sup>i</sup></code>
0747           is used as the coefficient of <i>x<sup>i</sup></i>.
0748 
0749         \param[in]     register_length  The number of significant low-order bits
0750           to be used from \a Register values.  It is the order of the modulo-2
0751           polynomial remainder and one less than the divisor's order.
0752         \param[in,out] remainder  The upper part of the dividend polynomial
0753           before division, and the remainder polynomial after.
0754         \param[in]     new_dividend_bit  The coefficient for the constant term
0755           of the dividend polynomial.
0756         \param[in]     truncated_divisor  The lowest coefficients of the divisor
0757           polynomial.  The highest-order coefficient is omitted and always
0758           assumed to be 1.
0759 
0760         \note  This routine performs straight-forward modulo-2 polynomial
0761           division.  It assumes that an augment string will be processed at the
0762           end of the message bits before doing CRC analysis.
0763         \todo  Use this function somewhere so I can test it.
0764      */
0765     template < typename Register >
0766     inline  void  augmented_crc_modulo_update( int register_length, Register
0767      &remainder, bool new_dividend_bit, Register truncated_divisor )
0768     {
0769         augmented_crc_modulo_word_update( register_length, remainder,
0770          static_cast<unsigned>(new_dividend_bit), truncated_divisor, 1, false );
0771     }
0772 
0773     /** \brief  A mix-in class that returns its argument
0774 
0775         This class template makes a function object that returns its argument
0776         as-is.  It's one case for #possible_reflector.
0777 
0778         \pre  0 \< \a BitLength \<= \c std\::numeric_limits\<uintmax_t\>
0779           \::digits
0780 
0781         \tparam BitLength  How many significant bits arguments have.
0782      */
0783     template < int BitLength >
0784     class non_reflector
0785     {
0786     public:
0787         /** \brief  The type to check for specialization
0788 
0789             This is a Boost integral constant indicating that this class
0790             does not reflect its input values.
0791          */
0792         typedef std::false_type                 is_reflecting_type;
0793         /** \brief  The type to check for register bit length
0794 
0795             This is a Boost integral constant indicating how many
0796             significant bits won't actually be reflected.
0797          */
0798         typedef std::integral_constant< int, BitLength >      width_c;
0799         /** \brief  The type of (not-)reflected values
0800 
0801             This type is the input and output type for the (possible-)
0802             reflection function, which does nothing here.
0803          */
0804         typedef typename boost::crc_detail::uint_t< BitLength >::fast  value_type;
0805 
0806         /** \brief  Does nothing
0807 
0808             Returns the given value, not reflecting any part of it.
0809 
0810             \param x  The value to not be reflected.
0811 
0812             \return  \a x
0813          */
0814         inline  static  value_type  reflect_q( value_type x )
0815         { return x; }
0816     };
0817 
0818     /** \brief  A mix-in class that reflects (the lower part of) its argument,
0819           generally for types larger than a byte
0820 
0821         This class template makes a function object that returns its argument
0822         after reflecting its lower-order bits.  It's one sub-case for
0823         #possible_reflector.
0824 
0825         \pre  \c CHAR_BIT \< \a BitLength \<= \c std\::numeric_limits\<uintmax_t
0826           \>\::digits
0827 
0828         \tparam BitLength  How many significant bits arguments have.
0829      */
0830     template < int BitLength >
0831     class super_byte_reflector
0832     {
0833     public:
0834         /** \brief  The type to check for specialization
0835 
0836             This is a Boost integral constant indicating that this class
0837             does reflect its input values.
0838          */
0839         typedef std::true_type                  is_reflecting_type;
0840         /** \brief  The type to check for register bit length
0841 
0842             This is a Boost integral constant indicating how many
0843             significant bits will be reflected.
0844          */
0845         typedef std::integral_constant< int, BitLength >      width_c;
0846         /** \brief  The type of reflected values
0847 
0848             This is both the input and output type for the reflection function.
0849          */
0850         typedef typename boost::crc_detail::uint_t< BitLength >::fast  value_type;
0851 
0852         /** \brief  Reflect (part of) the given value
0853 
0854             Reverses the order of the given number of bits within a value,
0855             using #reflect_unsigned.
0856 
0857             \param x  The value to be (partially) reflected.
0858 
0859             \return  ( <var>x</var> &amp;
0860               ~(2<sup><var>width_c</var>\::value</sup> - 1) ) | REFLECT(
0861               <var>x</var> &amp; (2<sup><var>width_c</var>\::value</sup> -
0862               1) )
0863          */
0864         inline  static  value_type  reflect_q( value_type x )
0865         { return reflect_unsigned(x, width_c::value); }
0866     };
0867 
0868     /** \brief  A mix-in class that reflects (the lower part of) its argument,
0869           generally for bytes
0870 
0871         This class template makes a function object that returns its argument
0872         after reflecting its lower-order bits.  It's one sub-case for
0873         #possible_reflector.
0874 
0875         \pre  0 \< \a BitLength \<= \c CHAR_BIT
0876 
0877         \tparam BitLength  How many significant bits arguments have.
0878      */
0879     template < int BitLength >
0880     class sub_type_reflector
0881     {
0882     public:
0883         /** \brief  The type to check for specialization
0884 
0885             This is a Boost integral constant indicating that this class
0886             does reflect its input values.
0887          */
0888         typedef std::true_type              is_reflecting_type;
0889         /** \brief  The type to check for register bit length
0890 
0891             This is a Boost integral constant indicating how many
0892             significant bits will be reflected.
0893          */
0894         typedef std::integral_constant< int, BitLength >  width_c;
0895         /** \brief  The type of reflected values
0896 
0897             This is both the input and output type for the reflection function.
0898          */
0899         typedef unsigned char                          value_type;
0900 
0901         /** \brief  Reflect (part of) the given value
0902 
0903             Reverses the order of the given number of bits within a value,
0904             using #reflect_sub_byte.
0905 
0906             \param x  The value to be (partially) reflected.
0907 
0908             \return  ( <var>x</var> &amp;
0909               ~(2<sup><var>width_c</var>\::value</sup> - 1) ) | REFLECT(
0910               <var>x</var> &amp; (2<sup><var>width_c</var>\::value</sup> -
0911               1) )
0912          */
0913         inline  static  value_type  reflect_q( value_type x )
0914         { return reflect_sub_byte(x, width_c::value); }
0915     };
0916 
0917     /** \brief  A mix-in class that reflects (the lower part of) its argument
0918 
0919         This class template makes a function object that returns its argument
0920         after reflecting its lower-order bits.  It's one case for
0921         #possible_reflector.
0922 
0923         \pre  0 \< \a BitLength \<= \c std\::numeric_limits\<uintmax_t\>
0924           \::digits
0925 
0926         \tparam BitLength  How many significant bits arguments have.
0927      */
0928     template < int BitLength >
0929     class reflector
0930         : public std::conditional< (BitLength > CHAR_BIT),
0931           super_byte_reflector<BitLength>, sub_type_reflector<BitLength> >::type
0932     { };
0933 
0934     /** This class template adds a member function #reflect_q that will
0935         conditionally reflect its first argument, controlled by a compile-time
0936         parameter.
0937 
0938         \pre  0 \< \a BitLength \<= \c std\::numeric_limits\<uintmax_t\>
0939           \::digits
0940 
0941         \tparam BitLength  How many significant bits arguments have.
0942         \tparam DoIt  \c true if #reflect_q will reflect, \c false if it should
0943           return its argument unchanged.
0944         \tparam Id  An extra differentiator if multiple copies of this class
0945           template are mixed-in as base classes.  Defaults to 0 if omitted.
0946      */
0947     template < int BitLength, bool DoIt, int Id >
0948     class possible_reflector
0949         : public std::conditional< DoIt, reflector<BitLength>,
0950           non_reflector<BitLength> >::type
0951     {
0952     public:
0953         /** \brief  The type to check for ID
0954 
0955             This is a Boost integral constant indicating what ID number this
0956             instantiation used.
0957          */
0958         typedef std::integral_constant<int, Id>  id_type;
0959     };
0960 
0961     /** \brief  Find the composite remainder update effect from a fixed bit
0962           sequence, for each potential sequence combination.
0963 
0964         For each value between 0 and 2<sup><var>SubOrder</var></sup> - 1,
0965         computes the XOR mask corresponding to the composite effect they update
0966         the incoming remainder, which is the upper part of the dividend that
0967         gets (partially) pushed out of its register by the incoming value's
0968         bits.  The composite value merges the \"partial products\" from each bit
0969         of the value being updated individually.
0970 
0971         \pre  \a Register is a built-in unsigned integer type
0972         \pre  0 \< \a SubOrder \<= \a register_length \<=
0973           std\::numeric_limits\<\a Register\>\::digits
0974 
0975         \tparam SubOrder  The number of low-order significant bits of the trial
0976           new dividends.
0977         \tparam Register  The type used for representing the remainder and
0978           divisor modulo-2 polynomials.  The bit at <code>2<sup>i</sup></code>
0979           is used as the coefficient of <i>x<sup>i</sup></i>.
0980 
0981         \param[in] register_length  The number of significant low-order bits
0982           to be used from \a Register values.  It is the order of the modulo-2
0983           polynomial remainder and one less than the divisor's order.
0984         \param[in] truncated_divisor  The lowest coefficients of the divisor
0985           polynomial.  The highest-order coefficient is omitted and always
0986           assumed to be 1.
0987         \param[in] reflect  If \c false, read from the highest-order marked
0988           bit from a new dividend's bits and go down, as normal.  Otherwise,
0989           proceed from the lowest-order bit and go up.
0990 
0991         \return  An array such that the element at index <var>i</var> is the
0992           composite effect XOR mask for value <var>i</var>.
0993 
0994         \note  This routine performs a modulo-2 polynomial division variant.
0995           The exclusive-or operations are applied in a different order, since
0996           that kind of operation is commutative and associative.  It also
0997           assumes that the zero-valued augment string was applied before this
0998           step, which means that the updated remainder can be directly used as
0999           the final CRC.
1000         \todo  Check that using the unaugmented-CRC division routines give the
1001           same composite mask table as using augmented-CRC routines.
1002      */
1003     template < int SubOrder, typename Register >
1004     std::array< Register, (UINTMAX_C( 1 ) << SubOrder) >
1005     make_partial_xor_products_table( int register_length, Register
1006      truncated_divisor, bool reflect )
1007     {
1008         std::array<Register, ( UINTMAX_C(1) << SubOrder )>  result = { 0 };
1009 
1010         // Loop over every possible dividend value
1011         for ( typename boost::crc_detail::uint_t<SubOrder + 1>::fast  dividend = 0u;
1012          dividend < result.size() ; ++dividend )
1013         {
1014             Register  remainder = 0u;
1015 
1016             crc_modulo_word_update( register_length, remainder, dividend,
1017              truncated_divisor, SubOrder, false );
1018             result[ reflect_optionally(dividend, reflect, SubOrder) ] =
1019              reflect_optionally( remainder, reflect, register_length );
1020         }
1021         return result;
1022     }
1023 
1024     /** \brief  A mix-in class for the table of table-driven CRC algorithms
1025 
1026         Encapsulates the parameters need to make a global (technically,
1027         class-static) table usuable in CRC algorithms, and generates said
1028         table.
1029 
1030         \pre  0 \< \a SubOrder \<= Order \<=
1031           std\::numeric_limits\<uintmax_t\>\::digits
1032 
1033         \tparam Order  The order of the modulo-2 polynomial remainder and one
1034           less than the divisor's order.
1035         \tparam SubOrder  The number of low-order significant bits of the trial
1036           new dividends.
1037         \tparam TruncatedPolynomial  The lowest coefficients of the divisor
1038           polynomial.  The highest-order coefficient is omitted and always
1039           assumed to be 1.
1040         \tparam Reflect  If \c false, read from the highest-order marked
1041           bit from a new dividend's bits and go down, as normal.  Otherwise,
1042           proceed from the lowest-order bit and go up.
1043      */
1044     template < int Order, int SubOrder, std::uintmax_t TruncatedPolynomial,
1045      bool Reflect >
1046     class crc_table_t
1047     {
1048     public:
1049         /** \brief  The type to check for register bit length
1050 
1051             This is a Boost integral constant indicating how many
1052             significant bits are in the remainder and (truncated) divisor.
1053          */
1054         typedef std::integral_constant< int, Order >              width_c;
1055         /** \brief  The type to check for index-unit bit length
1056 
1057             This is a Boost integral constant indicating how many
1058             significant bits are in the trial new dividends.
1059          */
1060         typedef std::integral_constant< int, SubOrder >      unit_width_c;
1061         /** \brief  The type of registers
1062 
1063             This is the output type for the partial-product map.
1064          */
1065         typedef typename boost::crc_detail::uint_t< Order >::fast          value_type;
1066         /** \brief  The type to check the divisor
1067 
1068             This is a Boost integral constant representing the (truncated)
1069             divisor.
1070          */
1071         typedef std::integral_constant< value_type, TruncatedPolynomial >
1072           poly_c;
1073         /** \brief  The type to check for reflection
1074 
1075             This is a Boost integral constant representing whether input
1076             units should be read in reverse order.
1077          */
1078         typedef std::integral_constant< bool, Reflect >           refin_c;
1079         /** \brief  The type to check for map size
1080 
1081             This is a Boost integral constant representing the number of
1082             elements in the partial-product map, based on the unit size.
1083          */
1084         typedef high_bit_mask_c< SubOrder >                  table_size_c;
1085         /** \brief  The type of the unit TO partial-product map
1086 
1087             This is the array type that takes units as the index and said unit's
1088             composite partial-product mask as the element.
1089          */
1090         typedef std::array<value_type, table_size_c::value>  array_type;
1091         /** \brief  Create a global array for the mapping table
1092 
1093             Creates an instance of a partial-product array with this class's
1094             parameters.
1095 
1096             \return  A reference to a immutable array giving the partial-product
1097               update XOR map for each potential sub-unit value.
1098          */
1099         static  array_type const &  get_table()
1100         {
1101             static  array_type const  table =
1102              make_partial_xor_products_table<unit_width_c::value>(
1103              width_c::value, poly_c::value, refin_c::value );
1104 
1105             return table;
1106         }
1107     };
1108 
1109     /** \brief  A mix-in class that handles direct (i.e. non-reflected) byte-fed
1110           table-driven CRC algorithms
1111 
1112         This class template adds member functions #augmented_crc_update and
1113         #crc_update to update remainders from new input bytes.  The bytes aren't
1114         reflected before processing.
1115 
1116         \pre  \c CHAR_BIT \<= \a Order \<= \c std\::numeric_limits\<uintmax_t\>
1117           \::digits
1118 
1119         \tparam Order  The order of the modulo-2 polynomial remainder and one
1120           less than the divisor's order.
1121         \tparam TruncatedPolynomial  The lowest coefficients of the divisor
1122           polynomial.  The highest-order coefficient is omitted and always
1123           assumed to be 1.
1124      */
1125     template < int Order, std::uintmax_t TruncatedPolynomial >
1126     class direct_byte_table_driven_crcs
1127         : public crc_table_t<Order, CHAR_BIT, TruncatedPolynomial, false>
1128     {
1129         typedef crc_table_t<Order, CHAR_BIT, TruncatedPolynomial, false>
1130           base_type;
1131 
1132     public:
1133         typedef typename base_type::value_type  value_type;
1134         typedef typename base_type::array_type  array_type;
1135 
1136         /** \brief  Compute the updated remainder after reading some bytes
1137 
1138             The implementation reads from a table to speed-up applying
1139             augmented-CRC updates byte-wise.
1140 
1141             \param remainder  The pre-update remainder
1142             \param new_dividend_bytes  The address where the new bytes start
1143             \param new_dividend_byte_count  The number of new bytes to read
1144 
1145             \return  The updated remainder
1146          */
1147         static  value_type  augmented_crc_update( value_type remainder, unsigned
1148          char const *new_dividend_bytes, std::size_t new_dividend_byte_count)
1149         {
1150             static  array_type const &  table = base_type::get_table();
1151 
1152             while ( new_dividend_byte_count-- )
1153             {
1154                 // Locates the merged partial product based on the leading byte
1155                 unsigned char const  index = ( remainder >> (Order - CHAR_BIT) )
1156                  & UCHAR_MAX;
1157 
1158                 // Complete the multi-bit modulo-2 polynomial division
1159                 remainder <<= CHAR_BIT;
1160                 remainder |= *new_dividend_bytes++;
1161                 remainder ^= table[ index ];
1162             }
1163 
1164             return remainder;
1165         }
1166 
1167         /** \brief  Compute the updated remainder after reading some bytes
1168 
1169             The implementation reads from a table to speed-up applying
1170             unaugmented-CRC updates byte-wise.
1171 
1172             \param remainder  The pre-update remainder
1173             \param new_dividend_bytes  The address where the new bytes start
1174             \param new_dividend_byte_count  The number of new bytes to read
1175 
1176             \return  The updated remainder
1177          */
1178         static  value_type  crc_update( value_type remainder, unsigned char
1179          const *new_dividend_bytes, std::size_t new_dividend_byte_count)
1180         {
1181             static  array_type const &  table = base_type::get_table();
1182 
1183             while ( new_dividend_byte_count-- )
1184             {
1185                 // Locates the merged partial product based on comparing the
1186                 // leading and incoming bytes
1187                 unsigned char const  index = ( (remainder >> ( Order - CHAR_BIT
1188                  )) & UCHAR_MAX ) ^ *new_dividend_bytes++;
1189 
1190                 // Complete the multi-bit altered modulo-2 polynomial division
1191                 remainder <<= CHAR_BIT;
1192                 remainder ^= table[ index ];
1193             }
1194 
1195             return remainder;
1196         }
1197     };
1198 
1199     /** \brief  A mix-in class that handles reflected byte-fed, table-driven CRC
1200           algorithms
1201 
1202         This class template adds member functions #augmented_crc_update and
1203         #crc_update to update remainders from new input bytes.  The bytes are
1204         reflected before processing.
1205 
1206         \pre  \c CHAR_BIT \<= \a Order \<= \c std\::numeric_limits\<uintmax_t\>
1207           \::digits
1208 
1209         \tparam Order  The order of the modulo-2 polynomial remainder and one
1210           less than the divisor's order.
1211         \tparam TruncatedPolynomial  The lowest coefficients of the divisor
1212           polynomial.  The highest-order coefficient is omitted and always
1213           assumed to be 1.
1214      */
1215     template < int Order, std::uintmax_t TruncatedPolynomial >
1216     class reflected_byte_table_driven_crcs
1217         : public crc_table_t<Order, CHAR_BIT, TruncatedPolynomial, true>
1218     {
1219         typedef crc_table_t<Order, CHAR_BIT, TruncatedPolynomial, true>
1220           base_type;
1221 
1222     public:
1223         typedef typename base_type::value_type  value_type;
1224         typedef typename base_type::array_type  array_type;
1225 
1226         /** \brief  Compute the updated remainder after reading some bytes
1227 
1228             The implementation reads from a table to speed-up applying
1229             reflecting augmented-CRC updates byte-wise.
1230 
1231             \param remainder  The pre-update remainder; since the bytes are
1232               being reflected, this remainder also has to be reflected
1233             \param new_dividend_bytes  The address where the new bytes start
1234             \param new_dividend_byte_count  The number of new bytes to read
1235 
1236             \return  The updated, reflected remainder
1237          */
1238         static  value_type  augmented_crc_update( value_type remainder, unsigned
1239          char const *new_dividend_bytes, std::size_t new_dividend_byte_count)
1240         {
1241             static  array_type const &  table = base_type::get_table();
1242 
1243             while ( new_dividend_byte_count-- )
1244             {
1245                 // Locates the merged partial product based on the leading byte
1246                 // (which is at the low-order end for reflected remainders)
1247                 unsigned char const  index = remainder & UCHAR_MAX;
1248 
1249                 // Complete the multi-bit reflected modulo-2 polynomial division
1250                 remainder >>= CHAR_BIT;
1251                 remainder |= static_cast<value_type>( *new_dividend_bytes++ )
1252                  << ( Order - CHAR_BIT );
1253                 remainder ^= table[ index ];
1254             }
1255 
1256             return remainder;
1257         }
1258 
1259         /** \brief  Compute the updated remainder after reading some bytes
1260 
1261             The implementation reads from a table to speed-up applying
1262             reflected unaugmented-CRC updates byte-wise.
1263 
1264             \param remainder  The pre-update remainder; since the bytes are
1265               being reflected, this remainder also has to be reflected
1266             \param new_dividend_bytes  The address where the new bytes start
1267             \param new_dividend_byte_count  The number of new bytes to read
1268 
1269             \return  The updated, reflected remainder
1270          */
1271         static  value_type  crc_update( value_type remainder, unsigned char
1272          const *new_dividend_bytes, std::size_t new_dividend_byte_count)
1273         {
1274             static  array_type const &  table = base_type::get_table();
1275 
1276             while ( new_dividend_byte_count-- )
1277             {
1278                 // Locates the merged partial product based on comparing the
1279                 // leading and incoming bytes
1280                 unsigned char const  index = ( remainder & UCHAR_MAX ) ^
1281                  *new_dividend_bytes++;
1282 
1283                 // Complete the multi-bit reflected altered modulo-2 polynomial
1284                 // division
1285                 remainder >>= CHAR_BIT;
1286                 remainder ^= table[ index ];
1287             }
1288 
1289             return remainder;
1290         }
1291     };
1292 
1293     /** \brief  Mix-in class for byte-fed, table-driven CRC algorithms with
1294           parameter values at least a byte in width
1295 
1296         This class template adds member functions #augmented_crc_update and
1297         #crc_update to update remainders from new input bytes.  The bytes may be
1298         reflected before processing, controlled by a compile-time parameter.
1299 
1300         \pre  \c CHAR_BIT \<= \a Order \<= \c std\::numeric_limits\<uintmax_t\>
1301           \::digits
1302 
1303         \tparam Order  The order of the modulo-2 polynomial remainder and one
1304           less than the divisor's order.
1305         \tparam TruncatedPolynomial  The lowest coefficients of the divisor
1306           polynomial.  The highest-order coefficient is omitted and always
1307           assumed to be 1.
1308         \tparam Reflect  If \c false, read from the highest-order bit from a new
1309           input byte and go down, as normal.  Otherwise, proceed from the
1310           lowest-order bit and go up.
1311      */
1312     template < int Order, std::uintmax_t TruncatedPolynomial, bool Reflect >
1313     class byte_table_driven_crcs
1314         : public std::conditional< Reflect,
1315           reflected_byte_table_driven_crcs<Order, TruncatedPolynomial>,
1316           direct_byte_table_driven_crcs<Order, TruncatedPolynomial> >::type
1317     { };
1318 
1319     /** \brief  A mix-in class that handles direct (i.e. non-reflected) byte-fed
1320           CRC algorithms for sub-byte parameters
1321 
1322         This class template adds member functions #augmented_crc_update and
1323         #crc_update to update remainders from new input bytes.  The bytes aren't
1324         reflected before processing.
1325 
1326         \pre  0 \< \a Order \< \c CHAR_BIT
1327 
1328         \tparam Order  The order of the modulo-2 polynomial remainder and one
1329           less than the divisor's order.
1330         \tparam TruncatedPolynomial  The lowest coefficients of the divisor
1331           polynomial.  The highest-order coefficient is omitted and always
1332           assumed to be 1.
1333      */
1334     template < int Order, std::uintmax_t TruncatedPolynomial >
1335     class direct_sub_byte_crcs
1336         : public crc_table_t<Order, Order, TruncatedPolynomial, false>
1337     {
1338         typedef crc_table_t<Order, Order, TruncatedPolynomial, false>
1339           base_type;
1340 
1341     public:
1342         typedef typename base_type::width_c     width_c;
1343         typedef typename base_type::value_type  value_type;
1344         typedef typename base_type::poly_c       poly_c;
1345         typedef typename base_type::array_type  array_type;
1346 
1347         /** \brief  Compute the updated remainder after reading some bytes
1348 
1349             The implementation reads from a table to speed-up applying
1350             augmented-CRC updates byte-wise.
1351 
1352             \param remainder  The pre-update remainder
1353             \param new_dividend_bytes  The address where the new bytes start
1354             \param new_dividend_byte_count  The number of new bytes to read
1355 
1356             \return  The updated remainder
1357 
1358             \todo  Use this function somewhere so I can test it.
1359          */
1360         static  value_type  augmented_crc_update( value_type remainder, unsigned
1361          char const *new_dividend_bytes, std::size_t new_dividend_byte_count)
1362         {
1363             //static  array_type const &  table = base_type::get_table();
1364 
1365             while ( new_dividend_byte_count-- )
1366             {
1367                 // Without a table, process each byte explicitly
1368                 augmented_crc_modulo_word_update( width_c::value, remainder,
1369                  *new_dividend_bytes++, poly_c::value, CHAR_BIT, false );
1370             }
1371 
1372             return remainder;
1373         }
1374 
1375         /** \brief  Compute the updated remainder after reading some bytes
1376 
1377             The implementation reads from a table to speed-up applying
1378             unaugmented-CRC updates byte-wise.
1379 
1380             \param remainder  The pre-update remainder
1381             \param new_dividend_bytes  The address where the new bytes start
1382             \param new_dividend_byte_count  The number of new bytes to read
1383 
1384             \return  The updated remainder
1385          */
1386         static  value_type  crc_update( value_type remainder, unsigned char
1387          const *new_dividend_bytes, std::size_t new_dividend_byte_count)
1388         {
1389             //static  array_type const &  table = base_type::get_table();
1390 
1391             while ( new_dividend_byte_count-- )
1392             {
1393                 // Without a table, process each byte explicitly
1394                 crc_modulo_word_update( width_c::value, remainder,
1395                  *new_dividend_bytes++, poly_c::value, CHAR_BIT, false );
1396             }
1397 
1398             return remainder;
1399         }
1400     };
1401 
1402     /** \brief  A mix-in class that handles reflected byte-fed, CRC algorithms
1403           for sub-byte parameters
1404 
1405         This class template adds member functions #augmented_crc_update and
1406         #crc_update to update remainders from new input bytes.  The bytes are
1407         reflected before processing.
1408 
1409         \pre  0 \< \a Order \< \c CHAR_BIT
1410 
1411         \tparam Order  The order of the modulo-2 polynomial remainder and one
1412           less than the divisor's order.
1413         \tparam TruncatedPolynomial  The lowest coefficients of the divisor
1414           polynomial.  The highest-order coefficient is omitted and always
1415           assumed to be 1.
1416      */
1417     template < int Order, std::uintmax_t TruncatedPolynomial >
1418     class reflected_sub_byte_crcs
1419         : public crc_table_t<Order, Order, TruncatedPolynomial, true>
1420     {
1421         typedef crc_table_t<Order, Order, TruncatedPolynomial, true>
1422           base_type;
1423 
1424     public:
1425         typedef typename base_type::width_c     width_c;
1426         typedef typename base_type::value_type  value_type;
1427         typedef typename base_type::poly_c       poly_c;
1428         typedef typename base_type::array_type  array_type;
1429 
1430         /** \brief  Compute the updated remainder after reading some bytes
1431 
1432             The implementation reads from a table to speed-up applying
1433             reflecting augmented-CRC updates byte-wise.
1434 
1435             \param remainder  The pre-update remainder; since the bytes are
1436               being reflected, this remainder also has to be reflected
1437             \param new_dividend_bytes  The address where the new bytes start
1438             \param new_dividend_byte_count  The number of new bytes to read
1439 
1440             \return  The updated, reflected remainder
1441 
1442             \todo  Use this function somewhere so I can test it.
1443          */
1444         static  value_type  augmented_crc_update( value_type remainder, unsigned
1445          char const *new_dividend_bytes, std::size_t new_dividend_byte_count)
1446         {
1447             //static  array_type const &  table = base_type::get_table();
1448 
1449             remainder = reflect_sub_byte( remainder, width_c::value );
1450             while ( new_dividend_byte_count-- )
1451             {
1452                 // Without a table, process each byte explicitly
1453                 augmented_crc_modulo_word_update( width_c::value, remainder,
1454                  *new_dividend_bytes++, poly_c::value, CHAR_BIT, true );
1455             }
1456             remainder = reflect_sub_byte( remainder, width_c::value );
1457 
1458             return remainder;
1459         }
1460 
1461         /** \brief  Compute the updated remainder after reading some bytes
1462 
1463             The implementation reads from a table to speed-up applying
1464             reflected unaugmented-CRC updates byte-wise.
1465 
1466             \param remainder  The pre-update remainder; since the bytes are
1467               being reflected, this remainder also has to be reflected
1468             \param new_dividend_bytes  The address where the new bytes start
1469             \param new_dividend_byte_count  The number of new bytes to read
1470 
1471             \return  The updated, reflected remainder
1472          */
1473         static  value_type  crc_update( value_type remainder, unsigned char
1474          const *new_dividend_bytes, std::size_t new_dividend_byte_count)
1475         {
1476             //static  array_type const &  table = base_type::get_table();
1477 
1478             remainder = reflect_sub_byte( remainder, width_c::value );
1479             while ( new_dividend_byte_count-- )
1480             {
1481                 // Without a table, process each byte explicitly
1482                 crc_modulo_word_update( width_c::value, remainder,
1483                  *new_dividend_bytes++, poly_c::value, CHAR_BIT, true );
1484             }
1485             remainder = reflect_sub_byte( remainder, width_c::value );
1486 
1487             return remainder;
1488         }
1489     };
1490 
1491     /** \brief  Mix-in class for byte-fed, table-driven CRC algorithms with
1492           sub-byte parameters
1493 
1494         This class template adds member functions #augmented_crc_update and
1495         #crc_update to update remainders from new input bytes.  The bytes may be
1496         reflected before processing, controlled by a compile-time parameter.
1497 
1498         \pre  0 \< \a Order \< \c CHAR_BIT
1499 
1500         \tparam Order  The order of the modulo-2 polynomial remainder and one
1501           less than the divisor's order.
1502         \tparam TruncatedPolynomial  The lowest coefficients of the divisor
1503           polynomial.  The highest-order coefficient is omitted and always
1504           assumed to be 1.
1505         \tparam Reflect  If \c false, read from the highest-order bit from a new
1506           input byte and go down, as normal.  Otherwise, proceed from the
1507           lowest-order bit and go up.
1508      */
1509     template < int Order, std::uintmax_t TruncatedPolynomial, bool Reflect >
1510     class sub_byte_crcs
1511         : public std::conditional< Reflect,
1512           reflected_sub_byte_crcs<Order, TruncatedPolynomial>,
1513           direct_sub_byte_crcs<Order, TruncatedPolynomial> >::type
1514     { };
1515 
1516     /** This class template adds member functions #augmented_crc_update and
1517         #crc_update to update remainders from new input bytes.  The bytes may be
1518         reflected before processing, controlled by a compile-time parameter.
1519 
1520         \pre  0 \< \a Order \<= \c std\::numeric_limits\<uintmax_t\>\::digits
1521 
1522         \tparam Order  The order of the modulo-2 polynomial remainder and one
1523           less than the divisor's order.
1524         \tparam TruncatedPolynomial  The lowest coefficients of the divisor
1525           polynomial.  The highest-order coefficient is omitted and always
1526           assumed to be 1.
1527         \tparam Reflect  If \c false, read from the highest-order bit from a new
1528           input byte and go down, as normal.  Otherwise, proceed from the
1529           lowest-order bit and go up.
1530         \tparam Id  An extra differentiator if multiple copies of this class
1531           template are mixed-in as base classes.  Defaults to 0 if omitted.
1532      */
1533     template < int Order, std::uintmax_t TruncatedPolynomial, bool Reflect,
1534      int Id >
1535     class crc_driver
1536         : public std::conditional< (Order < CHAR_BIT), sub_byte_crcs<Order,
1537           TruncatedPolynomial, Reflect>, byte_table_driven_crcs<Order,
1538           TruncatedPolynomial, Reflect> >::type
1539     {
1540     public:
1541         /** \brief  The type to check for ID
1542 
1543             This is a Boost integral constant indicating what ID number this
1544             instantiation used.
1545          */
1546         typedef std::integral_constant<int, Id>  id_type;
1547     };
1548 
1549 
1550 }  // namespace detail
1551 //! \endcond
1552 
1553 
1554 //  Simple CRC class function definitions  -----------------------------------//
1555 
1556 /** Constructs a \c crc_basic object with at least the required parameters to a
1557     particular CRC formula to be processed upon receiving input.
1558 
1559     \param[in] truncated_polynomial  The lowest coefficients of the divisor
1560       polynomial.  The highest-order coefficient is omitted and always assumed
1561       to be 1.  (\e Poly from the RMCA)
1562     \param[in] initial_remainder  The (unaugmented) initial state of the
1563       polynomial remainder.  Defaults to \c 0 if omitted.  (\e Init from the
1564       RMCA)
1565     \param[in] final_xor_value  The (XOR) bit-mask to be applied to the output
1566       remainder, after possible reflection but before returning.  Defaults to
1567       \c 0 (i.e. no bit changes) if omitted.  (\e XorOut from the RMCA)
1568     \param[in] reflect_input  If \c true, input bytes are read lowest-order bit
1569       first, otherwise highest-order bit first.  Defaults to \c false if
1570       omitted.  (\e RefIn from the RMCA)
1571     \param[in] reflect_remainder  If \c true, the output remainder is reflected
1572       before the XOR-mask.  Defaults to \c false if omitted.  (\e RefOut from
1573       the RMCA)
1574 
1575     \post  <code><var>truncated_polynomial</var> ==
1576       this-&gt;get_truncated_polynominal()</code>
1577     \post  <code><var>initial_remainder</var> ==
1578       this-&gt;get_initial_remainder()</code>
1579     \post  <code><var>final_xor_value</var> ==
1580       this-&gt;get_final_xor_value()</code>
1581     \post  <code><var>reflect_input</var> ==
1582       this-&gt;get_reflect_input()</code>
1583     \post  <code><var>reflect_remainder</var> ==
1584       this-&gt;get_reflect_remainder()</code>
1585     \post  <code><var>initial_remainder</var> ==
1586       this-&gt;get_interim_remainder()</code>
1587     \post  <code>(<var>reflect_remainder</var> ?
1588       REFLECT(<var>initial_remainder</var>) : <var>initial_remainder</var>) ^
1589       <var>final_xor_value</var> == this-&gt;checksum()</code>
1590  */
1591 template < std::size_t Bits >
1592 inline
1593 crc_basic<Bits>::crc_basic
1594 (
1595     value_type  truncated_polynomial,
1596     value_type  initial_remainder,      // = 0
1597     value_type  final_xor_value,        // = 0
1598     bool        reflect_input,          // = false
1599     bool        reflect_remainder       // = false
1600 )
1601     : rem_( initial_remainder ), poly_( truncated_polynomial )
1602     , init_( initial_remainder ), final_( final_xor_value )
1603     , rft_in_( reflect_input ), rft_out_( reflect_remainder )
1604 {
1605 }
1606 
1607 /** Returns a representation of the polynomial divisor.  The value of the
1608     2<sup>i</sup> bit is the value of the coefficient of the polynomial's
1609     x<sup>i</sup> term.  The omitted bit for x<sup>(#bit_count)</sup> term is
1610     always 1.
1611 
1612     \return  The bit-packed list of coefficients.  If the bit-length of
1613       #value_type exceeds #bit_count, the values of higher-placed bits should be
1614       ignored (even any for x<sup>(#bit_count)</sup>) since they're unregulated.
1615  */
1616 template < std::size_t Bits >
1617 inline
1618 typename crc_basic<Bits>::value_type
1619 crc_basic<Bits>::get_truncated_polynominal
1620 (
1621 ) const
1622 {
1623     return poly_;
1624 }
1625 
1626 /** Returns a representation of the polynomial remainder before any input has
1627     been submitted.  The value of the 2<sup>i</sup> bit is the value of the
1628     coefficient of the polynomial's x<sup>i</sup> term.
1629 
1630     \return  The bit-packed list of coefficients.  If the bit-length of
1631       #value_type exceeds #bit_count, the values of higher-placed bits should be
1632       ignored since they're unregulated.
1633  */
1634 template < std::size_t Bits >
1635 inline
1636 typename crc_basic<Bits>::value_type
1637 crc_basic<Bits>::get_initial_remainder
1638 (
1639 ) const
1640 {
1641     return init_;
1642 }
1643 
1644 /** Returns the mask to be used during creation of a checksum.  The mask is used
1645     for an exclusive-or (XOR) operation applied bit-wise to the interim
1646     remainder representation (after any reflection, if #get_reflect_remainder()
1647     returns \c true).
1648 
1649     \return  The bit-mask.  If the bit-length of #value_type exceeds #bit_count,
1650       the values of higher-placed bits should be ignored since they're
1651       unregulated.
1652  */
1653 template < std::size_t Bits >
1654 inline
1655 typename crc_basic<Bits>::value_type
1656 crc_basic<Bits>::get_final_xor_value
1657 (
1658 ) const
1659 {
1660     return final_;
1661 }
1662 
1663 /** Returns a whether or not a submitted byte will be \"reflected\" before it is
1664     used to update the interim remainder.  Only the byte-wise operations
1665     #process_byte, #process_block, and #process_bytes are affected.
1666 
1667     \retval true  Input bytes will be read starting from the lowest-order bit.
1668     \retval false  Input bytes will be read starting from the highest-order bit.
1669  */
1670 template < std::size_t Bits >
1671 inline
1672 bool
1673 crc_basic<Bits>::get_reflect_input
1674 (
1675 ) const
1676 {
1677     return rft_in_;
1678 }
1679 
1680 /** Indicates if the interim remainder will be \"reflected\" before it is passed
1681     to the XOR-mask stage when returning a checksum.
1682 
1683     \retval true  The interim remainder is reflected before further work.
1684     \retval false  The interim remainder is applied to the XOR-mask as-is.
1685  */
1686 template < std::size_t Bits >
1687 inline
1688 bool
1689 crc_basic<Bits>::get_reflect_remainder
1690 (
1691 ) const
1692 {
1693     return rft_out_;
1694 }
1695 
1696 /** Returns a representation of the polynomial remainder after all the input
1697     submissions since construction or the last #reset call.  The value of the
1698     2<sup>i</sup> bit is the value of the coefficient of the polynomial's
1699     x<sup>i</sup> term.  If CRC processing gets interrupted here, retain the
1700     value returned, and use it to start up the next CRC computer where you left
1701     off (with #reset(value_type) or construction).  The next computer has to
1702     have its other parameters compatible with this computer.
1703 
1704     \return  The bit-packed list of coefficients.  If the bit-length of
1705       #value_type exceeds #bit_count, the values of higher-placed bits should be
1706       ignored since they're unregulated.  No output processing (reflection or
1707       XOR mask) has been applied to the value.
1708  */
1709 template < std::size_t Bits >
1710 inline
1711 typename crc_basic<Bits>::value_type
1712 crc_basic<Bits>::get_interim_remainder
1713 (
1714 ) const
1715 {
1716     return rem_ & detail::low_bits_mask_c<bit_count>::value;
1717 }
1718 
1719 /** Changes the interim polynomial remainder to \a new_rem, purging any
1720     influence previously submitted input has had.  The value of the
1721     2<sup>i</sup> bit is the value of the coefficient of the polynomial's
1722     x<sup>i</sup> term.
1723 
1724     \param[in] new_rem  The (unaugmented) state of the polynomial remainder
1725       starting from this point, with no output processing applied.
1726 
1727     \post  <code><var>new_rem</var> == this-&gt;get_interim_remainder()</code>
1728     \post  <code>((this-&gt;get_reflect_remainder() ?
1729       REFLECT(<var>new_rem</var>) : <var>new_rem</var>) ^
1730       this-&gt;get_final_xor_value()) == this-&gt;checksum()</code>
1731  */
1732 template < std::size_t Bits >
1733 inline
1734 void
1735 crc_basic<Bits>::reset
1736 (
1737     value_type  new_rem
1738 )
1739 {
1740     rem_ = new_rem;
1741 }
1742 
1743 /** Changes the interim polynomial remainder to the initial remainder given
1744     during construction, purging any influence previously submitted input has
1745     had.  The value of the 2<sup>i</sup> bit is the value of the coefficient of
1746     the polynomial's x<sup>i</sup> term.
1747 
1748     \post  <code>this-&gt;get_initial_remainder() ==
1749       this-&gt;get_interim_remainder()</code>
1750     \post  <code>((this-&gt;get_reflect_remainder() ?
1751       REFLECT(this-&gt;get_initial_remainder()) :
1752       this-&gt;get_initial_remainder()) ^ this-&gt;get_final_xor_value())
1753       == this-&gt;checksum()</code>
1754  */
1755 template < std::size_t Bits >
1756 inline
1757 void
1758 crc_basic<Bits>::reset
1759 (
1760 )
1761 {
1762     this->reset( this->get_initial_remainder() );
1763 }
1764 
1765 /** Updates the interim remainder with a single altered-CRC-division step.
1766 
1767     \param[in] bit  The new input bit.
1768 
1769     \post  The interim remainder is updated though a modulo-2 polynomial
1770       division, where the division steps are altered for unaugmented CRCs.
1771  */
1772 template < std::size_t Bits >
1773 inline
1774 void
1775 crc_basic<Bits>::process_bit
1776 (
1777     bool  bit
1778 )
1779 {
1780     detail::crc_modulo_update( bit_count, rem_, bit, poly_ );
1781 }
1782 
1783 /** Updates the interim remainder with several altered-CRC-division steps.  Each
1784     bit is processed separately, starting from the one at the
1785     2<sup><var>bit_length</var> - 1</sup> place, then proceeding down to the
1786     lowest-placed bit.  Any order imposed by
1787     <code>this-&gt;get_reflect_input()</code> is ignored.
1788 
1789     \pre  0 \< \a bit_length \<= \c CHAR_BIT
1790 
1791     \param[in] bits  The byte containing the new input bits.
1792     \param[in] bit_length  The number of bits in the byte to be read.
1793 
1794     \post  The interim remainder is updated though \a bit_length modulo-2
1795       polynomial divisions, where the division steps are altered for unaugmented
1796       CRCs.
1797  */
1798 template < std::size_t Bits >
1799 void
1800 crc_basic<Bits>::process_bits
1801 (
1802     unsigned char  bits,
1803     std::size_t    bit_length
1804 )
1805 {
1806     // ignore the bits above the ones we want
1807     bits <<= CHAR_BIT - bit_length;
1808 
1809     // compute the CRC for each bit, starting with the upper ones
1810     unsigned char const  high_bit_mask = 1u << ( CHAR_BIT - 1u );
1811     for ( std::size_t i = bit_length ; i > 0u ; --i, bits <<= 1u )
1812     {
1813         process_bit( (bits & high_bit_mask) != 0 );
1814     }
1815 }
1816 
1817 /** Updates the interim remainder with a byte's worth of altered-CRC-division
1818     steps.  The bits within the byte are processed from the highest place down
1819     if <code>this-&gt;get_reflect_input()</code> is \c false, and lowest place
1820     up otherwise.
1821 
1822     \param[in] byte  The new input byte.
1823 
1824     \post  The interim remainder is updated though \c CHAR_BIT modulo-2
1825       polynomial divisions, where the division steps are altered for unaugmented
1826       CRCs.
1827  */
1828 template < std::size_t Bits >
1829 inline
1830 void
1831 crc_basic<Bits>::process_byte
1832 (
1833     unsigned char  byte
1834 )
1835 {
1836     process_bits( (rft_in_ ? detail::reflect_byte( byte ) : byte), CHAR_BIT );
1837 }
1838 
1839 /** Updates the interim remainder with several bytes' worth of
1840     altered-CRC-division steps.  The bits within each byte are processed from
1841     the highest place down if <code>this-&gt;get_reflect_input()</code> is
1842     \c false, and lowest place up otherwise.  The bytes themselves are processed
1843     starting from the one pointed by \a bytes_begin until \a bytes_end is
1844     reached through forward iteration, treating the two pointers as if they
1845     point to <code>unsigned char</code> objects.
1846 
1847     \pre  \a bytes_end has to equal \a bytes_begin if the latter is \c NULL or
1848       otherwise doesn't point to a valid buffer.
1849     \pre  \a bytes_end, if not equal to \a bytes_begin, has to point within or
1850       one-byte-past the same buffer \a bytes_begin points into.
1851     \pre  \a bytes_end has to be reachable from \a bytes_begin through a finite
1852       number of forward byte-pointer increments.
1853 
1854     \param[in] bytes_begin  The address where the memory block begins.
1855     \param[in] bytes_end  Points to one-byte past the address of the memory
1856       block's last byte, or \a bytes_begin if no bytes are to be read.
1857 
1858     \post  The interim remainder is updated though <code>CHAR_BIT * (((unsigned
1859       char const *) bytes_end) - ((unsigned char const *) bytes_begin))</code>
1860       modulo-2 polynomial divisions, where the division steps are altered for
1861       unaugmented CRCs.
1862  */
1863 template < std::size_t Bits >
1864 void
1865 crc_basic<Bits>::process_block
1866 (
1867     void const *  bytes_begin,
1868     void const *  bytes_end
1869 )
1870 {
1871     for ( unsigned char const * p
1872      = static_cast<unsigned char const *>(bytes_begin) ; p < bytes_end ; ++p )
1873     {
1874         process_byte( *p );
1875     }
1876 }
1877 
1878 /** Updates the interim remainder with several bytes' worth of
1879     altered-CRC-division steps.  The bits within each byte are processed from
1880     the highest place down if <code>this-&gt;get_reflect_input()</code> is
1881     \c false, and lowest place up otherwise.  The bytes themselves are processed
1882     starting from the one pointed by \a buffer, forward-iterated (as if the
1883     pointed-to objects were of <code>unsigned char</code>) until \a byte_count
1884     bytes are read.
1885 
1886     \pre  \a byte_count has to equal 0 if \a buffer is \c NULL or otherwise
1887       doesn't point to valid memory.
1888     \pre  If \a buffer points within valid memory, then that block has to have
1889       at least \a byte_count more valid bytes allocated from that point.
1890 
1891     \param[in] buffer  The address where the memory block begins.
1892     \param[in] byte_count  The number of bytes in the memory block.
1893 
1894     \post  The interim remainder is updated though <code>CHAR_BIT *
1895       <var>byte_count</var></code> modulo-2 polynomial divisions, where the
1896       division steps are altered for unaugmented CRCs.
1897  */
1898 template < std::size_t Bits >
1899 inline
1900 void
1901 crc_basic<Bits>::process_bytes
1902 (
1903     void const *  buffer,
1904     std::size_t   byte_count
1905 )
1906 {
1907     unsigned char const * const  b = static_cast<unsigned char const *>(
1908      buffer );
1909 
1910     process_block( b, b + byte_count );
1911 }
1912 
1913 /** Computes the checksum of all the submitted bits since construction or the
1914     last call to #reset.  The checksum will be the raw checksum, i.e. the
1915     (interim) remainder after all the modulo-2 polynomial division, plus any
1916     output processing.
1917 
1918     \return  <code>(this-&gt;get_reflect_remainder() ?
1919       REFLECT(this-&gt;get_interim_remainder()) :
1920       this-&gt;get_interim_remainder()) ^ this-&gt;get_final_xor_value()</code>
1921 
1922     \note  Since checksums are meant to be compared, any higher-placed bits
1923       (when the bit-length of #value_type exceeds #bit_count) will be set to 0.
1924  */
1925 template < std::size_t Bits >
1926 inline
1927 typename crc_basic<Bits>::value_type
1928 crc_basic<Bits>::checksum
1929 (
1930 ) const
1931 {
1932     return ( (rft_out_ ? detail::reflect_unsigned( rem_, bit_count ) :
1933      rem_) ^ final_ ) & detail::low_bits_mask_c<bit_count>::value;
1934 }
1935 
1936 
1937 //  Optimized CRC class function definitions  --------------------------------//
1938 
1939 // Macro to compact code
1940 #define BOOST_CRC_OPTIMAL_NAME  crc_optimal<Bits, TruncPoly, InitRem, \
1941  FinalXor, ReflectIn, ReflectRem>
1942 
1943 /** Constructs a \c crc_optimal object with a particular CRC formula to be
1944     processed upon receiving input.  The initial remainder may be overridden.
1945 
1946     \param[in] init_rem  The (unaugmented) initial state of the polynomial
1947       remainder.  Defaults to #initial_remainder if omitted.
1948 
1949     \post  <code>#truncated_polynominal ==
1950       this-&gt;get_truncated_polynominal()</code>
1951     \post  <code>#initial_remainder == this-&gt;get_initial_remainder()</code>
1952     \post  <code>#final_xor_value == this-&gt;get_final_xor_value()</code>
1953     \post  <code>#reflect_input == this-&gt;get_reflect_input()</code>
1954     \post  <code>#reflect_remainder == this-&gt;get_reflect_remainder()</code>
1955     \post  <code><var>init_rem</var> == this-&gt;get_interim_remainder()</code>
1956     \post  <code>(#reflect_remainder ? REFLECT(<var>init_rem</var>) :
1957       <var>init_rem</var>) ^ #final_xor_value == this-&gt;checksum()</code>
1958  */
1959 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
1960            BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
1961            bool ReflectIn, bool ReflectRem >
1962 inline
1963 BOOST_CRC_OPTIMAL_NAME::crc_optimal
1964 (
1965     value_type  init_rem  // = initial_remainder
1966 )
1967     : rem_( reflect_i_type::reflect_q(init_rem) )
1968 {
1969 }
1970 
1971 //! \copydetails  boost::crc_basic::get_truncated_polynominal
1972 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
1973            BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
1974            bool ReflectIn, bool ReflectRem >
1975 inline
1976 typename BOOST_CRC_OPTIMAL_NAME::value_type
1977 BOOST_CRC_OPTIMAL_NAME::get_truncated_polynominal
1978 (
1979 ) const
1980 {
1981     return truncated_polynominal;
1982 }
1983 
1984 //! \copydetails  boost::crc_basic::get_initial_remainder
1985 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
1986            BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
1987            bool ReflectIn, bool ReflectRem >
1988 inline
1989 typename BOOST_CRC_OPTIMAL_NAME::value_type
1990 BOOST_CRC_OPTIMAL_NAME::get_initial_remainder
1991 (
1992 ) const
1993 {
1994     return initial_remainder;
1995 }
1996 
1997 //! \copydetails  boost::crc_basic::get_final_xor_value
1998 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
1999            BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
2000            bool ReflectIn, bool ReflectRem >
2001 inline
2002 typename BOOST_CRC_OPTIMAL_NAME::value_type
2003 BOOST_CRC_OPTIMAL_NAME::get_final_xor_value
2004 (
2005 ) const
2006 {
2007     return final_xor_value;
2008 }
2009 
2010 //! \copydetails  boost::crc_basic::get_reflect_input
2011 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
2012            BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
2013            bool ReflectIn, bool ReflectRem >
2014 inline
2015 bool
2016 BOOST_CRC_OPTIMAL_NAME::get_reflect_input
2017 (
2018 ) const
2019 {
2020     return reflect_input;
2021 }
2022 
2023 //! \copydetails  boost::crc_basic::get_reflect_remainder
2024 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
2025            BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
2026            bool ReflectIn, bool ReflectRem >
2027 inline
2028 bool
2029 BOOST_CRC_OPTIMAL_NAME::get_reflect_remainder
2030 (
2031 ) const
2032 {
2033     return reflect_remainder;
2034 }
2035 
2036 //! \copydetails  boost::crc_basic::get_interim_remainder
2037 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
2038            BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
2039            bool ReflectIn, bool ReflectRem >
2040 inline
2041 typename BOOST_CRC_OPTIMAL_NAME::value_type
2042 BOOST_CRC_OPTIMAL_NAME::get_interim_remainder
2043 (
2044 ) const
2045 {
2046     // Interim remainder should be _un_-reflected, so we have to undo it.
2047     return reflect_i_type::reflect_q( rem_ ) &
2048      detail::low_bits_mask_c<bit_count>::value;
2049 }
2050 
2051 /** Changes the interim polynomial remainder to \a new_rem, purging any
2052     influence previously submitted input has had.  The value of the
2053     2<sup>i</sup> bit is the value of the coefficient of the polynomial's
2054     x<sup>i</sup> term.
2055 
2056     \param[in] new_rem  The (unaugmented) state of the polynomial remainder
2057       starting from this point, with no output processing applied.  Defaults to
2058       <code>this-&gt;get_initial_remainder()</code> if omitted.
2059 
2060     \post  <code><var>new_rem</var> == this-&gt;get_interim_remainder()</code>
2061     \post  <code>((this-&gt;get_reflect_remainder() ?
2062       REFLECT(<var>new_rem</var>) : <var>new_rem</var>) ^
2063       this-&gt;get_final_xor_value()) == this-&gt;checksum()</code>
2064  */
2065 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
2066            BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
2067            bool ReflectIn, bool ReflectRem >
2068 inline
2069 void
2070 BOOST_CRC_OPTIMAL_NAME::reset
2071 (
2072     value_type  new_rem  // = initial_remainder
2073 )
2074 {
2075     rem_ = reflect_i_type::reflect_q( new_rem );
2076 }
2077 
2078 /** \copydetails  boost::crc_basic::process_byte
2079 
2080     \note  Any modulo-2 polynomial divisions may use a table of pre-computed
2081       remainder changes (as XOR masks) to speed computation when reading data
2082       byte-wise.
2083  */
2084 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
2085            BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
2086            bool ReflectIn, bool ReflectRem >
2087 inline
2088 void
2089 BOOST_CRC_OPTIMAL_NAME::process_byte
2090 (
2091     unsigned char  byte
2092 )
2093 {
2094     process_bytes( &byte, sizeof(byte) );
2095 }
2096 
2097 /** \copydetails  boost::crc_basic::process_block
2098 
2099     \note  Any modulo-2 polynomial divisions may use a table of pre-computed
2100       remainder changes (as XOR masks) to speed computation when reading data
2101       byte-wise.
2102  */
2103 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
2104            BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
2105            bool ReflectIn, bool ReflectRem >
2106 inline
2107 void
2108 BOOST_CRC_OPTIMAL_NAME::process_block
2109 (
2110     void const *  bytes_begin,
2111     void const *  bytes_end
2112 )
2113 {
2114     process_bytes( bytes_begin, static_cast<unsigned char const *>(bytes_end) -
2115      static_cast<unsigned char const *>(bytes_begin) );
2116 }
2117 
2118 /** \copydetails  boost::crc_basic::process_bytes
2119 
2120     \note  Any modulo-2 polynomial divisions may use a table of pre-computed
2121       remainder changes (as XOR masks) to speed computation when reading data
2122       byte-wise.
2123  */
2124 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
2125            BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
2126            bool ReflectIn, bool ReflectRem >
2127 inline
2128 void
2129 BOOST_CRC_OPTIMAL_NAME::process_bytes
2130 (
2131     void const *   buffer,
2132     std::size_t  byte_count
2133 )
2134 {
2135     rem_ = crc_table_type::crc_update( rem_, static_cast<unsigned char const
2136      *>(buffer), byte_count );
2137 }
2138 
2139 //! \copydetails  boost::crc_basic::checksum
2140 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
2141            BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
2142            bool ReflectIn, bool ReflectRem >
2143 inline
2144 typename BOOST_CRC_OPTIMAL_NAME::value_type
2145 BOOST_CRC_OPTIMAL_NAME::checksum
2146 (
2147 ) const
2148 {
2149     return ( reflect_o_type::reflect_q(rem_) ^ get_final_xor_value() )
2150      & detail::low_bits_mask_c<bit_count>::value;
2151 }
2152 
2153 /** Updates the interim remainder with a byte's worth of altered-CRC-division
2154     steps.  The bits within the byte are processed from the highest place down
2155     if <code>this-&gt;get_reflect_input()</code> is \c false, and lowest place
2156     up otherwise.  This function is meant to present a function-object interface
2157     to code that wants to process a stream of bytes with
2158     <code>std::for_each</code> or similar range-processing algorithms.  Since
2159     some of these algorithms takes their function object by value, make sure to
2160     copy back the result to this object so the updates can be remembered.
2161 
2162     \param[in] byte  The new input byte.
2163 
2164     \post  The interim remainder is updated though \c CHAR_BIT modulo-2
2165       polynomial divisions, where the division steps are altered for unaugmented
2166       CRCs.
2167 
2168     \note  Any modulo-2 polynomial divisions may use a table of pre-computed
2169       remainder changes (as XOR masks) to speed computation when reading data
2170       byte-wise.
2171  */
2172 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
2173            BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
2174            bool ReflectIn, bool ReflectRem >
2175 inline
2176 void
2177 BOOST_CRC_OPTIMAL_NAME::operator ()
2178 (
2179     unsigned char  byte
2180 )
2181 {
2182     process_byte( byte );
2183 }
2184 
2185 /** Computes the checksum of all the submitted bits since construction or the
2186     last call to #reset.  The checksum will be the raw checksum, i.e. the
2187     (interim) remainder after all the modulo-2 polynomial division, plus any
2188     output processing.  This function is meant to present a function-object
2189     interface to code that wants to receive data like
2190     <code>std::generate_n</code> or similar data-processing algorithms.  Note
2191     that if this object is used as a generator multiple times without an
2192     intervening mutating operation, the same value will always be returned.
2193 
2194     \return  <code>(this-&gt;get_reflect_remainder() ?
2195       REFLECT(this-&gt;get_interim_remainder()) :
2196       this-&gt;get_interim_remainder()) ^ this-&gt;get_final_xor_value()</code>
2197 
2198     \note  Since checksums are meant to be compared, any higher-placed bits
2199       (when the bit-length of #value_type exceeds #bit_count) will be set to 0.
2200  */
2201 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
2202            BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
2203            bool ReflectIn, bool ReflectRem >
2204 inline
2205 typename BOOST_CRC_OPTIMAL_NAME::value_type
2206 BOOST_CRC_OPTIMAL_NAME::operator ()
2207 (
2208 ) const
2209 {
2210     return checksum();
2211 }
2212 
2213 
2214 //  CRC computation function definition  -------------------------------------//
2215 
2216 /** Computes the polynomial remainder of a CRC run, assuming that \a buffer and
2217     \a byte_count describe a memory block representing the polynomial dividend.
2218     The division steps are altered so the result directly gives a checksum,
2219     without need to augment the memory block with scratch-space bytes.  The
2220     first byte is considered the highest order, going down for subsequent bytes.
2221 
2222     \pre  0 \< \a Bits \<= \c std\::numeric_limits\<uintmax_t\>\::digits
2223 
2224     \tparam Bits  The order of the modulo-2 polynomial divisor.  (\e Width from
2225       the RMCA)
2226     \tparam TruncPoly  The lowest coefficients of the divisor polynomial.  The
2227       highest-order coefficient is omitted and always assumed to be 1.
2228       (\e Poly from the RMCA)
2229     \tparam InitRem  The (unaugmented) initial state of the polynomial
2230       remainder.  (\e Init from the RMCA)
2231     \tparam FinalXor  The (XOR) bit-mask to be applied to the output remainder,
2232       after possible reflection but before returning.  (\e XorOut from the RMCA)
2233     \tparam ReflectIn  If \c True, input bytes are read lowest-order bit first,
2234       otherwise highest-order bit first.  (\e RefIn from the RMCA)
2235     \tparam ReflectRem  If \c True, the output remainder is reflected before the
2236       XOR-mask.  (\e RefOut from the RMCA)
2237 
2238     \param[in] buffer  The address where the memory block begins.
2239     \param[in] byte_count  The number of bytes in the memory block.
2240 
2241     \return  The checksum, which is the last (interim) remainder plus any output
2242       processing.
2243 
2244     \note  Unaugmented-style CRC runs perform modulo-2 polynomial division in
2245       an altered order.  The trailing \a Bits number of zero-valued bits needed
2246       to extracted an (unprocessed) checksum is virtually moved to near the
2247       beginning of the message.  This is OK since the XOR operation is
2248       commutative and associative.  It also means that you can get a checksum
2249       anytime.  Since data is being read byte-wise, a table of pre-computed
2250       remainder changes (as XOR masks) can be used to speed computation.
2251 
2252  */
2253 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
2254            BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
2255            bool ReflectIn, bool ReflectRem >
2256 inline
2257 typename crc_detail::uint_t<Bits>::fast
2258 crc
2259 (
2260     void const *  buffer,
2261     std::size_t   byte_count
2262 )
2263 {
2264     BOOST_CRC_OPTIMAL_NAME  computer;
2265     computer.process_bytes( buffer, byte_count );
2266     return computer.checksum();
2267 }
2268 
2269 
2270 //  Augmented-message CRC computation function definition  -------------------//
2271 
2272 /** Computes the polynomial remainder of a CRC run, assuming that \a buffer and
2273     \a byte_count describe a memory block representing the polynomial dividend.
2274     The first byte is considered the highest order, going down for subsequent
2275     bytes.  Within a byte, the highest-order bit is read first (corresponding to
2276     \e RefIn = \c False in the RMCA).  Check the other parts of this function's
2277     documentation to see how a checksum can be gained and/or used.
2278 
2279     \pre  0 \< \a Bits \<= \c std\::numeric_limit\<uintmax_t\>\::digits
2280 
2281     \tparam Bits  The order of the modulo-2 polynomial divisor.  (\e Width from
2282       the RMCA)
2283     \tparam TruncPoly  The lowest coefficients of the divisor polynomial.  The
2284       highest-order coefficient is omitted and always assumed to be 1.
2285       (\e Poly from the RMCA)
2286 
2287     \param[in] buffer  The address where the memory block begins.
2288     \param[in] byte_count  The number of bytes in the memory block.
2289     \param[in] initial_remainder  The initial state of the polynomial
2290       remainder, defaulting to zero if omitted.  If you are reading a memory
2291       block in multiple runs, put the return value of the previous run here.
2292       (Note that initial-remainders given by RMCA parameter lists, as
2293       \e Init, assume that the initial remainder is in its \b unaugmented state,
2294       so you would need to convert the value to make it suitable for this
2295       function.  I currently don't provide a conversion routine.)
2296 
2297     \return  The interim remainder, if no augmentation is used.  A special value
2298       if augmentation is used (see the notes).  No output processing is done on
2299       the value.  (In RMCA terms, \e RefOut is \c False and \e XorOut is \c 0.)
2300 
2301     \note  Augmented-style CRC runs use straight-up modulo-2 polynomial
2302       division.  Since data is being read byte-wise, a table of pre-computed
2303       remainder changes (as XOR masks) can be used to speed computation.
2304     \note  Reading just a memory block will yield an interim remainder, and not
2305       the final checksum.  To get that checksum, allocate \a Bits / \c CHAR_BIT
2306       bytes directly after the block and fill them with zero values, then extend
2307       \a byte_count to include those extra bytes.  A data block is corrupt if
2308       the return value doesn't equal your separately given checksum.
2309     \note  Another way to perform a check is use the zero-byte extension method,
2310       but replace the zero values with your separately-given checksum.  The
2311       checksum must be loaded in big-endian order.  Here corruption, in either
2312       the data block or the given checksum, is confirmed if the return value is
2313       not zero.
2314     \note  The two checksum techniques assume the CRC-run is performed bit-wise,
2315       while this function works byte-wise.  That means that the techniques can
2316       be used only if \c CHAR_BIT divides \a Bits evenly!
2317  */
2318 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly >
2319 typename crc_detail::uint_t<Bits>::fast
2320 augmented_crc
2321 (
2322     void const *                 buffer,
2323     std::size_t                  byte_count,
2324     typename crc_detail::uint_t<Bits>::fast  initial_remainder  // = 0u
2325 )
2326 {
2327     return detail::low_bits_mask_c<Bits>::value &
2328      detail::byte_table_driven_crcs<Bits, TruncPoly, false>::
2329      augmented_crc_update( initial_remainder, static_cast<unsigned char const
2330      *>(buffer), byte_count );
2331 }
2332 
2333 
2334 }  // namespace boost
2335 
2336 
2337 // Undo header-private macros
2338 #undef BOOST_CRC_OPTIMAL_NAME
2339 #undef BOOST_CRC_PARM_TYPE
2340 
2341 
2342 #endif  // BOOST_CRC_HPP
2343