Updated string split method to accept limitParts and ignoreEmpty options.
This commit is contained in:
parent
d508ccfe2b
commit
03c899f17e
@ -5,7 +5,7 @@
|
|||||||
#define MIJIN_UTIL_STRING_HPP_INCLUDED 1
|
#define MIJIN_UTIL_STRING_HPP_INCLUDED 1
|
||||||
|
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <ranges>
|
#include <limits>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
@ -28,6 +28,12 @@ namespace mijin
|
|||||||
// public types
|
// public types
|
||||||
//
|
//
|
||||||
|
|
||||||
|
struct SplitOptions
|
||||||
|
{
|
||||||
|
std::size_t limitParts = std::numeric_limits<std::size_t>::max();
|
||||||
|
bool ignoreEmpty = true;
|
||||||
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
// public functions
|
// public functions
|
||||||
//
|
//
|
||||||
@ -56,11 +62,74 @@ namespace detail
|
|||||||
{
|
{
|
||||||
template<typename TChar, typename TTraits>
|
template<typename TChar, typename TTraits>
|
||||||
std::vector<std::basic_string_view<TChar, TTraits>> splitImpl(std::basic_string_view<TChar, TTraits> stringView,
|
std::vector<std::basic_string_view<TChar, TTraits>> splitImpl(std::basic_string_view<TChar, TTraits> stringView,
|
||||||
std::basic_string_view<TChar, TTraits> seperator)
|
std::basic_string_view<TChar, TTraits> separator,
|
||||||
|
const SplitOptions& options)
|
||||||
{
|
{
|
||||||
return std::views::split(stringView, seperator)
|
using sv_t = std::basic_string_view<TChar, TTraits>;
|
||||||
| std::views::transform([](auto val) { return std::string_view(val); })
|
|
||||||
| std::ranges::to<std::vector>();
|
MIJIN_ASSERT(options.limitParts > 0, "Cannot split to zero parts.");
|
||||||
|
MIJIN_ASSERT(!separator.empty(), "Separator cannot be empty.");
|
||||||
|
|
||||||
|
if (separator.empty())
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<sv_t> result;
|
||||||
|
if (options.limitParts <= 1)
|
||||||
|
{
|
||||||
|
result.push_back(stringView);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
auto start = stringView.begin();
|
||||||
|
auto pos = start;
|
||||||
|
const auto end = stringView.end();
|
||||||
|
|
||||||
|
auto seperatorFound = [&]()
|
||||||
|
{
|
||||||
|
return pos <= (end - separator.size()) && sv_t(pos, pos + separator.size()) == separator;
|
||||||
|
};
|
||||||
|
|
||||||
|
while (pos != end)
|
||||||
|
{
|
||||||
|
if (seperatorFound())
|
||||||
|
{
|
||||||
|
if (!options.ignoreEmpty || pos != start)
|
||||||
|
{
|
||||||
|
result.emplace_back(start, pos);
|
||||||
|
}
|
||||||
|
start = pos = (pos + separator.size());
|
||||||
|
if (result.size() == options.limitParts - 1)
|
||||||
|
{
|
||||||
|
if (options.ignoreEmpty)
|
||||||
|
{
|
||||||
|
while (seperatorFound())
|
||||||
|
{
|
||||||
|
pos += separator.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.emplace_back(pos, end);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (!options.ignoreEmpty && pos == end)
|
||||||
|
{
|
||||||
|
// skipped a separator at the very end, add an empty entry
|
||||||
|
result.emplace_back("");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start != end)
|
||||||
|
{
|
||||||
|
result.emplace_back(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename TChar, typename TTraitsA, typename TTraitsB>
|
template<typename TChar, typename TTraitsA, typename TTraitsB>
|
||||||
@ -87,9 +156,10 @@ static const TChar SPACE = TChar(' ');
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename TLeft, typename TRight>
|
template<typename TLeft, typename TRight>
|
||||||
[[nodiscard]] auto split(TLeft&& left, TRight&& right)
|
[[nodiscard]] auto split(TLeft&& stringView, TRight&& separator, const SplitOptions& options = {})
|
||||||
{
|
{
|
||||||
return detail::splitImpl(std::basic_string_view(std::forward<TLeft>(left)), std::basic_string_view(std::forward<TRight>(right)));
|
return detail::splitImpl(std::basic_string_view(std::forward<TLeft>(stringView)),
|
||||||
|
std::basic_string_view(std::forward<TRight>(separator)), options);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename TChar, typename TTraits>
|
template<typename TChar, typename TTraits>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user