Boost logo

Boost-Commit :

From: dwalker07_at_[hidden]
Date: 2008-08-02 16:12:09


Author: dlwalker
Date: 2008-08-02 16:12:09 EDT (Sat, 02 Aug 2008)
New Revision: 47947
URL: http://svn.boost.org/trac/boost/changeset/47947

Log:
Fixed comment spelling; duplicated or moved code around within headers and between classes; changed class-static numeric constants to integral meta-constant types; made bit-coding shell publicly derive from byte-coding shell; added explanations to some comments; used newer integer size & mask types
Text files modified:
   sandbox/md5/boost/coding/coding_shell.hpp | 628 ++++++++++++++++++---------------------
   sandbox/md5/boost/coding/md5.hpp | 200 ++++++++++--
   sandbox/md5/libs/coding/src/md5.cpp | 117 ++++++-
   3 files changed, 551 insertions(+), 394 deletions(-)

Modified: sandbox/md5/boost/coding/coding_shell.hpp
==============================================================================
--- sandbox/md5/boost/coding/coding_shell.hpp (original)
+++ sandbox/md5/boost/coding/coding_shell.hpp 2008-08-02 16:12:09 EDT (Sat, 02 Aug 2008)
@@ -19,7 +19,8 @@
 #include <boost/coding_fwd.hpp>
 
 #include <boost/assert.hpp> // for BOOST_ASSERT
-#include <boost/mpl/if.hpp> // for boost::mpl::if_c
+#include <boost/mpl/bool.hpp> // for boost::mpl::bool_
+#include <boost/mpl/if.hpp> // for boost::mpl::if_
 #include <boost/mpl/int.hpp> // for boost::mpl::int_
 #include <boost/serialization/access.hpp> // for boost::serialization::access
 #include <boost/typeof/typeof.hpp> // for BOOST_AUTO
@@ -52,7 +53,7 @@
                            support:
                            - copying (either through assignment operator or
                              constructor); default construction recommended.
- - a memeber type \c consumed_type that compatible
+ - a member type \c consumed_type that compatible
                              with a byte, like <code>unsigned char</code>.
                            - a member type \c product_type (that's "normal")
                            - a (non-<code>const</code>) member <code>operator
@@ -162,7 +163,182 @@
 }; // byte_coding_shell
 
 
-// Bit-processing coding shell class template declarations -----------------//
+// Byte-processing coding shell class template member definitions ----------//
+
+/** Constructs a byte-processor shell set to a given engine.
+
+ \param p The byte-processor engine to copy as the initial state. If not
+ given, a default-constructed engine is used.
+
+ \post \c #bytes uses a copy of \p p and refers to \c *this.
+ */
+template < class ByteProcessor >
+inline
+byte_coding_shell<ByteProcessor>::byte_coding_shell
+(
+ processor_type const & p // = processor_type()
+)
+ : bytes( p )
+{}
+
+/** Provides non-mutable access to the byte-processor engine.
+
+ \return A \c const reference to the internal engine.
+ */
+template < class ByteProcessor >
+inline typename byte_coding_shell<ByteProcessor>::processor_type const &
+byte_coding_shell<ByteProcessor>::context() const
+{ return this->bytes.source; }
+
+/** Provides mutable access to the byte-processor engine.
+
+ \post None, besides what tinkering with the result may do.
+
+ \return A non-<code>const</code> reference to the internal engine.
+ */
+template < class ByteProcessor >
+inline typename byte_coding_shell<ByteProcessor>::processor_type &
+byte_coding_shell<ByteProcessor>::context()
+{ return this->bytes.source; }
+
+/** Submits a byte for processing.
+
+ \param byte The byte value to be submitted.
+
+ \post Calls <code>this-&gt;bytes( <var>byte</var> )</code>.
+ */
+template < class ByteProcessor >
+inline void
+byte_coding_shell<ByteProcessor>::process_byte( unsigned char byte )
+{ this->bytes( byte ); }
+
+/** Submits multiple copies of a single byte value for processing.
+
+ \param value The byte value to be submitted.
+ \param byte_count The number of bytes to submit.
+
+ \post Calls <code>this-&gt;bytes( <var>value</var> )</code> \p byte_count
+ times.
+ */
+template < class ByteProcessor >
+inline void
+byte_coding_shell<ByteProcessor>::process_byte_copies
+(
+ unsigned char value,
+ size_type byte_count
+)
+{
+ while ( byte_count-- )
+ this->bytes( value );
+}
+
+/** Submits bytes, delimited by a pointer range, for processing.
+
+ \pre If \p bytes_begin is not \c NULL, then \p bytes_end has to be
+ reachable from \p bytes_begin via forward iterations of their
+ equivalent <code>unsigned char const *</code> values, otherwise
+ \p bytes_end has to be \c NULL too.
+
+ \param bytes_begin The start of the byte range to be submitted.
+ \param bytes_end One-past-the-end of the byte range in \p bytes_begin.
+
+ \post Calls <code>this-&gt;bytes( <var>x</var> )</code> for each byte \p x
+ in the given range, starting from the one at the address
+ \p bytes_begin to the byte just before the \p bytes_end mark. (If
+ the parameters are identical, then nothing is done.)
+ */
+template < class ByteProcessor >
+inline void
+byte_coding_shell<ByteProcessor>::process_block
+(
+ void const * bytes_begin,
+ void const * bytes_end
+)
+{
+ BOOST_ASSERT( !bytes_begin == !bytes_end ); // Can't test for reachable!
+
+ for ( BOOST_AUTO(p, static_cast<unsigned char const *>( bytes_begin )) ;
+ p != bytes_end ; ++p )
+ this->bytes( *p );
+}
+
+/** Submits bytes, bounded by a pointer and length, for processing.
+
+ \pre If \p buffer is \c NULL, then \p byte_count must be zero.
+
+ \param buffer The start of the byte range to be submitted.
+ \param byte_count Number of (leading) bytes to use from the range.
+
+ \post Calls <code>this-&gt;bytes( <var>x</var> )</code> for each byte \p x
+ in the given range, starting from the one at the address \p buffer,
+ going forward for \p byte_count bytes total.
+ */
+template < class ByteProcessor >
+inline void
+byte_coding_shell<ByteProcessor>::process_bytes
+(
+ void const * buffer,
+ size_type byte_count
+)
+{
+ BOOST_ASSERT( buffer || !byte_count );
+
+ for ( BOOST_AUTO(p, static_cast<unsigned char const *>( buffer )) ;
+ byte_count-- ; ++p )
+ this->bytes( *p );
+}
+
+/** Provides the computed check-sum of all the submitted values. Since this is
+ a \c const member function, the engine must act as if value-submission is
+ complete whenever this function is called.
+
+ \return The check-sum.
+ */
+template < class ByteProcessor >
+inline typename byte_coding_shell<ByteProcessor>::value_type
+byte_coding_shell<ByteProcessor>::checksum() const
+{ return this->context()(); }
+
+/** Compares byte-processor shells for equivalence. Such shells are equal if
+ their internal engines are equal.
+
+ \param o The right-side operand to be compared.
+
+ \retval true \c *this and \p o are equivalent.
+ \retval false \c *this and \p o are not equivalent.
+ */
+template < class ByteProcessor >
+inline bool
+byte_coding_shell<ByteProcessor>::operator ==( self_type const &o ) const
+{ return this->bytes == o.bytes; }
+
+/** Compares byte-processor shells for non-equivalence. Such shells are unequal
+ if their internal engines are unequal.
+
+ \param o The right-side operand to be compared.
+
+ \retval true \c *this and \p o are not equivalent.
+ \retval false \c *this and \p o are equivalent.
+ */
+template < class ByteProcessor >
+inline bool
+byte_coding_shell<ByteProcessor>::operator !=( self_type const &o ) const
+{ return !this->operator ==( o ); }
+
+/** Computes the check-sum of the submitted data, through a standard generator
+ interface.
+
+ \return The generated check-sum.
+
+ \see #checksum()const
+ */
+template < class ByteProcessor >
+inline typename byte_coding_shell<ByteProcessor>::value_type
+byte_coding_shell<ByteProcessor>::operator ()() const
+{ return this->checksum(); }
+
+
+// Byte-processing bit-processor wrapper class template declaration --------//
 
 /** \brief A conversion layer: a byte-processor from a bit-processor.
 
@@ -179,7 +355,7 @@
                           support:
                           - copying (either through assignment operator or
                             constructor); default construction recommended.
- - a memeber type \c consumed_type that compatible
+ - a member type \c consumed_type that compatible
                             with a Boolean, like <code>bool</code>.
                           - a member type \c product_type (that's "normal")
                           - a (non-<code>const</code>) member <code>operator
@@ -221,9 +397,11 @@
      */
     typedef unsigned char consumed_type;
 
