Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 10:02:34

0001 /*=============================================================================
0002     Copyright (c) 2001-2011 Hartmut Kaiser
0003     Copyright (c) 2001-2011 Joel de Guzman
0004 
0005     Distributed under the Boost Software License, Version 1.0. (See accompanying
0006     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 ==============================================================================*/
0008 #if !defined(BOOST_SPIRIT_X3_BINARY_MAY_08_2007_0808AM)
0009 #define BOOST_SPIRIT_X3_BINARY_MAY_08_2007_0808AM
0010 
0011 #include <boost/spirit/home/x3/core/parser.hpp>
0012 #include <boost/spirit/home/x3/core/skip_over.hpp>
0013 #include <boost/spirit/home/x3/support/traits/move_to.hpp>
0014 #include <cstdint>
0015 
0016 #include <boost/endian/conversion.hpp>
0017 #include <boost/endian/arithmetic.hpp>
0018 #include <boost/mpl/or.hpp>
0019 #include <boost/type_traits/is_integral.hpp>
0020 #include <boost/type_traits/is_enum.hpp>
0021 #include <boost/type_traits/is_floating_point.hpp>
0022 #include <boost/config.hpp>
0023 #include <climits>
0024 
0025 namespace boost { namespace spirit { namespace x3
0026 {
0027     template <typename T, boost::endian::order endian, std::size_t bits>
0028     struct binary_lit_parser
0029       : parser<binary_lit_parser<T, endian, bits> >
0030     {
0031         static bool const has_attribute = false;
0032         typedef unused_type attribute_type;
0033 
0034         constexpr binary_lit_parser(T n_)
0035           : n(n_) {}
0036 
0037         template <typename Iterator, typename Context, typename Attribute>
0038         bool parse(Iterator& first, Iterator const& last
0039           , Context const& context, unused_type, Attribute& attr_param) const
0040         {
0041             x3::skip_over(first, last, context);
0042 
0043             unsigned char const* bytes = n.data();
0044 
0045             Iterator it = first;
0046             for (unsigned int i = 0; i < sizeof(n); ++i)
0047             {
0048                 if (it == last || *bytes++ != static_cast<unsigned char>(*it++))
0049                     return false;
0050             }
0051 
0052             first = it;
0053             x3::traits::move_to(n, attr_param);
0054             return true;
0055         }
0056 
0057         boost::endian::endian_arithmetic<endian, T, bits> n;
0058     };
0059 
0060     ///////////////////////////////////////////////////////////////////////////
0061     template <typename T, boost::endian::order endian, std::size_t bits>
0062     struct any_binary_parser : parser<any_binary_parser<T, endian, bits > >
0063     {
0064 
0065         typedef T attribute_type;
0066         static bool const has_attribute =
0067             !is_same<unused_type, attribute_type>::value;
0068 
0069         template <typename Iterator, typename Context, typename Attribute>
0070         bool parse(Iterator& first, Iterator const& last
0071           , Context const& context, unused_type, Attribute& attr_param) const
0072         {
0073             x3::skip_over(first, last, context);
0074 
0075             // Properly align the buffer for performance reasons
0076             alignas(T) unsigned char buf[sizeof(T)];
0077             unsigned char * bytes = buf;
0078 
0079             Iterator it = first;
0080             for (unsigned int i = 0; i < sizeof(T); ++i)
0081             {
0082                 if (it == last)
0083                     return false;
0084                 *bytes++ = *it++;
0085             }
0086 
0087             first = it;
0088 
0089             static_assert(bits % CHAR_BIT == 0,
0090                           "Boost.Endian supports only multiples of CHAR_BIT");
0091             x3::traits::move_to(
0092                 endian::endian_load<T, bits / CHAR_BIT, endian>(buf),
0093                 attr_param);
0094             return true;
0095         }
0096 
0097         constexpr binary_lit_parser<T, endian, bits> operator()(T n) const
0098         {
0099             return {n};
0100         }
0101     };
0102 
0103 #define BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(name, endiantype, attrtype, bits)                  \
0104     typedef any_binary_parser< attrtype, boost::endian::order::endiantype, bits > name##type; \
0105     constexpr name##type name = name##type();
0106 
0107 
0108     BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(byte_, native, uint_least8_t, 8)
0109     BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(word, native, uint_least16_t, 16)
0110     BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_word, big, uint_least16_t, 16)
0111     BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_word, little, uint_least16_t, 16)
0112     BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(dword, native, uint_least32_t, 32)
0113     BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_dword, big, uint_least32_t, 32)
0114     BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_dword, little, uint_least32_t, 32)
0115 #ifdef BOOST_HAS_LONG_LONG
0116     BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(qword, native, uint_least64_t, 64)
0117     BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_qword, big, uint_least64_t, 64)
0118     BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_qword, little, uint_least64_t, 64)
0119 #endif
0120     BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(bin_float, native, float, sizeof(float) * CHAR_BIT)
0121     BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_bin_float, big, float, sizeof(float) * CHAR_BIT)
0122     BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_bin_float, little, float, sizeof(float) * CHAR_BIT)
0123     BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(bin_double, native, double, sizeof(double) * CHAR_BIT)
0124     BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_bin_double, big, double, sizeof(double) * CHAR_BIT)
0125     BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_bin_double, little, double, sizeof(double) * CHAR_BIT)
0126 
0127 #undef BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE
0128 
0129     ///////////////////////////////////////////////////////////////////////////
0130     template <typename T, std::size_t bits>
0131     struct get_info<any_binary_parser<T, endian::order::little, bits>>
0132     {
0133         typedef std::string result_type;
0134         std::string operator()(any_binary_parser<T, endian::order::little, bits> const&) const
0135         {
0136             return "little-endian binary";
0137         }
0138     };
0139 
0140     template <typename T, std::size_t bits>
0141     struct get_info<any_binary_parser<T, endian::order::big, bits>>
0142     {
0143         typedef std::string result_type;
0144         std::string operator()(any_binary_parser<T, endian::order::big, bits> const&) const
0145         {
0146             return "big-endian binary";
0147         }
0148     };
0149 
0150     template <typename T, std::size_t bits>
0151     struct get_info<binary_lit_parser<T, endian::order::little, bits>>
0152     {
0153         typedef std::string result_type;
0154         std::string operator()(binary_lit_parser<T, endian::order::little, bits> const&) const
0155         {
0156             return "little-endian binary";
0157         }
0158     };
0159 
0160     template <typename T, std::size_t bits>
0161     struct get_info<binary_lit_parser<T, endian::order::big, bits>>
0162     {
0163         typedef std::string result_type;
0164         std::string operator()(binary_lit_parser<T, endian::order::big, bits> const&) const
0165         {
0166             return "big-endian binary";
0167         }
0168     };
0169 
0170 }}}
0171 
0172 #endif