Hi Tom,
If you need a copy operation that is not the same as an intrinsic copy, you need
to write one. That would be the case however SOURCE= worked, the only
difference would be how you would use the copy operation.
In this case, ALLOCATE with SOURCE= will not call any copy operation that you
write. So you will have to use something else. I would suggest a tbp would do
the trick, you might want to make it generic if you want it to handle different
ranks etc.
Type t
...
Contains
Procedure :: copy_this_to => copy_to_t
Generic :: copy_to => copy_this_to
End Type
Subroutine copy_to_t(from,to)
Class(t),Intent(In) :: from
Class(t),Allocatable,Intent(Out) :: to
Allocate(to,Source=from)
... turn the pointer components into copies
End Subroutine
Use as
Call x%copy_to(y)
Yes, you will have to overload this for every extension that introduces more
pointer components that you want to deep-copy, but you'd have to do that anyway
if there was some "implicit" copy constructor that you could overload.
If multiple ranks are involved, perhaps an easier way would be to continue to
use ALLOCATE SOURCE= for the actual allocation, and use an elemental tb
subroutine to convert the shallow pointers into deep ones, so you'd do
Allocate(y,Source=x)
Call y%deepify_copy
where deepify_copy just does the "... turn the pointer components into copies"
part of "copy_to_t" above.
A third possibility would be to write a tb "copy" function. This would look
similar to the "copy_to" subroutine but return the allocation as the result.
This is probably not so attractive as it might end up doing double allocation
and copying of the allocatable components (though the compiler can sometimes
optimise some of those copies away), but it can work well in some situations.
Then you could do Allocate(y,Source=x%copy()). Of course this approach wouldn't
stop mistakes where someone forgets to put the "%copy()" on, but apart from that
it is similar to what you are wanting.
Hope that helps. I can't really say what kind of approach is best for you, but
I am sure that several are workable...
>Given that F2003 now supports analogs of overloaded constructors for derived
>types. (I am unsure of the formal term for this and do not have my reference
>material at hand.) I hoped, but did not realistically expect, that this
>facility might have some ability to introduce control over the allocation
>through the SOURCE= option.
This seems to be partly an unfortunate conflation of "constructor" with
"initialiser" (I blame C++!). Anyway, constructors are always explicitly
written in the code - they are just function calls, so you can do whatever you
like. There is nothing implicit going on with constructors, so naturally they
don't affect SOURCE= or indeed any other part of the syntax!
It seems unlikely that we will add overridable copying to the standard in the
foreseeable future (there are several other places that copies happen, it is not
just SOURCE=). Useful though it is in some situations, it is doubtful whether
the benefits outweigh the costs (especially given some of the older junk that we
have to support).
Cheers,
--
................................Malcolm Cohen, Nihon NAG, Tokyo.
|