| 
									
										
										
										
											2020-01-18 09:38:21 +01:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2021-04-17 01:18:39 +02:00
										 |  |  |  * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org> | 
					
						
							| 
									
										
										
										
											2020-01-18 09:38:21 +01:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2021-04-22 01:24:48 -07:00
										 |  |  |  * SPDX-License-Identifier: BSD-2-Clause | 
					
						
							| 
									
										
										
										
											2020-01-18 09:38:21 +01:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-14 15:48:01 -07:00
										 |  |  | #include <AK/AnyOf.h>
 | 
					
						
							| 
									
										
										
										
											2020-02-14 21:41:10 +01:00
										 |  |  | #include <AK/ByteBuffer.h>
 | 
					
						
							| 
									
										
										
										
											2021-01-14 15:48:01 -07:00
										 |  |  | #include <AK/Find.h>
 | 
					
						
							| 
									
										
										
										
											2021-11-10 11:05:21 +01:00
										 |  |  | #include <AK/Function.h>
 | 
					
						
							| 
									
										
										
										
											2020-03-08 12:34:33 +01:00
										 |  |  | #include <AK/Memory.h>
 | 
					
						
							| 
									
										
										
										
											2022-09-12 16:31:16 +02:00
										 |  |  | #include <AK/StringBuilder.h>
 | 
					
						
							| 
									
										
										
										
											2019-05-28 11:53:16 +02:00
										 |  |  | #include <AK/StringView.h>
 | 
					
						
							| 
									
										
										
										
											2021-11-10 11:05:21 +01:00
										 |  |  | #include <AK/Vector.h>
 | 
					
						
							| 
									
										
										
										
											2019-04-16 02:39:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-16 00:24:24 +02:00
										 |  |  | #ifndef KERNEL
 | 
					
						
							|  |  |  | #    include <AK/FlyString.h>
 | 
					
						
							|  |  |  | #    include <AK/String.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-16 02:39:16 +02:00
										 |  |  | namespace AK { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-16 00:24:24 +02:00
										 |  |  | #ifndef KERNEL
 | 
					
						
							| 
									
										
										
										
											2022-04-01 20:58:27 +03:00
										 |  |  | StringView::StringView(String const& string) | 
					
						
							| 
									
										
										
										
											2021-04-17 01:18:39 +02:00
										 |  |  |     : m_characters(string.characters()) | 
					
						
							| 
									
										
										
										
											2019-06-02 12:19:21 +02:00
										 |  |  |     , m_length(string.length()) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-01 20:58:27 +03:00
										 |  |  | StringView::StringView(FlyString const& string) | 
					
						
							| 
									
										
										
										
											2021-04-17 01:18:39 +02:00
										 |  |  |     : m_characters(string.characters()) | 
					
						
							| 
									
										
										
										
											2020-03-22 10:12:55 +01:00
										 |  |  |     , m_length(string.length()) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-02-16 00:24:24 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2020-03-22 10:12:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-01 20:58:27 +03:00
										 |  |  | StringView::StringView(ByteBuffer const& buffer) | 
					
						
							|  |  |  |     : m_characters((char const*)buffer.data()) | 
					
						
							| 
									
										
										
										
											2020-03-01 12:35:09 +01:00
										 |  |  |     , m_length(buffer.size()) | 
					
						
							| 
									
										
										
										
											2019-06-29 12:03:28 +02:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-22 15:38:21 +02:00
										 |  |  | Vector<StringView> StringView::split_view(char const separator, SplitBehavior split_behavior) const | 
					
						
							| 
									
										
										
										
											2019-04-16 02:39:16 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2022-01-09 01:51:02 -08:00
										 |  |  |     StringView seperator_view { &separator, 1 }; | 
					
						
							| 
									
										
										
										
											2022-10-22 15:38:21 +02:00
										 |  |  |     return split_view(seperator_view, split_behavior); | 
					
						
							| 
									
										
										
										
											2019-04-16 02:39:16 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-22 15:38:21 +02:00
										 |  |  | Vector<StringView> StringView::split_view(StringView separator, SplitBehavior split_behavior) const | 
					
						
							| 
									
										
										
										
											2020-05-28 00:51:43 +04:30
										 |  |  | { | 
					
						
							|  |  |  |     Vector<StringView> parts; | 
					
						
							| 
									
										
										
										
											2022-10-22 15:38:21 +02:00
										 |  |  |     for_each_split_view(separator, split_behavior, [&](StringView view) { | 
					
						
							| 
									
										
										
										
											2020-05-28 00:51:43 +04:30
										 |  |  |         parts.append(view); | 
					
						
							| 
									
										
										
										
											2022-01-09 02:26:45 -08:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2020-05-28 00:51:43 +04:30
										 |  |  |     return parts; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-02 07:42:33 -05:00
										 |  |  | Vector<StringView> StringView::lines(bool consider_cr) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (is_empty()) | 
					
						
							|  |  |  |         return {}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!consider_cr) | 
					
						
							| 
									
										
										
										
											2022-10-22 15:38:21 +02:00
										 |  |  |         return split_view('\n', SplitBehavior::KeepEmpty); | 
					
						
							| 
									
										
										
										
											2019-12-02 07:42:33 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Vector<StringView> v; | 
					
						
							| 
									
										
										
										
											2019-12-09 17:45:40 +01:00
										 |  |  |     size_t substart = 0; | 
					
						
							| 
									
										
										
										
											2019-12-02 07:42:33 -05:00
										 |  |  |     bool last_ch_was_cr = false; | 
					
						
							|  |  |  |     bool split_view = false; | 
					
						
							| 
									
										
										
										
											2019-12-09 17:45:40 +01:00
										 |  |  |     for (size_t i = 0; i < length(); ++i) { | 
					
						
							| 
									
										
										
										
											2019-12-02 07:42:33 -05:00
										 |  |  |         char ch = characters_without_null_termination()[i]; | 
					
						
							|  |  |  |         if (ch == '\n') { | 
					
						
							|  |  |  |             split_view = true; | 
					
						
							|  |  |  |             if (last_ch_was_cr) { | 
					
						
							|  |  |  |                 substart = i + 1; | 
					
						
							|  |  |  |                 split_view = false; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (ch == '\r') { | 
					
						
							|  |  |  |             split_view = true; | 
					
						
							|  |  |  |             last_ch_was_cr = true; | 
					
						
							| 
									
										
										
										
											2021-06-01 23:17:04 +12:00
										 |  |  |         } else { | 
					
						
							|  |  |  |             last_ch_was_cr = false; | 
					
						
							| 
									
										
										
										
											2019-12-02 07:42:33 -05:00
										 |  |  |         } | 
					
						
							|  |  |  |         if (split_view) { | 
					
						
							| 
									
										
										
										
											2019-12-09 17:45:40 +01:00
										 |  |  |             size_t sublen = i - substart; | 
					
						
							| 
									
										
										
										
											2019-12-02 20:41:15 +01:00
										 |  |  |             v.append(substring_view(substart, sublen)); | 
					
						
							| 
									
										
										
										
											2019-12-02 07:42:33 -05:00
										 |  |  |             substart = i + 1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         split_view = false; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-12-09 17:45:40 +01:00
										 |  |  |     size_t taillen = length() - substart; | 
					
						
							| 
									
										
										
										
											2019-12-02 07:42:33 -05:00
										 |  |  |     if (taillen != 0) | 
					
						
							|  |  |  |         v.append(substring_view(substart, taillen)); | 
					
						
							|  |  |  |     return v; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-15 10:14:22 +13:00
										 |  |  | bool StringView::starts_with(char ch) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (is_empty()) | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     return ch == characters_without_null_termination()[0]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-11 00:55:02 +01:00
										 |  |  | bool StringView::starts_with(StringView str, CaseSensitivity case_sensitivity) const | 
					
						
							| 
									
										
										
										
											2019-09-12 06:13:07 -05:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-18 17:59:38 +01:00
										 |  |  |     return StringUtils::starts_with(*this, str, case_sensitivity); | 
					
						
							| 
									
										
										
										
											2019-09-12 06:13:07 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-15 10:14:22 +13:00
										 |  |  | bool StringView::ends_with(char ch) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (is_empty()) | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     return ch == characters_without_null_termination()[length() - 1]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-11 00:55:02 +01:00
										 |  |  | bool StringView::ends_with(StringView str, CaseSensitivity case_sensitivity) const | 
					
						
							| 
									
										
										
										
											2019-12-30 01:44:30 +13:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-05-26 03:21:34 -07:00
										 |  |  |     return StringUtils::ends_with(*this, str, case_sensitivity); | 
					
						
							| 
									
										
										
										
											2019-12-30 01:44:30 +13:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-11 00:55:02 +01:00
										 |  |  | bool StringView::matches(StringView mask, Vector<MaskSpan>& mask_spans, CaseSensitivity case_sensitivity) const | 
					
						
							| 
									
										
										
										
											2020-10-25 09:04:39 +03:30
										 |  |  | { | 
					
						
							|  |  |  |     return StringUtils::matches(*this, mask, case_sensitivity, &mask_spans); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-11 00:55:02 +01:00
										 |  |  | bool StringView::matches(StringView mask, CaseSensitivity case_sensitivity) const | 
					
						
							| 
									
										
										
										
											2020-02-26 15:25:24 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     return StringUtils::matches(*this, mask, case_sensitivity); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-17 15:04:40 +02:00
										 |  |  | bool StringView::contains(char needle) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     for (char current : *this) { | 
					
						
							|  |  |  |         if (current == needle) | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-12 16:31:16 +02:00
										 |  |  | bool StringView::contains(u32 needle) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     // A code point should be at most four UTF-8 bytes, which easily fits into StringBuilder's inline-buffer.
 | 
					
						
							|  |  |  |     // Therefore, this will not allocate.
 | 
					
						
							|  |  |  |     StringBuilder needle_builder; | 
					
						
							|  |  |  |     auto result = needle_builder.try_append_code_point(needle); | 
					
						
							|  |  |  |     if (result.is_error()) { | 
					
						
							|  |  |  |         // The needle is invalid, therefore the string does not contain it.
 | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return contains(needle_builder.string_view()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-11 00:55:02 +01:00
										 |  |  | bool StringView::contains(StringView needle, CaseSensitivity case_sensitivity) const | 
					
						
							| 
									
										
										
										
											2020-07-04 22:34:00 +04:30
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-10-20 15:07:03 -06:00
										 |  |  |     return StringUtils::contains(*this, needle, case_sensitivity); | 
					
						
							| 
									
										
										
										
											2020-07-04 22:34:00 +04:30
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-11 00:55:02 +01:00
										 |  |  | bool StringView::equals_ignoring_case(StringView other) const | 
					
						
							| 
									
										
										
										
											2020-05-13 17:59:31 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     return StringUtils::equals_ignoring_case(*this, other); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-16 00:24:24 +02:00
										 |  |  | #ifndef KERNEL
 | 
					
						
							| 
									
										
										
										
											2021-07-01 13:45:59 +02:00
										 |  |  | String StringView::to_lowercase_string() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return StringImpl::create_lowercased(characters_without_null_termination(), length()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | String StringView::to_uppercase_string() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return StringImpl::create_uppercased(characters_without_null_termination(), length()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-26 13:55:41 -04:00
										 |  |  | String StringView::to_titlecase_string() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return StringUtils::to_titlecase(*this); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-02-16 00:24:24 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2021-08-26 13:55:41 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-11 00:55:02 +01:00
										 |  |  | StringView StringView::substring_view_starting_from_substring(StringView substring) const | 
					
						
							| 
									
										
										
										
											2019-06-13 16:30:55 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2022-04-01 20:58:27 +03:00
										 |  |  |     char const* remaining_characters = substring.characters_without_null_termination(); | 
					
						
							| 
									
										
										
										
											2021-02-23 20:42:32 +01:00
										 |  |  |     VERIFY(remaining_characters >= m_characters); | 
					
						
							|  |  |  |     VERIFY(remaining_characters <= m_characters + m_length); | 
					
						
							| 
									
										
										
										
											2019-12-09 17:45:40 +01:00
										 |  |  |     size_t remaining_length = m_length - (remaining_characters - m_characters); | 
					
						
							| 
									
										
										
										
											2019-06-13 16:30:55 +03:00
										 |  |  |     return { remaining_characters, remaining_length }; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-11 00:55:02 +01:00
										 |  |  | StringView StringView::substring_view_starting_after_substring(StringView substring) const | 
					
						
							| 
									
										
										
										
											2019-06-13 16:30:55 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2022-04-01 20:58:27 +03:00
										 |  |  |     char const* remaining_characters = substring.characters_without_null_termination() + substring.length(); | 
					
						
							| 
									
										
										
										
											2021-02-23 20:42:32 +01:00
										 |  |  |     VERIFY(remaining_characters >= m_characters); | 
					
						
							|  |  |  |     VERIFY(remaining_characters <= m_characters + m_length); | 
					
						
							| 
									
										
										
										
											2019-12-09 17:45:40 +01:00
										 |  |  |     size_t remaining_length = m_length - (remaining_characters - m_characters); | 
					
						
							| 
									
										
										
										
											2019-06-13 16:30:55 +03:00
										 |  |  |     return { remaining_characters, remaining_length }; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-03-29 02:52:20 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | bool StringView::copy_characters_to_buffer(char* buffer, size_t buffer_size) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     // We must fit at least the NUL-terminator.
 | 
					
						
							|  |  |  |     VERIFY(buffer_size > 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     size_t characters_to_copy = min(m_length, buffer_size - 1); | 
					
						
							|  |  |  |     __builtin_memcpy(buffer, m_characters, characters_to_copy); | 
					
						
							|  |  |  |     buffer[characters_to_copy] = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return characters_to_copy == m_length; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-06-13 16:30:55 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-11 00:17:30 +11:00
										 |  |  | template<typename T> | 
					
						
							|  |  |  | Optional<T> StringView::to_int() const | 
					
						
							| 
									
										
										
										
											2019-08-04 11:44:20 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-12-11 00:17:30 +11:00
										 |  |  |     return StringUtils::convert_to_int<T>(*this); | 
					
						
							| 
									
										
										
										
											2019-08-04 11:44:20 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-11 00:17:30 +11:00
										 |  |  | template Optional<i8> StringView::to_int() const; | 
					
						
							|  |  |  | template Optional<i16> StringView::to_int() const; | 
					
						
							|  |  |  | template Optional<i32> StringView::to_int() const; | 
					
						
							| 
									
										
										
										
											2021-10-01 01:00:54 -06:00
										 |  |  | template Optional<long> StringView::to_int() const; | 
					
						
							|  |  |  | template Optional<long long> StringView::to_int() const; | 
					
						
							| 
									
										
										
										
											2020-12-11 00:17:30 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  | template<typename T> | 
					
						
							|  |  |  | Optional<T> StringView::to_uint() const | 
					
						
							| 
									
										
										
										
											2019-04-16 02:39:16 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-12-11 00:17:30 +11:00
										 |  |  |     return StringUtils::convert_to_uint<T>(*this); | 
					
						
							| 
									
										
										
										
											2019-04-16 02:39:16 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-11 00:17:30 +11:00
										 |  |  | template Optional<u8> StringView::to_uint() const; | 
					
						
							|  |  |  | template Optional<u16> StringView::to_uint() const; | 
					
						
							|  |  |  | template Optional<u32> StringView::to_uint() const; | 
					
						
							| 
									
										
										
										
											2021-10-01 01:00:54 -06:00
										 |  |  | template Optional<unsigned long> StringView::to_uint() const; | 
					
						
							|  |  |  | template Optional<unsigned long long> StringView::to_uint() const; | 
					
						
							| 
									
										
										
										
											2021-01-11 21:39:22 +03:30
										 |  |  | template Optional<long> StringView::to_uint() const; | 
					
						
							|  |  |  | template Optional<long long> StringView::to_uint() const; | 
					
						
							| 
									
										
										
										
											2020-12-11 00:17:30 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-16 00:24:24 +02:00
										 |  |  | #ifndef KERNEL
 | 
					
						
							| 
									
										
										
										
											2022-10-11 00:48:45 +02:00
										 |  |  | Optional<double> StringView::to_double(TrimWhitespace trim_whitespace) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return StringUtils::convert_to_floating_point<double>(*this, trim_whitespace); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Optional<float> StringView::to_float(TrimWhitespace trim_whitespace) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return StringUtils::convert_to_floating_point<float>(*this, trim_whitespace); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-01 20:58:27 +03:00
										 |  |  | bool StringView::operator==(String const& string) const | 
					
						
							| 
									
										
										
										
											2020-03-23 13:45:10 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2022-01-29 15:49:33 +01:00
										 |  |  |     return *this == string.view(); | 
					
						
							| 
									
										
										
										
											2020-03-23 13:45:10 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-06 18:53:05 +02:00
										 |  |  | String StringView::to_string() const { return String { *this }; } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-05 22:33:15 +02:00
										 |  |  | String StringView::replace(StringView needle, StringView replacement, ReplaceMode replace_mode) const | 
					
						
							| 
									
										
										
										
											2021-09-11 02:15:44 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2022-07-05 22:33:15 +02:00
										 |  |  |     return StringUtils::replace(*this, needle, replacement, replace_mode); | 
					
						
							| 
									
										
										
										
											2021-09-11 02:15:44 +03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2022-02-16 00:24:24 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2021-09-11 02:15:44 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-10 11:05:21 +01:00
										 |  |  | Vector<size_t> StringView::find_all(StringView needle) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return StringUtils::find_all(*this, needle); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-22 15:38:21 +02:00
										 |  |  | Vector<StringView> StringView::split_view_if(Function<bool(char)> const& predicate, SplitBehavior split_behavior) const | 
					
						
							| 
									
										
										
										
											2021-11-10 11:05:21 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     if (is_empty()) | 
					
						
							|  |  |  |         return {}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Vector<StringView> v; | 
					
						
							|  |  |  |     size_t substart = 0; | 
					
						
							| 
									
										
										
										
											2022-10-22 15:38:21 +02:00
										 |  |  |     bool keep_empty = has_flag(split_behavior, SplitBehavior::KeepEmpty); | 
					
						
							| 
									
										
										
										
											2022-10-22 16:31:59 +02:00
										 |  |  |     bool keep_separator = has_flag(split_behavior, SplitBehavior::KeepTrailingSeparator); | 
					
						
							| 
									
										
										
										
											2021-11-10 11:05:21 +01:00
										 |  |  |     for (size_t i = 0; i < length(); ++i) { | 
					
						
							|  |  |  |         char ch = characters_without_null_termination()[i]; | 
					
						
							|  |  |  |         if (predicate(ch)) { | 
					
						
							|  |  |  |             size_t sublen = i - substart; | 
					
						
							|  |  |  |             if (sublen != 0 || keep_empty) | 
					
						
							| 
									
										
										
										
											2022-10-22 16:31:59 +02:00
										 |  |  |                 v.append(substring_view(substart, keep_separator ? sublen + 1 : sublen)); | 
					
						
							| 
									
										
										
										
											2021-11-10 11:05:21 +01:00
										 |  |  |             substart = i + 1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     size_t taillen = length() - substart; | 
					
						
							|  |  |  |     if (taillen != 0 || keep_empty) | 
					
						
							|  |  |  |         v.append(substring_view(substart, taillen)); | 
					
						
							|  |  |  |     return v; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-16 02:39:16 +02:00
										 |  |  | } |