Emulating Pascal sets.

R

Rudy Velthuis

Trying to use a Delphi for .NET generated enum, which is actually a
Pascal set (a bitset where each bit corresponds to an item in an enum,
with special operators for union, section and difference), I noticed that
there is not really good way to iterate over such an enum consisting of
bits. Or is there?

Part of my test code:

namespace BitSetsTest
{
class Test
{
public enum Bits
{
a = 1,
b = 2,
c = 4,
d = 8,
e = 16,
f = 32,
g = 64,
h = 128
}

public static void WriteBits(Bits b)
{
for (int i = (int)Bits.a; i <= (int)Bits.h; i <<= 1)
if ((i & (int)b) != 0)
Console.Write("{0} ", (Bits)i);
else
Console.Write(". ");

Console.WriteLine();
}

// snip

My question is: is there a better way to iterate over the values of such
a bitset -- like I'm doing in WriteBits() -- than casting back and forth
between enum and int?

In Delphi I would do:

type
Bit = (a, b, c, d, e, f, g, h); // base enum

Bits = set of Bit; // set

procedure WriteBits(b: Bits);
var
i: Bit;
begin
for i := Low(Bit) to High(Bit) do
if i in b then
Write(i.ToString, ' ')
else
Write('. ');

In C# such a type turns out to be coded in IL as the enum described in
the C# code above. Is there a way to iterate over the individual bits?
 
C

Chris R. Timmons

Trying to use a Delphi for .NET generated enum, which is
actually a Pascal set (a bitset where each bit corresponds to an
item in an enum, with special operators for union, section and
difference), I noticed that there is not really good way to
iterate over such an enum consisting of bits. Or is there?

Part of my test code:

namespace BitSetsTest
{
class Test
{
public enum Bits
{
a = 1,
b = 2,
c = 4,
d = 8,
e = 16,
f = 32,
g = 64,
h = 128
}

public static void WriteBits(Bits b)
{
for (int i = (int)Bits.a; i <= (int)Bits.h; i <<=
1)
if ((i & (int)b) != 0)
Console.Write("{0} ", (Bits)i);
else
Console.Write(". ");

Console.WriteLine();
}

// snip

My question is: is there a better way to iterate over the values
of such a bitset -- like I'm doing in WriteBits() -- than
casting back and forth between enum and int?

In Delphi I would do:

type
Bit = (a, b, c, d, e, f, g, h); // base enum

Bits = set of Bit; // set

procedure WriteBits(b: Bits);
var
i: Bit;
begin
for i := Low(Bit) to High(Bit) do
if i in b then
Write(i.ToString, ' ')
else
Write('. ');

In C# such a type turns out to be coded in IL as the enum
described in the C# code above. Is there a way to iterate over
the individual bits?

Rudy,

Here's another way to iterate over a bit enumeration:

public static void WriteBits2(Bits b)
{
foreach (int i in System.Enum.GetValues(typeof(Bits)))
if ((i & (int) b) != 0)
Console.Write("{0} ", System.Enum.GetName(typeof(Bits), i));
else
Console.Write(". ");
}

Here's some good code that adds "set" operations to C#:

http://www.codeproject.com/csharp/Sets.asp


Hope this helps.

Chris.
 
R

Rudy Velthuis

At said:
Rudy,

Here's another way to iterate over a bit enumeration:

public static void WriteBits2(Bits b)
{
foreach (int i in System.Enum.GetValues(typeof(Bits)))
if ((i & (int) b) != 0)
Console.Write("{0} ", System.Enum.GetName(typeof(Bits), i));
else
Console.Write(". ");
}

Thanks, that was exactly the kind of code I was looking for. Someone had
already pointed me to the set emulation code on codeproject, but my
question was for existing Pascal sets, which are emulated in Delphi via
bit enums.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top