View on GitHub

Vistle

Distributed Data-parallel Scientific Visualization in VR

byteswap.h
Go to the documentation of this file.
1#ifndef UTIL_BYTESWAP_H
2#define UTIL_BYTESWAP_H
3
4#define _USE_BUILTIN_BSWAPS
5
6// from Virvo
7// from http://www.cplusplus.com/forum/general/27544/
8
9
10#include <boost/type_traits.hpp>
11#include <boost/static_assert.hpp>
12#include <boost/version.hpp>
13#if BOOST_VERSION >= 106500
14#include <boost/predef/other/endian.h>
15#else
16#include <boost/detail/endian.hpp>
17#if defined(BOOST_LITTLE_ENDIAN)
18#define BOOST_ENDIAN_LITTLE_BYTE
19#elif defined(BOOST_BIG_ENDIAN)
20#define BOOST_ENDIAN_BIG_BYTE
21#else
22#error "unable to determine system endianness"
23#endif
24#endif
25#include <stdexcept>
26
27namespace vistle {
28
29// Little-endian operating systems:
30//---------------------------------
31// Linux on x86, x64, Alpha and Itanium
32// Mac OS on x86, x64
33// Solaris on x86, x64, PowerPC
34// Tru64 on Alpha
35// Windows on x86, x64 and Itanium
36
37// Big-endian operating systems:
38//------------------------------
39// AIX on POWER
40// AmigaOS on PowerPC and 680x0
41// HP-UX on Itanium and PA-RISC
42// Linux on MIPS, SPARC, PA-RISC, POWER, PowerPC, and 680x0
43// Mac OS on PowerPC and 680x0
44// Solaris on SPARC
45
50
51#if defined(BOOST_ENDIAN_LITTLE_BYTE)
52 host_endian = little_endian
53#elif defined(BOOST_ENDIAN_BIG_BYTE)
54 host_endian = big_endian
55#else
56#error "unable to determine system endianness"
57#endif
58};
59
60namespace detail {
61
62template<typename T, size_t sz>
63struct swap_bytes {
64 inline T operator()(T val)
65 {
66 (void)val;
67 throw std::out_of_range("data size");
68 }
69};
70
71template<typename T>
72struct swap_bytes<T, 1> {
73 inline T operator()(T val) { return val; }
74};
75
76template<typename T>
77struct swap_bytes<T, 2> // for 16 bit
78{
79 inline T operator()(T val) { return ((((val) >> 8) & 0xff) | (((val)&0xff) << 8)); }
80};
81
82template<typename T>
83struct swap_bytes<T, 4> // for 32 bit
84{
85 inline T operator()(T val)
86 {
87#if defined(_USE_BUILTIN_BSWAPS) && defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4)
88 return __builtin_bswap32(val);
89#else
90 return ((((val)&0xff000000) >> 24) | (((val)&0x00ff0000) >> 8) | (((val)&0x0000ff00) << 8) |
91 (((val)&0x000000ff) << 24));
92#endif
93 }
94};
95
96template<>
97struct swap_bytes<float, 4> {
98 inline float operator()(float val)
99 {
100 uint32_t mem = swap_bytes<uint32_t, sizeof(uint32_t)>()(*(uint32_t *)&val);
101 return *(float *)&mem;
102 }
103};
104
105template<typename T>
106struct swap_bytes<T, 8> // for 64 bit
107{
108 inline T operator()(T val)
109 {
110#if defined(_USE_BUILTIN_BSWAPS) && defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4)
111 return __builtin_bswap64(val);
112#else
113 return ((((val)&0xff00000000000000ull) >> 56) | (((val)&0x00ff000000000000ull) >> 40) |
114 (((val)&0x0000ff0000000000ull) >> 24) | (((val)&0x000000ff00000000ull) >> 8) |
115 (((val)&0x00000000ff000000ull) << 8) | (((val)&0x0000000000ff0000ull) << 24) |
116 (((val)&0x000000000000ff00ull) << 40) | (((val)&0x00000000000000ffull) << 56));
117#endif
118 }
119};
120
121template<>
122struct swap_bytes<double, 8> {
123 inline double operator()(double val)
124 {
125 uint64_t mem = swap_bytes<uint64_t, sizeof(uint64_t)>()(*(uint64_t *)&val);
126 return *(double *)&mem;
127 }
128};
129
130template<endianness from, endianness to, class T>
132 inline T operator()(T value) { return swap_bytes<T, sizeof(T)>()(value); }
133};
134// specialisations when attempting to swap to the same endianness
135template<class T>
137 inline T operator()(T value) { return value; }
138};
139template<class T>
141 inline T operator()(T value) { return value; }
142};
143
144} // namespace detail
145
146template<endianness from, endianness to, class T>
147inline T byte_swap(T value)
148{
149 // ensure the data is only 1, 2, 4 or 8 bytes
150 BOOST_STATIC_ASSERT(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8);
151 // ensure we're only swapping arithmetic types
152 BOOST_STATIC_ASSERT(boost::is_arithmetic<T>::value);
153
154 return detail::do_byte_swap<from, to, T>()(value);
155}
156
157} // namespace vistle
158#endif
Definition: allobjects.cpp:30
T byte_swap(T value)
Definition: byteswap.h:147
endianness
Definition: byteswap.h:46
@ network_endian
Definition: byteswap.h:49
@ little_endian
Definition: byteswap.h:47
@ big_endian
Definition: byteswap.h:48
T operator()(T value)
Definition: byteswap.h:141
Definition: byteswap.h:131
T operator()(T value)
Definition: byteswap.h:132
T operator()(T val)
Definition: byteswap.h:73
T operator()(T val)
Definition: byteswap.h:79
T operator()(T val)
Definition: byteswap.h:85
T operator()(T val)
Definition: byteswap.h:108
double operator()(double val)
Definition: byteswap.h:123
float operator()(float val)
Definition: byteswap.h:98
Definition: byteswap.h:63
T operator()(T val)
Definition: byteswap.h:64