Array2.copy
Stephen Weeks
sweeks@wasabi.epr.com
Mon, 18 Oct 1999 16:49:59 -0700 (PDT)
I finally got around to building an implementation of Array2.copy.
Let me know if you notice any bugs.
--------------------------------------------------------------------------------
fun checkSliceMax(start: int, num: int option, max: int): int =
case num of
NONE => if start < 0 orelse start > max
then raise Subscript
else max
| SOME num =>
if start < 0 orelse num < 0 orelse start > max - num
then raise Subscript
else start + num
fun checkRegion{base, row, col, nrows, ncols} =
let val (rows, cols) = dimensions base
in {stopRow = checkSliceMax(row, nrows, rows),
stopCol = checkSliceMax(col, ncols, cols)}
end
fun copy{src = src as {base, row, col, nrows, ncols},
dst, dst_row, dst_col} =
let val {stopRow, stopCol} = checkRegion src
val nrows = stopRow - row
val ncols = stopCol - col
val _ = checkRegion{base = dst, row = dst_row, col = dst_col,
nrows = SOME nrows, ncols = SOME ncols}
fun for(start, stop, f) =
let fun loop i = if i = stop then () else (f i; loop(i + 1))
in loop start
end
fun forDown(start, stop, f) =
let fun loop i = if i < start then () else (f i; loop(i - 1))
in loop(stop - 1)
end
val forRows = if row <= dst_row then forDown else for
val forCols = if col <= dst_col then for else forDown
in forRows(0, nrows, fn r =>
forCols(0, ncols, fn c =>
update(dst, dst_row + r, dst_col + c,
sub(base, row + r, col + c))))
end