container

package
v0.35.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 13, 2026 License: Unlicense Imports: 5 Imported by: 11

Documentation

Overview

Package container provides common container types.

TODO(a.garipov): Consider adding a set interface.

TODO(a.garipov): Consider adding a intersect and union operations on sets.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func MapSetToString

func MapSetToString[T cmp.Ordered](set *MapSet[T]) (s string)

MapSetToString converts a MapSet of values of an ordered type into a reproducible string.

func MapSetToStringFunc

func MapSetToStringFunc[T comparable](set *MapSet[T], compare func(a, b T) (res int)) (s string)

MapSetToStringFunc is like MapSetToString but uses an explicit comparison function.

Types

type KeyValue added in v0.25.3

type KeyValue[K comparable, V any] struct {
	Key   K
	Value V
}

KeyValue is a simple structure for pairs of values where one identifies the other. It is useful when multiple values need to be processed in a defined order and each value is associated with its own name or ID.

type KeyValues added in v0.25.3

type KeyValues[K comparable, V any] []KeyValue[K, V]

KeyValues is a slice of [KeyValue]s.

Example
package main

import (
	"fmt"

	"github.com/AdguardTeam/golibs/container"
)

func main() {
	type service struct{}

	var (
		serviceA = service{}
		serviceB = service{}
		serviceC = service{}
	)

	type svcName string

	validate := func(_ service) (err error) {
		return nil
	}

	// These should be validated in this order.
	services := container.KeyValues[svcName, service]{{
		Key:   "svc_a",
		Value: serviceA,
	}, {
		Key:   "svc_b",
		Value: serviceB,
	}, {
		Key:   "svc_c",
		Value: serviceC,
	}}

	for _, kv := range services {
		fmt.Printf("validating service %q: %v\n", kv.Key, validate(kv.Value))
	}

}
Output:

validating service "svc_a": <nil>
validating service "svc_b": <nil>
validating service "svc_c": <nil>

type MapSet

type MapSet[T comparable] struct {
	// contains filtered or unexported fields
}

MapSet is a set that uses a map as its storage.

TODO(a.garipov): Figure out a way to add a reproducible String method.

Example
package main

import (
	"fmt"
	"slices"

	"github.com/AdguardTeam/golibs/container"
)

func main() {
	const x = 1
	set := container.NewMapSet[int]()

	ok := set.Has(x)
	fmt.Printf("%s contains %v is %t\n", container.MapSetToString(set), x, ok)

	set.Add(x)
	ok = set.Has(x)
	fmt.Printf("%s contains %v is %t\n", container.MapSetToString(set), x, ok)

	other := container.NewMapSet(x)
	ok = set.Equal(other)
	fmt.Printf(
		"%s is equal to %s is %t\n",
		container.MapSetToString(set),
		container.MapSetToString(other),
		ok,
	)

	set.Add(2)
	values := set.Values()
	slices.Sort(values)
	fmt.Printf("values of %s are %v\n", container.MapSetToString(set), values)

	set.Delete(x)
	ok = set.Has(x)
	fmt.Printf("%s contains %v is %t\n", container.MapSetToString(set), x, ok)

	for n := range set.Range {
		fmt.Printf("got value %d\n", n)

		break
	}

	set = container.NewMapSet(x)
	fmt.Printf("%s has length %d\n", container.MapSetToString(set), set.Len())

	set.Clear()
	fmt.Printf("%s has length %d\n", container.MapSetToString(set), set.Len())

}
Output:


[] contains 1 is false
[1] contains 1 is true
[1] is equal to [1] is true
values of [1 2] are [1 2]
[2] contains 1 is false
got value 2
[1] has length 1
[] has length 0
Example (Nil)
package main

import (
	"fmt"

	"github.com/AdguardTeam/golibs/container"
)

