This commit is contained in:
Jocelyn Fiat
2024-06-17 09:09:33 +02:00
commit 6dde6425c2
560 changed files with 81728 additions and 0 deletions

6
jj_containers/README.md Normal file
View File

@@ -0,0 +1,6 @@
# jj_containers
This cluster of classes adds useful features to some of the base/elks containers. For example, features 'is\_all\_same' and 'is\_all\_different' are convinient for comparing items in a list.
Classes JJ\_ARRAYED\_STACK and JJ\_LINKED\_STACK grant access to any item in the stack, not just the top item.
Feature 'prune' removes the first occurrence starting from the beginning of a list instead of starting from the cursor position.

18
jj_containers/forum.txt Normal file
View File

@@ -0,0 +1,18 @@
Eiffel Forum License, version 2
1. Permission is hereby granted to use, copy, modify and/or
distribute this package, provided that:
* copyright notices are retained unchanged,
* any distribution of this package, whether modified or not,
includes this license text.
2. Permission is hereby also granted to distribute binary programs
which depend on this package. If the binary program depends on a
modified version of this package, you are encouraged to publicly
release the modified version of this package.
THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT WARRANTY. ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE TO ANY PARTY FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THIS PACKAGE.

154
jj_containers/jj_array.e Normal file
View File

@@ -0,0 +1,154 @@
note
description: "[
This class adds some useful features to the ARRAY class.
]"
author: "Jimmy J. Johnson"
date: "10/27/21"
copyright: "Copyright (c) 2021, Jimmy J. Johnson"
license: "Eiffel Forum v2 (http://www.eiffel.com/licensing/forum.txt)"
class
JJ_ARRAY [G]
inherit
ARRAY [G]
create
make,
make_filled,
make_from_array,
make_from_special,
make_from_cil
convert
to_cil: {NATIVE_ARRAY [G]},
to_special: {SPECIAL [G]},
make_from_cil ({NATIVE_ARRAY [G]})
feature -- Measurement
most_occuring_item: like item
-- The item in Current that occurs the most times.
-- If more than one item occurs the same most number of time, then
-- the then the first of those items.
require
not_empty: not is_empty
local
i, j: INTEGER_32
n, c: INTEGER_32
index: INTEGER_32
do
c := 0
n := 1
from i := 1
until i > count
loop
c := 1
from j := i + 1
until j > count
loop
if at (i) ~ at (j) then
c := c + 1
end
j := j + 1
end
if c > n then
index := i
end
i := i + 1
end
check
index_big_enough: index >= 1
end
check
index_small_enough: index <= count
end
Result := at (index)
end
unique_count: INTEGER_32
-- The number of items in Current that occur only once.
local
i, j: INTEGER_32
n: INTEGER_32
checked: ARRAYED_SET [like item]
duplicate_found: BOOLEAN
v: like item
do
create checked.make (count)
from i := 1
until i > count
loop
n := 1
v := at (i)
duplicate_found := False
if not checked.has (v) then
checked.extend (v)
from j := i + 1
until duplicate_found or else j > count
loop
if at (i) ~ at (j) then
duplicate_found := True
end
j := j + 1
end
end
if not duplicate_found then
Result := Result + 1
end
i := i + 1
end
ensure
result_large_enough: Result >= 0
result_small_enough: Result <= count
all_unique_implication:
end
feature -- Status report
is_all_same: BOOLEAN
-- Are all the elements in Current equivalent?
-- Uses object comparison to check sameness.
local
i: INTEGER
a: G
do
-- Simple check if all are same as the first
-- Assume true until finding a contradiction
a := at (1)
Result := True
from i := 2
until not Result or else i > count
loop
Result := a ~ at (i)
i := i + 1
end
end
is_all_different: BOOLEAN
-- Are all the elements in Current different from each other?
-- Uses object comparison not reference comparison.
local
i, j: INTEGER_32
a: G
do
-- Must check all against each of the others.
-- Assume true until finding two that are the same.
Result := True
from i := 1
until i > count
loop
a := at (i)
from j := i + 1
until not Result or else j > count
loop
Result := not (a ~ at (i))
j := j + 1
end
i := i + 1
end
end
end

