[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