aGrUM
0.20.3
a C++ library for (probabilistic) graphical models
PRMClass_tpl.h
Go to the documentation of this file.
1
/**
2
*
3
* Copyright (c) 2005-2021 by Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
4
* info_at_agrum_dot_org
5
*
6
* This library is free software: you can redistribute it and/or modify
7
* it under the terms of the GNU Lesser General Public License as published by
8
* the Free Software Foundation, either version 3 of the License, or
9
* (at your option) any later version.
10
*
11
* This library is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU Lesser General Public License for more details.
15
*
16
* You should have received a copy of the GNU Lesser General Public License
17
* along with this library. If not, see <http://www.gnu.org/licenses/>.
18
*
19
*/
20
21
22
/**
23
* @file
24
* @brief Inline implementation of gum::Class
25
*
26
* @author Lionel TORTI and Pierre-Henri WUILLEMIN(@LIP6)
27
*/
28
29
// to ease parsing
30
#
include
<
queue
>
31
32
#
include
<
agrum
/
PRM
/
elements
/
PRMClass
.
h
>
33
34
#
include
<
agrum
/
PRM
/
elements
/
PRMInterface
.
h
>
35
36
namespace
gum
{
37
namespace
prm
{
38
template
<
typename
GUM_SCALAR >
39
PRMClass< GUM_SCALAR >::PRMClass(
const
std::string& name) :
40
PRMClassElementContainer< GUM_SCALAR >(name), _superClass_(
nullptr
), _implements_(
nullptr
),
41
_bijection_(
nullptr
) {
42
GUM_CONSTRUCTOR(PRMClass);
43
}
44
45
template
<
typename
GUM_SCALAR
>
46
PRMClass
<
GUM_SCALAR
>::
PRMClass
(
const
std
::
string
&
name
,
47
PRMClass
<
GUM_SCALAR
>&
super
,
48
bool
delayInheritance
) :
49
PRMClassElementContainer
<
GUM_SCALAR
>(
name
),
50
_superClass_
(&
super
),
_implements_
(
nullptr
),
51
_bijection_
(
new
Bijection
<
const
DiscreteVariable
*,
const
DiscreteVariable
* >()) {
52
GUM_CONSTRUCTOR
(
PRMClass
);
53
if
(!
delayInheritance
) {
54
_dag_
=
super
.
containerDag
();
55
_inheritClass_
(
super
);
56
}
57
}
58
59
template
<
typename
GUM_SCALAR
>
60
PRMClass
<
GUM_SCALAR
>::
PRMClass
(
const
std
::
string
&
name
,
61
const
Set
<
PRMInterface
<
GUM_SCALAR
>* >&
set
,
62
bool
delayInheritance
) :
63
PRMClassElementContainer
<
GUM_SCALAR
>(
name
),
64
_superClass_
(
nullptr
),
_implements_
(
new
Set
<
PRMInterface
<
GUM_SCALAR
>* >(
set
)),
65
_bijection_
(
nullptr
) {
66
GUM_CONSTRUCTOR
(
PRMClass
);
67
68
if
(!
delayInheritance
) {
_implementInterfaces_
(
false
); }
69
}
70
71
template
<
typename
GUM_SCALAR
>
72
PRMClass
<
GUM_SCALAR
>::
PRMClass
(
const
std
::
string
&
name
,
73
PRMClass
<
GUM_SCALAR
>&
super
,
74
const
Set
<
PRMInterface
<
GUM_SCALAR
>* >&
set
,
75
bool
delayInheritance
) :
76
PRMClassElementContainer
<
GUM_SCALAR
>(
name
),
77
_superClass_
(&
super
),
_implements_
(
nullptr
),
78
_bijection_
(
new
Bijection
<
const
DiscreteVariable
*,
const
DiscreteVariable
* >()) {
79
GUM_CONSTRUCTOR
(
PRMClass
);
80
if
(!
delayInheritance
) {
81
_dag_
=
super
.
containerDag
();
82
_inheritClass_
(
super
);
83
}
84
85
// Adding other implementation
86
if
(
_implements_
==
nullptr
) {
// super has not created _implements_
87
_implements_
=
new
Set
<
PRMInterface
<
GUM_SCALAR
>* >(
set
);
88
}
else
{
// we just add the new implementations
89
for
(
const
auto
elt
:
set
) {
90
_implements_
->
insert
(
elt
);
91
}
92
}
93
94
if
(!
delayInheritance
) {
_implementInterfaces_
(
false
); }
95
}
96
97
template
<
typename
GUM_SCALAR
>
98
void
PRMClass
<
GUM_SCALAR
>::
_implementInterfaces_
(
bool
delayedInheritance
) {
99
for
(
const
auto
impl
: *
_implements_
) {
100
impl
->
_addImplementation_
(
this
);
101
if
((!
_superClass_
) || (!
super
().
isSubTypeOf
(*
impl
)) ||
delayedInheritance
) {
102
// Reserve reference id in DAG
103
for
(
auto
ref
:
impl
->
referenceSlots
()) {
104
_dag_
.
addNodeWithId
(
ref
->
id
());
105
}
106
// Reserve attribute id in DAG
107
for
(
auto
attr
:
impl
->
attributes
()) {
108
_dag_
.
addNodeWithId
(
attr
->
id
());
109
}
110
}
111
}
112
}
113
114
template
<
typename
GUM_SCALAR
>
115
PRMClass
<
GUM_SCALAR
>::~
PRMClass
() {
116
GUM_DESTRUCTOR
(
PRMClass
);
117
118
for
(
const
auto
&
elt
:
_nodeIdMap_
) {
119
delete
elt
.
second
;
120
}
121
122
if
(
_implements_
) {
delete
_implements_
; }
123
124
if
(
_bijection_
) {
delete
_bijection_
; }
125
}
126
127
template
<
typename
GUM_SCALAR
>
128
void
PRMClass
<
GUM_SCALAR
>::
initializeInheritance
() {
129
if
(
_superClass_
) {
130
_superClass_
->
_addExtension_
(
this
);
131
// Adding implemented interfaces, if any
132
if
(
_superClass_
->
_implements_
) {
133
if
(!
_implements_
) {
134
_implements_
=
new
Set
<
PRMInterface
<
GUM_SCALAR
>* >(*(
_superClass_
->
_implements_
));
135
}
else
{
136
for
(
auto
i
: *(
_superClass_
->
_implements_
)) {
137
_implements_
->
insert
(
i
);
138
}
139
}
140
}
141
}
142
if
(
_implements_
) {
_implementInterfaces_
(
true
); }
143
}
144
145
template
<
typename
GUM_SCALAR
>
146
void
PRMClass
<
GUM_SCALAR
>::
inheritReferenceSlots
() {
147
if
(
_superClass_
) {
148
// Copying reference slots
149
for
(
const
auto
c_refslot
:
_superClass_
->
_referenceSlots_
) {
150
auto
ref
=
new
PRMReferenceSlot
<
GUM_SCALAR
>(
151
c_refslot
->
name
(),
152
const_cast
<
PRMClassElementContainer
<
GUM_SCALAR
>& >(
c_refslot
->
slotType
()),
153
c_refslot
->
isArray
());
154
155
ref
->
setId
(
c_refslot
->
id
());
156
// Not reserved by an interface
157
if
(!
_dag_
.
existsNode
(
ref
->
id
())) {
_dag_
.
addNodeWithId
(
ref
->
id
()); }
158
_nodeIdMap_
.
insert
(
ref
->
id
(),
ref
);
159
_referenceSlots_
.
insert
(
ref
);
160
161
if
(
_superClass_
->
_nameMap_
[
c_refslot
->
name
()]
162
==
_superClass_
->
_nameMap_
[
c_refslot
->
safeName
()]) {
163
_nameMap_
.
insert
(
ref
->
name
(),
ref
);
164
}
165
166
_nameMap_
.
insert
(
ref
->
safeName
(),
ref
);
167
}
168
}
169
}
170
171
template
<
typename
GUM_SCALAR
>
172
void
PRMClass
<
GUM_SCALAR
>::
inheritParameters
() {
173
if
(
_superClass_
) {
174
// Copying parameters
175
for
(
const
auto
c_param
:
_superClass_
->
_parameters_
) {
176
auto
param
=
new
PRMParameter
<
GUM_SCALAR
>(
c_param
->
name
(),
177
c_param
->
valueType
(),
178
c_param
->
value
());
179
180
_parameters_
.
insert
(
param
);
181
182
param
->
setId
(
c_param
->
id
());
183
_dag_
.
addNodeWithId
(
param
->
id
());
184
_nodeIdMap_
.
insert
(
param
->
id
(),
param
);
185
_nameMap_
.
insert
(
param
->
name
(),
param
);
186
}
187
}
188
}
189
190
template
<
typename
GUM_SCALAR
>
191
void
PRMClass
<
GUM_SCALAR
>::
inheritAttributes
() {
192
if
(
_superClass_
) {
193
for
(
const
auto
c_attr
:
_superClass_
->
_attributes_
) {
194
// using multiDimSparse to prevent unecessary memory allocation for
195
// large arrays (the potentials are copied latter)
196
auto
attr
=
c_attr
->
newFactory
(*
this
);
197
198
_bijection_
->
insert
(&(
c_attr
->
type
().
variable
()), &(
attr
->
type
().
variable
()));
199
attr
->
setId
(
c_attr
->
id
());
200
try
{
201
_dag_
.
addNodeWithId
(
attr
->
id
());
202
}
catch
(
gum
::
Exception
&) {
203
// Node reserved by an interface
204
}
205
_nodeIdMap_
.
insert
(
attr
->
id
(),
attr
);
206
_attributes_
.
insert
(
attr
);
207
208
if
(
_superClass_
->
_nameMap_
[
c_attr
->
name
()]
209
==
_superClass_
->
_nameMap_
[
c_attr
->
safeName
()]) {
210
_nameMap_
.
insert
(
attr
->
name
(),
attr
);
211
}
212
213
_nameMap_
.
insert
(
attr
->
safeName
(),
attr
);
214
}
215
}
216
}
217
218
template
<
typename
GUM_SCALAR
>
219
void
PRMClass
<
GUM_SCALAR
>::
inheritAggregates
() {
220
if
(
_superClass_
) {
221
for
(
const
auto
c_agg
:
_superClass_
->
_aggregates_
) {
222
PRMAggregate
<
GUM_SCALAR
>*
agg
=
nullptr
;
223
224
try
{
225
agg
=
new
PRMAggregate
<
GUM_SCALAR
>(
c_agg
->
name
(),
226
c_agg
->
agg_type
(),
227
c_agg
->
type
(),
228
c_agg
->
label
());
229
}
catch
(
OperationNotAllowed
&) {
230
agg
=
new
PRMAggregate
<
GUM_SCALAR
>(
c_agg
->
name
(),
c_agg
->
agg_type
(),
c_agg
->
type
());
231
agg
->
sharedLabel
(
c_agg
->
sharedLabel
());
232
agg
->
setLabel
(
c_agg
->
labelValue
());
233
}
234
235
_bijection_
->
insert
(&(
c_agg
->
type
().
variable
()), &(
agg
->
type
().
variable
()));
236
agg
->
setId
(
c_agg
->
id
());
237
_dag_
.
addNodeWithId
(
agg
->
id
());
238
_nodeIdMap_
.
insert
(
agg
->
id
(),
agg
);
239
_aggregates_
.
insert
(
agg
);
240
241
if
(
_superClass_
->
_nameMap_
[
c_agg
->
name
()] ==
_superClass_
->
_nameMap_
[
c_agg
->
safeName
()])
242
_nameMap_
.
insert
(
agg
->
name
(),
agg
);
243
244
_nameMap_
.
insert
(
agg
->
safeName
(),
agg
);
245
}
246
}
247
}
248
249
template
<
typename
GUM_SCALAR
>
250
void
PRMClass
<
GUM_SCALAR
>::
inheritSlotChains
() {
251
if
(
_superClass_
) {
252
// Copying slot chains
253
for
(
const
auto
c_sc
:
_superClass_
->
_slotChains_
) {
254
// Because of aggregators, some slotchains may exists already
255
if
(!(
_nameMap_
.
exists
(
c_sc
->
name
()) &&
_nameMap_
.
exists
(
c_sc
->
safeName
()))) {
256
// We just need to change the first PRMReferenceSlot<GUM_SCALAR> in
257
// the
258
// chain
259
auto
chain
=
c_sc
->
chain
();
260
261
chain
.
setAtPos
(0,
_nameMap_
[
c_sc
->
chain
().
front
()->
name
()]);
262
263
auto
sc
=
new
PRMSlotChain
<
GUM_SCALAR
>(
c_sc
->
name
(),
chain
);
264
_bijection_
->
insert
(&(
c_sc
->
type
().
variable
()), &(
sc
->
type
().
variable
()));
265
sc
->
setId
(
c_sc
->
id
());
266
_dag_
.
addNodeWithId
(
sc
->
id
());
267
_nodeIdMap_
.
insert
(
sc
->
id
(),
sc
);
268
_slotChains_
.
insert
(
sc
);
269
270
if
(!
_nameMap_
.
exists
(
sc
->
name
())) {
_nameMap_
.
insert
(
sc
->
name
(),
sc
); }
271
if
(!
_nameMap_
.
exists
(
sc
->
safeName
())) {
_nameMap_
.
insert
(
sc
->
safeName
(),
sc
); }
272
}
273
}
274
}
275
}
276
277
template
<
typename
GUM_SCALAR
>
278
void
PRMClass
<
GUM_SCALAR
>::
completeInheritance
(
const
std
::
string
&
name
) {
279
if
(
_superClass_
) {
280
auto
&
elt
=
this
->
get
(
name
);
281
if
(!(
PRMClassElement
<
GUM_SCALAR
>::
isAttribute
(
elt
)
282
||
PRMClassElement
<
GUM_SCALAR
>::
isAggregate
(
elt
))) {
283
GUM_ERROR
(
OperationNotAllowed
,
"you can only complete inheritance for attributes"
)
284
}
285
286
for
(
const
auto
&
prnt
:
super
().
containerDag
().
parents
(
elt
.
id
())) {
287
this
->
addArc
(
super
().
get
(
prnt
).
safeName
(),
elt
.
safeName
());
288
}
289
290
if
(
PRMClassElement
<
GUM_SCALAR
>::
isAttribute
(
elt
)) {
291
auto
&
attr
=
static_cast
<
PRMAttribute
<
GUM_SCALAR
>& >(
elt
);
292
auto
&
super_attr
=
static_cast
<
const
PRMAttribute
<
GUM_SCALAR
>& >(
super
().
get
(
name
));
293
attr
.
copyCpf
(*
_bijection_
,
super_attr
);
294
}
295
}
296
}
297
298
template
<
typename
GUM_SCALAR
>
299
void
PRMClass
<
GUM_SCALAR
>::
_inheritClass_
(
const
PRMClass
<
GUM_SCALAR
>&
c
) {
300
if
(
_superClass_
) {
301
_superClass_
->
_addExtension_
(
this
);
302
// Adding implemented interfaces of c, if any
303
if
(
c
.
_implements_
) {
304
if
(!
_implements_
) {
305
_implements_
=
new
Set
<
PRMInterface
<
GUM_SCALAR
>* >(*(
c
.
_implements_
));
306
}
else
{
307
for
(
auto
i
: *(
c
.
_implements_
)) {
308
_implements_
->
insert
(
i
);
309
}
310
}
311
}
312
313
// Copying attributes, the bijection's firsts are attributes in this and
314
// its
315
// seconds are attributes
316
// in c.
317
Bijection
<
const
DiscreteVariable
*,
const
DiscreteVariable
* >
bij
;
318
319
// Copying parameters
320
for
(
const
auto
c_param
:
c
.
_parameters_
) {
321
auto
param
=
new
PRMParameter
<
GUM_SCALAR
>(
c_param
->
name
(),
322
c_param
->
valueType
(),
323
c_param
->
value
());
324
325
_parameters_
.
insert
(
param
);
326
327
param
->
setId
(
c_param
->
id
());
328
_nodeIdMap_
.
insert
(
param
->
id
(),
param
);
329
_nameMap_
.
insert
(
param
->
name
(),
param
);
330
}
331
332
// Copying attributes
333
for
(
const
auto
c_attr
:
c
.
_attributes_
) {
334
// using multiDimSparse to prevent unecessary memory allocation for
335
// large arrays (the potentials are copied latter)
336
auto
attr
=
c_attr
->
newFactory
(*
this
);
337
338
bij
.
insert
(&(
c_attr
->
type
().
variable
()), &(
attr
->
type
().
variable
()));
339
attr
->
setId
(
c_attr
->
id
());
340
_nodeIdMap_
.
insert
(
attr
->
id
(),
attr
);
341
_attributes_
.
insert
(
attr
);
342
343
if
(
c
.
_nameMap_
[
c_attr
->
name
()] ==
c
.
_nameMap_
[
c_attr
->
safeName
()]) {
344
_nameMap_
.
insert
(
attr
->
name
(),
attr
);
345
}
346
347
_nameMap_
.
insert
(
attr
->
safeName
(),
attr
);
348
}
349
350
// Copying aggregates
351
for
(
const
auto
c_agg
:
c
.
_aggregates_
) {
352
PRMAggregate
<
GUM_SCALAR
>*
agg
=
nullptr
;
353
354
try
{
355
agg
=
new
PRMAggregate
<
GUM_SCALAR
>(
c_agg
->
name
(),
356
c_agg
->
agg_type
(),
357
c_agg
->
type
(),
358
c_agg
->
label
());
359
}
catch
(
OperationNotAllowed
&) {
360
agg
=
new
PRMAggregate
<
GUM_SCALAR
>(
c_agg
->
name
(),
c_agg
->
agg_type
(),
c_agg
->
type
());
361
}
362
363
bij
.
insert
(&(
c_agg
->
type
().
variable
()), &(
agg
->
type
().
variable
()));
364
agg
->
setId
(
c_agg
->
id
());
365
_nodeIdMap_
.
insert
(
agg
->
id
(),
agg
);
366
_aggregates_
.
insert
(
agg
);
367
368
if
(
c
.
_nameMap_
[
c_agg
->
name
()] ==
c
.
_nameMap_
[
c_agg
->
safeName
()])
369
_nameMap_
.
insert
(
agg
->
name
(),
agg
);
370
371
_nameMap_
.
insert
(
agg
->
safeName
(),
agg
);
372
}
373
374
// Copying reference slots
375
for
(
const
auto
c_refslot
:
c
.
_referenceSlots_
) {
376
PRMReferenceSlot
<
GUM_SCALAR
>*
ref
=
new
PRMReferenceSlot
<
GUM_SCALAR
>(
377
c_refslot
->
name
(),
378
const_cast
<
PRMClassElementContainer
<
GUM_SCALAR
>& >(
c_refslot
->
slotType
()),
379
c_refslot
->
isArray
());
380
381
ref
->
setId
(
c_refslot
->
id
());
382
_nodeIdMap_
.
insert
(
ref
->
id
(),
ref
);
383
_referenceSlots_
.
insert
(
ref
);
384
385
if
(
c
.
_nameMap_
[
c_refslot
->
name
()] ==
c
.
_nameMap_
[
c_refslot
->
safeName
()])
386
_nameMap_
.
insert
(
ref
->
name
(),
ref
);
387
388
_nameMap_
.
insert
(
ref
->
safeName
(),
ref
);
389
}
390
391
// Copying slot chains
392
for
(
const
auto
c_slotchain
:
c
.
_slotChains_
) {
393
// We just need to change the first PRMReferenceSlot<GUM_SCALAR> in
394
// the
395
// chain
396
Sequence
<
PRMClassElement
<
GUM_SCALAR
>* >
chain
(
c_slotchain
->
chain
());
397
398
chain
.
setAtPos
(0,
_nameMap_
[
c_slotchain
->
chain
().
front
()->
name
()]);
399
400
PRMSlotChain
<
GUM_SCALAR
>*
sc
401
=
new
PRMSlotChain
<
GUM_SCALAR
>(
c_slotchain
->
name
(),
chain
);
402
bij
.
insert
(&(
c_slotchain
->
type
().
variable
()), &(
sc
->
type
().
variable
()));
403
sc
->
setId
(
c_slotchain
->
id
());
404
_nodeIdMap_
.
insert
(
sc
->
id
(),
sc
);
405
_slotChains_
.
insert
(
sc
);
406
407
_nameMap_
.
insert
(
sc
->
name
(),
sc
);
408
_nameMap_
.
insert
(
sc
->
safeName
(),
sc
);
409
}
410
411
// Copying dependencies yield by arcs
412
for
(
const
auto
&
arc
:
c
.
containerDag
().
arcs
()) {
413
_nodeIdMap_
[
arc
.
tail
()]->
addChild
(*(
_nodeIdMap_
[
arc
.
head
()]));
414
_nodeIdMap_
[
arc
.
head
()]->
addParent
(*(
_nodeIdMap_
[
arc
.
tail
()]));
415
}
416
417
// Copying the IO flag
418
this
->
copyIOFlags_
(
c
);
419
// Copying content of CPF
420
for
(
const
auto
attr
:
c
.
_attributes_
) {
421
auto
a
=
static_cast
<
PRMAttribute
<
GUM_SCALAR
>* >(
_nameMap_
[
attr
->
safeName
()]);
422
a
->
copyCpf
(
bij
, *
attr
);
423
}
424
}
425
}
426
427
template
<
typename
GUM_SCALAR
>
428
bool
PRMClass
<
GUM_SCALAR
>::
isSubTypeOf
(
429
const
PRMClassElementContainer
<
GUM_SCALAR
>&
cec
)
const
{
430
switch
(
cec
.
obj_type
()) {
431
case
PRMObject
::
prm_type
::
CLASS
: {
432
const
PRMClass
<
GUM_SCALAR
>*
current
=
this
;
433
434
while
(
current
!= 0) {
435
if
(
current
== &(
cec
))
return
true
;
436
437
current
=
current
->
_superClass_
;
438
}
439
440
return
false
;
441
}
442
443
case
PRMObject
::
prm_type
::
PRM_INTERFACE
: {
444
if
(
_implements_
!=
nullptr
) {
445
const
PRMInterface
<
GUM_SCALAR
>&
i
446
=
static_cast
<
const
PRMInterface
<
GUM_SCALAR
>& >(
cec
);
447
448
if
(
_implements_
->
exists
(
const_cast
<
PRMInterface
<
GUM_SCALAR
>* >(&
i
)))
return
true
;
449
450
for
(
const
auto
impl
: *
_implements_
)
451
if
(
impl
->
isSubTypeOf
(
i
))
return
true
;
452
}
453
454
return
false
;
455
}
456
457
default
: {
458
GUM_ERROR
(
FatalError
,
"unknown ClassElementContainer<GUM_SCALAR>"
)
459
}
460
}
461
}
462
463
template
<
typename
GUM_SCALAR
>
464
void
PRMClass
<
GUM_SCALAR
>::
addArc
(
const
std
::
string
&
tail_name
,
465
const
std
::
string
&
head_name
) {
466
PRMClassElement
<
GUM_SCALAR
>*
tail
= 0;
467
PRMClassElement
<
GUM_SCALAR
>*
head
= 0;
468
469
try
{
470
tail
=
_nameMap_
[
tail_name
];
471
head
=
_nameMap_
[
head_name
];
472
}
catch
(
NotFound
&) {
473
GUM_ERROR
(
NotFound
,
"tail and/or head of arc does not exists in this Class"
)
474
}
475
476
if
((
tail
->
elt_type
() ==
PRMClassElement
<
GUM_SCALAR
>::
prm_refslot
)
477
|| (
head
->
elt_type
() ==
PRMClassElement
<
GUM_SCALAR
>::
prm_refslot
)) {
478
GUM_ERROR
(
OperationNotAllowed
,
479
"a PRMReferenceSlot<GUM_SCALAR> can "
480
"not on neither side of an arc"
);
481
}
482
483
if
((
tail
->
elt_type
() ==
PRMClassElement
<
GUM_SCALAR
>::
prm_slotchain
)
484
&& (
head
->
elt_type
() ==
PRMClassElement
<
GUM_SCALAR
>::
prm_slotchain
)) {
485
GUM_ERROR
(
OperationNotAllowed
,
486
"illegal insertion of an arc between two SlotChain<GUM_SCALAR>"
)
487
}
488
489
if
(!
_dag_
.
existsArc
(
Arc
(
tail
->
id
(),
head
->
id
()))) {
490
_dag_
.
addArc
(
tail
->
id
(),
head
->
id
());
491
}
else
{
492
GUM_ERROR
(
DuplicateElement
,
"duplicate arc "
<<
tail_name
<<
"->"
<<
head_name
)
493
}
494
495
get
(
tail
->
id
()).
addChild
(
get
(
head
->
id
()));
496
get
(
head
->
id
()).
addParent
(
get
(
tail
->
id
()));
497
498
// Defining input / output nodes
499
if
(
tail
->
elt_type
() ==
PRMClassElement
<
GUM_SCALAR
>::
prm_slotchain
) {
500
PRMSlotChain
<
GUM_SCALAR
>*
sc
=
static_cast
<
PRMSlotChain
<
GUM_SCALAR
>* >(
tail
);
501
this
->
setInputNode
(*
head
,
true
);
502
sc
->
end
().
setOutputNode
(
sc
->
end
().
get
(
sc
->
lastElt
().
safeName
()),
true
);
503
}
504
}
505
506
template
<
typename
GUM_SCALAR
>
507
void
PRMClass
<
GUM_SCALAR
>::
_checkInterfaces_
(
PRMClassElement
<
GUM_SCALAR
>*
elt
) {
508
try
{
509
for
(
auto
i
:
implements
()) {
510
if
(
i
->
exists
(
elt
->
name
())) {
_checkInterface_
(
elt
,
i
); }
511
}
512
}
catch
(
NotFound
&) {
513
// No interface
514
}
515
}
516
517
template
<
typename
GUM_SCALAR
>
518
void
PRMClass
<
GUM_SCALAR
>::
_checkInterface_
(
PRMClassElement
<
GUM_SCALAR
>*
elt
,
519
PRMInterface
<
GUM_SCALAR
>*
i
) {
520
const
auto
&
i_elt
=
i
->
get
(
elt
->
name
());
521
bool
is_attr
=
PRMClassElement
<
GUM_SCALAR
>::
isAttribute
(
i_elt
);
522
bool
is_agg
=
PRMClassElement
<
GUM_SCALAR
>::
isAggregate
(
i_elt
);
523
524
if
(!(
is_attr
||
is_agg
)) {
525
GUM_ERROR
(
OperationNotAllowed
,
"Class does not respect it's interface"
)
526
}
527
528
if
(!
elt
->
type
().
isSubTypeOf
(
i_elt
.
type
())) {
529
GUM_ERROR
(
OperationNotAllowed
,
"Attribute type does not respect class interface"
)
530
}
531
532
if
(
elt
->
type
() !=
i_elt
.
type
()) {
533
if
(!
this
->
exists
(
i_elt
.
safeName
())) {
534
GUM_ERROR
(
OperationNotAllowed
,
"Attribute type does not respect class interface"
)
535
}
536
elt
= &(
this
->
get
(
i_elt
.
safeName
()));
537
}
538
539
// Node must be reserved by constructor
540
if
(!
_dag_
.
existsNode
(
i_elt
.
id
())) {
541
GUM_ERROR
(
FatalError
,
"Class does not reserved implemented nodes"
)
542
}
543
544
// Removing unused node and changing to proper node
545
if
(
elt
->
id
() !=
i_elt
.
id
()) {
546
// Update cast descendants
547
for
(
auto
child
:
_dag_
.
children
(
elt
->
id
())) {
548
_dag_
.
addArc
(
i_elt
.
id
(),
child
);
549
}
550
_dag_
.
eraseNode
(
elt
->
id
());
551
}
552
_nodeIdMap_
.
erase
(
elt
->
id
());
553
elt
->
setId
(
i_elt
.
id
());
554
_nodeIdMap_
.
insert
(
elt
->
id
(),
elt
);
555
}
556
557
template
<
typename
GUM_SCALAR
>
558
void
PRMClass
<
GUM_SCALAR
>::
_checkRefInterfaces_
(
PRMReferenceSlot
<
GUM_SCALAR
>*
ref
) {
559
try
{
560
for
(
auto
i
:
implements
()) {
561
if
(
i
->
exists
(
ref
->
name
())) {
_checkRefInterface_
(
ref
,
i
); }
562
}
563
}
catch
(
NotFound
&) {
564
// No interface to check
565
}
566
}
567
568
template
<
typename
GUM_SCALAR
>
569
void
PRMClass
<
GUM_SCALAR
>::
_checkRefInterface_
(
PRMReferenceSlot
<
GUM_SCALAR
>*
ref
,
570
PRMInterface
<
GUM_SCALAR
>*
i
) {
571
auto
&
i_elt
=
i
->
get
(
ref
->
name
());
572
if
(
i_elt
.
elt_type
() !=
ref
->
elt_type
()) {
573
GUM_ERROR
(
OperationNotAllowed
,
"Class does not respect it's interface"
)
574
}
575
auto
&
i_ref
=
static_cast
<
PRMReferenceSlot
<
GUM_SCALAR
>& >(
i_elt
);
576
if
(!
ref
->
slotType
().
isSubTypeOf
(
i_ref
.
slotType
())) {
577
GUM_ERROR
(
OperationNotAllowed
,
"ReferenceSlot type does not respect class interface"
)
578
}
579
// Node must be reserved by constructor
580
if
(!
_dag_
.
exists
(
i_ref
.
id
())) {
581
GUM_ERROR
(
FatalError
,
582
"class "
<<
this
->
name
() <<
" does not respect interface "
<<
i
->
name
()
583
<<
" implementation"
);
584
}
585
// Removing unused node and changin to propoer node
586
if
(
ref
->
id
() !=
i_ref
.
id
()) {
_dag_
.
eraseNode
(
ref
->
id
()); }
587
_nodeIdMap_
.
erase
(
ref
->
id
());
588
ref
->
setId
(
i_ref
.
id
());
589
_nodeIdMap_
.
insert
(
ref
->
id
(),
ref
);
590
}
591
592
template
<
typename
GUM_SCALAR
>
593
NodeId
PRMClass
<
GUM_SCALAR
>::
add
(
PRMClassElement
<
GUM_SCALAR
>*
elt
) {
594
if
(
_nameMap_
.
exists
(
elt
->
name
())) {
595
GUM_ERROR
(
DuplicateElement
,
596
"name "
<<
elt
->
name
() <<
" already used by another ClassElement"
);
597
}
598
599
elt
->
setId
(
nextNodeId
());
600
_dag_
.
addNodeWithId
(
elt
->
id
());
601
_nodeIdMap_
.
insert
(
elt
->
id
(),
elt
);
602
_nameMap_
.
insert
(
elt
->
name
(),
elt
);
603
604
try
{
605
_nameMap_
.
insert
(
elt
->
safeName
(),
elt
);
606
}
catch
(
DuplicateElement
&
e
) {
607
if
(!(
PRMClassElement
<
GUM_SCALAR
>::
isSlotChain
(*
elt
)
608
||
PRMClassElement
<
GUM_SCALAR
>::
isParameter
(*
elt
))) {
609
throw
DuplicateElement
(
e
);
610
}
611
}
612
613
switch
(
elt
->
elt_type
()) {
614
case
PRMClassElement
<
GUM_SCALAR
>::
prm_attribute
: {
615
_attributes_
.
insert
(
static_cast
<
PRMAttribute
<
GUM_SCALAR
>* >(
elt
));
616
_addCastDescendants_
(
static_cast
<
PRMAttribute
<
GUM_SCALAR
>* >(
elt
));
617
618
// Update attribute or cast descendant id to respect implemented
619
// interface
620
_checkInterfaces_
(
elt
);
621
622
_addIOInterfaceFlags_
(
elt
);
623
break
;
624
}
625
626
case
PRMClassElement
<
GUM_SCALAR
>::
prm_aggregate
: {
627
_aggregates_
.
insert
(
static_cast
<
PRMAggregate
<
GUM_SCALAR
>* >(
elt
));
628
_addCastDescendants_
(
static_cast
<
PRMAttribute
<
GUM_SCALAR
>* >(
elt
));
629
630
// Update attribute or cast descendant id to respect implemented
631
// interface
632
_checkInterfaces_
(
elt
);
633
634
_addIOInterfaceFlags_
(
elt
);
635
break
;
636
}
637
638
case
PRMClassElement
<
GUM_SCALAR
>::
prm_refslot
: {
639
auto
ref
=
static_cast
<
PRMReferenceSlot
<
GUM_SCALAR
>* >(
elt
);
640
_referenceSlots_
.
insert
(
ref
);
641
642
// Updating ref's id if ref implements an interface
643
_checkRefInterfaces_
(
ref
);
644
break
;
645
}
646
647
case
PRMClassElement
<
GUM_SCALAR
>::
prm_slotchain
: {
648
_slotChains_
.
insert
(
static_cast
<
PRMSlotChain
<
GUM_SCALAR
>* >(
elt
));
649
break
;
650
}
651
652
case
PRMClassElement
<
GUM_SCALAR
>::
prm_parameter
: {
653
_parameters_
.
insert
(
static_cast
<
PRMParameter
<
GUM_SCALAR
>* >(
elt
));
654
break
;
655
}
656
657
default
: {
658
GUM_ERROR
(
FatalError
,
"unknown ClassElement<GUM_SCALAR> type"
)
659
}
660
}
661
662
return
elt
->
id
();
663
}
664
665
template
<
typename
GUM_SCALAR
>
666
void
PRMClass
<
GUM_SCALAR
>::
_addCastDescendants_
(
PRMClassElement
<
GUM_SCALAR
>*
attr
) {
667
auto
parent
=
attr
;
668
PRMAttribute
<
GUM_SCALAR
>*
child
= 0;
669
670
while
(
parent
->
type
().
isSubType
()) {
671
child
=
parent
->
getCastDescendant
();
672
673
// Check if id was reserved by one of the class interfaces
674
bool
found
=
false
;
675
try
{
676
for
(
auto
i
:
implements
()) {
677
if
(
i
->
exists
(
child
->
safeName
())) {
678
child
->
setId
(
i
->
get
(
child
->
safeName
()).
id
());
679
found
=
true
;
680
break
;
681
}
682
}
683
}
catch
(
NotFound
&) {
684
// No interface
685
}
686
if
(!
found
) {
687
child
->
setId
(
nextNodeId
());
688
_dag_
.
addNodeWithId
(
child
->
id
());
689
}
690
_nodeIdMap_
.
insert
(
child
->
id
(),
child
);
691
// Only use child's safe name when adding to the name map!
692
_nameMap_
.
insert
(
child
->
safeName
(),
child
);
693
_attributes_
.
insert
(
child
);
694
// Do not use Class<GUM_SCALAR>::insertArc(), child's CPF is already
695
// initialized properly
696
_dag_
.
addArc
(
parent
->
id
(),
child
->
id
());
697
698
parent
=
child
;
699
}
700
}
701
702
template
<
typename
GUM_SCALAR
>
703
NodeId
PRMClass
<
GUM_SCALAR
>::
overload
(
PRMClassElement
<
GUM_SCALAR
>*
overloader
) {
704
try
{
705
if
(!
super
().
exists
(
overloader
->
name
())) {
706
GUM_ERROR
(
OperationNotAllowed
,
"found no ClassElement<GUM_SCALAR> to overload"
)
707
}
708
}
catch
(
NotFound
&) {
709
GUM_ERROR
(
OperationNotAllowed
,
"overload is possible only with subclasses"
)
710
}
711
712
PRMClassElement
<
GUM_SCALAR
>*
overloaded
=
_nameMap_
[
overloader
->
name
()];
713
if
(
overloaded
==
overloader
) {
714
GUM_ERROR
(
DuplicateElement
,
"dupplicate ClassElement "
<<
overloader
->
name
())
715
}
716
// Checking overload legality
717
if
(!
_checkOverloadLegality_
(
overloaded
,
overloader
)) {
718
GUM_ERROR
(
OperationNotAllowed
,
"illegal overload"
)
719
}
720
721
switch
(
overloader
->
elt_type
()) {
722
case
PRMClassElement
<
GUM_SCALAR
>::
prm_attribute
: {
723
auto
overloader_attr
=
static_cast
<
PRMAttribute
<
GUM_SCALAR
>* >(
overloader
);
724
auto
overloaded_attr
=
static_cast
<
PRMAttribute
<
GUM_SCALAR
>* >(
overloaded
);
725
_overloadAttribute_
(
overloader_attr
,
overloaded_attr
);
726
_addIOInterfaceFlags_
(
overloader
);
727
break
;
728
}
729
730
case
PRMClassElement
<
GUM_SCALAR
>::
prm_aggregate
: {
731
_overloadAggregate_
(
static_cast
<
PRMAggregate
<
GUM_SCALAR
>* >(
overloader
),
overloaded
);
732
_addIOInterfaceFlags_
(
overloader
);
733
break
;
734
}
735
736
case
PRMClassElement
<
GUM_SCALAR
>::
prm_refslot
: {
737
// _checkOverloadLegality_ guaranties that overloaded is a
738
// PRMReferenceSlot<GUM_SCALAR>
739
auto
overloader_ref
=
static_cast
<
PRMReferenceSlot
<
GUM_SCALAR
>* >(
overloader
);
740
auto
overloaded_ref
=
static_cast
<
PRMReferenceSlot
<
GUM_SCALAR
>* >(
overloaded
);
741
_overloadReference_
(
overloader_ref
,
overloaded_ref
);
742
break
;
743
}
744
745
case
PRMClassElement
<
GUM_SCALAR
>::
prm_slotchain
: {
746
GUM_ERROR
(
OperationNotAllowed
,
"SlotChain<GUM_SCALAR> can not be overloaded"
)
747
break
;
748
}
749
750
case
PRMClassElement
<
GUM_SCALAR
>::
prm_parameter
: {
751
auto
overloaded_param
=
static_cast
<
PRMParameter
<
GUM_SCALAR
>* >(
overloaded
);
752
auto
overloader_param
=
static_cast
<
PRMParameter
<
GUM_SCALAR
>* >(
overloader
);
753
_overloadParameter_
(
overloader_param
,
overloaded_param
);
754
break
;
755
}
756
default
: {
757
GUM_ERROR
(
OperationNotAllowed
,
"unknown ClassElement<GUM_SCALAR> type"
)
758
}
759
}
760
761
return
overloader
->
id
();
762
}
763
764
template
<
typename
GUM_SCALAR
>
765
void
PRMClass
<
GUM_SCALAR
>::
_overloadAttribute_
(
PRMAttribute
<
GUM_SCALAR
>*
overloader
,
766
PRMAttribute
<
GUM_SCALAR
>*
overloaded
) {
767
_dag_
.
eraseParents
(
overloaded
->
id
());
768
769
// Checking if we have to add cast descendant
770
if
(
overloader
->
type
() !=
overloaded
->
type
()) {
771
overloader
->
setId
(
nextNodeId
());
772
_dag_
.
addNodeWithId
(
overloader
->
id
());
773
_nodeIdMap_
.
insert
(
overloader
->
id
(),
overloader
);
774
_nameMap_
[
overloader
->
name
()] =
overloader
;
775
_nameMap_
.
insert
(
overloader
->
safeName
(),
overloader
);
776
_attributes_
.
insert
(
overloader
);
777
_addCastDescendants_
(
overloader
,
overloaded
);
778
}
else
{
779
overloader
->
setId
(
overloaded
->
id
());
780
_nodeIdMap_
[
overloader
->
id
()] =
overloader
;
781
_nameMap_
[
overloader
->
name
()] =
overloader
;
782
_nameMap_
[
overloader
->
safeName
()] =
overloader
;
783
_attributes_
.
erase
(
overloaded
);
784
_attributes_
.
insert
(
overloader
);
785
overloader
->
overload
(
overloaded
);
786
delete
overloaded
;
787
}
788
}
789
790
template
<
typename
GUM_SCALAR
>
791
void
PRMClass
<
GUM_SCALAR
>::
_overloadReference_
(
PRMReferenceSlot
<
GUM_SCALAR
>*
overloader
,
792
PRMReferenceSlot
<
GUM_SCALAR
>*
overloaded
) {
793
// Adding overloading reference
794
overloader
->
setId
(
overloaded
->
id
());
795
_nodeIdMap_
[
overloader
->
id
()] =
overloader
;
796
_nameMap_
[
overloader
->
name
()] =
overloader
;
797
_nameMap_
.
insert
(
overloader
->
safeName
(),
overloader
);
798
_referenceSlots_
.
insert
(
overloader
);
799
PRMSlotChain
<
GUM_SCALAR
>*
sc
= 0;
800
PRMReferenceSlot
<
GUM_SCALAR
>*
ref
= 0;
801
PRMClassElement
<
GUM_SCALAR
>*
next
= 0;
802
std
::
vector
<
PRMSlotChain
<
GUM_SCALAR
>* >
toRemove
,
toAdd
;
803
804
// Updating PRMSlotChain<GUM_SCALAR> which started with overloaded
805
for
(
const
auto
slotchain
:
_slotChains_
) {
806
// If the attribute pointed by this slotchain is overloaded, we need to
807
// change the slotchain
808
// names to it's safename version: ref.attr is replaced by
809
// ref.(type)attr.
810
if
((
slotchain
->
chain
().
atPos
(0) ==
overloaded
)) {
811
Sequence
<
PRMClassElement
<
GUM_SCALAR
>* >
seq
;
812
seq
.
insert
(
overloader
);
813
814
auto
elt
= ++(
slotchain
->
chain
().
begin
());
815
816
while
(
elt
!=
slotchain
->
chain
().
end
()) {
817
ref
=
static_cast
<
PRMReferenceSlot
<
GUM_SCALAR
>* >(
seq
.
back
());
818
next
= &(
ref
->
slotType
().
get
((*
elt
)->
name
()));
819
seq
.
insert
(
next
);
820
++
elt
;
821
}
822
823
// If the slotchain last element type changes, we change the slotchain
824
// to
825
// point towards the cast decendant
826
// with the correct type
827
if
(
seq
.
back
()->
type
() !=
slotchain
->
lastElt
().
type
()) {
828
seq
.
erase
(
seq
.
back
());
829
seq
.
insert
(&(
static_cast
<
PRMReferenceSlot
<
GUM_SCALAR
>* >(
seq
.
back
())
830
->
slotType
()
831
.
get
(
slotchain
->
lastElt
().
safeName
())));
832
std
::
string
sc_name
;
833
std
::
string
dot
=
"."
;
834
835
for
(
Size
i
= 0;
i
<
seq
.
size
() - 1; ++
i
) {
836
sc_name
+=
seq
.
atPos
(
i
)->
name
() +
dot
;
837
}
838
839
sc_name
+=
seq
.
back
()->
safeName
();
840
sc
=
new
PRMSlotChain
<
GUM_SCALAR
>(
sc_name
,
seq
);
841
sc
->
setId
(
slotchain
->
id
());
842
843
for
(
const
auto
child
:
this
->
containerDag
().
children
(
sc
->
id
())) {
844
auto
&
elt
=
get
(
child
);
845
if
(
PRMClassElement
<
GUM_SCALAR
>::
isAttribute
(
elt
)) {
846
auto
&
attr
=
static_cast
<
PRMAttribute
<
GUM_SCALAR
>& >(
elt
);
847
auto
&
old_type
=
slotchain
->
lastElt
().
type
();
848
auto
&
new_type
=
sc
->
lastElt
().
type
();
849
attr
.
swap
(
old_type
,
new_type
);
850
}
else
{
851
GUM_ERROR
(
OperationNotAllowed
,
"unexpected ClassElement"
)
852
// get( child ).cpf().replace(
853
// slotchain->lastElt().type().variable(),
854
// sc->lastElt().type().variable() );
855
}
856
}
857
858
toAdd
.
push_back
(
sc
);
859
toRemove
.
push_back
(
slotchain
);
860
}
else
{
861
// Types are identical, we just need to change the first reference
862
slotchain
->
chain
().
setAtPos
(0,
overloader
);
863
}
864
}
865
}
866
867
for
(
const
auto
torem
:
toRemove
) {
868
_nameMap_
.
erase
(
torem
->
name
());
869
_slotChains_
.
erase
(
torem
);
870
delete
torem
;
871
}
872
873
for
(
const
auto
toadd
:
toAdd
) {
874
_nameMap_
.
insert
(
toadd
->
name
(),
toadd
);
875
_nodeIdMap_
[
toadd
->
id
()] =
toadd
;
876
_slotChains_
.
insert
(
sc
);
877
}
878
879
// Removing overloaded PRMReferenceSlot<GUM_SCALAR>
880
_referenceSlots_
.
erase
(
overloaded
);
881
_nameMap_
.
erase
(
overloaded
->
safeName
());
882
delete
overloaded
;
883
}
884
885
template
<
typename
GUM_SCALAR
>
886
void
PRMClass
<
GUM_SCALAR
>::
_overloadParameter_
(
PRMParameter
<
GUM_SCALAR
>*
overloader
,
887
PRMParameter
<
GUM_SCALAR
>*
overloaded
) {
888
overloader
->
setId
(
overloaded
->
id
());
889
_nodeIdMap_
[
overloader
->
id
()] =
overloader
;
890
_nameMap_
[
overloader
->
name
()] =
overloader
;
891
_nameMap_
[
overloader
->
safeName
()] =
overloader
;
892
_parameters_
.
erase
(
overloaded
);
893
_parameters_
.
insert
(
overloader
);
894
delete
overloaded
;
895
}
896
897
template
<
typename
GUM_SCALAR
>
898
void
PRMClass
<
GUM_SCALAR
>::
_addCastDescendants_
(
PRMAttribute
<
GUM_SCALAR
>*
start
,
899
PRMAttribute
<
GUM_SCALAR
>*
end
) {
900
PRMAttribute
<
GUM_SCALAR
>*
parent
=
start
;
901
PRMAttribute
<
GUM_SCALAR
>*
child
= 0;
902
903
while
(
parent
->
type
().
superType
() !=
end
->
type
()) {
904
child
=
parent
->
getCastDescendant
();
905
child
->
setId
(
nextNodeId
());
906
_nodeIdMap_
.
insert
(
child
->
id
(),
child
);
907
_dag_
.
addNodeWithId
(
child
->
id
());
908
// Only use child's safe name when adding to the name map!
909
_nameMap_
.
insert
(
child
->
safeName
(),
child
);
910
_attributes_
.
insert
(
child
);
911
_addIOInterfaceFlags_
(
child
);
912
// Do not use Class<GUM_SCALAR>::insertArc(), child's CPF is already
913
// initialized properly
914
_dag_
.
addArc
(
parent
->
id
(),
child
->
id
());
915
parent
=
child
;
916
}
917
918
parent
->
setAsCastDescendant
(
end
);
919
_dag_
.
addArc
(
parent
->
id
(),
end
->
id
());
920
}
921
922
template
<
typename
GUM_SCALAR
>
923
void
PRMClass
<
GUM_SCALAR
>::
findAllSubtypes_
(
924
Set
<
PRMClassElementContainer
<
GUM_SCALAR
>* >&
set
) {
925
for
(
auto
ext
:
_extensions_
) {
926
set
.
insert
(
ext
);
927
ext
->
findAllSubtypes_
(
set
);
928
}
929
}
930
931
template
<
typename
GUM_SCALAR
>
932
void
PRMClass
<
GUM_SCALAR
>::
_addIOInterfaceFlags_
(
PRMClassElement
<
GUM_SCALAR
>*
elt
) {
933
// We only add IO Flags if elt matches is required by and interface
934
if
(
_implements_
!=
nullptr
) {
935
for
(
const
auto
impl
: *
_implements_
) {
936
PRMInterface
<
GUM_SCALAR
>*
super
=
impl
;
937
while
(
super
) {
938
// If the attribute is defined in an interface, we set it as an
939
// OutputNode
940
if
(
impl
->
exists
(
elt
->
name
())) {
941
try
{
942
this
->
getIOFlag_
(*
elt
).
second
=
true
;
943
}
catch
(
NotFound
&) {
this
->
setIOFlag_
(*
elt
,
std
::
make_pair
(
false
,
true
)); }
944
}
945
try
{
946
super
= &(
super
->
super
());
947
}
catch
(
NotFound
&) {
super
=
nullptr
; }
948
}
949
}
950
}
951
}
952
953
template
<
typename
GUM_SCALAR
>
954
void
PRMClass
<
GUM_SCALAR
>::
updateDescendants_
(
const
PRMClassElement
<
GUM_SCALAR
>&
elt
) {
955
// for ( const auto ext : _extensions_ ) {
956
// // We test to prevent unnecessary recursive call from iter
957
// if ( !ext->isOutputNode( elt ) ) {
958
// ext->setOutputNode( elt, true );
959
// }
960
//}
961
}
962
963
template
<
typename
GUM_SCALAR
>
964
INLINE
typename
PRMObject
::
prm_type
PRMClass
<
GUM_SCALAR
>::
obj_type
()
const
{
965
return
PRMObject
::
prm_type
::
CLASS
;
966
}
967
968
template
<
typename
GUM_SCALAR
>
969
INLINE
const
DAG
&
PRMClass
<
GUM_SCALAR
>::
dag_
()
const
{
970
return
_dag_
;
971
}
972
973
template
<
typename
GUM_SCALAR
>
974
INLINE
DAG
&
PRMClass
<
GUM_SCALAR
>::
dag_
() {
975
return
_dag_
;
976
}
977
978
template
<
typename
GUM_SCALAR
>
979
INLINE
PRMClassElement
<
GUM_SCALAR
>&
PRMClass
<
GUM_SCALAR
>::
get
(
NodeId
id
) {
980
try
{
981
return
*(
_nodeIdMap_
[
id
]);
982
}
catch
(
NotFound
&) {
983
GUM_ERROR
(
NotFound
,
"no ClassElement<GUM_SCALAR> with the given NodeId"
)
984
}
985
}
986
987
template
<
typename
GUM_SCALAR
>
988
INLINE
const
PRMClassElement
<
GUM_SCALAR
>&
PRMClass
<
GUM_SCALAR
>::
get
(
NodeId
id
)
const
{
989
try
{
990
return
*(
_nodeIdMap_
[
id
]);
991
}
catch
(
NotFound
&) {
992
GUM_ERROR
(
NotFound
,
"no ClassElement<GUM_SCALAR> with the given NodeId ("
<<
id
<<
")"
);
993
}
994
}
995
996
template
<
typename
GUM_SCALAR
>
997
INLINE
PRMClassElement
<
GUM_SCALAR
>&
PRMClass
<
GUM_SCALAR
>::
get
(
const
std
::
string
&
name
) {
998
try
{
999
return
*(
_nameMap_
[
name
]);
1000
}
catch
(
NotFound
&) {
1001
GUM_ERROR
(
NotFound
,
"no ClassElement<GUM_SCALAR> with the given name ("
<<
name
<<
")"
);
1002
}
1003
}
1004
1005
template
<
typename
GUM_SCALAR
>
1006
INLINE
const
PRMClassElement
<
GUM_SCALAR
>&
1007
PRMClass
<
GUM_SCALAR
>::
get
(
const
std
::
string
&
name
)
const
{
1008
try
{
1009
return
*(
_nameMap_
[
name
]);
1010
}
catch
(
NotFound
&) {
1011
GUM_ERROR
(
NotFound
,
"no ClassElement<GUM_SCALAR> with the given name ("
<<
name
<<
")"
);
1012
}
1013
}
1014
1015
template
<
typename
GUM_SCALAR
>
1016
INLINE
const
Set
<
PRMAttribute
<
GUM_SCALAR
>* >&
PRMClass
<
GUM_SCALAR
>::
attributes
()
const
{
1017
return
_attributes_
;
1018
}
1019
1020
template
<
typename
GUM_SCALAR
>
1021
INLINE
const
Set
<
PRMParameter
<
GUM_SCALAR
>* >&
PRMClass
<
GUM_SCALAR
>::
parameters
()
const
{
1022
return
_parameters_
;
1023
}
1024
1025
// Private struct for retrieving all params in scope
1026
template
<
typename
GUM_SCALAR
>
1027
struct
ParamScopeData
{
1028
std
::
string
prefix
;
1029
const
PRMClass
<
GUM_SCALAR
>*
c
;
1030
Idx
depth
;
1031
1032
ParamScopeData
(
const
std
::
string
&
s
,
const
PRMReferenceSlot
<
GUM_SCALAR
>&
ref
,
Idx
d
) :
1033
prefix
(
s
+
ref
.
name
() +
"."
),
1034
c
(
static_cast
<
const
PRMClass
<
GUM_SCALAR
>* >(&(
ref
.
slotType
()))),
depth
(
d
) {}
1035
};
1036
1037
template
<
typename
GUM_SCALAR >
1038
INLINE HashTable<
std
::
string
,
const
PRMParameter
<
GUM_SCALAR
>* >
1039
PRMClass
<
GUM_SCALAR
>::
scope
()
const
{
1040
HashTable
<
std
::
string
,
const
PRMParameter
<
GUM_SCALAR
>* >
params
;
1041
1042
for
(
const
auto
p
:
parameters
()) {
1043
params
.
insert
(
p
->
name
(),
p
);
1044
}
1045
1046
std
::
queue
<
ParamScopeData
<
GUM_SCALAR
> >
queue
;
1047
1048
for
(
const
auto
ref
:
referenceSlots
()) {
1049
if
(
PRMObject
::
isClass
(
ref
->
slotType
())) {
1050
queue
.
push
(
ParamScopeData
<
GUM_SCALAR
>(
""
, *
ref
, 1));
1051
}
1052
}
1053
1054
while
(!
queue
.
empty
()) {
1055
auto
data
=
queue
.
front
();
1056
queue
.
pop
();
1057
1058
if
(
data
.
depth
< 5) {
1059
for
(
const
auto
p
:
data
.
c
->
parameters
()) {
1060
params
.
insert
(
data
.
prefix
+
p
->
name
(),
p
);
1061
}
1062
1063
for
(
const
auto
ref
:
data
.
c
->
referenceSlots
()) {
1064
if
(
PRMObject
::
isClass
(
ref
->
slotType
())) {
1065
queue
.
push
(
ParamScopeData
<
GUM_SCALAR
>(
data
.
prefix
, *
ref
,
data
.
depth
+ 1));
1066
}
1067
}
1068
}
else
{
1069
// @todo depth>5 is a workaround. Cycle detection is needed here !
1070
GUM_ERROR
(
FatalError
,
"Depth limit reached when looking up parameters"
)
1071
}
1072
}
1073
1074
return
params
;
1075
}
1076
1077
template
<
typename
GUM_SCALAR
>
1078
INLINE
const
Set
<
PRMAggregate
<
GUM_SCALAR
>* >&
PRMClass
<
GUM_SCALAR
>::
aggregates
()
const
{
1079
return
_aggregates_
;
1080
}
1081
1082
template
<
typename
GUM_SCALAR
>
1083
INLINE
const
Set
<
PRMReferenceSlot
<
GUM_SCALAR
>* >&
1084
PRMClass
<
GUM_SCALAR
>::
referenceSlots
()
const
{
1085
return
_referenceSlots_
;
1086
}
1087
1088
template
<
typename
GUM_SCALAR
>
1089
INLINE
const
Set
<
PRMSlotChain
<
GUM_SCALAR
>* >&
PRMClass
<
GUM_SCALAR
>::
slotChains
()
const
{
1090
return
_slotChains_
;
1091
}
1092
1093
template
<
typename
GUM_SCALAR
>
1094
INLINE
const
PRMClass
<
GUM_SCALAR
>&
PRMClass
<
GUM_SCALAR
>::
super
()
const
{
1095
if
(
_superClass_
) {
1096
return
*
_superClass_
;
1097
}
else
{
1098
GUM_ERROR
(
NotFound
,
"this Class is not a subclass"
)
1099
}
1100
}
1101
1102
template
<
typename
GUM_SCALAR
>
1103
INLINE
const
Set
<
PRMInterface
<
GUM_SCALAR
>* >&
PRMClass
<
GUM_SCALAR
>::
implements
()
const
{
1104
if
(
_implements_
) {
1105
return
*
_implements_
;
1106
}
else
{
1107
GUM_ERROR
(
NotFound
,
"this Class does not implement any Interface<GUM_SCALAR>"
)
1108
}
1109
}
1110
1111
template
<
typename
GUM_SCALAR
>
1112
INLINE
PRMClassElement
<
GUM_SCALAR
>&
PRMClass
<
GUM_SCALAR
>::
operator
[](
NodeId
id
) {
1113
return
get
(
id
);
1114
}
1115
1116
template
<
typename
GUM_SCALAR
>
1117
INLINE
const
PRMClassElement
<
GUM_SCALAR
>&
1118
PRMClass
<
GUM_SCALAR
>::
operator
[](
NodeId
id
)
const
{
1119
return
get
(
id
);
1120
}
1121
1122
template
<
typename
GUM_SCALAR
>
1123
INLINE
PRMClassElement
<
GUM_SCALAR
>&
1124
PRMClass
<
GUM_SCALAR
>::
operator
[](
const
std
::
string
&
name
) {
1125
return
get
(
name
);
1126
}
1127
1128
template
<
typename
GUM_SCALAR
>
1129
INLINE
const
PRMClassElement
<
GUM_SCALAR
>&
1130
PRMClass
<
GUM_SCALAR
>::
operator
[](
const
std
::
string
&
name
)
const
{
1131
return
get
(
name
);
1132
}
1133
1134
template
<
typename
GUM_SCALAR
>
1135
INLINE
void
1136
PRMClass
<
GUM_SCALAR
>::
_overloadAggregate_
(
PRMAggregate
<
GUM_SCALAR
>*
overloader
,
1137
PRMClassElement
<
GUM_SCALAR
>*
overloaded
) {
1138
_nameMap_
.
insert
(
overloader
->
safeName
(),
overloader
);
1139
_aggregates_
.
insert
(
overloader
);
1140
}
1141
1142
template
<
typename
GUM_SCALAR
>
1143
INLINE
bool
PRMClass
<
GUM_SCALAR
>::
_checkOverloadLegality_
(
1144
const
PRMClassElement
<
GUM_SCALAR
>*
overloaded
,
1145
const
PRMClassElement
<
GUM_SCALAR
>*
overloader
) {
1146
if
(
overloaded
->
elt_type
() !=
overloader
->
elt_type
()) {
return
false
; }
1147
1148
switch
(
overloaded
->
elt_type
()) {
1149
case
PRMClassElement
<
GUM_SCALAR
>::
prm_attribute
: {
1150
if
(!
overloader
->
type
().
isSubTypeOf
(
overloaded
->
type
())) {
return
false
; }
1151
break
;
1152
}
1153
1154
case
PRMClassElement
<
GUM_SCALAR
>::
prm_refslot
: {
1155
const
auto
&
new_slot_type
1156
=
static_cast
<
const
PRMReferenceSlot
<
GUM_SCALAR
>* >(
overloader
)->
slotType
();
1157
const
auto
&
old_slot_type
1158
=
static_cast
<
const
PRMReferenceSlot
<
GUM_SCALAR
>* >(
overloaded
)->
slotType
();
1159
1160
if
(!
new_slot_type
.
isSubTypeOf
(
old_slot_type
)) {
return
false
; }
1161
1162
break
;
1163
}
1164
1165
case
PRMClassElement
<
GUM_SCALAR
>::
prm_parameter
: {
1166
auto
overloaded_param
=
static_cast
<
const
PRMParameter
<
GUM_SCALAR
>* >(
overloaded
);
1167
auto
overloader_param
=
static_cast
<
const
PRMParameter
<
GUM_SCALAR
>* >(
overloader
);
1168
1169
return
overloaded_param
->
valueType
() ==
overloader_param
->
valueType
();
1170
break
;
1171
}
1172
1173
default
: {
1174
return
false
;
1175
}
1176
}
1177
return
true
;
1178
}
1179
1180
template
<
typename
GUM_SCALAR
>
1181
INLINE
const
Set
<
PRMClass
<
GUM_SCALAR
>* >&
PRMClass
<
GUM_SCALAR
>::
extensions
()
const
{
1182
return
_extensions_
;
1183
}
1184
1185
template
<
typename
GUM_SCALAR
>
1186
INLINE
void
PRMClass
<
GUM_SCALAR
>::
_addExtension_
(
PRMClass
<
GUM_SCALAR
>*
c
) {
1187
_extensions_
.
insert
(
c
);
1188
}
1189
1190
template
<
typename
GUM_SCALAR
>
1191
INLINE
bool
PRMClass
<
GUM_SCALAR
>::
isCastDescendant
(
const
std
::
string
&
safe_name
)
const
{
1192
const
PRMClassElement
<
GUM_SCALAR
>&
elt
=
get
(
safe_name
);
1193
1194
try
{
1195
return
elt
.
type
().
name
() ==
get
(
elt
.
name
()).
type
().
name
();
1196
}
catch
(
OperationNotAllowed
&) {
GUM_ERROR
(
NotFound
,
"no attribute with the given name"
) }
1197
}
1198
1199
template
<
typename
GUM_SCALAR
>
1200
INLINE
bool
1201
PRMClass
<
GUM_SCALAR
>::
isOutputNode
(
const
PRMClassElement
<
GUM_SCALAR
>&
elt
)
const
{
1202
try
{
1203
if
(!
this
->
getIOFlag_
(
elt
).
second
) {
1204
if
(
_implements_
) {
1205
for
(
auto
i
: *
_implements_
) {
1206
if
(
i
->
isOutputNode
(
elt
)) {
return
true
; }
1207
}
1208
}
1209
1210
if
(
_superClass_
&& (
_superClass_
->
isOutputNode
(
elt
))) {
return
true
; }
1211
1212
}
else
{
1213
return
true
;
1214
}
1215
}
catch
(
NotFound
&) {}
1216
return
false
;
1217
}
1218
1219
1220
}
/* namespace prm */
1221
}
/* namespace gum */
gum::Set::emplace
INLINE void emplace(Args &&... args)
Definition:
set_tpl.h:643
gum::prm::ParamScopeData::ParamScopeData
ParamScopeData(const std::string &s, const PRMReferenceSlot< GUM_SCALAR > &ref, Idx d)
Definition:
PRMClass_tpl.h:1032