Figure 1: CRC Error-checking class

// Based on Ross Williams' Rocksoft Model CRC Algorithm,
// available as part of the document "A Painless Guide to
// CRC Error Detection Algorithms", also by Ross Williams

// NOTE: ... indicates code omitted for brevity

#if !defined(__CRC_H)
#define __CRC_H

namespace cdm_crc
   {
   static const int CRCMaxBits = 32;

   template<int Width, unsigned long Poly, unsigned long Init,
      unsigned long XOrOut, bool Ref, bool Direct = true>
   class CRCGenerator
      {
   public:
      class CRCTable;
      friend class CRCTable;
      class CRCTable
         {
         unsigned long Table[ 256 ];

         // Calculate the table entry at 'index'
         unsigned long CalcTableEntry( int index )
            {
            ...
            }

      public:
         CRCTable()
            {
            for( int i = 0; i < 256; i++ )
               {
               Table[ i ] = CalcTableEntry( i );
               }
            }
         unsigned long 
         operator[](int i) const  {return Table[ i ];}
         };

   private:
      static const CRCTable Table;

     // Register holds the current value of the CRC calculation
     unsigned long Register;      

     // Return an unsigned long with i'th bit set to one
     static unsigned long Bitmask( int i )   { return 1UL << i; }

     // Reflect the bottom b bits of val
     static unsigned long Reflect( unsigned long val, int b )
        {
        ...
        }

     // Return an unsigned long with value ( 2^width )-1
     static unsigned long WidthMask( int width )
        {
        return ( ( ( 1UL<<(width-1) ) -1UL )<<1 ) | 1UL;
        }
   public:
      CRCGenerator(): Register( Init ) {}
      unsigned long GetCRC() const
         {
         return (XOrOut ^ Register) & WidthMask( Width );
         }
      unsigned long GetNormalCRC() const
         {
         ...
         }
      bool GetDirect() const   { return Direct; }
      bool GetReflect() const  { return Ref; }
      int  GetWidth() const    { return Width; }
      void LoadRegister( unsigned long val )
         {
         ...
         }

      void Process( unsigned char ch )
         {
         ...
         }

      void Process( unsigned char* block, int block_length )
         {
         ...
         }
// Un-comment the following version if no member templates
///      void Process(unsigned char* first, unsigned char* last)
///         {
///         while( first != last )
///            {
///            Process( *first++ );
///            }
///         }
// Comment out the following version if no member templates
      template<class InIter>
      void Process( InIter first, InIter last )
         {
         while( first != last )
            {
            Process( *first );
            ++first;
            }
         }
      // Process 'count' bits from 'bits'. if 'Ref' is false 
      // reads starting from MSB of 'bits'. If 'Ref' is true 
      // starts from LSB
      void ProcessBits( unsigned char bits, int count )
         {
         ...
         }
     void Reset()
        {
        Register = Init;
        }
     void Write( ostream& os ) const
        {
        ...
        }
      };

   template<int Width, unsigned long Poly, unsigned long Init,
      unsigned long XOrOut, bool Ref, bool Direct>
   const 
   CRCGenerator<Width, Poly, Init, XOrOut, Ref, Direct>::CRCTable 
   CRCGenerator<Width, Poly, Init, XOrOut, Ref, Direct>::Table;

   template<int Width, unsigned long Poly, unsigned long Init, 
      unsigned long XOrOut, bool Ref, bool Direct>
   ostream& operator<<( ostream& os,
      CRCGenerator<Width, Poly, Init, XOrOut, Ref, Direct>& crc)
         {
         crc.Write( os );
         return os;
         }
   }; // end of namespace cdm_crc
#endif // __CRC_H