@@ -104,9 +104,10 @@ const commonSliceGenerateTest = `func generateTest${structName}() ${structName}
104104}
105105
106106func fillTest${structName}(tv ${structName}) {
107- tv.Resize(7)
108- for i := 0; i < tv.Len(); i++ {
109- fillTest${elementName}(tv.At(i))
107+ l := 7
108+ tv.EnsureCapacity(l)
109+ for i := 0; i < l; i++ {
110+ fillTest${elementName}(tv.AppendEmpty())
110111 }
111112}`
112113
@@ -119,7 +120,7 @@ const slicePtrTemplate = `// ${structName} logically represents a slice of ${ele
119120// Important: zero-initialized instance is not valid for use.
120121type ${structName} struct {
121122 // orig points to the slice ${originName} field contained somewhere else.
122- // We use pointer-to-slice to be able to modify it in functions like Resize .
123+ // We use pointer-to-slice to be able to modify it in functions like EnsureCapacity .
123124 orig *[]*${originName}
124125}
125126
@@ -128,7 +129,7 @@ func new${structName}(orig *[]*${originName}) ${structName} {
128129}
129130
130131// New${structName} creates a ${structName} with 0 elements.
131- // Can use "Resize " to initialize with a given length .
132+ // Can use "EnsureCapacity " to initialize with a given capacity .
132133func New${structName}() ${structName} {
133134 orig := []*${originName}(nil)
134135 return ${structName}{&orig}
@@ -172,6 +173,28 @@ func (es ${structName}) CopyTo(dest ${structName}) {
172173 *dest.orig = wrappers
173174}
174175
176+ // EnsureCapacity is an operation that ensures the slice has at least the specified capacity.
177+ // 1. If the newCap <= cap then no change in capacity.
178+ // 2. If the newCap > cap then the slice capacity will be expanded to equal newCap.
179+ //
180+ // Here is how a new ${structName} can be initialized:
181+ // es := New${structName}()
182+ // es.EnsureCapacity(4)
183+ // for i := 0; i < 4; i++ {
184+ // e := es.AppendEmpty()
185+ // // Here should set all the values for e.
186+ // }
187+ func (es ${structName}) EnsureCapacity(newCap int) {
188+ oldCap := cap(*es.orig)
189+ if newCap <= oldCap {
190+ return
191+ }
192+
193+ newOrig := make([]*${originName}, len(*es.orig), newCap)
194+ copy(newOrig, *es.orig)
195+ *es.orig = newOrig
196+ }
197+
175198// Resize is an operation that resizes the slice:
176199// 1. If the newLen <= len then equivalent with slice[0:newLen:cap].
177200// 2. If the newLen > len then (newLen - cap) empty elements will be appended to the slice.
@@ -183,20 +206,20 @@ func (es ${structName}) CopyTo(dest ${structName}) {
183206// e := es.At(i)
184207// // Here should set all the values for e.
185208// }
209+ //
210+ // Deprecated: Use EnsureCapacity() and AppendEmpty() instead.
186211func (es ${structName}) Resize(newLen int) {
187212 oldLen := len(*es.orig)
188213 oldCap := cap(*es.orig)
189214 if newLen <= oldLen {
190215 *es.orig = (*es.orig)[:newLen:oldCap]
191216 return
192217 }
193-
194218 if newLen > oldCap {
195219 newOrig := make([]*${originName}, oldLen, newLen)
196220 copy(newOrig, *es.orig)
197221 *es.orig = newOrig
198222 }
199-
200223 // Add extra empty elements to the array.
201224 extraOrigs := make([]${originName}, newLen-oldLen)
202225 for i := range extraOrigs {
@@ -209,22 +232,23 @@ func (es ${structName}) Resize(newLen int) {
209232func (es ${structName}) AppendEmpty() ${elementName} {
210233 *es.orig = append(*es.orig, &${originName}{})
211234 return es.At(es.Len() - 1)
212- }`
235+ } `
213236
214237const slicePtrTestTemplate = `func Test${structName}(t *testing.T) {
215238 es := New${structName}()
216239 assert.EqualValues(t, 0, es.Len())
217240 es = new${structName}(&[]*${originName}{})
218241 assert.EqualValues(t, 0, es.Len())
219242
220- es.Resize (7)
243+ es.EnsureCapacity (7)
221244 emptyVal := new${elementName}(&${originName}{})
222245 testVal := generateTest${elementName}()
223- assert.EqualValues(t, 7, es.Len( ))
246+ assert.EqualValues(t, 7, cap(* es.orig ))
224247 for i := 0; i < es.Len(); i++ {
225- assert.EqualValues(t, emptyVal, es.At(i))
226- fillTest${elementName}(es.At(i))
227- assert.EqualValues(t, testVal, es.At(i))
248+ el := es.AppendEmpty()
249+ assert.EqualValues(t, emptyVal, el)
250+ fillTest${elementName}(el)
251+ assert.EqualValues(t, testVal, el)
228252 }
229253}
230254
@@ -243,46 +267,38 @@ func Test${structName}_CopyTo(t *testing.T) {
243267 assert.EqualValues(t, generateTest${structName}(), dest)
244268}
245269
246- func Test${structName}_Resize (t *testing.T) {
270+ func Test${structName}_EnsureCapacity (t *testing.T) {
247271 es := generateTest${structName}()
248- emptyVal := new${elementName}(&${originName}{})
249- // Test Resize less elements.
250- const resizeSmallLen = 4
251- expectedEs := make(map[*${originName}]bool, resizeSmallLen)
252- for i := 0; i < resizeSmallLen; i++ {
272+ // Test ensure smaller capacity.
273+ const ensureSmallLen = 4
274+ expectedEs := make(map[*${originName}]bool)
275+ for i := 0; i < es.Len(); i++ {
253276 expectedEs[es.At(i).orig] = true
254277 }
255- assert.Equal(t, resizeSmallLen , len(expectedEs))
256- es.Resize(resizeSmallLen )
257- assert.Equal (t, resizeSmallLen , es.Len())
258- foundEs := make(map[*${originName}]bool, resizeSmallLen )
278+ assert.Equal(t, es.Len() , len(expectedEs))
279+ es.EnsureCapacity(ensureSmallLen )
280+ assert.Less (t, ensureSmallLen , es.Len())
281+ foundEs := make(map[*${originName}]bool, es.Len() )
259282 for i := 0; i < es.Len(); i++ {
260283 foundEs[es.At(i).orig] = true
261284 }
262285 assert.EqualValues(t, expectedEs, foundEs)
263286
264- // Test Resize more elements.
265- const resizeLargeLen = 7
287+ // Test ensure larger capacity
288+ const ensureLargeLen = 9
266289 oldLen := es.Len()
267290 expectedEs = make(map[*${originName}]bool, oldLen)
268291 for i := 0; i < oldLen; i++ {
269292 expectedEs[es.At(i).orig] = true
270293 }
271294 assert.Equal(t, oldLen, len(expectedEs))
272- es.Resize(resizeLargeLen )
273- assert.Equal(t, resizeLargeLen, es.Len( ))
295+ es.EnsureCapacity(ensureLargeLen )
296+ assert.Equal(t, ensureLargeLen, cap(* es.orig ))
274297 foundEs = make(map[*${originName}]bool, oldLen)
275298 for i := 0; i < oldLen; i++ {
276299 foundEs[es.At(i).orig] = true
277300 }
278301 assert.EqualValues(t, expectedEs, foundEs)
279- for i := oldLen; i < resizeLargeLen; i++ {
280- assert.EqualValues(t, emptyVal, es.At(i))
281- }
282-
283- // Test Resize 0 elements.
284- es.Resize(0)
285- assert.Equal(t, 0, es.Len())
286302}`
287303
288304const sliceValueTemplate = `// ${structName} logically represents a slice of ${elementName}.
@@ -294,7 +310,7 @@ const sliceValueTemplate = `// ${structName} logically represents a slice of ${e
294310// Important: zero-initialized instance is not valid for use.
295311type ${structName} struct {
296312 // orig points to the slice ${originName} field contained somewhere else.
297- // We use pointer-to-slice to be able to modify it in functions like Resize .
313+ // We use pointer-to-slice to be able to modify it in functions like EnsureCapacity .
298314 orig *[]${originName}
299315}
300316
@@ -303,7 +319,7 @@ func new${structName}(orig *[]${originName}) ${structName} {
303319}
304320
305321// New${structName} creates a ${structName} with 0 elements.
306- // Can use "Resize " to initialize with a given length .
322+ // Can use "EnsureCapacity " to initialize with a given capacity .
307323func New${structName}() ${structName} {
308324 orig := []${originName}(nil)
309325 return ${structName}{&orig}
@@ -342,6 +358,28 @@ func (es ${structName}) CopyTo(dest ${structName}) {
342358 }
343359}
344360
361+ // EnsureCapacity is an operation that ensures the slice has at least the specified capacity.
362+ // 1. If the newCap <= cap then no change in capacity.
363+ // 2. If the newCap > cap then the slice capacity will be expanded to equal newCap.
364+ //
365+ // Here is how a new ${structName} can be initialized:
366+ // es := New${structName}()
367+ // es.EnsureCapacity(4)
368+ // for i := 0; i < 4; i++ {
369+ // e := es.AppendEmpty()
370+ // // Here should set all the values for e.
371+ // }
372+ func (es ${structName}) EnsureCapacity(newCap int) {
373+ oldCap := cap(*es.orig)
374+ if newCap <= oldCap {
375+ return
376+ }
377+
378+ newOrig := make([]${originName}, len(*es.orig), newCap)
379+ copy(newOrig, *es.orig)
380+ *es.orig = newOrig
381+ }
382+
345383// Resize is an operation that resizes the slice:
346384// 1. If the newLen <= len then equivalent with slice[0:newLen:cap].
347385// 2. If the newLen > len then (newLen - cap) empty elements will be appended to the slice.
@@ -353,20 +391,20 @@ func (es ${structName}) CopyTo(dest ${structName}) {
353391// e := es.At(i)
354392// // Here should set all the values for e.
355393// }
394+ //
395+ // Deprecated: Use EnsureCapacity() and AppendEmpty() instead.
356396func (es ${structName}) Resize(newLen int) {
357397 oldLen := len(*es.orig)
358398 oldCap := cap(*es.orig)
359399 if newLen <= oldLen {
360400 *es.orig = (*es.orig)[:newLen:oldCap]
361401 return
362402 }
363-
364403 if newLen > oldCap {
365404 newOrig := make([]${originName}, oldLen, newLen)
366405 copy(newOrig, *es.orig)
367406 *es.orig = newOrig
368407 }
369-
370408 // Add extra empty elements to the array.
371409 empty := ${originName}{}
372410 for i := oldLen; i < newLen; i++ {
@@ -387,14 +425,15 @@ const sliceValueTestTemplate = `func Test${structName}(t *testing.T) {
387425 es = new${structName}(&[]${originName}{})
388426 assert.EqualValues(t, 0, es.Len())
389427
390- es.Resize (7)
428+ es.EnsureCapacity (7)
391429 emptyVal := new${elementName}(&${originName}{})
392430 testVal := generateTest${elementName}()
393- assert.EqualValues(t, 7, es.Len( ))
431+ assert.EqualValues(t, 7, cap(* es.orig ))
394432 for i := 0; i < es.Len(); i++ {
395- assert.EqualValues(t, emptyVal, es.At(i))
396- fillTest${elementName}(es.At(i))
397- assert.EqualValues(t, testVal, es.At(i))
433+ el := es.AppendEmpty()
434+ assert.EqualValues(t, emptyVal, el)
435+ fillTest${elementName}(el)
436+ assert.EqualValues(t, testVal, el)
398437 }
399438}
400439
@@ -413,46 +452,29 @@ func Test${structName}_CopyTo(t *testing.T) {
413452 assert.EqualValues(t, generateTest${structName}(), dest)
414453}
415454
416- func Test${structName}_Resize (t *testing.T) {
455+ func Test${structName}_EnsureCapacity (t *testing.T) {
417456 es := generateTest${structName}()
418- emptyVal := new${elementName}(&${originName}{})
419- // Test Resize less elements.
420- const resizeSmallLen = 4
421- expectedEs := make(map[*${originName}]bool, resizeSmallLen)
422- for i := 0; i < resizeSmallLen; i++ {
457+ // Test ensure smaller capacity.
458+ const ensureSmallLen = 4
459+ expectedEs := make(map[*${originName}]bool)
460+ for i := 0; i < es.Len(); i++ {
423461 expectedEs[es.At(i).orig] = true
424462 }
425- assert.Equal(t, resizeSmallLen , len(expectedEs))
426- es.Resize(resizeSmallLen )
427- assert.Equal (t, resizeSmallLen , es.Len())
428- foundEs := make(map[*${originName}]bool, resizeSmallLen )
463+ assert.Equal(t, es.Len() , len(expectedEs))
464+ es.EnsureCapacity(ensureSmallLen )
465+ assert.Less (t, ensureSmallLen , es.Len())
466+ foundEs := make(map[*${originName}]bool, es.Len() )
429467 for i := 0; i < es.Len(); i++ {
430468 foundEs[es.At(i).orig] = true
431469 }
432470 assert.EqualValues(t, expectedEs, foundEs)
433471
434- // Test Resize more elements.
435- const resizeLargeLen = 7
472+ // Test ensure larger capacity
473+ const ensureLargeLen = 9
436474 oldLen := es.Len()
437- expectedEs = make(map[*${originName}]bool, oldLen)
438- for i := 0; i < oldLen; i++ {
439- expectedEs[es.At(i).orig] = true
440- }
441475 assert.Equal(t, oldLen, len(expectedEs))
442- es.Resize(resizeLargeLen)
443- assert.Equal(t, resizeLargeLen, es.Len())
444- foundEs = make(map[*${originName}]bool, oldLen)
445- for i := 0; i < oldLen; i++ {
446- foundEs[es.At(i).orig] = true
447- }
448- assert.EqualValues(t, expectedEs, foundEs)
449- for i := oldLen; i < resizeLargeLen; i++ {
450- assert.EqualValues(t, emptyVal, es.At(i))
451- }
452-
453- // Test Resize 0 elements.
454- es.Resize(0)
455- assert.Equal(t, 0, es.Len())
476+ es.EnsureCapacity(ensureLargeLen)
477+ assert.Equal(t, ensureLargeLen, cap(*es.orig))
456478}`
457479
458480type baseSlice interface {
0 commit comments