-- This file is free software, which comes along with SmartEiffel. This -- software is distributed in the hope that it will be useful, but WITHOUT -- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -- FITNESS FOR A PARTICULAR PURPOSE. You can modify it as you want, provided -- this header is kept unaltered, and a notification of the changes is added. -- You are allowed to redistribute it and sell it, alone or as a part of -- another product. -- Copyright (C) 1994-2002 LORIA - INRIA - U.H.P. Nancy 1 - FRANCE -- Dominique COLNET and Suzanne COLLIN - SmartEiffel@loria.fr -- http://SmartEiffel.loria.fr -- class FIXED_ARRAY2[E] -- -- Resizable two dimensional array. -- Unlike ARRAY2, the `lower1' bound and the `lower2' bound are -- frozen to 0. Thus, one can expect better performances. -- inherit COLLECTION2[E] creation make, copy, from_collection2, from_collection, from_model feature upper1, count1, upper2, count2, count: INTEGER feature {FIXED_ARRAY2} storage: NATIVE_ARRAY[E] capacity : INTEGER; -- of `storage'. feature lower1: INTEGER is 0 lower2: INTEGER is 0 feature make(new_count1 , new_count2 : INTEGER) is -- Create or reset Current with new dimensions. -- All elements are set to the default value of type E. require new_count1 > 0 new_count2 > 0 do count1 := new_count1 upper1 := new_count1 - 1 count2 := new_count2 upper2 := new_count2 - 1 count := count1 * count2 if capacity < count then capacity := count storage := storage.calloc(capacity) else storage.clear_all(capacity - 1) end ensure count1 = new_count1 count2 = new_count2 all_default end from_collection(model: COLLECTION2[like item]) is -- Uses the `model' to update Current. local i, j: INTEGER do make(model.upper1+1, model.upper2+1) from i := 0 until i > upper1 loop from j := 0 until j > upper2 loop put(model.item(i,j),i,j) j := j + 1 end i := i + 1 end end feature -- Implementation of others feature from COLLECTION2: item(line, column: INTEGER): E is do Result := storage.item(line * count2 + column) end put(x: like item; line, column: INTEGER) is do storage.put(x,line * count2 + column) end force(element: like item; line , column : INTEGER) is do if not valid_index(line, column) then resize(line.max(upper1),column.max(upper2)) end put(element,line,column) end copy(other: like Current) is do count1 := other.count1 upper1 := count1 - 1 count2 := other.count2 upper2 := count2 - 1 count := count1 * count2 if capacity < count then capacity := count storage := storage.calloc(capacity) end storage.copy_from(other.storage, count - 1) end is_equal(other: like Current): BOOLEAN is do if other = Current then Result := true elseif upper1 /= other.upper1 then elseif upper2 /= other.upper2 then else Result := storage.memcmp(other.storage,count) end end feature -- Writing: set_all_with(x: E) is -- All element are set with the value x. do storage.set_all_with(x,count - 1) ensure count = old count end; -- set_all_with all_default: BOOLEAN is do result := storage.all_default(count - 1) end slice(l1,up1,l2,up2: INTEGER): like Current is -- Create a new collection initialized with elements of -- range `low'..`up'. Result has the same dynamic type -- as Current collection. local ligne,colonne : INTEGER do from !!Result.make((up1 - l1) + 1,(up2 - l2) + 1) ligne := l1 until ligne > up1 loop from colonne := l2 until colonne > up2 loop Result.put(item(ligne,colonne),ligne - l1,colonne - l2) colonne := colonne + 1 end ligne := ligne + 1 end end; -- slice set_slice(element: like item; l1,up1,l2,up2: INTEGER) is -- Set all the elements in the -- range [(l1,up1),(l2,up2)] of -- Current with the element 'element'. local i,j : INTEGER do from i := l1 * count2 until i > up1 * count2 loop from j := l2 until j > up2 loop storage.put(element,i + j) j := j + 1 end i := i + count2 end end swap(line1, column1, line2, column2 : INTEGER) is local tmp: like item c2, index1, index2 : INTEGER do c2 := count2 index1 := line1 * c2 + column1 index2 := line2 * c2 + column2 tmp := storage.item( index1) storage.put(storage.item(index2) ,index1) storage.put(tmp,index2) end feature -- Looking and comparison: occurrences(elt: E): INTEGER is do Result := storage.occurrences(elt,count - 1) end fast_occurrences(elt: E): INTEGER is do Result := storage.fast_occurrences(elt,count - 1) end feature -- Resizing: resize(new_count1 , new_count2: INTEGER) is require new_count1 > 0 new_count2 > 0 local tmp: like Current l, c: INTEGER do !!tmp.make(new_count1, new_count2) -- It may be possible to avoid this ceation when : -- new `capacity' <= old `capacity' from l := line_maximum until l < 0 loop from c := column_maximum until c < 0 loop if tmp.valid_index(l,c) then tmp.put(item(l,c),l,c) end c := c - 1 end l := l - 1 end standard_copy(tmp) ensure upper1 = new_count1 - 1 count1 = new_count1 upper2 = new_count2 - 1 count2 = new_count2 count = new_count1 * new_count2 end feature -- Looking and Searching: has(x: like item): BOOLEAN is -- Look for `x' using `equal' for comparison. do Result := storage.index_of(x,count-1) <= (count-1) end; -- has fast_has(x: like item): BOOLEAN is -- Same as `has' but use `=' for comparison do Result := storage.fast_index_of(x,count - 1) <= (count - 1) end; -- fast_has feature -- Other features: replace_all(old_value, new_value: like item) is do storage.replace_all(old_value,new_value,count - 1) end fast_replace_all(old_value, new_value: like item) is do storage.fast_replace_all(old_value,new_value,count - 1) end transpose is -- Transpose the Current array local i,j : INTEGER oldu1 , oldu2 : INTEGER do oldu1 := upper1 oldu2 := upper2 resize(upper2.max(upper1),upper2.max(upper1)) from i := 0 until i > upper1 - 1 loop from j := i + 1 until j > upper2 loop swap(i,j,j,i) j := j + 1 end i := i + 1 end resize(oldu2,oldu1) end to_external: POINTER is -- Gives C access to the internal `storage' (may be dangerous). do Result := storage.to_external end feature {COLLECTION2} same_as(other: COLLECTION2[E]): BOOLEAN is do Result := other.same_as_fixed_array2(Current) end same_as_array2(other: ARRAY2[E]): BOOLEAN is do Result := standard_same_as(other) end same_as_fixed_array2(other: FIXED_ARRAY2[E]): BOOLEAN is do Result := standard_same_as(other) end invariant count1 = upper1 + 1 count2 = upper2 + 1 count = count1 * count2 capacity >= count end -- FIXED_ARRAY2[E]