package sieve // Set is a set of comparable values backed by a plain map, so len, range, // delete and maps.Keys work on it directly. Create sets with SetOf: Has and // Slice work on a nil Set, but Add on a nil Set panics like any write to a nil // map. Slice returns the elements in unspecified order; use // slices.Sorted(maps.Keys(set)) for ordered output when T is ordered. type Set[T comparable] map[T]struct{} // SetOf returns a new set holding items, without duplicates. SetOf() with no // arguments returns an empty, non-nil set that Add can use. It accepts a slice // spread with ..., including a named slice type. func SetOf[T comparable](items ...T) Set[T] { s := make(Set[T], len(items)) for _, v := range items { s[v] = struct{}{} } return s } // Has reports whether v is in the set. A nil Set has no elements. func (s Set[T]) Has(v T) bool { _, ok := s[v] return ok } // Add puts items into the set; items already present are ignored. Add on a nil // Set panics, so create sets with SetOf. func (s Set[T]) Add(items ...T) { for _, v := range items { s[v] = struct{}{} } } // Slice returns a new slice holding each element of the set exactly once, in // unspecified order. It is non-nil even for an empty or nil Set. func (s Set[T]) Slice() []T { out := make([]T, 0, len(s)) for v := range s { out = append(out, v) } return out }