Generics - how to rewrite TOjectDictionary

classic Classic list List threaded Threaded
14 messages Options
Reply | Threaded
Open this post in threaded view
|

Generics - how to rewrite TOjectDictionary

Marius
Hello,

It was many years ago i tried fpc/lazarus so i'm not up to speed with eveything. At this moment I'm trying to rewrite a piece of software from delphi to fpc/laz and i'm having trouble rewriting generics and in special the TObjectDictionary. Below shows how it is implemented in delphi.

Is there a native fpc solution for this and if there is not what are the alternatives to rewrite this? Or would it even be better to avoid generics in general?

TMyDic = TObjectDictionary <string, TMyObject>;

I would welcome any tips to solve this

Thanks,
Marius


I'm using fpc 2.7.1, laz 1.1(svn 4/7/13)
fpc 2.7.1, laz 1.1 (latest svn)
Reply | Threaded
Open this post in threaded view
|

Re: Generics - how to rewrite TOjectDictionary

Dimitri Smits-2
Hi,

Ever tried TStringList with Strings[] and Objects[] properties?

kind regards,
Dimitri Smits


----- Oorspronkelijk e-mail -----

> Van: "Marius" <[hidden email]>
> Aan: [hidden email]
> Verzonden: Zondag 7 april 2013 18:48:02
> Onderwerp: [fpc-pascal] Generics - how to rewrite TOjectDictionary
>
> Hello,
>
> It was many years ago i tried fpc/lazarus so i'm not up to speed with
> eveything. At this moment I'm trying to rewrite a piece of software
> from
> delphi to fpc/laz and i'm having trouble rewriting generics and in
> special
> the TObjectDictionary. Below shows how it is implemented in delphi.
>
> Is there a native fpc solution for this and if there is not what are
> the
> alternatives to rewrite this? Or would it even be better to avoid
> generics
> in general?
>
> TMyDic = TObjectDictionary <string, TMyObject>;
>
> I would welcome any tips to solve this
>
> Thanks,
> Marius
>
>
> I'm using fpc 2.7.1, laz 1.1(svn 4/7/13)
>
>
>
>
> --
> View this message in context:
> http://free-pascal-general.1045716.n5.nabble.com/Generics-how-to-rewrite-TOjectDictionary-tp5714029.html
> Sent from the Free Pascal - General mailing list archive at
> Nabble.com.
> _______________________________________________
> fpc-pascal maillist  -  [hidden email]
> http://lists.freepascal.org/mailman/listinfo/fpc-pascal
>
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Generics - how to rewrite TOjectDictionary

Marius2
Thanks Dimitri,

