]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Boost endian.hpp header file -------------------------------------------------------// |
2 | ||
3 | // (C) Copyright Darin Adler 2000 | |
4 | // (C) Copyright Beman Dawes 2006, 2009 | |
5 | ||
6 | // Distributed under the Boost Software License, Version 1.0. | |
7 | // See http://www.boost.org/LICENSE_1_0.txt | |
8 | ||
9 | // See library home page at http://www.boost.org/libs/endian | |
10 | ||
11 | //--------------------------------------------------------------------------------------// | |
12 | ||
13 | // Original design developed by Darin Adler based on classes developed by Mark | |
14 | // Borgerding. Four original class templates were combined into a single endian | |
15 | // class template by Beman Dawes, who also added the unrolled_byte_loops sign | |
16 | // partial specialization to correctly extend the sign when cover integer size | |
17 | // differs from endian representation size. | |
18 | ||
19 | // TODO: When a compiler supporting constexpr becomes available, try possible uses. | |
20 | ||
21 | #ifndef BOOST_SPIRIT_ENDIAN_HPP | |
22 | #define BOOST_SPIRIT_ENDIAN_HPP | |
23 | ||
24 | #if defined(_MSC_VER) | |
25 | #pragma once | |
26 | #endif | |
27 | ||
28 | #ifdef BOOST_ENDIAN_LOG | |
29 | # include <iostream> | |
30 | #endif | |
31 | ||
32 | #if defined(__BORLANDC__) || defined( __CODEGEARC__) | |
33 | # pragma pack(push, 1) | |
34 | #endif | |
35 | ||
36 | #include <boost/config.hpp> | |
92f5a8d4 TL |
37 | #include <boost/predef/other/endian.h> |
38 | #ifndef BOOST_MINIMAL_INTEGER_COVER_OPERATORS | |
7c673cae | 39 | #define BOOST_MINIMAL_INTEGER_COVER_OPERATORS |
92f5a8d4 TL |
40 | #endif |
41 | #ifndef BOOST_NO_IO_COVER_OPERATORS | |
7c673cae | 42 | #define BOOST_NO_IO_COVER_OPERATORS |
92f5a8d4 | 43 | #endif |
7c673cae FG |
44 | #include <boost/spirit/home/support/detail/endian/cover_operators.hpp> |
45 | #undef BOOST_NO_IO_COVER_OPERATORS | |
46 | #undef BOOST_MINIMAL_INTEGER_COVER_OPERATORS | |
47 | #include <boost/type_traits/is_signed.hpp> | |
48 | #include <boost/type_traits/make_unsigned.hpp> | |
49 | #include <boost/cstdint.hpp> | |
50 | #include <boost/static_assert.hpp> | |
51 | #include <boost/spirit/home/support/detail/scoped_enum_emulation.hpp> | |
52 | #include <iosfwd> | |
53 | #include <climits> | |
54 | ||
55 | # if CHAR_BIT != 8 | |
56 | # error Platforms with CHAR_BIT != 8 are not supported | |
57 | # endif | |
58 | ||
92f5a8d4 | 59 | # define BOOST_SPIRIT_ENDIAN_DEFAULT_CONSTRUCT {} // C++03 |
7c673cae | 60 | |
92f5a8d4 TL |
61 | # if defined(BOOST_ENDIAN_NO_CTORS) || defined(BOOST_ENDIAN_FORCE_PODNESS) |
62 | # define BOOST_SPIRIT_ENDIAN_NO_CTORS | |
7c673cae FG |
63 | # endif |
64 | ||
65 | ||
66 | namespace boost { namespace spirit | |
67 | { | |
68 | namespace detail | |
69 | { | |
70 | // Unrolled loops for loading and storing streams of bytes. | |
71 | ||
72 | template <typename T, std::size_t n_bytes, | |
73 | bool sign=boost::is_signed<T>::value > | |
74 | struct unrolled_byte_loops | |
75 | { | |
76 | typedef unrolled_byte_loops<T, n_bytes - 1, sign> next; | |
77 | ||
78 | static typename boost::make_unsigned<T>::type load_big(const unsigned char* bytes) | |
79 | { return *(bytes - 1) | (next::load_big(bytes - 1) << 8); } | |
80 | static typename boost::make_unsigned<T>::type load_little(const unsigned char* bytes) | |
81 | { return *bytes | (next::load_little(bytes + 1) << 8); } | |
82 | ||
83 | static void store_big(char* bytes, T value) | |
84 | { | |
85 | *(bytes - 1) = static_cast<char>(value); | |
86 | next::store_big(bytes - 1, value >> 8); | |
87 | } | |
88 | static void store_little(char* bytes, T value) | |
89 | { | |
90 | *bytes = static_cast<char>(value); | |
91 | next::store_little(bytes + 1, value >> 8); | |
92 | } | |
93 | }; | |
94 | ||
95 | template <typename T> | |
96 | struct unrolled_byte_loops<T, 1, false> | |
97 | { | |
98 | static T load_big(const unsigned char* bytes) | |
99 | { return *(bytes - 1); } | |
100 | static T load_little(const unsigned char* bytes) | |
101 | { return *bytes; } | |
102 | static void store_big(char* bytes, T value) | |
103 | { *(bytes - 1) = static_cast<char>(value); } | |
104 | static void store_little(char* bytes, T value) | |
105 | { *bytes = static_cast<char>(value); } | |
106 | ||
107 | }; | |
108 | ||
109 | template <typename T> | |
110 | struct unrolled_byte_loops<T, 1, true> | |
111 | { | |
112 | static typename boost::make_unsigned<T>::type load_big(const unsigned char* bytes) | |
113 | { return *(bytes - 1); } | |
114 | static typename boost::make_unsigned<T>::type load_little(const unsigned char* bytes) | |
115 | { return *bytes; } | |
116 | static void store_big(char* bytes, T value) | |
117 | { *(bytes - 1) = static_cast<char>(value); } | |
118 | static void store_little(char* bytes, T value) | |
119 | { *bytes = static_cast<char>(value); } | |
120 | }; | |
121 | ||
122 | template <typename T, std::size_t n_bytes> | |
123 | inline | |
124 | T load_big_endian(const void* bytes) | |
125 | { | |
126 | return static_cast<T>(unrolled_byte_loops<T, n_bytes>::load_big | |
127 | (static_cast<const unsigned char*>(bytes) + n_bytes)); | |
128 | } | |
129 | ||
130 | template <> | |
131 | inline | |
132 | float load_big_endian<float, 4>(const void* bytes) | |
133 | { | |
134 | const unsigned char *b = reinterpret_cast<const unsigned char *>( | |
135 | bytes); | |
136 | b += 3; | |
137 | ||
138 | float value; | |
139 | unsigned char *v = reinterpret_cast<unsigned char *>(&value); | |
140 | ||
141 | for(std::size_t i = 0; i < 4; ++i) | |
142 | { | |
143 | *v++ = *b--; | |
144 | } | |
145 | ||
146 | return value; | |
147 | } | |
148 | ||
149 | template <> | |
150 | inline | |
151 | double load_big_endian<double, 8>(const void* bytes) | |
152 | { | |
153 | const unsigned char *b = reinterpret_cast<const unsigned char *>( | |
154 | bytes); | |
155 | b += 7; | |
156 | ||
157 | double value; | |
158 | unsigned char *v = reinterpret_cast<unsigned char *>(&value); | |
159 | ||
160 | for(std::size_t i = 0; i < 8; ++i) | |
161 | { | |
162 | *v++ = *b--; | |
163 | } | |
164 | ||
165 | return value; | |
166 | } | |
167 | ||
168 | template <typename T, std::size_t n_bytes> | |
169 | inline | |
170 | T load_little_endian(const void* bytes) | |
171 | { | |
172 | return static_cast<T>(unrolled_byte_loops<T, n_bytes>::load_little | |
173 | (static_cast<const unsigned char*>(bytes))); | |
174 | } | |
175 | ||
176 | template <> | |
177 | inline | |
178 | float load_little_endian<float, 4>(const void* bytes) | |
179 | { | |
180 | const unsigned char *b = reinterpret_cast<const unsigned char *>( | |
181 | bytes); | |
182 | ||
183 | float value; | |
184 | unsigned char *v = reinterpret_cast<unsigned char *>(&value); | |
185 | ||
186 | for(std::size_t i = 0; i < 4; ++i) | |
187 | { | |
188 | *v++ = *b++; | |
189 | } | |
190 | ||
191 | return value; | |
192 | } | |
193 | ||
194 | template <> | |
195 | inline | |
196 | double load_little_endian<double, 8>(const void* bytes) | |
197 | { | |
198 | const unsigned char *b = reinterpret_cast<const unsigned char *>( | |
199 | bytes); | |
200 | ||
201 | double value; | |
202 | unsigned char *v = reinterpret_cast<unsigned char *>(&value); | |
203 | ||
204 | for(std::size_t i = 0; i < 8; ++i) | |
205 | { | |
206 | *v++ = *b++; | |
207 | } | |
208 | ||
209 | return value; | |
210 | } | |
211 | ||
212 | template <typename T, std::size_t n_bytes> | |
213 | inline | |
214 | void store_big_endian(void* bytes, T value) | |
215 | { | |
216 | unrolled_byte_loops<T, n_bytes>::store_big | |
217 | (static_cast<char*>(bytes) + n_bytes, value); | |
218 | } | |
219 | ||
220 | template <> | |
221 | inline | |
222 | void store_big_endian<float, 4>(void* bytes, float value) | |
223 | { | |
224 | unsigned char *b = reinterpret_cast<unsigned char *>(bytes); | |
225 | b += 3; | |
226 | ||
227 | const unsigned char *v = reinterpret_cast<const unsigned char *>( | |
228 | &value); | |
229 | ||
230 | for(std::size_t i = 0; i < 4; ++i) | |
231 | { | |
232 | *b-- = *v++; | |
233 | } | |
234 | } | |
235 | ||
236 | template <> | |
237 | inline | |
238 | void store_big_endian<double, 8>(void* bytes, double value) | |
239 | { | |
240 | unsigned char *b = reinterpret_cast<unsigned char *>(bytes); | |
241 | b += 7; | |
242 | ||
243 | const unsigned char *v = reinterpret_cast<const unsigned char *>( | |
244 | &value); | |
245 | ||
246 | for(std::size_t i = 0; i < 8; ++i) | |
247 | { | |
248 | *b-- = *v++; | |
249 | } | |
250 | } | |
251 | ||
252 | template <typename T, std::size_t n_bytes> | |
253 | inline | |
254 | void store_little_endian(void* bytes, T value) | |
255 | { | |
256 | unrolled_byte_loops<T, n_bytes>::store_little | |
257 | (static_cast<char*>(bytes), value); | |
258 | } | |
259 | ||
260 | template <> | |
261 | inline | |
262 | void store_little_endian<float, 4>(void* bytes, float value) | |
263 | { | |
264 | unsigned char *b = reinterpret_cast<unsigned char *>(bytes); | |
265 | ||
266 | const unsigned char *v = reinterpret_cast<const unsigned char *>( | |
267 | &value); | |
268 | ||
269 | for(std::size_t i = 0; i < 4; ++i) | |
270 | { | |
271 | *b++ = *v++; | |
272 | } | |
273 | } | |
274 | ||
275 | template <> | |
276 | inline | |
277 | void store_little_endian<double, 8>(void* bytes, double value) | |
278 | { | |
279 | unsigned char *b = reinterpret_cast<unsigned char *>(bytes); | |
280 | ||
281 | const unsigned char *v = reinterpret_cast<const unsigned char *>( | |
282 | &value); | |
283 | ||
284 | for(std::size_t i = 0; i < 8; ++i) | |
285 | { | |
286 | *b++ = *v++; | |
287 | } | |
288 | } | |
289 | ||
290 | } // namespace detail | |
291 | ||
292 | namespace endian | |
293 | { | |
294 | ||
295 | # ifdef BOOST_ENDIAN_LOG | |
296 | bool endian_log(true); | |
297 | # endif | |
298 | ||
299 | ||
300 | // endian class template and specializations ---------------------------------------// | |
301 | ||
302 | BOOST_SCOPED_ENUM_START(endianness) { big, little, native }; BOOST_SCOPED_ENUM_END | |
303 | BOOST_SCOPED_ENUM_START(alignment) { unaligned, aligned }; BOOST_SCOPED_ENUM_END | |
304 | ||
305 | template <BOOST_SCOPED_ENUM(endianness) E, typename T, std::size_t n_bits, | |
306 | BOOST_SCOPED_ENUM(alignment) A = alignment::unaligned> | |
307 | class endian; | |
308 | ||
309 | // Specializations that represent unaligned bytes. | |
310 | // Taking an integer type as a parameter provides a nice way to pass both | |
311 | // the size and signedness of the desired integer and get the appropriate | |
312 | // corresponding integer type for the interface. | |
313 | ||
314 | // unaligned big endian specialization | |
315 | template <typename T, std::size_t n_bits> | |
316 | class endian< endianness::big, T, n_bits, alignment::unaligned > | |
317 | : cover_operators< endian< endianness::big, T, n_bits >, T > | |
318 | { | |
319 | BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits ); | |
320 | public: | |
321 | typedef T value_type; | |
92f5a8d4 TL |
322 | # ifndef BOOST_SPIRIT_ENDIAN_NO_CTORS |
323 | endian() BOOST_SPIRIT_ENDIAN_DEFAULT_CONSTRUCT | |
7c673cae FG |
324 | explicit endian(T val) |
325 | { | |
326 | # ifdef BOOST_ENDIAN_LOG | |
327 | if ( endian_log ) | |
328 | std::clog << "big, unaligned, " << n_bits << "-bits, construct(" << val << ")\n"; | |
329 | # endif | |
330 | detail::store_big_endian<T, n_bits/8>(m_value, val); | |
331 | } | |
332 | # endif | |
333 | endian & operator=(T val) { detail::store_big_endian<T, n_bits/8>(m_value, val); return *this; } | |
334 | operator T() const | |
335 | { | |
336 | # ifdef BOOST_ENDIAN_LOG | |
337 | if ( endian_log ) | |
338 | std::clog << "big, unaligned, " << n_bits << "-bits, convert(" << detail::load_big_endian<T, n_bits/8>(m_value) << ")\n"; | |
339 | # endif | |
340 | return detail::load_big_endian<T, n_bits/8>(m_value); | |
341 | } | |
342 | private: | |
343 | char m_value[n_bits/8]; | |
344 | }; | |
345 | ||
346 | // unaligned little endian specialization | |
347 | template <typename T, std::size_t n_bits> | |
348 | class endian< endianness::little, T, n_bits, alignment::unaligned > | |
349 | : cover_operators< endian< endianness::little, T, n_bits >, T > | |
350 | { | |
351 | BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits ); | |
352 | public: | |
353 | typedef T value_type; | |
92f5a8d4 TL |
354 | # ifndef BOOST_SPIRIT_ENDIAN_NO_CTORS |
355 | endian() BOOST_SPIRIT_ENDIAN_DEFAULT_CONSTRUCT | |
7c673cae FG |
356 | explicit endian(T val) |
357 | { | |
358 | # ifdef BOOST_ENDIAN_LOG | |
359 | if ( endian_log ) | |
360 | std::clog << "little, unaligned, " << n_bits << "-bits, construct(" << val << ")\n"; | |
361 | # endif | |
362 | detail::store_little_endian<T, n_bits/8>(m_value, val); | |
363 | } | |
364 | # endif | |
365 | endian & operator=(T val) { detail::store_little_endian<T, n_bits/8>(m_value, val); return *this; } | |
366 | operator T() const | |
367 | { | |
368 | # ifdef BOOST_ENDIAN_LOG | |
369 | if ( endian_log ) | |
370 | std::clog << "little, unaligned, " << n_bits << "-bits, convert(" << detail::load_little_endian<T, n_bits/8>(m_value) << ")\n"; | |
371 | # endif | |
372 | return detail::load_little_endian<T, n_bits/8>(m_value); | |
373 | } | |
374 | private: | |
375 | char m_value[n_bits/8]; | |
376 | }; | |
377 | ||
378 | // unaligned native endian specialization | |
379 | template <typename T, std::size_t n_bits> | |
380 | class endian< endianness::native, T, n_bits, alignment::unaligned > | |
381 | : cover_operators< endian< endianness::native, T, n_bits >, T > | |
382 | { | |
383 | BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits ); | |
384 | public: | |
385 | typedef T value_type; | |
92f5a8d4 TL |
386 | # ifndef BOOST_SPIRIT_ENDIAN_NO_CTORS |
387 | endian() BOOST_SPIRIT_ENDIAN_DEFAULT_CONSTRUCT | |
388 | # if BOOST_ENDIAN_BIG_BYTE | |
7c673cae FG |
389 | explicit endian(T val) { detail::store_big_endian<T, n_bits/8>(m_value, val); } |
390 | # else | |
391 | explicit endian(T val) { detail::store_little_endian<T, n_bits/8>(m_value, val); } | |
392 | # endif | |
393 | # endif | |
92f5a8d4 | 394 | # if BOOST_ENDIAN_BIG_BYTE |
7c673cae FG |
395 | endian & operator=(T val) { detail::store_big_endian<T, n_bits/8>(m_value, val); return *this; } |
396 | operator T() const { return detail::load_big_endian<T, n_bits/8>(m_value); } | |
397 | # else | |
398 | endian & operator=(T val) { detail::store_little_endian<T, n_bits/8>(m_value, val); return *this; } | |
399 | operator T() const { return detail::load_little_endian<T, n_bits/8>(m_value); } | |
400 | # endif | |
401 | private: | |
402 | char m_value[n_bits/8]; | |
403 | }; | |
404 | ||
405 | // Specializations that mimic built-in integer types. | |
406 | // These typically have the same alignment as the underlying types. | |
407 | ||
408 | // aligned big endian specialization | |
409 | template <typename T, std::size_t n_bits> | |
410 | class endian< endianness::big, T, n_bits, alignment::aligned > | |
411 | : cover_operators< endian< endianness::big, T, n_bits, alignment::aligned >, T > | |
412 | { | |
413 | BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits ); | |
414 | BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 ); | |
415 | public: | |
416 | typedef T value_type; | |
92f5a8d4 TL |
417 | # ifndef BOOST_SPIRIT_ENDIAN_NO_CTORS |
418 | endian() BOOST_SPIRIT_ENDIAN_DEFAULT_CONSTRUCT | |
419 | # if BOOST_ENDIAN_BIG_BYTE | |
7c673cae FG |
420 | endian(T val) : m_value(val) { } |
421 | # else | |
422 | explicit endian(T val) { detail::store_big_endian<T, sizeof(T)>(&m_value, val); } | |
423 | # endif | |
424 | # endif | |
92f5a8d4 | 425 | # if BOOST_ENDIAN_BIG_BYTE |
7c673cae FG |
426 | endian & operator=(T val) { m_value = val; return *this; } |
427 | operator T() const { return m_value; } | |
428 | # else | |
429 | endian & operator=(T val) { detail::store_big_endian<T, sizeof(T)>(&m_value, val); return *this; } | |
430 | operator T() const { return detail::load_big_endian<T, sizeof(T)>(&m_value); } | |
431 | # endif | |
432 | private: | |
433 | T m_value; | |
434 | }; | |
435 | ||
436 | // aligned little endian specialization | |
437 | template <typename T, std::size_t n_bits> | |
438 | class endian< endianness::little, T, n_bits, alignment::aligned > | |
439 | : cover_operators< endian< endianness::little, T, n_bits, alignment::aligned >, T > | |
440 | { | |
441 | BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits ); | |
442 | BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 ); | |
443 | public: | |
444 | typedef T value_type; | |
92f5a8d4 TL |
445 | # ifndef BOOST_SPIRIT_ENDIAN_NO_CTORS |
446 | endian() BOOST_SPIRIT_ENDIAN_DEFAULT_CONSTRUCT | |
447 | # if BOOST_ENDIAN_LITTLE_BYTE | |
7c673cae FG |
448 | endian(T val) : m_value(val) { } |
449 | # else | |
450 | explicit endian(T val) { detail::store_little_endian<T, sizeof(T)>(&m_value, val); } | |
451 | # endif | |
452 | # endif | |
92f5a8d4 | 453 | # if BOOST_ENDIAN_LITTLE_BYTE |
7c673cae FG |
454 | endian & operator=(T val) { m_value = val; return *this; } |
455 | operator T() const { return m_value; } | |
456 | #else | |
457 | endian & operator=(T val) { detail::store_little_endian<T, sizeof(T)>(&m_value, val); return *this; } | |
458 | operator T() const { return detail::load_little_endian<T, sizeof(T)>(&m_value); } | |
459 | #endif | |
460 | private: | |
461 | T m_value; | |
462 | }; | |
463 | ||
464 | // naming convention typedefs ------------------------------------------------------// | |
465 | ||
466 | // unaligned big endian signed integer types | |
467 | typedef endian< endianness::big, int_least8_t, 8 > big8_t; | |
468 | typedef endian< endianness::big, int_least16_t, 16 > big16_t; | |
469 | typedef endian< endianness::big, int_least32_t, 24 > big24_t; | |
470 | typedef endian< endianness::big, int_least32_t, 32 > big32_t; | |
471 | typedef endian< endianness::big, int_least64_t, 40 > big40_t; | |
472 | typedef endian< endianness::big, int_least64_t, 48 > big48_t; | |
473 | typedef endian< endianness::big, int_least64_t, 56 > big56_t; | |
474 | typedef endian< endianness::big, int_least64_t, 64 > big64_t; | |
475 | ||
476 | // unaligned big endian unsigned integer types | |
477 | typedef endian< endianness::big, uint_least8_t, 8 > ubig8_t; | |
478 | typedef endian< endianness::big, uint_least16_t, 16 > ubig16_t; | |
479 | typedef endian< endianness::big, uint_least32_t, 24 > ubig24_t; | |
480 | typedef endian< endianness::big, uint_least32_t, 32 > ubig32_t; | |
481 | typedef endian< endianness::big, uint_least64_t, 40 > ubig40_t; | |
482 | typedef endian< endianness::big, uint_least64_t, 48 > ubig48_t; | |
483 | typedef endian< endianness::big, uint_least64_t, 56 > ubig56_t; | |
484 | typedef endian< endianness::big, uint_least64_t, 64 > ubig64_t; | |
485 | ||
486 | // unaligned little endian signed integer types | |
487 | typedef endian< endianness::little, int_least8_t, 8 > little8_t; | |
488 | typedef endian< endianness::little, int_least16_t, 16 > little16_t; | |
489 | typedef endian< endianness::little, int_least32_t, 24 > little24_t; | |
490 | typedef endian< endianness::little, int_least32_t, 32 > little32_t; | |
491 | typedef endian< endianness::little, int_least64_t, 40 > little40_t; | |
492 | typedef endian< endianness::little, int_least64_t, 48 > little48_t; | |
493 | typedef endian< endianness::little, int_least64_t, 56 > little56_t; | |
494 | typedef endian< endianness::little, int_least64_t, 64 > little64_t; | |
495 | ||
496 | // unaligned little endian unsigned integer types | |
497 | typedef endian< endianness::little, uint_least8_t, 8 > ulittle8_t; | |
498 | typedef endian< endianness::little, uint_least16_t, 16 > ulittle16_t; | |
499 | typedef endian< endianness::little, uint_least32_t, 24 > ulittle24_t; | |
500 | typedef endian< endianness::little, uint_least32_t, 32 > ulittle32_t; | |
501 | typedef endian< endianness::little, uint_least64_t, 40 > ulittle40_t; | |
502 | typedef endian< endianness::little, uint_least64_t, 48 > ulittle48_t; | |
503 | typedef endian< endianness::little, uint_least64_t, 56 > ulittle56_t; | |
504 | typedef endian< endianness::little, uint_least64_t, 64 > ulittle64_t; | |
505 | ||
506 | // unaligned native endian signed integer types | |
507 | typedef endian< endianness::native, int_least8_t, 8 > native8_t; | |
508 | typedef endian< endianness::native, int_least16_t, 16 > native16_t; | |
509 | typedef endian< endianness::native, int_least32_t, 24 > native24_t; | |
510 | typedef endian< endianness::native, int_least32_t, 32 > native32_t; | |
511 | typedef endian< endianness::native, int_least64_t, 40 > native40_t; | |
512 | typedef endian< endianness::native, int_least64_t, 48 > native48_t; | |
513 | typedef endian< endianness::native, int_least64_t, 56 > native56_t; | |
514 | typedef endian< endianness::native, int_least64_t, 64 > native64_t; | |
515 | ||
516 | // unaligned native endian unsigned integer types | |
517 | typedef endian< endianness::native, uint_least8_t, 8 > unative8_t; | |
518 | typedef endian< endianness::native, uint_least16_t, 16 > unative16_t; | |
519 | typedef endian< endianness::native, uint_least32_t, 24 > unative24_t; | |
520 | typedef endian< endianness::native, uint_least32_t, 32 > unative32_t; | |
521 | typedef endian< endianness::native, uint_least64_t, 40 > unative40_t; | |
522 | typedef endian< endianness::native, uint_least64_t, 48 > unative48_t; | |
523 | typedef endian< endianness::native, uint_least64_t, 56 > unative56_t; | |
524 | typedef endian< endianness::native, uint_least64_t, 64 > unative64_t; | |
525 | ||
7c673cae FG |
526 | // These types only present if platform has exact size integers: |
527 | // aligned big endian signed integer types | |
528 | // aligned big endian unsigned integer types | |
529 | // aligned little endian signed integer types | |
530 | // aligned little endian unsigned integer types | |
531 | ||
532 | // aligned native endian typedefs are not provided because | |
533 | // <cstdint> types are superior for this use case | |
534 | ||
92f5a8d4 | 535 | #ifdef INT16_MAX |
7c673cae FG |
536 | typedef endian< endianness::big, int16_t, 16, alignment::aligned > aligned_big16_t; |
537 | typedef endian< endianness::big, uint16_t, 16, alignment::aligned > aligned_ubig16_t; | |
538 | typedef endian< endianness::little, int16_t, 16, alignment::aligned > aligned_little16_t; | |
539 | typedef endian< endianness::little, uint16_t, 16, alignment::aligned > aligned_ulittle16_t; | |
92f5a8d4 | 540 | #endif |
7c673cae | 541 | |
92f5a8d4 | 542 | #ifdef INT32_MAX |
7c673cae FG |
543 | typedef endian< endianness::big, int32_t, 32, alignment::aligned > aligned_big32_t; |
544 | typedef endian< endianness::big, uint32_t, 32, alignment::aligned > aligned_ubig32_t; | |
545 | typedef endian< endianness::little, int32_t, 32, alignment::aligned > aligned_little32_t; | |
546 | typedef endian< endianness::little, uint32_t, 32, alignment::aligned > aligned_ulittle32_t; | |
92f5a8d4 | 547 | #endif |
7c673cae | 548 | |
92f5a8d4 | 549 | #ifdef INT64_MAX |
7c673cae FG |
550 | typedef endian< endianness::big, int64_t, 64, alignment::aligned > aligned_big64_t; |
551 | typedef endian< endianness::big, uint64_t, 64, alignment::aligned > aligned_ubig64_t; | |
552 | typedef endian< endianness::little, int64_t, 64, alignment::aligned > aligned_little64_t; | |
553 | typedef endian< endianness::little, uint64_t, 64, alignment::aligned > aligned_ulittle64_t; | |
92f5a8d4 | 554 | #endif |
7c673cae FG |
555 | |
556 | } // namespace endian | |
557 | }} // namespace boost::spirit | |
558 | ||
92f5a8d4 TL |
559 | #undef BOOST_SPIRIT_ENDIAN_DEFAULT_CONSTRUCT |
560 | #undef BOOST_SPIRIT_ENDIAN_NO_CTORS | |
7c673cae FG |
561 | |
562 | #if defined(__BORLANDC__) || defined( __CODEGEARC__) | |
563 | # pragma pack(pop) | |
564 | #endif | |
565 | ||
566 | #endif // BOOST_SPIRIT_ENDIAN_HPP |