llrbtree 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1942 @@
1
+ /*
2
+ * MIT License
3
+ * Copyright (c) 2002-2013 OZAWA Takuma
4
+ */
5
+ #include <ruby.h>
6
+ #include <ruby/st.h>
7
+ #include "tree.h"
8
+
9
+ #define LLRBTREE_PROC_DEFAULT FL_USER2
10
+ #define HASH_PROC_DEFAULT FL_USER2
11
+
12
+ #ifdef RETURN_SIZED_ENUMERATOR
13
+ #define HAVE_SIZED_ENUMERATOR
14
+ #else
15
+ #ifdef RETURN_ENUMERATOR
16
+ #define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn) RETURN_ENUMERATOR(obj, argc, argv)
17
+ #else
18
+ #define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn) ((void)0)
19
+ #endif
20
+ #endif
21
+
22
+ #ifndef RARRAY_AREF
23
+ #define RARRAY_AREF(a, i) (RARRAY_PTR(a)[i])
24
+ #endif
25
+
26
+ #ifndef RHASH_SET_IFNONE
27
+ #define RHASH_SET_IFNONE(h, v) (RHASH(h)->ifnone = (v))
28
+ #endif
29
+
30
+ VALUE LLRBTree;
31
+
32
+ static ID id_cmp;
33
+ static ID id_call;
34
+ static ID id_default;
35
+ static ID id_flatten_bang;
36
+ static ID id_marshal;
37
+ static ID id_dump;
38
+
39
+ typedef struct {
40
+ tree_t* tree;
41
+ VALUE ifnone;
42
+ VALUE cmp_proc;
43
+ int iter_lev;
44
+ } llrbtree_t;
45
+
46
+ #define LLRBTREE(llrbtree) DATA_PTR(llrbtree)
47
+ #define TREE(llrbtree) ((llrbtree_t*)LLRBTREE(llrbtree))->tree
48
+ #define IFNONE(llrbtree) ((llrbtree_t*)LLRBTREE(llrbtree))->ifnone
49
+ #define CMP_PROC(llrbtree) ((llrbtree_t*)LLRBTREE(llrbtree))->cmp_proc
50
+ #define ITER_LEV(llrbtree) ((llrbtree_t*)LLRBTREE(llrbtree))->iter_lev
51
+
52
+ #define TO_KEY(arg) ((const void*)arg)
53
+ #define TO_VAL(arg) ((void*)arg)
54
+ #define GET_KEY(node) ((VALUE)node->key)
55
+ #define GET_VAL(node) ((VALUE)node->data)
56
+ #define ASSOC(node) rb_assoc_new(GET_KEY(node), GET_VAL(node))
57
+
58
+ /*********************************************************************/
59
+
60
+ static void
61
+ llrbtree_free(llrbtree_t* llrbtree)
62
+ {
63
+ tree_free(llrbtree->tree);
64
+ xfree(llrbtree->tree);
65
+ xfree(llrbtree);
66
+ }
67
+
68
+ static void
69
+ llrbtree_mark(llrbtree_t* llrbtree)
70
+ {
71
+ if (llrbtree == NULL) return;
72
+
73
+ if (llrbtree->tree != NULL) {
74
+ tree_t* tree = llrbtree->tree;
75
+ node_t* node;
76
+ for (node = tree_first(tree);
77
+ node != NULL;
78
+ node = tree_next(tree, node)) {
79
+
80
+ rb_gc_mark(GET_KEY(node));
81
+ rb_gc_mark(GET_VAL(node));
82
+ }
83
+ }
84
+ rb_gc_mark(llrbtree->ifnone);
85
+ rb_gc_mark(llrbtree->cmp_proc);
86
+ }
87
+
88
+ static node_t*
89
+ llrbtree_alloc_node(void* context)
90
+ {
91
+ return ALLOC(node_t);
92
+ }
93
+
94
+ static void
95
+ llrbtree_free_node(node_t* node, void* context)
96
+ {
97
+ xfree(node);
98
+ }
99
+
100
+ static void
101
+ llrbtree_check_argument_count(const int argc, const int min, const int max)
102
+ {
103
+ if (argc < min || argc > max) {
104
+ static const char* const message = "wrong number of arguments";
105
+ if (min == max) {
106
+ rb_raise(rb_eArgError, "%s (%d for %d)", message, argc, min);
107
+ } else if (max == INT_MAX) {
108
+ rb_raise(rb_eArgError, "%s (%d for %d+)", message, argc, -min - 1);
109
+ } else {
110
+ rb_raise(rb_eArgError, "%s (%d for %d..%d)", message, argc, min, max);
111
+ }
112
+ }
113
+ }
114
+
115
+ static void
116
+ llrbtree_check_proc_arity(VALUE proc, const int expected)
117
+ {
118
+ if (rb_proc_lambda_p(proc)) {
119
+ const int arity = rb_proc_arity(proc);
120
+ const int min = arity < 0 ? -arity - 1 : arity;
121
+ const int max = arity < 0 ? INT_MAX : arity;
122
+ if (expected < min || expected > max) {
123
+ rb_raise(rb_eTypeError, "proc takes %d arguments", expected);
124
+ }
125
+ }
126
+ }
127
+
128
+ static int
129
+ llrbtree_cmp(const void* key1, const void* key2, void* context)
130
+ {
131
+ VALUE result;
132
+ if (TYPE(key1) == T_STRING && TYPE(key2) == T_STRING)
133
+ return rb_str_cmp((VALUE)key1, (VALUE)key2);
134
+ result = rb_funcall2((VALUE)key1, id_cmp, 1, (VALUE*)&key2);
135
+ return rb_cmpint(result, (VALUE)key1, (VALUE)key2);
136
+ }
137
+
138
+ static VALUE
139
+ llrbtree_user_cmp_ensure(llrbtree_t* llrbtree)
140
+ {
141
+ llrbtree->iter_lev--;
142
+ return Qnil;
143
+ }
144
+
145
+ static VALUE
146
+ llrbtree_user_cmp_body(VALUE* args)
147
+ {
148
+ llrbtree_t* llrbtree = (llrbtree_t*)args[2];
149
+ llrbtree->iter_lev++;
150
+ return rb_funcall2(llrbtree->cmp_proc, id_call, 2, args);
151
+ }
152
+
153
+ static int
154
+ llrbtree_user_cmp(const void* key1, const void* key2, void* context)
155
+ {
156
+ llrbtree_t* llrbtree = (llrbtree_t*)context;
157
+ VALUE args[3];
158
+ VALUE result;
159
+
160
+ args[0] = (VALUE)key1;
161
+ args[1] = (VALUE)key2;
162
+ args[2] = (VALUE)llrbtree;
163
+ result = rb_ensure(llrbtree_user_cmp_body, (VALUE)&args,
164
+ llrbtree_user_cmp_ensure, (VALUE)llrbtree);
165
+ return rb_cmpint(result, (VALUE)key1, (VALUE)key2);
166
+ }
167
+
168
+ static void
169
+ llrbtree_modify(VALUE self)
170
+ {
171
+ if (ITER_LEV(self) > 0)
172
+ rb_raise(rb_eTypeError, "can't modify llrbtree during iteration");
173
+ rb_check_frozen(self);
174
+ if (!OBJ_TAINTED(self) && rb_safe_level() >= 4)
175
+ rb_raise(rb_eSecurityError, "Insecure: can't modify llrbtree");
176
+ }
177
+
178
+ static VALUE
179
+ llrbtree_alloc(VALUE klass)
180
+ {
181
+ tree_t* tree;
182
+ VALUE llrbtree = Data_Wrap_Struct(klass, llrbtree_mark, llrbtree_free, NULL);
183
+ LLRBTREE(llrbtree) = ALLOC(llrbtree_t);
184
+ MEMZERO(LLRBTREE(llrbtree), llrbtree_t, 1);
185
+
186
+ tree = ALLOC(tree_t);
187
+ tree_init(tree, llrbtree_cmp, llrbtree_alloc_node, llrbtree_free_node, LLRBTREE(llrbtree));
188
+
189
+ TREE(llrbtree) = tree;
190
+ IFNONE(llrbtree) = Qnil;
191
+ CMP_PROC(llrbtree) = Qnil;
192
+ return llrbtree;
193
+ }
194
+
195
+ VALUE llrbtree_aset(VALUE, VALUE, VALUE);
196
+ VALUE llrbtree_has_key(VALUE, VALUE);
197
+ VALUE llrbtree_update(VALUE, VALUE);
198
+ VALUE llrbtree_to_a(VALUE);
199
+
200
+ /*********************************************************************/
201
+
202
+ static int
203
+ hash_to_llrbtree_i(VALUE key, VALUE value, VALUE llrbtree)
204
+ {
205
+ if (key != Qundef)
206
+ llrbtree_aset(llrbtree, key, value);
207
+ return ST_CONTINUE;
208
+ }
209
+
210
+ /*
211
+ *
212
+ */
213
+ VALUE
214
+ llrbtree_s_create(int argc, VALUE* argv, VALUE klass)
215
+ {
216
+ long i;
217
+ VALUE llrbtree;
218
+
219
+ if (argc == 1) {
220
+ VALUE temp;
221
+
222
+ if (rb_obj_is_kind_of(argv[0], klass)) {
223
+ llrbtree = llrbtree_alloc(klass);
224
+ llrbtree_update(llrbtree, argv[0]);
225
+ return llrbtree;
226
+ }
227
+
228
+ temp = rb_check_convert_type(argv[0], T_HASH, "Hash", "to_hash");
229
+ if (!NIL_P(temp)) {
230
+ llrbtree = llrbtree_alloc(klass);
231
+ rb_hash_foreach(temp, hash_to_llrbtree_i, llrbtree);
232
+ return llrbtree;
233
+ }
234
+
235
+ temp = rb_check_array_type(argv[0]);
236
+ if (!NIL_P(temp)) {
237
+ llrbtree = llrbtree_alloc(klass);
238
+ for (i = 0; i < RARRAY_LEN(temp); i++) {
239
+ VALUE v = rb_check_array_type(RARRAY_AREF(temp, i));
240
+ if (NIL_P(v)) {
241
+ rb_warn("wrong element type %s at %ld (expected Array)",
242
+ rb_obj_classname(RARRAY_AREF(temp, i)), i);
243
+ continue;
244
+ }
245
+ switch(RARRAY_LEN(v)) {
246
+ case 1:
247
+ llrbtree_aset(llrbtree, RARRAY_AREF(v, 0), Qnil);
248
+ break;
249
+ case 2:
250
+ llrbtree_aset(llrbtree, RARRAY_AREF(v, 0), RARRAY_AREF(v, 1));
251
+ break;
252
+ default:
253
+ rb_warn("invalid number of elements (%ld for 1..2)",
254
+ RARRAY_LEN(v));
255
+ }
256
+ }
257
+ return llrbtree;
258
+ }
259
+ }
260
+
261
+ if (argc % 2 != 0)
262
+ rb_raise(rb_eArgError, "odd number of arguments for %s", rb_class2name(klass));
263
+
264
+ llrbtree = llrbtree_alloc(klass);
265
+ for (i = 0; i < argc; i += 2)
266
+ llrbtree_aset(llrbtree, argv[i], argv[i + 1]);
267
+ return llrbtree;
268
+ }
269
+
270
+ /*
271
+ *
272
+ */
273
+ VALUE
274
+ llrbtree_initialize(int argc, VALUE* argv, VALUE self)
275
+ {
276
+ llrbtree_modify(self);
277
+
278
+ if (rb_block_given_p()) {
279
+ VALUE proc;
280
+ llrbtree_check_argument_count(argc, 0, 0);
281
+ proc = rb_block_proc();
282
+ llrbtree_check_proc_arity(proc, 2);
283
+ IFNONE(self) = proc;
284
+ FL_SET(self, LLRBTREE_PROC_DEFAULT);
285
+ } else {
286
+ llrbtree_check_argument_count(argc, 0, 1);
287
+ if (argc == 1) {
288
+ IFNONE(self) = argv[0];
289
+ }
290
+ }
291
+ return self;
292
+ }
293
+
294
+ /*********************************************************************/
295
+
296
+ typedef enum {
297
+ NoNodeInserted,
298
+ KeyAllocationFailed,
299
+ InsertionSucceeded
300
+ } insert_result_t;
301
+
302
+ typedef struct {
303
+ tree_t* tree;
304
+ node_t* node;
305
+ insert_result_t result;
306
+ } llrbtree_insert_arg_t;
307
+
308
+ static VALUE
309
+ insert_node_body(llrbtree_insert_arg_t* arg)
310
+ {
311
+ tree_t* tree = arg->tree;
312
+ node_t* node = arg->node;
313
+
314
+ if (tree_insert(tree, node, node->key)) {
315
+ if (TYPE(GET_KEY(node)) == T_STRING) {
316
+ arg->result = KeyAllocationFailed;
317
+ node->key = TO_KEY(rb_str_new4(GET_KEY(node)));
318
+ }
319
+ } else {
320
+ tree->free_node(node, tree->context);
321
+ }
322
+ arg->result = InsertionSucceeded;
323
+ return Qnil;
324
+ }
325
+
326
+ static VALUE
327
+ insert_node_ensure(llrbtree_insert_arg_t* arg)
328
+ {
329
+ tree_t* tree = arg->tree;
330
+ node_t* node = arg->node;
331
+
332
+ switch (arg->result) {
333
+ case InsertionSucceeded:
334
+ break;
335
+ case NoNodeInserted:
336
+ tree->free_node(node, tree->context);
337
+ break;
338
+ case KeyAllocationFailed:
339
+ tree_delete(tree, node->key);
340
+ break;
341
+ }
342
+ return Qnil;
343
+ }
344
+
345
+ static void
346
+ llrbtree_insert(VALUE self, VALUE key, VALUE value)
347
+ {
348
+ llrbtree_insert_arg_t arg;
349
+ tree_t* tree = TREE(self);
350
+ node_t* node = tree->alloc_node(tree->context);
351
+
352
+ node_init(node, TO_VAL(value));
353
+ node->key = TO_KEY(key);
354
+
355
+ arg.tree = tree;
356
+ arg.node = node;
357
+ arg.result = NoNodeInserted;
358
+
359
+ rb_ensure(insert_node_body, (VALUE)&arg,
360
+ insert_node_ensure, (VALUE)&arg);
361
+ }
362
+
363
+ /*********************************************************************/
364
+
365
+ /*
366
+ *
367
+ */
368
+ VALUE
369
+ llrbtree_aset(VALUE self, VALUE key, VALUE value)
370
+ {
371
+ llrbtree_modify(self);
372
+
373
+ if (tree_isfull(TREE(self))) {
374
+ node_t* node = tree_lookup(TREE(self), TO_KEY(key));
375
+ if (node == NULL)
376
+ rb_raise(rb_eIndexError, "llrbtree full");
377
+ else
378
+ node->data = TO_VAL(value);
379
+ return value;
380
+ }
381
+ llrbtree_insert(self, key, value);
382
+ return value;
383
+ }
384
+
385
+ /*
386
+ *
387
+ */
388
+ VALUE
389
+ llrbtree_aref(VALUE self, VALUE key)
390
+ {
391
+ node_t* node = tree_lookup(TREE(self), TO_KEY(key));
392
+ if (node == NULL)
393
+ return rb_funcall2(self, id_default, 1, &key);
394
+ else
395
+ return GET_VAL(node);
396
+ }
397
+
398
+ /*
399
+ *
400
+ */
401
+ VALUE
402
+ llrbtree_fetch(int argc, VALUE* argv, VALUE self)
403
+ {
404
+ node_t* node;
405
+
406
+ llrbtree_check_argument_count(argc, 1, 2);
407
+ if (argc == 2 && rb_block_given_p()) {
408
+ rb_warn("block supersedes default value argument");
409
+ }
410
+
411
+ node = tree_lookup(TREE(self), TO_KEY(argv[0]));
412
+ if (node != NULL) {
413
+ return GET_VAL(node);
414
+ }
415
+
416
+ if (rb_block_given_p()) {
417
+ return rb_yield(argv[0]);
418
+ }
419
+ if (argc == 1) {
420
+ rb_raise(rb_eIndexError, "key not found");
421
+ }
422
+ return argv[1];
423
+ }
424
+
425
+ /*
426
+ *
427
+ */
428
+ VALUE
429
+ llrbtree_size(VALUE self)
430
+ {
431
+ return ULONG2NUM(TREE(self)->node_count);
432
+ }
433
+
434
+ /*
435
+ *
436
+ */
437
+ VALUE
438
+ llrbtree_empty_p(VALUE self)
439
+ {
440
+ return tree_isempty(TREE(self)) ? Qtrue : Qfalse;
441
+ }
442
+
443
+ /*
444
+ *
445
+ */
446
+ VALUE
447
+ llrbtree_default(int argc, VALUE* argv, VALUE self)
448
+ {
449
+ llrbtree_check_argument_count(argc, 0, 1);
450
+ if (FL_TEST(self, LLRBTREE_PROC_DEFAULT)) {
451
+ if (argc == 0) {
452
+ return Qnil;
453
+ }
454
+ return rb_funcall(IFNONE(self), id_call, 2, self, argv[0]);
455
+ }
456
+ return IFNONE(self);
457
+ }
458
+
459
+ /*
460
+ *
461
+ */
462
+ VALUE
463
+ llrbtree_set_default(VALUE self, VALUE ifnone)
464
+ {
465
+ llrbtree_modify(self);
466
+ IFNONE(self) = ifnone;
467
+ FL_UNSET(self, LLRBTREE_PROC_DEFAULT);
468
+ return ifnone;
469
+ }
470
+
471
+ /*
472
+ *
473
+ */
474
+ VALUE
475
+ llrbtree_default_proc(VALUE self)
476
+ {
477
+ if (FL_TEST(self, LLRBTREE_PROC_DEFAULT))
478
+ return IFNONE(self);
479
+ return Qnil;
480
+ }
481
+
482
+ /*
483
+ *
484
+ */
485
+ VALUE
486
+ llrbtree_set_default_proc(VALUE self, VALUE proc)
487
+ {
488
+ VALUE temp;
489
+
490
+ llrbtree_modify(self);
491
+ if (NIL_P(proc)) {
492
+ IFNONE(self) = Qnil;
493
+ FL_UNSET(self, LLRBTREE_PROC_DEFAULT);
494
+ return Qnil;
495
+ }
496
+
497
+ temp = rb_check_convert_type(proc, T_DATA, "Proc", "to_proc");
498
+ if (NIL_P(temp)) {
499
+ rb_raise(rb_eTypeError,
500
+ "wrong default_proc type %s (expected Proc)",
501
+ rb_obj_classname(proc));
502
+ }
503
+ llrbtree_check_proc_arity(temp, 2);
504
+ IFNONE(self) = temp;
505
+ FL_SET(self, LLRBTREE_PROC_DEFAULT);
506
+ return proc;
507
+ }
508
+
509
+ static VALUE
510
+ llrbtree_recursive_equal(VALUE self, VALUE other, int recursive)
511
+ {
512
+ tree_t* tree1 = TREE(self);
513
+ tree_t* tree2 = TREE(other);
514
+ node_t* node1;
515
+ node_t* node2;
516
+
517
+ if (recursive)
518
+ return Qtrue;
519
+ for (node1 = tree_first(tree1), node2 = tree_first(tree2);
520
+ node1 != NULL && node2 != NULL;
521
+ node1 = tree_next(tree1, node1), node2 = tree_next(tree2, node2)) {
522
+
523
+ if (!rb_equal(GET_KEY(node1), GET_KEY(node2)) ||
524
+ !rb_equal(GET_VAL(node1), GET_VAL(node2))) {
525
+
526
+ return Qfalse;
527
+ }
528
+ }
529
+ return Qtrue;
530
+ }
531
+
532
+ /*
533
+ *
534
+ */
535
+ VALUE
536
+ llrbtree_equal(VALUE self, VALUE other)
537
+ {
538
+ if (self == other)
539
+ return Qtrue;
540
+ if (!rb_obj_is_kind_of(other, LLRBTree))
541
+ return Qfalse;
542
+ if (TREE(self)->node_count != TREE(other)->node_count ||
543
+ TREE(self)->compare != TREE(other)->compare ||
544
+ CMP_PROC(self) != CMP_PROC(other)) {
545
+
546
+ return Qfalse;
547
+ }
548
+ return rb_exec_recursive_paired(llrbtree_recursive_equal, self, other, other);
549
+ }
550
+
551
+ /*********************************************************************/
552
+
553
+ typedef enum {
554
+ EACH_NEXT, EACH_STOP
555
+ } each_return_t;
556
+
557
+ typedef each_return_t (*each_callback_func)(node_t*, void*);
558
+
559
+ typedef struct {
560
+ VALUE self;
561
+ each_callback_func func;
562
+ void* arg;
563
+ int reverse;
564
+ } llrbtree_each_arg_t;
565
+
566
+ static VALUE
567
+ llrbtree_each_ensure(VALUE self)
568
+ {
569
+ ITER_LEV(self)--;
570
+ return Qnil;
571
+ }
572
+
573
+ static VALUE
574
+ llrbtree_each_body(llrbtree_each_arg_t* arg)
575
+ {
576
+ VALUE self = arg->self;
577
+ tree_t* tree = TREE(self);
578
+ node_t* node;
579
+ node_t* first_node;
580
+ node_t* (*next_func)(tree_t*, node_t*);
581
+
582
+ if (arg->reverse) {
583
+ first_node = tree_last(tree);
584
+ next_func = tree_prev;
585
+ } else {
586
+ first_node = tree_first(tree);
587
+ next_func = tree_next;
588
+ }
589
+
590
+ ITER_LEV(self)++;
591
+ for (node = first_node;
592
+ node != NULL;
593
+ node = next_func(tree, node)) {
594
+
595
+ if (arg->func(node, arg->arg) == EACH_STOP)
596
+ break;
597
+ }
598
+ return self;
599
+ }
600
+
601
+ static VALUE
602
+ llrbtree_for_each(VALUE self, each_callback_func func, void* arg)
603
+ {
604
+ llrbtree_each_arg_t each_arg;
605
+ each_arg.self = self;
606
+ each_arg.func = func;
607
+ each_arg.arg = arg;
608
+ each_arg.reverse = 0;
609
+ return rb_ensure(llrbtree_each_body, (VALUE)&each_arg,
610
+ llrbtree_each_ensure, self);
611
+ }
612
+
613
+ static VALUE
614
+ llrbtree_reverse_for_each(VALUE self, each_callback_func func, void* arg)
615
+ {
616
+ llrbtree_each_arg_t each_arg;
617
+ each_arg.self = self;
618
+ each_arg.func = func;
619
+ each_arg.arg = arg;
620
+ each_arg.reverse = 1;
621
+ return rb_ensure(llrbtree_each_body, (VALUE)&each_arg,
622
+ llrbtree_each_ensure, self);
623
+ }
624
+
625
+ /*********************************************************************/
626
+
627
+ static each_return_t
628
+ each_pair_i(node_t* node, void* arg)
629
+ {
630
+ rb_yield(ASSOC(node));
631
+ return EACH_NEXT;
632
+ }
633
+
634
+ /*
635
+ * call-seq:
636
+ * llrbtree.each {|key, value| block} => llrbtree
637
+ * llrbtree.each_pair {|key, value| block} => llrbtree
638
+ * llrbtree.each => enumerator
639
+ * llrbtree.each_pair => enumerator
640
+ *
641
+ * Calls block once for each key in order, passing the key-value pair
642
+ * as parameters.
643
+ *
644
+ * Returns an enumerator if no block is given.
645
+ */
646
+ VALUE
647
+ llrbtree_each_pair(VALUE self)
648
+ {
649
+ RETURN_SIZED_ENUMERATOR(self, 0, NULL, llrbtree_size);
650
+ return llrbtree_for_each(self, each_pair_i, NULL);
651
+ }
652
+
653
+ static each_return_t
654
+ each_key_i(node_t* node, void* arg)
655
+ {
656
+ rb_yield(GET_KEY(node));
657
+ return EACH_NEXT;
658
+ }
659
+
660
+ /*
661
+ * call-seq:
662
+ * llrbtree.each_key {|key| block} => llrbtree
663
+ * llrbtree.each_key => enumerator
664
+ *
665
+ * Calls block once for each key in order, passing the key as a
666
+ * parameter.
667
+ *
668
+ * Returns an enumerator if no block is given.
669
+ */
670
+ VALUE
671
+ llrbtree_each_key(VALUE self)
672
+ {
673
+ RETURN_SIZED_ENUMERATOR(self, 0, NULL, llrbtree_size);
674
+ return llrbtree_for_each(self, each_key_i, NULL);
675
+ }
676
+
677
+ static each_return_t
678
+ each_value_i(node_t* node, void* arg)
679
+ {
680
+ rb_yield(GET_VAL(node));
681
+ return EACH_NEXT;
682
+ }
683
+
684
+ /*
685
+ * call-seq:
686
+ * llrbtree.each_value {|value| block} => llrbtree
687
+ * llrbtree.each_value => enumerator
688
+ *
689
+ * Calls block once for each key in order, passing the value as a
690
+ * parameter.
691
+ *
692
+ * Returns an enumerator if no block is given.
693
+ */
694
+ VALUE
695
+ llrbtree_each_value(VALUE self)
696
+ {
697
+ RETURN_SIZED_ENUMERATOR(self, 0, NULL, llrbtree_size);
698
+ return llrbtree_for_each(self, each_value_i, NULL);
699
+ }
700
+
701
+ /*
702
+ * call-seq:
703
+ * llrbtree.reverse_each {|key, value| block} => llrbtree
704
+ * llrbtree.reverse_each => enumerator
705
+ *
706
+ * Calls block once for each key in reverse order, passing the
707
+ * key-value pair as parameters.
708
+ *
709
+ * Returns an enumerator if no block is given.
710
+ */
711
+ VALUE
712
+ llrbtree_reverse_each(VALUE self)
713
+ {
714
+ RETURN_SIZED_ENUMERATOR(self, 0, NULL, llrbtree_size);
715
+ return llrbtree_reverse_for_each(self, each_pair_i, NULL);
716
+ }
717
+
718
+ static each_return_t
719
+ aset_i(node_t* node, void* self)
720
+ {
721
+ llrbtree_aset((VALUE)self, GET_KEY(node), GET_VAL(node));
722
+ return EACH_NEXT;
723
+ }
724
+
725
+ static void
726
+ copy_tree(VALUE src, VALUE dest, compare_t cmp_func, VALUE cmp_proc)
727
+ {
728
+ VALUE temp = llrbtree_alloc(CLASS_OF(dest));
729
+ rb_obj_hide(temp);
730
+ TREE(temp)->compare = cmp_func;
731
+ CMP_PROC(temp) = cmp_proc;
732
+
733
+ llrbtree_for_each(src, aset_i, (void*)temp);
734
+ {
735
+ tree_t* t = TREE(temp);
736
+ TREE(temp) = TREE(dest);
737
+ TREE(dest) = t;
738
+ }
739
+ llrbtree_free(LLRBTREE(temp));
740
+ LLRBTREE(temp) = NULL;
741
+ rb_gc_force_recycle(temp);
742
+
743
+ TREE(dest)->context = LLRBTREE(dest);
744
+ CMP_PROC(dest) = cmp_proc;
745
+ }
746
+
747
+ /*
748
+ *
749
+ */
750
+ VALUE
751
+ llrbtree_initialize_copy(VALUE self, VALUE other)
752
+ {
753
+ llrbtree_modify(self);
754
+
755
+ if (self == other)
756
+ return self;
757
+ if (!rb_obj_is_kind_of(other, CLASS_OF(self))) {
758
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)",
759
+ rb_obj_classname(other),
760
+ rb_obj_classname(self));
761
+ }
762
+
763
+ copy_tree(other, self, TREE(other)->compare, CMP_PROC(other));
764
+
765
+ IFNONE(self) = IFNONE(other);
766
+ if (FL_TEST(other, LLRBTREE_PROC_DEFAULT))
767
+ FL_SET(self, LLRBTREE_PROC_DEFAULT);
768
+ else
769
+ FL_UNSET(self, LLRBTREE_PROC_DEFAULT);
770
+ return self;
771
+ }
772
+
773
+ /*
774
+ *
775
+ */
776
+ VALUE
777
+ llrbtree_values_at(int argc, VALUE* argv, VALUE self)
778
+ {
779
+ long i;
780
+ VALUE ary = rb_ary_new2(argc);
781
+
782
+ for (i = 0; i < argc; i++)
783
+ rb_ary_push(ary, llrbtree_aref(self, argv[i]));
784
+ return ary;
785
+ }
786
+
787
+ static each_return_t
788
+ key_i(node_t* node, void* args_)
789
+ {
790
+ VALUE* args = (VALUE*)args_;
791
+ if (rb_equal(GET_VAL(node), args[1])) {
792
+ args[0] = GET_KEY(node);
793
+ return EACH_STOP;
794
+ }
795
+ return EACH_NEXT;
796
+ }
797
+
798
+ /*
799
+ *
800
+ */
801
+ VALUE
802
+ llrbtree_key(VALUE self, VALUE value)
803
+ {
804
+ VALUE args[2];
805
+ args[0] = Qnil;
806
+ args[1] = value;
807
+ llrbtree_for_each(self, key_i, &args);
808
+ return args[0];
809
+ }
810
+
811
+ /*
812
+ *
813
+ */
814
+ VALUE
815
+ llrbtree_index(VALUE self, VALUE value)
816
+ {
817
+ const char* classname = rb_class2name(LLRBTree);
818
+ rb_warn("%s#index is deprecated; use %s#key", classname, classname);
819
+ return llrbtree_key(self, value);
820
+ }
821
+
822
+ /*
823
+ *
824
+ */
825
+ VALUE
826
+ llrbtree_clear(VALUE self)
827
+ {
828
+ llrbtree_modify(self);
829
+ tree_free(TREE(self));
830
+ return self;
831
+ }
832
+
833
+ /*
834
+ *
835
+ */
836
+ VALUE
837
+ llrbtree_delete(VALUE self, VALUE key)
838
+ {
839
+ tree_t* tree = TREE(self);
840
+ node_t* node;
841
+ VALUE value;
842
+
843
+ llrbtree_modify(self);
844
+ node = tree_lookup(tree, TO_KEY(key));
845
+ if (node == NULL)
846
+ return rb_block_given_p() ? rb_yield(key) : Qnil;
847
+ value = GET_VAL(node);
848
+ tree_delete(tree, TO_KEY(key));
849
+ return value;
850
+ }
851
+
852
+ /*********************************************************************/
853
+
854
+ typedef struct node_list_t_ {
855
+ struct node_list_t_* prev;
856
+ node_t* node;
857
+ } node_list_t;
858
+
859
+ typedef struct {
860
+ VALUE self;
861
+ node_list_t* list;
862
+ int raised;
863
+ int if_true;
864
+ } llrbtree_remove_if_arg_t;
865
+
866
+ static VALUE
867
+ llrbtree_remove_if_ensure(llrbtree_remove_if_arg_t* arg)
868
+ {
869
+ tree_t* tree = TREE(arg->self);
870
+ node_list_t* list = arg->list;
871
+
872
+ if (--ITER_LEV(arg->self) == 0) {
873
+ while (list != NULL) {
874
+ node_list_t* l = list;
875
+ if (!arg->raised)
876
+ tree_delete(tree, l->node->key);
877
+ list = l->prev;
878
+ xfree(l);
879
+ }
880
+ }
881
+ return Qnil;
882
+ }
883
+
884
+ static VALUE
885
+ llrbtree_remove_if_body(llrbtree_remove_if_arg_t* arg)
886
+ {
887
+ VALUE self = arg->self;
888
+ tree_t* tree = TREE(self);
889
+ node_t* node;
890
+
891
+ arg->raised = 1;
892
+ ITER_LEV(self)++;
893
+ for (node = tree_first(tree);
894
+ node != NULL;
895
+ node = tree_next(tree, node)) {
896
+
897
+ VALUE key = GET_KEY(node);
898
+ VALUE value = GET_VAL(node);
899
+ if (RTEST(rb_yield_values(2, key, value)) == arg->if_true) {
900
+ node_list_t* l = ALLOC(node_list_t);
901
+ l->node = node;
902
+ l->prev = arg->list;
903
+ arg->list = l;
904
+ }
905
+ }
906
+ arg->raised = 0;
907
+ return self;
908
+ }
909
+
910
+ static VALUE
911
+ llrbtree_remove_if(VALUE self, const int if_true)
912
+ {
913
+ llrbtree_remove_if_arg_t arg;
914
+
915
+ RETURN_SIZED_ENUMERATOR(self, 0, NULL, llrbtree_size);
916
+ llrbtree_modify(self);
917
+ arg.self = self;
918
+ arg.list = NULL;
919
+ arg.if_true = if_true;
920
+ return rb_ensure(llrbtree_remove_if_body, (VALUE)&arg,
921
+ llrbtree_remove_if_ensure, (VALUE)&arg);
922
+ }
923
+
924
+ /*********************************************************************/
925
+
926
+ /*
927
+ *
928
+ */
929
+ VALUE
930
+ llrbtree_delete_if(VALUE self)
931
+ {
932
+ return llrbtree_remove_if(self, 1);
933
+ }
934
+
935
+ /*
936
+ *
937
+ */
938
+ VALUE
939
+ llrbtree_keep_if(VALUE self)
940
+ {
941
+ return llrbtree_remove_if(self, 0);
942
+ }
943
+
944
+ /*
945
+ *
946
+ */
947
+ VALUE
948
+ llrbtree_reject_bang(VALUE self)
949
+ {
950
+ node_count_t count;
951
+
952
+ RETURN_SIZED_ENUMERATOR(self, 0, NULL, llrbtree_size);
953
+ count = TREE(self)->node_count;
954
+ llrbtree_delete_if(self);
955
+ if (count == TREE(self)->node_count)
956
+ return Qnil;
957
+ return self;
958
+ }
959
+
960
+ /*
961
+ *
962
+ */
963
+ VALUE
964
+ llrbtree_select_bang(VALUE self)
965
+ {
966
+ node_count_t count;
967
+
968
+ RETURN_SIZED_ENUMERATOR(self, 0, NULL, llrbtree_size);
969
+ count = TREE(self)->node_count;
970
+ llrbtree_keep_if(self);
971
+ if (count == TREE(self)->node_count)
972
+ return Qnil;
973
+ return self;
974
+
975
+ }
976
+
977
+ /*********************************************************************/
978
+
979
+ typedef struct {
980
+ VALUE result;
981
+ int if_true;
982
+ } llrbtree_select_if_arg_t;
983
+
984
+ static each_return_t
985
+ select_i(node_t* node, void* arg_)
986
+ {
987
+ VALUE key = GET_KEY(node);
988
+ VALUE value = GET_VAL(node);
989
+ llrbtree_select_if_arg_t* arg = arg_;
990
+
991
+ if (RTEST(rb_yield_values(2, key, value)) == arg->if_true) {
992
+ llrbtree_aset(arg->result, key, value);
993
+ }
994
+ return EACH_NEXT;
995
+ }
996
+
997
+ static VALUE
998
+ llrbtree_select_if(VALUE self, const int if_true)
999
+ {
1000
+ llrbtree_select_if_arg_t arg;
1001
+
1002
+ RETURN_SIZED_ENUMERATOR(self, 0, NULL, llrbtree_size);
1003
+ arg.result = llrbtree_alloc(CLASS_OF(self));
1004
+ arg.if_true = if_true;
1005
+ llrbtree_for_each(self, select_i, &arg);
1006
+ return arg.result;
1007
+ }
1008
+
1009
+ /*********************************************************************/
1010
+
1011
+ /*
1012
+ *
1013
+ */
1014
+ VALUE
1015
+ llrbtree_reject(VALUE self)
1016
+ {
1017
+ return llrbtree_select_if(self, 0);
1018
+ }
1019
+
1020
+ /*
1021
+ *
1022
+ */
1023
+ VALUE
1024
+ llrbtree_select(VALUE self)
1025
+ {
1026
+ return llrbtree_select_if(self, 1);
1027
+ }
1028
+
1029
+ static VALUE
1030
+ llrbtree_shift_pop(VALUE self, const int shift)
1031
+ {
1032
+ tree_t* tree = TREE(self);
1033
+ node_t* node;
1034
+ VALUE assoc;
1035
+
1036
+ llrbtree_modify(self);
1037
+
1038
+ if (tree_isempty(tree))
1039
+ return rb_funcall(self, id_default, 1, Qnil);
1040
+
1041
+ if (shift)
1042
+ node = tree_last(tree);
1043
+ else
1044
+ node = tree_first(tree);
1045
+ assoc = ASSOC(node);
1046
+ tree_delete(tree, node->key);
1047
+ return assoc;
1048
+ }
1049
+
1050
+ /*
1051
+ * call-seq:
1052
+ * llrbtree.shift => array or object or nil
1053
+ *
1054
+ * Removes the first (that is, the smallest) key-value pair and
1055
+ * returns it.
1056
+ */
1057
+ VALUE
1058
+ llrbtree_shift(VALUE self)
1059
+ {
1060
+ return llrbtree_shift_pop(self, 0);
1061
+ }
1062
+
1063
+ /*
1064
+ * call-seq:
1065
+ * llrbtree.pop => array or object or nil
1066
+ *
1067
+ * Removes the last (that is, the greatest) key-value pair and returns
1068
+ * it.
1069
+ */
1070
+ VALUE
1071
+ llrbtree_pop(VALUE self)
1072
+ {
1073
+ return llrbtree_shift_pop(self, 1);
1074
+ }
1075
+
1076
+ static each_return_t
1077
+ invert_i(node_t* node, void* llrbtree)
1078
+ {
1079
+ llrbtree_aset((VALUE)llrbtree, GET_VAL(node), GET_KEY(node));
1080
+ return EACH_NEXT;
1081
+ }
1082
+
1083
+ /*
1084
+ *
1085
+ */
1086
+ VALUE
1087
+ llrbtree_invert(VALUE self)
1088
+ {
1089
+ VALUE llrbtree = llrbtree_alloc(CLASS_OF(self));
1090
+ llrbtree_for_each(self, invert_i, (void*)llrbtree);
1091
+ return llrbtree;
1092
+ }
1093
+
1094
+ static each_return_t
1095
+ update_block_i(node_t* node, void* self_)
1096
+ {
1097
+ VALUE self = (VALUE)self_;
1098
+ VALUE key = GET_KEY(node);
1099
+ VALUE value = GET_VAL(node);
1100
+
1101
+ if (llrbtree_has_key(self, key))
1102
+ value = rb_yield_values(3, key, llrbtree_aref(self, key), value);
1103
+ llrbtree_aset(self, key, value);
1104
+ return EACH_NEXT;
1105
+ }
1106
+
1107
+ /*
1108
+ *
1109
+ */
1110
+ VALUE
1111
+ llrbtree_update(VALUE self, VALUE other)
1112
+ {
1113
+ llrbtree_modify(self);
1114
+
1115
+ if (self == other)
1116
+ return self;
1117
+ if (!rb_obj_is_kind_of(other, CLASS_OF(self))) {
1118
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)",
1119
+ rb_obj_classname(other),
1120
+ rb_obj_classname(self));
1121
+ }
1122
+
1123
+ if (rb_block_given_p())
1124
+ llrbtree_for_each(other, update_block_i, (void*)self);
1125
+ else
1126
+ llrbtree_for_each(other, aset_i, (void*)self);
1127
+ return self;
1128
+ }
1129
+
1130
+ /*
1131
+ *
1132
+ */
1133
+ VALUE
1134
+ llrbtree_merge(VALUE self, VALUE other)
1135
+ {
1136
+ return llrbtree_update(rb_obj_dup(self), other);
1137
+ }
1138
+
1139
+ static each_return_t
1140
+ to_flat_ary_i(node_t* node, void* ary)
1141
+ {
1142
+ rb_ary_push((VALUE)ary, GET_KEY(node));
1143
+ rb_ary_push((VALUE)ary, GET_VAL(node));
1144
+ return EACH_NEXT;
1145
+ }
1146
+
1147
+ /*
1148
+ *
1149
+ */
1150
+ VALUE
1151
+ llrbtree_flatten(int argc, VALUE* argv, VALUE self)
1152
+ {
1153
+ VALUE ary;
1154
+
1155
+ llrbtree_check_argument_count(argc, 0, 1);
1156
+ ary = rb_ary_new2(TREE(self)->node_count * 2);
1157
+ llrbtree_for_each(self, to_flat_ary_i, (void*)ary);
1158
+ if (argc == 1) {
1159
+ const int level = NUM2INT(argv[0]) - 1;
1160
+ if (level > 0) {
1161
+ argv[0] = INT2FIX(level);
1162
+ rb_funcall2(ary, id_flatten_bang, argc, argv);
1163
+ }
1164
+ }
1165
+ return ary;
1166
+ }
1167
+
1168
+ /*
1169
+ *
1170
+ */
1171
+ VALUE
1172
+ llrbtree_has_key(VALUE self, VALUE key)
1173
+ {
1174
+ return tree_lookup(TREE(self), TO_KEY(key)) == NULL ? Qfalse : Qtrue;
1175
+ }
1176
+
1177
+ static each_return_t
1178
+ has_value_i(node_t* node, void* args_)
1179
+ {
1180
+ VALUE* args = (VALUE*)args_;
1181
+ if (rb_equal(GET_VAL(node), args[1])) {
1182
+ args[0] = Qtrue;
1183
+ return EACH_STOP;
1184
+ }
1185
+ return EACH_NEXT;
1186
+ }
1187
+
1188
+ /*
1189
+ *
1190
+ */
1191
+ VALUE
1192
+ llrbtree_has_value(VALUE self, VALUE value)
1193
+ {
1194
+ VALUE args[2];
1195
+ args[0] = Qfalse;
1196
+ args[1] = value;
1197
+ llrbtree_for_each(self, has_value_i, &args);
1198
+ return args[0];
1199
+ }
1200
+
1201
+ static each_return_t
1202
+ keys_i(node_t* node, void* ary)
1203
+ {
1204
+ rb_ary_push((VALUE)ary, GET_KEY(node));
1205
+ return EACH_NEXT;
1206
+ }
1207
+
1208
+ /*
1209
+ *
1210
+ */
1211
+ VALUE
1212
+ llrbtree_keys(VALUE self)
1213
+ {
1214
+ VALUE ary = rb_ary_new2(TREE(self)->node_count);
1215
+ llrbtree_for_each(self, keys_i, (void*)ary);
1216
+ return ary;
1217
+ }
1218
+
1219
+ static each_return_t
1220
+ values_i(node_t* node, void* ary)
1221
+ {
1222
+ rb_ary_push((VALUE)ary, GET_VAL(node));
1223
+ return EACH_NEXT;
1224
+ }
1225
+
1226
+ /*
1227
+ *
1228
+ */
1229
+ VALUE
1230
+ llrbtree_values(VALUE self)
1231
+ {
1232
+ VALUE ary = rb_ary_new2(TREE(self)->node_count);
1233
+ llrbtree_for_each(self, values_i, (void*)ary);
1234
+ return ary;
1235
+ }
1236
+
1237
+ static each_return_t
1238
+ to_a_i(node_t* node, void* ary)
1239
+ {
1240
+ rb_ary_push((VALUE)ary, ASSOC(node));
1241
+ return EACH_NEXT;
1242
+ }
1243
+
1244
+ /*
1245
+ *
1246
+ */
1247
+ VALUE
1248
+ llrbtree_to_a(VALUE self)
1249
+ {
1250
+ VALUE ary = rb_ary_new2(TREE(self)->node_count);
1251
+ llrbtree_for_each(self, to_a_i, (void*)ary);
1252
+ OBJ_INFECT(ary, self);
1253
+ return ary;
1254
+ }
1255
+
1256
+ static each_return_t
1257
+ to_hash_i(node_t* node, void* hash)
1258
+ {
1259
+ rb_hash_aset((VALUE)hash, GET_KEY(node), GET_VAL(node));
1260
+ return EACH_NEXT;
1261
+ }
1262
+
1263
+ /*
1264
+ *
1265
+ */
1266
+ VALUE
1267
+ llrbtree_to_hash(VALUE self)
1268
+ {
1269
+ VALUE hash;
1270
+ hash = rb_hash_new();
1271
+ llrbtree_for_each(self, to_hash_i, (void*)hash);
1272
+ RHASH_SET_IFNONE(hash, IFNONE(self));
1273
+ if (FL_TEST(self, LLRBTREE_PROC_DEFAULT))
1274
+ FL_SET(hash, HASH_PROC_DEFAULT);
1275
+ OBJ_INFECT(hash, self);
1276
+ return hash;
1277
+ }
1278
+
1279
+ /*
1280
+ *
1281
+ */
1282
+ VALUE
1283
+ llrbtree_to_llrbtree(VALUE self)
1284
+ {
1285
+ return self;
1286
+ }
1287
+
1288
+ static VALUE
1289
+ llrbtree_begin_inspect(VALUE self)
1290
+ {
1291
+ VALUE result = rb_str_new2("#<");
1292
+ rb_str_cat2(result, rb_obj_classname(self));
1293
+ rb_str_cat2(result, ": ");
1294
+ return result;
1295
+ }
1296
+
1297
+ static each_return_t
1298
+ inspect_i(node_t* node, void* result_)
1299
+ {
1300
+ VALUE result = (VALUE)result_;
1301
+ VALUE str;
1302
+
1303
+ if (RSTRING_PTR(result)[0] == '-')
1304
+ RSTRING_PTR(result)[0] = '#';
1305
+ else
1306
+ rb_str_cat2(result, ", ");
1307
+
1308
+ str = rb_inspect(GET_KEY(node));
1309
+ rb_str_append(result, str);
1310
+ OBJ_INFECT(result, str);
1311
+
1312
+ rb_str_cat2(result, "=>");
1313
+
1314
+ str = rb_inspect(GET_VAL(node));
1315
+ rb_str_append(result, str);
1316
+ OBJ_INFECT(result, str);
1317
+
1318
+ return EACH_NEXT;
1319
+ }
1320
+
1321
+ static VALUE
1322
+ inspect_llrbtree(VALUE self, VALUE result)
1323
+ {
1324
+ VALUE str;
1325
+
1326
+ rb_str_cat2(result, "{");
1327
+ RSTRING_PTR(result)[0] = '-';
1328
+ llrbtree_for_each(self, inspect_i, (void*)result);
1329
+ RSTRING_PTR(result)[0] = '#';
1330
+ rb_str_cat2(result, "}");
1331
+
1332
+ str = rb_inspect(IFNONE(self));
1333
+ rb_str_cat2(result, ", default=");
1334
+ rb_str_append(result, str);
1335
+ OBJ_INFECT(result, str);
1336
+
1337
+ str = rb_inspect(CMP_PROC(self));
1338
+ rb_str_cat2(result, ", cmp_proc=");
1339
+ rb_str_append(result, str);
1340
+ OBJ_INFECT(result, str);
1341
+
1342
+ rb_str_cat2(result, ">");
1343
+ OBJ_INFECT(result, self);
1344
+ return result;
1345
+ }
1346
+
1347
+ static VALUE
1348
+ llrbtree_inspect_recursive(VALUE self, VALUE arg, int recursive)
1349
+ {
1350
+ VALUE str = llrbtree_begin_inspect(self);
1351
+ if (recursive)
1352
+ return rb_str_cat2(str, "...>");
1353
+ return inspect_llrbtree(self, str);
1354
+ }
1355
+
1356
+ /*
1357
+ *
1358
+ */
1359
+ VALUE
1360
+ llrbtree_inspect(VALUE self)
1361
+ {
1362
+ return rb_exec_recursive(llrbtree_inspect_recursive, self, Qnil);
1363
+ }
1364
+
1365
+ /*
1366
+ * call-seq:
1367
+ * llrbtree.lower_bound(key) => array or nil
1368
+ *
1369
+ * Retruns the key-value pair corresponding to the lowest key that is
1370
+ * equal to or greater than the given key (inside the lower
1371
+ * boundary). If there is no such key, returns nil.
1372
+ *
1373
+ * llrbtree = LLRBTree["az", 10, "ba", 20]
1374
+ * llrbtree.lower_bound("ba") # => ["ba", 20]
1375
+ *
1376
+ * # "ba" is the lowest key that is greater than "b"
1377
+ * llrbtree.lower_bound("b") # => ["ba", 20]
1378
+ *
1379
+ * # no key that is equal to or greater than "c"
1380
+ * llrbtree.lower_bound("c") # => nil
1381
+ */
1382
+ VALUE
1383
+ llrbtree_lower_bound(VALUE self, VALUE key)
1384
+ {
1385
+ node_t* node = tree_lower_bound(TREE(self), TO_KEY(key));
1386
+ if (node == NULL)
1387
+ return Qnil;
1388
+ return ASSOC(node);
1389
+ }
1390
+
1391
+ /*
1392
+ * call-seq:
1393
+ * llrbtree.upper_bound(key) => array or nil
1394
+ *
1395
+ * Retruns the key-value pair corresponding to the greatest key that
1396
+ * is equal to or lower than the given key (inside the upper
1397
+ * boundary). If there is no such key, returns nil.
1398
+ *
1399
+ * llrbtree = LLRBTree["az", 10, "ba", 20]
1400
+ * llrbtree.upper_bound("ba") # => ["ba", 20]
1401
+ *
1402
+ * # "az" is the greatest key that is lower than "b"
1403
+ * llrbtree.upper_bound("b") # => ["az", 10]
1404
+ *
1405
+ * # no key that is equal to or lower than "a"
1406
+ * llrbtree.upper_bound("a") # => nil
1407
+ */
1408
+ VALUE
1409
+ llrbtree_upper_bound(VALUE self, VALUE key)
1410
+ {
1411
+ node_t* node = tree_upper_bound(TREE(self), TO_KEY(key));
1412
+ if (node == NULL)
1413
+ return Qnil;
1414
+ return ASSOC(node);
1415
+ }
1416
+
1417
+ /*********************************************************************/
1418
+
1419
+ typedef struct {
1420
+ VALUE self;
1421
+ node_t* lower_node;
1422
+ node_t* upper_node;
1423
+ VALUE result;
1424
+ } llrbtree_bound_arg_t;
1425
+
1426
+ static VALUE
1427
+ llrbtree_bound_body(llrbtree_bound_arg_t* arg)
1428
+ {
1429
+ VALUE self = arg->self;
1430
+ tree_t* tree = TREE(self);
1431
+ node_t* lower_node = arg->lower_node;
1432
+ node_t* upper_node = arg->upper_node;
1433
+ const int block_given = rb_block_given_p();
1434
+ VALUE result = arg->result;
1435
+ node_t* node;
1436
+
1437
+ ITER_LEV(self)++;
1438
+ for (node = lower_node;
1439
+ node != NULL;
1440
+ node = tree_next(tree, node)) {
1441
+
1442
+ if (block_given)
1443
+ rb_yield_values(2, GET_KEY(node), GET_VAL(node));
1444
+ else
1445
+ rb_ary_push(result, ASSOC(node));
1446
+ if (node == upper_node)
1447
+ break;
1448
+ }
1449
+ return result;
1450
+ }
1451
+
1452
+ #ifdef HAVE_SIZED_ENUMERATOR
1453
+ static VALUE
1454
+ llrbtree_bound_size(VALUE self, VALUE args)
1455
+ {
1456
+ VALUE key1 = RARRAY_AREF(args, 0);
1457
+ VALUE key2 = RARRAY_AREF(args, RARRAY_LEN(args) - 1);
1458
+ node_t* lower_node = tree_lower_bound(TREE(self), TO_KEY(key1));
1459
+ node_t* upper_node = tree_upper_bound(TREE(self), TO_KEY(key2));
1460
+ node_count_t count = 0;
1461
+ node_t* node;
1462
+
1463
+ if (lower_node == NULL || upper_node == NULL ||
1464
+ TREE(self)->compare(lower_node->key,
1465
+ upper_node->key,
1466
+ TREE(self)->context) > 0) {
1467
+ return INT2FIX(0);
1468
+ }
1469
+
1470
+ for (node = lower_node;
1471
+ node != NULL;
1472
+ node = tree_next(TREE(self), node)) {
1473
+
1474
+ count++;
1475
+ if (node == upper_node) {
1476
+ break;
1477
+ }
1478
+ }
1479
+ return ULONG2NUM(count);
1480
+ }
1481
+ #endif
1482
+
1483
+ /*********************************************************************/
1484
+
1485
+ /*
1486
+ * call-seq:
1487
+ * llrbtree.bound(key1, key2 = key1) {|key, value| block} => llrbtree
1488
+ * llrbtree.bound(key1, key2 = key1) => enumerator
1489
+ *
1490
+ * Calls block once for each key between the result of
1491
+ * llrbtree.lower_bound(key1) and llrbtree.upper_bound(key2) in order,
1492
+ * passing the key-value pair as parameters. If the lower bound
1493
+ * exceeds the upper bound, block is not called.
1494
+ *
1495
+ * Returns an enumerator if no block is given.
1496
+ *
1497
+ * llrbtree = LLRBTree["a", "A", "b", "B", "c", "C"]
1498
+ * llrbtree.bound("a").to_a # => [["a", "A"]]
1499
+ * llrbtree.bound("b", "d").to_a # => [["b", "B"], ["c", "C"]]
1500
+ *
1501
+ */
1502
+ VALUE
1503
+ llrbtree_bound(int argc, VALUE* argv, VALUE self)
1504
+ {
1505
+ tree_t* tree = TREE(self);
1506
+ node_t* lower_node;
1507
+ node_t* upper_node;
1508
+ VALUE result;
1509
+
1510
+ llrbtree_check_argument_count(argc, 1, 2);
1511
+
1512
+ RETURN_SIZED_ENUMERATOR(self, argc, argv, llrbtree_bound_size);
1513
+
1514
+ lower_node = tree_lower_bound(tree, TO_KEY(argv[0]));
1515
+ upper_node = tree_upper_bound(tree, TO_KEY(argv[argc - 1]));
1516
+ result = rb_block_given_p() ? self : rb_ary_new();
1517
+
1518
+ if (lower_node == NULL || upper_node == NULL ||
1519
+ TREE(self)->compare(lower_node->key,
1520
+ upper_node->key,
1521
+ TREE(self)->context) > 0) {
1522
+ return result;
1523
+ } else {
1524
+ llrbtree_bound_arg_t arg;
1525
+ arg.self = self;
1526
+ arg.lower_node = lower_node;
1527
+ arg.upper_node = upper_node;
1528
+ arg.result = result;
1529
+ return rb_ensure(llrbtree_bound_body, (VALUE)&arg,
1530
+ llrbtree_each_ensure, self);
1531
+ }
1532
+ }
1533
+
1534
+ static VALUE
1535
+ llrbtree_first_last(VALUE self, const int first)
1536
+ {
1537
+ tree_t* tree = TREE(self);
1538
+ node_t* node;
1539
+
1540
+ if (tree_isempty(tree))
1541
+ return rb_funcall(self, id_default, 1, Qnil);
1542
+
1543
+ if (first)
1544
+ node = tree_first(tree);
1545
+ else
1546
+ node = tree_last(tree);
1547
+ return ASSOC(node);
1548
+ }
1549
+
1550
+ /*
1551
+ * call-seq:
1552
+ * llrbtree.first => array or object or nil
1553
+ *
1554
+ * Returns the first (that is, the smallest) key-value pair.
1555
+ */
1556
+ VALUE
1557
+ llrbtree_first(VALUE self)
1558
+ {
1559
+ return llrbtree_first_last(self, 1);
1560
+ }
1561
+
1562
+ /*
1563
+ * call-seq:
1564
+ * llrbtree.last => array or object or nil
1565
+ *
1566
+ * Returns the last (that is, the greatest) key-value pair.
1567
+ */
1568
+ VALUE
1569
+ llrbtree_last(VALUE self)
1570
+ {
1571
+ return llrbtree_first_last(self, 0);
1572
+ }
1573
+
1574
+ /*
1575
+ * call-seq:
1576
+ * llrbtree.readjust => llrbtree
1577
+ * llrbtree.readjust(nil) => llrbtree
1578
+ * llrbtree.readjust(proc) => llrbtree
1579
+ * llrbtree.readjust {|key1, key2| block} => llrbtree
1580
+ *
1581
+ * Sets a proc to compare keys and readjusts elements using the given
1582
+ * block or a Proc object given as an argument. The block takes two
1583
+ * keys and returns a negative integer, 0, or a positive integer as
1584
+ * the first argument is less than, equal to, or greater than the
1585
+ * second one. If no block is given, just readjusts elements using the
1586
+ * current comparison block. If nil is given as an argument the
1587
+ * default comparison block that uses the <=> method is set.
1588
+ *
1589
+ * llrbtree = LLRBTree["a", 10, "b", 20]
1590
+ * llrbtree.readjust {|a, b| b <=> a }
1591
+ * llrbtree.first # => ["b", 20]
1592
+ *
1593
+ * llrbtree.readjust(nil)
1594
+ * llrbtree.first # => ["a", 10]
1595
+ */
1596
+ VALUE
1597
+ llrbtree_readjust(int argc, VALUE* argv, VALUE self)
1598
+ {
1599
+ compare_t cmp_func = NULL;
1600
+ VALUE cmp_proc = Qnil;
1601
+
1602
+ llrbtree_modify(self);
1603
+
1604
+ if (rb_block_given_p()) {
1605
+ llrbtree_check_argument_count(argc, 0, 0);
1606
+ cmp_func = llrbtree_user_cmp;
1607
+ cmp_proc = rb_block_proc();
1608
+ llrbtree_check_proc_arity(cmp_proc, 2);
1609
+ } else {
1610
+ llrbtree_check_argument_count(argc, 0, 1);
1611
+ if (argc == 0) {
1612
+ cmp_func = TREE(self)->compare;
1613
+ cmp_proc = CMP_PROC(self);
1614
+ } else {
1615
+ if (NIL_P(argv[0])) {
1616
+ cmp_func = llrbtree_cmp;
1617
+ cmp_proc = Qnil;
1618
+ } else {
1619
+ VALUE proc = rb_check_convert_type(argv[0], T_DATA, "Proc", "to_proc");
1620
+ if (NIL_P(proc)) {
1621
+ rb_raise(rb_eTypeError,
1622
+ "wrong cmp_proc type %s (expected Proc)",
1623
+ rb_obj_classname(argv[0]));
1624
+ }
1625
+ cmp_func = llrbtree_user_cmp;
1626
+ cmp_proc = proc;
1627
+ llrbtree_check_proc_arity(cmp_proc, 2);
1628
+ }
1629
+ }
1630
+ }
1631
+
1632
+ if (tree_isempty(TREE(self))) {
1633
+ TREE(self)->compare = cmp_func;
1634
+ CMP_PROC(self) = cmp_proc;
1635
+ return self;
1636
+ }
1637
+ copy_tree(self, self, cmp_func, cmp_proc);
1638
+ return self;
1639
+ }
1640
+
1641
+ /*
1642
+ * call-seq:
1643
+ * llrbtree.cmp_proc => proc or nil
1644
+ *
1645
+ * Returns the comparison block that is set by
1646
+ * LLRBTree#readjust. If the default comparison block is set,
1647
+ * returns nil.
1648
+ */
1649
+ VALUE
1650
+ llrbtree_cmp_proc(VALUE self)
1651
+ {
1652
+ return CMP_PROC(self);
1653
+ }
1654
+
1655
+ /*********************************************************************/
1656
+
1657
+ static ID id_breakable;
1658
+ static ID id_comma_breakable;
1659
+ static ID id_group;
1660
+ static ID id_object_group;
1661
+ static ID id_pp;
1662
+ static ID id_text;
1663
+
1664
+ static VALUE
1665
+ pp_group(VALUE args_)
1666
+ {
1667
+ VALUE* args = (VALUE*)args_;
1668
+ return rb_funcall(args[0], id_group, 3, args[1], args[2], args[3]);
1669
+ }
1670
+
1671
+ typedef struct {
1672
+ VALUE pp;
1673
+ node_t* node;
1674
+ } pp_pair_arg_t;
1675
+
1676
+ static VALUE
1677
+ pp_value(VALUE nil, pp_pair_arg_t* pair_arg)
1678
+ {
1679
+ VALUE pp = pair_arg->pp;
1680
+ rb_funcall(pp, id_breakable, 1, rb_str_new(NULL, 0));
1681
+ return rb_funcall(pp, id_pp, 1, GET_VAL(pair_arg->node));
1682
+ }
1683
+
1684
+ static VALUE
1685
+ pp_pair(VALUE nil, pp_pair_arg_t* pair_arg)
1686
+ {
1687
+ VALUE pp = pair_arg->pp;
1688
+ VALUE group_args[4];
1689
+ group_args[0] = pp;
1690
+ group_args[1] = INT2FIX(1);
1691
+ group_args[2] = rb_str_new(NULL, 0);
1692
+ group_args[3] = rb_str_new(NULL, 0);
1693
+
1694
+ rb_funcall(pp, id_pp, 1, GET_KEY(pair_arg->node));
1695
+ rb_funcall(pp, id_text, 1, rb_str_new2("=>"));
1696
+ return rb_iterate(pp_group, (VALUE)&group_args, pp_value, (VALUE)pair_arg);
1697
+ }
1698
+
1699
+ typedef struct {
1700
+ VALUE pp;
1701
+ int first;
1702
+ } pp_each_pair_arg_t;
1703
+
1704
+ static each_return_t
1705
+ pp_each_pair_i(node_t* node, void* each_pair_arg_)
1706
+ {
1707
+ pp_each_pair_arg_t* each_pair_arg = (pp_each_pair_arg_t*)each_pair_arg_;
1708
+ VALUE group_args[4];
1709
+ pp_pair_arg_t pair_arg;
1710
+
1711
+ if (each_pair_arg->first) {
1712
+ each_pair_arg->first = 0;
1713
+ } else {
1714
+ rb_funcall(each_pair_arg->pp, id_comma_breakable, 0);
1715
+ }
1716
+
1717
+ group_args[0] = each_pair_arg->pp;
1718
+ group_args[1] = INT2FIX(0);
1719
+ group_args[2] = rb_str_new(NULL, 0);
1720
+ group_args[3] = rb_str_new(NULL, 0);
1721
+
1722
+ pair_arg.pp = each_pair_arg->pp;
1723
+ pair_arg.node = node;
1724
+
1725
+ rb_iterate(pp_group, (VALUE)&group_args, pp_pair, (VALUE)&pair_arg);
1726
+ return EACH_NEXT;
1727
+ }
1728
+
1729
+ typedef struct {
1730
+ VALUE pp;
1731
+ VALUE llrbtree;
1732
+ } pp_llrbtree_arg_t;
1733
+
1734
+ static VALUE
1735
+ pp_each_pair(VALUE nil, pp_llrbtree_arg_t* llrbtree_arg)
1736
+ {
1737
+ pp_each_pair_arg_t each_pair_arg;
1738
+ each_pair_arg.pp = llrbtree_arg->pp;
1739
+ each_pair_arg.first = 1;
1740
+ return llrbtree_for_each(llrbtree_arg->llrbtree, pp_each_pair_i, &each_pair_arg);
1741
+ }
1742
+
1743
+ static VALUE
1744
+ pp_llrbtree(VALUE nil, pp_llrbtree_arg_t* llrbtree_arg)
1745
+ {
1746
+ VALUE pp = llrbtree_arg->pp;
1747
+ VALUE llrbtree = llrbtree_arg->llrbtree;
1748
+
1749
+ VALUE group_args[4];
1750
+ group_args[0] = pp;
1751
+ group_args[1] = INT2FIX(1);
1752
+ group_args[2] = rb_str_new2("{");
1753
+ group_args[3] = rb_str_new2("}");
1754
+
1755
+ rb_funcall(pp, id_text, 1, rb_str_new2(": "));
1756
+ rb_iterate(pp_group, (VALUE)&group_args, pp_each_pair, (VALUE)llrbtree_arg);
1757
+ rb_funcall(pp, id_comma_breakable, 0);
1758
+ rb_funcall(pp, id_text, 1, rb_str_new2("default="));
1759
+ rb_funcall(pp, id_pp, 1, IFNONE(llrbtree));
1760
+ rb_funcall(pp, id_comma_breakable, 0);
1761
+ rb_funcall(pp, id_text, 1, rb_str_new2("cmp_proc="));
1762
+ return rb_funcall(pp, id_pp, 1, CMP_PROC(llrbtree));
1763
+ }
1764
+
1765
+ static VALUE
1766
+ pp_llrbtree_group(VALUE arg_)
1767
+ {
1768
+ pp_llrbtree_arg_t* arg = (pp_llrbtree_arg_t*)arg_;
1769
+ return rb_funcall(arg->pp, id_object_group, 1, arg->llrbtree);
1770
+ }
1771
+
1772
+ /*********************************************************************/
1773
+
1774
+ /* :nodoc:
1775
+ *
1776
+ */
1777
+ VALUE
1778
+ llrbtree_pretty_print(VALUE self, VALUE pp)
1779
+ {
1780
+ pp_llrbtree_arg_t arg;
1781
+ arg.llrbtree = self;
1782
+ arg.pp = pp;
1783
+ return rb_iterate(pp_llrbtree_group, (VALUE)&arg, pp_llrbtree, (VALUE)&arg);
1784
+ }
1785
+
1786
+ /* :nodoc:
1787
+ *
1788
+ */
1789
+ VALUE
1790
+ llrbtree_pretty_print_cycle(VALUE self, VALUE pp)
1791
+ {
1792
+ return rb_funcall(pp, id_pp, 1, llrbtree_inspect_recursive(self, Qnil, 1));
1793
+ }
1794
+
1795
+ /*********************************************************************/
1796
+
1797
+ /* :nodoc:
1798
+ *
1799
+ */
1800
+ VALUE
1801
+ llrbtree_dump(VALUE self, VALUE limit)
1802
+ {
1803
+ VALUE ary;
1804
+ VALUE result;
1805
+
1806
+ if (FL_TEST(self, LLRBTREE_PROC_DEFAULT))
1807
+ rb_raise(rb_eTypeError, "can't dump llrbtree with default proc");
1808
+ if (CMP_PROC(self) != Qnil)
1809
+ rb_raise(rb_eTypeError, "can't dump llrbtree with comparison proc");
1810
+
1811
+ ary = rb_ary_new2(TREE(self)->node_count * 2 + 1);
1812
+ llrbtree_for_each(self, to_flat_ary_i, (void*)ary);
1813
+ rb_ary_push(ary, IFNONE(self));
1814
+
1815
+ result = rb_funcall(rb_const_get(rb_cObject, id_marshal), id_dump, 2, ary, limit);
1816
+ rb_ary_resize(ary, 0);
1817
+ return result;
1818
+ }
1819
+
1820
+ /* :nodoc:
1821
+ *
1822
+ */
1823
+ VALUE
1824
+ llrbtree_s_load(VALUE klass, VALUE str)
1825
+ {
1826
+ VALUE llrbtree = llrbtree_alloc(klass);
1827
+ VALUE ary = rb_marshal_load(str);
1828
+ long len = RARRAY_LEN(ary) - 1;
1829
+ long i;
1830
+
1831
+ for (i = 0; i < len; i += 2)
1832
+ llrbtree_aset(llrbtree, RARRAY_AREF(ary, i), RARRAY_AREF(ary, i + 1));
1833
+ IFNONE(llrbtree) = RARRAY_AREF(ary, len);
1834
+
1835
+ rb_ary_resize(ary, 0);
1836
+ return llrbtree;
1837
+ }
1838
+
1839
+ /*********************************************************************/
1840
+ /*
1841
+ * Document-class: LLRBTree
1842
+ *
1843
+ * A sorted associative collection that cannot contain duplicate keys.
1844
+ */
1845
+ void Init_llrbtree()
1846
+ {
1847
+ LLRBTree = rb_define_class("LLRBTree", rb_cData);
1848
+
1849
+ rb_include_module(LLRBTree, rb_mEnumerable);
1850
+
1851
+ rb_define_alloc_func(LLRBTree, llrbtree_alloc);
1852
+
1853
+ rb_define_singleton_method(LLRBTree, "[]", llrbtree_s_create, -1);
1854
+
1855
+ rb_define_method(LLRBTree, "initialize", llrbtree_initialize, -1);
1856
+ rb_define_method(LLRBTree, "initialize_copy", llrbtree_initialize_copy, 1);
1857
+
1858
+ rb_define_method(LLRBTree, "to_a", llrbtree_to_a, 0);
1859
+ rb_define_method(LLRBTree, "to_h", llrbtree_to_hash, 0);
1860
+ rb_define_method(LLRBTree, "to_hash", llrbtree_to_hash, 0);
1861
+ rb_define_method(LLRBTree, "to_llrbtree", llrbtree_to_llrbtree, 0);
1862
+ rb_define_method(LLRBTree, "inspect", llrbtree_inspect, 0);
1863
+ rb_define_alias(LLRBTree, "to_s", "inspect");
1864
+
1865
+ rb_define_method(LLRBTree, "==", llrbtree_equal, 1);
1866
+ rb_define_method(LLRBTree, "[]", llrbtree_aref, 1);
1867
+ rb_define_method(LLRBTree, "fetch", llrbtree_fetch, -1);
1868
+ rb_define_method(LLRBTree, "lower_bound", llrbtree_lower_bound, 1);
1869
+ rb_define_method(LLRBTree, "upper_bound", llrbtree_upper_bound, 1);
1870
+ rb_define_method(LLRBTree, "bound", llrbtree_bound, -1);
1871
+ rb_define_method(LLRBTree, "first", llrbtree_first, 0);
1872
+ rb_define_method(LLRBTree, "last", llrbtree_last, 0);
1873
+ rb_define_method(LLRBTree, "[]=", llrbtree_aset, 2);
1874
+ rb_define_method(LLRBTree, "store", llrbtree_aset, 2);
1875
+ rb_define_method(LLRBTree, "default", llrbtree_default, -1);
1876
+ rb_define_method(LLRBTree, "default=", llrbtree_set_default, 1);
1877
+ rb_define_method(LLRBTree, "default_proc", llrbtree_default_proc, 0);
1878
+ rb_define_method(LLRBTree, "default_proc=", llrbtree_set_default_proc, 1);
1879
+ rb_define_method(LLRBTree, "key", llrbtree_key, 1);
1880
+ rb_define_method(LLRBTree, "index", llrbtree_index, 1);
1881
+ rb_define_method(LLRBTree, "empty?", llrbtree_empty_p, 0);
1882
+ rb_define_method(LLRBTree, "size", llrbtree_size, 0);
1883
+ rb_define_method(LLRBTree, "length", llrbtree_size, 0);
1884
+
1885
+ rb_define_method(LLRBTree, "each", llrbtree_each_pair, 0);
1886
+ rb_define_method(LLRBTree, "each_value", llrbtree_each_value, 0);
1887
+ rb_define_method(LLRBTree, "each_key", llrbtree_each_key, 0);
1888
+ rb_define_method(LLRBTree, "each_pair", llrbtree_each_pair, 0);
1889
+ rb_define_method(LLRBTree, "reverse_each", llrbtree_reverse_each, 0);
1890
+
1891
+ rb_define_method(LLRBTree, "keys", llrbtree_keys, 0);
1892
+ rb_define_method(LLRBTree, "values", llrbtree_values, 0);
1893
+ rb_define_method(LLRBTree, "values_at", llrbtree_values_at, -1);
1894
+
1895
+ rb_define_method(LLRBTree, "shift", llrbtree_shift, 0);
1896
+ rb_define_method(LLRBTree, "pop", llrbtree_pop, 0);
1897
+ rb_define_method(LLRBTree, "delete", llrbtree_delete, 1);
1898
+ rb_define_method(LLRBTree, "delete_if", llrbtree_delete_if, 0);
1899
+ rb_define_method(LLRBTree, "keep_if", llrbtree_keep_if, 0);
1900
+ rb_define_method(LLRBTree, "reject", llrbtree_reject, 0);
1901
+ rb_define_method(LLRBTree, "reject!", llrbtree_reject_bang, 0);
1902
+ rb_define_method(LLRBTree, "select", llrbtree_select, 0);
1903
+ rb_define_method(LLRBTree, "select!", llrbtree_select_bang, 0);
1904
+ rb_define_method(LLRBTree, "clear", llrbtree_clear, 0);
1905
+ rb_define_method(LLRBTree, "invert", llrbtree_invert, 0);
1906
+ rb_define_method(LLRBTree, "update", llrbtree_update, 1);
1907
+ rb_define_method(LLRBTree, "merge!", llrbtree_update, 1);
1908
+ rb_define_method(LLRBTree, "merge", llrbtree_merge, 1);
1909
+ rb_define_method(LLRBTree, "replace", llrbtree_initialize_copy, 1);
1910
+ rb_define_method(LLRBTree, "flatten", llrbtree_flatten, -1);
1911
+
1912
+ rb_define_method(LLRBTree, "include?", llrbtree_has_key, 1);
1913
+ rb_define_method(LLRBTree, "member?", llrbtree_has_key, 1);
1914
+ rb_define_method(LLRBTree, "has_key?", llrbtree_has_key, 1);
1915
+ rb_define_method(LLRBTree, "has_value?", llrbtree_has_value, 1);
1916
+ rb_define_method(LLRBTree, "key?", llrbtree_has_key, 1);
1917
+ rb_define_method(LLRBTree, "value?", llrbtree_has_value, 1);
1918
+
1919
+ rb_define_method(LLRBTree, "readjust", llrbtree_readjust, -1);
1920
+ rb_define_method(LLRBTree, "cmp_proc", llrbtree_cmp_proc, 0);
1921
+
1922
+ rb_define_method(LLRBTree, "_dump", llrbtree_dump, 1);
1923
+ rb_define_singleton_method(LLRBTree, "_load", llrbtree_s_load, 1);
1924
+
1925
+ id_cmp = rb_intern("<=>");
1926
+ id_call = rb_intern("call");
1927
+ id_default = rb_intern("default");
1928
+ id_flatten_bang = rb_intern("flatten!");
1929
+ id_marshal = rb_intern("Marshal");
1930
+ id_dump = rb_intern("dump");
1931
+
1932
+ rb_define_method(LLRBTree, "pretty_print", llrbtree_pretty_print, 1);
1933
+ rb_define_method(LLRBTree,
1934
+ "pretty_print_cycle", llrbtree_pretty_print_cycle, 1);
1935
+
1936
+ id_breakable = rb_intern("breakable");
1937
+ id_comma_breakable = rb_intern("comma_breakable");
1938
+ id_group = rb_intern("group");
1939
+ id_object_group = rb_intern("object_group");
1940
+ id_pp = rb_intern("pp");
1941
+ id_text = rb_intern("text");
1942
+ }