You will not be able to do it with a function or operator (since an operator is a function).
This is because neither of the 2 gives you access to the var that will receive the result. So you can not check if the variable that will receive the result is the same as the source.
Of course you can write a function/operator that always overwrites the source. But that is probably not what you want, since "arr1 := arr2 * 3" should not modify arr2.
You can do it with a procedure, using var params.
procedure arr_mul(var src: TArr; factor: integer; var dst: TArr);
begin
SetLength(dst, length(src));
for i := ...
dst[i] := src[i]* factor;
end;
If you pass in the same for src and dst, then the operation is done in place.
Note: the SetLength is still needed, even if src and dst are the same.
a2:= a1; // both point to same memory; only inc ref count
arr_mul(a1, 3, a1);
In the above a2 should NOT be modified.
The SetLenght, as detects, that dst has a ref count > 1 and copies it first, so it no longer shares the memory of a2.
however
a2:= a1;
arr_mul(a2, 3, a1);
even so a2 and a1 point to the same memory, this will make a new copy, and leave a1 un-modified.
But that is actually good, since a1 may get used later....