C++ Utilities 5.24.8
Useful C++ classes and routines such as argument parser, IO and conversion utilities
Loading...
Searching...
No Matches
binaryconversionprivate.h
Go to the documentation of this file.
1// assert that CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL is defined; a value of:
2// - 0 means to define functions for BE namespace
3// - 1 means to define functions for LE namespace
4#ifndef CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL
5#error "Do not include binaryconversionprivate.h directly."
6#else
7
8// define macro if swapping byte order is required
9#if (CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0 && defined(CONVERSION_UTILITIES_BYTE_ORDER_LITTLE_ENDIAN)) \
10 || (CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 1 && defined(CONVERSION_UTILITIES_BYTE_ORDER_BIG_ENDIAN))
11#define CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL_NEEDS_SWAP
12#endif
13
14// disable warnings about sign conversions when using GCC or Clang
15#ifdef __GNUC__
16#pragma GCC diagnostic push
17#pragma GCC diagnostic ignored "-Wsign-conversion"
18#endif
19
23CPP_UTILITIES_EXPORT constexpr std::int16_t toInt16(const char *value)
24{
25#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
26 return static_cast<std::int16_t>((static_cast<std::int16_t>(value[0]) << 8 & 0xFF00) | (static_cast<std::int16_t>(value[1]) & 0x00FF));
27#else
28 return static_cast<std::int16_t>((static_cast<std::int16_t>(value[1]) << 8 & 0xFF00) | (static_cast<std::int16_t>(value[0]) & 0x00FF));
29#endif
30}
31
35CPP_UTILITIES_EXPORT constexpr std::uint16_t toUInt16(const char *value)
36{
37#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
38 return static_cast<std::uint16_t>((static_cast<std::uint16_t>(value[0]) << 8 & 0xFF00) | (static_cast<std::uint16_t>(value[1]) & 0x00FF));
39#else
40 return static_cast<std::uint16_t>((static_cast<std::uint16_t>(value[1]) << 8 & 0xFF00) | (static_cast<std::uint16_t>(value[0]) & 0x00FF));
41#endif
42}
43
47CPP_UTILITIES_EXPORT constexpr std::int32_t toInt32(const char *value)
48{
49#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
50 return static_cast<std::int32_t>((static_cast<std::int32_t>(value[0]) << 24 & 0xFF000000)
51 | (static_cast<std::int32_t>(value[1]) << 16 & 0x00FF0000) | (static_cast<std::int32_t>(value[2]) << 8 & 0x0000FF00)
52 | (static_cast<std::int32_t>(value[3]) & 0x000000FF));
53#else
54 return static_cast<std::int32_t>((static_cast<std::int32_t>(value[3]) << 24 & 0xFF000000)
55 | (static_cast<std::int32_t>(value[2]) << 16 & 0x00FF0000) | (static_cast<std::int32_t>(value[1]) << 8 & 0x0000FF00)
56 | (static_cast<std::int32_t>(value[0]) & 0x000000FF));
57#endif
58}
59
63CPP_UTILITIES_EXPORT constexpr std::uint32_t toUInt24(const char *value)
64{
65#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
66 return (static_cast<std::uint32_t>(value[0]) << 16 & 0x00FF0000) | (static_cast<std::uint32_t>(value[1]) << 8 & 0x0000FF00)
67 | (static_cast<std::uint32_t>(value[2]) & 0x000000FF);
68#else
69 return (static_cast<std::uint32_t>(value[2]) << 16 & 0x00FF0000) | (static_cast<std::uint32_t>(value[1]) << 8 & 0x0000FF00)
70 | (static_cast<std::uint32_t>(value[0]) & 0x000000FF);
71#endif
72}
73
77CPP_UTILITIES_EXPORT constexpr std::uint32_t toUInt32(const char *value)
78{
79#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
80 return (static_cast<std::uint32_t>(value[0]) << 24 & 0xFF000000) | (static_cast<std::uint32_t>(value[1]) << 16 & 0x00FF0000)
81 | (static_cast<std::uint32_t>(value[2]) << 8 & 0x0000FF00) | (static_cast<std::uint32_t>(value[3]) & 0x000000FF);
82#else
83 return (static_cast<std::uint32_t>(value[3]) << 24 & 0xFF000000) | (static_cast<std::uint32_t>(value[2]) << 16 & 0x00FF0000)
84 | (static_cast<std::uint32_t>(value[1]) << 8 & 0x0000FF00) | (static_cast<std::uint32_t>(value[0]) & 0x000000FF);
85#endif
86}
87
91CPP_UTILITIES_EXPORT constexpr std::int64_t toInt64(const char *value)
92{
93#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
94 return (static_cast<std::int64_t>(value[0]) << 56 & 0xFF00000000000000) | (static_cast<std::int64_t>(value[1]) << 48 & 0x00FF000000000000)
95 | (static_cast<std::int64_t>(value[2]) << 40 & 0x0000FF0000000000) | (static_cast<std::int64_t>(value[3]) << 32 & 0x000000FF00000000)
96 | (static_cast<std::int64_t>(value[4]) << 24 & 0x00000000FF000000) | (static_cast<std::int64_t>(value[5]) << 16 & 0x0000000000FF0000)
97 | (static_cast<std::int64_t>(value[6]) << 8 & 0x000000000000FF00) | (static_cast<std::int64_t>(value[7]) & 0x00000000000000FF);
98#else
99 return (static_cast<std::int64_t>(value[7]) << 56 & 0xFF00000000000000) | (static_cast<std::int64_t>(value[6]) << 48 & 0x00FF000000000000)
100 | (static_cast<std::int64_t>(value[5]) << 40 & 0x0000FF0000000000) | (static_cast<std::int64_t>(value[4]) << 32 & 0x000000FF00000000)
101 | (static_cast<std::int64_t>(value[3]) << 24 & 0x00000000FF000000) | (static_cast<std::int64_t>(value[2]) << 16 & 0x0000000000FF0000)
102 | (static_cast<std::int64_t>(value[1]) << 8 & 0x000000000000FF00) | (static_cast<std::int64_t>(value[0]) & 0x00000000000000FF);
103#endif
104}
105
109CPP_UTILITIES_EXPORT constexpr std::uint64_t toUInt64(const char *value)
110{
111#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
112 return (static_cast<std::uint64_t>(value[0]) << 56 & 0xFF00000000000000) | (static_cast<std::uint64_t>(value[1]) << 48 & 0x00FF000000000000)
113 | (static_cast<std::uint64_t>(value[2]) << 40 & 0x0000FF0000000000) | (static_cast<std::uint64_t>(value[3]) << 32 & 0x000000FF00000000)
114 | (static_cast<std::uint64_t>(value[4]) << 24 & 0x00000000FF000000) | (static_cast<std::uint64_t>(value[5]) << 16 & 0x0000000000FF0000)
115 | (static_cast<std::uint64_t>(value[6]) << 8 & 0x000000000000FF00) | (static_cast<std::uint64_t>(value[7]) & 0x00000000000000FF);
116#else
117 return (static_cast<std::uint64_t>(value[7]) << 56 & 0xFF00000000000000) | (static_cast<std::uint64_t>(value[6]) << 48 & 0x00FF000000000000)
118 | (static_cast<std::uint64_t>(value[5]) << 40 & 0x0000FF0000000000) | (static_cast<std::uint64_t>(value[4]) << 32 & 0x000000FF00000000)
119 | (static_cast<std::uint64_t>(value[3]) << 24 & 0x00000000FF000000) | (static_cast<std::uint64_t>(value[2]) << 16 & 0x0000000000FF0000)
120 | (static_cast<std::uint64_t>(value[1]) << 8 & 0x000000000000FF00) | (static_cast<std::uint64_t>(value[0]) & 0x00000000000000FF);
121#endif
122}
123
127CPP_UTILITIES_EXPORT inline float toFloat32(const char *value)
128{
129 const auto val = toInt32(value);
130 const auto *const c = reinterpret_cast<const char *>(&val);
131 return *reinterpret_cast<const float *>(c);
132}
133
137CPP_UTILITIES_EXPORT inline double toFloat64(const char *value)
138{
139 const auto val = toInt64(value);
140 const auto *const c = reinterpret_cast<const char *>(&val);
141 return *reinterpret_cast<const double *>(c);
142}
143
152template <class T, Traits::EnableIf<std::is_integral<T>> * = nullptr> CPP_UTILITIES_EXPORT inline T toInt(const char *value)
153{
154 auto dst = T();
155 std::memcpy(&dst, value, sizeof(T));
156#ifdef CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL_NEEDS_SWAP
157 dst = swapOrder(dst);
158#endif
159 return dst;
160}
161
166CPP_UTILITIES_EXPORT inline void getBytes24(std::uint32_t value, char *outputbuffer)
167{
168#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
169 outputbuffer[0] = static_cast<char>((value >> 16) & 0xFF);
170 outputbuffer[1] = static_cast<char>((value >> 8) & 0xFF);
171 outputbuffer[2] = static_cast<char>((value) & 0xFF);
172#else
173 outputbuffer[2] = static_cast<char>((value >> 16) & 0xFF);
174 outputbuffer[1] = static_cast<char>((value >> 8) & 0xFF);
175 outputbuffer[0] = static_cast<char>((value) & 0xFF);
176#endif
177}
178
186template <class T, Traits::EnableIf<std::is_integral<T>> * = nullptr> CPP_UTILITIES_EXPORT inline void getBytes(T value, char *outputbuffer)
187{
188#ifdef CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL_NEEDS_SWAP
189 value = swapOrder(value);
190#endif
191 std::memcpy(outputbuffer, &value, sizeof(T));
192}
193
197CPP_UTILITIES_EXPORT inline void getBytes(float value, char *outputbuffer)
198{
199 auto *c = reinterpret_cast<char *>(&value);
200 auto i = *reinterpret_cast<std::int32_t *>(c);
201 getBytes(i, outputbuffer);
202}
203
207CPP_UTILITIES_EXPORT inline void getBytes(double value, char *outputbuffer)
208{
209 auto *c = reinterpret_cast<char *>(&value);
210 auto i = *reinterpret_cast<std::int64_t *>(c);
211 getBytes(i, outputbuffer);
212}
213
214#ifdef __GNUC__
215#pragma GCC diagnostic pop
216#endif
217
218#undef CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL_NEEDS_SWAP
219
220#endif // CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL
#define CPP_UTILITIES_EXPORT
Marks the symbol to be exported by the c++utilities library.
Definition global.h:14
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.
CPP_UTILITIES_EXPORT constexpr std::uint16_t swapOrder(std::uint16_t value)
Swaps the byte order of the specified 16-bit unsigned integer.
constexpr int i