OSVR-Core
Endianness.h
Go to the documentation of this file.
1 
11 // Copyright 2015 Sensics, Inc.
12 //
13 // Licensed under the Apache License, Version 2.0 (the "License");
14 // you may not use this file except in compliance with the License.
15 // You may obtain a copy of the License at
16 //
17 // http://www.apache.org/licenses/LICENSE-2.0
18 //
19 // Unless required by applicable law or agreed to in writing, software
20 // distributed under the License is distributed on an "AS IS" BASIS,
21 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 // See the License for the specific language governing permissions and
23 // limitations under the License.
24 
25 #ifndef INCLUDED_Endianness_h_GUID_A8D4BB43_3F1B_46AA_8044_BD082A07C299
26 #define INCLUDED_Endianness_h_GUID_A8D4BB43_3F1B_46AA_8044_BD082A07C299
27 
28 // Internal Includes
29 #include <osvr/Util/StdInt.h>
31 
32 // Library/third-party includes
33 #include <boost/version.hpp>
34 
35 #if BOOST_VERSION >= 105500
36 #include <boost/predef.h>
37 #if BOOST_ENDIAN_LITTLE_BYTE
38 #define OSVR_IS_LITTLE_ENDIAN
39 #define OSVR_BYTE_ORDER_ABCD
40 #elif BOOST_ENDIAN_BIG_BYTE
41 #define OSVR_IS_BIG_ENDIAN
42 #define OSVR_BYTE_ORDER_DCBA
43 #else
44 #error "Unsupported byte order!"
45 #endif
46 
47 #else
48 #include <boost/detail/endian.hpp>
49 
50 #if defined(BOOST_LITTLE_ENDIAN)
51 #define OSVR_IS_LITTLE_ENDIAN
52 #define OSVR_BYTE_ORDER_ABCD
53 #elif defined(BOOST_BIG_ENDIAN)
54 #define OSVR_IS_BIG_ENDIAN
55 #define OSVR_BYTE_ORDER_DCBA
56 #else
57 #error "Unsupported byte order!"
58 #endif
59 
60 #endif
61 
62 #include <boost/integer.hpp>
63 
64 // Standard/system includes
65 #include <type_traits>
66 
67 #if defined(__FLOAT_WORD_ORDER) && defined(__BYTE_ORDER)
68 #if (__FLOAT_WORD_ORDER != __BYTE_ORDER)
69 #define OSVR_FLOAT_ORDER_MIXED
71 #endif
72 #endif
73 
74 #include <string.h>
75 
76 namespace osvr {
77 namespace common {
78 
79  namespace serialization {
80  template <typename T, typename Dummy = void>
82 
85  template <typename Dest, typename Src>
86  inline Dest safe_pun(Src const src) {
87  static_assert(sizeof(Src) == sizeof(Dest),
88  "Can only use safe_pun for types of the same size");
89  Dest ret;
90  memcpy(reinterpret_cast<char *>(&ret),
91  reinterpret_cast<char const *>(&src), sizeof(src));
92  return ret;
93  }
94 
95  namespace detail {
97  template <typename T> struct NoOpHostNetworkConversion {
98  static T hton(T const v) { return v; }
99  static T ntoh(T const v) { return v; }
100  };
103  template <typename T> struct IntegerByteOrderSwap {
104  static T hton(T const v) { return integerByteSwap(v); }
105  static T ntoh(T const v) { return hton(v); }
106  };
109  template <typename T, typename UnsignedIntType>
111 
112  typedef T type;
113  typedef UnsignedIntType uint_t;
114 
115  static_assert(sizeof(T) == sizeof(UnsignedIntType),
116  "Type-punning host-network conversion only works "
117  "when the types are the same size");
118  static_assert(
119  std::is_unsigned<UnsignedIntType>::value,
120  "Template parameter UnsignedIntType should be unsigned!");
121 
123  static type hton(type const v) {
124  return safe_pun<type>(IntTraits::hton(safe_pun<uint_t>(v)));
125  }
126  static type ntoh(type const v) { return hton(v); }
127  };
128 
129  } // namespace detail
130 
131 #if defined(OSVR_IS_BIG_ENDIAN)
132  template <typename T>
133  struct NetworkByteOrderTraits<
134  T, typename std::enable_if<std::is_integral<T>::value>::type>
136 
137 #elif defined(OSVR_IS_LITTLE_ENDIAN)
138  template <typename T>
139  struct NetworkByteOrderTraits<
140  T, typename std::enable_if<std::is_integral<T>::value>::type>
142 #endif
143 
144 #if 0
145  template<>
147  struct NetworkByteOrderTraits<float, void> : detail::TypePunByteOrder<float, uint32_t> {
148  };
149 #endif
150 
151 #if defined(OSVR_FLOAT_ORDER_MIXED)
152  template <> struct NetworkByteOrderTraits<double, void> {
154  typedef ByteOrder::type type;
155  static const size_t WORD_SIZE = sizeof(type) / 2;
156  static inline type hton(type const v) {
158  type src = ByteOrder::hton(v);
159  type ret;
161  memcpy(reinterpret_cast<char *>(&ret),
162  reinterpret_cast<char const *>(&src) + WORD_SIZE,
163  WORD_SIZE);
164  memcpy(reinterpret_cast<char *>(&ret) + WORD_SIZE,
165  reinterpret_cast<char const *>(&src), WORD_SIZE);
166  return ret;
167  }
168  static type ntoh(type const v) { return hton(v); }
169  };
170 #else
171  template <>
172  struct NetworkByteOrderTraits<double, void>
173  : detail::TypePunByteOrder<double, uint64_t> {};
174 #endif
175 
177  template <typename T> inline T ntoh(T const v) {
179  }
180 
182  template <typename T> inline T hton(T const v) {
184  }
185  } // namespace serialization
186 } // namespace common
187 } // namespace osvr
188 
189 #endif // INCLUDED_Endianness_h_GUID_A8D4BB43_3F1B_46AA_8044_BD082A07C299
Dest safe_pun(Src const src)
Take the binary representation of a value with one type, and return it as another type...
Definition: Endianness.h:86
Handles spatial transformations.
Definition: SerializationTraitExample_Complicated.h:40
Header wrapping the C99 standard stdint header.
The main namespace for all C++ elements of the framework, internal and external.
Definition: namespace_osvr.dox:3
Stock implementation of a no-op host-network conversion.
Definition: Endianness.h:97
T ntoh(T const v)
Convert network byte order (big endian) to host byte order.
Definition: Endianness.h:177
Header providing optimized integer byte-swap functionality through a single function template...
Stock implementation of a type-punning host-network conversion.
Definition: Endianness.h:110
Definition: newuoa.h:1888
T hton(T const v)
Convert host byte order to network byte order (big endian)
Definition: Endianness.h:182
Stock implementation of a byte-swapping host-network conversion.
Definition: Endianness.h:103
Type integerByteSwap(Type const v)
Swap the order of bytes of an arbitrary integer type.
Definition: IntegerByteSwap.h:215