C++ Utilities
5.36.0
Useful C++ classes and routines such as argument parser, IO and conversion utilities
Toggle main menu visibility
Loading...
Searching...
No Matches
conversion
binaryconversion.h
Go to the documentation of this file.
1
#ifndef CONVERSION_UTILITIES_BINARY_CONVERSION_H
2
#define CONVERSION_UTILITIES_BINARY_CONVERSION_H
3
4
#include "
../global.h
"
5
#include "
../misc/traits.h
"
// used in binaryconversionprivate.h
6
7
#include <cstdint>
8
#include <cstring>
// used in binaryconversionprivate.h
9
10
// use helpers from bits header if available instead of custom code using bit operations
11
#if __cplusplus >= 202002L
12
#include <bit>
13
#endif
14
15
// detect byte order according to __BYTE_ORDER__
16
#if defined(__BYTE_ORDER__)
17
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
18
#define CONVERSION_UTILITIES_IS_BYTE_ORDER_LITTLE_ENDIAN false
19
#define CONVERSION_UTILITIES_IS_BYTE_ORDER_BIG_ENDIAN true
20
#define CONVERSION_UTILITIES_BYTE_ORDER_BIG_ENDIAN
21
#elif __BYTE_ORDER__ == __ORDER_PDP_ENDIAN__
22
#define CONVERSION_UTILITIES_IS_BYTE_ORDER_LITTLE_ENDIAN false
23
#define CONVERSION_UTILITIES_IS_BYTE_ORDER_BIG_ENDIAN false
24
#define CONVERSION_UTILITIES_BYTE_ORDER_MIDDLE_ENDIAN
25
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
26
#define CONVERSION_UTILITIES_IS_BYTE_ORDER_LITTLE_ENDIAN true
27
#define CONVERSION_UTILITIES_IS_BYTE_ORDER_BIG_ENDIAN false
28
#define CONVERSION_UTILITIES_BYTE_ORDER_LITTLE_ENDIAN
29
#endif
30
#endif
// defined(__BYTE_ORDER__)
31
32
// detect float byte order according to __FLOAT_WORD_ORDER__
33
#if defined(__FLOAT_WORD_ORDER__)
34
#if __FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__
35
#define CONVERSION_UTILITIES_FLOAT_BYTE_ORDER_BIG_ENDIAN
36
#elif __FLOAT_WORD_ORDER__ == __ORDER_PDP_ENDIAN__
37
#define CONVERSION_UTILITIES_FLOAT_BYTE_ORDER_MIDDLE_ENDIAN
38
#elif __FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__
39
#define CONVERSION_UTILITIES_FLOAT_BYTE_ORDER_LITTLE_ENDIAN
40
#endif
41
#endif
// defined(__FLOAT_WORD_ORDER__)
42
43
// detect (float) byte order according to other macros
44
#if !defined(__BYTE_ORDER__) || !defined(__FLOAT_WORD_ORDER__)
45
46
// assume little endian from the presence of several macros
47
#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64) \
48
|| defined(_M_ARM64) || defined(__LITTLE_ENDIAN__) || defined(_little_endian__) || defined(_LITTLE_ENDIAN) || defined(_WIN32_WCE) \
49
|| defined(WINAPI_FAMILY)
50
#if !defined(__BYTE_ORDER__)
51
#define CONVERSION_UTILITIES_IS_BYTE_ORDER_LITTLE_ENDIAN true
52
#define CONVERSION_UTILITIES_IS_BYTE_ORDER_BIG_ENDIAN false
53
#define CONVERSION_UTILITIES_BYTE_ORDER_LITTLE_ENDIAN
54
#endif
55
#if !defined(__FLOAT_WORD_ORDER__)
56
#define CONVERSION_UTILITIES_FLOAT_BYTE_ORDER_LITTLE_ENDIAN
57
#endif
58
59
// assume big endian from the presence of several macros
60
#elif defined(__MIPSEB__) || defined(__s390__) || defined(__BIG_ENDIAN__) || defined(_big_endian__) || defined(_BIG_ENDIAN)
61
#if !defined(__BYTE_ORDER__)
62
#define CONVERSION_UTILITIES_IS_BYTE_ORDER_LITTLE_ENDIAN false
63
#define CONVERSION_UTILITIES_IS_BYTE_ORDER_BIG_ENDIAN true
64
#define CONVERSION_UTILITIES_BYTE_ORDER_BIG_ENDIAN
65
#endif
66
#if !defined(__FLOAT_WORD_ORDER__)
67
#define CONVERSION_UTILITIES_FLOAT_BYTE_ORDER_BIG_ENDIAN
68
#endif
69
70
// fail if unable to detect endianness
71
#else
72
#error "Unable to determine byte order!"
73
#endif
74
75
#endif
// !defined(__BYTE_ORDER__) || !defined(__FLOAT_WORD_ORDER__)
76
77
// fail if middle endian detected
78
#if defined(CONVERSION_UTILITIES_BYTE_ORDER_MIDDLE_ENDIAN) || defined(CONVERSION_UTILITIES_FLOAT_BYTE_ORDER_MIDDLE_ENDIAN)
79
#error "Middle endian byte order is not supported!"
80
#endif
81
82
namespace
CppUtilities
{
83
87
CPP_UTILITIES_EXPORT
constexpr
std::uint16_t
toFixed8
(
float
float32value)
88
{
89
return
static_cast<
std::uint16_t
>
(float32value * 256.0f);
90
}
91
92
/*!
93
* \brief Returns a 32-bit floating point number converted from the specified 8.8 fixed point representation.
94
*/
95
CPP_UTILITIES_EXPORT
constexpr
float
toFloat32
(std::uint16_t fixed8value)
96
{
97
return
static_cast<
float
>
(fixed8value) / 256.0f;
98
}
99
103
CPP_UTILITIES_EXPORT
constexpr
std::uint32_t
toFixed16
(
float
float32value)
104
{
105
return
static_cast<
std::uint32_t
>
(float32value * 65536.0f);
106
}
107
110
*/
111
CPP_UTILITIES_EXPORT
constexpr
float
toFloat32
(std::uint32_t fixed16value)
112
{
113
return
static_cast<
float
>
(fixed16value) / 65536.0f;
114
}
115
121
CPP_UTILITIES_EXPORT
constexpr
std::uint32_t
toSynchsafeInt
(std::uint32_t normalInt)
122
{
123
return
((normalInt & 0x0000007fu)) | ((normalInt & 0x00003f80u) << 1) | ((normalInt & 0x001fc000u) << 2) | ((normalInt & 0x0fe00000u) << 3);
124
}
125
128
* \remarks Synchsafe integers appear in ID3 tags that are attached to an MP3 file.
129
* \sa <a href="http://id3.org/id3v2.4.0-structure">ID3 tag version 2.4.0 - Main Structure</a>
130
*/
131
CPP_UTILITIES_EXPORT
constexpr
std::uint32_t
toNormalInt
(std::uint32_t synchsafeInt)
132
{
133
return
((synchsafeInt & 0x0000007fu)) | ((synchsafeInt & 0x00007f00u) >> 1) | ((synchsafeInt & 0x007f0000u) >> 2)
134
| ((synchsafeInt & 0x7f000000u) >> 3);
135
}
136
137
// define helpers for byte swapping
138
#ifdef __cpp_lib_byteswap
// in C++ 23 we can just use the stdlib
139
template
<
class
T, Traits::EnableIf<std::is_
int
egral<T>> * =
nullptr
>
CPP_UTILITIES_EXPORT
constexpr
T
swapOrder
(T value)
140
{
141
return
std::byteswap(value);
142
}
143
144
#else
// provide custom code for C++ 20 and older (will also be optimized by GCC and Clang to use bswap)
145
149
CPP_UTILITIES_EXPORT
constexpr
std::uint16_t
swapOrder
(std::uint16_t value)
150
{
151
return
static_cast<
std::uint16_t
>
(((value >> 8) & 0x00FF) | ((value << 8) & 0xFF00));
152
}
153
157
CPP_UTILITIES_EXPORT
constexpr
std::uint32_t
swapOrder
(std::uint32_t value)
158
{
159
return
(value >> 24) | ((value & 0x00FF0000) >> 8) | ((value & 0x0000FF00) << 8) | (value << 24);
160
}
161
162
165
CPP_UTILITIES_EXPORT
constexpr
std::uint64_t
swapOrder
(std::uint64_t value)
166
{
167
return
(value >> (7 * 8)) | ((value & 0x00FF000000000000) >> (5 * 8)) | ((value & 0x0000FF0000000000) >> (3 * 8))
168
| ((value & 0x000000FF00000000) >> (1 * 8)) | ((value & 0x00000000FF000000) << (1 * 8)) | ((value & 0x0000000000FF0000) << (3 * 8))
169
| ((value & 0x000000000000FF00) << (5 * 8)) | ((value) << (7 * 8));
170
}
171
175
CPP_UTILITIES_EXPORT
constexpr
std::int16_t
swapOrder
(std::int16_t value)
176
{
177
return
static_cast<
std::int16_t
>
(((
static_cast<
std::uint16_t
>
(value) >> 8) & 0x00FF) | ((
static_cast<
std::uint16_t
>
(value) << 8) & 0xFF00));
178
}
179
183
CPP_UTILITIES_EXPORT
constexpr
std::int32_t
swapOrder
(std::int32_t value)
184
{
185
return
static_cast<
std::int32_t
>
((
static_cast<
std::uint32_t
>
(value) >> 24) | ((
static_cast<
std::uint32_t
>
(value) & 0x00FF0000) >> 8)
186
| ((
static_cast<
std::uint32_t
>
(value) & 0x0000FF00) << 8) | (
static_cast<
std::uint32_t
>
(value) << 24));
187
}
188
192
CPP_UTILITIES_EXPORT
constexpr
std::int64_t
swapOrder
(std::int64_t value)
193
{
194
return
static_cast<
std::int64_t
>
((
static_cast<
std::uint64_t
>
(value) >> (7 * 8))
195
| ((
static_cast<
std::uint64_t
>
(value) & 0x00FF000000000000) >> (5 * 8))
196
| ((
static_cast<
std::uint64_t
>
(value) & 0x0000FF0000000000) >> (3 * 8))
197
| ((
static_cast<
std::uint64_t
>
(value) & 0x000000FF00000000) >> (1 * 8))
198
| ((
static_cast<
std::uint64_t
>
(value) & 0x00000000FF000000) << (1 * 8))
199
| ((
static_cast<
std::uint64_t
>
(value) & 0x0000000000FF0000) << (3 * 8))
200
| ((
static_cast<
std::uint64_t
>
(value) & 0x000000000000FF00) << (5 * 8)) | ((
static_cast<
std::uint64_t
>
(value)) << (7 * 8)));
201
}
202
#endif
203
204
208
namespace
BE
{
209
210
#define CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL 0
211
#include "
./binaryconversionprivate.h
"
212
#undef CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL
213
}
// namespace BE
214
219
namespace
LE
{
220
221
#define CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL 1
222
#include "
./binaryconversionprivate.h
"
223
#undef CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL
224
}
// namespace LE
225
226
}
// namespace CppUtilities
227
228
#endif
// CONVERSION_UTILITIES_BINARY_CONVERSION_H
binaryconversionprivate.h
global.h
CPP_UTILITIES_EXPORT
#define CPP_UTILITIES_EXPORT
Marks the symbol to be exported by the c++utilities library.
Definition
global.h:14
CppUtilities::BE
Encapsulates binary conversion functions using the big endian byte order.
Definition
binaryconversion.h:208
CppUtilities::LE
Encapsulates binary conversion functions using the little endian byte order.
Definition
binaryconversion.h:219
CppUtilities
Contains all utilities provided by the c++utilities library.
Definition
argumentparser.h:18
CppUtilities::toFloat32
CPP_UTILITIES_EXPORT constexpr float toFloat32(std::uint16_t fixed8value)
Returns a 32-bit floating point number converted from the specified 8.8 fixed point representation.
Definition
binaryconversion.h:95
CppUtilities::toNormalInt
CPP_UTILITIES_EXPORT constexpr std::uint32_t toNormalInt(std::uint32_t synchsafeInt)
Returns a normal 32-bit integer converted from a 32-bit synchsafe integer.
Definition
binaryconversion.h:131
CppUtilities::swapOrder
CPP_UTILITIES_EXPORT constexpr std::uint16_t swapOrder(std::uint16_t value)
Swaps the byte order of the specified 16-bit unsigned integer.
Definition
binaryconversion.h:149
CppUtilities::toFixed16
CPP_UTILITIES_EXPORT constexpr std::uint32_t toFixed16(float float32value)
Returns the 16.16 fixed point representation converted from the specified 32-bit floating point numbe...
Definition
binaryconversion.h:103
CppUtilities::toFixed8
CPP_UTILITIES_EXPORT constexpr std::uint16_t toFixed8(float float32value)
Returns the 8.8 fixed point representation converted from the specified 32-bit floating point number.
Definition
binaryconversion.h:87
CppUtilities::toSynchsafeInt
CPP_UTILITIES_EXPORT constexpr std::uint32_t toSynchsafeInt(std::uint32_t normalInt)
Returns a 32-bit synchsafe integer converted from a normal 32-bit integer.
Definition
binaryconversion.h:121
traits.h
Generated on
for C++ Utilities by
1.18.0