2024-04-25 10:38:13 +08:00
|
|
|
#pragma once
|
2025-07-25 09:35:26 +08:00
|
|
|
#include <string>
|
|
|
|
#include <string_view>
|
2024-04-25 10:38:13 +08:00
|
|
|
#include <cstdarg>
|
2024-05-21 10:24:05 +08:00
|
|
|
#include <functional>
|
|
|
|
#include <vector>
|
2025-07-25 09:35:26 +08:00
|
|
|
#include <expected>
|
2024-04-25 10:38:13 +08:00
|
|
|
|
2025-06-20 23:38:34 +08:00
|
|
|
namespace yycc::string::op {
|
2024-06-10 17:55:23 +08:00
|
|
|
|
2025-07-25 09:35:26 +08:00
|
|
|
enum class FormatError {
|
2025-07-25 10:49:07 +08:00
|
|
|
NullFormat, ///< Given format string is nullptr.
|
|
|
|
NoDesiredSize, ///< Fail to fetch the expected size of result.
|
2025-07-25 09:35:26 +08:00
|
|
|
BadWrittenSize, ///< The written size is different with expected size.
|
|
|
|
};
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
using FormatResult = std::expected<T, FormatError>;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Perform an UTF8 string formatting operation.
|
|
|
|
* @param[in] format The format string.
|
|
|
|
* @param[in] ... Argument list of format string.
|
|
|
|
* @return The formatted result, or the fail reason.
|
|
|
|
*/
|
|
|
|
FormatResult<std::u8string> printf(const char8_t* format, ...);
|
|
|
|
/**
|
|
|
|
* @brief Perform an UTF8 string formatting operation.
|
|
|
|
* @param[in] format The format string.
|
|
|
|
* @param[in] argptr Argument list of format string.
|
|
|
|
* @return The formatted result, or the fail reason.
|
|
|
|
*/
|
|
|
|
FormatResult<std::u8string> vprintf(const char8_t* format, va_list argptr);
|
|
|
|
/**
|
|
|
|
* @brief Perform an ordinary string formatting operation.
|
|
|
|
* @param[in] format The format string.
|
|
|
|
* @param[in] ... Argument list of format string.
|
|
|
|
* @return The formatted result, or the fail reason.
|
|
|
|
*/
|
|
|
|
FormatResult<std::string> printf(const char* format, ...);
|
|
|
|
/**
|
|
|
|
* @brief Perform an ordinary string formatting operation.
|
|
|
|
* @param[in] format The format string.
|
|
|
|
* @param[in] argptr Argument list of format string.
|
|
|
|
* @return The formatted result, or the fail reason.
|
|
|
|
*/
|
|
|
|
FormatResult<std::string> vprintf(const char* format, va_list argptr);
|
2024-04-25 10:38:13 +08:00
|
|
|
|
2025-07-25 09:35:26 +08:00
|
|
|
/**
|
2024-07-24 15:03:31 +08:00
|
|
|
* @brief Modify given string with all occurrences of substring \e old replaced by \e new.
|
|
|
|
* @param[in,out] strl The string for replacing
|
|
|
|
* @param[in] _from_strl The \e old string.
|
|
|
|
* @param[in] _to_strl The \e new string.
|
|
|
|
*/
|
2025-07-25 09:35:26 +08:00
|
|
|
void replace(std::u8string& strl, const std::u8string_view& _from_strl, const std::u8string_view& _to_strl);
|
|
|
|
/**
|
2024-07-24 15:03:31 +08:00
|
|
|
* @brief Return a copy with all occurrences of substring \e old replaced by \e new.
|
|
|
|
* @param[in] _strl The string for replacing
|
|
|
|
* @param[in] _from_strl The \e old string.
|
|
|
|
* @param[in] _to_strl The \e new string.
|
|
|
|
* @return The result of replacement.
|
|
|
|
*/
|
2025-07-25 09:35:26 +08:00
|
|
|
std::u8string replace(const std::u8string_view& _strl, const std::u8string_view& _from_strl, const std::u8string_view& _to_strl);
|
2024-06-10 17:55:23 +08:00
|
|
|
|
2025-07-25 09:35:26 +08:00
|
|
|
/**
|
2024-07-24 15:03:31 +08:00
|
|
|
* @brief The data provider of general join function.
|
|
|
|
* @details
|
|
|
|
* For programmer using lambda to implement this function pointer:
|
|
|
|
* \li During calling, implementation should assign the reference of string view passed in argument
|
|
|
|
* to the string which need to be joined.
|
|
|
|
* \li Function return true to continue joining. otherwise return false to stop joining.
|
|
|
|
* The argument content assigned in the calling returning false is not included in join process.
|
2024-05-21 10:24:05 +08:00
|
|
|
*/
|
2025-07-25 09:35:26 +08:00
|
|
|
using JoinDataProvider = std::function<bool(std::u8string_view&)>;
|
|
|
|
/**
|
2024-07-24 15:03:31 +08:00
|
|
|
* @brief Universal join function.
|
|
|
|
* @details
|
|
|
|
* This function use function pointer as a general data provider interface,
|
|
|
|
* so this function suit for all types container.
|
|
|
|
* You can use this universal join function for any custom container by
|
|
|
|
* using C++ lambda syntax to create a code block adapted to this function pointer.
|
|
|
|
* @param[in] fct_data The function pointer in JoinDataProvider type prividing the data to be joined.
|
2025-06-22 17:14:49 +08:00
|
|
|
* @param[in] delimiter The delimiter used for joining.
|
2024-07-24 15:03:31 +08:00
|
|
|
* @return The result string of joining.
|
2024-05-21 10:24:05 +08:00
|
|
|
*/
|
2025-07-25 09:35:26 +08:00
|
|
|
std::u8string join(JoinDataProvider fct_data, const std::u8string_view& delimiter);
|
|
|
|
/**
|
2024-08-26 11:58:20 +08:00
|
|
|
* @brief Specialized join function for standard library container.
|
|
|
|
* @tparam InputIt
|
|
|
|
* Must meet the requirements of LegacyInputIterator.
|
2025-07-25 09:35:26 +08:00
|
|
|
* It also can be dereferenced and then implicitly converted to std::u8string_view.
|
2024-08-26 11:58:20 +08:00
|
|
|
* @param[in] first The beginning of the range of elements to join.
|
|
|
|
* @param[in] last The terminal of the range of elements to join (exclusive).
|
2025-06-22 17:14:49 +08:00
|
|
|
* @param[in] delimiter The delimiter used for joining.
|
2024-07-24 15:03:31 +08:00
|
|
|
* @return The result string of joining.
|
2024-05-21 10:24:05 +08:00
|
|
|
*/
|
2025-07-25 09:35:26 +08:00
|
|
|
template<class InputIt>
|
|
|
|
std::u8string join(InputIt first, InputIt last, const std::u8string_view& delimiter) {
|
|
|
|
return join(
|
|
|
|
[&first, &last](std::u8string_view& view) -> bool {
|
|
|
|
// if we reach tail, return false to stop join process
|
|
|
|
if (first == last) return false;
|
|
|
|
// otherwise fetch data, inc iterator and return.
|
|
|
|
view = *first;
|
|
|
|
++first;
|
|
|
|
return true;
|
|
|
|
},
|
|
|
|
delimiter);
|
|
|
|
}
|
2024-04-26 15:37:28 +08:00
|
|
|
|
2025-07-25 09:35:26 +08:00
|
|
|
/**
|
2024-07-24 15:03:31 +08:00
|
|
|
* @brief Convert given string to lowercase.
|
|
|
|
* @param[in,out] strl The string to be lowercase.
|
|
|
|
*/
|
2025-07-25 09:35:26 +08:00
|
|
|
void lower(std::u8string& strl);
|
|
|
|
/**
|
2024-08-26 11:58:20 +08:00
|
|
|
* @brief Return a copy of the string converted to lowercase.
|
|
|
|
* @param[in] strl The string to be lowercase.
|
|
|
|
* @return The copy of the string converted to lowercase.
|
2024-07-24 15:03:31 +08:00
|
|
|
*/
|
2025-07-25 09:35:26 +08:00
|
|
|
std::u8string to_lower(const std::u8string_view& strl);
|
|
|
|
/**
|
2024-07-24 15:03:31 +08:00
|
|
|
* @brief Convert given string to uppercase.
|
|
|
|
* @param[in,out] strl The string to be uppercase.
|
|
|
|
*/
|
2025-07-25 09:35:26 +08:00
|
|
|
void upper(std::u8string& strl);
|
|
|
|
/**
|
2024-08-26 11:58:20 +08:00
|
|
|
* @brief Return a copy of the string converted to uppercase.
|
|
|
|
* @param[in] strl The string to be uppercase.
|
|
|
|
* @return The copy of the string converted to uppercase.
|
|
|
|
*/
|
2025-07-25 09:35:26 +08:00
|
|
|
std::u8string to_upper(const std::u8string_view& strl);
|
|
|
|
|
|
|
|
// TODO:
|
|
|
|
// Add strip, lstrip and rstrip functions.
|
2024-05-21 10:24:05 +08:00
|
|
|
|
2025-06-22 17:14:49 +08:00
|
|
|
/**
|
|
|
|
* @brief Split given string with specified delimiter as string view.
|
|
|
|
* @param[in] strl The string need to be splitting.
|
|
|
|
* @param[in] _delimiter The delimiter for splitting.
|
|
|
|
* @return
|
|
|
|
* The split result with string view format.
|
|
|
|
* This will not produce any copy of original string.
|
|
|
|
* \par
|
|
|
|
* If given string or delimiter are empty,
|
|
|
|
* the result container will only contain 1 entry which is equal to given string.
|
2025-07-25 09:35:26 +08:00
|
|
|
* @see Split(const std::u8string_view&, const char8_t*)
|
2025-06-22 17:14:49 +08:00
|
|
|
*/
|
2025-07-25 09:35:26 +08:00
|
|
|
std::vector<std::u8string_view> split(const std::u8string_view& strl, const std::u8string_view& _delimiter);
|
|
|
|
/**
|
2025-06-22 17:14:49 +08:00
|
|
|
* @brief Split given string with specified delimiter.
|
2024-07-24 15:03:31 +08:00
|
|
|
* @param[in] strl The string need to be splitting.
|
2025-06-22 17:14:49 +08:00
|
|
|
* @param[in] _delimiter The delimiter for splitting.
|
2024-07-24 15:03:31 +08:00
|
|
|
* @return
|
|
|
|
* The split result.
|
|
|
|
* \par
|
2025-06-22 17:14:49 +08:00
|
|
|
* If given string or delimiter are empty,
|
2024-07-24 15:03:31 +08:00
|
|
|
* the result container will only contain 1 entry which is equal to given string.
|
2024-05-21 10:24:05 +08:00
|
|
|
*/
|
2025-07-25 09:35:26 +08:00
|
|
|
std::vector<std::u8string> split_owned(const std::u8string_view& strl, const std::u8string_view& _delimiter);
|
2024-06-29 17:39:13 +08:00
|
|
|
|
2025-07-25 09:35:26 +08:00
|
|
|
// TODO:
|
|
|
|
// Add lazy_split(const std::u8string_view& strl, const std::u8string_view& _delimiter);
|
|
|
|
// Once we add it, we need redirect all split function into it.
|
2025-06-20 23:38:34 +08:00
|
|
|
|
2025-07-25 09:35:26 +08:00
|
|
|
} // namespace yycc::string::op
|