{$MODE OBJFPC}
{$MODESWITCH AUTODEREF}
uses
  dstrings,
  dhashmap,
  dhashfuncs;

type
PSomeObject = ^TSomeObject;
TSomeObject = object
public
  S: AnsiString;
  constructor Init;
  destructor Done; virtual;
end;

TMapOfSomeObject = specialize THashMapToObject<AnsiString, TSomeObject>;
TMapOfPSomeObject = specialize THashMapToPointer<AnsiString, PSomeObject>;

constructor TSomeObject.Init;
begin
end;

destructor TSomeObject.Done;
begin
end;

var
  M: TMapOfSomeObject;
  It: TMapOfSomeObject.TIterator;
  M2: TMapOfPSomeObject;
  It2: TMapOfPSomeObject.TIterator;

function HashPjw32Str(const S: AnsiString): Cardinal;
begin
  Result := HashPjw32(@S[1], Length(S));
end;

begin
  M.Init(@HashPjw32Str);
  Writeln(M.Has('nonexists'));
  M['1'].S := 'Hi!';
  M['2'].S := 'Bye!';
  Writeln(M['1'].S);
  Writeln(M['2'].S);

  It.Init(@M);
  while It.Next do begin
    Writeln(It.Key, ' -> ', It.Value.S);
  end;
  It.Done;

  M2.Init(@HashPjw32Str);
  M2['a'] := M['1'];
  M2['b'] := M['2'];
  It2.Init(@M2);
  while It2.Next do begin
    Writeln(It2.Key, ' -> ', It2.Value.S);
  end;
  It2.Done;

  M2.Done;
  M.Done;
end.
