-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Logic cleanups for basic_string
#3862
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Logic cleanups for basic_string
#3862
Conversation
stl/inc/xstring
Outdated
| const _Elem* const _Right_ptr = _Right._Mypair._Myval2._Myptr(); | ||
| if (_Entails_large_string(_Right_size)) { | ||
| const auto _New_capacity = | ||
| _Calculate_growth(_Right_size, _SMALL_STRING_CAPACITY, _Right.max_size()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[won't be included in this pr]
If this fix is adopted, the second parameter of _Calculate_growth(x,y,z) will be uniformly _SMALL_STRING_CAPACITY and further rectification will be possible.
There is also a strange use of _Calculate_growth(newsize) in _Construct_from_iter. According to impl logic it is performing capacity*=1.5 logic. What about replacing the grow logic here with _Reallocate_grow_by or push_back?
Line 2712 in 40640c6
| const size_type _New_capacity = _Calculate_growth(_My_data._Mysize); |
| // invariant: _Myres >= _Mysize, and _Myres >= _SMALL_STRING_CAPACITY (after string's construction) | ||
| // both _Mysize and _Myres doesn't take account of the extra null terminator | ||
| size_type _Mysize = 0; // current length of string (size) | ||
| size_type _Myres = 0; // current storage reserved for string (capacity) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[won't be included in this pr]
suggestion: we can make _Myres initialized to _SMALL_STRING_CAPACITY to make _Myres >= _SMALL_STRING_CAPACITY throughout the lifetime of _String_val.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
…d` logic with it
This comment was marked as resolved.
This comment was marked as resolved.
1d7d1f3 to
9b0e590
Compare
|
As a special exception to our usual way of working, I've force-pushed the branch to rebase it on THANK YOU for the fine-grained commits, they were an enormous help in reviewing. After linearization, I was able to see the correctness of each transformation and I have high confidence in the resulting state. Overall I think that this is a great cleanup and makes the complicated Finally, I added commits to address the minor issues I found while reviewing:
|
stl/inc/xstring
Outdated
| } | ||
|
|
||
| const size_type _Target_capacity = (_STD min)(_My_data._Mysize | _ALLOC_MASK, max_size()); | ||
| size_type _Target_capacity = (_STD min)(_My_data._Mysize | _ALLOC_MASK, max_size()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(no changes requested) As _Exactly mode doesn't really require input capacity to be a referrence, I think we can restore constness for _Target_capacity in the future. Also here in <vector>:
Lines 1705 to 1706 in 0fe653a
| size_type _Newcapacity = static_cast<size_type>(_Oldlast - _Oldfirst); | |
| _Reallocate<_Reallocation_policy::_Exactly>(_Newcapacity); |
CaseyCarter
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll verify and push a change to address my comments, which are mostly naming nits.
Rename `_ALLOC_MASK`, `_SMALL_STRING_CAPACITY` and `_LEAST_ALLOCATION_SIZE` to avoid the macro identifier namespace. Comment that `_BUF_SIZE` is used by the debugger visualizer (and hence shouldn't be renamed).
... to avoid confusion about size vs. capacity since `_Large_string_engaged()` can be `true` for a very small string with a large capacity.
With the addition of `_SMALL_STRING_CAPACITY`, I think the expressions themselves (e.g., `_Count > _SMALL_STRING_CAPACITY`) are more readable than calls to the function.
It's more clearly the opposite of "large mode".
... to the more descriptive `_Actual_allocation_size`.
Grepping is quick, and this is very likely to bitrot.
231682b to
e2ac4ce
Compare
|
I'm mirroring this to the MSVC-internal repo - please notify me if any further changes are pushed. |
|
Thanks again for this maintainability overhaul and runtime correctness fix! 😻 🪄 🚀 |
This is a reorganized version of #3830.
basic_stringeasier to maintain.operator=(const&)which will break invariant.Thanks to @StephanTLavavej, @fsb4000 and @frederick-vs-ja for review in the original pr!