hmbdc
simplify-high-performance-messaging-programming
Endian.hpp
1 #include "hmbdc/Copyright.hpp"
2 #pragma once
3 #include <boost/endian/conversion.hpp>
4 #include <iostream>
5 
6 namespace hmbdc {
7 struct Endian {
8 private:
9  static constexpr uint32_t i32 = 0x01020304;
10  static constexpr uint8_t i32_1stbyte = (const uint8_t&)i32;
11  static_assert(i32_1stbyte == 0x04 || i32_1stbyte == 0x01, "Cannot determine endianness!");
12 public:
13  static constexpr bool little = i32_1stbyte == 0x04;
14 #ifdef HMBDC_XMIT_BIG_ENDIAN
15  static constexpr bool match_xmit = !little;
16 #else
17  static constexpr bool match_xmit = little;
18 #endif
19  template <typename iType>
20  static
21  iType toXmit(iType v) {
22  if (match_xmit) {
23  return v;
24  } else {
25  return boost::endian::endian_reverse(v);
26  }
27  }
28  template <typename iType>
29  static
30  iType toNative(iType v) {
31  return toXmit(v);
32  }
33 };
34 
35 template <typename T>
36 struct XmitEndian {
37  using RawType = T;
38  static_assert(sizeof(T) > 1, "not effective or apply");
39  XmitEndian(){}
40  explicit XmitEndian(T v)
41  : vx_(Endian::match_xmit?v:boost::endian::endian_reverse(v)) {
42  }
43 
44  operator T() const {
45  return Endian::match_xmit?vx_:boost::endian::endian_reverse(vx_);
46  }
47 
48  XmitEndian& operator = (T v) {
49  if (Endian::match_xmit) {
50  vx_ = v;
51  } else {
52  vx_ = boost::endian::endian_reverse(v);
53  }
54  return *this;
55  }
56 
57  XmitEndian& operator += (T v) {
58  if (Endian::match_xmit) {
59  vx_ += v;
60  } else {
61  auto tmp = boost::endian::endian_reverse(vx_) + v;
62  vx_ = boost::endian::endian_reverse(tmp);
63  }
64  return *this;
65  }
66 
67  XmitEndian& operator -= (T v) {
68  if (Endian::match_xmit) {
69  vx_ -= v;
70  } else {
71  auto tmp = boost::endian::endian_reverse(vx_) - v;
72  vx_ = boost::endian::endian_reverse(tmp);
73  }
74  return *this;
75  }
76 
77  friend std::istream& operator >> (std::istream& is, XmitEndian& t) {
78  T tmp;
79  is >> tmp;
80  t = tmp;
81  return is;
82  }
83 
84 private:
85  T vx_;
86 } __attribute__((packed));
87 
88 template <typename T, size_t N>
90  using RawType = T;
91  static_assert(sizeof(T) >= N, "not effective or apply");
93  explicit XmitEndianByteField(T v) {
94  vx_ = v;
95  if (!Endian::match_xmit) {
96  for (auto i = 0; i < N / 2; ++i)
97  std::swap(vb_[i], vb_[N - i - 1]);
98  }
99  }
100 
101  operator T() const {
102  return Endian::match_xmit?vx_:boost::endian::endian_reverse(
103  vx_ << (sizeof(T) - N) * 8);
104  }
105 
106  XmitEndianByteField& operator = (T v) {
107  vx_ = v;
108  if (!Endian::match_xmit) {
109  for (auto i = 0u; i < N / 2; ++i)
110  std::swap(vb_[i], vb_[N - i - 1]);
111  }
112  return *this;
113  }
114 
115  friend std::istream& operator >> (std::istream& is, XmitEndianByteField& f) {
116  T tmp;
117  is >> tmp;
118  f = tmp;
119  return is;
120  }
121 
122 private:
123  union {
124  uint8_t vb_[N];
125  T vx_ : N*8;
126  } __attribute__((packed));
127 } __attribute__((packed));
128 
129 // template <typename UT, typename T, uint8_t index, uint8_t bits>
130 // struct XmitEndianBitField {
131 // static_assert(sizeof(UT) >= sizeof(T), "UT not big enough");
132 // operator T() const {
133 // return Endian::match_xmit && bits > 8?vx_:boost::endian::endian_reverse(vx_);
134 // }
135 
136 // XmitEndianBitField& operator = (T v) {
137 // if (!Endian::match_xmit && bits > 8) {
138 // v &= (1u << bits) - 1;
139 // auto utv = (UT)(boost::endian::endian_reverse(v));
140 // vx_ = 0;
141 // if (Endian::little) {
142 // *reinterpret_cast<UT*>(this) ^= (utv >> index);
143 // } else {
144 // *reinterpret_cast<UT*>(this) ^= (utv << (sizeof(UT) * 8 - index - bits));
145 // }
146 // } else {
147 // vx_ = (v & ((1u << bits) - 1));
148 // }
149 // return *this;
150 // }
151 
152 // friend std::istream& operator >> (std::istream& is, XmitEndianBitField& f) {
153 // T tmp;
154 // is >> tmp;
155 // f = tmp;
156 // return is;
157 // }
158 
159 // private:
160 // UT : index;
161 // T vx_ : bits;
162 // } __attribute__((packed));
163 }
Definition: Endian.hpp:89
Definition: Endian.hpp:7
Definition: Endian.hpp:36
Definition: Base.hpp:12