aGrUM
0.20.3
a C++ library for (probabilistic) graphical models
bijection_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 Class providing generic double hash tables
25
*
26
* @author Jean-Philippe DUBUS, Christophe GONZALES(@AMU) and Pierre-Henri
27
* WUILLEMIN(@LIP6)
28
*/
29
30
// To simply IDE parsing
31
#
include
<
agrum
/
tools
/
core
/
bijection
.
h
>
32
33
namespace
gum
{
34
35
// ===========================================================================
36
// === NON SCALAR BIJECTION IMPLEMENTATION ===
37
// ===========================================================================
38
39
// returns the end iterator for other classes' statics
40
template
<
typename
T1,
typename
T2,
typename
Alloc,
bool
Gen >
41
const
BijectionIteratorSafe< T1, T2 >&
42
BijectionImplementation<
T1
,
T2
,
Alloc
,
Gen
>::
endSafe4Statics
() {
43
return
*(
reinterpret_cast
<
const
BijectionIteratorSafe
<
T1
,
T2
>* >(
44
BijectionIteratorStaticEnd
::
endSafe4Statics
()));
45
}
46
47
// returns the end iterator for other classes' statics
48
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
49
const
BijectionIterator
<
T1
,
T2
>&
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
end4Statics
() {
50
return
*(
reinterpret_cast
<
const
BijectionIterator
<
T1
,
T2
>* >(
51
BijectionIteratorStaticEnd
::
end4Statics
()));
52
}
53
54
// a function that performs a complete copy of another bijection
55
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
56
template
<
typename
OtherAlloc
>
57
INLINE
void
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
_copy_
(
58
const
HashTable
<
T1
,
T2
*,
OtherAlloc
>&
f2s
) {
59
// parse f2s and perform copies
60
for
(
auto
iter
=
f2s
.
cbegin
();
iter
!=
f2s
.
cend
(); ++
iter
) {
61
typename
HashTable12
::
value_type
*
val1
= &(
_firstToSecond_
.
insert
(
iter
.
key
(),
nullptr
));
62
typename
HashTable21
::
value_type
*
val2
;
63
64
try
{
65
val2
= &(
_secondToFirst_
.
insert
(*(
iter
.
val
()),
nullptr
));
66
}
catch
(...) {
67
_firstToSecond_
.
erase
(
iter
.
key
());
68
throw
;
69
}
70
71
val1
->
second
= &(
const_cast
<
T2
& >(
val2
->
first
));
72
val2
->
second
= &(
const_cast
<
T1
& >(
val1
->
first
));
73
}
74
75
// note that _iter_end_ is actually a constant, whatever we add/remove
76
// to/from _firstToSecond_. As a consequence, it need not be updated
77
// after _copy_
78
}
79
80
// Default constructor: creates a bijection without association
81
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
82
INLINE
83
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
BijectionImplementation
(
Size
size
,
84
bool
resize_policy
) :
85
// warning: below, we create the internal hashTables with a key
86
// uniqueness
87
// policy set to false because we will do the uniqueness tests ourselves
88
// (this
89
// will speed-up the process)
90
_firstToSecond_
(
size
,
resize_policy
,
false
),
91
_secondToFirst_
(
size
,
resize_policy
,
false
) {
92
GUM_CONSTRUCTOR
(
BijectionImplementation
);
93
94
// make sure the end() iterator is constructed properly
95
end4Statics
();
96
endSafe4Statics
();
97
}
98
99
// initializer list constructor
100
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
101
INLINE
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
BijectionImplementation
(
102
std
::
initializer_list
<
std
::
pair
<
T1
,
T2
> >
list
) :
103
_firstToSecond_
(
Size
(
list
.
size
()) / 2,
true
,
false
),
104
_secondToFirst_
(
Size
(
list
.
size
()) / 2,
true
,
false
) {
105
GUM_CONSTRUCTOR
(
BijectionImplementation
);
106
107
for
(
const
auto
&
elt
:
list
) {
108
insert
(
elt
.
first
,
elt
.
second
);
109
}
110
111
// make sure the end() iterator is constructed properly
112
end4Statics
();
113
endSafe4Statics
();
114
}
115
116
// Copy constructor
117
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
118
INLINE
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
BijectionImplementation
(
119
const
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>&
toCopy
) :
120
_firstToSecond_
(
toCopy
.
_firstToSecond_
.
capacity
(),
true
,
false
),
121
_secondToFirst_
(
toCopy
.
_secondToFirst_
.
capacity
(),
true
,
false
) {
122
GUM_CONS_CPY
(
BijectionImplementation
);
123
_copy_
(
toCopy
.
_firstToSecond_
);
124
}
125
126
// Generalized copy constructor
127
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
128
template
<
typename
OtherAlloc
>
129
INLINE
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
BijectionImplementation
(
130
const
BijectionImplementation
<
T1
,
T2
,
OtherAlloc
,
Gen
>&
toCopy
) :
131
_firstToSecond_
(
toCopy
.
_firstToSecond_
.
capacity
(),
true
,
false
),
132
_secondToFirst_
(
toCopy
.
_secondToFirst_
.
capacity
(),
true
,
false
) {
133
GUM_CONS_CPY
(
BijectionImplementation
);
134
_copy_
(
toCopy
.
_firstToSecond_
);
135
}
136
137
// move constructor
138
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
139
INLINE
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
BijectionImplementation
(
140
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>&&
from
)
noexcept
:
141
_firstToSecond_
(
std
::
move
(
from
.
_firstToSecond_
)),
142
_secondToFirst_
(
std
::
move
(
from
.
_secondToFirst_
)) {
143
GUM_CONS_MOV
(
BijectionImplementation
);
144
}
145
146
// destructor
147
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
148
INLINE
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::~
BijectionImplementation
() {
149
GUM_DESTRUCTOR
(
BijectionImplementation
);
150
}
151
152
// removes all the associations from the bijection
153
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
154
INLINE
void
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
clear
() {
155
_firstToSecond_
.
clear
();
156
_secondToFirst_
.
clear
();
157
// note that _iter_end_ is actually a constant, whatever we add/remove
158
// to/from _firstToSecond_. As a consequence, it need not be updated
159
// after the clear's
160
}
161
162
// Copy operator
163
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
164
INLINE
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>&
165
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
operator
=(
166
const
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>&
toCopy
) {
167
// avoid self assignment
168
if
(
this
!= &
toCopy
) {
169
clear
();
170
_copy_
(
toCopy
.
_firstToSecond_
);
171
}
172
173
// note that _iter_end_ is actually a constant, whatever we add/remove
174
// to/from _firstToSecond_. As a consequence, it need not be updated
175
// after _copy_
176
return
*
this
;
177
}
178
179
// Generalized copy operator
180
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
181
template
<
typename
OtherAlloc
>
182
INLINE
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>&
183
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
operator
=(
184
const
BijectionImplementation
<
T1
,
T2
,
OtherAlloc
,
Gen
>&
toCopy
) {
185
clear
();
186
_copy_
(
toCopy
.
_firstToSecond_
);
187
188
// note that _iter_end_ is actually a constant, whatever we add/remove
189
// to/from _firstToSecond_. As a consequence, it need not be updated
190
// after _copy_
191
return
*
this
;
192
}
193
194
// move operator
195
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
196
INLINE
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>&
197
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
operator
=(
198
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>&&
from
) {
199
// avoid self assignment
200
if
(
this
!= &
from
) {
201
clear
();
202
_firstToSecond_
=
std
::
move
(
from
.
_firstToSecond_
);
203
_secondToFirst_
=
std
::
move
(
from
.
_secondToFirst_
);
204
}
205
206
// note that _iter_end_ is actually a constant, whatever we add/remove
207
// to/from _firstToSecond_. As a consequence, it need not be updated
208
// after _copy_
209
return
*
this
;
210
}
211
212
// returns the iterator at the beginning of the bijection
213
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
214
INLINE
typename
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
iterator
215
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
begin
()
const
{
216
return
BijectionIterator
<
T1
,
T2
>{*
this
};
217
}
218
219
// returns the iterator at the beginning of the bijection
220
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
221
INLINE
typename
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
const_iterator
222
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
cbegin
()
const
{
223
return
BijectionIterator
<
T1
,
T2
>{*
this
};
224
}
225
226
// returns the iterator to the end of the bijection
227
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
228
INLINE
const
typename
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
iterator
&
229
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
end
()
const
noexcept
{
230
return
*(
reinterpret_cast
<
const
BijectionIterator
<
T1
,
T2
>* >(
231
BijectionIteratorStaticEnd
::
_BijectionIterEnd_
));
232
}
233
234
// returns the iterator to the end of the bijection
235
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
236
INLINE
const
typename
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
const_iterator
&
237
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
cend
()
const
noexcept
{
238
return
*(
reinterpret_cast
<
const
BijectionIterator
<
T1
,
T2
>* >(
239
BijectionIteratorStaticEnd
::
_BijectionIterEnd_
));
240
}
241
242
// returns the iterator at the beginning of the bijection
243
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
244
INLINE
typename
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
iterator_safe
245
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
beginSafe
()
const
{
246
return
BijectionIteratorSafe
<
T1
,
T2
>{*
this
};
247
}
248
249
// returns the iterator at the beginning of the bijection
250
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
251
INLINE
typename
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
const_iterator_safe
252
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
cbeginSafe
()
const
{
253
return
BijectionIteratorSafe
<
T1
,
T2
>{*
this
};
254
}
255
256
// returns the iterator to the end of the bijection
257
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
258
INLINE
const
typename
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
iterator_safe
&
259
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
endSafe
()
const
noexcept
{
260
return
*(
reinterpret_cast
<
const
BijectionIteratorSafe
<
T1
,
T2
>* >(
261
BijectionIteratorStaticEnd
::
_BijectionIterEndSafe_
));
262
}
263
264
// returns the iterator to the end of the bijection
265
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
266
INLINE
const
typename
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
const_iterator_safe
&
267
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
cendSafe
()
const
noexcept
{
268
return
*(
reinterpret_cast
<
const
BijectionIteratorSafe
<
T1
,
T2
>* >(
269
BijectionIteratorStaticEnd
::
_BijectionIterEndSafe_
));
270
}
271
272
// returns the value associated to the element passed in argument
273
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
274
INLINE
const
T1
&
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
first
(
const
T2
&
second
)
const
{
275
return
*(
_secondToFirst_
[
second
]);
276
}
277
278
// returns the value associated to the element passed in argument
279
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
280
INLINE
const
T2
&
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
second
(
const
T1
&
first
)
const
{
281
return
*(
_firstToSecond_
[
first
]);
282
}
283
284
// Test whether the bijection contains the "first" value
285
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
286
INLINE
bool
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
existsFirst
(
const
T1
&
first
)
const
{
287
return
_firstToSecond_
.
exists
(
first
);
288
}
289
290
// Test whether the bijection contains the "second" value
291
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
292
INLINE
bool
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
existsSecond
(
const
T2
&
second
)
const
{
293
return
_secondToFirst_
.
exists
(
second
);
294
}
295
296
// inserts a new association in the bijection
297
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
298
INLINE
typename
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
HashTable12
::
value_type
*
299
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
_insert_
(
const
T1
&
first
,
const
T2
&
second
) {
300
// check the uniqueness property
301
if
(
existsFirst
(
first
) ||
existsSecond
(
second
)) {
302
GUM_ERROR
(
DuplicateElement
,
303
"the bijection contains an element with the same couple ("
<<
first
<<
","
<<
second
304
<<
")"
);
305
}
306
307
// insert copies of first and second
308
typename
HashTable12
::
value_type
*
val1
= &(
_firstToSecond_
.
insert
(
first
,
nullptr
));
309
typename
HashTable21
::
value_type
*
val2
;
310
311
try
{
312
val2
= &(
_secondToFirst_
.
insert
(
second
,
nullptr
));
313
}
catch
(...) {
314
_firstToSecond_
.
erase
(
first
);
315
throw
;
316
}
317
318
val1
->
second
= &(
const_cast
<
T2
& >(
val2
->
first
));
319
val2
->
second
= &(
const_cast
<
T1
& >(
val1
->
first
));
320
321
return
val1
;
322
}
323
324
// inserts a new association in the bijection
325
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
326
INLINE
typename
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
HashTable12
::
value_type
*
327
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
_insert_
(
T1
&&
first
,
T2
&&
second
) {
328
// check the uniqueness property
329
if
(
existsFirst
(
first
) ||
existsSecond
(
second
)) {
330
GUM_ERROR
(
DuplicateElement
,
331
"the bijection contains an element with the same couple ("
<<
first
<<
","
<<
second
332
<<
")"
);
333
}
334
335
// insert copies of first and second
336
typename
HashTable12
::
value_type
*
val1
= &(
_firstToSecond_
.
insert
(
std
::
move
(
first
),
nullptr
));
337
typename
HashTable21
::
value_type
*
val2
;
338
339
try
{
340
val2
= &(
_secondToFirst_
.
insert
(
std
::
move
(
second
),
nullptr
));
341
}
catch
(...) {
342
_firstToSecond_
.
erase
(
val1
->
first
);
343
throw
;
344
}
345
346
val1
->
second
= &(
const_cast
<
T2
& >(
val2
->
first
));
347
val2
->
second
= &(
const_cast
<
T1
& >(
val1
->
first
));
348
349
return
val1
;
350
}
351
352
/* @brief Same method as first, but if the value is not found, a default
353
* value is inserted into the bijection */
354
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
355
INLINE
const
T1
&
356
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
firstWithDefault
(
const
T2
&
second
,
357
const
T1
&
val
)
const
{
358
try
{
359
return
first
(
second
);
360
}
catch
(
NotFound
&) {
return
_insert_
(
val
,
second
)->
first
; }
361
}
362
363
/* @brief Same method as second, but if the value is not found, a default
364
* value is inserted into the bijection */
365
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
366
INLINE
const
T2
&
367
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
secondWithDefault
(
const
T1
&
first
,
368
const
T2
&
val
)
const
{
369
try
{
370
return
second
(
first
);
371
}
catch
(
NotFound
&) {
return
*(
_insert_
(
first
,
val
)->
second
); }
372
}
373
374
// inserts a new association in the bijection
375
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
376
INLINE
void
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
insert
(
const
T1
&
first
,
377
const
T2
&
second
) {
378
_insert_
(
first
,
second
);
379
}
380
381
// inserts a new association in the bijection
382
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
383
INLINE
void
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
insert
(
T1
&&
first
,
T2
&&
second
) {
384
_insert_
(
std
::
move
(
first
),
std
::
move
(
second
));
385
}
386
387
// emplace a new element in the bijection
388
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
389
template
<
typename
...
Args
>
390
INLINE
void
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
emplace
(
Args
&&...
args
) {
391
std
::
pair
<
T1
,
T2
>
new_elt
(
std
::
forward
<
Args
>(
args
)...);
392
_insert_
(
std
::
move
(
new_elt
.
first
),
std
::
move
(
new_elt
.
second
));
393
}
394
395
// returns true if the bijection doesn't contain any relation
396
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
397
INLINE
bool
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
empty
()
const
noexcept
{
398
GUM_ASSERT
(
_firstToSecond_
.
empty
() ==
_secondToFirst_
.
empty
());
399
return
_firstToSecond_
.
empty
();
400
}
401
402
// returns the number of associations stored within the bijection
403
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
404
INLINE
Size
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
size
()
const
noexcept
{
405
GUM_ASSERT
(
_firstToSecond_
.
size
() ==
_secondToFirst_
.
size
());
406
return
_firstToSecond_
.
size
();
407
}
408
409
// erases an association containing the given first element
410
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
411
INLINE
void
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
eraseFirst
(
const
T1
&
first
) {
412
try
{
413
_secondToFirst_
.
erase
(*
_firstToSecond_
[
first
]);
414
_firstToSecond_
.
erase
(
first
);
415
}
catch
(
NotFound
&) {}
416
}
417
418
// erase an association containing the given second element
419
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
420
INLINE
void
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
eraseSecond
(
const
T2
&
second
) {
421
try
{
422
_firstToSecond_
.
erase
(*
_secondToFirst_
[
second
]);
423
_secondToFirst_
.
erase
(
second
);
424
}
catch
(
NotFound
&) {}
425
}
426
427
// returns the number of hashtables' slots used (@sa hashTable's capacity)
428
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
429
INLINE
Size
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
capacity
()
const
noexcept
{
430
return
_firstToSecond_
.
capacity
();
431
}
432
433
// similar to the hashtable's resize
434
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
435
INLINE
void
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
resize
(
Size
new_size
) {
436
_firstToSecond_
.
resize
(
new_size
);
437
_secondToFirst_
.
resize
(
new_size
);
438
}
439
440
// enables the user to change dynamically the resizing policy
441
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
442
INLINE
void
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
setResizePolicy
(
443
const
bool
new_policy
)
noexcept
{
444
_firstToSecond_
.
setResizePolicy
(
new_policy
);
445
_secondToFirst_
.
setResizePolicy
(
new_policy
);
446
}
447
448
// returns the current resizing policy
449
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
450
INLINE
bool
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
resizePolicy
()
const
noexcept
{
451
return
_firstToSecond_
.
resizePolicy
();
452
}
453
454
// friendly displays the content of the CliqueGraph
455
template
<
typename
T1
,
typename
T2
,
typename
Alloc
,
bool
Gen
>
456
std
::
string
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>::
toString
()
const
{
457
std
::
stringstream
stream
;
458
stream
<<
"{ "
;
459
bool
first
=
true
;
460
461
for
(
iterator
iter
=
begin
();
iter
!=
end
(); ++
iter
) {
462
if
(!
first
)
463
stream
<<
", "
;
464
else
465
first
=
false
;
466
467
stream
<<
'('
<<
iter
.
first
() <<
" <-> "
<<
iter
.
second
() <<
')'
;
468
}
469
470
stream
<<
" }"
;
471
return
stream
.
str
();
472
}
473
474
// ===========================================================================
475
// === SCALAR BIJECTION IMPLEMENTATION ===
476
// ===========================================================================
477
478
// returns the end iterator for other classes' statics
479
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
480
const
BijectionIteratorSafe
<
T1
,
T2
>&
481
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
endSafe4Statics
() {
482
return
*(
reinterpret_cast
<
const
BijectionIteratorSafe
<
T1
,
T2
>* >(
483
BijectionIteratorStaticEnd
::
endSafe4Statics
()));
484
}
485
486
// returns the end iterator for other classes' statics
487
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
488
const
BijectionIterator
<
T1
,
T2
>&
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
end4Statics
() {
489
return
*(
reinterpret_cast
<
const
BijectionIterator
<
T1
,
T2
>* >(
490
BijectionIteratorStaticEnd
::
end4Statics
()));
491
}
492
493
// Default constructor: creates a bijection without association
494
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
495
INLINE
496
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
BijectionImplementation
(
Size
size
,
497
bool
resize_policy
) :
498
// warning: below, we create the internal hashTables with a key
499
// uniqueness
500
// policy set to false because we will do the uniqueness tests ourselves
501
// (this
502
// will speed-up the process)
503
_firstToSecond_
(
size
,
resize_policy
,
false
),
504
_secondToFirst_
(
size
,
resize_policy
,
false
) {
505
GUM_CONSTRUCTOR
(
BijectionImplementation
);
506
507
// make sure the end() iterator is constructed properly
508
end4Statics
();
509
endSafe4Statics
();
510
}
511
512
// initializer list constructor
513
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
514
INLINE
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
BijectionImplementation
(
515
std
::
initializer_list
<
std
::
pair
<
T1
,
T2
> >
list
) :
516
_firstToSecond_
(
Size
(
list
.
size
()) / 2,
true
,
false
),
517
_secondToFirst_
(
Size
(
list
.
size
()) / 2,
true
,
false
) {
518
GUM_CONSTRUCTOR
(
BijectionImplementation
);
519
520
for
(
const
auto
&
elt
:
list
) {
521
insert
(
elt
.
first
,
elt
.
second
);
522
}
523
524
// make sure the end() iterator is constructed properly
525
end4Statics
();
526
endSafe4Statics
();
527
}
528
529
// a function that performs a complete copy of another bijection
530
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
531
template
<
typename
OtherAlloc
>
532
INLINE
void
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
_copy_
(
533
const
HashTable
<
T1
,
T2
,
OtherAlloc
>&
f2s
) {
534
// parse f2s and perform copies
535
for
(
auto
iter
=
f2s
.
cbegin
();
iter
!=
f2s
.
cend
(); ++
iter
) {
536
_firstToSecond_
.
insert
(
iter
.
key
(),
iter
.
val
());
537
538
try
{
539
_secondToFirst_
.
insert
(
iter
.
val
(),
iter
.
key
());
540
}
catch
(...) {
541
_firstToSecond_
.
erase
(
iter
.
key
());
542
throw
;
543
}
544
}
545
546
// note that _iter_end_ is actually a constant, whatever we add/remove
547
// to/from _firstToSecond_. As a consequence, it need not be updated
548
// after _copy_
549
}
550
551
// Copy constructor
552
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
553
INLINE
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
BijectionImplementation
(
554
const
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>&
toCopy
) :
555
_firstToSecond_
(
toCopy
.
_firstToSecond_
.
capacity
(),
true
,
false
),
556
_secondToFirst_
(
toCopy
.
_secondToFirst_
.
capacity
(),
true
,
false
) {
557
GUM_CONS_CPY
(
BijectionImplementation
);
558
_copy_
(
toCopy
.
_firstToSecond_
);
559
}
560
561
// Generalized copy constructor
562
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
563
template
<
typename
OtherAlloc
>
564
INLINE
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
BijectionImplementation
(
565
const
BijectionImplementation
<
T1
,
T2
,
OtherAlloc
,
true
>&
toCopy
) :
566
_firstToSecond_
(
toCopy
.
_firstToSecond_
.
capacity
(),
true
,
false
),
567
_secondToFirst_
(
toCopy
.
_secondToFirst_
.
capacity
(),
true
,
false
) {
568
GUM_CONS_CPY
(
BijectionImplementation
);
569
_copy_
(
toCopy
.
_firstToSecond_
);
570
}
571
572
// move constructor
573
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
574
INLINE
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
BijectionImplementation
(
575
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>&&
toCopy
)
noexcept
:
576
_firstToSecond_
(
std
::
move
(
toCopy
.
_firstToSecond_
)),
577
_secondToFirst_
(
std
::
move
(
toCopy
.
_secondToFirst_
)) {
578
GUM_CONS_MOV
(
BijectionImplementation
);
579
}
580
581
// destructor
582
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
583
INLINE
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::~
BijectionImplementation
() {
584
GUM_DESTRUCTOR
(
BijectionImplementation
);
585
}
586
587
// returns the iterator at the beginning of the bijection
588
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
589
INLINE
typename
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
iterator
590
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
begin
()
const
{
591
return
BijectionIterator
<
T1
,
T2
>{*
this
};
592
}
593
594
// returns the iterator at the beginning of the bijection
595
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
596
INLINE
typename
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
const_iterator
597
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
cbegin
()
const
{
598
return
BijectionIterator
<
T1
,
T2
>{*
this
};
599
}
600
601
// returns the iterator to the end of the bijection
602
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
603
INLINE
const
typename
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
iterator
&
604
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
end
()
const
noexcept
{
605
return
*(
reinterpret_cast
<
const
BijectionIterator
<
T1
,
T2
>* >(
606
BijectionIteratorStaticEnd
::
_BijectionIterEnd_
));
607
}
608
609
// returns the iterator to the end of the bijection
610
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
611
INLINE
const
typename
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
const_iterator
&
612
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
cend
()
const
noexcept
{
613
return
*(
reinterpret_cast
<
const
BijectionIterator
<
T1
,
T2
>* >(
614
BijectionIteratorStaticEnd
::
_BijectionIterEnd_
));
615
}
616
617
// returns the iterator at the beginning of the bijection
618
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
619
INLINE
typename
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
iterator_safe
620
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
beginSafe
()
const
{
621
return
BijectionIteratorSafe
<
T1
,
T2
>{*
this
};
622
}
623
624
// returns the iterator at the beginning of the bijection
625
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
626
INLINE
typename
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
const_iterator_safe
627
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
cbeginSafe
()
const
{
628
return
BijectionIteratorSafe
<
T1
,
T2
>{*
this
};
629
}
630
631
// returns the iterator to the end of the bijection
632
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
633
INLINE
const
typename
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
iterator_safe
&
634
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
endSafe
()
const
noexcept
{
635
return
*(
reinterpret_cast
<
const
BijectionIteratorSafe
<
T1
,
T2
>* >(
636
BijectionIteratorStaticEnd
::
_BijectionIterEndSafe_
));
637
}
638
639
// returns the iterator to the end of the bijection
640
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
641
INLINE
const
typename
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
const_iterator_safe
&
642
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
cendSafe
()
const
noexcept
{
643
return
*(
reinterpret_cast
<
const
BijectionIteratorSafe
<
T1
,
T2
>* >(
644
BijectionIteratorStaticEnd
::
_BijectionIterEndSafe_
));
645
}
646
647
// removes all the associations from the bijection
648
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
649
INLINE
void
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
clear
() {
650
_firstToSecond_
.
clear
();
651
_secondToFirst_
.
clear
();
652
// note that _iter_end_ is actually a constant, whatever we add/remove
653
// to/from _firstToSecond_. As a consequence, it need not be updated
654
// after the clear's
655
}
656
657
// Copy operator
658
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
659
INLINE
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>&
660
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
operator
=(
661
const
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>&
toCopy
) {
662
// avoid self assignment
663
if
(
this
!= &
toCopy
) {
664
clear
();
665
_copy_
(
toCopy
.
_firstToSecond_
);
666
}
667
668
// note that _iter_end_ is actually a constant, whatever we add/remove
669
// to/from _firstToSecond_. As a consequence, it need not be updated
670
// after _copy_
671
return
*
this
;
672
}
673
674
// Generalized copy operator
675
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
676
template
<
typename
OtherAlloc
>
677
INLINE
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>&
678
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
operator
=(
679
const
BijectionImplementation
<
T1
,
T2
,
OtherAlloc
,
true
>&
toCopy
) {
680
clear
();
681
_copy_
(
toCopy
.
_firstToSecond_
);
682
683
// note that _iter_end_ is actually a constant, whatever we add/remove
684
// to/from _firstToSecond_. As a consequence, it need not be updated
685
// after _copy_
686
return
*
this
;
687
}
688
689
// move operator
690
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
691
INLINE
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>&
692
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
operator
=(
693
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>&&
toCopy
) {
694
// avoid self assignment
695
if
(
this
!= &
toCopy
) {
696
clear
();
697
_firstToSecond_
=
std
::
move
(
toCopy
.
_firstToSecond_
);
698
_secondToFirst_
=
std
::
move
(
toCopy
.
_secondToFirst_
);
699
}
700
701
// note that _iter_end_ is actually a constant, whatever we add/remove
702
// to/from _firstToSecond_. As a consequence, it need not be updated
703
// after _copy_
704
return
*
this
;
705
}
706
707
// returns the value associated to the element passed in argument
708
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
709
INLINE
const
T1
&
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
first
(
T2
second
)
const
{
710
return
_secondToFirst_
[
second
];
711
}
712
713
// returns the value associated to the element passed in argument
714
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
715
INLINE
const
T2
&
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
second
(
T1
first
)
const
{
716
return
_firstToSecond_
[
first
];
717
}
718
719
// Test whether the bijection contains the "first" value
720
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
721
INLINE
bool
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
existsFirst
(
T1
first
)
const
{
722
return
_firstToSecond_
.
exists
(
first
);
723
}
724
725
// Test whether the bijection contains the "second" value
726
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
727
INLINE
bool
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
existsSecond
(
T2
second
)
const
{
728
return
_secondToFirst_
.
exists
(
second
);
729
}
730
731
// inserts a new association in the bijection
732
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
733
INLINE
void
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
_insert_
(
T1
first
,
T2
second
) {
734
// check the uniqueness property
735
if
(
existsFirst
(
first
) ||
existsSecond
(
second
)) {
736
GUM_ERROR
(
DuplicateElement
,
737
"the bijection contains an element with the same couple ("
<<
first
<<
","
<<
second
738
<<
")"
);
739
}
740
741
// insert copies of first and second
742
_firstToSecond_
.
insert
(
first
,
second
);
743
744
try
{
745
_secondToFirst_
.
insert
(
second
,
first
);
746
}
catch
(...) {
747
_firstToSecond_
.
erase
(
first
);
748
throw
;
749
}
750
}
751
752
// inserts a new association in the bijection
753
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
754
INLINE
void
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
insert
(
T1
first
,
T2
second
) {
755
_insert_
(
first
,
second
);
756
}
757
758
// emplace a new element in the bijection
759
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
760
template
<
typename
...
Args
>
761
INLINE
void
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
emplace
(
Args
&&...
args
) {
762
std
::
pair
<
T1
,
T2
>
new_elt
(
std
::
forward
<
Args
>(
args
)...);
763
_insert_
(
new_elt
.
first
,
new_elt
.
second
);
764
}
765
766
/* @brief Same method as first, but if the value is not found, a default
767
* value is inserted into the bijection */
768
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
769
INLINE
const
T1
&
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
firstWithDefault
(
T2
second
,
770
T1
val
)
const
{
771
try
{
772
return
first
(
second
);
773
}
catch
(
NotFound
&) {
774
_insert_
(
val
,
second
);
775
return
val
;
776
}
777
}
778
779
/* @brief Same method as second, but if the value is not found, a default
780
* value is inserted into the bijection */
781
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
782
INLINE
const
T2
&
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
secondWithDefault
(
T1
first
,
783
T2
val
)
const
{
784
try
{
785
return
second
(
first
);
786
}
catch
(
NotFound
&) {
787
_insert_
(
first
,
val
);
788
return
val
;
789
}
790
}
791
792
// returns true if the bijection doesn't contain any relation
793
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
794
INLINE
bool
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
empty
()
const
noexcept
{
795
GUM_ASSERT
(
_firstToSecond_
.
empty
() ==
_secondToFirst_
.
empty
());
796
return
_firstToSecond_
.
empty
();
797
}
798
799
// returns the number of associations stored within the bijection
800
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
801
INLINE
Size
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
size
()
const
noexcept
{
802
GUM_ASSERT
(
_firstToSecond_
.
size
() ==
_secondToFirst_
.
size
());
803
return
_firstToSecond_
.
size
();
804
}
805
806
// erases an association containing the given first element
807
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
808
INLINE
void
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
eraseFirst
(
T1
first
) {
809
try
{
810
_secondToFirst_
.
erase
(
_firstToSecond_
[
first
]);
811
_firstToSecond_
.
erase
(
first
);
812
}
catch
(
NotFound
&) {}
813
}
814
815
// erase an association containing the given second element
816
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
817
INLINE
void
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
eraseSecond
(
T2
second
) {
818
try
{
819
_firstToSecond_
.
erase
(
_secondToFirst_
[
second
]);
820
_secondToFirst_
.
erase
(
second
);
821
}
catch
(
NotFound
&) {}
822
}
823
824
// returns the number of hashtables' slots used (@sa hashTable's capacity)
825
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
826
INLINE
Size
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
capacity
()
const
noexcept
{
827
return
_firstToSecond_
.
capacity
();
828
}
829
830
// similar to the hashtable's resize
831
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
832
INLINE
void
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
resize
(
Size
new_size
) {
833
_firstToSecond_
.
resize
(
new_size
);
834
_secondToFirst_
.
resize
(
new_size
);
835
}
836
837
// enables the user to change dynamically the resizing policy
838
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
839
INLINE
void
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
setResizePolicy
(
840
const
bool
new_policy
)
noexcept
{
841
_firstToSecond_
.
setResizePolicy
(
new_policy
);
842
_secondToFirst_
.
setResizePolicy
(
new_policy
);
843
}
844
845
// returns the current resizing policy
846
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
847
INLINE
bool
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
resizePolicy
()
const
noexcept
{
848
return
_firstToSecond_
.
resizePolicy
();
849
}
850
851
// friendly displays the content of the CliqueGraph
852
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
853
std
::
string
BijectionImplementation
<
T1
,
T2
,
Alloc
,
true
>::
toString
()
const
{
854
std
::
stringstream
stream
;
855
stream
<<
"{ "
;
856
bool
first
=
true
;
857
858
for
(
iterator
iter
=
begin
();
iter
!=
end
(); ++
iter
) {
859
if
(!
first
)
860
stream
<<
", "
;
861
else
862
first
=
false
;
863
864
stream
<<
'('
<<
iter
.
first
() <<
" <-> "
<<
iter
.
second
() <<
')'
;
865
}
866
867
stream
<<
" }"
;
868
return
stream
.
str
();
869
}
870
871
// ===========================================================================
872
// === BIJECTION SAFE ITERATORS ===
873
// ===========================================================================
874
875
/// Default constructor
876
template
<
typename
T1
,
typename
T2
>
877
INLINE
BijectionIteratorSafe
<
T1
,
T2
>::
BijectionIteratorSafe
()
noexcept
{
878
GUM_CONSTRUCTOR
(
BijectionIteratorSafe
);
879
}
880
881
/// Constructor
882
template
<
typename
T1
,
typename
T2
>
883
template
<
typename
Alloc
,
bool
Gen
>
884
INLINE
BijectionIteratorSafe
<
T1
,
T2
>::
BijectionIteratorSafe
(
885
const
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>&
bijection
) :
886
_iter_
{
bijection
.
_firstToSecond_
.
cbeginSafe
()} {
887
GUM_CONSTRUCTOR
(
BijectionIteratorSafe
);
888
}
889
890
/// Constructor
891
template
<
typename
T1
,
typename
T2
>
892
template
<
typename
Alloc
>
893
INLINE
BijectionIteratorSafe
<
T1
,
T2
>::
BijectionIteratorSafe
(
894
const
Bijection
<
T1
,
T2
,
Alloc
>&
bijection
) :
895
_iter_
{
bijection
.
_firstToSecond_
.
cbeginSafe
()} {
896
GUM_CONSTRUCTOR
(
BijectionIteratorSafe
);
897
}
898
899
/// Copy constructor
900
template
<
typename
T1
,
typename
T2
>
901
INLINE
BijectionIteratorSafe
<
T1
,
T2
>::
BijectionIteratorSafe
(
902
const
BijectionIteratorSafe
<
T1
,
T2
>&
toCopy
) :
903
_iter_
{
toCopy
.
_iter_
} {
904
GUM_CONS_CPY
(
BijectionIteratorSafe
);
905
}
906
907
/// move constructor
908
template
<
typename
T1
,
typename
T2
>
909
INLINE
BijectionIteratorSafe
<
T1
,
T2
>::
BijectionIteratorSafe
(
910
BijectionIteratorSafe
<
T1
,
T2
>&&
from
)
noexcept
:
911
_iter_
{
std
::
move
(
from
.
_iter_
)} {
912
GUM_CONS_MOV
(
BijectionIteratorSafe
);
913
}
914
915
/// Destructor
916
template
<
typename
T1
,
typename
T2
>
917
INLINE
BijectionIteratorSafe
<
T1
,
T2
>::~
BijectionIteratorSafe
()
noexcept
{
918
GUM_DESTRUCTOR
(
BijectionIteratorSafe
);
919
}
920
921
/// Copy operator
922
template
<
typename
T1
,
typename
T2
>
923
INLINE
BijectionIteratorSafe
<
T1
,
T2
>&
924
BijectionIteratorSafe
<
T1
,
T2
>::
operator
=(
const
BijectionIteratorSafe
<
T1
,
T2
>&
toCopy
) {
925
_iter_
=
toCopy
.
_iter_
;
926
return
*
this
;
927
}
928
929
/// move operator
930
template
<
typename
T1
,
typename
T2
>
931
INLINE
BijectionIteratorSafe
<
T1
,
T2
>&
932
BijectionIteratorSafe
<
T1
,
T2
>::
operator
=(
BijectionIteratorSafe
<
T1
,
T2
>&&
toCopy
)
noexcept
{
933
_iter_
=
std
::
move
(
toCopy
.
_iter_
);
934
return
*
this
;
935
}
936
937
/// Go to the next association (if exists)
938
template
<
typename
T1
,
typename
T2
>
939
INLINE
BijectionIteratorSafe
<
T1
,
T2
>&
BijectionIteratorSafe
<
T1
,
T2
>::
operator
++()
noexcept
{
940
++
_iter_
;
941
return
*
this
;
942
}
943
944
/// moves the iterator by nb elements
945
template
<
typename
T1
,
typename
T2
>
946
INLINE
BijectionIteratorSafe
<
T1
,
T2
>&
947
BijectionIteratorSafe
<
T1
,
T2
>::
operator
+=(
Size
nb
)
noexcept
{
948
_iter_
+=
nb
;
949
return
*
this
;
950
}
951
952
/// returns a new iterator
953
template
<
typename
T1
,
typename
T2
>
954
INLINE
BijectionIteratorSafe
<
T1
,
T2
>
955
BijectionIteratorSafe
<
T1
,
T2
>::
operator
+(
Size
nb
)
noexcept
{
956
return
BijectionIteratorSafe
<
T1
,
T2
>{*
this
} +=
nb
;
957
}
958
959
/// Comparison of iterators
960
template
<
typename
T1
,
typename
T2
>
961
INLINE
bool
BijectionIteratorSafe
<
T1
,
T2
>::
operator
!=(
962
const
BijectionIteratorSafe
<
T1
,
T2
>&
toCompare
)
const
noexcept
{
963
return
_iter_
!=
toCompare
.
_iter_
;
964
}
965
966
/// Comparison of iterators
967
template
<
typename
T1
,
typename
T2
>
968
INLINE
bool
BijectionIteratorSafe
<
T1
,
T2
>::
operator
==(
969
const
BijectionIteratorSafe
<
T1
,
T2
>&
toCompare
)
const
noexcept
{
970
return
_iter_
==
toCompare
.
_iter_
;
971
}
972
973
/// return the first element of the current association
974
template
<
typename
T1
,
typename
T2
>
975
INLINE
const
T1
&
BijectionIteratorSafe
<
T1
,
T2
>::
first
()
const
{
976
return
_iter_
.
key
();
977
}
978
979
/// return the second element of the current association
980
template
<
typename
T1
,
typename
T2
>
981
INLINE
const
T2
&
BijectionIteratorSafe
<
T1
,
T2
>::
second
()
const
{
982
return
Getter
::
op_second
(
_iter_
.
val
());
983
}
984
985
/* ===========================================================================
986
*/
987
/* === BIJECTION UNSAFE ITERATORS ===
988
*/
989
/* ===========================================================================
990
*/
991
992
/// Default constructor
993
template
<
typename
T1
,
typename
T2
>
994
INLINE
BijectionIterator
<
T1
,
T2
>::
BijectionIterator
()
noexcept
{
995
GUM_CONSTRUCTOR
(
BijectionIterator
);
996
}
997
998
/// Constructor
999
template
<
typename
T1
,
typename
T2
>
1000
template
<
typename
Alloc
,
bool
Gen
>
1001
INLINE
BijectionIterator
<
T1
,
T2
>::
BijectionIterator
(
1002
const
BijectionImplementation
<
T1
,
T2
,
Alloc
,
Gen
>&
bijection
) :
1003
_iter_
{
bijection
.
_firstToSecond_
.
cbegin
()} {
1004
GUM_CONSTRUCTOR
(
BijectionIterator
);
1005
}
1006
1007
/// Constructor
1008
template
<
typename
T1
,
typename
T2
>
1009
template
<
typename
Alloc
>
1010
INLINE
1011
BijectionIterator
<
T1
,
T2
>::
BijectionIterator
(
const
Bijection
<
T1
,
T2
,
Alloc
>&
bijection
) :
1012
_iter_
{
bijection
.
_firstToSecond_
.
cbegin
()} {
1013
GUM_CONSTRUCTOR
(
BijectionIterator
);
1014
}
1015
1016
/// Copy constructor
1017
template
<
typename
T1
,
typename
T2
>
1018
INLINE
BijectionIterator
<
T1
,
T2
>::
BijectionIterator
(
const
BijectionIterator
<
T1
,
T2
>&
toCopy
) :
1019
_iter_
{
toCopy
.
_iter_
} {
1020
GUM_CONS_CPY
(
BijectionIterator
);
1021
}
1022
1023
/// move constructor
1024
template
<
typename
T1
,
typename
T2
>
1025
INLINE
BijectionIterator
<
T1
,
T2
>::
BijectionIterator
(
BijectionIterator
<
T1
,
T2
>&&
from
)
noexcept
1026
:
1027
_iter_
{
std
::
move
(
from
.
_iter_
)} {
1028
GUM_CONS_MOV
(
BijectionIterator
);
1029
}
1030
1031
/// Destructor
1032
template
<
typename
T1
,
typename
T2
>
1033
INLINE
BijectionIterator
<
T1
,
T2
>::~
BijectionIterator
()
noexcept
{
1034
GUM_DESTRUCTOR
(
BijectionIterator
);
1035
}
1036
1037
/// Copy operator
1038
template
<
typename
T1
,
typename
T2
>
1039
INLINE
BijectionIterator
<
T1
,
T2
>&
1040
BijectionIterator
<
T1
,
T2
>::
operator
=(
const
BijectionIterator
<
T1
,
T2
>&
toCopy
) {
1041
_iter_
=
toCopy
.
_iter_
;
1042
return
*
this
;
1043
}
1044
1045
/// move operator
1046
template
<
typename
T1
,
typename
T2
>
1047
INLINE
BijectionIterator
<
T1
,
T2
>&
1048
BijectionIterator
<
T1
,
T2
>::
operator
=(
BijectionIterator
<
T1
,
T2
>&&
toCopy
)
noexcept
{
1049
_iter_
=
std
::
move
(
toCopy
.
_iter_
);
1050
return
*
this
;
1051
}
1052
1053
/// Go to the next association (if exists)
1054
template
<
typename
T1
,
typename
T2
>
1055
INLINE
BijectionIterator
<
T1
,
T2
>&
BijectionIterator
<
T1
,
T2
>::
operator
++()
noexcept
{
1056
++
_iter_
;
1057
return
*
this
;
1058
}
1059
1060
/// moves the iterator by nb elements
1061
template
<
typename
T1
,
typename
T2
>
1062
INLINE
BijectionIterator
<
T1
,
T2
>&
BijectionIterator
<
T1
,
T2
>::
operator
+=(
Size
nb
)
noexcept
{
1063
_iter_
+=
nb
;
1064
return
*
this
;
1065
}
1066
1067
/// returns a new iterator
1068
template
<
typename
T1
,
typename
T2
>
1069
INLINE
BijectionIterator
<
T1
,
T2
>
BijectionIterator
<
T1
,
T2
>::
operator
+(
Size
nb
)
noexcept
{
1070
return
BijectionIterator
<
T1
,
T2
>{*
this
} +=
nb
;
1071
}
1072
1073
/// Comparison of iterators
1074
template
<
typename
T1
,
typename
T2
>
1075
INLINE
bool
BijectionIterator
<
T1
,
T2
>::
operator
!=(
1076
const
BijectionIterator
<
T1
,
T2
>&
toCompare
)
const
noexcept
{
1077
return
_iter_
!=
toCompare
.
_iter_
;
1078
}
1079
1080
/// Comparison of iterators
1081
template
<
typename
T1
,
typename
T2
>
1082
INLINE
bool
BijectionIterator
<
T1
,
T2
>::
operator
==(
1083
const
BijectionIterator
<
T1
,
T2
>&
toCompare
)
const
noexcept
{
1084
return
_iter_
==
toCompare
.
_iter_
;
1085
}
1086
1087
/// return the first element of the current association
1088
template
<
typename
T1
,
typename
T2
>
1089
INLINE
const
T1
&
BijectionIterator
<
T1
,
T2
>::
first
()
const
{
1090
return
_iter_
.
key
();
1091
}
1092
1093
/// return the second element of the current association
1094
template
<
typename
T1
,
typename
T2
>
1095
INLINE
const
T2
&
BijectionIterator
<
T1
,
T2
>::
second
()
const
{
1096
return
Getter
::
op_second
(
_iter_
.
val
());
1097
}
1098
1099
// ============================================================================
1100
// BIJECTION
1101
// ============================================================================
1102
1103
// Default constructor: creates a bijection without any association
1104
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
1105
INLINE
Bijection
<
T1
,
T2
,
Alloc
>::
Bijection
(
Size
size
,
bool
resize_policy
) :
1106
BijectionImplementation
<
T1
,
1107
T2
,
1108
Alloc
,
1109
std
::
is_scalar
<
T1
>::
value
&&
std
::
is_scalar
<
T2
>::
value
>(
1110
size
,
1111
resize_policy
) {
1112
GUM_CONSTRUCTOR
(
Bijection
);
1113
}
1114
1115
// initializer list constructor
1116
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
1117
INLINE
Bijection
<
T1
,
T2
,
Alloc
>::
Bijection
(
std
::
initializer_list
<
std
::
pair
<
T1
,
T2
> >
list
) :
1118
BijectionImplementation
<
T1
,
1119
T2
,
1120
Alloc
,
1121
std
::
is_scalar
<
T1
>::
value
&&
std
::
is_scalar
<
T2
>::
value
>(
list
) {
1122
GUM_CONSTRUCTOR
(
Bijection
);
1123
}
1124
1125
// Copy constructor
1126
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
1127
INLINE
Bijection
<
T1
,
T2
,
Alloc
>::
Bijection
(
const
Bijection
<
T1
,
T2
,
Alloc
>&
toCopy
) :
1128
BijectionImplementation
<
T1
,
1129
T2
,
1130
Alloc
,
1131
std
::
is_scalar
<
T1
>::
value
&&
std
::
is_scalar
<
T2
>::
value
>(
1132
toCopy
) {
1133
GUM_CONS_CPY
(
Bijection
);
1134
}
1135
1136
// Generalized copy constructor
1137
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
1138
template
<
typename
OtherAlloc
>
1139
INLINE
Bijection
<
T1
,
T2
,
Alloc
>::
Bijection
(
const
Bijection
<
T1
,
T2
,
OtherAlloc
>&
toCopy
) :
1140
BijectionImplementation
<
T1
,
1141
T2
,
1142
Alloc
,
1143
std
::
is_scalar
<
T1
>::
value
&&
std
::
is_scalar
<
T2
>::
value
>(
1144
toCopy
) {
1145
GUM_CONS_CPY
(
Bijection
);
1146
}
1147
1148
// move constructor
1149
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
1150
INLINE
Bijection
<
T1
,
T2
,
Alloc
>::
Bijection
(
Bijection
<
T1
,
T2
,
Alloc
>&&
from
)
noexcept
:
1151
BijectionImplementation
<
T1
,
1152
T2
,
1153
Alloc
,
1154
std
::
is_scalar
<
T1
>::
value
&&
std
::
is_scalar
<
T2
>::
value
>(
1155
std
::
move
(
from
)) {
1156
GUM_CONS_MOV
(
Bijection
);
1157
}
1158
1159
// destructor
1160
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
1161
INLINE
Bijection
<
T1
,
T2
,
Alloc
>::~
Bijection
() {
1162
GUM_DESTRUCTOR
(
Bijection
);
1163
}
1164
1165
// copy operator
1166
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
1167
INLINE
Bijection
<
T1
,
T2
,
Alloc
>&
1168
Bijection
<
T1
,
T2
,
Alloc
>::
operator
=(
const
Bijection
<
T1
,
T2
,
Alloc
>&
toCopy
) {
1169
Implementation
::
operator
=(
toCopy
);
1170
return
*
this
;
1171
}
1172
1173
// generalized copy operator
1174
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
1175
template
<
typename
OtherAlloc
>
1176
INLINE
Bijection
<
T1
,
T2
,
Alloc
>&
1177
Bijection
<
T1
,
T2
,
Alloc
>::
operator
=(
const
Bijection
<
T1
,
T2
,
OtherAlloc
>&
toCopy
) {
1178
Implementation
::
operator
=(
toCopy
);
1179
return
*
this
;
1180
}
1181
1182
// move operator
1183
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
1184
INLINE
Bijection
<
T1
,
T2
,
Alloc
>&
1185
Bijection
<
T1
,
T2
,
Alloc
>::
operator
=(
Bijection
<
T1
,
T2
,
Alloc
>&&
bij
) {
1186
Implementation
::
operator
=(
std
::
move
(
bij
));
1187
return
*
this
;
1188
}
1189
1190
// for friendly displaying the content of bijections
1191
template
<
typename
T1
,
typename
T2
,
typename
Alloc
>
1192
std
::
ostream
&
operator
<<(
std
::
ostream
&
stream
,
const
Bijection
<
T1
,
T2
,
Alloc
>&
b
) {
1193
stream
<<
b
.
toString
();
1194
return
stream
;
1195
}
1196
1197
}
/* namespace gum */
gum::Set::emplace
INLINE void emplace(Args &&... args)
Definition:
set_tpl.h:643