File: BigString%2BAppend.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (198 lines) | stat: -rw-r--r-- 5,890 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift Collections open source project
//
// Copyright (c) 2023 - 2024 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
//
//===----------------------------------------------------------------------===//

#if swift(>=5.8)

@available(macOS 13.3, iOS 16.4, watchOS 9.4, tvOS 16.4, *)
extension BigString {
  mutating func _append(contentsOf other: __owned Substring) {
    if other.isEmpty { return }
    if isEmpty {
      self = Self(other)
      return
    }
    var ingester = _ingester(forInserting: other, at: endIndex, allowForwardPeek: true)
    
    let last = _rope.index(before: _rope.endIndex)
    if let final = _rope[last].append(from: &ingester) {
      precondition(!final.isUndersized)
      _rope.append(final)
      return
    }
    
    // Make a temp rope out of the rest of the chunks and then join the two trees together.
    if !ingester.isAtEnd {
      var builder = _Rope.Builder()
      while let chunk = ingester.nextWellSizedChunk() {
        precondition(!chunk.isUndersized)
        builder.insertBeforeTip(chunk)
      }
      precondition(ingester.isAtEnd)
      _rope = _Rope.join(_rope, builder.finalize())
    }
  }
}

@available(macOS 13.3, iOS 16.4, watchOS 9.4, tvOS 16.4, *)
extension BigString {
  var _firstUnicodeScalar: Unicode.Scalar {
    assert(!isEmpty)
    return _rope.root.firstItem.value.string.unicodeScalars.first!
  }

  mutating func _append(contentsOf other: __owned BigString) {
    guard !other.isEmpty else { return }
    guard !self.isEmpty else {
      self = other
      return
    }

    let hint = other._firstUnicodeScalar
    var other = other._rope    
    var old = _CharacterRecognizer()
    var new = self._breakState(upTo: endIndex, nextScalarHint: hint)
    _ = other.resyncBreaks(old: &old, new: &new)
    _append(other)
  }

  mutating func _append(contentsOf other: __owned BigString, in range: Range<Index>) {
    guard !range._isEmptyUTF8 else { return }
    guard !self.isEmpty else {
      self = Self(_from: other, in: range)
      return
    }

    var other = BigString(_from: other, in: range)
    let hint = other._firstUnicodeScalar
    var old = _CharacterRecognizer()
    var new = self._breakState(upTo: endIndex, nextScalarHint: hint)
    _ = other._rope.resyncBreaks(old: &old, new: &new)
    _append(other._rope)
  }

  mutating func prepend(contentsOf other: __owned BigString) {
    guard !other.isEmpty else { return }
    guard !self.isEmpty else {
      self = other
      return
    }
    let hint = self._firstUnicodeScalar
    var old = _CharacterRecognizer()
    var new = other._breakState(upTo: other.endIndex, nextScalarHint: hint)
    _ = self._rope.resyncBreaks(old: &old, new: &new)
    _prepend(other._rope)
  }

  mutating func prepend(contentsOf other: __owned BigString, in range: Range<Index>) {
    guard !range._isEmptyUTF8 else { return }
    let extract = Self(_from: other, in: range)
    guard !self.isEmpty else {
      self = extract
      return
    }
    let hint = self._firstUnicodeScalar
    var old = _CharacterRecognizer()
    var new = extract._breakState(upTo: extract.endIndex, nextScalarHint: hint)
    _ = self._rope.resyncBreaks(old: &old, new: &new)
    _prepend(extract._rope)
  }
}

@available(macOS 13.3, iOS 16.4, watchOS 9.4, tvOS 16.4, *)
extension BigString {
  var isUndersized: Bool {
    _utf8Count < _Chunk.minUTF8Count
  }
}

@available(macOS 13.3, iOS 16.4, watchOS 9.4, tvOS 16.4, *)
extension BigString {
  /// Note: This assumes `other` already has the correct break positions.
  mutating func _append(_ other: __owned _Chunk) {
    assert(!other.isEmpty)
    guard !self.isEmpty else {
      self._rope.append(other)
      return
    }
    guard self.isUndersized || other.isUndersized else {
      self._rope.append(other)
      return
    }
    var other = other
    let last = self._rope.index(before: self._rope.endIndex)
    if !self._rope[last].rebalance(nextNeighbor: &other) {
      assert(!other.isUndersized)
      self._rope.append(other)
    }
  }
  
  /// Note: This assumes `self` and `other` already have the correct break positions.
  mutating func _prepend(_ other: __owned _Chunk) {
    assert(!other.isEmpty)
    guard !self.isEmpty else {
      self._rope.prepend(other)
      return
    }
    guard self.isUndersized || other.isUndersized else {
      self._rope.prepend(other)
      return
    }
    var other = other
    let first = self._rope.startIndex
    if !self._rope[first].rebalance(prevNeighbor: &other) {
      self._rope.prepend(other)
    }
  }
  
  /// Note: This assumes `other` already has the correct break positions.
  mutating func _append(_ other: __owned _Rope) {
    guard !other.isEmpty else { return }
    guard !self._rope.isEmpty else {
      self._rope = other
      return
    }
    if other.isSingleton {
      self._append(other.first!)
      return
    }
    if self.isUndersized {
      assert(self._rope.isSingleton)
      let chunk = self._rope.first!
      self._rope = other
      self._prepend(chunk)
      return
    }
    self._rope = _Rope.join(self._rope, other)
  }
  
  /// Note: This assumes `self` and `other` already have the correct break positions.
  mutating func _prepend(_ other: __owned _Rope) {
    guard !other.isEmpty else { return }
    guard !self.isEmpty else {
      self._rope = other
      return
    }
    if other.isSingleton {
      self._prepend(other.first!)
      return
    }
    if self.isUndersized {
      assert(self._rope.isSingleton)
      let chunk = self._rope.first!
      self._rope = other
      self._append(chunk)
      return
    }
    self._rope = _Rope.join(other, self._rope)
  }
}

#endif