Main MRPT website > C++ reference for MRPT 1.5.6
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 
13 #include <mrpt/utils/core_defs.h>
14 #include <mrpt/utils/bits.h>
15 #include <cstring>
16 #include <cstdlib>
17 
18 // These #defines from: 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 (defined(__clang__) && __has_builtin(__builtin_bswap32) && __has_builtin(__builtin_bswap64)) \
23  || (defined(__GNUC__ ) && \
24  (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
25  #define HAVE_BSWAP_INTRINSICS
26 #endif
27 
28 
29 
30 template <typename T>
31 void reverseBytesInPlace_2b(T& v_in_out)
32 {
33  uint16_t org;
34  ::memcpy(&org, &v_in_out, sizeof(T)); // Was: = *reinterpret_cast<uint16_t*>(&v_in_out); but caused SIGBUS in some archs
35  const uint16_t val_rev = ((org & 0xff00) >> 8) | ((org & 0x00ff) << 8);
36  ::memcpy(&v_in_out, &val_rev, sizeof(T)); // This avoid deref. puned pointer warning with: *reinterpret_cast<const T*>(&val_rev);
37 }
38 
39 template <typename T>
40 void reverseBytesInPlace_4b(T& v_in_out)
41 {
42  uint32_t org;
43  ::memcpy(&org, &v_in_out, sizeof(T)); // Was: = = *reinterpret_cast<uint32_t*>(&v_in_out); but caused SIGBUS in some archs
44  const uint32_t val_rev =
45 #if defined(_MSC_VER)
46  _byteswap_ulong(org);
47 #elif defined(HAVE_BSWAP_INTRINSICS)
48  __builtin_bswap32(org);
49 #else
50  ((org & 0xff000000) >> (3*8)) | ((org & 0x00ff0000) >> (1*8)) | ((org & 0x0000ff00) << (1*8)) | ((org & 0x000000ff) << (3*8));
51 #endif
52  ::memcpy(&v_in_out, &val_rev, sizeof(T)); // This avoid deref. puned pointer warning with: *reinterpret_cast<const T*>(&val_rev);
53 }
54 
55 template <typename T>
56 void reverseBytesInPlace_8b(T& v_in_out)
57 {
58  uint64_t org;
59  ::memcpy(&org, &v_in_out, sizeof(T)); // Was: = *reinterpret_cast<uint64_t*>(&v_in_out); but caused SIGBUS in some archs
60 #if defined(_MSC_VER)
61  uint64_t val_rev =_byteswap_uint64(org);
62 #elif defined(HAVE_BSWAP_INTRINSICS)
63  uint64_t val_rev =__builtin_bswap64(org);
64 #else
65  uint64_t val_rev = 0;
66  int i,j;
67  for (i=7,j=7;i>=4;i--,j-=2)
68  val_rev |= ((org & ( UINT64_C(0xff) << (i*8))) >> (j*8));
69  for (i=3,j=1;i>=0;i--,j+=2)
70  val_rev |= ((org & ( UINT64_C(0xff) << (i*8))) << (j*8));
71 #endif
72  ::memcpy(&v_in_out, &val_rev, sizeof(T)); // This avoid deref. puned pointer warning with: *reinterpret_cast<const T*>(&val_rev);
73 }
74 
76  // Nothing to do.
77 }
78 
80  // Nothing to do.
81 }
83  // Nothing to do.
84 }
85 
87  reverseBytesInPlace_2b(v_in_out);
88 }
89 
91  reverseBytesInPlace_2b(v_in_out);
92 }
93 
95  reverseBytesInPlace_4b(v_in_out);
96 }
97 
99  reverseBytesInPlace_4b(v_in_out);
100 }
101 
103  reverseBytesInPlace_8b(v_in_out);
104 }
105 
107  reverseBytesInPlace_8b(v_in_out);
108 }
109 
110 void mrpt::utils::reverseBytesInPlace(float& v_in_out) {
111  reverseBytesInPlace_4b(v_in_out);
112 }
113 
114 void mrpt::utils::reverseBytesInPlace(double& v_in_out) {
115  reverseBytesInPlace_8b(v_in_out);
116 }
117 
118 #ifdef HAVE_LONG_DOUBLE
119 void mrpt::utils::reverseBytesInPlace(long double& v_in_out) {
120  uint64_t dat[2];
121  ::memcpy(&dat[0], &v_in_out, sizeof(long double)); // This avoid deref. puned pointer warning with: *reinterpret_cast<const T*>(&val_rev);
122  std::swap(dat[0],dat[1]);
123  reverseBytesInPlace(dat[0]);
124  reverseBytesInPlace(dat[1]);
125  ::memcpy(&v_in_out, &dat[0], sizeof(long double));
126 }
127 #endif
128 
void BASE_IMPEXP memcpy(void *dest, size_t destSize, const void *src, size_t copyCount) MRPT_NO_THROWS
An OS and compiler independent version of "memcpy".
Definition: os.cpp:358
unsigned __int16 uint16_t
Definition: rptypes.h:46
signed char int8_t
Definition: rptypes.h:42
void reverseBytesInPlace_4b(T &v_in_out)
Definition: bits.cpp:40
void BASE_IMPEXP 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:75
unsigned char uint8_t
Definition: rptypes.h:43
__int16 int16_t
Definition: rptypes.h:45
__int64 int64_t
Definition: rptypes.h:51
__int32 int32_t
Definition: rptypes.h:48
unsigned __int64 uint64_t
Definition: rptypes.h:52
void reverseBytesInPlace_2b(T &v_in_out)
Definition: bits.cpp:31
void reverseBytesInPlace_8b(T &v_in_out)
Definition: bits.cpp:56
unsigned __int32 uint32_t
Definition: rptypes.h:49



Page generated by Doxygen 1.8.14 for MRPT 1.5.6 Git: 4c65e8431 Tue Apr 24 08:18:17 2018 +0200 at lun oct 28 01:35:26 CET 2019