home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 3 / AACD03.BIN / AACD / Programming / sofa / archive / SmallEiffel.lha / SmallEiffel / lib_std / fixed_array.e < prev    next >
Text File  |  1999-06-05  |  8KB  |  317 lines

  1. -- This file is  free  software, which  comes  along  with  SmallEiffel. This
  2. -- software  is  distributed  in the hope that it will be useful, but WITHOUT 
  3. -- ANY  WARRANTY;  without  even  the  implied warranty of MERCHANTABILITY or
  4. -- FITNESS  FOR A PARTICULAR PURPOSE. You can modify it as you want, provided
  5. -- this header is kept unaltered, and a notification of the changes is added.
  6. -- You  are  allowed  to  redistribute  it and sell it, alone or as a part of 
  7. -- another product.
  8. --          Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
  9. --            Dominique COLNET and Suzanne COLLIN - colnet@loria.fr 
  10. --                       http://SmallEiffel.loria.fr
  11. --
  12. class FIXED_ARRAY[E]
  13.    --
  14.    -- Resizable, fixed lower bound array.
  15.    -- Unlike ARRAY, the `lower' bound of a FIXED_ARRAY is frozen 
  16.    -- to 0. Thus, some memory is saved and looping toward `lower'
  17.    -- bound (which is 0) run a little bit faster.
  18.    --
  19.  
  20. inherit ARRAYED_COLLECTION[E];
  21.  
  22. creation 
  23.    make, with_capacity, from_collection
  24.  
  25. feature
  26.  
  27.    lower: INTEGER is 0;
  28.          -- Frozen lower bound.
  29.    
  30. feature -- Creation and modification :
  31.    
  32.    make(new_count: INTEGER) is
  33.          -- Make array with range [0 .. `new_count' - 1]. 
  34.          -- When `new_count' = 0 the array is empty.
  35.       require
  36.          new_count >= 0
  37.       do
  38.          if new_count = 0 then
  39.             upper := -1;
  40.          elseif capacity = 0 then
  41.             storage := storage.calloc(new_count);
  42.             capacity := new_count;
  43.             upper := new_count - 1;
  44.          elseif capacity < new_count then
  45.             storage := storage.calloc(new_count);
  46.             capacity := new_count;
  47.             upper := new_count - 1;
  48.          else
  49.             upper := new_count - 1;
  50.             clear_all;
  51.          end;
  52.       ensure
  53.          count = new_count;
  54.          capacity >= old capacity;
  55.          all_cleared
  56.       end;
  57.  
  58.    with_capacity(needed_capacity: INTEGER) is
  59.          -- Create an empty array with at least `needed_capacity'.
  60.       do
  61.          if capacity < needed_capacity then
  62.             storage := storage.calloc(needed_capacity);
  63.             capacity := needed_capacity;
  64.          end;
  65.          upper := -1;
  66.       ensure
  67.          capacity >= needed_capacity;
  68.          empty
  69.       end;
  70.  
  71. feature -- Modification :
  72.  
  73.    resize(new_count: INTEGER) is
  74.          -- Resize the array. When `new_count' is greater than
  75.          -- `count', new positions are initialized with appropriate 
  76.          -- default values.
  77.       require
  78.          new_count >= 0
  79.       local
  80.          new_capacity, i: INTEGER;
  81.          elt_default: like item;
  82.       do
  83.          if new_count <= count then
  84.             upper := new_count - 1;
  85.          else
  86.             new_capacity := new_count;
  87.             if capacity < new_capacity then
  88.                if capacity = 0 then
  89.                   storage := storage.calloc(new_capacity);
  90.                else
  91.                   storage := storage.realloc(capacity,new_capacity);
  92.                end;
  93.                capacity := new_capacity;
  94.             end;
  95.             from
  96.                new_capacity := upper;
  97.                upper := new_count - 1;
  98.                i := upper;
  99.             until
  100.                i = new_capacity
  101.             loop
  102.                put(elt_default,i);
  103.                i := i - 1;
  104.             end;
  105.          end;
  106.       ensure
  107.          count = new_count;
  108.          capacity >= old capacity
  109.       end;
  110.  
  111. feature 
  112.  
  113.    sub_array(low, up: INTEGER): like Current is
  114.       local
  115.          i1, i2: INTEGER;
  116.       do
  117.          from
  118.             i2 := up - low;
  119.             !!Result.with_capacity(i2 + 1);
  120.             Result.set_upper(i2);
  121.             i2 := low;
  122.             i1 := 0;
  123.          until
  124.             i2 > up
  125.          loop
  126.             Result.put(item(i2),i1);
  127.             i1 := i1 + 1;
  128.             i2 := i2 + 1;
  129.          end;
  130.       ensure then
  131.          Result.lower = 0
  132.       end;
  133.  
  134. feature -- Implementation of deferred :
  135.  
  136.    item, infix "@" (index: INTEGER): E is
  137.       do
  138.          Result := storage.item(index);
  139.       end;
  140.    
  141.    put(element: E; index: INTEGER) is
  142.       do
  143.          storage.put(element,index);
  144.       end;
  145.  
  146.    add_first(element: like item) is
  147.       do
  148.          add_last(element);
  149.          if upper = 0 then
  150.          elseif upper = 1 then
  151.             swap(0,1);
  152.          else
  153.             move(0,upper - 1,1);
  154.             put(element,0);
  155.          end;
  156.       end;
  157.  
  158.    add_last(element: like item) is
  159.       local
  160.          new_capacity: INTEGER;
  161.       do
  162.          if upper + 1 <= capacity - 1 then
  163.             upper := upper + 1;
  164.          elseif capacity = 0 then
  165.             storage := storage.calloc(2);
  166.             capacity := 2;
  167.             upper := 0
  168.          else
  169.             new_capacity := 2 * capacity;
  170.             storage := storage.realloc(capacity,new_capacity);
  171.             capacity := new_capacity;
  172.             upper := upper + 1;
  173.          end;
  174.          put(element,upper);
  175.       end;
  176.  
  177.    count: INTEGER is
  178.       do
  179.          Result := upper + 1;
  180.       end;
  181.  
  182.    clear is
  183.       do
  184.          upper := -1;
  185.       ensure then
  186.          capacity = old capacity
  187.       end;
  188.  
  189.    copy(other: like Current) is
  190.          -- Copy `other' onto Current.
  191.       local
  192.          other_upper, new_capacity: INTEGER;
  193.       do
  194.          other_upper := other.upper;
  195.          if other_upper >= 0 then
  196.             new_capacity := other_upper + 1;
  197.             if capacity < new_capacity then
  198.                capacity := new_capacity;
  199.                storage := storage.calloc(new_capacity);
  200.             elseif capacity > 0 then
  201.                storage.clear_all(capacity - 1);
  202.             end;
  203.             storage.copy_from(other.storage,other_upper);
  204.          elseif capacity > 0 then
  205.             storage.clear_all(capacity - 1);
  206.          end;
  207.          upper := other_upper;
  208.       end;
  209.  
  210.    set_all_with(v: like item) is
  211.       do
  212.          storage.set_all_with(v,upper);
  213.       end;
  214.  
  215.    from_collection(model: COLLECTION[like item]) is
  216.       local
  217.          i1, i2, up: INTEGER;
  218.       do
  219.          from
  220.             with_capacity(model.count);
  221.             upper := model.count - 1;
  222.             i1 := 0;
  223.             i2 := model.lower;
  224.             up := model.upper;
  225.          until
  226.             i2 > up 
  227.          loop
  228.             put(model.item(i2),i1);
  229.             i1 := i1 + 1;
  230.             i2 := i2 + 1;
  231.          end;
  232.       end;
  233.    
  234.    is_equal(other: like Current): BOOLEAN is
  235.       do
  236.          if Current = other then
  237.             Result := true;
  238.          elseif upper = other.upper then
  239.             Result := storage.memcmp(other.storage,upper + 1);
  240.          end;
  241.       end;
  242.  
  243.    all_cleared: BOOLEAN is
  244.       do
  245.          Result := storage.all_cleared(upper);
  246.       end;
  247.  
  248.    nb_occurrences(element: like item): INTEGER is
  249.       do
  250.          Result := storage.nb_occurrences(element,upper);
  251.       end;
  252.       
  253.    fast_nb_occurrences(element: E): INTEGER is
  254.       do
  255.          Result := storage.fast_nb_occurrences(element,upper);
  256.       end;
  257.  
  258.    index_of(element: like item): INTEGER is
  259.       do
  260.          Result := storage.index_of(element,upper);
  261.       end;
  262.  
  263.    fast_index_of(element: like item): INTEGER is
  264.       do
  265.          Result := storage.fast_index_of(element,upper);
  266.       end;
  267.  
  268.    slice(low, up: INTEGER): like Current is
  269.       local
  270.          i: INTEGER;
  271.       do
  272.          from
  273.             i := low;
  274.             !!Result.with_capacity(up - low + 1);
  275.          until
  276.             i > up
  277.          loop
  278.             Result.add_last(item(i));
  279.             i := i + 1;
  280.          end;
  281.       end;
  282.  
  283.    force(element: E; index: INTEGER) is
  284.       do
  285.          if index <= upper then
  286.             put(element,index);
  287.          else
  288.             resize(index + 1);
  289.             put(element,index);
  290.          end;
  291.       end;
  292.          
  293.    remove_first is
  294.       local
  295.          dummy: like storage;
  296.       do
  297.          if upper = 0 then
  298.             storage := dummy;
  299.             capacity := 0;
  300.             upper := -1;
  301.          else
  302.             storage.remove_first(upper);
  303.             upper := upper - 1;
  304.          end;
  305.       ensure then
  306.          lower = old lower
  307.       end;
  308.  
  309.    remove(index: INTEGER) is
  310.       do
  311.          storage.remove(index,upper);
  312.          upper := upper - 1;
  313.       end;
  314.    
  315. end -- FIXED_ARRAY[E]
  316.  
  317.