Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:53:17

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