$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r61670 - in sandbox/hash: boost/hash boost/hash/detail libs/hash/test
From: me22.ca+boost_at_[hidden]
Date: 2010-04-28 21:25:10
Author: smcmurray
Date: 2010-04-28 21:25:09 EDT (Wed, 28 Apr 2010)
New Revision: 61670
URL: http://svn.boost.org/trac/boost/changeset/61670
Log:
Hash: Add platform endianness pack, and specialize so little- or big-byte packers (depending on platform) use it for byte-oriented packing
Text files modified: 
   sandbox/hash/boost/hash/bitstream_endian.hpp    |    11 ++--                                    
   sandbox/hash/boost/hash/detail/exploder.hpp     |    30 +++++++++++++                           
   sandbox/hash/boost/hash/detail/imploder.hpp     |    30 +++++++++++++                           
   sandbox/hash/boost/hash/digest.hpp              |     4                                         
   sandbox/hash/boost/hash/pack.hpp                |    83 +++++++++++++++++++++++++++++++++------ 
   sandbox/hash/boost/hash/stream_preprocessor.hpp |     2                                         
   sandbox/hash/libs/hash/test/shacal.cpp          |     2                                         
   7 files changed, 138 insertions(+), 24 deletions(-)
Modified: sandbox/hash/boost/hash/bitstream_endian.hpp
==============================================================================
--- sandbox/hash/boost/hash/bitstream_endian.hpp	(original)
+++ sandbox/hash/boost/hash/bitstream_endian.hpp	2010-04-28 21:25:09 EDT (Wed, 28 Apr 2010)
@@ -13,12 +13,11 @@
 namespace hash {
 
 namespace bitstream_endian {
-    enum type {
-        big_byte_big_bit,
-        little_byte_big_bit,
-        big_byte_little_bit,
-        little_byte_little_bit,
-    };
+    struct big_byte_big_bit {};
+    struct little_byte_big_bit {};
+    struct big_byte_little_bit {};
+    struct little_byte_little_bit {};
+    struct platform {};
 }
 
 } // namespace hash
Modified: sandbox/hash/boost/hash/detail/exploder.hpp
==============================================================================
--- sandbox/hash/boost/hash/detail/exploder.hpp	(original)
+++ sandbox/hash/boost/hash/detail/exploder.hpp	2010-04-28 21:25:09 EDT (Wed, 28 Apr 2010)
@@ -13,11 +13,14 @@
 #include <boost/hash/detail/unbounded_shift.hpp>
 #include <boost/static_assert.hpp>
 
+#include <climits>
+#include <cstring>
+
 namespace boost {
 namespace hash {
 namespace detail {
 
-template <bitstream_endian::type Endianness,
+template <typename Endianness,
           int InputBits, int OutputBits,
           int k = 0>
 struct exploder;
@@ -138,6 +141,31 @@
     static void explode1_array(OutputType &, unsigned &, IntputValue) {}
 };
 
+template <int InputBits, int OutputBits,
+          int k>
+struct exploder<bitstream_endian::platform,
+                InputBits, OutputBits, k> {
+    BOOST_STATIC_ASSERT(InputBits  % CHAR_BIT == 0);
+    BOOST_STATIC_ASSERT(OutputBits % CHAR_BIT == 0);
+    template <typename OutputValue, typename InputValue>
+    static void step(OutputValue &z, InputValue x) {
+        std::memcpy(&z, (char*)&x + k/CHAR_BIT, OutputBits/CHAR_BIT);
+    }
+    template <typename OutputType, typename InputValue>
+    static void explode1_array(OutputType &out, unsigned &i, InputValue x) {
+        step(out[i++], x);
+        exploder<bitstream_endian::platform,
+                InputBits, OutputBits, k+OutputBits>
+         ::explode1_array(out, i, x);
+    }
+};
+template <int InputBits, int OutputBits>
+struct exploder<bitstream_endian::platform,
+                InputBits, OutputBits, InputBits> {
+    template <typename OutputType, typename IntputValue>
+    static void explode1_array(OutputType &, unsigned &, IntputValue) {}
+};
+
 } // namespace detail
 } // namespace hash
 } // namespace boost
