Zserio C++17 runtime library 1.3.0
Built for Zserio 2.20.0
Loading...
Searching...
No Matches
StringConvertUtil.h
Go to the documentation of this file.
1#ifndef ZSERIO_STRING_CONVERT_UTIL_H_INC
2#define ZSERIO_STRING_CONVERT_UTIL_H_INC
3
4#include <array>
5#include <limits>
6#include <sstream>
7#include <string_view>
8
10#include "zserio/String.h"
11
12namespace zserio
13{
14
15namespace detail
16{
17
25template <typename T, std::enable_if_t<std::is_unsigned_v<T> && !std::is_same_v<T, bool>, int> = 0>
26const char* convertIntToString(std::array<char, 24>& buffer, T value, bool isNegative)
27{
28 static const std::array<char, 201> DIGITS_100_10 = {
29 "0001020304050607080910111213141516171819"
30 "2021222324252627282930313233343536373839"
31 "4041424344454647484950515253545556575859"
32 "6061626364656667686970717273747576777879"
33 "8081828384858687888990919293949596979899"};
34 static const std::array<char, 11> DIGITS_1 = {"0123456789"};
35
36 auto bufferEnd = buffer.end();
37 *(--bufferEnd) = '\0'; // always terminate with '\0'
38
39 while (value >= 100)
40 {
41 const unsigned int index = static_cast<unsigned int>((value % 100) * 2);
42 value /= 100;
43 *(--bufferEnd) = DIGITS_100_10[index + 1];
44 *(--bufferEnd) = DIGITS_100_10[index];
45 }
46
47 if (value < 10)
48 {
49 *(--bufferEnd) = DIGITS_1[static_cast<unsigned int>(value)];
50 }
51 else
52 {
53 const unsigned int index = static_cast<unsigned int>(value * 2);
54 *(--bufferEnd) = DIGITS_100_10[index + 1];
55 *(--bufferEnd) = DIGITS_100_10[index];
56 }
57
58 if (isNegative)
59 {
60 *(--bufferEnd) = '-';
61 }
62
63 return &(*bufferEnd);
64}
65
66} // namespace detail
67
78template <typename T, std::enable_if_t<std::is_unsigned_v<T>, int> = 0>
79const char* convertIntToString(std::array<char, 24>& buffer, T value)
80{
81 return detail::convertIntToString(buffer, value, false);
82}
83
94template <typename T, std::enable_if_t<std::is_signed_v<T>, int> = 0>
95const char* convertIntToString(std::array<char, 24>& buffer, T value)
96{
97 using UnsignedType = typename std::make_unsigned_t<T>;
98 UnsignedType absValue = static_cast<UnsignedType>(value);
99 const bool isNegative = value < 0;
100 if (isNegative)
101 {
102 absValue = static_cast<UnsignedType>(0 - absValue);
103 }
104
105 return detail::convertIntToString(buffer, absValue, isNegative);
106}
107
119inline void convertFloatToString(std::array<char, 24>& integerPartBuffer,
120 std::array<char, 24>& floatingPartBuffer, float value, const char*& integerPartString,
121 const char*& floatingPartString)
122{
123 if (value >= static_cast<float>(std::numeric_limits<int64_t>::max()))
124 {
125 integerPartString = "+Inf";
126 floatingPartString = nullptr;
127 }
128 else if (value <= static_cast<float>(std::numeric_limits<int64_t>::min()))
129 {
130 integerPartString = "-Inf";
131 floatingPartString = nullptr;
132 }
133 else
134 {
135 const int64_t integerPart = static_cast<int64_t>(value);
136 const int64_t floatingPart =
137 static_cast<int64_t>((value - static_cast<float>(integerPart)) * 1e3F); // 3 digits
141 }
142}
143
151inline const char* convertBoolToString(bool value)
152{
153 return value ? "true" : "false";
154}
155
164template <typename ALLOC, typename T, std::enable_if_t<std::is_integral_v<T>, int> = 0>
166{
167 std::array<char, 24> buffer = {};
169}
170
179template <typename ALLOC, typename T, std::enable_if_t<std::is_integral_v<typename T::ValueType>, int> = 0>
180BasicString<RebindAlloc<ALLOC, char>> toString(T value, const ALLOC& allocator = ALLOC())
181{
182 if constexpr (std::is_same_v<bool, typename T::ValueType>)
183 {
184 return BasicString<RebindAlloc<ALLOC, char>>(convertBoolToString(value), allocator);
185 }
186 else
187 {
188 std::array<char, 24> buffer = {};
189 return BasicString<RebindAlloc<ALLOC, char>>(
190 convertIntToString(buffer, static_cast<typename T::ValueType>(value)), allocator);
191 }
192}
193
203template <typename ALLOC>
208
215template <typename ALLOC>
217{
219}
220
228template <typename T>
233
234} // namespace zserio
235
236#endif // ifndef ZSERIO_STRING_CONVERT_UTIL_H_INC
const char * convertIntToString(std::array< char, 24 > &buffer, T value)
const char * convertBoolToString(bool value)
BasicString< RebindAlloc< ALLOC, char > > toString(T value, const ALLOC &allocator=ALLOC())
void convertFloatToString(std::array< char, 24 > &integerPartBuffer, std::array< char, 24 > &floatingPartBuffer, float value, const char *&integerPartString, const char *&floatingPartString)