1
- module resource_m
1
+ module smart_pointer_m
2
2
implicit none
3
+
3
4
type, abstract :: resource_t
4
5
contains
5
6
procedure (free_interface), deferred :: free
6
7
end type
8
+
7
9
abstract interface
8
10
subroutine free_interface (self )
9
11
import resource_t
10
12
class(resource_t), intent (inout ) :: self
11
13
end subroutine
12
14
end interface
15
+
13
16
type reference_counter_t
14
17
integer , pointer :: count_ = > null ()
15
18
class(resource_t), pointer :: object_ = > null ()
@@ -20,13 +23,23 @@ subroutine free_interface(self)
20
23
generic :: assignment (= ) = > assign_reference_counter
21
24
final :: finalize
22
25
end type
26
+
27
+ type, abstract, extends(resource_t) :: smart_pointer_t
28
+ type (reference_counter_t) :: counter
29
+ contains
30
+ procedure , non_overridable :: release_handle
31
+ procedure , non_overridable :: start_counter
32
+ end type
33
+
23
34
contains
35
+
24
36
subroutine finalize (self )
25
37
type (reference_counter_t), intent (inout ) :: self
26
38
print * ," reference_counter_t%finalize: start"
27
39
if (associated (self% count_)) call self% release
28
40
print * ," reference_counter_t%finalize: end" // new_line(' ' )
29
41
end subroutine
42
+
30
43
function construct_reference_counter_t (object ) result(reference_counter)
31
44
class(resource_t), intent (in ) :: object
32
45
type (reference_counter_t) reference_counter
@@ -36,13 +49,15 @@ function construct_reference_counter_t(object) result(reference_counter)
36
49
call reference_counter% grab
37
50
print * ," construct_reference_counter_t: end" // new_line(' ' )
38
51
end function
52
+
39
53
subroutine grab (self )
40
54
class(reference_counter_t), intent (inout ) :: self
41
55
print * ," reference_counter_t%grab: start"
42
56
if (.not. associated (self% count_)) error stop " reference_counter_t%grab: associated(self%count_)"
43
57
self% count_ = self% count_ + 1
44
58
print * ," reference_counter_t%grab: end (self%count_ = " , self% count_," )"
45
59
end subroutine
60
+
46
61
subroutine release (self )
47
62
class (reference_counter_t), intent (inout ) :: self
48
63
print * ," reference_counter_t%release: start"
@@ -59,6 +74,7 @@ subroutine release(self)
59
74
end if
60
75
print * ," reference_counter_t%release: end"
61
76
end subroutine
77
+
62
78
subroutine assign_reference_counter (lhs , rhs )
63
79
class(reference_counter_t), intent (inout ) :: lhs
64
80
class(reference_counter_t), intent (in ) :: rhs
@@ -69,68 +85,73 @@ subroutine assign_reference_counter(lhs, rhs)
69
85
call lhs% grab
70
86
print * ," reference_counter_t%assign_reference_counter: end" // new_line(' ' )
71
87
end subroutine
72
- end module
73
- module smart_pointer_m
74
- use resource_m, only: resource_t, reference_counter_t, construct_reference_counter_t
75
- implicit none
76
- type, abstract, extends(resource_t) :: smart_pointer_t
77
- type (reference_counter_t) :: counter
78
- contains
79
- procedure , non_overridable :: release_handle
80
- procedure , non_overridable :: start_counter
81
- end type
82
- contains
88
+
83
89
subroutine release_handle (self )
84
90
class(smart_pointer_t), intent (inout ) :: self
85
91
print * ," smart_pointer_t%release_handle: start"
86
92
call self% counter% release
87
93
print * ," smart_pointer_t%release_handle: end" // new_line(' ' )
88
94
end subroutine
95
+
89
96
subroutine start_counter (self )
90
97
class(smart_pointer_t), intent (inout ) :: self
91
98
print * ," smart_pointer_t%start_counter: start" // new_line(' ' )
92
99
self% counter = construct_reference_counter_t(self)
93
100
print * ," smart_pointer_t%start_counter: end" // new_line(' ' )
94
101
end subroutine
102
+
95
103
end module
96
- module smart_pointer_test_m
104
+
105
+ module integer_pointer_m
97
106
use smart_pointer_m, only: smart_pointer_t
98
107
implicit none
99
- type, extends(smart_pointer_t) :: object_t
108
+
109
+ type, extends(smart_pointer_t) :: integer_pointer_t
100
110
integer , pointer :: ref = > null ()
101
111
contains
102
112
procedure :: free
103
113
end type
104
- integer , allocatable , target :: referenced_memory
114
+
115
+ integer , allocatable , target :: allocatable_integer
105
116
integer , parameter :: the_answer = 42
117
+
106
118
contains
107
- function construct_object_t () result(object)
108
- type (object_t) object
109
- print * ," construct_object_t: start" // new_line(' ' )
110
- if (.not. allocated (referenced_memory)) allocate (referenced_memory, source= the_answer)
111
- object% ref = > referenced_memory
112
- object% ref = the_answer
113
- call object% start_counter
114
- print * ," construct_object_t: end" // new_line(' ' )
119
+
120
+ function allocate_integer () result(integer_pointer)
121
+ type (integer_pointer_t) integer_pointer
122
+ print * ," allocate_integer: start" // new_line(' ' )
123
+ if (.not. allocated (allocatable_integer)) allocate (allocatable_integer, source= the_answer)
124
+ integer_pointer% ref = > allocatable_integer
125
+ integer_pointer% ref = the_answer
126
+ call integer_pointer% start_counter
127
+ print * ," allocate_integer: end" // new_line(' ' )
115
128
end function
129
+
116
130
subroutine free (self )
117
- class(object_t ), intent (inout ) :: self
118
- print * ," object_t %free: start"
119
- if (allocated (referenced_memory )) deallocate (referenced_memory )
131
+ class(integer_pointer_t ), intent (inout ) :: self
132
+ print * ," integer_pointer_t %free: start"
133
+ if (allocated (allocatable_integer )) deallocate (allocatable_integer )
120
134
nullify(self% ref)
121
- print * ," object_t %free: end" // new_line(' ' )
135
+ print * ," integer_pointer_t %free: end" // new_line(' ' )
122
136
end subroutine
137
+
123
138
end module
124
- use smart_pointer_test_m
139
+
140
+ program main
141
+ use integer_pointer_m, only : integer_pointer_t, allocate_integer
125
142
implicit none
143
+
126
144
print * ," main: start" // new_line(' ' )
127
- call check_creation
145
+ call test_reference_counting
128
146
print * ," main: end" ! ---> this line is not reached <---
147
+
129
148
contains
130
- subroutine check_creation
131
- type (object_t) object
149
+
150
+ subroutine test_reference_counting
151
+ type (integer_pointer_t) integer_pointer
132
152
print * ," main(check_creation): start" // new_line(' ' )
133
- object = construct_object_t ()
153
+ integer_pointer = allocate_integer ()
134
154
print * ," main(check_creation): end" // new_line(' ' )
135
155
end subroutine
136
- end
156
+
157
+ end program
0 commit comments