Modified: sandbox/hash/boost/hash/detail/imploder.hpp
==============================================================================
--- sandbox/hash/boost/hash/detail/imploder.hpp	(original)
+++ sandbox/hash/boost/hash/detail/imploder.hpp	2010-04-28 21:25:09 EDT (Wed, 28 Apr 2010)
@@ -13,11 +13,14 @@
 #include <boost/hash/detail/unbounded_shift.hpp>
 #include <boost/static_assert.hpp>
 
+#include <climits>
+#include <cstring>
+
 namespace boost {
 namespace hash {
 namespace detail {
 
-template <bitstream_endian::type Endianness,
+template <typename Endianness,
           int InputBits, int OutputBits,
           int k = 0>
 struct imploder;
@@ -138,6 +141,31 @@
     static void implode1_array(InputType const &, unsigned &, OutputValue &) {}
 };
 
+template <int InputBits, int OutputBits,
+          int k>
+struct imploder<bitstream_endian::platform,
+                InputBits, OutputBits, k> {
+    BOOST_STATIC_ASSERT(InputBits  % CHAR_BIT == 0);
+    BOOST_STATIC_ASSERT(OutputBits % CHAR_BIT == 0);
+    template <typename InputValue, typename OutputValue>
+    static void step(InputValue z, OutputValue &x) {
+        std::memcpy((char*)&x + k/CHAR_BIT, &z, InputBits/CHAR_BIT);
+    }
+    template <typename InputType, typename OutputValue>
+    static void implode1_array(InputType const &in, unsigned &i, OutputValue &x) {
+        step(in[i++], x);
+        imploder<bitstream_endian::platform,
+                InputBits, OutputBits, k+InputBits>
+         ::implode1_array(in, i, x);
+    }
+};
+template <int InputBits, int OutputBits>
+struct imploder<bitstream_endian::platform,
+                InputBits, OutputBits, OutputBits> {
+    template <typename InputType, typename OutputValue>
+    static void implode1_array(InputType const &, unsigned &, OutputValue &) {}
+};
+
 } // namespace detail
 } // namespace hash
 } // namespace boost
Modified: sandbox/hash/boost/hash/digest.hpp
==============================================================================
--- sandbox/hash/boost/hash/digest.hpp	(original)
+++ sandbox/hash/boost/hash/digest.hpp	2010-04-28 21:25:09 EDT (Wed, 28 Apr 2010)
@@ -60,7 +60,7 @@
         return s;
     }
 
-    template <bitstream_endian::type endian,
+    template <typename endian,
               unsigned state_bits,
               unsigned word_bits,
               typename state_type>
@@ -83,7 +83,7 @@
 };
 
 template <typename digest_type_,
