Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r75105 - in trunk: boost/spirit/home/karma/binary boost/spirit/home/qi/binary boost/spirit/home/support boost/spirit/home/support/detail/endian libs/spirit/doc libs/spirit/doc/karma libs/spirit/doc/qi libs/spirit/test/karma libs/spirit/test/qi
From: hartmut.kaiser_at_[hidden]
Date: 2011-10-24 11:05:46


Author: hkaiser
Date: 2011-10-24 11:05:44 EDT (Mon, 24 Oct 2011)
New Revision: 75105
URL: http://svn.boost.org/trac/boost/changeset/75105

Log:
Spirit: applying Vitaly Budovski's patch adding binary floating point parsers and generators
Text files modified:
   trunk/boost/spirit/home/karma/binary/binary.hpp | 119 ++++++++++++++++++++++-----
   trunk/boost/spirit/home/qi/binary/binary.hpp | 129 ++++++++++++++++++++++++-----
   trunk/boost/spirit/home/support/common_terminals.hpp | 6 +
   trunk/boost/spirit/home/support/detail/endian/endian.hpp | 154 +++++++++++++++++++++++++++++++++--
   trunk/libs/spirit/doc/index.idx | 18 +++
   trunk/libs/spirit/doc/karma/binary.qbk | 172 ++++++++++++++++++++++++++++++---------
   trunk/libs/spirit/doc/qi/binary.qbk | 88 +++++++++++++++----
   trunk/libs/spirit/doc/spirit2.qbk | 4
   trunk/libs/spirit/doc/what_s_new.qbk | 30 ++++--
   trunk/libs/spirit/test/karma/binary1.cpp | 20 ++++
   trunk/libs/spirit/test/karma/binary2.cpp | 26 ++++++
   trunk/libs/spirit/test/karma/binary3.cpp | 40 +++++++++
   trunk/libs/spirit/test/qi/binary.cpp | 38 ++++++++
   trunk/libs/spirit/test/qi/test.hpp | 52 ++++++++++++
   14 files changed, 762 insertions(+), 134 deletions(-)

Modified: trunk/boost/spirit/home/karma/binary/binary.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/binary/binary.hpp (original)
+++ trunk/boost/spirit/home/karma/binary/binary.hpp 2011-10-24 11:05:44 EDT (Mon, 24 Oct 2011)
@@ -27,6 +27,7 @@
 #include <boost/mpl/or.hpp>
 #include <boost/type_traits/is_integral.hpp>
 #include <boost/type_traits/is_enum.hpp>
+#include <boost/type_traits/is_floating_point.hpp>
 #include <boost/config.hpp>
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -45,6 +46,19 @@
                                                                               \
 /***/
 
+#define BOOST_SPIRIT_ENABLE_BINARY_IEEE754(name) \
+ template<> \
+ struct use_terminal<karma::domain, tag::name>: mpl::true_ {}; \
+ \
+ template<typename A0> \
+ struct use_terminal<karma::domain, terminal_ex<tag::name, \
+ fusion::vector1<A0> > >: is_floating_point<A0> {}; \
+ \
+ template<> \
+ struct use_lazy_terminal<karma::domain, tag::name, 1> : mpl::true_ {}; \
+ \
+/***/
+
 namespace boost { namespace spirit
 {
     ///////////////////////////////////////////////////////////////////////////
@@ -63,10 +77,16 @@
     BOOST_SPIRIT_ENABLE_BINARY(big_qword) // enables big_qword
     BOOST_SPIRIT_ENABLE_BINARY(little_qword) // enables little_qword
 #endif
-
+ BOOST_SPIRIT_ENABLE_BINARY_IEEE754(bin_float)
+ BOOST_SPIRIT_ENABLE_BINARY_IEEE754(big_bin_float)
+ BOOST_SPIRIT_ENABLE_BINARY_IEEE754(little_bin_float)
+ BOOST_SPIRIT_ENABLE_BINARY_IEEE754(bin_double)
+ BOOST_SPIRIT_ENABLE_BINARY_IEEE754(big_bin_double)
+ BOOST_SPIRIT_ENABLE_BINARY_IEEE754(little_bin_double)
 }}
 
 #undef BOOST_SPIRIT_ENABLE_BINARY
+#undef BOOST_SPIRIT_ENABLE_BINARY_IEEE754
 
 ///////////////////////////////////////////////////////////////////////////////
 namespace boost { namespace spirit { namespace karma
@@ -84,6 +104,12 @@
     using boost::spirit::big_qword;
     using boost::spirit::little_qword;
 #endif
+ using boost::spirit::bin_float;
+ using boost::spirit::big_bin_float;
+ using boost::spirit::little_bin_float;
+ using boost::spirit::bin_double;
+ using boost::spirit::big_bin_double;
+ using boost::spirit::little_bin_double;
 #endif
 
     using boost::spirit::byte_type;
@@ -98,6 +124,12 @@
     using boost::spirit::big_qword_type;
     using boost::spirit::little_qword_type;
 #endif
+ using boost::spirit::bin_float_type;
+ using boost::spirit::big_bin_float_type;
+ using boost::spirit::little_bin_float_type;
+ using boost::spirit::bin_double_type;
+ using boost::spirit::big_bin_double_type;
+ using boost::spirit::little_bin_double_type;
 
     namespace detail
     {
@@ -141,6 +173,26 @@
         };
 #endif
 
+ template <int bits>
+ struct floating_point
+ {
+ BOOST_SPIRIT_ASSERT_MSG(
+ bits == 32 || bits == 64,
+ not_supported_binary_size, ());
+ };
+
+ template <>
+ struct floating_point<32>
+ {
+ typedef float type;
+ };
+
+ template <>
+ struct floating_point<64>
+ {
+ typedef double type;
+ };
+
         ///////////////////////////////////////////////////////////////////////
         template <BOOST_SCOPED_ENUM(boost::endian::endianness) bits>
         struct what;
@@ -174,14 +226,12 @@
     }
 
     ///////////////////////////////////////////////////////////////////////////
- template <BOOST_SCOPED_ENUM(boost::endian::endianness) endian, int bits>
+ template <typename T, BOOST_SCOPED_ENUM(boost::endian::endianness) endian, int bits>
     struct any_binary_generator
- : primitive_generator<any_binary_generator<endian, bits> >
+ : primitive_generator<any_binary_generator<T, endian, bits> >
     {
         template <typename Context, typename Unused = unused_type>
- struct attribute
- : karma::detail::integer<bits>
- {};
+ struct attribute: T {};
 
         template <
             typename OutputIterator, typename Context, typename Delimiter
@@ -195,16 +245,14 @@
             // Even if the endian types are not pod's (at least not in the
             // definition of C++03) it seems to be safe to assume they are.
             // This allows us to treat them as a sequence of consecutive bytes.
- boost::endian::endian<
- endian, typename karma::detail::integer<bits>::type, bits
- > p;
+ boost::endian::endian<endian, typename T::type, bits> p;
 
 #if defined(BOOST_MSVC)
 // warning C4244: 'argument' : conversion from 'const int' to 'foo', possible loss of data
 #pragma warning(push)
 #pragma warning(disable: 4244)
 #endif
- typedef typename karma::detail::integer<bits>::type attribute_type;
+ typedef typename T::type attribute_type;
             p = traits::extract_from<attribute_type>(attr, context);
 #if defined(BOOST_MSVC)
 #pragma warning(pop)
@@ -245,9 +293,9 @@
     };
 
     ///////////////////////////////////////////////////////////////////////////
- template <BOOST_SCOPED_ENUM(boost::endian::endianness) endian, int bits>
+ template <typename T, BOOST_SCOPED_ENUM(boost::endian::endianness) endian, int bits>
     struct literal_binary_generator
- : primitive_generator<literal_binary_generator<endian, bits> >
+ : primitive_generator<literal_binary_generator<T, endian, bits> >
     {
         template <typename Context, typename Unused>
         struct attribute
@@ -255,15 +303,15 @@
             typedef unused_type type;
         };
 
- template <typename T>
- literal_binary_generator(T const& t)
+ template <typename V>
+ literal_binary_generator(V const& v)
         {
 #if defined(BOOST_MSVC)
 // warning C4244: 'argument' : conversion from 'const int' to 'foo', possible loss of data
 #pragma warning(push)
 #pragma warning(disable: 4244)
 #endif
- data_ = t;
+ data_ = v;
 #if defined(BOOST_MSVC)
 #pragma warning(pop)
 #endif
@@ -296,9 +344,8 @@
             return karma::detail::what<endian>::is();
         }
 
- typedef boost::endian::endian<
- endian, typename karma::detail::integer<bits>::type, bits
- > data_type;
+ typedef boost::endian::endian<endian, typename T::type,
+ bits> data_type;
 
         data_type data_;
     };
