MRPT
1.9.9
bit_cast.h
Go to the documentation of this file.
1
/* +------------------------------------------------------------------------+
2
| Mobile Robot Programming Toolkit (MRPT) |
3
| https://www.mrpt.org/ |
4
| |
5
| Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6
| See: https://www.mrpt.org/Authors - All rights reserved. |
7
| Released under BSD License. See: https://www.mrpt.org/License |
8
+------------------------------------------------------------------------+ */
9
10
// Copyright 2016 The Chromium Authors. All rights reserved.
11
// Use of this source code is governed by a BSD-style license that can be
12
// found in the LICENSE file.
13
#pragma once
14
#include <cstring>
15
#include <type_traits>
16
//#include "base/compiler_specific.h" // mrpt
17
//#include "base/template_util.h" // mrpt
18
//#include "build/build_config.h" // mrpt
19
// bit_cast<Dest,Source> is a template function that implements the equivalent
20
// of "*reinterpret_cast<Dest*>(&source)". We need this in very low-level
21
// functions like the protobuf library and fast math support.
22
//
23
// float f = 3.14159265358979;
24
// int i = bit_cast<int32_t>(f);
25
// // i = 0x40490fdb
26
//
27
// The classical address-casting method is:
28
//
29
// // WRONG
30
// float f = 3.14159265358979; // WRONG
31
// int i = * reinterpret_cast<int*>(&f); // WRONG
32
//
33
// The address-casting method actually produces undefined behavior according to
34
// the ISO C++98 specification, section 3.10 ("basic.lval"), paragraph 15.
35
// (This did not substantially change in C++11.) Roughly, this section says: if
36
// an object in memory has one type, and a program accesses it with a different
37
// type, then the result is undefined behavior for most values of "different
38
// type".
39
//
40
// This is true for any cast syntax, either *(int*)&f or
41
// *reinterpret_cast<int*>(&f). And it is particularly true for conversions
42
// between integral lvalues and floating-point lvalues.
43
//
44
// The purpose of this paragraph is to allow optimizing compilers to assume that
45
// expressions with different types refer to different memory. Compilers are
46
// known to take advantage of this. So a non-conforming program quietly
47
// produces wildly incorrect output.
48
//
49
// The problem is not the use of reinterpret_cast. The problem is type punning:
50
// holding an object in memory of one type and reading its bits back using a
51
// different type.
52
//
53
// The C++ standard is more subtle and complex than this, but that is the basic
54
// idea.
55
//
56
// Anyways ...
57
//
58
// bit_cast<> calls memcpy() which is blessed by the standard, especially by the
59
// example in section 3.9 . Also, of course, bit_cast<> wraps up the nasty
60
// logic in one place.
61
//
62
// Fortunately memcpy() is very fast. In optimized mode, compilers replace
63
// calls to memcpy() with inline object code when the size argument is a
64
// compile-time constant. On a 32-bit system, memcpy(d,s,4) compiles to one
65
// load and one store, and memcpy(d,s,8) compiles to two loads and two stores.
66
template
<
class
Dest,
class
Source>
67
inline
Dest
bit_cast
(
const
Source&
source
)
68
{
69
static_assert(
70
sizeof
(Dest) ==
sizeof
(Source),
71
"bit_cast requires source and destination to be the same size"
);
72
static_assert(
73
std::is_trivially_copyable<Dest>::value
,
74
"bit_cast requires the destination type to be copyable"
);
75
static_assert(
76
std::is_trivially_copyable<Source>::value
,
77
"bit_cast requires the source type to be copyable"
);
78
Dest dest;
79
memcpy
(&dest, &
source
,
sizeof
(dest));
80
return
dest;
81
}
source
GLsizei GLsizei GLchar * source
Definition:
glext.h:4097
bit_cast
Dest bit_cast(const Source &source)
Definition:
bit_cast.h:67
value
GLsizei const GLfloat * value
Definition:
glext.h:4134
mrpt::system::os::memcpy
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:358
Page generated by
Doxygen 1.8.14
for MRPT 1.9.9 Git: 8fe78517f Sun Jul 14 19:43:28 2019 +0200 at lun oct 28 02:10:00 CET 2019