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
|
namespace detail
|
||||||
{
|
{
|
||||||
template<typename TChar, typename TTraits>
|
template<typename TChar, typename TTraits, typename TOutIterator>
|
||||||
std::vector<std::basic_string_view<TChar, TTraits>> splitImpl(std::basic_string_view<TChar, TTraits> stringView,
|
void splitImpl(std::basic_string_view<TChar, TTraits> stringView,
|
||||||
std::basic_string_view<TChar, TTraits> separator,
|
std::basic_string_view<TChar, TTraits> separator,
|
||||||
const SplitOptions& options)
|
const SplitOptions& options,
|
||||||
|
TOutIterator outIterator,
|
||||||
|
std::size_t& numEmitted)
|
||||||
{
|
{
|
||||||
using sv_t = std::basic_string_view<TChar, TTraits>;
|
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())
|
if (separator.empty())
|
||||||
{
|
{
|
||||||
return {};
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<sv_t> result;
|
auto emit = [&](std::string_view result)
|
||||||
|
{
|
||||||
|
*outIterator = result;
|
||||||
|
++outIterator;
|
||||||
|
++numEmitted;
|
||||||
|
};
|
||||||
|
|
||||||
if (options.limitParts <= 1)
|
if (options.limitParts <= 1)
|
||||||
{
|
{
|
||||||
result.push_back(stringView);
|
emit(stringView);
|
||||||
return result;
|
return;
|
||||||
}
|
}
|
||||||
auto start = stringView.begin();
|
auto start = stringView.begin();
|
||||||
auto pos = start;
|
auto pos = start;
|
||||||
@ -108,10 +116,10 @@ std::vector<std::basic_string_view<TChar, TTraits>> splitImpl(std::basic_string_
|
|||||||
{
|
{
|
||||||
if (!options.ignoreEmpty || pos != start)
|
if (!options.ignoreEmpty || pos != start)
|
||||||
{
|
{
|
||||||
result.emplace_back(start, pos);
|
emit(std::string_view(start, pos));
|
||||||
}
|
}
|
||||||
start = pos = (pos + separator.size());
|
start = pos = (pos + separator.size());
|
||||||
if (result.size() == options.limitParts - 1)
|
if (numEmitted == options.limitParts - 1)
|
||||||
{
|
{
|
||||||
if (options.ignoreEmpty)
|
if (options.ignoreEmpty)
|
||||||
{
|
{
|
||||||
@ -120,14 +128,14 @@ std::vector<std::basic_string_view<TChar, TTraits>> splitImpl(std::basic_string_
|
|||||||
pos += separator.size();
|
pos += separator.size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result.emplace_back(pos, end);
|
emit(std::string_view(pos, end));
|
||||||
return result;
|
return;
|
||||||
}
|
}
|
||||||
if (!options.ignoreEmpty && pos == end)
|
if (!options.ignoreEmpty && pos == end)
|
||||||
{
|
{
|
||||||
// skipped a separator at the very end, add an empty entry
|
// skipped a separator at the very end, add an empty entry
|
||||||
result.emplace_back("");
|
emit("");
|
||||||
return result;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -138,9 +146,37 @@ std::vector<std::basic_string_view<TChar, TTraits>> splitImpl(std::basic_string_
|
|||||||
|
|
||||||
if (start != end)
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,6 +237,13 @@ template<typename TLeft, typename TRight>
|
|||||||
std::basic_string_view(std::forward<TRight>(separator)), options);
|
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>
|
template<typename TString, typename TChars>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
auto trimPrefix(TString&& string, TChars&& chars)
|
auto trimPrefix(TString&& string, TChars&& chars)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user