home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 3 / AACD03.BIN / AACD / Programming / sofa / archive / SmallEiffel.lha / SmallEiffel / lib_std / array2.e < prev    next >
Text File  |  1999-06-05  |  12KB  |  433 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 ARRAY2[E]
  13.    --
  14.    -- General prurpose, resizable, two dimensional array.
  15.    --
  16.  
  17. inherit COLLECTION2[E];
  18.    
  19. creation 
  20.    make, copy, from_collection2, from_collection, from_model
  21.  
  22. creation -- Obsolete :
  23.    array2
  24.    
  25. feature 
  26.    
  27.    lower1, lower2, upper1, upper2: INTEGER;
  28.    
  29. feature {ARRAY2}
  30.    
  31.    storage: NATIVE_ARRAY[E];
  32.          -- To store elements line by line.
  33.    
  34.    capacity: INTEGER;
  35.          -- Number of elements in `storage'.
  36.    
  37. feature -- Creation / modification :
  38.    
  39.    make(line_min, line_max, column_min, column_max: INTEGER) is
  40.          -- Reset all bounds `line_minimum' / `line_maximum' / `column_minimum' and
  41.          -- `column_maximum' using arguments as new values.
  42.          -- All elements are set to the default value of type E.
  43.       require
  44.          line_min <= line_max;
  45.          column_min <= column_max
  46.       do
  47.          lower1 := line_min;
  48.          upper1 := line_max;
  49.          lower2 := column_min;
  50.          upper2 := column_max;
  51.          if capacity >= count then
  52.             storage.clear_all(count - 1);
  53.          else
  54.             capacity := count;
  55.             storage := storage.calloc(count);
  56.          end;
  57.       ensure
  58.          line_minimum = line_min;
  59.          line_maximum = line_max;
  60.          column_minimum = column_min;
  61.          column_maximum = column_max;
  62.       end;
  63.    
  64.    from_collection2(model: COLLECTION2[like item]) is
  65.       local
  66.          i, j: INTEGER;
  67.       do
  68.          make(model.line_minimum,
  69.               model.line_maximum,
  70.               model.column_minimum,
  71.               model.column_maximum);
  72.          from
  73.             i := line_minimum;
  74.          until
  75.             i > line_maximum
  76.          loop
  77.             from
  78.                j := column_minimum;
  79.             until
  80.                j > column_maximum
  81.             loop
  82.                put(model.item(i,j),i,j);
  83.                j := j + 1;
  84.             end;
  85.             i := i + 1;
  86.          end;
  87.       ensure then
  88.          lower1 = model.lower1;
  89.          lower2 = model.lower2
  90.       end;
  91.    
  92.    from_collection(contents: COLLECTION[E];
  93.                    line_min, line_max, column_min, column_max: INTEGER) is
  94.          --  Reset all bounds using `line_min', `line_max', `column_min',
  95.          --  and `column_max' .
  96.          --  Copy all elements of `contents', line by line into Current.
  97.       require
  98.          line_min <= line_max;
  99.          column_min <= column_max;      
  100.          contents.count = (line_max - line_min + 1) * (column_max - column_min +1)
  101.       local
  102.          i: INTEGER 
  103.       do
  104.          make(line_min,line_max,column_min,column_max)
  105.          from 
  106.             i := 0  
  107.          until
  108.             i >= count
  109.          loop
  110.             storage.put(contents.item(contents.lower + i),i);
  111.             i := i + 1; 
  112.          end
  113.       ensure
  114.          line_minimum = line_min;
  115.          line_maximum = line_max;
  116.          column_minimum = column_min;
  117.          column_maximum = column_max;
  118.          count = contents.count
  119.       end
  120.  
  121.    from_model(model: COLLECTION[COLLECTION[E]]) is
  122.          -- The `model' is used to fill line by line the COLLECTION2.
  123.          -- Assume all sub-collections of `model' have the same indexing.
  124.       local
  125.          line, column: INTEGER;
  126.       do
  127.          make(model.lower,
  128.               model.upper,
  129.               model.first.lower,
  130.               model.first.upper);
  131.          from
  132.             line := model.lower;
  133.          until
  134.             line > model.upper
  135.          loop
  136.             from
  137.                column := model.first.lower
  138.             until
  139.                column > model.first.upper
  140.             loop
  141.                put(model.item(line).item(column),line,column);
  142.                column := column + 1;
  143.             end;
  144.             line := line + 1;
  145.          end;
  146.       ensure
  147.          line_minimum = model.lower;
  148.          line_maximum = model.upper;
  149.          column_minimum = model.first.lower;
  150.          column_maximum = model.first.upper
  151.       end;
  152.    
  153.    array2(model: ARRAY[ARRAY[E]]) is
  154.       obsolete "This feature will be soon removed. Use `from_model' instead."
  155.       do
  156.          from_model(model);
  157.       end;
  158.    
  159. feature -- Resizing :
  160.  
  161.    resize(line_min, line_max, column_min, column_max: INTEGER) is
  162.          -- Resize bounds of the Current array
  163.       require
  164.          line_max >= line_min;
  165.          column_max >= column_min;
  166.       local
  167.          tmp: like Current;
  168.          l, c: INTEGER;
  169.       do
  170.          !!tmp.make(line_min, line_max, column_min, column_max);
  171.          -- It may be possible to avoid this ceation when :
  172.          --    new `capacity' <= old `capacity'
  173.          from
  174.             l := lower1;
  175.          until
  176.             l > line_maximum
  177.          loop
  178.             from
  179.                c := lower2;
  180.             until
  181.                c > column_maximum
  182.             loop
  183.                if tmp.valid_index(l,c) then
  184.                   tmp.put(item(l,c),l,c);
  185.                end;
  186.                c := c + 1;
  187.             end;
  188.             l := l + 1;
  189.          end;
  190.          standard_copy(tmp);
  191.       ensure
  192.          line_minimum = line_min;
  193.          line_maximum = line_max;
  194.          column_minimum = column_min;
  195.          column_maximum = column_max;
  196.       end;
  197.    
  198. feature -- Implementation of others feature from COLLECTION2 :
  199.    
  200.    item(line, column: INTEGER): E is
  201.       do
  202.          Result := storage.item((line - lower1) * count2 + column - lower2);
  203.       end;
  204.  
  205.    put(element: like item; line, column: INTEGER) is
  206.       do
  207.          storage.put(element,(line - lower1) * count2 + column - lower2);
  208.       end;
  209.    
  210.    count1: INTEGER is
  211.       do
  212.          Result := upper1 - lower1 + 1;
  213.       end;
  214.    
  215.    count2: INTEGER is
  216.       do
  217.          Result := upper2 - lower2 + 1;
  218.       end;
  219.  
  220.    count: INTEGER is
  221.       do
  222.          Result := count1 * count2;
  223.       end;
  224.    
  225.    force(x: like item; line, column: INTEGER) is
  226.       require
  227.          true
  228.       do
  229.          if not valid_index(line,column) then
  230.             resize(line.min(lower1),
  231.                    line.max(upper1),
  232.                    column.min(lower2),
  233.                    column.max(upper2));
  234.          end;
  235.          put(x,line,column);
  236.       end;
  237.    
  238.    set_all_with(element: E) is
  239.       do
  240.          storage.set_all_with(element,count - 1);
  241.       end;
  242.    
  243.    replace_all(old_value, new_value: like item) is
  244.       do
  245.          storage.replace_all(old_value,new_value,count - 1);
  246.       end;
  247.          
  248.    fast_replace_all(old_value, new_value: like item) is
  249.       do
  250.          storage.fast_replace_all(old_value,new_value,count - 1);
  251.       end;
  252.          
  253.    sub_collection2(line_min, line_max, column_min, column_max: INTEGER): like Current is
  254.       require  
  255.          valid_index(line_min,line_max) 
  256.          valid_index(column_min,column_max)
  257.       local
  258.          i, j, k: INTEGER;
  259.       do
  260.          !!Result.make(line_min,line_max,column_min,column_max);
  261.          from
  262.             i := line_min;
  263.             k := 0;
  264.          until
  265.             i > line_max
  266.          loop
  267.             from
  268.                j := column_min;
  269.             until
  270.                j > column_max
  271.             loop
  272.                Result.storage.put(item(i,j),k);
  273.                j := j + 1;
  274.                k := k + 1;
  275.             end;
  276.             i := i + 1;
  277.          end;
  278.       ensure
  279.          Result.lower1 = line_min; 
  280.          Result.lower2 = column_min; 
  281.          Result.upper1 = line_max;
  282.          Result.upper2 = column_max;
  283.       end;
  284.  
  285. feature --  Looking and comparison :
  286.  
  287.    nb_occurrences(elt: E): INTEGER is
  288.          -- Number of occurrences using `equal'.
  289.          -- See also `fast_nb_occurrences' to chose
  290.          -- the apropriate one.
  291.       do
  292.          Result := storage.nb_occurrences(elt,count - 1);
  293.       ensure
  294.          Result >= 0;
  295.       end;
  296.    
  297.    fast_nb_occurrences(elt: E): INTEGER is
  298.          -- Number of occurrences using `='.
  299.       do
  300.          Result := storage.fast_nb_occurrences(elt,count - 1);
  301.       ensure
  302.          Result >= 0;
  303.       end;
  304.  
  305.    has(x: like item): BOOLEAN is
  306.          -- Search if a element x is in the array using `equal'.
  307.          -- See also `fast_has' to chose the apropriate one.
  308.       do
  309.          Result := storage.index_of(x,count - 1) <= count - 1;
  310.       end;
  311.    
  312.    fast_has(x: like item): BOOLEAN is
  313.          --  Search if a element x is in the array using `='.
  314.       do
  315.          Result := storage.fast_index_of(x,count - 1) <= count -1;
  316.       end;
  317.    
  318.    all_cleared : BOOLEAN is
  319.       do
  320.          result := storage.all_cleared(count - 1);
  321.       end;
  322.  
  323.    swap(line1, column1, line2, column2 : INTEGER) is
  324.       local
  325.          tmp: like item;
  326.          c2, index1, index2: INTEGER;
  327.       do
  328.          c2 := count2;
  329.          index1 := (line1 - lower1) * c2 + column1 - lower2;
  330.          index2 := (line2 - lower1) * c2 + column2 - lower2;
  331.          tmp := storage.item(index1);
  332.          storage.put(storage.item(index2),index1);
  333.          storage.put(tmp,index2);
  334.       end
  335.  
  336.    copy(other: like Current) is
  337.       do
  338.          lower1 := other.lower1;
  339.          upper1 := other.upper1;
  340.          lower2 := other.lower2;
  341.          upper2 := other.upper2;
  342.          if capacity < count then
  343.             capacity := count;
  344.             storage := storage.calloc(count);
  345.          end;
  346.          storage.copy_from(other.storage, count - 1);
  347.       end;
  348.    
  349.    is_equal(other: like Current): BOOLEAN is
  350.       do
  351.          if other = Current then
  352.             Result := true;
  353.          elseif lower1 /= other.lower1 then
  354.          elseif lower2 /= other.lower2 then
  355.          elseif upper1 /= other.upper1 then
  356.          elseif upper2 /= other.upper2 then
  357.          else
  358.             Result := storage.memcmp(other.storage,count);
  359.          end;
  360.       end;
  361.  
  362. feature -- Only for ARRAY2 :
  363.  
  364.    transpose is
  365.          -- Transpose the Current array
  366.       local
  367.          i,j : INTEGER;
  368.          oldu1,oldu2 : INTEGER;
  369.          oldl1,oldl2 : INTEGER;
  370.       do
  371.          oldu1 := line_maximum;
  372.          oldu2 := column_maximum;
  373.          oldl1 := lower1;
  374.          oldl2 := lower2;
  375.          resize(lower1.min(lower2),
  376.                 line_maximum.max(column_maximum),
  377.                 lower1.min(lower2),
  378.                 line_maximum.max(column_maximum));
  379.          from
  380.             i := lower1;
  381.          until 
  382.             i > line_maximum
  383.          loop
  384.             from 
  385.                j := i + 1;
  386.             until 
  387.                j > column_maximum
  388.             loop
  389.                swap(i,j,j,i);
  390.                j := j + 1;
  391.             end;
  392.             i := i + 1;
  393.          end;
  394.          resize(oldl2,oldu2,oldl1,oldu1);
  395.       ensure
  396.          line_minimum = old column_minimum; 
  397.          column_minimum = old line_minimum;
  398.          line_maximum = old column_maximum; 
  399.          column_maximum = old line_maximum;
  400.          count = old count;
  401.       end;
  402.  
  403.    to_external: POINTER is
  404.          -- Gives C access to the internal `storage' (may be dangerous).
  405.       do
  406.          Result := storage.to_external;
  407.       end;
  408.  
  409. feature {COLLECTION2}
  410.  
  411.    same_as(other: COLLECTION2[E]): BOOLEAN is
  412.       do
  413.          Result := other.same_as_array2(Current);
  414.       end;
  415.  
  416.    same_as_array2(other: ARRAY2[E]): BOOLEAN is
  417.       do
  418.          Result := standard_same_as(other);
  419.       end;
  420.  
  421.    same_as_fixed_array2(other: FIXED_ARRAY2[E]): BOOLEAN is
  422.       do
  423.          Result := standard_same_as(other);
  424.       end;
  425.  
  426. invariant
  427.  
  428.    count2 = upper2 - lower2 + 1;
  429.  
  430.    capacity >= count
  431.  
  432. end -- ARRAY2[E]
  433.