39#include <initializer_list>
64 template <
class CharT,
class Traits,
class Allocator>
65 std::basic_string<CharT, Traits, Allocator>
66 ltrim(std::basic_string<CharT, Traits, Allocator> str) {
67 auto it = std::find_if(str.begin(),
69 [](
unsigned char uc) ->
bool { return !isspace(uc); });
70 str.erase(str.begin(), it);
82 template <
class CharT,
class Traits,
class Allocator>
83 std::basic_string<CharT, Traits, Allocator>
84 rtrim(std::basic_string<CharT, Traits, Allocator> str) {
85 auto it = std::find_if(str.rbegin(),
87 [](
unsigned char uc) ->
bool { return !isspace(uc); });
88 str.erase(it.base(), str.end());
100 template <
class CharT,
class Traits,
class Allocator>
101 std::basic_string<CharT, Traits, Allocator>
102 trim(std::basic_string<CharT, Traits, Allocator> str) {
103 auto front = std::find_if(str.begin(),
105 [](
unsigned char uc) ->
bool { return !isspace(uc); });
106 if (front == str.end()) {
110 auto back = std::find_if(str.rbegin(),
112 [](
unsigned char uc) ->
bool { return !isspace(uc); });
113 str.erase(back.base(), str.end());
114 str.erase(str.begin(), front);
127 template <
class CharT,
class Traits,
class Allocator>
128 std::basic_string<CharT, Traits, Allocator>
129 ltrim(std::basic_string<CharT, Traits, Allocator> str,
130 const std::basic_string<CharT, Traits, Allocator> &chars) {
132 = std::find_if(str.begin(), str.end(), [&chars](
unsigned char ch) {
133 return chars.find(ch)
134 == std::basic_string<CharT, Traits, Allocator>::npos;
136 str.erase(str.begin(), it);
149 template <
class CharT,
class Traits,
class Allocator>
150 std::basic_string<CharT, Traits, Allocator>
151 rtrim(std::basic_string<CharT, Traits, Allocator> str,
152 const std::basic_string<CharT, Traits, Allocator> &chars) {
153 auto it = std::find_if(
154 str.rbegin(), str.rend(), [&chars](
unsigned char ch) {
155 return chars.find(ch)
156 == std::basic_string<CharT, Traits, Allocator>::npos;
158 str.erase(it.base(), str.end());
171 template <
class CharT,
class Traits,
class Allocator>
172 std::basic_string<CharT, Traits, Allocator>
173 trim(std::basic_string<CharT, Traits, Allocator> str,
174 const std::basic_string<CharT, Traits, Allocator> &chars) {
176 = std::find_if(str.begin(), str.end(), [&chars](
unsigned char ch) {
177 return chars.find(ch)
178 == std::basic_string<CharT, Traits, Allocator>::npos;
180 if (front == str.end()) {
184 auto back = std::find_if(
185 str.rbegin(), str.rend(), [&chars](
unsigned char ch) {
186 return chars.find(ch)
187 == std::basic_string<CharT, Traits, Allocator>::npos;
189 str.erase(back.base(), str.end());
190 str.erase(str.begin(), front);
203 template <
class CharT,
class Traits,
class Allocator>
204 std::basic_string<CharT, Traits, Allocator>
205 upper(std::basic_string<CharT, Traits, Allocator> str,
206 const std::locale &loc = std::locale{}) {
207 for (
auto &ch : str) ch = std::toupper(ch, loc);
220 template <
class CharT,
class Traits,
class Allocator>
221 std::basic_string<CharT, Traits, Allocator>
222 lower(std::basic_string<CharT, Traits, Allocator> str,
223 const std::locale &loc = std::locale{}) {
224 for (
auto &ch : str) ch = std::tolower(ch, loc);
237 template <
class CharT,
class Traits,
class Allocator>
238 std::basic_string<CharT, Traits, Allocator>
239 title(std::basic_string<CharT, Traits, Allocator> str,
240 const std::locale &loc = std::locale{}) {
241 using string_type = std::basic_string<CharT, Traits, Allocator>;
242 if (str.empty())
return string_type{};
243 str[0] = std::toupper(str[0], loc);
244 for (
size_t i = 1; i < str.size(); ++i) {
245 if (std::isspace(str[i - 1], loc))
246 str[i] = std::toupper(str[i], loc);
248 str[i] = std::tolower(str[i], loc);
260 template <
class CharT = char,
261 class Traits = std::char_traits<CharT>,
262 class Allocator = std::allocator<CharT>>
276 friend std::basic_ostream<CharT, Traits> &
277 operator<<(std::basic_ostream<CharT, Traits> &os,
279 return os <<
"BasicPartitionResult(\"" << pr.
left <<
"\", \""
299 template <
class CharT,
class Traits,
class Allocator>
301 partition(
const std::basic_string<CharT, Traits, Allocator> &text,
302 const std::basic_string<CharT, Traits, Allocator> &sep) {
303 using string_type = std::basic_string<CharT, Traits, Allocator>;
304 size_t pos = text.find(sep);
305 if (pos == string_type::npos)
307 text, string_type{}, string_type{}};
309 text.substr(0, pos), sep, text.substr(pos + sep.size())};
322 template <
class CharT,
class Traits,
class Allocator>
323 std::vector<std::basic_string<CharT, Traits, Allocator>>
324 split(
const std::basic_string<CharT, Traits, Allocator> &text,
325 const std::basic_string<CharT, Traits, Allocator> &sep
326 = std::basic_string<CharT, Traits, Allocator>(1, CharT{
' '})) {
327 using string_type = std::basic_string<CharT, Traits, Allocator>;
328 using vector_type = std::vector<string_type>;
330 if (sep.empty())
return {text};
332 while (start <= text.size()) {
333 size_t pos = text.find(sep, start);
334 if (pos == string_type::npos) {
335 result.push_back(text.substr(start));
338 result.push_back(text.substr(start, pos - start));
339 start = pos + sep.size();
356 class Traits = std::char_traits<CharT>,
357 class Allocator = std::allocator<CharT>>
358 std::basic_string<CharT, Traits, Allocator>
join(
const std::vector<T> &vec,
359 const std::basic_string<CharT, Traits, Allocator> &sep
360 = std::basic_string<CharT, Traits, Allocator>{}) {
361 using string_type = std::basic_string<CharT, Traits, Allocator>;
362 if (vec.empty())
return string_type{};
363 std::basic_ostringstream<CharT, Traits> ss;
364 auto it = vec.begin();
366 while (++it != vec.end()) ss << sep << *it;
371 inline std::string
ltrim(
const char *str) {
372 return ltrim(std::string(str));
375 inline std::wstring
ltrim(
const wchar_t *str) {
376 return ltrim(std::wstring(str));
380 inline std::string
rtrim(
const char *str) {
381 return rtrim(std::string(str));
384 inline std::wstring
rtrim(
const wchar_t *str) {
385 return rtrim(std::wstring(str));
389 inline std::string
trim(
const char *str) {
390 return trim(std::string(str));
393 inline std::wstring
trim(
const wchar_t *str) {
394 return trim(std::wstring(str));
398 inline std::string
ltrim(
const char *str,
const std::string &chars) {
399 return ltrim(std::string(str), chars);
402 inline std::wstring
ltrim(
const wchar_t *str,
const std::wstring &chars) {
403 return ltrim(std::wstring(str), chars);
407 inline std::string
rtrim(
const char *str,
const std::string &chars) {
408 return rtrim(std::string(str), chars);
411 inline std::wstring
rtrim(
const wchar_t *str,
const std::wstring &chars) {
412 return rtrim(std::wstring(str), chars);
416 inline std::string
trim(
const char *str,
const std::string &chars) {
417 return trim(std::string(str), chars);
420 inline std::wstring
trim(
const wchar_t *str,
const std::wstring &chars) {
421 return trim(std::wstring(str), chars);
425 inline std::string
ltrim(
const char *str,
const char *chars) {
426 return ltrim(std::string(str), std::string(chars));
429 inline std::wstring
ltrim(
const wchar_t *str,
const wchar_t *chars) {
430 return ltrim(std::wstring(str), std::wstring(chars));
434 inline std::string
rtrim(
const char *str,
const char *chars) {
435 return rtrim(std::string(str), std::string(chars));
438 inline std::wstring
rtrim(
const wchar_t *str,
const wchar_t *chars) {
439 return rtrim(std::wstring(str), std::wstring(chars));
443 inline std::string
trim(
const char *str,
const char *chars) {
444 return trim(std::string(str), std::string(chars));
447 inline std::wstring
trim(
const wchar_t *str,
const wchar_t *chars) {
448 return trim(std::wstring(str), std::wstring(chars));
452 inline std::string
ltrim(
const std::string &str,
const char *chars) {
453 return ltrim(str, std::string(chars));
456 inline std::wstring
ltrim(
const std::wstring &str,
const wchar_t *chars) {
457 return ltrim(str, std::wstring(chars));
461 inline std::string
rtrim(
const std::string &str,
const char *chars) {
462 return rtrim(str, std::string(chars));
465 inline std::wstring
rtrim(
const std::wstring &str,
const wchar_t *chars) {
466 return rtrim(str, std::wstring(chars));
470 inline std::string
trim(
const std::string &str,
const char *chars) {
471 return trim(str, std::string(chars));
474 inline std::wstring
trim(
const std::wstring &str,
const wchar_t *chars) {
475 return trim(str, std::wstring(chars));
480 upper(
const char *str,
const std::locale &loc = std::locale{}) {
481 return upper(std::string(str), loc);
485 upper(
const wchar_t *str,
const std::locale &loc = std::locale{}) {
486 return upper(std::wstring(str), loc);
490 lower(
const char *str,
const std::locale &loc = std::locale{}) {
491 return lower(std::string(str), loc);
495 lower(
const wchar_t *str,
const std::locale &loc = std::locale{}) {
496 return lower(std::wstring(str), loc);
501 title(
const char *str,
const std::locale &loc = std::locale{}) {
502 return title(std::string(str), loc);
506 title(
const wchar_t *str,
const std::locale &loc = std::locale{}) {
507 return title(std::wstring(str), loc);
511 template <
class CharT,
class Traits,
class Allocator>
513 partition(
const std::basic_string<CharT, Traits, Allocator> &text,
516 text, std::basic_string<CharT, Traits, Allocator>(sep));
520 template <
class CharT,
class Traits,
class Allocator>
521 std::vector<std::basic_string<CharT, Traits, Allocator>>
522 split(
const std::basic_string<CharT, Traits, Allocator> &text,
524 return split(text, std::basic_string<CharT, Traits, Allocator>(sep));
528 inline BasicPartitionResult<>
530 return partition(std::string(text), sep);
533 inline BasicPartitionResult<wchar_t>
534 partition(
const wchar_t *text,
const std::wstring &sep) {
535 return partition(std::wstring(text), sep);
539 inline std::vector<std::string>
540 split(
const char *text,
const std::string &sep =
" ") {
541 return split(std::string(text), sep);
544 inline std::vector<std::wstring>
545 split(
const wchar_t *text,
const std::wstring &sep = L
" ") {
546 return split(std::wstring(text), sep);
551 join(
const std::vector<std::string> &items,
const std::string &sep =
"") {
553 for (
const auto &item : items) {
554 if (!result.empty()) result += sep;
561 const std::vector<std::wstring> &items,
const std::wstring &sep = L
"") {
563 for (
const auto &item : items) {
564 if (!result.empty()) result += sep;
573 template <
class CharT,
class Traits>
574 inline void to_stream(
char ch, std::basic_ostream<CharT, Traits> &os) {
581 template <
class CharT,
class Traits>
582 inline void to_stream(
wchar_t wch, std::basic_ostream<CharT, Traits> &os) {
583 os << std::wcout.narrow(wch,
'?');
589 template <
class Traits>
591 to_stream(
wchar_t wch, std::basic_ostream<wchar_t, Traits> &os) {
598 template <
class CharT,
class Traits>
600 to_stream(
const std::string &str, std::basic_ostream<CharT, Traits> &os) {
607 template <
class CharT,
class Traits>
609 to_stream(
const std::wstring &wstr, std::basic_ostream<CharT, Traits> &os) {
610 for (
wchar_t wch : wstr)
to_stream(wch, os);
616 template <
class CharT,
class Traits>
618 to_stream(
const char *str, std::basic_ostream<CharT, Traits> &os) {
619 if (str ==
nullptr)
return;
626 template <
class CharT,
class Traits>
628 to_stream(
const wchar_t *wstr, std::basic_ostream<CharT, Traits> &os) {
629 for (
const wchar_t *p = wstr; p && *p; ++p)
to_stream(*p, os);
632 template <
class CharT,
class Traits, std::
size_t N>
634 to_stream(
char (&arr)[N], std::basic_ostream<CharT, Traits> &os) {
635 to_stream(
static_cast<const char *
>(arr), os);
638 template <
class CharT,
class Traits, std::
size_t N>
640 to_stream(
wchar_t (&arr)[N], std::basic_ostream<CharT, Traits> &os) {
641 to_stream(
static_cast<const wchar_t *
>(arr), os);
644 template <
class CharT,
class Traits,
class T>
645 inline typename std::enable_if<
646 !std::is_same<typename std::decay<T>::type,
char>::value &&
647 !std::is_same<typename std::decay<T>::type,
wchar_t>::value &&
648 !std::is_same<typename std::decay<T>::type,
char *>::value &&
649 !std::is_same<typename std::decay<T>::type,
wchar_t *>::value &&
650 !std::is_same<typename std::decay<T>::type, std::string>::value &&
651 !std::is_same<typename std::decay<T>::type, std::wstring>::value
653 to_stream(T &&value, std::basic_ostream<CharT, Traits> &os) {
654 os << std::forward<T>(value);
663 template <
class... Args>
665 std::ostringstream oss;
666 int _[] = {0, (
to_stream(args, oss), 0)...};
680 template <
class CharT,
class Traits,
class Allocator,
class... Args>
682 std::basic_string<CharT, Traits, Allocator> str, Args &...args) {
683 std::basic_istringstream<CharT, Traits> iss(str);
684 int _[] = {0, (iss >> args, 0)...};
定义 console 库使用的自定义异常类层次结构。
std::vector< std::basic_string< CharT, Traits, Allocator > > split(const std::basic_string< CharT, Traits, Allocator > &text, const std::basic_string< CharT, Traits, Allocator > &sep=std::basic_string< CharT, Traits, Allocator >(1, CharT{' '}))
以分隔符分割字符串(类似 Python 的 split,默认按空格分割)。
Definition strpp.h:324
BasicPartitionResult< wchar_t > WPartitionResult
BasicPartitionResult<wchar_t> 的类型别名。
Definition strpp.h:287
std::basic_string< CharT, Traits, Allocator > title(std::basic_string< CharT, Traits, Allocator > str, const std::locale &loc=std::locale{})
将字符串转换为标题格式(每个单词首字母大写,其余小写)。
Definition strpp.h:239
BasicPartitionResult< char > PartitionResult
BasicPartitionResult<char> 的类型别名。
Definition strpp.h:285
void to_stream(char ch, std::basic_ostream< CharT, Traits > &os)
将 ch 输出到流。
Definition strpp.h:574
std::basic_string< CharT, Traits, Allocator > join(const std::vector< T > &vec, const std::basic_string< CharT, Traits, Allocator > &sep=std::basic_string< CharT, Traits, Allocator >{})
以分隔符连接容器中的字符串元素。
Definition strpp.h:358
std::basic_string< CharT, Traits, Allocator > trim(std::basic_string< CharT, Traits, Allocator > str)
移除字符串两侧的空白字符。
Definition strpp.h:102
BasicPartitionResult< CharT, Traits, Allocator > partition(const std::basic_string< CharT, Traits, Allocator > &text, const std::basic_string< CharT, Traits, Allocator > &sep)
在字符串中查找第一个分隔符,并返回分隔符之前、分隔符本身、分隔符之后的三部分。
Definition strpp.h:301
std::string to_string(Args &&...args)
将任意多个参数转换为字符串并拼接(无分隔符)。
Definition strpp.h:664
std::basic_string< CharT, Traits, Allocator > upper(std::basic_string< CharT, Traits, Allocator > str, const std::locale &loc=std::locale{})
将字符串转换为大写。
Definition strpp.h:205
void from_string(std::basic_string< CharT, Traits, Allocator > str, Args &...args)
将字符串中的值提取到多个参数中,参数类型由调用者指定。
Definition strpp.h:681
std::basic_string< CharT, Traits, Allocator > rtrim(std::basic_string< CharT, Traits, Allocator > str)
移除字符串右侧的空白字符。
Definition strpp.h:84
std::basic_string< CharT, Traits, Allocator > ltrim(std::basic_string< CharT, Traits, Allocator > str)
移除字符串左侧的空白字符(空格、制表符等)。
Definition strpp.h:66
std::basic_string< CharT, Traits, Allocator > lower(std::basic_string< CharT, Traits, Allocator > str, const std::locale &loc=std::locale{})
将字符串转换为小写。
Definition strpp.h:222
字符串分区结果,包含左部分、分隔符、右部分。
Definition strpp.h:263
friend std::basic_ostream< char, std::char_traits< char > > & operator<<(std::basic_ostream< char, std::char_traits< char > > &os, const BasicPartitionResult &pr)
Definition strpp.h:277
string_type right
Definition strpp.h:268
std::basic_string< CharT, Traits, Allocator > string_type
Definition strpp.h:264
string_type middle
Definition strpp.h:267
string_type left
Definition strpp.h:266