Reputation: 11
I want to create a two-dimensional array of pointers which link to another one-dimensional array:
module class_GridUnit;use iso_fortran_env
implicit none
type,public :: CGridUnit
integer(int8)::index
endtype CGridUnit
type,public :: CGridLink
type(CGridUnit),pointer::L
endtype CGridLink
type(CGridUnit),target,allocatable,dimension(:)::gDATA
type(CGridLink),allocatable,dimension(:,:)::gLink
endmodule class_GridUnit
program tt
use class_GridUnit
integer::ix1=5,iy1=5,i1=20
integer(int8),dimension(2,2)::c=0
allocate ( gLink(ix1,iy1) )
forall(ix=1:ix1,iy=1:iy1)
gLink(ix,iy)%L=>null()
endforall
allocate ( gDATA(20) )
i0=0; do ix=1,ix1; do iy=1,iy1 ; i0=i0+1
if(i0<=20)then
gLink(ix,iy)%L=>gDATA(i0)
gLink(ix,iy)%L%index=i0
endif
enddo; enddo
forall(ix=1:2,iy=1:2) c(ix,iy)=gLink(ix,iy)%L%index
print *, c
end
forall works fine, but when i am trying to make slice i get:
c(1:2,1:2)=gLink(1:2,1:2)%L%index
1
Error: Component to the right of a part reference with nonzero rank must not have the POINTER attribute at (1)
So, my question -- is there some way to do this?
Upvotes: 1
Views: 86
Reputation: 60008
It is not possible to use this shorthand notation in Fortran, when any of the components of the derived type is pointer
or allocatable
.
The standard forbids it, because the array resulting from the expression gLink(1:2,1:2)%L%index
is not only non-contiguous, but it even doesn't have a constant stride. With an array of pointers the targets of the pointers can be randomly placed in memory. Therefore, you have to use a loop or similiar construct, such as forall
, which works, as you wrote:
forall(ix=1:2,iy=1:2) c(ix,iy)=gLink(ix,iy)%L%index
Upvotes: 4