Yes, I have used it lots of times and its really the last choice if theres something available like the objectdictionary. In this case the dict is also the owner of the objects, it saves me the continious ugly typecasting, takes care of the extra administration with freeing objects and all the additional troubles you get over time with this solution (its not as bad as i'm telling now). In other words tstrings.objects are working fine, but i find it a bad strategy if you have to use it in flatout in the whole application.

I'm curious how to rewrite/solve dictionaries, indexed list and even sorted strings.objects to a neat solution while (if possible) working with both delphi and fpc/laz.

Greetings,
Marius

Reply | Threaded
Open this post in threaded view
|

Re: Generics - how to rewrite TOjectDictionary

Sven Barth-2
In reply to this post by Dimitri Smits-2

Am 07.04.2013 23:09 schrieb "Dimitri Smits" <[hidden email]>:
>
> Hi,
>
> Ever tried TStringList with Strings[] and Objects[] properties?

The speciality of TObjectDirectory is that it frees the objects when an entry is deleted (similar to TObjectList).
But I now remember that we added an OwnsObjects property to TStringList some time ago...

Regards,
Sven


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Generics - how to rewrite TOjectDictionary

Marco van de Voort
In reply to this post by Marius2
In our previous episode, Marius2 said:

> Yes, I have used it lots of times and its really the last choice if theres
> something available like the objectdictionary. In this case the dict is also
> the owner of the objects, it saves me the continious ugly typecasting, takes
> care of the extra administration with freeing objects and all the additional
> troubles you get over time with this solution (its not as bad as i'm telling
> now). In other words tstrings.objects are working fine, but i find it a bad
> strategy if you have to use it in flatout in the whole application.
>
> I'm curious how to rewrite/solve dictionaries, indexed list and even sorted
> strings.objects to a neat solution while (if possible) working with both
> delphi and fpc/laz.

There is fgl.tfglmap and variants.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Generics - how to rewrite TOjectDictionary

Sven Barth-2
Am 08.04.2013 10:18, schrieb Marco van de Voort:

> In our previous episode, Marius2 said:
>> Yes, I have used it lots of times and its really the last choice if theres
>> something available like the objectdictionary. In this case the dict is also
>> the owner of the objects, it saves me the continious ugly typecasting, takes
>> care of the extra administration with freeing objects and all the additional
>> troubles you get over time with this solution (its not as bad as i'm telling
>> now). In other words tstrings.objects are working fine, but i find it a bad
>> strategy if you have to use it in flatout in the whole application.
>>
>> I'm curious how to rewrite/solve dictionaries, indexed list and even sorted
>> strings.objects to a neat solution while (if possible) working with both
>> delphi and fpc/laz.
> There is fgl.tfglmap and variants.
But AFAIK we don't have a TFGLObjectMap...

Regards,
Sven
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Generics - how to rewrite TOjectDictionary

dmitry boyarintsev
In reply to this post by Marius2
You can always use functions, to fight typecasting.

function GetMyObject(dic: TStrings; const nm: string): TMyObject;
var 
  i : integer;
begin
  if not Assigned(dic) then begin Result:=nil; Exit; end;
  i:=dic.indexof(nm); // replace with IndexOfName if necessary
  if (i<0) or (i>=dic.Count) or not (i.Objects[i] is TMyObject) then Result:=nil
  else Result:=TMyObject(i.Objects[i]); // not using "as" , since "is" has already been used
end;

Of course, people would use ClassHelpers these days to have nice syntax and avoid the sanity check.

thanks,
Dmitry


On Mon, Apr 8, 2013 at 1:42 AM, Marius2 <[hidden email]> wrote:
Thanks Dimitri,

Yes, I have used it lots of times and its really the last choice if theres
something available like the objectdictionary. In this case the dict is also
the owner of the objects, it saves me the continious ugly typecasting, takes
care of the extra administration with freeing objects and all the additional
troubles you get over time with this solution (its not as bad as i'm telling
now). In other words tstrings.objects are working fine, but i find it a bad
strategy if you have to use it in flatout in the whole application.

I'm curious how to rewrite/solve dictionaries, indexed list and even sorted
strings.objects to a neat solution while (if possible) working with both
delphi and fpc/laz.

Greetings,
Marius





--
View this message in context: http://free-pascal-general.1045716.n5.nabble.com/Generics-how-to-rewrite-TOjectDictionary-tp5714029p5714031.html
Sent from the Free Pascal - General mailing list archive at Nabble.com.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Generics - how to rewrite TOjectDictionary

dmitry boyarintsev
please disregard my last note about "avoiding the sanity check"



On Mon, Apr 8, 2013 at 1:52 PM, dmitry boyarintsev <[hidden email]> wrote:
You can always use functions, to fight typecasting.

function GetMyObject(dic: TStrings; const nm: string): TMyObject;
var 
  i : integer;
begin
  if not Assigned(dic) then begin Result:=nil; Exit; end;
  i:=dic.indexof(nm); // replace with IndexOfName if necessary
  if (i<0) or (i>=dic.Count) or not (i.Objects[i] is TMyObject) then Result:=nil
  else Result:=TMyObject(i.Objects[i]); // not using "as" , since "is" has already been used
end;

Of course, people would use ClassHelpers these days to have nice syntax and avoid the sanity check.

thanks,
Dmitry


On Mon, Apr 8, 2013 at 1:42 AM, Marius2 <[hidden email]> wrote:
Thanks Dimitri,

Yes, I have used it lots of times and its really the last choice if theres
something available like the objectdictionary. In this case the dict is also
the owner of the objects, it saves me the continious ugly typecasting, takes
care of the extra administration with freeing objects and all the additional
troubles you get over time with this solution (its not as bad as i'm telling
now). In other words tstrings.objects are working fine, but i find it a bad
strategy if you have to use it in flatout in the whole application.

I'm curious how to rewrite/solve dictionaries, indexed list and even sorted
strings.objects to a neat solution while (if possible) working with both
delphi and fpc/laz.

Greetings,
Marius





--
View this message in context: http://free-pascal-general.1045716.n5.nabble.com/Generics-how-to-rewrite-TOjectDictionary-tp5714029p5714031.html
Sent from the Free Pascal - General mailing list archive at Nabble.com.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal



_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Generics - how to rewrite TOjectDictionary

leledumbo
Administrator
In reply to this post by Marius
use the following unit:

unit StringMyObjectMap;

{$mode objfpc}{$H+}

interface

uses ghashmap;

type
  TStringHash = class
    class function hash(s: String; n: Integer): Integer;
  end;

  TMyObject = class ... end; // define yourself

  TStringMyObjectMap = class(specialize THashMap<String,TMyObject,TStringHash>)
    destructor Destroy; override;
  end;

implementation

class function TStringHash.hash(s: String; n: Integer): Integer;
var
  c: Char;
begin
  Result := 0;
  for c in s do Inc(Result,Ord(LowerCase(c))); // remove LowerCase if you want the key search to be case sensitive
  Result := Result mod n;
end;

destructor TStringMyObjectMap.Destroy;
var
  It: TIterator;
begin
  if Size > 0 then begin
    It := Iterator;
    repeat
      It.Value.Free;
    until not It.Next;
    It.Free;
  end;
  inherited Destroy;
end;

end.

WARNING: untested code, though I'm quite sure it works fine
Reply | Threaded
Open this post in threaded view
|

Re: Generics - how to rewrite TOjectDictionary

Marius2
In reply to this post by Marco van de Voort
Marco van de Voort wrote:

>
>There is fgl.tfglmap and variants.

Thank you Marco,

I was aware of this class but have to study it more nefore using it..




_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Generics - how to rewrite TOjectDictionary

Marius2
In reply to this post by dmitry boyarintsev
dmitry boyarintsev wrote:

>function GetMyObject(dic: TStrings; const nm: string): TMyObject;

It is one of the few solutions to share the code between delphi and fpc
(and yes, i would probably encase it in another class to hide the
typecasting). Still need to figure out how hashing compare to
stringlist (it should be a lot faster but i can't find the link at this
moment)




(Sorry I had some trouble with the mailing list, previous msg's are
delayed)

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Generics - how to rewrite TOjectDictionary

Marius2
In reply to this post by Sven Barth-2
Sven Barth wrote:

>But I now remember that we added an OwnsObjects property to
>TStringList some time ago...

Magic, I honestly have to admitt I was not aware of that, thanks!

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Generics - how to rewrite TOjectDictionary

Marius2
In reply to this post by leledumbo
leledumbo wrote:

>use the following unit:
>
>unit StringMyObjectMap;

Thanks,

That is a pretty advanced piece of generics, I found the fpc sources
together with the hasmapexample. I'm afraid i need to play to get
comfortable with generics g> but it will get me on my way..




(Sorry I had some trouble with the mailing list, previous msg's are
delayed)

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Generics - how to rewrite TOjectDictionary

leledumbo
Administrator
Oops, my bad. There's actually a bug in the search. It will still be case sensitive despite the hash function uses lowercase-d version of the key. It only affects the items distribution, but the key is still searched in case sensitive way through the selected bucket.