• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/predef/other/endian.h>
38 #ifndef BOOST_MINIMAL_INTEGER_COVER_OPERATORS
39 #define BOOST_MINIMAL_INTEGER_COVER_OPERATORS
40 #endif
41 #ifndef BOOST_NO_IO_COVER_OPERATORS
42 #define BOOST_NO_IO_COVER_OPERATORS
43 #endif
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 
59 # define BOOST_SPIRIT_ENDIAN_DEFAULT_CONSTRUCT {}          // C++03
60 
61 # if defined(BOOST_ENDIAN_NO_CTORS) || defined(BOOST_ENDIAN_FORCE_PODNESS)
62 #   define BOOST_SPIRIT_ENDIAN_NO_CTORS
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 
load_bigboost::spirit::detail::unrolled_byte_loops78       static typename boost::make_unsigned<T>::type load_big(const unsigned char* bytes)
79         { return *(bytes - 1) | (next::load_big(bytes - 1) << 8); }
load_littleboost::spirit::detail::unrolled_byte_loops80       static typename boost::make_unsigned<T>::type load_little(const unsigned char* bytes)
81         { return *bytes | (next::load_little(bytes + 1) << 8); }
82 
store_bigboost::spirit::detail::unrolled_byte_loops83       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         }
store_littleboost::spirit::detail::unrolled_byte_loops88       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     {
load_bigboost::spirit::detail::unrolled_byte_loops98       static T load_big(const unsigned char* bytes)
99         { return *(bytes - 1); }
load_littleboost::spirit::detail::unrolled_byte_loops100       static T load_little(const unsigned char* bytes)
101         { return *bytes; }
store_bigboost::spirit::detail::unrolled_byte_loops102       static void store_big(char* bytes, T value)
103         { *(bytes - 1) = static_cast<char>(value); }
store_littleboost::spirit::detail::unrolled_byte_loops104       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     {
load_bigboost::spirit::detail::unrolled_byte_loops112       static typename boost::make_unsigned<T>::type load_big(const unsigned char* bytes)
113         { return *(bytes - 1); }
load_littleboost::spirit::detail::unrolled_byte_loops114       static typename boost::make_unsigned<T>::type load_little(const unsigned char* bytes)
115         { return *bytes; }
store_bigboost::spirit::detail::unrolled_byte_loops116       static void store_big(char* bytes, T value)
117         { *(bytes - 1) = static_cast<char>(value); }
store_littleboost::spirit::detail::unrolled_byte_loops118       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
load_big_endian(const void * bytes)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
load_big_endian(const void * bytes)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
load_big_endian(const void * bytes)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
load_little_endian(const void * bytes)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
load_little_endian(const void * bytes)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
load_little_endian(const void * bytes)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
store_big_endian(void * bytes,T value)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
store_big_endian(void * bytes,float value)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
store_big_endian(void * bytes,double value)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
store_little_endian(void * bytes,T value)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
store_little_endian(void * bytes,float value)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
store_little_endian(void * bytes,double value)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 
BOOST_SCOPED_ENUM_START(endianness)302   BOOST_SCOPED_ENUM_START(endianness) { big, little, native }; BOOST_SCOPED_ENUM_END
BOOST_SCOPED_ENUM_START(alignment)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;
322 #     ifndef BOOST_SPIRIT_ENDIAN_NO_CTORS
endian()323         endian() BOOST_SPIRIT_ENDIAN_DEFAULT_CONSTRUCT
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
operator =(T val)333         endian & operator=(T val) { detail::store_big_endian<T, n_bits/8>(m_value, val); return *this; }
operator T() const334         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;
354 #     ifndef BOOST_SPIRIT_ENDIAN_NO_CTORS
endian()355         endian() BOOST_SPIRIT_ENDIAN_DEFAULT_CONSTRUCT
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
operator =(T val)365         endian & operator=(T val) { detail::store_little_endian<T, n_bits/8>(m_value, val); return *this; }
operator T() const366         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;
386 #   ifndef BOOST_SPIRIT_ENDIAN_NO_CTORS
endian()387         endian() BOOST_SPIRIT_ENDIAN_DEFAULT_CONSTRUCT
388 #     if BOOST_ENDIAN_BIG_BYTE
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
394 #   if BOOST_ENDIAN_BIG_BYTE
operator =(T val)395         endian & operator=(T val) { detail::store_big_endian<T, n_bits/8>(m_value, val); return *this; }
operator T() const396         operator T() const        { return detail::load_big_endian<T, n_bits/8>(m_value); }
397 #   else
operator =(T val)398         endian & operator=(T val) { detail::store_little_endian<T, n_bits/8>(m_value, val); return *this; }
operator T() const399         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;
417 #   ifndef BOOST_SPIRIT_ENDIAN_NO_CTORS
endian()418         endian() BOOST_SPIRIT_ENDIAN_DEFAULT_CONSTRUCT
419 #     if BOOST_ENDIAN_BIG_BYTE
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
425 #   if BOOST_ENDIAN_BIG_BYTE
operator =(T val)426         endian & operator=(T val) { m_value = val; return *this; }
operator T() const427         operator T() const        { return m_value; }
428 #   else
operator =(T val)429         endian & operator=(T val) { detail::store_big_endian<T, sizeof(T)>(&m_value, val); return *this; }
operator T() const430         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;
445 #   ifndef BOOST_SPIRIT_ENDIAN_NO_CTORS
endian()446         endian() BOOST_SPIRIT_ENDIAN_DEFAULT_CONSTRUCT
447 #     if BOOST_ENDIAN_LITTLE_BYTE
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
453 #   if BOOST_ENDIAN_LITTLE_BYTE
operator =(T val)454         endian & operator=(T val) { m_value = val; return *this; }
operator T() const455         operator T() const        { return m_value; }
456     #else
operator =(T val)457         endian & operator=(T val) { detail::store_little_endian<T, sizeof(T)>(&m_value, val); return *this; }
operator T() const458         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 
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 #ifdef INT16_MAX
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 #ifdef INT32_MAX
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 #ifdef INT64_MAX
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 #undef BOOST_SPIRIT_ENDIAN_DEFAULT_CONSTRUCT
560 #undef BOOST_SPIRIT_ENDIAN_NO_CTORS
561 
562 #if defined(__BORLANDC__) || defined( __CODEGEARC__)
563 # pragma pack(pop)
564 #endif
565 
566 #endif // BOOST_SPIRIT_ENDIAN_HPP
567