func main() {
	const x = 1

	var set *container.MapSet[int]

	panicked := false
	setPanicked := func() {
		panicked = recover() != nil
	}

	func() {
		defer setPanicked()

		set.Clear()
	}()
	fmt.Printf("panic after clear: %t\n", panicked)

	func() {
		defer setPanicked()

		set.Delete(x)
	}()
	fmt.Printf("panic after delete: %t\n", panicked)

	func() {
		defer setPanicked()

		set.Has(x)
	}()
	fmt.Printf("panic after has: %t\n", panicked)

	func() {
		defer setPanicked()

		set.Len()
	}()
	fmt.Printf("panic after len: %t\n", panicked)

	func() {
		defer setPanicked()

		for n := range set.Range {
			fmt.Printf("got value %d\n", n)
		}
	}()
	fmt.Printf("panic after range: %t\n", panicked)

	func() {
		defer setPanicked()

		set.Values()
	}()
	fmt.Printf("panic after values: %t\n", panicked)

	func() {
		defer setPanicked()

		set.Add(x)
	}()
	fmt.Printf("panic after add: %t\n", panicked)

	func() {
		defer setPanicked()

		set.Union(set, set)
	}()
	fmt.Printf("panic after union: %t\n", panicked)

	func() {
		defer setPanicked()

		set.Intersection(set, set)
	}()
	fmt.Printf("panic after intersection: %t\n", panicked)

	func() {
		defer setPanicked()

		set.Intersects(set)
	}()
	fmt.Printf("panic after intersects: %t\n", panicked)

}
Output:


panic after clear: false
panic after delete: false
panic after has: false
panic after len: false
panic after range: false
panic after values: false
panic after add: true
panic after union: true
panic after intersection: true
panic after intersects: false

func NewMapSet

func NewMapSet[T comparable](values ...T) (set *MapSet[T])

NewMapSet returns a new map set containing values.

TODO(f.setrakov): Delegate allocation decisions to the user.

func (*MapSet[T]) Add

func (set *MapSet[T]) Add(v T)

Add adds v to set.

func (*MapSet[T]) Clear

func (set *MapSet[T]) Clear()

Clear clears set in a way that retains the internal storage for later reuse to reduce allocations. Calling Clear on a nil set has no effect, just like a clear on a nil map doesn't.

func (*MapSet[T]) Clone

func (set *MapSet[T]) Clone() (clone *MapSet[T])

Clone returns a deep clone of set. If set is nil, clone is nil.

Example
package main

import (
	"fmt"

	"github.com/AdguardTeam/golibs/container"
)

func main() {
	var set *container.MapSet[int]
	fmt.Printf("nil:   %#v\n", set.Clone())

	const x, y = 1, 2
	set = container.NewMapSet(x)
	clone := set.Clone()
	clone.Add(y)

	fmt.Printf("orig:  %t %t\n", set.Has(x), set.Has(y))
	fmt.Printf("clone: %t %t\n", clone.Has(x), clone.Has(y))

}
Output:

nil:   (*container.MapSet[int])(nil)
orig:  true false
clone: true true

func (*MapSet[T]) Delete

func (set *MapSet[T]) Delete(v T)

Delete deletes v from set. Calling Delete on a nil set has no effect, just like delete on a nil map doesn't.

func (*MapSet[T]) Equal

func (set *MapSet[T]) Equal(other *MapSet[T]) (ok bool)

Equal returns true if set is equal to other. set and other may be nil; Equal returns true if both are nil, but a nil *MapSet is not equal to a non-nil empty one.

Example
package main

import (
	"fmt"

	"github.com/AdguardTeam/golibs/container"
)

func main() {
	const x, y = 1, 2
	set := container.NewMapSet(x)

	fmt.Printf("same:       %t\n", set.Equal(container.NewMapSet(x)))
	fmt.Printf("other elem: %t\n", set.Equal(container.NewMapSet(y)))
	fmt.Printf("other len:  %t\n", set.Equal(container.NewMapSet(x, y)))
	fmt.Printf("nil:        %t\n", set.Equal(nil))
	fmt.Printf("nil eq nil: %t\n", (*container.MapSet[int])(nil).Equal(nil))

}
Output:

same:       true
other elem: false
other len:  false
nil:        false
nil eq nil: true

