[fpc-devel] New feature announcement: constant parameters for generics

Benito van der Zander benito at benibela.de
Sun Apr 26 23:42:19 CEST 2020


Hi Sven,

>
> It's not that simple. In principle you're right that the compiler 
> could try to merge more implementations, but this does not depend on 
> the declaration of the generic, but the use of the parameter types.

I mostly use generics for containers, especially hashmaps. They only 
stores the values and never calls specific methods on them

>
>
> Not to mention that your TBaseHashMap would not work with managed types...

That would need be handled separately. There are probably also people 
who want a container that calls .free on TObject descendants.


Best,
Benito
On 26.04.20 14:18, Sven Barth wrote:
> Am 26.04.2020 um 14:01 schrieb Benito van der Zander:
>> Hi,
>>
>> perhaps it could be used to merge specializations (if fpc cannot do 
>> that on its own):
>>
>> Like when you have a hashmap THashMap<Key,Value>, and need three 
>> specializations:
>>
>> THashMap<string, pointer>
>>
>> THashMap<string, TObject>
>>
>> THashMap<string, sizeint>
>>
>> It is basically three times the same hashmap, but if fpc does not 
>> detect that, it might generate three times the same assembly code, 
>> which waste a lot of space.
>>
>>
>> But with constants it can be merged to TBaseHashMap<Key, ValueSize: 
>> integer> and then you only have one map in the assembly code, and 
>> three wrappers to remove the casting:
>>
>> THashMap<string, pointer> = TBaseHashMap<string, sizeof(pointer) > = 
>> TBaseHashMap<string, 8 >
>>
>> THashMap<string, TObject> = TBaseHashMap<string, sizeof(TObject) > = 
>> TBaseHashMap<string, 8 >
>>
>> THashMap<string, sizeint> = TBaseHashMap<string, sizeof(sizeint) > = 
>> TBaseHashMap<string, 8 >
>>
>
> It's not that simple. In principle you're right that the compiler 
> could try to merge more implementations, but this does not depend on 
> the declaration of the generic, but the use of the parameter types.
>
> Take the following example:
>
> === code begin ===
>
> {$mode objfpc}
>
> type
>   generic TTest<T> = class
>     procedure DoSomething;
>   end;
>
>   TMyClass1 = class
>      procedure Foobar;
>   end;
>
>   TMyClass2 = class
>     procedure Foobar; virtual;
>   end;
>
> procedure TTest.DoSomething;
> var
>   o: T;
> begin
>   o.Foobar;
> end;
>
> procedure TMyClass1.Foobar;
> begin
>   Writeln('TMyClass1.Foobar');
> end;
>
> procedure TMyClass2.Foobar;
> begin
>   Writeln('TMyClass2.Foobar');
> end;
>
> type
>   TTestMyClass1 = specialize TTest<TMyClass1>;
>   TTestMyClass2 = specialize TTest<TMyClass2>;
>
> begin
> end.
>
> === code end ===
>
> In case of TMyClass1 this will result in a static call to 
> TMyClass1.Foobar, however in case of TMyClass2 this will result in an 
> indirect call through the VMT.
>
> The type information needs to be correct as well, even more so once we 
> have support for Extended RTTI where one can enumerate non-published 
> fields, properties and methods in addition to published.
>
> Not to mention that your TBaseHashMap would not work with managed types...
>
> Regards,
> Sven
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-devel/attachments/20200426/9609a82a/attachment-0001.html>


More information about the fpc-devel mailing list