@@ -308,11 +355,11 @@
     ///////////////////////////////////////////////////////////////////////////
     namespace detail
     {
- template <BOOST_SCOPED_ENUM(boost::endian::endianness) endian
+ template <typename T, BOOST_SCOPED_ENUM(boost::endian::endianness) endian
           , int bits>
         struct basic_binary
         {
- typedef any_binary_generator<endian, bits> result_type;
+ typedef any_binary_generator<T, endian, bits> result_type;
 
             result_type operator()(unused_type, unused_type) const
             {
@@ -320,11 +367,11 @@
             }
         };
 
- template <typename Modifiers
+ template <typename Modifiers, typename T
           , BOOST_SCOPED_ENUM(boost::endian::endianness) endian, int bits>
         struct basic_binary_literal
         {
- typedef literal_binary_generator<endian, bits> result_type;
+ typedef literal_binary_generator<T, endian, bits> result_type;
 
             template <typename Terminal>
             result_type operator()(Terminal const& term, unused_type) const
@@ -337,12 +384,13 @@
 #define BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(name, endiantype, bits) \
     template <typename Modifiers> \
     struct make_primitive<tag::name, Modifiers> \
- : detail::basic_binary<boost::endian::endianness::endiantype, bits> {}; \
+ : detail::basic_binary<detail::integer<bits>, \
+ boost::endian::endianness::endiantype, bits> {}; \
                                                                               \
     template <typename Modifiers, typename A0> \
     struct make_primitive<terminal_ex<tag::name, fusion::vector1<A0> > \
           , Modifiers> \
- : detail::basic_binary_literal<Modifiers \
+ : detail::basic_binary_literal<Modifiers, detail::integer<bits> \
         , boost::endian::endianness::endiantype, bits> {}; \
                                                                               \
     /***/
@@ -362,6 +410,29 @@
 
 #undef BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE
 
+#define BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE(name, endiantype, bits) \
+ template <typename Modifiers> \
+ struct make_primitive<tag::name, Modifiers> \
+ : detail::basic_binary<detail::floating_point<bits>, \
+ boost::endian::endianness::endiantype, bits> {}; \
+ \
+ template <typename Modifiers, typename A0> \
+ struct make_primitive<terminal_ex<tag::name, fusion::vector1<A0> > \
+ , Modifiers> \
+ : detail::basic_binary_literal<Modifiers, detail::floating_point<bits> \
+ , boost::endian::endianness::endiantype, bits> {}; \
+ \
+ /***/
+
+ BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE(bin_float, native, 32)
+ BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE(big_bin_float, big, 32)
+ BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE(little_bin_float, little, 32)
+ BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE(bin_double, native, 64)
+ BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE(big_bin_double, big, 64)
+ BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE(little_bin_double, little, 64)
+
+#undef BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE
+
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/qi/binary/binary.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/binary/binary.hpp (original)
+++ trunk/boost/spirit/home/qi/binary/binary.hpp 2011-10-24 11:05:44 EDT (Mon, 24 Oct 2011)
@@ -25,6 +25,7 @@
 #include <boost/mpl/or.hpp>
 #include <boost/type_traits/is_integral.hpp>
 #include <boost/type_traits/is_enum.hpp>
+#include <boost/type_traits/is_floating_point.hpp>
 #include <boost/config.hpp>
 
 #define BOOST_SPIRIT_ENABLE_BINARY(name) \
@@ -42,6 +43,19 @@
                                                                                 \
 /***/
 
+#define BOOST_SPIRIT_ENABLE_BINARY_IEEE754(name) \
+ template<> \
+ struct use_terminal<qi::domain, tag::name>: mpl::true_ {}; \
+ \
+ template<typename A0> \
+ struct use_terminal<qi::domain, terminal_ex<tag::name, \
+ fusion::vector1<A0> > >: is_floating_point<A0> {}; \
+ \
+ template<> \
+ struct use_lazy_terminal<qi::domain, tag::name, 1>: mpl::true_ {}; \
+ \
+/***/
+
 namespace boost { namespace spirit
 {
     ///////////////////////////////////////////////////////////////////////////
@@ -59,9 +73,16 @@
     BOOST_SPIRIT_ENABLE_BINARY(big_qword) // enables big_qword
     BOOST_SPIRIT_ENABLE_BINARY(little_qword) // enables little_qword
 #endif
+ BOOST_SPIRIT_ENABLE_BINARY_IEEE754(bin_float)
+ BOOST_SPIRIT_ENABLE_BINARY_IEEE754(big_bin_float)
+ BOOST_SPIRIT_ENABLE_BINARY_IEEE754(little_bin_float)
+ BOOST_SPIRIT_ENABLE_BINARY_IEEE754(bin_double)
+ BOOST_SPIRIT_ENABLE_BINARY_IEEE754(big_bin_double)
+ BOOST_SPIRIT_ENABLE_BINARY_IEEE754(little_bin_double)
 }}
 
 #undef BOOST_SPIRIT_ENABLE_BINARY
+#undef BOOST_SPIRIT_ENABLE_BINARY_IEEE754
 
 namespace boost { namespace spirit { namespace qi
 {
@@ -78,6 +99,12 @@
     using boost::spirit::big_qword;
     using boost::spirit::little_qword;
 #endif
+ using boost::spirit::bin_float;
+ using boost::spirit::big_bin_float;
+ using boost::spirit::little_bin_float;
+ using boost::spirit::bin_double;
+ using boost::spirit::big_bin_double;
+ using boost::spirit::little_bin_double;
 #endif
 
     using boost::spirit::byte_type;
@@ -92,6 +119,12 @@
     using boost::spirit::big_qword_type;
     using boost::spirit::little_qword_type;
 #endif
+ using boost::spirit::bin_float_type;
+ using boost::spirit::big_bin_float_type;
+ using boost::spirit::little_bin_float_type;
+ using boost::spirit::bin_double_type;
+ using boost::spirit::big_bin_double_type;
+ using boost::spirit::little_bin_double_type;
 
     namespace detail
     {
@@ -139,6 +172,28 @@
         };
 #endif
 
+ template <int bits>
+ struct floating_point
+ {
+ BOOST_SPIRIT_ASSERT_MSG(
+ bits == 32 || bits == 64,
+ not_supported_binary_size, ());
+ };
+
+ template <>
+ struct floating_point<32>
+ {
+ enum { size = 4 };
+ typedef float type;
+ };
+
+ template <>
+ struct floating_point<64>
+ {
+ enum { size = 8 };
+ typedef double type;
+ };
+
         ///////////////////////////////////////////////////////////////////////
         template <BOOST_SCOPED_ENUM(boost::endian::endianness) bits>
         struct what;
@@ -172,15 +227,14 @@
     }
 
     ///////////////////////////////////////////////////////////////////////////
- template <BOOST_SCOPED_ENUM(boost::endian::endianness) endian, int bits>
- struct any_binary_parser : primitive_parser<any_binary_parser<endian, bits> >
+ template <typename T, BOOST_SCOPED_ENUM(boost::endian::endianness) endian, int bits>
+ struct any_binary_parser : primitive_parser<any_binary_parser<T, endian, bits> >
     {
         template <typename Context, typename Iterator>
         struct attribute
         {
- typedef boost::endian::endian<
- endian, typename qi::detail::integer<bits>::type, bits
- > type;
+ typedef boost::endian::endian<endian, typename T::type,
+ bits> type;
         };
 
         template <typename Iterator, typename Context
@@ -215,10 +269,10 @@
     };
 
     ///////////////////////////////////////////////////////////////////////////
- template <typename Int
+ template <typename V, typename T
       , BOOST_SCOPED_ENUM(boost::endian::endianness) endian, int bits>
     struct binary_lit_parser
- : primitive_parser<binary_lit_parser<Int, endian, bits> >
+ : primitive_parser<binary_lit_parser<V, T, endian, bits> >
     {
         template <typename Context, typename Iterator>
         struct attribute
@@ -226,7 +280,7 @@
             typedef unused_type type;
         };
 
- binary_lit_parser(Int n)
+ binary_lit_parser(V n)
           : n(n) {}
 
         template <typename Iterator, typename Context
@@ -241,8 +295,7 @@
             // definition of C++03) it seems to be safe to assume they are
             // (but in C++0x the endian types _are_ PODs).
             // This allows us to treat them as a sequence of consecutive bytes.
- boost::endian::endian<
- endian, typename qi::detail::integer<bits>::type, bits> attr_;
+ boost::endian::endian<endian, typename T::type, bits> attr_;
 
 #if defined(BOOST_MSVC)
 // warning C4244: 'argument' : conversion from 'const int' to 'foo', possible loss of data
@@ -274,27 +327,27 @@
             return info(qi::detail::what<endian>::is());
         }
 
- Int n;
+ V n;
     };
 
     ///////////////////////////////////////////////////////////////////////////
     // Parser generators: make_xxx function (objects)
     ///////////////////////////////////////////////////////////////////////////
- template <BOOST_SCOPED_ENUM(boost::endian::endianness) endian, int bits>
+ template <typename T, BOOST_SCOPED_ENUM(boost::endian::endianness) endian, int bits>
     struct make_binary_parser
     {
- typedef any_binary_parser<endian, bits> result_type;
+ typedef any_binary_parser<T, endian, bits> result_type;
         result_type operator()(unused_type, unused_type) const
         {
             return result_type();
         }
     };
 
- template <typename Int
+ template <typename V, typename T
       , BOOST_SCOPED_ENUM(boost::endian::endianness) endian, int bits>
     struct make_binary_lit_parser
     {
- typedef binary_lit_parser<Int, endian, bits> result_type;
+ typedef binary_lit_parser<V, T, endian, bits> result_type;
         template <typename Terminal>
         result_type operator()(Terminal const& term, unused_type) const
         {
@@ -302,16 +355,18 @@
         }
     };
 
-#define BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(name, endiantype, bits) \
- template <typename Modifiers> \
- struct make_primitive<tag::name, Modifiers> \
- : make_binary_parser<boost::endian::endianness::endiantype, bits> {}; \
- \
- template <typename Modifiers, typename A0> \
- struct make_primitive< \
- terminal_ex<tag::name, fusion::vector1<A0> > , Modifiers> \
- : make_binary_lit_parser<A0, boost::endian::endianness::endiantype, bits> {};\
- \
+#define BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(name, endiantype, bits) \
+ template <typename Modifiers> \
+ struct make_primitive<tag::name, Modifiers> \
+ : make_binary_parser<detail::integer<bits>, \
+ boost::endian::endianness::endiantype, bits> {}; \
+ \
+ template <typename Modifiers, typename A0> \
+ struct make_primitive< \
+ terminal_ex<tag::name, fusion::vector1<A0> > , Modifiers> \
+ : make_binary_lit_parser<A0, detail::integer<bits>, \
+ boost::endian::endianness::endiantype, bits> {}; \
+ \
     /***/
 
     BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(byte_, native, 8)
@@ -329,6 +384,30 @@
 
 #undef BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE
 
+#define BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE(name, endiantype, bits) \
+ template<typename Modifiers> \
+ struct make_primitive<tag::name, Modifiers> \
+ : make_binary_parser<detail::floating_point<bits>, \
+ boost::endian::endianness::endiantype, bits> {}; \
+ \
+ template<typename Modifiers, typename A0> \
+ struct make_primitive< \
+ terminal_ex<tag::name, fusion::vector1<A0> >, Modifiers> \
+ : make_binary_lit_parser<A0, detail::floating_point<bits>, \
+ boost::endian::endianness::endiantype, \
+ bits> {}; \
+ \
+ /***/
+
+ BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE(bin_float, native, 32)
+ BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE(big_bin_float, big, 32)
+ BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE(little_bin_float, little, 32)
+ BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE(bin_double, native, 64)
+ BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE(big_bin_double, big, 64)
+ BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE(little_bin_double, little, 64)
+
+#undef BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE
+
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/support/common_terminals.hpp
==============================================================================
--- trunk/boost/spirit/home/support/common_terminals.hpp (original)
+++ trunk/boost/spirit/home/support/common_terminals.hpp 2011-10-24 11:05:44 EDT (Mon, 24 Oct 2011)
@@ -116,6 +116,12 @@
         ( qword, qword_type )
         ( big_qword, big_qword_type )
         ( little_qword, little_qword_type )
+ ( bin_float, bin_float_type )
+ ( big_bin_float, big_bin_float_type )
+ ( little_bin_float, little_bin_float_type )
+ ( bin_double, bin_double_type )
+ ( big_bin_double, big_bin_double_type )
+ ( little_bin_double, little_bin_double_type )
         ( skip, skip_type )
         ( delimit, delimit_type )
         ( stream, stream_type )

Modified: trunk/boost/spirit/home/support/detail/endian/endian.hpp
==============================================================================
--- trunk/boost/spirit/home/support/detail/endian/endian.hpp (original)
+++ trunk/boost/spirit/home/support/detail/endian/endian.hpp 2011-10-24 11:05:44 EDT (Mon, 24 Oct 2011)
@@ -122,6 +122,44 @@
         (static_cast<const unsigned char*>(bytes) + n_bytes);
     }
 
+ template <>
+ inline
+ float load_big_endian<float, 4>(const void* bytes)
+ {
+ const unsigned char *b = reinterpret_cast<const unsigned char *>(
+ bytes);
+ b += 3;
+
+ float value;
+ unsigned char *v = reinterpret_cast<unsigned char *>(&value);
+
+ for(std::size_t i = 0; i < 4; ++i)
+ {
+ *v++ = *b--;
+ }
+
+ return value;
+ }
+
+ template <>
+ inline
+ double load_big_endian<double, 8>(const void* bytes)
+ {
+ const unsigned char *b = reinterpret_cast<const unsigned char *>(
+ bytes);
+ b += 7;
+
+ double value;
+ unsigned char *v = reinterpret_cast<unsigned char *>(&value);
+
+ for(std::size_t i = 0; i < 8; ++i)
+ {
+ *v++ = *b--;
+ }
+
+ return value;
+ }
+
     template <typename T, std::size_t n_bytes>
     inline
     T load_little_endian(const void* bytes)
@@ -130,6 +168,42 @@
         (static_cast<const unsigned char*>(bytes));
     }
 
