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

View File

@@ -29,7 +29,9 @@
#pragma once #pragma once
#include <algorithm>
#include <string_view> #include <string_view>
#include <type_traits>
template<typename T> template<typename T>
constexpr std::pair<std::basic_string_view<T>, std::basic_string_view<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()); 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> template<typename T>
constexpr std::pair<std::basic_string_view<T>, std::basic_string_view<T>> constexpr std::pair<std::basic_string_view<T>, std::basic_string_view<T>>
PartitionWithout(const std::basic_string_view<T> haystack, 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); 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);
}