func (*MapSet[T]) Has

func (set *MapSet[T]) Has(v T) (ok bool)

Has returns true if v is in set. Calling Has on a nil set returns false, just like indexing on an empty map does.

func (*MapSet[T]) Intersection added in v0.35.3

func (set *MapSet[T]) Intersection(a, b *MapSet[T]) (res *MapSet[T])

Intersection fills set with values that belong both to a and b. set must not be nil. Intersection returns empty set if one of the arguments is nil. If neither a nor b are equal to set, then the function will rewrite the contents of set.

Example
package main

import (
	"fmt"

	"github.com/AdguardTeam/golibs/container"
)

func main() {
	a := container.NewMapSet(1, 6, 10)
	b := container.NewMapSet(3, 6, 12)
	set := container.NewMapSet[int]()

	fmt.Printf("a = %s, b = %s\n", container.MapSetToString(a), container.MapSetToString(b))
	fmt.Printf("set = a ∩ b:     %s\n", container.MapSetToString(set.Intersection(a, b)))
	fmt.Printf("set = nil ∩ nil: %s\n", container.MapSetToString(set.Intersection(nil, nil)))
	fmt.Printf("set = nil ∩ b:   %s\n", container.MapSetToString(set.Intersection(nil, b)))
	fmt.Printf("set = a ∩ nil:   %s\n", container.MapSetToString(set.Intersection(a, nil)))
	fmt.Printf("a = a ∩ b:       %s\n", container.MapSetToString(a.Intersection(a, b)))

	a = container.NewMapSet(1, 6, 10)
	fmt.Printf("b = a ∩ b:       %s\n", container.MapSetToString(b.Intersection(a, b)))

}
Output:

a = [1 6 10], b = [3 6 12]
set = a ∩ b:     [6]
set = nil ∩ nil: []
set = nil ∩ b:   []
set = a ∩ nil:   []
a = a ∩ b:       [6]
b = a ∩ b:       [6]

func (*MapSet[T]) Intersects added in v0.35.3

func (set *MapSet[T]) Intersects(other *MapSet[T]) (ok bool)

Intersects returns true if set and other has at least one common element. If set or other is nil, result will be false.

Example
package main

import (
	"fmt"

	"github.com/AdguardTeam/golibs/container"
)

func main() {
	a := container.NewMapSet(1, 6, 10)
	b := container.NewMapSet(3, 6, 12)
	var nilSet *container.MapSet[int]

	fmt.Printf("a = %s, b = %s\n", container.MapSetToString(a), container.MapSetToString(b))
	fmt.Printf("a ∩ b:     %t\n", a.Intersects(b))
	fmt.Printf("nil ∩ a:   %t\n", nilSet.Intersects(a))
	fmt.Printf("a ∩ nil:   %t\n", a.Intersects(nilSet))
	fmt.Printf("nil ∩ nil: %t\n", nilSet.Intersects(nilSet))

}
Output:

a = [1 6 10], b = [3 6 12]
a ∩ b:     true
nil ∩ a:   false
a ∩ nil:   false
nil ∩ nil: false

func (*MapSet[T]) Len

func (set *MapSet[T]) Len() (n int)

Len returns the length of set. A nil set has a length of zero, just like an empty map.

func (*MapSet[T]) Range

func (set *MapSet[T]) Range(f func(v T) (cont bool))

Range calls f with each value of set in an undefined order. If cont is false, Range stops the iteration. Calling Range on a nil *MapSet has no effect.

func (*MapSet[T]) Union added in v0.35.3

func (set *MapSet[T]) Union(a, b *MapSet[T]) (res *MapSet[T])

Union fills set with values belonging to either a or b. set must not be nil. Union returns empty set if both a and b are nil. If neither a nor b are equal to set, then the function will rewrite the contents of set.

Example
package main

import (
	"fmt"

	"github.com/AdguardTeam/golibs/container"
)

