PDA

View Full Version : Variant parts record problem



masonwheeler
05-03-2008, 05:16 AM
Using variant parts in records makes a lot of things easier. For example, I wrote a color structure that looks like this:
TMyColor = record
case boolean of
false: (color: cardinal);
true: (rgba: packed array[1..4] of byte);
end;
It works great! Any changes made to the one interpretation get applied automatically to the other, because they're mapped to the same memory. But trying to set up a bitfield for easy bitwise operations... doesn't seem to work.
TBitfield16 = record
case boolean of
false: (num: word);
true: (bits: packed array[1..16] of boolean);
end;
In this one, changes made to the one value don't seem to affect the other one. Anyone know why, and how I can fix it?

cairnswm
05-03-2008, 05:43 AM
A boolean takes 1 byte of memory, not 1 bit



A Boolean variable occupies one byte of memory, a ByteBool variable also occupies one byte, a WordBool variable occupies two bytes (one word), and a LongBool variable occupies four bytes (two words).

masonwheeler
05-03-2008, 05:49 AM
Aww crap. I could have sworn that used to work in other versions...

JSoftware
05-03-2008, 05:52 AM
If you use FPC then you could do it with the bitpacked keyword:


TBitfield16 = bitpacked record
case boolean of
false: (num: word);
true: (bits: packed array[1..16] of boolean);
end;

masonwheeler
05-03-2008, 04:34 PM
Unfortunately, my code won't compile under Lazarus, so that's not an option for the moment.

I rewrote the whole thing using operator overloads, and most of them work... except for one that doesn't. Here's what I've got so far:
interface
type
TBitset16 = record
bits: array[1..16] of boolean;
class operator Implicit(a: word): TBitset16; inline; //works
class operator implicit(a: TBitset16): word; inline; //doesn't work
end;

implementation
{$R-}
class operator TBitset16.Implicit(a: word): TBitset16; //works
var
dummy: word;
i: integer;
begin
dummy := 1;
for I := 1 to 16 do
begin
result.bits[i] := (a and dummy > 0);
dummy := dummy shl 1;
end;
end;

class operator TBitset16.implicit(a: TBitset16): word; //doesn't work
var
dummy: word;
i: integer;
begin
result := 0;
dummy := 1;
for I := 1 to 16 do
begin
if a.bits[i] then
inc(result, dummy);
dummy := dummy shl 1;
end;
end;
{$R+}
This compiles, and I can assign a word to a TBitset16 just fine, but if I try to actually assign a TBitset16 to a word, the compiler says they're incompatible. How do I fix this?

User137
05-03-2008, 09:35 PM
If you are noto using FPC, then how class operators are working under delphi? What version it is?

masonwheeler
05-03-2008, 10:09 PM
I'm running BDS 2006, which supports class operators for records. But for some reason it doesn't like my assignment operator. Anyone with experience in this know what I'm doing wrong?

JSoftware
05-03-2008, 10:21 PM
Are you assigning it from a variable or from a constant?

I think most constant numeric arguments evaluate to longints

masonwheeler
06-03-2008, 01:38 PM
Assigning it *from* numbers works fine. (All integer types can be implicitly converted to each other anyway.) It's trying to assign it *to* a Word that doesn't work.


var
bitset: TBitset16;
number: word;
begin
bitset := number; //compiler likes this
bitset := 5; //this works just fine too
number := bitset; //compiler chokes on this one
end;