mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-08 10:59:10 +02:00
* allow generic parameters as iterator variable in for in loops, resolves #38050
git-svn-id: trunk@47425 -
This commit is contained in:
parent
3d2ee097b5
commit
878f6d9ce4
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -18529,6 +18529,7 @@ tests/webtbs/tw38022.pp svneol=native#text/pascal
|
||||
tests/webtbs/tw3805.pp svneol=native#text/plain
|
||||
tests/webtbs/tw38051.pp svneol=native#text/pascal
|
||||
tests/webtbs/tw38054.pp svneol=native#text/plain
|
||||
tests/webtbs/tw38058.pp svneol=native#text/pascal
|
||||
tests/webtbs/tw38069.pp svneol=native#text/pascal
|
||||
tests/webtbs/tw38074.pp svneol=native#text/pascal
|
||||
tests/webtbs/tw38083.pp svneol=native#text/pascal
|
||||
|
@ -985,9 +985,14 @@ implementation
|
||||
typecheckpass(expr);
|
||||
end;
|
||||
case expr.resultdef.typ of
|
||||
stringdef: result:=create_string_for_in_loop(hloopvar, hloopbody, expr);
|
||||
arraydef: result:=create_array_for_in_loop(hloopvar, hloopbody, expr);
|
||||
setdef: result:=create_set_for_in_loop(hloopvar, hloopbody, expr);
|
||||
stringdef:
|
||||
result:=create_string_for_in_loop(hloopvar, hloopbody, expr);
|
||||
arraydef:
|
||||
result:=create_array_for_in_loop(hloopvar, hloopbody, expr);
|
||||
setdef:
|
||||
result:=create_set_for_in_loop(hloopvar, hloopbody, expr);
|
||||
undefineddef:
|
||||
result:=cnothingnode.create;
|
||||
else
|
||||
begin
|
||||
result:=cerrornode.create;
|
||||
|
71
tests/webtbs/tw38058.pp
Normal file
71
tests/webtbs/tw38058.pp
Normal file
@ -0,0 +1,71 @@
|
||||
{$mode objfpc}
|
||||
program Project1;
|
||||
type
|
||||
|
||||
TElem=(a,b,c,d,e,f);
|
||||
TmyElem=(my_a,my_c,my_e);
|
||||
TElems=set of TElem;//Output set, need convert my_a->a, my_c->c, my_e->e остальное скипаем
|
||||
TmyElems=set of TmyElem;//Input set
|
||||
|
||||
|
||||
generic TSetConverter<TGEnumIn,TGSetIn,TGEnumOut,TGSetOut,TGEnumConverter>=class
|
||||
class function Convert(value:TGSetIn):TGSetOut;
|
||||
end;
|
||||
|
||||
TmyElem2TElem_Converter=class
|
||||
class function Convert(valueIn:TmyElem;out valueOut:TElem):boolean;
|
||||
end;
|
||||
|
||||
TConverter=specialize TSetConverter<TmyElem,TmyElems,TElem,TElems,TmyElem2TElem_Converter>;
|
||||
|
||||
class function TmyElem2TElem_Converter.Convert(valueIn:TmyElem;out valueOut:TElem):boolean;
|
||||
begin
|
||||
result:=true;
|
||||
case valueIn of
|
||||
my_a:valueOut:=a;
|
||||
my_c:valueOut:=c;
|
||||
my_e:valueOut:=e;
|
||||
else result:=false;
|
||||
end;
|
||||
end;
|
||||
|
||||
{//Variant 1
|
||||
class function TSetConverter.Convert(value:TGSetIn):TGSetOut;
|
||||
var
|
||||
CurrentEnumIn:TGEnumIn;
|
||||
CurrentEnumOut:TGEnumOut;
|
||||
tvalue:TGSetIn;
|
||||
begin
|
||||
result:=[];
|
||||
for CurrentEnumIn:=low(TGEnumIn) to high(TGEnumIn) do begin
|
||||
tvalue:=value-[CurrentEnumIn];
|
||||
if tvalue<>value then begin
|
||||
if TGEnumConverter.convert(CurrentEnumIn,CurrentEnumOut) then
|
||||
result:=result+[CurrentEnumOut];
|
||||
if tvalue=[] then exit;
|
||||
value:=tvalue;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
}
|
||||
//Variant 2
|
||||
class function TSetConverter.Convert(value:TGSetIn):TGSetOut;
|
||||
var
|
||||
CurrentEnumIn:TGEnumIn;
|
||||
CurrentEnumOut:TGEnumOut;
|
||||
begin
|
||||
result:=[];
|
||||
for CurrentEnumIn in value do
|
||||
if TGEnumConverter.convert(CurrentEnumIn,CurrentEnumOut) then
|
||||
result:=result+[CurrentEnumOut];
|
||||
end;
|
||||
|
||||
var
|
||||
Elems:TElems;
|
||||
Elem:TElem;
|
||||
begin
|
||||
Elems:=TConverter.Convert([my_a,my_c,my_e]);
|
||||
for Elem in Elems do
|
||||
write(Elem);
|
||||
readln;
|
||||
end.
|
Loading…
Reference in New Issue
Block a user