<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body smarttemplateinserted="true">
    <div id="smartTemplate4-template">Hi,</div>
    <div><br>
    </div>
    <div>perhaps a  safe, generic function for this copying could be
      added to the RTL. Like:<br>
    </div>
    <div><br>
    </div>
    <div> Procedure ManagedMove<T>(const source: T;var dest:
      T;count: SizeInt);</div>
    <div><br>
    </div>
    <div><br>
    </div>
    <div>a) For non-managed types it would be the same as Move(source,
      dest, count*sizeof(T))<br>
    </div>
    <div><br>
    </div>
    <div>b) For reference counted types (like strings or interfaces or
      records of them), it would do:</div>
    <div><br>
    </div>
    <div>1. finalize dest</div>
    <div>2. normal Move</div>
    <div>3. clear source, with fillchar<br>
    </div>
    <div><br>
    </div>
    <div>(for ranges where source and dest overlap, it should skip 1 and
      3 for the overlapping elements. Like when you shift some elements
      in an arrays by two elements to the left, it only has to finalize
      the two overridden elements before the shifted elements, and clear
      the last two shifted elements. There is only one way to do that
      keeps the reference counts valid)</div>
    <div><br>
    </div>
    <div>c) For user-defined managed, not reference counted types, it
      would just do <br>
    </div>
    <div>    <br>
    </div>
    <div>      for i := 0 to count - 1 do dest[i] := source[i]</div>
    <div><br>
      <p>Because you really want to use Move for strings, it can be
        vastly faster than updating the refcounts. But it might not work
        with user-defined types, like someone could build a managed type
        that cannot be moved. E.g.:<br>
      </p>
      <p> type TA = record<br>
          class operator Initialize(var a: TA);<br>
          procedure dosomething;<br>
        end;<br>
        <br>
        var globalPointer: ^TA;<br>
        class operator TA.Initialize(var a: TA);<br>
        begin<br>
          globalPointer := @a;<br>
        end;<br>
        procedure TA.dosomething;<br>
        begin<br>
          assert(globalPointer = @self)<br>
        end;            <br>
      </p>
      <p><br>
      </p>
      <p><br>
      </p>
      <p><br>
      </p>
      <p>And when you use IsManagedType, it does not distinguish
        standard strings with such weird managed types.</p>
      <p>And perhaps there could be a special attribute to mark which
        kind of moving is needed, e.g..<br>
      </p>
        type [moveable] TA = record<br>
      <div>
        <div> </div>
      </div>
        type [referencecounted] TA = record</div>
    <div>   type [nonmoveable] TA = record<br>
      <div> </div>
    </div>
    <div><br>
    </div>
    <div> Bye,<br>
      Benito </div>
    <div class="moz-cite-prefix">On 09.01.21 16:28, Bart via fpc-pascal
      wrote:<br>
    </div>
    <blockquote type="cite"
cite="mid:CAMye31xEVjs_-JCfLsu=fTd+_hUo_=nN5EZt-S+eTHBWQBxyug@mail.gmail.com">
      <pre class="moz-quote-pre" wrap="">Hi,

This may be a silly question.
I use System.Move() to move items in a dynamic array, like
  Move(FData[0], FData[OldEnd], FStart*SizeOf(T));
Where T is the type of the elements in the array.
This seems to work as expected.

I have some questions though:

1. Does this depend on the alignment of the array?
2. Is it OK if the elements of the array are (or contain) managed types?
3. Are there caveats if T is a specialization of a generic type definition?

</pre>
    </blockquote>
  </body>
</html>