| 2930 | } |
| 2931 | |
| 2932 | String String::remove_char(char32_t p_char) const { |
| 2933 | if (p_char == 0) { |
| 2934 | return *this; |
| 2935 | } |
| 2936 | |
| 2937 | int len = length(); |
| 2938 | if (len == 0) { |
| 2939 | return *this; |
| 2940 | } |
| 2941 | |
| 2942 | int index = 0; |
| 2943 | const char32_t *old_ptr = ptr(); |
| 2944 | for (; index < len; ++index) { |
| 2945 | if (old_ptr[index] == p_char) { |
| 2946 | break; |
| 2947 | } |
| 2948 | } |
| 2949 | |
| 2950 | // If no occurrence of `char` was found, return this. |
| 2951 | if (index == len) { |
| 2952 | return *this; |
| 2953 | } |
| 2954 | |
| 2955 | // If we found at least one occurrence of `char`, create new string, allocating enough space for the current length minus one. |
| 2956 | String new_string; |
| 2957 | new_string.resize_uninitialized(len); |
| 2958 | char32_t *new_ptr = new_string.ptrw(); |
| 2959 | |
| 2960 | // Copy part of input before `char`. |
| 2961 | memcpy(new_ptr, old_ptr, index * sizeof(char32_t)); |
| 2962 | |
| 2963 | int new_size = index; |
| 2964 | |
| 2965 | // Copy rest, skipping `char`. |
| 2966 | for (++index; index < len; ++index) { |
| 2967 | const char32_t old_char = old_ptr[index]; |
| 2968 | if (old_char != p_char) { |
| 2969 | new_ptr[new_size] = old_char; |
| 2970 | ++new_size; |
| 2971 | } |
| 2972 | } |
| 2973 | |
| 2974 | new_ptr[new_size] = _null; |
| 2975 | |
| 2976 | // Shrink new string to fit. |
| 2977 | new_string.resize_uninitialized(new_size + 1); |
| 2978 | |
| 2979 | return new_string; |
| 2980 | } |
| 2981 | |
| 2982 | template <class T> |
| 2983 | static String _remove_chars_common(const String &p_this, const T *p_chars, int p_chars_len) { |
no test coverage detected