[fpc-devel] Generics.Collections as package for Lazarus or package for FPC RTL
Maciej Izak
hnb.code at gmail.com
Wed Jan 27 22:47:59 CET 2016
2016-01-27 21:01 GMT+01:00 Anthony Walter <sysrpl at gmail.com>:
> I've just like to point out that with Svens new support for generic
> functions, we actually have template like functionality in Free Pascal. You
> can now write functions which will verify at compile time the support of a
> method or operator for a particular type. This somewhat obviates the need
> to register or pass compare or equal functions or interfaces.
>
>
You don't need to pass any compare nor equal functions in the
Generics.Collections.
Mentioned in your post kind of usage of operators was possible long before
"new generic functions":
class procedure TGArray<T>.Sort(var Items: TArray<T>);
{ ... identical code here ...}
In previous version of Generics.Collections library was possible to use two
kinds of all collections (one kind with operators and one kind with manual
interfaces) for example : TFastList (with operators verified at compile
time) and TList (more Delphi compatible with manual interfaces). Approach
with operators is weak in many points:
* is not much faster than manual interfaces (it is even slower in many
cases (!), that was shock for me)
* low level of encapsulation
* lack of support for more advanced collections (for example with usage of
cuckoo hashing)
* you need to define operators for all non trivial types (and that is not
always possible in simple way, for example: external library)
* Delphi/C# incompatible way of handling collections
* is harder for customization (case sensitive/insensitive)
* MOST IMPORTANT: it is only friendly for author of those collections, for
daily user it is hell - especially for advanced collections like
"dictionary/hashmap"
fpc-stl is implemented with usage of operators. look below (just
declaration example, problems with usage of operators grows exponentially
:).
Example code for Generics.Collections:
=== code begin ===
type
TRec = record
ID1, ID2: Int64;
end;
var
d1: THashMap<TRec, TSome1>;
d2: THashMap<string, TSome2>;
d3: THashMap<Int64, TSome3>;
=== code end ===
fpc-stl equivalent:
=== reduced (!) code example begin ===
type
TRec = record
ID1, ID2: Int64;
class operator Equal(a: TRec; b: TRec) : Boolean;
end;
class operator TRec.Equal(a: TRec; b: TRec) : Boolean;
begin
Result := (a.ID1 = b.ID1) and (a.ID2 = b.ID2);
end;
type
THash_TRec = record
class function Hash(A: TObject; B: SizeUInt): SizeUInt; static;
end;
THash_String = record
class function Hash(A: string; B: SizeUInt): SizeUInt; static;
end;
THash_Int64 = record
class function Hash(A: Int64; B: SizeUInt): SizeUInt; static;
end;
class function THash_TRec.Hash(A: TObject; B: SizeUInt): SizeUInt;
begin
{
some hash function for TRec... you need to provide
}
end;
class function THash_String.Hash(A: TObject; B: SizeUInt): SizeUInt;
begin
{
some hash function for string ... you need to provide
}
end;
class function THash_Int64.Hash(A: TObject; B: SizeUInt): SizeUInt;
begin
{
some hash function for Int64 ... you need to provide
}
end;
d1: THashmap<TRec, TSome1, THash_TRec>;
d2: THashmap<string, TSome2, THash_String>;
d2: THashmap<Int64, TSome3, THash_Int64>;
=== code end ===
--
Best regards,
Maciej Izak
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-devel/attachments/20160127/d2468158/attachment.html>
More information about the fpc-devel
mailing list