aGrUM
0.20.3
a C++ library for (probabilistic) graphical models
splay_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 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
41
SplayBinaryNode
<
Element
>::
copy_
(
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
>*
263
SplayBinaryNode
<
Element
>::
join
(
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
>*
SplayBinaryNode
<
Element
>::
getFg
()
const
{
330
return
fg
;
331
}
332
333
/*
334
* @return the right child
335
* @warning the returned value can be null
336
*/
337
338
template
<
class
Element
>
339
INLINE
const
SplayBinaryNode
<
Element
>*
SplayBinaryNode
<
Element
>::
getFd
()
const
{
340
return
fd
;
341
}
342
343
/* =========================================================================*/
344
/* =========================================================================*/
345
/* === Implementation of SplayTree === */
346
/* =========================================================================*/
347
/* =========================================================================*/
348
349
// a function used to perform copies
350
351
template
<
class
Element
>
352
INLINE
void
SplayTree
<
Element
>::
copy_
(
const
SplayTree
<
Element
>&
from
) {
353
if
(
from
.
root
) {
354
root
=
new
SplayBinaryNode
<
Element
>(*
from
.
root
,
addr
);
355
}
else
{
356
root
= 0;
357
}
358
}
359
360
// basic constructor, make an empty splay tree
361
362
template
<
class
Element
>
363
INLINE
SplayTree
<
Element
>::
SplayTree
() :
root
(0),
addr
() {
364
// for debugging purposes
365
GUM_CONSTRUCTOR
(
SplayTree
);
366
}
367
368
// basic constructor, make a splay tree with one element
369
/*
370
* @param e the element of the tree
371
*/
372
373
template
<
class
Element
>
374
INLINE
SplayTree
<
Element
>::
SplayTree
(
const
Element
&
e
) :
root
(0),
addr
() {
375
root
=
new
SplayBinaryNode
<
Element
>(
e
,
addr
);
376
// for debugging purposes
377
GUM_CONSTRUCTOR
(
SplayTree
);
378
}
379
380
// copy constructor
381
382
template
<
class
Element
>
383
INLINE
SplayTree
<
Element
>::
SplayTree
(
const
SplayTree
&
from
) :
addr
() {
384
copy_
(
from
);
385
// for debugging purposes
386
GUM_CONS_CPY
(
SplayTree
);
387
}
388
389
// Assignment operator
390
391
template
<
class
Element
>
392
INLINE
SplayTree
<
Element
>&
SplayTree
<
Element
>::
operator
=(
const
SplayTree
<
Element
>&
from
) {
393
// avoid self assignment
394
if
(
this
!= &
from
) {
395
// for debugging purposes
396
GUM_OP_CPY
(
SplayTree
);
397
// delete the old contents
398
399
if
(
root
)
delete
root
;
400
401
addr
.
clear
();
402
403
copy_
(
from
);
404
}
405
406
return
*
this
;
407
}
408
409
// Destructor
410
411
template
<
class
Element
>
412
INLINE
SplayTree
<
Element
>::~
SplayTree
() {
413
// for debugging purposes
414
GUM_DESTRUCTOR
(
SplayTree
);
415
416
if
(
root
)
delete
(
root
);
417
}
418
419
// Get the element at the position n
420
421
template
<
class
Element
>
422
Element
&
SplayTree
<
Element
>::
operator
[](
const
unsigned
int
i
) {
423
int
val
=
i
;
424
425
if
(!
root
) {
426
GUM_ERROR
(
NotFound
,
"The tree is empty !"
)
427
}
else
if
(
val
>=
root
->
size
) {
428
GUM_ERROR
(
NotFound
,
"The index is too large !"
)
429
}
else
{
430
// The element exists
431
// Find it
432
SplayBinaryNode
<
Element
>*
act
=
root
;
433
int
pos_act
=
val
- 1;
434
bool
next
=
true
;
435
436
while
(
next
) {
437
if
(!
act
->
fg
)
438
pos_act
= 0;
439
else
440
pos_act
=
act
->
fg
->
size
;
441
442
if
(
pos_act
>
val
) {
443
act
=
act
->
fg
;
444
}
else
if
(
pos_act
<
val
) {
445
act
=
act
->
fd
;
446
val
-= (
pos_act
+ 1);
447
}
else
{
448
next
=
false
;
449
}
450
}
451
452
root
=
act
->
splay
();
453
454
return
root
->
elt
;
455
}
456
}
457
458
template
<
class
Element
>
459
const
Element
&
SplayTree
<
Element
>::
operator
[](
const
unsigned
int
i
)
const
{
460
int
val
=
i
;
461
462
if
(!
root
) {
463
GUM_ERROR
(
NotFound
,
"The tree is empty !"
)
464
}
else
if
(
val
>=
root
->
size
) {
465
GUM_ERROR
(
NotFound
,
"The index is too large !"
)
466
}
else
{
467
// The element exists
468
// Find it
469
SplayBinaryNode
<
Element
>*
act
=
root
;
470
int
pos_act
=
val
- 1;
471
bool
next
=
true
;
472
473
while
(
next
) {
474
if
(!
act
->
fg
)
475
pos_act
= 0;
476
else
477
pos_act
=
act
->
fg
->
size
;
478
479
if
(
pos_act
>
val
) {
480
act
=
act
->
fg
;
481
}
else
if
(
pos_act
<
val
) {
482
act
=
act
->
fd
;
483
val
-= (
pos_act
+ 1);
484
}
else
{
485
next
=
false
;
486
}
487
}
488
489
root
=
act
->
splay
();
490
491
return
root
->
elt
;
492
}
493
}
494
495
// Get the first element
496
497
template
<
class
Element
>
498
INLINE
Element
&
SplayTree
<
Element
>::
front
() {
499
SplayBinaryNode
<
Element
>*
act
=
root
;
500
501
if
(!
root
) {
GUM_ERROR
(
NotFound
,
"The splay tree is empty"
) }
502
503
if
(
act
->
fg
)
504
for
(;
act
->
fg
;
act
=
act
->
fg
)
505
;
506
507
root
=
act
->
splay
();
508
509
return
root
->
elt
;
510
}
511
512
// Get the last element
513
514
template
<
class
Element
>
515
INLINE
Element
&
SplayTree
<
Element
>::
back
() {
516
SplayBinaryNode
<
Element
>*
act
=
root
;
517
518
if
(!
root
) {
GUM_ERROR
(
NotFound
,
"The splay tree is empty"
) }
519
520
if
(
act
->
fd
)
521
for
(;
act
->
fd
;
act
=
act
->
fd
)
522
;
523
524
root
=
act
->
splay
();
525
526
return
root
->
elt
;
527
}
528
529
// Remove the first element
530
531
template
<
class
Element
>
532
INLINE
void
SplayTree
<
Element
>::
popFront
() {
533
SplayBinaryNode
<
Element
>*
act
=
root
;
534
535
if
(
root
) {
536
if
(
root
->
fg
)
537
for
(;
act
->
fg
;
act
=
act
->
fg
)
538
;
539
540
act
=
act
->
splay
();
541
542
root
=
act
->
fd
;
543
544
if
(
root
)
root
->
pere
= 0;
545
546
act
->
fd
= 0;
547
548
delete
act
;
549
}
550
}
551
552
// Remove the last element
553
554
template
<
class
Element
>
555
INLINE
void
SplayTree
<
Element
>::
popBack
() {
556
SplayBinaryNode
<
Element
>*
act
=
root
;
557
558
if
(
root
) {
559
if
(
root
->
fd
)
560
for
(;
act
->
fd
;
act
=
act
->
fd
)
561
;
562
563
act
=
act
->
splay
();
564
565
root
=
act
->
fg
;
566
567
if
(
root
)
root
->
pere
= 0;
568
569
act
->
fg
= 0;
570
571
delete
act
;
572
}
573
}
574
575
// Add an element in the first position
576
577
template
<
class
Element
>
578
INLINE
void
SplayTree
<
Element
>::
pushFront
(
const
Element
&
e
) {
579
SplayBinaryNode
<
Element
>*
act
=
root
;
580
581
if
(
root
) {
582
if
(
root
->
fg
)
583
for
(;
act
->
fg
;
act
=
act
->
fg
)
584
;
585
586
root
=
act
->
splay
();
587
588
root
->
fg
=
new
SplayBinaryNode
<
Element
>(
e
,
addr
, 0, 0,
root
);
589
}
else
{
590
root
=
new
SplayBinaryNode
<
Element
>(
e
,
addr
);
591
}
592
}
593
594
// Add an element in the last position
595
596
template
<
class
Element
>
597
INLINE
void
SplayTree
<
Element
>::
pushBack
(
const
Element
&
e
) {
598
SplayBinaryNode
<
Element
>*
act
=
root
;
599
600
if
(
root
) {
601
if
(
root
->
fd
)
602
for
(;
act
->
fd
;
act
=
act
->
fd
)
603
;
604
605
root
=
act
->
splay
();
606
607
root
->
fd
=
new
SplayBinaryNode
<
Element
>(
e
,
addr
, 0, 0,
root
);
608
}
else
{
609
root
=
new
SplayBinaryNode
<
Element
>(
e
,
addr
);
610
}
611
}
612
613
// Add an element to the tree
614
615
template
<
class
Element
>
616
INLINE
void
SplayTree
<
Element
>::
insert
(
const
Element
&
e
) {
617
SplayBinaryNode
<
Element
>*
act
=
root
;
618
619
if
(!
root
) {
620
root
=
new
SplayBinaryNode
<
Element
>(
e
,
addr
);
621
}
else
{
622
while
(
act
->
fd
) {
623
++
act
->
size
;
624
act
=
act
->
fd
;
625
}
626
627
// act->fd == nullptr
628
act
->
fd
=
new
SplayBinaryNode
<
Element
>(
e
,
addr
, 0, 0,
act
);
629
630
++
act
->
size
;
631
632
root
=
act
->
fd
->
splay
();
633
}
634
}
635
636
// Concatenation of two trees
637
/*
638
* @param s the tree to add
639
*/
640
641
template
<
class
Element
>
642
INLINE
void
SplayTree
<
Element
>::
join
(
const
SplayTree
<
Element
>&
s
) {
643
if
(
s
.
root
) {
644
if
(
root
) {
645
root
=
root
->
join
(
s
.
root
,
addr
);
646
}
else
{
647
root
=
new
SplayBinaryNode
<
Element
>(*
s
.
root
,
addr
);
648
}
649
}
650
}
651
652
// removeInfo removes all the information about the nodes contains by e
653
654
template
<
class
Element
>
655
INLINE
static
void
removeInfo
(
const
SplayBinaryNode
<
Element
>*
e
,
656
HashTable
<
Element
,
SplayBinaryNode
<
Element
>* >&
addr
) {
657
GUM_ASSERT
(
addr
.
exists
(
e
->
getElement
()));
658
addr
.
erase
(
e
->
getElement
());
659
660
if
(
e
->
getFg
())
removeInfo
(
e
->
getFg
(),
addr
);
661
662
if
(
e
->
getFd
())
removeInfo
(
e
->
getFd
(),
addr
);
663
}
664
665
// Split the tree at the element
666
667
template
<
class
Element
>
668
INLINE
SplayTree
<
Element
>
SplayTree
<
Element
>::
split
(
const
int
i
) {
669
GUM_ASSERT
(
i
>= 0 &&
i
<
root
->
size
);
670
GUM_ASSERT
(
root
!= 0);
671
672
if
(
i
== 0) {
673
// the tree will be empty
674
// the returned tree is a copy of the present tree
675
SplayTree
<
Element
>
s
= *
this
;
676
addr
.
clear
();
677
delete
root
;
678
root
= 0;
679
return
s
;
680
}
else
if
(
i
==
root
->
size
- 1) {
681
SplayTree
<
Element
>
s
;
682
return
s
;
683
}
else
{
684
// We will find the node at position i
685
SplayBinaryNode
<
Element
>*
act
=
root
;
686
int
pos
=
root
->
position
();
687
688
while
(
pos
!=
i
) {
689
GUM_ASSERT
(
act
!= 0);
690
691
if
(
i
<
pos
) {
692
act
=
act
->
fg
;
693
}
else
{
694
act
=
act
->
fd
;
695
}
696
697
pos
=
act
->
position
();
698
}
699
700
// We reorganize the tree
701
act
->
splay
();
702
703
// We take the first part
704
root
=
act
->
fg
;
705
706
if
(
root
)
root
->
pere
= 0;
707
708
// We take the second part
709
SplayTree
<
Element
>
s
;
710
711
s
.
root
=
act
;
712
713
s
.
root
->
fg
= 0;
714
715
Size
size_
= 1;
716
717
if
(
s
.
root
->
fd
)
size_
+=
s
.
root
->
fd
->
size
;
718
719
s
.
root
->
size
=
size_
;
720
721
// We remove the old nodes in the hash table
722
// Complexity O(n) => very expensive
723
removeInfo
(
act
,
addr
);
724
725
return
s
;
726
}
727
}
728
729
// Split the tree at the element
730
731
template
<
typename
Element
>
732
INLINE
SplayTree
<
Element
>
SplayTree
<
Element
>::
split_by_val
(
const
Element
&
e
) {
733
GUM_ASSERT
(
root
!= 0);
734
735
if
(!
addr
.
exists
(
e
)) {
GUM_ERROR
(
NotFound
,
"not enough elements in the splay tree"
) }
736
737
// We will find the node at position i
738
SplayBinaryNode
<
Element
>*
act
=
addr
[
e
];
739
740
// We reorganize the tree
741
act
->
splay
();
742
743
// We take the two parts
744
SplayTree
<
Element
>
s
;
745
746
s
.
root
=
act
->
fd
;
747
748
if
(
s
.
root
) {
s
.
root
->
pere
= 0; }
749
750
root
=
act
->
fg
;
751
752
if
(
root
)
root
->
pere
= 0;
753
754
act
->
fg
= 0;
755
756
// We remove the old nodes in the hash table
757
// Complexity O(n) => very expensive
758
removeInfo
(
act
,
addr
);
759
760
act
->
fd
= 0;
761
762
delete
act
;
763
764
return
s
;
765
}
766
767
// The number of elements in the tree
768
769
template
<
class
Element
>
770
INLINE
Size
SplayTree
<
Element
>::
size
()
const
{
771
if
(
root
)
772
return
root
->
size
;
773
else
774
return
Size
(0);
775
}
776
777
// Test if the tree contains the element
778
779
template
<
class
Element
>
780
INLINE
bool
SplayTree
<
Element
>::
contains
(
const
Element
&
e
)
const
{
781
return
addr
.
exists
(
e
);
782
}
783
784
// Display the node
785
786
template
<
typename
Element
>
787
std
::
ostream
&
operator
<<(
std
::
ostream
&
out
,
const
SplayBinaryNode
<
Element
>&
e
) {
788
if
(
e
.
fg
)
out
<< *
e
.
fg
<<
","
;
789
790
out
<<
e
.
elt
;
791
792
if
(
e
.
fd
)
out
<<
","
<< *
e
.
fd
;
793
794
return
out
;
795
}
796
797
// Display the tree
798
799
template
<
typename
Element
>
800
INLINE
std
::
ostream
&
operator
<<(
std
::
ostream
&
out
,
const
SplayTree
<
Element
>&
s
) {
801
out
<<
"|["
;
802
803
if
(
s
.
root
)
out
<< *
s
.
root
;
804
805
out
<<
"]|"
;
806
807
return
out
;
808
}
809
810
}
/* namespace gum */
gum::Set::emplace
INLINE void emplace(Args &&... args)
Definition:
set_tpl.h:643