github.com/haraldrudell/parl@v0.4.176/pslices/insert.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 "github.com/haraldrudell/parl/perrors" 10 "golang.org/x/exp/constraints" 11 "golang.org/x/exp/slices" 12 ) 13 14 // InsertOrdered inserts value into an ordered slice 15 // - duplicate values are allowed, new values are placed at the end 16 // - insert is O(log n) 17 func InsertOrdered[E constraints.Ordered](slice0 []E, value E) (slice []E) { 18 19 // find position 20 var position int 21 var wasFound bool 22 if position, wasFound = slices.BinarySearch(slice0, value); wasFound { 23 24 // advance beyond last identical value 25 for { 26 position++ 27 if position == len(slice0) || slice0[position] != value { 28 break 29 } 30 } 31 } 32 33 return slices.Insert(slice0, position, value) 34 } 35 36 // InsertOrderedFunc inserts a value into a slice making it ordered using a comparison function. 37 // - duplicate values are allowed, new values are placed at the end 38 // - insert is O(log n) 39 // - cmp function can be provided by E being a type with Cmp method. 40 // - cmp(a, b) is expected to return an integer comparing the two parameters: 41 // 0 if a == b, a negative number if a < b and a positive number if a > b 42 func InsertOrderedFunc[E any](slice0 []E, value E, cmp func(a, b E) (result int)) (slice []E) { 43 44 // obtain comparison function 45 if cmp == nil { 46 panic(perrors.NewPF("cmp cannot be nil")) 47 } 48 49 // find position 50 var position int 51 var wasFound bool 52 if position, wasFound = slices.BinarySearchFunc(slice0, value, cmp); wasFound { 53 54 // advance beyond last identical value 55 for { 56 position++ 57 if position == len(slice0) || cmp(value, slice0[position]) != 0 { 58 break 59 } 60 } 61 } 62 63 return slices.Insert(slice0, position, value) 64 }