aGrUM
0.20.2
a C++ library for (probabilistic) graphical models
splay_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 of splay trees
25
*
26
* @author Karim Tekkal
27
*/
28
#
include
<
agrum
/
tools
/
core
/
splay
.
h
>
29
30
namespace
gum
{
31
/* =========================================================================*/
32
/* =========================================================================*/
33
/* === Implementation of gumSplayBinaryNode === */
34
/* =========================================================================*/
35
/* =========================================================================*/
36
37
// a function used to perform copies of HashTableLists
38
39
template
<
class
Element
>
40
INLINE
void
SplayBinaryNode
<
Element
>::
copy_
(
41
const
SplayBinaryNode
<
Element
>&
from
,
42
HashTable
<
Element
,
SplayBinaryNode
<
Element
>* >&
addr
) {
43
if
(
addr
.
exists
(
from
.
elt
))
44
addr
[
from
.
elt
] =
this
;
45
else
46
addr
.
insert
(
from
.
elt
,
this
);
47
48
elt
=
from
.
elt
;
49
50
size
=
from
.
size
;
51
52
pere
= 0;
53
54
if
(
from
.
fg
) {
55
fg
=
new
SplayBinaryNode
<
Element
>(*
from
.
fg
,
addr
);
56
fg
->
pere
=
this
;
57
}
else
{
58
fg
= 0;
59
}
60
61
if
(
from
.
fd
) {
62
fd
=
new
SplayBinaryNode
<
Element
>(*
from
.
fd
,
addr
);
63
fd
->
pere
=
this
;
64
}
else
{
65
fd
= 0;
66
}
67
}
68
69
// constructor
70
71
template
<
class
Element
>
72
INLINE
SplayBinaryNode
<
Element
>::
SplayBinaryNode
(
73
const
Element
&
e
,
74
HashTable
<
Element
,
SplayBinaryNode
<
Element
>* >&
addr
,
75
SplayBinaryNode
*
g
,
76
SplayBinaryNode
*
d
,
77
SplayBinaryNode
*
p
) :
78
elt
(
e
),
79
size
(1),
fg
(
g
),
fd
(
d
),
pere
(
p
) {
80
if
(
addr
.
exists
(
elt
))
81
addr
[
elt
] =
this
;
82
else
83
addr
.
insert
(
elt
,
this
);
84
85
// for debugging purposes
86
GUM_CONSTRUCTOR
(
SplayBinaryNode
);
87
}
88
89
// copy operator
90
91
template
<
class
Element
>
92
INLINE
SplayBinaryNode
<
Element
>::
SplayBinaryNode
(
93
const
SplayBinaryNode
<
Element
>&
from
,
94
HashTable
<
Element
,
SplayBinaryNode
<
Element
>* >&
addr
) {
95
copy_
(
from
,
addr
);
96
// for debugging purposes
97
GUM_CONSTRUCTOR
(
SplayBinaryNode
);
98
}
99
100
// destructor
101
102
template
<
class
Element
>
103
INLINE
SplayBinaryNode
<
Element
>::~
SplayBinaryNode
() {
104
// for debugging purposes
105
GUM_DESTRUCTOR
(
SplayBinaryNode
);
106
// remove the subtrees
107
108
if
(
fg
)
delete
fg
;
109
110
if
(
fd
)
delete
fd
;
111
}
112
113
// Perform a right rotation, returns the node
114
115
template
<
class
Element
>
116
INLINE
SplayBinaryNode
<
Element
>*
SplayBinaryNode
<
Element
>::
zig
() {
117
Size
size_
;
118
// Must be called on a node with a father
119
GUM_ASSERT
(
pere
!= 0);
120
// We chain childs
121
pere
->
fg
=
fd
;
122
123
if
(
fd
)
fd
->
pere
=
pere
;
124
125
fd
=
pere
;
126
127
SplayBinaryNode
<
Element
>*
p
=
fd
->
pere
;
128
129
fd
->
pere
=
this
;
130
131
// We compute the size of rigth child
132
size_
= 1;
133
134
if
(
fd
->
fg
)
size_
+=
fd
->
fg
->
size
;
135
136
if
(
fd
->
fd
)
size_
+=
fd
->
fd
->
size
;
137
138
fd
->
size
=
size_
;
139
140
// size_ == fd->size
141
if
(
fg
)
size_
+=
fg
->
size
;
142
143
++
size_
;
144
145
size
=
size_
;
146
147
// We chain father
148
pere
=
p
;
149
150
if
(
pere
) {
151
if
(
pere
->
fg
==
fd
) {
152
// I'm left child of my father
153
pere
->
fg
=
this
;
154
}
else
{
155
// I'm right child of my father
156
GUM_ASSERT
(
pere
->
fd
==
fd
);
157
pere
->
fd
=
this
;
158
}
159
}
160
161
return
this
;
162
}
163
164
// Perform a left rotation, returns the node
165
166
template
<
class
Element
>
167
INLINE
SplayBinaryNode
<
Element
>*
SplayBinaryNode
<
Element
>::
zag
() {
168
Size
size_
;
169
// Must be call on a node with a father
170
GUM_ASSERT
(
pere
!= 0);
171
// We chain childs
172
pere
->
fd
=
fg
;
173
174
if
(
fg
)
fg
->
pere
=
pere
;
175
176
fg
=
pere
;
177
178
SplayBinaryNode
<
Element
>*
p
=
fg
->
pere
;
179
180
fg
->
pere
=
this
;
181
182
// We compute the size of rigth child
183
size_
= 1;
184
185
if
(
fg
->
fg
)
size_
+=
fg
->
fg
->
size
;
186
187
if
(
fg
->
fd
)
size_
+=
fg
->
fd
->
size
;
188
189
fg
->
size
=
size_
;
190
191
if
(
fd
)
size_
+=
fd
->
size
;
192
193
++
size_
;
194
195
size
=
size_
;
196
197
// We chain father
198
pere
=
p
;
199
200
if
(
pere
) {
201
if
(
pere
->
fg
==
fg
) {
202
// I'm left child of my father
203
pere
->
fg
=
this
;
204
}
else
{
205
// I'm right child of my father
206
GUM_ASSERT
(
pere
->
fd
==
fg
);
207
pere
->
fd
=
this
;
208
}
209
}
210
211
return
this
;
212
}
213
214
// Perform a splay rotation, the node return is the root
215
216
template
<
class
Element
>
217
INLINE
SplayBinaryNode
<
Element
>*
SplayBinaryNode
<
Element
>::
splay
() {
218
SplayBinaryNode
<
Element
>*
gdp
;
219
220
while
(
pere
) {
221
// While this node isn't the root
222
gdp
=
pere
->
pere
;
// gdp can be nullptr
223
224
if
(!
gdp
) {
225
if
(
this
==
pere
->
fg
) {
226
// I'm the left child of my father
227
return
zig
();
228
}
else
{
229
GUM_ASSERT
(
this
==
pere
->
fd
);
230
// I'm the right child of my father
231
return
zag
();
232
}
233
}
else
{
234
if
(
this
==
pere
->
fg
) {
235
// I'm the left child of my father
236
if
(
pere
==
gdp
->
fg
) {
237
gdp
->
fg
=
zig
();
238
}
else
{
239
GUM_ASSERT
(
pere
==
gdp
->
fd
);
240
gdp
->
fd
=
zig
();
241
}
242
}
else
{
243
GUM_ASSERT
(
this
==
pere
->
fd
);
244
// I'm the right child of my father
245
246
if
(
pere
==
gdp
->
fg
) {
247
gdp
->
fg
=
zag
();
248
}
else
{
249
GUM_ASSERT
(
pere
==
gdp
->
fd
);
250
gdp
->
fd
=
zag
();
251
}
252
}
253
}
254
}
255
256
return
this
;
// for compiler satisfaction
257
}
258
259
// Concatenation of two threes
260
261
template
<
class
Element
>
262
INLINE
SplayBinaryNode
<
Element
>*
SplayBinaryNode
<
Element
>::
join
(
263
const
SplayBinaryNode
<
Element
>*
e
,
264
HashTable
<
Element
,
SplayBinaryNode
<
Element
>* >&
addr
) {
265
SplayBinaryNode
<
Element
>*
b
=
new
SplayBinaryNode
<
Element
>(*
e
,
addr
);
266
GUM_ASSERT
(
b
!= 0);
267
SplayBinaryNode
<
Element
>*
act
=
this
;
268
269
for
(;
act
->
fd
;
act
=
act
->
fd
)
270
;
271
272
// act is the rightmost element
273
act
->
splay
();
274
275
// insertion
276
act
->
fd
=
b
;
277
278
b
->
pere
=
act
;
279
280
act
->
size
= 1;
281
282
if
(
act
->
fg
)
act
->
size
+=
act
->
fg
->
size
;
283
284
act
->
size
+=
act
->
fd
->
size
;
285
286
return
act
;
287
}
288
289
// Get the position of the node
290
291
template
<
class
Element
>
292
INLINE
int
SplayBinaryNode
<
Element
>::
position
()
const
{
293
if
(!
pere
) {
294
// I'm the root
295
if
(
fg
)
296
return
fg
->
size
+ 1;
297
else
298
return
0;
299
}
else
if
(
pere
->
fg
==
this
) {
300
// I'm the left child of my father
301
int
pos
=
pere
->
position
() - 1;
302
303
if
(
fd
)
pos
-=
fd
->
size
;
304
305
return
pos
;
306
}
else
{
307
// I'm the right child of my father
308
int
pos
=
pere
->
position
() + 1;
309
310
if
(
fg
)
pos
+=
fg
->
size
;
311
312
return
pos
;
313
}
314
}
315
316
// Get the element in the node
317
318
template
<
class
Element
>
319
INLINE
const
Element
&
SplayBinaryNode
<
Element
>::
getElement
()
const
{
320
return
elt
;
321
}
322
323
/*
324
* @return the left child
325
* @warning the returned value can be null
326
*/
327
328
template
<
class
Element
>
329
INLINE
const
SplayBinaryNode
<
Element
>*
330
SplayBinaryNode
<
Element
>::
getFg
()
const
{
331
return
fg
;
332
}
333
334
/*
335
* @return the right child
336
* @warning the returned value can be null
337
*/
338
339
template
<
class
Element
>
340
INLINE
const
SplayBinaryNode
<
Element
>*
341
SplayBinaryNode
<
Element
>::
getFd
()
const
{
342
return
fd
;
343
}
344
345
/* =========================================================================*/
346
/* =========================================================================*/
347
/* === Implementation of SplayTree === */
348
/* =========================================================================*/
349
/* =========================================================================*/
350
351
// a function used to perform copies
352
353
template
<
class
Element
>
354
INLINE
void
SplayTree
<
Element
>::
copy_
(
const
SplayTree
<
Element
>&
from
) {
355
if
(
from
.
root
) {
356
root
=
new
SplayBinaryNode
<
Element
>(*
from
.
root
,
addr
);
357
}
else
{
358
root
= 0;
359
}
360
}
361
362
// basic constructor, make an empty splay tree
363
364
template
<
class
Element
>
365
INLINE
SplayTree
<
Element
>::
SplayTree
() :
root
(0),
addr
() {
366
// for debugging purposes
367
GUM_CONSTRUCTOR
(
SplayTree
);
368
}
369
370
// basic constructor, make a splay tree with one element
371
/*
372
* @param e the element of the tree
373
*/
374
375
template
<
class
Element
>
376
INLINE
SplayTree
<
Element
>::
SplayTree
(
const
Element
&
e
) :
root
(0),
addr
() {
377
root
=
new
SplayBinaryNode
<
Element
>(
e
,
addr
);
378
// for debugging purposes
379
GUM_CONSTRUCTOR
(
SplayTree
);
380
}
381
382
// copy constructor
383
384
template
<
class
Element
>
385
INLINE
SplayTree
<
Element
>::
SplayTree
(
const
SplayTree
&
from
) :
addr
() {
386
copy_
(
from
);
387
// for debugging purposes
388
GUM_CONS_CPY
(
SplayTree
);
389
}
390
391
// Assignment operator
392
393
template
<
class
Element
>
394
INLINE
SplayTree
<
Element
>&
395
SplayTree
<
Element
>::
operator
=(
const
SplayTree
<
Element
>&
from
) {
396
// avoid self assignment
397
if
(
this
!= &
from
) {
398
// for debugging purposes
399
GUM_OP_CPY
(
SplayTree
);
400
// delete the old contents
401
402
if
(
root
)
delete
root
;
403
404
addr
.
clear
();
405
406
copy_
(
from
);
407
}
408
409
return
*
this
;
410
}
411
412
// Destructor
413
414
template
<
class
Element
>
415
INLINE
SplayTree
<
Element
>::~
SplayTree
() {
416
// for debugging purposes
417
GUM_DESTRUCTOR
(
SplayTree
);
418
419
if
(
root
)
delete
(
root
);
420
}
421
422
// Get the element at the position n
423
424
template
<
class
Element
>
425
Element
&
SplayTree
<
Element
>::
operator
[](
const
unsigned
int
i
) {
426
int
val
=
i
;
427
428
if
(!
root
) {
429
GUM_ERROR
(
NotFound
,
"The tree is empty !"
);
430
}
else
if
(
val
>=
root
->
size
) {
431
GUM_ERROR
(
NotFound
,
"The index is too large !"
);
432
}
else
{
433
// The element exists
434
// Find it
435
SplayBinaryNode
<
Element
>*
act
=
root
;
436
int
pos_act
=
val
- 1;
437
bool
next
=
true
;
438
439
while
(
next
) {
440
if
(!
act
->
fg
)
441
pos_act
= 0;
442
else
443
pos_act
=
act
->
fg
->
size
;
444
445
if
(
pos_act
>
val
) {
446
act
=
act
->
fg
;
447
}
else
if
(
pos_act
<
val
) {
448
act
=
act
->
fd
;
449
val
-= (
pos_act
+ 1);
450
}
else
{
451
next
=
false
;
452
}
453
}
454
455
root
=
act
->
splay
();
456
457
return
root
->
elt
;
458
}
459
}
460
461
template
<
class
Element
>
462
const
Element
&
SplayTree
<
Element
>::
operator
[](
const
unsigned
int
i
)
const
{
463
int
val
=
i
;
464
465
if
(!
root
) {
466
GUM_ERROR
(
NotFound
,
"The tree is empty !"
);
467
}
else
if
(
val
>=
root
->
size
) {
468
GUM_ERROR
(
NotFound
,
"The index is too large !"
);
469
}
else
{
470
// The element exists
471
// Find it
472
SplayBinaryNode
<
Element
>*
act
=
root
;
473
int
pos_act
=
val
- 1;
474
bool
next
=
true
;
475
476
while
(
next
) {
477
if
(!
act
->
fg
)
478
pos_act
= 0;
479
else
480
pos_act
=
act
->
fg
->
size
;
481
482
if
(
pos_act
>
val
) {
483
act
=
act
->
fg
;
484
}
else
if
(
pos_act
<
val
) {
485
act
=
act
->
fd
;
486
val
-= (
pos_act
+ 1);
487
}
else
{
488
next
=
false
;
489
}
490
}
491
492
root
=
act
->
splay
();
493
494
return
root
->
elt
;
495
}
496
}
497
498
// Get the first element
499
500
template
<
class
Element
>
501
INLINE
Element
&
SplayTree
<
Element
>::
front
() {
502
SplayBinaryNode
<
Element
>*
act
=
root
;
503
504
if
(!
root
) {
GUM_ERROR
(
NotFound
,
"The splay tree is empty"
); }
505
506
if
(
act
->
fg
)
507
for
(;
act
->
fg
;
act
=
act
->
fg
)
508
;
509
510
root
=
act
->
splay
();
511
512
return
root
->
elt
;
513
}
514
515
// Get the last element
516
517
template
<
class
Element
>
518
INLINE
Element
&
SplayTree
<
Element
>::
back
() {
519
SplayBinaryNode
<
Element
>*
act
=
root
;
520
521
if
(!
root
) {
GUM_ERROR
(
NotFound
,
"The splay tree is empty"
); }
522
523
if
(
act
->
fd
)
524
for
(;
act
->
fd
;
act
=
act
->
fd
)
525
;
526
527
root
=
act
->
splay
();
528
529
return
root
->
elt
;
530
}
531
532
// Remove the first element
533
534
template
<
class
Element
>
535
INLINE
void
SplayTree
<
Element
>::
popFront
() {
536
SplayBinaryNode
<
Element
>*
act
=
root
;
537
538
if
(
root
) {
539
if
(
root
->
fg
)
540
for
(;
act
->
fg
;
act
=
act
->
fg
)
541
;
542
543
act
=
act
->
splay
();
544
545
root
=
act
->
fd
;
546
547
if
(
root
)
root
->
pere
= 0;
548
549
act
->
fd
= 0;
550
551
delete
act
;
552
}
553
}
554
555
// Remove the last element
556
557
template
<
class
Element
>
558
INLINE
void
SplayTree
<
Element
>::
popBack
() {
559
SplayBinaryNode
<
Element
>*
act
=
root
;
560
561
if
(
root
) {
562
if
(
root
->
fd
)
563
for
(;
act
->
fd
;
act
=
act
->
fd
)
564
;
565
566
act
=
act
->
splay
();
567
568
root
=
act
->
fg
;
569
570
if
(
root
)
root
->
pere
= 0;
571
572
act
->
fg
= 0;
573
574
delete
act
;
575
}
576
}
577
578
// Add an element in the first position
579
580
template
<
class
Element
>
581
INLINE
void
SplayTree
<
Element
>::
pushFront
(
const
Element
&
e
) {
582
SplayBinaryNode
<
Element
>*
act
=
root
;
583
584
if
(
root
) {
585
if
(
root
->
fg
)
586
for
(;
act
->
fg
;
act
=
act
->
fg
)
587
;
588
589
root
=
act
->
splay
();
590
591
root
->
fg
=
new
SplayBinaryNode
<
Element
>(
e
,
addr
, 0, 0,
root
);
592
}
else
{
593
root
=
new
SplayBinaryNode
<
Element
>(
e
,
addr
);
594
}
595
}
596
597
// Add an element in the last position
598
599
template
<
class
Element
>
600
INLINE
void
SplayTree
<
Element
>::
pushBack
(
const
Element
&
e
) {
601
SplayBinaryNode
<
Element
>*
act
=
root
;
602
603
if
(
root
) {
604
if
(
root
->
fd
)
605
for
(;
act
->
fd
;
act
=
act
->
fd
)
606
;
607
608
root
=
act
->
splay
();
609
610
root
->
fd
=
new
SplayBinaryNode
<
Element
>(
e
,
addr
, 0, 0,
root
);
611
}
else
{
612
root
=
new
SplayBinaryNode
<
Element
>(
e
,
addr
);
613
}
614
}
615
616
// Add an element to the tree
617
618
template
<
class
Element
>
619
INLINE
void
SplayTree
<
Element
>::
insert
(
const
Element
&
e
) {
620
SplayBinaryNode
<
Element
>*
act
=
root
;
621
622
if
(!
root
) {
623
root
=
new
SplayBinaryNode
<
Element
>(
e
,
addr
);
624
}
else
{
625
while
(
act
->
fd
) {
626
++
act
->
size
;
627
act
=
act
->
fd
;
628
}
629
630
// act->fd == nullptr
631
act
->
fd
=
new
SplayBinaryNode
<
Element
>(
e
,
addr
, 0, 0,
act
);
632
633
++
act
->
size
;
634
635
root
=
act
->
fd
->
splay
();
636
}
637
}
638
639
// Concatenation of two trees
640
/*
641
* @param s the tree to add
642
*/
643
644
template
<
class
Element
>
645
INLINE
void
SplayTree
<
Element
>::
join
(
const
SplayTree
<
Element
>&
s
) {
646
if
(
s
.
root
) {
647
if
(
root
) {
648
root
=
root
->
join
(
s
.
root
,
addr
);
649
}
else
{
650
root
=
new
SplayBinaryNode
<
Element
>(*
s
.
root
,
addr
);
651
}
652
}
653
}
654
655
// removeInfo removes all the information about the nodes contains by e
656
657
template
<
class
Element
>
658
INLINE
static
void
659
removeInfo
(
const
SplayBinaryNode
<
Element
>*
e
,
660
HashTable
<
Element
,
SplayBinaryNode
<
Element
>* >&
addr
) {
661
GUM_ASSERT
(
addr
.
exists
(
e
->
getElement
()));
662
addr
.
erase
(
e
->
getElement
());
663
664
if
(
e
->
getFg
())
removeInfo
(
e
->
getFg
(),
addr
);
665
666
if
(
e
->
getFd
())
removeInfo
(
e
->
getFd
(),
addr
);
667
}
668
669
// Split the tree at the element
670
671
template
<
class
Element
>
672
INLINE
SplayTree
<
Element
>
SplayTree
<
Element
>::
split
(
const
int
i
) {
673
GUM_ASSERT
(
i
>= 0 &&
i
<
root
->
size
);
674
GUM_ASSERT
(
root
!= 0);
675
676
if
(
i
== 0) {
677
// the tree will be empty
678
// the returned tree is a copy of the present tree
679
SplayTree
<
Element
>
s
= *
this
;
680
addr
.
clear
();
681
delete
root
;
682
root
= 0;
683
return
s
;
684
}
else
if
(
i
==
root
->
size
- 1) {
685
SplayTree
<
Element
>
s
;
686
return
s
;
687
}
else
{
688
// We will find the node at position i
689
SplayBinaryNode
<
Element
>*
act
=
root
;
690
int
pos
=
root
->
position
();
691
692
while
(
pos
!=
i
) {
693
GUM_ASSERT
(
act
!= 0);
694
695
if
(
i
<
pos
) {
696
act
=
act
->
fg
;
697
}
else
{
698
act
=
act
->
fd
;
699
}
700
701
pos
=
act
->
position
();
702
}
703
704
// We reorganize the tree
705
act
->
splay
();
706
707
// We take the first part
708
root
=
act
->
fg
;
709
710
if
(
root
)
root
->
pere
= 0;
711
712
// We take the second part
713
SplayTree
<
Element
>
s
;
714
715
s
.
root
=
act
;
716
717
s
.
root
->
fg
= 0;
718
719
Size
size_
= 1;
720
721
if
(
s
.
root
->
fd
)
size_
+=
s
.
root
->
fd
->
size
;
722
723
s
.
root
->
size
=
size_
;
724
725
// We remove the old nodes in the hash table
726
// Complexity O(n) => very expensive
727
removeInfo
(
act
,
addr
);
728
729
return
s
;
730
}
731
}
732
733
// Split the tree at the element
734
735
template
<
typename
Element
>
736
INLINE
SplayTree
<
Element
>
737
SplayTree
<
Element
>::
split_by_val
(
const
Element
&
e
) {
738
GUM_ASSERT
(
root
!= 0);
739
740
if
(!
addr
.
exists
(
e
)) {
741
GUM_ERROR
(
NotFound
,
"not enough elements in the splay tree"
);
742
}
743
744
// We will find the node at position i
745
SplayBinaryNode
<
Element
>*
act
=
addr
[
e
];
746
747
// We reorganize the tree
748
act
->
splay
();
749
750
// We take the two parts
751
SplayTree
<
Element
>
s
;
752
753
s
.
root
=
act
->
fd
;
754
755
if
(
s
.
root
) {
s
.
root
->
pere
= 0; }
756
757
root
=
act
->
fg
;
758
759
if
(
root
)
root
->
pere
= 0;
760
761
act
->
fg
= 0;
762
763
// We remove the old nodes in the hash table
764
// Complexity O(n) => very expensive
765
removeInfo
(
act
,
addr
);
766
767
act
->
fd
= 0;
768
769
delete
act
;
770
771
return
s
;
772
}
773
774
// The number of elements in the tree
775
776
template
<
class
Element
>
777
INLINE
Size
SplayTree
<
Element
>::
size
()
const
{
778
if
(
root
)
779
return
root
->
size
;
780
else
781
return
Size
(0);
782
}
783
784
// Test if the tree contains the element
785
786
template
<
class
Element
>
787
INLINE
bool
SplayTree
<
Element
>::
contains
(
const
Element
&
e
)
const
{
788
return
addr
.
exists
(
e
);
789
}
790
791
// Display the node
792
793
template
<
typename
Element
>
794
std
::
ostream
&
operator
<<(
std
::
ostream
&
out
,
795
const
SplayBinaryNode
<
Element
>&
e
) {
796
if
(
e
.
fg
)
out
<< *
e
.
fg
<<
","
;
797
798
out
<<
e
.
elt
;
799
800
if
(
e
.
fd
)
out
<<
","
<< *
e
.
fd
;
801
802
return
out
;
803
}
804
805
// Display the tree
806
807
template
<
typename
Element
>
808
INLINE
std
::
ostream
&
operator
<<(
std
::
ostream
&
out
,
809
const
SplayTree
<
Element
>&
s
) {
810
out
<<
"|["
;
811
812
if
(
s
.
root
)
out
<< *
s
.
root
;
813
814
out
<<
"]|"
;
815
816
return
out
;
817
}
818
819
}
/* namespace gum */
gum::Set::emplace
INLINE void emplace(Args &&... args)
Definition:
set_tpl.h:669