VCL类学习之(三) TBits

  1. Unit Classes;
  2. { TBits class }
  3.   TBits = class
  4.   private
  5.     FSize: Integer;
  6.     FBits: Pointer;
  7.     procedure Error;
  8.     procedure SetSize(Value: Integer);
  9.     procedure SetBit(Index: Integer; Value: Boolean);
  10.     function GetBit(Index: Integer): Boolean;
  11.   public
  12.     destructor Destroy; override;
  13.     function OpenBit: Integer;
  14.     property Bits[Index: Integer]: Boolean read GetBit write SetBit; default;
  15.     property Size: Integer read FSize write SetSize;
  16.   end;
  17. { TBits }
  18. const
  19.   BitsPerInt = SizeOf(Integer) * 8;
  20. type
  21.   TBitEnum = 0..BitsPerInt - 1;
  22.   TBitSet = set of TBitEnum;
  23.   PBitArray = ^TBitArray;
  24.   TBitArray = array[0..4096of TBitSet;
  25. destructor TBits.Destroy;
  26. begin
  27.   SetSize(0);
  28.   inherited Destroy;
  29. end;
  30. procedure TBits.Error;
  31. begin
  32.   raise EBitsError.CreateRes(@SBitsIndexError);
  33. end;
  34. procedure TBits.SetSize(Value: Integer);
  35. var
  36.   NewMem: Pointer;
  37.   NewMemSize: Integer;
  38.   OldMemSize: Integer;
  39.   function Min(X, Y: Integer): Integer;
  40.   begin
  41.     Result := X;
  42.     if X > Y then Result := Y;
  43.   end;
  44. begin
  45.   if Value <> Size then
  46.   begin
  47.     if Value < 0 then Error;
  48.     NewMemSize := ((Value + BitsPerInt - 1div BitsPerInt) * SizeOf(Integer);
  49.     OldMemSize := ((Size + BitsPerInt - 1div BitsPerInt) * SizeOf(Integer);
  50.     if NewMemSize <> OldMemSize then
  51.     begin
  52.       NewMem := nil;
  53.       if NewMemSize <> 0 then
  54.       begin
  55.         GetMem(NewMem, NewMemSize);
  56.         FillChar(NewMem^, NewMemSize, 0);
  57.       end;
  58.       if OldMemSize <> 0 then
  59.       begin
  60.         if NewMem <> nil then
  61.           Move(FBits^, NewMem^, Min(OldMemSize, NewMemSize));
  62.         FreeMem(FBits, OldMemSize);
  63.       end;
  64.       FBits := NewMem;
  65.     end;
  66.     FSize := Value;
  67.   end;
  68. end;
  69. procedure TBits.SetBit(Index: Integer; Value: Boolean); assembler;
  70. asm
  71.         CMP     Index,[EAX].FSize
  72.         JAE     @@Size
  73. @@1:    MOV     EAX,[EAX].FBits
  74.         OR      Value,Value
  75.         JZ      @@2
  76.         BTS     [EAX],Index
  77.         RET
  78. @@2:    BTR     [EAX],Index
  79.         RET
  80. @@Size: CMP     Index,0
  81.         JL      TBits.Error
  82.         PUSH    Self
  83.         PUSH    Index
  84.         PUSH    ECX {Value}
  85.         INC     Index
  86.         CALL    TBits.SetSize
  87.         POP     ECX {Value}
  88.         POP     Index
  89.         POP     Self
  90.         JMP     @@1
  91. end;
  92. function TBits.GetBit(Index: Integer): Boolean; assembler;
  93. asm
  94.         CMP     Index,[EAX].FSize
  95.         JAE     TBits.Error
  96.         MOV     EAX,[EAX].FBits
  97.         BT      [EAX],Index
  98.         SBB     EAX,EAX
  99.         AND     EAX,1
  100. end;
  101. function TBits.OpenBit: Integer;
  102. var
  103.   I: Integer;
  104.   B: TBitSet;
  105.   J: TBitEnum;
  106.   E: Integer;
  107. begin
  108.   E := (Size + BitsPerInt - 1div BitsPerInt - 1;
  109.   for I := 0 to E do
  110.     if PBitArray(FBits)^[I] <> [0..BitsPerInt - 1then
  111.     begin
  112.       B := PBitArray(FBits)^[I];
  113.       for J := Low(J) to High(J) do
  114.       begin
  115.         if not (J in B) then
  116.         begin
  117.           Result := I * BitsPerInt + J;
  118.           if Result >= Size then Result := Size;
  119.           Exit;
  120.         end;
  121.       end;
  122.     end;
  123.   Result := Size;
  124. end;
  125. Description
  126. Use TBits to store and access an indefinite number of boolean values. TBits can store as many of boolean values as can fit in available memory, automatically expanding its storage space as needed. If the number of boolean values is limited to 32, the same functionality can be achieved using a 32-bit integer with the bitwise AND (Delphi) or & (C++) and OR (Delphi) or | (C++) operators.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值