func main() {
	a := container.NewMapSet(1, 6, 10)
	b := container.NewMapSet(3, 6, 12)
	set := container.NewMapSet[int]()

	fmt.Printf("a = %s, b = %s\n", container.MapSetToString(a), container.MapSetToString(b))
	fmt.Printf("set = a ∪ b:     %s\n", container.MapSetToString(set.Union(a, b)))
	fmt.Printf("set = nil ∪ nil: %s\n", container.MapSetToString(set.Union(nil, nil)))
	fmt.Printf("set = nil ∪ b:   %s\n", container.MapSetToString(set.Union(nil, b)))
	fmt.Printf("set = a ∪ nil:   %s\n", container.MapSetToString(set.Union(a, nil)))
	fmt.Printf("a = a ∪ b:       %s\n", container.MapSetToString(a.Union(a, b)))

	a = container.NewMapSet(1, 6, 10)
	fmt.Printf("b = a ∪ b:       %s\n", container.MapSetToString(b.Union(a, b)))

}
Output:

a = [1 6 10], b = [3 6 12]
set = a ∪ b:     [1 3 6 10 12]
set = nil ∪ nil: []
set = nil ∪ b:   [3 6 12]
set = a ∪ nil:   [1 6 10]
a = a ∪ b:       [1 3 6 10 12]
b = a ∪ b:       [1 3 6 10 12]

func (*MapSet[T]) Values

func (set *MapSet[T]) Values() (values []T)

Values returns all values in set. The order of the values is undefined. Values returns nil if set is nil.

type RingBuffer added in v0.25.2

type RingBuffer[T any] struct {
	// contains filtered or unexported fields
}

RingBuffer is the generic implementation of ring buffer data structure.

func NewRingBuffer added in v0.25.2

func NewRingBuffer[T any](size uint) (rb *RingBuffer[T])

NewRingBuffer initializes a new ring buffer with the given size.

func (*RingBuffer[T]) Clear added in v0.25.2

func (rb *RingBuffer[T]) Clear()

Clear clears the buffer.

func (*RingBuffer[T]) Current added in v0.25.2

func (rb *RingBuffer[T]) Current() (e T)

Current returns the element at the current position. It returns zero value of T if rb is nil or empty.

Example
package main

import (
	"fmt"

	"github.com/AdguardTeam/golibs/container"
)

func main() {
	const size, x, y, z = 2, 1, 2, 3

	var rb *container.RingBuffer[int]
	fmt.Printf("nil: %#v\n", rb.Current())

	rb = container.NewRingBuffer[int](size)
	fmt.Printf("empty: %#v\n", rb.Current())

	rb.Push(x)
	fmt.Printf("push %d: %#v\n", x, rb.Current())

	rb.Push(y)
	fmt.Printf("push %d: %#v\n", y, rb.Current())

	rb.Push(z)
	fmt.Printf("push %d: %#v\n", z, rb.Current())
	fmt.Printf("current: %#v\n", rb.Current())

}
Output:

nil: 0
empty: 0
push 1: 0
push 2: 1
push 3: 2
current: 2

func (*RingBuffer[T]) Len added in v0.25.2

func (rb *RingBuffer[T]) Len() (l uint)

Len returns a length of the buffer.

func (*RingBuffer[T]) Push added in v0.25.2

func (rb *RingBuffer[T]) Push(e T)

Push adds an element to the buffer and sets the current position to the next element.

func (*RingBuffer[T]) Range added in v0.25.2

func (rb *RingBuffer[T]) Range(f func(T) (cont bool))

Range calls f for each element of the buffer starting from the current position until f returns false.

func (*RingBuffer[T]) ReverseRange added in v0.25.2

func (rb *RingBuffer[T]) ReverseRange(f func(T) (cont bool))

ReverseRange calls f for each element of the buffer in reverse order ending with the current position until f returns false.

type SortedSliceSet added in v0.30.1

type SortedSliceSet[T cmp.Ordered] struct {
	// contains filtered or unexported fields
}

SortedSliceSet is a simple set implementation that has a sorted set of values as its underlying storage.

TODO(a.garipov): Consider relaxing the type requirement or adding a version with a comparison function.

