forked from zerothi/fdict
-
Notifications
You must be signed in to change notification settings - Fork 0
/
var_funcs_inc.inc
234 lines (222 loc) · 6.56 KB
/
var_funcs_inc.inc
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
#ifdef COMMENTS
! For LICENSE, see README.md
#endif
#include "settings.inc"
subroutine ROUTINE(assign_set,VAR)(this,rhs,dealloc)
type(var), intent(inout) :: this
VAR_TYPE, intent(in)DIMS :: rhs
logical, intent(in), optional :: dealloc
logical :: ldealloc
type :: pt
VAR_TYPE, pointer DIMS :: p
end type
type(pt) :: p
! ASSIGNMENT in fortran is per default destructive
ldealloc = .true.
if(present(dealloc))ldealloc = dealloc
if (ldealloc) then
call delete(this)
else
call nullify(this)
end if
! With pointer transfer we need to deallocate
! else bounds might change...
this%t = STR(VAR)
nullify(p%p)
ALLOC(p%p,rhs) ! allocate space
p%p = rhs ! copy data over
allocate(this%enc(size(transfer(p, local_enc_type)))) ! allocate encoding
this%enc = transfer(p, local_enc_type) ! transfer pointer type to the encoding
end subroutine ROUTINE(assign_set,VAR)
subroutine ROUTINE(assign_get,VAR)(lhs,this,success)
VAR_TYPE, intent(out)DIMS :: lhs
type(var), intent(in) :: this
logical, intent(out), optional :: success
logical :: lsuccess
type :: pt
VAR_TYPE, pointer DIMS :: p
end type
type(pt) :: p
nullify(p%p)
lsuccess = this%t == STR(VAR)
#if DIM > 0
if (lsuccess) then
p = transfer(this%enc,p) ! retrieve pointer encoding
lsuccess = all(shape(p%p)==shape(lhs)) !&
! .and. all((lbound(p%p) == lbound(lhs))) &
! .and. all((ubound(p%p) == ubound(lhs)))
end if
#endif
if (present(success)) success = lsuccess
if (.not. lsuccess) return
#if DIM == 0
p = transfer(this%enc,p) ! retrieve pointer encoding
#endif
lhs = p%p
end subroutine ROUTINE(assign_get,VAR)
subroutine ROUTINE(associate_get,VAR)(lhs,this,dealloc,success)
VAR_TYPE, pointer DIMS :: lhs
type(var), intent(in) :: this
logical, intent(in), optional :: dealloc
logical, intent(out), optional :: success
logical :: ldealloc, lsuccess
type :: pt
VAR_TYPE, pointer DIMS :: p
end type
type(pt) :: p
lsuccess = this%t == STR(VAR)
if (present(success)) success = lsuccess
! ASSOCIATION in fortran is per default non-destructive
ldealloc = .false.
if(present(dealloc))ldealloc = dealloc
! there is one problem, say if lhs is not nullified...
if (ldealloc.and.associated(lhs)) then
deallocate(lhs)
nullify(lhs)
end if
if (.not. lsuccess ) return
nullify(p%p)
p = transfer(this%enc,p) ! retrieve pointer encoding
lhs => p%p
end subroutine ROUTINE(associate_get,VAR)
subroutine ROUTINE(associate_set,VAR)(this,rhs,dealloc)
type(var), intent(inout) :: this
#ifdef COMMENTS
! Setting the intent(inout) ensures that no constants
! will be able to be passed.
! However, the dictionary type does not allow
! this due to OPERATORS, hence we keep it as this
! and proclaim that any user creating a pointer
! to a constant is insane...
#endif
VAR_TYPE, intent(in)DIMS, target :: rhs
logical, intent(in), optional :: dealloc
logical :: ldealloc
type :: pt
VAR_TYPE, pointer DIMS :: p
end type
type(pt) :: p
! ASSOCIATION in fortran is per default non-destructive
ldealloc = .false.
if(present(dealloc))ldealloc = dealloc
if (ldealloc) then
call delete(this)
else
call nullify(this)
end if
this%t = STR(VAR)
p%p => rhs
allocate(this%enc(size(transfer(p, local_enc_type)))) ! allocate encoding
this%enc = transfer(p, local_enc_type) ! transfer pointer type to the encoding
end subroutine ROUTINE(associate_set,VAR)
pure function ROUTINE(associatd_l,VAR)(lhs,this) result(ret)
VAR_TYPE, pointer DIMS :: lhs
type(var), intent(in) :: this
logical :: ret
type :: pt
VAR_TYPE, pointer DIMS :: p
end type
type(pt) :: p
ret = this%t == STR(VAR)
if (ret) then
nullify(p%p)
p = transfer(this%enc,p)
ret = associated(lhs,p%p)
endif
end function ROUTINE(associatd_l,VAR)
pure function ROUTINE(associatd_r,VAR)(this,rhs) result(ret)
type(var), intent(in) :: this
VAR_TYPE, pointer DIMS :: rhs
logical :: ret
type :: pt
VAR_TYPE, pointer DIMS :: p
end type
type(pt) :: p
ret = this%t == STR(VAR)
if (ret) then
nullify(p%p)
p = transfer(this%enc,p)
ret = associated(p%p,rhs)
endif
end function ROUTINE(associatd_r,VAR)
! All boolean functions
#ifdef BOOLEANS
function ROUTINE(eq_l,VAR)(this,rhs) result(ret)
type(var), intent(in) :: this
VAR_TYPE, intent(in)DIMS :: rhs
logical :: ret
ret = this%t == STR(VAR)
if (.not. ret) return
ret = all(THIS(VAR) == rhs)
end function ROUTINE(eq_l,VAR)
function ROUTINE(eq_r,VAR)(lhs,this) result(ret)
VAR_TYPE, intent(in)DIMS :: lhs
type(var), intent(in) :: this
logical :: ret
ret = this == lhs
end function ROUTINE(eq_r,VAR)
function ROUTINE(ne_l,VAR)(this,rhs) result(ret)
type(var), intent(in) :: this
VAR_TYPE, intent(in)DIMS :: rhs
logical :: ret
ret = .not. this == rhs
end function ROUTINE(ne_l,VAR)
function ROUTINE(ne_r,VAR)(lhs,this) result(ret)
VAR_TYPE, intent(in)DIMS :: lhs
type(var), intent(in) :: this
logical :: ret
ret = .not. this == lhs
end function ROUTINE(ne_r,VAR)
function ROUTINE(gt_l,VAR)(this,rhs) result(ret)
type(var), intent(in) :: this
VAR_TYPE, intent(in)DIMS :: rhs
logical :: ret
ret = this%t == STR(VAR)
if (.not. ret) return
ret = all(THIS(VAR) > rhs)
end function ROUTINE(gt_l,VAR)
function ROUTINE(gt_r,VAR)(lhs,this) result(ret)
VAR_TYPE, intent(in)DIMS :: lhs
type(var), intent(in) :: this
logical :: ret
ret = this%t == STR(VAR)
if (.not. ret) return
ret = all(lhs > THIS(VAR))
end function ROUTINE(gt_r,VAR)
function ROUTINE(lt_l,VAR)(this,rhs) result(ret)
type(var), intent(in) :: this
VAR_TYPE, intent(in)DIMS :: rhs
logical :: ret
ret = rhs > this
end function ROUTINE(lt_l,VAR)
function ROUTINE(lt_r,VAR)(lhs,this) result(ret)
VAR_TYPE, intent(in)DIMS :: lhs
type(var), intent(in) :: this
logical :: ret
ret = this > lhs
end function ROUTINE(lt_r,VAR)
function ROUTINE(ge_l,VAR)(this,rhs) result(ret)
type(var), intent(in) :: this
VAR_TYPE, intent(in)DIMS :: rhs
logical :: ret
ret = .not. this < rhs
end function ROUTINE(ge_l,VAR)
function ROUTINE(ge_r,VAR)(lhs,this) result(ret)
VAR_TYPE, intent(in)DIMS :: lhs
type(var), intent(in) :: this
logical :: ret
ret = .not. lhs < this
end function ROUTINE(ge_r,VAR)
function ROUTINE(le_l,VAR)(this,rhs) result(ret)
type(var), intent(in) :: this
VAR_TYPE, intent(in)DIMS :: rhs
logical :: ret
ret = .not. this > rhs
end function ROUTINE(le_l,VAR)
function ROUTINE(le_r,VAR)(lhs,this) result(ret)
VAR_TYPE, intent(in)DIMS :: lhs
type(var), intent(in) :: this
logical :: ret
ret = .not. lhs > this
end function ROUTINE(le_r,VAR)
#endif