Search code examples
arraysdelphisettype-safety

Can I use a set type as an array index?


I cannot use a set type as an size indicator for an array, however doing so for small sets is perfectly sensible.

Suppose I have the following code:

  TFutureCoreSet = set of 0..15;
  TLookupTable = record
    FData: array[TFutureCoreSet] of TSomeRecord; //error ordinal type required
  ....

The following code compiles and works.

  TFutureCoreSet = set of 0..15;
  TLookupTable = record
    FData: array[word] of TSomeRecord;

This however breaks the link between the allowed number of states in TFutureCoreSet and the elements in the lookup table.
Is there a simple way to link the two so when one changes the other updates as well?


Solution

  • Just do it slightly differently:

    type
      TFutureCore = 0..15;
      TFutureCoreSet = set of TFutureCore;
      TFutureCoreIndex = 0..(2 shl High(TFutureCore)) - 1;
      TLookupTable = record
        FData: array[TFutureCoreIndex] of TSomeRecord;
      end;
    

    The other advantage of using a TFutureCoreIndex is that you can use it to typecast TFutureCoreSet to an ordinal type. When typecasting a set type you must cast to an ordinal type of the same size.

    AllowedStates = LookupTable.FData[TFutureCoreIndex(FutureCores)]; //works
    AllowedStates = LookupTable.FData[Integer(FutureCores)]; //invalid typecast
    AllowedStates = LookupTable.FData[Word(FutureCores)]; //works, but not type safe.