english
version "1.0"
identify "xyz"

#: Copyright (c) 1991-2005 by Wayne C. Gramlich.
#, All rights reserved.

module table

#: This module implements a key-value table abstraction.

define pair[key, value]			#: Key/value pair
    record
	key key				#: Key
	value value			#: Value
    generate allocate, erase

# This is the actual table type.
define table[key, value]		#: Table of key value associations
    record
	set set[pair[key, value]]	#: Use a {set} to implement
	pair pair[key, value]		#: Temporary {pair}
    generate allocate, erase, identical



#: {pair} procedures:

procedure create@pair[key, value]
    takes
	key key
	value value
    returns pair[key, value]

    #: This procedure will create and return a new {pair} object containing
    #, {key} and {value}.


procedure equal@pair[key, value]
    takes
	pair1 pair[key, value]
	pair2 pair[key, value]
    returns logical
    needs
	procedure equal@key
	    takes key, key
	    returns logical

    #: {equal} returns {true} if {pair1} is equal to {pair2} and returns
    #, {false} otherwise.


procedure hash@pair[key, value]
    takes
	pair pair[key, value]
    returns unsigned
    needs
	procedure hash@key
	    takes key
	    returns unsigned

    #: {hash} returns a hash value for {pair}.


procedure print@pair[key, value]
    takes
	pair pair[key, value]
	out_stream out_stream
    returns_nothing
    needs
	procedure print@key
	    takes key, out_stream
	    returns_nothing
	procedure print@value
	    takes value, out_stream
	    returns_nothing

    #: This procedure will output {pair} to {out_stream}.


procedure read@pair[key, value]
    takes
	in_stream in_stream
    returns pair[key, value]
    needs
	procedure read@key
	    takes in_stream
	    returns key
	procedure read@value
	    takes in_stream
	    returns value

    #: This procedure read in a {pair} object from {in_stream} and
    #, return it.


procedure write@pair[key, value]
    takes
	pair pair[key, value]
	out_stream out_stream
    returns_nothing
    needs
	procedure write@key
	    takes key, out_stream
	    returns_nothing
	procedure write@value
	    takes value, out_stream
	    returns_nothing

    #: This procedure will write {pair} to {out_stream}.


#: {table} procedures:

procedure create@table[key, value]
    takes
	size unsigned
    returns table[key, value]

    #: {create} will return an empty table using {size} as a prediction
    #, for the number of items likely to be entered into the returned table.


procedure xcreate@table[key, value]
    takes
	size unsigned
    returns table[key, value]

    #: {create} will return an empty table using {size} as a prediction
    #, for the number of items likely to be entered into the returned table.


procedure delete@table[key, value]
    takes
	table table[key, value]
	key key
    returns logical

    #: This procedure will delete {key} from {table].  {true} is returned
    #, {key} is not in {table} and {false} otherwise.


procedure fetch1@table[key, value]
    takes
	table table[key, value]
	key key
    returns value
    needs
	procedure equal@key
	    takes key, key
	    returns logical
	procedure hash@key
	    takes key
	    returns unsigned

    #: This procedure will return the value associated with {key} in {table}.
    #, {no_matching_key} is signaled if there is no key that matches {key}
    #, in {table}.


procedure lookup@table[key, value]
    takes
	table table[key, value]
	key key
    returns value
    needs
	procedure equal@key
	    takes key, key
	    returns logical
	procedure hash@key
	    takes key
	    returns unsigned

    #: This procedure will return the value associated with {key} in {table}.
    #, {no_matching_key} is signaled if there is no key that matches {key}
    #, in {table}.


procedure insert@table[key, value]
    takes
	table table[key, value]
	key key
	value value
    returns logical
    needs
	procedure equal@key
	    takes key, key
	    returns logical
	procedure hash@key
	    takes key
	    returns unsigned

    #: This procedure will insert {key} and {value} into {table}.  If {key} is
    #, already in {table}, {true} is returned and the value already associated
    #, with {value} is left unchanged; otherwise {false} is returend.


procedure is_in@table[key, value]
    takes
	table table[key, value]
	key key
    returns logical
    needs
	procedure equal@key
	    takes key, key
	    returns logical
	procedure hash@key
	    takes key
	    returns unsigned

    #: This procedure will return {true} if {key} is in {table} and {false}
    #, otherwise.


procedure keys_get@table[key, value]
    takes
	table table[key, value]
    returns vector[key]

    #: This procedure will return the keys from {table}.


procedure pairs_get@table[key, value]
    takes
	table table[key, value]
    returns vector[pair[key, value]]

    #: This procedure will return the keys from {table}.


procedure print@table[key, value]
    takes
	table table[key, value]
	out_stream out_stream
    returns_nothing
    needs
	procedure print@key
	    takes key, out_stream
	    returns_nothing
	procedure print@value
	    takes value, out_stream
	    returns_nothing

    #: This procedure print out the contents of {table} to {out_stream}.


procedure replace@table[key, value]
    takes
	table table[key, value]
	key key
	value value
    returns logical
    needs
	procedure equal@key
	    takes key, key
	    returns logical
	procedure hash@key
	    takes key
	    returns unsigned

    #: This procedure will insert {key} and {value} into {table}.  If {key} is
    #, already in {table}, {false} is returned; otherwise {true} is returend.


procedure size_get@table[key, value]
    takes
	table table[key, value]
    returns unsigned

    #: This procedure will return the number of entries in {table}.


procedure store1@table[key, value]
    takes
	table table[key, value]
	key key
	value value
    returns_nothing
    needs
	procedure equal@key
	    takes key, key
	    returns logical
	procedure hash@key
	    takes key
	    returns unsigned

    #: This procedure will return the value associated with {key} in {table}.
    #, {no_matching_key} is signaled if there is no key that matches {key}
    #,  in {table}.


procedure read@table[key, value]
    takes
	in_stream in_stream
    returns table[key, value]
    needs
	procedure read@key
	    takes in_stream
	    returns key
	procedure read@value
	    takes in_stream
	    returns value

    #: This procedure will read in a {table} object from {in_stream} and
    #, return it.


procedure values_get@table[key, value]
    takes
	table table[key, value]
    returns vector[value]

    #: This procedure will return the values from {table}.


procedure write@table[key, value]
    takes
	table table[key, value]
	out_stream out_stream
    returns_nothing
    needs
	procedure write@key
	    takes key, out_stream
	    returns_nothing
	procedure write@value
	    takes key, out_stream
	    returns_nothing

    #: This procedure will write the contents of {table} to {out_stream}