Skip to content

Commit

Permalink
Added iterators to sync2 package
Browse files Browse the repository at this point in the history
  • Loading branch information
applejag committed Feb 19, 2025
1 parent 6acb6c8 commit e6f3704
Show file tree
Hide file tree
Showing 9 changed files with 413 additions and 0 deletions.
6 changes: 6 additions & 0 deletions go.work
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
go 1.24.0

use (
.
./sync2/internal/go_1_23
)
1 change: 1 addition & 0 deletions go.work.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
gopkg.in/typ.v4 v4.3.1/go.mod h1:wolXe8DlewxRCjA7SOiT3zjrZ0eQJZcr8cmV6bQWJUM=
9 changes: 9 additions & 0 deletions sync2/internal/go_1_23/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// SPDX-FileCopyrightText: 2025 Kalle Fagerberg
//
// SPDX-License-Identifier: CC0-1.0

module gopkg.in/typ.v4/internal/go_1_23

go 1.23.0

require gopkg.in/typ.v4 v4.3.1
2 changes: 2 additions & 0 deletions sync2/internal/go_1_23/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
gopkg.in/typ.v4 v4.3.1 h1:z3vGwIIn2X8GjP589+YS8YWmpNqBFEy0w7OcGWj0NZ4=
gopkg.in/typ.v4 v4.3.1/go.mod h1:wolXe8DlewxRCjA7SOiT3zjrZ0eQJZcr8cmV6bQWJUM=
30 changes: 30 additions & 0 deletions sync2/internal/go_1_23/map_iter_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// SPDX-FileCopyrightText: 2025 Kalle Fagerberg
//
// SPDX-License-Identifier: MIT

package go123_test

import (
"maps"
"testing"

"gopkg.in/typ.v4/sync2"
)

func TestMapIterCompiles(t *testing.T) {
m := new(sync2.Map[int, string])

for range sync2.MapAll(m) {
// do nothing
}
for range sync2.MapKeys(m) {
// do nothing
}
for range sync2.MapValues(m) {
// do nothing
}

otherMap := map[int]string{}
sync2.MapInsert(m, maps.All(otherMap))
_ = sync2.MapCollect(maps.All(otherMap))
}
46 changes: 46 additions & 0 deletions sync2/map_example_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// SPDX-FileCopyrightText: 2025 Kalle Fagerberg
//
// SPDX-License-Identifier: MIT

package sync2_test

import (
"fmt"

"gopkg.in/typ.v4/sync2"
)

func ExampleMap() {
m := new(sync2.Map[int, string])
m.Store(1, "one")
m.Store(2, "two")
m.Store(3, "three")

fmt.Println("Len:", m.Len())

// Output:
// Len: 3
}

func ExampleMap_Load() {
m := new(sync2.Map[int, string])
m.Store(1, "one")
m.Store(2, "two")
m.Store(3, "three")

if value, ok := m.Load(0); ok {
fmt.Println("Map[0]:", value)
} else {
fmt.Println("Map[0]: (no value)")
}

if value, ok := m.Load(1); ok {
fmt.Println("Map[1]:", value)
} else {
fmt.Println("Map[1]: (no value)")
}

// Output:
// Map[0]: (no value)
// Map[1]: one
}
58 changes: 58 additions & 0 deletions sync2/map_iter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// SPDX-FileCopyrightText: 2025 Kalle Fagerberg
//
// SPDX-License-Identifier: MIT

package sync2

// MapAll returns an iterator over key-value pairs in m.
// The iteeration order is not specified and is not guaranteed to be the same
// from one call to the next.
func MapAll[K comparable, V any](m *Map[K, V]) func(yield func(K, V) bool) {
return func(yield func(K, V) bool) {
m.Range(func(key K, value V) bool {
return yield(key, value)
})
}
}

// MapKeys returns an iterator over keys in m.
// The iteeration order is not specified and is not guaranteed to be the same
// from one call to the next.
func MapKeys[K comparable, V any](m *Map[K, V]) func(yield func(K) bool) {
return func(yield func(K) bool) {
m.Range(func(key K, _ V) bool {
return yield(key)
})
}
}

// MapValues returns an iterator over values in m.
// The iteeration order is not specified and is not guaranteed to be the same
// from one call to the next.
func MapValues[K comparable, V any](m *Map[K, V]) func(yield func(V) bool) {
return func(yield func(V) bool) {
m.Range(func(_ K, value V) bool {
return yield(value)
})
}
}

// MapInsert adds the key-value pairs from seq to m.
// If a key in seq already exists in m, its value will be overwritten.
func MapInsert[K comparable, V any](m *Map[K, V], iter func(yield func(K, V) bool)) {
iter(func(k K, v V) bool {
m.Store(k, v)
return true
})
}

// MapCollect collects key-value pairs from seq into a new map
// and returns it.
func MapCollect[K comparable, V any](iter func(yield func(K, V) bool)) *Map[K, V] {
m := new(Map[K, V])
iter(func(k K, v V) bool {
m.Store(k, v)
return true
})
return m
}
53 changes: 53 additions & 0 deletions sync2/map_iter_example_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// SPDX-FileCopyrightText: 2025 Kalle Fagerberg
//
// SPDX-License-Identifier: MIT

package sync2_test

import (
"gopkg.in/typ.v4/sync2"
)

func ExampleMapAll() {
m := new(sync2.Map[int, string])
m.Store(1, "one")
m.Store(2, "two")

// In Go 1.23+ you can iterate the values like so:
/*
for k, v := range sync2.MapAll(m) {
fmt.Printf("%s: %q\n", k, v)
}
*/
}

func ExampleMapKeys() {
m := new(sync2.Map[int, string])
m.Store(1, "one")
m.Store(2, "two")

// In Go 1.23+ you can iterate the values like so:
/*
for k := range sync2.MapKeys(m) {
fmt.Printf("key: %s\n", k)
}
*/
}

func ExampleMapValues() {
m := new(sync2.Map[int, string])
m.Store(1, "one")
m.Store(2, "two")

// In Go 1.23+ you can iterate the values like so:
/*
for k := range sync2.MapValues(m) {
fmt.Printf("value: %q\n", v)
}
*/

// Alternatively you can get a slice of keys like so:
/*
keys := slices.Collect(sync2.MapValues(m))
*/
}
Loading

0 comments on commit e6f3704

Please sign in to comment.