diff --git a/src/yycc/string/op.cpp b/src/yycc/string/op.cpp index 79af3ef..9b2525d 100644 --- a/src/yycc/string/op.cpp +++ b/src/yycc/string/op.cpp @@ -1,7 +1,6 @@ #include "op.hpp" #include #include -#include #include #include #include @@ -113,19 +112,15 @@ namespace yycc::string::op { std::u8string join(JoinDataProvider fct_data, const std::u8string_view& delimiter) { std::u8string ret; bool is_first = true; - std::u8string_view element; // fetch element - while (fct_data(element)) { - // insert delimiter + while (auto item = fct_data()) { + // append delimiter if it is not first if (is_first) is_first = false; - else { - // append delimiter. - ret.append(delimiter); - } + else ret.append(delimiter); - // insert element if it is not empty - if (!element.empty()) ret.append(element); + // append element + ret.append(item.value()); } return ret; diff --git a/src/yycc/string/op.hpp b/src/yycc/string/op.hpp index e9a9a3d..3e6e8dd 100644 --- a/src/yycc/string/op.hpp +++ b/src/yycc/string/op.hpp @@ -6,6 +6,7 @@ #include #include #include +#include namespace yycc::string::op { @@ -67,13 +68,12 @@ namespace yycc::string::op { /** * @brief The data provider of general join function. * @details + * This data provider is more like Rust iterator. * 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. + * \li Return \c std::nullopt if there is no more data for join. + * \li Return \c std::u8string_view for the data of join. */ - using JoinDataProvider = std::function; + using JoinDataProvider = std::function()>; /** * @brief Universal join function. * @details @@ -96,16 +96,15 @@ namespace yycc::string::op { * @param[in] delimiter The delimiter used for joining. * @return The result string of joining. */ - template + template + requires std::is_constructible_v> 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; + [&first, &last]() -> std::optional { + // if we reach tail, return std::nullopt to stop join process + if (first == last) return std::nullopt; // otherwise fetch data, inc iterator and return. - view = *first; - ++first; - return true; + return std::u8string_view(*(first++)); }, delimiter); }