fpc/rtl/objpas/classes/intf.inc
paul aa5a5e79ce merge revisions: 13909,13923,13924,13934,13935,13942,13943,13944,13946,13948,13950,13951,13952,13983,13994:
rtl: add enumerators to the basic classes
tests: add enumerators test which compiles and work both by fpc and dcc
compiler: 
  + start for-in loop implementation: implement for-in loop for types (enumerations and ranges), strings, arrays and sets. todo: perform type checking, optimize array and string loops - use temp for expression, implement for-in loop for classes
test:
  + add a simple test for the 'for-in' loop
compiler: fix string for-in loop. now it uses a temp variable to store string expression result
complier: fix for-in array loop. use a temp variable for the loop expression only if loop is not an open array loop
complier: continue enumerator implementation:
  + add operator enumerator which give an ability to add enumerator for an existent type (for example to override builtin string enumerator)
  + add class enumerator support via delphi compatible GetEnumerator method + enumerator class/object template (function MoveNext: Boolean; property Current)
  + tests
compiler: fix for-in loop for arrays. delphi does not copy arrays to a temp variable and it is possible to change array during loop. + test
compiler: add reference for the enumerator operator when it is used + another test for operator enumerator for a class
compiler: add reference for the enumerator operator when it is used + another test for operator enumerator for a class
compiler: enumerator directive support:
  + allow to mark methods and properties by 'enumerator MoveNext' and 'enumerator Current' modifiers. Parser checks return types and duplicates.
  + prefer *marked* by enumerator directive methods and properties than GetEnumerator and Current builtin symbols
  + increase ppu version
  + test
rtl: add IEnumerator and IEnumerable interfaces declarations
tests: for-in loop tests:
  + add small comment at the top of test program
compiler: allow 'enumerator MoveNext' for the interface function declaration + test
compiler: move all for-in loop helpers to the nflw unit
compiler: don't allow the compiler to choose the non-valid enumerator operator for the for-in loop

git-svn-id: trunk@14008 -
2009-11-02 03:24:48 +00:00

253 lines
5.4 KiB
PHP

{
This file is part of the Free Component Library (FCL)
Copyright (c) 2002 by the Free Pascal development team
See the file COPYING.FPC, included in this distribution,
for details about the copyright.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
**********************************************************************}
{ TInerfaceListEnumerator }
constructor TInterfaceListEnumerator.Create(AList: TInterfaceList);
begin
inherited create;
FList:=AList;
FPosition:=-1;
end;
function TInterfaceListEnumerator.GetCurrent: IUnknown;
begin
Result:=FList[FPosition];
end;
function TInterfaceListEnumerator.MoveNext: Boolean;
begin
Inc(FPosition);
Result:=FPosition<FList.Count;
end;
{ TInterfaceList }
constructor TInterfaceList.Create;
begin
inherited create;
FList:=TThreadList.Create;
end;
destructor TInterfaceList.Destroy;
begin
Clear;
FList.Free;
inherited Destroy;
end;
function TInterfaceList.Get(i : Integer) : IUnknown;
begin
FList.Locklist;
try
if (i<0) or (i>=FList.FList.Count) then
FList.FList.Error(SListIndexError,i);
result:=IUnknown(FList.FList.List^[i]);
finally
FList.UnlockList;
end;
end;
function TInterfaceList.GetCapacity : Integer;
begin
FList.Locklist;
try
result:=FList.FList.Capacity;
finally
FList.UnlockList;
end;
end;
function TInterfaceList.GetCount : Integer;
begin
FList.Locklist;
try
result:=FList.FList.Count;
finally
FList.UnlockList;
end;
end;
procedure TInterfaceList.Put(i : Integer;item : IUnknown);
begin
FList.Locklist;
try
if (i<0) or (i>=FList.FList.Count) then
FList.FList.Error(SListIndexError,i);
IUnknown(FList.FList.List^[i]):=item;
finally
FList.UnlockList;
end;
end;
procedure TInterfaceList.SetCapacity(NewCapacity : Integer);
begin
FList.Locklist;
try
FList.FList.Capacity:=NewCapacity;
finally
FList.UnlockList;
end;
end;
procedure TInterfaceList.SetCount(NewCount : Integer);
begin
FList.Locklist;
try
FList.FList.Count:=NewCount;
finally
FList.UnlockList;
end;
end;
procedure TInterfaceList.Clear;
var
i : SizeInt;
begin
FList.Locklist;
try
for i:=0 to FList.FList.Count-1 do
IUnknown(FList.FList.List^[i]):=nil;
FList.Clear;
finally
FList.UnlockList;
end;
end;
procedure TInterfaceList.Delete(index : Integer);
begin
FList.Locklist;
try
if (index<0) or (index>=FList.FList.Count) then
FList.FList.Error(SListIndexError,index);
IUnknown(FList.FList.List^[index]):=nil;
FList.FList.Delete(index);
finally
FList.UnlockList;
end;
end;
procedure TInterfaceList.Exchange(index1,index2 : Integer);
begin
FList.Locklist;
try
FList.FList.Exchange(index1,index2);
finally
FList.UnlockList;
end;
end;
function TInterfaceList.First : IUnknown;
begin
result:=Get(0);
end;
function TInterfaceList.GetEnumerator: TInterfaceListEnumerator;
begin
result:=TInterfaceListEnumerator.Create(Self)
end;
function TInterfaceList.IndexOf(item : IUnknown) : Integer;
begin
FList.Locklist;
try
result:=FList.FList.IndexOf(Pointer(Item));
finally
FList.UnlockList;
end;
end;
function TInterfaceList.Add(item : IUnknown) : Integer;
begin
FList.Locklist;
try
result:=FList.FList.Add(nil);
IUnknown(FList.FList.List^[result]):=item;
finally
FList.UnlockList;
end;
end;
procedure TInterfaceList.Insert(i : Integer;item : IUnknown);
begin
FList.Locklist;
try
FList.FList.Insert(i,nil);
IUnknown(FList.FList.List^[i]):=item;
finally
FList.UnlockList;
end;
end;
function TInterfaceList.Last : IUnknown;
begin
result:=Get(Count-1);
end;
function TInterfaceList.Remove(item : IUnknown): Integer;
begin
FList.Locklist;
try
result:=FList.FList.IndexOf(item);
if result>=0 then
begin
IUnknown(FList.FList.List^[result]):=nil;
FList.FList.Delete(result);
end;
finally
FList.UnlockList;
end;
end;
procedure TInterfaceList.Lock;
begin
FList.Locklist;
end;
procedure TInterfaceList.Unlock;
begin
FList.UnlockList;
end;
function TInterfaceList.Expand : TInterfaceList;
begin
FList.Locklist;
try
FList.FList.Expand;
result:=self;
finally
FList.UnlockList;
end;
end;