NomDL: CodeGen for Map extras

This adds Iter, IterAll and Filter to Maps

Issue #303
This commit is contained in:
Erik Arvidsson
2015-09-17 17:20:49 -04:00
parent 24f1f58042
commit f64f6ae81c
5 changed files with 149 additions and 6 deletions

View File

@@ -6,8 +6,6 @@ type {{.Name}} struct {
type {{.Name}}Def map[{{defType .KeyType}}]{{defType .ValueType}}
type {{.Name}}IterCallback (func(k {{userType .KeyType}}, v {{userType .ValueType}}) (stop bool))
func New{{.Name}}() {{.Name}} {
return {{.Name}}{types.NewMap()}
}
@@ -72,8 +70,31 @@ func (m {{.Name}}) Remove(p {{userType .KeyType}}) {{.Name}} {
return {{.Name}}{m.m.Remove({{userToValue "p" .KeyType}})}
}
type {{.Name}}IterCallback func(k {{userType .KeyType}}, v {{userType .ValueType}}) (stop bool)
func (m {{.Name}}) Iter(cb {{.Name}}IterCallback) {
m.m.Iter(func(k, v types.Value) bool {
return cb({{valueToUser "k" .KeyType}}, {{valueToUser "v" .ValueType}})
})
}
type {{.Name}}IterAllCallback func(k {{userType .KeyType}}, v {{userType .ValueType}})
func (m {{.Name}}) IterAll(cb {{.Name}}IterAllCallback) {
m.m.IterAll(func(k, v types.Value) {
cb({{valueToUser "k" .KeyType}}, {{valueToUser "v" .ValueType}})
})
}
type {{.Name}}FilterCallback func(k {{userType .KeyType}}, v {{userType .ValueType}}) (keep bool)
func (m {{.Name}}) Filter(cb {{.Name}}FilterCallback) {{.Name}} {
nm := New{{.Name}}()
m.IterAll(func(k {{userType .KeyType}}, v {{userType .ValueType}}) {
if cb(k, v) {
nm = nm.Set(k, v)
}
})
return nm
}

View File

@@ -15,8 +15,6 @@ type MapOfBoolToString struct {
type MapOfBoolToStringDef map[bool]string
type MapOfBoolToStringIterCallback (func(k bool, v string) (stop bool))
func NewMapOfBoolToString() MapOfBoolToString {
return MapOfBoolToString{types.NewMap()}
}
@@ -81,12 +79,34 @@ func (m MapOfBoolToString) Remove(p bool) MapOfBoolToString {
return MapOfBoolToString{m.m.Remove(types.Bool(p))}
}
type MapOfBoolToStringIterCallback func(k bool, v string) (stop bool)
func (m MapOfBoolToString) Iter(cb MapOfBoolToStringIterCallback) {
m.m.Iter(func(k, v types.Value) bool {
return cb(bool(k.(types.Bool)), v.(types.String).String())
})
}
type MapOfBoolToStringIterAllCallback func(k bool, v string)
func (m MapOfBoolToString) IterAll(cb MapOfBoolToStringIterAllCallback) {
m.m.IterAll(func(k, v types.Value) {
cb(bool(k.(types.Bool)), v.(types.String).String())
})
}
type MapOfBoolToStringFilterCallback func(k bool, v string) (keep bool)
func (m MapOfBoolToString) Filter(cb MapOfBoolToStringFilterCallback) MapOfBoolToString {
nm := NewMapOfBoolToString()
m.IterAll(func(k bool, v string) {
if cb(k, v) {
nm = nm.Set(k, v)
}
})
return nm
}
// MapOfStringToValue
type MapOfStringToValue struct {
@@ -95,8 +115,6 @@ type MapOfStringToValue struct {
type MapOfStringToValueDef map[string]types.Value
type MapOfStringToValueIterCallback (func(k string, v types.Value) (stop bool))
func NewMapOfStringToValue() MapOfStringToValue {
return MapOfStringToValue{types.NewMap()}
}
@@ -161,8 +179,30 @@ func (m MapOfStringToValue) Remove(p string) MapOfStringToValue {
return MapOfStringToValue{m.m.Remove(types.NewString(p))}
}
type MapOfStringToValueIterCallback func(k string, v types.Value) (stop bool)
func (m MapOfStringToValue) Iter(cb MapOfStringToValueIterCallback) {
m.m.Iter(func(k, v types.Value) bool {
return cb(k.(types.String).String(), v)
})
}
type MapOfStringToValueIterAllCallback func(k string, v types.Value)
func (m MapOfStringToValue) IterAll(cb MapOfStringToValueIterAllCallback) {
m.m.IterAll(func(k, v types.Value) {
cb(k.(types.String).String(), v)
})
}
type MapOfStringToValueFilterCallback func(k string, v types.Value) (keep bool)
func (m MapOfStringToValue) Filter(cb MapOfStringToValueFilterCallback) MapOfStringToValue {
nm := NewMapOfStringToValue()
m.IterAll(func(k string, v types.Value) {
if cb(k, v) {
nm = nm.Set(k, v)
}
})
return nm
}

View File

@@ -60,3 +60,45 @@ func TestValueMapValue(t *testing.T) {
m2 := MapOfStringToValueFromVal(val)
assert.True(m.Equals(m2))
}
func TestMapIter(t *testing.T) {
assert := assert.New(t)
m := MapOfBoolToStringDef{true: "hi", false: "bye"}.New()
acc := NewMapOfBoolToString()
m.Iter(func(k bool, v string) bool {
acc = acc.Set(k, v)
return false
})
assert.True(m.Equals(acc))
acc = NewMapOfBoolToString()
m.Iter(func(k bool, v string) bool {
return true
})
assert.True(acc.Empty())
}
func TestMapIterAll(t *testing.T) {
assert := assert.New(t)
m := MapOfBoolToStringDef{true: "hi", false: "bye"}.New()
acc := NewMapOfBoolToString()
m.IterAll(func(k bool, v string) {
acc = acc.Set(k, v)
})
assert.True(m.Equals(acc))
}
func TestMapFilter(t *testing.T) {
assert := assert.New(t)
m := MapOfBoolToStringDef{true: "hi", false: "bye"}.New()
m2 := m.Filter(func(k bool, v string) bool {
return k
})
assert.True(NewMapOfBoolToString().Set(true, "hi").Equals(m2))
m3 := m.Filter(func(k bool, v string) bool {
return v == "bye"
})
assert.True(NewMapOfBoolToString().Set(false, "bye").Equals(m3))
}

View File

@@ -83,12 +83,42 @@ func (fm Map) Iter(cb mapIterCallback) {
for _, entry := range fm.m {
k := entry.key.Deref(fm.cs)
v := entry.value.Deref(fm.cs)
entry.key.Release()
entry.value.Release()
if cb(k, v) {
break
}
}
}
type mapIterAllCallback func(key, value Value)
func (fm Map) IterAll(cb mapIterAllCallback) {
for _, entry := range fm.m {
k := entry.key.Deref(fm.cs)
v := entry.value.Deref(fm.cs)
cb(k, v)
entry.key.Release()
entry.value.Release()
}
}
type mapFilterCallback func(key, value Value) (keep bool)
func (fm Map) Filter(cb mapFilterCallback) Map {
nm := NewMap()
for _, entry := range fm.m {
k := entry.key.Deref(fm.cs)
v := entry.value.Deref(fm.cs)
if cb(k, v) {
nm = nm.Set(k, v)
}
entry.key.Release()
entry.value.Release()
}
return nm
}
func (fm Map) Ref() ref.Ref {
return ensureRef(fm.ref, fm)
}

View File

@@ -135,6 +135,16 @@ func TestMapIter(t *testing.T) {
assert.True(got(NewString("a"), Int32(0)) || got(NewString("b"), Int32(1)))
}
func TestMapFilter(t *testing.T) {
assert := assert.New(t)
m := NewMap(Int8(0), NewString("a"), Int8(1), NewString("b"), Int8(2), NewString("c"))
m2 := m.Filter(func(k, v Value) bool {
return k.Equals(Int8(0)) || v.Equals(NewString("c"))
})
assert.True(NewMap(Int8(0), NewString("a"), Int8(2), NewString("c")).Equals(m2))
}
func TestMapEquals(t *testing.T) {
assert := assert.New(t)
m1 := NewMap()