rbtree 0.4.1 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (8) hide show
  1. checksums.yaml +4 -4
  2. data/README +3 -6
  3. data/dict.c +309 -4
  4. data/dict.h +3 -3
  5. data/extconf.rb +2 -1
  6. data/rbtree.c +74 -73
  7. data/test.rb +17 -19
  8. metadata +9 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 42305188c5448bb5c684e198069f323816d32d5a
4
- data.tar.gz: f1d5608adf7f2c1d142048d5abbe499d11cc83a6
3
+ metadata.gz: 35a51532a317785f995191b86990fd197d3a08d7
4
+ data.tar.gz: fc58dc292ed9763c6b8731ca2998c6affe591007
5
5
  SHA512:
6
- metadata.gz: 892207ef1dc38a23044b15480bcd57a4ab722cc944131f1d56d1878aa668b539d0c10f6a0cdd6c52b7d3255e17c14fb466ed898a3bc56fbe0e15472da912a888
7
- data.tar.gz: c2a3503fcc68622ab775d421843b25d07afa7f1702e870ad57a600f3c06b904179c86d62bc6dd3d6c86e5948af09f95e37998de35fb7c8e48e00c4478fae9e15
6
+ metadata.gz: 75b7c55bd29b9341ae5969742855aa15893af18574d7c5ff734ea8e52b3e25f1ccb290c72bb27b58ae8e61db533b2d04b15cab80ff3e64239aee02f63591be35
7
+ data.tar.gz: d1b1c0def86af19fd6b6a2bdcf7e2147b3f0e1ea340276d283884ee50b7fe3bd91c5f55e7495dcda3652fd9443b55d930044ce007ab707dc196cca3f45834011
data/README CHANGED
@@ -57,6 +57,9 @@ 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.
62
+
60
63
  === 0.4.1
61
64
  * Fixed a crash that could be triggered when GC happened.
62
65
 
@@ -78,9 +81,3 @@ dict.c and dict.h are modified copies that are originally in Kazlib
78
81
  1.20 written by Kaz Kylheku. Its license is similar to the MIT
79
82
  license. See dict.c and dict.h for the details. The web page of Kazlib
80
83
  is at http://www.kylheku.com/~kaz/kazlib.html.
81
-
82
- == Contact
83
-
84
- Run the following command.
85
-
86
- $ ruby -e "puts 'YnVybmluZ2Rvd250aGVvcGVyYUB5YWhvby5jby5qcA==\n'.unpack('m')"
data/dict.c CHANGED
@@ -14,12 +14,12 @@
14
14
  * into proprietary software; there is no requirement for such software to
15
15
  * contain a copyright notice related to this source.
16
16
  *
17
- * $Id: dict.c,v 1.15 2005/10/06 05:16:35 kuma Exp $
18
- * $Name: $
17
+ * $Id: dict.c,v 1.40.2.7 2000/11/13 01:36:44 kaz Exp $
18
+ * $Name: kazlib_1_20 $
19
19
  */
20
20
 
21
21
  /*
22
- * Modified for Ruby/RBTree by OZAWA Takuma.
22
+ * Modified for Ruby/RBTree.
23
23
  */
24
24
 
25
25
  #include <stdlib.h>
@@ -29,7 +29,7 @@
29
29
  #include "dict.h"
30
30
 
31
31
  #ifdef KAZLIB_RCSID
32
- static const char rcsid[] = "$Id: dict.c,v 1.15 2005/10/06 05:16:35 kuma Exp $";
32
+ static const char rcsid[] = "$Id: dict.c,v 1.40.2.7 2000/11/13 01:36:44 kaz Exp $";
33
33
  #endif
34
34
 
