github.com/haraldrudell/parl@v0.4.176/sets/basic-set.go (about) 1 /* 2 © 2023–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/) 3 ISC License 4 */ 5 6 package sets 7 8 import ( 9 "github.com/haraldrudell/parl/iters" 10 "github.com/haraldrudell/parl/perrors" 11 "github.com/haraldrudell/parl/pfmt" 12 "github.com/haraldrudell/parl/plog" 13 ) 14 15 // BasicSet elements are basic-type comparable 16 type BasicSet[E comparable] struct { 17 elementMap map[E]struct{} 18 elements []E 19 } 20 21 var emptyStuct struct{} 22 23 // NewBasicSet returns a set of basic-type comparable elements 24 func NewBasicSet[E comparable](elements []E) (set Set[E]) { 25 var m = make(map[E]struct{}, len(elements)) 26 for i, e := range elements { 27 if _, ok := m[e]; ok { 28 panic(perrors.ErrorfPF( 29 "duplicate set-element:"+ 30 " type E: %T duplicate value: ‘%s’"+ 31 " number of added values: %d", 32 e, pfmt.NoRecurseVPrint(e), 33 i, 34 )) 35 } 36 m[e] = emptyStuct 37 } 38 return &BasicSet[E]{ 39 elementMap: m, 40 elements: elements, 41 } 42 } 43 44 // IsValid returns whether value is part of the set 45 func (s *BasicSet[E]) IsValid(value E) (isValid bool) { 46 _, isValid = s.elementMap[value] 47 return 48 } 49 50 // Iterator allows iteration over all set elements 51 func (s *BasicSet[E]) Iterator() (iterator iters.Iterator[E]) { 52 return iters.NewSliceIterator(s.elements) 53 } 54 55 // StringT returns a string representation for an element of this set. 56 // If value is not a valid element, a fmt.Printf value is output like ?'%v' 57 func (s *BasicSet[E]) StringT(value E) (s2 string) { 58 // StringT is intended to be the String method of a named type implementing set. 59 // if StringT method code would somehow invoke the T.String method again, 60 // this will cause infinite recursion and stack overflow panic. 61 s2 = pfmt.NoRecurseVPrint(value) 62 if _, ok := s.elementMap[value]; ok { 63 return 64 } 65 s2 = "?‘" + s2 + "’" 66 67 return 68 } 69 70 // Description returns a more elaborate string representation 71 // for an element. Description and StringT may return the same value 72 func (s *BasicSet[E]) Description(value E) (full string) { 73 74 // type assert to Element with Description method 75 var elementDescription ElementDescription 76 var ok bool 77 if elementDescription, ok = any(&value).(ElementDescription); !ok { 78 return // not a full element return 79 } 80 81 full = elementDescription.Description() 82 83 return 84 } 85 86 func (s *BasicSet[E]) String() (s2 string) { 87 var e E 88 s2 = plog.Sprintf("basicSet_%T:%d", e, len(s.elementMap)) 89 return 90 }