17#ifndef __STDC_WANT_LIB_EXT1__
18# define __STDC_WANT_LIB_EXT1__ 1
25# if __has_include(<version>)
28#elif defined(_MSC_VER) && \
29 ((defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L))
44#ifdef __cpp_lib_string_view
45# include <string_view>
50#if defined(_MSC_VER) && _MSC_VER >= 1600
51# define UTIL_STRFUNC_STRCASE_CMP(l, r) _stricmp(l, r)
52# define UTIL_STRFUNC_STRNCASE_CMP(l, r, s) _strnicmp(l, r, s)
53# define UTIL_STRFUNC_STRCMP(l, r) strcmp(l, r)
54# define UTIL_STRFUNC_STRNCMP(l, r, s) strncmp(l, r, s)
56# define UTIL_STRFUNC_STRCASE_CMP(l, r) strcasecmp(l, r)
57# define UTIL_STRFUNC_STRNCASE_CMP(l, r, s) strncasecmp(l, r, s)
58# define UTIL_STRFUNC_STRCMP(l, r) strcmp(l, r)
59# define UTIL_STRFUNC_STRNCMP(l, r, s) strncmp(l, r, s)
62#if (defined(_MSC_VER) && _MSC_VER >= 1600) || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || \
63 defined(__STDC_LIB_EXT1__)
64# define UTIL_STRFUNC_SSCANF(...) sscanf_s(__VA_ARGS__)
67# define UTIL_STRFUNC_VSNPRINTF(buffer, bufsz, fmt, arg) \
68 vsnprintf_s(buffer, static_cast<size_t>(bufsz), _TRUNCATE, fmt, arg)
69# define UTIL_STRFUNC_SNPRINTF(buffer, bufsz, ...) sprintf_s(buffer, static_cast<size_t>(bufsz), __VA_ARGS__)
71# define UTIL_STRFUNC_VSNPRINTF(buffer, bufsz, fmt, arg) vsnprintf_s(buffer, static_cast<rsize_t>(bufsz), fmt, arg)
72# define UTIL_STRFUNC_SNPRINTF(buffer, bufsz, fmt, args...) \
73 snprintf_s(buffer, static_cast<rsize_t>(bufsz), fmt, ##args)
76# define UTIL_STRFUNC_C11_SUPPORT 1
78# define UTIL_STRFUNC_SSCANF(...) sscanf(__VA_ARGS__)
79# define UTIL_STRFUNC_SNPRINTF(buffer, bufsz, fmt, args...) snprintf(buffer, static_cast<size_t>(bufsz), fmt, ##args)
80# define UTIL_STRFUNC_VSNPRINTF(buffer, bufsz, fmt, arg) vsnprintf(buffer, static_cast<size_t>(bufsz), fmt, arg)
91template <
class TCH =
char>
93 if (c >=
'A' && c <=
'Z') {
94 return static_cast<TCH
>(c +
static_cast<TCH
>(
'a' -
'A'));
106template <
class TCH =
char>
108 if (c >=
'a' && c <=
'z') {
109 return static_cast<TCH
>(c -
'a' +
'A');
122 return ' ' == c ||
'\t' == c ||
'\r' == c ||
'\n' == c;
135std::pair<const TCH *, size_t>
trim(
const TCH *str_begin,
size_t sz,
bool trim_left =
true,
bool trim_right =
true) {
137 const TCH *str_end = str_begin;
138 while (str_end && *str_end) {
142 sz =
static_cast<size_t>(str_end - str_begin);
145 if (trim_left && str_begin) {
146 while (*str_begin && sz > 0) {
156 size_t sub_str_sz = sz;
157 if (trim_right && str_begin) {
158 while (sub_str_sz > 0) {
159 if (
is_space(str_begin[sub_str_sz - 1])) {
167 return std::make_pair(str_begin, sub_str_sz);
135std::pair<const TCH *, size_t>
trim(
const TCH *str_begin,
size_t sz,
bool trim_left =
true,
bool trim_right =
true) {
…}
175template <
class TCH,
class TCHE>
177 TCH *end =
reinterpret_cast<TCH *
>(end_any);
178 if (
nullptr == begin) {
182 if (
nullptr == end) {
195 while (begin < end) {
204 reverse<TCH, TCH *>(begin,
reinterpret_cast<TCH *
>(
static_cast<intptr_t
>(end_any)));
208inline void reverse(TCH *begin, std::nullptr_t) {
209 reverse<TCH, TCH *>(begin,
static_cast<TCH *
>(
nullptr));
224 while (ret < strsz && in > 0) {
225 str[ret] =
static_cast<char>((in % 10) +
'0');
231 if (in > 0 && ret >= strsz) {
247 size_t ret =
int2str_unsigned(str + 1, strsz - 1,
static_cast<typename std::make_unsigned<T>::type
>(-in));
254 return int2str_unsigned(str, strsz,
static_cast<typename std::make_unsigned<T>::type
>(in));
276inline size_t int2str(
char *str,
size_t strsz,
const T &in) {
276inline size_t int2str(
char *str,
size_t strsz,
const T &in) {
…}
291template <
class T,
class TCHAR>
292const TCHAR *
str2int(T &out,
const TCHAR *str,
size_t strsz = 0) {
293 out =
static_cast<T
>(0);
294 if (
nullptr == str || !(*str)) {
301 bool is_negative =
false;
302 while ((0 == strsz || cur < strsz) && (str[cur] && str[cur] ==
'-')) {
303 is_negative = !is_negative;
307 while ((0 == strsz || cur < strsz) && (str[cur] &&
is_space(str[cur]))) {
315 if ((0 == strsz || cur + 1 < strsz) &&
'0' == str[cur] &&
'x' ==
tolower(str[cur + 1])) {
316 for (cur += 2; (0 == strsz || cur < strsz) && str[cur]; ++cur) {
318 if (c >=
'0' && c <=
'9') {
319 out =
static_cast<T
>(out << 4);
320 out =
static_cast<T
>(out +
static_cast<T
>(c -
static_cast<char>(
'0')));
321 }
else if (c >=
'a' && c <=
'f') {
322 out =
static_cast<T
>(out << 4);
323 out =
static_cast<T
>(out +
static_cast<T
>(c -
static_cast<char>(
'a') + 10));
328 }
else if ((0 == strsz || cur < strsz) &&
'\\' == str[cur]) {
329 for (++cur; (0 == strsz || cur < strsz) && (str[cur] >=
'0' && str[cur] <
'8'); ++cur) {
330 out =
static_cast<T
>(out << 3);
331 out =
static_cast<T
>(out +
static_cast<T
>(str[cur] -
static_cast<char>(
'0')));
334 for (; (0 == strsz || cur < strsz) && (str[cur] >=
'0' && str[cur] <=
'9'); ++cur) {
335 out =
static_cast<T
>(out * 10);
336 out =
static_cast<T
>(out +
static_cast<T
>(str[cur] -
static_cast<char>(
'0')));
341 out =
static_cast<T
>((~out) + 1);
292const TCHAR *
str2int(T &out,
const TCHAR *str,
size_t strsz = 0) {
…}
347template <
class T,
class TCHAR>
348const TCHAR *
str2int(T &out,
const std::basic_string<TCHAR> &str) {
349 return str2int(out, str.c_str(), str.size());
348const TCHAR *
str2int(T &out,
const std::basic_string<TCHAR> &str) {
…}
352#ifdef __cpp_lib_string_view
353template <
class T,
class TCHAR>
354const TCHAR *
str2int(T &out, std::basic_string_view<TCHAR> str) {
355 return str2int(out, str.data(), str.size());
364template <
class T,
class TINPUT>
367 str2int(ret, std::forward<TINPUT>(input));
377template <
class TStr,
class TCh>
378void hex(TStr *out, TCh c,
bool upper_case =
false) {
379 out[0] =
static_cast<TStr
>((c >> 4) & 0x0F);
380 out[1] =
static_cast<TStr
>(c & 0x0F);
382 for (
int i = 0; i < 2; ++i) {
386 base =
static_cast<TStr
>(
'A');
388 base =
static_cast<TStr
>(
'a');
390 base =
static_cast<TStr
>(base - 10);
391 out[i] =
static_cast<TStr
>(out[i] + base);
393 out[i] =
static_cast<TStr
>(out[i] +
static_cast<TStr
>(
'0'));
378void hex(TStr *out, TCh c,
bool upper_case =
false) {
…}
404template <
class TStr,
class TCh>
405void oct(TStr *out, TCh c) {
406 out[0] =
static_cast<TStr
>(((c >> 6) & 0x07) +
'0');
407 out[1] =
static_cast<TStr
>(((c >> 3) & 0x07) +
'0');
408 out[2] =
static_cast<TStr
>((c & 0x07) +
'0');
420 const TCh *cs =
reinterpret_cast<const TCh *
>(src);
422 for (i = 0, j = 0; i < ss && j < os; ++i) {
423 if (cs[i] >= 32 && cs[i] < 127) {
426 }
else if (j + 4 <= os) {
444template <
class Elem,
class Traits>
445void serialization(
const void *src,
size_t ss, std::basic_ostream<Elem, Traits> &out) {
446 const Elem *cs =
reinterpret_cast<const Elem *
>(src);
448 for (i = 0; i < ss; ++i) {
449 if (cs[i] >= 32 && cs[i] < 127) {
452 Elem tmp[4] = {
'\\', 0, 0, 0};
445void serialization(
const void *src,
size_t ss, std::basic_ostream<Elem, Traits> &out) {
…}
467void dumphex(
const void *src,
size_t ss, TCh *out,
bool upper_case =
false) {
468 const unsigned char *cs =
reinterpret_cast<const unsigned char *
>(src);
470 for (i = 0; i < ss; ++i) {
471 hex<TCh, unsigned char>(&out[i << 1], cs[i], upper_case);
467void dumphex(
const void *src,
size_t ss, TCh *out,
bool upper_case =
false) {
…}
482template <
class Elem,
class Traits>
483void dumphex(
const void *src,
size_t ss, std::basic_ostream<Elem, Traits> &out,
bool upper_case =
false) {
484 const unsigned char *cs =
reinterpret_cast<const unsigned char *
>(src);
487 for (i = 0; i < ss; ++i) {
488 hex<Elem, unsigned char>(tmp, cs[i], upper_case);
483void dumphex(
const void *src,
size_t ss, std::basic_ostream<Elem, Traits> &out,
bool upper_case =
false) {
…}
LIBCOPP_COPP_API_HEAD_ONLY void swap(LIBCOPP_COPP_NAMESPACE_ID::memory::strong_rc_ptr< T > &a, LIBCOPP_COPP_NAMESPACE_ID::memory::strong_rc_ptr< T > &b) noexcept
Support std::swap for strong_rc_ptr.
size_t int2str(char *str, size_t strsz, const T &in)
整数转字符串
size_t int2str_unsigned(char *str, size_t strsz, T in)
bool is_space(const TCH &c)
是否是空白字符
void hex(TStr *out, TCh c, bool upper_case=false)
字符转十六进制表示
void dumphex(const void *src, size_t ss, TCh *out, bool upper_case=false)
字符转16进制表示
void oct(TStr *out, TCh c)
字符转8进制表示
std::pair< const TCH *, size_t > trim(const TCH *str_begin, size_t sz, bool trim_left=true, bool trim_right=true)
移除两边或一边的空白字符
T to_int(TINPUT &&input)
字符串转整数
const TCHAR * str2int(T &out, const TCHAR *str, size_t strsz=0)
字符串转整数
void reverse(TCH *begin, TCHE end_any)
翻转字符串
size_t int2str_signed(char *str, size_t strsz, T in)
void serialization(const void *src, size_t ss, TCh *out, size_t &os)
字符转8进制表示
typename std::make_unsigned< T >::type value_type_u
static size_t call(char *str, size_t strsz, value_type_u in)
static size_t call(char *str, size_t strsz, value_type_s in)