program test
  implicit none

  type :: TPoint
     integer :: id
     real :: x
  end type TPoint

  type :: TComponent
     class(TComponent), pointer :: prev => null(), next => null()
     type(TPoint), pointer :: p1 => null()
     type(TPoint) :: pa
     integer :: id
  end type TComponent

  class(TComponent), pointer :: ptr, root, cur
  integer :: i

  nullify(root, cur, ptr)

  do i = 1, 3
     ! init component
     allocate(ptr)
     nullify(ptr%prev, ptr%next, ptr%p1)
     ptr%id = i

     ! init point
     ptr%pa%id = i
     ptr%pa%x = real(i)
     ptr%p1 => ptr%pa

     ! add component to linked list
     if (associated(cur)) then
        cur%next => ptr
        ptr%prev => cur
        cur => cur%next
     else
        root => ptr
        cur => ptr
     end if
     
     nullify(ptr)
  end do

  write(*,*) 'run update routine using linked list pointer'
  root%p1%x = 1.
  write(*,*) root%p1%x
  call update(root%p1, root%next%p1)
  write(*,*) root%p1%x

  write(*,*) 'run update routine using associate block'
  root%p1%x = 1.
  write(*,*) root%p1%x
  associate(p => root%next)
    call update(root%p1, p%p1)
  end associate
  write(*,*) root%p1%x

contains
  subroutine update(p1, p2)
    type(TPoint), intent(inout) :: p1
    type(TPoint), intent(in) :: p2
    p1%x = 10. * p2%x
  end subroutine update
end program test