89
jj_containers/jj_array2.e Normal file
View File

@@ -0,0 +1,89 @@
note
description: "[
A 2-d array with some additional features, including those added
by class {JJ_ARRAY}.
]"
author: "Jimmy J. Johnson"
date: "10/27/21"
copyright: "Copyright (c) 2021, Jimmy J. Johnson"
license: "Eiffel Forum v2 (http://www.eiffel.com/licensing/forum.txt)"
class
JJ_ARRAY2 [G]
inherit
ARRAY2 [G]
JJ_ARRAY [G]
rename
make as array_make,
item as array_item,
put as array_put,
force as array_force,
resize as array_resize,
wipe_out as array_wipe_out,
make_filled as array_make_filled
export
{NONE}
array_make, array_force,
array_resize, array_wipe_out, make_from_array,
array_make_filled, make_from_special, make_from_cil,
remove_head, remove_tail, keep_head, keep_tail,
grow, conservative_resize, conservative_resize_with_default,
automatic_grow
{ARRAY2}
array_put, array_item
{ANY}
copy, is_equal, area, to_c
end
create
make,
make_filled
feature -- Query
occurrences_per_row (a_item: G; a_row: INTEGER_32): INTEGER_32
-- The number of times `a_item' appears in `a_row'.
require
row_index_big_enough: a_row >= 1
row_index_small_enough: a_row <= height
local
i: INTEGER
do
from i := 1
until i > width
loop
if a_item ~ item (a_row, i) then
Result := Result + 1
end
i := i + 1
end
ensure
result_large_enough: Result >= 0
result_small_enough: Result <= width
end
occurrences_per_column (a_item: G; a_column: INTEGER_32): INTEGER_32
-- The number of times `a_item' appears in `a_column'.
require
column_index_big_enough: a_column >= 1
column_index_small_enough: a_column <= width
local
i: INTEGER
do
from i := 1
until i > height
loop
if a_item ~ item (i, a_column) then
Result := Result + 1
end
i := i + 1
end
ensure
result_large_enough: Result >= 0
result_small_enough: Result <= height
end
end

View File

