home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 3 / AACD03.BIN / AACD / Programming / sofa / archive / SmallEiffel.lha / SmallEiffel / lib_std / fixed_array2.e < prev    next >
Text File  |  1999-06-05  |  9KB  |  359 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_ARRAY2[E]
  13.    --   
  14.    -- Resizable two dimensional array.
  15.    -- Unlike ARRAY2, the `lower1' bound and the `lower2' bound are 
  16.    -- frozen to 0. Thus, one can expect better performances.
  17.    --
  18.    
  19. inherit COLLECTION2[E];
  20.    
  21. creation
  22.    make, copy, from_collection2, from_collection, from_model
  23.    
  24. feature
  25.    
  26.    upper1, count1, upper2, count2, count: INTEGER;
  27.    
  28. feature {FIXED_ARRAY2}
  29.    
  30.    storage: NATIVE_ARRAY[E];
  31.    
  32.    capacity : INTEGER; -- of `storage'.
  33.  
  34. feature
  35.    
  36.    lower1: INTEGER is 0;      
  37.  
  38.    lower2: INTEGER is 0;      
  39.    
  40. feature
  41.    
  42.    make(new_count1 , new_count2 : INTEGER) is
  43.          -- Create or reset Current with new dimensions.
  44.          -- All elements are set to the default value of type E.
  45.       require
  46.          new_count1 > 0;
  47.          new_count2 > 0
  48.       do
  49.          count1 := new_count1;
  50.          upper1 := new_count1 - 1;
  51.          count2 := new_count2;
  52.          upper2 := new_count2 - 1;
  53.          count := count1 * count2;
  54.          if capacity < count then
  55.             capacity := count;
  56.             storage := storage.calloc(capacity);
  57.          else
  58.             storage.clear_all(capacity - 1);
  59.          end;
  60.       ensure
  61.          count1 = new_count1;
  62.          count2 = new_count2;
  63.          all_cleared
  64.       end;
  65.    
  66.    from_collection(model: COLLECTION2[like item]) is
  67.          -- Uses the `model' to update Current.
  68.       local
  69.          i, j: INTEGER;
  70.       do
  71.          make(model.upper1+1, model.upper2+1);
  72.          from
  73.             i := 0;
  74.          until
  75.             i > upper1
  76.          loop
  77.             from
  78.                j := 0;
  79.             until
  80.                j > upper2
  81.             loop
  82.                put(model.item(i,j),i,j);
  83.                j := j + 1;
  84.             end
  85.             i := i + 1;
  86.          end
  87.       end;
  88.  
  89. feature -- Implementation of others feature from COLLECTION2 :
  90.  
  91.    item(line, column: INTEGER): E is
  92.       do
  93.          Result := storage.item(line * count2 + column);
  94.       end;
  95.    
  96.    put(x: like item; line, column: INTEGER) is
  97.       do
  98.          storage.put(x,line * count2 + column);
  99.       end;
  100.    
  101.    force(element: like item; line , column : INTEGER) is
  102.       do
  103.          if not valid_index(line, column) then
  104.             resize(line.max(upper1),column.max(upper2));
  105.          end;
  106.          put(element,line,column);
  107.       end;
  108.  
  109.    copy(other: like Current) is
  110.       do
  111.          count1 := other.count1;
  112.          upper1 := count1 - 1;
  113.          count2 := other.count2;
  114.          upper2 := count2 - 1;
  115.          count := count1 * count2;
  116.          if capacity < count then
  117.             capacity := count;
  118.             storage := storage.calloc(capacity);
  119.          end;
  120.          storage.copy_from(other.storage, count - 1);
  121.       end;
  122.    
  123.    is_equal(other: like Current): BOOLEAN is
  124.       do
  125.          if other = Current then
  126.             Result := true;
  127.          elseif upper1 /= other.upper1 then
  128.          elseif upper2 /= other.upper2 then
  129.          else
  130.             Result := storage.memcmp(other.storage,count);
  131.          end;
  132.       end;
  133.  
  134. feature -- Writing :
  135.    
  136.    set_all_with(x: E) is
  137.          --  All element are set with the value x.
  138.       do
  139.          storage.set_all_with(x,count - 1)
  140.       ensure
  141.          count = old count
  142.       end; -- set_all_with
  143.  
  144.    all_cleared : BOOLEAN is
  145.       do
  146.          result := storage.all_cleared(count - 1);
  147.       end;
  148.    
  149.    slice(l1,up1,l2,up2: INTEGER): like Current is
  150.          -- Create a new collection initialized with elements of
  151.          -- range `low'..`up'. Result has the same dynamic type 
  152.          -- as Current collection.
  153.       local
  154.          ligne,colonne : INTEGER;
  155.          k : INTEGER;
  156.       do
  157.          from 
  158.             !!Result.make((up1 - l1) + 1,(up2 - l2) + 1);
  159.             ligne := l1;
  160.          until 
  161.             ligne > up1
  162.          loop 
  163.             from 
  164.                colonne := l2;
  165.             until 
  166.                colonne > up2
  167.             loop 
  168.                Result.put(item(ligne,colonne),ligne - l1,colonne - l2);
  169.                colonne := colonne + 1;
  170.             end; 
  171.             ligne := ligne + 1;
  172.          end; 
  173.       end; -- slice
  174.    
  175.    set_slice(element: like item;  l1,up1,l2,up2: INTEGER) is
  176.     -- Set all the elements in the 
  177.     -- range [(l1,up1),(l2,up2)] of
  178.     -- Current with the element 'element'.
  179.  
  180.       local
  181.          i,j : INTEGER;
  182.       do
  183.          from 
  184.             i := l1 * count2;
  185.          until 
  186.             i > up1 * count2
  187.          loop 
  188.             from 
  189.                j := l2;
  190.             until 
  191.                j > up2
  192.             loop 
  193.                storage.put(element,i + j);
  194.                j := j + 1;
  195.             end; 
  196.             i := i + count2;
  197.          end; 
  198.       end;
  199.  
  200.    swap(line1, column1, line2, column2 : INTEGER) is
  201.       local
  202.          tmp: like item;
  203.          c2, index1, index2 : INTEGER
  204.       do
  205.          c2 := count2;
  206.          index1 := line1 * c2 + column1;
  207.          index2 := line2 * c2 + column2;
  208.          tmp := storage.item( index1);
  209.          storage.put(storage.item(index2) ,index1);
  210.          storage.put(tmp,index2);
  211.       end
  212.    
  213. feature -- Looking and comparison :
  214.  
  215.    nb_occurrences(elt: E): INTEGER is
  216.          -- Number of occurrences using `equal'.
  217.          -- See also `fast_nb_occurrences' to chose
  218.          -- the apropriate one.
  219.       do
  220.          Result := storage.nb_occurrences(elt,count - 1);
  221.       ensure
  222.          Result >= 0;
  223.       end; -- nb_occurences
  224.       
  225.    fast_nb_occurrences(elt: E): INTEGER is
  226.          -- Number of occurrences using `='.
  227.       do
  228.          Result := storage.fast_nb_occurrences(elt,count - 1);
  229.       ensure
  230.          Result >= 0;
  231.       end; -- fast_nb_occurrences
  232.  
  233. feature -- Resizing :
  234.  
  235.    resize(new_count1 , new_count2: INTEGER) is
  236.       require
  237.          new_count1 > 0;
  238.          new_count2 > 0
  239.       local
  240.          tmp: like Current;
  241.          l, c: INTEGER;
  242.       do
  243.          !!tmp.make(new_count1, new_count2);
  244.          -- It may be possible to avoid this ceation when :
  245.          --    new `capacity' <= old `capacity'
  246.          from
  247.             l := line_maximum;
  248.          until
  249.             l < 0
  250.          loop
  251.             from
  252.                c := column_maximum;
  253.             until
  254.                c < 0
  255.             loop
  256.                if tmp.valid_index(l,c) then
  257.                   tmp.put(item(l,c),l,c);
  258.                end;
  259.                c := c - 1;
  260.             end;
  261.             l := l - 1;
  262.          end;
  263.          standard_copy(tmp);
  264.       ensure
  265.          upper1 = new_count1 - 1;
  266.          count1 = new_count1;
  267.          upper2 = new_count2 - 1;
  268.          count2 = new_count2;
  269.          count = new_count1 * new_count2
  270.       end;
  271.  
  272. feature -- Looking and Searching :
  273.  
  274.    has(x: like item): BOOLEAN is
  275.          -- Look for `x' using `equal' for comparison.      
  276.       do
  277.          Result := storage.index_of(x,count-1) <= (count-1);
  278.       end;  -- has
  279.    
  280.    fast_has(x: like item): BOOLEAN is
  281.          -- Same as `has' but use `=' for comparison      
  282.       do
  283.          Result := storage.fast_index_of(x,count - 1) <= (count - 1);
  284.       end; -- fast_has
  285.  
  286. feature -- Other features :
  287.    
  288.    replace_all(old_value, new_value: like item) is
  289.       do
  290.          storage.replace_all(old_value,new_value,count - 1);
  291.       end;
  292.          
  293.    fast_replace_all(old_value, new_value: like item) is
  294.       do
  295.          storage.fast_replace_all(old_value,new_value,count - 1);
  296.       end;
  297.          
  298.    transpose is
  299.          -- Transpose the Current array
  300.       local
  301.          i,j : INTEGER;
  302.          oldu1 , oldu2 : INTEGER;
  303.       do
  304.          oldu1 := upper1;
  305.          oldu2 := upper2;
  306.          resize(upper2.max(upper1),upper2.max(upper1));
  307.          from  
  308.             i := 0;
  309.          until 
  310.             i > upper1 - 1
  311.          loop
  312.             from  
  313.                j := i + 1;
  314.             until 
  315.                j > upper2
  316.             loop
  317.                swap(i,j,j,i);
  318.                j := j + 1;
  319.             end;
  320.             i := i + 1;
  321.          end;
  322.          resize(oldu2,oldu1);
  323.       end;
  324.  
  325.    to_external: POINTER is
  326.          -- Gives C access to the internal `storage' (may be dangerous).
  327.       do
  328.          Result := storage.to_external;
  329.       end;
  330.    
  331. feature {COLLECTION2}
  332.  
  333.    same_as(other: COLLECTION2[E]): BOOLEAN is
  334.       do
  335.          Result := other.same_as_fixed_array2(Current);
  336.       end;
  337.  
  338.    same_as_array2(other: ARRAY2[E]): BOOLEAN is
  339.       do
  340.          Result := standard_same_as(other);
  341.       end;
  342.  
  343.    same_as_fixed_array2(other: FIXED_ARRAY2[E]): BOOLEAN is
  344.       do
  345.          Result := standard_same_as(other);
  346.       end;
  347.  
  348. invariant
  349.  
  350.    count1 = upper1 + 1;
  351.    
  352.    count2 = upper2 + 1;
  353.  
  354.    count = count1 * count2;
  355.  
  356.    capacity >= count;
  357.  
  358. end -- FIXED_ARRAY2[E]
  359.