Example
package main

import (
	"fmt"
	"slices"

	"github.com/AdguardTeam/golibs/container"
)

func main() {
	const x = 1
	set := container.NewSortedSliceSet[int]()

	ok := set.Has(x)
	fmt.Printf("%s contains %v is %t\n", set, x, ok)

	set.Add(x)
	ok = set.Has(x)
	fmt.Printf("%s contains %v is %t\n", set, x, ok)

	other := container.NewSortedSliceSet(x)
	ok = set.Equal(other)
	fmt.Printf("%s is equal to %s is %t\n", set, other, ok)

	set.Add(2)
	values := set.Values()
	slices.Sort(values)
	fmt.Printf("values of %s are %v\n", set, values)

	set.Delete(x)
	ok = set.Has(x)
	fmt.Printf("%s contains %v is %t\n", set, x, ok)

	for n := range set.Range {
		fmt.Printf("got value %d\n", n)

		break
	}

	set = container.NewSortedSliceSet(x)
	fmt.Printf("%s has length %d\n", set, set.Len())

	set.Clear()
	fmt.Printf("%s has length %d\n", set, set.Len())

}
Output:


[] contains 1 is false
[1] contains 1 is true
[1] is equal to [1] is true
values of [1 2] are [1 2]
[2] contains 1 is false
got value 2
[1] has length 1
[] has length 0
Example (Nil)
package main

import (
	"fmt"

	"github.com/AdguardTeam/golibs/container"
)

func main() {
	const x = 1

	var set *container.SortedSliceSet[int]

	panicked := false
	setPanicked := func() {
		panicked = recover() != nil
	}

	func() {
		defer setPanicked()

		set.Clear()
	}()
	fmt.Printf("panic after clear: %t\n", panicked)

	func() {
		defer setPanicked()

		set.Delete(x)
	}()
	fmt.Printf("panic after delete: %t\n", panicked)

	func() {
		defer setPanicked()

		set.Has(x)
	}()
	fmt.Printf("panic after has: %t\n", panicked)

	func() {
		defer setPanicked()

		set.Len()
	}()
	fmt.Printf("panic after len: %t\n", panicked)

	func() {
		defer setPanicked()

		for n := range set.Range {
			fmt.Printf("got value %d\n", n)
		}
	}()
	fmt.Printf("panic after range: %t\n", panicked)

	func() {
		defer setPanicked()

		set.Values()
	}()
	fmt.Printf("panic after values: %t\n", panicked)

	func() {
		defer setPanicked()

		set.Add(x)
	}()
	fmt.Printf("panic after add: %t\n", panicked)

	func() {
		defer setPanicked()

		set.Union(set, set)
	}()
	fmt.Printf("panic after union: %t\n", panicked)

	func() {
		defer setPanicked()

		set.Intersection(set, set)
	}()
	fmt.Printf("panic after intersection: %t\n", panicked)

	func() {
		defer setPanicked()

		set.Intersects(set)
	}()
	fmt.Printf("panic after intersects: %t\n", panicked)

}
Output:


panic after clear: false
panic after delete: true
panic after has: false
panic after len: false
panic after range: false
panic after values: false
panic after add: true
panic after union: true
panic after intersection: true
panic after intersects: false

func NewSortedSliceSet added in v0.30.1

func NewSortedSliceSet[T cmp.Ordered](elems ...T) (set *SortedSliceSet[T])

NewSortedSliceSet returns a new *SortedSliceSet. elems must not be modified after calling NewSortedSliceSet.

TODO(f.setrakov): Delegate allocation decisions to the user.

func (*SortedSliceSet[T]) Add added in v0.30.1

func (set *SortedSliceSet[T]) Add(v T)

Add adds v to set.

func (*SortedSliceSet[T]) Clear added in v0.30.1

func (set *SortedSliceSet[T]) Clear()

Clear clears set in a way that retains the internal storage for later reuse to reduce allocations. Calling Clear on a nil set has no effect, just like a clear on a nil slice doesn't.

