home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 3 / AACD03.BIN / AACD / Programming / sofa / archive / SmallEiffel.lha / SmallEiffel / lib_std / array.e < prev    next >
Text File  |  1999-06-05  |  9KB  |  316 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 ARRAY[E]
  13.    -- 
  14.    -- General purpose resizable ARRAYs.
  15.    -- 
  16.  
  17. inherit ARRAYED_COLLECTION[E];
  18.  
  19. creation make, with_capacity, from_collection
  20.  
  21. feature
  22.    
  23.    lower: INTEGER;     
  24.          -- Lower index bound.
  25.    
  26. feature -- Creation and Modification :
  27.    
  28.    make(minindex, maxindex: INTEGER) is
  29.          -- Make array with range [`minindex' .. `maxindex']. 
  30.          -- When `maxindex' = `minindex' - 1, the array is empty.
  31.       require
  32.          minindex -1 <= maxindex
  33.       local
  34.          needed: INTEGER;
  35.       do
  36.          lower := minindex;
  37.          upper := maxindex;
  38.          needed := maxindex - minindex + 1;
  39.          if needed > 0 then
  40.             if capacity < needed then
  41.                storage := storage.calloc(needed);
  42.                capacity := needed;
  43.             else
  44.                clear_all;
  45.             end;
  46.          end;
  47.       ensure
  48.          lower = minindex;
  49.          upper = maxindex;
  50.          all_cleared
  51.       end;
  52.  
  53.    with_capacity(needed_capacity, low: INTEGER) is
  54.          -- Create an empty array with `capacity' initialized
  55.          -- at least to `needed_capacity' and `lower' set to `low'.
  56.       require
  57.          needed_capacity >= 0
  58.       do
  59.          if capacity < needed_capacity then
  60.             storage := storage.calloc(needed_capacity);
  61.             capacity := needed_capacity;
  62.          end;
  63.          lower := low;
  64.          upper := low - 1;
  65.       ensure
  66.          empty;
  67.          needed_capacity <= capacity;
  68.          lower = low
  69.       end;
  70.  
  71. feature -- Modification :
  72.    
  73.    resize(minindex, maxindex: INTEGER) is
  74.          -- Resize the array. No elements will be lost in the 
  75.          -- intersection of [old `lower' .. old `upper'] and 
  76.          -- [`minindex' .. `maxindex'].
  77.          -- New positions are initialized with appropriate 
  78.          -- default values.
  79.       require
  80.          minindex -1 <= maxindex
  81.       local
  82.          needed, offset, intersize: INTEGER;
  83.       do
  84.          needed := maxindex - minindex + 1;
  85.          if needed > 0 then
  86.             if needed > capacity then
  87.                if capacity = 0 then
  88.                   storage := storage.calloc(needed);
  89.                   capacity := needed;
  90.                else
  91.                   storage := storage.realloc(capacity, needed);
  92.                   capacity := needed;
  93.                end;
  94.             end;
  95.             offset := lower - minindex;
  96.             intersize := maxindex.min(upper) - minindex.max(lower) + 1;
  97.             if intersize > 0 then
  98.                if offset = 0 then
  99.                   if intersize < needed then
  100.                      storage.clear(intersize, needed - 1);
  101.                   end;
  102.                elseif offset < 0 then
  103.                   storage.move(-offset, intersize - offset - 1, offset);
  104.                   if intersize < needed then
  105.                      storage.clear(intersize, needed - 1);
  106.                   end;
  107.                else
  108.                   storage.move(0, intersize - 1, offset);
  109.                   storage.clear(0, offset - 1);
  110.                   if intersize + offset < needed then
  111.                      storage.clear(intersize + offset, needed - 1);
  112.                   end;
  113.                end;
  114.             else
  115.                storage.clear(0, needed - 1);
  116.             end;
  117.          end;
  118.          lower := minindex;
  119.          upper := maxindex;
  120.       end;
  121.  
  122. feature 
  123.  
  124.    sub_array(low, up: INTEGER): like Current is
  125.       local
  126.          i: INTEGER;
  127.       do
  128.          from
  129.             !!Result.with_capacity(up - low + 1,low);
  130.             Result.set_upper(up);
  131.             i := low;
  132.          until
  133.             i > up
  134.          loop
  135.             Result.put(item(i),i);
  136.             i := i + 1;
  137.          end;
  138.       ensure then
  139.          Result.lower = low;
  140.       end;
  141.  
  142. feature -- Implementation of deferred :
  143.  
  144.    count: INTEGER is
  145.       do
  146.          Result := upper - lower + 1;
  147.       end;
  148.  
  149.    item, infix "@" (index: INTEGER): E is
  150.       do
  151.          Result := storage.item(index - lower);
  152.       end;
  153.    
  154.    put(element: like item; index: INTEGER) is
  155.       do
  156.          storage.put(element,index - lower);
  157.       end;
  158.  
  159.    force(element: like item; index: INTEGER) is
  160.          -- Put `element' at position `index'. Current is
  161.          -- resized if `index' is not inside current bounds.
  162.          -- New bounds are initialized with default values.
  163.       require else
  164.          true
  165.       do
  166.          if upper < index then
  167.             resize(lower,index);
  168.          elseif index < lower then
  169.             resize(index,upper);
  170.          end;
  171.          put(element,index);
  172.       end;
  173.  
  174.    copy(other: like Current) is
  175.       local
  176.          needed_capacity: INTEGER;
  177.       do
  178.          lower := other.lower;
  179.          upper := other.upper;
  180.          needed_capacity := upper - lower + 1;
  181.          if capacity < needed_capacity then
  182.             capacity := needed_capacity;
  183.             storage := storage.calloc(capacity);
  184.          end;
  185.          if needed_capacity > 0 then
  186.             storage.copy_from(other.storage,needed_capacity - 1);
  187.          end;
  188.       end;
  189.    
  190.    set_all_with(v: like item) is
  191.       do
  192.          storage.set_all_with(v,upper - lower);
  193.       end;
  194.  
  195.    remove_first is
  196.       do
  197.          storage.remove_first(upper - lower);
  198.          lower := lower + 1;
  199.       ensure then
  200.          upper = old upper;
  201.       end;
  202.    
  203.    remove(index: INTEGER) is
  204.       do
  205.          storage.remove(index - lower,upper - lower);
  206.          upper := upper - 1;
  207.       end;
  208.    
  209.    clear is
  210.       do
  211.          upper := lower - 1;
  212.       ensure then
  213.          capacity = old capacity
  214.       end;
  215.  
  216.    add_first(element: like item) is
  217.       do
  218.          if upper < lower then
  219.             add_last(element);
  220.          else
  221.             add_last(element);
  222.             move(lower,upper - 1,1);
  223.             put(element,lower);
  224.          end;
  225.       end;
  226.  
  227.    add_last(element: like item) is
  228.       local
  229.          new_capacity: INTEGER;
  230.       do
  231.          if capacity < count + 1 then
  232.             if capacity = 0 then
  233.                capacity := 16;
  234.                storage := storage.calloc(capacity);
  235.             else
  236.                new_capacity := 2 * capacity;
  237.                storage := storage.realloc(capacity,new_capacity);
  238.                capacity := new_capacity;
  239.             end;
  240.          end;
  241.          upper := upper + 1;
  242.          put(element,upper);
  243.       end;
  244.  
  245.    from_collection(model: COLLECTION[like item]) is
  246.       local
  247.          i, up: INTEGER;
  248.       do
  249.          from
  250.             with_capacity(model.count,model.lower);
  251.             i := model.lower;
  252.             up := model.upper;
  253.             upper := up;
  254.          until
  255.             i > up
  256.          loop
  257.             put(model.item(i),i);
  258.             i := i + 1;
  259.          end;
  260.       ensure then
  261.          lower = model.lower;
  262.          upper = model.upper
  263.       end;
  264.  
  265.    all_cleared: BOOLEAN is
  266.       do
  267.          Result := storage.all_cleared(upper - lower);
  268.       end;
  269.  
  270.    nb_occurrences(element: like item): INTEGER is
  271.       do
  272.          Result := storage.nb_occurrences(element,upper - lower);
  273.       end;
  274.       
  275.    fast_nb_occurrences(element: like item): INTEGER is
  276.       do
  277.          Result := storage.fast_nb_occurrences(element,upper - lower);
  278.       end;
  279.       
  280.    index_of(element: like item): INTEGER is
  281.       do
  282.          Result := lower + storage.index_of(element,upper - lower);
  283.       end;
  284.  
  285.    fast_index_of(element: like item): INTEGER is
  286.       do
  287.          Result := lower + storage.fast_index_of(element,upper - lower);
  288.       end;
  289.  
  290.    is_equal(other: like Current): BOOLEAN is
  291.       do
  292.          if Current = other then
  293.             Result := true;
  294.          elseif lower = other.lower and then upper = other.upper then
  295.             Result := storage.memcmp(other.storage,count);
  296.          end;
  297.       end;
  298.  
  299.    slice(low, up: INTEGER): like Current is
  300.       local
  301.          i: INTEGER;
  302.       do
  303.          from
  304.             i := low;
  305.             !!Result.with_capacity(up - low + 1,lower);
  306.          until
  307.             i > up
  308.          loop
  309.             Result.add_last(item(i));
  310.             i := i + 1;
  311.          end;
  312.       end;
  313.  
  314. end -- ARRAY[E]
  315.  
  316.