shithub: mc

Download patch

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)
+		}],
+	][:])
+}