Skip to content
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

[SR-2689] String.CharacterView does not shift endIndex correctly #45294

Closed
karwa opened this issue Sep 19, 2016 · 3 comments
Closed

[SR-2689] String.CharacterView does not shift endIndex correctly #45294

karwa opened this issue Sep 19, 2016 · 3 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. standard library Area: Standard library umbrella

Comments

@karwa
Copy link
Contributor

karwa commented Sep 19, 2016

Previous ID SR-2689
Radar None
Original Reporter @karwa
Type Bug
Status Resolved
Resolution Invalid
Environment

Swift 3.0 GM
Swift 08e7963

Additional Detail from JIRA
Votes 0
Component/s Standard Library
Labels Bug
Assignee None
Priority Medium

md5: 4e16ff61b5da4458c56147cc14e0fe85

Issue Description:

See the following snippet. This kind of shifting produces the expected result (referencing the same character) for every index except the pre-prepending endIndex:

var characters = "This is a test".characters
assert(characters.count == 14)

let endBeforePrepending = characters.endIndex

let insertedCharacters = "[PREPENDED]".characters
assert(insertedCharacters.count == 11)

characters.replaceSubrange(characters.startIndex..<characters.startIndex, with: insertedCharacters)

let endAfterPrepending = characters.index(endBeforePrepending, offsetBy: insertedCharacters.count)
assert(endAfterPrepending == characters.endIndex) // Fails. 24 != 25
@karwa
Copy link
Contributor Author

karwa commented Sep 19, 2016

CC @gribozavr

This was working in some of the developer snapshots in February-March-ish. So we fixed it then regressed.

@gribozavr
Copy link
Collaborator

The replaceSubrange() call replaces elements before the index that you saved. This invalidates the index, and using that index afterwards is a precondition violation (whether the program will trap or not is unspecified).

@karwa
Copy link
Contributor Author

karwa commented Sep 19, 2016

@gribozavr what would you suggest then for keeping a pointer to a position in a character view across a mutation? Like I said, this used to work in a Dev snapshot. I'm worried I'm going to have to rewrite my code to linearly traverse the string for every position in every marker every time there's a mutation.

It seems to be an actual problem with swift's String model that we can't actuallly do that, even though I know a valid location prior to mutation and exactly how it will be mutated. We have all of the information to make this possible, but the standard library doesn't expose it.

I think we would need a version of replaceSubrange which returns a new type which I'll call IndexDisplacement. It would know how many internal UTF-16 codepoints have been inserted/removed and where (for a single replaceSubrange operation), and provide a way to translate indexes back and forth. It would allow us to perform this vital operation which we can't today, and with maximum performance.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. standard library Area: Standard library umbrella
Projects
None yet
Development

No branches or pull requests

2 participants