- // Constants
- //! The bit-wise endian setting
- static bool const reads_start_highest = BigEndian;
+ /** \brief The bit-wise endian setting
+
+ Represents which way the bits within a submitted byte are processed.
+ */
+ typedef mpl::bool_<BigEndian> read_from_highest;
 
     // Member data
     /** \brief The wrapped bit-processing engine
@@ -261,13 +439,13 @@
     // Bit-loop implementation
     void consume_bits( unsigned char byte, int amount )
     {
- typedef boost::mpl::int_<+1> one_type;
- typedef boost::mpl::int_< 0> zero_type;
- typedef boost::mpl::int_<-1> one_ntype;
+ typedef mpl::int_<+1> one_type;
+ typedef mpl::int_< 0> zero_type;
+ typedef mpl::int_<-1> one_ntype;
 
- typedef typename boost::mpl::if_c<BigEndian, one_type, zero_type>::type
+ typedef typename mpl::if_<read_from_highest, one_type, zero_type>::type
           starting_type;
- typedef typename boost::mpl::if_c<BigEndian, one_ntype, one_type>::type
+ typedef typename mpl::if_<read_from_highest, one_ntype, one_type>::type
           direction_type;
 
         BOOST_ASSERT( (amount >= 0) && (amount <= CHAR_BIT) );
@@ -282,6 +460,82 @@
 
 }; // bit_to_byte_processor
 
+
+// Byte-processing bit-processor wrapper class template member definitions -//
+
+/** Constructs a byte-processor engine from to a given bit-processor engine.
+
+ \param p The bit-processor engine to copy as the initial state. If not
+ given, a default-constructed engine is used.
+
+ \post <code>#inner == <var>p</var></code>.
+ */
+template < class BitProcessor, bool BigEndian >
+inline
+bit_to_byte_processor<BitProcessor, BigEndian>::bit_to_byte_processor
+(
+ processor_type const & p // = processor_type()
+)
+ : inner( p )
+{}
+
+/** Submits a byte for processing, bit-wise in the initialized endian order.
+
+ \param byte The byte value to be submitted.
+
+ \post Calls <code>this-&gt;inner( <var>x</var> )</code> \c CHAR_BIT times,
+ with \p x iterating from either the highest-order bit (if
+ \c #reads_start_highest is \c true) or lowest-order bit (if \c false)
+ towards, and including, the opposite-order bit.
+ */
+template < class BitProcessor, bool BigEndian >
+inline void
+bit_to_byte_processor<BitProcessor, BigEndian>::operator ()(consumed_type byte)
+{ this->consume_bits( byte, CHAR_BIT ); }
+
+/** Compares byte-processors for equivalence. Such engines are equal if their
+ internal bit-processors are equal.
+
+ \param o The right-side operand to be compared.
+
+ \retval true \c *this and \p o are equivalent.
+ \retval false \c *this and \p o are not equivalent.
+ */
+template < class BitProcessor, bool BigEndian >
+inline bool
+bit_to_byte_processor<BitProcessor, BigEndian>::operator ==
+( self_type const &o ) const
+{ return this->inner == o.inner; }
+
+/** Compares byte-processors for non-equivalence. Such engines are unequal if
+ their internal bit-processors are unequal.
+
+ \param o The right-side operand to be compared.
+
+ \retval true \c *this and \p o are not equivalent.
+ \retval false \c *this and \p o are equivalent.
+ */
+template < class BitProcessor, bool BigEndian >
+inline bool
+bit_to_byte_processor<BitProcessor, BigEndian>::operator !=
+( self_type const &o ) const
+{ return !this->operator ==( o ); }
+
+/** Provides the computed check-sum of all the submitted bytes, through a
+ standard generator interface. Since this is a \c const member function, the
+ engine must act as if bit-submission is complete whenever this function is
+ called.
+
+ \return The check-sum.
+ */
+template < class BitProcessor, bool BigEndian >
+inline typename bit_to_byte_processor<BitProcessor, BigEndian>::product_type
+bit_to_byte_processor<BitProcessor, BigEndian>::operator ()() const
+{ return this->inner(); }
+
+
+// Bit-processing coding shell class template declaration ------------------//
+
 /** \brief A presentation layer for encapsulating bit-processing.
 
     This class template can wrap a bit-computation class type. This template
@@ -301,7 +555,7 @@
                           support:
                           - copying (either through assignment operator or
                             constructor); default construction recommended.
- - a memeber type \c consumed_type that compatible
+ - a member type \c consumed_type that compatible
                             with a Boolean, like <code>bool</code>.
                           - a member type \c product_type (that's "normal")
                           - a (non-<code>const</code>) member <code>operator
@@ -324,7 +578,7 @@
  */
 template < class BitProcessor, bool BigEndian >
 class bit_coding_shell
