Lesson 11 · 11 of 20
Generics with fgl · Pascal
Use the generic lists and maps from Free Pascal's fgl unit, TFPGList and TFPGMap, to store orders and stock with their exact types.

A generic is a type with a slot for another type. Free Pascal's `fgl` unit provides TFPGList<T> (a list) and TFPGMap<K, V> (a key-value map). In objfpc mode you make them concrete with `specialize`: TQtyList is a list of Integer and TStockMap a map from String to Integer. The compiler checks the types: a string will not fit in orders.
orders.Sort(@Descending) sorts with your own comparison function, which returns a negative number, zero or a positive number depending on how a and b compare. With b - a, largest first. Afterwards orders[0] is the biggest order and orders.Last the smallest.
With `stock.Sorted := True`, the map keeps its keys in alphabetical order and finds them by binary search. Its default property lets you write stock['monitor'] := 7: if the key does not exist it is added; if it does, its value changes, as in the line that takes off 5 keyboards.
To walk it, Keys[i] and Data[i] give the key and value at each position, already sorted. Reading stock['webcam'] would raise an exception because it does not exist; to ask safely there is `IndexOf`, which returns -1. Both collections are objects, so they are freed in the finally block.
Code · main.pas
program main;uses fgl;type TQtyList = specialize TFPGList<Integer>; TStockMap = specialize TFPGMap<String, Integer>;function Descending(const a, b: Integer): Integer;begin Result := b - a;end;var orders: TQtyList; stock: TStockMap; i: Integer;begin orders := TQtyList.Create; stock := TStockMap.Create; try orders.Add(12); orders.Add(5); orders.Add(30); orders.Add(8); orders.Sort(@Descending); WriteLn('Orders: ', orders.Count, ', largest: ', orders[0], ', smallest: ', orders.Last); stock.Sorted := True; // keys kept in order, found by binary search stock['monitor'] := 7; stock['keyboard'] := 25; stock['mouse'] := 40; stock['keyboard'] := stock['keyboard'] - 5; // 5 keyboards sold for i := 0 to stock.Count - 1 do WriteLn(stock.Keys[i]:10, stock.Data[i]:4); WriteLn('Has webcams: ', stock.IndexOf('webcam') >= 0); finally orders.Free; stock.Free; end;end.Output · fpc main.pas && ./main
Orders: 4, largest: 30, smallest: 5
keyboard 20
monitor 7
mouse 40
Has webcams: FALSEKey points
specialize TFPGList<Integer>makes a type-checked list of integers.Sorttakes a function that compares two items.TFPGMapwithSorted := Truekeeps its keys in order.map[key] := valueadds or updates.IndexOfchecks whether a key exists without raising errors.
Exercise
Add 'webcam' with 12 units to the map only if IndexOf says it is missing, and print the total number of units by adding up Data[i].