I just came across an efficiency issue when using management operators that I’d 
like to fix before the next release and we have backwards compatibility 
problems.

Basically the problem is that the Copy operator doesn’t know if the source 
value is actually mapped to memory or just a temporary value so we’re forced to 
always copy memory (just to be safe) even when a simple move would be good 
enough. C++ has a similar idea of rvalues and lvalues and a copy and move 
constructor which addresses this.

Here’s a little example of the problem. What I propose is that we either add a 
3rd boolean parameter to the Copy operator or add a new Move operator which is 
preferred over the Copy operator if it exists (this is much more work obviously 
but maybe has some benefit). 

================================        

{$mode objfpc}
{$modeswitch advancedrecords}

program test;

type
  generic TList<T> = record
      data: array of T;
      constructor Create(num: integer);
      class operator Copy(constref src: TList; var dest: TList);
  end;

constructor TList.Create(num: integer);
begin
  SetLength(data, num);
end;


class operator TList.Copy(constref src: TList; var dest: TList);
begin
  // ...if we knew the “src” was a temporary would could simply swap the data...
  dest.data := system.copy(src.data);
end;

var
  a: specialize TList<integer>;
begin
  // TList.Create allocates a new array but we don’t really need to copy
  // on assignment because the source is a temporary object that doesn’t
  // actually exist at any static address.
  a := specialize TList<integer>.Create(10);
end.

Regards,
        Ryan Joseph

_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply via email to