note description: "A sequence of actions to be performed on call." legal: "See notice at end of class." instructions: "[ Use features inherited from LIST to add/remove actions. An action is a procedure of ANY class that takes EVENT_DATA. When call is called the actions in the list will be executed in order stating at first. An action may call abort which will cause call to stop executing actions in the sequence. (Until the next call to call). Descendants may redefine initialize to arrange for call to be called by an event source. Use block, pause, flush and resume to change the behavior of call. eg. birthday_data: TUPLE [INTEGER, STRING] -- (age, name) birthday_actions: ACTION_SEQUENCE [like birthday_data] create birthday_actions.make ("birthday", <<"age","name">>) send_card (age: INTEGER, name, from: STRING) is ... buy_gift (age: INTEGER, name, gift, from: STRING) is ... birthday_actions.extend (agent send_card (?, ?, "Sam") birthday_actions.extend (agent buy_gift (?, ?, "Wine", "Sam") birthday_actions.call ([35, "Julia"]) causes call to: send_card (35, "Julia", "Sam") buy_gift (35, "Julia", "Wine", "Sam") ]" status: "See notice at end of class." keywords: event, action date: "$Date: 2018-11-14 15:15:17 +0000 (Wed, 14 Nov 2018) $" revision: "$Revision: 102463 $" class ACTION_SEQUENCE [EVENT_DATA -> detachable TUPLE create default_create end] create default_create, make create {ACTION_SEQUENCE} arrayed_list_make, make_filled feature {NONE} -- Initialization default_create -- Begin in Normal_state. require -- from ANY True do arrayed_list_make (0) state := Normal_state 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_v2.make_empty (n) ensure -- from TO_SPECIAL area_allocated: area_v2 /= Void capacity_set: area_v2.capacity = n count_set: area_v2.count = 0 end make_filled_area (a_default_value: PROCEDURE [EVENT_DATA]; 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_v2.make_filled (a_default_value, n) ensure -- from TO_SPECIAL area_allocated: area_v2 /= Void capacity_set: area_v2.capacity = n count_set: area_v2.count = n area_filled: area_v2.filled_with (a_default_value, 0, n - 1) end make_from_array (a: ARRAY [like item]) -- Create list from array a. -- (from INTERACTIVE_LIST) require -- from ARRAYED_LIST array_exists: a /= Void local l_index: INTEGER_32 do arrayed_list_make (a.count) from l_index := a.lower until l_index > a.upper loop extend (a.item (l_index)) l_index := l_index + 1 end ensure -- from ARRAYED_LIST shared: area = a.area correct_position: before filled: count = a.count end make_from_iterable (other: ITERABLE [PROCEDURE [EVENT_DATA]]) -- Create a circular chain with all items obtained from other. -- (from ARRAYED_LIST) local a: like area_v2 i, n: like area_v2.count do n := estimated_count_of (other) arrayed_list_make (n) a := area_v2 across other as o loop i := i + 1 if i > n then n := i a := a.aliased_resized_area (n) area_v2 := a end; a.extend (o.item) end end feature -- Initialization arrayed_list_make (n: INTEGER_32) -- Allocate list with n items. -- (n may be zero for empty list.) -- (from ARRAYED_LIST) require -- from ARRAYED_LIST valid_number_of_items: n >= 0 do index := 0 create area_v2.make_empty (n) ensure -- from ARRAYED_LIST correct_position: before is_empty: is_empty end make_filled (n: INTEGER_32) -- Allocate list with n items. -- (n may be zero for empty list.) -- This list will be full. -- (from ARRAYED_LIST) require -- from ARRAYED_LIST valid_number_of_items: n >= 0 has_default: ({PROCEDURE [EVENT_DATA]}).has_default do index := 0 make_filled_area (({PROCEDURE [EVENT_DATA]}).default, n) ensure -- from ARRAYED_LIST correct_position: before filled: full end feature -- Access area: SPECIAL [PROCEDURE [EVENT_DATA]] -- Access to internal storage of ARRAYED_LIST -- (from ARRAYED_LIST) do Result := area_v2 end area_v2: SPECIAL [PROCEDURE [EVENT_DATA]] -- Special data zone. -- (from TO_SPECIAL) at alias "@" (i: INTEGER_32): like item assign put_i_th -- Item at i-th position -- Was declared in ARRAYED_LIST as synonym of i_th. -- (from ARRAYED_LIST) require -- from TABLE valid_key: valid_index (i) do Result := area_v2.item (i - 1) end array_at (i: INTEGER_32): PROCEDURE [EVENT_DATA] assign array_put -- Entry at index i, if in index interval. -- Was declared in TO_SPECIAL as synonym of item. -- (from TO_SPECIAL) require -- from TO_SPECIAL valid_index: array_valid_index (i) do Result := area_v2.item (i) end cursor: ARRAYED_LIST_CURSOR -- Current cursor position -- (from ARRAYED_LIST) do create Result.make (index) ensure -- from CURSOR_STRUCTURE cursor_not_void: Result /= Void end event_data_names: detachable ARRAY [STRING_8] obsolete "Not implemented. To be removed. [2017-05-31]" -- Textual description of each event datum. local i: like event_data_names_internal do i := event_data_names_internal if i /= Void then Result := i.deep_twin end ensure equal_to_event_data_names_internal: deep_equal (Result, event_data_names_internal) end first: like item -- Item at first position -- (from ARRAYED_LIST) require -- from CHAIN not_empty: not is_empty do Result := area_v2.item (0) end generating_type: TYPE [detachable ACTION_SEQUENCE [EVENT_DATA]] -- 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: like item): BOOLEAN -- Does current include v? -- (Reference or object equality, -- based on object_comparison.) -- (from ARRAYED_LIST) require -- from CONTAINER True local l_area: like area_v2 i, nb: INTEGER_32 do l_area := area_v2 nb := count if object_comparison and v /= Void then from until i >= nb or Result loop Result := v ~ l_area.item (i) i := i + 1 end else from until i >= nb or Result loop Result := v = l_area.item (i) i := i + 1 end end ensure -- from CONTAINER not_found_in_empty: Result implies not is_empty end sequential_has (v: like item): BOOLEAN -- Does structure include an occurrence of v? -- (Reference or object equality, -- based on object_comparison.) -- (from LINEAR) require -- from CONTAINER True do start if not off then search (v) end Result := not exhausted ensure -- from CONTAINER not_found_in_empty: Result implies not is_empty end i_th alias "[]" (i: INTEGER_32): like item assign put_i_th -- Item at i-th position -- Was declared in ARRAYED_LIST as synonym of at. -- (from ARRAYED_LIST) require -- from TABLE valid_key: valid_index (i) require -- from READABLE_INDEXABLE valid_index: valid_index (i) do Result := area_v2.item (i - 1) end index: INTEGER_32 -- Index of item, if valid. -- (from ARRAYED_LIST) sequential_index_of (v: like item; i: INTEGER_32): INTEGER_32 -- Index of i-th occurrence of v. -- 0 if none. -- (Reference or object equality, -- based on object_comparison.) -- (from LINEAR) require -- from LINEAR positive_occurrences: i > 0 local occur, pos: INTEGER_32 do if object_comparison and v /= Void then from start pos := 1 until exhausted or (occur = i) loop if item ~ v then occur := occur + 1 end forth pos := pos + 1 end else from start pos := 1 until exhausted or (occur = i) loop if item = v then occur := occur + 1 end forth pos := pos + 1 end end if occur = i then Result := pos - 1 end ensure -- from LINEAR non_negative_result: Result >= 0 end index_of (v: like item; i: INTEGER_32): INTEGER_32 -- Index of i-th occurrence of item identical to v. -- (Reference or object equality, -- based on object_comparison.) -- 0 if none. -- (from CHAIN) local pos: CURSOR do pos := cursor Result := sequential_index_of (v, i) go_to (pos) end array_item (i: INTEGER_32): PROCEDURE [EVENT_DATA] assign array_put -- Entry at index i, if in index interval. -- Was declared in TO_SPECIAL as synonym of at. -- (from TO_SPECIAL) require -- from TO_SPECIAL valid_index: array_valid_index (i) do Result := area_v2.item (i) end item: PROCEDURE [EVENT_DATA] -- Current item -- (from ARRAYED_LIST) require -- from ACTIVE readable: readable require -- from TRAVERSABLE not_off: not off require else -- from ARRAYED_LIST index_is_valid: valid_index (index) do Result := area_v2.item (index - 1) end item_for_iteration: PROCEDURE [EVENT_DATA] -- Item at current position -- (from LINEAR) require -- from LINEAR not_off: not off do Result := item end last: like first -- Item at last position -- (from ARRAYED_LIST) require -- from CHAIN not_empty: not is_empty do Result := area_v2.item (count - 1) end name: detachable STRING_8 -- Textual description. local i: like name_internal do i := name_internal if i /= Void then Result := i.twin end ensure equal_to_name_internal: Result ~ name_internal end new_cursor: ARRAYED_LIST_ITERATION_CURSOR [PROCEDURE [EVENT_DATA]] -- Fresh cursor associated with current structure -- (from ARRAYED_LIST) require -- from ITERABLE True do create Result.make (Current) ensure -- from ITERABLE result_attached: Result /= Void end sequential_occurrences (v: like item): INTEGER_32 -- Number of times v appears. -- (Reference or object equality, -- based on object_comparison.) -- (from LINEAR) require -- from BAG True do from start search (v) until exhausted loop Result := Result + 1 forth search (v) end ensure -- from BAG non_negative_occurrences: Result >= 0 end to_array: ARRAY [PROCEDURE [EVENT_DATA]] -- Share content to be used as an ARRAY. -- Note that although the content is shared, it might -- not be shared when a resizing occur in either ARRAY or Current. -- (from ARRAYED_LIST) do create Result.make_from_special (area_v2) ensure -- from ARRAYED_LIST to_array_attached: Result /= Void array_lower_set: Result.lower = 1 array_upper_set: Result.upper = count shared_area: Result.area = area 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 items that may be stored -- (from ARRAYED_LIST) do Result := area_v2.capacity ensure -- from BOUNDED capacity_non_negative: Result >= 0 end count: INTEGER_32 -- Number of items. -- (from ARRAYED_LIST) require -- from FINITE True require -- from READABLE_INDEXABLE True do Result := area_v2.count ensure -- from FINITE count_non_negative: Result >= 0 end Growth_percentage: INTEGER_32 = 50 -- Percentage by which structure will grow automatically -- (from RESIZABLE) 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, count) ensure -- from READABLE_INDEXABLE not_void: Result /= Void empty_if_not_in_order: (Lower > count) implies Result.is_empty same_lower_if_not_empty: (Lower <= count) implies Result.lower = Lower same_upper_if_not_empty: (Lower <= count) implies Result.upper = count end Lower: INTEGER_32 = 1 -- Minimum index. -- (from CHAIN) Minimal_increase: INTEGER_32 = 5 -- Minimal number of additional items -- (from RESIZABLE) occurrences (v: like item): INTEGER_32 -- Number of times v appears. -- (Reference or object equality, -- based on object_comparison.) -- (from CHAIN) local pos: CURSOR do pos := cursor Result := sequential_occurrences (v) go_to (pos) end upper: INTEGER_32 -- Maximum index. -- Use count instead. -- (from ARRAYED_LIST) do Result := area_v2.count ensure -- from ARRAYED_LIST definition: Result = count end feature {NONE} -- Measurement estimated_count_of (other: ITERABLE [PROCEDURE [EVENT_DATA]]): INTEGER_32 -- Estimated number of elements in other. -- (from CONTAINER) do if attached {FINITE [PROCEDURE [EVENT_DATA]]} other as f then Result := f.count elseif attached {READABLE_INDEXABLE [PROCEDURE [EVENT_DATA]]} 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: ACTION_SEQUENCE [EVENT_DATA]): 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: ACTION_SEQUENCE [EVENT_DATA]): BOOLEAN -- Is array made of the same items as other? -- (from ARRAYED_LIST) require -- from ANY other_not_void: other /= Void local i: INTEGER_32 do if other = Current then Result := True elseif count = other.count 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 := i_th (i) ~ other.i_th (i) i := i + 1 end else Result := area_v2.same_items (other.area_v2, 0, 0, count) end end ensure -- from ANY symmetric: Result implies other ~ Current consistent: standard_is_equal (other) implies Result ensure then -- from LIST indices_unchanged: index = old index and other.index = old other.index true_implies_same_size: Result implies count = other.count 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: ACTION_SEQUENCE [EVENT_DATA]): 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 after: BOOLEAN -- Is there no valid cursor position to the right of cursor? -- (from LIST) require -- from LINEAR True do Result := index = count + 1 end all_default: BOOLEAN -- Are all items set to default values? -- (from ARRAYED_LIST) require -- from ARRAYED_LIST has_default: ({PROCEDURE [EVENT_DATA]}).has_default do Result := area_v2.filled_with (({PROCEDURE [EVENT_DATA]}).default, 0, area_v2.upper) end before: BOOLEAN -- Is there no valid cursor position to the left of cursor? -- (from LIST) require -- from BILINEAR True do Result := index = 0 end Blocked_state: INTEGER_32 = 3 call_is_underway: BOOLEAN -- Is call currently being executed? do Result := not is_aborted_stack.is_empty ensure Result = not is_aborted_stack.is_empty 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 exhausted: BOOLEAN -- Has structure been completely explored? -- (from LINEAR) do Result := off ensure -- from LINEAR exhausted_when_off: off implies Result end extendible: BOOLEAN -- May new items be added? (Answer: yes.) -- (from DYNAMIC_CHAIN) require -- from COLLECTION True do Result := True end full: BOOLEAN -- Is structure full? -- (from BOUNDED) require -- from BOX True do Result := count = capacity end is_empty: BOOLEAN -- Is structure empty? -- (from FINITE) do Result := count = 0 end is_inserted (v: PROCEDURE [EVENT_DATA]): BOOLEAN -- Has v been inserted at the end by the most recent put or -- extend? -- (from ARRAYED_LIST) do if not is_empty then Result := (v = last) or else (not off and then (v = item)) end end isfirst: BOOLEAN -- Is cursor at first position? -- (from CHAIN) do Result := not is_empty and (index = 1) ensure -- from CHAIN valid_position: Result implies not is_empty end islast: BOOLEAN -- Is cursor at last position? -- (from CHAIN) do Result := not is_empty and (index = count) ensure -- from CHAIN valid_position: Result implies not is_empty end Normal_state: INTEGER_32 = 1 object_comparison: BOOLEAN -- Must search operations use equal rather than = -- for comparing references? (Default: no, use =.) -- (from CONTAINER) off: BOOLEAN -- Is there no current item? -- (from CHAIN) require -- from TRAVERSABLE True do Result := (index = 0) or (index = count + 1) end Paused_state: INTEGER_32 = 2 prunable: BOOLEAN -- May items be removed? (Answer: yes.) -- (from ARRAYED_LIST) require -- from COLLECTION True do Result := True end readable: BOOLEAN -- Is there a current item that may be read? -- (from SEQUENCE) require -- from ACTIVE True do Result := not off end replaceable: BOOLEAN -- Can current item be replaced? -- (from ACTIVE) do Result := True end resizable: BOOLEAN -- May capacity be changed? (Answer: yes.) -- (from RESIZABLE) do Result := True 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 state: INTEGER_32 -- One of Normal_state Paused_state or Blocked_state valid_cursor (p: CURSOR): BOOLEAN -- Can the cursor be moved to position p? -- (from ARRAYED_LIST) do if attached {ARRAYED_LIST_CURSOR} p as al_c then Result := valid_cursor_index (al_c.index) end end valid_cursor_index (i: INTEGER_32): BOOLEAN -- Is i correctly bounded for cursor movement? -- (from CHAIN) do Result := (i >= 0) and (i <= count + 1) ensure -- from CHAIN valid_cursor_index_definition: Result = ((i >= 0) and (i <= count + 1)) end valid_index (i: INTEGER_32): BOOLEAN -- Is i a valid index? -- (from ARRAYED_LIST) require -- from READABLE_INDEXABLE True require -- from TABLE True do Result := (1 <= i) and (i <= count) ensure -- from READABLE_INDEXABLE only_if_in_index_set: Result implies (Lower <= i and i <= count) ensure then -- from CHAIN valid_index_definition: Result = ((i >= 1) and (i <= count)) end array_valid_index (i: INTEGER_32): BOOLEAN -- Is i within the bounds of Current? -- (from TO_SPECIAL) do Result := area_v2.valid_index (i) end writable: BOOLEAN -- Is there a current item that may be modified? -- (from SEQUENCE) require -- from ACTIVE True do Result := not off end feature -- Status setting abort -- Abort the current call. -- (The current item.call will be completed.) require call_is_underway: call_is_underway do is_aborted_stack.replace (True) ensure is_aborted_set: is_aborted_stack.item end block -- Ignore subsequent calls. do state := Blocked_state ensure blocked_state: state = Blocked_state end 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 flush -- Discard any buffered calls. do call_buffer.wipe_out ensure call_buffer_empty: call_buffer.is_empty end pause -- Buffer subsequent calls for later execution. -- If is_blocked calls will simply be ignored. do state := Paused_state ensure paused_state: state = Paused_state end resume -- Used after block or pause to resume normal call -- execution. Executes any buffered calls. local l_call_buffer: like call_buffer do state := Normal_state from l_call_buffer := call_buffer until l_call_buffer.is_empty loop call (l_call_buffer.item); l_call_buffer.remove end ensure normal_state: state = Normal_state end feature -- Cursor movement back -- Move cursor one position backward. -- (from ARRAYED_LIST) require -- from BILINEAR not_before: not before do index := index - 1 end finish -- Move cursor to last position if any. -- (from ARRAYED_LIST) require -- from LINEAR True do index := count ensure then -- from CHAIN at_last: not is_empty implies islast ensure then -- from ARRAYED_LIST before_when_empty: is_empty implies before end forth -- Move cursor one position forward. -- (from ARRAYED_LIST) require -- from LINEAR not_after: not after do index := index + 1 ensure then -- from LIST moved_forth: index = old index + 1 end go_i_th (i: INTEGER_32) -- Move cursor to i-th position. -- (from ARRAYED_LIST) require -- from CHAIN valid_cursor_index: valid_cursor_index (i) do index := i ensure -- from CHAIN position_expected: index = i end go_to (p: CURSOR) -- Move cursor to position p. -- (from ARRAYED_LIST) require -- from CURSOR_STRUCTURE cursor_position_valid: valid_cursor (p) do if attached {ARRAYED_LIST_CURSOR} p as al_c then index := al_c.index else check correct_cursor_type: False end end end move (i: INTEGER_32) -- Move cursor i positions. -- (from ARRAYED_LIST) do index := index + i if index > count + 1 then index := count + 1 elseif index < 0 then index := 0 end ensure -- from CHAIN too_far_right: (old index + i > count) implies exhausted too_far_left: (old index + i < 1) implies exhausted expected_index: (not exhausted) implies (index = old index + i) end search (v: like item) -- Move to first position (at or after current -- position) where item and v are equal. -- If structure does not include v ensure that -- exhausted will be true. -- (Reference or object equality, -- based on object_comparison.) -- (from ARRAYED_LIST) require -- from LINEAR True local l_area: like area_v2 i, nb: INTEGER_32 l_found: BOOLEAN do l_area := area_v2 nb := count - 1 i := (index - 1).max (0) if object_comparison and v /= Void then from until i > nb or l_found loop l_found := v ~ l_area.item (i) i := i + 1 end else from until i > nb or l_found loop l_found := v = l_area.item (i) i := i + 1 end end if l_found then index := i else index := i + 1 end ensure -- from LINEAR object_found: (not exhausted and object_comparison) implies v ~ item item_found: (not exhausted and not object_comparison) implies v = item end start -- Move cursor to first position if any. -- (from ARRAYED_LIST) require -- from TRAVERSABLE True do index := 1 ensure then -- from CHAIN at_first: not is_empty implies isfirst ensure then -- from ARRAYED_LIST after_when_empty: is_empty implies after end feature -- Element change fill (other: CONTAINER [PROCEDURE [EVENT_DATA]]) -- Fill with as many items of other as possible. -- The representations of other and current structure -- need not be the same. -- (from CHAIN) require -- from COLLECTION other_not_void: other /= Void extendible: extendible local lin_rep: LINEAR [PROCEDURE [EVENT_DATA]] l_cursor: CURSOR do lin_rep := other.linear_representation from l_cursor := cursor; lin_rep.start until not extendible or else lin_rep.off loop extend (lin_rep.item) finish; lin_rep.forth end go_to (l_cursor) end force (v: like item) -- Add v to end. -- Do not move cursor. -- Was declared in ARRAYED_LIST as synonym of extend. -- (from ARRAYED_LIST) require -- from SEQUENCE extendible: extendible local i: INTEGER_32 l_area: like area_v2 do i := count + 1 l_area := area_v2 if i > l_area.capacity then l_area := l_area.aliased_resized_area (i + additional_space) area_v2 := l_area end; l_area.extend (v) ensure then -- from SEQUENCE new_count: count = old count + 1 item_inserted: has (v) end array_put (v: PROCEDURE [EVENT_DATA]; i: INTEGER_32) -- Replace i-th entry, if in index interval, by v. -- (from TO_SPECIAL) require -- from TO_SPECIAL valid_index: array_valid_index (i) do area_v2.put (v, i) ensure -- from TO_SPECIAL inserted: array_item (i) = v end put (v: like item) -- Replace current item by v. -- (Synonym for replace) -- (from CHAIN) require -- from CHAIN writeable: writable replaceable: replaceable do replace (v) ensure -- from CHAIN same_count: count = old count is_inserted: is_inserted (v) end sequence_put (v: like item) -- Add v to end. -- (from SEQUENCE) require -- from COLLECTION extendible: extendible do extend (v) ensure -- from COLLECTION item_inserted: is_inserted (v) ensure then -- from SEQUENCE new_count: count = old count + 1 end feature {NONE} -- Element change set_area (other: like area_v2) -- Make other the new area. -- (from TO_SPECIAL) do area_v2 := other ensure -- from TO_SPECIAL area_set: area_v2 = other end feature -- Removal prune (v: like item) -- Remove first occurrence of v, if any, -- after cursor position. -- Move cursor to right neighbor. -- (or after if no right neighbor or v does not occur) require -- from COLLECTION prunable: prunable local l_compare_objects: BOOLEAN l_kamikazes: like kamikazes_internal do Precursor (v) l_kamikazes := kamikazes_internal if l_kamikazes /= Void then if object_comparison then l_compare_objects := l_kamikazes.object_comparison; l_kamikazes.compare_objects; l_kamikazes.start; l_kamikazes.prune (v) if not l_compare_objects then l_kamikazes.compare_references end else l_kamikazes.prune (v) end end end prune_when_called (an_action: like item) -- Remove an_action after the next time it is called. require has (an_action) do kamikazes.extend (an_action) end remove_i_th (i: INTEGER_32) -- Remove item at index i. -- Move cursor to next neighbor (or after if no next neighbor) if it is at i-th position. -- Do not change cursor otherwise. -- (from ARRAYED_LIST) require -- from DYNAMIC_TABLE prunable: prunable valid_key: valid_index (i) do if i < count then area_v2.move_data (i, i - 1, count - i) end; area_v2.remove_tail (1) if index > i then index := index - 1 end ensure then -- from DYNAMIC_CHAIN new_count: count = old count - 1 same_index_if_below: index <= i implies index = old index new_index_if_above: index > i implies index = old index - 1 same_leading_items: across old twin as c all c.target_index < i implies c.item = i_th (c.target_index) end same_trailing_items: across old twin as c all c.target_index > i implies c.item = i_th (c.target_index - 1) end end remove_left -- Remove item to the left of cursor position. -- Do not move cursor. -- (from ARRAYED_LIST) require -- from DYNAMIC_CHAIN left_exists: index > 1 do index := index - 1 remove ensure -- from DYNAMIC_CHAIN new_count: count = old count - 1 new_index: index = old index - 1 end wipe_out -- Remove all items. -- (from INTERACTIVE_LIST) local l: like area i, l_count: INTEGER_32 do l := area.twin l_count := count Precursor {ARRAYED_LIST} from i := 0 until i = l_count loop on_item_removed_at (l @ i, 1) i := i + 1 end ensure then -- from DYNAMIC_LIST is_before: before end chain_wipe_out -- Remove all items. -- (from DYNAMIC_CHAIN) require -- from COLLECTION prunable: prunable do from start until is_empty loop remove end 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 grow (i: INTEGER_32) -- Change the capacity to at least i. -- (from ARRAYED_LIST) require -- from RESIZABLE resizable: resizable do if i > area_v2.capacity then area_v2 := area_v2.aliased_resized_area (i) end ensure -- from RESIZABLE new_capacity: capacity >= i end resize (new_capacity: INTEGER_32) -- Resize list so that it can contain -- at least n items. Do not lose any item. -- (from ARRAYED_LIST) require -- from ARRAYED_LIST resizable: resizable new_capacity_large_enough: new_capacity >= capacity do grow (new_capacity) ensure -- from ARRAYED_LIST capacity_set: capacity >= new_capacity end trim -- Decrease capacity to the minimum value. -- Apply to reduce allocated storage. -- (from ARRAYED_LIST) require -- from RESIZABLE True local n: like count do n := count if n < area_v2.capacity then area_v2 := area_v2.aliased_resized_area (n) end ensure -- from RESIZABLE same_count: count = old count minimal_capacity: capacity = count ensure then -- from ARRAYED_LIST same_items: to_array.same_items (old to_array) end feature -- Transformation swap (i: INTEGER_32) -- Exchange item at i-th position with item -- at cursor position. -- (from ARRAYED_LIST) require -- from CHAIN not_off: not off valid_index: valid_index (i) local old_item: like item do old_item := item replace (area_v2.item (i - 1)); area_v2.put (old_item, i - 1) ensure -- from CHAIN swapped_to_item: item = old i_th (i) swapped_from_item: i_th (i) = old item end feature -- Conversion linear_representation: LINEAR [PROCEDURE [EVENT_DATA]] -- Representation as a linear structure -- (from LINEAR) require -- from CONTAINER True do Result := Current 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: ACTION_SEQUENCE [EVENT_DATA]) -- Reinitialize by copying all the items of other. -- (This is also used by clone.) -- (from ARRAYED_LIST) 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_v2.twin) end ensure -- from ANY is_equal: Current ~ other ensure then -- from ARRAYED_LIST equal_areas: area_v2 ~ other.area_v2 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: ACTION_SEQUENCE [EVENT_DATA]) -- 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: ACTION_SEQUENCE [EVENT_DATA] -- 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 duplicate (n: INTEGER_32): ACTION_SEQUENCE [EVENT_DATA] obsolete "[ Create a new container explicitly using `make_from_iterable` if available. Otherwise, replace a call to the feature with code that creates and initializes container. [2018-11-30] ]" -- Copy of sub-list beginning at current position -- and having min (n, count - index + 1) items. -- (from ARRAYED_LIST) require -- from CHAIN not_off_unless_after: off implies after valid_subchain: n >= 0 local m: INTEGER_32 do if after then Result := new_filled_list (0) else m := (count - index + 1).min (n) Result := new_filled_list (m); Result.area_v2.copy_data (area_v2, index - 1, 0, m) end 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: ACTION_SEQUENCE [EVENT_DATA]) -- 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: ACTION_SEQUENCE [EVENT_DATA] -- 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: ACTION_SEQUENCE [EVENT_DATA] -- 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 -- Miscellaneous on_item_added_at (an_item: like item; item_index: INTEGER_32) -- an_item has just been added at index item_index. require -- from INTERACTIVE_LIST item_index_valid: (1 <= item_index) and (item_index <= count) do if count = 1 and not_empty_actions_internal /= Void then call_action_list (not_empty_actions) end end on_item_removed_at (an_item: like item; item_index: INTEGER_32) -- an_item has just been removed from index item_index. require -- from INTERACTIVE_LIST item_index_valid: (1 <= item_index) and (item_index <= count + 1) do if count = 0 and empty_actions_internal /= Void then call_action_list (empty_actions) end end feature -- Basic operations frozen as_attached: attached ACTION_SEQUENCE [EVENT_DATA] 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 call (event_data: detachable EVENT_DATA) -- Call each procedure in order unless is_blocked. -- If is_paused delay execution until resume. -- Stop at current point in list on abort. local l_routines_snapshot: SPECIAL [like item] l_count: INTEGER_32 l_action: like item l_kamikazes: SPECIAL [like item] l_kamikazes_internal: like kamikazes_internal l_is_aborted_stack: like is_aborted_stack i: INTEGER_32 do if count > 0 then create l_routines_snapshot.make_empty (count); l_routines_snapshot.copy_data (area, 0, 0, count) l_kamikazes_internal := kamikazes_internal if l_kamikazes_internal /= Void and then not l_kamikazes_internal.is_empty then from l_kamikazes := l_kamikazes_internal.area l_count := l_kamikazes_internal.count i := 0 until i = l_count loop prune_all (l_kamikazes @ i) i := i + 1 end; l_kamikazes_internal.wipe_out end inspect state when Normal_state then from l_is_aborted_stack := is_aborted_stack; l_is_aborted_stack.extend (False) l_count := l_routines_snapshot.count i := 0 variant l_count - i until i = l_count or l_is_aborted_stack.item loop l_action := l_routines_snapshot @ i if l_action /= Void then l_action.call (event_data) end i := i + 1 end; l_is_aborted_stack.remove when Paused_state then call_buffer.extend (event_data) when Blocked_state then end end ensure is_aborted_stack_unchanged: (old is_aborted_stack) ~ is_aborted_stack end frozen default: detachable ACTION_SEQUENCE [EVENT_DATA] -- 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 extend_kamikaze (an_item: like item) -- Extend an_item and remove it again after it is called. do extend (an_item) prune_when_called (an_item) end feature -- Obsolete make obsolete "Use `default_create`. [2017-05-31]" do default_create end set_source_connection_agent (a_source_connection_agent: PROCEDURE) obsolete "Use `not_empty_actions`. [2017-05-31]" -- Set a_source_connection_agent that will connect sequence to an -- actual event source. The agent will be called when the first action is -- added to the sequence. If there are already actions in the -- sequence the agent is called immediately. do not_empty_actions.extend (a_source_connection_agent) if not is_empty then a_source_connection_agent.call (Void) end end feature {DYNAMIC_CHAIN} -- Inapplicable new_chain: ACTION_SEQUENCE [EVENT_DATA] obsolete "Use explicit creation instead. See also explanations for `duplicate`. [2018-11-30]" -- Unused -- (from ARRAYED_LIST) do Result := Current ensure -- from DYNAMIC_CHAIN result_exists: Result /= Void end feature {NONE} -- Implementation add_all (other: ACTION_SEQUENCE [EVENT_DATA]; start_index: INTEGER_32) -- Call on_item_added for all elements in other. -- (from INTERACTIVE_LIST) local cur: CURSOR current_index: INTEGER_32 do current_index := start_index cur := other.cursor from other.start until other.after loop added_item (other.item, current_index); other.forth current_index := current_index + 1 end; other.go_to (cur) end added_item (an_item: like item; item_index: INTEGER_32) -- an_item is has been added. -- (from INTERACTIVE_LIST) do if not in_operation then on_item_added_at (an_item, item_index) end end call_action_list (actions: ARRAYED_LIST [PROCEDURE]) -- Call each action in actions. require actions_not_void: actions /= Void local snapshot: like actions i: INTEGER_32 do if not actions.is_empty then snapshot := actions.twin from i := 1 until i > snapshot.count loop if snapshot @ i /= Void then snapshot.i_th (i).call (Void) end i := i + 1 end end end call_buffer: LINKED_QUEUE [detachable EVENT_DATA] -- Holds calls made while is_paused -- to be executed on resume. do Result := call_buffer_internal if Result = Void then create Result.make call_buffer_internal := Result end end call_buffer_internal: detachable like call_buffer -- Internal storage for call_buffer. dummy_event_data_internal: detachable EVENT_DATA -- See dummy_event_data. empty_actions_internal: detachable like empty_actions -- Internal storage for empty_actions. event_data_names_internal: detachable ARRAY [STRING_8] -- See event_data_names. force_i_th (v: like i_th; pos: INTEGER_32) -- (from ARRAYED_LIST) do if count + 1 > capacity then grow (count + additional_space) end; area_v2.force (v, pos) end in_operation: BOOLEAN -- Are we executing an operation from ARRAYED_LIST? -- (from INTERACTIVE_LIST) insert (v: like item; pos: INTEGER_32) -- Add v at pos, moving subsequent items -- to the right. -- (from ARRAYED_LIST) require -- from ARRAYED_LIST index_small_enough: pos <= count index_large_enough: pos >= 1 do if count + 1 > capacity then grow (count + additional_space) end; area_v2.move_data (pos - 1, pos, count - pos + 1) put_i_th (v, pos) ensure -- from ARRAYED_LIST new_count: count = old count + 1 index_unchanged: index = old index insertion_done: i_th (pos) = v end is_aborted_stack: LINKED_STACK [BOOLEAN] -- item holds abort status of -- innermost of possibly recursive calls. do Result := is_aborted_stack_internal if Result = Void then create Result.make is_aborted_stack_internal := Result end end is_aborted_stack_internal: detachable like is_aborted_stack -- Internal storage for is_aborted_stack. kamikazes: ARRAYED_LIST [like item] -- Used by prune_when_called. do Result := kamikazes_internal if Result = Void then create Result.make (0) kamikazes_internal := Result end end kamikazes_internal: detachable like kamikazes -- Internal storage for kamikazes. name_internal: detachable STRING_8 -- See name. new_filled_list (n: INTEGER_32): like Current obsolete "Use explicit creation instead. See also explanations for `duplicate`. [2018-11-30]" -- New list with n elements. require -- from ARRAYED_LIST n_non_negative: n >= 0 do create Result.make_filled (n) ensure -- from ARRAYED_LIST new_filled_list_not_void: Result /= Void new_filled_list_count_set: Result.is_empty new_filled_list_before: Result.before end not_empty_actions_internal: detachable like not_empty_actions -- Internal storage for not_empty_actions. removed_item (an_item: like item; item_index: INTEGER_32) -- an_item has been removed. -- (from INTERACTIVE_LIST) do if not in_operation then on_item_removed_at (an_item, item_index) end end feature -- Correction Mismatch_information: MISMATCH_INFORMATION -- Original attribute values of mismatched object -- (from MISMATCH_CORRECTOR) once create Result end feature -- Element Change append (s: SEQUENCE [like item]) -- Append a copy of s. -- (from INTERACTIVE_LIST) require -- from SEQUENCE argument_not_void: s /= Void local new_count: INTEGER_32 do new_count := count + s.count if new_count > capacity then grow (new_count) end across if s = Current then s.twin else s end as c loop extend (c.item) end ensure -- from SEQUENCE new_count: count >= old count end extend (v: like item) -- Add v to end. -- Do not move cursor. -- (from INTERACTIVE_LIST) require -- from COLLECTION extendible: extendible do in_operation := True Precursor {ARRAYED_LIST} (v) in_operation := False added_item (v, count) ensure -- from COLLECTION item_inserted: is_inserted (v) end merge_left (other: ACTION_SEQUENCE [EVENT_DATA]) -- Merge other into current structure after cursor -- position. Do not move cursor. Empty other -- (from INTERACTIVE_LIST) require -- from DYNAMIC_CHAIN extendible: extendible not_before: not before other_exists: other /= Void not_current: other /= Current local original_index: INTEGER_32 original_other_count: INTEGER_32 do original_index := index original_other_count := other.count index := index - 1 merge_right (other) index := original_index + original_other_count ensure -- from DYNAMIC_CHAIN new_count: count = old count + old other.count new_index: index = old index + old other.count other_is_empty: other.is_empty end merge_right (other: ACTION_SEQUENCE [EVENT_DATA]) -- Merge other into current structure before cursor -- position. Do not move cursor. Empty other -- (from INTERACTIVE_LIST) require -- from DYNAMIC_CHAIN extendible: extendible not_after: not after other_exists: other /= Void not_current: other /= Current local original_index: INTEGER_32 do original_index := index in_operation := True Precursor {ARRAYED_LIST} (other) in_operation := False update_for_added (original_index + 1) go_i_th (original_index) ensure -- from DYNAMIC_CHAIN new_count: count = old count + old other.count same_index: index = old index other_is_empty: other.is_empty end prune_all (v: like item) -- Remove all occurrences of v. -- (Reference or object equality, -- based on object_comparison.) -- (from INTERACTIVE_LIST) require -- from COLLECTION prunable: prunable local i, nb: INTEGER_32 offset: INTEGER_32 res: BOOLEAN obj_cmp: BOOLEAN l_item: like item l_area: like area do obj_cmp := object_comparison from l_area := area i := 0 nb := count until i = count loop if i < nb - offset then if offset > 0 then l_area.put (l_area.item (i + offset), i) end l_item := l_area.item (i) if obj_cmp then res := v ~ l_item else res := v = l_item end if res then removed_item (l_item, i + Lower) offset := offset + 1 else i := i + 1 end else i := i + 1 end end; l_area.remove_tail (offset) index := count + 1 ensure -- from COLLECTION no_more_occurrences: not has (v) ensure then -- from DYNAMIC_CHAIN is_exhausted: exhausted ensure then -- from ARRAYED_LIST is_after: after ensure then -- from INTERACTIVE_LIST is_after: after end put_front (v: like item) -- Add v to beginning. -- Do not move cursor. -- (from INTERACTIVE_LIST) require -- from DYNAMIC_CHAIN extendible: extendible do in_operation := True Precursor {ARRAYED_LIST} (v) in_operation := False added_item (v, 1) ensure -- from DYNAMIC_CHAIN new_count: count = old count + 1 item_inserted: first = v end put_i_th (v: like i_th; i: INTEGER_32) -- Replace i-th entry, if in index interval, by v. -- (from INTERACTIVE_LIST) require -- from TABLE valid_key: valid_index (i) require -- from TABLE valid_key: valid_index (i) local original_item: like item do original_item := i_th (i) in_operation := True Precursor {ARRAYED_LIST} (v, i) in_operation := False if original_item /= Void then removed_item (original_item, i) end added_item (v, i) ensure -- from TABLE inserted: i_th (i) = v end put_left (v: like item) -- Add v to the left of cursor position. -- Do not move cursor. -- (from INTERACTIVE_LIST) require -- from DYNAMIC_CHAIN extendible: extendible not_before: not before do in_operation := True Precursor {ARRAYED_LIST} (v) in_operation := False added_item (v, index - 1) ensure -- from DYNAMIC_CHAIN new_count: count = old count + 1 new_index: index = old index + 1 end put_right (v: like item) -- Add v to the right of cursor position. -- Do not move cursor. -- (from INTERACTIVE_LIST) require -- from DYNAMIC_CHAIN extendible: extendible not_after: not after do in_operation := True Precursor {ARRAYED_LIST} (v) in_operation := False added_item (v, index + 1) ensure -- from DYNAMIC_CHAIN new_count: count = old count + 1 same_index: index = old index end remove -- Remove current item. -- Move cursor to right neighbor -- (or after if no right neighbor). -- (from INTERACTIVE_LIST) require -- from ACTIVE prunable: prunable writable: writable local original_index: INTEGER_32 original_item: like item do original_index := index original_item := item in_operation := True Precursor {ARRAYED_LIST} in_operation := False removed_item (original_item, original_index) ensure then -- from DYNAMIC_LIST after_when_empty: is_empty implies after ensure then -- from ARRAYED_LIST index: index = old index end remove_right -- Remove item to the right of cursor position. -- Do not move cursor. -- (from INTERACTIVE_LIST) require -- from DYNAMIC_CHAIN right_exists: index < count local item_removed: like item do item_removed := i_th (index + 1) in_operation := True Precursor {ARRAYED_LIST} in_operation := False removed_item (item_removed, index + 1) ensure -- from DYNAMIC_CHAIN new_count: count = old count - 1 same_index: index = old index end replace (v: like item) -- Replace current item by v. -- (from INTERACTIVE_LIST) require -- from ACTIVE writable: writable replaceable: replaceable local original_index: INTEGER_32 original_item: like item do original_index := index original_item := item in_operation := True Precursor {ARRAYED_LIST} (v) in_operation := False removed_item (original_item, original_index) added_item (v, original_index) ensure -- from ACTIVE item_replaced: item = v end update_for_added (start_index: INTEGER_32) -- Call added_item for all items from index start_index to count -- (from INTERACTIVE_LIST) local l_index: INTEGER_32 do l_index := index from go_i_th (start_index) until index > count loop added_item (item, index) forth end go_i_th (l_index) end feature -- Element status has_kamikaze_action (an_action: like item): BOOLEAN -- Return True is an_action is found and will be pruned when called. require has (an_action) do Result := has (an_action) and then kamikazes.has (an_action) end feature -- Event handling empty_actions: ARRAYED_LIST [PROCEDURE] -- Actions to be performed on transition from not is_empty to is_empty. do Result := empty_actions_internal if Result = Void then create Result.make (0) empty_actions_internal := Result end end not_empty_actions: ARRAYED_LIST [PROCEDURE] -- Actions to be performed on transition from is_empty to not is_empty. do Result := not_empty_actions_internal if Result = Void then create Result.make (0) not_empty_actions_internal := Result end end feature -- Iteration do_all (action: PROCEDURE [PROCEDURE [EVENT_DATA]]) -- 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 ARRAYED_LIST) require -- from TRAVERSABLE action_exists: action /= Void do area_v2.do_all_in_bounds (action, 0, area_v2.count - 1) end do_all_with_index (action: PROCEDURE [PROCEDURE [EVENT_DATA], 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 ARRAYED_LIST) require -- from ARRAYED_LIST action_not_void: action /= Void local i, j, nb: INTEGER_32 l_area: like area_v2 do from i := 0 j := Lower nb := count - 1 l_area := area_v2 until i > nb loop action.call ([l_area.item (i), j]) j := j + 1 i := i + 1 end end do_if (action: PROCEDURE [PROCEDURE [EVENT_DATA]]; test: FUNCTION [PROCEDURE [EVENT_DATA], 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 ARRAYED_LIST) require -- from TRAVERSABLE action_exists: action /= Void test_exists: test /= Void do area_v2.do_if_in_bounds (action, test, 0, area_v2.count - 1) end do_if_with_index (action: PROCEDURE [PROCEDURE [EVENT_DATA], INTEGER_32]; test: FUNCTION [PROCEDURE [EVENT_DATA], 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 ARRAYED_LIST) require -- from ARRAYED_LIST action_not_void: action /= Void test_not_void: test /= Void local i, j, nb: INTEGER_32 l_area: like area_v2 do from i := 0 j := Lower nb := count - 1 l_area := area_v2 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 [PROCEDURE [EVENT_DATA], BOOLEAN]): BOOLEAN -- Is test true for all items? -- (from ARRAYED_LIST) require -- from TRAVERSABLE test_exists: test /= Void do Result := area_v2.for_all_in_bounds (test, 0, area_v2.count - 1) ensure then -- from LINEAR empty: is_empty implies Result end there_exists (test: FUNCTION [PROCEDURE [EVENT_DATA], BOOLEAN]): BOOLEAN -- Is test true for at least one item? -- (from ARRAYED_LIST) require -- from TRAVERSABLE test_exists: test /= Void do Result := area_v2.there_exists_in_bounds (test, 0, area_v2.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 -- Retrieval correct_mismatch -- Attempt to correct object mismatch using Mismatch_information. -- (from ARRAYED_LIST) local i: INTEGER_32 do if not Mismatch_information.has ("area_v2") and then attached {SPECIAL [PROCEDURE [EVENT_DATA]]} Mismatch_information.item ("area") as l_area and then attached {INTEGER_32} Mismatch_information.item ("count") as l_count and then attached {BOOLEAN} Mismatch_information.item ("object_comparison") as l_comp and then attached {INTEGER_32} Mismatch_information.item ("index") as l_index then create area_v2.make_empty (l_count) from i := 0 until i = l_count loop area_v2.extend (l_area.item (i)) i := i + 1 end object_comparison := l_comp index := l_index else Precursor end 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 is_aborted_stack_not_void: is_aborted_stack /= Void call_buffer_not_void: call_buffer /= Void valid_state: state = Normal_state or state = Paused_state or state = Blocked_state call_buffer_consistent: state = Normal_state implies call_buffer.is_empty not_empty_actions_not_void: not_empty_actions /= Void empty_actions_not_void: empty_actions /= Void -- from ARRAYED_LIST prunable: prunable starts_from_one: Lower = 1 -- from ANY reflexive_equality: standard_is_equal (Current) reflexive_conformance: conforms_to (Current) -- 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 LIST before_definition: before = (index = 0) after_definition: after = (index = count + 1) -- from CHAIN non_negative_index: index >= 0 index_small_enough: index <= count + 1 off_definition: off = ((index = 0) or (index = count + 1)) isfirst_definition: isfirst = ((not is_empty) and (index = 1)) islast_definition: islast = ((not is_empty) and (index = count)) item_corresponds_to_index: (not off) implies (item = i_th (index)) -- from ACTIVE writable_constraint: writable implies readable empty_constraint: is_empty implies (not readable) and (not writable) -- from READABLE_INDEXABLE consistent_boundaries: Lower <= count or else Lower = count + 1 -- from BILINEAR not_both: not (after and before) before_constraint: before implies off -- from LINEAR after_constraint: after implies off -- from TRAVERSABLE empty_constraint: is_empty implies off note library: "EiffelBase: Library of reusable components for Eiffel." copyright: "Copyright (c) 1984-2018, 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 ACTION_SEQUENCE
Generated by ISE EiffelStudio