diff: uniq_array.m bug fix and enhancement

Andrew Bromage bromage at murlibobo.cs.mu.OZ.AU
Tue Jul 15 13:30:44 AEST 1997


G'day.

Fergus, could you review this one please?

Cheers,
Andrew Bromage


Estimated hours taken: 0.5

Three changes:

	- Documentation fix to uniq_array__make_empty_array/1.  It
	  used to say that an array of size zero had bounds from 0
	  to 0, but that's not true.  An array with bounds from 0
	  to 0 has size one.

	- Bug fix to uniq_array__resize/4.  Previously, if the
	  destination array size was smaller than the source array,
	  ML_resize_uniq_array would overwrite the bounds of the
	  newly created array.

	- Added new predicate uniq_array__shrink/3.

Note that array__shrink/3 has not been added because the module is
about to disappear.

library/uniq_array.m:
	Changes detailed above.

NEWS:
	Report change to interface of uniq_array.

Index: NEWS
===================================================================
RCS file: /home/staff/zs/imp/mercury/NEWS,v
retrieving revision 1.58
diff -u -r1.58 NEWS
--- NEWS	1997/07/08 16:48:05	1.58
+++ NEWS	1997/07/15 03:17:08
@@ -208,3 +208,8 @@
     (string__to_char_list(String, Chars), list__foldl(Pred, Chars, Acc0, Acc))
     but is implemented more efficiently.
 
+  - uniq_array__shrink/3 has been added to the library.  This is similar
+    to uniq_array__resize/4 except that it's designed for cases when you
+    only want to make an array smaller, so you don't have to supply a
+    filler element.
+
Index: library/uniq_array.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/library/uniq_array.m,v
retrieving revision 1.23
diff -u -r1.23 uniq_array.m
--- uniq_array.m	1997/05/21 02:16:31	1.23
+++ uniq_array.m	1997/07/15 03:14:33
@@ -34,9 +34,10 @@
 :- mode uniq_array_uo == out(uniq_array).
 :- mode uniq_array_ui == in(uniq_array).
 
-	% uniq_array__make_empty_array(Array) creates an array of size zero
-	% with bounds from 0 to 0.
+%-----------------------------------------------------------------------------%
 
+	% uniq_array__make_empty_array(Array) creates an array of size zero
+	% starting at lower bound 0.
 :- pred uniq_array__make_empty_array(uniq_array(T)).
 :- mode uniq_array__make_empty_array(uniq_array_uo) is det.
 
@@ -52,6 +53,8 @@
 :- func uniq_array(list(T)) = uniq_array(T).
 :- mode uniq_array(in) = uniq_array_uo is det.
 
+%-----------------------------------------------------------------------------%
+
 	% uniq_array__max returns the upper bound of the array
 :- pred uniq_array__max(uniq_array(_T), int).
 :- mode uniq_array__max(uniq_array_ui, out) is det.
@@ -69,6 +72,8 @@
 :- mode uniq_array__in_bounds(uniq_array_ui, in) is semidet.
 :- mode uniq_array__in_bounds(in, in) is semidet.
 
+%-----------------------------------------------------------------------------%
+
 	% uniq_array__lookup returns the Nth element of a uniq_array.
 	% It is an error if the index is out of bounds.
 :- pred uniq_array__lookup(uniq_array(T), int, T).
@@ -126,6 +131,12 @@
 :- pred uniq_array__resize(uniq_array(T), int, T, uniq_array(T)).
 :- mode uniq_array__resize(uniq_array_di, in, in, uniq_array_uo) is det.
 
+	% uniq_array__shrink(Array0, Size, Array):
+	% The uniq_array is shrunk to make it fit the new size `Size'.
+	% It is an error if `Size' is larger than the size of `Array0'.
+:- pred uniq_array__shrink(uniq_array(T), int, uniq_array(T)).
+:- mode uniq_array__shrink(uniq_array_di, in, uniq_array_uo) is det.
+
 	% uniq_array__from_list takes a list,
 	% and returns a uniq_array containing those elements in
 	% the same order that they occured in the list.
@@ -508,14 +519,17 @@
 {
 	Integer i;
 	MR_UniqArrayType* array;
-	Integer old_array_size;
+	Integer elements_to_copy;
 
-	old_array_size = old_array->size;
-	if (old_array_size == array_size) return old_array;
+	elements_to_copy = old_array->size;
+	if (elements_to_copy == array_size) return old_array;
+	if (elements_to_copy > array_size) {
+		elements_to_copy = array_size;
+	}
 
 	array = (MR_UniqArrayType *) make_many(Word, array_size + 1);
 	array->size = array_size;
-	for (i = 0; i < old_array_size; i++) {
+	for (i = 0; i < elements_to_copy; i++) {
 		array->elements[i] = old_array->elements[i];
 	}
 	for (; i < array_size; i++) {
@@ -538,6 +552,51 @@
 "
 	UniqArray = (Word) ML_resize_uniq_array(
 				(MR_UniqArrayType *) UniqArray0, Size, Item);
+").
+
+%-----------------------------------------------------------------------------%
+
+:- pragma(c_header_code, "
+MR_UniqArrayType * ML_shrink_uniq_array(MR_UniqArrayType *old_array,
+					Integer array_size);
+").
+
+:- pragma(c_code, "
+MR_UniqArrayType *
+ML_shrink_uniq_array(MR_UniqArrayType *old_array, Integer array_size)
+{
+	Integer i;
+	MR_UniqArrayType* array;
+	Integer old_array_size;
+
+	old_array_size = old_array->size;
+	if (old_array_size == array_size) return old_array;
+	if (old_array_size < array_size) {
+		fatal_error(""uniq_array__shrink: can't shrink to a larger size"");
+	}
+
+	array = (MR_UniqArrayType *) make_many(Word, array_size + 1);
+	array->size = array_size;
+	for (i = 0; i < array_size; i++) {
+		array->elements[i] = old_array->elements[i];
+	}
+
+	/*
+	** since the mode on the old array is `uniq_array_di', it is safe to
+	** deallocate the storage for it
+	*/
+	oldmem(old_array);
+
+	return array;
+}
+").
+
+:- pragma(c_code,
+	uniq_array__shrink(UniqArray0::uniq_array_di, Size::in,
+		UniqArray::uniq_array_uo),
+"
+	UniqArray = (Word) ML_shrink_uniq_array(
+				(MR_UniqArrayType *) UniqArray0, Size);
 ").
 
 %-----------------------------------------------------------------------------%




More information about the developers mailing list