Unlimited Polymorphic Data Structures in Fortran
March 20, 2010
I’ve been experimenting with using unlimited polymorphic pointers
(e.g., class(*), pointer :: p
) to build generic data structures and I
wondered if anyone might have suggestions about how to improve the
interface. I have in mind lists, hash tables, etc., but the important
components are simply a container with a pointer and procedures to get
and set the pointer, so I’ll use that as a starting point:
module container
implicit none
type :: container_t
private
class(*), pointer :: p
end type container_t
contains
subroutine container_set(self, p)
type(container_t), intent(inout) :: self
class(*), target, intent(in) :: p
self%p => p
end subroutine container_set
subroutine container_get(self, p)
type(container_t), intent(inout) :: self
class(*), pointer, intent(out) :: p
p => self%p
end subroutine container_get
end module container
The set subroutine has a non-pointer polymorphic argument (with the target attribute), so we can pass it things directly without first setting a pointer. The difference being that we can write:
type(container_t) :: c
type(mytype_t), target :: foo
call container_set(c, foo)
as opposed to:
type(container_t) :: c
type(mytype_t), target :: foo
class(*), pointer :: p
p => foo
call container_set(c, p)
So we can avoid some work in the set procedure, and this all seems pretty natural, but in order to retrieve the pointer and do something with the data, this is the simplest thing I can come up with:
type(container_t) :: c
class(*), pointer :: p
call container_get(c, p)
select type (p)
type is (mytype_t)
! do something with p now
end select
In this case, since we know the type of p, the select type block seems like overkill, but I don’t think it can be avoided. If it had to be done often though, one could place all of this in a helper function in practice, when the type is known. However, I’d be happy to hear if anyone knows of a more natural or less verbose way to get the data out of the container, or any suggestions for improving the interface overall.