user3664363
user3664363

Reputation: 11

Is there some way to make slice of pointer array?

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

Answers (1)

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

Related Questions