unit bitwiseclass;

{*=====================================================================
  Classes:   ByteBitWise, WordBitWise, DWordBitWise, DDWordBitWise and
             BitWise

  File:      bitwiseclass.pas

  Summary:

       ByteBitWise, WordBitWise, DWordBitWise, DDWordBitWise  are
       classes to support shl and shr operations at byte, word (UInt16),
       DWORD (UInt32) or UInt64 (DDWord) level need unsafe .NET by default.
       The 5th class is BitWise, which useable for these level by
       demonstrate the selection of the best method according to length of
       parameter. This class also contain methods to select HI and LO bytes
       from a Word or HI and LO Words of a DWord respectively. So, you can
       reach all of the bytes of a DWord.

       //UInt64 bit methods probably need more tests
---------------------------------------------------------------------
  This file is submitted by:

  endresy@axelero.hu
  Endre I. Simay,
  Hungary

THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
=====================================================================*}
interface

type
  ByteBitWise = class
    ext: array[0..7] of byte;
  public
    constructor Create;
    function byteshr(basic: byte; n: byte): byte;
    function byteshl(basic: byte; n: byte): byte;
  end;
  TByteBitWise = class (ByteBitWise);

  WordBitWise = class
    ext: array[0..15] of word;
  public
    constructor Create;
    function wordshr(basic: word; n: word): word;
    function wordshl(basic: word; n: word): word;
  end;
  TWordBitWise = class (WordBitWise);

  DWordBitWise = class
    ext: array[0..31] of UInt32;
  public
    constructor Create;
    function dwordshr(basic: UInt32; n: UInt32): UInt32;
    function dwordshl(basic: UInt32; n: UInt32): UInt32;
  end;
  TDWordBitWise = class (DWordBitWise);

  DDWordBitWise = class
    ext: array[0..63] of UInt64;
  public
    constructor Create;
    function ddwordshr(basic: UInt64; n: UInt64): UInt64;
    function ddwordshl(basic: UInt64; n: UInt64): UInt64;
  end;
  TDDWordBitWise = class (DDWordBitWise);

  BitWise = class
    ext8: array[0..7] of byte;
    ext16: array[0..15] of word;
    ext32: array[0..31] of UInt32;
    ext64: array[0..63] of UInt64;
  public
    constructor Create;
    function bitwiseshr(basic: byte; n: byte): byte; overload;
    function bitwiseshl(basic: byte; n: byte): byte; overload;

    function bitwiseshr(basic: word; n: word): word; overload;
    function bitwiseshl(basic: word; n: word): word; overload;

    function bitwiseshr(basic: UInt32; n: UInt32): UInt32; overload;
    function bitwiseshl(basic: UInt32; n: UInt32): UInt32; overload;

    function bitwiseshr(basic: UInt64; n: UInt64): UInt64; overload;
    function bitwiseshl(basic: UInt64; n: UInt64): UInt64; overload;

    function bitwiseLO(basic: word): byte; overload;
    function bitwiseHI(basic: word): byte; overload;

    function bitwiseLO(basic: UInt32): word; overload;
    function bitwiseHI(basic: UInt32): word; overload;

    function bitwiseLO(basic: UInt64): UInt32; overload;
    function bitwiseHI(basic: UInt64): UInt32; overload;
  end;
  TBitWise = class (BitWise);

implementation

constructor ByteBitWise.Create;
var
  i: integer;
begin
  inherited;
  ext[0] := 1;
  for i := 1 to 7 do // 1, 2, 4, 8, 16, 32, 64, 128...;
  begin
    ext[i] := byte(ext[i - 1] * 2);
  end;
end;

function ByteBitWise.byteshr(basic: byte; n: byte): byte;
begin
  Result := byte(basic div ext[n and (8 - 1)]);
end;

function ByteBitWise.byteshl(basic: byte; n: byte): byte;
begin
  Result := byte(basic * ext[n and (8 - 1)]);
end;


constructor WordBitWise.Create();
var
  i: integer;
begin
  inherited;
  ext[0] := 1;
  for i := 1 to 15 do // 1, 2, 4, 8, 16, 32, 64, 128...;
  begin
    ext[i] := word(ext[i - 1] * 2);
  end;
end;

function WordBitWise.wordshr(basic: word; n: word): word;
begin
  Result := word(basic div ext[n and (16 - 1)]);
