@@ -22,21 +22,21 @@ import (
22
22
const commonSliceTemplate = `
23
23
// MoveAndAppendTo moves all elements from the current slice and appends them to the dest.
24
24
// The current slice will be cleared.
25
- func (es ${structName}) MoveAndAppendTo(dest ${structName}) {
26
- if *dest.orig == nil {
25
+ func (es mutable ${structName}) MoveAndAppendTo(dest mutable ${structName}) {
26
+ if *dest.getOrig() == nil {
27
27
// We can simply move the entire vector and avoid any allocations.
28
- *dest.orig = *es.orig
28
+ *dest.getOrig() = *es.getOrig()
29
29
} else {
30
- *dest.orig = append(*dest.orig , *es.orig ...)
30
+ *dest.getOrig() = append(*dest.getOrig() , *es.getOrig() ...)
31
31
}
32
- *es.orig = nil
32
+ *es.getOrig() = nil
33
33
}
34
34
35
35
// RemoveIf calls f sequentially for each element present in the slice.
36
36
// If f returns true, the element is removed from the slice.
37
- func (es ${structName}) RemoveIf(f func(${elementName}) bool) {
37
+ func (es mutable ${structName}) RemoveIf(f func(Mutable ${elementName}) bool) {
38
38
newLen := 0
39
- for i := 0; i < len(*es.orig ); i++ {
39
+ for i := 0; i < len(*es.getOrig() ); i++ {
40
40
if f(es.At(i)) {
41
41
continue
42
42
}
@@ -45,7 +45,7 @@ func (es ${structName}) RemoveIf(f func(${elementName}) bool) {
45
45
newLen++
46
46
continue
47
47
}
48
- (*es.orig) [newLen] = (*es.orig )[i]
48
+ (*es.getOrig()) [newLen] = (*es.getOrig() )[i]
49
49
newLen++
50
50
}
51
51
// TODO: Prevent memory leak by erasing truncated values.
@@ -98,32 +98,57 @@ func Test${structName}_RemoveIf(t *testing.T) {
98
98
}`
99
99
100
100
const slicePtrTemplate = `// ${structName} logically represents a slice of ${elementName}.
101
- //
102
- // This is a reference type. If passed by value and callee modifies it, the
103
- // caller will see the modification.
104
- //
105
- // Must use New${structName} function to create new instances.
106
- // Important: zero-initialized instance is not valid for use.
107
- type ${structName} struct {
101
+ type ${structName} interface {
102
+ common${structName}
103
+ At(ix int) ${elementName}
104
+ }
105
+
106
+ type Mutable${structName} interface {
107
+ common${structName}
108
+ At(ix int) Mutable${elementName}
109
+ EnsureCapacity(newCap int)
110
+ AppendEmpty() Mutable${elementName}
111
+ Sort(less func(a, b Mutable${elementName}) bool)
112
+ }
113
+
114
+ type common${structName} interface {
115
+ Len() int
116
+ CopyTo(dest Mutable${structName})
117
+ getOrig() *[]*${originName}
118
+ }
119
+
120
+ type immutable${structName} struct {
108
121
orig *[]*${originName}
109
122
}
110
123
111
- func new${structName}(orig *[]*${originName}) ${structName} {
112
- return ${structName}{orig}
124
+ type mutable${structName} struct {
125
+ immutable${structName}
126
+ }
127
+
128
+ func (es immutable${structName}) getOrig() *[]*${originName} {
129
+ return es.orig
130
+ }
131
+
132
+ func newImmutable${structName}(orig *[]*${originName}) immutable${structName} {
133
+ return immutable${structName}{orig}
134
+ }
135
+
136
+ func newMutable${structName}(orig *[]*${originName}) mutable${structName} {
137
+ return mutable${structName}{immutable${structName}{orig}}
113
138
}
114
139
115
140
// New${structName} creates a ${structName} with 0 elements.
116
141
// Can use "EnsureCapacity" to initialize with a given capacity.
117
- func New${structName}() ${structName} {
142
+ func New${structName}() Mutable ${structName} {
118
143
orig := []*${originName}(nil)
119
- return new ${structName}(&orig)
144
+ return newMutable ${structName}(&orig)
120
145
}
121
146
122
147
// Len returns the number of elements in the slice.
123
148
//
124
149
// Returns "0" for a newly instance created with "New${structName}()".
125
- func (es ${structName}) Len() int {
126
- return len(*es.orig )
150
+ func (es immutable ${structName}) Len() int {
151
+ return len(*es.getOrig() )
127
152
}
128
153
129
154
// At returns the element at the given index.
@@ -133,28 +158,32 @@ func (es ${structName}) Len() int {
133
158
// e := es.At(i)
134
159
// ... // Do something with the element
135
160
// }
136
- func (es ${structName}) At(ix int) ${elementName} {
137
- return new${elementName}((*es.orig)[ix])
161
+ func (es immutable${structName}) At(ix int) ${elementName} {
162
+ return newImmutable${elementName}((*es.getOrig())[ix])
163
+ }
164
+
165
+ func (es mutable${structName}) At(ix int) Mutable${elementName} {
166
+ return newMutable${elementName}((*es.getOrig())[ix])
138
167
}
139
168
140
169
// CopyTo copies all elements from the current slice overriding the destination.
141
- func (es ${structName}) CopyTo(dest ${structName}) {
170
+ func (es immutable ${structName}) CopyTo(dest Mutable ${structName}) {
142
171
srcLen := es.Len()
143
- destCap := cap(*dest.orig )
172
+ destCap := cap(*dest.getOrig() )
144
173
if srcLen <= destCap {
145
- (*dest.orig) = (*dest.orig )[:srcLen:destCap]
146
- for i := range *es.orig {
147
- new ${elementName}((*es.orig) [i]).CopyTo(new ${elementName}((*dest.orig )[i]))
174
+ (*dest.getOrig()) = (*dest.getOrig() )[:srcLen:destCap]
175
+ for i := range *es.getOrig() {
176
+ newImmutable ${elementName}((*es.getOrig()) [i]).CopyTo(newMutable ${elementName}((*dest.getOrig() )[i]))
148
177
}
149
178
return
150
179
}
151
180
origs := make([]${originName}, srcLen)
152
181
wrappers := make([]*${originName}, srcLen)
153
- for i := range *es.orig {
182
+ for i := range *es.getOrig() {
154
183
wrappers[i] = &origs[i]
155
- new ${elementName}((*es.orig) [i]).CopyTo(new ${elementName}(wrappers[i]))
184
+ newImmutable ${elementName}((*es.getOrig()) [i]).CopyTo(newMutable ${elementName}(wrappers[i]))
156
185
}
157
- *dest.orig = wrappers
186
+ *dest.getOrig() = wrappers
158
187
}
159
188
160
189
// EnsureCapacity is an operation that ensures the slice has at least the specified capacity.
@@ -168,29 +197,29 @@ func (es ${structName}) CopyTo(dest ${structName}) {
168
197
// e := es.AppendEmpty()
169
198
// // Here should set all the values for e.
170
199
// }
171
- func (es ${structName}) EnsureCapacity(newCap int) {
172
- oldCap := cap(*es.orig )
200
+ func (es mutable ${structName}) EnsureCapacity(newCap int) {
201
+ oldCap := cap(*es.getOrig() )
173
202
if newCap <= oldCap {
174
203
return
175
204
}
176
205
177
- newOrig := make([]*${originName}, len(*es.orig ), newCap)
178
- copy(newOrig, *es.orig )
179
- *es.orig = newOrig
206
+ newOrig := make([]*${originName}, len(*es.getOrig() ), newCap)
207
+ copy(newOrig, *es.getOrig() )
208
+ *es.getOrig() = newOrig
180
209
}
181
210
182
211
// AppendEmpty will append to the end of the slice an empty ${elementName}.
183
212
// It returns the newly added ${elementName}.
184
- func (es ${structName}) AppendEmpty() ${elementName} {
185
- *es.orig = append(*es.orig , &${originName}{})
213
+ func (es mutable ${structName}) AppendEmpty() Mutable ${elementName} {
214
+ *es.getOrig() = append(*es.getOrig() , &${originName}{})
186
215
return es.At(es.Len() - 1)
187
216
}
188
217
189
218
// Sort sorts the ${elementName} elements within ${structName} given the
190
219
// provided less function so that two instances of ${structName}
191
220
// can be compared.
192
- func (es ${structName}) Sort(less func(a, b ${elementName}) bool) {
193
- sort.SliceStable(*es.orig , func(i, j int) bool { return less(es.At(i), es.At(j)) })
221
+ func (es mutable ${structName}) Sort(less func(a, b Mutable ${elementName}) bool) {
222
+ sort.SliceStable(*es.getOrig() , func(i, j int) bool { return less(es.At(i), es.At(j)) })
194
223
}
195
224
`
196
225
@@ -278,31 +307,56 @@ func fillTest${structName}(tv ${structName}) {
278
307
}`
279
308
280
309
const sliceValueTemplate = `// ${structName} logically represents a slice of ${elementName}.
281
- //
282
- // This is a reference type. If passed by value and callee modifies it, the
283
- // caller will see the modification.
284
- //
285
- // Must use New${structName} function to create new instances.
286
- // Important: zero-initialized instance is not valid for use.
287
- type ${structName} struct {
310
+ type ${structName} interface {
311
+ common${structName}
312
+ At(ix int) ${elementName}
313
+ }
314
+
315
+ type Mutable${structName} interface {
316
+ common${structName}
317
+ RemoveIf(f func(Mutable${elementName}) bool)
318
+ At(ix int) Mutable${elementName}
319
+ EnsureCapacity(newCap int)
320
+ AppendEmpty() Mutable${elementName}
321
+ }
322
+
323
+ type common${structName} interface {
324
+ Len() int
325
+ CopyTo(dest Mutable${structName})
326
+ getOrig() *[]${originName}
327
+ }
328
+
329
+ type immutable${structName} struct {
288
330
orig *[]${originName}
289
331
}
290
332
291
- func new${structName}(orig *[]${originName}) ${structName} {
292
- return ${structName}{orig}
333
+ type mutable${structName} struct {
334
+ immutable${structName}
335
+ }
336
+
337
+ func newImmutable${structName}(orig *[]${originName}) immutable${structName} {
338
+ return immutable${structName}{orig}
339
+ }
340
+
341
+ func newMutable${structName}(orig *[]${originName}) mutable${structName} {
342
+ return mutable${structName}{immutable${structName}{orig}}
343
+ }
344
+
345
+ func (es immutable${structName}) getOrig() *[]${originName} {
346
+ return es.orig
293
347
}
294
348
295
349
// New${structName} creates a ${structName} with 0 elements.
296
350
// Can use "EnsureCapacity" to initialize with a given capacity.
297
- func New${structName}() ${structName} {
351
+ func New${structName}() Mutable ${structName} {
298
352
orig := []${originName}(nil)
299
- return new ${structName}(&orig)
353
+ return newMutable ${structName}(&orig)
300
354
}
301
355
302
356
// Len returns the number of elements in the slice.
303
357
//
304
358
// Returns "0" for a newly instance created with "New${structName}()".
305
- func (es ${structName}) Len() int {
359
+ func (es immutable ${structName}) Len() int {
306
360
return len(*es.orig)
307
361
}
308
362
@@ -313,22 +367,26 @@ func (es ${structName}) Len() int {
313
367
// e := es.At(i)
314
368
// ... // Do something with the element
315
369
// }
316
- func (es ${structName}) At(ix int) ${elementName} {
317
- return new${elementName}(&(*es.orig)[ix])
370
+ func (es immutable${structName}) At(ix int) ${elementName} {
371
+ return newImmutable${elementName}(&(*es.orig)[ix])
372
+ }
373
+
374
+ func (es mutable${structName}) At(ix int) Mutable${elementName} {
375
+ return newMutable${elementName}(&(*es.getOrig())[ix])
318
376
}
319
377
320
378
// CopyTo copies all elements from the current slice overriding the destination.
321
- func (es ${structName}) CopyTo(dest ${structName}) {
379
+ func (es immutable ${structName}) CopyTo(dest Mutable ${structName}) {
322
380
srcLen := es.Len()
323
- destCap := cap(*dest.orig )
381
+ destCap := cap(*dest.getOrig() )
324
382
if srcLen <= destCap {
325
- (*dest.orig) = (*dest.orig )[:srcLen:destCap]
383
+ (*dest.getOrig()) = (*dest.getOrig() )[:srcLen:destCap]
326
384
} else {
327
- (*dest.orig ) = make([]${originName}, srcLen)
385
+ (*dest.getOrig() ) = make([]${originName}, srcLen)
328
386
}
329
387
330
- for i := range *es.orig {
331
- new ${elementName}(&(*es.orig) [i]).CopyTo(new ${elementName}(&(*dest.orig )[i]))
388
+ for i := range *es.getOrig() {
389
+ newImmutable ${elementName}(&(*es.getOrig()) [i]).CopyTo(newMutable ${elementName}(&(*dest.getOrig() )[i]))
332
390
}
333
391
}
334
392
@@ -343,21 +401,21 @@ func (es ${structName}) CopyTo(dest ${structName}) {
343
401
// e := es.AppendEmpty()
344
402
// // Here should set all the values for e.
345
403
// }
346
- func (es ${structName}) EnsureCapacity(newCap int) {
347
- oldCap := cap(*es.orig )
404
+ func (es mutable ${structName}) EnsureCapacity(newCap int) {
405
+ oldCap := cap(*es.getOrig() )
348
406
if newCap <= oldCap {
349
407
return
350
408
}
351
409
352
- newOrig := make([]${originName}, len(*es.orig ), newCap)
353
- copy(newOrig, *es.orig )
354
- *es.orig = newOrig
410
+ newOrig := make([]${originName}, len(*es.getOrig() ), newCap)
411
+ copy(newOrig, *es.getOrig() )
412
+ *es.getOrig() = newOrig
355
413
}
356
414
357
415
// AppendEmpty will append to the end of the slice an empty ${elementName}.
358
416
// It returns the newly added ${elementName}.
359
- func (es ${structName}) AppendEmpty() ${elementName} {
360
- *es.orig = append(*es.orig , ${originName}{})
417
+ func (es mutable ${structName}) AppendEmpty() Mutable ${elementName} {
418
+ *es.getOrig() = append(*es.getOrig() , ${originName}{})
361
419
return es.At(es.Len() - 1)
362
420
}`
363
421
@@ -481,7 +539,7 @@ func (ss *sliceOfPtrs) templateFields() func(name string) string {
481
539
}
482
540
}
483
541
484
- func (ss * sliceOfPtrs ) generateInternal (_ * bytes.Buffer ) {}
542
+ func (ss * sliceOfPtrs ) generateAliases (_ * bytes.Buffer ) {}
485
543
486
544
var _ baseStruct = (* sliceOfPtrs )(nil )
487
545
@@ -529,6 +587,6 @@ func (ss *sliceOfValues) templateFields() func(name string) string {
529
587
}
530
588
}
531
589
532
- func (ss * sliceOfValues ) generateInternal (_ * bytes.Buffer ) {}
590
+ func (ss * sliceOfValues ) generateAliases (_ * bytes.Buffer ) {}
533
591
534
592
var _ baseStruct = (* sliceOfValues )(nil )
0 commit comments