unit hashmap_string_to_pointer;

{$MODE FPC}
{$MODESWITCH DEFAULTPARAMETERS}
{$MODESWITCH OUT}
{$MODESWITCH RESULT}

interface

uses
  ultimate_generic_hashmap,
  ansistring_traits,
  plain_traits,
  hashfunc_djb2,
  default_allocator;

type
TPointerTraits = specialize TPlainTraits<Pointer>;
THashmapOfStringToUntypedPointerImpl = specialize TUltimateGenericHashmap<
  AnsiString, TAnsiStringTraits,
  Pointer, TPointerTraits,
  UInt32, THashFuncDjb2, THashFuncDjb2.TInitializer,
  TDefaultAllocator, TDefaultAllocator.TInitializer
>;

generic TMapOfStringToPointer<TPtr> = object
public type
  TValue = TPtr;
  PValue = ^TValue;
private
  FImpl: THashmapOfStringToUntypedPointerImpl;
public
  procedure Init; inline;
  procedure Done; inline;
  procedure Clear; inline;
  function Has(const Key: AnsiString): Boolean; inline;
  function Put(const Key: AnsiString; const Value: TPtr): Boolean; inline;
  function Find(const Key: AnsiString; out Value: TPtr): Boolean; inline;
  function Get(const Key: AnsiString; const DefaultValue: TPtr): TPtr; inline;
end;

implementation

procedure TMapOfStringToPointer.Init;
begin
  FImpl.Init(THashFuncDjb2.DefaultInitializer,
                       TDefaultAllocator.DefaultInitializer);
end;

procedure TMapOfStringToPointer.Done;
begin
  FImpl.Done;
end;

procedure TMapOfStringToPointer.Clear;
begin
  FImpl.Clear;
end;

function TMapOfStringToPointer.Has(const Key: AnsiString): Boolean;
begin
  Exit(FImpl.Has(Key));
end;

function TMapOfStringToPointer.Put(const Key: AnsiString; const Value: TPtr): Boolean;
begin
  Exit(FImpl.Put(Key, Pointer(Value)));
end;

function TMapOfStringToPointer.Find(const Key: AnsiString; out Value: TPtr): Boolean;
var
  ImplementationValue: PValue;
begin
  if FImpl.Find(Key, PPointer(ImplementationValue)) then begin
    Value := ImplementationValue^;
    Exit(True);
  end else
    Exit(False);
end;

function TMapOfStringToPointer.Get(const Key: AnsiString; const DefaultValue: TPtr): TPtr;
var
  Value: PValue;
begin
  if FImpl.Find(Key, PPointer(Value)) then begin
    Exit(Value^);
  end else
    Exit(DefaultValue);
end;

end.
