View on GitHub
jbson
C++11/1y BSON library
endian.hpp
1 // Copyright Christian Manning 2013.
2 // Distributed under the Boost Software License, Version 1.0.
3 // (See accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
5 
6 #ifndef JBSON_ENDIAN_HPP
7 #define JBSON_ENDIAN_HPP
8 
9 #include <type_traits>
10 
11 #include "./config.hpp"
12 
13 JBSON_PUSH_DISABLE_DOCUMENTATION_WARNING
14 #include <boost/predef/other/endian.h>
15 JBSON_CLANG_POP_WARNINGS
16 
17 namespace jbson {
18 namespace detail {
19 
20 // endian shit
21 template <typename T, typename ForwardIterator> T little_endian_to_native(ForwardIterator first, ForwardIterator last) {
22  static_assert(std::is_pod<T>::value, "Can only byte swap POD types");
23  assert(std::distance(first, last) >= static_cast<ptrdiff_t>(sizeof(T)));
24  last = std::next(first, sizeof(T));
25  assert(std::distance(first, last) == static_cast<ptrdiff_t>(sizeof(T)));
26  union {
27  T u;
28  unsigned char u8[sizeof(T)];
29  } source;
30 
31  std::copy(first, last, source.u8);
32 
33 #if BOOST_ENDIAN_BIG_BYTE
34 #warning "big endian untested"
35  std::reverse(std::begin(source.u8), std::end(source.u8));
36 #elif !BOOST_ENDIAN_LITTLE_BYTE
37 #error "unsupported endianness"
38 #endif
39  return source.u;
40 }
41 
42 template <typename T> std::array<char, sizeof(T)> native_to_little_endian(T val) {
43  using T2 = std::decay_t<T>;
44  static_assert(std::is_pod<T2>::value, "Can only byte swap POD types");
45 
46  union {
47  T2 u;
48  std::array<char, sizeof(T2)> u8;
49  } source;
50 
51  source.u = val;
52 
53 #if BOOST_ENDIAN_BIG_BYTE
54 #warning "big endian untested"
55  std::reverse(std::begin(source.u8), std::end(source.u8));
56 #elif !BOOST_ENDIAN_LITTLE_BYTE
57 #error "unsupported endianness"
58 #endif
59  return source.u8;
60 }
61 
62 } // namespace detail
63 } // namespace jbson
64 
65 #endif // JBSON_ENDIAN_HPP