rbtree 0.4.2 → 0.4.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. checksums.yaml +5 -5
  2. data/README +8 -12
  3. data/extconf.rb +3 -0
  4. data/rbtree.c +141 -85
  5. data/test.rb +1 -1
  6. metadata +8 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 35a51532a317785f995191b86990fd197d3a08d7
4
- data.tar.gz: fc58dc292ed9763c6b8731ca2998c6affe591007
2
+ SHA256:
3
+ metadata.gz: a5ec1fb39918d82821706cea18cb63b25fd4d20a989579664f7b95774f43881f
4
+ data.tar.gz: 3795d33cbbf811cdfd7b92664eca4156760c8d3bb36fa28a9854720279c6c1dd
5
5
  SHA512:
6
- metadata.gz: 75b7c55bd29b9341ae5969742855aa15893af18574d7c5ff734ea8e52b3e25f1ccb290c72bb27b58ae8e61db533b2d04b15cab80ff3e64239aee02f63591be35
7
- data.tar.gz: d1b1c0def86af19fd6b6a2bdcf7e2147b3f0e1ea340276d283884ee50b7fe3bd91c5f55e7495dcda3652fd9443b55d930044ce007ab707dc196cca3f45834011
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.2
61
- * Fixed build failure with Ruby 2.1.0.
60
+ === 0.4.6
61
+ * Make it work with clang 15.
62
62
 
63
- === 0.4.1
64
- * Fixed a crash that could be triggered when GC happened.
63
+ === 0.4.5
64
+ * Support Ruby 3.2.0-dev (development branch).
65
65
 
66
- === 0.4.0
66
+ === 0.4.4
67
+ * Remove the rb_safe_level warning on Ruby 2.7.
67
68
 
68
- * Fixed build failure with Ruby 2.0.0.
69
- * \#bound now returns an enumerator if no block is given.
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(rbtree_t* rbtree)
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* args)
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(rbtree_insert_arg_t* arg)
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(rbtree_insert_arg_t* arg)
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(rbtree_each_arg_t* arg)
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(rbtree_remove_if_arg_t* arg)
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(rbtree_remove_if_arg_t* arg)
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
- OBJ_INFECT(ary, self);
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
- OBJ_INFECT(hash, self);
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
- OBJ_INFECT(result, str);
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
- OBJ_INFECT(result, str);
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
- OBJ_INFECT(result, str);
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
- OBJ_INFECT(result, str);
1392
+ RBTREE_OBJ_INFECT(result, str);
1370
1393
 
1371
1394
  rb_str_cat2(result, ">");
1372
- OBJ_INFECT(result, self);
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(rbtree_bound_arg_t* arg)
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(VALUE nil, pp_pair_arg_t* pair_arg)
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(VALUE nil, pp_pair_arg_t* pair_arg)
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 rb_iterate(pp_group, (VALUE)&group_args, pp_value, (VALUE)pair_arg);
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
- rb_iterate(pp_group, (VALUE)&group_args, pp_pair, (VALUE)&pair_arg);
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(VALUE nil, pp_rbtree_arg_t* rbtree_arg)
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(VALUE nil, pp_rbtree_arg_t* rbtree_arg)
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
- rb_iterate(pp_group, (VALUE)&group_args, pp_each_pair, (VALUE)rbtree_arg);
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, limit);
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", rb_cData);
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+(@#{__FILE__}:\d+)?>/o, cmp_proc)
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.2
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: 2013-12-26 00:00:00.000000000 Z
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
- rubyforge_project: rbtree
61
- rubygems_version: 2.2.0
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: []