@@ -0,0 +1,148 @@
note
description: "[
An {ARRAYED_LIST} but with feature `prune' changed to remove the first
occurance of an item after the *beginning* of the list instead of after
the current cursor postion.
]"
author: "Jimmy J. Johnson"
date: "10/27/21"
copyright: "Copyright (c) 2021, Jimmy J. Johnson"
license: "Eiffel Forum v2 (http://www.eiffel.com/licensing/forum.txt)"
class
JJ_ARRAYED_LIST [G]
inherit
ARRAYED_LIST [G]
rename
replace as list_replace,
after as is_after, -- I just don't like the original names
before as is_before,
full as is_full
redefine
prune, -- to prune from beginning of list
array_item
select
prune
end
ARRAYED_LIST [G]
rename
prune as prune_ise, -- to keep the original version
replace as list_replace,
after as is_after,
before as is_before,
full as is_full
redefine
array_item
end
create
make, make_filled
feature -- Access
as_set: JJ_ARRAYED_SET [G]
-- The set of items in Current.
local
i: INTEGER
do
create Result.make (count)
from i := 1
until i > count
loop
Result.extend (i_th (i))
i := i + 1
end
end
feature -- Basic operations
prune (a_item: like item)
-- Remove first occurance of `a_item' starting at the first item.
-- Move cursor to right neighbor.
-- (or `after' if no right neighbor or if `a_item' does not occur).
do
start
Precursor {ARRAYED_LIST} (a_item)
end
replace (a_item, a_new_item: like item)
-- Remove `a_item' and insert `a_new_item'.
require
item_exists: a_item /= Void
new_item_exists: a_new_item /= Void
has_item: has (a_item)
local
i: INTEGER
do
i := index
start
search (a_item)
check
object_found: object_comparison implies a_item ~ item
item_found: not object_comparison implies a_item = item
-- because of pecondition "has_item"
end
list_replace (a_new_item)
go_i_th (i)
ensure
has_new_item: has (a_new_item)
count_same: count = old count
end
feature -- Status report
is_all_same: BOOLEAN
-- Are all the elements in Current equivalent?
-- Uses object comparison to check sameness.
local
i: INTEGER_32
a: G
do
-- Simple check if all are same as the first.
-- Assume true until finding a contradiction
a := at (i)
Result := True
from i := 2
until not Result or else i > count
loop
Result := a ~ at (i)
i := i + 1
end
end
is_all_different: BOOLEAN
-- Are all the elements in Current different from each other?
-- Uses object comparison not reference comparison
local
i, j: INTEGER_32
a: G
do
-- Must check all against each of the others.
-- Assume true until finding two that are the same.
Result := True
from i := 1
until not Result or else i > count
loop
from j := i + 1
until not Result or else j > count
loop
Result := not (a ~ at (i))
j := j + 1
end
i := i + 1
end
end
feature {NONE} -- Implementation
array_item (i: INTEGER): like item
-- Entry at index `i', if in index interval.
-- Redefined to make result type "like item" instead of type G.
do
Result := Precursor {ARRAYED_LIST} (i)
end
end

View File

@@ -0,0 +1,65 @@
note
description: "[
ARRAYED_SET with added feature for replacing an existing item.
]"
author: "Jimmy J. Johnson"
date: "10/27/21"
copyright: "Copyright (c) 2021, Jimmy J. Johnson"
license: "Eiffel Forum v2 (http://www.eiffel.com/licensing/forum.txt)"
class
JJ_ARRAYED_SET [G]
inherit
ARRAYED_SET [G]
rename
replace as list_replace,
after as is_after,
before as is_before,
full as is_full
export
{ANY}
for_all,
there_exists,
capacity,
i_th
undefine
make_from_iterable,
-- put,
prune,
array_item,
is_inserted,
changeable_comparison_criterion -- Possibly allows duplicates
select
put
end
JJ_ARRAYED_LIST [G]
rename
has as has alias "∋"
undefine
put,
sequence_put,
extend,
force
-- changeable_comparison_criterion
redefine
replace
end
create
make, make_filled
feature -- Basic operations
replace (a_item, a_new_item: like item)
-- If `a_new_item' is not in Current and `a_item' is, remove
-- `a_item' and insert `a_new_item'.
do
if has (a_item) and then not has (a_new_item) then
Precursor {JJ_ARRAYED_LIST} (a_item, a_new_item)
end
end
end

View File

@@ -0,0 +1,45 @@
note
description: "[
An {ARRAYED_STACK} which allows inspection of any item, not just the
top one. Items are still added to and removed from the top.
]"
author: "Jimmy J. Johnson"
date: "10/27/21"
copyright: "Copyright (c) 2021, Jimmy J. Johnson"
license: "Eiffel Forum v2 (http://www.eiffel.com/licensing/forum.txt)"
class
JJ_ARRAYED_STACK [G]
inherit
ARRAYED_STACK [G]
export
{ANY}
i_th,
first,
last,
valid_index,
do_all,
do_all_with_index,
do_if,
do_if_with_index,
for_all,
there_exists
redefine
array_item
end
create
make, make_filled
feature {NONE} -- Implementation
array_item (i: INTEGER): like item
-- Entry at index `i', if in index interval.
-- Redefined to make result type "like item" instead of type G.
do
Result := Precursor {ARRAYED_STACK} (i)
end
end

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-21-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-21-0 http://www.eiffel.com/developers/xml/configuration-1-21-0.xsd" name="jj_containers" uuid="BACF2C54-C8D8-4C99-826C-D73A3B069BF6" library_target="jj_containers">
<target name="jj_containers">
<root all_classes="true"/>
<capability>
<catcall_detection support="none"/>
<void_safety support="all" use="all"/>
</capability>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<cluster name="jj_containers" location=".\" recursive="true">
<file_rule>
<exclude>/.git$</exclude>
<exclude>/.svn$</exclude>
<exclude>/CVS$</exclude>
<exclude>/EIFGENs$</exclude>
<exclude>/demo$</exclude>
<exclude>/docs$</exclude>
</file_rule>
</cluster>
</target>
</system>

View File

@@ -0,0 +1,34 @@
note
description: "[
An arrayed list that cannot change size.
]"
author: "Jimmy J. Johnson"
date: "10/27/21"
copyright: "Copyright (c) 2021, Jimmy J. Johnson"
license: "Eiffel Forum v2 (http://www.eiffel.com/licensing/forum.txt)"
class
JJ_FIXED_ARRAY [G]
inherit
FIXED [G]
rename
full as is_full
undefine
copy,
is_equal
end
JJ_ARRAYED_LIST [G]
undefine
is_full,
resizable
end
create
make,
make_filled
end

View File

@@ -0,0 +1,35 @@
note
description: "[
A set implemented as an array that cannot resize.
]"
author: "Jimmy J. Johnson"
date: "10/27/21"
copyright: "Copyright (c) 2021, Jimmy J. Johnson"
license: "Eiffel Forum v2 (http://www.eiffel.com/licensing/forum.txt)"
class
JJ_FIXED_SET [G]
inherit
FIXED [G]
rename
has as has alias "∋",
full as is_full
undefine
copy,
is_equal,
changeable_comparison_criterion
end
JJ_ARRAYED_SET [G]
undefine
is_full,
resizable
end
create
make,
make_filled
end

View File

@@ -0,0 +1,47 @@
note
description: "[
A {LINKED_STACK} which allows inspection of any item, not just the
top one. Items are still added to and removed from the top.
]"
author: "Jimmy J. Johnson"
date: "10/27/21"
copyright: "Copyright (c) 2021, Jimmy J. Johnson"
license: "Eiffel Forum v2 (http://www.eiffel.com/licensing/forum.txt)"
class
JJ_LINKED_STACK [G]
inherit
LINKED_STACK [G]
export {ANY}
i_th,
first,
last,
valid_index
redefine
i_th,
at
end
create
make
feature -- Access
i_th alias "[]" (a_index: INTEGER): like item
-- Redefined to anchor to item.
do
Result := Precursor {LINKED_STACK} (a_index)
end
feature {NONE} -- Implementation
at alias "@" (i: INTEGER): like item
-- Entry at index `i', if in index interval.
-- Redefined to make result type "like item" instead of type G.
do
Result := Precursor {LINKED_STACK} (i)
end
end

