home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / eiffel / smalleif.97 / se.t / SmallEiffel / lib_std / collection.e < prev    next >
Encoding:
Text File  |  1996-05-02  |  7.9 KB  |  419 lines

  1. -- Part of SmallEiffel -- Read DISCLAIMER file -- Copyright (C) 
  2. -- Dominique COLNET and Suzanne COLLIN -- colnet@loria.fr
  3. --
  4. deferred class COLLECTION[E]
  5. -- 
  6. -- Such a collection is a traversable one using INTEGER indexing
  7. -- from `lower' to `upper'.
  8. -- Standard ARRAY[E] inherit from COLLECTION[E].
  9. --
  10.  
  11. inherit
  12.    ANY
  13.       undefine copy 
  14.       redefine is_equal, print_attributes_on 
  15.       end;
  16.  
  17. feature -- Indexing :
  18.  
  19.    lower: INTEGER is
  20.      -- Lower index bound.
  21.       deferred
  22.       end;
  23.  
  24.    upper: INTEGER is
  25.      -- Upper index bound.
  26.       deferred
  27.       end;
  28.  
  29.    valid_index(index: INTEGER): BOOLEAN is
  30.      -- True when `index' is valid (ie inside actual bounds).
  31.       do
  32.      Result := lower <= index and then index <= upper;
  33.       ensure      
  34.      Result = (lower <= index and index <= upper);
  35.       end;
  36.  
  37.    count: INTEGER is
  38.      -- Length of index interval.
  39.       do
  40.      Result := upper - lower + 1;
  41.       end;
  42.  
  43.    empty: BOOLEAN is
  44.      -- Is collection empty?
  45.       do
  46.      Result := (count = 0);
  47.       end;
  48.  
  49. feature -- Accessing :
  50.  
  51.    infix "@", item(index: INTEGER): E is
  52.      -- Item at position `index'.
  53.       require
  54.      inside_bounds: valid_index(index)
  55.       deferred
  56.       end;
  57.  
  58.    first: E is
  59.       require
  60.      count >= 1
  61.       do
  62.      Result := item(lower);
  63.       end;
  64.    
  65.    last: E is
  66.       require
  67.      count >= 1
  68.       do
  69.      Result := item(upper);
  70.       end;
  71.  
  72. feature -- Writing :
  73.  
  74.    put(element: E; index: INTEGER) is
  75.      -- Put `element' at position `index'.
  76.       require
  77.      valid_index(index)
  78.       deferred
  79.       ensure
  80.      item(index) = element
  81.       end;
  82.  
  83.    swap(i1, i2: INTEGER) is
  84.       require
  85.      valid_index(i1);
  86.      valid_index(i2);
  87.       local
  88.      tmp: E;
  89.      -- *** WHAT ABOUT like item ?
  90.       do
  91.      tmp := item(i1);
  92.      put(item(i2),i1);
  93.      put(tmp,i2);
  94.       ensure
  95.      item(i1) = old item(i2);
  96.      item(i2) = old item(i1);
  97.       end;
  98.         
  99.    set_all_with(v: E) is
  100.      -- Set all item with `v'.
  101.       local
  102.      i: INTEGER;
  103.       do
  104.      from  
  105.         i := upper;
  106.      until
  107.         i < lower
  108.      loop
  109.         put(v,i);
  110.         i := i - 1;
  111.      end;      
  112.       ensure
  113.      count = old count
  114.       end;
  115.    
  116.    set_slice_with(v: E; lower_index, upper_index: INTEGER) is
  117.      -- Set all item with `v'.
  118.       require
  119.      lower_index <= upper_index;
  120.      valid_index(lower_index);
  121.      valid_index(upper_index);
  122.       local
  123.      i: INTEGER;
  124.       do
  125.      from  
  126.         i := lower_index;
  127.      until
  128.         i > upper_index
  129.      loop
  130.         put(v,i);
  131.         i := i + 1;
  132.      end;      
  133.       ensure
  134.      count = old count
  135.       end;
  136.    
  137.     clear_all is
  138.      -- Set all items to default values.
  139.       local
  140.      value: E;
  141.       do
  142.      set_all_with(value);
  143.       ensure
  144.      count = old count;
  145.       end;
  146.    
  147. feature -- Looking and Searching :
  148.  
  149.    has(x: E): BOOLEAN is
  150.      -- Look for `x' using `equal'.
  151.       do
  152.      Result := (index_of(x) /= upper + 1);
  153.       end;
  154.    
  155.    fast_has(x: E): BOOLEAN is
  156.      -- Same as `has' but use `='.
  157.       do
  158.      Result := (fast_index_of(x) /= upper + 1);
  159.       end;
  160.    
  161.    index_of(x: E): INTEGER is
  162.      -- Give the index of the first occurrence of `x' using `equal'.
  163.      -- Answer `upper + 1' when `x' is not inside.
  164.       do
  165.      from  
  166.         Result := lower;
  167.      until
  168.         (Result > upper) or else equal_like(x,item(Result))
  169.      loop
  170.         Result := Result + 1;
  171.      end;
  172.       ensure
  173.      lower <= Result;
  174.      Result <= upper + 1;
  175.      Result <= upper implies equal(x,item(Result));
  176.       end;
  177.    
  178.    fast_index_of(x: E): INTEGER is
  179.      -- Same as `index_of' but use `=' for comparison.
  180.       do
  181.      from  
  182.         Result := lower;
  183.      until
  184.         (Result > upper) or else x = item(Result)
  185.      loop
  186.         Result := Result + 1;
  187.      end;
  188.       ensure
  189.      lower <= Result;
  190.      Result <= upper + 1;
  191.      Result <= upper implies x = item(Result);
  192.       end;
  193.    
  194. feature -- Looking and comparison :
  195.  
  196.    is_equal(other: like Current): BOOLEAN is
  197.      -- Use `equal' to compare elements. 
  198.       local
  199.      i: INTEGER;
  200.      e1, e2: E;
  201.       do
  202.      if Current = other then
  203.         Result := true;
  204.      elseif lower = other.lower and then 
  205.         upper = other.upper then
  206.         from
  207.            Result := true;
  208.            i := lower;
  209.         until
  210.            i > upper or not Result
  211.         loop
  212.            Result := equal_like(item(i),other.item(i));
  213.            i := i + 1;
  214.         end;        
  215.      end;
  216.       end;
  217.  
  218.    all_cleared: BOOLEAN is
  219.      -- Are all items set to default values?
  220.       local
  221.      value: E;
  222.      i: INTEGER;
  223.       do
  224.      from  
  225.         Result := true;
  226.         i := lower;
  227.      until
  228.         i > upper
  229.      loop
  230.         Result := value = item(i);
  231.         if Result then
  232.            i := i + 1;
  233.         else
  234.            i := upper + 1;
  235.         end;
  236.      end;
  237.       end;
  238.  
  239.    nb_occurrences(elt: E): INTEGER is
  240.      -- Number of occurrences using `equal'.
  241.      -- See also `fast_nb_occurrences' to chose
  242.      -- the apropriate one.
  243.       local
  244.      i: INTEGER;
  245.       do
  246.      from  
  247.         i := lower;
  248.      until
  249.         i > upper
  250.      loop
  251.         if equal_like(elt,item(i)) then
  252.            Result := Result + 1;
  253.         end;
  254.         i := i + 1;
  255.      end;
  256.       ensure
  257.      Result >= 0;
  258.       end;
  259.       
  260.    fast_nb_occurrences(elt: E): INTEGER is
  261.      -- Number of occurrences using `='.
  262.       local
  263.      i: INTEGER;
  264.       do
  265.      from  
  266.         i := lower;
  267.      until
  268.         i > upper
  269.      loop
  270.         if elt = item(i) then
  271.            Result := Result + 1;
  272.         end;
  273.         i := i + 1;
  274.      end;
  275.       ensure
  276.      Result >= 0;
  277.       end;
  278.       
  279. feature -- Printing :
  280.  
  281.    print_attributes_on(file: STD_FILE_WRITE) is
  282.       local
  283.      counter, i: INTEGER;
  284.      v: like item;
  285.       do
  286.      file.put_string("lower: "); 
  287.      file.put_integer(lower);
  288.      file.put_string(" upper: "); 
  289.      file.put_integer(upper);
  290.      file.put_string(" [");
  291.      from  
  292.         i := lower;
  293.         counter := 10;
  294.      until
  295.         i > upper or else counter = 0
  296.      loop
  297.         v := item(i);
  298.         if v.is_expanded_type then
  299.            v.print_on(file);
  300.         elseif ("STRING").is_equal(v.generator) then
  301.            v.print_on(file);
  302.         else
  303.            file.put_string(v.generating_type);
  304.            file.put_character('#');
  305.            file.put_integer(v.object_id);
  306.         end;
  307.         if i < upper then
  308.            file.put_character(' ');
  309.         end;
  310.         i := i + 1;
  311.         counter := counter - 1;
  312.      end;
  313.      if i <= upper then
  314.         file.put_string(" ..."); 
  315.      end;
  316.      file.put_character(']'); 
  317.       end;
  318.  
  319. feature -- Other Features :
  320.  
  321.    clear is
  322.      -- Discard all items.
  323.       deferred
  324.       ensure
  325.      empty;
  326.       end;
  327.  
  328.    replace_all(x, r: E) is
  329.       local
  330.      i: INTEGER;
  331.       do
  332.      from
  333.         i := lower;
  334.      until 
  335.         i > upper
  336.      loop
  337.         if equal_like(item(i),x) then
  338.            put(r,i);
  339.         end;
  340.         i := i + 1;
  341.      end;
  342.       end;
  343.    
  344.    fast_replace_all(x, r: E) is
  345.       local
  346.      i: INTEGER;
  347.       do
  348.      from 
  349.         i := lower;
  350.      until
  351.         i > upper
  352.      loop
  353.         if item(i) = x then
  354.            put(r, i);
  355.         end;
  356.         i := i + 1;
  357.      end;
  358.       end;
  359.  
  360.    move(lower_index, upper_index, distance: INTEGER) is
  361.      -- Move Range `lower_index' .. `upper_index' by `distance' 
  362.      -- positions. Negative distance moves towards lower indices.
  363.      -- Free places get default values.
  364.       require
  365.      lower_index <= upper_index;
  366.      valid_index(lower_index);
  367.      valid_index(lower_index + distance);
  368.      valid_index(upper_index);
  369.      valid_index(upper_index + distance);
  370.       local
  371.      default_value: E;
  372.      i: INTEGER;
  373.       do
  374.      if distance < 0 then
  375.         from  
  376.            i := lower_index;
  377.         until
  378.            i > upper_index
  379.         loop
  380.            put(item(i),i + distance);
  381.            put(default_value,i);
  382.            i := i + 1;
  383.         end;
  384.      elseif distance > 0 then
  385.         from  
  386.            i := upper_index;
  387.         until
  388.            i < lower_index
  389.         loop
  390.            put(item(i),i + distance);
  391.            put(default_value,i);
  392.            i := i - 1;
  393.         end;
  394.      end;
  395.       end;
  396.  
  397. feature {NONE}
  398.  
  399.    equal_like(e1, e2: E): BOOLEAN is
  400.      -- Note: to avoid calling `equal' :-(
  401.      -- Because SmallEiffel is not yet able to infer 
  402.      -- arguments types.
  403.       do
  404.      if e1.is_expanded_type then
  405.         Result := e1 = e2 or else e1.is_equal(e2);
  406.         --        *******
  407.         -- Problem with post-condition of ELKS standard_is_equal.
  408.         -- same_type is always false when receiver is an expanded 
  409.         -- type.
  410.      elseif e1 = e2 then
  411.         Result := true;
  412.      elseif e1 = Void or else e2 = Void then
  413.      else
  414.         Result := e1.is_equal(e2);
  415.      end;
  416.       end;
  417.  
  418. end -- COLLECTION
  419.