view gcc/testsuite/gfortran.dg/pdt_5.f03 @ 128:fe568345ddd5

fix CbC-example
author mir3636
date Wed, 11 Apr 2018 19:32:28 +0900
parents 04ced10e8804
children 84e7813d76e9
line wrap: on
line source

! { dg-do run }
!
! Third, complete example from the PGInsider article:
! "Object-Oriented Programming in Fortran 2003 Part 3: Parameterized Derived Types"
! by Mark Leair
!
!     Copyright (c) 2013, NVIDIA CORPORATION.  All rights reserved.
!
! NVIDIA CORPORATION and its licensors retain all intellectual property
! and proprietary rights in and to this software, related documentation
! and any modifications thereto.  Any use, reproduction, disclosure or
! distribution of this software and related documentation without an express
! license agreement from NVIDIA CORPORATION is strictly prohibited.
!

!          THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT
!   WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT
!   NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR
!   FITNESS FOR A PARTICULAR PURPOSE.
!
! Note that modification had to be made all of which are commented.
!
module matrix

type :: base_matrix(k,c,r)
  private
    integer, kind :: k = 4
    integer, len :: c = 1
    integer, len :: r = 1
end type base_matrix

type, extends(base_matrix) ::  adj_matrix
  private
    class(*), pointer :: m(:,:) => null()
end type adj_matrix

interface getKind
  module procedure getKind4
  module procedure getKind8
end interface getKind

interface getColumns
  module procedure getNumCols4
  module procedure getNumCols8
end interface getColumns

interface getRows
  module procedure getNumRows4
  module procedure getNumRows8
end interface getRows

interface adj_matrix
   module procedure construct_4   ! kind=4 constructor
   module procedure construct_8   ! kind=8 constructor
end interface adj_matrix

interface assignment(=)
   module procedure m2m4          ! assign kind=4 matrix
   module procedure a2m4          ! assign kind=4 array
   module procedure m2m8          ! assign kind=8 matrix
   module procedure a2m8          ! assign kind=8 array
   module procedure m2a4          ! assign kind=4 matrix to array
   module procedure m2a8          ! assign kind=8 matrix to array
end interface assignment(=)


contains

  function getKind4(this) result(rslt)
   class(adj_matrix(4,*,*)) :: this
   integer :: rslt
   rslt = this%k
  end function getKind4

 function getKind8(this) result(rslt)
   class(adj_matrix(8,*,*)) :: this
   integer :: rslt
   rslt = this%k
 end function getKind8

  function getNumCols4(this) result(rslt)
   class(adj_matrix(4,*,*)) :: this
   integer :: rslt
   rslt = this%c
  end function getNumCols4

  function getNumCols8(this) result(rslt)
   class(adj_matrix(8,*,*)) :: this
   integer :: rslt
   rslt = this%c
  end function getNumCols8

  function getNumRows4(this) result(rslt)
   class(adj_matrix(4,*,*)) :: this
   integer :: rslt
   rslt = this%r
  end function getNumRows4

  function getNumRows8(this) result(rslt)
   class(adj_matrix(8,*,*)) :: this
   integer :: rslt
   rslt = this%r
  end function getNumRows8


 function construct_4(k,c,r) result(mat)
     integer(4) :: k
     integer :: c
     integer :: r
     class(adj_matrix(4,:,:)),allocatable :: mat

     allocate(adj_matrix(4,c,r)::mat)

  end function construct_4

  function construct_8(k,c,r) result(mat)
     integer(8) :: k
     integer :: c
     integer :: r
     class(adj_matrix(8,:,:)),allocatable :: mat

     allocate(adj_matrix(8,c,r)::mat)

  end function construct_8

  subroutine a2m4(d,s)
   class(adj_matrix(4,:,:)),allocatable :: d
   class(*),dimension(:,:) :: s

   if (allocated(d)) deallocate(d)
