package threadsafeset import ( "sync" "code.wmdillon.com/wmdillon/set/simpleset" ) type Set[T comparable] struct { mutex sync.RWMutex set *simpleset.Set[T] } func New[T comparable](elements ...T) *Set[T] { s := &Set[T]{ set: simpleset.New(elements...), } return s } func (s *Set[T]) Add(element T) { s.mutex.Lock() defer s.mutex.Unlock() s.set.Add(element) } func (s *Set[T]) Remove(element T) { s.mutex.Lock() defer s.mutex.Unlock() s.set.Remove(element) } func (s *Set[T]) Contains(element T) bool { s.mutex.RLock() defer s.mutex.RUnlock() return s.set.Contains(element) } func (s *Set[T]) Size() int { s.mutex.RLock() defer s.mutex.RUnlock() return s.set.Size() } func (s *Set[T]) ToSlice() []T { s.mutex.RLock() defer s.mutex.RUnlock() return s.set.ToSlice() } // only locks this.mutex, locking other.mutex is the responsibility // of the caller. func (this *Set[T]) Equal(other *Set[T]) bool { this.mutex.RLock() defer this.mutex.RUnlock() return this.set.Equal(other.set) } // only locks this.mutex, locking other.mutex is the responsibility // of the caller. func (this *Set[T]) Union(other *Set[T]) *Set[T] { this.mutex.RLock() defer this.mutex.RUnlock() return &Set[T]{set: this.set.Union(other.set)} } // only locks this.mutex, locking other.mutex is the responsibility // of the caller. func (this *Set[T]) Intersection(other *Set[T]) *Set[T] { this.mutex.RLock() defer this.mutex.RUnlock() return &Set[T]{set: this.set.Intersection(other.set)} } // only locks this.mutex, locking other.mutex is the responsibility // of the caller. func (this *Set[T]) Difference(other *Set[T]) *Set[T] { this.mutex.RLock() defer this.mutex.RUnlock() return &Set[T]{set: this.set.Difference(other.set)} }