package sets import ( "sync" ) // Set represents a set of values. type Set[T comparable] struct { store map[T]struct{} mux sync.RWMutex } // New creates a new set. func New[T comparable](data ...T) *Set[T] { set := &Set[T]{ store: map[T]struct{}{}, } for _, element := range data { set.Insert(element) } return set } // NewFromSlice creates a new set from a slice. func NewFromSlice[T comparable](data []T) *Set[T] { return New[T](data...) } // Size returns number of elements in set. func (s *Set[T]) Size() int { s.mux.RLock() defer s.mux.RUnlock() return len(s.store) } // Contains checks whether the value is contained in the set. func (s *Set[T]) Contains(val T) bool { s.mux.RLock() defer s.mux.RUnlock() _, ok := s.store[val] return ok } // Insert inserts a value into the set if the value was not already present. func (s *Set[T]) Insert(val T) bool { s.mux.Lock() defer s.mux.Unlock() if _, ok := s.store[val]; !ok { s.store[val] = struct{}{} return false } return true } // Delete removes a value from the set if the value was already present. func (s *Set[T]) Delete(val T) bool { s.mux.Lock() defer s.mux.Unlock() if _, ok := s.store[val]; ok { delete(s.store, val) return true } return false } // Slice returns a slice which contains the elements from the set. func (s *Set[T]) Slice() []T { s.mux.RLock() defer s.mux.RUnlock() elements := []T{} for k := range s.store { elements = append(elements, k) } return elements }