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