rbtree 0.4.2 → 0.4.6
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.
- 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: []
|