// SPDX-License-Identifier: BSD-2-Clause // author: Max Kellermann #pragma once #include #include #include template constexpr std::pair, std::basic_string_view> Partition(const std::basic_string_view haystack, const typename std::basic_string_view::size_type position) noexcept { return { haystack.substr(0, position), haystack.substr(position), }; } template constexpr std::pair, std::basic_string_view> Partition(const std::basic_string_view haystack, const typename std::basic_string_view::const_pointer position) noexcept { return Partition(haystack, position - haystack.data()); } template requires(!std::is_same_v::const_pointer, typename std::basic_string_view::const_iterator>) constexpr std::pair, std::basic_string_view> Partition(const std::basic_string_view haystack, const typename std::basic_string_view::const_iterator i) noexcept { return Partition(haystack, i - haystack.begin()); } template constexpr std::pair, std::basic_string_view> PartitionWithout(const std::basic_string_view haystack, const typename std::basic_string_view::size_type separator) noexcept { return { haystack.substr(0, separator), haystack.substr(separator + 1), }; } /** * Split the string at the first occurrence of the given character. * If the character is not found, then the first value is the whole * string and the second value is nullptr. */ template constexpr std::pair, std::basic_string_view> Split(const std::basic_string_view haystack, const T ch) noexcept { const auto i = haystack.find(ch); if (i == haystack.npos) return {haystack, {}}; return PartitionWithout(haystack, i); } /** * Split the string at the last occurrence of the given * character. If the character is not found, then the first * value is the whole string and the second value is nullptr. */ template constexpr std::pair, std::basic_string_view> SplitLast(const std::basic_string_view haystack, const T ch) noexcept { const auto i = haystack.rfind(ch); if (i == haystack.npos) return {haystack, {}}; return PartitionWithout(haystack, i); } /** * Find the first character that does not match the given predicate * and split at this boundary. */ template constexpr std::pair, std::basic_string_view> SplitWhile(const std::basic_string_view haystack, P &&predicate) noexcept { const auto i = std::find_if_not(haystack.begin(), haystack.end(), std::forward

(predicate)); return Partition(haystack, i); }