@@ -37,7 +37,29 @@ internal struct _FixedArray${N}<T> {
3737 )
3838
3939 @_versioned // FIXME(sil-serialize-all)
40- internal static var _arraySize : Int { return ${ N} }
40+ var _count : Int8
41+ }
42+
43+
44+ extension _FixedArray ${ N} {
45+ @_inlineable // FIXME(sil-serialize-all)
46+ @_versioned // FIXME(sil-serialize-all)
47+ internal static var capacity : Int {
48+ @inline ( __always) get { return ${ N} }
49+ }
50+
51+ @_inlineable // FIXME(sil-serialize-all)
52+ @_versioned // FIXME(sil-serialize-all)
53+ internal var capacity : Int {
54+ @inline ( __always) get { return ${ N} }
55+ }
56+
57+ @_inlineable // FIXME(sil-serialize-all)
58+ @_versioned // FIXME(sil-serialize-all)
59+ internal var count : Int {
60+ @inline ( __always) get { return Int ( truncatingIfNeeded: _count) }
61+ @inline ( __always) set { _count = Int8 ( newValue) }
62+ }
4163}
4264
4365extension _FixedArray ${ N} : Rando mAccessCollection, MutableCollection {
@@ -52,18 +74,17 @@ extension _FixedArray${N} : RandomAccessCollection, MutableCollection {
5274 @_inlineable // FIXME(sil-serialize-all)
5375 @_versioned // FIXME(sil-serialize-all)
5476 internal var endIndex : Index {
55- return _FixedArray $ { N } . _arraySize
77+ return count
5678 }
5779
58- @_versioned // FIXME(sil-serialize-all)
59- internal var count : Int { return _FixedArray ${ N} . _arraySize }
60-
6180 @_inlineable // FIXME(sil-serialize-all)
6281 @_versioned // FIXME(sil-serialize-all)
6382 internal subscript( i: Index) - > T {
6483 @_versioned
6584 @inline ( __always)
6685 get {
86+ let count = self . count // for exclusive access
87+ _sanityCheck ( i >= 0 && i < count)
6788 var copy = storage
6889 let res : T = withUnsafeBytes ( of: & copy) {
6990 ( rawPtr : UnsafeRawBufferPointer ) -> T in
@@ -79,16 +100,9 @@ extension _FixedArray${N} : RandomAccessCollection, MutableCollection {
79100 @_versioned
80101 @inline ( __always)
81102 set {
82- let count = self . count
83- withUnsafeBytes ( of: & storage) {
84- ( rawPtr : UnsafeRawBufferPointer ) -> ( ) in
85- let rawPtr = UnsafeMutableRawBufferPointer ( mutating: rawPtr)
86- let stride = MemoryLayout< T> . stride
87- _sanityCheck ( rawPtr. count == ${ N} * stride, " layout mismatch? " )
88- let bufPtr = UnsafeMutableBufferPointer (
89- start: rawPtr. baseAddress!. assumingMemoryBound ( to: T . self) ,
90- count: count)
91- bufPtr [ i] = newValue
103+ _sanityCheck ( i >= 0 && i < count)
104+ self . withUnsafeMutableBufferPointer { buffer in
105+ buffer [ i] = newValue
92106 }
93107 }
94108 }
@@ -106,22 +120,45 @@ extension _FixedArray${N} : RandomAccessCollection, MutableCollection {
106120 internal func index( before i: Index ) -> Index {
107121 return i- 1
108122 }
123+ }
109124
110- // TODO: Any customization hooks it's profitable to override, e.g. append?
111-
125+ extension _FixedArray ${ N} {
126+ @_inlineable // FIXME(sil-serialize-all)
127+ @_versioned
128+ internal mutating func append( _ newElement: T ) {
129+ _sanityCheck ( count < capacity)
130+ self [ count] = newElement
131+ _count += 1
132+ }
112133}
113134
114135extension _FixedArray ${ N} where T : ExpressibleByIntegerLiteral {
115136 @_inlineable // FIXME(sil-serialize-all)
116137 @_versioned // FIXME(sil-serialize-all)
117138 @inline ( __always)
118- internal init ( allZeros: ( ) ) {
139+ internal init ( count: Int ) {
140+ _sanityCheck ( count >= 0 && count <= _FixedArray${ N} . capacity)
119141 self . storage = (
120142% for i in range( 0 , N- 1 ) :
121143 0 ,
122144% end
123145 0
124146 )
147+ self . _count = Int8 ( truncatingIfNeeded: count)
148+ }
149+
150+ @_inlineable // FIXME(sil-serialize-all)
151+ @_versioned // FIXME(sil-serialize-all)
152+ @inline ( __always)
153+ internal init ( ) {
154+ self . init ( count: 0 )
155+ }
156+
157+ @_inlineable // FIXME(sil-serialize-all)
158+ @_versioned // FIXME(sil-serialize-all)
159+ @inline ( __always)
160+ internal init ( allZeros: ( ) ) {
161+ self . init ( count: ${ N} )
125162 }
126163}
127164
@@ -131,8 +168,10 @@ extension _FixedArray${N} {
131168 internal mutating func withUnsafeMutableBufferPointer< R> (
132169 _ body: ( UnsafeMutableBufferPointer < Element > ) throws -> R
133170 ) rethrows -> R {
134- let count = self . count
171+ let count = self . count // for exclusive access
135172 return try withUnsafeMutableBytes ( of: & storage) { rawBuffer in
173+ _sanityCheck ( rawBuffer. count == ${ N} * MemoryLayout< T> . stride,
174+ " layout mismatch? " )
136175 let buffer = UnsafeMutableBufferPointer < Element > (
137176 start: rawBuffer. baseAddress. _unsafelyUnwrappedUnchecked
138177 . assumingMemoryBound ( to: Element . self) ,
@@ -146,8 +185,10 @@ extension _FixedArray${N} {
146185 internal mutating func withUnsafeBufferPointer< R> (
147186 _ body: ( UnsafeBufferPointer < Element > ) throws -> R
148187 ) rethrows -> R {
149- let count = self . count
188+ let count = self . count // for exclusive access
150189 return try withUnsafeBytes ( of: & storage) { rawBuffer in
190+ _sanityCheck ( rawBuffer. count == ${ N} * MemoryLayout< T> . stride,
191+ " layout mismatch? " )
151192 let buffer = UnsafeBufferPointer < Element > (
152193 start: rawBuffer. baseAddress. _unsafelyUnwrappedUnchecked
153194 . assumingMemoryBound ( to: Element . self) ,
0 commit comments