@@ -40,7 +40,7 @@ extension ManagedBufferPointer
4040
4141struct CountAndCapacity {
4242 var count : LifetimeTracked
43- let capacity : Int
43+ var capacity : Int
4444}
4545
4646// An example of ManagedBuffer, very similar to what Array will use.
@@ -96,6 +96,23 @@ final class TestManagedBuffer<T> : ManagedBuffer<CountAndCapacity, T> {
9696 }
9797 self . count = count + 2
9898 }
99+
100+ class func tryGrow( _ buffer: inout TestManagedBuffer < T > , newCapacity: Int ) -> Bool {
101+ guard isKnownUniquelyReferenced ( & buffer) else {
102+ return false
103+ }
104+ guard newCapacity > buffer. capacity else {
105+ return false
106+ }
107+
108+ if tryReallocateUniquelyReferenced ( buffer: & buffer,
109+ newMinimumCapacity: newCapacity) {
110+ buffer. header. capacity = newCapacity
111+ return true
112+ } else {
113+ return false
114+ }
115+ }
99116}
100117
101118class MyBuffer < T> {
@@ -241,4 +258,35 @@ tests.test("isKnownUniquelyReferenced") {
241258 _fixLifetime ( s2)
242259}
243260
261+ tests. test ( " canGrowUsingRealloc " ) {
262+ #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
263+ return // realloc currently unsupported on Darwin
264+ #endif
265+ func testGrow( _ buffer: inout TestManagedBuffer < LifetimeTracked > ,
266+ newCapacity: Int ,
267+ shouldSucceed: Bool = true ) {
268+ let s = TestManagedBuffer . tryGrow ( & buffer, newCapacity: newCapacity)
269+ expectEqual ( s, shouldSucceed)
270+ if shouldSucceed {
271+ expectLE ( newCapacity, buffer. myCapacity)
272+ expectGE ( ( newCapacity + 1 ) * 2 , buffer. myCapacity)
273+ }
274+ repeat {
275+ buffer. append ( LifetimeTracked ( buffer. count) )
276+ } while buffer. count < buffer. myCapacity - 2
277+ }
278+
279+ var b = TestManagedBuffer< LifetimeTracked> . create( 0 )
280+ // allow some over-allocation
281+ expectLE ( 0 , b. myCapacity)
282+ expectGE ( 3 , b. myCapacity)
283+
284+ testGrow ( & b, newCapacity: 5 )
285+ testGrow ( & b, newCapacity: 8 )
286+ testGrow ( & b, newCapacity: 1000 )
287+ testGrow ( & b, newCapacity: 16000 )
288+ var b2 = b
289+ testGrow ( & b, newCapacity: 2000 , shouldSucceed: false )
290+ }
291+
244292runAllTests ( )
0 commit comments