aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/gfortran.dg/finalize_59.f90
blob: 8be5f7123a1ac727004a0be8e9255d5f36a65ecd (plain)
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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
! { dg-do run }
!
! Test the fix for PR117897 in which the rhs of the pointer assignment at line
! 216 below was marked as being finalizable, contrary to F2023 7.5.6.3 for
! ordinary assignment and certainly wrong in this context.
!
! Contributed by Jean Gual  <jean.gual@cerema.fr>
!
Module  Uef_Classe_Vector
! Ce module implemente le vector de la STL du C++
Private
CHARACTER (len=3),  Parameter :: UEF_PAR_CHAINE_NON_RENSEIGNEE                              = "N_R"
real, parameter          :: UEF_par_vector_progression_ratio = 2
Integer, parameter       :: UEF_par_vector_initial_lenght   = 10

Type, abstract, public :: Uef_Vector_element
    Logical, public         :: m_Element_pointe = .false.
End type Uef_Vector_element

Type, private  :: Uef_Pointeur_element ! Classe pointeur
    Class (Uef_Vector_element), public, pointer  :: m_ptr_element => null()
End type Uef_Pointeur_element

Type, public :: Uef_Vector  ! Vecteur des classes pointeur
    integer  , private                                              :: m_position_fin               = 0
    type(Uef_Pointeur_element), private, allocatable, dimension(:)  :: m_les_pointeur_element
    Character (:), private, allocatable                             :: m_label
    Class (Uef_Vector_element), allocatable, private                :: m_type_element
    logical                                ,private                 :: m_polymorphe = .false.
 Contains
    PROCEDURE :: create                  => Vector_create
    PROCEDURE :: add                     => Vector_add
    PROCEDURE :: Pointer                 => Vector_pointer
    PROCEDURE :: size                    => vector_size
End Type Uef_Vector

Contains
!--------------------
! Vector_create : Cree un vector non deja alloue avec une taille initiale eventuelle
!--------------------
Subroutine Vector_create(le_vector, label, type_element, opt_taille, opt_polymorphe)
!   parametres en entree/sortie
    Class(Uef_Vector),intent (inout)                    :: le_vector
    Character (len=*),intent(in)                        :: label
    Class (Uef_Vector_element),intent(in)               :: type_element
    Integer, intent(in), optional                       :: opt_taille
    Logical, intent(in), optional                       :: opt_polymorphe

!   parametres locaux
    integer                                             :: taille_initiale