35
35
  /*
@@ -1190,3 +1190,308 @@ void dict_merge(dict_t *dest, dict_t *source)
1190
1190
  dict_clear(source);
1191
1191
  dict_load_end(&load);
1192
1192
  }
1193
+
1194
+ #ifdef KAZLIB_TEST_MAIN
1195
+
1196
+ #include <stdio.h>
1197
+ #include <string.h>
1198
+ #include <ctype.h>
1199
+ #include <stdarg.h>
1200
+
1201
+ typedef char input_t[256];
1202
+
1203
+ static int tokenize(char *string, ...)
1204
+ {
1205
+ char **tokptr;
1206
+ va_list arglist;
1207
+ int tokcount = 0;
1208
+
1209
+ va_start(arglist, string);
1210
+ tokptr = va_arg(arglist, char **);
1211
+ while (tokptr) {
1212
+ while (*string && isspace((unsigned char) *string))
1213
+ string++;
1214
+ if (!*string)
1215
+ break;
1216
+ *tokptr = string;
1217
+ while (*string && !isspace((unsigned char) *string))
1218
+ string++;
1219
+ tokptr = va_arg(arglist, char **);
1220
+ tokcount++;
1221
+ if (!*string)
1222
+ break;
1223
+ *string++ = 0;
1224
+ }
1225
+ va_end(arglist);
1226
+
1227
+ return tokcount;
1228
+ }
1229
+
1230
+ static int comparef(const void *key1, const void *key2)
1231
+ {
1232
+ return strcmp(key1, key2);
1233
+ }
1234
+
1235
+ static char *dupstring(char *str)
1236
+ {
1237
+ int sz = strlen(str) + 1;
1238
+ char *new = malloc(sz);
1239
+ if (new)
1240
+ memcpy(new, str, sz);
1241
+ return new;
1242
+ }
1243
+
1244
+ static dnode_t *new_node(void *c)
1245
+ {
1246
+ static dnode_t few[5];
1247
+ static int count;
1248
+
1249
+ if (count < 5)
1250
+ return few + count++;
1251
+
1252
+ return NULL;
1253
+ }
1254
+
1255
+ static void del_node(dnode_t *n, void *c)
1256
+ {
1257
+ }
1258
+
1259
+ static int prompt = 0;
1260
+
1261
+ static void construct(dict_t *d)
1262
+ {
1263
+ input_t in;
1264
+ int done = 0;
1265
+ dict_load_t dl;
1266
+ dnode_t *dn;
1267
+ char *tok1, *tok2, *val;
1268
+ const char *key;
1269
+ char *help =
1270
+ "p turn prompt on\n"
1271
+ "q finish construction\n"
1272
+ "a <key> <val> add new entry\n";
1273
+
1274
+ if (!dict_isempty(d))
1275
+ puts("warning: dictionary not empty!");
1276
+
1277
+ dict_load_begin(&dl, d);
1278
+
1279
+ while (!done) {
1280
+ if (prompt)
1281
+ putchar('>');
1282
+ fflush(stdout);
1283
+
1284
+ if (!fgets(in, sizeof(input_t), stdin))
1285
+ break;
1286
+
1287
+ switch (in[0]) {
1288
+ case '?':
1289
+ puts(help);
1290
+ break;
1291
+ case 'p':
1292
+ prompt = 1;
1293
+ break;
1294
+ case 'q':
1295
+ done = 1;
1296
+ break;
1297
+ case 'a':
1298
+ if (tokenize(in+1, &tok1, &tok2, (char **) 0) != 2) {
1299
+ puts("what?");
1300
+ break;
1301
+ }
1302
+ key = dupstring(tok1);
1303
+ val = dupstring(tok2);
1304
+ dn = dnode_create(val);
1305
+
1306
+ if (!key || !val || !dn) {
1307
+ puts("out of memory");
1308
+ free((void *) key);
1309
+ free(val);
1310
+ if (dn)
1311
+ dnode_destroy(dn);
1312
+ }
1313
+
1314
+ dict_load_next(&dl, dn, key);
1315
+ break;
1316
+ default:
1317
+ putchar('?');
1318
+ putchar('\n');
1319
+ break;
1320
+ }
1321
+ }
1322
+
1323
+ dict_load_end(&dl);
1324
+ }
1325
+
1326
+ int main(void)
1327
+ {
1328
+ input_t in;
1329
+ dict_t darray[10];
1330
+ dict_t *d = &darray[0];
1331
+ dnode_t *dn;
1332
+ int i;
1333
+ char *tok1, *tok2, *val;
1334
+ const char *key;
1335
+
1336
+ char *help =
1337
+ "a <key> <val> add value to dictionary\n"
1338
+ "d <key> delete value from dictionary\n"
1339
+ "l <key> lookup value in dictionary\n"
1340
+ "( <key> lookup lower bound\n"
1341
+ ") <key> lookup upper bound\n"
1342
+ "# <num> switch to alternate dictionary (0-9)\n"
1343
+ "j <num> <num> merge two dictionaries\n"
1344
+ "f free the whole dictionary\n"
1345
+ "k allow duplicate keys\n"
1346
+ "c show number of entries\n"
1347
+ "t dump whole dictionary in sort order\n"
1348
+ "m make dictionary out of sorted items\n"
1349
+ "p turn prompt on\n"
1350
+ "s switch to non-functioning allocator\n"
1351
+ "q quit";
1352
+
1353
+ for (i = 0; i < sizeof darray / sizeof *darray; i++)
1354
+ dict_init(&darray[i], DICTCOUNT_T_MAX, comparef);
1355
+
1356
+ for (;;) {
1357
+ if (prompt)
1358
+ putchar('>');
1359
+ fflush(stdout);
1360
+
1361
+ if (!fgets(in, sizeof(input_t), stdin))
1362
+ break;
1363
+
1364
+ switch(in[0]) {
1365
+ case '?':
1366
+ puts(help);
1367
+ break;
1368
+ case 'a':
1369
+ if (tokenize(in+1, &tok1, &tok2, (char **) 0) != 2) {
1370
+ puts("what?");
1371
+ break;
1372
+ }
1373
+ key = dupstring(tok1);
1374
+ val = dupstring(tok2);
1375
+
1376
+ if (!key || !val) {
1377
+ puts("out of memory");
1378
+ free((void *) key);
1379
+ free(val);
1380
+ }
1381
+
1382
+ if (!dict_alloc_insert(d, key, val)) {
1383
+ puts("dict_alloc_insert failed");
1384
+ free((void *) key);
1385
+ free(val);
1386
+ break;
1387
+ }
1388
+ break;
1389
+ case 'd':
1390
+ if (tokenize(in+1, &tok1, (char **) 0) != 1) {
1391
+ puts("what?");
1392
+ break;
1393
+ }
1394
+ dn = dict_lookup(d, tok1);
1395
+ if (!dn) {
1396
+ puts("dict_lookup failed");
1397
+ break;
1398
+ }
1399
+ val = dnode_get(dn);
1400
+ key = dnode_getkey(dn);
1401
+ dict_delete_free(d, dn);
1402
+
1403
+ free(val);
1404
+ free((void *) key);
1405
+ break;
1406
+ case 'f':
1407
+ dict_free(d);
1408
+ break;
1409
+ case 'l':
1410
+ case '(':
1411
+ case ')':
1412
+ if (tokenize(in+1, &tok1, (char **) 0) != 1) {
1413
+ puts("what?");
1414
+ break;
1415
+ }
1416
+ dn = 0;
1417
+ switch (in[0]) {
1418
+ case 'l':
1419
+ dn = dict_lookup(d, tok1);
1420
+ break;
1421
+ case '(':
1422
+ dn = dict_lower_bound(d, tok1);
1423
+ break;
1424
+ case ')':
1425
+ dn = dict_upper_bound(d, tok1);
1426
+ break;
1427
+ }
1428
+ if (!dn) {
1429
+ puts("lookup failed");
1430
+ break;
1431
+ }
1432
+ val = dnode_get(dn);
1433
+ puts(val);
1434
+ break;
1435
+ case 'm':
1436
+ construct(d);
1437
+ break;
1438
+ case 'k':
1439
+ dict_allow_dupes(d);
1440
+ break;
1441
+ case 'c':
1442
+ printf("%lu\n", (unsigned long) dict_count(d));
1443
+ break;
1444
+ case 't':
1445
+ for (dn = dict_first(d); dn; dn = dict_next(d, dn)) {
1446
+ printf("%s\t%s\n", (char *) dnode_getkey(dn),
1447
+ (char *) dnode_get(dn));
1448
+ }
1449
+ break;
1450
+ case 'q':
1451
+ exit(0);
1452
+ break;
1453
+ case '\0':
1454
+ break;
1455
+ case 'p':
1456
+ prompt = 1;
1457
+ break;
1458
+ case 's':
1459
+ dict_set_allocator(d, new_node, del_node, NULL);
1460
+ break;
1461
+ case '#':
1462
+ if (tokenize(in+1, &tok1, (char **) 0) != 1) {
1463
+ puts("what?");
1464
+ break;
1465
+ } else {
1466
+ int dictnum = atoi(tok1);
1467
+ if (dictnum < 0 || dictnum > 9) {
1468
+ puts("invalid number");
1469
+ break;
1470
+ }
1471
+ d = &darray[dictnum];
1472
+ }
1473
+ break;
1474
+ case 'j':
1475
+ if (tokenize(in+1, &tok1, &tok2, (char **) 0) != 2) {
1476
+ puts("what?");
1477
+ break;
1478
+ } else {
1479
+ int dict1 = atoi(tok1), dict2 = atoi(tok2);
1480
+ if (dict1 < 0 || dict1 > 9 || dict2 < 0 || dict2 > 9) {
1481
+ puts("invalid number");
1482
+ break;
1483
+ }
1484
+ dict_merge(&darray[dict1], &darray[dict2]);
1485
+ }
1486
+ break;
1487
+ default:
1488
+ putchar('?');
1489
+ putchar('\n');
1490
+ break;
1491
+ }
1492
+ }
1493
+
1494
+ return 0;
1495
+ }
1496
+
1497
+ #endif
data/dict.h CHANGED
@@ -14,12 +14,12 @@
14
14
  * into proprietary software; there is no requirement for such software to
15
15
  * contain a copyright notice related to this source.
16
16
  *
17
- * $Id: dict.h,v 1.9 2005/10/06 05:16:35 kuma Exp $
18
- * $Name: $
17
+ * $Id: dict.h,v 1.22.2.6 2000/11/13 01:36:44 kaz Exp $
18
+ * $Name: kazlib_1_20 $
19
19
  */