end;

function WordBitWise.wordshl(basic: word; n: word): word;
begin
  Result := word(basic * ext[n and (16 - 1)]);
end;

constructor DWordBitWise.Create();
var
  i: integer;
begin
  inherited;
  ext[0] := 1;
  for i := 1 to 31 do // 1, 2, 4, 8, 16, 32, 64, 128...;
  begin
    ext[i] := UInt32(ext[i - 1] * 2);
  end;
end;

function DWordBitWise.dwordshr(basic: UInt32; n: UInt32): UInt32;
begin
  Result := UInt32(basic div ext[n and (32 - 1)]);
end;

function DWordBitWise.dwordshl(basic: UInt32; n: UInt32): UInt32;
begin
  Result := UInt32(basic * ext[n and (32 - 1)]);
end;

constructor DDWordBitWise.Create();
var
  i: integer;
begin
  inherited;
  ext[0] := 1;
  for i := 1 to 31 do // 1, 2, 4, 8, 16, 32, 64, 128...;
  begin
    ext[i] := UInt64(ext[i - 1] * 2);
  end;
end;

function DDWordBitWise.ddwordshr(basic: UInt64; n: UInt64): UInt64;
begin
  Result := UInt64(basic div ext[n and (64 - 1)]);
end;

function DDWordBitWise.ddwordshl(basic: UInt64; n: UInt64): UInt64;
begin
  Result := UInt64(basic * ext[n and (64 - 1)]);
end;

constructor BitWise.Create();
var
  i: integer;
begin
  inherited;
  ext8[0] := 1;
  ext16[0] := 1;
  ext32[0] := 1;
  ext64[0] := 1;

  for i := 1 to 63 do // 1, 2, 4, 8, 16, 32, 64, 128...;
  begin
    if (i < 8) then
    begin
      ext8[i] := byte(ext8[i - 1] * 2);
    end;
    if (i < 16) then
    begin
      ext16[i] := word(ext16[i - 1] * 2);
    end;
    if (i < 32) then
    begin
      ext32[i] := UInt32(ext32[i - 1] * 2);
    end;
    ext64[i] := UInt64(ext64[i - 1] * 2);
  end;
end;

function BitWise.bitwiseshr(basic: byte; n: byte): byte;
begin
  Result := byte(basic div ext8[n and (8 - 1)]);
end;

function BitWise.bitwiseshl(basic: byte; n: byte): byte;
begin
  Result := byte(basic * ext8[n and (8 - 1)]);
end;

function BitWise.bitwiseshr(basic: word; n: word): word;
begin
  Result := (basic div ext16[n and (16 - 1)]);
end;

function BitWise.bitwiseshl(basic: word; n: word): word;
begin
  Result := (basic * ext16[n and (16 - 1)]);
end;

function BitWise.bitwiseshr(basic: UInt32; n: UInt32): UInt32;
begin
  Result := UInt32(basic div ext32[n and (32 - 1)]);
end;

function BitWise.bitwiseshl(basic: UInt32; n: UInt32): UInt32;
begin
  Result := UInt32(basic * ext32[n and (32 - 1)]);
end;

function BitWise.bitwiseshr(basic: UInt64; n: UInt64): UInt64;
begin
  Result := UInt64(basic div ext64[n and (64 - 1)]);
end;

function BitWise.bitwiseshl(basic: UInt64; n: UInt64): UInt64;
begin
  Result := UInt64(basic * ext64[n and (64 - 1)]);
end;

function BitWise.bitwiseLO(basic: word): byte;
begin
  Result := byte(basic);
end;

function BitWise.bitwiseHI(basic: word): byte;
begin
  Result := byte(bitwiseshr((basic), word(8)));
end;

function BitWise.bitwiseLO(basic: UInt32): word;
begin
  Result := word(basic);
end;

function BitWise.bitwiseHI(basic: UInt32): word;
begin
  Result := word(bitwiseshr(UInt32(basic), UInt32(16)));
end;

function BitWise.bitwiseLO(basic: UInt64): UInt32;
begin
  Result := UInt32(basic);
end;

function BitWise.bitwiseHI(basic: UInt64): UInt32;
begin
  Result := UInt32(bitwiseshr((basic), UInt64(32)));
end;

end.
