123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335 |
- {
- This file is part of the Free Pascal FCL library.
- BSD parts (c) 2011 Vlado Boza
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY;without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **********************************************************************}
- {$mode objfpc}
- unit gmap;
- interface
- uses gset;
- type
- generic TMapCompare<TPair, TKeyCompare>=class
- class function c(a,b :TPair):boolean;
- end;
- { TMapIterator }
- generic TMapIterator<TKey, TValue, TPair, TNode>=class
- public
- type PNode=^TNode;
- TLMapIterator = specialize TMapIterator<TKey, TValue, TPair, TNode>;
- var FNode:PNode;
- type PValue=^TValue;
- function GetData:TPair;inline;
- function GetKey:TKey;inline;
- function GetValue:TValue;inline;
- function GetMutable:PValue;inline;
- procedure SetValue(value:TValue);inline;
- function MoveNext:boolean;inline;
- function Next:boolean;inline;
- function Prev:boolean;inline;
- function GetEnumerator: TLMapIterator; inline;
- property Data:TPair read GetData;
- property Key:TKey read GetKey;
- property Value:TValue read GetValue write SetValue;
- property MutableValue:PValue read GetMutable;
- property Current : TPair read GetData;
- end;
- generic TMap<TKey, TValue, TCompare>=class
- public
- type
- TPair=record
- Value:TValue;
- Key:TKey;
- end;
- TMCompare = specialize TMapCompare<TPair, TCompare>;
- TMSet = specialize TSet<TPair, TMCompare>;
- TIterator = specialize TMapIterator<TKey, TValue, TPair, TMSet.Node>;
- PTValue = ^TValue;
- PTPair = ^TPair;
- var
- private
- FSet:TMSet;
- public
- function Find(key:TKey):TIterator;inline;
- function FindLess(key:TKey):TIterator;inline;
- function FindLessEqual(key:TKey):TIterator;inline;
- function FindGreater(key:TKey):TIterator;inline;
- function FindGreaterEqual(key:TKey):TIterator;inline;
- function GetValue(key:TKey):TValue;inline;
- function TryGetValue(key:TKey; out Value: TValue): boolean;inline;
- procedure Insert(key:TKey; value:TValue);inline;
- function InsertAndGetIterator(key:TKey; value:TValue):TIterator;inline;
- function Min:TIterator;inline;
- function Max:TIterator;inline;
- procedure Delete(key:TKey);inline;
- function Size:SizeUInt;inline;
- function IsEmpty:boolean;inline;
- function GetEnumerator: TIterator; inline;
- constructor Create;
- destructor Destroy;override;
- property Items[i : TKey]: TValue read GetValue write Insert; default;
- end;
- implementation
- class function TMapCompare.c(a,b: TPair):boolean;
- begin
- c:= TKeyCompare.c(a.Key, b.Key);
- end;
- constructor TMap.Create;
- begin
- FSet:=TMSet.Create;
- end;
- destructor TMap.Destroy;
- begin
- FSet.Destroy;
- end;
- procedure TMap.Delete(key:TKey);inline;
- var Pair:TPair;
- begin
- Pair.Key:=key;
- FSet.Delete(Pair);
- end;
- function TMap.Find(key:TKey):TIterator;inline;
- var Pair:TPair; ret:TIterator;
- begin
- Pair.Key:=key;
- ret := TIterator.create;
- ret.FNode:=FSet.NFind(Pair);
- if ret.FNode = nil then begin
- ret.Destroy; ret := nil;
- end;
- Find := ret;
- end;
- function TMap.FindLess(key:TKey):TIterator;inline;
- var Pair:TPair; ret:TIterator;
- begin
- Pair.Key:=key;
- ret := TIterator.create;
- ret.FNode:=FSet.NFindLess(Pair);
- if ret.FNode = nil then begin
- ret.Destroy; ret := nil;
- end;
- FindLess := ret;
- end;
- function TMap.FindLessEqual(key:TKey):TIterator;inline;
- var Pair:TPair; ret:TIterator;
- begin
- Pair.Key:=key;
- ret := TIterator.create;
- ret.FNode:=FSet.NFindLessEqual(Pair);
- if ret.FNode = nil then begin
- ret.Destroy; ret := nil;
- end;
- FindLessEqual := ret;
- end;
- function TMap.FindGreater(key:TKey):TIterator;inline;
- var Pair:TPair; ret:TIterator;
- begin
- Pair.Key:=key;
- ret := TIterator.create;
- ret.FNode:=FSet.NFindGreater(Pair);
- if ret.FNode = nil then begin
- ret.Destroy; ret := nil;
- end;
- FindGreater := ret;
- end;
- function TMap.FindGreaterEqual(key:TKey):TIterator;inline;
- var Pair:TPair; ret:TIterator;
- begin
- Pair.Key:=key;
- ret := TIterator.create;
- ret.FNode:=FSet.NFindGreaterEqual(Pair);
- if ret.FNode = nil then begin
- ret.Destroy; ret := nil;
- end;
- FindGreaterEqual := ret;
- end;
- function TMap.GetValue(key:TKey):TValue;inline;
- var Pair:TPair;
- begin
- Pair.Key:=key;
- GetValue:=FSet.NFind(Pair)^.Data.Value;
- end;
- function TMap.TryGetValue(key: TKey; out Value: TValue): boolean;
- var Pair:TPair;
- Node: TMSet.PNode;
- begin
- Pair.Key:=key;
- Node := FSet.NFind(Pair);
- Result := Node <> nil;
- if Result then
- Value := Node^.Data.Value;
- end;
- procedure TMap.Insert(key:TKey; value:TValue);inline;
- var Pair:TPair;
- begin
- Pair.Key:=key;
- FSet.NInsert(Pair)^.Data.Value := value;
- end;
- function TMap.InsertAndGetIterator(key:TKey; value:TValue):TIterator;inline;
- var Pair:TPair; ret:TIterator;
- begin
- ret := TIterator.create;
- Pair.Key:=key;
- ret.FNode := FSet.NInsert(Pair);
- ret.FNode^.Data.Value := value;
- InsertAndGetIterator := ret;
- end;
- function TMap.Min:TIterator;inline;
- var ret:TIterator;
- begin
- ret := TIterator.create;
- ret.FNode:=FSet.NMin;
- if ret.FNode = nil then begin
- ret.Destroy; ret := nil;
- end;
- Min := ret;
- end;
- function TMap.Max:TIterator;inline;
- var ret:TIterator;
- begin
- ret := TIterator.create;
- ret.FNode:=FSet.NMax;
- if ret.FNode = nil then begin
- ret.Destroy; ret := nil;
- end;
- Max := ret;
- end;
- function TMap.Size:SizeUInt;inline;
- begin
- Size:=FSet.Size;
- end;
- function TMap.IsEmpty:boolean;inline;
- begin
- IsEmpty:=FSet.IsEmpty;
- end;
- function TMap.GetEnumerator: TIterator;
- begin
- result:=titerator.create;
- end;
- function TMapIterator.GetData:TPair;inline;
- begin
- GetData:=FNode^.Data;
- end;
- function TMapIterator.GetKey:TKey;inline;
- begin
- GetKey:=FNode^.Data.Key;
- end;
- function TMapIterator.GetValue:TValue;inline;
- begin
- GetValue:=FNode^.Data.Value;
- end;
- function TMapIterator.GetMutable:PValue;inline;
- begin
- GetMutable:=@(FNode^.Data.Value);
- end;
- procedure TMapIterator.SetValue(value:TValue);inline;
- begin
- FNode^.Data.Value := value;
- end;
- function TMapIterator.MoveNext: boolean;
- var temp:PNode;
- begin
- if(FNode=nil) then exit(false);
- if(FNode^.Right<>nil) then begin
- temp:=FNode^.Right;
- while(temp^.Left<>nil) do temp:=temp^.Left;
- end
- else begin
- temp:=FNode;
- while(true) do begin
- if(temp^.Parent=nil) then begin temp:=temp^.Parent; break; end;
- if(temp^.Parent^.Left=temp) then begin temp:=temp^.Parent; break; end;
- temp:=temp^.Parent;
- end;
- end;
- if (temp = nil) then exit(false);
- FNode:=temp;
- MoveNext:=true;
- end;
- function TMapIterator.Next:boolean;inline;
- var temp:PNode;
- begin
- if(FNode=nil) then exit(false);
- if(FNode^.Right<>nil) then begin
- temp:=FNode^.Right;
- while(temp^.Left<>nil) do temp:=temp^.Left;
- end
- else begin
- temp:=FNode;
- while(true) do begin
- if(temp^.Parent=nil) then begin temp:=temp^.Parent; break; end;
- if(temp^.Parent^.Left=temp) then begin temp:=temp^.Parent; break; end;
- temp:=temp^.Parent;
- end;
- end;
- if (temp = nil) then exit(false);
- FNode:=temp;
- Next:=true;
- end;
- function TMapIterator.Prev:boolean;inline;
- var temp:PNode;
- begin
- if(FNode=nil) then exit(false);
- if(FNode^.Left<>nil) then begin
- temp:=FNode^.Left;
- while(temp^.Right<>nil) do temp:=temp^.Right;
- end
- else begin
- temp:=FNode;
- while(true) do begin
- if(temp^.Parent=nil) then begin temp:=temp^.Parent; break; end;
- if(temp^.Parent^.Right=temp) then begin temp:=temp^.Parent; break; end;
- temp:=temp^.Parent;
- end;
- end;
- if (temp = nil) then exit(false);
- FNode:=temp;
- Prev:=true;
- end;
- function TMapIterator.GetEnumerator: TLMapIterator;
- begin
- result:=Self;
- end;
- end.
|