-- 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 -- deferred class COLLECTION3[E] -- -- Abstract definition of a 3 dimensional collection of elements -- of type E. -- -- The SmartEiffel standard library (SmartEiffel/lib/base) provides two -- implementations of COLLECTION3[E]: ARRAY3[E] and FIXED_ARRAY3[E]. -- All implementations have exactly the same behavior. Switching -- from one implementation to another only change the memory used -- and the execution time. -- inherit SAFE_EQUAL[E] undefine copy, is_equal redefine fill_tagged_out_memory end feature -- Indexing: lower1: INTEGER is -- Lower index bound for dimension 1. deferred end lower2: INTEGER is -- Lower index bound for dimension 2. deferred end lower3: INTEGER is -- Lower index bound for dimension 3. deferred end frozen line_minimum: INTEGER is -- Equivalent of `lower1'. do Result := lower1 end frozen column_minimum: INTEGER is -- Equivalent of `lower2'. do Result := lower2 end frozen depth_minimum: INTEGER is -- Equivalent of `lower3'. do Result := lower3 end upper1: INTEGER is -- Upper index bound for dimension 1. deferred end upper2: INTEGER is -- Upper index bound for dimension 2. deferred end upper3: INTEGER is -- Upper index bound for dimension 3. deferred end frozen line_maximum: INTEGER is -- Equivalent of `upper1'. do Result := upper1 end frozen column_maximum: INTEGER is -- Equivalent of `upper2'. do Result := upper2 end frozen depth_maximum: INTEGER is -- Equivalent of `upper3'. do Result := upper3 end feature -- Reading: item(line, column, depth: INTEGER): E is require valid_index(line,column,depth) deferred end feature -- Writing: put(element: like item; line, column, depth: INTEGER) is require valid_index(line,column,depth) deferred ensure item(line,column,depth) = element end force(element: like item; line, column, depth: INTEGER) is -- Put `element' at position (`line',`column',`depth'). -- Collection is resized first when (`line',`column',`depth') -- is not inside current bounds. -- New bounds are initialized with default values. require line >= 0 column >= 0 depth >= 0 deferred ensure item(line,column,depth) = element count >= old count end feature -- Index validity: frozen valid_line, valid_index1(line: INTEGER): BOOLEAN is do Result := lower1 <= line and then line <= upper1 ensure Result = (lower1 <= line and line <= upper1) end frozen valid_column, valid_index2(column: INTEGER): BOOLEAN is do Result := lower2 <= column and then column <= upper2 ensure Result = (lower2 <= column and column <= upper2) end frozen valid_depth, valid_index3(depth: INTEGER): BOOLEAN is do Result := lower3 <= depth and then depth <= upper3 ensure Result = (lower3 <= depth and depth <= upper3) end frozen valid_index(line, column, depth: INTEGER): BOOLEAN is do Result := ((lower1 <= line) and then (line <= upper1) and then (lower2 <= column) and then (column <= upper2) and then (lower3 <= depth) and then (depth <= upper3)) ensure Result = (valid_line(line) and valid_column(column) and valid_depth(depth)) end feature -- Counting: count1: INTEGER is -- Size of the first dimension. deferred ensure Result = upper1 - lower1 + 1 end frozen line_count: INTEGER is -- Equivalent of `count1'. do Result := count1 end count2: INTEGER is -- Size of the second dimension. deferred ensure Result = upper2 - lower2 + 1 end frozen column_count: INTEGER is do Result := count2 end count3: INTEGER is -- Size of the third dimension. deferred ensure Result = upper3 - lower3 + 1 end frozen depth_count: INTEGER is do Result := count3 end count: INTEGER is -- Total number of elements. deferred ensure Result = line_count * column_count * depth_count end feature swap(line1, column1, depth1, line2, column2, depth2: INTEGER) is -- Swap the element at index (`line1',`column1',`depth1') -- with the element at index (`line2',`column2',`depth2'). require valid_index(line1,column1,depth1) valid_index(line2,column2,depth2) deferred ensure item(line1,column1,depth1) = old item(line2,column2,depth2) item(line2,column2,depth2) = old item(line1,column1,depth1) count = old count end set_all_with(v: like item) is -- Set all item with value `v'. deferred ensure count = old count end frozen clear_all is -- Set all items to default values. local value: like item do set_all_with(value) ensure count = old count end feature -- Creating or initializing: from_collection3(model: COLLECTION3[like item]) is -- Uses `model' to initialize Current. require model /= Void deferred ensure count1 = model.count1 count2 = model.count2 count3 = model.count3 end from_model(model: COLLECTION[COLLECTION[COLLECTION[E]]]) is -- The `model' is used to fill line by line Current. -- Assume all sub-collections have the same -- dimension. require model /= Void deferred ensure count1 = model.count count2 > 0 implies count2 = model.first.count count3 > 0 implies count3 = model.first.first.count end feature -- Looking and comparison: all_default: BOOLEAN is -- Do all items have their type's default value? deferred end same_as(other: COLLECTION3[E]): BOOLEAN is -- Unlike `is_equal', this feature can be used to compare -- distinct implementation of COLLECTION3. require other /= Void deferred ensure Result implies standard_same_as(other) end feature -- Printing: frozen fill_tagged_out_memory is local line, column, depth: INTEGER v: like item do tagged_out_memory.append(once "lower1: ") lower1.append_in(tagged_out_memory) tagged_out_memory.append(once " upper1: ") upper1.append_in(tagged_out_memory) tagged_out_memory.append(once " lower2: ") lower2.append_in(tagged_out_memory) tagged_out_memory.append(once " upper2: ") upper2.append_in(tagged_out_memory) tagged_out_memory.append(once " lower3: ") lower3.append_in(tagged_out_memory) tagged_out_memory.append(once " upper3: ") upper3.append_in(tagged_out_memory) tagged_out_memory.append(once " [%N") from line := lower1 until line > upper1 or else tagged_out_memory.count > 4096 loop tagged_out_memory.append(once "line ") line.append_in(tagged_out_memory) tagged_out_memory.append(once "%T: ") from column := lower2 until column > upper2 loop tagged_out_memory.append(once "column ") column.append_in(tagged_out_memory) tagged_out_memory.append(once "%T: ") from depth := lower3 until depth > upper3 loop tagged_out_memory.append(once "depth ") depth.append_in(tagged_out_memory) tagged_out_memory.append(once "%T: ") v := item(line,column,depth) if v = Void then tagged_out_memory.append(once "Void") else v.out_in_tagged_out_memory end tagged_out_memory.extend(' ') depth := depth + 1 end tagged_out_memory.extend('%N') column := column + 1 end tagged_out_memory.extend('%N') line := line + 1 end if valid_line(line) then tagged_out_memory.append(once "......%N") end end feature -- Miscellaneous features: occurrences(elt: E): INTEGER is -- Number of occurrences using `equal'. -- See also `fast_occurrences' to choose the apropriate one. deferred ensure Result >= 0 end fast_occurrences(elt: E): INTEGER is -- Number of occurrences using `='. -- See also `occurrences' to choose the apropriate one. deferred ensure Result >= 0 end has(x: like item): BOOLEAN is -- Search if a element x is in the array using `equal'. -- See also `fast_has' to choose the apropriate one. deferred end fast_has(x: like item): BOOLEAN is -- Search if a element x is in the array using `='. deferred end replace_all(old_value, new_value: like item) is -- Replace all occurences of the element `old_value' by `new_value' -- using `equal' for comparison. -- See also `fast_replace_all' to choose the apropriate one. deferred ensure count = old count occurrences(old_value) = 0 end fast_replace_all(old_value, new_value: like item) is -- Replace all occurences of the element `old_value' by `new_value' -- using operator `=' for comparison. -- See also `replace_all' to choose the apropriate one. deferred ensure count = old count fast_occurrences(old_value) = 0 end sub_collection3(line_min, line_max, column_min, column_max, depth_min, depth_max: INTEGER): like Current is -- Create a new object using selected area of `Current'. require valid_index(line_min,column_min,depth_min) valid_index(line_max,column_max,depth_max) deferred ensure Result /= Void end set_area(element: like item; line_min, line_max, column_min, column_max, depth_min, depth_max: INTEGER) is -- Set all the elements of the selected area rectangle with `element'. require valid_index(line_min,column_min,depth_min) valid_index(line_max,column_max,depth_max) local line, column, depth : INTEGER do from line := line_min until line > line_max loop from column := column_min until column > column_max loop from depth := depth_min until depth > depth_max loop put(element,line,column,depth) depth := depth + 1 end column := column + 1 end line := line + 1 end ensure count = old count end feature {COLLECTION3} -- For `same_as' implementation: frozen standard_same_as(other: COLLECTION3[E]): BOOLEAN is require generating_type /= other.generating_type local line, column, depth: INTEGER do if lower1 /= other.lower1 then elseif upper1 /= other.upper1 then elseif lower2 /= other.lower2 then elseif upper2 /= other.upper2 then elseif lower3 /= other.lower3 then elseif upper3 /= other.upper3 then else from Result := true line := upper1 until not Result or else line < lower1 loop from column := upper2 until not Result or else column < lower2 loop from depth := upper3 until not Result or else depth < lower3 loop Result := safe_equal(item(line,column,depth), other.item(line,column,depth)) depth := depth - 1 end column := column - 1 end line := line - 1 end end end same_as_array3(other: ARRAY3[E]): BOOLEAN is require other /= Void deferred end same_as_fixed_array3(other: FIXED_ARRAY3[E]): BOOLEAN is require other /= Void deferred end end -- COLLECTION3[E]