Discussion:
[fpc-pascal] Generics - how to rewrite TOjectDictionary
Marius
2013-04-07 16:48:02 UTC
Permalink
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.
Dimitri Smits
2013-04-07 21:08:50 UTC
Permalink
Hi,

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

kind regards,
Dimitri Smits


----- Oorspronkelijk e-mail -----
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)
--
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.
_______________________________________________
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Sven Barth
2013-04-08 05:56:18 UTC
Permalink
Post by Dimitri Smits
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
Marius
2013-04-09 20:07:29 UTC
Permalink
Post by Sven Barth
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!
Marius2
2013-04-07 21:42:38 UTC
Permalink
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.
dmitry boyarintsev
2013-04-08 09:52:28 UTC
Permalink
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
Post by 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
--
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.
_______________________________________________
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
dmitry boyarintsev
2013-04-08 10:06:30 UTC
Permalink
please disregard my last note about "avoiding the sanity check"



On Mon, Apr 8, 2013 at 1:52 PM, dmitry boyarintsev <
Post by dmitry boyarintsev
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
Post by 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
--
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.
_______________________________________________
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Marius
2013-04-09 20:00:05 UTC
Permalink
Post by dmitry boyarintsev
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)
Marco van de Voort
2013-04-08 08:18:24 UTC
Permalink
Post by Marius2
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.
Sven Barth
2013-04-08 08:19:30 UTC
Permalink
Post by Marco van de Voort
Post by Marius2
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
Marius
2013-04-08 20:54:08 UTC
Permalink
Post by Marco van de Voort
There is fgl.tfglmap and variants.
Thank you Marco,

I was aware of this class but have to study it more nefore using it..
leledumbo
2013-04-08 11:48:03 UTC
Permalink
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



--
View this message in context: http://free-pascal-general.1045716.n5.nabble.com/Generics-how-to-rewrite-TOjectDictionary-tp5714029p5714045.html
Sent from the Free Pascal - General mailing list archive at Nabble.com.
Marius
2013-04-09 20:23:56 UTC
Permalink
Post by leledumbo
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)
leledumbo
2013-04-10 07:48:52 UTC
Permalink
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.



--
View this message in context: http://free-pascal-general.1045716.n5.nabble.com/Generics-how-to-rewrite-TOjectDictionary-tp5714029p5714071.html
Sent from the Free Pascal - General mailing list archive at Nabble.com.
Loading...