25#ifndef JAU_STRING_UTIL_HPP_
26#define JAU_STRING_UTIL_HPP_
34#include <unordered_map>
35#include <unordered_set>
56 return 0 != std::iscntrl(c) || 0 != std::isprint(c);
75 std::string
trim(
const std::string &s)
noexcept;
78 std::vector<std::string>
split_string(
const std::string& str,
const std::string& separator)
noexcept;
82 std::string
toLower(
const std::string& s)
noexcept;
109 size_t hexStringBytes(std::vector<uint8_t>& out,
const std::string& hexstr,
const bool lsbFirst,
const bool checkLeading0x)
noexcept;
112 size_t hexStringBytes(std::vector<uint8_t>& out,
const uint8_t hexstr[],
const size_t hexstr_len,
const bool lsbFirst,
const bool checkLeading0x)
noexcept;
145 const
bool lsbFirst, const
bool lowerCase=true, const
bool skipLeading0x=false) noexcept;
147 template< class uint8_container_type,
148 std::enable_if_t<
std::is_integral_v<typename uint8_container_type::value_type> &&
149 std::is_convertible_v<typename uint8_container_type::value_type, uint8_t>,
152 const
bool lsbFirst, const
bool lowerCase=true, const
bool skipLeading0x=false) noexcept {
153 return bytesHexString((
const uint8_t *)bytes.data(), bytes.size(), lsbFirst, lowerCase, skipLeading0x);
163 std::string&
byteHexString(std::string& dest,
const uint8_t
value,
const bool lowerCase)
noexcept;
174 template<
class value_type,
175 std::enable_if_t<std::is_pointer_v<value_type>,
177 inline std::string
to_hexstring(value_type
const & v,
const bool skipLeading0x=
false) noexcept
179 #if defined(__EMSCRIPTEN__)
181 const uintptr_t v_le =
reinterpret_cast<uintptr_t
>(v);
183 false ,
true , skipLeading0x);
185 const uintptr_t v_le =
jau::cpu_to_le(
reinterpret_cast<uintptr_t
>(v) );
187 false ,
true , skipLeading0x);
200 template<
class value_type,
201 std::enable_if_t<!std::is_pointer_v<value_type> &&
202 std::is_standard_layout_v<value_type>,
204 inline std::string
to_hexstring(value_type
const & v,
const bool skipLeading0x=
false) noexcept
208 false ,
true , skipLeading0x);
212 false ,
true , skipLeading0x);
230 template<
class value_type,
231 std::enable_if_t< std::is_integral_v<value_type>,
236 const nsize_t digit10_count2 = v_sign < 0 ? digit10_count1 - 1 : digit10_count1;
238 const nsize_t comma_count = 0 == separator ? 0 : ( digit10_count1 - 1 ) / 3;
239 const nsize_t net_chars = digit10_count1 + comma_count;
240 const nsize_t total_chars = std::max<nsize_t>(width, net_chars);
241 std::string res(total_chars,
' ');
246 for(
nsize_t digit10_iter = 0; digit10_iter < digit10_count2 ; digit10_iter++ ) {
247 const int digit = v_sign < 0 ?
invert_sign( n % 10 ) : n % 10;
249 if( 0 < digit10_iter && 0 == digit10_iter % 3 ) {
250 res[total_chars-1-(char_iter++)] = separator;
252 res[total_chars-1-(char_iter++)] =
'0' + digit;
255 res[total_chars-1-(char_iter++)] =
'-';
293 template <
typename... Args>
294 constexpr std::string
format_string_v(
const std::size_t maxStrLen,
const std::string_view format,
const Args &...args) {
297 str.reserve(maxStrLen + 1);
298 str.resize(maxStrLen);
304 const size_t nchars = std::snprintf(&str[0], maxStrLen + 1, format.data(), args...);
306 if( nchars < maxStrLen + 1 ) {
322 template<
class value_type,
323 std::enable_if_t< std::is_integral_v<value_type> ||
324 std::is_floating_point_v<value_type>,
328 return std::to_string(ref);
331 template<
class value_type,
332 std::enable_if_t<!std::is_integral_v<value_type> &&
333 !std::is_floating_point_v<value_type> &&
334 std::is_base_of_v<std::string, value_type>,
336 inline std::string
to_string(
const value_type & ref) {
340 template<
class value_type,
341 std::enable_if_t<!std::is_integral_v<value_type> &&
342 !std::is_floating_point_v<value_type> &&
343 !std::is_base_of_v<std::string, value_type> &&
344 std::is_base_of_v<std::string_view, value_type>,
346 inline std::string
to_string(
const value_type & ref) {
347 return std::string(ref);
350 template<
class value_type,
351 std::enable_if_t<!std::is_integral_v<value_type> &&
352 !std::is_floating_point_v<value_type> &&
353 !std::is_base_of_v<std::string, value_type> &&
354 !std::is_base_of_v<std::string_view, value_type> &&
355 std::is_pointer_v<value_type>,
357 inline std::string
to_string(
const value_type & ref)
362 template<
class value_type,
363 std::enable_if_t<!std::is_integral_v<value_type> &&
364 !std::is_floating_point_v<value_type> &&
365 !std::is_base_of_v<std::string, value_type> &&
366 !std::is_base_of_v<std::string_view, value_type> &&
367 !std::is_pointer_v<value_type> &&
370 inline std::string
to_string(
const value_type & ref) {
371 return ref.toString();
374 template<
class value_type,
375 std::enable_if_t<!std::is_integral_v<value_type> &&
376 !std::is_floating_point_v<value_type> &&
377 !std::is_base_of_v<std::string, value_type> &&
378 !std::is_base_of_v<std::string_view, value_type> &&
379 !std::is_pointer_v<value_type> &&
383 inline std::string
to_string(
const value_type & ref) {
384 return ref.to_string();
387 template<
class value_type,
388 std::enable_if_t<!std::is_integral_v<value_type> &&
389 !std::is_floating_point_v<value_type> &&
390 !std::is_base_of_v<std::string, value_type> &&
391 !std::is_base_of_v<std::string_view, value_type> &&
392 !std::is_pointer_v<value_type> &&
397 inline std::string
to_string(
const value_type & ref) {
401 template<
class value_type,
402 std::enable_if_t<!std::is_integral_v<value_type> &&
403 !std::is_floating_point_v<value_type> &&
404 !std::is_base_of_v<std::string, value_type> &&
405 !std::is_base_of_v<std::string_view, value_type> &&
406 !std::is_pointer_v<value_type> &&
411 inline std::string
to_string(
const value_type & ref) {
417 std::string
to_string(std::vector<T>
const &list,
const std::string& delim)
419 if ( list.empty() ) {
420 return std::string();
422 bool need_delim =
false;
424 for(
const T& e : list) {
436 bool to_integer(
long long & result,
const std::string& str,
const char limiter=
'\0',
const char *limiter_pos=
nullptr);
437 bool to_integer(
long long & result,
const char * str,
size_t str_len,
const char limiter=
'\0',
const char *limiter_pos=
nullptr);
447 return std::hash<std::string_view>{}(txt);
449 [[nodiscard]]
size_t operator()(std::string_view txt)
const {
450 return std::hash<std::string_view>{}(txt);
452 [[nodiscard]]
size_t operator()(
const std::string& txt)
const {
453 return std::hash<std::string>{}(txt);
458 using StringHashMap = std::unordered_map<std::string, T, string_hash, std::equal_to<>>;
460 using StringHashSet = std::unordered_set<std::string, string_hash, std::equal_to<>>;
466#define jau_format_string_static(...) \
467 jau::format_string(__VA_ARGS__); \
468 static_assert( 0 <= jau::cfmt::checkR(__VA_ARGS__).argCount() );
constexpr bool is_little_endian() noexcept
Evaluates true if platform is running in little endian mode, i.e.
constexpr uint16_t bswap(uint16_t const source) noexcept
std::string to_string(const endian_t v) noexcept
Return std::string representation of the given endian.
constexpr bool is_little_endian(const endian_t byte_order) noexcept
Returns true if given byte_order equals endian::little, otherwise false.
constexpr uint16_t cpu_to_le(uint16_t const h) noexcept
constexpr bool value(const Bool rhs) noexcept
constexpr bool has_toString_v
constexpr bool has_member_of_pointer_v
constexpr bool has_to_string_v
#define PRAGMA_DISABLE_WARNING_PUSH
constexpr std::enable_if_t< sizeof(Dest)==sizeof(Source) &&std::is_pointer_v< Source > &&std::is_pointer_v< Dest >, Dest > pointer_cast(const Source &src) noexcept
A constexpr pointer cast implementation for C++17, inspired by C++20 bit_cast<>(arg).
#define PRAGMA_DISABLE_WARNING_POP
#define PRAGMA_DISABLE_WARNING_FORMAT_NONLITERAL
constexpr T invert_sign(const T x) noexcept
Safely inverts the sign of an arithmetic number w/ branching in O(1)
constexpr nsize_t digits10(const T x, const snsize_t x_sign, const bool sign_is_digit=true) noexcept
Returns the number of decimal digits of the given integral value number using std::log10<T>().
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.
constexpr int sign(const T x) noexcept
Returns the value of the sign function (w/o branching ?) in O(1).
constexpr std::string format_string_v(const std::size_t maxStrLen, const std::string_view format, const Args &...args)
Safely returns a string according to printf() formatting rules and variable number of arguments follo...
std::string & toLowerInPlace(std::string &s) noexcept
std::string trim(const std::string &s) noexcept
trim copy
std::string vformat_string(const char *format, va_list ap)
Returns a string according to vprintf() formatting rules using va_list instead of a variable number o...
void trimInPlace(std::string &s) noexcept
trim in place
std::string to_hexstring(value_type const &v, const bool skipLeading0x=false) noexcept
Produce a lower-case hexadecimal string representation with leading 0x in MSB of the given pointer.
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).
uint64_t from_hexstring(std::string const &s, const bool lsbFirst=!jau::is_little_endian(), const bool checkLeading0x=true) noexcept
Converts a given hexadecimal string representation into a uint64_t value according to hexStringBytes(...
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::unordered_set< std::string, string_hash, std::equal_to<> > StringHashSet
bool to_integer(long long &result, const std::string &str, const char limiter='\0', const char *limiter_pos=nullptr)
std::string bytesHexString(const void *data, const nsize_t length, const bool lsbFirst, const bool lowerCase=true, const bool skipLeading0x=false) noexcept
Produce a hexadecimal string representation of the given byte values.
constexpr bool check2(const std::string_view fmt) noexcept
Strict type validation of arguments against the format string.
std::unordered_map< std::string, T, string_hash, std::equal_to<> > StringHashMap
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 format_string(const char *format,...)
Returns a string according to printf() formatting rules and variable number of arguments following th...
bool is_ascii_code(int c) noexcept
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_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.
C++20: Heterogeneous Lookup in (Un)ordered Containers.
size_t operator()(const std::string &txt) const
size_t operator()(const char *txt) const
size_t operator()(std::string_view txt) const
static std::string to_string(const bool withSize=true) noexcept