github.com/jxskiss/gopkg@v0.17.3/set/template.go (about) 1 // +build ignore 2 3 // This program generates set implementation for concrete types. 4 // It can be invoked by running `go generate`. 5 package main 6 7 import ( 8 "log" 9 "os" 10 "text/template" 11 "time" 12 ) 13 14 type Type struct { 15 Type string 16 SetType string 17 ZeroValue string 18 } 19 20 var targetTypes = []Type{ 21 {"int", "Int", "0"}, 22 {"int32", "Int32", "0"}, 23 {"uint32", "Uint32", "0"}, 24 {"int64", "Int64", "0"}, 25 {"uint64", "Uint64", "0"}, 26 {"string", "String", `""`}, 27 } 28 29 func main() { 30 timestamp := func() func() string { 31 now := time.Now().Format(time.RFC3339) 32 return func() string { return now } 33 }() 34 35 tmpl := template.Must(template.New(""). 36 Funcs(template.FuncMap{"Timestamp": timestamp}). 37 Parse(codetmpl)) 38 39 for _, t := range targetTypes { 40 func() { 41 f, err := os.Create(t.Type + ".go") 42 if err != nil { 43 log.Fatal(err) 44 } 45 defer f.Close() 46 if err = tmpl.Execute(f, t); err != nil { 47 log.Fatal(err) 48 } 49 }() 50 } 51 } 52 53 var codetmpl = `// Code generated by go generate at {{ Timestamp }}; DO NOT EDIT. 54 55 package set 56 57 import "encoding/json" 58 59 // {{ .SetType }} is {{ .Type }} set collection. 60 // The zero value of {{ .SetType }} is an empty instance ready to use. A zero {{ .SetType }} 61 // value shall not be copied, or it may result incorrect behavior. 62 type {{ .SetType }} struct { 63 m map[{{ .Type }}]struct{} 64 } 65 66 // New{{ .SetType }} creates {{ .SetType }} instance. 67 func New{{ .SetType }}(vals ...{{ .Type }}) {{ .SetType }} { 68 size := max(len(vals), minSize) 69 set := {{ .SetType }}{ 70 m: make(map[{{ .Type }}]struct{}, size), 71 } 72 set.Add(vals...) 73 return set 74 } 75 76 // New{{ .SetType }}WithSize creates {{ .SetType }} instance with given initial size. 77 func New{{ .SetType }}WithSize(size int) {{ .SetType }} { 78 set := {{ .SetType }}{ 79 m: make(map[{{ .Type }}]struct{}, size), 80 } 81 return set 82 } 83 84 // Size returns the size of set. 85 func (s {{ .SetType }}) Size() int { return len(s.m) } 86 87 // Add adds values into the set. 88 func (s *{{ .SetType }}) Add(vals ...{{ .Type }}) { 89 if s.m == nil { 90 size := max(len(vals), minSize) 91 s.m = make(map[{{ .Type }}]struct{}, size) 92 } 93 for idx := range vals { 94 s.m[vals[idx]] = struct{}{} 95 } 96 } 97 98 // Del deletes values from the set. 99 func (s *{{ .SetType }}) Del(vals ...{{ .Type }}) { 100 for idx := range vals { 101 delete(s.m, vals[idx]) 102 } 103 } 104 105 // Pop pops an element from the set, in no particular order. 106 func (s *{{ .SetType }}) Pop() {{ .Type }} { 107 for val := range s.m { 108 delete(s.m, val) 109 return val 110 } 111 return {{ .ZeroValue }} 112 } 113 114 // Iterate iterates the set in no particular order and call the given function 115 // for each set element. 116 func (s {{ .SetType }}) Iterate(fn func({{ .Type }})) { 117 for val := range s.m { 118 fn(val) 119 } 120 } 121 122 // Contains returns true if the set contains all the values. 123 func (s {{ .SetType }}) Contains(vals ...{{ .Type }}) bool { 124 if len(vals) == 0 { 125 return false 126 } 127 for _, v := range vals { 128 if _, ok := s.m[v]; !ok { 129 return false 130 } 131 } 132 return true 133 } 134 135 // ContainsAny returns true if the set contains any of the values. 136 func (s {{ .SetType }}) ContainsAny(vals ...{{ .Type }}) bool { 137 for _, v := range vals { 138 if _, ok := s.m[v]; ok { 139 return true 140 } 141 } 142 return false 143 } 144 145 // Diff returns new {{ .SetType }} about the values which other set doesn't contain. 146 func (s {{ .SetType }}) Diff(other {{ .SetType }}) {{ .SetType }} { 147 res := New{{ .SetType }}WithSize(s.Size()) 148 149 for val := range s.m { 150 if _, ok := other.m[val]; !ok { 151 res.m[val] = struct{}{} 152 } 153 } 154 return res 155 } 156 157 // DiffSlice is similar to Diff, but takes a slice as parameter. 158 func (s {{ .SetType }}) DiffSlice(other []{{ .Type }}) {{ .SetType }} { 159 if len(s.m) > len(other) { 160 tmp := New{{ .SetType }}WithSize(len(other)) 161 dup := 0 162 for _, val := range other { 163 if _, ok := s.m[val]; ok { 164 dup++ 165 } 166 tmp.m[val] = struct{}{} 167 } 168 res := New{{ .SetType }}WithSize(max(s.Size()-dup, 0)) 169 for val := range s.m { 170 if _, ok := tmp.m[val]; !ok { 171 res.m[val] = struct{}{} 172 } 173 } 174 return res 175 } else { 176 res := New{{ .SetType }}WithSize(s.Size()) 177 for val := range s.m { 178 res.m[val] = struct{}{} 179 } 180 for _, val := range other { 181 if _, ok := res.m[val]; ok { 182 delete(res.m, val) 183 } 184 } 185 return res 186 } 187 } 188 189 // FilterInclude returns a new slice which contains values that present in 190 // the provided slice and also present in the {{ .SetType }} set. 191 func (s {{ .SetType }}) FilterInclude(slice []{{ .Type }}) []{{ .Type }} { 192 res := make([]{{ .Type }}, 0, min(s.Size(), len(slice))) 193 for _, val := range slice { 194 if _, ok := s.m[val]; ok { 195 res = append(res, val) 196 } 197 } 198 return res 199 } 200 201 // FilterExclude returns a new slice which contains values that present in 202 // the provided slice but don't present in the {{ .SetType }} set. 203 func (s {{ .SetType }}) FilterExclude(slice []{{ .Type }}) []{{ .Type }} { 204 res := make([]{{ .Type }}, 0, len(slice)) 205 for _, val := range slice { 206 if _, ok := s.m[val]; !ok { 207 res = append(res, val) 208 } 209 } 210 return res 211 } 212 213 // Intersect returns new {{ .SetType }} about values which other set also contains. 214 func (s {{ .SetType }}) Intersect(other {{ .SetType }}) {{ .SetType }} { 215 res := New{{ .SetType }}WithSize(min(s.Size(), other.Size())) 216 217 // loop over the smaller set 218 if len(s.m) <= len(other.m) { 219 for val := range s.m { 220 if _, ok := other.m[val]; ok { 221 res.m[val] = struct{}{} 222 } 223 } 224 } else { 225 for val := range other.m { 226 if _, ok := s.m[val]; ok { 227 res.m[val] = struct{}{} 228 } 229 } 230 } 231 return res 232 } 233 234 // IntersectSlice is similar to Intersect, but takes a slice as parameter. 235 func (s {{ .SetType }}) IntersectSlice(other []{{ .Type }}) {{ .SetType }} { 236 res := New{{ .SetType }}WithSize(min(s.Size(), len(other))) 237 238 for _, val := range other { 239 if _, ok := s.m[val]; ok { 240 res.m[val] = struct{}{} 241 } 242 } 243 return res 244 } 245 246 // Union returns new {{ .SetType }} about values either in the set or the other set. 247 func (s {{ .SetType }}) Union(other {{ .SetType }}) {{ .SetType }} { 248 res := New{{ .SetType }}WithSize(s.Size() + other.Size()) 249 250 for val := range s.m { 251 res.m[val] = struct{}{} 252 } 253 for val := range other.m { 254 res.m[val] = struct{}{} 255 } 256 return res 257 } 258 259 // UnionSlice is similar to Union, but takes a slice as parameter. 260 func (s {{ .SetType }}) UnionSlice(other []{{ .Type }}) {{ .SetType }} { 261 res := New{{ .SetType }}WithSize(s.Size() + len(other)) 262 263 for val := range s.m { 264 res.m[val] = struct{}{} 265 } 266 for _, val := range other { 267 res.m[val] = struct{}{} 268 } 269 return res 270 } 271 272 // Slice converts set into {{ .Type }} slice. 273 func (s {{ .SetType }}) Slice() []{{ .Type }} { 274 res := make([]{{ .Type }}, 0, len(s.m)) 275 276 for val := range s.m { 277 res = append(res, val) 278 } 279 return res 280 } 281 282 // Map converts set into map[{{ .Type }}]bool. 283 func (s {{ .SetType }}) Map() map[{{ .Type }}]bool { 284 res := make(map[{{ .Type }}]bool, len(s.m)) 285 286 for val := range s.m { 287 res[val] = true 288 } 289 return res 290 } 291 292 // MarshalJSON implements json.Marshaler interface, the set will be 293 // marshaled as an {{ .Type }} array. 294 func (s {{ .SetType }}) MarshalJSON() ([]byte, error) { 295 res := s.Slice() 296 return json.Marshal(res) 297 } 298 299 // UnmarshalJSON implements json.Unmarshaler interface, it will unmarshal 300 // an {{ .Type }} array to the set. 301 func (s *{{ .SetType }}) UnmarshalJSON(b []byte) error { 302 vals := make([]{{ .Type }}, 0) 303 err := json.Unmarshal(b, &vals) 304 if err == nil { 305 s.Add(vals...) 306 } 307 return err 308 } 309 310 // MarshalYAML implements yaml.Marshaler interface of the yaml package, 311 // the set will be marshaled as an {{ .Type }} array. 312 func (s {{ .SetType }}) MarshalYAML() (interface{}, error) { 313 res := s.Slice() 314 return res, nil 315 } 316 317 // UnmarshalYAML implements yaml.Unmarshaler interface of the yaml package, 318 // it will unmarshal an {{ .Type }} array to the set. 319 func (s *{{ .SetType }}) UnmarshalYAML(unmarshal func(interface{}) error) error { 320 vals := make([]{{ .Type }}, 0) 321 err := unmarshal(&vals) 322 if err == nil { 323 s.Add(vals...) 324 } 325 return err 326 } 327 `