note description: "[ Special objects: homogeneous sequences of values, used to represent arrays and strings ]" library: "Free implementation of ELKS library" status: "See notice at end of class." legal: "See notice at end of class." date: "$Date: 2017-04-15 12:05:54 +0000 (Sat, 15 Apr 2017) $" revision: "$Revision: 100207 $" frozen class SPECIAL [T] create make_empty, make_filled, make_from_native_array feature {NONE} -- Initialization default_create -- Process instances of classes with no creation clause. -- (Default: do nothing.) -- (from ANY) do end make_empty (n: INTEGER_32) -- Create a special object for n entries. require non_negative_argument: n >= 0 do ensure capacity_set: capacity = n count_set: count = 0 end make_filled (v: T; n: INTEGER_32) -- Create a special object for n entries initialized with v. require non_negative_argument: n >= 0 do make_empty (n) fill_with (v, 0, n - 1) ensure capacity_set: capacity = n count_set: count = n filled: filled_with (v, 0, n - 1) end make_from_native_array (an_array: like native_array) -- Create a special object from an_array. require is_dotnet: {PLATFORM}.is_dotnet an_array_not_void: an_array /= Void do end feature -- Access at alias "@" (i: INTEGER_32): T -- Item at i-th position. -- (indices begin at 0) require valid_index: valid_index (i) do Result := item (i) end base_address: POINTER -- Address of element at position 0. -- Use only when interfacing with C externals when Current is guaranteed to not move in memory. require not_dotnet: not {PLATFORM}.is_dotnet external "built_in" ensure base_address_not_null: Result /= default_pointer end generating_type: TYPE [detachable SPECIAL [T]] -- 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 index_of (v: T; start_position: INTEGER_32): INTEGER_32 -- Index of first occurrence of item identical to v. -- -1 if none. -- (Use object equality for comparison.) require valid_start_position: start_position >= 0 local nb: INTEGER_32 do from Result := start_position nb := count until Result >= nb or else item (Result) ~ v loop Result := Result + 1 end if Result >= nb then Result := -1 end ensure found_or_not_found: Result = -1 or else (Result >= 0 and then Result < count) end item alias "[]" (i: INTEGER_32): T assign put -- Item at i-th position. -- (indices begin at 0) require -- from READABLE_INDEXABLE valid_index: valid_index (i) local r: detachable T do check attached r then Result := r end end item_address (i: INTEGER_32): POINTER -- Address of element at position i. -- Use only when interfacing with C externals when Current is guaranteed to not move in memory. require not_dotnet: not {PLATFORM}.is_dotnet index_large_enough: i >= 0 index_small_enough: i < count do Result := base_address + i * element_size ensure element_address_not_null: Result /= default_pointer end native_array: NATIVE_ARRAY [T] -- Only for compatibility with .NET. require is_dotnet: {PLATFORM}.is_dotnet do create Result end new_cursor: SPECIAL_ITERATION_CURSOR [T] -- Fresh cursor associated with current structure require -- from ITERABLE True do create Result.make (Current) ensure -- from ITERABLE result_attached: Result /= Void end to_array: ARRAY [T] -- Build an array representation of Current from 1 to count. do create Result.make_from_special (Current) ensure to_array_attached: Result /= Void to_array_lower_set: Result.lower = 1 to_array_upper_set: Result.upper = count end feature -- Measurement capacity: INTEGER_32 -- Capacity of special area. external "built_in" ensure -- from ABSTRACT_SPECIAL count_non_negative: Result >= 0 end count: INTEGER_32 -- Count of special area. external "built_in" ensure -- from ABSTRACT_SPECIAL count_non_negative: Result >= 0 end 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 = 0 -- Minimum index of Current. upper: INTEGER_32 -- Maximum index of Current. do Result := count - 1 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: SPECIAL [T]): 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: SPECIAL [T]): BOOLEAN -- Is other attached to an object considered -- equal to current object? -- (from ANY) require -- from ANY other_not_void: other /= Void external "built_in" 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: SPECIAL [T]): 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 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 filled_with (v: T; start_index, end_index: INTEGER_32): BOOLEAN -- Are all items between index start_index and end_index -- set to v? -- (Use reference equality for comparison.) require start_index_non_negative: start_index >= 0 start_index_not_too_big: start_index <= end_index + 1 end_index_valid: end_index < count local i: INTEGER_32 do from Result := True i := start_index until i > end_index or else not Result loop Result := item (i) = v i := i + 1 end end same_items (other: like Current; source_index, destination_index, n: INTEGER_32): BOOLEAN -- Are the n elements of other from source_index position the same as -- the n elements of Current from destination_index? -- (Use reference equality for comparison.) require other_not_void: other /= Void source_index_non_negative: source_index >= 0 destination_index_non_negative: destination_index >= 0 n_non_negative: n >= 0 n_is_small_enough_for_source: source_index + n <= other.count n_is_small_enough_for_destination: destination_index + n <= count local i, j, nb: INTEGER_32 do Result := True if other /= Current then from i := source_index j := destination_index nb := source_index + n until i = nb loop if other.item (i) /= item (j) then Result := False i := nb - 1 end i := i + 1 j := j + 1 end end ensure valid_on_empty_area: n = 0 implies Result 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 Current? require -- from ABSTRACT_SPECIAL True require -- from READABLE_INDEXABLE True do Result := 0 <= i and i < count ensure -- from READABLE_INDEXABLE only_if_in_index_set: Result implies (Lower <= i and i <= upper) end feature -- Element change copy_data (other: SPECIAL [T]; source_index, destination_index, n: INTEGER_32) -- Copy n elements of other from source_index position to Current at -- destination_index. Other elements of Current remain unchanged. require other_not_void: other /= Void source_index_non_negative: source_index >= 0 destination_index_non_negative: destination_index >= 0 destination_index_in_bound: destination_index <= count n_non_negative: n >= 0 n_is_small_enough_for_source: source_index + n <= other.count n_is_small_enough_for_destination: destination_index + n <= capacity same_type: other.conforms_to (Current) local i, j, nb: INTEGER_32 do if other = Current then move_data (source_index, destination_index, n) else from i := source_index j := destination_index nb := source_index + n until i = nb loop force (other.item (i), j) i := i + 1 j := j + 1 end end ensure copied: same_items (other, source_index, destination_index, n) count_updated: count = (old count).max (destination_index + n) end extend (v: T) -- Add v at index count. require count_small_enough: count < capacity do ensure count_increased: count = old count + 1 same_capacity: capacity = old capacity inserted: item (count - 1) = v end extend_filled (v: T) -- Set items between count and capacity - 1 with v. do fill_with (v, count, capacity - 1) ensure same_capacity: capacity = old capacity count_increased: count = capacity filled: filled_with (v, old count, capacity - 1) end fill_with (v: T; start_index, end_index: INTEGER_32) -- Set items between start_index and end_index with v. require start_index_non_negative: start_index >= 0 start_index_in_bound: start_index <= count start_index_not_too_big: start_index <= end_index + 1 end_index_valid: end_index < capacity local i, nb: INTEGER_32 l_count: like count do from i := start_index l_count := count.min (end_index + 1) nb := l_count until i = nb loop put (v, i) i := i + 1 end from i := l_count nb := end_index + 1 until i = nb loop extend (v) i := i + 1 end ensure same_capacity: capacity = old capacity count_definition: count = (old count).max (end_index + 1) filled: filled_with (v, start_index, end_index) end fill_with_default (start_index, end_index: INTEGER_32) -- Clear items between start_index and end_index. require is_self_initializing: ({T}).has_default start_index_non_negative: start_index >= 0 start_index_not_too_big: start_index <= end_index + 1 end_index_valid: end_index < count do fill_with (({T}).default, start_index, end_index) ensure filled: filled_with (({T}).default, start_index, end_index) end force (v: T; i: INTEGER_32) -- If i is equal to count increase count by one and insert v at index count, -- otherwise replace i-th item by v. -- (Indices begin at 0.) require index_large_enough: i >= 0 index_small_enough: i <= count not_full: i = count implies count < capacity do if i < count then put (v, i) else extend (v) end ensure count_updated: count = (i + 1).max (old count) same_capacity: capacity = old capacity inserted: item (i) = v end insert_data (other: SPECIAL [T]; source_index, destination_index, n: INTEGER_32) -- Insert n elements of other from source_index position to Current at -- destination_index and shift elements between destination_index and count -- to the right. Other elements of Current remain unchanged. require other_not_void: other /= Void source_index_non_negative: source_index >= 0 destination_index_non_negative: destination_index >= 0 destination_index_in_bound: destination_index <= count n_non_negative: n >= 0 n_is_small_enough_for_source: source_index + n <= other.count n_is_small_enough_for_destination: count + n <= capacity same_type: other.conforms_to (Current) local l_remaining_items, l_offset, l_nb_items_left: INTEGER_32 l_source_index, l_end_index, l_destination_index: INTEGER_32 do l_remaining_items := count - destination_index if l_remaining_items = 0 then copy_data (other, source_index, destination_index, n) elseif n <= l_remaining_items then move_data (destination_index, destination_index + n, l_remaining_items) copy_data (other, source_index, destination_index, n) else from l_source_index := source_index l_destination_index := destination_index l_end_index := source_index + n l_nb_items_left := n l_offset := l_remaining_items until l_source_index >= l_end_index loop move_data (l_destination_index, l_destination_index + l_offset, l_remaining_items) copy_data (other, l_source_index, l_destination_index, l_offset) l_destination_index := l_destination_index + l_offset l_source_index := l_source_index + l_offset l_nb_items_left := l_nb_items_left - l_remaining_items l_offset := l_offset.min (l_nb_items_left) end end ensure copied: same_items (other, source_index, destination_index, n) count_updated: count = old count + n end move_data (source_index, destination_index, n: INTEGER_32) -- Move n elements of Current from source_start position to destination_index. -- Other elements remain unchanged. require source_index_non_negative: source_index >= 0 destination_index_non_negative: destination_index >= 0 destination_index_in_bound: destination_index <= count n_non_negative: n >= 0 n_is_small_enough_for_source: source_index + n <= count n_is_small_enough_for_destination: destination_index + n <= capacity do if source_index = destination_index then elseif source_index > destination_index then if destination_index + n < source_index then non_overlapping_move (source_index, destination_index, n) else overlapping_move (source_index, destination_index, n) end else if source_index + n < destination_index then non_overlapping_move (source_index, destination_index, n) else overlapping_move (source_index, destination_index, n) end end ensure moved: same_items (old twin, source_index, destination_index, n) count_updated: count = (old count).max (destination_index + n) end non_overlapping_move (source_index, destination_index, n: INTEGER_32) -- Move n elements of Current from source_start position to destination_index. -- Other elements remain unchanged. require source_index_non_negative: source_index >= 0 destination_index_non_negative: destination_index >= 0 destination_index_in_bound: destination_index <= count n_non_negative: n >= 0 different_source_and_target: source_index /= destination_index non_overlapping: (source_index < destination_index implies source_index + n < destination_index) or (source_index > destination_index implies destination_index + n < source_index) n_is_small_enough_for_source: source_index + n <= count n_is_small_enough_for_destination: destination_index + n <= capacity local i, nb: INTEGER_32 l_offset: INTEGER_32 do from i := source_index nb := source_index + n l_offset := destination_index - source_index until i = nb loop force (item (i), i + l_offset) i := i + 1 end ensure moved: same_items (Current, source_index, destination_index, n) count_updated: count = (old count).max (destination_index + n) end overlapping_move (source_index, destination_index, n: INTEGER_32) -- Move n elements of Current from source_start position to destination_index. -- Other elements remain unchanged. require source_index_non_negative: source_index >= 0 destination_index_non_negative: destination_index >= 0 destination_index_in_bound: destination_index <= count n_non_negative: n >= 0 different_source_and_target: source_index /= destination_index n_is_small_enough_for_source: source_index + n <= count n_is_small_enough_for_destination: destination_index + n <= capacity local i, nb: INTEGER_32 l_offset: INTEGER_32 do if source_index < destination_index then from i := source_index + n - 1 nb := source_index - 1 l_offset := destination_index - source_index if destination_index + n >= count then fill_with (item (source_index), count, destination_index + n - 1) end check l_offset_positive: l_offset > 0 end until i = nb loop put (item (i), i + l_offset) i := i - 1 end else from i := source_index nb := source_index + n l_offset := source_index - destination_index check l_offset_positive: l_offset > 0 end until i = nb loop force (item (i), i - l_offset) i := i + 1 end end ensure moved: same_items (old twin, source_index, destination_index, n) count_updated: count = (old count).max (destination_index + n) end put (v: T; i: INTEGER_32) -- Replace i-th item by v. -- (Indices begin at 0.) require index_large_enough: i >= 0 index_small_enough: i < count do ensure inserted: item (i) = v same_count: count = old count same_capacity: capacity = old capacity end feature -- Removal clear_all obsolete "Because of the new precondition, it is recommended to use `fill_with' instead. [2017-05-31]" -- Reset all items to default values. require has_default: ({T}).has_default do fill_with_default (0, upper) ensure same_capacity: capacity = old capacity count_reset: count = old count end replace_all (v: T) -- Replace all items with v. local i: INTEGER_32 do from i := count - 1 until i < 0 loop put (v, i) i := i - 1 end ensure cleared: filled_with (v, 0, upper) end wipe_out -- Reset count to zero. do set_count (0) ensure same_capacity: capacity = old capacity count_reset: count = 0 end feature -- Resizing aliased_resized_area (n: INTEGER_32): like Current -- Try to resize Current with a count of n, if not -- possible a new copy. require n_non_negative: n >= 0 external "built_in" ensure result_not_void: Result /= Void new_count: Result.count = n.min (old count) new_capacity: Result.capacity = n preserved: Result.same_items (old twin, 0, 0, n.min (old count)) end aliased_resized_area_with_default (a_default_value: T; n: INTEGER_32): like Current -- Try to resize Current with a count of n, if not -- possible a new copy. Non yet initialized entries are set to a_default_value. require n_non_negative: n >= 0 do Result := aliased_resized_area (n); Result.fill_with (a_default_value, Result.count, n - 1) ensure result_not_void: Result /= Void new_count: Result.count = n new_capacity: Result.capacity = n preserved: Result.same_items (old twin, 0, 0, n.min (old count)) end keep_head (n: INTEGER_32) -- Keep the first n entries. require non_negative_argument: n >= 0 less_than_count: n <= count do set_count (n) ensure count_updated: count = n kept: same_items (old twin, 0, 0, n) end keep_tail (n: INTEGER_32) -- Keep the last n entries. require non_negative_argument: n >= 0 less_than_count: n <= count do overlapping_move (count - n, 0, n) set_count (n) ensure count_updated: count = n kept: same_items (old twin, n, 0, n) end remove_head (n: INTEGER_32) -- Remove the first n entries. require non_negative_argument: n >= 0 less_than_count: n <= count do keep_tail (count - n) ensure count_updated: count = old count - n kept: same_items (old twin, n, 0, count) end remove_tail (n: INTEGER_32) -- Keep the first count - n entries. require non_negative_argument: n >= 0 less_than_count: n <= count do keep_head (count - n) ensure count_updated: count = old count - n kept: same_items (old twin, 0, 0, count) end resized_area (n: INTEGER_32): like Current -- A copy of Current with a count of n. require n_non_negative: n >= 0 do create Result.make_empty (n); Result.copy_data (Current, 0, 0, n.min (count)) ensure result_not_void: Result /= Void result_different_from_current: Result /= Current new_count: Result.count = n.min (old count) new_capacity: Result.capacity = n preserved: Result.same_items (Current, 0, 0, n.min (old count)) end resized_area_with_default (a_default_value: T; n: INTEGER_32): like Current -- Create a copy of Current with a count of n where not yet initialized -- entries are set to a_default_value. require n_non_negative: n >= 0 do create Result.make_empty (n) if n > count then Result.copy_data (Current, 0, 0, count); Result.fill_with (a_default_value, count, n - 1) else Result.copy_data (Current, 0, 0, n) end ensure result_not_void: Result /= Void result_different_from_current: Result /= Current new_count: Result.count = n new_capacity: Result.capacity = n preserved: Result.same_items (Current, 0, 0, n.min (old count)) 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: SPECIAL [T]) -- Update current object using fields of object attached -- to other, so as to yield equal objects. -- (from ANY) require -- from ANY other_not_void: other /= Void type_identity: same_type (other) external "built_in" ensure -- from ANY is_equal: Current ~ other 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: SPECIAL [T]) -- 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: SPECIAL [T] -- 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: SPECIAL [T]) -- 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: SPECIAL [T] -- 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 frozen twin: SPECIAL [T] -- 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 SPECIAL [T] 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 SPECIAL [T] -- 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 {NONE} -- Implementation element_size: INTEGER_32 -- Size of elements. external "built_in" ensure element_size_non_negative: Result >= 0 end set_count (n: INTEGER_32) -- Set count with n. require n_non_negative: n >= 0 valid_new_count: n <= count external "built_in" ensure count_set: count = n capacity_preserved: capacity = old capacity end feature -- Iteration do_all_in_bounds (action: PROCEDURE [T]; start_index, end_index: INTEGER_32) -- 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. require action_not_void: action /= Void local i, nb: INTEGER_32 do from i := start_index nb := end_index until i > nb loop action.call ([item (i)]) i := i + 1 end end do_all_with_index_in_bounds (action: PROCEDURE [T, INTEGER_32]; start_index, end_index: 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. require action_not_void: action /= Void local i, j, nb: INTEGER_32 do from i := start_index j := Lower nb := end_index until i > nb loop action.call ([item (i), j]) j := j + 1 i := i + 1 end end do_if_in_bounds (action: PROCEDURE [T]; test: FUNCTION [T, BOOLEAN]; start_index, end_index: INTEGER_32) -- 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. require action_not_void: action /= Void test_not_void: test /= Void local i, nb: INTEGER_32 do from i := start_index nb := end_index until i > nb loop if test.item ([item (i)]) then action.call ([item (i)]) end i := i + 1 end end do_if_with_index_in_bounds (action: PROCEDURE [T, INTEGER_32]; test: FUNCTION [T, INTEGER_32, BOOLEAN]; start_index, end_index: INTEGER_32) -- 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. require action_not_void: action /= Void test_not_void: test /= Void local i, j, nb: INTEGER_32 do from i := start_index j := Lower nb := end_index until i > nb loop if test.item ([item (i), j]) then action.call ([item (i), j]) end j := j + 1 i := i + 1 end end for_all_in_bounds (test: FUNCTION [T, BOOLEAN]; start_index, end_index: INTEGER_32): BOOLEAN -- Is test true for all items? require test_not_void: test /= Void local i, nb: INTEGER_32 do from i := start_index nb := end_index Result := True until i > nb or not Result loop Result := test.item ([item (i)]) i := i + 1 end end there_exists_in_bounds (test: FUNCTION [T, BOOLEAN]; start_index, end_index: INTEGER_32): BOOLEAN -- Is test true for at least one item? require test_not_void: test /= Void local i, nb: INTEGER_32 do from i := start_index nb := end_index until i > nb or Result loop Result := test.item ([item (i)]) i := i + 1 end end feature -- Output debug_output: STRING_8 -- String that should be displayed in debugger to represent Current. require -- from DEBUG_OUTPUT True do Result := Precursor; Result.append_string (", capacity="); Result.append_integer (capacity) ensure -- from DEBUG_OUTPUT result_not_void: Result /= Void end 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 consistent_count: count = upper - Lower + 1 -- from ABSTRACT_SPECIAL count_less_than_capacity: count <= capacity -- 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 SPECIAL
Generated by ISE EiffelStudio