Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2014-11

Is it possible to specialize a generic class more than once, with different types, in the same unit?

5 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Noel Duffy

I just started investigating the generics classes in fcl-stl for a program that I'm writing. I haven't written anything using generics in Free Pascal before, so this is all new to me. I am trying to specialize THashMap to map both strings to unsigned integers and then again to map integers back to strings, like so:

program maps;
{$mode objfpc}{$H+}
uses
    ghashmap, gutil;
type
    TStrHashingClass = class
        class function hash(a: AnsiString; b: SizeUint): SizeUint;
    end;
    TWordHashingClass = class
        class function hash(a: Word; b: SizeUint): SizeUint;
    end;
    TStringWordMap = specialize THashMap<AnsiString, Word, TStrHashingClass>;
    TWordStringMap = specialize THashMap<Word, AnsiString, TWordHashingClass>;
function StrHash(const S: string): Cardinal;
begin
    Result := 3; // yes I know, I'm trying to keep this short to illustrate my problem. I have a real hash function for my program.
end;
class function TWordHashingClass.hash(a: Word; b: SizeUint): SizeUint;
begin
    Result := a mod b;
end;
class function TStrHashingClass.hash(a: AnsiString; b: SizeUint): SizeUint;
begin
    Result := StrHash(a) mod b;
end;
var
    strtable: TStringWordMap;
begin
    strtable := TStringWordMap.Create;
    strtable['ábcdéf'] := 3;
    strtable.Destroy;
end.

This code will not compile:

$ fpc -Fu/usr/share/fpcsrc/2.6.4/packages/fcl-stl/src/ -FU.  maps.lpr
Free Pascal Compiler version 2.6.4 [2014/04/20] for x86_64
Copyright (c) 1993-2014 by Florian Klaempfl and others
Target OS: Linux for x86-64
Compiling maps.lpr
ghashmap.pp(111,16) Error: Incompatible types: got "THashmap$AnsiString$Word$TStrHashingClass.TPair" expected "THashmap$Word$AnsiString$TWordHashingClass.TPair"
ghashmap.pp(116,34) Error: Incompatible type for arg no. 1: Got "THashmap$Word$AnsiString$TWordHashingClass.TPair", expected "THashmap$AnsiString$Word$TStrHashingClass.TPair"
ghashmap.pp(160,29) Error: Incompatible types: got "Word" expected "AnsiString"
ghashmap.pp(161,41) Error: Incompatible types: got "AnsiString" expected "Word"
ghashmap.pp(168,27) Error: Incompatible type for arg no. 1: Got "THashmap$Word$AnsiString$TWordHashingClass.TPair", expected "THashmap$AnsiString$Word$TStrHashingClass.TPair"
ghashmap.pp(139,29) Error: Incompatible types: got "Word" expected "AnsiString"
ghashmap.pp(180,29) Error: Incompatible types: got "Word" expected "AnsiString"
ghashmap.pp(150,29) Error: Incompatible types: got "Word" expected "AnsiString"
ghashmap.pp(150,44) Error: Incompatible types: got "Word" expected "AnsiString"
ghashmap.pp(206,12) Error: Incompatible types: got "THashmap$AnsiString$Word$TStrHashingClass.TPair" expected "THashmap$Word$AnsiString$TWordHashingClass.TPair"
ghashmap.pp(227,11) Error: Incompatible types: got "AnsiString" expected "Word"
ghashmap.pp(232,13) Error: Incompatible types: got "Word" expected "AnsiString"
ghashmap.pp(242,39) Error: Incompatible types: got "AnsiString" expected "Word"
maps.lpr(44) Fatal: There were 13 errors compiling module, stopping
Fatal: Compilation aborted
Error: /usr/bin/ppcx64 returned an error exitcode (normal if you did not specify a source file to be compiled)

But, if I remove the definition of TWordStringMap on line 18 from the type section, the code compiles just fine. It seems that fpc has gotten confused by the second specialization and has confused the two.

As I understand it, fpc generics work by writing placeholders into the ppu which are then replaced with the specialized types. But how does it handle cases where there's more than one specialization? Or is there something else I've overlooked?

I am running fpc 2.6.4 on Debian stable and on Fedora 20, and both display the same behaviour.

silvioprog
to Noel Duffy

On Sat, Nov 15, 2014 at 5:10 AM, Noel Duffy
wrote:
<snip>

I am running fpc 2.6.4 on Debian stable and on Fedora 20, and both display the same behaviour.

Compiled like a charm in FPC 2.7.1 from trunk. So this problem will not exist in 2.8. =)

Silvio Clécio My public projects - github.com/silvioprog
leledumbo
to silvioprog

Indeed, stable will not get anymore generics fixes and enhancements. Trunk already contains HUGE changes that cannot be easily merged to stable. Use trunk if you really need to use generics properly ATM. If you realize, fcl-stl doesn't even ship in precompiled form for stable.

silvioprog wrote

Show quoted text 24 lines
On Sat, Nov 15, 2014 at 5:10 AM, Noel Duffy &lt; &gt; wrote: <snip> > I am running fpc 2.6.4 on Debian stable and on Fedora 20, and both > display the same behaviour. Compiled like a charm in FPC 2.7.1 from trunk. So this problem will not exist in 2.8. =) -- Silvio Clécio My public projects - github.com/silvioprog _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Noel Duffy
to silvioprog: On Sat, Nov 15, 2014 at 5:10 AM, Noel Duffy <snip> Compiled like a charm in FPC 2.7.1…
silvioprog wrote 10 lines
On Sat, Nov 15, 2014 at 5:10 AM, Noel Duffy wrote: <snip> > I am running fpc 2.6.4 on Debian stable and on Fedora 20, and both > display the same behaviour. Compiled like a charm in FPC 2.7.1 from trunk. So this problem will not exist in 2.8. =)

Good to know, thanks. Do you know when 2.8 will be released? I prefer to stay with the stable release where possible, even if it means re-writing code to work around problems like these.

silvioprog
to Noel Duffy
Noel Duffy wrote 17 lines
On Sun, 16 Nov 2014 11:06:09 -0300, silvioprog wrote: > On Sat, Nov 15, 2014 at 5:10 AM, Noel Duffy < > > wrote: > <snip> > >> I am running fpc 2.6.4 on Debian stable and on Fedora 20, and both >> display the same behaviour. > > > Compiled like a charm in FPC 2.7.1 from trunk. So this problem will not > exist in 2.8. =) Good to know, thanks. Do you know when 2.8 will be released? I prefer to stay with the stable release where possible, even if it means re-writing code to work around problems like these.

Me too. I prefer to use stable version of any tool/compiler that I use.

AFAIK it seems the 2.8 will be released in the next semester.

Silvio Clécio My public projects - github.com/silvioprog