- : private byte_coding_shell<bit_to_byte_processor<BitProcessor, BigEndian> >
+ : public byte_coding_shell<bit_to_byte_processor<BitProcessor, BigEndian> >
 {
     typedef byte_coding_shell< bit_to_byte_processor<BitProcessor, BigEndian> >
       base_type;
@@ -368,13 +622,13 @@
      */
     typedef typename BitProcessor::product_type value_type;
 
- // Constants
- //! The bit-wise endian setting
- static bool const reads_start_highest = BigEndian;
+ /** \brief The bit-wise endian setting (as a integral meta-constant)
 
- // Member data
- using base_type::bytes;
+ Represents which way the bits within a submitted byte are processed.
+ */
+ typedef mpl::bool_<BigEndian> read_from_highest;
 
+ // Member data
     /** \brief Proxy for bit-oriented application interface
 
         Accesses an interface where <code>this-&gt;bits</code> can be used as a
@@ -387,7 +641,7 @@
                \c #bytes' wrapped engine, but copies of this sub-object will
                allocate (with regular <code>operator new</code>) independent
                copies of that engine. This will cause throws/crashes in
- situtations when default memory allocation is full or disabled.
+ situations when default memory allocation is full or disabled.
                (And there's no choice for an alternate allocation scheme.)
                Maybe a <code>boost::variant&lt; BitProcessor *, BitProcessor
                &gt;</code> can be used, but it has its own complicated storage
@@ -410,34 +664,17 @@
 
     /*! \name Input reading */ //@{
     // Processors
- using base_type::process_byte;
- using base_type::process_byte_copies;
- using base_type::process_block;
- using base_type::process_bytes;
-
     //! Enters one bit for hashing
     void process_bit( bool bit );
- //! Enters lowest-signficant part of a byte
+ //! Enters lowest-significant part of a byte
     void process_bits( unsigned char bits, size_type bit_count );
     //! Enters several bits, all of the same value
- void process_bit_copies( bool value, size_type bit_count );
-
- //! Enters an octet
- void process_octet( uint_least8_t octet );//@}
-
- // Finishers
- using base_type::checksum;
+ void process_bit_copies( bool value, size_type bit_count );//@}
 
     /*! \name Operators */ //@{
     // Operators
     //! Copy-assignment
     self_type & operator =( self_type const &c );
- //! Equals
- bool operator ==( self_type const &o ) const;
- //! Not-equals
- bool operator !=( self_type const &o ) const;
-
- using base_type::operator ();//@} // remove?
 
 private:
     /*! \name Persistence */ //@{
@@ -451,262 +688,7 @@
 }; // bit_coding_shell
 
 