20
20
 
21
21
  /*
22
- * Modified for Ruby/RBTree by OZAWA Takuma.
22
+ * Modified for Ruby/RBTree.
23
23
  */
24
24
 
25
25
  #ifndef DICT_H
data/extconf.rb CHANGED
@@ -5,10 +5,11 @@ if enable_config('debug')
5
5
  else
6
6
  $defs << '-DNDEBUG'
7
7
  end
8
- have_header('ruby/st.h')
9
8
  have_func('rb_exec_recursive', 'ruby.h')
10
9
  have_func('rb_exec_recursive_paired', 'ruby.h')
11
10
  have_func('rb_proc_lambda_p', 'ruby.h')
11
+ have_func('rb_ary_resize', 'ruby.h')
12
+ have_func('rb_obj_hide', 'ruby.h')
12
13
  if Hash.method_defined?(:flatten)
13
14
  $defs << '-DHAVE_HASH_FLATTEN'
14
15
  end
data/rbtree.c CHANGED
@@ -23,11 +23,12 @@
23
23
  #endif
24
24
  #endif
25
25
 
26
- #ifndef RHASH_TBL
27
- #define RHASH_TBL(h) RHASH(h)->tbl
26
+ #ifndef RARRAY_AREF
27
+ #define RARRAY_AREF(a, i) (RARRAY_PTR(a)[i])
28
28
  #endif
