english
version "1.0"
identify "%Z%%M% %I% %E%"

#: Copyright (c) 1995, 1997, 2003 by Wayne C. Gramlich.
#, All rights reserved.
#,
#, Permission to use, copy, modify, distribute, and sell this software
#, for any purpose is hereby granted without fee provided that the above
#, copyright notice and this permission are retained.  The author makes
#, no representations about the suitability of this software for any purpose.
#, It is provided "as is" without express or implied warranty.

module matrix

#: This module implements a rectangular matrix abstraction.  The matrix
#, can either have fixed dimensionality or be autosizing.

define matrix[element]			#: Matrix abstraction
    routine_types
	procedure copy_routine
	    takes element
	    returns element
    record
	auto_size logical		#: {true}=>expand bounds as necessary
	columns unsigned		#: Total number of x columns
	copy_routine copy_routine	#: Routine to copy element
	data vector[vector[element]]	#: Matrix data
	empty element			#: Empty element
	share_empty logical		#: [true}=>share emtpy;{false}=>copy
	rows unsigned			#: Total number of y rows
    generate allocate, erase, print



procedure create@matrix[element]
    takes_nothing
    returns matrix[element]

    #: This procedure will create and return an empty {matrix}.
    #, The returned matrix is autosizing.


procedure empty_xset@matrix[element]
    takes
	matrix matrix[element]
	empty element
    returns_nothing

    #: This routine will set the empty value to use for uninitialized
    #, (x, y) entries in {matrix} to {empty}.  Unless {empties_copy}@{matrix}
    #, is invoked, pointers to {empty} will be shared; otherwise, copies
    #, of {empty} will be made.


procedure empties_copy@matrix[element]
    takes
	matrix matrix[element]
    returns_nothing
    needs    
	procedure copy@element
	    takes element
	    returns element

    #: This procedure will cause the


procedure fetch2@matrix[element]
    takes
	matrix matrix[element]
	x unsigned
	y unsigned
    returns element

    #: This procedure will return the element at the ({x}, {y]) location
    #, {matrix}.  For fixed matrices, this operation will fail if either
    #, {x} or {y} is out of bounds.


procedure store2@matrix[element]
    takes
	matrix matrix[element]
	x unsigned
	y unsigned
	element element
    returns_nothing

    #: This procedure will store {element} into {matrix} at ({x}, {y}).
    #, For fixed matrices, this operation will fail if either {x} or {y}
    #, is out of bounds.