ref: 0d5960f41c718947e1f838407eefb5ac12f54c51
parent: 65d4e2176f7f0ea82fe641571fc1542a4856da77
author: Ori Bernstein <ori@eigenstate.org>
date: Mon Oct 17 15:10:39 EDT 2016
Add bitset iteration and tests.
--- a/lib/escfmt/test/escsh.myr
+++ b/lib/escfmt/test/escsh.myr
@@ -3,7 +3,7 @@
use testr
const main = {
- testr.run([\
+ testr.run([
[.name="basic", .fn={ctx
var s = std.fmt("{}", escfmt.sh("word"))
testr.check(ctx, std.sleq("'word'", s), "mismatched escape")
--- a/lib/std/bitset.myr
+++ b/lib/std/bitset.myr
@@ -15,6 +15,7 @@
const mkbs : (-> bitset#)
const bsdup : (bs : bitset# -> bitset#)
const bsfree : (bs : bitset# -> void)
+ const bsclear : (bs : bitset# -> bitset#)
const bsmax : (a : bitset# -> size)
@@ -28,8 +29,13 @@
const bseq : (a : bitset#, b : bitset# -> bool)
const bsissubset : (a : bitset#, b : bitset# -> bool)
+ type bsiter = struct
+ idx : size
+ bs : bitset#
+ ;;
- const bsclear : (bs : bitset# -> bitset#)
+ impl iterable bsiter -> size
+ generic bsbyvalue : (bs : bitset# -> bsiter)
;;
const mkbs = {
@@ -149,4 +155,29 @@
ensurelen(a, sz)
ensurelen(b, sz)
}
+
+generic bsbyvalue = {bs
+ -> [.idx=0, .bs=bs]
+}
+
+impl iterable bsiter -> size =
+ __iternext__ = {itp, valp
+ var bs = itp.bs
+ var n = bsmax(bs)
+ for var i = itp.idx; i < n; i++
+ /* fast forward by whole chunks */
+ while i < n && bs.bits[i >> 8*sizeof(size)] != 0
+ i = (i + 8*sizeof(size)) & ~(8*sizeof(size) - 1)
+ ;;
+ if bshas(bs, i)
+ valp# = i
+ -> true
+ ;;
+ ;;
+ -> false
+ }
+
+ __iterfin__ = {itp, valp
+ }
+;;
--- a/lib/std/bld.sub
+++ b/lib/std/bld.sub
@@ -1,3 +1,5 @@
+testdeps = ../testr:testr ;;
+
lib std {inc=.} =
lib ../sys:sys
--- /dev/null
+++ b/lib/std/test/bitset.myr
@@ -1,0 +1,57 @@
+use std
+use testr
+
+const main = {
+ testr.run([
+ [.name="basic", .fn={ctx
+ var bs = std.mkbs()
+ std.bsput(bs, 0)
+ std.bsput(bs, 1)
+ std.bsput(bs, 16)
+ testr.check(ctx, std.bshas(bs, 0), "missing 0")
+ testr.check(ctx, std.bshas(bs, 1), "missing 1")
+ testr.check(ctx, std.bshas(bs, 16), "missing 16")
+ testr.check(ctx, !std.bshas(bs, -1), "negative val")
+ testr.check(ctx, !std.bshas(bs, 2), "extra 2")
+ testr.check(ctx, !std.bshas(bs, 15), "extra 15")
+ testr.check(ctx, !std.bshas(bs, 17), "extra 2")
+ std.bsfree(bs)
+ }],
+ [.name="bigsets", .fn={ctx
+ var bs = std.mkbs()
+ /* multiple chunks */
+ std.bsput(bs, 0)
+ std.bsput(bs, 63)
+ std.bsput(bs, 64)
+ std.bsput(bs, 65)
+ std.bsput(bs, 73)
+ std.bsput(bs, 127)
+ std.bsput(bs, 128)
+ std.bsput(bs, 129)
+ testr.check(ctx, std.bshas(bs, 0), "missing 0")
+ testr.check(ctx, std.bshas(bs, 63), "missing 63")
+ testr.check(ctx, std.bshas(bs, 64), "missing 64")
+ testr.check(ctx, std.bshas(bs, 65), "missing 65")
+ testr.check(ctx, std.bshas(bs, 127), "missing 127")
+ testr.check(ctx, std.bshas(bs, 128), "missing 128")
+ testr.check(ctx, std.bshas(bs, 129), "missing 129")
+ std.bsfree(bs)
+ }],
+ [.name="iter", .fn={ctx
+ var bs = std.mkbs()
+ var expected = [0,1,3,7,16][:]
+ var i = 0
+
+ std.bsput(bs, 1)
+ std.bsput(bs, 0)
+ std.bsput(bs, 16)
+ std.bsput(bs, 7)
+ std.bsput(bs, 3)
+ for e in std.bsbyvalue(bs)
+ testr.check(ctx, e == expected[i], "expected[{}] ({}) != {}", i, e, expected[i])
+ i++
+ ;;
+ std.bsfree(bs)
+ }],
+ ][:])
+}