Re: How to construct a heterogenous list?
- From: nospam@xxxxxxxxxxxxx (Richard Maine)
- Date: Fri, 29 Sep 2006 11:01:35 -0700
James Giles <jamesgiles@xxxxxxxxxxxxxxxx> wrote:
Richard Maine wrote:
Mark Morss <mfmorss@xxxxxxx> wrote:
Does anyone know how, in Fortran, to construct a linked list, the
elements of which are different sorts of data, e.g. different
intrinsic and user-defined types?
That's a textbook example of some of the object oriented stuff in
f2003. [...]
I'd like to see that actually.
Let's see... Yes, I have it here. The following code works with the
current NAG compiler (well, I guess it was 5.0 I tried it with; 5.1 is
out now). It was something I did while experimenting with NAG 5.0 as the
first compiler to implement some of this stuff. There are things here
that aren't quite as I'd really prefer to do them. Part of that is
because the NAG compiler still doesn't implement all of the related
features. For example, it doesn't yet allow allocatable scalars, which
turn out to be something that you want to use extensively in things like
this (at least I end up wanting to use them).
(Oh, and speaking of textboks, permission to use is granted, but I
wouldn't mind being cited as the source if this is copied verbatim.)
module poly_list
!-- Polymorphic lists using type extension.
implicit none
type, public :: node_type
private
class(node_type), pointer :: next => null()
end type node_type
type, public :: list_type
private
class(node_type), pointer :: head => null(), tail => null()
end type list_type
contains
subroutine append_node (list, new_node)
!-- Append a node to a list.
!-- Caller is responsible for allocating the node.
!---------- interface.
type(list_type), intent(inout) :: list
class(node_type), target :: new_node
!---------- executable code.
if (.not.associated(list%head)) list%head => new_node
if (associated(list%tail)) list%tail%next => new_node
list%tail => new_node
return
end subroutine append_node
function first_node (list)
!-- Get the first node of a list.
!---------- interface.
type(list_type), intent(in) :: list
class(node_type), pointer :: first_node
!---------- executable code.
first_node => list%head
return
end function first_node
function next_node (node)
!-- Step to the next node of a list.
!---------- interface.
class(node_type), target :: node
class(node_type), pointer :: next_node
!---------- executable code.
next_node => node%next
return
end function next_node
subroutine destroy_list (list)
!-- Delete (and deallocate) all the nodes of a list.
!---------- interface.
type(list_type), intent(inout) :: list
!---------- local.
class(node_type), pointer :: node, next
!---------- executable code.
node => list%head
do while (associated(node))
next => node%next
deallocate(node)
node => next
end do
nullify(list%head, list%tail)
return
end subroutine destroy_list
end module poly_list
program main
use poly_list
implicit none
type, extends(node_type) :: real_node_type
real :: x
end type real_node_type
type, extends(node_type) :: integer_node_type
integer :: i
end type integer_node_type
type, extends(node_type) :: character_node_type
character*1 :: c
end type character_node_type
type(list_type) :: list
class(node_type), pointer :: node
type(integer_node_type), pointer :: integer_node
type(real_node_type), pointer :: real_node
type(character_node_type), pointer :: character_node
!---------- executable code.
!----- Build the list.
allocate(real_node)
real_node%x = 1.23
call append_node(list, real_node)
allocate(integer_node)
integer_node%i = 42
call append_node(list, integer_node)
allocate(node)
call append_node(list, node)
allocate(character_node)
character_node%c = "z"
call append_node(list, character_node)
allocate(real_node)
real_node%x = 4.56
call append_node(list, real_node)
!----- Retrieve from it.
node => first_node(list)
do while (associated(node))
select type (node)
type is (real_node_type)
write (*,*) node%x
type is (integer_node_type)
write (*,*) node%i
type is (node_type)
write (*,*) "Node with no data."
class default
Write (*,*) "Some other node type."
end select
node => next_node(node)
end do
call destroy_list(list)
stop
end program main
--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain
.
- Follow-Ups:
- Re: How to construct a heterogenous list?
- From: James Giles
- Re: How to construct a heterogenous list?
- References:
- How to construct a heterogenous list?
- From: Mark Morss
- Re: How to construct a heterogenous list?
- From: Richard Maine
- Re: How to construct a heterogenous list?
- From: James Giles
- How to construct a heterogenous list?
- Prev by Date: Re: How to construct a heterogenous list?
- Next by Date: Re: Wikipedia article
- Previous by thread: Re: How to construct a heterogenous list?
- Next by thread: Re: How to construct a heterogenous list?
- Index(es):
Relevant Pages
|