[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