Zserio C++ runtime library  1.3.0
Built for Zserio 2.18.0
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 
8 #include "zserio/RebindAlloc.h"
9 #include "zserio/String.h"
10 #include "zserio/Types.h"
11 
12 namespace zserio
13 {
14 
15 namespace detail
16 {
17 
25 template <typename T,
26  typename std::enable_if<std::is_unsigned<T>::value && !std::is_same<T, bool>::value, int>::type = 0>
27 const char* convertIntToString(std::array<char, 24>& buffer, T value, bool isNegative)
28 {
29  static const std::array<char, 201> DIGITS_100_10 = {
30  "0001020304050607080910111213141516171819"
31  "2021222324252627282930313233343536373839"
32  "4041424344454647484950515253545556575859"
33  "6061626364656667686970717273747576777879"
34  "8081828384858687888990919293949596979899"};
35  static const std::array<char, 11> DIGITS_1 = {"0123456789"};
36 
37  auto bufferEnd = buffer.end();
38  *(--bufferEnd) = '\0'; // always terminate with '\0'
39 
40  while (value >= 100)
41  {
42  const unsigned int index = static_cast<unsigned int>((value % 100) * 2);
43  value /= 100;
44  *(--bufferEnd) = DIGITS_100_10[index + 1];
45  *(--bufferEnd) = DIGITS_100_10[index];
46  }
47 
48  if (value < 10)
49  {
50  *(--bufferEnd) = DIGITS_1[static_cast<unsigned int>(value)];
51  }
52  else
53  {
54  const unsigned int index = static_cast<unsigned int>(value * 2);
55  *(--bufferEnd) = DIGITS_100_10[index + 1];
56  *(--bufferEnd) = DIGITS_100_10[index];
57  }
58 
59  if (isNegative)
60  {
61  *(--bufferEnd) = '-';
62  }
63 
64  return &(*bufferEnd);
65 }
66 
67 } // namespace detail
68 
79 template <typename T, typename std::enable_if<std::is_unsigned<T>::value, int>::type = 0>
80 const char* convertIntToString(std::array<char, 24>& buffer, T value)
81 {
82  return detail::convertIntToString(buffer, value, false);
83 }
84 
95 template <typename T, typename std::enable_if<std::is_signed<T>::value, int>::type = 0>
96 const char* convertIntToString(std::array<char, 24>& buffer, T value)
97 {
98  using unsigned_type = typename std::make_unsigned<T>::type;
99  unsigned_type absValue = static_cast<unsigned_type>(value);
100  const bool isNegative = value < 0;
101  if (isNegative)
102  {
103  absValue = static_cast<unsigned_type>(0 - absValue);
104  }
105 
106  return detail::convertIntToString(buffer, absValue, isNegative);
107 }
108 
120 inline void convertFloatToString(std::array<char, 24>& integerPartBuffer,
121  std::array<char, 24>& floatingPartBuffer, float value, const char*& integerPartString,
122  const char*& floatingPartString)
123 {
124  if (value >= static_cast<float>(std::numeric_limits<int64_t>::max()))
125  {
126  integerPartString = "+Inf";
127  floatingPartString = nullptr;
128  }
129  else if (value <= static_cast<float>(std::numeric_limits<int64_t>::min()))
130  {
131  integerPartString = "-Inf";
132  floatingPartString = nullptr;
133  }
134  else
135  {
136  const int64_t integerPart = static_cast<int64_t>(value);
137  const int64_t floatingPart =
138  static_cast<int64_t>((value - static_cast<float>(integerPart)) * 1e3F); // 3 digits
139  const int64_t floatingPartAbs = (floatingPart < 0) ? 0 - floatingPart : floatingPart;
140  integerPartString = convertIntToString(integerPartBuffer, integerPart);
141  floatingPartString = convertIntToString(floatingPartBuffer, floatingPartAbs);
142  }
143 }
144 
152 inline const char* convertBoolToString(bool value)
153 {
154  return value ? "true" : "false";
155 }
156 
165 template <typename ALLOC, typename T>
166 string<ALLOC> toString(T value, const ALLOC& allocator = ALLOC())
167 {
168  std::array<char, 24> buffer = {};
169  return string<ALLOC>(convertIntToString(buffer, value), allocator);
170 }
171 
181 template <typename ALLOC>
182 string<ALLOC> toString(bool value, const ALLOC& allocator = ALLOC())
183 {
184  return string<ALLOC>(convertBoolToString(value), allocator);
185 }
186 
194 template <typename T>
196 {
197  return toString<std::allocator<char>>(value);
198 }
199 
200 } // namespace zserio
201 
202 #endif // ifndef ZSERIO_STRING_CONVERT_UTIL_H_INC
const char * convertIntToString(std::array< char, 24 > &buffer, T value)
std::basic_string< char, std::char_traits< char >, RebindAlloc< ALLOC, char > > string
Definition: String.h:17
const char * convertBoolToString(bool value)
void convertFloatToString(std::array< char, 24 > &integerPartBuffer, std::array< char, 24 > &floatingPartBuffer, float value, const char *&integerPartString, const char *&floatingPartString)
string< ALLOC > toString(T value, const ALLOC &allocator=ALLOC())