]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/spirit/home/x3/binary/binary.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / spirit / home / x3 / binary / binary.hpp
CommitLineData
7c673cae
FG
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>
7c673cae
FG
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>
20effc67 23#include <climits>
7c673cae
FG
24
25namespace boost { namespace spirit { namespace x3
26{
27 template <typename V, typename T
28 , boost::endian::order endian, std::size_t bits>
29 struct binary_lit_parser
30 : parser<binary_lit_parser<V, T, endian, bits> >
31 {
32 static bool const has_attribute = false;
33 typedef unused_type attribute_type;
34
f67539c2 35 constexpr binary_lit_parser(V n_)
7c673cae
FG
36 : n(n_) {}
37
38 template <typename Iterator, typename Context, typename Attribute>
39 bool parse(Iterator& first, Iterator const& last
11fdf7f2 40 , Context const& context, unused_type, Attribute& attr_param) const
7c673cae
FG
41 {
42 x3::skip_over(first, last, context);
43
f67539c2 44 unsigned char const* bytes = n.data();
7c673cae
FG
45
46 Iterator it = first;
47 for (unsigned int i = 0; i < sizeof(n); ++i)
48 {
49 if (it == last || *bytes++ != static_cast<unsigned char>(*it++))
50 return false;
51 }
52
53 first = it;
54 x3::traits::move_to(n, attr_param);
55 return true;
56 }
57
58 boost::endian::endian_arithmetic<endian, T, bits> n;
59 };
60
61 ///////////////////////////////////////////////////////////////////////////
62 template <typename T, boost::endian::order endian, std::size_t bits>
63 struct any_binary_parser : parser<any_binary_parser<T, endian, bits > >
64 {
65
66 typedef T attribute_type;
67 static bool const has_attribute =
68 !is_same<unused_type, attribute_type>::value;
69
70 template <typename Iterator, typename Context, typename Attribute>
71 bool parse(Iterator& first, Iterator const& last
11fdf7f2 72 , Context const& context, unused_type, Attribute& attr_param) const
7c673cae
FG
73 {
74 x3::skip_over(first, last, context);
75
20effc67
TL
76 // Properly align the buffer for performance reasons
77 alignas(T) unsigned char buf[sizeof(T)];
78 unsigned char * bytes = buf;
7c673cae
FG
79
80 Iterator it = first;
20effc67 81 for (unsigned int i = 0; i < sizeof(T); ++i)
7c673cae
FG
82 {
83 if (it == last)
84 return false;
85 *bytes++ = *it++;
86 }
87
88 first = it;
20effc67
TL
89
90 static_assert(bits % CHAR_BIT == 0,
91 "Boost.Endian supports only multiples of CHAR_BIT");
7c673cae 92 x3::traits::move_to(
20effc67
TL
93 endian::endian_load<T, bits / CHAR_BIT, endian>(buf),
94 attr_param);
7c673cae
FG
95 return true;
96 }
97
98 template <typename V>
f67539c2 99 constexpr binary_lit_parser< V, T, endian, bits> operator()(V n) const
7c673cae
FG
100 {
101 return {n};
102 }
103 };
104
105#define BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(name, endiantype, attrtype, bits) \
106 typedef any_binary_parser< attrtype, boost::endian::order::endiantype, bits > name##type; \
f67539c2 107 constexpr name##type name = name##type();
7c673cae
FG
108
109
110 BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(byte_, native, uint_least8_t, 8)
111 BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(word, native, uint_least16_t, 16)
112 BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_word, big, uint_least16_t, 16)
113 BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_word, little, uint_least16_t, 16)
114 BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(dword, native, uint_least32_t, 32)
115 BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_dword, big, uint_least32_t, 32)
116 BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_dword, little, uint_least32_t, 32)
117#ifdef BOOST_HAS_LONG_LONG
118 BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(qword, native, uint_least64_t, 64)
119 BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_qword, big, uint_least64_t, 64)
120 BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_qword, little, uint_least64_t, 64)
121#endif
20effc67
TL
122 BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(bin_float, native, float, sizeof(float) * CHAR_BIT)
123 BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_bin_float, big, float, sizeof(float) * CHAR_BIT)
124 BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_bin_float, little, float, sizeof(float) * CHAR_BIT)
125 BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(bin_double, native, double, sizeof(double) * CHAR_BIT)
126 BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_bin_double, big, double, sizeof(double) * CHAR_BIT)
127 BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_bin_double, little, double, sizeof(double) * CHAR_BIT)
7c673cae
FG
128
129#undef BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE
130
131 ///////////////////////////////////////////////////////////////////////////
132 template <typename T, std::size_t bits>
133 struct get_info<any_binary_parser<T, endian::order::little, bits>>
134 {
135 typedef std::string result_type;
20effc67 136 std::string operator()(any_binary_parser<T, endian::order::little, bits> const&) const
7c673cae
FG
137 {
138 return "little-endian binary";
139 }
140 };
141
142 template <typename T, std::size_t bits>
143 struct get_info<any_binary_parser<T, endian::order::big, bits>>
144 {
145 typedef std::string result_type;
20effc67 146 std::string operator()(any_binary_parser<T, endian::order::big, bits> const&) const
7c673cae
FG
147 {
148 return "big-endian binary";
149 }
150 };
151
152 template <typename V, typename T, std::size_t bits>
153 struct get_info<binary_lit_parser<V, T, endian::order::little, bits>>
154 {
155 typedef std::string result_type;
20effc67 156 std::string operator()(binary_lit_parser<V, T, endian::order::little, bits> const&) const
7c673cae
FG
157 {
158 return "little-endian binary";
159 }
160 };
161
162 template <typename V, typename T, std::size_t bits>
163 struct get_info<binary_lit_parser<V, T, endian::order::big, bits>>
164 {
165 typedef std::string result_type;
20effc67 166 std::string operator()(binary_lit_parser<V, T, endian::order::big, bits> const&) const
7c673cae
FG
167 {
168 return "big-endian binary";
169 }
170 };
171
172}}}
173
174#endif