View File

@@ -0,0 +1,48 @@
note
description: "[
A priority queue implemented as sorted lists, but giving
the minimum value instead of, like Eiffel Software's class,
the maximum value.
]"
author: "Jimmy J. Johnson"
date: "11/11/21"
copyright: "Copyright (c) 2021, Jimmy J. Johnson"
license: "Eiffel Forum v2 (http://www.eiffel.com/licensing/forum.txt)"
class
JJ_MINIMUM_PRIORITY_QUEUE [G -> COMPARABLE]
inherit
LINKED_PRIORITY_QUEUE [G]
redefine
item,
remove
end
create
make,
make_from_iterable
create {JJ_MINIMUM_PRIORITY_QUEUE}
make_sublist
feature -- Access
item: G
-- Item at bottom of queue (i.e. smallest value)
do
Result := i_th (1)
end
feature -- Removal
remove
-- Remove item of highest value.
do
go_i_th (1)
Precursor {LINKED_PRIORITY_QUEUE}
go_i_th (1)
end
end

View File

@@ -0,0 +1,264 @@
note
description: "[
An array whose items *can* be ordered by a total-ordered relationship.
Feature `set_ordered' causes `extend' to place an item into the array
at its proper sort order position.
Feature `prune' is redefined in {JJ_ARRAYED_LIST} to remove the first
occurrence of an item at or after the beginning of the list, not after
the current position, as in {ARRAYED_LIST}.
]"
author: "Jimmy J. Johnson"
date: "10/27/21"
copyright: "Copyright (c) 2021, Jimmy J. Johnson"
license: "Eiffel Forum v2 (http://www.eiffel.com/licensing/forum.txt)"
class
JJ_SORTABLE_ARRAY [G -> COMPARABLE]
inherit
JJ_ARRAYED_LIST [G]
export
{NONE}
force -- to trap a design error temporarily
redefine
put,
extend,
replace,
has,
is_inserted
end
create
make, make_filled
feature -- Status report
is_inserting_ordered: BOOLEAN
-- Should items be inserted in their ordered position?
-- The default is to add items at the end of the list; the list
-- can be sorted later.
is_sorted: BOOLEAN
-- Is the structure sorted?
local
c: CURSOR
prev: like item
do
Result := True
if count > 1 then
from
c := cursor
start
check not off end
prev := item
forth
until
is_after or not Result
loop
Result := (prev <= item)
prev := item
forth
end
go_to (c)
end
end
feature -- Status setting
set_ordered
-- Sort Current and then ensure future insertions place items
-- at their proper position based on a total order relation.
do
sort
is_inserting_ordered := True
ensure
is_ordered: is_inserting_ordered
is_sorted: is_sorted
end
set_unordered
-- Make future insertions place items at the end of the list.
-- This is the default.
do
is_inserting_ordered := False
ensure
not_ordered: not is_inserting_ordered
end
feature -- Query
has (a_item: like item): BOOLEAN
-- Does current include `v'?
do
if object_comparison then
-- can use the binary search
Result := seek_position (a_item).was_found
else
-- Must check references; the binary search does not;
-- it uses `is_less' which compares objects.
Result := Precursor (a_item)
end
end
seek_position (a_item: like item): TUPLE [position: INTEGER; was_found: BOOLEAN]
-- The position of `a_item' in Current or the position where
-- it would be inserted. Sets `was_found' if `a_item' was
-- in Current.
local
pos: INTEGER
low, mid, high: INTEGER
found: BOOLEAN
c: CURSOR
do
if is_inserting_ordered then
-- do a binary search
check
is_sorted: is_sorted
-- because `is_inserting_ordered' keeps Current sorted.
end
from
low := 1
high := count
until found or else (low > high)
loop
mid := (low + high) // 2
if a_item < i_th (mid) then
high := mid - 1
elseif a_item > i_th (mid) then
low := mid + 1
else
found := True
end
end
if found then
-- Account for duplicates
from pos := mid
until pos > count - 1 or else i_th (pos + 1) > a_item
loop
pos := pos + 1
end
elseif count = 0 then
pos := 1
elseif a_item < i_th (mid) then
pos := mid
else
pos := mid + 1
end
else
-- perform a linear search
c := cursor
start
search (a_item)
pos := index
if is_after then
found := False
else
found := True
end
go_to (c)
end
Result := [pos, found]
end
is_inserted (a_item: like item): BOOLEAN
-- Was `a_item' inserted into Current?
-- Redefined because {ARRAYED_LIST} always extends items at the
-- end; that is not necessarily the case for this class.
do
Result := has (a_item)
end
feature -- Basic operations
extend (a_item: like item)
-- Put `a_item' into Current at `seek_position'.
local
i: INTEGER
do
if is_empty or else not is_inserting_ordered then
-- add to end
Precursor {JJ_ARRAYED_LIST} (a_item)
else
i := seek_position (a_item).position
if i > count then
-- Add at end
Precursor {JJ_ARRAYED_LIST} (a_item)
else
-- Add at ordered position.
insert (a_item, i)
end
end
ensure then
still_sorted: is_inserting_ordered implies is_sorted
end
put (a_item: like item)
-- Put `a_item' into Current at `seek_position'.
-- Same as extend.
do
extend (a_item)
end
replace (a_item, a_new_item: like item)
-- Remove `a_item' and insert `a_new_item'.
-- Redefined to ensure `a_new_item' is inserted into the proper
-- place.
do
prune (a_item)
extend (a_new_item)
end
sort
-- Sort all items.
-- Has O(`count' * log (`count')) complexity.
--| Uses comb-sort (BYTE February '91)
-- Adapted from ISE's feature from {SORTED_TWO_WAY_LIST}.
local
no_change: BOOLEAN
gap: INTEGER
i, j: INTEGER
left_v, v: like item
do
if not is_empty then
from
gap := count * 10 // 13
until
gap = 0
loop
from
no_change := False
i := 1 + gap
until
no_change
loop
no_change := True
from
j := 1 -- first element index
until
i > count
loop
left_v := i_th (j)
v := i_th (i) -- item at first index + gap
if v < left_v then
-- Swap `left_v' with `v'
no_change := False
put_i_th (left_v, i)
put_i_th (v, j)
end
j := j + 1
i := i + 1
end
end
gap := gap * 10 // 13
end
end
ensure
is_sorted: is_sorted
end
invariant
is_inserting_ordered_implication: is_inserting_ordered implies is_sorted
end

View File

@@ -0,0 +1,33 @@
note
description: "[
An array that can be sorted and cannot resize.
]"
author: "Jimmy J. Johnson"
date: "10/27/21"
copyright: "Copyright (c) 2021, Jimmy J. Johnson"
license: "Eiffel Forum v2 (http://www.eiffel.com/licensing/forum.txt)"
class
JJ_SORTABLE_FIXED_ARRAY [G -> COMPARABLE]
inherit
FIXED [G]
rename
full as is_full
undefine
copy,
is_equal
end
JJ_SORTABLE_ARRAY [G]
undefine
is_full,
resizable
end
create
make,
make_filled
end

