[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