1 //  Boost CRC library crc.hpp header file  -----------------------------------//
2 
3 //  Copyright 2001, 2004, 2011 Daryle Walker.
4 //  Distributed under the Boost Software License, Version 1.0.  (See the
5 //  accompanying file LICENSE_1_0.txt or a copy at
6 //  <http://www.boost.org/LICENSE_1_0.txt>.)
7 
8 //  See <http://www.boost.org/libs/crc/> for the library's home page.
9 
10 /** \file
11     \brief  A collection of function templates and class templates that compute
12       various forms of Cyclic Redundancy Codes (CRCs).
13 
14     \author  Daryle Walker
15 
16     \version  1.5
17 
18     \copyright  Boost Software License, version 1.0
19 
20     Contains the declarations (and definitions) of various kinds of CRC
21     computation functions, function object types, and encapsulated policy types.
22 
23     \warning  The sample CRC-computer types were just checked against the
24       <a href="http://regregex.bbcmicro.net/crc-catalogue.htm">Catalogue of
25       parametrised CRC algorithms</a>.  New type aliases were added where I got
26       a standard wrong.  However, the mistaken <code>typedef</code>s are still
27       there for backwards compatibility.
28     \note  There are references to the <i>Rocksoft&trade; Model CRC
29       Algorithm</i>, as described within \"A Painless Guide to CRC Error
30       Detection Algorithms,\" linked from \"<a
31       href="http://www.ross.net/crc/crcpaper.html">CRC: A Paper On CRCs</a>\" by
32       Ross Williams.  It will be abbreviated \"RMCA\" in other documentation
33       blocks.
34  */
35 
36 #ifndef BOOST_CRC_HPP
37 #define BOOST_CRC_HPP
38 
39 #include <boost/array.hpp>           // for boost::array
40 #include <boost/config.hpp>          // for BOOST_STATIC_CONSTANT, etc.
41 #include <boost/cstdint.hpp>         // for UINTMAX_C, boost::uintmax_t
42 #include <boost/integer.hpp>         // for boost::uint_t
43 #include <boost/type_traits/conditional.hpp>
44 #include <boost/type_traits/integral_constant.hpp>
45 
46 #include <climits>  // for CHAR_BIT, etc.
47 #include <cstddef>  // for std::size_t
48 
49 #include <boost/limits.hpp>  // for std::numeric_limits
50 
51 
52 // The type of CRC parameters that can go in a template should be related
53 // on the CRC's bit count.  This macro expresses that type in a compact
54 // form, but also allows an alternate type for compilers that don't support
55 // dependent types (in template value-parameters).
56 #if !(defined(BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS))
57 #define BOOST_CRC_PARM_TYPE  typename ::boost::uint_t<Bits>::fast
58 #else
59 #define BOOST_CRC_PARM_TYPE  unsigned long
60 #endif
61 
62 namespace boost
63 {
64 
65 
66 //  Forward declarations  ----------------------------------------------------//
67 
68 //! Bit-wise CRC computer
69 template < std::size_t Bits >
70     class crc_basic;
71 
72 //! Table-driven CRC computer, usable as a function object
73 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly = 0u,
74            BOOST_CRC_PARM_TYPE InitRem = 0u,
75            BOOST_CRC_PARM_TYPE FinalXor = 0u, bool ReflectIn = false,
76            bool ReflectRem = false >
77     class crc_optimal;
78 
79 //! Compute the (unaugmented) CRC of a memory block
80 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
81            BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
82            bool ReflectIn, bool ReflectRem >
83     typename uint_t<Bits>::fast  crc( void const *buffer,
84      std::size_t byte_count);
85 
86 //! Compute the CRC of a memory block, with any augmentation provided by user
87 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly >
88     typename uint_t<Bits>::fast  augmented_crc( void const *buffer,
89      std::size_t byte_count,
90      typename uint_t<Bits>::fast initial_remainder = 0u);
91 
92 //! Computation type for ARC|CRC-16|CRC-IBM|CRC-16/ARC|CRC-16/LHA standard
93 typedef crc_optimal<16, 0x8005, 0, 0, true, true>         crc_16_type;
94 //! Computation type for CRC-16/CCITT-FALSE standard
95 typedef crc_optimal<16, 0x1021, 0xFFFF, 0, false, false>  crc_ccitt_false_t;
96 //! Computation type for the CRC mistakenly called the CCITT standard
97 typedef crc_ccitt_false_t                                 crc_ccitt_type;
98 //! Computation type for the actual
99 //! KERMIT|CRC-16/CCITT|CRC-16/CCITT-TRUE|CRC-CCITT standard
100 typedef crc_optimal<16, 0x1021, 0, 0, true, true>         crc_ccitt_true_t;
101 //! Computation type that I mistakenly called the XMODEM standard; it inverts
102 //! both reflection parameters and reflects the truncated divisor (Don't use?!)
103 typedef crc_optimal<16, 0x8408, 0, 0, true, true>         crc_xmodem_type;
104 //! Computation type for the actual XMODEM|ZMODEM|CRC-16/ACORN standard
105 typedef crc_optimal<16, 0x1021, 0, 0, false, false>       crc_xmodem_t;
106 
107 //! Computation type for CRC-32|CRC-32/ADCCP|PKZIP standard
108 typedef crc_optimal<32, 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, true, true>
109   crc_32_type;
110 
111 
112 //  Forward declarations for implementation detail stuff  --------------------//
113 //  (Just for the stuff that will be needed for the next two sections)
114 
115 //! \cond
116 namespace detail
117 {
118     //! Mix-in class to add a possibly-reflecting member function
119     template < int BitLength, bool DoIt, int Id = 0 >
120         class possible_reflector;
121 
122     //! Mix-in class for byte-fed, table-driven CRC algorithms
123     template < int Order, boost::uintmax_t TruncatedPolynomial, bool Reflect,
124      int Id = 0 >
125     class crc_driver;
126 
127 }  // namespace detail
128 //! \endcond
129 
130 
131 //  Simple cyclic redundancy code (CRC) class declaration  -------------------//
132 
133 /** Objects of this type compute the CRC checksum of submitted data, where said
134     data can be entered piecemeal through several different kinds of groupings.
135     Modulo-2 polynomial division steps are always performed bit-wise, without
136     the use of pre-computation tables.  Said division uses the altered
137     algorithm, so any data has to be unaugmented.
138 
139     \pre  0 \< \a Bits \<= \c std\::numeric_limits\<uintmax_t\>\::digits
140 
141     \tparam Bits  The order of the modulo-2 polynomial divisor.  (\e Width from
142       the RMCA)
143  */
144 template < std::size_t Bits >
145 class crc_basic
146 {
147 public:
148     // Type
149     /** \brief  The register type used for computations
150 
151         This type is used for CRC calculations and is the type for any returned
152         checksums and returned or submitted remainders, (truncated) divisors, or
153         XOR masks.  It is a built-in unsigned integer type.
154      */
155     typedef typename boost::uint_t<Bits>::fast  value_type;
156 
157     // Constant for the template parameter
158     //! A copy of \a Bits provided for meta-programming purposes
159     BOOST_STATIC_CONSTANT( std::size_t, bit_count = Bits );
160 
161     // Constructor (use the automatic copy-ctr, move-ctr, and dtr)
162     //! Create a computer, separately listing each needed parameter
163     explicit  crc_basic( value_type truncated_polynomial,
164                value_type initial_remainder = 0, value_type final_xor_value = 0,
165                bool reflect_input = false, bool reflect_remainder = false );
166 
167     // Internal Operations
168     //! Return the (truncated) polynomial divisor
169     value_type  get_truncated_polynominal() const;
170     //! Return what the polynomial remainder was set to during construction
171     value_type  get_initial_remainder() const;
172     //! Return the XOR-mask used during output processing
173     value_type  get_final_xor_value() const;
174     //! Check if input-bytes will be reflected before processing
175     bool        get_reflect_input() const;
176     //! Check if the remainder will be reflected during output processing
177     bool        get_reflect_remainder() const;
178 
179     //! Return the remainder based from already-processed bits
180     value_type  get_interim_remainder() const;
181     //! Change the interim remainder to a new value
182     void        reset( value_type new_rem );
183     //! Change the interim remainder back to the initial value
184     void        reset();
185 
186     // External Operations
187     //! Submit a single bit for input processing
188     void  process_bit( bool bit );
189     //! Submit the lowest \a bit_length bits of a byte for input processing
190     void  process_bits( unsigned char bits, std::size_t bit_length );
191     //! Submit a single byte for input processing
192     void  process_byte( unsigned char byte );
193     //! Submit a memory block for input processing, iterator-pair style
194     void  process_block( void const *bytes_begin, void const *bytes_end );
195     //! Submit a memory block for input processing, pointer-and-size style
196     void  process_bytes( void const *buffer, std::size_t byte_count );
197 
198     //! Return the checksum of the already-processed bits
199     value_type  checksum() const;
200 
201 private:
202     // Member data
203     value_type  rem_;
204     value_type  poly_, init_, final_;  // non-const to allow assignability
205     bool        rft_in_, rft_out_;     // non-const to allow assignability
206 
207 };  // boost::crc_basic
208 
209 
210 //  Optimized cyclic redundancy code (CRC) class declaration  ----------------//
211 
212 /** Objects of this type compute the CRC checksum of submitted data, where said
213     data can be entered piecemeal through several different kinds of groupings.
214     Modulo-2 polynomial division steps are performed byte-wise, aided by the use
215     of pre-computation tables.  Said division uses the altered algorithm, so any
216     data has to be unaugmented.
217 
218     \pre  0 \< \a Bits \<= \c std\::numeric_limits\<uintmax_t\>\::digits
219 
220     \tparam Bits  The order of the modulo-2 polynomial divisor.  (\e Width from
221       the RMCA)
222     \tparam TruncPoly  The lowest coefficients of the divisor polynomial.  The
223       highest-order coefficient is omitted and always assumed to be 1.  Defaults
224       to \c 0, i.e. the only non-zero term is the implicit one for
225       x<sup><var>Bits</var></sup>.  (\e Poly from the RMCA)
226     \tparam InitRem  The (unaugmented) initial state of the polynomial
227       remainder.  Defaults to \c 0 if omitted.  (\e Init from the RMCA)
228     \tparam FinalXor  The (XOR) bit-mask to be applied to the output remainder,
229       after possible reflection but before returning.  Defaults to \c 0 (i.e. no
230       bit changes) if omitted.  (\e XorOut from the RMCA)
231     \tparam ReflectIn  If \c true, input bytes are read lowest-order bit first,
232       otherwise highest-order bit first.  Defaults to \c false if omitted.
233       (\e RefIn from the RMCA)
234     \tparam ReflectRem  If \c true, the output remainder is reflected before the
235       XOR-mask.  Defaults to \c false if omitted.  (\e RefOut from the RMCA)
236 
237     \todo  Get rid of the default value for \a TruncPoly.  Choosing a divisor is
238       an important decision with many factors, so a default is never useful,
239       especially a bad one.
240  */
241 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
242            BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
243            bool ReflectIn, bool ReflectRem >
244 class crc_optimal
245 {
246 public:
247     // Type
248     //! \copydoc  boost::crc_basic::value_type
249     typedef typename boost::uint_t<Bits>::fast  value_type;
250 
251     // Constants for the template parameters
252     //! \copydoc  boost::crc_basic::bit_count
253     BOOST_STATIC_CONSTANT( std::size_t, bit_count = Bits );
254     //! A copy of \a TruncPoly provided for meta-programming purposes
255     BOOST_STATIC_CONSTANT( value_type, truncated_polynominal = TruncPoly );
256     //! A copy of \a InitRem provided for meta-programming purposes
257     BOOST_STATIC_CONSTANT( value_type, initial_remainder = InitRem );
258     //! A copy of \a FinalXor provided for meta-programming purposes
259     BOOST_STATIC_CONSTANT( value_type, final_xor_value = FinalXor );
260     //! A copy of \a ReflectIn provided for meta-programming purposes
261     BOOST_STATIC_CONSTANT( bool, reflect_input = ReflectIn );
262     //! A copy of \a ReflectRem provided for meta-programming purposes
263     BOOST_STATIC_CONSTANT( bool, reflect_remainder = ReflectRem );
264 
265     // Constructor (use the automatic copy-ctr, move-ctr, and dtr)
266     //! Create a computer, giving an initial remainder if desired
267     explicit  crc_optimal( value_type init_rem = initial_remainder );
268 
269     // Internal Operations
270     //! \copybrief  boost::crc_basic::get_truncated_polynominal
271     value_type  get_truncated_polynominal() const;
272     //! \copybrief  boost::crc_basic::get_initial_remainder
273     value_type  get_initial_remainder() const;
274     //! \copybrief  boost::crc_basic::get_final_xor_value
275     value_type  get_final_xor_value() const;
276     //! \copybrief  boost::crc_basic::get_reflect_input
277     bool        get_reflect_input() const;
278     //! \copybrief  boost::crc_basic::get_reflect_remainder
279     bool        get_reflect_remainder() const;
280 
281     //! \copybrief  boost::crc_basic::get_interim_remainder
282     value_type  get_interim_remainder() const;
283     //! Change the interim remainder to either a given value or the initial one
284     void        reset( value_type new_rem = initial_remainder );
285 
286     // External Operations
287     //! \copybrief  boost::crc_basic::process_byte
288     void  process_byte( unsigned char byte );
289     //! \copybrief  boost::crc_basic::process_block
290     void  process_block( void const *bytes_begin, void const *bytes_end );
291     //! \copybrief  boost::crc_basic::process_bytes
292     void  process_bytes( void const *buffer, std::size_t byte_count );
293 
294     //! \copybrief  boost::crc_basic::checksum
295     value_type  checksum() const;
296 
297     // Operators
298     //! Submit a single byte for input processing, suitable for the STL
299     void        operator ()( unsigned char byte );
300     //! Return the checksum of the already-processed bits, suitable for the STL
301     value_type  operator ()() const;
302 
303 private:
304     // Implementation types
305     // (Processing for reflected input gives reflected remainders, so you only
306     // have to apply output-reflection if Reflect-Remainder doesn't match
307     // Reflect-Input.)
308     typedef detail::possible_reflector<Bits, ReflectIn>     reflect_i_type;
309     typedef detail::crc_driver<Bits, TruncPoly, ReflectIn>  crc_table_type;
310     typedef detail::possible_reflector<Bits, ReflectRem != ReflectIn>
311       reflect_o_type;
312 
313     // Member data
314     value_type  rem_;
315 
316 };  // boost::crc_optimal
317 
318 
319 //  Implementation detail stuff  ---------------------------------------------//
320 
321 //! \cond
322 namespace detail
323 {
324     /** \brief  Meta-programming integral constant for a single-bit bit-mask
325 
326         Generates a compile-time constant for a bit-mask that affects a single
327         bit.  The \c value will be 2<sup><var>BitIndex</var></sup>.  The \c type
328         will be the smallest built-in unsigned integer type that can contain the
329         value, unless there's a built-in type that the system can handle easier,
330         then the \c type will be smallest fast-handled unsigned integer type.
331 
332         \pre  0 \<= BitIndex \< \c std\::numeric_limits\<uintmax_t\>\::digits
333 
334         \tparam BitIndex  The place of the sole set bit.
335      */
336     template < int BitIndex >
337     struct high_bit_mask_c
338         : boost::integral_constant<typename boost::uint_t< BitIndex + 1 >::fast,
339            ( UINTMAX_C(1) << BitIndex )>
340     {};
341 
342     /** \brief  Meta-programming integral constant for a lowest-bits bit-mask
343 
344         Generates a compile-time constant for a bit-mask that affects the lowest
345         bits.  The \c value will be 2<sup><var>BitCount</var></sup> - 1.  The
346         \c type will be the smallest built-in unsigned integer type that can
347         contain the value, unless there's a built-in type that the system can
348         handle easier, then the \c type will be smallest fast-handled unsigned
349         integer type.
350 
351         \pre  0 \<= BitCount \<= \c std\::numeric_limits\<uintmax_t\>\::digits
352 
353         \tparam BitCount  The number of lowest-placed bits set.
354      */
355     template < int BitCount >
356     struct low_bits_mask_c
357         : boost::integral_constant<typename boost::uint_t< BitCount >::fast, (
358            BitCount ? (( (( UINTMAX_C(1) << (BitCount - 1) ) - 1u) << 1 ) |
359            UINTMAX_C( 1 )) : 0u )>
360     {};
361 
362     /** \brief  Reflects the bits of a number
363 
364         Reverses the order of the given number of bits within a value.  For
365         instance, if the given reflect count is 5, then the bit values for the
366         16- and 1-place will switch and the 8- and 2-place will switch, leaving
367         the other bits alone.  (The 4-place bit is in the middle, so it wouldn't
368         change.)
369 
370         \pre  \a Unsigned is a built-in unsigned integer type
371         \pre  0 \< word_length \<= \c std\::numeric_limits\<Unsigned\>\::digits
372 
373         \tparam Unsigned  The type of \a x.
374 
375         \param x  The value to be (partially) reflected.
376         \param word_length  The number of low-order bits to reflect.  Defaults
377           to the total number of value bits in \a Unsigned.
378 
379         \return  The (partially) reflected value.
380 
381         \todo  Check if this is the fastest way.
382      */
383     template < typename Unsigned >
reflect_unsigned(Unsigned x,int word_length=std::numeric_limits<Unsigned>::digits)384     Unsigned  reflect_unsigned( Unsigned x, int word_length
385      = std::numeric_limits<Unsigned>::digits )
386     {
387         for ( Unsigned  l = 1u, h = l << (word_length - 1) ; h > l ; h >>= 1, l
388          <<= 1 )
389         {
390             Unsigned const  m = h | l, t = x & m;
391 
392             if ( (t == h) || (t == l) )
393                 x ^= m;
394         }
395 
396         return x;
397     }
398 
399     /** \brief  Make a byte-to-byte-reflection map
400 
401         Creates a mapping array so the results can be cached.  Uses
402         #reflect_unsigned to generate the element values.
403 
404         \return  An array <var>a</var> such that, for a given byte value
405           <var>i</var>, <code><var>a</var>[ <var>i</var> ]</code> resolves to
406           the reflected value of <var>i</var>.
407      */
408     boost::array< unsigned char, (UINTMAX_C( 1 ) << CHAR_BIT) >
make_byte_reflection_table()409     inline make_byte_reflection_table()
410     {
411         boost::array<unsigned char, ( UINTMAX_C(1) << CHAR_BIT )>  result;
412         unsigned char                                              i = 0u;
413 
414         do
415             result[ i ] = reflect_unsigned( i );
416         while ( ++i );
417         return result;
418     }
419 
420     /** \brief  Reflects the bits of a single byte
421 
422         Reverses the order of all the bits within a value.  For instance, the
423         bit values for the 2<sup><code>CHAR_BIT</code> - 1</sup>- and 1-place
424         will switch and the 2<sup><code>CHAR_BIT</code> - 2</sup>- and 2-place
425         will switch, etc.
426 
427         \param x  The byte value to be reflected.
428 
429         \return  The reflected value.
430 
431         \note  Since this could be the most common type of reflection, and the
432           number of states is relatively small, the implementation pre-computes
433           and uses a table of all the results.
434      */
reflect_byte(unsigned char x)435     inline unsigned char  reflect_byte( unsigned char x )
436     {
437         static  boost::array<unsigned char, ( UINTMAX_C(1) << CHAR_BIT )> const
438           table = make_byte_reflection_table();
439 
440         return table[ x ];
441     }
442 
443     /** \brief  Reflects some bits within a single byte
444 
445         Like #reflect_unsigned, except it takes advantage of any (long-term)
446         speed gains #reflect_byte may bring.
447 
448         \pre  0 \< \a word_length \<= \c CHAR_BIT
449 
450         \param x  The value to be (partially) reflected.
451         \param word_length  The number of low-order bits to reflect.
452 
453         \return  The (partially) reflected value.
454      */
reflect_sub_byte(unsigned char x,int word_length)455     inline  unsigned char  reflect_sub_byte( unsigned char x, int word_length )
456     { return reflect_byte(x) >> (CHAR_BIT - word_length); }
457 
458     /** \brief  Possibly reflects the bits of a number
459 
460         Reverses the order of the given number of bits within a value.  For
461         instance, if the given reflect count is 5, then the bit values for the
462         16- and 1-place will switch and the 8- and 2-place will switch, leaving
463         the other bits alone.  (The 4-place bit is in the middle, so it wouldn't
464         change.)  This variant function allows the reflection be controlled by
465         an extra parameter, in case the decision to use reflection is made at
466         run-time.
467 
468         \pre  \a Unsigned is a built-in unsigned integer type
469         \pre  0 \< word_length \<= \c std\::numeric_limits\<Unsigned\>\::digits
470 
471         \tparam Unsigned  The type of \a x.
472 
473         \param x  The value to be (partially) reflected.
474         \param reflect  Controls whether \a x is actually reflected (\c true) or
475           left alone (\c false).
476         \param word_length  The number of low-order bits to reflect.  Defaults
477           to the total number of value bits in \a Unsigned.
478 
479         \return  The possibly (partially) reflected value.
480      */
481     template < typename Unsigned >
482     inline
reflect_optionally(Unsigned x,bool reflect,int word_length=std::numeric_limits<Unsigned>::digits)483     Unsigned  reflect_optionally( Unsigned x, bool reflect, int word_length
484      = std::numeric_limits<Unsigned>::digits )
485     { return reflect ? reflect_unsigned(x, word_length) : x; }
486 
487     /** \brief  Possibly reflects the bits of a single byte
488 
489         Uses #reflect_byte (if \a reflect is \c true).
490 
491         \param x  The byte value to be (possibly) reflected.
492         \param reflect  Whether (\c true) or not (\c false) \a x is reflected.
493 
494         \return  <code><var>reflect</var> ? reflect_byte(<var>x</var>) :
495           <var>x</var></code>
496      */
497     inline
reflect_byte_optionally(unsigned char x,bool reflect)498     unsigned char  reflect_byte_optionally( unsigned char x, bool reflect )
499     { return reflect ? reflect_byte(x) : x; }
500 
501     /** \brief  Update a CRC remainder by several bits, assuming a non-augmented
502           message
503 
504         Performs several steps of division required by the CRC algorithm, giving
505         a new remainder polynomial based on the divisor polynomial and the
506         synthesized dividend polynomial (from the old remainder and the
507         newly-provided input).  The computations assume that the CRC is directly
508         exposed from the remainder, without any zero-valued bits augmented to
509         the message bits.
510 
511         \pre  \a Register and \a Word are both built-in unsigned integer types
512         \pre  0 \< \a register_length \<= std\::numeric_limits\<\a Register\>
513           \::digits
514         \pre  0 \< \a word_length \<= std\::numeric_limits\<\a Word\>\::digits
515 
516         \tparam Register  The type used for representing the remainder and
517           divisor modulo-2 polynomials.  The bit at <code>2<sup>i</sup></code>
518           is used as the coefficient of <i>x<sup>i</sup></i>.
519         \tparam Word  The type used for storing the incoming terms of the
520           dividend modulo-2 polynomial.  The bit at <code>2<sup>i</sup></code>
521           is used as the coefficient of <i>x<sup>i</sup></i> when \a reflect is
522           \c false, and the coefficient of <i>x<sup><var>word_length</var> - 1 -
523           i</sup></i> otherwise.
524 
525         \param[in]     register_length  The number of significant low-order bits
526           to be used from \a Register values.  It is the order of the modulo-2
527           polynomial remainder and one less than the divisor's order.
528         \param[in,out] remainder  The upper part of the dividend polynomial
529           before division, and the remainder polynomial after.
530         \param[in]     new_dividend_bits  The coefficients for the next
531           \a word_length lowest terms of the dividend polynomial.
532         \param[in]     truncated_divisor  The lowest coefficients of the divisor
533           polynomial.  The highest-order coefficient is omitted and always
534           assumed to be 1.
535         \param[in]     word_length  The number of lowest-order bits to read from
536           \a new_dividend_bits.
537         \param[in]     reflect  If \c false, read from the highest-order marked
538           bit from \a new_dividend_bits and go down, as normal.  Otherwise,
539           proceed from the lowest-order bit and go up.
540 
541         \note  This routine performs a modulo-2 polynomial division variant.
542           The exclusive-or operations are applied in a different order, since
543           that kind of operation is commutative and associative.  It also
544           assumes that the zero-valued augment string was applied before this
545           step, which means that the updated remainder can be directly used as
546           the final CRC.
547      */
548     template < typename Register, typename Word >
crc_modulo_word_update(int register_length,Register & remainder,Word new_dividend_bits,Register truncated_divisor,int word_length,bool reflect)549     void  crc_modulo_word_update( int register_length, Register &remainder, Word
550      new_dividend_bits, Register truncated_divisor, int word_length, bool
551      reflect )
552     {
553         // Create this masking constant outside the loop.
554         Register const  high_bit_mask = UINTMAX_C(1) << (register_length - 1);
555 
556         // The natural reading order for division is highest digit/bit first.
557         // The "reflect" parameter switches this.  However, building a bit mask
558         // for the lowest bit is the easiest....
559         new_dividend_bits = reflect_optionally( new_dividend_bits, !reflect,
560          word_length );
561 
562         // Perform modulo-2 division for each new dividend input bit
563         for ( int  i = word_length ; i ; --i, new_dividend_bits >>= 1 )
564         {
565             // compare the new bit with the remainder's highest
566             remainder ^= ( new_dividend_bits & 1u ) ? high_bit_mask : 0u;
567 
568             // perform modulo-2 division
569             bool const  quotient = remainder & high_bit_mask;
570 
571             remainder <<= 1;
572             remainder ^= quotient ? truncated_divisor : 0u;
573 
574             // The quotient isn't used for anything, so don't keep it.
575         }
576     }
577 
578     /** \brief  Update a CRC remainder by a single bit, assuming a non-augmented
579           message
580 
581         Performs the next step of division required by the CRC algorithm, giving
582         a new remainder polynomial based on the divisor polynomial and the
583         synthesized dividend polynomial (from the old remainder and the
584         newly-provided input).  The computations assume that the CRC is directly
585         exposed from the remainder, without any zero-valued bits augmented to
586         the message bits.
587 
588         \pre  \a Register is a built-in unsigned integer type
589         \pre  0 \< \a register_length \<= std\::numeric_limits\<\a Register\>
590           \::digits
591 
592         \tparam Register  The type used for representing the remainder and
593           divisor modulo-2 polynomials.  The bit at <code>2<sup>i</sup></code>
594           is used as the coefficient of <i>x<sup>i</sup></i>.
595 
596         \param[in]     register_length  The number of significant low-order bits
597           to be used from \a Register values.  It is the order of the modulo-2
598           polynomial remainder and one less than the divisor's order.
599         \param[in,out] remainder  The upper part of the dividend polynomial
600           before division, and the remainder polynomial after.
601         \param[in]     new_dividend_bit  The coefficient for the constant term
602           of the dividend polynomial.
603         \param[in]     truncated_divisor  The lowest coefficients of the divisor
604           polynomial.  The highest-order coefficient is omitted and always
605           assumed to be 1.
606 
607         \note  This routine performs a modulo-2 polynomial division variant.
608           The exclusive-or operations are applied in a different order, since
609           that kind of operation is commutative and associative.  It also
610           assumes that the zero-valued augment string was applied before this
611           step, which means that the updated remainder can be directly used as
612           the final CRC.
613      */
614     template < typename Register >
crc_modulo_update(int register_length,Register & remainder,bool new_dividend_bit,Register truncated_divisor)615     inline  void  crc_modulo_update( int register_length, Register &remainder,
616      bool new_dividend_bit, Register truncated_divisor )
617     {
618         crc_modulo_word_update( register_length, remainder,
619          static_cast<unsigned>(new_dividend_bit), truncated_divisor, 1, false );
620     }
621 
622     /** \brief  Update a CRC remainder by several bits, assuming an augmented
623           message
624 
625         Performs several steps of division required by the CRC algorithm, giving
626         a new remainder polynomial based on the divisor polynomial and the
627         synthesized dividend polynomial (from the old remainder and the
628         newly-provided input).  The computations assume that a zero-valued
629         string of bits will be appended to the message before extracting the
630         CRC.
631 
632         \pre  \a Register and \a Word are both built-in unsigned integer types
633         \pre  0 \< \a register_length \<= std\::numeric_limits\<\a Register\>
634           \::digits
635         \pre  0 \< \a word_length \<= std\::numeric_limits\<\a Word\>\::digits
636 
637         \tparam Register  The type used for representing the remainder and
638           divisor modulo-2 polynomials.  The bit at <code>2<sup>i</sup></code>
639           is used as the coefficient of <i>x<sup>i</sup></i>.
640         \tparam Word  The type used for storing the incoming terms of the
641           dividend modulo-2 polynomial.  The bit at <code>2<sup>i</sup></code>
642           is used as the coefficient of <i>x<sup>i</sup></i> when \a reflect is
643           \c false, and the coefficient of <i>x<sup><var>word_length</var> - 1 -
644           i</sup></i> otherwise.
645 
646         \param[in]     register_length  The number of significant low-order bits
647           to be used from \a Register values.  It is the order of the modulo-2
648           polynomial remainder and one less than the divisor's order.
649         \param[in,out] remainder  The upper part of the dividend polynomial
650           before division, and the remainder polynomial after.
651         \param[in]     new_dividend_bits  The coefficients for the next
652           \a word_length lowest terms of the dividend polynomial.
653         \param[in]     truncated_divisor  The lowest coefficients of the divisor
654           polynomial.  The highest-order coefficient is omitted and always
655           assumed to be 1.
656         \param[in]     word_length  The number of lowest-order bits to read from
657           \a new_dividend_bits.
658         \param[in]     reflect  If \c false, read from the highest-order marked
659           bit from \a new_dividend_bits and go down, as normal.  Otherwise,
660           proceed from the lowest-order bit and go up.
661 
662         \note  This routine performs straight-forward modulo-2 polynomial
663           division.  It assumes that an augment string will be processed at the
664           end of the message bits before doing CRC analysis.
665         \todo  Use this function somewhere so I can test it.
666      */
667     template < typename Register, typename Word >
augmented_crc_modulo_word_update(int register_length,Register & remainder,Word new_dividend_bits,Register truncated_divisor,int word_length,bool reflect)668     void  augmented_crc_modulo_word_update( int register_length, Register
669      &remainder, Word new_dividend_bits, Register truncated_divisor, int
670      word_length, bool reflect )
671     {
672         // Create this masking constant outside the loop.
673         Register const  high_bit_mask = UINTMAX_C(1) << (register_length - 1);
674 
675         // The natural reading order for division is highest digit/bit first.
676         // The "reflect" parameter switches this.  However, building a bit mask
677         // for the lowest bit is the easiest....
678         new_dividend_bits = reflect_optionally( new_dividend_bits, not reflect,
679          word_length );
680 
681         // Perform modulo-2 division for each new dividend input bit
682         for ( int  i = word_length ; i ; --i, new_dividend_bits >>= 1 )
683         {
684             bool const  quotient = remainder & high_bit_mask;
685 
686             remainder <<= 1;
687             remainder |= new_dividend_bits & 1u;
688             remainder ^= quotient ? truncated_divisor : 0u;
689 
690             // The quotient isn't used for anything, so don't keep it.
691         }
692     }
693 
694     /** \brief  Update a CRC remainder by a single bit, assuming an augmented
695           message
696 
697         Performs the next step of division required by the CRC algorithm, giving
698         a new remainder polynomial based on the divisor polynomial and the
699         synthesized dividend polynomial (from the old remainder and the
700         newly-provided input).  The computations assume that a zero-valued
701         string of bits will be appended to the message before extracting the
702         CRC.
703 
704         \pre  \a Register is a built-in unsigned integer type
705         \pre  0 \< \a register_length \<= std\::numeric_limits\<\a Register\>
706           \::digits
707 
708         \tparam Register  The type used for representing the remainder and
709           divisor modulo-2 polynomials.  The bit at <code>2<sup>i</sup></code>
710           is used as the coefficient of <i>x<sup>i</sup></i>.
711 
712         \param[in]     register_length  The number of significant low-order bits
713           to be used from \a Register values.  It is the order of the modulo-2
714           polynomial remainder and one less than the divisor's order.
715         \param[in,out] remainder  The upper part of the dividend polynomial
716           before division, and the remainder polynomial after.
717         \param[in]     new_dividend_bit  The coefficient for the constant term
718           of the dividend polynomial.
719         \param[in]     truncated_divisor  The lowest coefficients of the divisor
720           polynomial.  The highest-order coefficient is omitted and always
721           assumed to be 1.
722 
723         \note  This routine performs straight-forward modulo-2 polynomial
724           division.  It assumes that an augment string will be processed at the
725           end of the message bits before doing CRC analysis.
726         \todo  Use this function somewhere so I can test it.
727      */
728     template < typename Register >
augmented_crc_modulo_update(int register_length,Register & remainder,bool new_dividend_bit,Register truncated_divisor)729     inline  void  augmented_crc_modulo_update( int register_length, Register
730      &remainder, bool new_dividend_bit, Register truncated_divisor )
731     {
732         augmented_crc_modulo_word_update( register_length, remainder,
733          static_cast<unsigned>(new_dividend_bit), truncated_divisor, 1, false );
734     }
735 
736     /** \brief  A mix-in class that returns its argument
737 
738         This class template makes a function object that returns its argument
739         as-is.  It's one case for #possible_reflector.
740 
741         \pre  0 \< \a BitLength \<= \c std\::numeric_limits\<uintmax_t\>
742           \::digits
743 
744         \tparam BitLength  How many significant bits arguments have.
745      */
746     template < int BitLength >
747     class non_reflector
748     {
749     public:
750         /** \brief  The type to check for specialization
751 
752             This is a Boost integral constant indicating that this class
753             does not reflect its input values.
754          */
755         typedef boost::false_type                 is_reflecting_type;
756         /** \brief  The type to check for register bit length
757 
758             This is a Boost integral constant indicating how many
759             significant bits won't actually be reflected.
760          */
761         typedef boost::integral_constant< int, BitLength >      width_c;
762         /** \brief  The type of (not-)reflected values
763 
764             This type is the input and output type for the (possible-)
765             reflection function, which does nothing here.
766          */
767         typedef typename boost::uint_t< BitLength >::fast  value_type;
768 
769         /** \brief  Does nothing
770 
771             Returns the given value, not reflecting any part of it.
772 
773             \param x  The value to not be reflected.
774 
775             \return  \a x
776          */
reflect_q(value_type x)777         inline  static  value_type  reflect_q( value_type x )
778         { return x; }
779     };
780 
781     /** \brief  A mix-in class that reflects (the lower part of) its argument,
782           generally for types larger than a byte
783 
784         This class template makes a function object that returns its argument
785         after reflecting its lower-order bits.  It's one sub-case for
786         #possible_reflector.
787 
788         \pre  \c CHAR_BIT \< \a BitLength \<= \c std\::numeric_limits\<uintmax_t
789           \>\::digits
790 
791         \tparam BitLength  How many significant bits arguments have.
792      */
793     template < int BitLength >
794     class super_byte_reflector
795     {
796     public:
797         /** \brief  The type to check for specialization
798 
799             This is a Boost integral constant indicating that this class
800             does reflect its input values.
801          */
802         typedef boost::true_type                  is_reflecting_type;
803         /** \brief  The type to check for register bit length
804 
805             This is a Boost integral constant indicating how many
806             significant bits will be reflected.
807          */
808         typedef boost::integral_constant< int, BitLength >      width_c;
809         /** \brief  The type of reflected values
810 
811             This is both the input and output type for the reflection function.
812          */
813         typedef typename boost::uint_t< BitLength >::fast  value_type;
814 
815         /** \brief  Reflect (part of) the given value
816 
817             Reverses the order of the given number of bits within a value,
818             using #reflect_unsigned.
819 
820             \param x  The value to be (partially) reflected.
821 
822             \return  ( <var>x</var> &amp;
823               ~(2<sup><var>width_c</var>\::value</sup> - 1) ) | REFLECT(
824               <var>x</var> &amp; (2<sup><var>width_c</var>\::value</sup> -
825               1) )
826          */
reflect_q(value_type x)827         inline  static  value_type  reflect_q( value_type x )
828         { return reflect_unsigned(x, width_c::value); }
829     };
830 
831     /** \brief  A mix-in class that reflects (the lower part of) its argument,
832           generally for bytes
833 
834         This class template makes a function object that returns its argument
835         after reflecting its lower-order bits.  It's one sub-case for
836         #possible_reflector.
837 
838         \pre  0 \< \a BitLength \<= \c CHAR_BIT
839 
840         \tparam BitLength  How many significant bits arguments have.
841      */
842     template < int BitLength >
843     class sub_type_reflector
844     {
845     public:
846         /** \brief  The type to check for specialization
847 
848             This is a Boost integral constant indicating that this class
849             does reflect its input values.
850          */
851         typedef boost::true_type              is_reflecting_type;
852         /** \brief  The type to check for register bit length
853 
854             This is a Boost integral constant indicating how many
855             significant bits will be reflected.
856          */
857         typedef boost::integral_constant< int, BitLength >  width_c;
858         /** \brief  The type of reflected values
859 
860             This is both the input and output type for the reflection function.
861          */
862         typedef unsigned char                          value_type;
863 
864         /** \brief  Reflect (part of) the given value
865 
866             Reverses the order of the given number of bits within a value,
867             using #reflect_sub_byte.
868 
869             \param x  The value to be (partially) reflected.
870 
871             \return  ( <var>x</var> &amp;
872               ~(2<sup><var>width_c</var>\::value</sup> - 1) ) | REFLECT(
873               <var>x</var> &amp; (2<sup><var>width_c</var>\::value</sup> -
874               1) )
875          */
reflect_q(value_type x)876         inline  static  value_type  reflect_q( value_type x )
877         { return reflect_sub_byte(x, width_c::value); }
878     };
879 
880     /** \brief  A mix-in class that reflects (the lower part of) its argument
881 
882         This class template makes a function object that returns its argument
883         after reflecting its lower-order bits.  It's one case for
884         #possible_reflector.
885 
886         \pre  0 \< \a BitLength \<= \c std\::numeric_limits\<uintmax_t\>
887           \::digits
888 
889         \tparam BitLength  How many significant bits arguments have.
890      */
891     template < int BitLength >
892     class reflector
893         : public boost::conditional< (BitLength > CHAR_BIT),
894           super_byte_reflector<BitLength>, sub_type_reflector<BitLength> >::type
895     { };
896 
897     /** This class template adds a member function #reflect_q that will
898         conditionally reflect its first argument, controlled by a compile-time
899         parameter.
900 
901         \pre  0 \< \a BitLength \<= \c std\::numeric_limits\<uintmax_t\>
902           \::digits
903 
904         \tparam BitLength  How many significant bits arguments have.
905         \tparam DoIt  \c true if #reflect_q will reflect, \c false if it should
906           return its argument unchanged.
907         \tparam Id  An extra differentiator if multiple copies of this class
908           template are mixed-in as base classes.  Defaults to 0 if omitted.
909      */
910     template < int BitLength, bool DoIt, int Id >
911     class possible_reflector
912         : public boost::conditional< DoIt, reflector<BitLength>,
913           non_reflector<BitLength> >::type
914     {
915     public:
916         /** \brief  The type to check for ID
917 
918             This is a Boost integral constant indicating what ID number this
919             instantiation used.
920          */
921         typedef boost::integral_constant<int, Id>  id_type;
922     };
923 
924     /** \brief  Find the composite remainder update effect from a fixed bit
925           sequence, for each potential sequence combination.
926 
927         For each value between 0 and 2<sup><var>SubOrder</var></sup> - 1,
928         computes the XOR mask corresponding to the composite effect they update
929         the incoming remainder, which is the upper part of the dividend that
930         gets (partially) pushed out of its register by the incoming value's
931         bits.  The composite value merges the \"partial products\" from each bit
932         of the value being updated individually.
933 
934         \pre  \a Register is a built-in unsigned integer type
935         \pre  0 \< \a SubOrder \<= \a register_length \<=
936           std\::numeric_limits\<\a Register\>\::digits
937 
938         \tparam SubOrder  The number of low-order significant bits of the trial
939           new dividends.
940         \tparam Register  The type used for representing the remainder and
941           divisor modulo-2 polynomials.  The bit at <code>2<sup>i</sup></code>
942           is used as the coefficient of <i>x<sup>i</sup></i>.
943 
944         \param[in] register_length  The number of significant low-order bits
945           to be used from \a Register values.  It is the order of the modulo-2
946           polynomial remainder and one less than the divisor's order.
947         \param[in] truncated_divisor  The lowest coefficients of the divisor
948           polynomial.  The highest-order coefficient is omitted and always
949           assumed to be 1.
950         \param[in] reflect  If \c false, read from the highest-order marked
951           bit from a new dividend's bits and go down, as normal.  Otherwise,
952           proceed from the lowest-order bit and go up.
953 
954         \return  An array such that the element at index <var>i</var> is the
955           composite effect XOR mask for value <var>i</var>.
956 
957         \note  This routine performs a modulo-2 polynomial division variant.
958           The exclusive-or operations are applied in a different order, since
959           that kind of operation is commutative and associative.  It also
960           assumes that the zero-valued augment string was applied before this
961           step, which means that the updated remainder can be directly used as
962           the final CRC.
963         \todo  Check that using the unaugmented-CRC division routines give the
964           same composite mask table as using augmented-CRC routines.
965      */
966     template < int SubOrder, typename Register >
967     boost::array< Register, (UINTMAX_C( 1 ) << SubOrder) >
make_partial_xor_products_table(int register_length,Register truncated_divisor,bool reflect)968     make_partial_xor_products_table( int register_length, Register
969      truncated_divisor, bool reflect )
970     {
971         boost::array<Register, ( UINTMAX_C(1) << SubOrder )>  result;
972 
973         // Loop over every possible dividend value
974         for ( typename boost::uint_t<SubOrder + 1>::fast  dividend = 0u;
975          dividend < result.size() ; ++dividend )
976         {
977             Register  remainder = 0u;
978 
979             crc_modulo_word_update( register_length, remainder, dividend,
980              truncated_divisor, SubOrder, false );
981             result[ reflect_optionally(dividend, reflect, SubOrder) ] =
982              reflect_optionally( remainder, reflect, register_length );
983         }
984         return result;
985     }
986 
987     /** \brief  A mix-in class for the table of table-driven CRC algorithms
988 
989         Encapsulates the parameters need to make a global (technically,
990         class-static) table usuable in CRC algorithms, and generates said
991         table.
992 
993         \pre  0 \< \a SubOrder \<= Order \<=
994           std\::numeric_limits\<uintmax_t\>\::digits
995 
996         \tparam Order  The order of the modulo-2 polynomial remainder and one
997           less than the divisor's order.
998         \tparam SubOrder  The number of low-order significant bits of the trial
999           new dividends.
1000         \tparam TruncatedPolynomial  The lowest coefficients of the divisor
1001           polynomial.  The highest-order coefficient is omitted and always
1002           assumed to be 1.
1003         \tparam Reflect  If \c false, read from the highest-order marked
1004           bit from a new dividend's bits and go down, as normal.  Otherwise,
1005           proceed from the lowest-order bit and go up.
1006      */
1007     template < int Order, int SubOrder, boost::uintmax_t TruncatedPolynomial,
1008      bool Reflect >
1009     class crc_table_t
1010     {
1011     public:
1012         /** \brief  The type to check for register bit length
1013 
1014             This is a Boost integral constant indicating how many
1015             significant bits are in the remainder and (truncated) divisor.
1016          */
1017         typedef boost::integral_constant< int, Order >              width_c;
1018         /** \brief  The type to check for index-unit bit length
1019 
1020             This is a Boost integral constant indicating how many
1021             significant bits are in the trial new dividends.
1022          */
1023         typedef boost::integral_constant< int, SubOrder >      unit_width_c;
1024         /** \brief  The type of registers
1025 
1026             This is the output type for the partial-product map.
1027          */
1028         typedef typename boost::uint_t< Order >::fast          value_type;
1029         /** \brief  The type to check the divisor
1030 
1031             This is a Boost integral constant representing the (truncated)
1032             divisor.
1033          */
1034         typedef boost::integral_constant< value_type, TruncatedPolynomial >
1035           poly_c;
1036         /** \brief  The type to check for reflection
1037 
1038             This is a Boost integral constant representing whether input
1039             units should be read in reverse order.
1040          */
1041         typedef boost::integral_constant< bool, Reflect >           refin_c;
1042         /** \brief  The type to check for map size
1043 
1044             This is a Boost integral constant representing the number of
1045             elements in the partial-product map, based on the unit size.
1046          */
1047         typedef high_bit_mask_c< SubOrder >                  table_size_c;
1048         /** \brief  The type of the unit TO partial-product map
1049 
1050             This is the array type that takes units as the index and said unit's
1051             composite partial-product mask as the element.
1052          */
1053         typedef boost::array<value_type, table_size_c::value>  array_type;
1054         /** \brief  Create a global array for the mapping table
1055 
1056             Creates an instance of a partial-product array with this class's
1057             parameters.
1058 
1059             \return  A reference to a immutable array giving the partial-product
1060               update XOR map for each potential sub-unit value.
1061          */
get_table()1062         static  array_type const &  get_table()
1063         {
1064             static  array_type const  table =
1065              make_partial_xor_products_table<unit_width_c::value>(
1066              width_c::value, poly_c::value, refin_c::value );
1067 
1068             return table;
1069         }
1070     };
1071 
1072     /** \brief  A mix-in class that handles direct (i.e. non-reflected) byte-fed
1073           table-driven CRC algorithms
1074 
1075         This class template adds member functions #augmented_crc_update and
1076         #crc_update to update remainders from new input bytes.  The bytes aren't
1077         reflected before processing.
1078 
1079         \pre  \c CHAR_BIT \<= \a Order \<= \c std\::numeric_limits\<uintmax_t\>
1080           \::digits
1081 
1082         \tparam Order  The order of the modulo-2 polynomial remainder and one
1083           less than the divisor's order.
1084         \tparam TruncatedPolynomial  The lowest coefficients of the divisor
1085           polynomial.  The highest-order coefficient is omitted and always
1086           assumed to be 1.
1087      */
1088     template < int Order, boost::uintmax_t TruncatedPolynomial >
1089     class direct_byte_table_driven_crcs
1090         : public crc_table_t<Order, CHAR_BIT, TruncatedPolynomial, false>
1091     {
1092         typedef crc_table_t<Order, CHAR_BIT, TruncatedPolynomial, false>
1093           base_type;
1094 
1095     public:
1096         typedef typename base_type::value_type  value_type;
1097         typedef typename base_type::array_type  array_type;
1098 
1099         /** \brief  Compute the updated remainder after reading some bytes
1100 
1101             The implementation reads from a table to speed-up applying
1102             augmented-CRC updates byte-wise.
1103 
1104             \param remainder  The pre-update remainder
1105             \param new_dividend_bytes  The address where the new bytes start
1106             \param new_dividend_byte_count  The number of new bytes to read
1107 
1108             \return  The updated remainder
1109          */
augmented_crc_update(value_type remainder,unsigned char const * new_dividend_bytes,std::size_t new_dividend_byte_count)1110         static  value_type  augmented_crc_update( value_type remainder, unsigned
1111          char const *new_dividend_bytes, std::size_t new_dividend_byte_count)
1112         {
1113             static  array_type const &  table = base_type::get_table();
1114 
1115             while ( new_dividend_byte_count-- )
1116             {
1117                 // Locates the merged partial product based on the leading byte
1118                 unsigned char const  index = ( remainder >> (Order - CHAR_BIT) )
1119                  & UCHAR_MAX;
1120 
1121                 // Complete the multi-bit modulo-2 polynomial division
1122                 remainder <<= CHAR_BIT;
1123                 remainder |= *new_dividend_bytes++;
1124                 remainder ^= table.elems[ index ];
1125             }
1126 
1127             return remainder;
1128         }
1129 
1130         /** \brief  Compute the updated remainder after reading some bytes
1131 
1132             The implementation reads from a table to speed-up applying
1133             unaugmented-CRC updates byte-wise.
1134 
1135             \param remainder  The pre-update remainder
1136             \param new_dividend_bytes  The address where the new bytes start
1137             \param new_dividend_byte_count  The number of new bytes to read
1138 
1139             \return  The updated remainder
1140          */
crc_update(value_type remainder,unsigned char const * new_dividend_bytes,std::size_t new_dividend_byte_count)1141         static  value_type  crc_update( value_type remainder, unsigned char
1142          const *new_dividend_bytes, std::size_t new_dividend_byte_count)
1143         {
1144             static  array_type const &  table = base_type::get_table();
1145 
1146             while ( new_dividend_byte_count-- )
1147             {
1148                 // Locates the merged partial product based on comparing the
1149                 // leading and incoming bytes
1150                 unsigned char const  index = ( (remainder >> ( Order - CHAR_BIT
1151                  )) & UCHAR_MAX ) ^ *new_dividend_bytes++;
1152 
1153                 // Complete the multi-bit altered modulo-2 polynomial division
1154                 remainder <<= CHAR_BIT;
1155                 remainder ^= table.elems[ index ];
1156             }
1157 
1158             return remainder;
1159         }
1160     };
1161 
1162     /** \brief  A mix-in class that handles reflected byte-fed, table-driven CRC
1163           algorithms
1164 
1165         This class template adds member functions #augmented_crc_update and
1166         #crc_update to update remainders from new input bytes.  The bytes are
1167         reflected before processing.
1168 
1169         \pre  \c CHAR_BIT \<= \a Order \<= \c std\::numeric_limits\<uintmax_t\>
1170           \::digits
1171 
1172         \tparam Order  The order of the modulo-2 polynomial remainder and one
1173           less than the divisor's order.
1174         \tparam TruncatedPolynomial  The lowest coefficients of the divisor
1175           polynomial.  The highest-order coefficient is omitted and always
1176           assumed to be 1.
1177      */
1178     template < int Order, boost::uintmax_t TruncatedPolynomial >
1179     class reflected_byte_table_driven_crcs
1180         : public crc_table_t<Order, CHAR_BIT, TruncatedPolynomial, true>
1181     {
1182         typedef crc_table_t<Order, CHAR_BIT, TruncatedPolynomial, true>
1183           base_type;
1184 
1185     public:
1186         typedef typename base_type::value_type  value_type;
1187         typedef typename base_type::array_type  array_type;
1188 
1189         /** \brief  Compute the updated remainder after reading some bytes
1190 
1191             The implementation reads from a table to speed-up applying
1192             reflecting augmented-CRC updates byte-wise.
1193 
1194             \param remainder  The pre-update remainder; since the bytes are
1195               being reflected, this remainder also has to be reflected
1196             \param new_dividend_bytes  The address where the new bytes start
1197             \param new_dividend_byte_count  The number of new bytes to read
1198 
1199             \return  The updated, reflected remainder
1200          */
augmented_crc_update(value_type remainder,unsigned char const * new_dividend_bytes,std::size_t new_dividend_byte_count)1201         static  value_type  augmented_crc_update( value_type remainder, unsigned
1202          char const *new_dividend_bytes, std::size_t new_dividend_byte_count)
1203         {
1204             static  array_type const &  table = base_type::get_table();
1205 
1206             while ( new_dividend_byte_count-- )
1207             {
1208                 // Locates the merged partial product based on the leading byte
1209                 // (which is at the low-order end for reflected remainders)
1210                 unsigned char const  index = remainder & UCHAR_MAX;
1211 
1212                 // Complete the multi-bit reflected modulo-2 polynomial division
1213                 remainder >>= CHAR_BIT;
1214                 remainder |= static_cast<value_type>( *new_dividend_bytes++ )
1215                  << ( Order - CHAR_BIT );
1216                 remainder ^= table.elems[ index ];
1217             }
1218 
1219             return remainder;
1220         }
1221 
1222         /** \brief  Compute the updated remainder after reading some bytes
1223 
1224             The implementation reads from a table to speed-up applying
1225             reflected unaugmented-CRC updates byte-wise.
1226 
1227             \param remainder  The pre-update remainder; since the bytes are
1228               being reflected, this remainder also has to be reflected
1229             \param new_dividend_bytes  The address where the new bytes start
1230             \param new_dividend_byte_count  The number of new bytes to read
1231 
1232             \return  The updated, reflected remainder
1233          */
crc_update(value_type remainder,unsigned char const * new_dividend_bytes,std::size_t new_dividend_byte_count)1234         static  value_type  crc_update( value_type remainder, unsigned char
1235          const *new_dividend_bytes, std::size_t new_dividend_byte_count)
1236         {
1237             static  array_type const &  table = base_type::get_table();
1238 
1239             while ( new_dividend_byte_count-- )
1240             {
1241                 // Locates the merged partial product based on comparing the
1242                 // leading and incoming bytes
1243                 unsigned char const  index = ( remainder & UCHAR_MAX ) ^
1244                  *new_dividend_bytes++;
1245 
1246                 // Complete the multi-bit reflected altered modulo-2 polynomial
1247                 // division
1248                 remainder >>= CHAR_BIT;
1249                 remainder ^= table.elems[ index ];
1250             }
1251 
1252             return remainder;
1253         }
1254     };
1255 
1256     /** \brief  Mix-in class for byte-fed, table-driven CRC algorithms with
1257           parameter values at least a byte in width
1258 
1259         This class template adds member functions #augmented_crc_update and
1260         #crc_update to update remainders from new input bytes.  The bytes may be
1261         reflected before processing, controlled by a compile-time parameter.
1262 
1263         \pre  \c CHAR_BIT \<= \a Order \<= \c std\::numeric_limits\<uintmax_t\>
1264           \::digits
1265 
1266         \tparam Order  The order of the modulo-2 polynomial remainder and one
1267           less than the divisor's order.
1268         \tparam TruncatedPolynomial  The lowest coefficients of the divisor
1269           polynomial.  The highest-order coefficient is omitted and always
1270           assumed to be 1.
1271         \tparam Reflect  If \c false, read from the highest-order bit from a new
1272           input byte and go down, as normal.  Otherwise, proceed from the
1273           lowest-order bit and go up.
1274      */
1275     template < int Order, boost::uintmax_t TruncatedPolynomial, bool Reflect >
1276     class byte_table_driven_crcs
1277         : public boost::conditional< Reflect,
1278           reflected_byte_table_driven_crcs<Order, TruncatedPolynomial>,
1279           direct_byte_table_driven_crcs<Order, TruncatedPolynomial> >::type
1280     { };
1281 
1282     /** \brief  A mix-in class that handles direct (i.e. non-reflected) byte-fed
1283           CRC algorithms for sub-byte parameters
1284 
1285         This class template adds member functions #augmented_crc_update and
1286         #crc_update to update remainders from new input bytes.  The bytes aren't
1287         reflected before processing.
1288 
1289         \pre  0 \< \a Order \< \c CHAR_BIT
1290 
1291         \tparam Order  The order of the modulo-2 polynomial remainder and one
1292           less than the divisor's order.
1293         \tparam TruncatedPolynomial  The lowest coefficients of the divisor
1294           polynomial.  The highest-order coefficient is omitted and always
1295           assumed to be 1.
1296      */
1297     template < int Order, boost::uintmax_t TruncatedPolynomial >
1298     class direct_sub_byte_crcs
1299         : public crc_table_t<Order, Order, TruncatedPolynomial, false>
1300     {
1301         typedef crc_table_t<Order, Order, TruncatedPolynomial, false>
1302           base_type;
1303 
1304     public:
1305         typedef typename base_type::width_c     width_c;
1306         typedef typename base_type::value_type  value_type;
1307         typedef typename base_type::poly_c       poly_c;
1308         typedef typename base_type::array_type  array_type;
1309 
1310         /** \brief  Compute the updated remainder after reading some bytes
1311 
1312             The implementation reads from a table to speed-up applying
1313             augmented-CRC updates byte-wise.
1314 
1315             \param remainder  The pre-update remainder
1316             \param new_dividend_bytes  The address where the new bytes start
1317             \param new_dividend_byte_count  The number of new bytes to read
1318 
1319             \return  The updated remainder
1320 
1321             \todo  Use this function somewhere so I can test it.
1322          */
augmented_crc_update(value_type remainder,unsigned char const * new_dividend_bytes,std::size_t new_dividend_byte_count)1323         static  value_type  augmented_crc_update( value_type remainder, unsigned
1324          char const *new_dividend_bytes, std::size_t new_dividend_byte_count)
1325         {
1326             //static  array_type const &  table = base_type::get_table();
1327 
1328             while ( new_dividend_byte_count-- )
1329             {
1330                 // Without a table, process each byte explicitly
1331                 augmented_crc_modulo_word_update( width_c::value, remainder,
1332                  *new_dividend_bytes++, poly_c::value, CHAR_BIT, false );
1333             }
1334 
1335             return remainder;
1336         }
1337 
1338         /** \brief  Compute the updated remainder after reading some bytes
1339 
1340             The implementation reads from a table to speed-up applying
1341             unaugmented-CRC updates byte-wise.
1342 
1343             \param remainder  The pre-update remainder
1344             \param new_dividend_bytes  The address where the new bytes start
1345             \param new_dividend_byte_count  The number of new bytes to read
1346 
1347             \return  The updated remainder
1348          */
crc_update(value_type remainder,unsigned char const * new_dividend_bytes,std::size_t new_dividend_byte_count)1349         static  value_type  crc_update( value_type remainder, unsigned char
1350          const *new_dividend_bytes, std::size_t new_dividend_byte_count)
1351         {
1352             //static  array_type const &  table = base_type::get_table();
1353 
1354             while ( new_dividend_byte_count-- )
1355             {
1356                 // Without a table, process each byte explicitly
1357                 crc_modulo_word_update( width_c::value, remainder,
1358                  *new_dividend_bytes++, poly_c::value, CHAR_BIT, false );
1359             }
1360 
1361             return remainder;
1362         }
1363     };
1364 
1365     /** \brief  A mix-in class that handles reflected byte-fed, CRC algorithms
1366           for sub-byte parameters
1367 
1368         This class template adds member functions #augmented_crc_update and
1369         #crc_update to update remainders from new input bytes.  The bytes are
1370         reflected before processing.
1371 
1372         \pre  0 \< \a Order \< \c CHAR_BIT
1373 
1374         \tparam Order  The order of the modulo-2 polynomial remainder and one
1375           less than the divisor's order.
1376         \tparam TruncatedPolynomial  The lowest coefficients of the divisor
1377           polynomial.  The highest-order coefficient is omitted and always
1378           assumed to be 1.
1379      */
1380     template < int Order, boost::uintmax_t TruncatedPolynomial >
1381     class reflected_sub_byte_crcs
1382         : public crc_table_t<Order, Order, TruncatedPolynomial, true>
1383     {
1384         typedef crc_table_t<Order, Order, TruncatedPolynomial, true>
1385           base_type;
1386 
1387     public:
1388         typedef typename base_type::width_c     width_c;
1389         typedef typename base_type::value_type  value_type;
1390         typedef typename base_type::poly_c       poly_c;
1391         typedef typename base_type::array_type  array_type;
1392 
1393         /** \brief  Compute the updated remainder after reading some bytes
1394 
1395             The implementation reads from a table to speed-up applying
1396             reflecting augmented-CRC updates byte-wise.
1397 
1398             \param remainder  The pre-update remainder; since the bytes are
1399               being reflected, this remainder also has to be reflected
1400             \param new_dividend_bytes  The address where the new bytes start
1401             \param new_dividend_byte_count  The number of new bytes to read
1402 
1403             \return  The updated, reflected remainder
1404 
1405             \todo  Use this function somewhere so I can test it.
1406          */
augmented_crc_update(value_type remainder,unsigned char const * new_dividend_bytes,std::size_t new_dividend_byte_count)1407         static  value_type  augmented_crc_update( value_type remainder, unsigned
1408          char const *new_dividend_bytes, std::size_t new_dividend_byte_count)
1409         {
1410             //static  array_type const &  table = base_type::get_table();
1411 
1412             remainder = reflect_sub_byte( remainder, width_c::value );
1413             while ( new_dividend_byte_count-- )
1414             {
1415                 // Without a table, process each byte explicitly
1416                 augmented_crc_modulo_word_update( width_c::value, remainder,
1417                  *new_dividend_bytes++, poly_c::value, CHAR_BIT, true );
1418             }
1419             remainder = reflect_sub_byte( remainder, width_c::value );
1420 
1421             return remainder;
1422         }
1423 
1424         /** \brief  Compute the updated remainder after reading some bytes
1425 
1426             The implementation reads from a table to speed-up applying
1427             reflected unaugmented-CRC updates byte-wise.
1428 
1429             \param remainder  The pre-update remainder; since the bytes are
1430               being reflected, this remainder also has to be reflected
1431             \param new_dividend_bytes  The address where the new bytes start
1432             \param new_dividend_byte_count  The number of new bytes to read
1433 
1434             \return  The updated, reflected remainder
1435          */
crc_update(value_type remainder,unsigned char const * new_dividend_bytes,std::size_t new_dividend_byte_count)1436         static  value_type  crc_update( value_type remainder, unsigned char
1437          const *new_dividend_bytes, std::size_t new_dividend_byte_count)
1438         {
1439             //static  array_type const &  table = base_type::get_table();
1440 
1441             remainder = reflect_sub_byte( remainder, width_c::value );
1442             while ( new_dividend_byte_count-- )
1443             {
1444                 // Without a table, process each byte explicitly
1445                 crc_modulo_word_update( width_c::value, remainder,
1446                  *new_dividend_bytes++, poly_c::value, CHAR_BIT, true );
1447             }
1448             remainder = reflect_sub_byte( remainder, width_c::value );
1449 
1450             return remainder;
1451         }
1452     };
1453 
1454     /** \brief  Mix-in class for byte-fed, table-driven CRC algorithms with
1455           sub-byte parameters
1456 
1457         This class template adds member functions #augmented_crc_update and
1458         #crc_update to update remainders from new input bytes.  The bytes may be
1459         reflected before processing, controlled by a compile-time parameter.
1460 
1461         \pre  0 \< \a Order \< \c CHAR_BIT
1462 
1463         \tparam Order  The order of the modulo-2 polynomial remainder and one
1464           less than the divisor's order.
1465         \tparam TruncatedPolynomial  The lowest coefficients of the divisor
1466           polynomial.  The highest-order coefficient is omitted and always
1467           assumed to be 1.
1468         \tparam Reflect  If \c false, read from the highest-order bit from a new
1469           input byte and go down, as normal.  Otherwise, proceed from the
1470           lowest-order bit and go up.
1471      */
1472     template < int Order, boost::uintmax_t TruncatedPolynomial, bool Reflect >
1473     class sub_byte_crcs
1474         : public boost::conditional< Reflect,
1475           reflected_sub_byte_crcs<Order, TruncatedPolynomial>,
1476           direct_sub_byte_crcs<Order, TruncatedPolynomial> >::type
1477     { };
1478 
1479     /** This class template adds member functions #augmented_crc_update and
1480         #crc_update to update remainders from new input bytes.  The bytes may be
1481         reflected before processing, controlled by a compile-time parameter.
1482 
1483         \pre  0 \< \a Order \<= \c std\::numeric_limits\<uintmax_t\>\::digits
1484 
1485         \tparam Order  The order of the modulo-2 polynomial remainder and one
1486           less than the divisor's order.
1487         \tparam TruncatedPolynomial  The lowest coefficients of the divisor
1488           polynomial.  The highest-order coefficient is omitted and always
1489           assumed to be 1.
1490         \tparam Reflect  If \c false, read from the highest-order bit from a new
1491           input byte and go down, as normal.  Otherwise, proceed from the
1492           lowest-order bit and go up.
1493         \tparam Id  An extra differentiator if multiple copies of this class
1494           template are mixed-in as base classes.  Defaults to 0 if omitted.
1495      */
1496     template < int Order, boost::uintmax_t TruncatedPolynomial, bool Reflect,
1497      int Id >
1498     class crc_driver
1499         : public boost::conditional< (Order < CHAR_BIT), sub_byte_crcs<Order,
1500           TruncatedPolynomial, Reflect>, byte_table_driven_crcs<Order,
1501           TruncatedPolynomial, Reflect> >::type
1502     {
1503     public:
1504         /** \brief  The type to check for ID
1505 
1506             This is a Boost integral constant indicating what ID number this
1507             instantiation used.
1508          */
1509         typedef boost::integral_constant<int, Id>  id_type;
1510     };
1511 
1512 
1513 }  // namespace detail
1514 //! \endcond
1515 
1516 
1517 //  Simple CRC class function definitions  -----------------------------------//
1518 
1519 /** Constructs a \c crc_basic object with at least the required parameters to a
1520     particular CRC formula to be processed upon receiving input.
1521 
1522     \param[in] truncated_polynomial  The lowest coefficients of the divisor
1523       polynomial.  The highest-order coefficient is omitted and always assumed
1524       to be 1.  (\e Poly from the RMCA)
1525     \param[in] initial_remainder  The (unaugmented) initial state of the
1526       polynomial remainder.  Defaults to \c 0 if omitted.  (\e Init from the
1527       RMCA)
1528     \param[in] final_xor_value  The (XOR) bit-mask to be applied to the output
1529       remainder, after possible reflection but before returning.  Defaults to
1530       \c 0 (i.e. no bit changes) if omitted.  (\e XorOut from the RMCA)
1531     \param[in] reflect_input  If \c true, input bytes are read lowest-order bit
1532       first, otherwise highest-order bit first.  Defaults to \c false if
1533       omitted.  (\e RefIn from the RMCA)
1534     \param[in] reflect_remainder  If \c true, the output remainder is reflected
1535       before the XOR-mask.  Defaults to \c false if omitted.  (\e RefOut from
1536       the RMCA)
1537 
1538     \post  <code><var>truncated_polynomial</var> ==
1539       this-&gt;get_truncated_polynominal()</code>
1540     \post  <code><var>initial_remainder</var> ==
1541       this-&gt;get_initial_remainder()</code>
1542     \post  <code><var>final_xor_value</var> ==
1543       this-&gt;get_final_xor_value()</code>
1544     \post  <code><var>reflect_input</var> ==
1545       this-&gt;get_reflect_input()</code>
1546     \post  <code><var>reflect_remainder</var> ==
1547       this-&gt;get_reflect_remainder()</code>
1548     \post  <code><var>initial_remainder</var> ==
1549       this-&gt;get_interim_remainder()</code>
1550     \post  <code>(<var>reflect_remainder</var> ?
1551       REFLECT(<var>initial_remainder</var>) : <var>initial_remainder</var>) ^
1552       <var>final_xor_value</var> == this-&gt;checksum()</code>
1553  */
1554 template < std::size_t Bits >
1555 inline
crc_basic(value_type truncated_polynomial,value_type initial_remainder,value_type final_xor_value,bool reflect_input,bool reflect_remainder)1556 crc_basic<Bits>::crc_basic
1557 (
1558     value_type  truncated_polynomial,
1559     value_type  initial_remainder,      // = 0
1560     value_type  final_xor_value,        // = 0
1561     bool        reflect_input,          // = false
1562     bool        reflect_remainder       // = false
1563 )
1564     : rem_( initial_remainder ), poly_( truncated_polynomial )
1565     , init_( initial_remainder ), final_( final_xor_value )
1566     , rft_in_( reflect_input ), rft_out_( reflect_remainder )
1567 {
1568 }
1569 
1570 /** Returns a representation of the polynomial divisor.  The value of the
1571     2<sup>i</sup> bit is the value of the coefficient of the polynomial's
1572     x<sup>i</sup> term.  The omitted bit for x<sup>(#bit_count)</sup> term is
1573     always 1.
1574 
1575     \return  The bit-packed list of coefficients.  If the bit-length of
1576       #value_type exceeds #bit_count, the values of higher-placed bits should be
1577       ignored (even any for x<sup>(#bit_count)</sup>) since they're unregulated.
1578  */
1579 template < std::size_t Bits >
1580 inline
1581 typename crc_basic<Bits>::value_type
get_truncated_polynominal() const1582 crc_basic<Bits>::get_truncated_polynominal
1583 (
1584 ) const
1585 {
1586     return poly_;
1587 }
1588 
1589 /** Returns a representation of the polynomial remainder before any input has
1590     been submitted.  The value of the 2<sup>i</sup> bit is the value of the
1591     coefficient of the polynomial's x<sup>i</sup> term.
1592 
1593     \return  The bit-packed list of coefficients.  If the bit-length of
1594       #value_type exceeds #bit_count, the values of higher-placed bits should be
1595       ignored since they're unregulated.
1596  */
1597 template < std::size_t Bits >
1598 inline
1599 typename crc_basic<Bits>::value_type
get_initial_remainder() const1600 crc_basic<Bits>::get_initial_remainder
1601 (
1602 ) const
1603 {
1604     return init_;
1605 }
1606 
1607 /** Returns the mask to be used during creation of a checksum.  The mask is used
1608     for an exclusive-or (XOR) operation applied bit-wise to the interim
1609     remainder representation (after any reflection, if #get_reflect_remainder()
1610     returns \c true).
1611 
1612     \return  The bit-mask.  If the bit-length of #value_type exceeds #bit_count,
1613       the values of higher-placed bits should be ignored since they're
1614       unregulated.
1615  */
1616 template < std::size_t Bits >
1617 inline
1618 typename crc_basic<Bits>::value_type
get_final_xor_value() const1619 crc_basic<Bits>::get_final_xor_value
1620 (
1621 ) const
1622 {
1623     return final_;
1624 }
1625 
1626 /** Returns a whether or not a submitted byte will be \"reflected\" before it is
1627     used to update the interim remainder.  Only the byte-wise operations
1628     #process_byte, #process_block, and #process_bytes are affected.
1629 
1630     \retval true  Input bytes will be read starting from the lowest-order bit.
1631     \retval false  Input bytes will be read starting from the highest-order bit.
1632  */
1633 template < std::size_t Bits >
1634 inline
1635 bool
get_reflect_input() const1636 crc_basic<Bits>::get_reflect_input
1637 (
1638 ) const
1639 {
1640     return rft_in_;
1641 }
1642 
1643 /** Indicates if the interim remainder will be \"reflected\" before it is passed
1644     to the XOR-mask stage when returning a checksum.
1645 
1646     \retval true  The interim remainder is reflected before further work.
1647     \retval false  The interim remainder is applied to the XOR-mask as-is.
1648  */
1649 template < std::size_t Bits >
1650 inline
1651 bool
get_reflect_remainder() const1652 crc_basic<Bits>::get_reflect_remainder
1653 (
1654 ) const
1655 {
1656     return rft_out_;
1657 }
1658 
1659 /** Returns a representation of the polynomial remainder after all the input
1660     submissions since construction or the last #reset call.  The value of the
1661     2<sup>i</sup> bit is the value of the coefficient of the polynomial's
1662     x<sup>i</sup> term.  If CRC processing gets interrupted here, retain the
1663     value returned, and use it to start up the next CRC computer where you left
1664     off (with #reset(value_type) or construction).  The next computer has to
1665     have its other parameters compatible with this computer.
1666 
1667     \return  The bit-packed list of coefficients.  If the bit-length of
1668       #value_type exceeds #bit_count, the values of higher-placed bits should be
1669       ignored since they're unregulated.  No output processing (reflection or
1670       XOR mask) has been applied to the value.
1671  */
1672 template < std::size_t Bits >
1673 inline
1674 typename crc_basic<Bits>::value_type
get_interim_remainder() const1675 crc_basic<Bits>::get_interim_remainder
1676 (
1677 ) const
1678 {
1679     return rem_ & detail::low_bits_mask_c<bit_count>::value;
1680 }
1681 
1682 /** Changes the interim polynomial remainder to \a new_rem, purging any
1683     influence previously submitted input has had.  The value of the
1684     2<sup>i</sup> bit is the value of the coefficient of the polynomial's
1685     x<sup>i</sup> term.
1686 
1687     \param[in] new_rem  The (unaugmented) state of the polynomial remainder
1688       starting from this point, with no output processing applied.
1689 
1690     \post  <code><var>new_rem</var> == this-&gt;get_interim_remainder()</code>
1691     \post  <code>((this-&gt;get_reflect_remainder() ?
1692       REFLECT(<var>new_rem</var>) : <var>new_rem</var>) ^
1693       this-&gt;get_final_xor_value()) == this-&gt;checksum()</code>
1694  */
1695 template < std::size_t Bits >
1696 inline
1697 void
reset(value_type new_rem)1698 crc_basic<Bits>::reset
1699 (
1700     value_type  new_rem
1701 )
1702 {
1703     rem_ = new_rem;
1704 }
1705 
1706 /** Changes the interim polynomial remainder to the initial remainder given
1707     during construction, purging any influence previously submitted input has
1708     had.  The value of the 2<sup>i</sup> bit is the value of the coefficient of
1709     the polynomial's x<sup>i</sup> term.
1710 
1711     \post  <code>this-&gt;get_initial_remainder() ==
1712       this-&gt;get_interim_remainder()</code>
1713     \post  <code>((this-&gt;get_reflect_remainder() ?
1714       REFLECT(this-&gt;get_initial_remainder()) :
1715       this-&gt;get_initial_remainder()) ^ this-&gt;get_final_xor_value())
1716       == this-&gt;checksum()</code>
1717  */
1718 template < std::size_t Bits >
1719 inline
1720 void
reset()1721 crc_basic<Bits>::reset
1722 (
1723 )
1724 {
1725     this->reset( this->get_initial_remainder() );
1726 }
1727 
1728 /** Updates the interim remainder with a single altered-CRC-division step.
1729 
1730     \param[in] bit  The new input bit.
1731 
1732     \post  The interim remainder is updated though a modulo-2 polynomial
1733       division, where the division steps are altered for unaugmented CRCs.
1734  */
1735 template < std::size_t Bits >
1736 inline
1737 void
process_bit(bool bit)1738 crc_basic<Bits>::process_bit
1739 (
1740     bool  bit
1741 )
1742 {
1743     detail::crc_modulo_update( bit_count, rem_, bit, poly_ );
1744 }
1745 
1746 /** Updates the interim remainder with several altered-CRC-division steps.  Each
1747     bit is processed separately, starting from the one at the
1748     2<sup><var>bit_length</var> - 1</sup> place, then proceeding down to the
1749     lowest-placed bit.  Any order imposed by
1750     <code>this-&gt;get_reflect_input()</code> is ignored.
1751 
1752     \pre  0 \< \a bit_length \<= \c CHAR_BIT
1753 
1754     \param[in] bits  The byte containing the new input bits.
1755     \param[in] bit_length  The number of bits in the byte to be read.
1756 
1757     \post  The interim remainder is updated though \a bit_length modulo-2
1758       polynomial divisions, where the division steps are altered for unaugmented
1759       CRCs.
1760  */
1761 template < std::size_t Bits >
1762 void
process_bits(unsigned char bits,std::size_t bit_length)1763 crc_basic<Bits>::process_bits
1764 (
1765     unsigned char  bits,
1766     std::size_t    bit_length
1767 )
1768 {
1769     // ignore the bits above the ones we want
1770     bits <<= CHAR_BIT - bit_length;
1771 
1772     // compute the CRC for each bit, starting with the upper ones
1773     unsigned char const  high_bit_mask = 1u << ( CHAR_BIT - 1u );
1774     for ( std::size_t i = bit_length ; i > 0u ; --i, bits <<= 1u )
1775     {
1776         process_bit( static_cast<bool>(bits & high_bit_mask) );
1777     }
1778 }
1779 
1780 /** Updates the interim remainder with a byte's worth of altered-CRC-division
1781     steps.  The bits within the byte are processed from the highest place down
1782     if <code>this-&gt;get_reflect_input()</code> is \c false, and lowest place
1783     up otherwise.
1784 
1785     \param[in] byte  The new input byte.
1786 
1787     \post  The interim remainder is updated though \c CHAR_BIT modulo-2
1788       polynomial divisions, where the division steps are altered for unaugmented
1789       CRCs.
1790  */
1791 template < std::size_t Bits >
1792 inline
1793 void
process_byte(unsigned char byte)1794 crc_basic<Bits>::process_byte
1795 (
1796     unsigned char  byte
1797 )
1798 {
1799     process_bits( (rft_in_ ? detail::reflect_byte( byte ) : byte), CHAR_BIT );
1800 }
1801 
1802 /** Updates the interim remainder with several bytes' worth of
1803     altered-CRC-division steps.  The bits within each byte are processed from
1804     the highest place down if <code>this-&gt;get_reflect_input()</code> is
1805     \c false, and lowest place up otherwise.  The bytes themselves are processed
1806     starting from the one pointed by \a bytes_begin until \a bytes_end is
1807     reached through forward iteration, treating the two pointers as if they
1808     point to <code>unsigned char</code> objects.
1809 
1810     \pre  \a bytes_end has to equal \a bytes_begin if the latter is \c NULL or
1811       otherwise doesn't point to a valid buffer.
1812     \pre  \a bytes_end, if not equal to \a bytes_begin, has to point within or
1813       one-byte-past the same buffer \a bytes_begin points into.
1814     \pre  \a bytes_end has to be reachable from \a bytes_begin through a finite
1815       number of forward byte-pointer increments.
1816 
1817     \param[in] bytes_begin  The address where the memory block begins.
1818     \param[in] bytes_end  Points to one-byte past the address of the memory
1819       block's last byte, or \a bytes_begin if no bytes are to be read.
1820 
1821     \post  The interim remainder is updated though <code>CHAR_BIT * (((unsigned
1822       char const *) bytes_end) - ((unsigned char const *) bytes_begin))</code>
1823       modulo-2 polynomial divisions, where the division steps are altered for
1824       unaugmented CRCs.
1825  */
1826 template < std::size_t Bits >
1827 void
process_block(void const * bytes_begin,void const * bytes_end)1828 crc_basic<Bits>::process_block
1829 (
1830     void const *  bytes_begin,
1831     void const *  bytes_end
1832 )
1833 {
1834     for ( unsigned char const * p
1835      = static_cast<unsigned char const *>(bytes_begin) ; p < bytes_end ; ++p )
1836     {
1837         process_byte( *p );
1838     }
1839 }
1840 
1841 /** Updates the interim remainder with several bytes' worth of
1842     altered-CRC-division steps.  The bits within each byte are processed from
1843     the highest place down if <code>this-&gt;get_reflect_input()</code> is
1844     \c false, and lowest place up otherwise.  The bytes themselves are processed
1845     starting from the one pointed by \a buffer, forward-iterated (as if the
1846     pointed-to objects were of <code>unsigned char</code>) until \a byte_count
1847     bytes are read.
1848 
1849     \pre  \a byte_count has to equal 0 if \a buffer is \c NULL or otherwise
1850       doesn't point to valid memory.
1851     \pre  If \a buffer points within valid memory, then that block has to have
1852       at least \a byte_count more valid bytes allocated from that point.
1853 
1854     \param[in] buffer  The address where the memory block begins.
1855     \param[in] byte_count  The number of bytes in the memory block.
1856 
1857     \post  The interim remainder is updated though <code>CHAR_BIT *
1858       <var>byte_count</var></code> modulo-2 polynomial divisions, where the
1859       division steps are altered for unaugmented CRCs.
1860  */
1861 template < std::size_t Bits >
1862 inline
1863 void
process_bytes(void const * buffer,std::size_t byte_count)1864 crc_basic<Bits>::process_bytes
1865 (
1866     void const *  buffer,
1867     std::size_t   byte_count
1868 )
1869 {
1870     unsigned char const * const  b = static_cast<unsigned char const *>(
1871      buffer );
1872 
1873     process_block( b, b + byte_count );
1874 }
1875 
1876 /** Computes the checksum of all the submitted bits since construction or the
1877     last call to #reset.  The checksum will be the raw checksum, i.e. the
1878     (interim) remainder after all the modulo-2 polynomial division, plus any
1879     output processing.
1880 
1881     \return  <code>(this-&gt;get_reflect_remainder() ?
1882       REFLECT(this-&gt;get_interim_remainder()) :
1883       this-&gt;get_interim_remainder()) ^ this-&gt;get_final_xor_value()</code>
1884 
1885     \note  Since checksums are meant to be compared, any higher-placed bits
1886       (when the bit-length of #value_type exceeds #bit_count) will be set to 0.
1887  */
1888 template < std::size_t Bits >
1889 inline
1890 typename crc_basic<Bits>::value_type
checksum() const1891 crc_basic<Bits>::checksum
1892 (
1893 ) const
1894 {
1895     return ( (rft_out_ ? detail::reflect_unsigned( rem_, bit_count ) :
1896      rem_) ^ final_ ) & detail::low_bits_mask_c<bit_count>::value;
1897 }
1898 
1899 
1900 //  Optimized CRC class function definitions  --------------------------------//
1901 
1902 // Macro to compact code
1903 #define BOOST_CRC_OPTIMAL_NAME  crc_optimal<Bits, TruncPoly, InitRem, \
1904  FinalXor, ReflectIn, ReflectRem>
1905 
1906 /** Constructs a \c crc_optimal object with a particular CRC formula to be
1907     processed upon receiving input.  The initial remainder may be overridden.
1908 
1909     \param[in] init_rem  The (unaugmented) initial state of the polynomial
1910       remainder.  Defaults to #initial_remainder if omitted.
1911 
1912     \post  <code>#truncated_polynominal ==
1913       this-&gt;get_truncated_polynominal()</code>
1914     \post  <code>#initial_remainder == this-&gt;get_initial_remainder()</code>
1915     \post  <code>#final_xor_value == this-&gt;get_final_xor_value()</code>
1916     \post  <code>#reflect_input == this-&gt;get_reflect_input()</code>
1917     \post  <code>#reflect_remainder == this-&gt;get_reflect_remainder()</code>
1918     \post  <code><var>init_rem</var> == this-&gt;get_interim_remainder()</code>
1919     \post  <code>(#reflect_remainder ? REFLECT(<var>init_rem</var>) :
1920       <var>init_rem</var>) ^ #final_xor_value == this-&gt;checksum()</code>
1921  */
1922 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
1923            BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
1924            bool ReflectIn, bool ReflectRem >
1925 inline
crc_optimal(value_type init_rem)1926 BOOST_CRC_OPTIMAL_NAME::crc_optimal
1927 (
1928     value_type  init_rem  // = initial_remainder
1929 )
1930     : rem_( reflect_i_type::reflect_q(init_rem) )
1931 {
1932 }
1933 
1934 //! \copydetails  boost::crc_basic::get_truncated_polynominal
1935 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
1936            BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
1937            bool ReflectIn, bool ReflectRem >
1938 inline
1939 typename BOOST_CRC_OPTIMAL_NAME::value_type
get_truncated_polynominal() const1940 BOOST_CRC_OPTIMAL_NAME::get_truncated_polynominal
1941 (
1942 ) const
1943 {
1944     return truncated_polynominal;
1945 }
1946 
1947 //! \copydetails  boost::crc_basic::get_initial_remainder
1948 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
1949            BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
1950            bool ReflectIn, bool ReflectRem >
1951 inline
1952 typename BOOST_CRC_OPTIMAL_NAME::value_type
get_initial_remainder() const1953 BOOST_CRC_OPTIMAL_NAME::get_initial_remainder
1954 (
1955 ) const
1956 {
1957     return initial_remainder;
1958 }
1959 
1960 //! \copydetails  boost::crc_basic::get_final_xor_value
1961 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
1962            BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
1963            bool ReflectIn, bool ReflectRem >
1964 inline
1965 typename BOOST_CRC_OPTIMAL_NAME::value_type
get_final_xor_value() const1966 BOOST_CRC_OPTIMAL_NAME::get_final_xor_value
1967 (
1968 ) const
1969 {
1970     return final_xor_value;
1971 }
1972 
1973 //! \copydetails  boost::crc_basic::get_reflect_input
1974 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
1975            BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
1976            bool ReflectIn, bool ReflectRem >
1977 inline
1978 bool
get_reflect_input() const1979 BOOST_CRC_OPTIMAL_NAME::get_reflect_input
1980 (
1981 ) const
1982 {
1983     return reflect_input;
1984 }
1985 
1986 //! \copydetails  boost::crc_basic::get_reflect_remainder
1987 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
1988            BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
1989            bool ReflectIn, bool ReflectRem >
1990 inline
1991 bool
get_reflect_remainder() const1992 BOOST_CRC_OPTIMAL_NAME::get_reflect_remainder
1993 (
1994 ) const
1995 {
1996     return reflect_remainder;
1997 }
1998 
1999 //! \copydetails  boost::crc_basic::get_interim_remainder
2000 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
2001            BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
2002            bool ReflectIn, bool ReflectRem >
2003 inline
2004 typename BOOST_CRC_OPTIMAL_NAME::value_type
get_interim_remainder() const2005 BOOST_CRC_OPTIMAL_NAME::get_interim_remainder
2006 (
2007 ) const
2008 {
2009     // Interim remainder should be _un_-reflected, so we have to undo it.
2010     return reflect_i_type::reflect_q( rem_ ) &
2011      detail::low_bits_mask_c<bit_count>::value;
2012 }
2013 
2014 /** Changes the interim polynomial remainder to \a new_rem, purging any
2015     influence previously submitted input has had.  The value of the
2016     2<sup>i</sup> bit is the value of the coefficient of the polynomial's
2017     x<sup>i</sup> term.
2018 
2019     \param[in] new_rem  The (unaugmented) state of the polynomial remainder
2020       starting from this point, with no output processing applied.  Defaults to
2021       <code>this-&gt;get_initial_remainder()</code> if omitted.
2022 
2023     \post  <code><var>new_rem</var> == this-&gt;get_interim_remainder()</code>
2024     \post  <code>((this-&gt;get_reflect_remainder() ?
2025       REFLECT(<var>new_rem</var>) : <var>new_rem</var>) ^
2026       this-&gt;get_final_xor_value()) == this-&gt;checksum()</code>
2027  */
2028 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
2029            BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
2030            bool ReflectIn, bool ReflectRem >
2031 inline
2032 void
reset(value_type new_rem)2033 BOOST_CRC_OPTIMAL_NAME::reset
2034 (
2035     value_type  new_rem  // = initial_remainder
2036 )
2037 {
2038     rem_ = reflect_i_type::reflect_q( new_rem );
2039 }
2040 
2041 /** \copydetails  boost::crc_basic::process_byte
2042 
2043     \note  Any modulo-2 polynomial divisions may use a table of pre-computed
2044       remainder changes (as XOR masks) to speed computation when reading data
2045       byte-wise.
2046  */
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 void
process_byte(unsigned char byte)2052 BOOST_CRC_OPTIMAL_NAME::process_byte
2053 (
2054     unsigned char  byte
2055 )
2056 {
2057     process_bytes( &byte, sizeof(byte) );
2058 }
2059 
2060 /** \copydetails  boost::crc_basic::process_block
2061 
2062     \note  Any modulo-2 polynomial divisions may use a table of pre-computed
2063       remainder changes (as XOR masks) to speed computation when reading data
2064       byte-wise.
2065  */
2066 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
2067            BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
2068            bool ReflectIn, bool ReflectRem >
2069 inline
2070 void
process_block(void const * bytes_begin,void const * bytes_end)2071 BOOST_CRC_OPTIMAL_NAME::process_block
2072 (
2073     void const *  bytes_begin,
2074     void const *  bytes_end
2075 )
2076 {
2077     process_bytes( bytes_begin, static_cast<unsigned char const *>(bytes_end) -
2078      static_cast<unsigned char const *>(bytes_begin) );
2079 }
2080 
2081 /** \copydetails  boost::crc_basic::process_bytes
2082 
2083     \note  Any modulo-2 polynomial divisions may use a table of pre-computed
2084       remainder changes (as XOR masks) to speed computation when reading data
2085       byte-wise.
2086  */
2087 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
2088            BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
2089            bool ReflectIn, bool ReflectRem >
2090 inline
2091 void
process_bytes(void const * buffer,std::size_t byte_count)2092 BOOST_CRC_OPTIMAL_NAME::process_bytes
2093 (
2094     void const *   buffer,
2095     std::size_t  byte_count
2096 )
2097 {
2098     rem_ = crc_table_type::crc_update( rem_, static_cast<unsigned char const
2099      *>(buffer), byte_count );
2100 }
2101 
2102 //! \copydetails  boost::crc_basic::checksum
2103 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
2104            BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
2105            bool ReflectIn, bool ReflectRem >
2106 inline
2107 typename BOOST_CRC_OPTIMAL_NAME::value_type
checksum() const2108 BOOST_CRC_OPTIMAL_NAME::checksum
2109 (
2110 ) const
2111 {
2112     return ( reflect_o_type::reflect_q(rem_) ^ get_final_xor_value() )
2113      & detail::low_bits_mask_c<bit_count>::value;
2114 }
2115 
2116 /** Updates the interim remainder with a byte's worth of altered-CRC-division
2117     steps.  The bits within the byte are processed from the highest place down
2118     if <code>this-&gt;get_reflect_input()</code> is \c false, and lowest place
2119     up otherwise.  This function is meant to present a function-object interface
2120     to code that wants to process a stream of bytes with
2121     <code>std::for_each</code> or similar range-processing algorithms.  Since
2122     some of these algorithms takes their function object by value, make sure to
2123     copy back the result to this object so the updates can be remembered.
2124 
2125     \param[in] byte  The new input byte.
2126 
2127     \post  The interim remainder is updated though \c CHAR_BIT modulo-2
2128       polynomial divisions, where the division steps are altered for unaugmented
2129       CRCs.
2130 
2131     \note  Any modulo-2 polynomial divisions may use a table of pre-computed
2132       remainder changes (as XOR masks) to speed computation when reading data
2133       byte-wise.
2134  */
2135 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
2136            BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
2137            bool ReflectIn, bool ReflectRem >
2138 inline
2139 void
operator ()(unsigned char byte)2140 BOOST_CRC_OPTIMAL_NAME::operator ()
2141 (
2142     unsigned char  byte
2143 )
2144 {
2145     process_byte( byte );
2146 }
2147 
2148 /** Computes the checksum of all the submitted bits since construction or the
2149     last call to #reset.  The checksum will be the raw checksum, i.e. the
2150     (interim) remainder after all the modulo-2 polynomial division, plus any
2151     output processing.  This function is meant to present a function-object
2152     interface to code that wants to receive data like
2153     <code>std::generate_n</code> or similar data-processing algorithms.  Note
2154     that if this object is used as a generator multiple times without an
2155     intervening mutating operation, the same value will always be returned.
2156 
2157     \return  <code>(this-&gt;get_reflect_remainder() ?
2158       REFLECT(this-&gt;get_interim_remainder()) :
2159       this-&gt;get_interim_remainder()) ^ this-&gt;get_final_xor_value()</code>
2160 
2161     \note  Since checksums are meant to be compared, any higher-placed bits
2162       (when the bit-length of #value_type exceeds #bit_count) will be set to 0.
2163  */
2164 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
2165            BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
2166            bool ReflectIn, bool ReflectRem >
2167 inline
2168 typename BOOST_CRC_OPTIMAL_NAME::value_type
operator ()() const2169 BOOST_CRC_OPTIMAL_NAME::operator ()
2170 (
2171 ) const
2172 {
2173     return checksum();
2174 }
2175 
2176 
2177 //  CRC computation function definition  -------------------------------------//
2178 
2179 /** Computes the polynomial remainder of a CRC run, assuming that \a buffer and
2180     \a byte_count describe a memory block representing the polynomial dividend.
2181     The division steps are altered so the result directly gives a checksum,
2182     without need to augment the memory block with scratch-space bytes.  The
2183     first byte is considered the highest order, going down for subsequent bytes.
2184 
2185     \pre  0 \< \a Bits \<= \c std\::numeric_limits\<uintmax_t\>\::digits
2186 
2187     \tparam Bits  The order of the modulo-2 polynomial divisor.  (\e Width from
2188       the RMCA)
2189     \tparam TruncPoly  The lowest coefficients of the divisor polynomial.  The
2190       highest-order coefficient is omitted and always assumed to be 1.
2191       (\e Poly from the RMCA)
2192     \tparam InitRem  The (unaugmented) initial state of the polynomial
2193       remainder.  (\e Init from the RMCA)
2194     \tparam FinalXor  The (XOR) bit-mask to be applied to the output remainder,
2195       after possible reflection but before returning.  (\e XorOut from the RMCA)
2196     \tparam ReflectIn  If \c True, input bytes are read lowest-order bit first,
2197       otherwise highest-order bit first.  (\e RefIn from the RMCA)
2198     \tparam ReflectRem  If \c True, the output remainder is reflected before the
2199       XOR-mask.  (\e RefOut from the RMCA)
2200 
2201     \param[in] buffer  The address where the memory block begins.
2202     \param[in] byte_count  The number of bytes in the memory block.
2203 
2204     \return  The checksum, which is the last (interim) remainder plus any output
2205       processing.
2206 
2207     \note  Unaugmented-style CRC runs perform modulo-2 polynomial division in
2208       an altered order.  The trailing \a Bits number of zero-valued bits needed
2209       to extracted an (unprocessed) checksum is virtually moved to near the
2210       beginning of the message.  This is OK since the XOR operation is
2211       commutative and associative.  It also means that you can get a checksum
2212       anytime.  Since data is being read byte-wise, a table of pre-computed
2213       remainder changes (as XOR masks) can be used to speed computation.
2214 
2215  */
2216 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
2217            BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
2218            bool ReflectIn, bool ReflectRem >
2219 inline
2220 typename uint_t<Bits>::fast
crc(void const * buffer,std::size_t byte_count)2221 crc
2222 (
2223     void const *  buffer,
2224     std::size_t   byte_count
2225 )
2226 {
2227     BOOST_CRC_OPTIMAL_NAME  computer;
2228     computer.process_bytes( buffer, byte_count );
2229     return computer.checksum();
2230 }
2231 
2232 
2233 //  Augmented-message CRC computation function definition  -------------------//
2234 
2235 /** Computes the polynomial remainder of a CRC run, assuming that \a buffer and
2236     \a byte_count describe a memory block representing the polynomial dividend.
2237     The first byte is considered the highest order, going down for subsequent
2238     bytes.  Within a byte, the highest-order bit is read first (corresponding to
2239     \e RefIn = \c False in the RMCA).  Check the other parts of this function's
2240     documentation to see how a checksum can be gained and/or used.
2241 
2242     \pre  0 \< \a Bits \<= \c std\::numeric_limit\<uintmax_t\>\::digits
2243 
2244     \tparam Bits  The order of the modulo-2 polynomial divisor.  (\e Width from
2245       the RMCA)
2246     \tparam TruncPoly  The lowest coefficients of the divisor polynomial.  The
2247       highest-order coefficient is omitted and always assumed to be 1.
2248       (\e Poly from the RMCA)
2249 
2250     \param[in] buffer  The address where the memory block begins.
2251     \param[in] byte_count  The number of bytes in the memory block.
2252     \param[in] initial_remainder  The initial state of the polynomial
2253       remainder, defaulting to zero if omitted.  If you are reading a memory
2254       block in multiple runs, put the return value of the previous run here.
2255       (Note that initial-remainders given by RMCA parameter lists, as
2256       \e Init, assume that the initial remainder is in its \b unaugmented state,
2257       so you would need to convert the value to make it suitable for this
2258       function.  I currently don't provide a conversion routine.)
2259 
2260     \return  The interim remainder, if no augmentation is used.  A special value
2261       if augmentation is used (see the notes).  No output processing is done on
2262       the value.  (In RMCA terms, \e RefOut is \c False and \e XorOut is \c 0.)
2263 
2264     \note  Augmented-style CRC runs use straight-up modulo-2 polynomial
2265       division.  Since data is being read byte-wise, a table of pre-computed
2266       remainder changes (as XOR masks) can be used to speed computation.
2267     \note  Reading just a memory block will yield an interim remainder, and not
2268       the final checksum.  To get that checksum, allocate \a Bits / \c CHAR_BIT
2269       bytes directly after the block and fill them with zero values, then extend
2270       \a byte_count to include those extra bytes.  A data block is corrupt if
2271       the return value doesn't equal your separately given checksum.
2272     \note  Another way to perform a check is use the zero-byte extension method,
2273       but replace the zero values with your separately-given checksum.  The
2274       checksum must be loaded in big-endian order.  Here corruption, in either
2275       the data block or the given checksum, is confirmed if the return value is
2276       not zero.
2277     \note  The two checksum techniques assume the CRC-run is performed bit-wise,
2278       while this function works byte-wise.  That means that the techniques can
2279       be used only if \c CHAR_BIT divides \a Bits evenly!
2280  */
2281 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly >
2282 typename uint_t<Bits>::fast
augmented_crc(void const * buffer,std::size_t byte_count,typename uint_t<Bits>::fast initial_remainder)2283 augmented_crc
2284 (
2285     void const *                 buffer,
2286     std::size_t                  byte_count,
2287     typename uint_t<Bits>::fast  initial_remainder  // = 0u
2288 )
2289 {
2290     return detail::low_bits_mask_c<Bits>::value &
2291      detail::byte_table_driven_crcs<Bits, TruncPoly, false>::
2292      augmented_crc_update( initial_remainder, static_cast<unsigned char const
2293      *>(buffer), byte_count );
2294 }
2295 
2296 
2297 }  // namespace boost
2298 
2299 
2300 // Undo header-private macros
2301 #undef BOOST_CRC_OPTIMAL_NAME
2302 #undef BOOST_CRC_PARM_TYPE
2303 
2304 
2305 #endif  // BOOST_CRC_HPP
2306 
2307