29
- #ifndef RHASH_IFNONE
30
- #define RHASH_IFNONE(h) RHASH(h)->ifnone
29
+
30
+ #ifndef RHASH_SET_IFNONE
31
+ #define RHASH_SET_IFNONE(h, v) (RHASH(h)->ifnone = (v))
31
32
  #endif
32
33
 
33
34
  VALUE RBTree;
@@ -100,15 +101,17 @@ rbtree_free_node(dnode_t* node, void* context)
100
101
  }
101
102
 
102
103
  static void
103
- rbtree_argc_error(const int argc, const int min, const int max)
104
- {
105
- const char* message = "wrong number of arguments";
106
- if (min == max) {
107
- rb_raise(rb_eArgError, "%s (%d for %d)", message, argc, min);
108
- } else if (max == INT_MAX) {
109
- rb_raise(rb_eArgError, "%s (%d for %d+)", message, argc, -min - 1);
110
- } else {
111
- rb_raise(rb_eArgError, "%s (%d for %d..%d)", message, argc, min, max);
104
+ rbtree_check_argument_count(const int argc, const int min, const int max)
105
+ {
106
+ if (argc < min || argc > max) {
107
+ static const char* const message = "wrong number of arguments";
108
+ if (min == max) {
109
+ rb_raise(rb_eArgError, "%s (%d for %d)", message, argc, min);
110
+ } else if (max == INT_MAX) {
111
+ rb_raise(rb_eArgError, "%s (%d for %d+)", message, argc, -min - 1);
112
+ } else {
113
+ rb_raise(rb_eArgError, "%s (%d for %d..%d)", message, argc, min, max);
114
+ }
112
115
  }
113
116
  }
114
117
 
@@ -181,7 +184,7 @@ static VALUE
181
184
  rbtree_alloc(VALUE klass)
182
185
  {
183
186
  dict_t* dict;
184
- VALUE rbtree = Data_Wrap_Struct(klass, rbtree_mark, rbtree_free, 0);
187
+ VALUE rbtree = Data_Wrap_Struct(klass, rbtree_mark, rbtree_free, NULL);
185
188
  RBTREE(rbtree) = ALLOC(rbtree_t);
186
189
  MEMZERO(RBTREE(rbtree), rbtree_t, 1);
187
190
 
@@ -248,18 +251,18 @@ rbtree_s_create(int argc, VALUE* argv, VALUE klass)
248
251
  if (!NIL_P(temp)) {
249
252
  rbtree = rbtree_alloc(klass);
250
253
  for (i = 0; i < RARRAY_LEN(temp); i++) {
251
- VALUE v = rb_check_array_type(RARRAY_PTR(temp)[i]);
254
+ VALUE v = rb_check_array_type(RARRAY_AREF(temp, i));
252
255
  if (NIL_P(v)) {
253
256
  rb_warn("wrong element type %s at %ld (expected Array)",
254
- rb_obj_classname(RARRAY_PTR(temp)[i]), i);
257
+ rb_obj_classname(RARRAY_AREF(temp, i)), i);
255
258
  continue;
256
259
  }
257
260
  switch(RARRAY_LEN(v)) {
258
261
  case 1:
259
- rbtree_aset(rbtree, RARRAY_PTR(v)[0], Qnil);
262
+ rbtree_aset(rbtree, RARRAY_AREF(v, 0), Qnil);
260
263
  break;
261
264
  case 2:
262
- rbtree_aset(rbtree, RARRAY_PTR(v)[0], RARRAY_PTR(v)[1]);
265
+ rbtree_aset(rbtree, RARRAY_AREF(v, 0), RARRAY_AREF(v, 1));
263
266
  break;
264
267
  default:
265
268
  rb_warn("invalid number of elements (%ld for 1..2)",
@@ -289,17 +292,14 @@ rbtree_initialize(int argc, VALUE* argv, VALUE self)
289
292
 
290
293
  if (rb_block_given_p()) {
291
294
  VALUE proc;
292
- if (argc > 0) {
293
- rbtree_argc_error(argc, 0, 0);
294
- }
295
+ rbtree_check_argument_count(argc, 0, 0);
295
296
  proc = rb_block_proc();
296
297
  rbtree_check_proc_arity(proc, 2);
297
298
  IFNONE(self) = proc;
298
299
  FL_SET(self, RBTREE_PROC_DEFAULT);
299
300
  } else {
300
- if (argc > 1) {
301
- rbtree_argc_error(argc, 1, 1);
302
- } else if (argc == 1) {
301
+ rbtree_check_argument_count(argc, 0, 1);
302
+ if (argc == 1) {
303
303
  IFNONE(self) = argv[0];
304
304
  }
305
305
  }
@@ -418,12 +418,9 @@ rbtree_fetch(int argc, VALUE* argv, VALUE self)
418
418
  {
419
419
  dnode_t* node;
420
420
 
421
- if (argc == 0 || argc > 2) {
422
- rbtree_argc_error(argc, 1, 2);
423
- } else if (argc == 2) {
424
- if (rb_block_given_p()) {
425
- rb_warn("block supersedes default value argument");
426
- }
421
+ rbtree_check_argument_count(argc, 1, 2);
422
+ if (argc == 2 && rb_block_given_p()) {
423
+ rb_warn("block supersedes default value argument");
427
424
  }
428
425
 
429
426
  node = dict_lookup(DICT(self), TO_KEY(argv[0]));
@@ -464,9 +461,7 @@ rbtree_empty_p(VALUE self)
464
461
  VALUE
465
462
  rbtree_default(int argc, VALUE* argv, VALUE self)
466
463
  {
467
- if (argc > 1) {
468
- rbtree_argc_error(argc, 0, 1);
469
- }
464
+ rbtree_check_argument_count(argc, 0, 1);
470
465
  if (FL_TEST(self, RBTREE_PROC_DEFAULT)) {
471
466
  if (argc == 0) {
472
467
  return Qnil;
@@ -752,7 +747,11 @@ static void
752
747
  copy_dict(VALUE src, VALUE dest, dict_comp_t cmp_func, VALUE cmp_proc)
753
748
  {
754
749
  VALUE temp = rbtree_alloc(CLASS_OF(dest));
750
+ #ifdef HAVE_RB_OBJ_HIDE
751
+ rb_obj_hide(temp);
752
+ #else
755
753
  RBASIC(temp)->klass = 0;
754
+ #endif
756
755
  DICT(temp)->dict_compare = cmp_func;
757
756
  CMP_PROC(temp) = cmp_proc;
758
757
 
@@ -763,6 +762,7 @@ copy_dict(VALUE src, VALUE dest, dict_comp_t cmp_func, VALUE cmp_proc)
763
762
  DICT(dest) = t;
764
763
  }
765
764
  rbtree_free(RBTREE(temp));
765
+ RBTREE(temp) = NULL;
766
766
  rb_gc_force_recycle(temp);
767
767
 
768
768
  DICT(dest)->dict_context = RBTREE(dest);
@@ -840,9 +840,8 @@ VALUE
840
840
  rbtree_index(VALUE self, VALUE value)
841
841
  {
842
842
  VALUE klass = rb_obj_is_kind_of(self, RBTree) ? RBTree : MultiRBTree;
843
- volatile VALUE class_name = rb_class_name(klass);
844
- rb_warn("%s#index is deprecated; use %s#key",
845
- RSTRING_PTR(class_name), RSTRING_PTR(class_name));
843
+ const char* classname = rb_class2name(klass);
844
+ rb_warn("%s#index is deprecated; use %s#key", classname, classname);
846
845
  return rbtree_key(self, value);
847
846
  }
848
847
 
@@ -1163,6 +1162,14 @@ rbtree_merge(VALUE self, VALUE other)
1163
1162
  return rbtree_update(rb_obj_dup(self), other);
1164
1163
  }
1165
1164
 
1165
+ static each_return_t
1166
+ to_flat_ary_i(dnode_t* node, void* ary)
1167
+ {
1168
+ rb_ary_push((VALUE)ary, GET_KEY(node));
1169
+ rb_ary_push((VALUE)ary, GET_VAL(node));
1170
+ return EACH_NEXT;
1171
+ }
1172
+
1166
1173
  /*
1167
1174
  *
1168
1175
  */
@@ -1170,15 +1177,17 @@ VALUE
1170
1177
  rbtree_flatten(int argc, VALUE* argv, VALUE self)
1171
1178
  {
1172
1179
  VALUE ary;
1173
- VALUE level;
1174
-
1175
- ary = rbtree_to_a(self);
1176
- if (argc == 0) {
1177
- argc = 1;
1178
- level = INT2FIX(1);
1179
- argv = &level;
1180
+
1181
+ rbtree_check_argument_count(argc, 0, 1);
1182
+ ary = rb_ary_new2(dict_count(DICT(self)) * 2);
1183
+ rbtree_for_each(self, to_flat_ary_i, (void*)ary);
1184
+ if (argc == 1) {
1185
+ const int level = NUM2INT(argv[0]) - 1;
1186
+ if (level > 0) {
1187
+ argv[0] = INT2FIX(level);
1188
+ rb_funcall2(ary, id_flatten_bang, argc, argv);
1189
+ }
1180
1190
  }
1181
- rb_funcall2(ary, id_flatten_bang, argc, argv);
1182
1191
  return ary;
1183
1192
  }
1184
1193
 
@@ -1289,7 +1298,7 @@ rbtree_to_hash(VALUE self)
1289
1298
 
1290
1299
  hash = rb_hash_new();
1291
1300
  rbtree_for_each(self, to_hash_i, (void*)hash);
1292
- RHASH_IFNONE(hash) = IFNONE(self);
1301
+ RHASH_SET_IFNONE(hash, IFNONE(self));
1293
1302
  if (FL_TEST(self, RBTREE_PROC_DEFAULT))
1294
1303
  FL_SET(hash, HASH_PROC_DEFAULT);
1295
1304
  OBJ_INFECT(hash, self);
@@ -1308,10 +1317,10 @@ rbtree_to_rbtree(VALUE self)
1308
1317
  static VALUE
1309
1318
  rbtree_begin_inspect(VALUE self)
1310
1319
  {
1311
- volatile VALUE class_name = rb_class_name(CLASS_OF(self));
1312
- VALUE str = rb_str_new(NULL, RSTRING_LEN(class_name) + 4);
1313
- sprintf(RSTRING_PTR(str), "#<%s: ", RSTRING_PTR(class_name));
1314
- return str;
1320
+ VALUE result = rb_str_new2("#<");
1321
+ rb_str_cat2(result, rb_obj_classname(self));
1322
+ rb_str_cat2(result, ": ");
1323
+ return result;
1315
1324
  }
1316
1325
 
1317
1326
  static each_return_t
@@ -1480,8 +1489,8 @@ rbtree_bound_body(rbtree_bound_arg_t* arg)
1480
1489
  static VALUE
1481
1490
  rbtree_bound_size(VALUE self, VALUE args)
1482
1491
  {
1483
- VALUE key1 = RARRAY_PTR(args)[0];
1484
- VALUE key2 = RARRAY_PTR(args)[RARRAY_LEN(args) - 1];
1492
+ VALUE key1 = RARRAY_AREF(args, 0);
1493
+ VALUE key2 = RARRAY_AREF(args, RARRAY_LEN(args) - 1);
1485
1494
  dnode_t* lower_node = dict_lower_bound(DICT(self), TO_KEY(key1));
1486
1495
  dnode_t* upper_node = dict_upper_bound(DICT(self), TO_KEY(key2));
1487
1496
  dictcount_t count = 0;
@@ -1536,9 +1545,7 @@ rbtree_bound(int argc, VALUE* argv, VALUE self)
1536
1545
  dnode_t* upper_node;
1537
1546
  VALUE result;
1538
1547
 
1539
- if (argc == 0 || argc > 2) {
1540
- rbtree_argc_error(argc, 1, 2);
1541
- }
1548
+ rbtree_check_argument_count(argc, 1, 2);
1542
1549
 
1543
1550
  RETURN_SIZED_ENUMERATOR(self, argc, argv, rbtree_bound_size);
1544
1551
 
@@ -1633,17 +1640,16 @@ rbtree_readjust(int argc, VALUE* argv, VALUE self)
1633
1640
  rbtree_modify(self);
1634
1641
 
1635
1642
  if (rb_block_given_p()) {
1636
- if (argc != 0) {
1637
- rbtree_argc_error(argc, 0, 0);
1638
- }
1643
+ rbtree_check_argument_count(argc, 0, 0);
1639
1644
  cmp_func = rbtree_user_cmp;
1640
1645
  cmp_proc = rb_block_proc();
1641
1646
  rbtree_check_proc_arity(cmp_proc, 2);
1642
1647
  } else {
1648
+ rbtree_check_argument_count(argc, 0, 1);
1643
1649
  if (argc == 0) {
1644
1650
  cmp_func = DICT(self)->dict_compare;
1645
1651
  cmp_proc = CMP_PROC(self);
1646
- } else if (argc == 1) {
1652
+ } else {
1647
1653
  if (NIL_P(argv[0])) {
1648
1654
  cmp_func = rbtree_cmp;
1649
1655
  cmp_proc = Qnil;
@@ -1658,8 +1664,6 @@ rbtree_readjust(int argc, VALUE* argv, VALUE self)
1658
1664
  cmp_proc = proc;
1659
1665
  rbtree_check_proc_arity(cmp_proc, 2);
1660
1666
  }
1661
- } else {
1662
- rbtree_argc_error(argc, 0, 1);
1663
1667
  }
1664
1668
  }
1665
1669
 
@@ -1828,14 +1832,6 @@ rbtree_pretty_print_cycle(VALUE self, VALUE pp)
1828
1832
 
1829
1833
  /*********************************************************************/
1830
1834
 
1831
- static each_return_t
1832
- to_flat_ary_i(dnode_t* node, void* ary)
1833
- {
1834
- rb_ary_push((VALUE)ary, GET_KEY(node));
1835
- rb_ary_push((VALUE)ary, GET_VAL(node));
1836
- return EACH_NEXT;
1837
- }
1838
-
1839
1835
  /* :nodoc:
1840
1836
  *
1841
1837
  */
@@ -1855,8 +1851,11 @@ rbtree_dump(VALUE self, VALUE limit)
1855
1851
  rb_ary_push(ary, IFNONE(self));
1856
1852
 
1857
1853
  result = rb_marshal_dump(ary, limit);
1854
+ #ifdef HAVE_RB_ARY_RESIZE
1855
+ rb_ary_resize(ary, 0);
1856
+ #else
1858
1857
  rb_ary_clear(ary);
1859
- rb_gc_force_recycle(ary);
1858
+ #endif
1860
1859
  return result;
1861
1860
  }
1862
1861
 
@@ -1868,16 +1867,18 @@ rbtree_s_load(VALUE klass, VALUE str)
1868
1867
  {
1869
1868
  VALUE rbtree = rbtree_alloc(klass);
1870
1869
  VALUE ary = rb_marshal_load(str);
1871
- VALUE* ptr = RARRAY_PTR(ary);
1872
1870
  long len = RARRAY_LEN(ary) - 1;
1873
1871
  long i;
1874
1872
 
1875
1873
  for (i = 0; i < len; i += 2)
1876
- rbtree_aset(rbtree, ptr[i], ptr[i + 1]);
1877
- IFNONE(rbtree) = ptr[len];
1874
+ rbtree_aset(rbtree, RARRAY_AREF(ary, i), RARRAY_AREF(ary, i + 1));
1875
+ IFNONE(rbtree) = RARRAY_AREF(ary, len);
1878
1876
 
1877
+ #ifdef HAVE_RB_ARY_RESIZE
1878
+ rb_ary_resize(ary, 0);
1879
+ #else
1879
1880
  rb_ary_clear(ary);
1880
- rb_gc_force_recycle(ary);
1881
+ #endif
1881
1882
  return rbtree;
1882
1883
  }
1883
1884
 
data/test.rb CHANGED
@@ -11,6 +11,10 @@ class RBTreeTest < Test::Unit::TestCase
11
11
  @rbtree = RBTree[*%w(b B d D a A c C)]
12
12
  end
13
13
 
14
+ def have_enumerator?
15
+ defined?(Enumerable::Enumerator) or defined?(Enumerator)
16
+ end
17
+
14
18
  def test_new
15
19
  assert_nothing_raised {
16
20
  RBTree.new
@@ -250,12 +254,6 @@ class RBTreeTest < Test::Unit::TestCase
250
254
  b[1] = b
251
255
  assert_equal(a, b)
252
256
  end
253
-
254
- # a = RBTree.new
255
- # a[1] = a
256
- # b = RBTree.new
257
- # b[1] = a
258
- # assert_not_equal(a, b)
259
257
  end
260
258
 
261
259
  def test_fetch
@@ -304,7 +302,7 @@ class RBTreeTest < Test::Unit::TestCase
304
302
  }
305
303
  assert_equal(4, @rbtree.size)
306
304
 
307
- if defined?(Enumerable::Enumerator) or defined?(Enumerator)
305
+ if have_enumerator?
308
306
  enumerator = @rbtree.each
309
307
  assert_equal(%w(a A b B c C d D), enumerator.to_a.flatten)
310
308
  end
@@ -329,7 +327,7 @@ class RBTreeTest < Test::Unit::TestCase
329
327
  }
330
328
  assert_equal(4, @rbtree.size)
331
329
 
332
- if defined?(Enumerable::Enumerator) or defined?(Enumerator)
330
+ if have_enumerator?
333
331
  enumerator = @rbtree.each_key
334
332
  assert_equal(%w(a b c d), enumerator.to_a.flatten)
335
333
  end
@@ -354,7 +352,7 @@ class RBTreeTest < Test::Unit::TestCase
354
352
  }
355
353
  assert_equal(4, @rbtree.size)
356
354
 
357
- if defined?(Enumerable::Enumerator) or defined?(Enumerator)
355
+ if have_enumerator?
358
356
  enumerator = @rbtree.each_value
359
357
  assert_equal(%w(A B C D), enumerator.to_a.flatten)
360
358
  end
@@ -428,7 +426,7 @@ class RBTreeTest < Test::Unit::TestCase
428
426
  }
429
427
  assert_equal(0, @rbtree.size)
430
428
 
431
- if defined?(Enumerable::Enumerator) or defined?(Enumerator)
429
+ if have_enumerator?
432
430
  rbtree = RBTree[*%w(b B d D a A c C)]
433
431
  rbtree.delete_if.with_index {|(key, val), i| i < 2 }
434
432
  assert_equal(RBTree[*%w(c C d D)], rbtree)
@@ -440,7 +438,7 @@ class RBTreeTest < Test::Unit::TestCase
440
438
  assert_same(@rbtree, result)
441
439
  assert_equal(RBTree[*%w(a A b B)], @rbtree)
442
440
 
443
- if defined?(Enumerable::Enumerator) or defined?(Enumerator)
441
+ if have_enumerator?
444
442
  rbtree = RBTree[*%w(b B d D a A c C)]
445
443
  rbtree.keep_if.with_index {|(key, val), i| i < 2 }
446
444
  assert_equal(RBTree[*%w(a A b B)], rbtree)
@@ -456,7 +454,7 @@ class RBTreeTest < Test::Unit::TestCase
456
454
  assert_same(@rbtree, result)
457
455
  assert_equal(RBTree[*%w(c C d D)], result)
458
456
 
459
- if defined?(Enumerable::Enumerator) or defined?(Enumerator)
457
+ if have_enumerator?
460
458
  rbtree = RBTree[*%w(b B d D a A c C)]
461
459
  rbtree.reject!.with_index {|(key, val), i| i < 2 }
462
460
  assert_equal(RBTree[*%w(c C d D)], rbtree)
@@ -472,7 +470,7 @@ class RBTreeTest < Test::Unit::TestCase
472
470
  assert_equal(RBTree[*%w(c C d D)], result)
473
471
  assert_equal(4, @rbtree.size)
474
472
 
475
- if defined?(Enumerable::Enumerator) or defined?(Enumerator)
473
+ if have_enumerator?
476
474
  result = @rbtree.reject.with_index {|(key, val), i| i < 2 }
477
475
  assert_equal(RBTree[*%w(c C d D)], result)
478
476
  end
@@ -487,7 +485,7 @@ class RBTreeTest < Test::Unit::TestCase
487
485
  assert_same(@rbtree, result)
488
486
  assert_equal(RBTree[*%w(a A b B)], result)
489
487
 
490
- if defined?(Enumerable::Enumerator) or defined?(Enumerator)
488
+ if have_enumerator?
491
489
  rbtree = RBTree[*%w(b B d D a A c C)]
492
490
  rbtree.select!.with_index {|(key, val), i| i < 2 }
493
491
  assert_equal(RBTree[*%w(a A b B)], rbtree)
@@ -503,7 +501,7 @@ class RBTreeTest < Test::Unit::TestCase
503
501
  assert_equal(RBTree[*%w(a A b B)], result)
504
502
  assert_raises(ArgumentError) { @rbtree.select("c") }
505
503
 
506
- if defined?(Enumerable::Enumerator) or defined?(Enumerator)
504
+ if have_enumerator?
507
505
  result = @rbtree.select.with_index {|(key, val), i| i < 2 }
508
506
  assert_equal(RBTree[*%w(a A b B)], result)
509
507
  end
@@ -554,13 +552,13 @@ class RBTreeTest < Test::Unit::TestCase
554
552
  rbtree[["a"]] = ["A"]
555
553
  rbtree[[["b"]]] = [["B"]]
556
554
  assert_equal([["a"], ["A"], [["b"]], [["B"]]], rbtree.flatten)
557
- assert_equal([[["a"], ["A"]], [[["b"]], [["B"]]]], rbtree.flatten(0))
555
+ assert_equal([["a"], ["A"], [["b"]], [["B"]]], rbtree.flatten(0))
558
556
  assert_equal([["a"], ["A"], [["b"]], [["B"]]], rbtree.flatten(1))
559
557
  assert_equal(["a", "A", ["b"], ["B"]], rbtree.flatten(2))
560
558
  assert_equal(["a", "A", "b", "B"], rbtree.flatten(3))
561
559
 
562
560
  assert_raises(TypeError) { @rbtree.flatten("e") }
563
- assert_raises(ArgumentError) { @rbtree.flatten(2, 2) }
561
+ assert_raises(ArgumentError) { @rbtree.flatten(1, 2) }
564
562
  end
565
563
  end
566
564
 
@@ -669,7 +667,7 @@ class RBTreeTest < Test::Unit::TestCase
669
667
  assert_equal([], rbtree.bound("Y", "Z").to_a)
670
668
  assert_equal([], rbtree.bound("f", "g").to_a)
671
669
  assert_equal([], rbtree.bound("f", "Z").to_a)
672
-
670
+
673
671
  if defined?(Enumerator) and Enumerator.method_defined?(:size)
674
672
  assert_equal(2, rbtree.bound("a", "c").size)
675
673
  assert_equal(1, rbtree.bound("a").size)
@@ -821,7 +819,7 @@ class RBTreeTest < Test::Unit::TestCase
821
819
  @rbtree.reverse_each { |key, val| result.push([key, val]) }
822
820
  assert_equal(%w(d D c C b B a A), result.flatten)
823
821
 
824
- if defined?(Enumerable::Enumerator) or defined?(Enumerator)
822
+ if have_enumerator?
825
823
  enumerator = @rbtree.reverse_each
826
824
  assert_equal(%w(d D c C b B a A), enumerator.to_a.flatten)
827
825
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbtree
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - OZAWA Takuma
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-03-29 00:00:00.000000000 Z
11
+ date: 2013-12-26 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
@@ -38,27 +38,27 @@ licenses:
38
38
  metadata: {}
39
39
  post_install_message:
40
40
  rdoc_options:
41
- - --title
41
+ - "--title"
42
42
  - Ruby/RBTree
43
- - --main
43
+ - "--main"
44
44
  - README
45
- - --exclude
46
- - \A(?!README|rbtree\.c).*\z
45
+ - "--exclude"
46
+ - "\\A(?!README|rbtree\\.c).*\\z"
47
47
  require_paths:
48
48
  - lib
49
49
  required_ruby_version: !ruby/object:Gem::Requirement
50
50
  requirements:
51
- - - '>='
51
+ - - ">="
52
52
  - !ruby/object:Gem::Version
53
53
  version: 1.8.6
54
54
  required_rubygems_version: !ruby/object:Gem::Requirement
55
55
  requirements:
56
- - - '>='
56
+ - - ">="
57
57
  - !ruby/object:Gem::Version
58
58
  version: '0'
59
59
  requirements: []
60
60
  rubyforge_project: rbtree
61
- rubygems_version: 2.0.0
61
+ rubygems_version: 2.2.0
62
62
  signing_key:
63
63
  specification_version: 4
64
64
  summary: A sorted associative collection.