]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/spirit/home/x3/binary/binary.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / spirit / home / x3 / binary / binary.hpp
1 /*=============================================================================
2 Copyright (c) 2001-2011 Hartmut Kaiser
3 Copyright (c) 2001-2011 Joel de Guzman
4
5 Distributed under the Boost Software License, Version 1.0. (See accompanying
6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 ==============================================================================*/
8 #if !defined(BOOST_SPIRIT_X3_BINARY_MAY_08_2007_0808AM)
9 #define BOOST_SPIRIT_X3_BINARY_MAY_08_2007_0808AM
10
11 #include <boost/spirit/home/x3/core/parser.hpp>
12 #include <boost/spirit/home/x3/core/skip_over.hpp>
13 #include <boost/spirit/home/x3/support/traits/move_to.hpp>
14 #include <cstdint>
15
16 #include <boost/endian/conversion.hpp>
17 #include <boost/endian/arithmetic.hpp>
18 #include <boost/mpl/or.hpp>
19 #include <boost/type_traits/is_integral.hpp>
20 #include <boost/type_traits/is_enum.hpp>
21 #include <boost/type_traits/is_floating_point.hpp>
22 #include <boost/config.hpp>
23
24 namespace boost { namespace spirit { namespace x3
25 {
26 template <typename V, typename T
27 , boost::endian::order endian, std::size_t bits>
28 struct binary_lit_parser
29 : parser<binary_lit_parser<V, T, endian, bits> >
30 {
31 static bool const has_attribute = false;
32 typedef unused_type attribute_type;
33
34 binary_lit_parser(V n_)
35 : n(n_) {}
36
37 template <typename Iterator, typename Context, typename Attribute>
38 bool parse(Iterator& first, Iterator const& last
39 , Context const& context, unused_type, Attribute& attr_param) const
40 {
41 x3::skip_over(first, last, context);
42
43 auto bytes = reinterpret_cast<const unsigned char*>(&n);
44
45 Iterator it = first;
46 for (unsigned int i = 0; i < sizeof(n); ++i)
47 {
48 if (it == last || *bytes++ != static_cast<unsigned char>(*it++))
49 return false;
50 }
51
52 first = it;
53 x3::traits::move_to(n, attr_param);
54 return true;
55 }
56
57 boost::endian::endian_arithmetic<endian, T, bits> n;
58 };
59
60 ///////////////////////////////////////////////////////////////////////////
61 template <typename T, boost::endian::order endian, std::size_t bits>
62 struct any_binary_parser : parser<any_binary_parser<T, endian, bits > >
63 {
64
65 typedef T attribute_type;
66 static bool const has_attribute =
67 !is_same<unused_type, attribute_type>::value;
68
69 template <typename Iterator, typename Context, typename Attribute>
70 bool parse(Iterator& first, Iterator const& last
71 , Context const& context, unused_type, Attribute& attr_param) const
72 {
73 x3::skip_over(first, last, context);
74
75 attribute_type attr_;
76 auto bytes = reinterpret_cast<unsigned char*>(&attr_);
77
78 Iterator it = first;
79 for (unsigned int i = 0; i < sizeof(attr_); ++i)
80 {
81 if (it == last)
82 return false;
83 *bytes++ = *it++;
84 }
85
86 first = it;
87 x3::traits::move_to(
88 endian::conditional_reverse<endian, endian::order::native>(attr_)
89 , attr_param );
90 return true;
91 }
92
93 template <typename V>
94 binary_lit_parser< V, T, endian, bits> operator()(V n) const
95 {
96 return {n};
97 }
98 };
99
100 #define BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(name, endiantype, attrtype, bits) \
101 typedef any_binary_parser< attrtype, boost::endian::order::endiantype, bits > name##type; \
102 name##type const name = name##type();
103
104
105 BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(byte_, native, uint_least8_t, 8)
106 BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(word, native, uint_least16_t, 16)
107 BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_word, big, uint_least16_t, 16)
108 BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_word, little, uint_least16_t, 16)
109 BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(dword, native, uint_least32_t, 32)
110 BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_dword, big, uint_least32_t, 32)
111 BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_dword, little, uint_least32_t, 32)
112 #ifdef BOOST_HAS_LONG_LONG
113 BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(qword, native, uint_least64_t, 64)
114 BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_qword, big, uint_least64_t, 64)
115 BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_qword, little, uint_least64_t, 64)
116 #endif
117
118 // Use a pseudo configuration macro to make clear that endian libray support
119 // for floating point types is required. Must be removed as soon as the endian library
120 // properly supports floating point types.
121 #ifdef BOOST_ENDIAN_HAS_FLOATING_POINT
122 BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(bin_float, native, float, 32)
123 BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_bin_float, big, float, 32)
124 BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_bin_float, little, float, 32)
125 BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(bin_double, native, double, 64)
126 BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_bin_double, big, double, 64)
127 BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_bin_double, little, double, 64)
128 #endif
129
130 #undef BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE
131
132 ///////////////////////////////////////////////////////////////////////////
133 template <typename T, std::size_t bits>
134 struct get_info<any_binary_parser<T, endian::order::little, bits>>
135 {
136 typedef std::string result_type;
137 std::string operator()(any_binary_parser<T, endian::order::little, bits> const& p) const
138 {
139 return "little-endian binary";
140 }
141 };
142
143 template <typename T, std::size_t bits>
144 struct get_info<any_binary_parser<T, endian::order::big, bits>>
145 {
146 typedef std::string result_type;
147 std::string operator()(any_binary_parser<T, endian::order::big, bits> const& p) const
148 {
149 return "big-endian binary";
150 }
151 };
152
153 template <typename V, typename T, std::size_t bits>
154 struct get_info<binary_lit_parser<V, T, endian::order::little, bits>>
155 {
156 typedef std::string result_type;
157 std::string operator()(binary_lit_parser<V, T, endian::order::little, bits> const& p) const
158 {
159 return "little-endian binary";
160 }
161 };
162
163 template <typename V, typename T, std::size_t bits>
164 struct get_info<binary_lit_parser<V, T, endian::order::big, bits>>
165 {
166 typedef std::string result_type;
167 std::string operator()(binary_lit_parser<V, T, endian::order::big, bits> const& p) const
168 {
169 return "big-endian binary";
170 }
171 };
172
173 }}}
174
175 #endif