feat: finish string helper except Split()
- add string lower upper function in string helper. - add join function in string helper. - add split function in string helper but implementation is not perfect and should be imporved in future.
This commit is contained in:
parent
6ebb457bd1
commit
9c943705de
@ -1,4 +1,5 @@
|
|||||||
#include "StringHelper.hpp"
|
#include "StringHelper.hpp"
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace YYCC::StringHelper {
|
namespace YYCC::StringHelper {
|
||||||
|
|
||||||
@ -64,4 +65,124 @@ namespace YYCC::StringHelper {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Join(JoinDataProvider fct_data, const char* decilmer) {
|
||||||
|
std::string ret;
|
||||||
|
bool is_first = true;
|
||||||
|
const char* element;
|
||||||
|
|
||||||
|
// fetch element
|
||||||
|
while ((element = fct_data()) != nullptr) {
|
||||||
|
// insert decilmer
|
||||||
|
if (is_first) is_first = false;
|
||||||
|
else {
|
||||||
|
// only insert non-nullptr decilmer.
|
||||||
|
if (decilmer != nullptr)
|
||||||
|
ret.append(decilmer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert element
|
||||||
|
ret.append(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Join(const std::vector<std::string>& data, const char* decilmer, bool reversed) {
|
||||||
|
if (reversed) {
|
||||||
|
auto iter = data.crbegin();
|
||||||
|
auto stop = data.crend();
|
||||||
|
return Join([&iter, &stop]() -> const char* {
|
||||||
|
// if we reach tail, return nullptr
|
||||||
|
if (iter == stop) return nullptr;
|
||||||
|
// otherwise fetch data, inc iterator and return.
|
||||||
|
const char* ret = iter->c_str();
|
||||||
|
++iter;
|
||||||
|
return ret;
|
||||||
|
}, decilmer);
|
||||||
|
} else {
|
||||||
|
auto iter = data.cbegin();
|
||||||
|
auto stop = data.cend();
|
||||||
|
return Join([&iter, &stop]() -> const char* {
|
||||||
|
// if we reach tail, return nullptr
|
||||||
|
if (iter == stop) return nullptr;
|
||||||
|
// otherwise fetch data, inc iterator and return.
|
||||||
|
const char* ret = iter->c_str();
|
||||||
|
++iter;
|
||||||
|
return ret;
|
||||||
|
}, decilmer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<bool bIsToLower>
|
||||||
|
void GeneralStringLowerUpper(std::string& strl) {
|
||||||
|
// https://en.cppreference.com/w/cpp/algorithm/transform
|
||||||
|
// https://en.cppreference.com/w/cpp/string/byte/tolower
|
||||||
|
std::transform(
|
||||||
|
strl.cbegin(), strl.cend(), strl.begin(),
|
||||||
|
[](unsigned char c) -> char {
|
||||||
|
if constexpr (bIsToLower) return std::tolower(c);
|
||||||
|
else return std::toupper(c);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Lower(const char* strl) {
|
||||||
|
std::string ret;
|
||||||
|
if (strl == nullptr) return ret;
|
||||||
|
else ret = strl;
|
||||||
|
Lower(ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lower(std::string& strl) {
|
||||||
|
GeneralStringLowerUpper<true>(strl);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Upper(const char* strl) {
|
||||||
|
// same as Lower, just replace char transform function.
|
||||||
|
std::string ret;
|
||||||
|
if (strl == nullptr) return ret;
|
||||||
|
else ret = strl;
|
||||||
|
Upper(ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Upper(std::string& strl) {
|
||||||
|
GeneralStringLowerUpper<false>(strl);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> Split(const char* _strl, const char* _decilmer) {
|
||||||
|
std::vector<std::string> elems;
|
||||||
|
|
||||||
|
// check whether string and decilmer are nullptr
|
||||||
|
std::string strl, decilmer;
|
||||||
|
if (_strl == nullptr || _decilmer == nullptr)
|
||||||
|
return elems;
|
||||||
|
else {
|
||||||
|
strl = _strl;
|
||||||
|
decilmer = _decilmer;
|
||||||
|
}
|
||||||
|
// if no decilmer, return the whole string as the only one element of result.
|
||||||
|
if (decilmer.empty()) {
|
||||||
|
elems.push_back(strl);
|
||||||
|
return elems;
|
||||||
|
}
|
||||||
|
|
||||||
|
// start spliting
|
||||||
|
std::size_t previous = 0;
|
||||||
|
std::size_t current = strl.find(decilmer.c_str());
|
||||||
|
while (current != std::string::npos) {
|
||||||
|
if (current >= previous) {
|
||||||
|
elems.push_back(strl.substr(previous, current - previous));
|
||||||
|
}
|
||||||
|
previous = current + decilmer.size();
|
||||||
|
current = strl.find(decilmer, previous);
|
||||||
|
}
|
||||||
|
if (previous != strl.size()) {
|
||||||
|
elems.push_back(strl.substr(previous));
|
||||||
|
}
|
||||||
|
return elems;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
|
#include <functional>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace YYCC::StringHelper {
|
namespace YYCC::StringHelper {
|
||||||
|
|
||||||
@ -10,6 +12,53 @@ namespace YYCC::StringHelper {
|
|||||||
std::string Printf(const char* format, ...);
|
std::string Printf(const char* format, ...);
|
||||||
std::string VPrintf(const char* format, va_list argptr);
|
std::string VPrintf(const char* format, va_list argptr);
|
||||||
|
|
||||||
//std::string Join(const char* decilmer);
|
/**
|
||||||
|
* @brief The data provider of general Join function.
|
||||||
|
* This function pointer return non-null string pointer to represent a element of joined series.
|
||||||
|
* otherwise return nullptr to terminate the joining process.
|
||||||
|
*/
|
||||||
|
using JoinDataProvider = std::function<const char*()>;
|
||||||
|
/**
|
||||||
|
* @brief General Join function.
|
||||||
|
* @details This function use function pointer as a general data provider interface,
|
||||||
|
* so this function suit for all types container, the user only need write a little bit adaption code.
|
||||||
|
* @param fct_data[in] The function pointer to data provider.
|
||||||
|
* @param decilmer[in] The decilmer.
|
||||||
|
* @return A std::string instance which containing the join result.
|
||||||
|
*/
|
||||||
|
std::string Join(JoinDataProvider fct_data, const char* decilmer);
|
||||||
|
/**
|
||||||
|
* @brief Specialized Join function for common used container.
|
||||||
|
* @param data
|
||||||
|
* @param decilmer
|
||||||
|
* @param reversed
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
std::string Join(const std::vector<std::string>& data, const char* decilmer, bool reversed = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Transform string to lower.
|
||||||
|
* @param strl
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
std::string Lower(const char* strl);
|
||||||
|
void Lower(std::string& strl);
|
||||||
|
/**
|
||||||
|
* @brief Transform string to upper.
|
||||||
|
* @param strl
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
std::string Upper(const char* strl);
|
||||||
|
void Upper(std::string& strl);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief General Split function.
|
||||||
|
* @param _strl
|
||||||
|
* @param _decilmer
|
||||||
|
* @return
|
||||||
|
* @remarks This function may be low performance because it just a homebrew Split functon.
|
||||||
|
* It can works in most toy cases but not suit for high performance scenario.
|
||||||
|
* Also, this function will produce a copy of original string because it is not zero copy.
|
||||||
|
*/
|
||||||
|
std::vector<std::string> Split(const char* _strl, const char* _decilmer);
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,18 @@ namespace Testbench {
|
|||||||
YYCC::StringHelper::Printf(u8"Translation: %s == %s\n", u8"Hello World", u8"你好世界").c_str(),
|
YYCC::StringHelper::Printf(u8"Translation: %s == %s\n", u8"Hello World", u8"你好世界").c_str(),
|
||||||
stdout
|
stdout
|
||||||
);
|
);
|
||||||
|
|
||||||
|
std::string test_string(u8"UPPER -> lower\n");
|
||||||
|
YYCC::TerminalHelper::FPuts(test_string.c_str(), stdout);
|
||||||
|
YYCC::TerminalHelper::FPuts(YYCC::StringHelper::Lower(test_string.c_str()).c_str(), stdout);
|
||||||
|
YYCC::TerminalHelper::FPuts(YYCC::StringHelper::Upper(test_string.c_str()).c_str(), stdout);
|
||||||
|
|
||||||
|
std::vector<std::string> test_container {
|
||||||
|
"test1", "test2", "test3", "test4"
|
||||||
|
};
|
||||||
|
YYCC::TerminalHelper::FPuts(YYCC::StringHelper::Join(test_container, ", ").c_str(), stdout);
|
||||||
|
std::string test_split(", 1, 3, 5, 7, 9, ");
|
||||||
|
YYCC::TerminalHelper::FPuts(YYCC::StringHelper::Join(YYCC::StringHelper::Split(test_split.c_str(), ", "), " -> ").c_str(), stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user