mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-11-04 10:03:42 +08:00 
			
		
		
		
	
							
								
								
									
										76
									
								
								vendor/github.com/zclconf/go-cty/cty/set/gob.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								vendor/github.com/zclconf/go-cty/cty/set/gob.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,76 @@
 | 
			
		||||
package set
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"encoding/gob"
 | 
			
		||||
	"fmt"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// GobEncode is an implementation of the interface gob.GobEncoder, allowing
 | 
			
		||||
// sets to be included in structures encoded via gob.
 | 
			
		||||
//
 | 
			
		||||
// The set rules are included in the serialized value, so the caller must
 | 
			
		||||
// register its concrete rules type with gob.Register before using a
 | 
			
		||||
// set in a gob, and possibly also implement GobEncode/GobDecode to customize
 | 
			
		||||
// how any parameters are persisted.
 | 
			
		||||
//
 | 
			
		||||
// The set elements are also included, so if they are of non-primitive types
 | 
			
		||||
// they too must be registered with gob.
 | 
			
		||||
//
 | 
			
		||||
// If the produced gob values will persist for a long time, the caller must
 | 
			
		||||
// ensure compatibility of the rules implementation. In particular, if the
 | 
			
		||||
// definition of element equivalence changes between encoding and decoding
 | 
			
		||||
// then two distinct stored elements may be considered equivalent on decoding,
 | 
			
		||||
// causing the recovered set to have fewer elements than when it was stored.
 | 
			
		||||
