soa
is an SoA code generator and generic SoA slice library.
To install the code generator, add it as a tool dependency:
go get -tool github.com/ichiban/soa/cmd/soagen
The basic usage is to include the line //go:generate go tool soagen
in your file with the structs you want to generate SoA slices.
Let's say you have point.go
containing Point
, you can generate point_soa.go
containing PointSlice
by executing go generate ./...
.
point.go
:
package main
//go:generate go tool soagen
type Point struct {
X int
Y int
}
point_soa.go
:
// Code generated by soagen; DO NOT EDIT.
package main
type PointSlice struct {
X []int
Y []int
}
// And some methods.
Now, PointSlice
works as an alternative to []Point
.
package main
import "fmt"
func main() {
// s := make([]Point, 3, 10)
var s PointSlice
s = s.Grow(10)
s = s.Slice(0, 3, s.Cap())
// s[i] = ...
s.Set(0, Point{X: 1, Y: 1})
s.Set(1, Point{X: 2, Y: 2})
s.Set(2, Point{X: 3, Y: 3})
for i := 0; i < s.Len(); i++ {
// p := s[i]
p := s.Get(i)
fmt.Printf("s[%d] = (%d, %d)\n", i, p.X, p.Y)
}
}
Output:
s[0] = (1, 1)
s[1] = (2, 2)
s[2] = (3, 3)
You can specify the pattern for the SoA slices with `-name`. It'll replace `{{.}}` with the original struct name.
point.go
:
package main
//go:generate go tool soagen -name "{{.}}Collection"
type Point struct {
X int
Y int
}
point_soa.go
// Code generated by soagen; DO NOT EDIT.
package main
type PointCollection struct {
X []int
Y []int
}
// And some methods.
You can specify the output filenames with `-out`.
point.go
:
package main
//go:generate go tool soagen -out point_gen.go
type Point struct {
X int
Y int
}
point_gen.go
:
// Code generated by soagen; DO NOT EDIT.
package main
type PointSlice struct {
X []int
Y []int
}
// And some methods.
If you list struct names, it'll process listed structs only.
foo_bar_baz.go
:
package main
//go:generate go tool soagen Foo Baz
type Foo struct {
X int
Y int
}
type Bar struct {
X int
Y int
}
type Baz struct {
X int
Y int
}
foo_bar_baz_soa.go
:
// Code generated by soagen; DO NOT EDIT.
package main
type FooSlice struct {
X []int
Y []int
}
// And some methods.
type BazSlice struct {
X []int
Y []int
}
// And some methods.
You can manipulate SoA slices with the library github.com/ichiban/soa
.
It implements slices
-compatible functions.
With the library, the example in Basic Usage can be written with much ease.
package main
import (
"fmt"
"github.com/ichiban/soa"
)
func main() {
// s := make([]Point, 0, 10)
s := soa.Make[PointSlice](0, 10)
// s = append(s, ...)
s = soa.Append(s, Point{X: 1, Y: 1}, Point{X: 2, Y: 2}, Point{X: 3, Y: 3})
// for i, p := range s {
for i, p := range soa.All(s) {
fmt.Printf("s[%d] = (%d, %d)\n", i, p.X, p.Y)
}
}
Distributed under the MIT license. See LICENSE
for more information.
- Fork it (https://github.com/ichiban/soa/fork)
- Create your feature branch (git checkout -b feature/fooBar)
- Commit your changes (git commit -am 'Add some fooBar')
- Push to the branch (git push origin feature/fooBar)
- Create a new Pull Request