Fully implemented splitStringInVector
This commit is contained in:
parent
f625cb1503
commit
38f2d7f65a
@ -1,6 +1,7 @@
|
||||
#include "string.hpp"
|
||||
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
namespace gz::util {
|
||||
@ -25,7 +26,34 @@ std::vector<std::string> splitStringInVector(std::string& s, char separator) {
|
||||
}
|
||||
}
|
||||
return v;
|
||||
|
||||
}
|
||||
|
||||
|
||||
template<SplitStringInVectorImplemented T>
|
||||
std::vector<T> splitStringInVector(const std::string_view& s, const std::string& separator, bool skipEmptyStrings) {
|
||||
std::vector<T> v;
|
||||
|
||||
std::string::size_type posStart = 0;
|
||||
std::string::size_type posEnd = s.find(separator, posStart);
|
||||
while (posEnd != std::string::npos) {
|
||||
if (!(skipEmptyStrings and posStart == posEnd)) {
|
||||
v.emplace_back(T(s.begin() + posStart, s.begin() + posEnd));
|
||||
}
|
||||
posStart = posEnd + 1;
|
||||
posEnd = s.find(separator, posStart);
|
||||
}
|
||||
// last element
|
||||
if (posStart < s.size()) {
|
||||
v.emplace_back(T(s.begin() + posStart, s.end()));
|
||||
}
|
||||
// if last char is separator, append empty string
|
||||
else if (!skipEmptyStrings and posStart == s.size()) {
|
||||
v.emplace_back(T(s.begin(), s.begin()));
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
template std::vector<std::string_view> splitStringInVector<std::string_view>(const std::string_view&, const std::string&, bool);
|
||||
template std::vector<std::string> splitStringInVector<std::string>(const std::string_view&, const std::string&, bool);
|
||||
|
||||
} // namespace gz::util
|
||||
|
@ -3,13 +3,33 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <map>
|
||||
|
||||
namespace gz::util {
|
||||
template<typename T>
|
||||
concept SplitStringInVectorImplemented = std::same_as<T, std::string_view> || std::same_as<T, std::string>;
|
||||
|
||||
/**
|
||||
* @todo document
|
||||
* @brief Split a string at a separator into a vector
|
||||
* @details
|
||||
* Splits a string at a separator.\n
|
||||
* Two templates exist, one where the vector will hold std::string_views into s
|
||||
* and one where it will hold std::strings.
|
||||
* Behavior:
|
||||
* - the elements of the returned vector will not contain the separator.
|
||||
* - if the separator is not in s, the vector will contain s as only element.
|
||||
* - empty elements will occur if:
|
||||
* - separator is the first char
|
||||
* - separator is the last char
|
||||
* - two or more separator appear after each other\n
|
||||
* You can turn this behaviour off by setting skipEmptyStrings to true
|
||||
* @note
|
||||
* The string_view variant has the advantage of being faster, however:\n
|
||||
* The string_views will reference the original string, so it must not be changed or destroyed
|
||||
* as long as the string_views are used!
|
||||
*/
|
||||
std::vector<std::string> splitStringInVector(std::string& s, char separator = ',');
|
||||
template<SplitStringInVectorImplemented T>
|
||||
std::vector<T> splitStringInVector(const std::string_view& s, const std::string& separator, bool skipEmptyStrings=false);
|
||||
|
||||
/**
|
||||
* @name Map with string type as key, works with strings, string_view and char*
|
||||
@ -24,8 +44,27 @@ namespace gz::util {
|
||||
size_t operator()(std::string_view str) const { return hash_type{}(str); }
|
||||
size_t operator()(std::string const& str) const { return hash_type{}(str); }
|
||||
};
|
||||
/**
|
||||
* @brief A unordered_map where you can use string_views to access elements
|
||||
* @details
|
||||
* To retrieve an element using a string view, you need to do this:
|
||||
* @code
|
||||
* std::string_view sv = ...;
|
||||
* gz::util::unordered_string_map<T> smap = { ... };
|
||||
* ...
|
||||
* if (smap.contains(sv)) {
|
||||
* return smap.find(sv)->second;
|
||||
* }
|
||||
* @endcode
|
||||
* The at() member and [] operator do not work with the string_view.
|
||||
*/
|
||||
template<typename T>
|
||||
using unordered_string_map = std::unordered_map<std::string, T, util::string_hash, std::equal_to<>>;
|
||||
/**
|
||||
* @brief same as unordered_string_map, but using std::map instead of std::unordered_map
|
||||
*/
|
||||
template<typename T>
|
||||
using string_map = std::map<std::string, T, util::string_hash, std::equal_to<>>;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user