util/StringSplit: add SplitWhile()

This commit is contained in:
Max Kellermann 2022-07-06 11:45:03 +02:00 committed by Max Kellermann
parent 3ab3d5555e
commit 988f5d1b5d
1 changed files with 25 additions and 0 deletions

View File

@ -29,7 +29,9 @@
#pragma once
#include <algorithm>
#include <string_view>
#include <type_traits>
template<typename T>
constexpr std::pair<std::basic_string_view<T>, std::basic_string_view<T>>
@ -50,6 +52,16 @@ Partition(const std::basic_string_view<T> haystack,
return Partition(haystack, position - haystack.data());
}
template<typename T>
requires(!std::is_same_v<typename std::basic_string_view<T>::const_pointer,
typename std::basic_string_view<T>::const_iterator>)
constexpr std::pair<std::basic_string_view<T>, std::basic_string_view<T>>
Partition(const std::basic_string_view<T> haystack,
const typename std::basic_string_view<T>::const_iterator i) noexcept
{
return Partition(haystack, i - haystack.begin());
}
template<typename T>
constexpr std::pair<std::basic_string_view<T>, std::basic_string_view<T>>
PartitionWithout(const std::basic_string_view<T> haystack,
@ -92,3 +104,16 @@ SplitLast(const std::basic_string_view<T> haystack, const T ch) noexcept
return PartitionWithout(haystack, i);
}
/**
* Find the first character that does not match the given predicate
* and split at this boundary.
*/
template<typename T, typename P>
constexpr std::pair<std::basic_string_view<T>, std::basic_string_view<T>>
SplitWhile(const std::basic_string_view<T> haystack, P &&predicate) noexcept
{
const auto i = std::find_if_not(haystack.begin(), haystack.end(),
std::forward<P>(predicate));
return Partition(haystack, i);
}