summaryrefslogtreecommitdiff
path: root/lib/iter
diff options
context:
space:
mode:
authorS. Gilles <sgilles@math.umd.edu>2018-01-08 14:05:55 -0500
committerOri Bernstein <ori@markovcorp.com>2018-01-08 11:24:25 -0800
commite761ce9ef2f89c9f87a4be72b88b837109630c2b (patch)
tree42d81dbbb850ce9d55268e1f5a666481e36c1f14 /lib/iter
parent93db6a9fd69794d74e56cbdfc7796b46da407812 (diff)
downloadmc-e761ce9ef2f89c9f87a4be72b88b837109630c2b.tar.gz
let bychunk() read the last element; guard for negative sz
I mentioned on IRC that bychunk() was skipping the last element of a slice, here's a fix for that, as well as some redundant tests and some probably unneeded input validation. I don't have any strong feelings about protecting someone from shooting themselves in the foot with bychunk([1][:], -100), but it's easier to remove in review than to add later.
Diffstat (limited to 'lib/iter')
-rw-r--r--lib/iter/chunk.myr4
-rw-r--r--lib/iter/test/chunk.myr44
2 files changed, 46 insertions, 2 deletions
diff --git a/lib/iter/chunk.myr b/lib/iter/chunk.myr
index 5d0d68c..80a74e6 100644
--- a/lib/iter/chunk.myr
+++ b/lib/iter/chunk.myr
@@ -12,7 +12,7 @@ pkg iter =
;;
generic bychunk = {a, sz
- -> [.sl = a, .idx = 0, .blksz = sz]
+ -> [.sl = a, .idx = 0, .blksz = std.max(sz, 1)]
}
impl iterable chunkiter(@a) -> @a[:] =
@@ -20,7 +20,7 @@ impl iterable chunkiter(@a) -> @a[:] =
var len
len = std.min(itp.blksz, itp.sl.len - itp.idx)
- if itp.idx + len == itp.sl.len
+ if itp.idx + len > itp.sl.len || itp.idx >= itp.sl.len
-> false
;;
valp# = itp.sl[itp.idx: itp.idx + len]
diff --git a/lib/iter/test/chunk.myr b/lib/iter/test/chunk.myr
new file mode 100644
index 0000000..38465d7
--- /dev/null
+++ b/lib/iter/test/chunk.myr
@@ -0,0 +1,44 @@
+use std
+use testr
+
+use iter
+
+const main = {
+ testr.run([
+ [.name = "bychunk-01", .fn = bychunk01],
+ [.name = "bychunk-02", .fn = bychunk02],
+ [.name = "bychunk-03", .fn = bychunk03],
+ [.name = "bychunk-04", .fn = bychunk04],
+ [.name = "bychunk-05", .fn = bychunk05],
+ ][:])
+}
+
+const verify_bychunk = {c, v, n, e
+ var sb : std.strbuf# = std.mksb()
+ std.sbfmt(sb, " ")
+ for w : iter.bychunk(v, n)
+ std.sbfmt(sb, "{} ", w)
+ ;;
+ var a : byte[:] = std.sbfin(sb)
+ testr.check(c, std.eq(e, a), "expected “{}”, got “{}”", e, a)
+}
+
+const bychunk01 = {c
+ verify_bychunk(c, [1, 2, 3, 4][:], 1, " [1] [2] [3] [4] ")
+}
+
+const bychunk02 = {c
+ verify_bychunk(c, [1, 2, 3, 4, 5, 6, 7, 8][:], 3, " [1, 2, 3] [4, 5, 6] [7, 8] ")
+}
+
+const bychunk03 = {c
+ verify_bychunk(c, [1, 2, 3, 4][:], 99, " [1, 2, 3, 4] ")
+}
+
+const bychunk04 = {c
+ verify_bychunk(c, [1, 2, 3, 4][:], -2, " [1] [2] [3] [4] ")
+}
+
+const bychunk05 = {c
+ verify_bychunk(c, [][:], 3, " ")
+}