home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 3 / AACD03.BIN / AACD / Programming / sofa / archive / SmallEiffel.lha / SmallEiffel / lib_std / native_array.e < prev    next >
Text File  |  1999-06-05  |  14KB  |  514 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. expanded class NATIVE_ARRAY[E]
  13. --
  14. -- This class gives access to the lowest level for arrays both
  15. -- for the C language and Java language.
  16. -- 
  17. -- Warning : using this class makes your Eiffel code non
  18. -- portable on other Eiffel systems.
  19. -- This class may also be modified in further release for a better
  20. -- interoperability between Java and C low level arrays.
  21. --
  22.  
  23. feature -- Basic features :
  24.  
  25.    element_sizeof: INTEGER is
  26.          -- The size in number of bytes for type `E'.
  27.       external "SmallEiffel"
  28.       end;
  29.  
  30.    calloc(nb_elements: INTEGER): like Current is
  31.          -- Allocate a new array of `nb_elements' of type `E'.
  32.          -- The new array is initialized with default values.
  33.       external "SmallEiffel"
  34.       end;
  35.  
  36.    item(index: INTEGER): E is
  37.          -- To read an `item'.
  38.          -- Assume that `calloc' is already done and that `index'
  39.          -- is the range [0 .. nb_elements-1].
  40.       external "SmallEiffel"
  41.       end;
  42.  
  43.    put(element: E; index: INTEGER) is
  44.          -- To write an item.
  45.          -- Assume that `calloc' is already done and that `index'
  46.          -- is the range [0 .. nb_elements-1].
  47.       external "SmallEiffel"
  48.       end;
  49.  
  50. feature 
  51.  
  52.    realloc(old_nb_elts, new_nb_elts: INTEGER): like Current is
  53.          -- Assume Current is a valid NATIVE_ARRAY in range 
  54.          -- [0 .. `old_nb_elts'-1]. Allocate a bigger new array in
  55.          -- range [0 .. `new_nb_elts'-1].
  56.          -- Old range is copied in the new allocated array.
  57.          -- No initialization done for new items in C.
  58.          -- Initialization is done for Java.
  59.          --
  60.       require
  61.          is_not_null;
  62.          old_nb_elts < new_nb_elts
  63.       do
  64.          Result := calloc(new_nb_elts);
  65.          Result.copy_from(Current,old_nb_elts - 1);
  66.       end;
  67.  
  68. feature -- Comparison :
  69.  
  70.    memcmp(other: like Current; capacity: INTEGER): BOOLEAN is
  71.          -- True if all elements in range [0..capacity-1] are
  72.          -- identical using `equal'. Assume Current and `other' 
  73.          -- are big enough. 
  74.          -- See also `fast_memcmp'.
  75.       require
  76.          capacity > 0 implies other.is_not_null
  77.       local
  78.          i: INTEGER;
  79.       do
  80.          from
  81.             Result := true;
  82.             i := capacity - 1;
  83.          until
  84.             i < 0 or else not Result
  85.          loop
  86.             Result := equal_like(item(i),other.item(i));
  87.             i := i - 1;
  88.          end;
  89.       end;
  90.  
  91.    fast_memcmp(other: like Current; capacity: INTEGER): BOOLEAN is
  92.          -- Same jobs as `memcmp' but uses infix "=" instead `equal'.
  93.       require
  94.          capacity > 0 implies other.is_not_null
  95.       local
  96.          i: INTEGER;
  97.       do
  98.          from
  99.             Result := true;
  100.             i := capacity - 1;
  101.          until
  102.             i < 0 
  103.          loop
  104.             if item(i) = other.item(i) then
  105.                i := i - 1;
  106.             else
  107.                Result := false;
  108.                i := -1;
  109.             end;
  110.          end;
  111.       end;
  112.  
  113. feature -- Searching :
  114.  
  115.    index_of(element: like item; upper: INTEGER): INTEGER is
  116.          -- Give the index of the first occurrence of `element' using
  117.          -- `is_equal' for comparison.
  118.          -- Answer `upper + 1' when `element' is not inside.
  119.       require
  120.          upper >= -1
  121.       do
  122.          from  
  123.          until
  124.             Result > upper or else equal_like(element,item(Result))
  125.          loop
  126.             Result := Result + 1;
  127.          end;
  128.       end;
  129.  
  130.    fast_index_of(element: like item; upper: INTEGER): INTEGER is
  131.          -- Same as `index_of' but use basic `=' for comparison.
  132.       require
  133.          upper >= -1
  134.       do
  135.          from  
  136.          until
  137.             Result > upper or else element = item(Result)
  138.          loop
  139.             Result := Result + 1;
  140.          end;
  141.       end;
  142.  
  143.    has(element: like item; upper: INTEGER): BOOLEAN is
  144.          -- Look for `element' using `is_equal' for comparison.
  145.          -- Also consider `has' to choose the most appropriate.
  146.       require
  147.          upper >= -1
  148.       local
  149.          i: INTEGER;
  150.       do
  151.          from
  152.             i := upper;
  153.          until
  154.             Result or else i < 0
  155.          loop
  156.             Result := equal_like(element,item(i));
  157.             i := i - 1;
  158.          end;
  159.       end;
  160.  
  161.    fast_has(element: like item; upper: INTEGER): BOOLEAN is
  162.          -- Look for `element' using basic `=' for comparison.
  163.          -- Also consider `has' to choose the most appropriate.
  164.       require
  165.          upper >= -1
  166.       local
  167.          i: INTEGER;
  168.       do
  169.          from
  170.             i := upper;
  171.          until
  172.             Result or else i < 0
  173.          loop
  174.             Result := element = item(i);
  175.             i := i - 1;
  176.          end;
  177.       end;
  178.  
  179. feature -- Removing :
  180.  
  181.    remove_first(upper: INTEGER) is
  182.          -- Assume `upper' is a valid index.
  183.          -- Move range [1 .. `upper'] by 1 position left.
  184.       require
  185.          upper >= 0
  186.       local
  187.          i: INTEGER;
  188.       do
  189.          from 
  190.          until
  191.             i = upper
  192.          loop
  193.             put(item(i + 1),i);
  194.             i := i + 1;
  195.          end;
  196.       end;
  197.  
  198.    remove(index, upper: INTEGER) is
  199.          -- Assume `upper' is a valid index.
  200.          -- Move range [`index' + 1 .. `upper'] by 1 position left.
  201.       require
  202.          index >= 0;
  203.          index <= upper
  204.       local
  205.          i: INTEGER;
  206.       do
  207.          from 
  208.             i := index;
  209.          until
  210.             i = upper
  211.          loop
  212.             put(item(i + 1),i);
  213.             i := i + 1;
  214.          end;
  215.       end;
  216.  
  217. feature -- Replacing :
  218.  
  219.    replace_all(old_value, new_value: like item; upper: INTEGER) is
  220.          -- Replace all occurences of the element `old_value' by `new_value' 
  221.          -- using `is_equal' for comparison.
  222.          -- See also `fast_replace_all' to choose the apropriate one.
  223.       require
  224.          upper >= -1
  225.       local
  226.          i: INTEGER;
  227.       do
  228.          from
  229.             i := upper;
  230.          until
  231.             i < 0
  232.          loop
  233.             if equal_like(old_value,item(i)) then
  234.                put(new_value,i);
  235.             end;
  236.             i := i - 1;
  237.          end;
  238.       end;
  239.  
  240.  
  241.    fast_replace_all(old_value, new_value: like item; upper: INTEGER) is
  242.          -- Replace all occurences of the element `old_value' by `new_value' 
  243.          -- using basic `=' for comparison.
  244.          -- See also `replace_all' to choose the apropriate one.
  245.       require
  246.          upper >= -1
  247.       local
  248.          i: INTEGER;
  249.       do
  250.          from
  251.             i := upper;
  252.          until
  253.             i < 0
  254.          loop
  255.             if old_value = item(i) then
  256.                put(new_value,i);
  257.             end;
  258.             i := i - 1;
  259.          end;
  260.       end;
  261.  
  262. feature -- Adding :
  263.  
  264.    copy_at(start_index: INTEGER; model: like Current; model_capacity: INTEGER) is
  265.          -- Copy range [0 .. model_capacity-1] of `model' starting to 
  266.          -- write at `start_index' of Current.
  267.          -- Range [start_index .. start_index+model_capacity] of 
  268.          -- Current is affected (assume Current is large enough).
  269.       require
  270.          start_index >= 0;
  271.          model_capacity >= 0;
  272.          model_capacity > 0 implies model.is_not_null
  273.       local
  274.          i1, i2: INTEGER;
  275.       do
  276.          from
  277.             i1 := start_index;
  278.          until
  279.             i2 = model_capacity
  280.          loop
  281.             put(model.item(i2),i1);
  282.             i2 := i2 + 1;
  283.             i1 := i1 + 1;
  284.          end;
  285.       end;
  286.  
  287. feature -- Other :
  288.  
  289.    set_all_with(v: like item; upper: INTEGER) is
  290.          -- Set all elements in range [0 .. upper] with
  291.          -- value `v'.
  292.       local
  293.          i: INTEGER;
  294.       do
  295.          from
  296.             i := upper;
  297.          until
  298.             i < 0
  299.          loop
  300.             put(v,i);
  301.             i := i - 1;
  302.          end;
  303.       end;
  304.  
  305.    clear_all(upper: INTEGER) is
  306.          -- Set all elements in range [0 .. `upper'] with
  307.          -- the default value.
  308.       local
  309.          v: E;
  310.          i: INTEGER;
  311.       do
  312.          from
  313.             i := upper;
  314.          until
  315.             i < 0
  316.          loop
  317.             put(v,i);
  318.             i := i - 1;
  319.          end;
  320.       end;
  321.  
  322.    clear(lower, upper: INTEGER) is
  323.          -- Set all elements in range [`lower' .. `upper'] with
  324.          -- the default value
  325.       require
  326.          lower >= 0;
  327.          upper >= lower
  328.       local
  329.          v: E;
  330.          i: INTEGER;
  331.       do
  332.          from
  333.             i := lower
  334.          until
  335.             i > upper
  336.          loop
  337.             put(v, i);
  338.             i := i + 1;
  339.          end
  340.       end
  341.  
  342.    copy_from(model: like Current; upper: INTEGER) is
  343.          -- Assume `upper' is a valid index both in Current and `model'.
  344.       local
  345.          i: INTEGER;
  346.       do
  347.          from
  348.             i := upper;
  349.          until
  350.             i < 0
  351.          loop
  352.             put(model.item(i),i);
  353.             i := i - 1;
  354.          end;
  355.       end;
  356.  
  357.    move(lower, upper, offset: INTEGER) is
  358.          -- Move range [`lower' .. `upper'] by `offset' positions.
  359.          -- Freed positions are not initialized to default values.
  360.       require
  361.          lower >= 0;
  362.          upper >= lower;
  363.          lower + offset >= 0
  364.       local
  365.          i: INTEGER;
  366.       do
  367.          if offset = 0 then
  368.          elseif offset < 0 then
  369.             from
  370.                i := lower;
  371.             until
  372.                i > upper
  373.             loop
  374.                put(item(i), i + offset);
  375.                i := i + 1;
  376.             end
  377.          else
  378.             from
  379.                i := upper;
  380.             until
  381.                i < lower
  382.             loop
  383.                put(item(i), i + offset);
  384.                i := i - 1;
  385.             end
  386.          end
  387.       end
  388.  
  389.    nb_occurrences(element: like item; upper: INTEGER): INTEGER is
  390.          -- Number of occurrences of `element' in range [0..upper]
  391.          -- using `equal' for comparison.
  392.          -- See also `fast_nb_occurrences' to chose the apropriate one.
  393.       local
  394.          i: INTEGER;
  395.       do
  396.          from  
  397.             i := upper;
  398.          until
  399.             i < 0
  400.          loop
  401.             if equal_like(element,item(i)) then
  402.                Result := Result + 1;
  403.             end;
  404.             i := i - 1;
  405.          end;
  406.       end;
  407.  
  408.    fast_nb_occurrences(element: like item; upper: INTEGER): INTEGER is
  409.          -- Number of occurrences of `element' in range [0..upper]
  410.          -- using basic "=" for comparison.
  411.          -- See also `fast_nb_occurrences' to chose the apropriate one.
  412.       local
  413.          i: INTEGER;
  414.       do
  415.          from  
  416.             i := upper;
  417.          until
  418.             i < 0
  419.          loop
  420.             if element = item(i) then
  421.                Result := Result + 1;
  422.             end;
  423.             i := i - 1;
  424.          end;
  425.       end;
  426.  
  427.    all_cleared(upper: INTEGER): BOOLEAN is
  428.          -- Are all items in range [0..upper] set to default
  429.          -- values?
  430.       require
  431.          upper >= -1
  432.       local
  433.          i: INTEGER;
  434.          model: like item;
  435.       do
  436.          from
  437.             Result := true;
  438.             i := upper;
  439.          until
  440.             i < 0 or else not Result
  441.          loop
  442.             Result := model = item(i)
  443.             i := i - 1;
  444.          end;
  445.       end;
  446.  
  447. feature -- The Guru section :
  448.  
  449.    free is
  450.          -- Do nothing when producing Java byte code.
  451.          -- Do what's to be done when producing C code (depends
  452.          -- on GC is on or off).
  453.       obsolete "Since release -0.81, the Garbage Collector is %
  454.                %implemented. This feature will be soon removed."
  455.       do
  456.       end;
  457.  
  458. feature -- Interfacing with C :
  459.  
  460.    to_external: POINTER is
  461.          -- Gives access to the C pointer on the area of storage.
  462.       do
  463.          Result := to_pointer;
  464.       end;
  465.  
  466.    from_pointer(pointer: POINTER): like Current is
  467.          -- Convert `pointer' into Current type.
  468.       external "SmallEiffel"
  469.       end;
  470.  
  471.    is_not_null: BOOLEAN is
  472.       do
  473.          Result := to_pointer.is_not_null;
  474.       end;
  475.  
  476.    is_not_void: BOOLEAN is
  477.       obsolete "This feature will be soon removed. %
  478.                %Since release -0.78, the new name for this feature %
  479.                %is `is_not_null'. Please, update your code."
  480.       do
  481.          Result := is_not_null;
  482.       end;
  483.  
  484. feature -- For C only :
  485.  
  486.    bytes_malloc(nb_bytes: INTEGER): like Current is
  487.       obsolete "This dangerous feature will be soon removed. %
  488.                %Please, update your code."
  489.       external "C_InlineWithoutCurrent"
  490.       alias "malloc"
  491.       end;
  492.  
  493. feature {NONE}
  494.  
  495.    frozen equal_like(e1, e2: like item): BOOLEAN is
  496.          -- Note: this feature is called to avoid calling `equal'
  497.          -- on expanded types (no automatic conversion to 
  498.          -- corresponding reference type).
  499.       do
  500.          if e1.is_basic_expanded_type then
  501.             Result := e1 = e2;
  502.          elseif e1.is_expanded_type then
  503.             Result := e1.is_equal(e2);
  504.          elseif e1 = e2 then
  505.             Result := true;
  506.          elseif e1 = Void or else e2 = Void then
  507.          else
  508.             Result := e1.is_equal(e2);
  509.          end;
  510.       end;
  511.  
  512. end -- NATIVE_ARRAY[E]
  513.  
  514.