@kha I've added iterator.extract : iterator -> iterator -> option string It returns `none` if the iterators are "incompatible". If this function is inconvenient to use, we can change it and return the empty string in these cases. Given iterators `it1` and `it2`, if they are sharing the same string object in memory, then the cost is O(pos(it2) - pos(it1)). If not, we have an extra O(N) step where we check whether the strings being iterated by it1 and it2 are equal (`N` is the size of the strings). In most applications, I believe the iterators will share the string object. I didn't test the code much. BTW, I found an unrelated bug at vm_string.cpp. So, I'm not very confident this code is rock solid.
79 lines
1.6 KiB
Text
79 lines
1.6 KiB
Text
#eval "abc"
|
|
|
|
/- some "a" -/
|
|
#eval
|
|
let s₁ := "abcde" in
|
|
let it₁ := s₁.mk_iterator in
|
|
let it₂ := it₁.next in
|
|
it₁.extract it₂
|
|
|
|
/- some "" -/
|
|
#eval
|
|
let s₁ := "abcde" in
|
|
let it₁ := s₁.mk_iterator in
|
|
it₁.extract it₁
|
|
|
|
/- none -/
|
|
#eval
|
|
let s₁ := "abcde" in
|
|
let it₁ := s₁.mk_iterator in
|
|
let it₂ := it₁.next in
|
|
it₂.extract it₁
|
|
|
|
/- some "abc" -/
|
|
#eval
|
|
let s₁ := "abcde" in
|
|
let it₁ := s₁.mk_iterator in
|
|
let it₂ := it₁.next.next.next.prev.next in
|
|
it₁.extract it₂
|
|
|
|
/- some "bcde" -/
|
|
#eval
|
|
let s₁ := "abcde" in
|
|
let it₁ := s₁.mk_iterator.next in
|
|
let it₂ := it₁.next.next.next.next in
|
|
it₁.extract it₂
|
|
|
|
/- some "abcde" -/
|
|
#eval
|
|
let s₁ := "abcde" in
|
|
let it₁ := s₁.mk_iterator in
|
|
let it₂ := it₁.next.next.next.next.next in
|
|
it₁.extract it₂
|
|
|
|
/- some "ab" -/
|
|
#eval
|
|
let s₁ := "abcde" in
|
|
let s₂ := "abcde" in
|
|
let it₁ := s₁.mk_iterator in
|
|
let it₂ := s₂.mk_iterator.next.next in
|
|
it₁.extract it₂
|
|
|
|
/- none -/
|
|
#eval
|
|
let s₁ := "abcde" in
|
|
let s₂ := "abhde" in
|
|
let it₁ := s₁.mk_iterator in
|
|
let it₂ := s₂.mk_iterator.next.next in
|
|
it₁.extract it₂
|
|
|
|
/- none -/
|
|
#eval
|
|
let s₁ := "abcde" in
|
|
let it₁ := s₁.mk_iterator in
|
|
let it₂ := it₁.next.set_curr 'a' in
|
|
it₁.extract it₂
|
|
|
|
/- some "a" -/
|
|
#eval
|
|
let s₁ := "abcde" in
|
|
let it₁ := s₁.mk_iterator in
|
|
let it₂ := it₁.next.set_curr 'b' in
|
|
it₁.extract it₂
|
|
|
|
/- some "a" -/
|
|
#eval
|
|
let s₁ := "abcde" in
|
|
let it₁ := s₁.mk_iterator in
|
|
let it₂ := (it₁.next.set_curr 'a').set_curr 'b' in
|
|
it₁.extract it₂
|