Index: home/karma/binary/binary.hpp =================================================================== --- home/karma/binary/binary.hpp (revision 72619) +++ home/karma/binary/binary.hpp (working copy) @@ -27,6 +27,7 @@ #include #include #include +#include #include /////////////////////////////////////////////////////////////////////////////// @@ -45,6 +46,19 @@ \ /***/ +#define BOOST_SPIRIT_ENABLE_BINARY_IEEE754(name) \ + template<> \ + struct use_terminal: mpl::true_ {}; \ + \ + template \ + struct use_terminal > >: is_floating_point {}; \ + \ + template<> \ + struct use_lazy_terminal : 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 @@ -98,6 +118,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 +167,26 @@ }; #endif + template + 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 struct what; @@ -174,14 +220,12 @@ } /////////////////////////////////////////////////////////////////////////// - template + template struct any_binary_generator - : primitive_generator > + : primitive_generator > { template - struct attribute - : karma::detail::integer - {}; + struct attribute: T {}; template < typename OutputIterator, typename Context, typename Delimiter @@ -195,16 +239,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::integer::endian< - endian, typename karma::detail::integer::type, bits - > p; + boost::integer::endian 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::type attribute_type; + typedef typename T::type attribute_type; p = traits::extract_from(attr, context); #if defined(BOOST_MSVC) #pragma warning(pop) @@ -245,9 +287,9 @@ }; /////////////////////////////////////////////////////////////////////////// - template + template struct literal_binary_generator - : primitive_generator > + : primitive_generator > { template struct attribute @@ -255,15 +297,15 @@ typedef unused_type type; }; - template - literal_binary_generator(T const& t) + template + 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 @@ -297,7 +339,7 @@ } typedef boost::integer::endian< - endian, typename karma::detail::integer::type, bits + endian, typename T::type, bits > data_type; data_type data_; @@ -308,11 +350,11 @@ /////////////////////////////////////////////////////////////////////////// namespace detail { - template struct basic_binary { - typedef any_binary_generator result_type; + typedef any_binary_generator result_type; result_type operator()(unused_type, unused_type) const { @@ -320,11 +362,11 @@ } }; - template struct basic_binary_literal { - typedef literal_binary_generator result_type; + typedef literal_binary_generator result_type; template result_type operator()(Terminal const& term, unused_type) const @@ -337,12 +379,13 @@ #define BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(name, endian, bits) \ template \ struct make_primitive \ - : detail::basic_binary {}; \ + : detail::basic_binary, \ + boost::integer::endianness::endian, bits> {}; \ \ template \ struct make_primitive > \ , Modifiers> \ - : detail::basic_binary_literal \ , boost::integer::endianness::endian, bits> {}; \ \ /***/ @@ -362,6 +405,29 @@ #undef BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE +#define BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE(name, endian, bits) \ + template \ + struct make_primitive \ + : detail::basic_binary, \ + boost::integer::endianness::endian, bits> {}; \ + \ + template \ + struct make_primitive > \ + , Modifiers> \ + : detail::basic_binary_literal \ + , boost::integer::endianness::endian, 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