home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 3 / AACD03.BIN / AACD / Programming / sofa / archive / SmallEiffel.lha / SmallEiffel / lib_std / bit_n.e < prev    next >
Text File  |  1999-06-05  |  8KB  |  318 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 BIT_N
  13. --
  14. -- Indexed Bit sequences of length `N'. This class is a template,
  15. -- not a real class; to obtain a meaningful class, replace `N' 
  16. -- with a positive integer throughout.
  17. -- 
  18. -- An INTEGER index can be used to access each bit of the sequence.
  19. -- The leftmost bit has index 1 and the rightmost bit has index `N'.
  20. --
  21. -- Note 1 : corresponding C mapping depends on actual `N' and is 
  22. --        PLATFORM dependant (see class PLATFORM).
  23. --        When `N' is in range [0  .. Character_bits], C type 
  24. --        is a simple "unsigned char".
  25. --        When `N' is in range [Character_bits+1 .. Integer_bits],
  26. --        C type is "unsigned".
  27. --        When `N' is greater than Integer_bits, C type is C array
  28. --        of "unsigned" of the form :
  29. --                 "unsigned storage[`N' div Integer_bits]"
  30. --        The array is obviously big enough to fit with `N'. As
  31. --        for previous mapping, the left most bit (at index 1 in 
  32. --        Eiffel) is always the left most in C memory.
  33. --
  34. -- Note 2 : Eiffel BIT code is portable. Generated C code for class
  35. --        BIT may not be portable (because sizeof(int) may change).
  36. --        To produce a portable C code, you can compile your Eiffel
  37. --        code using a machine with very small sizeof(int). Also note
  38. --        that doing this may run a little bit slowly.
  39. --
  40.  
  41. inherit 
  42.    BIT_N_REF 
  43.       redefine out_in_tagged_out_memory, fill_tagged_out_memory
  44.    end;
  45.  
  46. feature {NONE}
  47.  
  48.    storage: POINTER;
  49.          -- The beginning of the storage zone (first byte
  50.          -- contains the beginning of the sequence).
  51.  
  52. feature -- Basic Accessing :
  53.    
  54.    count: INTEGER is
  55.          -- Number of bits in the sequence (the value of `N').
  56.       external "SmallEiffel"
  57.       end;
  58.  
  59.    item(idx: INTEGER): BOOLEAN is
  60.          -- True if i-th bit is 1, false otherwise.
  61.       require
  62.          inside_bounds: 1 <= idx and then idx <= count
  63.       external "SmallEiffel"
  64.       end;
  65.    
  66.    put(value: BOOLEAN; idx: INTEGER) is
  67.          -- Set bit `idx' to 1 if value is true, 0 otherwise.
  68.       require
  69.          inside_bounds: 1 <= idx and idx <= count
  70.       external "SmallEiffel"
  71.       ensure
  72.          value = item(idx)
  73.       end;
  74.  
  75.    put_1(idx: INTEGER) is
  76.          -- Set bit `idx' to 1.
  77.       require
  78.          inside_bounds: 1 <= idx and idx <= count
  79.       external "SmallEiffel"
  80.       ensure
  81.          item(idx)
  82.       end;
  83.  
  84.    put_0(idx: INTEGER) is
  85.          -- Set bit `idx' to 0.
  86.       require
  87.          inside_bounds: 1 <= idx and idx <= count
  88.       external "SmallEiffel"
  89.       ensure
  90.          not item(idx)
  91.       end;
  92.  
  93. feature -- Rotating and shifting :
  94.  
  95.    infix "^" (s: INTEGER): like Current is 
  96.          -- Sequence shifted by `s' positions (positive `s' shifts 
  97.          -- right, negative left; bits falling off the sequence's
  98.          -- bounds are lost).
  99.          -- See also infix "@>>" and infix "@<<".
  100.       require
  101.          s.abs < count
  102.       do
  103.          if s >= 0 then
  104.             if s = 0 then
  105.                Result := Current;
  106.             else
  107.                Result := Current @>> s;
  108.             end;
  109.          else
  110.             Result := Current @<< -s;
  111.          end;
  112.       end;
  113.  
  114.    infix "@>>" (s: INTEGER): like Current is 
  115.          -- Sequence shifted right by `s' positions.
  116.          -- Same as infix "^" when `s' is positive (may run a little 
  117.          -- bit faster).
  118.       require
  119.          s > 0
  120.       external "SmallEiffel"
  121.       end;
  122.  
  123.    infix "@<<" (s: INTEGER): like Current is 
  124.          -- Sequence shifted left by `s' positions.
  125.          -- Same as infix "^" when `s' is negative (may run a little 
  126.          -- bit faster.
  127.       require
  128.          s > 0
  129.       external "SmallEiffel"
  130.       end;
  131.  
  132.    infix "#" (s: INTEGER): like Current is 
  133.          -- Sequence rotated by `s' positions (positive right,
  134.          -- negative left).
  135.       require
  136.          s.abs < count;
  137.       do
  138.          if s >= 0 then
  139.             Result := Current #>> s;
  140.          else
  141.             Result := Current #<< -s;
  142.          end;
  143.       end
  144.  
  145.    infix "#>>" (s: INTEGER): like Current is 
  146.          -- Sequence rotated by `s' positions right.      
  147.       require
  148.          s >= 0;
  149.          s < count
  150.       local
  151.          i: INTEGER;
  152.          bit: BOOLEAN;
  153.       do
  154.          Result := Current;
  155.          from
  156.             i := s;
  157.          until
  158.             i = 0
  159.          loop
  160.             bit := Result.item(count);
  161.             Result := Result @>> 1;
  162.             Result.put(bit,1);
  163.             i := i - 1;
  164.          end;
  165.       end;
  166.    
  167.    infix "#<<" (s: INTEGER): like Current is 
  168.              -- Sequence rotated by `s' positions left.      
  169.       require
  170.          s >= 0;
  171.          s < count
  172.       local
  173.          i: INTEGER;
  174.          bit: BOOLEAN;
  175.       do
  176.          from
  177.             i := s;
  178.             Result := Current;
  179.          until
  180.             i = 0
  181.          loop
  182.             bit := Result.item(1);
  183.             Result := Result @<< 1;
  184.             Result.put(bit,count);
  185.             i := i - 1;
  186.          end;
  187.       end;
  188.    
  189. feature -- Bitwise Logical Operators :
  190.  
  191.    infix "and" (other: like Current): like Current is
  192.          -- Bitwise `and' of Current with `other'
  193.       external "SmallEiffel"
  194.       end;
  195.  
  196.    infix "implies" (other: like Current): like Current is
  197.          -- Bitwise implication of Current with `other'
  198.       do
  199.          Result := (not Current) or other;
  200.       end;
  201.  
  202.    prefix "not": like Current is
  203.          -- Bitwise `not' of Current.
  204.       external "SmallEiffel"
  205.       end;
  206.  
  207.    infix "or" (other: like Current): like Current is
  208.          -- Bitwise `or' of Current with `other'
  209.       external "SmallEiffel"
  210.       end;
  211.  
  212.    infix "xor" (other : like Current) : like Current is
  213.          -- Bitwise `xor' of Current with `other'
  214.       external "SmallEiffel"
  215.       end;
  216.  
  217. feature -- Conversions :
  218.  
  219.    to_string: STRING is
  220.          -- String representation of bit sequence. 
  221.          -- A zero bit is mapped to '0', a one bit to '1'. 
  222.          -- Leftmost bit is at index 1 in the returned string.
  223.          --
  224.          -- Note: see `append_in' to save memory.
  225.       do
  226.          tmp_string.clear;
  227.          append_in(tmp_string);
  228.          Result := tmp_string.twin;
  229.       ensure then
  230.          Result.count = count
  231.       end;
  232.    
  233.    to_integer: INTEGER is
  234.          -- No sign-extension.
  235.       require
  236.          count <= Integer_bits
  237.       external "SmallEiffel"
  238.       end;
  239.  
  240.    to_character: CHARACTER is
  241.       require
  242.          count <= Character_bits
  243.       external "SmallEiffel"
  244.       end;
  245.  
  246.    to_bit_string: BIT_STRING is
  247.       local
  248.          i: INTEGER;
  249.       do
  250.          from
  251.             !!Result.make(count);
  252.             i := count;
  253.          until
  254.             i = 0
  255.          loop
  256.             if item(i) then
  257.                Result.put_1(i);
  258.             end;
  259.             i := i - 1;
  260.          end;
  261.       ensure
  262.          count = Result.count
  263.       end;
  264.  
  265. feature -- Others :
  266.  
  267.    all_cleared: BOOLEAN is
  268.          -- Are all bits set to 0 ?
  269.       local
  270.         other: like Current;
  271.       do
  272.          Result := Current = other;
  273.       end;
  274.  
  275.    all_set: BOOLEAN is
  276.          -- Are all bits set to 1 ?
  277.       local
  278.         other: like Current;
  279.       do
  280.          Result := Current = not other;
  281.       end;
  282.  
  283. feature -- Printing :
  284.  
  285.    append_in(str: STRING) is
  286.       local
  287.          i: INTEGER;
  288.       do
  289.          from  
  290.             i := 1;
  291.          until
  292.             i > count
  293.          loop
  294.             if item(i) then
  295.                str.extend('1');
  296.             else
  297.                str.extend('0');
  298.             end;
  299.             i := i + 1;
  300.          end;
  301.       end;
  302.    
  303.    out_in_tagged_out_memory, fill_tagged_out_memory is
  304.       do
  305.          Current.append_in(tagged_out_memory);
  306.          tagged_out_memory.extend('B');
  307.       end;
  308.  
  309. feature {NONE}
  310.  
  311.    tmp_string: STRING is
  312.       once
  313.          !!Result.make(128);
  314.       end;
  315.  
  316. end -- BIT_N
  317.  
  318.