!    allocate(adj_matrix(4,size(s,1),size(s,2))::d)     ! generates assembler error
   allocate(d, mold = adj_matrix(4,size(s,1),size(s,2)))
   allocate(d%m(size(s,1),size(s,2)),source=s)
 end subroutine a2m4

 subroutine a2m8(d,s)
   class(adj_matrix(8,:,:)),allocatable :: d
   class(*),dimension(:,:) :: s

   if (allocated(d)) deallocate(d)
!    allocate(adj_matrix(8,size(s,1),size(s,2))::d)     ! generates assembler error
   allocate(d, mold = adj_matrix(8_8,size(s,1),size(s,2))) ! Needs 8_8 to match arg1 of 'construct_8'
   allocate(d%m(size(s,1),size(s,2)),source=s)
 end subroutine a2m8

subroutine m2a8(a,this)
class(adj_matrix(8,*,*)), intent(in) :: this         ! Intents required for
real(8),allocatable, intent(out) :: a(:,:)           ! defined assignment
  select type (array => this%m)                      ! Added SELECT TYPE because...
    type is (real(8))
  if (allocated(a)) deallocate(a)
  allocate(a,source=array)
  end select
!   allocate(a(size(this%m,1),size(this%m,2)),source=this%m) ! ...CLASS(*) source does not work in gfortran
 end subroutine m2a8

 subroutine m2a4(a,this)
 class(adj_matrix(4,*,*)), intent(in) :: this        ! Intents required for
 real(4),allocatable, intent(out) :: a(:,:)          ! defined assignment
  select type (array => this%m)                      ! Added SELECT TYPE because...
    type is (real(4))
   if (allocated(a)) deallocate(a)
   allocate(a,source=array)
  end select
!   allocate(a(size(this%m,1),size(this%m,2)),source=this%m) ! ...CLASS(*) source does not work in gfortran
 end subroutine m2a4

  subroutine m2m4(d,s)
   CLASS(adj_matrix(4,:,:)),allocatable, intent(OUT) :: d   ! Intents required for
   CLASS(adj_matrix(4,*,*)), intent(in) :: s                ! defined assignment

   if (allocated(d)) deallocate(d)
   allocate(d,source=s)
 end subroutine m2m4

 subroutine m2m8(d,s)
   CLASS(adj_matrix(8,:,:)),allocatable, intent(OUT) :: d   ! Intents required for
   CLASS(adj_matrix(8,*,*)), intent(in) :: s                ! defined assignment

   if (allocated(d)) deallocate(d)
   allocate(d,source=s)
 end subroutine m2m8


end module matrix


program adj3

  use matrix
  implicit none
  integer(8) :: i

  class(adj_matrix(8,:,:)),allocatable :: adj             ! Was TYPE: Fails in
  real(8) :: a(2,3)                                       ! defined assignment
  real(8),allocatable :: b(:,:)

  class(adj_matrix(4,:,:)),allocatable :: adj_4           ! Ditto and ....
  real(4) :: a_4(3,2)                                     ! ... these declarations were
  real(4),allocatable :: b_4(:,:)                         ! added to check KIND=4

! Check constructor of PDT and instrinsic assignment
  adj = adj_matrix(INT(8,8),2,4)
  if (adj%k .ne. 8) call abort
  if (adj%c .ne. 2) call abort
  if (adj%r .ne. 4) call abort
  a = reshape ([(i, i = 1, 6)], [2,3])
  adj = a
  b = adj
  if (any (b .ne. a)) call abort

! Check allocation with MOLD of PDT. Note that only KIND parameters set.
  allocate (adj_4, mold = adj_matrix(4,3,2))           ! Added check of KIND = 4
  if (adj_4%k .ne. 4) call abort
  a_4 = reshape (a, [3,2])
  adj_4 = a_4
  b_4 = adj_4
  if (any (b_4 .ne. a_4)) call abort

end program adj3