6 constexpr union { uint32_t i; uint8_t is_little_endian; } endianness{1};
8 inline uint8_t hton(uint8_t t) { return t; }
9 inline int8_t hton(int8_t t) { return t; }
10 inline uint16_t hton(uint16_t t) { return htons(t); }
11 inline int16_t hton(int16_t t) { return (int16_t)htons((uint16_t)t); }
12 inline uint32_t hton(uint32_t t) { return htonl(t); }
13 inline int32_t hton(int32_t t) { return (int32_t)htonl((uint32_t)t); }
14 inline uint64_t hton(uint64_t t) {
15 if (!endianness.is_little_endian)
17 return (uint64_t)htonl((uint32_t)(t >> 32)) | ((uint64_t)htonl((uint32_t)t) << 32);
19 inline int64_t hton(int64_t t) { return (int64_t)hton((uint64_t)t); }
21 template <class T> inline T ntoh(T t) { return hton(t); }
23 template <class... Args, size_t... Indices> inline tuple<typename remove_reference<Args>::type...>
24 tuple_hton_imp(tuple<Args...> && t, tuple_indices<Indices...>) {
25 return tuple<typename remove_reference<Args>::type...>(hton(get<Indices>(t))...);
28 template <class... Args> inline tuple<typename remove_reference<Args>::type...>
29 hton(tuple<Args...> && t) {
30 using Indices = typename make_tuple_indices<sizeof...(Args)>::type;
31 return tuple_hton_imp(forward<tuple<Args...>>(t), Indices());
34 #define ENDIAN_SWAPPABLE(_c_) \
35 inline _c_ hton(_c_ && t) { \
37 result._tuple_() = hton(t._tuple_()); \