aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/zclconf/go-cty/cty/set/ops.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/zclconf/go-cty/cty/set/ops.go')
-rw-r--r--vendor/github.com/zclconf/go-cty/cty/set/ops.go199
1 files changed, 199 insertions, 0 deletions
diff --git a/vendor/github.com/zclconf/go-cty/cty/set/ops.go b/vendor/github.com/zclconf/go-cty/cty/set/ops.go
new file mode 100644
index 0000000..726e707
--- /dev/null
+++ b/vendor/github.com/zclconf/go-cty/cty/set/ops.go
@@ -0,0 +1,199 @@
1package set
2
3import (
4 "sort"
5)
6
7// Add inserts the given value into the receiving Set.
8//
9// This mutates the set in-place. This operation is not thread-safe.
10func (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)
14 }
15 bucket := s.vals[hv]
16
17 // See if an equivalent value is already present
18 for _, ev := range bucket {
19 if s.rules.Equivalent(val, ev) {
20 return
21 }
22 }
23
24 s.vals[hv] = append(bucket, val)
25}
26
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.
29func (s Set) Remove(val interface{}) {
30 hv := s.rules.Hash(val)
31 bucket, ok := s.vals[hv]
32 if !ok {
33 return
34 }
35
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
43 } else {
44 delete(s.vals, hv)
45 }
46 return
47 }
48 }
49}
50
51// Has returns true if the given value is in the receiving set, or false if
52// it is not.
53func (s Set) Has(val interface{}) bool {
54 hv := s.rules.Hash(val)
55 bucket, ok := s.vals[hv]
56 if !ok {
57 return false
58 }
59
60 for _, ev := range bucket {
61 if s.rules.Equivalent(val, ev) {
62 return true
63 }
64 }
65 return false
66}
67
68// Copy performs a shallow copy of the receiving set, returning a new set
69// with the same rules and elements.
70func (s Set) Copy() Set {
71 ret := NewSet(s.rules)
72 for k, v := range s.vals {
73 ret.vals[k] = v
74 }
75 return ret
76}
77
78// Iterator returns an iterator over values in the set, in an undefined order
79// that callers should not depend on.
80//
81// The pattern for using the returned iterator is:
82//
83// it := set.Iterator()
84// for it.Next() {
85// val := it.Value()
86// // ...
87// }
88//
89// Once an iterator has been created for a set, the set *must not* be mutated
90// until the iterator is no longer in use.
91func (s Set) Iterator() *Iterator {
92 // Sort the bucketIds to ensure that we always traverse in a
93 // consistent order.
94 bucketIds := make([]int, 0, len(s.vals))
95 for id := range s.vals {
96 bucketIds = append(bucketIds, id)
97 }
98 sort.Ints(bucketIds)
99
100 return &Iterator{
101 bucketIds: bucketIds,
102 vals: s.vals,
103 bucketIdx: -1,
104 }
105}
106
107// EachValue calls the given callback once for each value in the set, in an
108// undefined order that callers should not depend on.
109func (s Set) EachValue(cb func(interface{})) {
110 it := s.Iterator()
111 for it.Next() {
112 cb(it.Value())
113 }
114}
115
116// Values returns a slice of all of the values in the set in no particular
117// order. This is just a wrapper around EachValue that accumulates the results
118// in a slice for caller convenience.
119//
120// The returned slice will be nil if there are no values in the set.
121func (s Set) Values() []interface{} {
122 var ret []interface{}
123 s.EachValue(func(v interface{}) {
124 ret = append(ret, v)
125 })
126 return ret
127}
128
129// Length returns the number of values in the set.
130func (s Set) Length() int {
131 var count int
132 for _, bucket := range s.vals {
133 count = count + len(bucket)
134 }
135 return count
136}
137
138// Union returns a new set that contains all of the members of both the
139// receiving set and the given set. Both sets must have the same rules, or
140// else this function will panic.
141func (s1 Set) Union(s2 Set) Set {
142 mustHaveSameRules(s1, s2)
143 rs := NewSet(s1.rules)
144 s1.EachValue(func(v interface{}) {
145 rs.Add(v)
146 })
147 s2.EachValue(func(v interface{}) {
148 rs.Add(v)
149 })
150 return rs
151}
152
153// Intersection returns a new set that contains the values that both the
154// receiver and given sets have in common. Both sets must have the same rules,
155// or else this function will panic.
156func (s1 Set) Intersection(s2 Set) Set {
157 mustHaveSameRules(s1, s2)
158 rs := NewSet(s1.rules)
159 s1.EachValue(func(v interface{}) {
160 if s2.Has(v) {
161 rs.Add(v)
162 }
163 })
164 return rs
165}
166
167// Subtract returns a new set that contains all of the values from the receiver
168// that are not also in the given set. Both sets must have the same rules,
169// or else this function will panic.
170func (s1 Set) Subtract(s2 Set) Set {
171 mustHaveSameRules(s1, s2)
172 rs := NewSet(s1.rules)
173 s1.EachValue(func(v interface{}) {
174 if !s2.Has(v) {
175 rs.Add(v)
176 }
177 })
178 return rs
179}
180
181// SymmetricDifference returns a new set that contains all of the values from
182// both the receiver and given sets, except those that both sets have in
183// common. Both sets must have the same rules, or else this function will
184// panic.
185func (s1 Set) SymmetricDifference(s2 Set) Set {
186 mustHaveSameRules(s1, s2)
187 rs := NewSet(s1.rules)
188 s1.EachValue(func(v interface{}) {
189 if !s2.Has(v) {
190 rs.Add(v)
191 }
192 })
193 s2.EachValue(func(v interface{}) {
194 if !s1.Has(v) {
195 rs.Add(v)
196 }
197 })
198 return rs
199}