+ template <>
+ inline
+ float load_little_endian<float, 4>(const void* bytes)
+ {
+ const unsigned char *b = reinterpret_cast<const unsigned char *>(
+ bytes);
+
+ float value;
+ unsigned char *v = reinterpret_cast<unsigned char *>(&value);
+
+ for(std::size_t i = 0; i < 4; ++i)
+ {
+ *v++ = *b++;
+ }
+
+ return value;
+ }
+
+ template <>
+ inline
+ double load_little_endian<double, 8>(const void* bytes)
+ {
+ const unsigned char *b = reinterpret_cast<const unsigned char *>(
+ bytes);
+
+ double value;
+ unsigned char *v = reinterpret_cast<unsigned char *>(&value);
+
+ for(std::size_t i = 0; i < 8; ++i)
+ {
+ *v++ = *b++;
+ }
+
+ return value;
+ }
+
     template <typename T, std::size_t n_bytes>
     inline
     void store_big_endian(void* bytes, T value)
@@ -138,6 +212,38 @@
         (static_cast<char*>(bytes) + n_bytes, value);
     }
 
+ template <>
+ inline
+ void store_big_endian<float, 4>(void* bytes, float value)
+ {
+ unsigned char *b = reinterpret_cast<unsigned char *>(bytes);
+ b += 3;
+
+ const unsigned char *v = reinterpret_cast<const unsigned char *>(
+ &value);
+
+ for(std::size_t i = 0; i < 4; ++i)
+ {
+ *b-- = *v++;
+ }
+ }
+
+ template <>
+ inline
+ void store_big_endian<double, 8>(void* bytes, double value)
+ {
+ unsigned char *b = reinterpret_cast<unsigned char *>(bytes);
+ b += 7;
+
+ const unsigned char *v = reinterpret_cast<const unsigned char *>(
+ &value);
+
+ for(std::size_t i = 0; i < 8; ++i)
+ {
+ *b-- = *v++;
+ }
+ }
+
     template <typename T, std::size_t n_bytes>
     inline
     void store_little_endian(void* bytes, T value)
@@ -146,6 +252,36 @@
         (static_cast<char*>(bytes), value);
     }
 
+ template <>
+ inline
+ void store_little_endian<float, 4>(void* bytes, float value)
+ {
+ unsigned char *b = reinterpret_cast<unsigned char *>(bytes);
+
+ const unsigned char *v = reinterpret_cast<const unsigned char *>(
+ &value);
+
+ for(std::size_t i = 0; i < 4; ++i)
+ {
+ *b++ = *v++;
+ }
+ }
+
+ template <>
+ inline
+ void store_little_endian<double, 8>(void* bytes, double value)
+ {
+ unsigned char *b = reinterpret_cast<unsigned char *>(bytes);
+
+ const unsigned char *v = reinterpret_cast<const unsigned char *>(
+ &value);
+
+ for(std::size_t i = 0; i < 8; ++i)
+ {
+ *b++ = *v++;
+ }
+ }
+
   } // namespace detail
 
   namespace endian
@@ -181,7 +317,7 @@
 # ifndef BOOST_ENDIAN_NO_CTORS
         endian() BOOST_ENDIAN_DEFAULT_CONSTRUCT
         explicit endian(T val)
