The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 2,318 other followers

Delphi: combining intrinsic functions and inline to have no-code checks on concrete generic instantiation

Posted by jpluimers on 2021/03/04

The title might sound like a lot of gibberish, but the mechanism it describes helps solving a problem when using generics: lack of generic constraints in the compiler.

For instance, you cannot constrain on enumeration types (C# could not do this either: you could not do T GetEnumFromString<T>(string valueString, T defaultValue) where T : Enum, but [WayBack] since C# 7.3, you can do ... where T : Enum) unless you [WayBack] did some real hackery.

For Delphi, you still cannot do the constraint, but with some hackery, you can avoid code generation. Spring4d uses this in [WayBack] Spring.pas, from which I copied these fragments:

class function TType.Kind<T>: TTypeKind;
{$IFDEF DELPHIXE7_UP}
begin
  Result := System.GetTypeKind(T);
{$ELSE}
var
  typeInfo: PTypeInfo;
begin
  typeInfo := System.TypeInfo(T);
  if typeInfo = nil then
    Exit(tkUnknown);
  Result := typeInfo.Kind;
{$ENDIF}
end;

class procedure Guard.CheckTypeKind<T>(expectedTypeKind: TTypeKind;
  const argumentName: string);
begin
  if TType.Kind<T> <> expectedTypeKind then
    RaiseArgumentException(TType.Kind<T>, argumentName);
end;

class function TEnum.IsValid<T>(const value: Integer): Boolean;
var
  data: PTypeData;
begin
  Guard.CheckTypeKind<T>(tkEnumeration, 'T');
  data := GetTypeData(TypeInfo(T));
  Result := (value >= data.MinValue) and (value <= data.MaxValue);
end;

When <T> is an enumeration type, any code for that call is eliminated by the compiler.

Related

Concrete versus generic type:

–jeroen

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

 
<span>%d</span> bloggers like this: