149 lines
6.3 KiB
Plaintext
149 lines
6.3 KiB
Plaintext
namespace YYCC::StringHelper {
|
|
/**
|
|
|
|
\page string_helper String Helper
|
|
|
|
\section string_helper__printf Printf VPrintf
|
|
|
|
YYCC::StringHelper provides 4 functions for formatting string.
|
|
These functions are mainly provided to programmer who can not use C++ 20 \c std::format feature.
|
|
|
|
\code
|
|
bool Printf(yycc_u8string&, const yycc_char8_t*, ...);
|
|
bool VPrintf(yycc_u8string&, const yycc_char8_t*, va_list argptr);
|
|
yycc_u8string Printf(const yycc_char8_t*, ...);
|
|
yycc_u8string VPrintf(const yycc_char8_t*, va_list argptr);
|
|
\endcode
|
|
|
|
#Printf and #VPrintf is similar to \c std::sprintf and \c std::vsprintf.
|
|
#Printf accepts UTF8 format string and variadic arguments specifying data to print.
|
|
This is commonly used by programmer.
|
|
However, #VPrintf also do the same work but its second argument is \c va_list,
|
|
the representation of variadic arguments.
|
|
It is mostly used by other function which has variadic arguments.
|
|
|
|
The only difference between these function and standard library functions is
|
|
that you don't need to worry about whether the space of given buffer is enough,
|
|
because these functions help you to calculate this internally.
|
|
|
|
There is the same design like we introduced in \ref encoding_helper.
|
|
There are 2 overloads for #Printf and #VPrintf respectively.
|
|
First overload return bool value and require a string container as argument for storing result.
|
|
The second overload return result string directly.
|
|
As you expected, first overload will return false if fail to format string (this is barely happened).
|
|
and second overload will return empty string when formatter failed.
|
|
|
|
\section string_helper__replace Replace
|
|
|
|
YYCC::StringHelper provide 2 functions for programmer do string replacement:
|
|
|
|
\code
|
|
void Replace(yycc_u8string&, const yycc_u8string_view&, const yycc_u8string_view&);
|
|
yycc_u8string Replace(const yycc_u8string_view&, const yycc_u8string_view&, const yycc_u8string_view&);
|
|
\endcode
|
|
|
|
The first overload will do replacement in given string container directly.
|
|
The second overload will produce a copy of original string and do replacement on the copied string.
|
|
|
|
#Replace has special treatments for following scenarios:
|
|
|
|
\li If given string is empty, the return value will be empty.
|
|
\li If the character sequence to be replaced is empty string, no replacement will happen.
|
|
\li If the character sequence will be replaced into string is or empty, it will simply delete found character sequence from given string.
|
|
|
|
\section string_helper__join Join
|
|
|
|
YYCC::StringHelper provide an universal way for joining string and various specialized join functions.
|
|
|
|
\subsection string_helper__join__universal Universal Join Function
|
|
|
|
Because C++ list types are various.
|
|
There is no unique and convenient way to create an universal join function.
|
|
So we create #JoinDataProvider to describe join context.
|
|
|
|
Before using universal join function,
|
|
you should setup #JoinDataProvider first, the context of join function.
|
|
It actually is an \c std::function object which can be easily fetched by C++ lambda syntax.
|
|
This function pointer accept a reference to \c yycc_u8string_view,
|
|
programmer should set it to the string to be joined when at each calling.
|
|
And this function pointer return a bool value to indicate the end of join.
|
|
You can simply return \c false to terminate join process.
|
|
The argument you assigned to argument will not be taken into join process when you return false.
|
|
|
|
Then, you can pass the created #JoinDataProvider object to #Join function.
|
|
And specify delimiter at the same time.
|
|
Then you can get the final joined string.
|
|
There is an example:
|
|
|
|
\code
|
|
std::vector<yycc_u8string> data {
|
|
YYCC_U8(""), YYCC_U8("1"), YYCC_U8("2"), YYCC_U8("")
|
|
};
|
|
auto iter = data.cbegin();
|
|
auto stop = data.cend();
|
|
auto joined_string = YYCC::StringHelper::Join(
|
|
[&iter, &stop](yycc_u8string_view& view) -> bool {
|
|
if (iter == stop) return false;
|
|
view = *iter;
|
|
++iter;
|
|
return true;
|
|
},
|
|
delimiter
|
|
);
|
|
\endcode
|
|
|
|
\subsection string_helper__join__specialized Specialized Join Function
|
|
|
|
Despite universal join function,
|
|
YYCC::StringHelper also provide a specialized join functions for standard library container.
|
|
For example, the code written above can be written in following code by using this specialized overload.
|
|
The first two argument is just the begin and end iterator.
|
|
However, you must make sure that we can dereference it and then implicitly convert it to yycc_u8string_view.
|
|
Otherwise this overload will throw template error.
|
|
|
|
\code
|
|
std::vector<yycc_u8string> data {
|
|
YYCC_U8(""), YYCC_U8("1"), YYCC_U8("2"), YYCC_U8("")
|
|
};
|
|
auto joined_string = YYCC::StringHelper::Join(data.begin(), data.end(), delimiter);
|
|
\endcode
|
|
|
|
\section string_helper__lower_upper Lower Upper
|
|
|
|
String helper provides Python-like string lower and upper function.
|
|
Both lower and upper function have 2 overloads:
|
|
|
|
\code
|
|
yycc_u8string Lower(const yycc_u8string_view&);
|
|
void Lower(yycc_u8string&);
|
|
\endcode
|
|
|
|
First overload accepts a string view as argument and return a \b copy whose content are all the lower case of original string.
|
|
Second overload accepts a mutable string container as argument and will make all characters stored in it become their lower case.
|
|
You can choose on of them for your flavor and requirements.
|
|
Upper also has similar 2 overloads.
|
|
|
|
\section string_helper__split Split
|
|
|
|
String helper provides Python-like string split function.
|
|
It has 2 types for you:
|
|
|
|
\code
|
|
std::vector<yycc_u8string> Split(const yycc_u8string_view&, const yycc_u8string_view&);
|
|
std::vector<yycc_u8string_view> SplitView(const yycc_u8string_view&, const yycc_u8string_view&);
|
|
\endcode
|
|
|
|
All these overloads take a string view as the first argument representing the string need to be split.
|
|
The second argument is a string view representing the delimiter for splitting.
|
|
The only difference between these 2 split function are overt according to their names.
|
|
The first split function will return a list of copied string as its split result.
|
|
The second split function will return a list of string view as its split result,
|
|
and it will keep valid as long as the life time of your given string view argument.
|
|
It also means that the last overload will cost less memory if you don't need the copy of original string.
|
|
|
|
If the source string (the string need to be split) is empty, or the delimiter is empty,
|
|
the result will only has 1 item and this item is source string itself.
|
|
There is no way that these methods return an empty list, except the code is buggy.
|
|
|
|
*/
|
|
} |