summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--range.c60
2 files changed, 67 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 82017c6c2d..a5daae391a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Fri Nov 25 10:29:48 2005 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * range.c (range_min): use <=> comparison rather than iteration.
+ [ruby-talk:167420]
+
+ * range.c (range_max): ditto.
+
Thu Nov 24 01:31:44 2005 Hirokazu Yamamoto <ocean@m2.ccsnet.ne.jp>
* file.c (w32_io_info): CreateFile failed on Win9x if file was already
diff --git a/range.c b/range.c
index 4475608eee..f3f1f3191c 100644
--- a/range.c
+++ b/range.c
@@ -436,6 +436,64 @@ range_last(VALUE range)
return rb_ivar_get(range, id_end);
}
+/*
+ * call-seq:
+ * rng.min => obj
+ * rng.min {| a,b | block } => obj
+ *
+ * Returns the minimum value in <i>rng</i>. The second uses
+ * the block to compare values. Returns nil if the first
+ * value in range is larger than the last value.
+ *
+ */
+
+
+static VALUE
+range_min(VALUE range)
+{
+ if (rb_block_given_p()) {
+ return rb_call_super(0, 0);
+ }
+ else {
+ VALUE b = rb_ivar_get(range, id_beg);
+ VALUE e = rb_ivar_get(range, id_end);
+ VALUE r = rb_funcall(b, id_cmp, 1, e);
+ int c = rb_cmpint(r, b, e);
+
+ if (c > 0) return Qnil;
+ return b;
+ }
+}
+
+/*
+ * call-seq:
+ * rng.max => obj
+ * rng.max {| a,b | block } => obj
+ *
+ * Returns the maximum value in <i>rng</i>. The second uses
+ * the block to compare values. Returns nil if the first
+ * value in range is larger than the last value.
+ *
+ */
+
+
+static VALUE
+range_max(VALUE range)
+{
+ if (rb_block_given_p() || EXCL(range)) {
+ return rb_call_super(0, 0);
+ }
+ else {
+ VALUE b = rb_ivar_get(range, id_beg);
+ VALUE e = rb_ivar_get(range, id_end);
+ VALUE r = rb_funcall(b, id_cmp, 1, e);
+ int c = rb_cmpint(r, b, e);
+
+ if (c > 0) return Qnil;
+ return e;
+ }
+}
+
VALUE
rb_range_beg_len(VALUE range, long *begp, long *lenp, long len, int err)
{
@@ -638,6 +696,8 @@ Init_Range(void)
rb_define_method(rb_cRange, "last", range_last, 0);
rb_define_method(rb_cRange, "begin", range_first, 0);
rb_define_method(rb_cRange, "end", range_last, 0);
+ rb_define_method(rb_cRange, "min", range_min, 0);
+ rb_define_method(rb_cRange, "max", range_max, 0);
rb_define_method(rb_cRange, "to_s", range_to_s, 0);
rb_define_method(rb_cRange, "inspect", range_inspect, 0);