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