rbtree 0.4.2 → 0.4.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README +8 -12
- data/extconf.rb +3 -0
- data/rbtree.c +141 -85
- data/test.rb +1 -1
- metadata +8 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a5ec1fb39918d82821706cea18cb63b25fd4d20a989579664f7b95774f43881f
|
4
|
+
data.tar.gz: 3795d33cbbf811cdfd7b92664eca4156760c8d3bb36fa28a9854720279c6c1dd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3df17e8770de0b0e7396b454905ca5a1d1de24d2dc006de0283a29c9a0805b772442f510dd9ce66bbe590499128d5375da4e61ae7e8396abed455833204af79d
|
7
|
+
data.tar.gz: ba6402624a047e104e2ddb70a37b19f1d01c2ce7b88752f19c9396fd197c8b58c8e3e3daa21974038b1a44676ee2af40c220dfc1fd300ad6796590fecdca5e30
|
data/README
CHANGED
@@ -57,21 +57,17 @@ Run the following command.
|
|
57
57
|
$ sudo gem install rbtree
|
58
58
|
|
59
59
|
== Changes
|
60
|
-
=== 0.4.
|
61
|
-
*
|
60
|
+
=== 0.4.6
|
61
|
+
* Make it work with clang 15.
|
62
62
|
|
63
|
-
=== 0.4.
|
64
|
-
*
|
63
|
+
=== 0.4.5
|
64
|
+
* Support Ruby 3.2.0-dev (development branch).
|
65
65
|
|
66
|
-
=== 0.4.
|
66
|
+
=== 0.4.4
|
67
|
+
* Remove the rb_safe_level warning on Ruby 2.7.
|
67
68
|
|
68
|
-
|
69
|
-
*
|
70
|
-
* \#select now returns a new MultiRBTree / RBTree.
|
71
|
-
* Fixed a bug where \#reject could return nil.
|
72
|
-
* \#to_s is now equivalent to \#inspect.
|
73
|
-
* \#each now passes a two elements array as an argument to the given block.
|
74
|
-
* Added new methods: \#default_proc=, \#flatten, \#keep_if, \#key, \#select! and \#to_h.
|
69
|
+
=== 0.4.3
|
70
|
+
* Quick bug fixes for Ruby 3.
|
75
71
|
|
76
72
|
== License
|
77
73
|
|
data/extconf.rb
CHANGED
@@ -5,11 +5,14 @@ if enable_config('debug')
|
|
5
5
|
else
|
6
6
|
$defs << '-DNDEBUG'
|
7
7
|
end
|
8
|
+
have_header('ruby/version.h')
|
8
9
|
have_func('rb_exec_recursive', 'ruby.h')
|
9
10
|
have_func('rb_exec_recursive_paired', 'ruby.h')
|
10
11
|
have_func('rb_proc_lambda_p', 'ruby.h')
|
11
12
|
have_func('rb_ary_resize', 'ruby.h')
|
12
13
|
have_func('rb_obj_hide', 'ruby.h')
|
14
|
+
have_func('rb_safe_level', 'ruby.h')
|
15
|
+
have_func('rb_cData', 'ruby.h')
|
13
16
|
if Hash.method_defined?(:flatten)
|
14
17
|
$defs << '-DHAVE_HASH_FLATTEN'
|
15
18
|
end
|
data/rbtree.c
CHANGED
@@ -3,6 +3,9 @@
|
|
3
3
|
* Copyright (c) 2002-2013 OZAWA Takuma
|
4
4
|
*/
|
5
5
|
#include <ruby.h>
|
6
|
+
#ifdef HAVE_RUBY_VERSION_H
|
7
|
+
#include <ruby/version.h>
|
8
|
+
#endif
|
6
9
|
#ifdef HAVE_RUBY_ST_H
|
7
10
|
#include <ruby/st.h>
|
8
11
|
#else
|
@@ -134,22 +137,24 @@ static int
|
|
134
137
|
rbtree_cmp(const void* key1, const void* key2, void* context)
|
135
138
|
{
|
136
139
|
VALUE result;
|
137
|
-
if (TYPE(key1) == T_STRING && TYPE(key2) == T_STRING)
|
140
|
+
if (TYPE((VALUE)key1) == T_STRING && TYPE((VALUE)key2) == T_STRING)
|
138
141
|
return rb_str_cmp((VALUE)key1, (VALUE)key2);
|
139
142
|
result = rb_funcall2((VALUE)key1, id_cmp, 1, (VALUE*)&key2);
|
140
143
|
return rb_cmpint(result, (VALUE)key1, (VALUE)key2);
|
141
144
|
}
|
142
145
|
|
143
146
|
static VALUE
|
144
|
-
rbtree_user_cmp_ensure(
|
147
|
+
rbtree_user_cmp_ensure(VALUE arg)
|
145
148
|
{
|
149
|
+
rbtree_t* rbtree = (rbtree_t*)arg;
|
146
150
|
rbtree->iter_lev--;
|
147
151
|
return Qnil;
|
148
152
|
}
|
149
153
|
|
150
154
|
static VALUE
|
151
|
-
rbtree_user_cmp_body(VALUE
|
155
|
+
rbtree_user_cmp_body(VALUE arg)
|
152
156
|
{
|
157
|
+
VALUE *args = (VALUE*)arg;
|
153
158
|
rbtree_t* rbtree = (rbtree_t*)args[2];
|
154
159
|
rbtree->iter_lev++;
|
155
160
|
return rb_funcall2(rbtree->cmp_proc, id_call, 2, args);
|
@@ -176,8 +181,10 @@ rbtree_modify(VALUE self)
|
|
176
181
|
if (ITER_LEV(self) > 0)
|
177
182
|
rb_raise(rb_eTypeError, "can't modify rbtree during iteration");
|
178
183
|
rb_check_frozen(self);
|
184
|
+
#if defined(HAVE_RB_SAFE_LEVEL) && !defined(RUBY_SAFE_LEVEL_MAX)
|
179
185
|
if (!OBJ_TAINTED(self) && rb_safe_level() >= 4)
|
180
186
|
rb_raise(rb_eSecurityError, "Insecure: can't modify rbtree");
|
187
|
+
#endif
|
181
188
|
}
|
182
189
|
|
183
190
|
static VALUE
|
@@ -187,14 +194,14 @@ rbtree_alloc(VALUE klass)
|
|
187
194
|
VALUE rbtree = Data_Wrap_Struct(klass, rbtree_mark, rbtree_free, NULL);
|
188
195
|
RBTREE(rbtree) = ALLOC(rbtree_t);
|
189
196
|
MEMZERO(RBTREE(rbtree), rbtree_t, 1);
|
190
|
-
|
197
|
+
|
191
198
|
dict = ALLOC(dict_t);
|
192
199
|
dict_init(dict, rbtree_cmp);
|
193
200
|
dict_set_allocator(dict, rbtree_alloc_node, rbtree_free_node,
|
194
201
|
RBTREE(rbtree));
|
195
202
|
if (!RTEST(rb_class_inherited_p(klass, RBTree)))
|
196
203
|
dict_allow_dupes(dict);
|
197
|
-
|
204
|
+
|
198
205
|
DICT(rbtree) = dict;
|
199
206
|
IFNONE(rbtree) = Qnil;
|
200
207
|
CMP_PROC(rbtree) = Qnil;
|
@@ -224,29 +231,29 @@ rbtree_s_create(int argc, VALUE* argv, VALUE klass)
|
|
224
231
|
{
|
225
232
|
long i;
|
226
233
|
VALUE rbtree;
|
227
|
-
|
234
|
+
|
228
235
|
if (argc == 1) {
|
229
236
|
VALUE temp;
|
230
|
-
|
237
|
+
|
231
238
|
if (rb_obj_is_kind_of(argv[0], klass)) {
|
232
239
|
rbtree = rbtree_alloc(klass);
|
233
240
|
rbtree_update(rbtree, argv[0]);
|
234
241
|
return rbtree;
|
235
242
|
}
|
236
|
-
|
243
|
+
|
237
244
|
if (RTEST(rb_class_inherited_p(klass, RBTree)) &&
|
238
245
|
(rb_obj_is_kind_of(argv[0], MultiRBTree) && !rb_obj_is_kind_of(argv[0], RBTree))) {
|
239
|
-
|
246
|
+
|
240
247
|
rb_raise(rb_eTypeError, "wrong argument type MultiRBTree (expected RBTree)");
|
241
248
|
}
|
242
|
-
|
249
|
+
|
243
250
|
temp = rb_check_convert_type(argv[0], T_HASH, "Hash", "to_hash");
|
244
251
|
if (!NIL_P(temp)) {
|
245
252
|
rbtree = rbtree_alloc(klass);
|
246
253
|
rb_hash_foreach(temp, hash_to_rbtree_i, rbtree);
|
247
254
|
return rbtree;
|
248
255
|
}
|
249
|
-
|
256
|
+
|
250
257
|
temp = rb_check_array_type(argv[0]);
|
251
258
|
if (!NIL_P(temp)) {
|
252
259
|
rbtree = rbtree_alloc(klass);
|
@@ -272,7 +279,7 @@ rbtree_s_create(int argc, VALUE* argv, VALUE klass)
|
|
272
279
|
return rbtree;
|
273
280
|
}
|
274
281
|
}
|
275
|
-
|
282
|
+
|
276
283
|
if (argc % 2 != 0)
|
277
284
|
rb_raise(rb_eArgError, "odd number of arguments for %s", rb_class2name(klass));
|
278
285
|
|
@@ -321,11 +328,12 @@ typedef struct {
|
|
321
328
|
} rbtree_insert_arg_t;
|
322
329
|
|
323
330
|
static VALUE
|
324
|
-
insert_node_body(
|
331
|
+
insert_node_body(VALUE arg_)
|
325
332
|
{
|
333
|
+
rbtree_insert_arg_t* arg = (rbtree_insert_arg_t*)arg_;
|
326
334
|
dict_t* dict = arg->dict;
|
327
335
|
dnode_t* node = arg->node;
|
328
|
-
|
336
|
+
|
329
337
|
if (dict_insert(dict, node, dnode_getkey(node))) {
|
330
338
|
if (TYPE(GET_KEY(node)) == T_STRING) {
|
331
339
|
arg->result = KeyAllocationFailed;
|
@@ -339,11 +347,12 @@ insert_node_body(rbtree_insert_arg_t* arg)
|
|
339
347
|
}
|
340
348
|
|
341
349
|
static VALUE
|
342
|
-
insert_node_ensure(
|
350
|
+
insert_node_ensure(VALUE arg_)
|
343
351
|
{
|
352
|
+
rbtree_insert_arg_t* arg = (rbtree_insert_arg_t*)arg_;
|
344
353
|
dict_t* dict = arg->dict;
|
345
354
|
dnode_t* node = arg->node;
|
346
|
-
|
355
|
+
|
347
356
|
switch (arg->result) {
|
348
357
|
case InsertionSucceeded:
|
349
358
|
break;
|
@@ -366,7 +375,7 @@ rbtree_insert(VALUE self, VALUE key, VALUE value)
|
|
366
375
|
|
367
376
|
dnode_init(node, TO_VAL(value));
|
368
377
|
node->dict_key = TO_KEY(key);
|
369
|
-
|
378
|
+
|
370
379
|
arg.dict = dict;
|
371
380
|
arg.node = node;
|
372
381
|
arg.result = NoNodeInserted;
|
@@ -501,14 +510,14 @@ VALUE
|
|
501
510
|
rbtree_set_default_proc(VALUE self, VALUE proc)
|
502
511
|
{
|
503
512
|
VALUE temp;
|
504
|
-
|
513
|
+
|
505
514
|
rbtree_modify(self);
|
506
515
|
if (NIL_P(proc)) {
|
507
516
|
IFNONE(self) = Qnil;
|
508
517
|
FL_UNSET(self, RBTREE_PROC_DEFAULT);
|
509
518
|
return Qnil;
|
510
519
|
}
|
511
|
-
|
520
|
+
|
512
521
|
temp = rb_check_convert_type(proc, T_DATA, "Proc", "to_proc");
|
513
522
|
if (NIL_P(temp)) {
|
514
523
|
rb_raise(rb_eTypeError,
|
@@ -528,16 +537,16 @@ rbtree_recursive_equal(VALUE self, VALUE other, int recursive)
|
|
528
537
|
dict_t* dict2 = DICT(other);
|
529
538
|
dnode_t* node1;
|
530
539
|
dnode_t* node2;
|
531
|
-
|
540
|
+
|
532
541
|
if (recursive)
|
533
542
|
return Qtrue;
|
534
543
|
for (node1 = dict_first(dict1), node2 = dict_first(dict2);
|
535
544
|
node1 != NULL && node2 != NULL;
|
536
545
|
node1 = dict_next(dict1, node1), node2 = dict_next(dict2, node2)) {
|
537
|
-
|
546
|
+
|
538
547
|
if (!rb_equal(GET_KEY(node1), GET_KEY(node2)) ||
|
539
548
|
!rb_equal(GET_VAL(node1), GET_VAL(node2))) {
|
540
|
-
|
549
|
+
|
541
550
|
return Qfalse;
|
542
551
|
}
|
543
552
|
}
|
@@ -557,7 +566,7 @@ rbtree_equal(VALUE self, VALUE other)
|
|
557
566
|
if (dict_count(DICT(self)) != dict_count(DICT(other)) ||
|
558
567
|
DICT(self)->dict_compare != DICT(other)->dict_compare ||
|
559
568
|
CMP_PROC(self) != CMP_PROC(other)) {
|
560
|
-
|
569
|
+
|
561
570
|
return Qfalse;
|
562
571
|
}
|
563
572
|
#if defined(HAVE_RB_EXEC_RECURSIVE_PAIRED)
|
@@ -592,14 +601,15 @@ rbtree_each_ensure(VALUE self)
|
|
592
601
|
}
|
593
602
|
|
594
603
|
static VALUE
|
595
|
-
rbtree_each_body(
|
604
|
+
rbtree_each_body(VALUE arg_)
|
596
605
|
{
|
606
|
+
rbtree_each_arg_t* arg = (rbtree_each_arg_t*)arg_;
|
597
607
|
VALUE self = arg->self;
|
598
608
|
dict_t* dict = DICT(self);
|
599
609
|
dnode_t* node;
|
600
610
|
dnode_t* first_node;
|
601
611
|
dnode_t* (*next_func)(dict_t*, dnode_t*);
|
602
|
-
|
612
|
+
|
603
613
|
if (arg->reverse) {
|
604
614
|
first_node = dict_last(dict);
|
605
615
|
next_func = dict_prev;
|
@@ -607,12 +617,12 @@ rbtree_each_body(rbtree_each_arg_t* arg)
|
|
607
617
|
first_node = dict_first(dict);
|
608
618
|
next_func = dict_next;
|
609
619
|
}
|
610
|
-
|
620
|
+
|
611
621
|
ITER_LEV(self)++;
|
612
622
|
for (node = first_node;
|
613
623
|
node != NULL;
|
614
624
|
node = next_func(dict, node)) {
|
615
|
-
|
625
|
+
|
616
626
|
if (arg->func(node, arg->arg) == EACH_STOP)
|
617
627
|
break;
|
618
628
|
}
|
@@ -763,7 +773,11 @@ copy_dict(VALUE src, VALUE dest, dict_comp_t cmp_func, VALUE cmp_proc)
|
|
763
773
|
}
|
764
774
|
rbtree_free(RBTREE(temp));
|
765
775
|
RBTREE(temp) = NULL;
|
776
|
+
#if defined(RUBY_API_VERSION_CODE) && RUBY_API_VERSION_CODE >= 30100
|
777
|
+
/* do nothing */
|
778
|
+
#else
|
766
779
|
rb_gc_force_recycle(temp);
|
780
|
+
#endif
|
767
781
|
|
768
782
|
DICT(dest)->dict_context = RBTREE(dest);
|
769
783
|
CMP_PROC(dest) = cmp_proc;
|
@@ -776,7 +790,7 @@ VALUE
|
|
776
790
|
rbtree_initialize_copy(VALUE self, VALUE other)
|
777
791
|
{
|
778
792
|
rbtree_modify(self);
|
779
|
-
|
793
|
+
|
780
794
|
if (self == other)
|
781
795
|
return self;
|
782
796
|
if (!rb_obj_is_kind_of(other, CLASS_OF(self))) {
|
@@ -784,9 +798,9 @@ rbtree_initialize_copy(VALUE self, VALUE other)
|
|
784
798
|
rb_obj_classname(other),
|
785
799
|
rb_obj_classname(self));
|
786
800
|
}
|
787
|
-
|
801
|
+
|
788
802
|
copy_dict(other, self, DICT(other)->dict_compare, CMP_PROC(other));
|
789
|
-
|
803
|
+
|
790
804
|
IFNONE(self) = IFNONE(other);
|
791
805
|
if (FL_TEST(other, RBTREE_PROC_DEFAULT))
|
792
806
|
FL_SET(self, RBTREE_PROC_DEFAULT);
|
@@ -803,7 +817,7 @@ rbtree_values_at(int argc, VALUE* argv, VALUE self)
|
|
803
817
|
{
|
804
818
|
long i;
|
805
819
|
VALUE ary = rb_ary_new2(argc);
|
806
|
-
|
820
|
+
|
807
821
|
for (i = 0; i < argc; i++)
|
808
822
|
rb_ary_push(ary, rbtree_aref(self, argv[i]));
|
809
823
|
return ary;
|
@@ -890,8 +904,9 @@ typedef struct {
|
|
890
904
|
} rbtree_remove_if_arg_t;
|
891
905
|
|
892
906
|
static VALUE
|
893
|
-
rbtree_remove_if_ensure(
|
907
|
+
rbtree_remove_if_ensure(VALUE arg_)
|
894
908
|
{
|
909
|
+
rbtree_remove_if_arg_t* arg = (rbtree_remove_if_arg_t*)arg_;
|
895
910
|
dict_t* dict = DICT(arg->self);
|
896
911
|
dnode_list_t* list = arg->list;
|
897
912
|
|
@@ -908,8 +923,9 @@ rbtree_remove_if_ensure(rbtree_remove_if_arg_t* arg)
|
|
908
923
|
}
|
909
924
|
|
910
925
|
static VALUE
|
911
|
-
rbtree_remove_if_body(
|
926
|
+
rbtree_remove_if_body(VALUE arg_)
|
912
927
|
{
|
928
|
+
rbtree_remove_if_arg_t* arg = (rbtree_remove_if_arg_t*)arg_;
|
913
929
|
VALUE self = arg->self;
|
914
930
|
dict_t* dict = DICT(self);
|
915
931
|
dnode_t* node;
|
@@ -937,7 +953,7 @@ static VALUE
|
|
937
953
|
rbtree_remove_if(VALUE self, const int if_true)
|
938
954
|
{
|
939
955
|
rbtree_remove_if_arg_t arg;
|
940
|
-
|
956
|
+
|
941
957
|
RETURN_SIZED_ENUMERATOR(self, 0, NULL, rbtree_size);
|
942
958
|
rbtree_modify(self);
|
943
959
|
arg.self = self;
|
@@ -974,7 +990,7 @@ VALUE
|
|
974
990
|
rbtree_reject_bang(VALUE self)
|
975
991
|
{
|
976
992
|
dictcount_t count;
|
977
|
-
|
993
|
+
|
978
994
|
RETURN_SIZED_ENUMERATOR(self, 0, NULL, rbtree_size);
|
979
995
|
count = dict_count(DICT(self));
|
980
996
|
rbtree_delete_if(self);
|
@@ -990,14 +1006,14 @@ VALUE
|
|
990
1006
|
rbtree_select_bang(VALUE self)
|
991
1007
|
{
|
992
1008
|
dictcount_t count;
|
993
|
-
|
1009
|
+
|
994
1010
|
RETURN_SIZED_ENUMERATOR(self, 0, NULL, rbtree_size);
|
995
1011
|
count = dict_count(DICT(self));
|
996
1012
|
rbtree_keep_if(self);
|
997
1013
|
if (count == dict_count(DICT(self)))
|
998
1014
|
return Qnil;
|
999
1015
|
return self;
|
1000
|
-
|
1016
|
+
|
1001
1017
|
}
|
1002
1018
|
|
1003
1019
|
/*********************************************************************/
|
@@ -1013,7 +1029,7 @@ select_i(dnode_t* node, void* arg_)
|
|
1013
1029
|
VALUE key = GET_KEY(node);
|
1014
1030
|
VALUE value = GET_VAL(node);
|
1015
1031
|
rbtree_select_if_arg_t* arg = arg_;
|
1016
|
-
|
1032
|
+
|
1017
1033
|
if (RTEST(rb_yield_values(2, key, value)) == arg->if_true) {
|
1018
1034
|
rbtree_aset(arg->result, key, value);
|
1019
1035
|
}
|
@@ -1024,7 +1040,7 @@ static VALUE
|
|
1024
1040
|
rbtree_select_if(VALUE self, const int if_true)
|
1025
1041
|
{
|
1026
1042
|
rbtree_select_if_arg_t arg;
|
1027
|
-
|
1043
|
+
|
1028
1044
|
RETURN_SIZED_ENUMERATOR(self, 0, NULL, rbtree_size);
|
1029
1045
|
arg.result = rbtree_alloc(CLASS_OF(self));
|
1030
1046
|
arg.if_true = if_true;
|
@@ -1063,7 +1079,7 @@ rbtree_shift_pop(VALUE self, const int shift)
|
|
1063
1079
|
|
1064
1080
|
if (dict_isempty(dict))
|
1065
1081
|
return rb_funcall(self, id_default, 1, Qnil);
|
1066
|
-
|
1082
|
+
|
1067
1083
|
if (shift)
|
1068
1084
|
node = dict_last(dict);
|
1069
1085
|
else
|
@@ -1145,7 +1161,7 @@ rbtree_update(VALUE self, VALUE other)
|
|
1145
1161
|
rb_obj_classname(other),
|
1146
1162
|
rb_obj_classname(self));
|
1147
1163
|
}
|
1148
|
-
|
1164
|
+
|
1149
1165
|
if (rb_block_given_p())
|
1150
1166
|
rbtree_for_each(other, update_block_i, (void*)self);
|
1151
1167
|
else
|
@@ -1267,6 +1283,13 @@ to_a_i(dnode_t* node, void* ary)
|
|
1267
1283
|
return EACH_NEXT;
|
1268
1284
|
}
|
1269
1285
|
|
1286
|
+
|
1287
|
+
#if defined(RUBY_API_VERSION_CODE) && RUBY_API_VERSION_CODE >= 30100
|
1288
|
+
# define RBTREE_OBJ_INFECT(obj1, obj2)
|
1289
|
+
#else
|
1290
|
+
# define RBTREE_OBJ_INFECT(obj1, obj2) OBJ_INFECT(obj1, obj2)
|
1291
|
+
#endif
|
1292
|
+
|
1270
1293
|
/*
|
1271
1294
|
*
|
1272
1295
|
*/
|
@@ -1275,7 +1298,7 @@ rbtree_to_a(VALUE self)
|
|
1275
1298
|
{
|
1276
1299
|
VALUE ary = rb_ary_new2(dict_count(DICT(self)));
|
1277
1300
|
rbtree_for_each(self, to_a_i, (void*)ary);
|
1278
|
-
|
1301
|
+
RBTREE_OBJ_INFECT(ary, self);
|
1279
1302
|
return ary;
|
1280
1303
|
}
|
1281
1304
|
|
@@ -1295,13 +1318,13 @@ rbtree_to_hash(VALUE self)
|
|
1295
1318
|
VALUE hash;
|
1296
1319
|
if (!rb_obj_is_kind_of(self, RBTree))
|
1297
1320
|
rb_raise(rb_eTypeError, "can't convert MultiRBTree to Hash");
|
1298
|
-
|
1321
|
+
|
1299
1322
|
hash = rb_hash_new();
|
1300
1323
|
rbtree_for_each(self, to_hash_i, (void*)hash);
|
1301
1324
|
RHASH_SET_IFNONE(hash, IFNONE(self));
|
1302
1325
|
if (FL_TEST(self, RBTREE_PROC_DEFAULT))
|
1303
1326
|
FL_SET(hash, HASH_PROC_DEFAULT);
|
1304
|
-
|
1327
|
+
RBTREE_OBJ_INFECT(hash, self);
|
1305
1328
|
return hash;
|
1306
1329
|
}
|
1307
1330
|
|
@@ -1336,13 +1359,13 @@ inspect_i(dnode_t* node, void* result_)
|
|
1336
1359
|
|
1337
1360
|
str = rb_inspect(GET_KEY(node));
|
1338
1361
|
rb_str_append(result, str);
|
1339
|
-
|
1362
|
+
RBTREE_OBJ_INFECT(result, str);
|
1340
1363
|
|
1341
1364
|
rb_str_cat2(result, "=>");
|
1342
1365
|
|
1343
1366
|
str = rb_inspect(GET_VAL(node));
|
1344
1367
|
rb_str_append(result, str);
|
1345
|
-
|
1368
|
+
RBTREE_OBJ_INFECT(result, str);
|
1346
1369
|
|
1347
1370
|
return EACH_NEXT;
|
1348
1371
|
}
|
@@ -1351,7 +1374,7 @@ static VALUE
|
|
1351
1374
|
inspect_rbtree(VALUE self, VALUE result)
|
1352
1375
|
{
|
1353
1376
|
VALUE str;
|
1354
|
-
|
1377
|
+
|
1355
1378
|
rb_str_cat2(result, "{");
|
1356
1379
|
RSTRING_PTR(result)[0] = '-';
|
1357
1380
|
rbtree_for_each(self, inspect_i, (void*)result);
|
@@ -1361,15 +1384,15 @@ inspect_rbtree(VALUE self, VALUE result)
|
|
1361
1384
|
str = rb_inspect(IFNONE(self));
|
1362
1385
|
rb_str_cat2(result, ", default=");
|
1363
1386
|
rb_str_append(result, str);
|
1364
|
-
|
1365
|
-
|
1387
|
+
RBTREE_OBJ_INFECT(result, str);
|
1388
|
+
|
1366
1389
|
str = rb_inspect(CMP_PROC(self));
|
1367
1390
|
rb_str_cat2(result, ", cmp_proc=");
|
1368
1391
|
rb_str_append(result, str);
|
1369
|
-
|
1392
|
+
RBTREE_OBJ_INFECT(result, str);
|
1370
1393
|
|
1371
1394
|
rb_str_cat2(result, ">");
|
1372
|
-
|
1395
|
+
RBTREE_OBJ_INFECT(result, self);
|
1373
1396
|
return result;
|
1374
1397
|
}
|
1375
1398
|
|
@@ -1460,8 +1483,9 @@ typedef struct {
|
|
1460
1483
|
} rbtree_bound_arg_t;
|
1461
1484
|
|
1462
1485
|
static VALUE
|
1463
|
-
rbtree_bound_body(
|
1486
|
+
rbtree_bound_body(VALUE arg_)
|
1464
1487
|
{
|
1488
|
+
rbtree_bound_arg_t* arg = (rbtree_bound_arg_t*)arg_;
|
1465
1489
|
VALUE self = arg->self;
|
1466
1490
|
dict_t* dict = DICT(self);
|
1467
1491
|
dnode_t* lower_node = arg->lower_node;
|
@@ -1495,18 +1519,18 @@ rbtree_bound_size(VALUE self, VALUE args)
|
|
1495
1519
|
dnode_t* upper_node = dict_upper_bound(DICT(self), TO_KEY(key2));
|
1496
1520
|
dictcount_t count = 0;
|
1497
1521
|
dnode_t* node;
|
1498
|
-
|
1522
|
+
|
1499
1523
|
if (lower_node == NULL || upper_node == NULL ||
|
1500
1524
|
DICT(self)->dict_compare(dnode_getkey(lower_node),
|
1501
1525
|
dnode_getkey(upper_node),
|
1502
1526
|
DICT(self)->dict_context) > 0) {
|
1503
1527
|
return INT2FIX(0);
|
1504
1528
|
}
|
1505
|
-
|
1529
|
+
|
1506
1530
|
for (node = lower_node;
|
1507
1531
|
node != NULL;
|
1508
1532
|
node = dict_next(DICT(self), node)) {
|
1509
|
-
|
1533
|
+
|
1510
1534
|
count++;
|
1511
1535
|
if (node == upper_node) {
|
1512
1536
|
break;
|
@@ -1533,7 +1557,7 @@ rbtree_bound_size(VALUE self, VALUE args)
|
|
1533
1557
|
* mrbtree = MultiRBTree["az", 10, "ba", 20, "ba", 30, "bz", 40]
|
1534
1558
|
* mrbtree.bound("ba").to_a # => [["ba", 20], ["ba", 30]]
|
1535
1559
|
* mrbtree.bound("b", "c").to_a # => [["ba", 20], ["ba", 30], ["bz", 40]]
|
1536
|
-
*
|
1560
|
+
*
|
1537
1561
|
* # the lower bound ("ba") exceeds the upper bound ("az")
|
1538
1562
|
* mrbtree.bound("b").to_a # => []
|
1539
1563
|
*/
|
@@ -1544,15 +1568,15 @@ rbtree_bound(int argc, VALUE* argv, VALUE self)
|
|
1544
1568
|
dnode_t* lower_node;
|
1545
1569
|
dnode_t* upper_node;
|
1546
1570
|
VALUE result;
|
1547
|
-
|
1571
|
+
|
1548
1572
|
rbtree_check_argument_count(argc, 1, 2);
|
1549
|
-
|
1573
|
+
|
1550
1574
|
RETURN_SIZED_ENUMERATOR(self, argc, argv, rbtree_bound_size);
|
1551
|
-
|
1575
|
+
|
1552
1576
|
lower_node = dict_lower_bound(dict, TO_KEY(argv[0]));
|
1553
1577
|
upper_node = dict_upper_bound(dict, TO_KEY(argv[argc - 1]));
|
1554
1578
|
result = rb_block_given_p() ? self : rb_ary_new();
|
1555
|
-
|
1579
|
+
|
1556
1580
|
if (lower_node == NULL || upper_node == NULL ||
|
1557
1581
|
DICT(self)->dict_compare(dnode_getkey(lower_node),
|
1558
1582
|
dnode_getkey(upper_node),
|
@@ -1577,7 +1601,7 @@ rbtree_first_last(VALUE self, const int first)
|
|
1577
1601
|
|
1578
1602
|
if (dict_isempty(dict))
|
1579
1603
|
return rb_funcall(self, id_default, 1, Qnil);
|
1580
|
-
|
1604
|
+
|
1581
1605
|
if (first)
|
1582
1606
|
node = dict_first(dict);
|
1583
1607
|
else
|
@@ -1627,7 +1651,7 @@ rbtree_last(VALUE self)
|
|
1627
1651
|
* rbtree = RBTree["a", 10, "b", 20]
|
1628
1652
|
* rbtree.readjust {|a, b| b <=> a }
|
1629
1653
|
* rbtree.first # => ["b", 20]
|
1630
|
-
*
|
1654
|
+
*
|
1631
1655
|
* rbtree.readjust(nil)
|
1632
1656
|
* rbtree.first # => ["a", 10]
|
1633
1657
|
*/
|
@@ -1636,7 +1660,7 @@ rbtree_readjust(int argc, VALUE* argv, VALUE self)
|
|
1636
1660
|
{
|
1637
1661
|
dict_comp_t cmp_func = NULL;
|
1638
1662
|
VALUE cmp_proc = Qnil;
|
1639
|
-
|
1663
|
+
|
1640
1664
|
rbtree_modify(self);
|
1641
1665
|
|
1642
1666
|
if (rb_block_given_p()) {
|
@@ -1699,12 +1723,28 @@ static ID id_object_group;
|
|
1699
1723
|
static ID id_pp;
|
1700
1724
|
static ID id_text;
|
1701
1725
|
|
1726
|
+
#if defined(RUBY_VERSION_MAJOR) && RUBY_VERSION_MAJOR == 1 && RUBY_VERSION_MINOR == 8
|
1727
|
+
#define RUBY_1_8
|
1728
|
+
#endif
|
1729
|
+
|
1730
|
+
#ifdef RUBY_1_8
|
1702
1731
|
static VALUE
|
1703
1732
|
pp_group(VALUE args_)
|
1704
1733
|
{
|
1705
1734
|
VALUE* args = (VALUE*)args_;
|
1706
1735
|
return rb_funcall(args[0], id_group, 3, args[1], args[2], args[3]);
|
1707
1736
|
}
|
1737
|
+
#endif
|
1738
|
+
|
1739
|
+
static VALUE
|
1740
|
+
call_group_with_block(VALUE *group_args, VALUE (*blk)(RB_BLOCK_CALL_FUNC_ARGLIST(nil, arg)), VALUE data)
|
1741
|
+
{
|
1742
|
+
#ifdef RUBY_1_8
|
1743
|
+
return rb_iterate(pp_group, (VALUE)&group_args, blk, data);
|
1744
|
+
#else
|
1745
|
+
return rb_block_call(group_args[0], id_group, 3, group_args + 1, blk, data);
|
1746
|
+
#endif
|
1747
|
+
}
|
1708
1748
|
|
1709
1749
|
typedef struct {
|
1710
1750
|
VALUE pp;
|
@@ -1712,26 +1752,28 @@ typedef struct {
|
|
1712
1752
|
} pp_pair_arg_t;
|
1713
1753
|
|
1714
1754
|
static VALUE
|
1715
|
-
pp_value(
|
1755
|
+
pp_value(RB_BLOCK_CALL_FUNC_ARGLIST(nil, arg))
|
1716
1756
|
{
|
1757
|
+
pp_pair_arg_t* pair_arg = (pp_pair_arg_t*)arg;
|
1717
1758
|
VALUE pp = pair_arg->pp;
|
1718
1759
|
rb_funcall(pp, id_breakable, 1, rb_str_new(NULL, 0));
|
1719
1760
|
return rb_funcall(pp, id_pp, 1, GET_VAL(pair_arg->node));
|
1720
1761
|
}
|
1721
1762
|
|
1722
1763
|
static VALUE
|
1723
|
-
pp_pair(
|
1764
|
+
pp_pair(RB_BLOCK_CALL_FUNC_ARGLIST(nil, arg))
|
1724
1765
|
{
|
1766
|
+
pp_pair_arg_t* pair_arg = (pp_pair_arg_t*)arg;
|
1725
1767
|
VALUE pp = pair_arg->pp;
|
1726
1768
|
VALUE group_args[4];
|
1727
1769
|
group_args[0] = pp;
|
1728
1770
|
group_args[1] = INT2FIX(1);
|
1729
1771
|
group_args[2] = rb_str_new(NULL, 0);
|
1730
1772
|
group_args[3] = rb_str_new(NULL, 0);
|
1731
|
-
|
1773
|
+
|
1732
1774
|
rb_funcall(pp, id_pp, 1, GET_KEY(pair_arg->node));
|
1733
1775
|
rb_funcall(pp, id_text, 1, rb_str_new2("=>"));
|
1734
|
-
return
|
1776
|
+
return call_group_with_block(group_args, pp_value, (VALUE)pair_arg);
|
1735
1777
|
}
|
1736
1778
|
|
1737
1779
|
typedef struct {
|
@@ -1745,22 +1787,22 @@ pp_each_pair_i(dnode_t* node, void* each_pair_arg_)
|
|
1745
1787
|
pp_each_pair_arg_t* each_pair_arg = (pp_each_pair_arg_t*)each_pair_arg_;
|
1746
1788
|
VALUE group_args[4];
|
1747
1789
|
pp_pair_arg_t pair_arg;
|
1748
|
-
|
1790
|
+
|
1749
1791
|
if (each_pair_arg->first) {
|
1750
1792
|
each_pair_arg->first = 0;
|
1751
1793
|
} else {
|
1752
1794
|
rb_funcall(each_pair_arg->pp, id_comma_breakable, 0);
|
1753
1795
|
}
|
1754
|
-
|
1796
|
+
|
1755
1797
|
group_args[0] = each_pair_arg->pp;
|
1756
1798
|
group_args[1] = INT2FIX(0);
|
1757
1799
|
group_args[2] = rb_str_new(NULL, 0);
|
1758
1800
|
group_args[3] = rb_str_new(NULL, 0);
|
1759
|
-
|
1801
|
+
|
1760
1802
|
pair_arg.pp = each_pair_arg->pp;
|
1761
1803
|
pair_arg.node = node;
|
1762
|
-
|
1763
|
-
|
1804
|
+
|
1805
|
+
call_group_with_block(group_args, pp_pair, (VALUE)&pair_arg);
|
1764
1806
|
return EACH_NEXT;
|
1765
1807
|
}
|
1766
1808
|
|
@@ -1770,8 +1812,9 @@ typedef struct {
|
|
1770
1812
|
} pp_rbtree_arg_t;
|
1771
1813
|
|
1772
1814
|
static VALUE
|
1773
|
-
pp_each_pair(
|
1815
|
+
pp_each_pair(RB_BLOCK_CALL_FUNC_ARGLIST(nil, arg))
|
1774
1816
|
{
|
1817
|
+
pp_rbtree_arg_t* rbtree_arg = (pp_rbtree_arg_t*)arg;
|
1775
1818
|
pp_each_pair_arg_t each_pair_arg;
|
1776
1819
|
each_pair_arg.pp = rbtree_arg->pp;
|
1777
1820
|
each_pair_arg.first = 1;
|
@@ -1779,19 +1822,20 @@ pp_each_pair(VALUE nil, pp_rbtree_arg_t* rbtree_arg)
|
|
1779
1822
|
}
|
1780
1823
|
|
1781
1824
|
static VALUE
|
1782
|
-
pp_rbtree(
|
1825
|
+
pp_rbtree(RB_BLOCK_CALL_FUNC_ARGLIST(nil, arg))
|
1783
1826
|
{
|
1827
|
+
pp_rbtree_arg_t* rbtree_arg = (pp_rbtree_arg_t*)arg;
|
1784
1828
|
VALUE pp = rbtree_arg->pp;
|
1785
1829
|
VALUE rbtree = rbtree_arg->rbtree;
|
1786
|
-
|
1830
|
+
|
1787
1831
|
VALUE group_args[4];
|
1788
1832
|
group_args[0] = pp;
|
1789
1833
|
group_args[1] = INT2FIX(1);
|
1790
1834
|
group_args[2] = rb_str_new2("{");
|
1791
1835
|
group_args[3] = rb_str_new2("}");
|
1792
|
-
|
1836
|
+
|
1793
1837
|
rb_funcall(pp, id_text, 1, rb_str_new2(": "));
|
1794
|
-
|
1838
|
+
call_group_with_block(group_args, pp_each_pair, (VALUE)rbtree_arg);
|
1795
1839
|
rb_funcall(pp, id_comma_breakable, 0);
|
1796
1840
|
rb_funcall(pp, id_text, 1, rb_str_new2("default="));
|
1797
1841
|
rb_funcall(pp, id_pp, 1, IFNONE(rbtree));
|
@@ -1800,12 +1844,14 @@ pp_rbtree(VALUE nil, pp_rbtree_arg_t* rbtree_arg)
|
|
1800
1844
|
return rb_funcall(pp, id_pp, 1, CMP_PROC(rbtree));
|
1801
1845
|
}
|
1802
1846
|
|
1847
|
+
#ifdef RUBY_1_8
|
1803
1848
|
static VALUE
|
1804
1849
|
pp_rbtree_group(VALUE arg_)
|
1805
1850
|
{
|
1806
1851
|
pp_rbtree_arg_t* arg = (pp_rbtree_arg_t*)arg_;
|
1807
1852
|
return rb_funcall(arg->pp, id_object_group, 1, arg->rbtree);
|
1808
1853
|
}
|
1854
|
+
#endif
|
1809
1855
|
|
1810
1856
|
/*********************************************************************/
|
1811
1857
|
|
@@ -1818,7 +1864,11 @@ rbtree_pretty_print(VALUE self, VALUE pp)
|
|
1818
1864
|
pp_rbtree_arg_t arg;
|
1819
1865
|
arg.rbtree = self;
|
1820
1866
|
arg.pp = pp;
|
1867
|
+
#ifdef RUBY_1_8
|
1821
1868
|
return rb_iterate(pp_rbtree_group, (VALUE)&arg, pp_rbtree, (VALUE)&arg);
|
1869
|
+
#else
|
1870
|
+
return rb_block_call(arg.pp, id_object_group, 1, &self, pp_rbtree, (VALUE)&arg);
|
1871
|
+
#endif
|
1822
1872
|
}
|
1823
1873
|
|
1824
1874
|
/* :nodoc:
|
@@ -1840,17 +1890,17 @@ rbtree_dump(VALUE self, VALUE limit)
|
|
1840
1890
|
{
|
1841
1891
|
VALUE ary;
|
1842
1892
|
VALUE result;
|
1843
|
-
|
1893
|
+
|
1844
1894
|
if (FL_TEST(self, RBTREE_PROC_DEFAULT))
|
1845
1895
|
rb_raise(rb_eTypeError, "can't dump rbtree with default proc");
|
1846
1896
|
if (CMP_PROC(self) != Qnil)
|
1847
1897
|
rb_raise(rb_eTypeError, "can't dump rbtree with comparison proc");
|
1848
|
-
|
1898
|
+
|
1849
1899
|
ary = rb_ary_new2(dict_count(DICT(self)) * 2 + 1);
|
1850
1900
|
rbtree_for_each(self, to_flat_ary_i, (void*)ary);
|
1851
1901
|
rb_ary_push(ary, IFNONE(self));
|
1852
1902
|
|
1853
|
-
result = rb_marshal_dump(ary,
|
1903
|
+
result = rb_marshal_dump(ary, Qnil);
|
1854
1904
|
#ifdef HAVE_RB_ARY_RESIZE
|
1855
1905
|
rb_ary_resize(ary, 0);
|
1856
1906
|
#else
|
@@ -1869,11 +1919,11 @@ rbtree_s_load(VALUE klass, VALUE str)
|
|
1869
1919
|
VALUE ary = rb_marshal_load(str);
|
1870
1920
|
long len = RARRAY_LEN(ary) - 1;
|
1871
1921
|
long i;
|
1872
|
-
|
1922
|
+
|
1873
1923
|
for (i = 0; i < len; i += 2)
|
1874
1924
|
rbtree_aset(rbtree, RARRAY_AREF(ary, i), RARRAY_AREF(ary, i + 1));
|
1875
1925
|
IFNONE(rbtree) = RARRAY_AREF(ary, len);
|
1876
|
-
|
1926
|
+
|
1877
1927
|
#ifdef HAVE_RB_ARY_RESIZE
|
1878
1928
|
rb_ary_resize(ary, 0);
|
1879
1929
|
#else
|
@@ -1893,9 +1943,15 @@ rbtree_s_load(VALUE klass, VALUE str)
|
|
1893
1943
|
* A sorted associative collection that cannot contain duplicate
|
1894
1944
|
* keys. RBTree is a subclass of MultiRBTree.
|
1895
1945
|
*/
|
1896
|
-
void Init_rbtree()
|
1946
|
+
void Init_rbtree(void)
|
1897
1947
|
{
|
1898
|
-
MultiRBTree = rb_define_class("MultiRBTree",
|
1948
|
+
MultiRBTree = rb_define_class("MultiRBTree",
|
1949
|
+
#ifdef HAVE_RB_CDATA
|
1950
|
+
rb_cData
|
1951
|
+
#else
|
1952
|
+
rb_cObject
|
1953
|
+
#endif
|
1954
|
+
);
|
1899
1955
|
RBTree = rb_define_class("RBTree", MultiRBTree);
|
1900
1956
|
|
1901
1957
|
rb_include_module(MultiRBTree, rb_mEnumerable);
|
@@ -1975,7 +2031,7 @@ void Init_rbtree()
|
|
1975
2031
|
|
1976
2032
|
rb_define_method(MultiRBTree, "_dump", rbtree_dump, 1);
|
1977
2033
|
rb_define_singleton_method(MultiRBTree, "_load", rbtree_s_load, 1);
|
1978
|
-
|
2034
|
+
|
1979
2035
|
id_cmp = rb_intern("<=>");
|
1980
2036
|
id_call = rb_intern("call");
|
1981
2037
|
id_default = rb_intern("default");
|
data/test.rb
CHANGED
@@ -620,7 +620,7 @@ class RBTreeTest < Test::Unit::TestCase
|
|
620
620
|
tree, default, cmp_proc = match.to_a[1..-1]
|
621
621
|
assert_equal(%({"a"=>"A", "b"=>"B", "c"=>"C", "d"=>"D"}), tree)
|
622
622
|
assert_equal(%("e"), default)
|
623
|
-
assert_match(/#<Proc:\w+(
|
623
|
+
assert_match(/#<Proc:\w+([@ ]#{__FILE__}:\d+)?>/o, cmp_proc)
|
624
624
|
|
625
625
|
rbtree = RBTree.new
|
626
626
|
assert_match(re, rbtree.send(method))
|
metadata
CHANGED
@@ -1,21 +1,21 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rbtree
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- OZAWA Takuma
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-12-10 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |
|
14
14
|
A RBTree is a sorted associative collection that is implemented with a
|
15
15
|
Red-Black Tree. It maps keys to values like a Hash, but maintains its
|
16
16
|
elements in ascending key order. The interface is the almost identical
|
17
17
|
to that of Hash.
|
18
|
-
email:
|
18
|
+
email:
|
19
19
|
executables: []
|
20
20
|
extensions:
|
21
21
|
- extconf.rb
|
@@ -36,7 +36,7 @@ homepage: http://rbtree.rubyforge.org/
|
|
36
36
|
licenses:
|
37
37
|
- MIT
|
38
38
|
metadata: {}
|
39
|
-
post_install_message:
|
39
|
+
post_install_message:
|
40
40
|
rdoc_options:
|
41
41
|
- "--title"
|
42
42
|
- Ruby/RBTree
|
@@ -57,10 +57,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
57
57
|
- !ruby/object:Gem::Version
|
58
58
|
version: '0'
|
59
59
|
requirements: []
|
60
|
-
|
61
|
-
|
62
|
-
signing_key:
|
60
|
+
rubygems_version: 3.4.0.dev
|
61
|
+
signing_key:
|
63
62
|
specification_version: 4
|
64
63
|
summary: A sorted associative collection.
|
65
|
-
test_files:
|
66
|
-
- test.rb
|
64
|
+
test_files: []
|