!
!-----DEBUT-----------------------------------------------------------------------------------------------------------------------
!    write (*,*) "create:", label
    if (allocated(le_vector%m_les_pointeur_element)) then
        Call Uef_assert(.false., "Vector_create : vecteur deja cree :"// le_vector%m_label)
    endif

    if (present(opt_taille)) then
        taille_initiale = max( 1, opt_taille )
    else
        taille_initiale = UEF_par_vector_initial_lenght
    endif

    if (present(opt_polymorphe)) then
        le_vector%m_polymorphe =  opt_polymorphe
    endif

    allocate( le_vector%m_les_pointeur_element(1:taille_initiale))
    le_vector%m_position_fin                    = 0
    le_vector%m_label                           = label
    allocate (le_vector%m_type_element, source  = type_element)
End Subroutine Vector_create
!--------------------
! Vector_add : ajoute une copie d'un element a la fin du vecteur
!--------------------
Subroutine Vector_add(le_vector, l_element)
!   parametres en entree/sortie
    Class(Uef_Vector),intent(inout)                  :: le_vector
    Class(Uef_Vector_element), intent(in)            :: l_element

!   parametres locaux
    type(Uef_Pointeur_element)                       :: le_ptr_element
!
!-----DEBUT-----------------------------------------------------------------------------------------------------------------------
!
!    write (*,*) "ajout:", le_vector%m_label
    if ( .not. allocated(le_vector%m_les_pointeur_element) ) Then
        Call Vector_create(le_vector, label= UEF_PAR_CHAINE_NON_RENSEIGNEE, type_element = l_element)
    End if
    if ( .not. same_type_as (l_element,le_vector%m_type_element).and. .not. le_vector%m_polymorphe) then
        Call Uef_assert(.false., "Vector_add : element de type incorrect pour :"// le_vector%m_label)
    End if

    if ( le_vector%m_position_fin >= size(le_vector%m_les_pointeur_element) ) then
        call vector_increase_size( le_vector, le_vector%m_position_fin+1 )
    endif

    le_vector%m_position_fin                                = le_vector%m_position_fin + 1
    allocate (le_ptr_element%m_ptr_element, source = l_element)
    le_vector%m_les_pointeur_element(le_vector%m_position_fin) =  le_ptr_element
End Subroutine Vector_add
!--------------------
! vector_size : retourne le nombre d'elements effectifs du vector
!--------------------
Pure Integer Function vector_size(le_vector)
!   parametres en entree
    Class(Uef_Vector), intent (in)       :: le_vector
!
!-----DEBUT-----------------------------------------------------------------------------------------------------------------------
    vector_size = le_vector%m_position_fin
End Function vector_size
!--------------------
! Vector_pointer : pointe sur une valeur
!--------------------
 Function  Vector_pointer( le_vector, position_element )
!   parametres en entree/sortie
    Class(Uef_Vector),intent(inout)         :: le_vector
    integer,intent (in)                     :: position_element
!   parametres en sortie
    Class(Uef_Vector_element), Pointer       :: Vector_pointer
!
!-----DEBUT-----------------------------------------------------------------------------------------------------------------------
!
    if ( position_element < 1 .or. position_element  > le_vector%m_position_fin ) then
        write (*,*) "Vector_pointer : pointage impossible de ", le_vector%m_label, " position_element:",&
                     position_element," size:",le_vector%m_position_fin
        Call Uef_assert(.false., "Vector_pointer : pointage impossible dans "// le_vector%m_label)
    else
        le_vector%m_les_pointeur_element(position_element)%m_ptr_element%m_Element_pointe =.true.
        Vector_pointer => le_vector%m_les_pointeur_element(position_element)%m_ptr_element
    endif
End Function Vector_pointer
!--------------------
! vector_increase_size : augmente la taille du vector
!--------------------
Subroutine vector_increase_size( le_vector, taille_demandee )
!   parametres en entree/sortie
    Class(Uef_Vector),intent(inout)                     :: le_vector
    integer,intent(in)                                  :: taille_demandee
!   Parametres en locaux
    integer                                                 :: Nouvelle_taille, taille_actuelle
    type(Uef_Pointeur_element),dimension (:), allocatable:: tmp_vector
!
!-----DEBUT-----------------------------------------------------------------------------------------------------------------------
!
    taille_actuelle = size(le_vector%m_les_pointeur_element)
    Nouvelle_taille = max(taille_demandee, nint( UEF_par_vector_progression_ratio * taille_actuelle))

    if (Nouvelle_taille > taille_actuelle) then
        allocate(tmp_vector(1:Nouvelle_taille))
        tmp_vector(1:taille_actuelle) = le_vector%m_les_pointeur_element(1:le_vector%m_position_fin)
        call move_alloc(from = tmp_vector  , to = le_vector%m_les_pointeur_element)
    endif
End Subroutine vector_increase_size
!------------------------
Subroutine Uef_Assert (assertion, message)
!--------------------
! traitement des assertions
!--------------------
! Parametres en entree
Logical, Intent(in) ::  assertion
Character (len = *) , intent(in):: message
!-------------------------------------------------------------------------------------------------
    if (.not. assertion ) Then

        write(*,*) message
        write(*,*) " ARRET PREMATURE : PREVENIR LE GESTIONNAIRE"
    stop
    End if
End Subroutine Uef_Assert

End Module  Uef_Classe_Vector

Program Cds_Principal
   Use Uef_Classe_vector
!
!--------------------------------------------------------------------------------------------------
    TYPE, extends(Uef_Vector_element),   abstract :: Cds_Materiau
        Character (len=8)               :: m_Nom_materiau                = "12345678"
        Type(Uef_Vector)                :: m_Les_situations
    END TYPE Cds_Materiau

    Type,   extends (Cds_Materiau)      :: Cds_Materiau_Acier_EC
        Double precision                :: m_Fyk                                = 0.00
    End type Cds_Materiau_Acier_EC

   Type(Uef_Vector)                                    :: Cds_Mod_Les_materiaux
   Type (Cds_Materiau_Acier_EC)                        :: acier_ec
   Class (Cds_Materiau), pointer                       :: pt_materiau
   Character *(8)                                      :: nom_materiau
!-------------------------------------------------------------------------------------------------
      CaLL  Cds_Mod_Les_materiaux%Add (acier_ec)
      nom_materiau = "12345678"
      pt_materiau => Get_pt_materiau_nom (Cds_Mod_Les_materiaux, nom_materiau)
contains

Function Get_Pt_Materiau_nom (vecteur, nom_materiau)
    !--------------------
    !   Fonction :
    !--------------------
     ! Parametres en entree
    Character *(8), Intent (in)        :: nom_materiau
    Type (Uef_Vector)          , Intent (inout)     :: vecteur

    ! Parametres en sortie
    Class  (Cds_Materiau),pointer                    :: Get_Pt_Materiau_nom

    ! Parametres locaux
    Integer                                         :: no_materiau

    Class (Uef_Vector_element),pointer           ::  pt_vector_element
    !--------------------
    do no_materiau = 1 , vecteur%size()
        pt_vector_element => vecteur%Pointer(no_materiau)
! this instruction did not work
         Get_Pt_Materiau_nom => Cds_pt_materiau(pt_vector_element)

        if (trim (Get_Pt_Materiau_nom%m_Nom_materiau) /= '12345678') stop 1
        if (Get_Pt_Materiau_nom%m_Nom_materiau == nom_materiau) Then
            return
        End if
    End do
    Get_Pt_Materiau_nom => null()
End Function Get_Pt_Materiau_nom
!
!--------------------
function Cds_Pt_Materiau(vector_element)
!--------------------
!   Fonction : pointage de la valeur
!--------------------

    ! Parametres en entree
    Class (Uef_Vector_element),intent(in),target   ::  vector_element
    ! Parametres en sortie
    Class(Cds_Materiau), pointer                   ::  Cds_Pt_Materiau
    !-----------------------------------------------------------------------------------------------
    select type(vector_element)
    Class is (Cds_Materiau)
        Cds_Pt_Materiau => vector_element
    class default
        stop 2
    end select
End Function Cds_Pt_Materiau

End Program Cds_Principal