Sometimes you need a little bitmanipulation, but you are worried about all those AND, OR, XOR, SHL and SHR? So why don't you give a simple but smart set a chance?

First of all, we give the bits names for better handling, then we defining the sets, that represent the bits in a machine word:

`type Bits = (Bit0,  Bit1,  Bit2,  Bit3,  Bit4,             Bit5,  Bit6,  Bit7,  Bit8,  Bit9,             Bit10, Bit11, Bit12, Bit13, Bit14,             Bit15, Bit16, Bit17, Bit18, Bit19,             Bit20, Bit21, Bit22, Bit23, Bit24,             Bit25, Bit26, Bit27, Bit28, Bit29,             Bit30, Bit31, Bit32, Bit33, Bit34,             Bit35, Bit36, Bit37, Bit38, Bit39,             Bit40, Bit41, Bit42, Bit43, Bit44,             Bit45, Bit46, Bit47, Bit48, Bit49,             Bit50, Bit51, Bit52, Bit53, Bit54,             Bit55, Bit56, Bit57, Bit58, Bit59,             Bit60, Bit61, Bit62, Bit63);// Now we define the sets:type TByteBits = set of Bit0..Bit7;     TWordBits = set of Bit0..Bit15;     TLongBits = set of Bit0..Bit31;     TInt64Bits = set of Bit0..Bit63;                  // or set of Bits;`

Thats nearly all. To set, clear or test a bit, we just use the usual set operators:

To set a bit
`Include (mybitset, Bit24);`
To clear it
`Exclude (mybitset, Bit15);`
Test it
`if Bit5 in mybitset then ...`

Even you can do bitwise manipulation:

AND
`mybitset:= [Bit7, Bit8] * [Bit5, Bit6];`
OR
`mybitset:= [Bit7, Bit5] + [Bit5, Bit6];`

To transfer numeric values to the Bitsets you can use these functions:

`function ValToByteBits         (CONST v8: Byte): TByteBits;// convert a Byte to a Bitsetvar b: TByteBits absolute v8;begin Result:= b;end;function ValToWordBits         (CONST v16: Word): TWordBits;// convert a Word to a Bitsetvar b: TWordBits absolute v16;begin Result:= b;end;function ValToLongBits         (CONST v32: Integer): TLongBits;// convert a Longword to a Bitsetvar b: TLongBits absolute v32;begin Result:= b;end;function ValToInt64Bits         (CONST v64: Int64): TInt64Bits;// convert a Int64 to a Bitsetvar b: TInt64Bits absolute i64;begin Result:= b;end;`

These functions turn the set back to an numeric value:

`function BitsToByte         (CONST v8: TByteBits): Byte;// convert a Bitset to a Bytevar b: Byte absolute v8;begin Result:= b;end;function BitsToWord         (CONST v16: TWordBits): Word;// convert a Bitset to a Wordvar b: Word absolute v16;begin Result:= b;end;function BitsToInteger         (CONST v32: TLongBits): Integer;// convert a Bitset to a Integervar b: Integer absolute v32;begin Result:= b;end;function BitsToInt64         (CONST v64: TInt64Bits): Int64;// convert a Bitset to a Int64var b: Int64 absolute v64;begin Result:= b;end;`

As you see, we use the absolute directive to advice the compiler to put the local variable "on top" of the function parameter. With this technique the compiler produces a minimum of code and we get high performance.

##### Counting Bits

As seen before, bit manipulation is an easy job if you treat the bits as a set. Now I will show you a function, that will count the number of Bits (or Elements) in a given variable. In this function we use a special Pascal feature, the anonymous parameter. The parameter setvar is declared without any type. In fact, when we call the function we can put any variable on this place - not only a set for example, but we need to know the concrete size in bytes of the parameter to avoid reading outside the variable. To inner restrictions of the function, the size of the variable is limited to 256 Bit (the maximum size for a set). If you need more, make the type TBitArray bigger.

```function CountBits (CONST setvar; size: Integer): Integer;
// First we declare an array of Bitsets:
type TBitArray = array [0..31] of TByteBits;
// We set it on top of setvar
var bits: TBitArray absolute setvar;
i, c: Integer; // counting variables
b: Bits;
begin
c:= 0; // start value for number of bits
// count the number of bytes
for i:= 0 to size - 1 do begin
// for each byte count the number of bits
for b:= Bit0 to Bit7 do begin
if b in bits[i] then Inc (c);
end;
end;
Result:= c;
end;
```