Class ARRAY
Visual Eiffel 3.2 beta
indexing
title : "Sequences of values, all of the same type or",
"of a conforming one, accessible through integer indices",
"in a contiguous interval.";
cluster : "%VE_Lib%\Kernel";
project : "Eiffel Kernel Library";
copyright : "Object Tools, 1996-1998";
original : 26,Apr,96;
version : 1.0;
last_change : no_changes;
key : ELKS;
done_at : "Object Tools (info@object-tools.com)";
extrnl_name : "array.e"
-----------------------------------------------------------------------------
class ARRAY [G]
-----------------------------------------------------------------------------
inherit
------------------------------------------------------------------------- ANY
ANY
redefine
is_equal, copy
end
-----------------------------------------------------------------------------
creation {ANY}
make, make_from_array
-----------------------------------------------------------------------------
feature -- Creation
------------------------------------------------------------------------ make
make (minindex, maxindex : INTEGER) is
-- Allocate array; set index interval to 'minindex' .. 'maxindex';
-- set all values to default.
-- (Make array empty if 'minindex' > 'maxindex')
require
valid_indices : (minindex <= maxindex) or (minindex = maxindex + 1)
do
c_array_make (maxindex - minindex + 1, minindex);
ensure
no_count : (minindex > maxindex) implies (count = 0);
count_constraint : (minindex <= maxindex) implies
(count = maxindex - minindex + 1)
end; -- make
------------------------------------------------------------- make_from_array
make_from_array (arr : ARRAY [G]) is
-- Initialize from the items of 'arr'.
-- (Useful in proper descendants of class ARRAY,
-- to initialize an array-like object from a manifest array)
require
array_exists: arr /= Void
do
c_array_make (arr.upper - arr.lower + 1, arr.lower);
c_array_copy (arr);
end; -- make_from_array
-----------------------------------------------------------------------------
feature -- Access
----------------------------------------------------------------------- entry
entry (i : INTEGER) : G is
-- Entry at index 'i', if in index interval.
-- (Redefinable synonym for 'item' and 'infix "@"')
require
good_key : valid_index (i)
external "CWC"
alias "_ARRAY_item"
end; -- entry
------------------------------------------------------------- infix "@", item
frozen infix "@", item (i : INTEGER) : G is
-- Entry at index 'i', if in index interval
require
good_key : valid_index (i)
external "CWC"
alias "_ARRAY_item"
end; -- infix "@", item
-----------------------------------------------------------------------------
feature {NONE} -- Implementation
------------------------------------------------------------------------ area
frozen area : POINTER;
-- in fact it's pointer to array's data
-- (for internal use only)
---------------------------------------------------------------------- b_area
frozen b_area : POINTER;
-- in fact it's pointer to array's data
-- (for internal use only)
-----------------------------------------------------------------------------
feature -- Measurement
----------------------------------------------------------------------- count
frozen count : INTEGER;
-- Eiffel number of items in the array
----------------------------------------------------------------------- lower
frozen lower : INTEGER;
-- Eiffel lower index of the array
----------------------------------------------------------------------- upper
upper : INTEGER is
-- Maximum index
do
Result := lower + count - 1;
end; -- upper
-----------------------------------------------------------------------------
feature -- Comparison
-------------------------------------------------------------------- is_equal
is_equal (other : like Current) : BOOLEAN is
-- Is array made of the same items as 'other' ?
-- (Redefined from GENERAL)
do
if count = other.count and then lower = other.lower then
Result := c_array_is_equal (other);
end; -- if
end; -- is_equal
-----------------------------------------------------------------------------
feature -- Status report
----------------------------------------------------------------- valid_index
valid_index (i : INTEGER) : BOOLEAN is
-- Is 'i' within the bounds of the array ?
do
Result := i >= lower and then i <= upper;
end; -- valid_index
-----------------------------------------------------------------------------
feature -- Element change
----------------------------------------------------------------------- enter
enter (v : G; i : INTEGER) is
-- Replace 'i-th' entry, if in index interval, by 'v'.
-- (Redefinable synonym for 'put')
require
good_key : valid_index (i)
do
put (v, i);
ensure
inserted : item (i) = v
end; -- enter
----------------------------------------------------------------------- force
force (v : G; i : INTEGER) is
-- Assign item 'v' to 'i-th' entry.
-- Always applicable: resize the array if 'i' falls out of
-- currently defined bounds; preserve existing items
do
if upper < lower then
resize (i, i);
elseif i < lower then
resize (i, upper);
elseif i > upper then
resize (lower, i);
end; -- if
put (v, i);
ensure
inserted : item (i) = v
higher_count : count >= old count
end; -- force
------------------------------------------------------------------------- put
frozen put (v : G; i : INTEGER) is
-- Replace 'i-th' entry, if in index interval, by 'v'
require
good_key : valid_index (i)
do
c_array_put (i, v);
ensure
inserted : item (i) = v
end; -- put
---------------------------------------------------------------------- append
append (other : ARRAY [G]) is
-- Append all items of 'other', if not void, at end
local
old_count : INTEGER
cnt : INTEGER
oth : ARRAY [G]
do
if other /= Void then
cnt := other.count
if cnt > 0 then
oth := other
if oth = Current then
oth := clone (oth)
end; -- if
old_count := count;
c_array_resize (count + cnt, lower);
array_mem_copy (to_c + old_count * size_item, oth.to_c, cnt * size_item)
end; -- if
end; -- if
ensure
higher_count : count >= old count
end; -- append
-----------------------------------------------------------------------------
feature -- Resizing
---------------------------------------------------------------------- resize
resize (minindex, maxindex : INTEGER) is
-- Rearrange array so that it can accommodate
-- indices down to 'minindex' and up to 'maxindex'.
-- Do not lose any previously entered item
require
good_indices : (minindex <= maxindex) or (minindex = maxindex + 1)
do
c_array_resize (maxindex - minindex + 1, minindex);
ensure
minindex_included : lower <= minindex
maxindex_included : upper >= maxindex
end; -- resize
-----------------------------------------------------------------------------
feature -- Conversion
------------------------------------------------------------------------ to_c
to_c : POINTER is
-- Address of actual sequence of values,
-- for passing to external (non-Eiffel) routines
external "CWC"
alias "_ARRAY_to_external"
end; -- to_c
---------------------------------------------------------------------- from_c
from_c (ptr : POINTER; cnt : INTEGER) is
-- Creates array from its external representation
require
non_void_pointer : ptr /= default_pointer;
valid_count : cnt >= 0
do
make (1, cnt)
c_og_move( Current.to_external, 1, ptr, count * size_item )
end; -- from_c
-----------------------------------------------------------------------------
feature -- Duplication
------------------------------------------------------------------------ copy
copy (other : like Current) is
-- Reinitialize by copying all the items of 'other'.
-- (This is also used by 'clone'.)
-- (From GENERAL)
do
c_array_copy (other);
end; -- copy
-----------------------------------------------------------------------------
feature -- Eiffel/S 1.3 compatibility
----------------------------------------------------------------- to_external
to_external : POINTER is
-- Pointer to actual storage area
obsolete "Eiffel/S 1.3 compatibility"
external "CWC"
alias "_ARRAY_to_external"
end; -- to_external
------------------------------------------------------------------------ size
size : INTEGER is
-- Length of index interval
obsolete "Eiffel/S 1.3 compatibility"
do
Result := count;
end; -- size
--------------------------------------------------------------------- reindex
reindex (new_lower : INTEGER) is
-- Change index interval so that
-- it starts at 'new_lower'.
-- No elements will be lost
obsolete "Eiffel/S 1.3 compatibility"
external "CWC"
alias "_ARRAY_reindex"
ensure
bounds_adjusted : lower = new_lower and then
upper = new_lower + count - 1
end; -- reindex
------------------------------------------------------------------- clear_all
clear_all is
-- Set all items to default values
obsolete "Eiffel/S 1.3 compatibility"
external "CWC"
alias "_ARRAY_clear_all"
end; -- clear_all
---------------------------------------------------------------------- insert
insert (element : G; index : INTEGER) is
-- Insert 'element' after position 'index'.
-- Element at position 'upper' will be lost!
-- Note: Insertion is AFTER 'index'!
obsolete "Eiffel/S 1.3 compatibility"
require
inside_bounds : index >= lower - 1 and then index < upper
local
real_index : INTEGER;
do
real_index := index + 1;
if real_index /= upper then
move (real_index, upper - 1, 1);
end; -- if
put (element, real_index);
end; -- insert
------------------------------------------------------------------------ move
move (lower_index, upper_index, distance : INTEGER) is
-- Move Range 'lower_index' .. 'upper_index' by 'distance'
-- positions. Neg. distance moves towards lower indices.
-- Free places get default values
obsolete "Eiffel/S 1.3 compatibility"
require
non_empty_range : lower_index <= upper_index;
inside_bounds_before : lower <= lower_index
and then
upper_index <= upper;
inside_bounds_after : lower <= lower_index + distance
and then
upper_index + distance <= upper
do
c_move (lower_index - lower, upper_index - lower_index + 1, distance);
end; -- move
---------------------------------------------------------------------- remove
remove (index : INTEGER) is
-- Remove element at position 'index'.
-- Elements after 'index' will move
-- one position left (=towards lower indices).
-- Element at position 'upper' is set to default value.
-- Note: Position 'upper' will be set to
-- appropriate default value
obsolete "Eiffel/S 1.3 compatibility"
require
inside_bounds : index >= lower and then index <= upper
do
if index /= upper then
move (index + 1, upper, -1);
end; -- if
c_put_default (upper);
end; -- remove
-------------------------------------------------------------------- wipe_out
wipe_out is
-- Empty the array, discard all items
obsolete "Eiffel/S 1.3 compatibility"
external "CWC"
alias "_ARRAY_wipe_out"
end; -- wipe_out
----------------------------------------------------------------------- empty
empty : BOOLEAN is
-- Is array empty ?
obsolete "Eiffel/S 1.3 compatibility"
do
Result := count = 0;
end; -- empty
----------------------------------------------------------------- all_cleared
all_cleared : BOOLEAN is
-- Are all items set to default values ?
obsolete "Eiffel/S 1.3 compatibility"
external "CWC"
alias "_ARRAY_all_cleared"
end; -- all_cleared
-----------------------------------------------------------------------------
feature {NONE} -- Implementation
---------------------------------------------------------------------- pcount
frozen pcount : INTEGER;
-- Physical number of item in the array
------------------------------------------------------------------- size_item
frozen size_item : INTEGER;
-- Size of array item
---------------------------------------------------------------------- c_move
c_move (lower_index, number, distance : INTEGER) is
-- Eiffel/S 1.3 compatibility
external "CWC"
alias "_ARRAY_move"
end; -- c_move
--------------------------------------------------------------- c_put_default
c_put_default (index : INTEGER) is
-- Eiffel/S 1.3 compatibility
external "CWC"
alias "_ARRAY_put_default"
end; -- c_put_default
---------------------------------------------------------------- c_array_make
c_array_make (cnt : INTEGER; lwr : INTEGER) is
external "CWC"
alias "_ARRAY_make"
end; -- c_array_make
---------------------------------------------------------------- c_array_copy
c_array_copy (other : ARRAY [G]) is
external "CWC"
alias "_ARRAY_copy"
end; -- c_array_copy
------------------------------------------------------------ c_array_is_equal
c_array_is_equal (other : ARRAY [G]) : BOOLEAN is
external "CWC"
alias "_ARRAY_is_equal"
end; -- c_array_is_equal
-------------------------------------------------------------- c_array_resize
c_array_resize (cnt : INTEGER; lwr : INTEGER) is
external "CWC"
alias "_ARRAY_resize"
end; -- c_array_resize
----------------------------------------------------------------- c_array_put
c_array_put (i : INTEGER; v : G) is
external "CWC"
alias "_ARRAY_put"
end; -- put
------------------------------------------------------------------- c_og_move
c_og_move (
dst : Pointer; dst_index : Integer; src : Pointer; src_size : INTEGER
) is
external "C"
alias "og_move"
end; -- c_og_move
-------------------------------------------------------------- array_mem_copy
array_mem_copy (dest, source : POINTER; bytes_number : INTEGER) is
external "C"
alias "_mem_copy"
end; -- array_mem_copy
-----------------------------------------------------------------------------
invariant
consistent_size : count = upper - lower + 1;
non_negative_count : count >= 0
-----------------------------------------------------------------------------
end -- class ARRAY