Virtual Testbed
Ship dynamics simulator for extreme conditions
byte_order.hh
1 #ifndef VTESTBED_BASE_BYTE_ORDER_HH
2 #define VTESTBED_BASE_BYTE_ORDER_HH
3 
4 #include <cstdint>
5 #include <type_traits>
6 
7 #include <vtestbed/config/endian.hh>
8 
9 namespace vtb {
10 
11  namespace base {
12 
13  template <int Size> struct integer;
14  template <> struct integer<1> { using type = std::uint8_t; };
15  template <> struct integer<2> { using type = std::uint16_t; };
16  template <> struct integer<4> { using type = std::uint32_t; };
17  template <> struct integer<8> { using type = std::uint64_t; };
18 
19  template <int Size> void swap(typename integer<Size>::type& n);
20  template <> inline void swap<1>(integer<1>::type& n) {}
21 
22  template <> inline void swap<2>(integer<2>::type& n) {
23  #if defined(VTB_HAVE_BUILTIN_BSWAP16)
24  n = __builtin_bswap16(n);
25  #else
26  n = ((n & 0xff00)>>8) | ((n & 0x00ff)<<8);
27  #endif
28  }
29 
30  template <> inline void swap<4>(integer<4>::type& n) {
31  #if defined(VTB_HAVE_BUILTIN_BSWAP32)
32  n = __builtin_bswap32(n);
33  #else
34  n = ((n & UINT32_C(0xff000000)) >> 24) |
35  ((n & UINT32_C(0x00ff0000)) >> 8) |
36  ((n & UINT32_C(0x0000ff00)) << 8) |
37  ((n & UINT32_C(0x000000ff)) << 24);
38  #endif
39  }
40 
41  template <> inline void swap<8>(integer<8>::type& n) {
42  #if defined(VTB_HAVE_BUILTIN_BSWAP64)
43  n = __builtin_bswap64(n);
44  #else
45  n = ((n & UINT64_C(0xff00000000000000)) >> 56) |
46  ((n & UINT64_C(0x00ff000000000000)) >> 40) |
47  ((n & UINT64_C(0x0000ff0000000000)) >> 24) |
48  ((n & UINT64_C(0x000000ff00000000)) >> 8) |
49  ((n & UINT64_C(0x00000000ff000000)) << 8) |
50  ((n & UINT64_C(0x0000000000ff0000)) << 24) |
51  ((n & UINT64_C(0x000000000000ff00)) << 40) |
52  ((n & UINT64_C(0x00000000000000ff)) << 56);
53  #endif
54  }
55 
56  template <class T>
57  union bytes {
59  "bad type");
60  T orig;
61  typename integer<sizeof(T)>::type integral;
62  char bytes[sizeof(T)];
63  inline void swap() {
64  #if defined(VTB_LITTLE_ENDIAN)
65  ::vtb::base::swap<sizeof(T)>(this->integral);
66  #endif
67  }
68  };
69 
70  }
71 
72 }
73 
74 #endif // vim:filetype=cpp
Main namespace.
Definition: convert.hh:9