3 ! [OOP] Fortran runtime error: internal error: bad hash value in dynamic dispatch
5 ! Contributed by David Car <david.car7@gmail.com>
9 type, public, abstract :: Strategy
11 procedure(strategy_update), pass( this ), deferred :: update
12 procedure(strategy_pre_update), pass( this ), deferred :: preUpdate
13 procedure(strategy_post_update), pass( this ), deferred :: postUpdate
17 subroutine strategy_update( this )
19 class (Strategy), target, intent(in) :: this
20 end subroutine strategy_update
24 subroutine strategy_pre_update( this )
26 class (Strategy), target, intent(in) :: this
27 end subroutine strategy_pre_update
31 subroutine strategy_post_update( this )
33 class (Strategy), target, intent(in) :: this
34 end subroutine strategy_post_update
37 end module BaseStrategy
39 !==============================================================================
41 module LaxWendroffStrategy
45 private :: update, preUpdate, postUpdate
47 type, public, extends( Strategy ) :: LaxWendroff
48 class (Strategy), pointer :: child => null()
50 procedure, pass( this ) :: update
51 procedure, pass( this ) :: preUpdate
52 procedure, pass( this ) :: postUpdate
57 subroutine update( this )
58 class (LaxWendroff), target, intent(in) :: this
60 print *, 'Calling LaxWendroff update'
63 subroutine preUpdate( this )
64 class (LaxWendroff), target, intent(in) :: this
66 print *, 'Calling LaxWendroff preUpdate'
67 end subroutine preUpdate
69 subroutine postUpdate( this )
70 class (LaxWendroff), target, intent(in) :: this
72 print *, 'Calling LaxWendroff postUpdate'
73 end subroutine postUpdate
75 end module LaxWendroffStrategy
77 !==============================================================================
82 ! Uncomment the line below and it runs fine
83 ! use LaxWendroffStrategy
85 private :: update, preUpdate, postUpdate
87 type, public, extends( Strategy ) :: KE
88 class (Strategy), pointer :: child => null()
90 procedure, pass( this ) :: update
91 procedure, pass( this ) :: preUpdate
92 procedure, pass( this ) :: postUpdate
97 subroutine init( this, other )
98 class (KE), intent(inout) :: this
99 class (Strategy), target, intent(in) :: other
101 this % child => other
104 subroutine update( this )
105 class (KE), target, intent(in) :: this
107 if ( associated( this % child ) ) then
108 call this % child % update()
111 print *, 'Calling KE update'
112 end subroutine update
114 subroutine preUpdate( this )
115 class (KE), target, intent(in) :: this
117 if ( associated( this % child ) ) then
118 call this % child % preUpdate()
121 print *, 'Calling KE preUpdate'
122 end subroutine preUpdate
124 subroutine postUpdate( this )
125 class (KE), target, intent(in) :: this
127 if ( associated( this % child ) ) then
128 call this % child % postUpdate()
131 print *, 'Calling KE postUpdate'
132 end subroutine postUpdate
134 end module KEStrategy
136 !==============================================================================
140 use LaxWendroffStrategy
144 class (Strategy), pointer :: strat => null()
147 type (LaxWendroff), target :: lw_strat
148 type (KE), target :: ke_strat
150 type (StratSeq), allocatable, dimension( : ) :: seq
154 call init( ke_strat, lw_strat )
155 call ke_strat % preUpdate()
156 call ke_strat % update()
157 call ke_strat % postUpdate()
158 ! call lw_strat % update()
160 seq( 1 ) % strat => ke_strat
161 seq( 2 ) % strat => lw_strat
163 call seq( 1 ) % strat % update()
166 call seq( i ) % strat % update()