25#ifndef JAU_STRING_UTIL_HPP_
26#define JAU_STRING_UTIL_HPP_
67 std::string
trim(
const std::string &s)
noexcept;
70 std::vector<std::string>
split_string(
const std::string& str,
const std::string& separator)
noexcept;
74 std::string
toLower(
const std::string& s)
noexcept;
94 size_t hexStringBytes(std::vector<uint8_t>& out,
const std::string& hexstr,
const bool lsbFirst,
const bool checkLeading0x)
noexcept;
97 size_t hexStringBytes(std::vector<uint8_t>& out,
const uint8_t hexstr[],
const size_t hexstr_len,
const bool lsbFirst,
const bool checkLeading0x)
noexcept;
115 const bool lsbFirst,
const bool lowerCase=
true) noexcept;
117 template< class uint8_container_type,
118 std::enable_if_t<
std::is_integral_v<typename uint8_container_type::value_type> &&
119 std::is_convertible_v<typename uint8_container_type::value_type, uint8_t>,
122 const
bool lsbFirst, const
bool lowerCase=true) noexcept {
123 return bytesHexString((
const uint8_t *)bytes.data(), 0, bytes.size(), lsbFirst, lowerCase);
133 std::string&
byteHexString(std::string& dest,
const uint8_t value,
const bool lowerCase)
noexcept;
142 template<
class value_type,
143 std::enable_if_t<std::is_pointer_v<value_type>,
147 const uintptr_t v2 =
reinterpret_cast<uintptr_t
>(v);
148 return bytesHexString(pointer_cast<const uint8_t*>(&v2), 0,
sizeof(v),
false );
158 template<
class value_type,
159 std::enable_if_t<!std::is_pointer_v<value_type> &&
160 std::is_standard_layout_v<value_type>,
162 inline std::string
to_hexstring(value_type
const & v)
noexcept
164 return bytesHexString(pointer_cast<const uint8_t*>(&v), 0,
sizeof(v),
false );
181 template<
class value_type,
182 std::enable_if_t< std::is_integral_v<value_type>,
185 const snsize_t v_sign = jau::sign<value_type>(v);
186 const nsize_t digit10_count1 = jau::digits10<value_type>(v, v_sign,
true );
187 const nsize_t digit10_count2 = v_sign < 0 ? digit10_count1 - 1 : digit10_count1;
189 const nsize_t comma_count = 0 == separator ? 0 : ( digit10_count1 - 1 ) / 3;
190 const nsize_t net_chars = digit10_count1 + comma_count;
191 const nsize_t total_chars = std::max<nsize_t>(width, net_chars);
192 std::string res(total_chars,
' ');
197 for(
nsize_t digit10_iter = 0; digit10_iter < digit10_count2 ; digit10_iter++ ) {
198 const int digit = v_sign < 0 ?
invert_sign( n % 10 ) : n % 10;
200 if( 0 < digit10_iter && 0 == digit10_iter % 3 ) {
201 res[total_chars-1-(char_iter++)] = separator;
203 res[total_chars-1-(char_iter++)] =
'0' + digit;
206 res[total_chars-1-(char_iter++)] =
'-';
223 std::string
vformat_string(
const char* format, va_list ap)
noexcept;
238 template< class value_type,
239 std::enable_if_t<
std::is_integral_v<value_type> ||
240 std::is_floating_point_v<value_type>,
247 template<
class value_type,
248 std::enable_if_t<!std::is_integral_v<value_type> &&
249 !std::is_floating_point_v<value_type> &&
250 std::is_base_of_v<std::string, value_type>,
252 inline std::string
to_string(
const value_type & ref) {
256 template<
class value_type,
257 std::enable_if_t<!std::is_integral_v<value_type> &&
258 !std::is_floating_point_v<value_type> &&
259 !std::is_base_of_v<std::string, value_type> &&
260 std::is_base_of_v<std::string_view, value_type>,
262 inline std::string
to_string(
const value_type & ref) {
263 return std::string(ref);
266 template<
class value_type,
267 std::enable_if_t<!std::is_integral_v<value_type> &&
268 !std::is_floating_point_v<value_type> &&
269 !std::is_base_of_v<std::string, value_type> &&
270 !std::is_base_of_v<std::string_view, value_type> &&
271 std::is_pointer_v<value_type>,
273 inline std::string
to_string(
const value_type & ref)
278 template<
class value_type,
279 std::enable_if_t<!std::is_integral_v<value_type> &&
280 !std::is_floating_point_v<value_type> &&
281 !std::is_base_of_v<std::string, value_type> &&
282 !std::is_base_of_v<std::string_view, value_type> &&
283 !std::is_pointer_v<value_type> &&
284 jau::has_toString_v<value_type>,
286 inline std::string
to_string(
const value_type & ref) {
287 return ref.toString();
290 template<
class value_type,
291 std::enable_if_t<!std::is_integral_v<value_type> &&
292 !std::is_floating_point_v<value_type> &&
293 !std::is_base_of_v<std::string, value_type> &&
294 !std::is_base_of_v<std::string_view, value_type> &&
295 !std::is_pointer_v<value_type> &&
296 !jau::has_toString_v<value_type> &&
297 jau::has_to_string_v<value_type>,
299 inline std::string
to_string(
const value_type & ref) {
300 return ref.to_string();
303 template<
class value_type,
304 std::enable_if_t<!std::is_integral_v<value_type> &&
305 !std::is_floating_point_v<value_type> &&
306 !std::is_base_of_v<std::string, value_type> &&
307 !std::is_base_of_v<std::string_view, value_type> &&
308 !std::is_pointer_v<value_type> &&
309 !jau::has_toString_v<value_type> &&
310 !jau::has_to_string_v<value_type> &&
311 jau::has_member_of_pointer_v<value_type>,
313 inline std::string
to_string(
const value_type & ref) {
317 template<
class value_type,
318 std::enable_if_t<!std::is_integral_v<value_type> &&
319 !std::is_floating_point_v<value_type> &&
320 !std::is_base_of_v<std::string, value_type> &&
321 !std::is_base_of_v<std::string_view, value_type> &&
322 !std::is_pointer_v<value_type> &&
323 !jau::has_toString_v<value_type> &&
324 !jau::has_to_string_v<value_type> &&
325 !jau::has_member_of_pointer_v<value_type>,
327 inline std::string
to_string(
const value_type & ref) {
333 std::string
to_string(std::vector<T>
const &list,
const std::string& delim)
335 if ( list.empty() ) {
336 return std::string();
338 bool need_delim =
false;
340 for(
const T& e : list) {
350 std::string
to_string(std::vector<T>
const &list) {
return to_string<T>(list,
", "); }
352 bool to_integer(
long long & result,
const std::string& str,
const char limiter=
'\0',
const char *limiter_pos=
nullptr);
353 bool to_integer(
long long & result,
const char * str,
size_t str_len,
const char limiter=
'\0',
const char *limiter_pos=
nullptr);
std::string to_string(const endian_t v) noexcept
Return std::string representation of the given endian.
constexpr T invert_sign(const T x) noexcept
Safely inverts the sign of an arithmetic number w/ branching in O(1)
uint_fast32_t nsize_t
Natural 'size_t' alternative using uint_fast32_t as its natural sized type.
int_fast32_t snsize_t
Natural 'ssize_t' alternative using int_fast32_t as its natural sized type.
std::string & toLowerInPlace(std::string &s) noexcept
std::string format_string(const char *format,...) noexcept
Returns a string according to printf() formatting rules and variable number of arguments following th...
std::string trim(const std::string &s) noexcept
trim copy
std::string bytesHexString(const void *data, const nsize_t offset, const nsize_t length, const bool lsbFirst, const bool lowerCase=true) noexcept
Produce a hexadecimal string representation of the given byte values.
void trimInPlace(std::string &s) noexcept
trim in place
std::string to_string(std::vector< T > const &list)
std::string get_string(const uint8_t *buffer, nsize_t const buffer_len, nsize_t const max_len) noexcept
Returns a C++ String taken from buffer with maximum length of min(max_len, max_len).
std::string & byteHexString(std::string &dest, const uint8_t value, const bool lowerCase) noexcept
Produce a hexadecimal string representation of the given byte value.
std::string vformat_string(const char *format, va_list ap) noexcept
Returns a string according to vprintf() formatting rules using va_list instead of a variable number o...
bool to_integer(long long &result, const std::string &str, const char limiter='\0', const char *limiter_pos=nullptr)
std::vector< std::string > split_string(const std::string &str, const std::string &separator) noexcept
Split given string str at separator into the resulting std::vector excluding the separator sequence .
std::string toLower(const std::string &s) noexcept
size_t hexStringBytes(std::vector< uint8_t > &out, const std::string &hexstr, const bool lsbFirst, const bool checkLeading0x) noexcept
Converts a given hexadecimal string representation into a byte vector.
std::string to_hexstring(value_type const &v) noexcept
Produce a lower-case hexadecimal string representation of the given pointer.
std::string to_decstring(const value_type &v, const char separator=',', const nsize_t width=0) noexcept
Produce a decimal string representation of an integral integer value.
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
static void print(const std::string &typedefname, const TypeTraitGroup verbosity=TypeTraitGroup::NONE)
Print information of this type to stdout, potentially with all Type traits known.