- {
+ {
 # ifdef BOOST_ENDIAN_LOG
           if ( endian_log )
             std::clog << "big, unaligned, " << n_bits << "-bits, construct(" << val << ")\n";
@@ -191,7 +327,7 @@
 # endif
         endian & operator=(T val) { detail::store_big_endian<T, n_bits/8>(m_value, val); return *this; }
         operator T() const
- {
+ {
 # ifdef BOOST_ENDIAN_LOG
           if ( endian_log )
             std::clog << "big, unaligned, " << n_bits << "-bits, convert(" << detail::load_big_endian<T, n_bits/8>(m_value) << ")\n";
@@ -213,7 +349,7 @@
 # ifndef BOOST_ENDIAN_NO_CTORS
         endian() BOOST_ENDIAN_DEFAULT_CONSTRUCT
         explicit endian(T val)
- {
+ {
 # ifdef BOOST_ENDIAN_LOG
           if ( endian_log )
             std::clog << "little, unaligned, " << n_bits << "-bits, construct(" << val << ")\n";
@@ -223,7 +359,7 @@
 # endif
         endian & operator=(T val) { detail::store_little_endian<T, n_bits/8>(m_value, val); return *this; }
         operator T() const
- {
+ {
 # ifdef BOOST_ENDIAN_LOG
           if ( endian_log )
             std::clog << "little, unaligned, " << n_bits << "-bits, convert(" << detail::load_little_endian<T, n_bits/8>(m_value) << ")\n";
@@ -250,7 +386,7 @@
         explicit endian(T val) { detail::store_little_endian<T, n_bits/8>(m_value, val); }
 # endif
 # endif
-# ifdef BOOST_BIG_ENDIAN
+# ifdef BOOST_BIG_ENDIAN
         endian & operator=(T val) { detail::store_big_endian<T, n_bits/8>(m_value, val); return *this; }
         operator T() const { return detail::load_big_endian<T, n_bits/8>(m_value); }
 # else
@@ -281,13 +417,13 @@
         explicit endian(T val) { detail::store_big_endian<T, sizeof(T)>(&m_value, val); }
 # endif
 # endif
-# ifdef BOOST_BIG_ENDIAN
+# ifdef BOOST_BIG_ENDIAN
         endian & operator=(T val) { m_value = val; return *this; }
         operator T() const { return m_value; }
-# else
+# else
         endian & operator=(T val) { detail::store_big_endian<T, sizeof(T)>(&m_value, val); return *this; }
         operator T() const { return detail::load_big_endian<T, sizeof(T)>(&m_value); }
-# endif
+# endif
       private:
         T m_value;
     };
@@ -385,7 +521,7 @@
 #define BOOST_HAS_INT16_T
 #define BOOST_HAS_INT32_T
 #define BOOST_HAS_INT64_T
-
+
   // These types only present if platform has exact size integers:
   // aligned big endian signed integer types
   // aligned big endian unsigned integer types

Modified: trunk/libs/spirit/doc/index.idx
==============================================================================
--- trunk/libs/spirit/doc/index.idx (original)
+++ trunk/libs/spirit/doc/index.idx 2011-10-24 11:05:44 EDT (Mon, 24 Oct 2011)
@@ -6,8 +6,8 @@
 # http://www.boost.org/LICENSE_1_0.txt)
 #==============================================================================
 
-#!scan-path "../../../boost/spirit/home/qi" ".*hpp" true
-#!scan-path "../../../boost/spirit/home/karma" ".*hpp" true
+#!scan-path "../../../boost/spirit/home/qi" ".*hpp" true
+#!scan-path "../../../boost/spirit/home/karma" ".*hpp" true
 
 ###############################################################################
 # Qi API
@@ -59,23 +59,35 @@
 word "" ".*qi.reference.binary.binary_native.*" qi_index
 dword "" ".*qi.reference.binary.binary_native.*" qi_index
 qword "" ".*qi.reference.binary.binary_native.*" qi_index
+bin_float "" ".*qi.reference.binary.binary_native.*" qi_index
+bin_double "" ".*qi.reference.binary.binary_native.*" qi_index
 little_word "" ".*qi.reference.binary.binary_little.*" qi_index
 little_dword "" ".*qi.reference.binary.binary_little.*" qi_index
 little_qword "" ".*qi.reference.binary.binary_little.*" qi_index
+little_bin_float "" ".*qi.reference.binary.binary_little.*" qi_index
+little_bin_double "" ".*qi.reference.binary.binary_little.*" qi_index
 big_word "" ".*qi.reference.binary.binary_big.*" qi_index
 big_dword "" ".*qi.reference.binary.binary_big.*" qi_index
 big_qword "" ".*qi.reference.binary.binary_big.*" qi_index
+big_bin_float "" ".*qi.reference.binary.binary_big.*" qi_index
+big_bin_double "" ".*qi.reference.binary.binary_big.*" qi_index
 
 byte_ "" ".*karma.reference.binary.binary_native.*" karma_index
 word "" ".*karma.reference.binary.binary_native.*" karma_index
 dword "" ".*karma.reference.binary.binary_native.*" karma_index
 qword "" ".*karma.reference.binary.binary_native.*" karma_index
+bin_float "" ".*karma.reference.binary.binary_native.*" karma_index
+bin_double "" ".*karma.reference.binary.binary_native.*" karma_index
 little_word "" ".*karma.reference.binary.binary_little.*" karma_index
 little_dword "" ".*karma.reference.binary.binary_little.*" karma_index
 little_qword "" ".*karma.reference.binary.binary_little.*" karma_index
+little_bin_float "" ".*karma.reference.binary.binary_little.*" karma_index
+little_bin_double "" ".*karma.reference.binary.binary_little.*" karma_index
 big_word "" ".*karma.reference.binary.binary_big.*" karma_index
 big_dword "" ".*karma.reference.binary.binary_big.*" karma_index
 big_qword "" ".*karma.reference.binary.binary_big.*" karma_index
+big_bin_float "" ".*karma.reference.binary.binary_big.*" karma_index
+big_bin_double "" ".*karma.reference.binary.binary_big.*" karma_index
 
 # char parsers/generators
 char_ "" ".*qi.reference.char\..*" qi_index
@@ -269,7 +281,7 @@
 _pass "" ".*karma.quick_reference.phoenix.*" karma_index
 
 ###############################################################################
-#!exclude N
+#!exclude N
 #!exclude type iterator Auto call where: f info derived_type subject_type
 #!exclude if floatfield precision trailing_zeros force_sign in pointer
 #!exclude result_type value_type difference_type assign clear

Modified: trunk/libs/spirit/doc/karma/binary.qbk
==============================================================================
--- trunk/libs/spirit/doc/karma/binary.qbk (original)
+++ trunk/libs/spirit/doc/karma/binary.qbk 2011-10-24 11:05:44 EDT (Mon, 24 Oct 2011)
@@ -44,6 +44,8 @@
     [[`boost::spirit::word // alias: boost::spirit::karma::word` ]]
     [[`boost::spirit::dword // alias: boost::spirit::karma::dword` ]]
     [[`boost::spirit::qword // alias: boost::spirit::karma::qword` ]]
+ [[`boost::spirit::bin_float // alias: boost::spirit::karma::bin_float` ]]
+ [[`boost::spirit::bin_double // alias: boost::spirit::karma::bin_double` ]]
 ]
 
 [note The generators `qword` and `qword(qw)` are only available on
@@ -67,6 +69,12 @@
     [[`qw`] [A 64 bit binary value or a __karma_lazy_argument__ that
                evaluates to a 64 bit binary value. This value is always
                interpreted using native endianness.]]
+ [[`f`] [A float binary value or a __karma_lazy_argument__ that
+ evaluates to a float binary value. This value is always
+ interpreted using native endianness.]]
+ [[`d`] [A double binary value or a __karma_lazy_argument__ that
+ evaluates to a double binary value. This value is always
+ interpreted using native endianness.]]
 ]
 
 [heading Expression Semantics]
@@ -95,6 +103,14 @@
                              in native endian representation. This generator
                              never fails (unless the underlying output stream
                              reports an error).]]
+ [[`bin_float`] [Output the binary representation of the mandatory
+ float attribute in native endian representation.
+ This generator never fails (unless the underlying
+ output stream reports an error).]]
+ [[`bin_double`] [Output the binary representation of the mandatory
+ double attribute in native endian representation.
+ This generator never fails (unless the underlying
+ output stream reports an error).]]
     [[`byte_(b)`] [Output the binary representation of the least
                              significant byte of the immediate parameter. This
                              generator never fails (unless the underlying
@@ -114,6 +130,14 @@
                              in native endian representation. This generator
                              never fails (unless the underlying output stream
                              reports an error).]]
+ [[`bin_float(f)`] [Output the binary representation of the immediate
+ float parameter in native endian representation.
+ This generator never fails (unless the underlying
+ output stream reports an error).]]
+ [[`bin_double(d)`] [Output the binary representation of the immediate
+ double parameter in native endian representation.
+ This generator never fails (unless the underlying
+ output stream reports an error).]]
 ]
 
 [heading Attributes]
@@ -128,10 +152,16 @@
                              (otherwise compilation will fail)]]
     [[`qword`] [`boost::uint_least64_t`, attribute is mandatory
                              (otherwise compilation will fail)]]
+ [[`bin_float`] [`float`, attribute is mandatory
+ (otherwise compilation will fail)]]
+ [[`bin_double`] [`double`, attribute is mandatory
+ (otherwise compilation will fail)]]
     [[`byte_(b)`] [__unused__]]
     [[`word(w)`] [__unused__]]
     [[`dword(dw)`] [__unused__]]
     [[`qword(qw)`] [__unused__]]
+ [[`bin_float(f)`] [__unused__]]
+ [[`bin_double(d)`] [__unused__]]
 ]
 
 [note In addition to their usual attribute of type `Attrib` all listed generators
@@ -192,6 +222,8 @@
     [[`boost::spirit::little_word // alias: boost::spirit::karma::little_word` ]]
     [[`boost::spirit::little_dword // alias: boost::spirit::karma::little_dword` ]]
     [[`boost::spirit::little_qword // alias: boost::spirit::karma::little_qword` ]]
+ [[`boost::spirit::little_bin_float // alias: boost::spirit::karma::little_bin_float` ]]
+ [[`boost::spirit::little_bin_double // alias: boost::spirit::karma::little_bin_double` ]]
 ]
 
 [note The generators `little_qword` and `little_qword(qw)` are only available on
@@ -213,6 +245,12 @@
     [[`qw`] [A 64 bit binary value or a __karma_lazy_argument__ that
                evaluates to a 64 bit binary value. This value is always
                interpreted using native endianness.]]
+ [[`f`] [A float binary value or a __karma_lazy_argument__ that
+ evaluates to a float binary value. This value is always
+ interpreted using native endianness.]]
+ [[`d`] [A double binary value or a __karma_lazy_argument__ that
+ evaluates to a double binary value. This value is always
+ interpreted using native endianness.]]
 ]
 
 [heading Expression Semantics]
@@ -221,52 +259,74 @@
 not defined in __primitive_generator_concept__.
 
 [table
- [[Expression] [Description]]
- [[`little_word`] [Output the binary representation of the least
- significant 16 bits of the mandatory attribute
- in little endian representation. This generator
- never fails (unless the underlying output stream
- reports an error).]]
- [[`little_dword`] [Output the binary representation of the least
- significant 32 bits of the mandatory attribute
- in little endian representation. This generator
- never fails (unless the underlying output stream
- reports an error).]]
- [[`little_qword`] [Output the binary representation of the least
- significant 64 bits of the mandatory attribute
- in little endian representation. This generator
- never fails (unless the underlying output stream
- reports an error).]]
- [[`little_word(w)`] [Output the binary representation of the least
- significant 16 bits of the immediate parameter
- in little endian representation. This generator
- never fails (unless the underlying output stream
- reports an error).]]
- [[`little_dword(dw)`] [Output the binary representation of the least
- significant 32 bits of the immediate parameter
- in little endian representation. This generator
- never fails (unless the underlying output stream
- reports an error).]]
- [[`little_qword(qw)`] [Output the binary representation of the least
- significant 64 bits of the immediate parameter
- in little endian representation. This generator
- never fails (unless the underlying output stream
- reports an error).]]
+ [[Expression] [Description]]
+ [[`little_word`] [Output the binary representation of the least
+ significant 16 bits of the mandatory attribute
+ in little endian representation. This generator
+ never fails (unless the underlying output stream
+ reports an error).]]
+ [[`little_dword`] [Output the binary representation of the least
+ significant 32 bits of the mandatory attribute
+ in little endian representation. This generator
+ never fails (unless the underlying output stream
+ reports an error).]]
+ [[`little_qword`] [Output the binary representation of the least
+ significant 64 bits of the mandatory attribute
+ in little endian representation. This generator
+ never fails (unless the underlying output stream
+ reports an error).]]
+ [[`little_bin_float`] [Output the binary representation of the mandatory
+ float attribute in little endian representation.
+ This generator never fails (unless the underlying
+ output stream reports an error).]]
+ [[`little_bin_double`] [Output the binary representation of the mandatory
+ double attribute in little endian representation.
+ This generator never fails (unless the underlying
+ output stream reports an error).]]
+ [[`little_word(w)`] [Output the binary representation of the least
+ significant 16 bits of the immediate parameter
+ in little endian representation. This generator
+ never fails (unless the underlying output stream
+ reports an error).]]
+ [[`little_dword(dw)`] [Output the binary representation of the least
+ significant 32 bits of the immediate parameter
+ in little endian representation. This generator
+ never fails (unless the underlying output stream
+ reports an error).]]
+ [[`little_qword(qw)`] [Output the binary representation of the least
+ significant 64 bits of the immediate parameter
+ in little endian representation. This generator
+ never fails (unless the underlying output stream
+ reports an error).]]
+ [[`little_bin_float(f)`] [Output the binary representation of the immediate
+ float parameter in little endian representation.
+ This generator never fails (unless the underlying
+ output stream reports an error).]]
+ [[`little_bin_double(d)`] [Output the binary representation of the immediate
+ double parameter in little endian representation.
+ This generator never fails (unless the underlying
+ output stream reports an error).]]
 ]
 
 [heading Attributes]
 
 [table
- [[Expression] [Attribute]]
- [[`little_word`] [`boost::uint_least16_t`, attribute is mandatory
- (otherwise compilation will fail)]]
- [[`little_dword`] [`boost::uint_least32_t`, attribute is mandatory
- (otherwise compilation will fail)]]
- [[`little_qword`] [`boost::uint_least64_t`, attribute is mandatory
- (otherwise compilation will fail)]]
- [[`little_word(w)`] [__unused__]]
- [[`little_dword(dw)`] [__unused__]]
- [[`little_qword(qw)`] [__unused__]]
+ [[Expression] [Attribute]]
+ [[`little_word`] [`boost::uint_least16_t`, attribute is mandatory
+ (otherwise compilation will fail)]]
+ [[`little_dword`] [`boost::uint_least32_t`, attribute is mandatory
+ (otherwise compilation will fail)]]
+ [[`little_qword`] [`boost::uint_least64_t`, attribute is mandatory
+ (otherwise compilation will fail)]]
+ [[`little_bin_float`] [`float`, attribute is mandatory
+ (otherwise compilation will fail)]]
+ [[`little_bin_double`] [`double`, attribute is mandatory
+ (otherwise compilation will fail)]]
+ [[`little_word(w)`] [__unused__]]
+ [[`little_dword(dw)`] [__unused__]]
+ [[`little_qword(qw)`] [__unused__]]
+ [[`little_bin_float(f)`] [__unused__]]
+ [[`little_bin_double(d)`] [__unused__]]
 ]
 
 [heading Complexity]
@@ -315,6 +375,8 @@
     [[`boost::spirit::big_word // alias: boost::spirit::karma::big_word` ]]
     [[`boost::spirit::big_dword // alias: boost::spirit::karma::big_dword` ]]
     [[`boost::spirit::big_qword // alias: boost::spirit::karma::big_qword` ]]
+ [[`boost::spirit::big_bin_float // alias: boost::spirit::karma::big_bin_float` ]]
+ [[`boost::spirit::big_bin_double // alias: boost::spirit::karma::big_bin_double` ]]
 ]
 
 [note The generators `big_qword` and `big_qword(qw)` are only available on
@@ -336,6 +398,12 @@
     [[`qw`] [A 64 bit binary value or a __karma_lazy_argument__ that
                evaluates to a 64 bit binary value. This value is always
                interpreted using native endianness.]]
+ [[`f`] [A float binary value or a __karma_lazy_argument__ that
+ evaluates to a float binary value. This value is always
+ interpreted using native endianness.]]
+ [[`d`] [A double binary value or a __karma_lazy_argument__ that
+ evaluates to a double binary value. This value is always
+ interpreted using native endianness.]]
 ]
 
 [heading Expression Semantics]
