home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Environments / SmallEiffel 0.3.3 / SmallEiffel 68k / lib_std / array.e < prev    next >
Encoding:
Text File  |  1996-06-13  |  7.9 KB  |  410 lines  |  [TEXT/EDIT]

  1. -- Part of SmallEiffel -- Read DISCLAIMER file -- Copyright (C) 
  2. -- Dominique COLNET and Suzanne COLLIN -- colnet@loria.fr
  3. --
  4. class ARRAY[E]
  5. -- 
  6. -- General purpose arrays.
  7. --
  8.  
  9. inherit 
  10.    COLLECTION[E]
  11.       redefine eval_read_attribute, eval_write_attribute
  12.       end;
  13.  
  14. creation make
  15.  
  16. feature {NONE}
  17.    
  18.    storage: POINTER;
  19.      -- Internal access to storage location.
  20.    
  21. feature
  22.    
  23.    capacity: INTEGER;
  24.      -- Internal storage capacity in number of item.
  25.    
  26.    lower: INTEGER;     
  27.      -- Lower index bound.
  28.    
  29.    upper: INTEGER;
  30.      -- Upper index bound.
  31.    
  32. feature -- Creation and Modification :
  33.    
  34.    make(minindex, maxindex: INTEGER) is
  35.      -- Make array with range [minindex .. maxindex]. 
  36.      -- When maxindex = minindex - 1, the array is empty.
  37.       require
  38.      minindex -1 <= maxindex
  39.       do
  40.      if storage.is_not_void then
  41.         free_pointer(storage);
  42.      end;
  43.      lower := minindex;
  44.      upper := maxindex;
  45.      capacity := maxindex - minindex + 1;
  46.      if capacity > 0 then
  47.         if capacity < 16 then capacity := 16 end;
  48.         storage := malloc(capacity);
  49.         clear_all;
  50.      end;
  51.       ensure
  52.      lower = minindex;
  53.      upper = maxindex;
  54.      all_cleared;
  55.       end;
  56.  
  57. feature -- Modification :
  58.    
  59.    resize(minindex, maxindex: INTEGER) is
  60.      -- Resize the array. No elements will be lost in the 
  61.      -- intersection of [old lower .. old upper] and 
  62.      -- [minindex .. maxindex].
  63.      -- New positions are initialized with appropriate 
  64.      -- default values.
  65.       require
  66.      minindex <= maxindex
  67.       local
  68.      other: like Current;
  69.      i, up: INTEGER;
  70.       do
  71.      from
  72.         !!other.make(minindex,maxindex);
  73.         i := lower.max(other.lower);
  74.         up := upper.min(other.upper);
  75.      until
  76.         i > up
  77.      loop
  78.         other.put(item(i),i);
  79.         i := i + 1;
  80.      end;
  81.      if storage.is_not_void then
  82.         free_pointer(storage);
  83.      end;
  84.      standard_copy(other);
  85.      other.free_array;
  86.       end;
  87.  
  88. feature -- No modification :
  89.  
  90.    item, infix "@" (index: INTEGER): E is
  91.       external "CSE"
  92.       end;
  93.    
  94. feature -- Modification :
  95.    
  96.    put(element: E; index: INTEGER) is
  97.       external "CSE"
  98.       end;
  99.  
  100.    force(element: E; index: INTEGER) is
  101.      -- Put `element' at position `index'.
  102.      -- Resize array, if `index' is not
  103.      -- inside current bounds.
  104.       do
  105.      if upper < index then
  106.         resize(lower,index);
  107.      elseif index < lower then
  108.         resize(index,upper);
  109.      end;
  110.      put(element,index);
  111.       ensure
  112.      valid_index(index); 
  113.      item(index) = element;
  114.       end;
  115.  
  116.    clear is
  117.      -- Empty the array, discard all items.
  118.       do
  119.      upper := lower - 1;
  120.       ensure
  121.      empty;
  122.       end;
  123.  
  124.    copy(other: like Current) is
  125.      -- Copy `other' onto Current.
  126.       local
  127.      i: INTEGER;
  128.       do
  129.      upper := lower - 1;
  130.      if capacity = 0 then
  131.         make(other.lower,other.upper);
  132.      else
  133.         resize(other.lower,other.upper);
  134.      end;
  135.      from
  136.         i := lower;
  137.      until
  138.         i > upper
  139.      loop
  140.         put(other.item(i),i);
  141.         i := i + 1;
  142.      end;
  143.       end;
  144.    
  145.    remove(index: INTEGER) is
  146.      -- Remove one element at position `index'. Followings 
  147.      -- elements (after `index') are moved one position left.
  148.       require
  149.      valid_index(index); 
  150.       local
  151.      i: INTEGER;
  152.       do
  153.      from  
  154.         i := index;
  155.      until
  156.         i + 1 > upper
  157.      loop
  158.         put(item(i + 1),i);
  159.         i := i + 1;
  160.      end;
  161.      upper := upper - 1;
  162.       ensure
  163.      count + 1 = old count;
  164.      upper + 1 = old upper;
  165.       end;
  166.    
  167.    remove_last is
  168.       require
  169.      not empty;
  170.       do
  171.      upper := upper - 1;
  172.       ensure
  173.      count + 1 = old count;
  174.      lower = old lower
  175.       end;
  176.    
  177.    remove_first is
  178.       require
  179.      not empty;
  180.       local
  181.      i: INTEGER;
  182.       do
  183.      from
  184.         i := lower;
  185.      until
  186.         i = upper
  187.      loop
  188.         put(item(i+1),i);
  189.         i := i + 1;
  190.      end;
  191.      lower := lower + 1;
  192.       ensure
  193.      count + 1 = old count;
  194.      upper = old upper;
  195.       end;
  196.    
  197. feature -- Adding Elements :
  198.    
  199.    add_last(elt: E) is
  200.       do
  201.      if storage = Void then end;
  202.      if capacity < count + 1 then
  203.         if capacity = 0 then
  204.            capacity := 16;
  205.            storage := malloc(capacity);
  206.         else
  207.            capacity := capacity + 16;
  208.            storage := realloc(storage,capacity);
  209.         end;
  210.      end;
  211.      upper := upper + 1;
  212.      put(elt,upper);
  213.       ensure
  214.      last = elt;
  215.      count = 1 + old count
  216.       end;
  217.    
  218.    add(elt: E) is
  219.       do
  220.      if not has(elt) then
  221.         add_last(elt);
  222.      end;
  223.       ensure
  224.      has(elt);
  225.      count >= old count;
  226.       end;
  227.    
  228.    fast_add(elt: E) is
  229.       do
  230.      if not fast_has(elt) then
  231.         add_last(elt);
  232.      end;
  233.       ensure
  234.      fast_has(elt);
  235.      count >= old count;
  236.       end;
  237.    
  238.    insert(element : E; index: INTEGER) is
  239.      -- Insert `element' after position `index'.
  240.      -- Element at position `upper' will be lost!
  241.       require
  242.      inside_bounds: lower - 1 <= index and then index < upper
  243.      -- Note: Insertion is AFTER `index'!
  244.       do
  245.      if index < upper - 1 then
  246.         move(index+1,upper-1,1);
  247.      end;
  248.      put (element, index + 1);
  249.       end;
  250.    
  251.    sub_array(low, up: INTEGER): ARRAY[E] is
  252.       require
  253.      valid_index(low);
  254.      valid_index(up);
  255.      low <= up
  256.       local
  257.      i: INTEGER;
  258.       do
  259.      from  
  260.         !!Result.make(low,up);
  261.         i := low;
  262.      until
  263.         i > up
  264.      loop
  265.         Result.put(item(i),i);
  266.         i := i + 1;
  267.      end;
  268.       ensure
  269.      Result.lower = low;
  270.      Result.upper = up;
  271.       end;
  272.  
  273. feature -- Other Features :
  274.  
  275.    put_first(elt: E) is
  276.      -- Put `elt' at the first free place
  277.      -- or `add_last' it no Void places.
  278.       local
  279.      i: INTEGER;
  280.      null: E;
  281.       do
  282.      from  
  283.         i := lower;
  284.      until
  285.         i > upper or else item(i) = null
  286.      loop
  287.         i := i + 1;
  288.      end;
  289.      if i > upper then
  290.         add_last(elt);
  291.      else
  292.         put(elt,i);
  293.      end;
  294.       end;
  295.       
  296.    take_first: E is
  297.      -- Take the first element non Void or not set to 
  298.      -- the default value. Then set the corresponding 
  299.      -- place to the default value.
  300.       local
  301.      i: INTEGER;
  302.      null: E;
  303.       do
  304.      from  
  305.         i := lower;
  306.      until
  307.         i > upper or else Result /= null
  308.      loop
  309.         Result := item(i);
  310.         i := i + 1;
  311.      end;
  312.      if i <= upper then
  313.         put(null,i-1);
  314.      end;
  315.       ensure
  316.      count = old count;
  317.       end;
  318.  
  319. feature -- Interfacing with C :
  320.    
  321.    to_external: POINTER is
  322.      -- Gives C access into the internal `storage' of the ARRAY.
  323.      -- Result is pointing the element at index `lower'.
  324.      -- 
  325.      -- NOTE: do not free/realloc the Result. Resizing of the array 
  326.      --       can makes this pointer invalid. 
  327.       require
  328.      not empty
  329.       do
  330.      Result := storage;
  331.       ensure
  332.      Result.is_not_void
  333.       end;
  334.  
  335. feature {NONE}
  336.  
  337.    malloc(size: INTEGER): POINTER is
  338.       require
  339.      size > 0
  340.       local
  341.      x: like item;
  342.       do
  343.      c_inline_c("R=malloc((size_t)(a1*sizeof(_x)));");
  344.       end;
  345.  
  346.    realloc(pointer: POINTER; size: INTEGER): POINTER is
  347.       require
  348.      size > 0
  349.       local
  350.      x: like item;
  351.       do           
  352.      c_inline_c("R=realloc(a1,((size_t)(a2*sizeof(_x))));");
  353.       end;
  354.  
  355.    free_pointer(p: POINTER) is
  356.       require
  357.      p.is_not_void
  358.       external "C"
  359.       alias "free"
  360.       end;
  361.  
  362. feature {ARRAY}
  363.  
  364.    free_array is
  365.       external "CWC"
  366.       alias "free"
  367.       end;
  368.  
  369. feature -- To implement eval :
  370.    
  371.    eval_read_attribute(name: STRING; dest: POINTER) is
  372.       do 
  373.      if ("capacity").is_equal(name) then
  374.         eval_virtual_machine.put_integer(dest,capacity);
  375.      elseif ("lower").is_equal(name) then
  376.         eval_virtual_machine.put_integer(dest,lower);
  377.      elseif ("upper").is_equal(name) then
  378.         eval_virtual_machine.put_integer(dest,upper);
  379.      else
  380.         check
  381.            ("storage").is_equal(name)
  382.         end;
  383.         eval_virtual_machine.put_pointer(dest,storage);
  384.      end;
  385.       end;
  386.  
  387.    eval_write_attribute(name: STRING; source: POINTER) is
  388.       do 
  389.      if ("capacity").is_equal(name) then
  390.         capacity := eval_virtual_machine.get_integer(source);
  391.      elseif ("lower").is_equal(name) then
  392.         lower := eval_virtual_machine.get_integer(source);
  393.      elseif ("upper").is_equal(name) then
  394.         upper := eval_virtual_machine.get_integer(source);
  395.      else
  396.         check
  397.            ("storage").is_equal(name)
  398.         end;
  399.         storage := eval_virtual_machine.get_pointer(source);
  400.      end;
  401.       end;
  402.  
  403. invariant
  404.    
  405.    capacity >= (upper - lower + 1);
  406.  
  407.    capacity > 0 implies storage.is_not_void;
  408.  
  409. end -- ARRAY[E]
  410.