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:
- [WayBack] Hallvard’s Blog: Highlander2 Beta: Generics in Delphi for .NET
- [WayBack] Generic Types
A Class, Record or Interface can be generic, if it operates on one or more types that are not specified in concrete when the type is defined.
…
When using the generic class for a concrete purpose, it can be instantiated with a concrete type replacing
T
: as aList<String>
or aList<Integer>
for example. - [WayBack] Delphi Factory with generic Type – Stack Overflow
- [WayBack] c# – Getting concrete type of generic method’s T type – Stack Overflow
- [WayBack] AngelikaLanger.com – Java Generics FAQs – Generic And Parameterized Types – Angelika Langer Training/Consulting
An instantiation of a generic type where all type arguments are concrete types rather than wildcards.
…
different instantiations of the same generic type for different concrete type arguments have no type relationship.
- [WayBack] delphi – Conditional behaviour based on concrete type for generic class – Stack Overflow
- [WayBack] delphi – Size of generic type – Stack Overflow
–jeroen
Leave a comment