@@ -360,6 +428,14 @@
                              in big endian representation. This generator
                              never fails (unless the underlying output stream
                              reports an error).]]
+ [[`big_bin_float`] [Output the binary representation of the mandatory
+ float attribute in big endian representation.
+ This generator never fails (unless the underlying
+ output stream reports an error).]]
+ [[`big_bin_double`] [Output the binary representation of the mandatory
+ double attribute in big endian representation.
+ This generator never fails (unless the underlying
+ output stream reports an error).]]
     [[`big_word(w)`] [Output the binary representation of the least
                              significant 16 bits of the immediate parameter
                              in big endian representation. This generator
@@ -375,6 +451,14 @@
                              in big endian representation. This generator
                              never fails (unless the underlying output stream
                              reports an error).]]
+ [[`big_bin_float(f)`] [Output the binary representation of the immediate
+ float parameter in big endian representation.
+ This generator never fails (unless the underlying
+ output stream reports an error).]]
+ [[`big_bin_double(d)`] [Output the binary representation of the immediate
+ double parameter in big endian representation.
+ This generator never fails (unless the underlying
+ output stream reports an error).]]
 ]
 
 [heading Attributes]
@@ -387,9 +471,15 @@
                              (otherwise compilation will fail)]]
     [[`big_qword`] [`boost::uint_least64_t`, attribute is mandatory
                              (otherwise compilation will fail)]]
+ [[`big_bin_float`] [`float`, attribute is mandatory
+ (otherwise compilation will fail)]]
+ [[`big_bin_double`] [`double`, attribute is mandatory
+ (otherwise compilation will fail)]]
     [[`big_word(w)`] [__unused__]]
     [[`big_dword(dw)`] [__unused__]]
     [[`big_qword(qw)`] [__unused__]]
+ [[`big_bin_float(f)`] [__unused__]]
+ [[`big_bin_double(d)`] [__unused__]]
 ]
 
 [heading Complexity]

Modified: trunk/libs/spirit/doc/qi/binary.qbk
==============================================================================
--- trunk/libs/spirit/doc/qi/binary.qbk (original)
+++ trunk/libs/spirit/doc/qi/binary.qbk 2011-10-24 11:05:44 EDT (Mon, 24 Oct 2011)
@@ -43,6 +43,8 @@
     [[`boost::spirit::word // alias: boost::spirit::qi::word`]]
     [[`boost::spirit::dword // alias: boost::spirit::qi::dword`]]
     [[`boost::spirit::qword // alias: boost::spirit::qi::qword`]]
+ [[`boost::spirit::bin_float // alias: boost::spirit::qi::bin_float`]]
+ [[`boost::spirit::bin_double // alias: boost::spirit::qi::bin_double`]]
 ]
 
 [note `qword` is only available on platforms where the preprocessor
@@ -66,6 +68,12 @@
     [[`qw`] [A 64 bit binary value or a __qi_lazy_argument__ that
                evaluates to a 64 bit binary value. This value is always
                in native endian.]]
+ [[`f`] [A float binary value or a __qi_lazy_argument__ that
+ evaluates to a float binary value. This value is always
+ in native endian.]]
+ [[`d`] [A double binary value or a __qi_lazy_argument__ that
+ evaluates to a double binary value. This value is always
+ in native endian.]]
 ]
 
 [heading Expression Semantics]
@@ -79,10 +87,14 @@
     [[`word`] [Matches any 16 bit native endian binary.]]
     [[`dword`] [Matches any 32 bit native endian binary.]]
     [[`qword`] [Matches any 64 bit native endian binary.]]
+ [[`bin_float`] [Matches any float native endian binary.]]
+ [[`bin_double`] [Matches any double native endian binary.]]
     [[`byte_(b)`] [Matches an exact 8 bit native endian binary.]]
     [[`word(w)`] [Matches an exact 16 bit native endian binary.]]
     [[`dword(dw)`] [Matches an exact 32 bit native endian binary.]]
     [[`qword(qw)`] [Matches an exact 64 bit native endian binary.]]
+ [[`bin_float(f)`] [Matches an exact float native endian binary.]]
+ [[`bin_double(d)`] [Matches an exact double native endian binary.]]
 ]
 
 [heading Attributes]
@@ -93,10 +105,14 @@
     [[`word`] [`boost::uint_least16_t`]]
     [[`dword`] [`boost::uint_least32_t`]]
     [[`qword`] [`boost::uint_least64_t`]]
+ [[`bin_float`] [`float`]]
+ [[`bin_double`] [`double`]]
     [[`byte_(b)`] [__unused__]]
     [[`word(w)`] [__unused__]]
     [[`dword(dw)`] [__unused__]]
     [[`qword(qw)`] [__unused__]]
+ [[`bin_float(f)`] [__unused__]]
+ [[`bin_double(d)`] [__unused__]]
 ]
 
 [heading Complexity]
@@ -131,9 +147,11 @@
 
 [table
     [[Name]]
- [[`boost::spirit::little_word // alias: boost::spirit::qi::little_word` ]]
- [[`boost::spirit::little_dword // alias: boost::spirit::qi::little_dword` ]]
- [[`boost::spirit::little_qword // alias: boost::spirit::qi::little_qword` ]]
+ [[`boost::spirit::little_word // alias: boost::spirit::qi::little_word` ]]
+ [[`boost::spirit::little_dword // alias: boost::spirit::qi::little_dword` ]]
+ [[`boost::spirit::little_qword // alias: boost::spirit::qi::little_qword` ]]
+ [[`boost::spirit::little_bin_float // alias: boost::spirit::qi::little_bin_float` ]]
+ [[`boost::spirit::little_bin_double // alias: boost::spirit::qi::little_bin_double` ]]
 ]
 
 [note `little_qword` is only available on platforms where the
@@ -155,6 +173,12 @@
     [[`qw`] [A 64 bit binary value or a __qi_lazy_argument__ that
                evaluates to a 64 bit binary value. This value is always
                in native endian.]]
+ [[`f`] [A float binary value or a __qi_lazy_argument__ that
+ evaluates to a float binary value. This value is always
+ in native endian.]]
+ [[`d`] [A double binary value or a __qi_lazy_argument__ that
+ evaluates to a double binary value. This value is always
+ in native endian.]]
 ]
 
 [heading Expression Semantics]
@@ -163,25 +187,33 @@
 not defined in __primitive_parser_concept__.
 
 [table
- [[Expression] [Description]]
- [[`little_word`] [Matches any 16 bit little endian binary.]]
- [[`little_dword`] [Matches any 32 bit little endian binary.]]
- [[`little_qword`] [Matches any 64 bit little endian binary.]]
- [[`little_word(w)`] [Matches an exact 16 bit little endian binary.]]
- [[`little_dword(dw)`] [Matches an exact 32 bit little endian binary.]]
- [[`little_qword(qw)`] [Matches an exact 32 bit little endian binary.]]
+ [[Expression] [Description]]
+ [[`little_word`] [Matches any 16 bit little endian binary.]]
+ [[`little_dword`] [Matches any 32 bit little endian binary.]]
+ [[`little_qword`] [Matches any 64 bit little endian binary.]]
+ [[`little_bin_float`] [Matches any float little endian binary.]]
+ [[`little_bin_double`] [Matches any double little endian binary.]]
+ [[`little_word(w)`] [Matches an exact 16 bit little endian binary.]]
+ [[`little_dword(dw)`] [Matches an exact 32 bit little endian binary.]]
+ [[`little_qword(qw)`] [Matches an exact 32 bit little endian binary.]]
+ [[`little_bin_float(f)`] [Matches an exact float little endian binary.]]
+ [[`little_bin_double(d)`] [Matches an exact double little endian binary.]]
 ]
 
 [heading Attributes]
 
 [table
- [[Expression] [Attribute]]
- [[`little_word`] [`boost::uint_least16_t`]]
- [[`little_dword`] [`boost::uint_least32_t`]]
- [[`little_qword`] [`boost::uint_least64_t`]]
- [[`little_word(w)`] [__unused__]]
- [[`little_dword(dw)`] [__unused__]]
- [[`little_qword(qw)`] [__unused__]]
+ [[Expression] [Attribute]]
+ [[`little_word`] [`boost::uint_least16_t`]]
+ [[`little_dword`] [`boost::uint_least32_t`]]
+ [[`little_qword`] [`boost::uint_least64_t`]]
+ [[`little_bin_float`] [`float`]]
+ [[`little_bin_double`] [`double`]]
+ [[`little_word(w)`] [__unused__]]
+ [[`little_dword(dw)`] [__unused__]]
+ [[`little_qword(qw)`] [__unused__]]
+ [[`little_bin_float(f)`] [__unused__]]
+ [[`little_bin_double(d)`] [__unused__]]
 ]
 
 [heading Complexity]
@@ -216,9 +248,11 @@
 
 [table
     [[Name]]
- [[`boost::spirit::big_word // alias: boost::spirit::qi::big_word` ]]
- [[`boost::spirit::big_dword // alias: boost::spirit::qi::big_dword` ]]
- [[`boost::spirit::big_qword // alias: boost::spirit::qi::big_qword` ]]
+ [[`boost::spirit::big_word // alias: boost::spirit::qi::big_word` ]]
+ [[`boost::spirit::big_dword // alias: boost::spirit::qi::big_dword` ]]
+ [[`boost::spirit::big_qword // alias: boost::spirit::qi::big_qword` ]]
+ [[`boost::spirit::big_bin_float // alias: boost::spirit::qi::big_bin_float` ]]
+ [[`boost::spirit::big_bin_double // alias: boost::spirit::qi::big_bin_double` ]]
 ]
 
 [note `big_qword` is only available on platforms where the
@@ -240,6 +274,12 @@
     [[`qw`] [A 64 bit binary value or a __qi_lazy_argument__ that
                 evaluates to a 64 bit binary value. This value is always
                 in native endian.]]
+ [[`f`] [A float binary value or a __qi_lazy_argument__ that
+ evaluates to a float binary value. This value is always
+ in native endian.]]
+ [[`d`] [A double binary value or a __qi_lazy_argument__ that
+ evaluates to a double binary value. This value is always
+ in native endian.]]
 ]
 
 [heading Expression Semantics]
@@ -252,9 +292,13 @@
     [[`big_word`] [Matches any 16 bit big endian binary.]]
     [[`big_dword`] [Matches any 32 bit big endian binary.]]
     [[`big_qword`] [Matches any 64 bit big endian binary.]]
+ [[`big_bin_float`] [Matches any float big endian binary.]]
+ [[`big_bin_double`] [Matches any double big endian binary.]]
     [[`big_word(w)`] [Matches an exact 16 bit big endian binary.]]
     [[`big_dword(dw)`] [Matches an exact 32 bit big endian binary.]]
     [[`big_qword(qw)`] [Matches an exact 32 bit big endian binary.]]
+ [[`big_bin_float(f)`] [Matches an exact float big endian binary.]]
+ [[`big_bin_double(d)`] [Matches an exact double big endian binary.]]
 ]
 
 [heading Attributes]
@@ -264,9 +308,13 @@
     [[`big_word`] [`boost::uint_least16_t`]]
     [[`big_dword`] [`boost::uint_least32_t`]]
     [[`big_qword`] [`boost::uint_least64_t`]]
+ [[`big_bin_float`] [`float`]]
+ [[`big_bin_double`] [`double`]]
     [[`big_word(w)`] [__unused__]]
     [[`big_dword(dw)`] [__unused__]]
     [[`big_qword(qw)`] [__unused__]]
+ [[`big_bin_float(f)`] [__unused__]]
+ [[`big_bin_double(d)`] [__unused__]]
 ]
 
 [heading Complexity]

