home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 3
/
AACD03.BIN
/
AACD
/
Programming
/
sofa
/
archive
/
SmallEiffel.lha
/
SmallEiffel
/
lib_std
/
array.e
< prev
next >
Wrap
Text File
|
1999-06-05
|
9KB
|
316 lines
-- This file is free software, which comes along with SmallEiffel. This
-- software is distributed in the hope that it will be useful, but WITHOUT
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-- FITNESS FOR A PARTICULAR PURPOSE. You can modify it as you want, provided
-- this header is kept unaltered, and a notification of the changes is added.
-- You are allowed to redistribute it and sell it, alone or as a part of
-- another product.
-- Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
-- Dominique COLNET and Suzanne COLLIN - colnet@loria.fr
-- http://SmallEiffel.loria.fr
--
class ARRAY[E]
--
-- General purpose resizable ARRAYs.
--
inherit ARRAYED_COLLECTION[E];
creation make, with_capacity, from_collection
feature
lower: INTEGER;
-- Lower index bound.
feature -- Creation and Modification :
make(minindex, maxindex: INTEGER) is
-- Make array with range [`minindex' .. `maxindex'].
-- When `maxindex' = `minindex' - 1, the array is empty.
require
minindex -1 <= maxindex
local
needed: INTEGER;
do
lower := minindex;
upper := maxindex;
needed := maxindex - minindex + 1;
if needed > 0 then
if capacity < needed then
storage := storage.calloc(needed);
capacity := needed;
else
clear_all;
end;
end;
ensure
lower = minindex;
upper = maxindex;
all_cleared
end;
with_capacity(needed_capacity, low: INTEGER) is
-- Create an empty array with `capacity' initialized
-- at least to `needed_capacity' and `lower' set to `low'.
require
needed_capacity >= 0
do
if capacity < needed_capacity then
storage := storage.calloc(needed_capacity);
capacity := needed_capacity;
end;
lower := low;
upper := low - 1;
ensure
empty;
needed_capacity <= capacity;
lower = low
end;
feature -- Modification :
resize(minindex, maxindex: INTEGER) is
-- Resize the array. No elements will be lost in the
-- intersection of [old `lower' .. old `upper'] and
-- [`minindex' .. `maxindex'].
-- New positions are initialized with appropriate
-- default values.
require
minindex -1 <= maxindex
local
needed, offset, intersize: INTEGER;
do
needed := maxindex - minindex + 1;
if needed > 0 then
if needed > capacity then
if capacity = 0 then
storage := storage.calloc(needed);
capacity := needed;
else
storage := storage.realloc(capacity, needed);
capacity := needed;
end;
end;
offset := lower - minindex;
intersize := maxindex.min(upper) - minindex.max(lower) + 1;
if intersize > 0 then
if offset = 0 then
if intersize < needed then
storage.clear(intersize, needed - 1);
end;
elseif offset < 0 then
storage.move(-offset, intersize - offset - 1, offset);
if intersize < needed then
storage.clear(intersize, needed - 1);
end;
else
storage.move(0, intersize - 1, offset);
storage.clear(0, offset - 1);
if intersize + offset < needed then
storage.clear(intersize + offset, needed - 1);
end;
end;
else
storage.clear(0, needed - 1);
end;
end;
lower := minindex;
upper := maxindex;
end;
feature
sub_array(low, up: INTEGER): like Current is
local
i: INTEGER;
do
from
!!Result.with_capacity(up - low + 1,low);
Result.set_upper(up);
i := low;
until
i > up
loop
Result.put(item(i),i);
i := i + 1;
end;
ensure then
Result.lower = low;
end;
feature -- Implementation of deferred :
count: INTEGER is
do
Result := upper - lower + 1;
end;
item, infix "@" (index: INTEGER): E is
do
Result := storage.item(index - lower);
end;
put(element: like item; index: INTEGER) is
do
storage.put(element,index - lower);
end;
force(element: like item; index: INTEGER) is
-- Put `element' at position `index'. Current is
-- resized if `index' is not inside current bounds.
-- New bounds are initialized with default values.
require else
true
do
if upper < index then
resize(lower,index);
elseif index < lower then
resize(index,upper);
end;
put(element,index);
end;
copy(other: like Current) is
local
needed_capacity: INTEGER;
do
lower := other.lower;
upper := other.upper;
needed_capacity := upper - lower + 1;
if capacity < needed_capacity then
capacity := needed_capacity;
storage := storage.calloc(capacity);
end;
if needed_capacity > 0 then
storage.copy_from(other.storage,needed_capacity - 1);
end;
end;
set_all_with(v: like item) is
do
storage.set_all_with(v,upper - lower);
end;
remove_first is
do
storage.remove_first(upper - lower);
lower := lower + 1;
ensure then
upper = old upper;
end;
remove(index: INTEGER) is
do
storage.remove(index - lower,upper - lower);
upper := upper - 1;
end;
clear is
do
upper := lower - 1;
ensure then
capacity = old capacity
end;
add_first(element: like item) is
do
if upper < lower then
add_last(element);
else
add_last(element);
move(lower,upper - 1,1);
put(element,lower);
end;
end;
add_last(element: like item) is
local
new_capacity: INTEGER;
do
if capacity < count + 1 then
if capacity = 0 then
capacity := 16;
storage := storage.calloc(capacity);
else
new_capacity := 2 * capacity;
storage := storage.realloc(capacity,new_capacity);
capacity := new_capacity;
end;
end;
upper := upper + 1;
put(element,upper);
end;
from_collection(model: COLLECTION[like item]) is
local
i, up: INTEGER;
do
from
with_capacity(model.count,model.lower);
i := model.lower;
up := model.upper;
upper := up;
until
i > up
loop
put(model.item(i),i);
i := i + 1;
end;
ensure then
lower = model.lower;
upper = model.upper
end;
all_cleared: BOOLEAN is
do
Result := storage.all_cleared(upper - lower);
end;
nb_occurrences(element: like item): INTEGER is
do
Result := storage.nb_occurrences(element,upper - lower);
end;
fast_nb_occurrences(element: like item): INTEGER is
do
Result := storage.fast_nb_occurrences(element,upper - lower);
end;
index_of(element: like item): INTEGER is
do
Result := lower + storage.index_of(element,upper - lower);
end;
fast_index_of(element: like item): INTEGER is
do
Result := lower + storage.fast_index_of(element,upper - lower);
end;
is_equal(other: like Current): BOOLEAN is
do
if Current = other then
Result := true;
elseif lower = other.lower and then upper = other.upper then
Result := storage.memcmp(other.storage,count);
end;
end;
slice(low, up: INTEGER): like Current is
local
i: INTEGER;
do
from
i := low;
!!Result.with_capacity(up - low + 1,lower);
until
i > up
loop
Result.add_last(item(i));
i := i + 1;
end;
end;
end -- ARRAY[E]