GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
#ifndef ZSERIO_STRING_CONVERT_UTIL_H_INC |
||
2 |
#define ZSERIO_STRING_CONVERT_UTIL_H_INC |
||
3 |
|||
4 |
#include <sstream> |
||
5 |
#include <limits> |
||
6 |
#include <array> |
||
7 |
|||
8 |
#include "zserio/String.h" |
||
9 |
#include "zserio/RebindAlloc.h" |
||
10 |
|||
11 |
namespace zserio |
||
12 |
{ |
||
13 |
|||
14 |
namespace detail |
||
15 |
{ |
||
16 |
|||
17 |
/** |
||
18 |
* Converts integer value to string into the given buffer. |
||
19 |
* |
||
20 |
* The string is filled from backwards starting at the 24th byte. |
||
21 |
* |
||
22 |
* \return Beginning of the resulting string which is null-terminated. |
||
23 |
*/ |
||
24 |
template <typename T, |
||
25 |
typename std::enable_if<std::is_unsigned<T>::value && !std::is_same<T, bool>::value, int>::type = 0> |
||
26 |
2439 |
const char* convertIntToString(std::array<char, 24>& buffer, T value, bool isNegative) |
|
27 |
{ |
||
28 |
static const std::array<char, 201> DIGITS = {"0001020304050607080910111213141516171819" |
||
29 |
"2021222324252627282930313233343536373839" |
||
30 |
"4041424344454647484950515253545556575859" |
||
31 |
"6061626364656667686970717273747576777879" |
||
32 |
"8081828384858687888990919293949596979899"}; |
||
33 |
|||
34 |
2439 |
auto bufferEnd = buffer.end(); |
|
35 |
2439 |
*--bufferEnd = 0; // always terminate with '\0' |
|
36 |
|||
37 |
✓✓✓✓ ✗✗✗✗ ✗✗ |
7481 |
while (value >= 100) |
38 |
{ |
||
39 |
2521 |
const unsigned int index = static_cast<unsigned int>((value % 100) * 2); |
|
40 |
2521 |
value /= 100; |
|
41 |
2521 |
*--bufferEnd = DIGITS[index + 1]; |
|
42 |
2521 |
*--bufferEnd = DIGITS[index]; |
|
43 |
} |
||
44 |
|||
45 |
✓✓✓✓ ✗✗✗✗ ✗✗ |
2439 |
if (value < 10) |
46 |
{ |
||
47 |
1639 |
*--bufferEnd = static_cast<char>('0' + value); |
|
48 |
} |
||
49 |
else |
||
50 |
{ |
||
51 |
800 |
const unsigned int index = static_cast<unsigned int>(value * 2); |
|
52 |
800 |
*--bufferEnd = DIGITS[index + 1]; |
|
53 |
800 |
*--bufferEnd = DIGITS[index]; |
|
54 |
} |
||
55 |
|||
56 |
✓✓✓✓ ✗✗✗✗ ✗✗ |
2439 |
if (isNegative) |
57 |
231 |
*--bufferEnd = '-'; |
|
58 |
|||
59 |
2439 |
return &(*bufferEnd); |
|
60 |
} |
||
61 |
|||
62 |
} // namespace detail |
||
63 |
|||
64 |
/** |
||
65 |
* Converts unsigned integral value to string and writes the result to the given buffer. |
||
66 |
* |
||
67 |
* Note that the buffer is filled from behind. |
||
68 |
* |
||
69 |
* \param buffer Buffer to fill with the string representation of the given value. |
||
70 |
* \param value Value to convert. |
||
71 |
* |
||
72 |
* \return Pointer to the beginning of the resulting string. |
||
73 |
*/ |
||
74 |
template <typename T, |
||
75 |
typename std::enable_if<std::is_unsigned<T>::value, int>::type = 0> |
||
76 |
1941 |
const char* convertIntToString(std::array<char, 24>& buffer, T value) |
|
77 |
{ |
||
78 |
1941 |
return detail::convertIntToString(buffer, value, false); |
|
79 |
} |
||
80 |
|||
81 |
/** |
||
82 |
* Converts signed integral value to string and writes the result to the given buffer. |
||
83 |
* |
||
84 |
* Note that the buffer is filled from behind. |
||
85 |
* |
||
86 |
* \param buffer Buffer to fill with the string representation of the given value. |
||
87 |
* \param value Value to convert. |
||
88 |
* |
||
89 |
* \return Pointer to the beginning of the resulting string. |
||
90 |
*/ |
||
91 |
template <typename T, typename std::enable_if<std::is_signed<T>::value, int>::type = 0> |
||
92 |
498 |
const char* convertIntToString(std::array<char, 24>& buffer, T value) |
|
93 |
{ |
||
94 |
using unsigned_type = typename std::make_unsigned<T>::type; |
||
95 |
498 |
unsigned_type absValue = static_cast<unsigned_type>(value); |
|
96 |
498 |
const bool isNegative = value < 0; |
|
97 |
✓✓✓✓ ✗✗✓✓ ✗✗ |
498 |
if (isNegative) |
98 |
231 |
absValue = 0 - absValue; |
|
99 |
|||
100 |
498 |
return detail::convertIntToString(buffer, absValue, isNegative); |
|
101 |
} |
||
102 |
|||
103 |
/** |
||
104 |
* Converts float to string and writes the result to the given buffer. |
||
105 |
* |
||
106 |
* Note that only five three digits after point are used and that the buffers are filled from behind. |
||
107 |
* |
||
108 |
* \param integerPartBuffer Buffer to fill with the string representation of the integer part. |
||
109 |
* \param floatingPartBuffer Buffer to fill with the string representation of the floating part. |
||
110 |
* \param value Value to convert. |
||
111 |
* \param floatingPartString Reference where to fill pointer to the beginning of the floating part in string. |
||
112 |
* \param integerPartString Reference where to fill pointer to the beginning of the integer part in string. |
||
113 |
*/ |
||
114 |
21 |
inline void convertFloatToString(std::array<char, 24>& integerPartBuffer, |
|
115 |
std::array<char, 24>& floatingPartBuffer, float value, const char*& integerPartString, |
||
116 |
const char*& floatingPartString) |
||
117 |
{ |
||
118 |
✓✓ | 21 |
if (value >= static_cast<float>(std::numeric_limits<int64_t>::max())) |
119 |
{ |
||
120 |
2 |
integerPartString = "+Inf"; |
|
121 |
2 |
floatingPartString = nullptr; |
|
122 |
} |
||
123 |
✓✓ | 19 |
else if (value <= static_cast<float>(std::numeric_limits<int64_t>::min())) |
124 |
{ |
||
125 |
1 |
integerPartString = "-Inf"; |
|
126 |
1 |
floatingPartString = nullptr; |
|
127 |
} |
||
128 |
else |
||
129 |
{ |
||
130 |
18 |
const int64_t integerPart = static_cast<int64_t>(value); |
|
131 |
const int64_t floatingPart = static_cast<int64_t>( |
||
132 |
18 |
(value - static_cast<float>(integerPart)) * 1e3F); // 3 digits |
|
133 |
18 |
const int64_t floatingPartAbs = (floatingPart < 0) ? 0 - floatingPart : floatingPart; |
|
134 |
18 |
integerPartString = convertIntToString(integerPartBuffer, integerPart); |
|
135 |
18 |
floatingPartString = convertIntToString(floatingPartBuffer, floatingPartAbs); |
|
136 |
} |
||
137 |
21 |
} |
|
138 |
|||
139 |
/** |
||
140 |
* Converts bool value to boolalpha C-string ("true" or "false"). |
||
141 |
* |
||
142 |
* \param value Value to convert. |
||
143 |
* |
||
144 |
* \return C-string representation of the given bool value. |
||
145 |
*/ |
||
146 |
23 |
inline const char* convertBoolToString(bool value) |
|
147 |
{ |
||
148 |
✓✓ | 23 |
return value ? "true" : "false"; |
149 |
} |
||
150 |
|||
151 |
/** |
||
152 |
* Converts an integral value to string using the given allocator. Defined for convenience. |
||
153 |
* |
||
154 |
* \param value Value to convert. |
||
155 |
* \param allocator Allocator to use for the string allocation. |
||
156 |
* |
||
157 |
* \return String representation of the given integral value. |
||
158 |
*/ |
||
159 |
template <typename ALLOC, typename T> |
||
160 |
497 |
string<ALLOC> toString(T value, const ALLOC& allocator = ALLOC()) |
|
161 |
{ |
||
162 |
497 |
std::array<char, 24> buffer = {}; |
|
163 |
✓✓✗✓ ✓✗✗✓ ✓✗✓✓ ✗✓✗✗ ✗✗✗✓ ✓✗✓✗ ✗✗✗✗ ✗✓✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✗✓ ✗✓✗✗ ✗✗✗✗ ✗✗✗✓ ✗✓✗✓ ✗✓✗✓ ✗✓✗ |
497 |
return string<ALLOC>(convertIntToString(buffer, value), allocator); |
164 |
} |
||
165 |
|||
166 |
/** |
||
167 |
* Converts a boolean value to string using the given allocator. Defined for convenience. |
||
168 |
* |
||
169 |
* Note that in contrast to std::to_string, this behaves as STL streams with boolalpha flag and produces |
||
170 |
* "true" and "false" strings. |
||
171 |
* |
||
172 |
* \param value Value to convert. |
||
173 |
* \param allocator Allocator to use for the string allocation. |
||
174 |
*/ |
||
175 |
template <typename ALLOC> |
||
176 |
21 |
string<ALLOC> toString(bool value, const ALLOC& allocator = ALLOC()) |
|
177 |
{ |
||
178 |
✓✗ | 21 |
return string<ALLOC>(convertBoolToString(value), allocator); |
179 |
} |
||
180 |
|||
181 |
/** |
||
182 |
* Converts an integral (or a boolean) value to string. Convenience wrapper to call without allocator. |
||
183 |
* |
||
184 |
* \param value Value to convert. |
||
185 |
* |
||
186 |
* \return String representation of the given value. |
||
187 |
*/ |
||
188 |
template <typename T> |
||
189 |
287 |
string<std::allocator<char>> toString(T value) |
|
190 |
{ |
||
191 |
✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✗✗✗✗ |
287 |
return toString<std::allocator<char>>(value); |
192 |
} |
||
193 |
|||
194 |
} // namespace zserio |
||
195 |
|||
196 |
#endif // ifndef ZSERIO_STRING_CONVERT_UTIL_H_INC |
Generated by: GCOVR (Version 4.2) |