-// Byte-processing coding shell class template member definitions ----------//
-
-/** Constructs a byte-processor shell set to a given engine.
-
- \param p The byte-processor engine to copy as the initial state. If not
- given, a default-constructed engine is used.
-
- \post \c #bytes uses a copy of \p p and refers to \c *this.
- */
-template < class ByteProcessor >
-inline
-byte_coding_shell<ByteProcessor>::byte_coding_shell
-(
- processor_type const & p // = processor_type()
-)
- : bytes( p )
-{}
-
-/** Provides non-mutable access to the byte-processor engine.
-
- \return A \c const reference to the internal engine.
- */
-template < class ByteProcessor >
-inline typename byte_coding_shell<ByteProcessor>::processor_type const &
-byte_coding_shell<ByteProcessor>::context() const
-{ return this->bytes.source; }
-
-/** Provides mutable access to the byte-processor engine.
-
- \post None, besides what tinkering with the result may do.
-
- \return A non-<code>const</code> reference to the internal engine.
- */
-template < class ByteProcessor >
-inline typename byte_coding_shell<ByteProcessor>::processor_type &
-byte_coding_shell<ByteProcessor>::context()
-{ return this->bytes.source; }
-
-/** Submits a byte for processing.
-
- \param byte The byte value to be submitted.
-
- \post Calls <code>this-&gt;bytes( <var>byte</var> )</code>.
- */
-template < class ByteProcessor >
-inline void
-byte_coding_shell<ByteProcessor>::process_byte( unsigned char byte )
-{ this->bytes( byte ); }
-
-/** Submits multiple copies of a single byte value for processing.
-
- \param value The byte value to be submitted.
- \param byte_count The number of bytes to submit.
-
- \post Calls <code>this-&gt;bytes( <var>value</var> )</code> \p byte_count
- times.
- */
-template < class ByteProcessor >
-inline void
-byte_coding_shell<ByteProcessor>::process_byte_copies
-(
- unsigned char value,
- size_type byte_count
-)
-{
- while ( byte_count-- )
- this->bytes( value );
-}
-
-/** Submits bytes, delimited by a pointer range, for processing.
-
- \pre If \p bytes_begin is not \c NULL, then \p bytes_end has to be
- reachable from \p bytes_begin via forward iterations of their
- equivalent <code>unsigned char const *</code> values, otherwise
- \p bytes_end has to be \c NULL too.
-
- \param bytes_begin The start of the byte range to be submitted.
- \param bytes_end One-past-the-end of the byte range in \p bytes_begin.
-
- \post Calls <code>this-&gt;bytes( <var>x</var> )</code> for each byte \p x
- in the given range, starting from the one at the address
- \p bytes_begin to the byte just before the \p bytes_end mark. (If
- the parameters are identical, then nothing is done.)
- */
-template < class ByteProcessor >
-inline void
-byte_coding_shell<ByteProcessor>::process_block
-(
- void const * bytes_begin,
- void const * bytes_end
-)
-{
- BOOST_ASSERT( !bytes_begin == !bytes_end ); // Can't test reachability!
-
- for ( BOOST_AUTO(p, static_cast<unsigned char const *>( bytes_begin )) ;
- p != bytes_end ; ++p )
- this->bytes( *p );
-}
-
-/** Submits bytes, bounded by a pointer and length, for processing.
-
- \pre If \p buffer is \c NULL, then \p byte_count must be zero.
-
- \param buffer The start of the byte range to be submitted.
- \param byte_count Number of (leading) bytes to use from the range.
-
- \post Calls <code>this-&gt;bytes( <var>x</var> )</code> for each byte \p x
- in the given range, starting from the one at the address \p buffer,
- going forward for \p byte_count bytes total.
- */
-template < class ByteProcessor >
-inline void
-byte_coding_shell<ByteProcessor>::process_bytes
-(
- void const * buffer,
- size_type byte_count
-)
-{
- BOOST_ASSERT( buffer || !byte_count );
-
- for ( BOOST_AUTO(p, static_cast<unsigned char const *>( buffer )) ;
- byte_count-- ; ++p )
- this->bytes( *p );
-}
-
-/** Provides the computed check-sum of all the submitted values. Since this is
- a \c const member function, the engine must act as if value-submission is
- complete whenever this function is called.
-
- \return The check-sum.
- */
-template < class ByteProcessor >
-inline typename byte_coding_shell<ByteProcessor>::value_type
-byte_coding_shell<ByteProcessor>::checksum() const
-{ return this->context()(); }
-
-/** Compares byte-processor shells for equivalence. Such shells are equal if
- their internal engines are equal.
-
- \param o The right-side operand to be compared.
-
- \retval true \c *this and \p o are equivalent.
- \retval false \c *this and \p o are not equivalent.
- */
-template < class ByteProcessor >
-inline bool
-byte_coding_shell<ByteProcessor>::operator ==( self_type const &o ) const
-{ return this->bytes == o.bytes; }
-
-/** Compares byte-processor shells for non-equivalence. Such shells are unequal
- if their internal engines are unequal.
-
- \param o The right-side operand to be compared.
-
- \retval true \c *this and \p o are not equivalent.
- \retval false \c *this and \p o are equivalent.
- */
-template < class ByteProcessor >
-inline bool
-byte_coding_shell<ByteProcessor>::operator !=( self_type const &o ) const
-{ return !this->operator ==( o ); }
-
-/** Computes the check-sum of the submitted data, through a standard generator
- interface.
-
- \return The generated check-sum.
-
- \see #checksum()const
- */
-template < class ByteProcessor >
-inline typename byte_coding_shell<ByteProcessor>::value_type
-byte_coding_shell<ByteProcessor>::operator ()() const
-{ return this->checksum(); }
-
-
-// Bit-processing coding shell class templates member defintions -----------//
-
-/** Represents which way the bits within a submitted byte are processed.
- */
-template < class BitProcessor, bool BigEndian >
-bool const bit_to_byte_processor<BitProcessor, BigEndian>::reads_start_highest;
-
-/** Constructs a byte-processor engine from to a given bit-processor engine.
-
- \param p The bit-processor engine to copy as the initial state. If not
- given, a default-constructed engine is used.
-
- \post <code>#inner == <var>p</var></code>.
- */
-template < class BitProcessor, bool BigEndian >
-inline
-bit_to_byte_processor<BitProcessor, BigEndian>::bit_to_byte_processor
-(
- processor_type const & p // = processor_type()
-)
- : inner( p )
-{}
-
-/** Submits a byte for processing, bit-wise in the initialized endian order.
-
- \param byte The byte value to be submitted.
-
- \post Calls <code>this-&gt;inner( <var>x</var> )</code> \c CHAR_BIT times,
- with \p x iterating from either the highest-order bit (if
- \c #reads_start_highest is \c true) or lowest-order bit (if \c false)
- towards, and including, the opposite-order bit.
- */
-template < class BitProcessor, bool BigEndian >
-inline void
-bit_to_byte_processor<BitProcessor, BigEndian>::operator ()(consumed_type byte)
-{ this->consume_bits( byte, CHAR_BIT ); }
-
-/** Compares byte-processors for equivalence. Such engines are equal if their
- internal bit-processors are equal.
-
- \param o The right-side operand to be compared.
-
- \retval true \c *this and \p o are equivalent.
- \retval false \c *this and \p o are not equivalent.
- */
-template < class BitProcessor, bool BigEndian >
-inline bool
-bit_to_byte_processor<BitProcessor, BigEndian>::operator ==
-( self_type const &o ) const
-{ return this->inner == o.inner; }
-
-/** Compares byte-processors for non-equivalence. Such engines are unequal if
- their internal bit-processors are unequal.
-
- \param o The right-side operand to be compared.
-
- \retval true \c *this and \p o are not equivalent.
- \retval false \c *this and \p o are equivalent.
- */
-template < class BitProcessor, bool BigEndian >
-inline bool
-bit_to_byte_processor<BitProcessor, BigEndian>::operator !=
-( self_type const &o ) const
-{ return !this->operator ==( o ); }
-
-/** Provides the computed check-sum of all the submitted bytes, through a
- standard generator interface. Since this is a \c const member function, the
- engine must act as if bit-submission is complete whenever this function is
- called.
-
- \return The check-sum.
- */
-template < class BitProcessor, bool BigEndian >
-inline typename bit_to_byte_processor<BitProcessor, BigEndian>::product_type
-bit_to_byte_processor<BitProcessor, BigEndian>::operator ()() const
-{ return this->inner(); }
-
-/** Represents which way the bits within a submitted byte are processed.
- */
-template < class BitProcessor, bool BigEndian >
-bool const bit_coding_shell<BitProcessor, BigEndian>::reads_start_highest;
+// Bit-processing coding shell class template member definitions -----------//
 
 /** Constructs a bit-processor shell set to a given engine.
 
@@ -740,7 +722,9 @@
     , bits( &this->base_type::context().inner )
 {}
 
-/** Provides non-mutable access to the bit-processor engine.
+/** Provides non-mutable access to the bit-processor engine. This overload
+ exists to give direct access to the bit-processor engine, since the base
+ class's version will return access to the wrapping byte-processing engine.
 
     \return A \c const reference to the internal engine.
  */