-          bitstream_endian::type endian>
+          typename endian>
 struct digest_from_state {
     typedef digest_type_ digest_type;
     template <unsigned state_bits,
Modified: sandbox/hash/boost/hash/pack.hpp
==============================================================================
--- sandbox/hash/boost/hash/pack.hpp	(original)
+++ sandbox/hash/boost/hash/pack.hpp	2010-04-28 21:25:09 EDT (Wed, 28 Apr 2010)
@@ -15,18 +15,26 @@
 #include <boost/hash/detail/imploder.hpp>
 #include <boost/static_assert.hpp>
 
+#ifndef BOOST_HASH_NO_OPTIMIZATION
+#include <boost/detail/endian.hpp>
+#endif
+
 namespace boost {
 namespace hash {
 
-template <bitstream_endian::type Endianness,
+template <typename Endianness,
           int InputBits, int OutputBits,
           bool Explode = (InputBits > OutputBits),
-          bool Implode = (InputBits < OutputBits)>
+          bool Implode = (InputBits < OutputBits),
+          bool BytesOnly = (InputBits % CHAR_BIT == 0 &&
+                            OutputBits % CHAR_BIT == 0),
+          bool Prefer = true>
 struct packer;
 
-template <bitstream_endian::type Endianness,
-          int Bits>
-struct packer<Endianness, Bits, Bits, false, false> {
+template <typename Endianness,
+          int Bits,
+          bool BytesOnly>
+struct packer<Endianness, Bits, Bits, false, false, BytesOnly, false> {
 
     template <typename OutputType, typename InputType>
     static OutputType pack_array(InputType const &in) {
@@ -41,11 +49,12 @@
 
 };
 
-template <bitstream_endian::type Endianness,
-          int InputBits, int OutputBits>
+template <typename Endianness,
+          int InputBits, int OutputBits,
+          bool BytesOnly>
 struct packer<Endianness,
               InputBits, OutputBits,
-              true, false> {
+              true, false, BytesOnly, false> {
 
     BOOST_STATIC_ASSERT(InputBits % OutputBits == 0);
 
@@ -65,11 +74,12 @@
 
 };
 
-template <bitstream_endian::type Endianness,
-          int InputBits, int OutputBits>
+template <typename Endianness,
+          int InputBits, int OutputBits,
+          bool BytesOnly>
 struct packer<Endianness,
               InputBits, OutputBits,
-              false, true> {
+              false, true, BytesOnly, false> {
 
     BOOST_STATIC_ASSERT(OutputBits % InputBits == 0);
 
@@ -89,9 +99,56 @@
 
 };
 
-// TODO: Add specializations to optimize the easy platform-endianness cases
+// Forward Prefer to !Prefer if nothing better matches
+template <typename Endianness,
+          int InputBits, int OutputBits,
+          bool Explode, bool Implode, bool BytesOnly>
+struct packer<Endianness,
+              InputBits, OutputBits,
+              Explode, Implode, BytesOnly, true>
+ : packer<Endianness,
+              InputBits, OutputBits,
+              Explode, Implode, BytesOnly, false> {};
+
+#ifndef BOOST_HASH_NO_OPTIMIZATION
+
+#ifdef BOOST_LITTLE_ENDIAN
+template <int InputBits, int OutputBits, bool Ex, bool Im>
+struct packer<bitstream_endian::little_byte_big_bit,
+              InputBits, OutputBits,
+              Ex, Im, true, true>
+ : packer<bitstream_endian::platform,
+          InputBits, OutputBits,
+          Ex, Im, true, true> {};
+template <int InputBits, int OutputBits, bool Ex, bool Im>
+struct packer<bitstream_endian::little_byte_little_bit,
+              InputBits, OutputBits,
+              Ex, Im, true, true>
+ : packer<bitstream_endian::platform,
+          InputBits, OutputBits,
+          Ex, Im, true, true> {};
+#endif
+
+#ifdef BOOST_BIG_ENDIAN
+template <int InputBits, int OutputBits, bool Ex, bool Im>
+struct packer<bitstream_endian::big_byte_big_bit,
+              InputBits, OutputBits,
+              Ex, Im, true, true>
+ : packer<bitstream_endian::platform,
+          InputBits, OutputBits,
+          Ex, Im, true, true> {};
+template <int InputBits, int OutputBits, bool Ex, bool Im>
+struct packer<bitstream_endian::big_byte_little_bit,
+              InputBits, OutputBits,
+              Ex, Im, true, true>
+ : packer<bitstream_endian::platform,
+          InputBits, OutputBits,
+          Ex, Im, true, true> {};
+#endif
+
+#endif
 
-template <bitstream_endian::type Endianness,
+template <typename Endianness,
           int InBits, int OutBits,
           typename T1, typename T2>
 void pack(T1 const &in, T2 &out) {
Modified: sandbox/hash/boost/hash/stream_preprocessor.hpp
==============================================================================
--- sandbox/hash/boost/hash/stream_preprocessor.hpp	(original)
+++ sandbox/hash/boost/hash/stream_preprocessor.hpp	2010-04-28 21:25:09 EDT (Wed, 28 Apr 2010)
@@ -22,7 +22,7 @@
 // This will do the usual Merkle-DamgÃ¥rd-style strengthening, padding with
 // a 1 bit, then 0 bits as needed, then, if requested, the length.
 //
-template <bitstream_endian::type endian,
+template <typename endian,
           unsigned value_bits_,
           unsigned length_bits_,
           typename block_hash_T>
Modified: sandbox/hash/libs/hash/test/shacal.cpp
==============================================================================
--- sandbox/hash/libs/hash/test/shacal.cpp	(original)
+++ sandbox/hash/libs/hash/test/shacal.cpp	2010-04-28 21:25:09 EDT (Wed, 28 Apr 2010)
@@ -194,6 +194,7 @@
     typedef sha1_byte_hash::digest_type digest_type;
 
 #ifndef BOOST_HASH_SHOW_PROGRESS
+#ifndef QUICK
     {
     // perl -e 'for ($x = 1000000000; $x--;) {print "a";}' | sha1sum
     sha1_byte_hash h;
@@ -204,6 +205,7 @@
     assert(!strcmp(ed, d.cstring().data()));
     }
 #endif
+#endif
 }
 
 void test_sha512() {