rbtree 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (7) hide show
  1. data/ChangeLog +119 -61
  2. data/LICENSE +1 -1
  3. data/README +54 -26
  4. data/extconf.rb +4 -27
  5. data/rbtree.c +117 -138
  6. data/test.rb +110 -66
  7. metadata +45 -35
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2002-2004, 2007 OZAWA Takuma
1
+ Copyright (c) 2002-2004, 2007, 2009 OZAWA Takuma
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person
4
4
  obtaining a copy of this software and associated documentation
data/README CHANGED
@@ -2,10 +2,10 @@
2
2
 
3
3
  = Ruby/RBTree
4
4
 
5
- RBTree is a sorted associative collection using Red-Black Tree as
6
- the internal data structure. The elements of RBTree are ordered and
7
- the interface is the almost same as Hash, so simply you can
8
- consider RBTree sorted Hash.
5
+ RBTree is a sorted associative collection that is implemented with
6
+ Red-Black Tree. The elements of RBTree are ordered and its interface
7
+ is the almost same as Hash, so simply you can consider RBTree sorted
8
+ Hash.
9
9
 
10
10
  Red-Black Tree is a kind of binary tree that automatically balances
11
11
  by itself when a node is inserted or deleted. Thus the complexity
@@ -14,28 +14,48 @@ case. On the other hand the complexity of Hash is O(1). Because
14
14
  Hash is unordered the data structure is more effective than
15
15
  Red-Black Tree as an associative collection.
16
16
 
