7 // Add inserts the given value into the receiving Set.
9 // This mutates the set in-place. This operation is not thread-safe.
10 func (s Set) Add(val interface{}) {
11 hv := s.rules.Hash(val)
12 if _, ok := s.vals[hv]; !ok {
13 s.vals[hv] = make([]interface{}, 0, 1)
17 // See if an equivalent value is already present
18 for _, ev := range bucket {
19 if s.rules.Equivalent(val, ev) {
24 s.vals[hv] = append(bucket, val)
27 // Remove deletes the given value from the receiving set, if indeed it was
28 // there in the first place. If the value is not present, this is a no-op.
29 func (s Set) Remove(val interface{}) {
30 hv := s.rules.Hash(val)
31 bucket, ok := s.vals[hv]
36 for i, ev := range bucket {
37 if s.rules.Equivalent(val, ev) {
38 newBucket := make([]interface{}, 0, len(bucket)-1)
39 newBucket = append(newBucket, bucket[:i]...)
40 newBucket = append(newBucket, bucket[i+1:]...)
41 if len(newBucket) > 0 {
42 s.vals[hv] = newBucket
51 // Has returns true if the given value is in the receiving set, or false if
53 func (s Set) Has(val interface{}) bool {
54 hv := s.rules.Hash(val)
55 bucket, ok := s.vals[hv]
60 for _, ev := range bucket {
61 if s.rules.Equivalent(val, ev) {
68 // Copy performs a shallow copy of the receiving set, returning a new set
69 // with the same rules and elements.
70 func (s Set) Copy() Set {
71 ret := NewSet(s.rules)
72 for k, v := range s.vals {
78 // Iterator returns an iterator over values in the set. If the set's rules
79 // implement OrderedRules then the result is ordered per those rules. If
80 // no order is provided, or if it is not a total order, then the iteration
81 // order is undefined but consistent for a particular version of cty. Do not
82 // rely on specific ordering between cty releases unless the rules order is a
85 // The pattern for using the returned iterator is:
87 // it := set.Iterator()
93 // Once an iterator has been created for a set, the set *must not* be mutated
94 // until the iterator is no longer in use.
95 func (s Set) Iterator() *Iterator {
104 // EachValue calls the given callback once for each value in the set, in an
105 // undefined order that callers should not depend on.
106 func (s Set) EachValue(cb func(interface{})) {
113 // Values returns a slice of all the values in the set. If the set rules have
114 // an order then the result is in that order. If no order is provided or if
115 // it is not a total order then the result order is undefined, but consistent
116 // for a particular set value within a specific release of cty.
117 func (s Set) Values() []interface{} {
118 var ret []interface{}
119 // Sort the bucketIds to ensure that we always traverse in a
121 bucketIDs := make([]int, 0, len(s.vals))
122 for id := range s.vals {
123 bucketIDs = append(bucketIDs, id)
127 for _, bucketID := range bucketIDs {
128 ret = append(ret, s.vals[bucketID]...)
131 if orderRules, ok := s.rules.(OrderedRules); ok {
132 sort.SliceStable(ret, func(i, j int) bool {
133 return orderRules.Less(ret[i], ret[j])
140 // Length returns the number of values in the set.
141 func (s Set) Length() int {
143 for _, bucket := range s.vals {
144 count = count + len(bucket)
149 // Union returns a new set that contains all of the members of both the
150 // receiving set and the given set. Both sets must have the same rules, or
151 // else this function will panic.
152 func (s1 Set) Union(s2 Set) Set {
153 mustHaveSameRules(s1, s2)
154 rs := NewSet(s1.rules)
155 s1.EachValue(func(v interface{}) {
158 s2.EachValue(func(v interface{}) {
164 // Intersection returns a new set that contains the values that both the
165 // receiver and given sets have in common. Both sets must have the same rules,
166 // or else this function will panic.
167 func (s1 Set) Intersection(s2 Set) Set {
168 mustHaveSameRules(s1, s2)
169 rs := NewSet(s1.rules)
170 s1.EachValue(func(v interface{}) {
178 // Subtract returns a new set that contains all of the values from the receiver
179 // that are not also in the given set. Both sets must have the same rules,
180 // or else this function will panic.
181 func (s1 Set) Subtract(s2 Set) Set {
182 mustHaveSameRules(s1, s2)
183 rs := NewSet(s1.rules)
184 s1.EachValue(func(v interface{}) {
192 // SymmetricDifference returns a new set that contains all of the values from
193 // both the receiver and given sets, except those that both sets have in
194 // common. Both sets must have the same rules, or else this function will
196 func (s1 Set) SymmetricDifference(s2 Set) Set {
197 mustHaveSameRules(s1, s2)
198 rs := NewSet(s1.rules)
199 s1.EachValue(func(v interface{}) {
204 s2.EachValue(func(v interface{}) {