View File

@@ -0,0 +1,34 @@
note
description: "[
An array that can be sorted and cannot resize.
]"
author: "Jimmy J. Johnson"
date: "10/27/21"
copyright: "Copyright (c) 2021, Jimmy J. Johnson"
license: "Eiffel Forum v2 (http://www.eiffel.com/licensing/forum.txt)"
class
JJ_SORTABLE_FIXED_SET [G -> COMPARABLE]
inherit
FIXED [G]
rename
has as has alias "∋",
full as is_full
undefine
changeable_comparison_criterion,
copy,
is_equal
end
JJ_SORTABLE_SET [G]
undefine
is_full,
resizable
end
create
make, make_filled
end

View File

@@ -0,0 +1,76 @@
note
description: "[
A set, implemented as an array, whose items *can* be ordered based on
a total-order relationship.
Feature `set_ordered' causes `extend' to place an item into the array
at its proper sort-order position.
Feature `prune' is redefined in {JJ_ARRAYED_LIST} to remove the first
occurrence of an item at or after the beginning of the list, not after
the current position, as in {ARRAYED_LIST}.
]"
author: "Jimmy J. Johnson"
date: "10/27/21"
copyright: "Copyright (c) 2021, Jimmy J. Johnson"
license: "Eiffel Forum v2 (http://www.eiffel.com/licensing/forum.txt)"
class
JJ_SORTABLE_SET [G -> COMPARABLE]
inherit
JJ_ARRAYED_SET [G]
export
{ANY}
for_all,
there_exists,
capacity,
i_th
undefine
put,
sequence_put,
prune,
array_item,
is_inserted,
has
redefine
extend
select
put,
extend
end
JJ_SORTABLE_ARRAY [G]
rename
has as has alias "∋",
extend as jj_sl_extend
export {ANY}
i_th
undefine
changeable_comparison_criterion,
replace
end
create
make, make_filled
feature -- Basic operations
extend (a_item: like item)
-- Put `a_item' into Current at `seek_position' if
-- not alread in the array.
local
i: INTEGER
do
if not has (a_item) then
i := seek_position (a_item).position
if i > count then
-- add `a_item' at the end
force (a_item)
else
-- add `a_item' at its ordered position
insert (a_item, i)
end
end
end
end