Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 223 lines (197 sloc) 5.241 kB
9595725 update copyrights to 2011
Laurent Sansonetti authored
1 /*
2 * This file is covered by the Ruby license. See COPYING for more details.
7d7d3e8 @ferrous26 Change ownership to The MacRuby Team and update copyrights
ferrous26 authored
3 *
4 * Copyright (C) 2012, The MacRuby Team. All rights reserved.
9595725 update copyrights to 2011
Laurent Sansonetti authored
5 * Copyright (C) 2007-2011, Apple Inc. All rights reserved.
6 * Copyright (C) 1993-2007 Yukihiro Matsumoto
7 */
9c1d230 committing experimental branch content
Laurent Sansonetti authored
8
d0898dd include/ruby/macruby.h -> macruby_internal.h
Laurent Sansonetti authored
9 #include "macruby_internal.h"
9c1d230 committing experimental branch content
Laurent Sansonetti authored
10 #include "ruby/node.h"
cb65416 the great schism, part I
Laurent Sansonetti authored
11 #include "vm.h"
9c1d230 committing experimental branch content
Laurent Sansonetti authored
12
13 VALUE rb_mComparable;
14
15 static SEL cmp = 0;
16
17 void
18 rb_cmperr(VALUE x, VALUE y)
19 {
20 const char *classname;
21
22 if (SPECIAL_CONST_P(y)) {
23 y = rb_inspect(y);
24 classname = StringValuePtr(y);
25 }
26 else {
27 classname = rb_obj_classname(y);
28 }
29 rb_raise(rb_eArgError, "comparison of %s with %s failed",
30 rb_obj_classname(x), classname);
31 }
32
78bea84 optimized dummy calls to <=>:
Laurent Sansonetti authored
33 VALUE
34 rb_objs_cmp(VALUE x, VALUE y)
35 {
70ea0b5 per-vm method cache + misc fixes/improvements
Laurent Sansonetti authored
36 return rb_vm_call(x, cmp, 1, &y);
78bea84 optimized dummy calls to <=>:
Laurent Sansonetti authored
37 }
38
9c1d230 committing experimental branch content
Laurent Sansonetti authored
39 static VALUE
40 cmp_eq(VALUE *a)
41 {
70ea0b5 per-vm method cache + misc fixes/improvements
Laurent Sansonetti authored
42 VALUE c = rb_vm_call(a[0], cmp, 1, &a[1]);
78bea84 optimized dummy calls to <=>:
Laurent Sansonetti authored
43 if (NIL_P(c)) {
44 return Qfalse;
45 }
46 if (rb_cmpint(c, a[0], a[1]) == 0) {
47 return Qtrue;
48 }
9c1d230 committing experimental branch content
Laurent Sansonetti authored
49 return Qfalse;
50 }
51
52 static VALUE
53 cmp_failed(void)
54 {
55 return Qfalse;
56 }
57
58 /*
59 * call-seq:
60 * obj == other => true or false
61 *
62 * Compares two objects based on the receiver's <code><=></code>
63 * method, returning true if it returns 0. Also returns true if
64 * _obj_ and _other_ are the same object.
65 */
66
67 static VALUE
68 cmp_equal(VALUE x, SEL sel, VALUE y)
69 {
70 VALUE a[2];
71
72 if (x == y) return Qtrue;
73
74 a[0] = x; a[1] = y;
75 return rb_rescue(cmp_eq, (VALUE)a, cmp_failed, 0);
76 }
77
78 /*
79 * call-seq:
80 * obj > other => true or false
81 *
82 * Compares two objects based on the receiver's <code><=></code>
83 * method, returning true if it returns 1.
84 */
85
86 static VALUE
87 cmp_gt(VALUE x, SEL sel, VALUE y)
88 {
70ea0b5 per-vm method cache + misc fixes/improvements
Laurent Sansonetti authored
89 VALUE c = rb_vm_call(x, cmp, 1, &y);
90 if (rb_cmpint(c, x, y) > 0) {
91 return Qtrue;
92 }
9c1d230 committing experimental branch content
Laurent Sansonetti authored
93 return Qfalse;
94 }
95
96 /*
97 * call-seq:
98 * obj >= other => true or false
99 *
100 * Compares two objects based on the receiver's <code><=></code>
101 * method, returning true if it returns 0 or 1.
102 */
103
104 static VALUE
105 cmp_ge(VALUE x, SEL sel, VALUE y)
106 {
70ea0b5 per-vm method cache + misc fixes/improvements
Laurent Sansonetti authored
107 VALUE c = rb_vm_call(x, cmp, 1, &y);
108 if (rb_cmpint(c, x, y) >= 0) {
109 return Qtrue;
110 }
9c1d230 committing experimental branch content
Laurent Sansonetti authored
111 return Qfalse;
112 }
113
114 /*
115 * call-seq:
116 * obj < other => true or false
117 *
118 * Compares two objects based on the receiver's <code><=></code>
119 * method, returning true if it returns -1.
120 */
121
122 static VALUE
123 cmp_lt(VALUE x, SEL sel, VALUE y)
124 {
70ea0b5 per-vm method cache + misc fixes/improvements
Laurent Sansonetti authored
125 VALUE c = rb_vm_call(x, cmp, 1, &y);
126 if (rb_cmpint(c, x, y) < 0) {
127 return Qtrue;
128 }
9c1d230 committing experimental branch content
Laurent Sansonetti authored
129 return Qfalse;
130 }
131
132 /*
133 * call-seq:
134 * obj <= other => true or false
135 *
136 * Compares two objects based on the receiver's <code><=></code>
137 * method, returning true if it returns -1 or 0.
138 */
139
140 static VALUE
141 cmp_le(VALUE x, SEL sel, VALUE y)
142 {
70ea0b5 per-vm method cache + misc fixes/improvements
Laurent Sansonetti authored
143 VALUE c = rb_vm_call(x, cmp, 1, &y);
144 if (rb_cmpint(c, x, y) <= 0) {
145 return Qtrue;
146 }
9c1d230 committing experimental branch content
Laurent Sansonetti authored
147 return Qfalse;
148 }
149
150 /*
151 * call-seq:
152 * obj.between?(min, max) => true or false
153 *
154 * Returns <code>false</code> if <i>obj</i> <code><=></code>
155 * <i>min</i> is less than zero or if <i>anObject</i> <code><=></code>
156 * <i>max</i> is greater than zero, <code>true</code> otherwise.
157 *
158 * 3.between?(1, 5) #=> true
159 * 6.between?(1, 5) #=> false
160 * 'cat'.between?('ant', 'dog') #=> true
161 * 'gnu'.between?('ant', 'dog') #=> false
162 *
163 */
164
165 static VALUE
166 cmp_between(VALUE x, SEL sel, VALUE min, VALUE max)
167 {
168 if (RTEST(cmp_lt(x, 0, min))) return Qfalse;
169 if (RTEST(cmp_gt(x, 0, max))) return Qfalse;
170 return Qtrue;
171 }
172
173 /*
174 * The <code>Comparable</code> mixin is used by classes whose objects
175 * may be ordered. The class must define the <code><=></code> operator,
176 * which compares the receiver against another object, returning -1, 0,
177 * or +1 depending on whether the receiver is less than, equal to, or
178 * greater than the other object. <code>Comparable</code> uses
179 * <code><=></code> to implement the conventional comparison operators
180 * (<code><</code>, <code><=</code>, <code>==</code>, <code>>=</code>,
181 * and <code>></code>) and the method <code>between?</code>.
182 *
183 * class SizeMatters
184 * include Comparable
185 * attr :str
186 * def <=>(anOther)
187 * str.size <=> anOther.str.size
188 * end
189 * def initialize(str)
190 * @str = str
191 * end
192 * def inspect
193 * @str
194 * end
195 * end
196 *
197 * s1 = SizeMatters.new("Z")
198 * s2 = SizeMatters.new("YY")
199 * s3 = SizeMatters.new("XXX")
200 * s4 = SizeMatters.new("WWWW")
201 * s5 = SizeMatters.new("VVVVV")
202 *
203 * s1 < s2 #=> true
204 * s4.between?(s1, s3) #=> false
205 * s4.between?(s3, s5) #=> true
206 * [ s3, s2, s5, s4, s1 ].sort #=> [Z, YY, XXX, WWWW, VVVVV]
207 *
208 */
209
210 void
211 Init_Comparable(void)
212 {
213 rb_mComparable = rb_define_module("Comparable");
214 rb_objc_define_method(rb_mComparable, "==", cmp_equal, 1);
215 rb_objc_define_method(rb_mComparable, ">", cmp_gt, 1);
216 rb_objc_define_method(rb_mComparable, ">=", cmp_ge, 1);
217 rb_objc_define_method(rb_mComparable, "<", cmp_lt, 1);
218 rb_objc_define_method(rb_mComparable, "<=", cmp_le, 1);
219 rb_objc_define_method(rb_mComparable, "between?", cmp_between, 2);
220
221 cmp = sel_registerName("<=>:");
222 }
Something went wrong with that request. Please try again.