Modified: trunk/libs/spirit/doc/spirit2.qbk
==============================================================================
--- trunk/libs/spirit/doc/spirit2.qbk (original)
+++ trunk/libs/spirit/doc/spirit2.qbk 2011-10-24 11:05:44 EDT (Mon, 24 Oct 2011)
@@ -8,7 +8,7 @@
 
 [article Spirit
     [quickbook 1.5]
- [version 2.5.1]
+ [version 2.5.2]
     [authors [de Guzman, Joel], [Kaiser, Hartmut]]
     [copyright 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 Joel de Guzman, Hartmut Kaiser]
     [/ purpose Parser and Generator Library]
@@ -23,7 +23,7 @@
 
 [/ Some links ]
 
-[def __version__ V2.5.1]
+[def __version__ V2.5.2]
 
 [def __spirit__ [@http://boost-spirit.com Spirit]]
 [def __spirit_list__ [@http://www.nabble.com/The-Spirit-Parser-Library-f3430.html Spirit General List]]

Modified: trunk/libs/spirit/doc/what_s_new.qbk
==============================================================================
--- trunk/libs/spirit/doc/what_s_new.qbk (original)
+++ trunk/libs/spirit/doc/what_s_new.qbk 2011-10-24 11:05:44 EDT (Mon, 24 Oct 2011)
@@ -9,25 +9,35 @@
 [section What's New]
 
 [/////////////////////////////////////////////////////////////////////////////]
+[section:spirit_2_5_2 Spirit V2.5.2]
+
+[heading What's changed from V2.5.1 (Boost V1.48.0) to V2.5.2 (Boost V1.49.0)]
+
+* Integrated Vitaly Budovski's patch to add binary floating point parsers and
+ generators.
+
+[endsect]
+
+[/////////////////////////////////////////////////////////////////////////////]
 [section:spirit_2_5_1 Spirit V2.5.1]
 
 [heading What's changed from V2.5 (Boost V1.47.0) to V2.5.1 (Boost V1.48.0)]
 
-* The `spirit::istream_iterator` (see __multi_pass__) now checks at
+* The `spirit::istream_iterator` (see __multi_pass__) now checks at
   construction time whether the underlying stream has reached eof (end of file).
-* __qi__ now properly collapses attributes generated from optionals embedded
+* __qi__ now properly collapses attributes generated from optionals embedded
   inside another optional parser (i.e. `-('(' > -int_ >> ')'). That means that
   attributes like `boost::optiona<boost::optional<int> >` will be collapsed
- to `boost::optional<int>`. Thanks to Peter Schueller for reporting that
+ to `boost::optional<int>`. Thanks to Peter Schueller for reporting that
   problem.
-* Actions attached to binary parsers now properly propagate the parser's
+* Actions attached to binary parsers now properly propagate the parser's
   attribute. Thanks to Mathias Born for reporting this issue.
 
 [heading Bug Fixes in Lex]
 
-* Fixed Boost ticket #5701: lexertl token_value_type returns const unused for
+* Fixed Boost ticket #5701: lexertl token_value_type returns const unused for
   nonconst ref.
-* Fixed a problem in the lexer (position_token) causing problems with enabled
+* Fixed a problem in the lexer (position_token) causing problems with enabled
   parser debugging (MSVC2010).
 
 [endsect]
@@ -79,7 +89,7 @@
   This change unifies the handling of the `_val` placeholder allowing to use it
   everywhere, not only in semantic actions attached to the right hand sides of
   a rule.
-* Added support for __karma__ [unsigned_int unsigned numeric generators] with
+* Added support for __karma__ [unsigned_int unsigned numeric generators] with
   arbitrary radix values in the (inclusive) range from `2` .. `36`.
 
 [heading Bug Fixes in Qi or Karma]
@@ -122,14 +132,14 @@
   using `lex::char_` and `lex::string`. Both primitives now accept a second
   parameter which will be interpreted as the requested token id for any token
   generated from this definition.
-* Added a new token type `lex::lexertl::position_token<>`, which is essentially
+* Added a new token type `lex::lexertl::position_token<>`, which is essentially
   plup-in compatible with the existing `lex::lexertl::token<>` class. However
- it additionally stores the pair of iterators pointing to the underlying
+ it additionally stores the pair of iterators pointing to the underlying
   matched input sequence as an iterator_range.
 
 [heading Bug Fixes in Lex]
 
-* Fixed a problem with associating token definitions with all states (using
+* Fixed a problem with associating token definitions with all states (using
   `"*"` as the state name) when actions were attached to them.
 
 [heading Making Stuff Work]

Modified: trunk/libs/spirit/test/karma/binary1.cpp
==============================================================================
--- trunk/libs/spirit/test/karma/binary1.cpp (original)
+++ trunk/libs/spirit/test/karma/binary1.cpp 2011-10-24 11:05:44 EDT (Mon, 24 Oct 2011)
@@ -39,6 +39,9 @@
         BOOST_TEST(binary_test("\x81\x02\x03\x04\x05\x06\x07\x08", 8, qword,
             0x0807060504030281LL));
 #endif
+ BOOST_TEST(binary_test("\x00\x00\x80\x3f", 4, bin_float, 1.0f));
+ BOOST_TEST(binary_test("\x00\x00\x00\x00\x00\x00\xf0\x3f", 8,
+ bin_double, 1.0));
 
         BOOST_TEST(binary_test_delimited("\x01\x00\x00\x00", 4, byte_, 0x01, pad(4)));
         BOOST_TEST(binary_test_delimited("\x01\x02\x00\x00", 4, word, 0x0201, pad(4)));
@@ -47,6 +50,10 @@
         BOOST_TEST(binary_test_delimited("\x01\x02\x03\x04\x05\x06\x07\x08\x00\x00", 10,
             qword, 0x0807060504030201LL, pad(10)));
 #endif
+ BOOST_TEST(binary_test_delimited("\x00\x00\x80\x3f", 4, bin_float,
+ 1.0f, pad(4)));
+ BOOST_TEST(binary_test_delimited("\x00\x00\x00\x00\x00\x00\xf0\x3f", 8,
+ bin_double, 1.0, pad(8)));
 
 #else // BOOST_LITTLE_ENDIAN
 
@@ -62,6 +69,9 @@
         BOOST_TEST(binary_test("\x81\x02\x03\x04\x05\x06\x07\x08", 8, qword,
             0x8102030405060708LL));
 #endif
+ BOOST_TEST(binary_test("\x3f\x80\x00\x00", 4, bin_float, 1.0f));
+ BOOST_TEST(binary_test("\x3f\xf0\x00\x00\x00\x00\x00\x00", 8,
+ bin_double, 1.0));
 
         BOOST_TEST(binary_test_delimited("\x01\x00\x00\x00", 4, byte_, 0x01, pad(4)));
         BOOST_TEST(binary_test_delimited("\x01\x02\x00\x00", 4, word, 0x0102, pad(4)));
@@ -70,6 +80,10 @@
         BOOST_TEST(binary_test_delimited("\x01\x02\x03\x04\x05\x06\x07\x08\x00\x00", 10,
             qword, 0x0102030405060708LL, pad(10)));
 #endif
+ BOOST_TEST(binary_test_delimited("\x3f\x80\x00\x00", 4, bin_float,
+ 1.0f, pad(4)));
+ BOOST_TEST(binary_test_delimited("\x3f\xf0\x00\x00\x00\x00\x00\x00", 8,
+ bin_double, 1.0, pad(8)));
 #endif
     }
 
@@ -82,6 +96,9 @@
         BOOST_TEST(binary_test("\x01\x02\x03\x04\x05\x06\x07\x08", 8,
             qword(0x0807060504030201LL)));
 #endif
+ BOOST_TEST(binary_test("\x00\x00\x80\x3f", 4, bin_float(1.0f)));
+ BOOST_TEST(binary_test("\x00\x00\x00\x00\x00\x00\xf0\x3f", 8,
+ bin_double(1.0)));
 #else
         BOOST_TEST(binary_test("\x01", 1, byte_(0x01)));
         BOOST_TEST(binary_test("\x01\x02", 2, word(0x0102)));
@@ -90,6 +107,9 @@
         BOOST_TEST(binary_test("\x01\x02\x03\x04\x05\x06\x07\x08", 8,
             qword(0x0102030405060708LL)));
 #endif
+ BOOST_TEST(binary_test("\x3f\x80\x00\x00", 4, bin_float(1.0f)));
+ BOOST_TEST(binary_test("\x3f\xf0\x00\x00\x00\x00\x00\x00", 8,
+ bin_double(1.0)));
 #endif
     }
 

Modified: trunk/libs/spirit/test/karma/binary2.cpp
==============================================================================
--- trunk/libs/spirit/test/karma/binary2.cpp (original)
+++ trunk/libs/spirit/test/karma/binary2.cpp 2011-10-24 11:05:44 EDT (Mon, 24 Oct 2011)
@@ -38,6 +38,11 @@
         BOOST_TEST(binary_test_delimited("\x01\x02\x03\x04\x05\x06\x07\x08\x00\x00",
             10, big_qword, 0x0102030405060708LL, pad(10)));
 #endif
+ BOOST_TEST(binary_test("\x3f\x80\x00\x00", 4, big_bin_float, 1.0f));
+ BOOST_TEST(binary_test("\x3f\xf0\x00\x00\x00\x00\x00\x00", 8,
+ big_bin_double, 1.0));
+ BOOST_TEST(binary_test_delimited("\x3f\xf0\x00\x00\x00\x00\x00\x00\x00\x00",
+ 10, big_bin_double, 1.0, pad(10)));
     }
 
     {
@@ -49,6 +54,11 @@
         BOOST_TEST(binary_test_delimited("\x01\x02\x03\x04\x05\x06\x07\x08\x00\x00",
             10, big_qword(0x0102030405060708LL), pad(10)));
 #endif
+ BOOST_TEST(binary_test("\x3f\x80\x00\x00", 4, big_bin_float(1.0f)));
+ BOOST_TEST(binary_test("\x3f\xf0\x00\x00\x00\x00\x00\x00", 8,
+ big_bin_double(1.0)));
+ BOOST_TEST(binary_test_delimited("\x3f\xf0\x00\x00\x00\x00\x00\x00\x00\x00",
+ 10, big_bin_double(1.0), pad(10)));
     }
 
     { // test little endian binaries
@@ -64,6 +74,11 @@
         BOOST_TEST(binary_test_delimited("\x01\x02\x03\x04\x05\x06\x07\x08\x00\x00",
             10, little_qword, 0x0807060504030201LL, pad(10)));
 #endif
+ BOOST_TEST(binary_test("\x00\x00\x80\x3f", 4, little_bin_float, 1.0f));
+ BOOST_TEST(binary_test("\x00\x00\x00\x00\x00\x00\xf0\x3f", 8,
+ little_bin_double, 1.0));
+ BOOST_TEST(binary_test_delimited("\x00\x00\x00\x00\x00\x00\xf0\x3f\x00\x00",
+ 10, little_bin_double, 1.0, pad(10)));
     }
 
     {
@@ -75,12 +90,19 @@
         BOOST_TEST(binary_test_delimited("\x01\x02\x03\x04\x05\x06\x07\x08\x00\x00",
             10, little_qword(0x0807060504030201LL), pad(10)));
 #endif
+ BOOST_TEST(binary_test("\x00\x00\x80\x3f", 4, little_bin_float(1.0f)));
+ BOOST_TEST(binary_test("\x00\x00\x00\x00\x00\x00\xf0\x3f", 8,
+ little_bin_double(1.0)));
+ BOOST_TEST(binary_test_delimited("\x00\x00\x00\x00\x00\x00\xf0\x3f\x00\x00",
+ 10, little_bin_double(1.0), pad(10)));
     }
 
     { // test native endian binaries
         boost::optional<boost::uint8_t> v8;
         boost::optional<boost::uint16_t> v16;
         boost::optional<boost::uint32_t> v32;
+ boost::optional<float> vf;
+ boost::optional<double> vd;
 
 #ifdef BOOST_LITTLE_ENDIAN
 
@@ -91,6 +113,8 @@
         boost::optional<boost::uint64_t> v64;
         BOOST_TEST(!binary_test("", 8, qword, v64));
 #endif
+ BOOST_TEST(!binary_test("", 4, bin_float, vf));
+ BOOST_TEST(!binary_test("", 8, bin_double, vd));
 
 #else // BOOST_LITTLE_ENDIAN
 
@@ -101,6 +125,8 @@
         boost::optional<boost::uint64_t> v64;
         BOOST_TEST(!binary_test("", 8, qword, v64));
 #endif
+ BOOST_TEST(!binary_test("", 4, bin_float, vf));
+ BOOST_TEST(!binary_test("", 8, bin_double, vd));
 
 #endif
     }

Modified: trunk/libs/spirit/test/karma/binary3.cpp
==============================================================================
--- trunk/libs/spirit/test/karma/binary3.cpp (original)
+++ trunk/libs/spirit/test/karma/binary3.cpp 2011-10-24 11:05:44 EDT (Mon, 24 Oct 2011)
@@ -38,6 +38,11 @@
         boost::optional<boost::uint64_t> v64 (0x0807060504030201LL);
         BOOST_TEST(binary_test("\x01\x02\x03\x04\x05\x06\x07\x08", 8, qword, v64));
 #endif
+ boost::optional<float> vf(1.0f);
+ BOOST_TEST(binary_test("\x00\x00\x80\x3f", 4, bin_float, vf));
+ boost::optional<double> vd(1.0);
+ BOOST_TEST(binary_test("\x00\x00\x00\x00\x00\x00\xf0\x3f", 8,
+ bin_double, vd));
 
 #else // BOOST_LITTLE_ENDIAN
 
@@ -51,6 +56,11 @@
         boost::optional<boost::uint64_t> v64 (0x0102030405060708LL);
         BOOST_TEST(binary_test("\x01\x02\x03\x04\x05\x06\x07\x08", 8, qword, v64));
 #endif
+ boost::optional<float> vf(1.0f);
+ BOOST_TEST(binary_test("\x3f\x80\x00\x00", 4, bin_float, vf));
+ boost::optional<double> vd(1.0);
+ BOOST_TEST(binary_test("\x3f\xf0\x00\x00\x00\x00\x00\x00", 8,
+ bin_double, vd));
 
 #endif
     }
@@ -89,6 +99,21 @@
         BOOST_TEST(binary_test("\x02\x02\x03\x04\x05\x06\x07\x08", 8, qword,
             ++phoenix::ref(v64)));
 #endif
+ BOOST_TEST(binary_test("\x00\x00\x80\x3f", 4, bin_float,
+ phoenix::val(1.0f)));
+ float vf(1.0f);
+ BOOST_TEST(binary_test("\x00\x00\x80\x3f", 4, bin_float,
+ phoenix::ref(vf)));
+ BOOST_TEST(binary_test("\x00\x00\x00\x40", 4, bin_float,
+ ++phoenix::ref(vf)));
+
+ BOOST_TEST(binary_test("\x00\x00\x00\x00\x00\x00\xf0\x3f", 8,
+ bin_double, phoenix::val(1.0)));
+ double vd(1.0);
+ BOOST_TEST(binary_test("\x00\x00\x00\x00\x00\x00\xf0\x3f", 8,
+ bin_double, phoenix::ref(vd)));
+ BOOST_TEST(binary_test("\x00\x00\x00\x00\x00\x00\x00\x40", 8,
+ bin_double, ++phoenix::ref(vd)));
 
 #else // BOOST_LITTLE_ENDIAN
 
@@ -119,6 +144,21 @@
         BOOST_TEST(binary_test("\x01\x02\x03\x04\x05\x06\x07\x09", 8, qword,
             ++phoenix::ref(v64)));
 #endif
+ BOOST_TEST(binary_test("\x3f\x80\x00\x00", 4, bin_float,
+ phoenix::val(1.0f)));
+ float vf(1.0f);
+ BOOST_TEST(binary_test("\x3f\x80\x00\x00", 4, bin_float,
+ phoenix::ref(vf)));
+ BOOST_TEST(binary_test("\x40\x00\x00\x00", 4, bin_float,
+ ++phoenix::ref(vf)));
+
+ BOOST_TEST(binary_test("\x3f\xf0\x00\x00\x00\x00\x00\x00", 8,
+ bin_double, phoenix::val(1.0)));
+ double vd(1.0);
+ BOOST_TEST(binary_test("\x3f\xf0\x00\x00\x00\x00\x00\x00", 8,
+ bin_double, phoenix::ref(vd)));
+ BOOST_TEST(binary_test("\x40\x00\x00\x00\x00\x00\x00\x00", 8,
+ bin_double, ++phoenix::ref(vd)));
 
 #endif
     }

Modified: trunk/libs/spirit/test/qi/binary.cpp
==============================================================================
--- trunk/libs/spirit/test/qi/binary.cpp (original)
+++ trunk/libs/spirit/test/qi/binary.cpp 2011-10-24 11:05:44 EDT (Mon, 24 Oct 2011)
@@ -16,6 +16,8 @@
 {
     using spirit_test::test_attr;
     using spirit_test::test;
+ using spirit_test::binary_test;
+ using spirit_test::binary_test_attr;
 
     using boost::spirit::qi::byte_;
     using boost::spirit::qi::word;
@@ -29,6 +31,12 @@
     using boost::spirit::qi::big_qword;
     using boost::spirit::qi::little_qword;
 #endif
+ using boost::spirit::qi::bin_float;
+ using boost::spirit::qi::big_bin_float;
+ using boost::spirit::qi::little_bin_float;
+ using boost::spirit::qi::bin_double;
+ using boost::spirit::qi::big_bin_double;
+ using boost::spirit::qi::little_bin_double;
 
     boost::uint8_t uc;
     boost::uint16_t us;
@@ -36,6 +44,8 @@
 #ifdef BOOST_HAS_LONG_LONG
     boost::uint64_t ul;
 #endif
+ float f;
+ double d;
 
     { // test native endian binaries
 #ifdef BOOST_LITTLE_ENDIAN
@@ -46,6 +56,10 @@
         BOOST_TEST(test_attr("\x01\x02\x03\x04\x05\x06\x07\x08", qword, ul) &&
             ul == 0x0807060504030201LL);
 #endif
+ BOOST_TEST(binary_test_attr("\x00\x00\x80\x3f", 4, bin_float, f) &&
+ f == 1.0f);
+ BOOST_TEST(binary_test_attr("\x00\x00\x00\x00\x00\x00\xf0\x3f",
+ 8, bin_double, d) && f == 1.0);
 #else
         BOOST_TEST(test_attr("\x01", byte_, uc) && uc == 0x01);
         BOOST_TEST(test_attr("\x01\x02", word, us) && us == 0x0102);
@@ -54,6 +68,10 @@
         BOOST_TEST(test_attr("\x01\x02\x03\x04\x05\x06\x07\x08", qword, ul) &&
             ul == 0x0102030405060708LL);
 #endif
+ BOOST_TEST(binary_test_attr("\x3f\x80\x00\x00", 4, bin_float, f) &&
+ f == 1.0f);
+ BOOST_TEST(binary_test_attr("\x3f\xf0\x00\x00\x00\x00\x00\x00",
+ 8, bin_double, d) && f == 1.0);
 #endif
     }
 
@@ -66,6 +84,9 @@
         BOOST_TEST(test("\x01\x02\x03\x04\x05\x06\x07\x08",
             qword(0x0807060504030201LL)));
 #endif
+ BOOST_TEST(binary_test("\x00\x00\x80\x3f", 4, bin_float(1.0f)));
+ BOOST_TEST(binary_test("\x00\x00\x00\x00\x00\x00\xf0\x3f", 8,
+ bin_double(1.0)));
 #else
         BOOST_TEST(test("\x01", byte_(0x01)));
         BOOST_TEST(test("\x01\x02", word(0x0102)));
@@ -74,6 +95,9 @@
         BOOST_TEST(test("\x01\x02\x03\x04\x05\x06\x07\x08",
             qword(0x0102030405060708LL)));
 #endif
+ BOOST_TEST(binary_test("\x3f\x80\x00\x00", 4, bin_float(1.0f)));
+ BOOST_TEST(binary_test("\x3f\x80\x00\x00\x00\x00\x00\x00", 8,
+ bin_double(1.0)));
 #endif
     }
 
@@ -84,6 +108,10 @@
         BOOST_TEST(test_attr("\x01\x02\x03\x04\x05\x06\x07\x08", big_qword, ul)
             && ul == 0x0102030405060708LL);
 #endif
+ BOOST_TEST(binary_test_attr("\x3f\x80\x00\x00", 4, big_bin_float, f) &&
+ f == 1.0f);
+ BOOST_TEST(binary_test_attr("\x3f\xf0\x00\x00\x00\x00\x00\x00",
+ 8, big_bin_double, d) && f == 1.0);
     }
 
     {
@@ -93,6 +121,9 @@
         BOOST_TEST(test("\x01\x02\x03\x04\x05\x06\x07\x08",
             big_qword(0x0102030405060708LL)));
 #endif
+ BOOST_TEST(binary_test("\x3f\x80\x00\x00", 4, big_bin_float(1.0f)));
+ BOOST_TEST(binary_test("\x3f\xf0\x00\x00\x00\x00\x00\x00", 8,
+ big_bin_double(1.0)));
     }
 
     { // test little endian binaries
@@ -102,6 +133,10 @@
         BOOST_TEST(test_attr("\x01\x02\x03\x04\x05\x06\x07\x08", little_qword, ul)
             && ul == 0x0807060504030201LL);
 #endif
+ BOOST_TEST(binary_test_attr("\x00\x00\x80\x3f", 4,
+ little_bin_float, f) && f == 1.0f);
+ BOOST_TEST(binary_test_attr("\x00\x00\x00\x00\x00\x00\xf0\x3f",
+ 8, little_bin_double, d) && f == 1.0);
     }
 
     {
@@ -111,6 +146,9 @@
         BOOST_TEST(test("\x01\x02\x03\x04\x05\x06\x07\x08",
             little_qword(0x0807060504030201LL)));
 #endif
+ BOOST_TEST(binary_test("\x00\x00\x80\x3f", 4, little_bin_float(1.0f)));
+ BOOST_TEST(binary_test("\x00\x00\x00\x00\x00\x00\xf0\x3f", 8,
+ little_bin_double(1.0)));
     }
 
     return boost::report_errors();

Modified: trunk/libs/spirit/test/qi/test.hpp
==============================================================================
--- trunk/libs/spirit/test/qi/test.hpp (original)
+++ trunk/libs/spirit/test/qi/test.hpp 2011-10-24 11:05:44 EDT (Mon, 24 Oct 2011)
@@ -44,6 +44,32 @@
             && (!full_match || (in == last));
     }
 
+ template <typename Char, typename Parser>
+ bool binary_test(Char const* in, std::size_t size, Parser const& p,
+ bool full_match = true)
+ {
+ // we don't care about the result of the "what" function.
+ // we only care that all parsers have it:
+ boost::spirit::qi::what(p);
+
+ Char const* last = in + size;
+ return boost::spirit::qi::parse(in, last, p)
+ && (!full_match || (in == last));
+ }
+
+ template <typename Char, typename Parser, typename Skipper>
+ bool binary_test(Char const* in, std::size_t size, Parser const& p,
+ Skipper const& s, bool full_match = true)
+ {
+ // we don't care about the result of the "what" function.
+ // we only care that all parsers have it:
+ boost::spirit::qi::what(p);
+
+ Char const* last = in + size;
+ return boost::spirit::qi::phrase_parse(in, last, p, s)
+ && (!full_match || (in == last));
+ }
+
     template <typename Char, typename Parser, typename Attr>
     bool test_attr(Char const* in, Parser const& p
         , Attr& attr, bool full_match = true)
@@ -74,6 +100,32 @@
             && (!full_match || (in == last));
     }
 
+ template <typename Char, typename Parser, typename Attr>
+ bool binary_test_attr(Char const* in, std::size_t size, Parser const& p,
+ Attr& attr, bool full_match = true)
+ {
+ // we don't care about the result of the "what" function.
+ // we only care that all parsers have it:
+ boost::spirit::qi::what(p);
+
+ Char const* last = in + size;
+ return boost::spirit::qi::parse(in, last, p, attr)
+ && (!full_match || (in == last));
+ }
+
+ template <typename Char, typename Parser, typename Attr, typename Skipper>
+ bool binary_test_attr(Char const* in, std::size_t size, Parser const& p,
+ Attr& attr, Skipper const& s, bool full_match = true)
+ {
+ // we don't care about the result of the "what" function.
+ // we only care that all parsers have it:
+ boost::spirit::qi::what(p);
+
+ Char const* last = in + size;
+ return boost::spirit::qi::phrase_parse(in, last, p, s, attr)
+ && (!full_match || (in == last));
+ }
+
     struct printer
     {
         typedef boost::spirit::utf8_string string;


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