Added splitFixed() function to avoid heap-allocation when the number of (expected) splits is known at compile-time.
This commit is contained in:
parent
8e117e0f47
commit
aff59724fc
@ -72,10 +72,12 @@ template <typename TRange, typename TValue = typename TRange::value_type>
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template<typename TChar, typename TTraits>
|
||||
std::vector<std::basic_string_view<TChar, TTraits>> splitImpl(std::basic_string_view<TChar, TTraits> stringView,
|
||||
std::basic_string_view<TChar, TTraits> separator,
|
||||
const SplitOptions& options)
|
||||
template<typename TChar, typename TTraits, typename TOutIterator>
|
||||
void splitImpl(std::basic_string_view<TChar, TTraits> stringView,
|
||||
std::basic_string_view<TChar, TTraits> separator,
|
||||
const SplitOptions& options,
|
||||
TOutIterator outIterator,
|
||||
std::size_t& numEmitted)
|
||||
{
|
||||
using sv_t = std::basic_string_view<TChar, TTraits>;
|
||||
|
||||
@ -84,14 +86,20 @@ std::vector<std::basic_string_view<TChar, TTraits>> splitImpl(std::basic_string_
|
||||
|
||||
if (separator.empty())
|
||||
{
|
||||
return {};
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<sv_t> result;
|
||||
auto emit = [&](std::string_view result)
|
||||
{
|
||||
*outIterator = result;
|
||||
++outIterator;
|
||||
++numEmitted;
|
||||
};
|
||||
|
||||
if (options.limitParts <= 1)
|
||||
{
|
||||
result.push_back(stringView);
|
||||
return result;
|
||||
emit(stringView);
|
||||
return;
|
||||
}
|
||||
auto start = stringView.begin();
|
||||
auto pos = start;
|
||||
@ -108,10 +116,10 @@ std::vector<std::basic_string_view<TChar, TTraits>> splitImpl(std::basic_string_
|
||||
{
|
||||
if (!options.ignoreEmpty || pos != start)
|
||||
{
|
||||
result.emplace_back(start, pos);
|
||||
emit(std::string_view(start, pos));
|
||||
}
|
||||
start = pos = (pos + separator.size());
|
||||
if (result.size() == options.limitParts - 1)
|
||||
if (numEmitted == options.limitParts - 1)
|
||||
{
|
||||
if (options.ignoreEmpty)
|
||||
{
|
||||
@ -120,14 +128,14 @@ std::vector<std::basic_string_view<TChar, TTraits>> splitImpl(std::basic_string_
|
||||
pos += separator.size();
|
||||
}
|
||||
}
|
||||
result.emplace_back(pos, end);
|
||||
return result;
|
||||
emit(std::string_view(pos, end));
|
||||
return;
|
||||
}
|
||||
if (!options.ignoreEmpty && pos == end)
|
||||
{
|
||||
// skipped a separator at the very end, add an empty entry
|
||||
result.emplace_back("");
|
||||
return result;
|
||||
emit("");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -138,9 +146,37 @@ std::vector<std::basic_string_view<TChar, TTraits>> splitImpl(std::basic_string_
|
||||
|
||||
if (start != end)
|
||||
{
|
||||
result.emplace_back(start, end);
|
||||
emit(std::string_view(start, end));
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TChar, typename TTraits>
|
||||
std::vector<std::basic_string_view<TChar, TTraits>> splitImpl(std::basic_string_view<TChar, TTraits> stringView,
|
||||
std::basic_string_view<TChar, TTraits> separator,
|
||||
const SplitOptions& options)
|
||||
{
|
||||
std::vector<std::basic_string_view<TChar, TTraits>> result;
|
||||
std::size_t numEmitted = 0;
|
||||
splitImpl(stringView, separator, options, std::back_inserter(result), numEmitted);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
template<std::size_t count, typename TChar, typename TTraits>
|
||||
std::array<std::basic_string_view<TChar, TTraits>, count> splitFixedImpl(std::basic_string_view<TChar, TTraits> stringView,
|
||||
std::basic_string_view<TChar, TTraits> separator,
|
||||
SplitOptions options,
|
||||
std::size_t* outNumResults)
|
||||
{
|
||||
options.limitParts = count;
|
||||
|
||||
std::array<std::basic_string_view<TChar, TTraits>, count> result;
|
||||
std::size_t numEmitted = 0;
|
||||
splitImpl(stringView, separator, options, result.begin(), numEmitted);
|
||||
if (outNumResults != nullptr)
|
||||
{
|
||||
*outNumResults = numEmitted;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -201,6 +237,13 @@ template<typename TLeft, typename TRight>
|
||||
std::basic_string_view(std::forward<TRight>(separator)), options);
|
||||
}
|
||||
|
||||
template<std::size_t count, typename TLeft, typename TRight>
|
||||
[[nodiscard]] auto splitFixed(TLeft&& stringView, TRight&& separator, SplitOptions options = {}, std::size_t* outNumResults = nullptr)
|
||||
{
|
||||
return detail::splitFixedImpl<count>(std::basic_string_view(std::forward<TLeft>(stringView)),
|
||||
std::basic_string_view(std::forward<TRight>(separator)), options, outNumResults);
|
||||
}
|
||||
|
||||
template<typename TString, typename TChars>
|
||||
[[nodiscard]]
|
||||
auto trimPrefix(TString&& string, TChars&& chars)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user