Search code examples
delphitypesfor-looploopsenumerate

How to iterate initialized enumerated types with Delphi 6 and avoid the "out of bounds" error?


I am using Delphi 6 Professional. I am interfacing with a DLL libraty that declares an enumberated type as follows:

TExtDllEnum = (ENUM1 = $0, ENUM2 = $1, ENUM3 = $2, ENUM4 = $4, ENUM5 = $8, ENUM6 = $10);

As you can see the initialized values are not contiguous. If I try to iterate the type using a for loop as follows:

var
    e: TExtDllEnum;
begin
    for e := Low(TExtToDllEnum) to High(TExtToDllEnum) do
    ... // More code
end;

Delphi still increments e by 1 each loop invocation and thereby creates numeric values for e that are not members of the enumerated type (for example, '3'), and resulting in an 'out of bounds' error. How can I iterate the enumerated type in a for loop that generates only valid values for the enumerated type?

Thanks.


Solution

  • By defining a set of constants...

    type
      TExtDllEnum = (ENUM1 = $0, ENUM2 = $1, ENUM3 = $2, ENUM4 = $4, ENUM5 = $8, ENUM6 = $10);
    
    const
      CExtDllEnumSet = [ENUM1, ENUM2, ENUM3, ENUM4, ENUM5, ENUM6];
    
    
    var
      e: TExtDllEnum;
    begin
      e := Low(TExtDllEnum);
      while e <= High(TExtDllEnum) do
      begin
        if e in CExtDllEnumSet then 
          WriteLn(Ord(e));
    
        Inc(e);
      end;
    
      ReadLn;
    end.
    

    and implemented as an iterator - just for fun...

    type
      TExtDllEnum = (ENUM1 = $0, ENUM2 = $1, ENUM3 = $2, ENUM4 = $4, ENUM5 = $8, ENUM6 = $10);
    const
      CExtDllEnumSet = [ENUM1, ENUM2, ENUM3, ENUM4, ENUM5, ENUM6];
    
    type
      TMyIterator = class
      private
        FValue: TExtDllEnum;
      public
        constructor Create;
        function Next: TExtDllEnum;
        function HasNext: Boolean;
      end;
    
      constructor TMyIterator.Create;
      begin
        FValue := Low(TExtDllEnum);
      end;
    
      function TMyIterator.HasNext: Boolean;
      begin
        Result := FValue <= High(TExtDllEnum);
      end;
    
      function TMyIterator.Next: TExtDllEnum;
      begin
        Result := FValue;
    
        repeat
          Inc(FValue);
        until (FValue in CExtDllEnumSet) or (FValue > High(TExtDllEnum))
      end;
    
    var
      MyIterator: TMyIterator;
    begin
      MyIterator := TMyIterator.Create;
    
      while MyIterator.HasNext do
        WriteLn(Ord(MyIterator.Next));
    
      MyIterator.Free;
    
      ReadLn;
    end.