note description: "Two-dimensional arrays" library: "Free implementation of ELKS library" legal: "See notice at end of class." status: "See notice at end of class." names: array2, matrix, table representation: array access: index, row_and_column, membership size: resizable contents: generic date: "$Date: 2017-03-23 19:18:26 +0000 (Thu, 23 Mar 2017) $" revision: "$Revision: 100033 $" class ARRAY2 [G] create make, make_filled feature -- Initialization initialize (v: G) -- Make each entry have value v. do fill_with (v) end array_make (min_index, max_index: INTEGER_32) obsolete " `make' is not void-safe statically. Use `make_empty' or `make_filled' instead. [2017-05-31]" -- Allocate array; set index interval to -- min_index .. max_index; set all values to default. -- (Make array empty if min_index = max_index + 1). -- (from ARRAY) require -- from ARRAY valid_bounds: min_index <= max_index + 1 has_default: min_index <= max_index implies ({G}).has_default do lower := min_index upper := max_index if min_index <= max_index then make_filled_area (({G}).default, max_index - min_index + 1) else make_empty_area (0) end ensure -- from ARRAY lower_set: lower = min_index upper_set: upper = max_index items_set: all_default end make (nb_rows, nb_columns: INTEGER_32) obsolete "`make' is not void-safe statically. Use `make_filled' instead. [2017-05-31]" -- Create a two dimensional array which has nb_rows -- rows and nb_columns columns, -- with lower bounds starting at 1. require nb_rows_non_negative: nb_rows >= 0 nb_columns_non_negative: nb_columns >= 0 both_zero_or_both_non_zero: not (nb_rows = 0 xor nb_columns = 0) has_default: (nb_rows * nb_columns) /= 0 implies ({G}).has_default do height := nb_rows width := nb_columns array_make (1, nb_rows * nb_columns) ensure new_count: count = height * width end make_empty -- Allocate empty array starting at 1. -- (from ARRAY) do lower := 1 upper := 0 make_empty_area (0) ensure -- from ARRAY lower_set: lower = 1 upper_set: upper = 0 items_set: all_default end make_filled (a_default_value: G; nb_rows, nb_columns: INTEGER_32) -- Create a two dimensional array which has nb_rows -- rows and nb_columns columns, -- with lower bounds starting at 1 filled with value a_default_value. require nb_rows_non_negative: nb_rows >= 0 nb_columns_non_negative: nb_columns >= 0 both_zero_or_both_non_zero: not (nb_rows = 0 xor nb_columns = 0) do height := nb_rows width := nb_columns array_make_filled (a_default_value, 1, nb_rows * nb_columns) ensure new_count: count = height * width filled: filled_with (a_default_value) end array_make_filled (a_default_value: G; min_index, max_index: INTEGER_32) -- Allocate array; set index interval to -- min_index .. max_index; set all values to default. -- (Make array empty if min_index = max_index + 1). -- (from ARRAY) require -- from ARRAY valid_bounds: min_index <= max_index + 1 local n: INTEGER_32 do lower := min_index upper := max_index if min_index <= max_index then n := max_index - min_index + 1 end make_filled_area (a_default_value, n) ensure -- from ARRAY lower_set: lower = min_index upper_set: upper = max_index items_set: filled_with (a_default_value) end make_from_array (a: ARRAY [G]) -- Initialize from the items of a. -- (Useful in proper descendants of class ARRAY, -- to initialize an array-like object from a manifest array.) -- (from ARRAY) require -- from ARRAY array_exists: a /= Void do set_area (a.area) lower := a.lower upper := a.upper ensure -- from ARRAY shared: area = a.area lower_set: lower = a.lower upper_set: upper = a.upper end make_from_cil (na: NATIVE_ARRAY [like array_item]) -- Initialize array from na. -- (from ARRAY) require -- from ARRAY is_dotnet: {PLATFORM}.is_dotnet na_not_void: na /= Void do create area.make_from_native_array (na) lower := 1 upper := area.count end make_from_special (a: SPECIAL [G]) -- Initialize Current from items of a. -- (from ARRAY) require -- from ARRAY special_attached: a /= Void do set_area (a) lower := 1 upper := a.count ensure -- from ARRAY shared: area = a lower_set: lower = 1 upper_set: upper = a.count end feature {NONE} -- Initialization default_create -- Process instances of classes with no creation clause. -- (Default: do nothing.) -- (from ANY) do end make_empty_area (n: INTEGER_32) -- Creates a special object for n entries. -- (from TO_SPECIAL) require -- from TO_SPECIAL non_negative_argument: n >= 0 do create area.make_empty (n) ensure -- from TO_SPECIAL area_allocated: area /= Void capacity_set: area.capacity = n count_set: area.count = 0 end make_filled_area (a_default_value: G; n: INTEGER_32) -- Creates a special object for n entries. -- (from TO_SPECIAL) require -- from TO_SPECIAL non_negative_argument: n >= 0 do create area.make_filled (a_default_value, n) ensure -- from TO_SPECIAL area_allocated: area /= Void capacity_set: area.capacity = n count_set: area.count = n area_filled: area.filled_with (a_default_value, 0, n - 1) end feature -- Access area: SPECIAL [G] -- Special data zone. -- (from TO_SPECIAL) at alias "@" (i: INTEGER_32): G assign array_put -- Entry at index i, if in index interval. -- Was declared in ARRAY as synonym of item. -- (from ARRAY) require -- from TABLE valid_key: valid_index (i) require -- from TO_SPECIAL valid_index: valid_index (i) do Result := area.item (i - lower) end entry (i: INTEGER_32): G -- Entry at index i, if in index interval. -- (from ARRAY) require -- from ARRAY valid_key: valid_index (i) do Result := array_item (i) end generating_type: TYPE [detachable ARRAY2 [G]] -- Type of current object -- (type of which it is a direct instance) -- (from ANY) external "built_in" ensure -- from ANY generating_type_not_void: Result /= Void end generator: STRING_8 -- Name of current object's generating class -- (base class of the type of which it is a direct instance) -- (from ANY) external "built_in" ensure -- from ANY generator_not_void: Result /= Void generator_not_empty: not Result.is_empty end has (v: G): BOOLEAN -- Does v appear in array? -- (Reference or object equality, -- based on object_comparison.) -- (from ARRAY) local i, nb: INTEGER_32 l_area: like area do l_area := area nb := upper - lower if object_comparison and v /= Void then from until i > nb or Result loop Result := l_area.item (i) ~ v i := i + 1 end else from until i > nb or Result loop Result := l_area.item (i) = v i := i + 1 end end ensure -- from CONTAINER not_found_in_empty: Result implies not is_empty end item alias "[]" (row, column: INTEGER_32): G assign put -- Entry at coordinates (row, column) require valid_row: (1 <= row) and (row <= height) valid_column: (1 <= column) and (column <= width) do Result := array_item ((row - 1) * width + column) end array_item (i: INTEGER_32): G assign array_put -- Entry at index i, if in index interval. -- Was declared in ARRAY as synonym of at. -- (from ARRAY) require -- from TABLE valid_key: valid_index (i) require -- from READABLE_INDEXABLE valid_index: valid_index (i) require -- from TO_SPECIAL valid_index: valid_index (i) do Result := area.item (i - lower) end new_cursor: ARRAY_ITERATION_CURSOR [G] -- Fresh cursor associated with current structure -- (from ARRAY) require -- from ITERABLE True do create Result.make (Current) ensure -- from ITERABLE result_attached: Result /= Void end feature -- Measurement additional_space: INTEGER_32 -- Proposed number of additional items -- (from RESIZABLE) do Result := (capacity // 2).max (Minimal_increase) ensure -- from RESIZABLE at_least_one: Result >= 1 end capacity: INTEGER_32 -- Number of available indices. -- Was declared in ARRAY as synonym of count. -- (from ARRAY) require -- from BOUNDED True do Result := upper - lower + 1 ensure -- from BOUNDED capacity_non_negative: Result >= 0 ensure then -- from ARRAY consistent_with_bounds: Result = upper - lower + 1 end count: INTEGER_32 -- Number of available indices. -- Was declared in ARRAY as synonym of capacity. -- (from ARRAY) require -- from FINITE True do Result := upper - lower + 1 ensure -- from FINITE count_non_negative: Result >= 0 ensure then -- from ARRAY consistent_with_bounds: Result = upper - lower + 1 end Growth_percentage: INTEGER_32 = 50 -- Percentage by which structure will grow automatically -- (from RESIZABLE) height: INTEGER_32 -- Number of rows index_set: INTEGER_INTERVAL obsolete "Use `lower' and `upper' instead. [2017-05-31]" -- Range of acceptable indexes. -- (from READABLE_INDEXABLE) do create Result.make (lower, upper) ensure -- from READABLE_INDEXABLE not_void: Result /= Void empty_if_not_in_order: (lower > upper) implies Result.is_empty same_lower_if_not_empty: (lower <= upper) implies Result.lower = lower same_upper_if_not_empty: (lower <= upper) implies Result.upper = upper end lower: INTEGER_32 -- Minimum index. -- (from ARRAY) Minimal_increase: INTEGER_32 = 5 -- Minimal number of additional items -- (from RESIZABLE) occurrences (v: G): INTEGER_32 -- Number of times v appears in structure. -- (from ARRAY) local i: INTEGER_32 do if object_comparison then from i := lower until i > upper loop if array_item (i) ~ v then Result := Result + 1 end i := i + 1 end else from i := lower until i > upper loop if array_item (i) = v then Result := Result + 1 end i := i + 1 end end ensure -- from BAG non_negative_occurrences: Result >= 0 end upper: INTEGER_32 -- Maximum index. -- (from ARRAY) width: INTEGER_32 -- Number of columns feature {NONE} -- Measurement estimated_count_of (other: ITERABLE [G]): INTEGER_32 -- Estimated number of elements in other. -- (from CONTAINER) do if attached {FINITE [G]} other as f then Result := f.count elseif attached {READABLE_INDEXABLE [G]} other as r then Result := r.upper - r.lower + 1 end ensure -- from CONTAINER instance_free: class non_negative_result: Result >= 0 end feature -- Comparison frozen deep_equal (a: detachable ANY; b: like arg #1): BOOLEAN -- Are a and b either both void -- or attached to isomorphic object structures? -- (from ANY) do if a = Void then Result := b = Void else Result := b /= Void and then a.is_deep_equal (b) end ensure -- from ANY instance_free: class shallow_implies_deep: standard_equal (a, b) implies Result both_or_none_void: (a = Void) implies (Result = (b = Void)) same_type: (Result and (a /= Void)) implies (b /= Void and then a.same_type (b)) symmetric: Result implies deep_equal (b, a) end frozen equal (a: detachable ANY; b: like arg #1): BOOLEAN -- Are a and b either both void or attached -- to objects considered equal? -- (from ANY) do if a = Void then Result := b = Void else Result := b /= Void and then a.is_equal (b) end ensure -- from ANY instance_free: class definition: Result = (a = Void and b = Void) or else ((a /= Void and b /= Void) and then a.is_equal (b)) end frozen is_deep_equal alias "≡≡≡" (other: ARRAY2 [G]): BOOLEAN -- Are Current and other attached to isomorphic object structures? -- (from ANY) require -- from ANY other_not_void: other /= Void external "built_in" ensure -- from ANY shallow_implies_deep: standard_is_equal (other) implies Result same_type: Result implies same_type (other) symmetric: Result implies other.is_deep_equal (Current) end is_equal (other: ARRAY2 [G]): BOOLEAN -- Is array made of the same items as other? -- (from ARRAY) require -- from ANY other_not_void: other /= Void local i: INTEGER_32 do if other = Current then Result := True elseif lower = other.lower and then upper = other.upper and then object_comparison = other.object_comparison then if object_comparison then from Result := True i := lower until not Result or i > upper loop Result := array_item (i) ~ other.array_item (i) i := i + 1 end else Result := area.same_items (other.area, 0, 0, count) end end ensure -- from ANY symmetric: Result implies other ~ Current consistent: standard_is_equal (other) implies Result end frozen standard_equal (a: detachable ANY; b: like arg #1): BOOLEAN -- Are a and b either both void or attached to -- field-by-field identical objects of the same type? -- Always uses default object comparison criterion. -- (from ANY) do if a = Void then Result := b = Void else Result := b /= Void and then a.standard_is_equal (b) end ensure -- from ANY instance_free: class definition: Result = (a = Void and b = Void) or else ((a /= Void and b /= Void) and then a.standard_is_equal (b)) end frozen standard_is_equal alias "≜" (other: ARRAY2 [G]): BOOLEAN -- Is other attached to an object of the same type -- as current object, and field-by-field identical to it? -- (from ANY) require -- from ANY other_not_void: other /= Void external "built_in" ensure -- from ANY same_type: Result implies same_type (other) symmetric: Result implies other.standard_is_equal (Current) end feature -- Status report all_default: BOOLEAN -- Are all items set to default values? -- (from ARRAY) do if count > 0 then Result := ({G}).has_default and then area.filled_with (({G}).default, 0, upper - lower) else Result := True end ensure -- from ARRAY definition: Result = (count = 0 or else ((not attached array_item (upper) as i or else i = ({G}).default) and subarray (lower, upper - 1).all_default)) end changeable_comparison_criterion: BOOLEAN -- May object_comparison be changed? -- (Answer: yes by default.) -- (from CONTAINER) do Result := True end conforms_to (other: ANY): BOOLEAN -- Does type of current object conform to type -- of other (as per Eiffel: The Language, chapter 13)? -- (from ANY) require -- from ANY other_not_void: other /= Void external "built_in" end empty: BOOLEAN obsolete "ELKS 2000: Use `is_empty' instead. [2017-05-31]" -- Is there no element? -- (from CONTAINER) do Result := is_empty end extendible: BOOLEAN -- May items be added? -- (Answer: no, although array may be resized.) -- (from ARRAY) do Result := False end filled_with (v: G): BOOLEAN -- Are all items set to v? -- (from ARRAY) do Result := area.filled_with (v, 0, upper - lower) ensure -- from ARRAY definition: Result = (count = 0 or else (array_item (upper) = v and subarray (lower, upper - 1).filled_with (v))) end full: BOOLEAN -- Is structure filled to capacity? -- (Answer: yes) -- (from ARRAY) require -- from BOX True do Result := True end is_empty: BOOLEAN -- Is structure empty? -- (from FINITE) require -- from CONTAINER True do Result := count = 0 end is_inserted (v: G): BOOLEAN -- Has v been inserted by the most recent insertion? -- (By default, the value returned is equivalent to calling -- has (v). However, descendants might be able to provide more -- efficient implementations.) -- (from COLLECTION) do Result := has (v) end object_comparison: BOOLEAN -- Must search operations use equal rather than = -- for comparing references? (Default: no, use =.) -- (from CONTAINER) prunable: BOOLEAN -- May items be removed? -- (Answer: no.) -- (from ARRAY) do Result := False end resizable: BOOLEAN -- Can array be resized automatically? -- (from ARRAY) require -- from BOUNDED True do Result := ({G}).has_default end same_items (other: ARRAY2 [G]): BOOLEAN -- Do other and Current have same items? -- (from ARRAY) require -- from ARRAY other_not_void: other /= Void do if count = other.count then Result := area.same_items (other.area, 0, 0, count) end ensure -- from ARRAY definition: Result = (count = other.count and then (count = 0 or else (array_item (upper) = other.array_item (other.upper) and subarray (lower, upper - 1).same_items (other.subarray (other.lower, other.upper - 1))))) end same_type (other: ANY): BOOLEAN -- Is type of current object identical to type of other? -- (from ANY) require -- from ANY other_not_void: other /= Void external "built_in" ensure -- from ANY definition: Result = (conforms_to (other) and other.conforms_to (Current)) end valid_index (i: INTEGER_32): BOOLEAN -- Is i within the bounds of the array? -- (from ARRAY) require -- from READABLE_INDEXABLE True require -- from TABLE True require -- from TO_SPECIAL True do Result := (lower <= i) and then (i <= upper) ensure -- from READABLE_INDEXABLE only_if_in_index_set: Result implies (lower <= i and i <= upper) end feature -- Status setting compare_objects -- Ensure that future search operations will use equal -- rather than = for comparing references. -- (from CONTAINER) require -- from CONTAINER changeable_comparison_criterion: changeable_comparison_criterion do object_comparison := True ensure -- from CONTAINER object_comparison end compare_references -- Ensure that future search operations will use = -- rather than equal for comparing references. -- (from CONTAINER) require -- from CONTAINER changeable_comparison_criterion: changeable_comparison_criterion do object_comparison := False ensure -- from CONTAINER reference_comparison: not object_comparison end feature -- Element change enter (v: like array_item; i: INTEGER_32) -- Replace i-th entry, if in index interval, by v. -- (from ARRAY) require -- from ARRAY valid_key: valid_index (i) do area.put (v, i - lower) end fill (other: CONTAINER [G]) -- Fill with as many items of other as possible. -- The representations of other and current structure -- need not be the same. -- (from COLLECTION) require -- from COLLECTION other_not_void: other /= Void extendible: extendible local lin_rep: LINEAR [G] do lin_rep := other.linear_representation from lin_rep.start until not extendible or else lin_rep.off loop extend (lin_rep.item); lin_rep.forth end end fill_with (v: G) -- Set items between lower and upper with v. -- (from ARRAY) do area.fill_with (v, 0, upper - lower) ensure -- from ARRAY same_capacity: capacity = old capacity count_definition: count = old count filled: filled_with (v) end array_force (v: like array_item; i: INTEGER_32) -- Assign item v to i-th entry. -- Resize the array if i falls out of currently defined bounds; preserve existing items. -- In void-safe mode, if ({G}).has_default does not hold, then you can only insert between -- lower - 1 and upper + 1 positions in the ARRAY. -- (from ARRAY) require -- from ARRAY has_default_if_too_low: (i < lower - 1 and lower /= {like lower}.min_value) implies ({G}).has_default has_default_if_too_high: (i > upper + 1 and upper /= {like upper}.max_value) implies ({G}).has_default local old_size, new_size: INTEGER_32 new_lower, new_upper: INTEGER_32 l_count, l_offset: INTEGER_32 l_increased_by_one: BOOLEAN do new_lower := lower.min (i) new_upper := upper.max (i) new_size := new_upper - new_lower + 1 l_increased_by_one := (i = upper + 1) or (i = lower - 1) if empty_area then make_empty_area (new_size.max (additional_space)) if new_lower < lower then area.extend (v) if not l_increased_by_one then area.fill_with (({G}).default, 1, new_size - 1) end else if not l_increased_by_one then area.fill_with (({G}).default, 0, new_size - 2) end; area.extend (v) end else old_size := area.capacity if new_size > old_size then set_area (area.aliased_resized_area (new_size.max (old_size + additional_space))) end if new_lower < lower then l_offset := lower - new_lower l_count := capacity if not l_increased_by_one and l_offset > l_count then area.fill_with (({G}).default, l_count, l_offset - 1) end; area.move_data (0, l_offset, l_count) if not l_increased_by_one then area.fill_with (({G}).default, 1, l_offset - 1) end; area.put (v, 0) else if new_size > area.count then if not l_increased_by_one then area.fill_with (({G}).default, area.count, new_size - 2) end; area.extend (v) else area.put (v, i - lower) end end end lower := new_lower upper := new_upper ensure -- from ARRAY inserted: array_item (i) = v higher_count: count >= old count lower_set: lower = (old lower).min (i) upper_set: upper = (old upper).max (i) end force (v: like item; row, column: INTEGER_32) -- Assign item v at coordinates (row, column). -- Resize if necessary. require row_large_enough: 1 <= row column_large_enough: 1 <= column has_default: ({G}).has_default do resize_with_default (({G}).default, row, column) put (v, row, column) end force_and_fill (v: like array_item; i: INTEGER_32) -- Assign item v to i-th entry. -- If i falls out of currently defined bounds: -- - Resize array as needed. -- - Fill in any new entry (in addition to the one at position i with value v). -- - Preserve existing items. -- (from ARRAY) local old_size, new_size: INTEGER_32 new_lower, new_upper: INTEGER_32 l_offset: INTEGER_32 do new_lower := lower.min (i) new_upper := upper.max (i) new_size := new_upper - new_lower + 1 old_size := area.capacity if old_size = 0 then make_empty_area (new_size.max (additional_space)); area.fill_with (v, 0, new_size - 1) else if new_size > old_size then set_area (area.aliased_resized_area (new_size.max (old_size + additional_space))) end if new_lower < lower then l_offset := lower - new_lower; area.move_data (0, l_offset, capacity); area.fill_with (v, 0, l_offset - 1) elseif new_size > area.count then area.fill_with (v, area.count, new_size - 1) else area.put (v, i - lower) end end lower := new_lower upper := new_upper ensure -- from ARRAY inserted: array_item (i) = v filled_below_lower: ∀ c: i |..| old lower ¦ c < old lower implies array_item (c) = v filled_above_upper: ∀ c: old upper |..| i ¦ c > old upper implies array_item (c) = v higher_count: count >= old count lower_set: lower = (old lower).min (i) upper_set: upper = (old upper).max (i) end put (v: like item; row, column: INTEGER_32) -- Assign item v at coordinates (row, column). require valid_row: 1 <= row and row <= height valid_column: 1 <= column and column <= width do array_put (v, (row - 1) * width + column) end array_put (v: like array_item; i: INTEGER_32) -- Replace i-th entry, if in index interval, by v. -- (from ARRAY) require -- from TABLE valid_key: valid_index (i) require -- from TABLE valid_key: valid_index (i) require -- from TO_SPECIAL valid_index: valid_index (i) do area.put (v, i - lower) ensure -- from TABLE inserted: array_item (i) = v ensure -- from TO_SPECIAL inserted: array_item (i) = v end subcopy (other: ARRAY [like array_item]; start_pos, end_pos, index_pos: INTEGER_32) -- Copy items of other within bounds start_pos and end_pos -- to current array starting at index index_pos. -- (from ARRAY) require -- from ARRAY other_not_void: other /= Void valid_start_pos: start_pos >= other.lower valid_end_pos: end_pos <= other.upper valid_bounds: start_pos <= end_pos + 1 valid_index_pos: index_pos >= lower enough_space: (upper - index_pos) >= (end_pos - start_pos) do area.copy_data (other.area, start_pos - other.lower, index_pos - lower, end_pos - start_pos + 1) end feature {ARRAY} -- Element change set_area (other: like area) -- Make other the new area. -- (from TO_SPECIAL) do area := other ensure -- from TO_SPECIAL area_set: area = other end feature -- Removal clear_all -- Reset all items to default values. -- (from ARRAY) require -- from ARRAY has_default: ({G}).has_default do area.fill_with (({G}).default, 0, area.count - 1) ensure -- from ARRAY stable_lower: lower = old lower stable_upper: upper = old upper default_items: all_default end discard_items -- Reset all items to default values with reallocation. -- (from ARRAY) require -- from ARRAY has_default: ({G}).has_default do create area.make_filled (({G}).default, capacity) ensure -- from ARRAY default_items: all_default end keep_head (n: INTEGER_32) -- Remove all items except for the first n; -- do nothing if n >= count. -- (from ARRAY) require -- from ARRAY non_negative_argument: n >= 0 do if n < count then upper := lower + n - 1 area := area.aliased_resized_area (n) end ensure -- from ARRAY new_count: count = n.min (old count) same_lower: lower = old lower end keep_tail (n: INTEGER_32) -- Remove all items except for the last n; -- do nothing if n >= count. -- (from ARRAY) require -- from ARRAY non_negative_argument: n >= 0 local nb: INTEGER_32 do nb := count if n < nb then area.overlapping_move (nb - n, 0, n) lower := upper - n + 1 area := area.aliased_resized_area (n) end ensure -- from ARRAY new_count: count = n.min (old count) same_upper: upper = old upper end prune_all (v: G) -- Remove all occurrences of v. -- (Reference or object equality, -- based on object_comparison.) -- (from COLLECTION) require -- from COLLECTION prunable: prunable do from until not has (v) loop prune (v) end ensure -- from COLLECTION no_more_occurrences: not has (v) end remove_head (n: INTEGER_32) -- Remove first n items; -- if n > count, remove all. -- (from ARRAY) require -- from ARRAY n_non_negative: n >= 0 do if n > count then lower := upper + 1 area := area.aliased_resized_area (0) else keep_tail (count - n) end ensure -- from ARRAY new_count: count = (old count - n).max (0) same_upper: upper = old upper end remove_tail (n: INTEGER_32) -- Remove last n items; -- if n > count, remove all. -- (from ARRAY) require -- from ARRAY n_non_negative: n >= 0 do if n > count then upper := lower - 1 area := area.aliased_resized_area (0) else keep_head (count - n) end ensure -- from ARRAY new_count: count = (old count - n).max (0) same_lower: lower = old lower end wipe_out -- Remove all items. do height := 0 width := 0 make_empty end array_wipe_out obsolete "Not applicable since not `prunable'. Use `discard_items' instead. [2017-05-31]" -- Make array empty. -- (from ARRAY) require -- from COLLECTION prunable: prunable do discard_items ensure -- from COLLECTION wiped_out: is_empty end feature -- Resizing automatic_grow -- Change the capacity to accommodate at least -- Growth_percentage more items. -- (from RESIZABLE) require -- from RESIZABLE resizable: resizable do grow (capacity + additional_space) ensure -- from RESIZABLE increased_capacity: capacity >= old capacity + old additional_space end conservative_resize (min_index, max_index: INTEGER_32) obsolete " `conservative_resize' is not void-safe statically. Use `conservative_resize_with_default' instead. [2017-05-31]" -- Rearrange array so that it can accommodate -- indices down to min_index and up to max_index. -- Do not lose any previously entered item. -- (from ARRAY) require -- from ARRAY good_indices: min_index <= max_index has_default: ({G}).has_default do conservative_resize_with_default (({G}).default, min_index, max_index) ensure -- from ARRAY no_low_lost: lower = min_index or else lower = old lower no_high_lost: upper = max_index or else upper = old upper end conservative_resize_with_default (a_default_value: G; min_index, max_index: INTEGER_32) -- Rearrange array so that it can accommodate -- indices down to min_index and up to max_index. -- Do not lose any previously entered item. -- (from ARRAY) require -- from ARRAY good_indices: min_index <= max_index local new_size: INTEGER_32 new_lower, new_upper: INTEGER_32 offset: INTEGER_32 do if empty_area then set_area (area.aliased_resized_area_with_default (a_default_value, max_index - min_index + 1)) lower := min_index upper := max_index else new_lower := min_index.min (lower) new_upper := max_index.max (upper) new_size := new_upper - new_lower + 1 if new_size > area.count then set_area (area.aliased_resized_area_with_default (a_default_value, new_size)) end if new_lower < lower then offset := lower - new_lower; area.move_data (0, offset, upper - lower + 1); area.fill_with (a_default_value, 0, offset - 1) end lower := new_lower upper := new_upper end ensure -- from ARRAY no_low_lost: lower = min_index or else lower = old lower no_high_lost: upper = max_index or else upper = old upper end grow (i: INTEGER_32) -- Change the capacity to at least i. -- (from ARRAY) require -- from RESIZABLE resizable: resizable do if i > capacity then conservative_resize_with_default (({G}).default, lower, upper + i - capacity) end ensure -- from RESIZABLE new_capacity: capacity >= i end rebase (a_lower: like lower) -- Without changing the actual content of Current we set lower to a_lower -- and upper accordingly to a_lower + count - 1. -- (from ARRAY) local l_old_lower: like lower do l_old_lower := lower lower := a_lower upper := a_lower + (upper - l_old_lower) ensure -- from ARRAY lower_set: lower = a_lower upper_set: upper = a_lower + old count - 1 end resize (nb_rows, nb_columns: INTEGER_32) obsolete "`resize' is not void-safe statically. Use `resize_with_default' instead. [2017-05-31]" -- Rearrange array so that it can accommodate -- nb_rows rows and nb_columns columns, -- without losing any previously -- entered items, nor changing their coordinates; -- do nothing if new values are smaller. require valid_row: nb_rows >= 1 valid_column: nb_columns >= 1 has_default: ({G}).has_default do if (nb_columns > width) or (nb_rows > height) then resize_with_default (({G}).default, nb_rows, nb_columns) end ensure no_smaller_height: height >= old height no_smaller_width: width >= old width end array_resize (min_index, max_index: INTEGER_32) obsolete "Use `conservative_resize_with_default' instead as future versions will implement `resize' as specified in ELKS. [2017-05-31]" -- Rearrange array so that it can accommodate -- indices down to min_index and up to max_index. -- Do not lose any previously entered item. -- (from ARRAY) require -- from ARRAY good_indices: min_index <= max_index has_default: ({G}).has_default do conservative_resize_with_default (({G}).default, min_index, max_index) ensure -- from ARRAY no_low_lost: lower = min_index or else lower = old lower no_high_lost: upper = max_index or else upper = old upper end resize_with_default (a_default: G; nb_rows, nb_columns: INTEGER_32) -- Rearrange array so that it can accommodate -- nb_rows rows and nb_columns columns, -- without losing any previously -- entered items, nor changing their coordinates; -- do nothing if new values are smaller. require valid_row: nb_rows >= 1 valid_column: nb_columns >= 1 local i: INTEGER_32 new_height: like height previous_width: like width do if nb_columns > width then new_height := nb_rows.max (height) previous_width := width conservative_resize_with_default (a_default, 1, new_height * nb_columns) from i := height until i = 0 loop area.move_data ((i - 1) * previous_width, (i - 1) * nb_columns, previous_width); area.fill_with (a_default, (i - 1) * nb_columns + previous_width, i * nb_columns - 1) i := i - 1 end width := nb_columns height := new_height elseif nb_rows > height then conservative_resize_with_default (a_default, 1, nb_rows * width) height := nb_rows end ensure no_smaller_height: height >= old height no_smaller_width: width >= old width end trim -- Decrease capacity to the minimum value. -- Apply to reduce allocated storage. -- (from ARRAY) require -- from RESIZABLE True local n: like count do n := count if n < area.capacity then area := area.aliased_resized_area (n) end ensure -- from RESIZABLE same_count: count = old count minimal_capacity: capacity = count ensure then -- from ARRAY same_items: same_items (old twin) end feature -- Conversion linear_representation: LINEAR [G] -- Representation as a linear structure. -- (from ARRAY) local temp: ARRAYED_LIST [G] i: INTEGER_32 do create temp.make (capacity) from i := lower until i > upper loop temp.extend (array_item (i)) i := i + 1 end Result := temp end to_c: ANY -- Address of actual sequence of values, -- for passing to external (non-Eiffel) routines. -- (from ARRAY) require -- from ARRAY not_is_dotnet: not {PLATFORM}.is_dotnet do Result := area end to_cil: NATIVE_ARRAY [G] -- Address of actual sequence of values, -- for passing to external (non-Eiffel) routines. -- (from ARRAY) require -- from ARRAY is_dotnet: {PLATFORM}.is_dotnet do Result := area.native_array ensure -- from ARRAY to_cil_not_void: Result /= Void end to_special: SPECIAL [G] -- 'area'. -- (from ARRAY) do Result := area ensure -- from ARRAY to_special_not_void: Result /= Void end feature -- Duplication frozen clone (other: detachable ANY): like other obsolete "Use `twin' instead. [2017-05-31]" -- Void if other is void; otherwise new object -- equal to other -- -- For non-void other, clone calls copy; -- to change copying/cloning semantics, redefine copy. -- (from ANY) do if other /= Void then Result := other.twin end ensure -- from ANY instance_free: class equal: Result ~ other end copy (other: ARRAY2 [G]) -- Reinitialize by copying all the items of other. -- (This is also used by clone.) -- (from ARRAY) require -- from ANY other_not_void: other /= Void type_identity: same_type (other) do if other /= Current then standard_copy (other) set_area (other.area.twin) end ensure -- from ANY is_equal: Current ~ other ensure then -- from ARRAY equal_areas: area ~ other.area end frozen deep_clone (other: detachable ANY): like other obsolete "Use `deep_twin' instead. [2017-05-31]" -- Void if other is void: otherwise, new object structure -- recursively duplicated from the one attached to other -- (from ANY) do if other /= Void then Result := other.deep_twin end ensure -- from ANY instance_free: class deep_equal: deep_equal (other, Result) end frozen deep_copy (other: ARRAY2 [G]) -- Effect equivalent to that of: -- copy (other . deep_twin) -- (from ANY) require -- from ANY other_not_void: other /= Void do copy (other.deep_twin) ensure -- from ANY deep_equal: deep_equal (Current, other) end frozen deep_twin: ARRAY2 [G] -- New object structure recursively duplicated from Current. -- (from ANY) external "built_in" ensure -- from ANY deep_twin_not_void: Result /= Void deep_equal: deep_equal (Current, Result) end frozen standard_clone (other: detachable ANY): like other obsolete "Use `standard_twin' instead. [2017-05-31]" -- Void if other is void; otherwise new object -- field-by-field identical to other. -- Always uses default copying semantics. -- (from ANY) do if other /= Void then Result := other.standard_twin end ensure -- from ANY instance_free: class equal: standard_equal (Result, other) end frozen standard_copy (other: ARRAY2 [G]) -- Copy every field of other onto corresponding field -- of current object. -- (from ANY) require -- from ANY other_not_void: other /= Void type_identity: same_type (other) external "built_in" ensure -- from ANY is_standard_equal: standard_is_equal (other) end frozen standard_twin: ARRAY2 [G] -- New object field-by-field identical to other. -- Always uses default copying semantics. -- (from ANY) external "built_in" ensure -- from ANY standard_twin_not_void: Result /= Void equal: standard_equal (Result, Current) end subarray (start_pos, end_pos: INTEGER_32): ARRAY [G] -- Array made of items of current array within -- bounds start_pos and end_pos. -- (from ARRAY) require -- from ARRAY valid_start_pos: lower <= start_pos valid_end_pos: end_pos <= upper valid_bounds: (start_pos <= end_pos) or (start_pos = end_pos + 1) do if start_pos <= end_pos then create Result.make_filled (array_item (start_pos), start_pos, end_pos); Result.subcopy (Current, start_pos, end_pos, start_pos) else create Result.make_empty; Result.rebase (start_pos) end ensure -- from ARRAY lower: Result.lower = start_pos upper: Result.upper = end_pos end frozen twin: ARRAY2 [G] -- New object equal to Current -- twin calls copy; to change copying/twinning semantics, redefine copy. -- (from ANY) external "built_in" ensure -- from ANY twin_not_void: Result /= Void is_equal: Result ~ Current end feature -- Basic operations frozen as_attached: attached ARRAY2 [G] obsolete "Remove calls to this feature. [2017-05-31]" -- Attached version of Current. -- (Can be used during transitional period to convert -- non-void-safe classes to void-safe ones.) -- (from ANY) do Result := Current end frozen default: detachable ARRAY2 [G] -- Default value of object's type -- (from ANY) do end frozen default_pointer: POINTER -- Default value of type POINTER -- (Avoid the need to write p.default for -- some p of type POINTER.) -- (from ANY) do ensure -- from ANY instance_free: class end default_rescue -- Process exception for routines with no Rescue clause. -- (Default: do nothing.) -- (from ANY) do end frozen do_nothing -- Execute a null action. -- (from ANY) do ensure -- from ANY instance_free: class end feature -- Inapplicable bag_put (v: G) -- Ensure that structure includes v. -- (from TABLE) require -- from COLLECTION extendible: extendible do ensure -- from COLLECTION item_inserted: is_inserted (v) end extend (v: G) -- Add v to structure. -- (Precondition is False.) -- (from ARRAY) require -- from COLLECTION extendible: extendible do ensure -- from COLLECTION item_inserted: is_inserted (v) end prune (v: G) -- Remove first occurrence of v if any. -- (Precondition is False.) -- (from ARRAY) require -- from COLLECTION prunable: prunable do end feature {NONE} -- Implementation empty_area: BOOLEAN -- Is area empty? -- (from ARRAY) do Result := area.capacity = 0 end feature -- Iteration do_all (action: PROCEDURE [G]) -- Apply action to every item, from first to last. -- Semantics not guaranteed if action changes the structure; -- in such a case, apply iterator to clone of structure instead. -- (from ARRAY) require -- from ARRAY action_not_void: action /= Void do area.do_all_in_bounds (action, 0, count - 1) end do_all_with_index (action: PROCEDURE [G, INTEGER_32]) -- Apply action to every item, from first to last. -- action receives item and its index. -- Semantics not guaranteed if action changes the structure; -- in such a case, apply iterator to clone of structure instead. -- (from ARRAY) local i, j, nb: INTEGER_32 l_area: like area do from i := 0 j := lower nb := count - 1 l_area := area until i > nb loop action.call ([l_area.item (i), j]) j := j + 1 i := i + 1 end end do_if (action: PROCEDURE [G]; test: FUNCTION [G, BOOLEAN]) -- Apply action to every item that satisfies test, from first to last. -- Semantics not guaranteed if action or test changes the structure; -- in such a case, apply iterator to clone of structure instead. -- (from ARRAY) require -- from ARRAY action_not_void: action /= Void test_not_void: test /= Void do area.do_if_in_bounds (action, test, 0, count - 1) end do_if_with_index (action: PROCEDURE [G, INTEGER_32]; test: FUNCTION [G, INTEGER_32, BOOLEAN]) -- Apply action to every item that satisfies test, from first to last. -- action and test receive the item and its index. -- Semantics not guaranteed if action or test changes the structure; -- in such a case, apply iterator to clone of structure instead. -- (from ARRAY) local i, j, nb: INTEGER_32 l_area: like area do from i := 0 j := lower nb := count - 1 l_area := area until i > nb loop if test.item ([l_area.item (i), j]) then action.call ([l_area.item (i), j]) end j := j + 1 i := i + 1 end end for_all (test: FUNCTION [G, BOOLEAN]): BOOLEAN -- Is test true for all items? -- (from ARRAY) require -- from ARRAY test_not_void: test /= Void do Result := area.for_all_in_bounds (test, 0, count - 1) end there_exists (test: FUNCTION [G, BOOLEAN]): BOOLEAN -- Is test true for at least one item? -- (from ARRAY) require -- from ARRAY test_not_void: test /= Void do Result := area.there_exists_in_bounds (test, 0, count - 1) end feature -- Output Io: STD_FILES -- Handle to standard file setup -- (from ANY) once create Result; Result.set_output_default ensure -- from ANY instance_free: class io_not_void: Result /= Void end out: STRING_8 -- New string containing terse printable representation -- of current object -- (from ANY) do Result := tagged_out ensure -- from ANY out_not_void: Result /= Void end print (o: detachable ANY) -- Write terse external representation of o -- on standard output. -- (from ANY) local s: READABLE_STRING_8 do if attached o then s := o.out if attached {READABLE_STRING_32} s as s32 then Io.put_string_32 (s32) elseif attached {READABLE_STRING_8} s as s8 then Io.put_string (s8) else Io.put_string_32 (s.as_string_32) end end ensure -- from ANY instance_free: class end frozen tagged_out: STRING_8 -- New string containing terse printable representation -- of current object -- (from ANY) external "built_in" ensure -- from ANY tagged_out_not_void: Result /= Void end feature -- Platform Operating_environment: OPERATING_ENVIRONMENT -- Objects available from the operating system -- (from ANY) once create Result ensure -- from ANY instance_free: class operating_environment_not_void: Result /= Void end feature {NONE} -- Retrieval frozen internal_correct_mismatch -- Called from runtime to perform a proper dynamic dispatch on correct_mismatch -- from MISMATCH_CORRECTOR. -- (from ANY) local l_msg: STRING_32 l_exc: EXCEPTIONS do if attached {MISMATCH_CORRECTOR} Current as l_corrector then l_corrector.correct_mismatch else create l_msg.make_from_string ("Mismatch: ".as_string_32) create l_exc; l_msg.append (generating_type.name_32); l_exc.raise_retrieval_exception (l_msg) end end invariant items_number: count = width * height -- from ARRAY area_exists: area /= Void consistent_size: capacity = upper - lower + 1 non_negative_count: count >= 0 -- from RESIZABLE increase_by_at_least_one: Minimal_increase >= 1 -- from BOUNDED valid_count: count <= capacity full_definition: full = (count = capacity) -- from FINITE empty_definition: is_empty = (count = 0) -- from ANY reflexive_equality: standard_is_equal (Current) reflexive_conformance: conforms_to (Current) -- from READABLE_INDEXABLE consistent_boundaries: lower <= upper or else lower = upper + 1 note copyright: "Copyright (c) 1984-2017, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" source: "[ Eiffel Software 5949 Hollister Ave., Goleta, CA 93117 USA Telephone 805-685-1006, Fax 805-685-6869 Website http://www.eiffel.com Customer support http://support.eiffel.com ]" end -- class ARRAY2
Generated by ISE EiffelStudio