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