Module: internal Author: Jonathan Bachrach Copyright: Original Code is Copyright (c) 1995-2004 Functional Objects, Inc. All rights reserved. License: Functional Objects Library Public License Version 1.0 Dual-license: GNU Lesser General Public License Warranty: Distributed WITHOUT WARRANTY OF ANY KIND define sealed inline method make (class == , #rest all-keys, #key) => (array :: ) apply(make, , all-keys) end method make; define sealed inline method empty? (array :: ) => (b :: ) array.size = 0 end method empty?; define constant = limited(, of: ); define constant $empty-dimensions = make(, size: 0); define macro limited-array-minus-constructor-definer { define limited-array-minus-constructor "<" ## ?:name ## ">" (?superclasses:*) (#key ?fill:expression) } => { define primary class "" (?superclasses) constant slot dimensions :: = $empty-dimensions, init-keyword: dimensions:; repeated slot "row-major-" ## ?name ## "-array-element" :: "<" ## ?name ## ">", init-keyword: fill:, init-value: ?fill, size-getter: size, size-init-keyword: size:, size-init-value: 0; end class; define sealed domain initialize (""); define sealed domain size (""); define sealed domain empty? (""); define sealed domain rank (""); define sealed domain row-major-index (""); define sealed domain dimensions (""); define sealed domain dimension ("", ); define sealed domain aref (""); define sealed domain aref-setter ("<" ## ?name ## ">", ""); define inline sealed method element (array :: "", index :: , #key default = unsupplied()) => (object :: "<" ## ?name ## ">") if (element-range-check(index, size(array))) "row-major-" ## ?name ## "-array-element"(array, index) else if (unsupplied?(default)) element-range-error(array, index) else check-type(default, element-type(array)); default end if end if end method element; define inline sealed method element-no-bounds-check (array :: "", index :: , #key default) => (object :: "<" ## ?name ## ">") "row-major-" ## ?name ## "-array-element"(array, index) end method element-no-bounds-check; define inline sealed method element-no-bounds-check-setter (new-value :: "<" ## ?name ## ">", array :: "", index :: ) => (object :: "<" ## ?name ## ">") "row-major-" ## ?name ## "-array-element"(array, index) := new-value end method element-no-bounds-check-setter; define method fill! (target :: "", value :: "<" ## ?name ## ">", #key start :: = 0, end: last = unsupplied()) => (target :: "") let last :: = check-start-compute-end(target, start, last); without-bounds-checks for (index :: from start below last) target[index] := value end; end without-bounds-checks; target end method; } end macro; define inline function compute-size-from-dimensions (dimensions :: false-or()) => (size :: false-or()) dimensions & if (dimensions.size = 0) 0 else reduce(\*, 1, dimensions) end if end function; define function compute-array-dimensions-and-size (dimensions) => (dimensions :: , size :: ) if (supplied?(dimensions)) let canonical-dimensions = as(, dimensions); values(canonical-dimensions, compute-size-from-dimensions(canonical-dimensions)); else error(make(, format-string: "No dimensions in call to make()")); end if; end function; define macro limited-array-minus-selector-definer { define limited-array-minus-selector "<" ## ?:name ## ">" (?superclasses:*) (#key ?fill:expression) } => { define limited-array-minus-constructor "<" ## ?name ## ">" (?superclasses) (fill: ?fill); define sealed inline method element-type (t :: "") => (type :: ) "<" ## ?name ## ">" end method; define sealed method element-setter (new-value :: "<" ## ?name ## ">", array :: "", index :: ) => (object :: "<" ## ?name ## ">") if (index >= 0 & index < array.size) "row-major-" ## ?name ## "-array-element"(array, index) := new-value else element-range-error(array, index) end if end method element-setter; define sealed method make (class == "", #key dimensions = unsupplied(), fill) => (array :: "") let (dimensions, size) = compute-array-dimensions-and-size(dimensions); ?=next-method(class, dimensions: dimensions, size: size, fill: fill) end method make } end macro; define macro limited-array-definer { define limited-array "<" ## ?:name ## ">" (#key ?fill:expression) } => { define limited-array-minus-selector "<" ## ?name ## ">" () (fill: ?fill); define method concrete-limited-array-class (of == "<" ## ?name ## ">") => (res :: ) "" end method } end macro; define limited-array (fill: #f); define method limited-array (of :: , dimensions :: false-or()) => (type :: ) let concrete-class = concrete-limited-vector-class(of); let default-concrete-class = ; if (dimensions | concrete-class == default-concrete-class) let size = compute-size-from-dimensions(dimensions); make(, class: , element-type: of, concrete-class: concrete-class, size: size, dimensions: dimensions); else concrete-class end if; end method; // eof