1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
! { dg-do run }
!
! Example in F2008 C.8.4 to demonstrate submodules
!
module color_points
type color_point
private
real :: x, y
integer :: color
end type color_point
interface
! Interfaces for procedures with separate
! bodies in the submodule color_points_a
module subroutine color_point_del ( p ) ! Destroy a color_point object
type(color_point), allocatable :: p
end subroutine color_point_del
! Distance between two color_point objects
real module function color_point_dist ( a, b )
type(color_point), intent(in) :: a, b
end function color_point_dist
module subroutine color_point_draw ( p ) ! Draw a color_point object
type(color_point), intent(in) :: p
end subroutine color_point_draw
module subroutine color_point_new ( p ) ! Create a color_point object
type(color_point), allocatable :: p
end subroutine color_point_new
module subroutine verify_cleanup ( p1, p2 ) ! Check cleanup of color_point objects
type(color_point), allocatable :: p1, p2
end subroutine verify_cleanup
end interface
end module color_points
module palette_stuff
type :: palette ;
!...
end type palette
contains
subroutine test_palette ( p )
! Draw a color wheel using procedures from the color_points module
use color_points ! This does not cause a circular dependency because
! the "use palette_stuff" that is logically within
! color_points is in the color_points_a submodule.
type(palette), intent(in) :: p
end subroutine test_palette
end module palette_stuff
submodule ( color_points ) color_points_a ! Submodule of color_points
integer :: instance_count = 0
interface
! Interface for a procedure with a separate
! body in submodule color_points_b
module subroutine inquire_palette ( pt, pal )
use palette_stuff
! palette_stuff, especially submodules
! thereof, can reference color_points by use
! association without causing a circular
! dependence during translation because this
! use is not in the module. Furthermore,
! changes in the module palette_stuff do not
! affect the translation of color_points.
type(color_point), intent(in) :: pt
type(palette), intent(out) :: pal
end subroutine inquire_palette
end interface
contains
! Invisible bodies for public separate module procedures
! declared in the module
module subroutine color_point_del ( p )
type(color_point), allocatable :: p
instance_count = instance_count - 1
deallocate ( p )
end subroutine color_point_del
real module function color_point_dist ( a, b ) result ( dist )
type(color_point), intent(in) :: a, b
dist = sqrt( (b%x - a%x)**2 + (b%y - a%y)**2 )
end function color_point_dist
module subroutine color_point_new ( p )
type(color_point), allocatable :: p
instance_count = instance_count + 1
allocate ( p )
! Added to example so that it does something.
p%x = real (instance_count) * 1.0
p%y = real (instance_count) * 2.0
p%color = instance_count
end subroutine color_point_new
end submodule color_points_a
submodule ( color_points:color_points_a ) color_points_b ! Subsidiary**2 submodule
contains
! Invisible body for interface declared in the ancestor module
module subroutine color_point_draw ( p )
use palette_stuff, only: palette
type(color_point), intent(in) :: p
type(palette) :: MyPalette
call inquire_palette ( p, MyPalette )
! Added to example so that it does something.
if (abs (p%x - real (p%color) * 1.0) .gt. 1.0e-6) STOP 1
if (abs (p%y - real (p%color) * 2.0) .gt. 1.0e-6) STOP 2
end subroutine color_point_draw
! Invisible body for interface declared in the parent submodule
module procedure inquire_palette
!... implementation of inquire_palette
end procedure inquire_palette
module procedure verify_cleanup
if (allocated (p1) .or. allocated (p2)) STOP 3
if (instance_count .ne. 0) STOP 4
end procedure
subroutine private_stuff ! not accessible from color_points_a
!...
end subroutine private_stuff
end submodule color_points_b
program main
use color_points
! "instance_count" and "inquire_palette" are not accessible here
! because they are not declared in the "color_points" module.
! "color_points_a" and "color_points_b" cannot be referenced by
! use association.
interface draw
! just to demonstrate it’s possible
module procedure color_point_draw
end interface
type(color_point), allocatable :: C_1, C_2
real :: RC
!...
call color_point_new (c_1)
call color_point_new (c_2)
! body in color_points_a, interface in color_points
!...
call draw (c_1)
! body in color_points_b, specific interface
! in color_points, generic interface here.
!...
rc = color_point_dist (c_1, c_2) ! body in color_points_a, interface in color_points
if (abs (rc - 2.23606801) .gt. 1.0e-6) STOP 5
!...
call color_point_del (c_1)
call color_point_del (c_2)
! body in color_points_a, interface in color_points
call verify_cleanup (c_1, c_2)
!...
end program main
|