@@ -749,7 +733,9 @@
 bit_coding_shell<BitProcessor, BigEndian>::context() const
 { return *this->bits.source; }
 
-/** Provides mutable access to the bit-processor engine.
+/** Provides mutable access to the bit-processor engine. This overload exists
+ to give direct access to the bit-processor engine, since the base class's
+ version will return access to the wrapping byte-processing engine.
 
     \post None, besides what tinkering with the result may do.
 
@@ -814,21 +800,9 @@
         this->bits( value );
 }
 
-/** Submits an octet for processing, bit-wise in the initialized endian order.
-
- \param octet The octet value to be submitted.
-
- \post Calls <code>this-&gt;process_bits( <var>octet</var>, 8 )</code>.
-
- \see #process_bits(unsigned char,#size_type)
- */
-template < class BitProcessor, bool BigEndian >
-inline void
-bit_coding_shell<BitProcessor, BigEndian>::process_octet( uint_least8_t octet )
-{ this->process_bits( octet, 8 ); }
-
 /** Changes a bit-processing shell to have the same observable state as a given
- shell. (No function object proxies are reseated, however.)
+ shell. (No function object proxies are reseated, however.) This overload
+ exists because the default action would perform an unnecessary extra copy.
 
     \param c The source object with the new state.
 
@@ -841,36 +815,14 @@
 bit_coding_shell<BitProcessor, BigEndian>::operator =( self_type const &c )
 {
     static_cast<base_type &>( *this ) = static_cast<base_type const &>( c );
- // "bits" is NOT reseated
+ // "bits" can't be reseated; but if it got assigned, it would ultimately
+ // perform a copy of the core bit-processing engine, which was already done
+ // in the base class's version of the copy-assignment operator. (This would
+ // be bad of the engine's assignment took a lot of time or resources.) So
+ // we can skip it.
     return *this;
 }
 
-/** Compares bit-processor shells for equivalence. Such shells are equal if
- their internal engines are equal.
-
- \param o The right-side operand to be compared.
-
- \retval true \c *this and \p o are equivalent.
- \retval false \c *this and \p o are not equivalent.
- */
-template < class BitProcessor, bool BigEndian >
-inline bool
-bit_coding_shell<BitProcessor, BigEndian>::operator ==(self_type const &o) const
-{ return this->bits == o.bits; }
-
-/** Compares bit-processor shells for non-equivalence. Such shells are unequal
- if their internal engines are unequal.
-
- \param o The right-side operand to be compared.
-
- \retval true \c *this and \p o are not equivalent.
- \retval false \c *this and \p o are equivalent.
- */
-template < class BitProcessor, bool BigEndian >
-inline bool
-bit_coding_shell<BitProcessor, BigEndian>::operator !=(self_type const &o) const
-{ return !this->operator ==( o ); }
-
 
 } // namespace coding
 } // namespace boost

Modified: sandbox/md5/boost/coding/md5.hpp
==============================================================================
--- sandbox/md5/boost/coding/md5.hpp (original)
+++ sandbox/md5/boost/coding/md5.hpp 2008-08-02 16:12:09 EDT (Sat, 02 Aug 2008)
@@ -23,7 +23,11 @@
 #include <boost/assert.hpp> // for BOOST_ASSERT
 #include <boost/coding/coding_shell.hpp> // for b:c:bit_coding_shell
 #include <boost/coding/operations.hpp> // for b:c:queued_bit_processing_base
-#include <boost/integer.hpp> // for boost::sized_integral
+#include <boost/cstdint.hpp> // for boost::uint_least8_t, etc.
+#include <boost/integer.hpp> // for boost::sized_integral, etc.
+#include <boost/mpl/arithmetic.hpp> // for boost::mpl::times
+#include <boost/mpl/int.hpp> // for boost::mpl::int_
+#include <boost/mpl/size_t.hpp> // for boost::mpl::size_t
 #include <boost/serialization/access.hpp> // for boost::serialization::access
 #include <boost/static_assert.hpp> // for BOOST_STATIC_ASSERT
 #include <boost/typeof/typeof.hpp> // for BOOST_AUTO
@@ -65,25 +69,31 @@
 class md5_digest
 {
 public:
- //! Number of bits for word-sized quantities
- static int const bits_per_word = 32;
+ // Types
+ /** \brief Number of bits for word-sized quantities
 
+ Represents the number of bits per word as given in RFC 1321, section 2.
+ */
+ typedef mpl::int_<32> bits_per_word;
     /** \brief Type of MD register
 
         Represents the type of each register of the MD buffer.
      */
- typedef boost::sized_integral<bits_per_word, unsigned>::type word_type;
+ typedef sized_integral<bits_per_word::value, unsigned>::type word_type;
+ /** \brief Length of MD buffer
 
- //! Length of MD buffer
- static std::size_t const words_per_digest = 4u;
+ Represents the number of registers in a MD buffer.
+ */
+ typedef mpl::size_t<4u> words_per_digest;
 
+ // Member data
     /** \brief The MD5 message digest checksum
 
         Represents the checksum from a MD5 hashing, mirroring for format of the
         MD buffer (see RFC 1321, section 3.3). The zero-index corresponds to
         the "A" register, up to index 3 representing the "D" register.
      */
- word_type hash[ words_per_digest ];
+ word_type hash[ words_per_digest::value ];
 
 }; // md5_digest
 
