I'm trying to make a type, which would serve as a wrapper for an arbitrary other types, so I could make a heterogeneous array, as it's advised in Heterogeneous array of Fortran classes and Creating heterogeneous arrays in Fortran.
So, I've tried to implement it like this:
module m
implicit none
type :: container
class(*), pointer, public :: item
end type container
end module m
program mwe
use m
implicit none
type(container) :: cont
integer, target :: i
i = 5
cont = container(i)
write(*,*) cont%item
end program mwe
Now I'm getting error
test4.f90(20): error #5513: A polymorphic I/O list item requires a user-defined derived-type input/output procedure.
write(*,*) cont%item
----^
compilation aborted for test4.f90 (code 1)
So I tried to implement I/O like this:
module m
implicit none
type :: container
class(*), pointer, public :: item
contains
procedure :: write_sample => write_container_sample_impl
procedure :: read_sample => read_container_sample_impl
generic :: write(unformatted) => write_sample
generic :: read(unformatted) => read_sample
end type container
contains
subroutine write_container_sample_impl(this, unit, iostat, iomsg)
class(container), intent(in) :: this
integer, intent(in) :: unit
integer, intent(out) :: iostat
character(*), intent(inout) :: iomsg
write(unit, iostat=iostat, iomsg=iomsg) this%item
end subroutine write_container_sample_impl
subroutine read_container_sample_impl(this, unit, iostat, iomsg)
class(container), intent(inout) :: this
integer, intent(in) :: unit
integer, intent(out) :: iostat
character(*), intent(inout) :: iomsg
read(unit, iostat=iostat, iomsg=iomsg) this%item
end subroutine read_container_sample_impl
end module m
program mwe
use m
implicit none
type(container) :: cont
integer, target :: i
i = 5
cont = container(i)
write(*,*) cont%item
end program mwe
But the same error occurs even in my new methods:
test4.f90(22): error #5513: A polymorphic I/O list item requires a user-defined derived-type input/output procedure.
write(unit, iostat=iostat, iomsg=iomsg) this%item
--------^
test4.f90(31): error #5513: A polymorphic I/O list item requires a user-defined derived-type input/output procedure.
read(unit, iostat=iostat, iomsg=iomsg) this%item
--------^
test4.f90(47): error #5513: A polymorphic I/O list item requires a user-defined derived-type input/output procedure.
write(*,*) cont%item
----^
So, I have two questions:
Working with unlimited polymorphic entities is demanding.
Adding the defined input/output procedures for the container type doesn't solve your problem because the problem isn't with the container itself. Instead it is the component of the container which is polymorphic and requiring the defined I/O procedure.
Unfortunately though, because that component is unlimited polymorphic it isn't possible to define such a procedure.1
Further, your defined I/O procedures for the container type won't actually be used. You have defined procedures only for unformatted input and output, but write(*,*)
is (list-directed) formatted output.
As to how you can solve this problem: at some point you have to decide what your unlimited polymorphic entity is. Part of the reason working with unlimited polymorphic entities is tricky is because intrinsic and derived types cannot be treated the same. As with your previous question, if you can use class(something_not_star)
instead of class(*)
you will find life easier.
With things how they are, select type
is probably your best hope.
1 Defined I/O procedures may exist only for derived types.