work in progress | array

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