Is there some way to make slice of pointer array?

Refresh

December 2018

Views

61 time

1

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?

1 answers

4

Это не представляется возможным использовать эту сокращенную нотацию в Fortran, когда какое - либо из компонентов производного типа pointerили allocatable.

Стандарт запрещает это, потому что результирующий массив из выражения gLink(1:2,1:2)%L%indexне только несмежный, но даже не имеет постоянный шаг. С массив указателей объекты указателей могут быть размещены случайным образом в памяти. Таким образом, вы должны использовать цикл или похожую конструкцию, такие как forall, которая работает, как вы писали:

forall(ix=1:2,iy=1:2) c(ix,iy)=gLink(ix,iy)%L%index