github.com/haraldrudell/parl@v0.4.176/pslices/slice.go (about) 1 /* 2 © 2022–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/) 3 ISC License 4 */ 5 6 package pslices 7 8 import ( 9 "golang.org/x/exp/slices" 10 ) 11 12 // Slice is a base type for reusable slice implementations 13 // - super-types could implement Insert Delete Index 14 // - Length 15 // - Element single-element access 16 // - Slice multiple-element access 17 // - DeleteIndex delete elements 18 // - Clear Clone 19 // - List clone of n first items 20 // - Slice implements parl.Slice[E any]. 21 type Slice[E any] struct { 22 list []E 23 } 24 25 // Element returns element by index. 26 // if index is negative or the length of the slice or larger, the E zero-value is returned. 27 func (o *Slice[E]) Element(index int) (element E) { 28 if index >= 0 && index < len(o.list) { 29 element = o.list[index] 30 } 31 return 32 } 33 34 // Slice returns a multiple-element sub-slice 35 func (o *Slice[E]) SubSlice(index0, index1 int) (elements []E) { 36 if index0 >= 0 && index0 <= index1 && index1 <= len(o.list) { 37 elements = o.list[index0:index1] 38 } 39 return 40 } 41 42 func (o *Slice[E]) SetElement(index int, element E) { 43 if index < 0 { 44 index = 0 45 } 46 if index >= cap(o.list) { 47 list := o.list 48 o.list = make([]E, index+1) 49 copy(o.list, list) 50 } else if index >= len(o.list) { 51 o.list = o.list[:index+1] 52 } 53 o.list[index] = element 54 } 55 56 // Append adds element at end 57 func (o *Slice[E]) Append(slice []E) { 58 o.list = append(o.list, slice...) 59 } 60 61 // DeleteIndex removes elements by index 62 // - index1 default is slice length 63 func (o *Slice[E]) DeleteIndex(index0 int, index1 ...int) { 64 length := len(o.list) 65 var index2 int 66 if len(index1) > 0 { 67 index2 = index1[0] 68 } else { 69 index2 = length 70 } 71 72 // ensure indexes are valid 73 if index0 < 0 { 74 index0 = 0 75 } else if index0 > length { 76 index0 = length 77 } 78 if index2 < index0 { 79 index2 = index0 80 } else if index2 > length { 81 index2 = length 82 } 83 84 // execute delete 85 if index0 == index2 { 86 return // nothing to do return 87 } else if index0 == 0 { 88 89 // delete at beginning 90 TrimLeft(&o.list, index2) 91 return 92 } else if index2 == length { 93 94 // delete at end 95 SetLength(&o.list, index0) 96 return // delete at end return 97 } 98 99 // delete in the middle 100 deleteCount := index2 - index0 101 copy(o.list[index0:], o.list[index2:]) 102 SetLength(&o.list, length-deleteCount) 103 } 104 105 // Length returns number of elements in the slice 106 func (o *Slice[E]) Length() (index int) { 107 return len(o.list) 108 } 109 110 // Cap returns slice capacity 111 func (o *Slice[E]) Cap() (capacity int) { 112 return cap(o.list) 113 } 114 115 // Clear empties the ordered slice 116 func (o *Slice[E]) Clear() { 117 o.list = o.list[:0] 118 } 119 120 // Clone returns a shallow clone of the slice 121 func (o *Slice[E]) Clone() (clone *Slice[E]) { 122 return &Slice[E]{list: slices.Clone(o.list)} 123 } 124 125 // List returns a clone of the n or all first slice elements 126 func (o *Slice[E]) List(n ...int) (list []E) { 127 length := o.Length() 128 129 // get number of items n0 130 var n0 int 131 if len(n) > 0 { 132 n0 = n[0] 133 } 134 if n0 < 1 || n0 > length { 135 n0 = length 136 } 137 138 return slices.Clone(o.list[:n0]) 139 }