Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

D2009 TStringlist ansistring

The businesswise calm of the summer has started so I picked up the migration to D2009. I roughly determined for every subsystem of the program if they should remain ascii, or can be unicode, and started porting.

It went pretty ok, all components were there in D2009 versions (some, like VSTView, slightly incompatible though) but I now have run into a problem, in some part that must remain ansistring, I extensively use TStringList, mostly as a basic map.

Is there already something easy to replace it with, or should I simply include a cut down ansistring tstringlist, based on old Delphi or FPC source?

I can't imagine I'm the first to run into this?

The changes must be relatively localised, so that the code remains compilable with BDS2006 while I go through the validation-trajectory. A few ifdefs here and there are no problem. Of course string->ansistring and char ->ansichar etc don't count as modifications in my source, since I have to do that anyway, and it is fully backwards compat.

Edit: I've been able to work away some of the stuff in reader/writer classes. This makes going for Mason's solution easier than I originally thought. I'll holds Gabr's suggestion in mind as a fallback.

Generics is pretty much the reason I bought D2009. Pity that they made it FPC incompatible though

like image 975
Marco van de Voort Avatar asked Jul 13 '09 14:07

Marco van de Voort


2 Answers

JCL implements TAnsiStrings and TAnsiStringList in the JclAnsiStrings unit.

like image 76
gabr Avatar answered Sep 22 '22 22:09

gabr


If by "map" you mean "hash table", you can replace it with the generic TDictionary. Try declaring something like this:

uses
  Generics.Collections;

type
  TStringMap<T: class> = TDictionary<ansiString, T>;

Then just replace your StringLists with TStringMaps of the right object type. (Better type-safety gets thrown in free.) Also, if you'd like the dictionary to own the objects and free them when you're done, change it to a TObjectDictionary and when you call the constructor, pass [doOwnsValues] to the appropriate parameter.

(BTW if you're going to use TDictionary, make sure you download D2009 Update 3. The original release had some severe bugs in TDictionary that made it almost unusable.)

EDIT: If it still has to compile under D2006, then you'll have to tweak things a little. Try something like this:

type
  TStringMap =
{$IFDEF UNICODE}
    class TDictionary<ansiString, TObject>
    (Add some basic wrapper functions here.)
    end;
{$ELSE}
    TStringList;
{$ENDIF}

The wrapper shouldn't take too much work if you were using it as a map in the first place. You lose the extra type safety in exchange for backwards compatibility, but you gain a real hash table that does its lookups in O(1) time.

like image 9
Mason Wheeler Avatar answered Sep 20 '22 22:09

Mason Wheeler