@@ -119,18 +129,18 @@
  */
 class md5_computerX
     : protected queued_bit_processing_base<md5_computerX, uint_fast64_t, 16u *
- md5_digest::bits_per_word>
+ md5_digest::bits_per_word::value>
 {
     typedef queued_bit_processing_base<md5_computerX, uint_fast64_t, 16u *
- md5_digest::bits_per_word> base_type;
+ md5_digest::bits_per_word::value> base_type;
 
     friend void base_type::process_bit( bool ); // needs "update_hash" access
 
     // Implementation constants, followed by sanity checks
     static std::size_t const words_per_block = base_type::queue_length /
- md5_digest::bits_per_word;
+ md5_digest::bits_per_word::value;
 
- BOOST_STATIC_ASSERT( (base_type::queue_length % md5_digest::bits_per_word)
+ BOOST_STATIC_ASSERT( (base_type::queue_length % md5_digest::bits_per_word::value)
      == 0u );
     BOOST_STATIC_ASSERT( words_per_block == 16u ); // RFC 1321, section 3.4
 
@@ -142,7 +152,7 @@
     // Constants
     //! Number of bits for length quantities
     static int const significant_bits_per_length = 2 *
- md5_digest::bits_per_word;
+ md5_digest::bits_per_word::value;
     //! Number of bits in hash queue
     static std::size_t const bits_per_block = base_type::queue_length;
 
@@ -174,7 +184,7 @@
         prior \e completed hashed blocks. The zero-index corresponds to the "A"
         register, up to index 3 representing the "D" register.
      */
- typedef array<md5_digest::word_type, md5_digest::words_per_digest>
+ typedef array<md5_digest::word_type, md5_digest::words_per_digest::value>
       buffer_type;
 
     // Lifetime management (use automatic destructor)
@@ -263,14 +273,16 @@
     // Implementation types
     typedef md5_computerX self_type;
 
- typedef uint_t<md5_digest::bits_per_word>::fast iword_type;
- typedef array<iword_type, md5_digest::words_per_digest> ibuffer_type;
+ typedef uint_t<md5_digest::bits_per_word::value>::fast iword_type;
+ typedef array<iword_type, md5_digest::words_per_digest::value> ibuffer_type;
 
     // (Computation) member data
     ibuffer_type buffer_;
 
     static ibuffer_type const initial_buffer_;
 
+ friend class md5_context;
+
 }; // md5_computerX
 
 /** \brief A computer that produces MD5 message digests from consuming bits.
@@ -285,27 +297,134 @@
 {
     typedef md5_context self_type;
 
- friend class md5_computer;
-
 public:
+ // Types
+ /** \brief Type of the produced output
+
+ Represents the result type, the checksums from hashing.
+ */
     typedef md5_digest product_type;
- typedef bool consumed_type;
+ /** \brief Type of the consumed input
+
+ Represents the argument type, the data to hash.
+ */
+ typedef bool consumed_type;
+
+ // Lifetime management (use automatic copy constructor and destructor)
+ //! Default construction
+ md5_context() : worker(), length(), buffer( initial_buffer ), queue() {}
 
- void operator ()( consumed_type bit ) { this->worker.process_bit(bit); }
+ /*! \name Operators */ //@{
+ // Operators (use automatic copy-assignment)
+ //! Application, consumer
+ void operator ()( consumed_type bit )
+ {
+ this->worker.process_bit(bit);
+ this->consume_bit( bit );
+ }
+ //! Equals
     bool operator ==( self_type const &o ) const
- { return this->worker == o.worker; }
+ {
+ bool const result1( this->worker == o.worker );
+ bool const result2( (this->length == o.length) && (this->buffer ==
+ o.buffer) && std::equal(this->queue.begin(), this->queue.begin() +
+ this->length % bits_per_block::value, o.queue.begin()) );
+ BOOST_ASSERT( result1 == result2 );
+ return result1;
+ }
+ //! Not-equals
     bool operator !=( self_type const &o ) const
       { return !this->operator ==( o ); }
- product_type operator ()() const { return this->worker.checksum(); }
+ //! Application, producer
+ product_type operator ()() const
+ {
+ product_type const result1( this->worker.checksum() );
+ product_type result2;
+ {
+ self_type c( *this );
+ c.finish();
+ std::copy( c.buffer.begin(), c.buffer.end(), result2.hash );
+ }
+ BOOST_ASSERT( std::equal(result1.hash, result1.hash+4, result2.hash) );
+ return result1;
+ }//@}
 
 private:
+ friend class md5_computer;
+
+ // Implementation types and meta-constants
+ typedef md5_digest::bits_per_word bits_per_word;
+ typedef md5_digest::word_type word_type;
+ typedef md5_digest::words_per_digest words_per_digest;
+
+ typedef mpl::int_<2> words_per_length;
+ typedef mpl::times<words_per_length, bits_per_word> bits_per_length;
+ typedef mpl::int_<16> words_per_block;
+ typedef mpl::times<words_per_block, bits_per_word> bits_per_block;
+
+ typedef sized_integral<bits_per_length::value, unsigned>::type length_type;
+ typedef fast_integral<length_type>::type length_ftype;
+ typedef fast_integral<word_type>::type word_ftype;
+ typedef array<word_ftype, words_per_digest::value> buffer_type;
+ typedef array<consumed_type, bits_per_block::value> queue_type;
+ typedef array<word_ftype, 64> hash_table_type;
+
+ // Implementation constants
+ static buffer_type const initial_buffer;
+ static hash_table_type const hashing_table;
+
+ // Member data
     md5_computerX worker;
+ length_ftype length;
+ buffer_type buffer;
+ queue_type queue;
+
+ // Implementation
+ void update_hash();
+ void consume_bit( bool bit )
+ {
+ this->queue[ this->length++ % bits_per_block::value ] = bit;
+ if ( this->length % bits_per_block::value == 0u )
+ this->update_hash();
+ }
+ void consume_octet( uint_fast8_t octet )
+ {
+ for ( int i = 0 ; i < 8 ; ++i, octet <<= 1 ) // high bit going down
+ this->consume_bit( octet & 0x80u );
+ }
+ void consume_word( word_ftype word )
+ {
+ for ( int i = 0 ; i < 4 ; ++i, word >>= 8 ) // low octet going up
+ this->consume_octet( word & 0xFFu );
+ }
+ void consume_dword( length_ftype dword )
+ {
+ for ( int i = 0 ; i < 2 ; ++i, dword >>= 32 ) // low word going up
+ this->consume_word( dword & 0xFFFFFFFFul );
+ }
+ void finish()
+ {
+ // Save the current length before we mutate it.
+ length_ftype const original_length = length;
+
+ // Enter a One, then enough Zeros so the length would fill the queue.
+ this->consume_bit( true );
+ for ( int i = bits_per_block::value - (this->length +
+ bits_per_length::value) % bits_per_block::value ; i > 0 ; --i )
+ this->consume_bit( false );
+
+ this->consume_dword( original_length );
+ BOOST_ASSERT( !(this->length % bits_per_block::value) );
+
+ // Now a finished checksum in this->buffer is ready to read.
+ }
 
+ /*! \name Persistence */ //@{
     // Serialization
     friend class boost::serialization::access;
 
     template < class Archive >
- void serialize( Archive &ar, const unsigned int version ); // not defined yet
+ void serialize( Archive &ar, const unsigned int version );//@} // not defined yet
 
 }; // md5_context
 