func (*SortedSliceSet[T]) Clone added in v0.30.1

func (set *SortedSliceSet[T]) Clone() (clone *SortedSliceSet[T])

Clone returns a clone of set. If set is nil, clone is nil.

NOTE: It calls slices.Clone on the underlying storage, so these elements are cloned shallowly.

Example
package main

import (
	"fmt"

	"github.com/AdguardTeam/golibs/container"
)

func main() {
	var set *container.SortedSliceSet[int]
	fmt.Printf("nil:   %#v\n", set.Clone())

	const x, y = 1, 2
	set = container.NewSortedSliceSet(x)
	clone := set.Clone()
	clone.Add(y)

	fmt.Printf("orig:  %t %t\n", set.Has(x), set.Has(y))
	fmt.Printf("clone: %t %t\n", clone.Has(x), clone.Has(y))

}
Output:

nil:   (*container.SortedSliceSet[int])(nil)
orig:  true false
clone: true true

func (*SortedSliceSet[T]) Delete added in v0.30.1

func (set *SortedSliceSet[T]) Delete(v T)

Delete deletes v from set.

func (*SortedSliceSet[T]) Equal added in v0.30.1

func (set *SortedSliceSet[T]) Equal(other *SortedSliceSet[T]) (ok bool)

Equal returns true if set is equal to other. set and other may be nil; Equal returns true if both are nil, but a nil *SortedSliceSet is not equal to a non-nil empty one.

Example
package main

import (
	"fmt"

	"github.com/AdguardTeam/golibs/container"
)

func main() {
	const x, y = 1, 2
	set := container.NewSortedSliceSet(x)

	fmt.Printf("same:       %t\n", set.Equal(container.NewSortedSliceSet(x)))
	fmt.Printf("other elem: %t\n", set.Equal(container.NewSortedSliceSet(y)))
	fmt.Printf("other len:  %t\n", set.Equal(container.NewSortedSliceSet(x, y)))
	fmt.Printf("nil:        %t\n", set.Equal(nil))
	fmt.Printf("nil eq nil: %t\n", (*container.SortedSliceSet[int])(nil).Equal(nil))

}
Output:

same:       true
other elem: false
other len:  false
nil:        false
nil eq nil: true

func (*SortedSliceSet[T]) Has added in v0.30.1

func (set *SortedSliceSet[T]) Has(v T) (ok bool)

Has returns true if v is in set. Calling Has on a nil set returns false, just like iterating over a nil or empty slice does.

func (*SortedSliceSet[T]) Intersection added in v0.35.3

func (set *SortedSliceSet[T]) Intersection(a, b *SortedSliceSet[T]) (res *SortedSliceSet[T])

Intersection fills set with values that belong to both a and b. This function guarantees zero-allocation, but may not perform well with large sets. If you need better performance, consider using MapSet. Intersection returns an empty set if one of the arguments is nil. set must not be nil. If neither a nor b are equal to set, then the function will rewrite the contents of set.

Example
package main

import (
	"fmt"

	"github.com/AdguardTeam/golibs/container"
)

func main() {
	a := container.NewSortedSliceSet(1, 6, 10)
	b := container.NewSortedSliceSet(3, 6, 12)
	set := container.NewSortedSliceSet[int]()

	fmt.Printf("a = %s, b = %s\n", a, b)
	fmt.Printf("set = a ∩ b:     %s\n", set.Intersection(a, b))
	fmt.Printf("set = nil ∩ nil: %s\n", set.Intersection(nil, nil))
	fmt.Printf("set = nil ∩ b:   %s\n", set.Intersection(nil, b))
	fmt.Printf("set = a ∩ nil:   %s\n", set.Intersection(a, nil))
	fmt.Printf("a = a ∩ b:       %s\n", a.Intersection(a, b))

	a = container.NewSortedSliceSet(1, 6, 10)
	fmt.Printf("b = a ∩ b:       %s\n", b.Intersection(a, b))

}
Output:

