Main MRPT website > C++ reference for MRPT 1.9.9
bits.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "base-precomp.h" // Precompiled headers
11 
12 #include <mrpt/utils/core_defs.h>
13 #include <mrpt/utils/bits.h>
14 #include <cstring>
15 #include <cstdlib>
16 
17 // These #defines from:
18 // https://github.com/boostorg/endian/blob/master/include/boost/endian/detail/intrinsic.hpp
19 #ifndef __has_builtin
20 #define __has_builtin(x) 0 // Compatibility with non-clang compilers
21 #endif
22 #if ( \
23  defined(__clang__) && __has_builtin(__builtin_bswap32) && \
24  __has_builtin(__builtin_bswap64)) || \
25  (defined(__GNUC__) && \
26  (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
27 #define HAVE_BSWAP_INTRINSICS
28 #endif
29 
30 template <typename T>
31 void reverseBytesInPlace_2b(T& v_in_out)
32 {
33  uint16_t org;
34  ::memcpy(
35  &org, &v_in_out,
36  sizeof(T)); // Was: = *reinterpret_cast<uint16_t*>(&v_in_out); but
37  // caused SIGBUS in some archs
38  const uint16_t val_rev = ((org & 0xff00) >> 8) | ((org & 0x00ff) << 8);
39  ::memcpy(&v_in_out, &val_rev, sizeof(T)); // This avoid deref. puned
40  // pointer warning with:
41  // *reinterpret_cast<const
42  // T*>(&val_rev);
43 }
44 
45 template <typename T>
46 void reverseBytesInPlace_4b(T& v_in_out)
47 {
48  uint32_t org;
49  ::memcpy(
50  &org, &v_in_out,
51  sizeof(T)); // Was: = = *reinterpret_cast<uint32_t*>(&v_in_out); but
52  // caused SIGBUS in some archs
53  const uint32_t val_rev =
54 #if defined(_MSC_VER)
55  _byteswap_ulong(org);
56 #elif defined(HAVE_BSWAP_INTRINSICS)
57  __builtin_bswap32(org);
58 #else
59  ((org & 0xff000000) >> (3 * 8)) | ((org & 0x00ff0000) >> (1 * 8)) |
60  ((org & 0x0000ff00) << (1 * 8)) | ((org & 0x000000ff) << (3 * 8));
61 #endif
62  ::memcpy(&v_in_out, &val_rev, sizeof(T)); // This avoid deref. puned
63  // pointer warning with:
64  // *reinterpret_cast<const
65  // T*>(&val_rev);
66 }
67 
68 template <typename T>
69 void reverseBytesInPlace_8b(T& v_in_out)
70 {
71  uint64_t org;
72  ::memcpy(
73  &org, &v_in_out,
74  sizeof(T)); // Was: = *reinterpret_cast<uint64_t*>(&v_in_out); but
75 // caused SIGBUS in some archs
76 #if defined(_MSC_VER)
77  uint64_t val_rev = _byteswap_uint64(org);
78 #elif defined(HAVE_BSWAP_INTRINSICS)
79  uint64_t val_rev = __builtin_bswap64(org);
80 #else
81  uint64_t val_rev = 0;
82  int i, j;
83  for (i = 7, j = 7; i >= 4; i--, j -= 2)
84  val_rev |= ((org & (UINT64_C(0xff) << (i * 8))) >> (j * 8));
85  for (i = 3, j = 1; i >= 0; i--, j += 2)
86  val_rev |= ((org & (UINT64_C(0xff) << (i * 8))) << (j * 8));
87 #endif
88  ::memcpy(&v_in_out, &val_rev, sizeof(T)); // This avoid deref. puned
89  // pointer warning with:
90  // *reinterpret_cast<const
91  // T*>(&val_rev);
92 }
93 
95 {
96  // Nothing to do.
97 }
98 
100 {
101  // Nothing to do.
102 }
104 {
105  // Nothing to do.
106 }
107 
109 {
110  reverseBytesInPlace_2b(v_in_out);
111 }
112 
114 {
115  reverseBytesInPlace_2b(v_in_out);
116 }
117 
119 {
120  reverseBytesInPlace_4b(v_in_out);
121 }
122 
124 {
125  reverseBytesInPlace_4b(v_in_out);
126 }
127 
129 {
130  reverseBytesInPlace_8b(v_in_out);
131 }
132 
134 {
135  reverseBytesInPlace_8b(v_in_out);
136 }
137 
138 void mrpt::utils::reverseBytesInPlace(float& v_in_out)
139 {
140  reverseBytesInPlace_4b(v_in_out);
141 }
142 
143 void mrpt::utils::reverseBytesInPlace(double& v_in_out)
144 {
145  reverseBytesInPlace_8b(v_in_out);
146 }
147 
148 #ifdef HAVE_LONG_DOUBLE
149 void mrpt::utils::reverseBytesInPlace(long double& v_in_out)
150 {
151  uint64_t dat[2];
152  ::memcpy(
153  &dat[0], &v_in_out, sizeof(long double)); // This avoid deref. puned
154  // pointer warning with:
155  // *reinterpret_cast<const
156  // T*>(&val_rev);
157  std::swap(dat[0], dat[1]);
158  reverseBytesInPlace(dat[0]);
159  reverseBytesInPlace(dat[1]);
160  ::memcpy(&v_in_out, &dat[0], sizeof(long double));
161 }
162 #endif
unsigned __int16 uint16_t
Definition: rptypes.h:44
signed char int8_t
Definition: rptypes.h:40
void reverseBytesInPlace_4b(T &v_in_out)
Definition: bits.cpp:46
void reverseBytesInPlace(bool &v_in_out)
Reverse the order of the bytes of a given type (useful for transforming btw little/big endian) ...
Definition: bits.cpp:94
unsigned char uint8_t
Definition: rptypes.h:41
__int16 int16_t
Definition: rptypes.h:43
__int64 int64_t
Definition: rptypes.h:49
__int32 int32_t
Definition: rptypes.h:46
unsigned __int64 uint64_t
Definition: rptypes.h:50
void reverseBytesInPlace_2b(T &v_in_out)
Definition: bits.cpp:31
void reverseBytesInPlace_8b(T &v_in_out)
Definition: bits.cpp:69
unsigned __int32 uint32_t
Definition: rptypes.h:47
void memcpy(void *dest, size_t destSize, const void *src, size_t copyCount) noexcept
An OS and compiler independent version of "memcpy".
Definition: os.cpp:355



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019