@@ -343,7 +462,7 @@
 
     // Types
     typedef uint_least64_t length_type;
- typedef array<md5_digest::word_type, md5_digest::words_per_digest>
+ typedef array<md5_digest::word_type, md5_digest::words_per_digest::value>
       buffer_type;
 
     // Assignment
@@ -371,18 +490,24 @@
       { return this->context().worker.copy_unbuffered( o ); }
 
     // Input processing
+ //! Enters an octet
+ void process_octet( uint_least8_t octet )
+ {
+ this->context().worker.process_octet( octet );
+ this->context().consume_octet( octet );
+ }
     //! Enters a word for hashing
     void process_word( md5_digest::word_type word )
- { this->context().worker.process_word( word ); }
+ {
+ this->context().worker.process_word( word );
+ this->context().consume_word( word );
+ }
     //! Enters a double-word for hashing
     void process_double_word( length_type dword )
- { this->context().worker.process_double_word( dword ); }
-
- // Operators
- bool operator ==( self_type const &o ) const
- { return this->base_type::operator ==( o ); }
- bool operator !=( self_type const &o ) const
- { return !this->operator ==( o ); }
+ {
+ this->context().worker.process_double_word( dword );
+ this->context().consume_dword( dword );
+ }
 
     // Extras
     static array<md5_digest::word_type, 64> generate_hashing_table()
@@ -417,13 +542,13 @@
     static char const hex_digits_uc[ number_of_hexadecimal_digits + 1 ];
 
     // MD words
- static std::size_t const nybbles_per_word = md5_digest::bits_per_word /
- bits_per_nybble;
+ static std::size_t const nybbles_per_word =
+ md5_digest::bits_per_word::value / bits_per_nybble;
 
     // MD strings
- static std::size_t const characters_per_digest = md5_digest::bits_per_word
- * md5_digest::words_per_digest / ( nybbles_per_hexadecimal_digit *
- bits_per_nybble );
+ static std::size_t const characters_per_digest =
+ md5_digest::bits_per_word::value * md5_digest::words_per_digest::value /
+ ( nybbles_per_hexadecimal_digit * bits_per_nybble );
 
 }; // md5_constants
 
@@ -450,7 +575,8 @@
 bool
 operator ==( md5_digest const &l, md5_digest const &r )
 {
- return std::equal( l.hash, l.hash + md5_digest::words_per_digest, r.hash );
+ return std::equal( l.hash, l.hash + md5_digest::words_per_digest::value,
+ r.hash );
 }
 
 /** \brief Not-equals

Modified: sandbox/md5/libs/coding/src/md5.cpp
==============================================================================
--- sandbox/md5/libs/coding/src/md5.cpp (original)
+++ sandbox/md5/libs/coding/src/md5.cpp 2008-08-02 16:12:09 EDT (Sat, 02 Aug 2008)
@@ -18,7 +18,7 @@
 
 #include <boost/array.hpp> // for boost::array
 #include <boost/assert.hpp> // for BOOST_ASSERT
-#include <boost/integer/integer_mask.hpp> // for boost::low_bits_mask_t
+#include <boost/integer/integer_mask.hpp> // for boost::integer_lo_mask
 #include <boost/math/common_factor_rt.hpp> // for boost::math::gcd
 #include <boost/static_assert.hpp> // for BOOST_STATIC_ASSERT
 
@@ -185,16 +185,6 @@
 {
 
 
-// MD5 message-digest class-static member definitions ----------------------//
-
-/** Represents the number of bits per word as given in RFC 1321, section 2.
- */
-int const md5_digest::bits_per_word;
-/** Represents the number of registers in a MD buffer.
- */
-std::size_t const md5_digest::words_per_digest;
-
-
 //! \cond
 // Implementation detail object definitions --------------------------------//
 
@@ -311,12 +301,18 @@
     0xEB86D391ul
 } };
 
+md5_context::hash_table_type const md5_context::hashing_table =
+ md5_computerX::hashing_table;
+
 // Initial values of the MD buffer, taken from RFC 1321, section 3.3. (Note
 // that the RFC lists each number low-order byte first, while numbers need to be
 // written high-order byte first in C++.)
 md5_computerX::ibuffer_type const md5_computerX::initial_buffer_ = {
  {0x67452301ul, 0xEFCDAB89ul, 0x98BADCFEul, 0x10325476ul} };
 
+md5_context::buffer_type const md5_context::initial_buffer =
+ md5_computerX::initial_buffer_;
+
 
 // MD5 message-digest computer class-static member function definitions ----//
 
@@ -350,6 +346,89 @@
 
 // Hash an entire block into the running checksum, using RFC 1321, section 3.4
 void