17
- The interface of RBTree is the almost same as Hash although there
18
- are some limitations.
19
-
20
- * While iterating (e.g. in RBTree#each block), RBTree is
21
- unmodifiable.
22
-
23
- * Comparison is done using <=> method of key objects. So all types
24
- of keys in RBTree should be comparable each other or an arbitrary
25
- Proc might be set by RBTree#readjust.
26
-
27
- RBTree has a few searching methods that Hash doesn't have. They are
28
- RBTree#lower_bound, RBTree#upper_bound and RBTree#bound. See document
29
- of each method for details.
30
-
31
- Pretty printing is available for RBTree by using pp.rb. The output
32
- of pp is easier than p to read. Just call Kernel#pp for the object.
33
-
34
- MultiRBTree that allows duplicates of keys is also available.
17
+ The elements of RBTree are sorted with natural ordering (by <=>
18
+ method) of its keys or by a comparator(Proc) set by readjust
19
+ method. It means all keys in RBTree should be comparable with each
20
+ other. Or a comparator that takes two arguments of a key should return
21
+ negative, 0, or positive depending on the first argument is less than,
22
+ equal to, or greater than the second one.
23
+
24
+ The interface of RBTree is the almost same as Hash and there are a
25
+ few methods to take advantage of the ordering:
26
+
27
+ * lower_bound, upper_bound, bound
28
+ * first, last
29
+ * shift, pop
30
+ * reverse_each
31
+
32
+ Note: while iterating RBTree (e.g. in a block of each method), it is
33
+ not modifiable, or TypeError is thrown.
34
+
35
+ RBTree supoorts pretty printing using pp.
36
+
37
+ This library contains two classes. One is RBTree and the other is
38
+ MultiRBTree that is a parent class of RBTree. RBTree does not allow
39
+ duplications of keys but MultiRBTree does.
40
+
41
+ require "rbtree"
42
+
43
+ rbtree = RBTree["c", 10, "a", 20]
44
+ rbtree["b"] = 30
45
+ p rbtree["b"] # => 30
46
+ rbtree.each do |k, v|
47
+ p [k, v]
48
+ end # => ["a", 20] ["b", 30] ["c", 10]
49
+
50
+ mrbtree = MultiRBTree["c", 10, "a", 20, "e", 30, "a", 40]
51
+ p mrbtree.lower_bound("b") # => ["c", 10]
52
+ mrbtree.bound("a", "d") do |k, v|
53
+ p [k, v]
54
+ end # => ["a", 20] ["a", 40] ["c", 10]
35
55
 
36
56
  == Requirement
37
57
 
38
- * Ruby 1.6.7 or higher
58
+ * Ruby 1.8.x
39
59
 
40
60
  == Install
41
61
 
@@ -43,7 +63,7 @@ MultiRBTree that allows duplicates of keys is also available.
43
63
 
44
64
  or download a tarball from the link below
45
65
 
46
- * ((<"Ruby/RBTree 0.2.0"|URL:rbtree-0.2.0.tar.gz>))
66
+ * ((<"Ruby/RBTree 0.2.1"|URL:rbtree-0.2.1.tar.gz>))
47
67
 
48
68
  and then
49
69
 
@@ -57,13 +77,15 @@ and then
57
77
 
58
78
  $ ruby test.rb
59
79
 
60
- == Incomplete Document
80
+ == Incomplete Documents
61
81
 
62
82
  $ rdoc rbtree.c
63
83
 
84
+ or online documents at ((<URL:http://rbtree.rubyforge.org/>)).
85
+
64
86
  == License
65
87
 
66
- MIT License. Copyright (c) 2002-2004, 2007 OZAWA Takuma.
88
+ MIT License. Copyright (c) 2002-2004, 2007, 2009 OZAWA Takuma.
67
89
 
68
90
  dict.c and dict.h are modified copies that are originally in Kazlib
69
91
  written by Kaz Kylheku. Copyright is held by Kaz Kylheku, see dict.c
@@ -75,4 +97,10 @@ and dict.h for the license. The web page of Kazlib is at
75
97
  Bug fixes, suggestions and other feedbacks are welcomed. Please mail
76
98
  me at burningdowntheopera at yahoo dot co dot jp.
77
99
 
100
+ == Links
101
+
102
+ * ((<RAA - ruby-rbtree|URL:http://raa.ruby-lang.org/project/ruby-rbtree/>))
103
+ * ((<RubyForge: rbtree: Project Info|URL:http://rubyforge.org/projects/rbtree/>))
104
+ * ((<URL:http://www.geocities.co.jp/SiliconValley-PaloAlto/3388/rbtree/README.html>))
105
+
78
106
  =end
data/extconf.rb CHANGED
@@ -1,34 +1,11 @@
1
1
  require 'mkmf'
2
- require 'rbconfig'
3
2
 
4
- if Config::CONFIG['CC'] =~ /gcc/
3
+ if $DEBUG
5
4
  $CFLAGS << ' -std=c89 -pedantic -Wall -Wno-long-long'
6
- end
7
-
8
- $defs << '-DNDEBUG'
9
-
10
- print 'checking for allocation framework... '
11
- if Object.respond_to?(:allocate)
12
- print "yes\n"
13
- $defs << '-DHAVE_OBJECT_ALLOCATE'
5
+ $defs << ' -Dinline=__inline'
14
6
  else
15
- print "no\n"
7
+ $defs << '-DNDEBUG'
16
8
  end
17
9
 
18
- have_func('rb_obj_init_copy')
19
- have_func('rb_block_proc')
20
- have_func('rb_yield_values')
21
- have_func('rb_marshal_dump')
22
- have_func('rb_marshal_load')
23
-
24
- print 'checking for inline keyword... '
25
- inline = ['inline', '__inline', '__inline__', ''].find {|e|
26
- try_link(<<EOS)
27
- int main() { return 0; }
28
- #{e} void foo() {}
29
- EOS
30
- }
31
- print "#{inline}\n"
32
- $defs << "-Dinline=#{inline}"
33
-
10
+ have_func('rb_enumeratorize')
34
11
  create_makefile('rbtree')
data/rbtree.c CHANGED
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * MIT License
3
- * Copyright (c) 2002-2004, 2007 OZAWA Takuma
3
+ * Copyright (c) 2002-2004, 2007, 2009 OZAWA Takuma
4
4
  */
5
5
  #include <ruby.h>
6
6
  #include <version.h>
@@ -8,12 +8,11 @@
8
8
  #include <stdarg.h>
9
9
  #include "dict.h"
10
10
 
11
- #define RBTREE_IN_ITERATION FL_USER1
12
11
  #define RBTREE_PROC_DEFAULT FL_USER2
13
12
  #define HASH_PROC_DEFAULT FL_USER2
14
13
 
15
- #ifndef ULONG2NUM
16
- #define ULONG2NUM UINT2NUM
14
+ #ifndef HAVE_RB_ENUMERATORIZE
15
+ #define RETURN_ENUMERATOR(obj, argc, argv) ((void)0)
17
16
  #endif
18
17
 
19
18
  VALUE RBTree;
@@ -24,12 +23,6 @@ static ID id_cmp;
24
23
  static ID id_call;
25
24
  static ID id_default;
26
25
 
27
- #ifndef HAVE_RB_MARSHAL_DUMP
28
- static VALUE rb_mMarshal;
29
- static ID id_dump;
30
- static ID id_load;
31
- #endif
32
-
33
26
  typedef struct {
34
27
  dict_t* dict;
35
28
  VALUE ifnone;
@@ -51,41 +44,12 @@ typedef struct {
51
44
 
52
45
  /*********************************************************************/
53
46
 
54
- #ifndef HAVE_RB_BLOCK_PROC
55
- static VALUE
56
- rb_block_proc()
57
- {
58
- return rb_f_lambda();
59
- }
60
- #endif
61
-
62
- #ifndef HAVE_RB_YIELD_VALUES
63
- static VALUE
64
- rb_yield_values(int n, ...)
65
- {
66
- int i;
67
- va_list ap;
68
- VALUE ary = rb_ary_new2(n);
69
-
70
- va_start(ap, n);
71
- for (i = 0; i < n; i++)
72
- rb_ary_push(ary, va_arg(ap, VALUE));
73
- va_end(ap);
74
- return rb_yield(ary);
75
- }
76
- #endif
77
-
78
47
  static int
79
48
  cmpint(VALUE i, VALUE a, VALUE b)
80
49
  {
81
- #if RUBY_VERSION_CODE >= 180
82
50
  return rb_cmpint(i, a, b);
83
- #else
84
- return rb_cmpint(i);
85
- #endif
86
51
  }
87
52
 
88
-
89
53
  static void
90
54
  rbtree_free(rbtree_t* rbtree)
91
55
  {
@@ -187,19 +151,6 @@ VALUE rbtree_update(VALUE, VALUE);
187
151
 
188
152
  /*********************************************************************/
189
153
 
190
- #ifndef HAVE_OBJECT_ALLOCATE
191
- /*
192
- *
193
- */
194
- VALUE
195
- rbtree_s_new(int argc, VALUE* argv, VALUE klass)
196
- {
197
- VALUE rbtree = rbtree_alloc(klass);
198
- rb_obj_call_init(rbtree, argc, argv);
199
- return rbtree;
200
- }
201
- #endif
202
-
203
154
  static int
204
155
  hash_to_rbtree_i(VALUE key, VALUE value, VALUE rbtree)
205
156
  {
@@ -214,17 +165,48 @@ hash_to_rbtree_i(VALUE key, VALUE value, VALUE rbtree)
214
165
  VALUE
215
166
  rbtree_s_create(int argc, VALUE* argv, VALUE klass)
216
167
  {
217
- int i;
168
+ long i;
218
169
  VALUE rbtree;
219
-
170
+
220
171
  if (argc == 1) {
172
+ VALUE tmp;
173
+
174
+ if (klass == RBTree && CLASS_OF(argv[0]) == MultiRBTree) {
175
+ rb_raise(rb_eTypeError, "can't convert MultiRBTree to RBTree");
176
+ }
177
+
221
178
  if (rb_obj_is_kind_of(argv[0], klass)) {
222
179
  rbtree = rbtree_alloc(klass);
223
180
  rbtree_update(rbtree, argv[0]);
224
181
  return rbtree;
225
- } else if (TYPE(argv[0]) == T_HASH) {
182
+ }
183
+
184
+ tmp = rb_check_convert_type(argv[0], T_HASH, "Hash", "to_hash");
185
+ if (!NIL_P(tmp)) {
186
+ rbtree = rbtree_alloc(klass);
187
+ st_foreach(RHASH(tmp)->tbl, hash_to_rbtree_i, rbtree);
188
+ return rbtree;
189
+ }
190
+
191
+ tmp = rb_check_array_type(argv[0]);
192
+ if (!NIL_P(tmp)) {
226
193
  rbtree = rbtree_alloc(klass);
227
- st_foreach(RHASH(argv[0])->tbl, hash_to_rbtree_i, rbtree);
194
+ for (i = 0; i < RARRAY(tmp)->len; i++) {
195
+ VALUE v = rb_check_array_type(RARRAY(tmp)->ptr[i]);
196
+ if (NIL_P(v)) {
197
+ continue;
198
+ }
199
+ switch(RARRAY(v)->len) {
200
+ case 1:
201
+ rbtree_aset(rbtree, RARRAY(v)->ptr[0], Qnil);
202
+ break;
203
+ case 2:
204
+ rbtree_aset(rbtree, RARRAY(v)->ptr[0], RARRAY(v)->ptr[1]);
205
+ break;
206
+ default:
207
+ continue;
208
+ }
209
+ }
228
210
  return rbtree;
229
211
  }
230
212
  }
@@ -556,6 +538,7 @@ each_i(dnode_t* node, void* arg)
556
538
  VALUE
557
539
  rbtree_each(VALUE self)
558
540
  {
541
+ RETURN_ENUMERATOR(self, 0, NULL);
559
542
  return rbtree_for_each(self, each_i, NULL);
560
543
  }
561
544
 
@@ -576,6 +559,7 @@ each_pair_i(dnode_t* node, void* arg)
576
559
  VALUE
577
560
  rbtree_each_pair(VALUE self)
578
561
  {
562
+ RETURN_ENUMERATOR(self, 0, NULL);
579
563
  return rbtree_for_each(self, each_pair_i, NULL);
580
564
  }
581
565
 
@@ -596,6 +580,7 @@ each_key_i(dnode_t* node, void* arg)
596
580
  VALUE
597
581
  rbtree_each_key(VALUE self)
598
582
  {
583
+ RETURN_ENUMERATOR(self, 0, NULL);
599
584
  return rbtree_for_each(self, each_key_i, NULL);
600
585
  }
601
586
 
@@ -616,6 +601,7 @@ each_value_i(dnode_t* node, void* arg)
616
601
  VALUE
617
602
  rbtree_each_value(VALUE self)
618
603
  {
604
+ RETURN_ENUMERATOR(self, 0, NULL);
619
605
  return rbtree_for_each(self, each_value_i, NULL);
620
606
  }
621
607
 
@@ -629,6 +615,7 @@ rbtree_each_value(VALUE self)
629
615
  VALUE
630
616
  rbtree_reverse_each(VALUE self)
631
617
  {
618
+ RETURN_ENUMERATOR(self, 0, NULL);
632
619
  return rbtree_reverse_for_each(self, each_pair_i, NULL);
633
620
  }
634
621
 
@@ -679,26 +666,13 @@ rbtree_initialize_copy(VALUE self, VALUE other)
679
666
  return self;
680
667
  }
681
668
 
682
- #ifndef HAVE_RB_OBJ_INIT_COPY
683
- /*
684
- *
685
- */
686
- VALUE
687
- rbtree_clone(VALUE self)
688
- {
689
- VALUE clone = rbtree_alloc(CLASS_OF(self));
690
- rbtree_initialize_copy(clone, self);
691
- return clone;
692
- }
693
- #endif
694
-
695
669
  /*
696
670
  *
697
671
  */
698
672
  VALUE
699
673
  rbtree_values_at(int argc, VALUE* argv, VALUE self)
700
674
  {
701
- int i;
675
+ long i;
702
676
  VALUE ary = rb_ary_new();
703
677
 
704
678
  for (i = 0; i < argc; i++)
@@ -720,7 +694,10 @@ select_i(dnode_t* node, void* ary)
720
694
  VALUE
721
695
  rbtree_select(VALUE self)
722
696
  {
723
- VALUE ary = rb_ary_new();
697
+ VALUE ary;
698
+
699
+ RETURN_ENUMERATOR(self, 0, NULL);
700
+ ary = rb_ary_new();
724
701
  rbtree_for_each(self, select_i, (void*)ary);
725
702
  return ary;
726
703
  }
@@ -843,7 +820,8 @@ VALUE
843
820
  rbtree_delete_if(VALUE self)
844
821
  {
845
822
  rbtree_delete_if_arg_t arg;
846
-
823
+
824
+ RETURN_ENUMERATOR(self, 0, NULL);
847
825
  rbtree_modify(self);
848
826
  arg.self = self;
849
827
  arg.list = NULL;
@@ -857,7 +835,10 @@ rbtree_delete_if(VALUE self)
857
835
  VALUE
858
836
  rbtree_reject_bang(VALUE self)
859
837
  {
860
- const dictcount_t count = dict_count(DICT(self));
838
+ dictcount_t count;
839
+
840
+ RETURN_ENUMERATOR(self, 0, NULL);
841
+ count = dict_count(DICT(self));
861
842
  rbtree_delete_if(self);
862
843
  if (count == dict_count(DICT(self)))
863
844
  return Qnil;
@@ -874,7 +855,7 @@ rbtree_reject(VALUE self)
874
855
  }
875
856
 
876
857
  static VALUE
877
- rbtree_shift_pop(VALUE self, const int mode)
858
+ rbtree_shift_pop(VALUE self, const int shift)
878
859
  {
879
860
  dict_t* dict = DICT(self);
880
861
  dnode_t* node;
@@ -889,10 +870,10 @@ rbtree_shift_pop(VALUE self, const int mode)
889
870
  return IFNONE(self);
890
871
  }
891
872
 
892
- if (mode == 0)
893
- node = dict_first(dict);
894
- else
873
+ if (shift)
895
874
  node = dict_last(dict);
875
+ else
876
+ node = dict_first(dict);
896
877
  ret = ASSOC(node);
897
878
  dict_delete_free(dict, node);
898
879
  return ret;
@@ -1088,7 +1069,12 @@ to_hash_i(dnode_t* node, void* hash)
1088
1069
  VALUE
1089
1070
  rbtree_to_hash(VALUE self)
1090
1071
  {
1091
- VALUE hash = rb_hash_new();
1072
+ VALUE hash;
1073
+ if (CLASS_OF(self) == MultiRBTree) {
1074
+ rb_raise(rb_eTypeError, "can't convert MultiRBTree to Hash");
1075
+ }
1076
+
1077
+ hash = rb_hash_new();
1092
1078
  rbtree_for_each(self, to_hash_i, (void*)hash);
1093
1079
  RHASH(hash)->ifnone = IFNONE(self);
1094
1080
  if (FL_TEST(self, RBTREE_PROC_DEFAULT))
@@ -1307,7 +1293,7 @@ rbtree_bound(int argc, VALUE* argv, VALUE self)
1307
1293
  }
1308
1294
 
1309
1295
  static VALUE
1310
- rbtree_first_last(VALUE self, const int mode)
1296
+ rbtree_first_last(VALUE self, const int first)
1311
1297
  {
1312
1298
  dict_t* dict = DICT(self);
1313
1299
  dnode_t* node;
@@ -1319,7 +1305,7 @@ rbtree_first_last(VALUE self, const int mode)
1319
1305
  return IFNONE(self);
1320
1306
  }
1321
1307
 
1322
- if (mode == 0)
1308
+ if (first)
1323
1309
  node = dict_first(dict);
1324
1310
  else
1325
1311
  node = dict_last(dict);
@@ -1335,7 +1321,7 @@ rbtree_first_last(VALUE self, const int mode)
1335
1321
  VALUE
1336
1322
  rbtree_first(VALUE self)
1337
1323
  {
1338
- return rbtree_first_last(self, 0);
1324
+ return rbtree_first_last(self, 1);
1339
1325
  }
1340
1326
 
1341
1327
  /*
@@ -1347,7 +1333,7 @@ rbtree_first(VALUE self)
1347
1333
  VALUE
1348
1334
  rbtree_last(VALUE self)
1349
1335
  {
1350
- return rbtree_first_last(self, 1);
1336
+ return rbtree_first_last(self, 0);
1351
1337
  }
1352
1338
 
1353
1339
  /*
@@ -1359,11 +1345,11 @@ rbtree_last(VALUE self)
1359
1345
  *
1360
1346
  * Sets a proc to compare keys and readjusts elements using the given
1361
1347
  * block or a Proc object given as the argument. The block takes two
1362
- * key arguments and returns negative, 0, or positive depending on the
1363
- * first argument is less than, equal to, or greater than the second
1364
- * one. If no block is given it just readjusts elements using current
1365
- * comparison block. If nil is given as the argument it sets default
1366
- * comparison block.
1348
+ * arguments of a key and returns negative, 0, or positive depending
1349
+ * on the first argument is less than, equal to, or greater than the
1350
+ * second one. If no block is given it just readjusts elements using
1351
+ * current comparison block. If nil is given as the argument it sets
1352
+ * default comparison block.
1367
1353
  */
1368
1354
  VALUE
1369
1355
  rbtree_readjust(int argc, VALUE* argv, VALUE self)
@@ -1482,20 +1468,6 @@ rbtree_pretty_print_cycle(VALUE self, VALUE pp)
1482
1468
 
1483
1469
  /*********************************************************************/
1484
1470
 
1485
- #ifndef HAVE_RB_MARSHAL_DUMP
1486
- static VALUE
1487
- rb_marshal_dump(VALUE obj, VALUE port)
1488
- {
1489
- return rb_funcall(rb_mMarshal, id_dump, 2, obj, port);
1490
- }
1491
-
1492
- static VALUE
1493
- rb_marshal_load(VALUE port)
1494
- {
1495
- return rb_funcall(rb_mMarshal, id_load, 1, port);
1496
- }
1497
- #endif
1498
-
1499
1471
  static each_return_t
1500
1472
  to_flatten_ary_i(dnode_t* node, void* ary)
1501
1473
  {
@@ -1554,10 +1526,10 @@ rbtree_s_load(VALUE klass, VALUE str)
1554
1526
  /*********************************************************************/
1555
1527
 
1556
1528
  /*
1557
- * RBTree is a sorted associative collection using Red-Black Tree as
1558
- * the internal data structure. The elements of RBTree are ordered and
1559
- * the interface is the almost same as Hash, so simply you can
1560
- * consider RBTree sorted Hash.
1529
+ * RBTree is a sorted associative collection that is implemented with
1530
+ * Red-Black Tree. The elements of RBTree are ordered and its interface
1531
+ * is the almost same as Hash, so simply you can consider RBTree sorted
1532
+ * Hash.
1561
1533
  *
1562
1534
  * Red-Black Tree is a kind of binary tree that automatically balances
1563
1535
  * by itself when a node is inserted or deleted. Thus the complexity
@@ -1565,25 +1537,45 @@ rbtree_s_load(VALUE klass, VALUE str)
1565
1537
  * case. On the other hand the complexity of Hash is O(1). Because
1566
1538
  * Hash is unordered the data structure is more effective than
1567
1539
  * Red-Black Tree as an associative collection.
1540
+ *
1541
+ * The elements of RBTree are sorted with natural ordering (by <=>
1542
+ * method) of its keys or by a comparator(Proc) set by readjust
1543
+ * method. It means all keys in RBTree should be comparable with each
1544
+ * other. Or a comparator that takes two arguments of a key should return
1545
+ * negative, 0, or positive depending on the first argument is less than,
1546
+ * equal to, or greater than the second one.
1547
+ *
1548
+ * The interface of RBTree is the almost same as Hash and there are a
1549
+ * few methods to take advantage of the ordering:
1550
+ *
1551
+ * * lower_bound, upper_bound, bound
1552
+ * * first, last
1553
+ * * shift, pop
1554
+ * * reverse_each
1555
+ *
1556
+ * Note: while iterating RBTree (e.g. in a block of each method), it is
1557
+ * not modifiable, or TypeError is thrown.
1558
+ *
1559
+ * RBTree supoorts pretty printing using pp.
1560
+ *
1561
+ * This library contains two classes. One is RBTree and the other is
1562
+ * MultiRBTree that is a parent class of RBTree. RBTree does not allow
1563
+ * duplications of keys but MultiRBTree does.
1568
1564
  *
1569
- * The interface of RBTree is the almost same as Hash although there
1570
- * are some limitations.
1571
- *
1572
- * * While iterating (e.g. in RBTree#each block), RBTree is
1573
- * unmodifiable.
1574
- *
1575
- * * Comparison is done using <=> method of key objects. So all types
1576
- * of keys in RBTree should be comparable each other or an arbitrary
1577
- * Proc might be set by RBTree#readjust.
1578
- *
1579
- * RBTree has a few searching methods that Hash doesn't have. They are
1580
- * RBTree#lower_bound, RBTree#upper_bound and RBTree#bound. See
1581
- * document of each method for details.
1582
- *
1583
- * Pretty printing is available for RBTree by using pp.rb. The output
1584
- * of pp is easier than p to read. Just call Kernel#pp for the object.
1585
- *
1586
- * MultiRBTree that allows duplicates of keys is also available.
1565
+ * require "rbtree"
1566
+ *
1567
+ * rbtree = RBTree["c", 10, "a", 20]
1568
+ * rbtree["b"] = 30
1569
+ * p rbtree["b"] # => 30
1570
+ * rbtree.each do |k, v|
1571
+ * p [k, v]
1572
+ * end # => ["a", 20] ["b", 30] ["c", 10]
1573
+ *
1574
+ * mrbtree = MultiRBTree["c", 10, "a", 20, "e", 30, "a", 40]
1575
+ * p mrbtree.lower_bound("b") # => ["c", 10]
1576
+ * mrbtree.bound("a", "d") do |k, v|
1577
+ * p [k, v]
1578
+ * end # => ["a", 20] ["a", 40] ["c", 10]
1587
1579
  */
1588
1580
  void Init_rbtree()
1589
1581
  {
@@ -1591,21 +1583,13 @@ void Init_rbtree()
1591
1583
  RBTree = rb_define_class("RBTree", MultiRBTree);
1592
1584
 
1593
1585
  rb_include_module(MultiRBTree, rb_mEnumerable);
1594
-
1595
- #ifdef HAVE_OBJECT_ALLOCATE
1586
+
1596
1587
  rb_define_alloc_func(MultiRBTree, rbtree_alloc);
1597
- #else
1598
- rb_define_singleton_method(MultiRBTree, "new", rbtree_s_new, -1);
1599
- #endif
1588
+
1600
1589
  rb_define_singleton_method(MultiRBTree, "[]", rbtree_s_create, -1);
1601
1590
 
1602
1591
  rb_define_method(MultiRBTree, "initialize", rbtree_initialize, -1);
1603
-
1604
- #ifdef HAVE_RB_OBJ_INIT_COPY
1605
1592
  rb_define_method(MultiRBTree, "initialize_copy", rbtree_initialize_copy, 1);
1606
- #else
1607
- rb_define_method(MultiRBTree, "clone", rbtree_clone, 0);
1608
- #endif
1609
1593
 
1610
1594
  rb_define_method(MultiRBTree, "to_a", rbtree_to_a, 0);
1611
1595
  rb_define_method(MultiRBTree, "to_s", rbtree_to_s, 0);
@@ -1667,11 +1651,6 @@ void Init_rbtree()
1667
1651
 
1668
1652
  rb_define_method(MultiRBTree, "_dump", rbtree_dump, 1);
1669
1653
  rb_define_singleton_method(MultiRBTree, "_load", rbtree_s_load, 1);
1670
- #ifndef HAVE_RB_MARSHAL_DUMP
1671
- rb_mMarshal = rb_path2class("Marshal");
1672
- id_dump = rb_intern("dump");
1673
- id_load = rb_intern("load");
1674
- #endif
1675
1654
 
1676
1655
  id_bound = rb_intern("bound");
1677
1656
  id_cmp = rb_intern("<=>");