Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-19 09:47:34

0001 //  Copyright (c) 2001-2011 Hartmut Kaiser
0002 //
0003 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
0004 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 #if !defined(BOOST_SPIRIT_KARMA_BINARY_MAY_04_2007_0904AM)
0007 #define BOOST_SPIRIT_KARMA_BINARY_MAY_04_2007_0904AM
0008 
0009 #if defined(_MSC_VER)
0010 #pragma once
0011 #endif
0012 
0013 #include <boost/spirit/home/support/common_terminals.hpp>
0014 #include <boost/spirit/home/support/info.hpp>
0015 #include <boost/spirit/home/support/detail/endian.hpp>
0016 
0017 #include <boost/spirit/home/karma/domain.hpp>
0018 #include <boost/spirit/home/karma/meta_compiler.hpp>
0019 #include <boost/spirit/home/karma/delimit_out.hpp>
0020 #include <boost/spirit/home/karma/auxiliary/lazy.hpp>
0021 #include <boost/spirit/home/karma/detail/generate_to.hpp>
0022 #include <boost/spirit/home/karma/detail/extract_from.hpp>
0023 #include <boost/spirit/home/support/unused.hpp>
0024 #include <boost/spirit/home/support/container.hpp>
0025 #include <boost/fusion/include/vector.hpp>
0026 #include <boost/fusion/include/at.hpp>
0027 #include <boost/mpl/or.hpp>
0028 #include <boost/type_traits/is_integral.hpp>
0029 #include <boost/type_traits/is_enum.hpp>
0030 #include <boost/type_traits/is_floating_point.hpp>
0031 #include <boost/config.hpp>
0032 
0033 ///////////////////////////////////////////////////////////////////////////////
0034 #define BOOST_SPIRIT_ENABLE_BINARY(name)                                      \
0035     template <>                                                               \
0036     struct use_terminal<karma::domain, tag::name>                             \
0037       : mpl::true_ {};                                                        \
0038                                                                               \
0039     template <typename A0>                                                    \
0040     struct use_terminal<karma::domain                                         \
0041         , terminal_ex<tag::name, fusion::vector1<A0> > >                      \
0042       : mpl::or_<is_integral<A0>, is_enum<A0> > {};                           \
0043                                                                               \
0044     template <>                                                               \
0045     struct use_lazy_terminal<karma::domain, tag::name, 1> : mpl::true_ {};    \
0046                                                                               \
0047 /***/
0048 
0049 #define BOOST_SPIRIT_ENABLE_BINARY_IEEE754(name)                              \
0050     template<>                                                                \
0051     struct use_terminal<karma::domain, tag::name>: mpl::true_ {};             \
0052                                                                               \
0053     template<typename A0>                                                     \
0054     struct use_terminal<karma::domain, terminal_ex<tag::name,                 \
0055         fusion::vector1<A0> > >: is_floating_point<A0> {};                    \
0056                                                                               \
0057     template<>                                                                \
0058     struct use_lazy_terminal<karma::domain, tag::name, 1> : mpl::true_ {};    \
0059                                                                               \
0060 /***/
0061 
0062 namespace boost { namespace spirit
0063 {
0064     ///////////////////////////////////////////////////////////////////////////
0065     // Enablers
0066     ///////////////////////////////////////////////////////////////////////////
0067 
0068     BOOST_SPIRIT_ENABLE_BINARY(byte_)                   // enables byte_
0069     BOOST_SPIRIT_ENABLE_BINARY(word)                    // enables word
0070     BOOST_SPIRIT_ENABLE_BINARY(big_word)                // enables big_word
0071     BOOST_SPIRIT_ENABLE_BINARY(little_word)             // enables little_word
0072     BOOST_SPIRIT_ENABLE_BINARY(dword)                   // enables dword
0073     BOOST_SPIRIT_ENABLE_BINARY(big_dword)               // enables big_dword
0074     BOOST_SPIRIT_ENABLE_BINARY(little_dword)            // enables little_dword
0075 #ifdef BOOST_HAS_LONG_LONG
0076     BOOST_SPIRIT_ENABLE_BINARY(qword)                   // enables qword
0077     BOOST_SPIRIT_ENABLE_BINARY(big_qword)               // enables big_qword
0078     BOOST_SPIRIT_ENABLE_BINARY(little_qword)            // enables little_qword
0079 #endif
0080     BOOST_SPIRIT_ENABLE_BINARY_IEEE754(bin_float)
0081     BOOST_SPIRIT_ENABLE_BINARY_IEEE754(big_bin_float)
0082     BOOST_SPIRIT_ENABLE_BINARY_IEEE754(little_bin_float)
0083     BOOST_SPIRIT_ENABLE_BINARY_IEEE754(bin_double)
0084     BOOST_SPIRIT_ENABLE_BINARY_IEEE754(big_bin_double)
0085     BOOST_SPIRIT_ENABLE_BINARY_IEEE754(little_bin_double)
0086 }}
0087 
0088 #undef BOOST_SPIRIT_ENABLE_BINARY
0089 #undef BOOST_SPIRIT_ENABLE_BINARY_IEEE754
0090 
0091 ///////////////////////////////////////////////////////////////////////////////
0092 namespace boost { namespace spirit { namespace karma
0093 {
0094 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
0095     using boost::spirit::byte_;
0096     using boost::spirit::word;
0097     using boost::spirit::big_word;
0098     using boost::spirit::little_word;
0099     using boost::spirit::dword;
0100     using boost::spirit::big_dword;
0101     using boost::spirit::little_dword;
0102 #ifdef BOOST_HAS_LONG_LONG
0103     using boost::spirit::qword;
0104     using boost::spirit::big_qword;
0105     using boost::spirit::little_qword;
0106 #endif
0107     using boost::spirit::bin_float;
0108     using boost::spirit::big_bin_float;
0109     using boost::spirit::little_bin_float;
0110     using boost::spirit::bin_double;
0111     using boost::spirit::big_bin_double;
0112     using boost::spirit::little_bin_double;
0113 #endif
0114 
0115     using boost::spirit::byte_type;
0116     using boost::spirit::word_type;
0117     using boost::spirit::big_word_type;
0118     using boost::spirit::little_word_type;
0119     using boost::spirit::dword_type;
0120     using boost::spirit::big_dword_type;
0121     using boost::spirit::little_dword_type;
0122 #ifdef BOOST_HAS_LONG_LONG
0123     using boost::spirit::qword_type;
0124     using boost::spirit::big_qword_type;
0125     using boost::spirit::little_qword_type;
0126 #endif
0127     using boost::spirit::bin_float_type;
0128     using boost::spirit::big_bin_float_type;
0129     using boost::spirit::little_bin_float_type;
0130     using boost::spirit::bin_double_type;
0131     using boost::spirit::big_bin_double_type;
0132     using boost::spirit::little_bin_double_type;
0133 
0134     namespace detail
0135     {
0136         template <int bits>
0137         struct integer
0138         {
0139 #ifdef BOOST_HAS_LONG_LONG
0140             BOOST_SPIRIT_ASSERT_MSG(
0141                 bits == 8 || bits == 16 || bits == 32 || bits == 64,
0142                 not_supported_binary_size, ());
0143 #else
0144             BOOST_SPIRIT_ASSERT_MSG(
0145                 bits == 8 || bits == 16 || bits == 32,
0146                 not_supported_binary_size, ());
0147 #endif
0148         };
0149 
0150         template <>
0151         struct integer<8>
0152         {
0153             typedef uint_least8_t type;
0154         };
0155 
0156         template <>
0157         struct integer<16>
0158         {
0159             typedef uint_least16_t type;
0160         };
0161 
0162         template <>
0163         struct integer<32>
0164         {
0165             typedef uint_least32_t type;
0166         };
0167 
0168 #ifdef BOOST_HAS_LONG_LONG
0169         template <>
0170         struct integer<64>
0171         {
0172             typedef uint_least64_t type;
0173         };
0174 #endif
0175 
0176         template <int bits>
0177         struct floating_point
0178         {
0179             BOOST_SPIRIT_ASSERT_MSG(
0180                 bits == 32 || bits == 64,
0181                 not_supported_binary_size, ());
0182         };
0183 
0184         template <>
0185         struct floating_point<32>
0186         {
0187             typedef float type;
0188         };
0189 
0190         template <>
0191         struct floating_point<64>
0192         {
0193             typedef double type;
0194         };
0195 
0196         ///////////////////////////////////////////////////////////////////////
0197         template <BOOST_SCOPED_ENUM(boost::endian::order) bits>
0198         struct what;
0199 
0200         template <>
0201         struct what<boost::endian::order::little>
0202         {
0203             static info is()
0204             {
0205                 return info("little-endian binary");
0206             }
0207         };
0208 
0209         template <>
0210         struct what<boost::endian::order::big>
0211         {
0212             static info is()
0213             {
0214                 return info("big-endian binary");
0215             }
0216         };
0217     }
0218 
0219     ///////////////////////////////////////////////////////////////////////////
0220     template <typename T, BOOST_SCOPED_ENUM(boost::endian::order) endian, int bits>
0221     struct any_binary_generator
0222       : primitive_generator<any_binary_generator<T, endian, bits> >
0223     {
0224         template <typename Context, typename Unused = unused_type>
0225         struct attribute: T {};
0226 
0227         template <
0228             typename OutputIterator, typename Context, typename Delimiter
0229           , typename Attribute>
0230         static bool generate(OutputIterator& sink, Context& context
0231           , Delimiter const& d, Attribute const& attr)
0232         {
0233             if (!traits::has_optional_value(attr))
0234                 return false;
0235 
0236             boost::endian::endian_arithmetic<endian, typename T::type, bits> p;
0237 
0238 #if defined(BOOST_MSVC)
0239 // warning C4244: 'argument' : conversion from 'const int' to 'foo', possible loss of data
0240 #pragma warning(push)
0241 #pragma warning(disable: 4244)
0242 #endif
0243             typedef typename T::type attribute_type;
0244             p = traits::extract_from<attribute_type>(attr, context);
0245 #if defined(BOOST_MSVC)
0246 #pragma warning(pop)
0247 #endif
0248 
0249             unsigned char const* bytes = p.data();
0250 
0251             for (unsigned int i = 0; i < sizeof(p); ++i)
0252             {
0253                 if (!detail::generate_to(sink, *bytes++))
0254                     return false;
0255             }
0256             return karma::delimit_out(sink, d);     // always do post-delimiting
0257         }
0258 
0259         // this any_byte_director has no parameter attached, it needs to have
0260         // been initialized from a direct literal
0261         template <
0262             typename OutputIterator, typename Context, typename Delimiter>
0263         static bool generate(OutputIterator&, Context&, Delimiter const&
0264           , unused_type)
0265         {
0266             // It is not possible (doesn't make sense) to use binary generators
0267             // without providing any attribute, as the generator doesn't 'know'
0268             // what to output. The following assertion fires if this situation
0269             // is detected in your code.
0270             BOOST_SPIRIT_ASSERT_FAIL(OutputIterator,
0271                 binary_generator_not_usable_without_attribute, ());
0272             return false;
0273         }
0274 
0275         template <typename Context>
0276         static info what(Context const& /*context*/)
0277         {
0278             return karma::detail::what<endian>::is();
0279         }
0280     };
0281 
0282     ///////////////////////////////////////////////////////////////////////////
0283     template <typename T, BOOST_SCOPED_ENUM(boost::endian::order) endian, int bits>
0284     struct literal_binary_generator
0285       : primitive_generator<literal_binary_generator<T, endian, bits> >
0286     {
0287         template <typename Context, typename Unused>
0288         struct attribute
0289         {
0290             typedef unused_type type;
0291         };
0292 
0293         template <typename V>
0294         literal_binary_generator(V const& v)
0295         {
0296 #if defined(BOOST_MSVC)
0297 // warning C4244: 'argument' : conversion from 'const int' to 'foo', possible loss of data
0298 #pragma warning(push)
0299 #pragma warning(disable: 4244)
0300 #endif
0301             data_ = v;
0302 #if defined(BOOST_MSVC)
0303 #pragma warning(pop)
0304 #endif
0305         }
0306 
0307         template <
0308             typename OutputIterator, typename Context, typename Delimiter
0309           , typename Attribute>
0310         bool generate(OutputIterator& sink, Context&, Delimiter const& d
0311           , Attribute const&) const
0312         {
0313             unsigned char const* bytes = data_.data();
0314 
0315             for (unsigned int i = 0; i < sizeof(data_type); ++i)
0316             {
0317                 if (!detail::generate_to(sink, *bytes++))
0318                     return false;
0319             }
0320             return karma::delimit_out(sink, d);  // always do post-delimiting
0321         }
0322 
0323         template <typename Context>
0324         static info what(Context const& /*context*/)
0325         {
0326             return karma::detail::what<endian>::is();
0327         }
0328 
0329         typedef boost::endian::endian_arithmetic<endian, typename T::type,
0330             bits> data_type;
0331 
0332         data_type data_;
0333     };
0334 
0335     ///////////////////////////////////////////////////////////////////////////
0336     // Generator generators: make_xxx function (objects)
0337     ///////////////////////////////////////////////////////////////////////////
0338     namespace detail
0339     {
0340         template <typename T, BOOST_SCOPED_ENUM(boost::endian::order) endian
0341           , int bits>
0342         struct basic_binary
0343         {
0344             typedef any_binary_generator<T, endian, bits> result_type;
0345 
0346             result_type operator()(unused_type, unused_type) const
0347             {
0348                 return result_type();
0349             }
0350         };
0351 
0352         template <typename Modifiers, typename T
0353           , BOOST_SCOPED_ENUM(boost::endian::order) endian, int bits>
0354         struct basic_binary_literal
0355         {
0356             typedef literal_binary_generator<T, endian, bits> result_type;
0357 
0358             template <typename Terminal>
0359             result_type operator()(Terminal const& term, unused_type) const
0360             {
0361                 return result_type(fusion::at_c<0>(term.args));
0362             }
0363         };
0364     }
0365 
0366 #define BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(name, endiantype, bits)            \
0367     template <typename Modifiers>                                             \
0368     struct make_primitive<tag::name, Modifiers>                               \
0369       : detail::basic_binary<detail::integer<bits>,                           \
0370         boost::endian::order::endiantype, bits> {};                           \
0371                                                                               \
0372     template <typename Modifiers, typename A0>                                \
0373     struct make_primitive<terminal_ex<tag::name, fusion::vector1<A0> >        \
0374           , Modifiers>                                                        \
0375       : detail::basic_binary_literal<Modifiers, detail::integer<bits>         \
0376         , boost::endian::order::endiantype, bits> {};                         \
0377                                                                               \
0378     /***/
0379 
0380     BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(byte_, native, 8)
0381     BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(word, native, 16)
0382     BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_word, big, 16)
0383     BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_word, little, 16)
0384     BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(dword, native, 32)
0385     BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_dword, big, 32)
0386     BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_dword, little, 32)
0387 #ifdef BOOST_HAS_LONG_LONG
0388     BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(qword, native, 64)
0389     BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_qword, big, 64)
0390     BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_qword, little, 64)
0391 #endif
0392 
0393 #undef BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE
0394 
0395 #define BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE(name, endiantype, bits)    \
0396     template <typename Modifiers>                                             \
0397     struct make_primitive<tag::name, Modifiers>                               \
0398       : detail::basic_binary<detail::floating_point<bits>,                    \
0399         boost::endian::order::endiantype, bits> {};                           \
0400                                                                               \
0401     template <typename Modifiers, typename A0>                                \
0402     struct make_primitive<terminal_ex<tag::name, fusion::vector1<A0> >        \
0403           , Modifiers>                                                        \
0404       : detail::basic_binary_literal<Modifiers, detail::floating_point<bits>  \
0405         , boost::endian::order::endiantype, bits> {};                         \
0406                                                                               \
0407     /***/
0408 
0409     BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE(bin_float, native, 32)
0410     BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE(big_bin_float, big, 32)
0411     BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE(little_bin_float, little, 32)
0412     BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE(bin_double, native, 64)
0413     BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE(big_bin_double, big, 64)
0414     BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE(little_bin_double, little, 64)
0415 
0416 #undef BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE
0417 
0418 }}}
0419 
0420 #endif