+md5_context::update_hash()
+{
+ using std::size_t;
+
+ // Convert the queued bit block to a word block
+ std::valarray<word_ftype> words( words_per_block::value ),
+ scratch( words_per_block::value ); // for later
+
+ for ( size_t i = 0u ; i < words_per_block::value ; ++i )
+ {
+ // Use the default inner-product; since "queue" has "bool" elements,
+ // which convert to 0 or 1, multiplication acts as AND; since
+ // "order_in_word" has distinct single-bit values, addition acts as OR.
+ words[ i ] = std::inner_product( order_in_word.begin(),
+ order_in_word.end(), this->queue.begin() + i * bits_per_word::value,
+ word_ftype(0u) );
+ }
+
+ // Set up rounds
+ buffer_type buffer = this->buffer;
+
+ // Round 1
+ {
+ md5_special_op<md5_f, word_ftype, bits_per_word::value> ff;
+
+ scratch = words[ skipped_indices(words_per_block::value, 0, 1) ];
+ for ( size_t i = 0u ; i < words_per_block::value ; ++i )
+ {
+ ff( buffer[( 16u - i ) % 4u], buffer[( 17u - i ) % 4u],
+ buffer[( 18u - i ) % 4u], buffer[( 19u - i ) % 4u], scratch[i],
+ md5_s[0][i % 4u], hashing_table[i] );
+ }
+ }
+
+ // Round 2
+ {
+ md5_special_op<md5_g, word_ftype, bits_per_word::value> gg;
+
+ scratch = words[ skipped_indices(words_per_block::value, 1, 5) ];
+ for ( size_t i = 0u ; i < words_per_block::value ; ++i )
+ {
+ gg( buffer[( 16u - i ) % 4u], buffer[( 17u - i ) % 4u],
+ buffer[( 18u - i ) % 4u], buffer[( 19u - i ) % 4u], scratch[i],
+ md5_s[1][i % 4u], hashing_table[16 + i] );
+ }
+ }
+
+ // Round 3
+ {
+ md5_special_op<md5_h, word_ftype, bits_per_word::value> hh;
+
+ scratch = words[ skipped_indices(words_per_block::value, 5, 3) ];
+ for ( size_t i = 0u ; i < words_per_block::value ; ++i )
+ {
+ hh( buffer[( 16u - i ) % 4u], buffer[( 17u - i ) % 4u],
+ buffer[( 18u - i ) % 4u], buffer[( 19u - i ) % 4u], scratch[i],
+ md5_s[2][i % 4u], hashing_table[32 + i] );
+ }
+ }
+
+ // Round 4
+ {
+ md5_special_op<md5_i, word_ftype, bits_per_word::value> ii;
+
+ scratch = words[ skipped_indices(words_per_block::value, 0, 7) ];
+ for ( size_t i = 0u ; i < words_per_block::value ; ++i )
+ {
+ ii( buffer[( 16u - i ) % 4u], buffer[( 17u - i ) % 4u],
+ buffer[( 18u - i ) % 4u], buffer[( 19u - i ) % 4u], scratch[i],
+ md5_s[3][i % 4u], hashing_table[48 + i] );
+ }
+ }
+
+ // Update buffer
+ for ( size_t i = 0u ; i < words_per_digest::value ; ++i )
+ {
+ this->buffer[ i ] += buffer[ i ];
+ this->buffer[ i ] &= integer_lo_mask<bits_per_word::value>::value;
+ }
+}
+
+// Hash an entire block into the running checksum, using RFC 1321, section 3.4
+void
 md5_computerX::update_hash( bool const *queue_b, bool const *queue_e )
 {
     using std::size_t;
@@ -366,7 +445,7 @@
         // elements, which convert to 0 or 1, multiplication acts as AND; since
         // "order_in_word" has distinct single-bit values, addition acts as OR
         words[ i ] = std::inner_product( order_in_word.begin(),
- order_in_word.end(), &scratch[ i * md5_digest::bits_per_word ],
+ order_in_word.end(), &scratch[ i * md5_digest::bits_per_word::value ],
          iword_type(0u) );
     }
 
@@ -377,7 +456,7 @@
 
     // Round 1
     {
- md5_special_op<md5_f, iword_type, md5_digest::bits_per_word> ff;
+ md5_special_op<md5_f, iword_type, md5_digest::bits_per_word::value> ff;
 
         scratch = words[ skipped_indices(words_per_block, 0, 1) ];
         for ( size_t i = 0u ; i < words_per_block ; ++i )
@@ -390,7 +469,7 @@
 
     // Round 2
     {
- md5_special_op<md5_g, iword_type, md5_digest::bits_per_word> gg;
+ md5_special_op<md5_g, iword_type, md5_digest::bits_per_word::value> gg;
 
         scratch = words[ skipped_indices(words_per_block, 1, 5) ];
         for ( size_t i = 0u ; i < words_per_block ; ++i )
@@ -403,7 +482,7 @@
 
     // Round 3
     {
- md5_special_op<md5_h, iword_type, md5_digest::bits_per_word> hh;
+ md5_special_op<md5_h, iword_type, md5_digest::bits_per_word::value> hh;
 
         scratch = words[ skipped_indices(words_per_block, 5, 3) ];
         for ( size_t i = 0u ; i < words_per_block ; ++i )
@@ -416,7 +495,7 @@
 
     // Round 4
     {
- md5_special_op<md5_i, iword_type, md5_digest::bits_per_word> ii;
+ md5_special_op<md5_i, iword_type, md5_digest::bits_per_word::value> ii;
 
         scratch = words[ skipped_indices(words_per_block, 0, 7) ];
         for ( size_t i = 0u ; i < words_per_block ; ++i )
@@ -428,11 +507,11 @@
     }
 
     // Update buffer
- for ( size_t i = 0u ; i < md5_digest::words_per_digest ; ++i )
+ for ( size_t i = 0u ; i < md5_digest::words_per_digest::value ; ++i )
     {
         this->buffer_[ i ] += buffer[ i ];
- this->buffer_[ i ] &= low_bits_mask_t< md5_digest :: bits_per_word > ::
- sig_bits;
+ this->buffer_[ i ] &= integer_lo_mask<md5_digest::bits_per_word::value>
+ ::value;
     }
 }
 


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk