[fpc-pascal] best method: multiple three state options in a decision tree
Jürgen Hestermann
juergen.hestermann at gmx.de
Mon Jan 27 18:50:29 CET 2014
Am 2014-01-27 17:41, schrieb waldo kitty:
> well, i can't set any option more than once, anyway... not unless i make a code error and set or clear the wrong bit but that will be noticed very quickly during testing ;) for readability, i find setting the bits and then running down a simple CASE statement much easier to follow... especially since i wrote my code generator tool that creates the CASE statement and all of its valid selections ;)
I recently had a similar problem and solved it this way:
With
-----------------------------------
type FlagType = (FlagA,
FlagB,
FlagC,
FlagD,
FlagE,
FlagF);
FlagSetType = set of FlagType;
var FlagSet : FlagSetType;
-----------------------------------
I get a compact bit array (a set) where I can give each bit an individual name.
Then these sets
-----------------------------------
[FlagA,FlagB,FlagC,FlagD,FlagE,FlagF]
[FlagA, FlagC,FlagD,FlagE,FlagF]
[FlagA,FlagB,FlagC,FlagD,FlagE,FlagF]
[FlagA, FlagD,FlagE,FlagF]
[FlagA,FlagB, FlagE,FlagF]
[FlagA,FlagB,FlagC,FlagD,FlagE ]
-----------------------------------
select one "number" (which it internaly is) and
-----------------------------------
byte([FlagA,FlagB,FlagC,FlagD,FlagE,FlagF])
byte([FlagA, FlagC,FlagD,FlagE,FlagF])
byte([FlagA,FlagB,FlagC,FlagD,FlagE,FlagF])
byte([FlagA, FlagD,FlagE,FlagF])
byte([FlagA,FlagB, FlagE,FlagF])
byte([FlagA,FlagB,FlagC,FlagD,FlagE ])
-----------------------------------
can be used to convert them to real (integer) numbers in a case statement:
-----------------------------------
case byte(FlagSet) of
byte([FlagA,FlagB,FlagC,FlagD,FlagE,FlagF]) : begin .. end;
byte([FlagA, FlagC,FlagD,FlagE,FlagF]) : begin .. end;
byte([FlagA,FlagB,FlagC,FlagD,FlagE,FlagF]) : begin .. end;
byte([FlagA, FlagD,FlagE,FlagF]) : begin .. end;
byte([FlagA,FlagB, FlagE,FlagF]) : begin .. end;
byte([FlagA,FlagB,FlagC,FlagD,FlagE ]) : begin .. end;
end; // of case
-----------------------------------
and still I can use the set as a usual set:
-----------------------------------
include(FlagSet,FlagD);
...
if FlagA in Flagset then..
...
etc.
-----------------------------------
I even use an array which is indexed with the set variable:
-----------------------------------
type FlagSetArrayType = array[0..(1 shl (ord(High(FlagSetType))+1))-1] of any_other_type; // 0..2^n-1
-----------------------------------
which holds information for all 2^n possible flag combination in the set.
Then I can use the set variable to index the array like this:
-----------------------------------
var FlagSetArray = FlagSetArrayType;
...
any_other_type_variable := FlagSetArray[ byte([FlagA,FlagB,FlagC,FlagD,FlagE,FlagF]) ];
-----------------------------------
(I hope there is no typo in the above code)
More information about the fpc-pascal
mailing list