func (s Set) GobEncode() ([]byte, error) {
 | 
			
		||||
	gs := gobSet{
 | 
			
		||||
		Version: 0,
 | 
			
		||||
		Rules:   s.rules,
 | 
			
		||||
		Values:  s.Values(),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	buf := &bytes.Buffer{}
 | 
			
		||||
	enc := gob.NewEncoder(buf)
 | 
			
		||||
	err := enc.Encode(gs)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, fmt.Errorf("error encoding set.Set: %s", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return buf.Bytes(), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GobDecode is the opposite of GobEncode. See GobEncode for information
 | 
			
		||||
// on the requirements for and caveats of including set values in gobs.
 | 
			
		||||
func (s *Set) GobDecode(buf []byte) error {
 | 
			
		||||
	r := bytes.NewReader(buf)
 | 
			
		||||
	dec := gob.NewDecoder(r)
 | 
			
		||||
 | 
			
		||||
	var gs gobSet
 | 
			
		||||
	err := dec.Decode(&gs)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("error decoding set.Set: %s", err)
 | 
			
		||||
	}
 | 
			
		||||
	if gs.Version != 0 {
 | 
			
		||||
		return fmt.Errorf("unsupported set.Set encoding version %d; need 0", gs.Version)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	victim := NewSetFromSlice(gs.Rules, gs.Values)
 | 
			
		||||
	s.vals = victim.vals
 | 
			
		||||
	s.rules = victim.rules
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type gobSet struct {
 | 
			
		||||
	Version int
 | 
			
		||||
	Rules   Rules
 | 
			
		||||
 | 
			
		||||
	// The bucket-based representation is for efficient in-memory access, but
 | 
			
		||||
	// for serialization it's enough to just retain the values themselves,
 | 
			
		||||
	// which we can re-bucket using the rules (which may have changed!) when
 | 
			
		||||
	// we re-inflate.
 | 
			
		||||
	Values []interface{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	gob.Register([]interface{}(nil))
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										15
									
								
								vendor/github.com/zclconf/go-cty/cty/set/iterator.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								vendor/github.com/zclconf/go-cty/cty/set/iterator.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
package set
 | 
			
		||||
 | 
			
		||||
type Iterator struct {
 | 
			
		||||
	vals []interface{}
 | 
			
		||||
	idx  int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (it *Iterator) Value() interface{} {
 | 
			
		||||
	return it.vals[it.idx]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (it *Iterator) Next() bool {
 | 
			
		||||
	it.idx++
 | 
			
		||||
	return it.idx < len(it.vals)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										210
									
								
								vendor/github.com/zclconf/go-cty/cty/set/ops.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										210
									
								
								vendor/github.com/zclconf/go-cty/cty/set/ops.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,210 @@
 | 
			
		||||
package set
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"sort"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Add inserts the given value into the receiving Set.
 | 
			
		||||
//
 | 
			
		||||
// This mutates the set in-place. This operation is not thread-safe.
 | 
			
		||||
func (s Set) Add(val interface{}) {
 | 
			
		||||
	hv := s.rules.Hash(val)
 | 
			
		||||
	if _, ok := s.vals[hv]; !ok {
 | 
			
		||||
		s.vals[hv] = make([]interface{}, 0, 1)
 | 
			
		||||
	}
 | 
			
		||||
	bucket := s.vals[hv]
 | 
			
		||||
 | 
			
		||||
	// See if an equivalent value is already present
 | 
			
		||||
	for _, ev := range bucket {
 | 
			
		||||
		if s.rules.Equivalent(val, ev) {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s.vals[hv] = append(bucket, val)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Remove deletes the given value from the receiving set, if indeed it was
 | 
			
		||||
// there in the first place. If the value is not present, this is a no-op.
 | 
			
		||||
func (s Set) Remove(val interface{}) {
 | 
			
		||||
	hv := s.rules.Hash(val)
 | 
			
		||||
	bucket, ok := s.vals[hv]
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for i, ev := range bucket {
 | 
			
		||||
		if s.rules.Equivalent(val, ev) {
 | 
			
		||||
			newBucket := make([]interface{}, 0, len(bucket)-1)
 | 
			
		||||
			newBucket = append(newBucket, bucket[:i]...)
 | 
			
		||||
			newBucket = append(newBucket, bucket[i+1:]...)
 | 
			
		||||
			if len(newBucket) > 0 {
 | 
			
		||||
				s.vals[hv] = newBucket
 | 
			
		||||
			} else {
 | 
			
		||||
				delete(s.vals, hv)
 | 
			
		||||
			}
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Has returns true if the given value is in the receiving set, or false if
 | 
			
		||||
// it is not.
 | 
			
		||||
func (s Set) Has(val interface{}) bool {
 | 
			
		||||
	hv := s.rules.Hash(val)
 | 
			
		||||
	bucket, ok := s.vals[hv]
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, ev := range bucket {
 | 
			
		||||
		if s.rules.Equivalent(val, ev) {
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Copy performs a shallow copy of the receiving set, returning a new set
 | 
			
		||||
// with the same rules and elements.
 | 
			
		||||
func (s Set) Copy() Set {
 | 
			
		||||
	ret := NewSet(s.rules)
 | 
			
		||||
	for k, v := range s.vals {
 | 
			
		||||
		ret.vals[k] = v
 | 
			
		||||
	}
 | 
			
		||||
	return ret
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Iterator returns an iterator over values in the set. If the set's rules
 | 
			
		||||
// implement OrderedRules then the result is ordered per those rules. If
 | 
			
		||||
// no order is provided, or if it is not a total order, then the iteration
 | 
			
		||||
// order is undefined but consistent for a particular version of cty. Do not
 | 
			
		||||
// rely on specific ordering between cty releases unless the rules order is a
 | 
			
		||||
// total order.
 | 
			
		||||
//
 | 
			
		||||
// The pattern for using the returned iterator is:
 | 
			
		||||
//
 | 
			
		||||
//     it := set.Iterator()
 | 
			
		||||
//     for it.Next() {
 | 
			
		||||
//         val := it.Value()
 | 
			
		||||
//         // ...
 | 
			
		||||
//     }
 | 
			
		||||
//
 | 
			
		||||
// Once an iterator has been created for a set, the set *must not* be mutated
 | 
			
		||||
// until the iterator is no longer in use.
 | 
			
		||||
func (s Set) Iterator() *Iterator {
 | 
			
		||||
	vals := s.Values()
 | 
			
		||||
 | 
			
		||||
	return &Iterator{
 | 
			
		||||
		vals: vals,
 | 
			
		||||
		idx:  -1,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// EachValue calls the given callback once for each value in the set, in an
 | 
			
		||||
// undefined order that callers should not depend on.
 | 
			
		||||
func (s Set) EachValue(cb func(interface{})) {
 | 
			
		||||
	it := s.Iterator()
 | 
			
		||||
	for it.Next() {
 | 
			
		||||
		cb(it.Value())
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Values returns a slice of all the values in the set. If the set rules have
 | 
			
		||||
// an order then the result is in that order. If no order is provided or if
 | 
			
		||||
// it is not a total order then the result order is undefined, but consistent
 | 
			
		||||
// for a particular set value within a specific release of cty.
 | 
			
		||||
func (s Set) Values() []interface{} {
 | 
			
		||||
	var ret []interface{}
 | 
			
		||||
	// Sort the bucketIds to ensure that we always traverse in a
 | 
			
		||||
	// consistent order.
 | 
			
		||||
	bucketIDs := make([]int, 0, len(s.vals))
 | 
			
		||||
	for id := range s.vals {
 | 
			
		||||
		bucketIDs = append(bucketIDs, id)
 | 
			
		||||
	}
 | 
			
		||||
	sort.Ints(bucketIDs)
 | 
			
		||||
 | 
			
		||||
	for _, bucketID := range bucketIDs {
 | 
			
		||||
		ret = append(ret, s.vals[bucketID]...)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if orderRules, ok := s.rules.(OrderedRules); ok {
 | 
			
		||||
		sort.SliceStable(ret, func(i, j int) bool {
 | 
			
		||||
			return orderRules.Less(ret[i], ret[j])
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ret
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Length returns the number of values in the set.
 | 
			
		||||
func (s Set) Length() int {
 | 
			
		||||
	var count int
 | 
			
		||||
	for _, bucket := range s.vals {
 | 
			
		||||
		count = count + len(bucket)
 | 
			
		||||
	}
 | 
			
		||||
	return count
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Union returns a new set that contains all of the members of both the
 | 
			
		||||
// receiving set and the given set. Both sets must have the same rules, or
 | 
			
		||||
// else this function will panic.
 | 
			
		||||
func (s1 Set) Union(s2 Set) Set {
 | 
			
		||||
	mustHaveSameRules(s1, s2)
 | 
			
		||||
	rs := NewSet(s1.rules)
 | 
			
		||||
	s1.EachValue(func(v interface{}) {
 | 
			
		||||
		rs.Add(v)
 | 
			
		||||
	})
 | 
			
		||||
	s2.EachValue(func(v interface{}) {
 | 
			
		||||
		rs.Add(v)
 | 
			
		||||
	})
 | 
			
		||||
	return rs
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Intersection returns a new set that contains the values that both the
 | 
			
		||||
// receiver and given sets have in common. Both sets must have the same rules,
 | 
			
		||||
// or else this function will panic.
 | 
			
		||||
func (s1 Set) Intersection(s2 Set) Set {
 | 
			
		||||
	mustHaveSameRules(s1, s2)
 | 
			
		||||
	rs := NewSet(s1.rules)
 | 
			
		||||
	s1.EachValue(func(v interface{}) {
 | 
			
		||||
		if s2.Has(v) {
 | 
			
		||||
			rs.Add(v)
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
	return rs
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Subtract returns a new set that contains all of the values from the receiver
 | 
			
		||||
// that are not also in the given set. Both sets must have the same rules,
 | 
			
		||||
// or else this function will panic.
 | 
			
		||||
func (s1 Set) Subtract(s2 Set) Set {
 | 
			
		||||
	mustHaveSameRules(s1, s2)
 | 
			
		||||
	rs := NewSet(s1.rules)
 | 
			
		||||
	s1.EachValue(func(v interface{}) {
 | 
			
		||||
		if !s2.Has(v) {
 | 
			
		||||
			rs.Add(v)
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
	return rs
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SymmetricDifference returns a new set that contains all of the values from
 | 
			
		||||
// both the receiver and given sets, except those that both sets have in
 | 
			
		||||
// common. Both sets must have the same rules, or else this function will
 | 
			
		||||
// panic.
 | 
			
		||||
func (s1 Set) SymmetricDifference(s2 Set) Set {
 | 
			
		||||
	mustHaveSameRules(s1, s2)
 | 
			
		||||
	rs := NewSet(s1.rules)
 | 
			
		||||
	s1.EachValue(func(v interface{}) {
 | 
			
		||||
		if !s2.Has(v) {
 | 
			
		||||
			rs.Add(v)
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
	s2.EachValue(func(v interface{}) {
 | 
			
		||||
		if !s1.Has(v) {
 | 
			
		||||
			rs.Add(v)
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
	return rs
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										43
									
								
								vendor/github.com/zclconf/go-cty/cty/set/rules.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								vendor/github.com/zclconf/go-cty/cty/set/rules.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
			
		||||
package set
 | 
			
		||||
 | 
			
		||||
// Rules represents the operations that define membership for a Set.
 | 
			
		||||
//
 | 
			
		||||
// Each Set has a Rules instance, whose methods must satisfy the interface
 | 
			
		||||
// contracts given below for any value that will be added to the set.
 | 
			
		||||
type Rules interface {
 | 
			
		||||
	// Hash returns an int that somewhat-uniquely identifies the given value.
 | 
			
		||||
	//
 | 
			
		||||
	// A good hash function will minimize collisions for values that will be
 | 
			
		||||
	// added to the set, though collisions *are* permitted. Collisions will
 | 
			
		||||
	// simply reduce the efficiency of operations on the set.
 | 
			
		||||
	Hash(interface{}) int
 | 
			
		||||
 | 
			
		||||
	// Equivalent returns true if and only if the two values are considered
 | 
			
		||||
	// equivalent for the sake of set membership. Two values that are
 | 
			
		||||
	// equivalent cannot exist in the set at the same time, and if two
 | 
			
		||||
	// equivalent values are added it is undefined which one will be
 | 
			
		||||
	// returned when enumerating all of the set members.
 | 
			
		||||
	//
 | 
			
		||||
	// Two values that are equivalent *must* result in the same hash value,
 | 
			
		||||
	// though it is *not* required that two values with the same hash value
 | 
			
		||||
	// be equivalent.
 | 
			
		||||
	Equivalent(interface{}, interface{}) bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// OrderedRules is an extension of Rules that can apply a partial order to
 | 
			
		||||
// element values. When a set's Rules implements OrderedRules an iterator
 | 
			
		||||
// over the set will return items in the order described by the rules.
 | 
			
		||||
//
 | 
			
		||||
// If the given order is not a total order (that is, some pairs of non-equivalent
 | 
			
		||||
// elements do not have a defined order) then the resulting iteration order
 | 
			
		||||
// is undefined but consistent for a particular version of cty. The exact
 | 
			
		||||
// order in that case is not part of the contract and is subject to change
 | 
			
		||||
// between versions.
 | 
			
		||||
type OrderedRules interface {
 | 
			
		||||
	Rules
 | 
			
		||||
 | 
			
		||||
	// Less returns true if and only if the first argument should sort before
 | 
			
		||||
	// the second argument. If the second argument should sort before the first
 | 
			
		||||
	// or if there is no defined order for the values, return false.
 | 
			
		||||
	Less(interface{}, interface{}) bool
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										62
									
								
								vendor/github.com/zclconf/go-cty/cty/set/set.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								vendor/github.com/zclconf/go-cty/cty/set/set.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
			
		||||
package set
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Set is an implementation of the concept of a set: a collection where all
 | 
			
		||||
// values are conceptually either in or out of the set, but the members are
 | 
			
		||||
// not ordered.
 | 
			
		||||
//
 | 
			
		||||
// This type primarily exists to be the internal type of sets in cty, but
 | 
			
		||||
// it is considered to be at the same level of abstraction as Go's built in
 | 
			
		||||
// slice and map collection types, and so should make no cty-specific
 | 
			
		||||
// assumptions.
 | 
			
		||||
//
 | 
			
		||||
// Set operations are not thread safe. It is the caller's responsibility to
 | 
			
		||||
// provide mutex guarantees where necessary.
 | 
			
		||||
//
 | 
			
		||||
// Set operations are not optimized to minimize memory pressure. Mutating
 | 
			
		||||
// a set will generally create garbage and so should perhaps be avoided in
 | 
			
		||||
// tight loops where memory pressure is a concern.
 | 
			
		||||
type Set struct {
 | 
			
		||||
	vals  map[int][]interface{}
 | 
			
		||||
	rules Rules
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewSet returns an empty set with the membership rules given.
 | 
			
		||||
func NewSet(rules Rules) Set {
 | 
			
		||||
	return Set{
 | 
			
		||||
		vals:  map[int][]interface{}{},
 | 
			
		||||
		rules: rules,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewSetFromSlice(rules Rules, vals []interface{}) Set {
 | 
			
		||||
	s := NewSet(rules)
 | 
			
		||||
	for _, v := range vals {
 | 
			
		||||
		s.Add(v)
 | 
			
		||||
	}
 | 
			
		||||
	return s
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func sameRules(s1 Set, s2 Set) bool {
 | 
			
		||||
	return s1.rules == s2.rules
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func mustHaveSameRules(s1 Set, s2 Set) {
 | 
			
		||||
	if !sameRules(s1, s2) {
 | 
			
		||||
		panic(fmt.Errorf("incompatible set rules: %#v, %#v", s1.rules, s2.rules))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// HasRules returns true if and only if the receiving set has the given rules
 | 
			
		||||
// instance as its rules.
 | 
			
		||||
func (s Set) HasRules(rules Rules) bool {
 | 
			
		||||
	return s.rules == rules
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Rules returns the receiving set's rules instance.
 | 
			
		||||
func (s Set) Rules() Rules {
 | 
			
		||||
	return s.rules
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user