OSVR Framework (Internal Development Docs)  0.6-1962-g59773924
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
IntegerByteSwap.h
Go to the documentation of this file.
1 
13 // Copyright 2015 Sensics, Inc.
14 //
15 // Licensed under the Apache License, Version 2.0 (the "License");
16 // you may not use this file except in compliance with the License.
17 // You may obtain a copy of the License at
18 //
19 // http://www.apache.org/licenses/LICENSE-2.0
20 //
21 // Unless required by applicable law or agreed to in writing, software
22 // distributed under the License is distributed on an "AS IS" BASIS,
23 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24 // See the License for the specific language governing permissions and
25 // limitations under the License.
26 
27 #ifndef INCLUDED_IntegerByteSwap_h_GUID_11841216_B020_47A7_D0A9_9B1CFFEB1C5C
28 #define INCLUDED_IntegerByteSwap_h_GUID_11841216_B020_47A7_D0A9_9B1CFFEB1C5C
29 
30 // Internal Includes
31 #include <osvr/Util/StdInt.h>
33 
34 // Library/third-party includes
35 #include <boost/integer.hpp>
36 
37 // Standard includes
38 #include <type_traits>
39 
40 #if defined(OSVR_HAVE_INTRIN_H) && defined(OSVR_HAVE_WORKING_MS_BYTESWAPS)
41 #include <intrin.h>
42 #endif
43 
44 #ifdef OSVR_HAVE_BYTESWAP_H
45 #include <byteswap.h>
46 #endif
47 
48 namespace osvr {
49 namespace common {
50  namespace detail {
54 
57  template <typename T> struct ByteSwap : UnspecializedByteSwapBase {};
58 
61  template <typename T>
62  using IsByteSwapperUnspecialized = std::integral_constant<
63  bool, std::is_base_of<UnspecializedByteSwapBase, T>::value>;
64 
67  template <typename T>
68  using IsByteSwapperSpecialized =
69  std::integral_constant<bool, !IsByteSwapperUnspecialized<T>::value>;
70 
71  struct NoOpFunction {
72  template <typename ArgType> static ArgType apply(ArgType const v) {
73  return v;
74  }
75  };
76 
78  template <> struct ByteSwap<uint8_t> : NoOpFunction {};
79 
81  template <> struct ByteSwap<int8_t> : NoOpFunction {};
82 #if defined(OSVR_HAVE_WORKING_MS_BYTESWAPS)
83  template <> struct ByteSwap<uint16_t> {
84  static uint16_t apply(uint16_t const v) {
85  return _byteswap_ushort(v);
86  }
87  };
88 
89  template <> struct ByteSwap<uint32_t> {
90  static uint32_t apply(uint32_t const v) {
91  return _byteswap_ulong(v);
92  }
93  };
94  template <> struct ByteSwap<uint64_t> {
95  static uint64_t apply(uint64_t const v) {
96  return _byteswap_uint64(v);
97  }
98  };
99 #elif defined(OSVR_HAVE_BYTESWAP_H) && defined(OSVR_HAVE_WORKING_BSWAP)
100  template <> struct ByteSwap<uint16_t> {
101  static uint16_t apply(uint16_t const v) { return bswap16(v); }
102  };
103  template <> struct ByteSwap<uint32_t> {
104  static uint32_t apply(uint32_t const v) { return bswap32(v); }
105  };
106  template <> struct ByteSwap<uint64_t> {
107  static uint64_t apply(uint64_t const v) { return bswap64(v); }
108  };
109 #elif defined(OSVR_HAVE_BYTESWAP_H) && \
110  defined(OSVR_HAVE_WORKING_BSWAP_UNDERSCORE)
111  template <> struct ByteSwap<uint16_t> {
112  static uint16_t apply(uint16_t const v) { return bswap_16(v); }
113  };
114 
115  template <> struct ByteSwap<uint32_t> {
116  static uint32_t apply(uint32_t const v) { return bswap_32(v); }
117  };
118  template <> struct ByteSwap<uint64_t> {
119  static uint64_t apply(uint64_t const v) { return bswap_64(v); }
120  };
121 #elif defined(OSVR_HAVE_BYTESWAP_H) && \
122  defined(OSVR_HAVE_WORKING_UNDERSCORES_BSWAP)
123  template <> struct ByteSwap<uint16_t> {
124  static uint16_t apply(uint16_t const v) { return __bswap_16(v); }
125  };
126 
127  template <> struct ByteSwap<uint32_t> {
128  static uint32_t apply(uint32_t const v) { return __bswap_32(v); }
129  };
130  template <> struct ByteSwap<uint64_t> {
131  static uint64_t apply(uint64_t const v) { return __bswap_64(v); }
132  };
133 #endif
134  template <typename T> inline T genericByteSwap(T const v) {
137  T ret;
138  for (size_t i = 0; i < sizeof(T); ++i) {
139  reinterpret_cast<char *>(&ret)[i] =
140  reinterpret_cast<char const *>(&v)[sizeof(T) - 1 - i];
141  }
142  return ret;
143  }
144 
149  template <typename T> struct IntegerByteSwapTraits {
150 
151  typedef typename boost::int_t<sizeof(T) * 8>::exact int_t;
152  typedef typename boost::uint_t<sizeof(T) * 8>::exact uint_t;
153  typedef
154  typename std::conditional<std::is_signed<T>::value, uint_t,
155  int_t>::type opposite_signedness_type;
156  typedef typename std::add_const<opposite_signedness_type>::type
157  const_opposite_signedness_type;
158 
159  typedef ByteSwap<T> ByteSwapper;
161 
162  static const bool HAVE_BYTESWAPPER =
163  IsByteSwapperSpecialized<ByteSwapper>::value;
164  static const bool HAVE_OPPPOSITEBYTESWAPPER =
165  IsByteSwapperSpecialized<OppositeByteSwapper>::value;
166  };
167 
170  template <typename T>
171  inline T integerByteSwapImpl(
172  T const v,
173  typename std::enable_if<
174  IntegerByteSwapTraits<T>::HAVE_BYTESWAPPER>::type * = nullptr) {
175  typedef IntegerByteSwapTraits<T> Traits;
176  return Traits::ByteSwapper::apply(v);
177  }
178 
182  template <typename T>
183  inline T integerByteSwapImpl(
184  T const v,
185  typename std::enable_if<
186  (!IntegerByteSwapTraits<T>::HAVE_BYTESWAPPER) &&
187  (IntegerByteSwapTraits<T>::HAVE_OPPPOSITEBYTESWAPPER)>::type * =
188  nullptr) {
189  typedef IntegerByteSwapTraits<T> Traits;
190  return static_cast<T>(Traits::OppositeByteSwapper::apply(
191  static_cast<typename Traits::const_opposite_signedness_type>(
192  v)));
193  }
194 
198  template <typename T>
199  inline T integerByteSwapImpl(
200  T const v,
201  typename std::enable_if<
202  (!IntegerByteSwapTraits<T>::HAVE_BYTESWAPPER) &&
203  (!IntegerByteSwapTraits<T>::HAVE_OPPPOSITEBYTESWAPPER)>::
204  type * = nullptr) {
205  return genericByteSwap(v);
206  }
207  } // namespace detail
208 
215  template <typename Type> inline Type integerByteSwap(Type const v) {
216  static_assert(std::is_integral<Type>::value,
217  "Can only apply integerByteSwap to integers");
218  typedef typename std::remove_cv<
219  typename std::remove_reference<Type>::type>::type T;
220 
221  return detail::integerByteSwapImpl<T>(v);
222  }
223 } // namespace common
224 } // namespace osvr
225 
226 #endif // INCLUDED_IntegerByteSwap_h_GUID_11841216_B020_47A7_D0A9_9B1CFFEB1C5C
Automatically-generated configuration header - do not edit!
Template for providing/describing optimized/intrinsic byte swap functions.
Header wrapping the C99 standard stdint header.
typename F::template apply< Args...> apply
Apply an alias class.
Definition: Apply.h:44
Tag type used only for recognizing ByteSwap specializations that aren't explicitly specialized...
Traits assisting selection of optimized integer byte swapping.
Type integerByteSwap(Type const v)
Swap the order of bytes of an arbitrary integer type.