| 4301 | |
| 4302 | template <typename char_type_, typename allocator_> |
| 4303 | bool basic_string<char_type_, allocator_>::try_assign(string_view other) noexcept { |
| 4304 | // We can't just assign the other string state, as its start address may be somewhere else on the stack. |
| 4305 | sz_ptr_t string_start; |
| 4306 | sz_size_t string_length; |
| 4307 | sz_string_range(&string_, &string_start, &string_length); |
| 4308 | |
| 4309 | // One nasty special case is when the other string is a substring of this string. |
| 4310 | // We need to handle that separately, as the `sz_string_expand` may invalidate the `other` pointer. |
| 4311 | if (other.data() >= string_start && other.data() < string_start + string_length) { |
| 4312 | auto offset_in_this = other.data() - string_start; |
| 4313 | sz_string_erase(&string_, 0, offset_in_this); |
| 4314 | sz_string_erase(&string_, other.length(), SZ_SIZE_MAX); |
| 4315 | } |
| 4316 | // In some of the other cases, when the assigned string is short, we don't need to re-allocate. |
| 4317 | else if (string_length >= other.length()) { |
| 4318 | other.copy(string_start, other.length()); |
| 4319 | sz_string_erase(&string_, other.length(), SZ_SIZE_MAX); |
| 4320 | } |
| 4321 | // In the common case, however, we need to allocate. |
| 4322 | else { |
| 4323 | if (_with_alloc([&](sz_alloc_type &alloc) { |
| 4324 | string_start = sz_string_expand(&string_, SZ_SIZE_MAX, other.length() - string_length, &alloc); |
| 4325 | if (!string_start) return sz_bad_alloc_k; |
| 4326 | other.copy(string_start, other.length()); |
| 4327 | return sz_success_k; |
| 4328 | }) != status_t::success_k) |
| 4329 | return false; |
| 4330 | } |
| 4331 | return true; |
| 4332 | } |
| 4333 | |
| 4334 | template <typename char_type_, typename allocator_> |
| 4335 | bool basic_string<char_type_, allocator_>::try_push_back(char_type c) noexcept { |