Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-01 08:31:50

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