a = [1 6 10], b = [3 6 12]
set = a ∩ b:     [6]
set = nil ∩ nil: []
set = nil ∩ b:   []
set = a ∩ nil:   []
a = a ∩ b:       [6]
b = a ∩ b:       [6]

func (*SortedSliceSet[T]) Intersects added in v0.35.3

func (set *SortedSliceSet[T]) Intersects(other *SortedSliceSet[T]) (ok bool)

Intersects returns true if set and other has at least one common element. If set or other is nil, result will be false.

Example
package main

import (
	"fmt"

	"github.com/AdguardTeam/golibs/container"
)

func main() {
	a := container.NewSortedSliceSet(1, 6, 10)
	b := container.NewSortedSliceSet(3, 6, 12)
	var nilSet *container.SortedSliceSet[int]

	fmt.Printf("a = %s, b = %s\n", a, b)
	fmt.Printf("a ∩ b:     %t\n", a.Intersects(b))
	fmt.Printf("nil ∩ a:   %t\n", nilSet.Intersects(a))
	fmt.Printf("a ∩ nil:   %t\n", a.Intersects(nilSet))
	fmt.Printf("nil ∩ nil: %t\n", nilSet.Intersects(nilSet))

}
Output:

a = [1 6 10], b = [3 6 12]
a ∩ b:     true
nil ∩ a:   false
a ∩ nil:   false
nil ∩ nil: false

func (*SortedSliceSet[T]) Len added in v0.30.1

func (set *SortedSliceSet[T]) Len() (n int)

Len returns the length of set. A nil set has a length of zero, just like an nil or empty slice.

func (*SortedSliceSet[T]) Range added in v0.30.1

func (set *SortedSliceSet[T]) Range(f func(v T) (cont bool))

Range calls f with each value of set in their sorted order. If cont is false, Range stops the iteration. Calling Range on a nil *SortedSliceSet has no effect.

func (*SortedSliceSet[T]) String added in v0.30.1

func (set *SortedSliceSet[T]) String() (s string)

String implements the fmt.Stringer interface for *SortedSliceSet. Calling String on a nil *SortedSliceSet does not panic.

func (*SortedSliceSet[T]) Union added in v0.35.3

func (set *SortedSliceSet[T]) Union(a, b *SortedSliceSet[T]) (res *SortedSliceSet[T])

Union fills set with values belonging to either a or b. This function guarantees zero-allocation, but may not perform well with large sets. Union returns empty set if both a and b are nil. set must not be nil. If neither a nor b are equal to set, then the function will rewrite the contents of set.

Example
package main

import (
	"fmt"

	"github.com/AdguardTeam/golibs/container"
)

func main() {
	a := container.NewSortedSliceSet(1, 6, 10)
	b := container.NewSortedSliceSet(3, 6, 12)
	set := container.NewSortedSliceSet[int]()

	fmt.Printf("a = %s, b = %s\n", a, b)
	fmt.Printf("set = a ∪ b:     %s\n", set.Union(a, b))
	fmt.Printf("set = nil ∪ nil: %s\n", set.Union(nil, nil))
	fmt.Printf("set = nil ∪ b:   %s\n", set.Union(nil, b))
	fmt.Printf("set = a ∪ nil:   %s\n", set.Union(a, nil))
	fmt.Printf("a = a ∪ b:       %s\n", a.Union(a, b))

	a = container.NewSortedSliceSet(1, 6, 10)
	fmt.Printf("b = a ∪ b:       %s\n", b.Union(a, b))

}
Output:

a = [1 6 10], b = [3 6 12]
set = a ∪ b:     [1 3 6 10 12]
set = nil ∪ nil: []
set = nil ∪ b:   [3 6 12]
set = a ∪ nil:   [1 6 10]
a = a ∪ b:       [1 3 6 10 12]
b = a ∪ b:       [1 3 6 10 12]

func (*SortedSliceSet[T]) Values added in v0.30.1

func (set *SortedSliceSet[T]) Values() (values []T)

Values returns the underlying slice of set. values must not be modified. Values returns nil if set is nil.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL