ich versuche gerade eine C++ Map ( https://en.cppreference.com/w/cpp/container/map )mittels FPC nach zu bauen.
So wie ich das Verstehe ist die C++ Map ein Array bestehend aus tuppeln. Nach dem 1. Element (first) kann man suchen / Sortieren und all so kram, das 2. Element (second) ist generisch.
Basierend darauf habe ich mir mal folgende Classe gebastelt:
Code: Alles auswählen
Unit umap;
{$MODE ObjFPC}{$H+}
Interface
Uses
Classes, SysUtils;
Type
{ TMap }
Generic TMap < T > = Class
Type
TPair = Record
first: integer;
second: T;
End;
private
aReadPointer: integer;
fdata: Array Of TPair;
Function getElement(index: integer): T;
Procedure SetElement(index: integer; AValue: T);
public
Property Element[index: integer]: T read getElement write SetElement; default;
Procedure Insert(Index: Integer; Second: T);
Constructor Create();
Function First(): TPair; // Warum aktzeptiert der Compiler diese Funktion überhaupt ?
Function Next(): TPair; // Warum aktzeptiert der Compiler diese Funktion überhaupt ?
Function Count: integer;
End;
Implementation
function TMap.getElement(index: integer): T;
Var
i: Integer;
Begin
For i := 0 To high(fdata) Do Begin
If fdata[i].first = index Then Begin
result := fdata[i].second;
End;
End;
Raise exception.create('Not found.');
End;
procedure TMap.SetElement(index: integer; AValue: T);
Var
i: Integer;
Begin
For i := 0 To high(fdata) Do Begin
If fdata[i].first = index Then Begin
fdata[i].second := AValue;
End;
End;
Insert(index, AValue);
End;
procedure TMap.Insert(Index: Integer; Second: T);
Var
i: Integer;
Begin
For i := 0 To high(fdata) Do Begin
If fdata[i].first = index Then Begin
Raise exception.create('Error, already exists.');
End;
End;
setlength(fdata, high(fdata) + 2);
fdata[high(fdata)].first := index;
fdata[high(fdata)].second := Second;
End;
constructor TMap.Create;
Begin
fdata := Nil;
aReadPointer := -1;
End;
function TMap.First: TPair;
Begin
aReadPointer := 0;
result := fdata[aReadPointer];
End;
function TMap.Next: TPair;
Begin
If aReadPointer = -1 Then Begin
Raise exception.Create('missed "first" call');
End;
inc(aReadPointer);
If aReadPointer > high(fdata) Then Begin
Raise exception.Create('No next.');
End;
result := fdata[aReadPointer];
End;
function TMap.Count: integer;
Begin
result := length(fdata);
End;
End.
Code: Alles auswählen
type
TPointMap = specialize TMap < TPoint > ;
Procedure TForm1.Button1Click(Sender: TObject);
var pm: TPointMap;
p: tpair; // ----------- Hier ist das Problem, dass kennt er net
i: Integer;
Begin
pm := TPointMap.create();
// Einfügen
pm.Insert(42, point(1, 42));
pm[42] := point(2,42); // Überschreiben
pm[40] := point(1,40); // implizites einfügen
// -- Iterieren
p := pm.First();
For i := 0 To pm.Count - 1 Do Begin
p := pm.Next();
End;
End;