Sign in Join
Wiki copytemporary

Generics: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: Generics

OldNewLine
1+**Generics** are sometimes called parameterized types.
2+
3+## Introduction
4+
5+[[FPC]] has had official support for generics in [[Mode ObjFPC|{$mode ObjFPC}]] since version 2.2.0, and in [[Mode Delphi|{$mode Delphi}]] since version 2.6.0.
6+
7+The reason that FPC supports two different dialects is simply that FPC implemented generics several years before [[Delphi]].
8+
9+It is possible to use [[Unit|units]] written in `{$mode ObjFPC}` syntax in other units that use `{$mode Delphi}`, and vice versa.
10+
11+The **Free Generics Library** or **FGL** is an FPC-native collection of generic containers written in `{$mode ObjFPC}`.
12+
13+The **rtl-generics** package is a larger, somewhat more featureful collection of generic containers written in `{$mode Delphi}` that tries to be compatible with the Delphi generics library. This package is provided as standard in FPC 3.1.1+, but there is a version for FPC 3.0.4 available as well.
14+
15+Both **FGL** and **rtl-generics** can be used in both syntax modes.
16+
17+## FGL unit
18+
19+The easiest way to get started with generics is to use the [fgl unit](https://www.freepascal.org/docs-html/current/rtl/fgl/index.html), which is a prototype unit for base system generic [[Class|classes]]. So far it contains a few basic classes:
20+
21+- TFPGList
22+- TFPGObjectList
23+- TFPGInterfacedObjectList
24+- TFPGMap
25+
26+### Getting started
27+
28+The following simple example shows how to store multiple instances of a user defined class in a list:
29+
30+``` pascal
31+{$mode objfpc}
32+uses fgl;
33+
34+type
35+ TMyClass = class(TObject)
36+ fld1 : string;
37+ end;
38+
39+ TMyList = specialize TFPGObjectList<TMyClass>;
40+
41+var
42+ list : TMyList;
43+ c : TMyClass;
44+
45+begin
46+ // create the list and add an element
47+ list := TMyList.Create;
48+ c := TMyClass.Create;
49+ c.fld1 := 'c1';
50+ list.Add(c);
51+ // retrieve an element from the list
52+ c := list[0];
53+```
54+
55+## Custom generic classes
56+
57+If the generics defined in the fgl unit do not suit your needs, you may need to define your own generic classes from scratch using the underlying language primitives.
58+
59+A generic class is defined using the [[Keyword|keyword]] **generic** before the class name and use in class declaration:
60+
61+``` pascal
62+type
63+ generic TList<T> = class
64+ Items: array of T;
65+ procedure Add(Value: T);
66+ end;
67+```
68+
69+Here's an example of a generic class implementation:
70+
71+``` pascal
72+implementation
73+
74+procedure TList.Add(Value: T);
75+begin
76+ SetLength(Items, Length(Items) + 1);
77+ Items[Length(Items) - 1] := Value;
78+end;
79+```
80+
81+A generic class, [[Object|object]], [[Record|record]], [[Interfaces|interface]] or [[Method|method]] can be simply specialized for a particular type by using the **specialize** keyword.
82+
83+``` pascal
84+Type
85+ TIntegerList = specialize TList<Integer>;
86+ TPointerList = specialize TList<Pointer>;
87+ TStringList = specialize TList<string>;
88+```
89+
90+## Other points
91+
92+1. The [[Compiler|compiler]] parses a generic, but instead of generating code it stores all tokens in a token buffer inside the PPU file.
93+2. The compiler parses a specialization; for this it loads the token buffer from the PPU file and parses that again. It replaces the generic parameters (in most examples "T") by the particular given type (e.g. **[[Longint|LongInt]]**, **[[TObject]]**). The code basically appears as if the same class had been written as the generic but with T replaced by the given type.
94+
95+Therefore, in theory, there should be no speed differences between a "normal" class and a generic one.
96+
97+## Example
98+
99+## See also
100+
101+- [[Templates]]
102+- [[Generics proposals]]
103+- [[Data Structures, Containers, Collections|Data Structures, Containers and Collections]]
104+
105+## External links
106+
107+- [Free Pascal: Reference Guide – Generics](https://www.freepascal.org/docs-html/ref/refch8.html)
108+
109+---
110+*From the Free Pascal wiki, page "Generics", as it stood on 2024-03-28 after a change by Raskaton, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history