Reputation: 76743
Is it possible to create a conditional define like so:
{$if typeof(TNode) = record}
type PNode = ^TNode;
{$else}
type PNode = TNode;
{$end}
Why do I want this?
I'm alternating between using class
and record
for a specific problem.
I want to use record for speed reasons, but also want to use class
for convenience.
For this reason I'm switching between the two.
Obviously I can add a {$define}
statement, but it would be nice to be able to automate this.
Upvotes: 3
Views: 147
Reputation: 6502
If you control both definition of TNode, you could do it like this (Does not need to be in same unit, but must reference the same constant) :
const
NODE_IS_RECORD = False;
type
{$if NODE_IS_RECORD}
TNode = record
end;
PNode = ^TNode;
{$ELSE}
TNode = class
end;
PNode = TNode;
{$IFEND}
If you control only 1 declaration of TNode, you could still do it like this :
{Unit1}
type
TNode = record
end;
PNode = ^TNode;
{Unit2}
{$IF not DECLARED(PNode)}
//if you don't use the unit where TNode is a record, then PNode shouldn't be declared.
PNode = TNode;
{$ENDIF}
If you control neither declaration, but they are declared in different units(Actually, I think it's required...) and you never use both, or using both always means you want to use a specific declaration of PNode :
{$IF DECLARED(UnitContainingTNodeAsRecord)}
PNode = ^TNode;
{$ELSE}
PNode = TNode;
{$IFEND}
You might want to prefix TNode with the name of the unit if you have both unit in the uses. "DECLARED" only ensure it is declared, not that it's the "closest" in scope.
I think that covers most situations.
Upvotes: 1
Reputation: 47819
Although I personally recommend the general DEFINE approach, you might be successful in those cases where the record is not of a specific size:
{$if Sizeof(TNode) <> Sizeof(Pointer)}
type PNode = ^TNode;
{$else}
type PNode = TNode;
{$end}
OK, I know that is dirty programming, but you asked for it in the first place.
Upvotes: 3