1 /**********************************************************************
6 created at: Thu Aug 19 17:46:47 JST 1993
8 Copyright (C) 1993-2007 Yukihiro Matsumoto
10 **********************************************************************/
12 #include "ruby/internal/config.h"
23 #include "internal/array.h"
24 #include "internal/compar.h"
25 #include "internal/enum.h"
26 #include "internal/enumerator.h"
27 #include "internal/error.h"
28 #include "internal/numeric.h"
29 #include "internal/range.h"
32 static ID id_beg
, id_end
, id_excl
;
34 #define id_succ idSucc
38 static VALUE
r_cover_p(VALUE
, VALUE
, VALUE
, VALUE
);
40 #define RANGE_SET_BEG(r, v) (RSTRUCT_SET(r, 0, v))
41 #define RANGE_SET_END(r, v) (RSTRUCT_SET(r, 1, v))
42 #define RANGE_SET_EXCL(r, v) (RSTRUCT_SET(r, 2, v))
44 #define EXCL(r) RTEST(RANGE_EXCL(r))
47 range_init(VALUE range
, VALUE beg
, VALUE end
, VALUE exclude_end
)
49 if ((!FIXNUM_P(beg
) || !FIXNUM_P(end
)) && !NIL_P(beg
) && !NIL_P(end
)) {
52 v
= rb_funcall(beg
, id_cmp
, 1, end
);
54 rb_raise(rb_eArgError
, "bad value for range");
57 RANGE_SET_EXCL(range
, exclude_end
);
58 RANGE_SET_BEG(range
, beg
);
59 RANGE_SET_END(range
, end
);
61 if (CLASS_OF(range
) == rb_cRange
) {
67 rb_range_new(VALUE beg
, VALUE end
, int exclude_end
)
69 VALUE range
= rb_obj_alloc(rb_cRange
);
71 range_init(range
, beg
, end
, RBOOL(exclude_end
));
76 range_modify(VALUE range
)
78 rb_check_frozen(range
);
79 /* Ranges are immutable, so that they should be initialized only once. */
80 if (RANGE_EXCL(range
) != Qnil
) {
81 rb_name_err_raise("`initialize' called twice", range
, ID2SYM(idInitialize
));
87 * Range.new(begin, end, exclude_end = false) -> new_range
89 * Returns a new range based on the given objects +begin+ and +end+.
90 * Optional argument +exclude_end+ determines whether object +end+
91 * is included as the last object in the range:
93 * Range.new(2, 5).to_a # => [2, 3, 4, 5]
94 * Range.new(2, 5, true).to_a # => [2, 3, 4]
95 * Range.new('a', 'd').to_a # => ["a", "b", "c", "d"]
96 * Range.new('a', 'd', true).to_a # => ["a", "b", "c"]
101 range_initialize(int argc
, VALUE
*argv
, VALUE range
)
103 VALUE beg
, end
, flags
;
105 rb_scan_args(argc
, argv
, "21", &beg
, &end
, &flags
);
107 range_init(range
, beg
, end
, RBOOL(RTEST(flags
)));
113 range_initialize_copy(VALUE range
, VALUE orig
)
116 rb_struct_init_copy(range
, orig
);
122 * exclude_end? -> true or false
124 * Returns +true+ if +self+ excludes its end value; +false+ otherwise:
126 * Range.new(2, 5).exclude_end? # => false
127 * Range.new(2, 5, true).exclude_end? # => true
128 * (2..5).exclude_end? # => false
129 * (2...5).exclude_end? # => true
133 range_exclude_end_p(VALUE range
)
135 return RBOOL(EXCL(range
));
139 recursive_equal(VALUE range
, VALUE obj
, int recur
)
141 if (recur
) return Qtrue
; /* Subtle! */
142 if (!rb_equal(RANGE_BEG(range
), RANGE_BEG(obj
)))
144 if (!rb_equal(RANGE_END(range
), RANGE_END(obj
)))
147 return RBOOL(EXCL(range
) == EXCL(obj
));
153 * self == other -> true or false
155 * Returns +true+ if and only if:
157 * - +other+ is a range.
158 * - <tt>other.begin == self.begin</tt>.
159 * - <tt>other.end == self.end</tt>.
160 * - <tt>other.exclude_end? == self.exclude_end?</tt>.
162 * Otherwise returns +false+.
165 * r == (1..5) # => true
166 * r = Range.new(1, 5)
167 * r == 'foo' # => false
168 * r == (2..5) # => false
169 * r == (1..4) # => false
170 * r == (1...5) # => false
171 * r == Range.new(1, 5, true) # => false
173 * Note that even with the same argument, the return values of #== and #eql? can differ:
175 * (1..2) == (1..2.0) # => true
176 * (1..2).eql? (1..2.0) # => false
178 * Related: Range#eql?.
183 range_eq(VALUE range
, VALUE obj
)
187 if (!rb_obj_is_kind_of(obj
, rb_cRange
))
190 return rb_exec_recursive_paired(recursive_equal
, range
, obj
, obj
);
193 /* compares _a_ and _b_ and returns:
196 * > 0: a > b or non-comparable
199 r_less(VALUE a
, VALUE b
)
201 VALUE r
= rb_funcall(a
, id_cmp
, 1, b
);
205 return rb_cmpint(r
, a
, b
);
209 recursive_eql(VALUE range
, VALUE obj
, int recur
)
211 if (recur
) return Qtrue
; /* Subtle! */
212 if (!rb_eql(RANGE_BEG(range
), RANGE_BEG(obj
)))
214 if (!rb_eql(RANGE_END(range
), RANGE_END(obj
)))
217 return RBOOL(EXCL(range
) == EXCL(obj
));
222 * eql?(other) -> true or false
224 * Returns +true+ if and only if:
226 * - +other+ is a range.
227 * - <tt>other.begin eql? self.begin</tt>.
228 * - <tt>other.end eql? self.end</tt>.
229 * - <tt>other.exclude_end? == self.exclude_end?</tt>.
231 * Otherwise returns +false+.
234 * r.eql?(1..5) # => true
235 * r = Range.new(1, 5)
236 * r.eql?('foo') # => false
237 * r.eql?(2..5) # => false
238 * r.eql?(1..4) # => false
239 * r.eql?(1...5) # => false
240 * r.eql?(Range.new(1, 5, true)) # => false
242 * Note that even with the same argument, the return values of #== and #eql? can differ:
244 * (1..2) == (1..2.0) # => true
245 * (1..2).eql? (1..2.0) # => false
251 range_eql(VALUE range
, VALUE obj
)
255 if (!rb_obj_is_kind_of(obj
, rb_cRange
))
257 return rb_exec_recursive_paired(recursive_eql
, range
, obj
, obj
);
264 * Returns the integer hash value for +self+.
265 * Two range objects +r0+ and +r1+ have the same hash value
266 * if and only if <tt>r0.eql?(r1)</tt>.
268 * Related: Range#eql?, Object#hash.
272 range_hash(VALUE range
)
274 st_index_t hash
= EXCL(range
);
277 hash
= rb_hash_start(hash
);
278 v
= rb_hash(RANGE_BEG(range
));
279 hash
= rb_hash_uint(hash
, NUM2LONG(v
));
280 v
= rb_hash(RANGE_END(range
));
281 hash
= rb_hash_uint(hash
, NUM2LONG(v
));
282 hash
= rb_hash_uint(hash
, EXCL(range
) << 24);
283 hash
= rb_hash_end(hash
);
289 range_each_func(VALUE range
, int (*func
)(VALUE
, VALUE
), VALUE arg
)
292 VALUE b
= RANGE_BEG(range
);
293 VALUE e
= RANGE_END(range
);
297 while (r_less(v
, e
) < 0) {
298 if ((*func
)(v
, arg
)) break;
299 v
= rb_funcallv(v
, id_succ
, 0, 0);
303 while ((c
= r_less(v
, e
)) <= 0) {
304 if ((*func
)(v
, arg
)) break;
306 v
= rb_funcallv(v
, id_succ
, 0, 0);
312 step_i_iter(VALUE arg
)
314 VALUE
*iter
= (VALUE
*)arg
;
316 if (FIXNUM_P(iter
[0])) {
317 iter
[0] -= INT2FIX(1) & ~FIXNUM_FLAG
;
320 iter
[0] = rb_funcall(iter
[0], '-', 1, INT2FIX(1));
322 if (iter
[0] != INT2FIX(0)) return false;
328 sym_step_i(VALUE i
, VALUE arg
)
330 if (step_i_iter(arg
)) {
331 rb_yield(rb_str_intern(i
));
337 step_i(VALUE i
, VALUE arg
)
339 if (step_i_iter(arg
)) {
346 discrete_object_p(VALUE obj
)
348 return rb_respond_to(obj
, id_succ
);
352 linear_object_p(VALUE obj
)
354 if (FIXNUM_P(obj
) || FLONUM_P(obj
)) return TRUE
;
355 if (SPECIAL_CONST_P(obj
)) return FALSE
;
356 switch (BUILTIN_TYPE(obj
)) {
363 if (rb_obj_is_kind_of(obj
, rb_cNumeric
)) return TRUE
;
364 if (rb_obj_is_kind_of(obj
, rb_cTime
)) return TRUE
;
369 check_step_domain(VALUE step
)
371 VALUE zero
= INT2FIX(0);
373 if (!rb_obj_is_kind_of(step
, rb_cNumeric
)) {
374 step
= rb_to_int(step
);
376 cmp
= rb_cmpint(rb_funcallv(step
, idCmp
, 1, &zero
), step
, zero
);
378 rb_raise(rb_eArgError
, "step can't be negative");
381 rb_raise(rb_eArgError
, "step can't be 0");
387 range_step_size(VALUE range
, VALUE args
, VALUE eobj
)
389 VALUE b
= RANGE_BEG(range
), e
= RANGE_END(range
);
390 VALUE step
= INT2FIX(1);
392 step
= check_step_domain(RARRAY_AREF(args
, 0));
395 if (rb_obj_is_kind_of(b
, rb_cNumeric
) && rb_obj_is_kind_of(e
, rb_cNumeric
)) {
396 return ruby_num_interval_step_size(b
, e
, step
, EXCL(range
));
403 * step(n = 1) {|element| ... } -> self
404 * step(n = 1) -> enumerator
406 * Iterates over the elements of +self+.
408 * With a block given and no argument,
409 * calls the block each element of the range; returns +self+:
412 * (1..5).step {|element| a.push(element) } # => 1..5
413 * a # => [1, 2, 3, 4, 5]
415 * ('a'..'e').step {|element| a.push(element) } # => "a".."e"
416 * a # => ["a", "b", "c", "d", "e"]
418 * With a block given and a positive integer argument +n+ given,
419 * calls the block with element +0+, element +n+, element <tt>2n</tt>, and so on:
422 * (1..5).step(2) {|element| a.push(element) } # => 1..5
425 * ('a'..'e').step(2) {|element| a.push(element) } # => "a".."e"
426 * a # => ["a", "c", "e"]
428 * With no block given, returns an enumerator,
429 * which will be of class Enumerator::ArithmeticSequence if +self+ is numeric;
430 * otherwise of class Enumerator:
432 * e = (1..5).step(2) # => ((1..5).step(2))
433 * e.class # => Enumerator::ArithmeticSequence
434 * ('a'..'e').step # => #<Enumerator: ...>
439 range_step(int argc
, VALUE
*argv
, VALUE range
)
441 VALUE b
, e
, step
, tmp
;
443 b
= RANGE_BEG(range
);
444 e
= RANGE_END(range
);
445 step
= (!rb_check_arity(argc
, 0, 1) ? INT2FIX(1) : argv
[0]);
447 if (!rb_block_given_p()) {
448 if (!rb_obj_is_kind_of(step
, rb_cNumeric
)) {
449 step
= rb_to_int(step
);
451 if (rb_equal(step
, INT2FIX(0))) {
452 rb_raise(rb_eArgError
, "step can't be 0");
455 const VALUE b_num_p
= rb_obj_is_kind_of(b
, rb_cNumeric
);
456 const VALUE e_num_p
= rb_obj_is_kind_of(e
, rb_cNumeric
);
457 if ((b_num_p
&& (NIL_P(e
) || e_num_p
)) || (NIL_P(b
) && e_num_p
)) {
458 return rb_arith_seq_new(range
, ID2SYM(rb_frame_this_func()), argc
, argv
,
459 range_step_size
, b
, e
, step
, EXCL(range
));
462 RETURN_SIZED_ENUMERATOR(range
, argc
, argv
, range_step_size
);
465 step
= check_step_domain(step
);
466 VALUE iter
[2] = {INT2FIX(1), step
};
468 if (FIXNUM_P(b
) && NIL_P(e
) && FIXNUM_P(step
)) {
469 long i
= FIX2LONG(b
), unit
= FIX2LONG(step
);
471 rb_yield(LONG2FIX(i
));
472 i
+= unit
; /* FIXABLE+FIXABLE never overflow */
473 } while (FIXABLE(i
));
476 for (;; b
= rb_big_plus(b
, step
))
479 else if (FIXNUM_P(b
) && FIXNUM_P(e
) && FIXNUM_P(step
)) { /* fixnums are special */
480 long end
= FIX2LONG(e
);
481 long i
, unit
= FIX2LONG(step
);
487 rb_yield(LONG2NUM(i
));
488 if (i
+ unit
< i
) break;
493 else if (SYMBOL_P(b
) && (NIL_P(e
) || SYMBOL_P(e
))) { /* symbols are special */
496 rb_str_upto_endless_each(b
, sym_step_i
, (VALUE
)iter
);
499 rb_str_upto_each(b
, rb_sym2str(e
), EXCL(range
), sym_step_i
, (VALUE
)iter
);
502 else if (ruby_float_step(b
, e
, step
, EXCL(range
), TRUE
)) {
505 else if (rb_obj_is_kind_of(b
, rb_cNumeric
) ||
506 !NIL_P(rb_check_to_integer(b
, "to_int")) ||
507 !NIL_P(rb_check_to_integer(e
, "to_int"))) {
508 ID op
= EXCL(range
) ? '<' : idLE
;
512 while (NIL_P(e
) || RTEST(rb_funcall(v
, op
, 1, e
))) {
515 v
= rb_funcall(b
, '+', 1, rb_funcall(INT2NUM(i
), '*', 1, step
));
519 tmp
= rb_check_string_type(b
);
524 rb_str_upto_endless_each(b
, step_i
, (VALUE
)iter
);
527 rb_str_upto_each(b
, e
, EXCL(range
), step_i
, (VALUE
)iter
);
531 if (!discrete_object_p(b
)) {
532 rb_raise(rb_eTypeError
, "can't iterate from %s",
533 rb_obj_classname(b
));
535 range_each_func(range
, step_i
, (VALUE
)iter
);
543 * %(n) {|element| ... } -> self
546 * Iterates over the elements of +self+.
548 * With a block given, calls the block with selected elements of the range;
552 * (1..5).%(2) {|element| a.push(element) } # => 1..5
555 * ('a'..'e').%(2) {|element| a.push(element) } # => "a".."e"
556 * a # => ["a", "c", "e"]
558 * With no block given, returns an enumerator,
559 * which will be of class Enumerator::ArithmeticSequence if +self+ is numeric;
560 * otherwise of class Enumerator:
562 * e = (1..5) % 2 # => ((1..5).%(2))
563 * e.class # => Enumerator::ArithmeticSequence
564 * ('a'..'e') % 2 # => #<Enumerator: ...>
566 * Related: Range#step.
569 range_percent_step(VALUE range
, VALUE step
)
571 return range_step(1, &step
, range
);
574 #if SIZEOF_DOUBLE == 8 && defined(HAVE_INT64_T)
581 int64_as_double_to_num(int64_t i
)
583 union int64_double convert
;
586 return DBL2NUM(-convert
.d
);
590 return DBL2NUM(convert
.d
);
595 double_as_int64(double d
)
597 union int64_double convert
;
599 return d
< 0 ? -convert
.i
: convert
.i
;
604 is_integer_p(VALUE v
)
608 CONST_ID(id_integer_p
, "integer?");
609 is_int
= rb_check_funcall(v
, id_integer_p
, 0, 0);
610 return RTEST(is_int
) && is_int
!= Qundef
;
614 bsearch_integer_range(VALUE beg
, VALUE end
, int excl
)
616 VALUE satisfied
= Qnil
;
619 #define BSEARCH_CHECK(expr) \
621 VALUE val = (expr); \
622 VALUE v = rb_yield(val); \
624 if (v == INT2FIX(0)) return val; \
625 smaller = (SIGNED_VALUE)v < 0; \
627 else if (v == Qtrue) { \
631 else if (!RTEST(v)) { \
634 else if (rb_obj_is_kind_of(v, rb_cNumeric)) { \
635 int cmp = rb_cmpint(rb_funcall(v, id_cmp, 1, INT2FIX(0)), v, INT2FIX(0)); \
636 if (!cmp) return val; \
640 rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE \
641 " (must be numeric, true, false or nil)", \
646 VALUE low
= rb_to_int(beg
);
647 VALUE high
= rb_to_int(end
);
650 CONST_ID(id_div
, "div");
652 if (excl
) high
= rb_funcall(high
, '-', 1, INT2FIX(1));
655 while (rb_cmpint(rb_funcall(low
, id_cmp
, 1, high
), low
, high
) < 0) {
656 mid
= rb_funcall(rb_funcall(high
, '+', 1, low
), id_div
, 1, INT2FIX(2));
662 low
= rb_funcall(mid
, '+', 1, INT2FIX(1));
665 if (rb_equal(low
, org_high
)) {
667 if (!smaller
) return Qnil
;
674 * bsearch {|obj| block } -> value
676 * Returns an element from +self+ selected by a binary search.
678 * See {Binary Searching}[rdoc-ref:bsearch.rdoc].
683 range_bsearch(VALUE range
)
685 VALUE beg
, end
, satisfied
= Qnil
;
688 /* Implementation notes:
689 * Floats are handled by mapping them to 64 bits integers.
690 * Apart from sign issues, floats and their 64 bits integer have the
691 * same order, assuming they are represented as exponent followed
692 * by the mantissa. This is true with or without implicit bit.
694 * Finding the average of two ints needs to be careful about
695 * potential overflow (since float to long can use 64 bits)
696 * as well as the fact that -1/2 can be 0 or -1 in C89.
698 * Note that -0.0 is mapped to the same int as 0.0 as we don't want
699 * (-1...0.0).bsearch to yield -0.0.
702 #define BSEARCH(conv) \
704 RETURN_ENUMERATOR(range, 0, 0); \
705 if (EXCL(range)) high--; \
707 while (low < high) { \
708 mid = ((high < 0) == (low < 0)) ? low + ((high - low) / 2) \
709 : (low < -high) ? -((-1 - low - high)/2 + 1) : (low + high) / 2; \
710 BSEARCH_CHECK(conv(mid)); \
718 if (low == org_high) { \
719 BSEARCH_CHECK(conv(low)); \
720 if (!smaller) return Qnil; \
726 beg
= RANGE_BEG(range
);
727 end
= RANGE_END(range
);
729 if (FIXNUM_P(beg
) && FIXNUM_P(end
)) {
730 long low
= FIX2LONG(beg
);
731 long high
= FIX2LONG(end
);
735 #if SIZEOF_DOUBLE == 8 && defined(HAVE_INT64_T)
736 else if (RB_FLOAT_TYPE_P(beg
) || RB_FLOAT_TYPE_P(end
)) {
737 int64_t low
= double_as_int64(NIL_P(beg
) ? -HUGE_VAL
: RFLOAT_VALUE(rb_Float(beg
)));
738 int64_t high
= double_as_int64(NIL_P(end
) ? HUGE_VAL
: RFLOAT_VALUE(rb_Float(end
)));
739 int64_t mid
, org_high
;
740 BSEARCH(int64_as_double_to_num
);
743 else if (is_integer_p(beg
) && is_integer_p(end
)) {
744 RETURN_ENUMERATOR(range
, 0, 0);
745 return bsearch_integer_range(beg
, end
, EXCL(range
));
747 else if (is_integer_p(beg
) && NIL_P(end
)) {
748 VALUE diff
= LONG2FIX(1);
749 RETURN_ENUMERATOR(range
, 0, 0);
751 VALUE mid
= rb_funcall(beg
, '+', 1, diff
);
754 return bsearch_integer_range(beg
, mid
, 0);
756 diff
= rb_funcall(diff
, '*', 1, LONG2FIX(2));
759 else if (NIL_P(beg
) && is_integer_p(end
)) {
760 VALUE diff
= LONG2FIX(-1);
761 RETURN_ENUMERATOR(range
, 0, 0);
763 VALUE mid
= rb_funcall(end
, '+', 1, diff
);
766 return bsearch_integer_range(mid
, end
, 0);
768 diff
= rb_funcall(diff
, '*', 1, LONG2FIX(2));
772 rb_raise(rb_eTypeError
, "can't do binary search for %s", rb_obj_classname(beg
));
778 each_i(VALUE v
, VALUE arg
)
785 sym_each_i(VALUE v
, VALUE arg
)
787 return each_i(rb_str_intern(v
), arg
);
792 * size -> non_negative_integer or Infinity or nil
794 * Returns the count of elements in +self+
795 * if both begin and end values are numeric;
796 * otherwise, returns +nil+:
799 * (1...4).size # => 3
800 * (1..).size # => Infinity
801 * ('a'..'z').size #=> nil
803 * Related: Range#count.
807 range_size(VALUE range
)
809 VALUE b
= RANGE_BEG(range
), e
= RANGE_END(range
);
810 if (rb_obj_is_kind_of(b
, rb_cNumeric
)) {
811 if (rb_obj_is_kind_of(e
, rb_cNumeric
)) {
812 return ruby_num_interval_step_size(b
, e
, INT2FIX(1), EXCL(range
));
815 return DBL2NUM(HUGE_VAL
);
819 return DBL2NUM(HUGE_VAL
);
829 * Returns an array containing the elements in +self+, if a finite collection;
830 * raises an exception otherwise.
832 * (1..4).to_a # => [1, 2, 3, 4]
833 * (1...4).to_a # => [1, 2, 3]
834 * ('a'..'d').to_a # => ["a", "b", "c", "d"]
836 * Range#entries is an alias for Range#to_a.
840 range_to_a(VALUE range
)
842 if (NIL_P(RANGE_END(range
))) {
843 rb_raise(rb_eRangeError
, "cannot convert endless range to an array");
845 return rb_call_super(0, 0);
849 range_enum_size(VALUE range
, VALUE args
, VALUE eobj
)
851 return range_size(range
);
854 RBIMPL_ATTR_NORETURN()
856 range_each_bignum_endless(VALUE beg
)
858 for (;; beg
= rb_big_plus(beg
, INT2FIX(1))) {
864 RBIMPL_ATTR_NORETURN()
866 range_each_fixnum_endless(VALUE beg
)
868 for (long i
= FIX2LONG(beg
); FIXABLE(i
); i
++) {
869 rb_yield(LONG2FIX(i
));
872 range_each_bignum_endless(LONG2NUM(RUBY_FIXNUM_MAX
+ 1));
877 range_each_fixnum_loop(VALUE beg
, VALUE end
, VALUE range
)
879 long lim
= FIX2LONG(end
) + !EXCL(range
);
880 for (long i
= FIX2LONG(beg
); i
< lim
; i
++) {
881 rb_yield(LONG2FIX(i
));
888 * each {|element| ... } -> self
889 * each -> an_enumerator
891 * With a block given, passes each element of +self+ to the block:
894 * (1..4).each {|element| a.push(element) } # => 1..4
895 * a # => [1, 2, 3, 4]
897 * Raises an exception unless <tt>self.first.respond_to?(:succ)</tt>.
899 * With no block given, returns an enumerator.
904 range_each(VALUE range
)
909 RETURN_SIZED_ENUMERATOR(range
, 0, 0, range_enum_size
);
911 beg
= RANGE_BEG(range
);
912 end
= RANGE_END(range
);
914 if (FIXNUM_P(beg
) && NIL_P(end
)) {
915 range_each_fixnum_endless(beg
);
917 else if (FIXNUM_P(beg
) && FIXNUM_P(end
)) { /* fixnums are special */
918 return range_each_fixnum_loop(beg
, end
, range
);
920 else if (RB_INTEGER_TYPE_P(beg
) && (NIL_P(end
) || RB_INTEGER_TYPE_P(end
))) {
921 if (SPECIAL_CONST_P(end
) || RBIGNUM_POSITIVE_P(end
)) { /* end >= FIXNUM_MIN */
922 if (!FIXNUM_P(beg
)) {
923 if (RBIGNUM_NEGATIVE_P(beg
)) {
926 } while (!FIXNUM_P(beg
= rb_big_plus(beg
, INT2FIX(1))));
927 if (NIL_P(end
)) range_each_fixnum_endless(beg
);
928 if (FIXNUM_P(end
)) return range_each_fixnum_loop(beg
, end
, range
);
931 if (NIL_P(end
)) range_each_bignum_endless(beg
);
932 if (FIXNUM_P(end
)) return range
;
938 rb_yield(LONG2FIX(i
));
939 } while (POSFIXABLE(++i
));
942 ASSUME(!FIXNUM_P(beg
));
943 ASSUME(!SPECIAL_CONST_P(end
));
945 if (!FIXNUM_P(beg
) && RBIGNUM_SIGN(beg
) == RBIGNUM_SIGN(end
)) {
947 while (rb_big_cmp(beg
, end
) == INT2FIX(-1)) {
949 beg
= rb_big_plus(beg
, INT2FIX(1));
954 while ((c
= rb_big_cmp(beg
, end
)) != INT2FIX(1)) {
956 if (c
== INT2FIX(0)) break;
957 beg
= rb_big_plus(beg
, INT2FIX(1));
962 else if (SYMBOL_P(beg
) && (NIL_P(end
) || SYMBOL_P(end
))) { /* symbols are special */
963 beg
= rb_sym2str(beg
);
965 rb_str_upto_endless_each(beg
, sym_each_i
, 0);
968 rb_str_upto_each(beg
, rb_sym2str(end
), EXCL(range
), sym_each_i
, 0);
972 VALUE tmp
= rb_check_string_type(beg
);
976 rb_str_upto_each(tmp
, end
, EXCL(range
), each_i
, 0);
979 rb_str_upto_endless_each(tmp
, each_i
, 0);
983 if (!discrete_object_p(beg
)) {
984 rb_raise(rb_eTypeError
, "can't iterate from %s",
985 rb_obj_classname(beg
));
988 range_each_func(range
, each_i
, 0);
990 for (;; beg
= rb_funcallv(beg
, id_succ
, 0, 0))
999 * self.begin -> object
1001 * Returns the object that defines the beginning of +self+.
1003 * (1..4).begin # => 1
1004 * (..2).begin # => nil
1006 * Related: Range#first, Range#end.
1010 range_begin(VALUE range
)
1012 return RANGE_BEG(range
);
1018 * self.end -> object
1020 * Returns the object that defines the end of +self+.
1023 * (1...4).end # => 4
1024 * (1..).end # => nil
1026 * Related: Range#begin, Range#last.
1031 range_end(VALUE range
)
1033 return RANGE_END(range
);
1038 first_i(RB_BLOCK_CALL_FUNC_ARGLIST(i
, cbarg
))
1040 VALUE
*ary
= (VALUE
*)cbarg
;
1041 long n
= NUM2LONG(ary
[0]);
1046 rb_ary_push(ary
[1], i
);
1048 ary
[0] = LONG2NUM(n
);
1057 * With no argument, returns the first element of +self+, if it exists:
1059 * (1..4).first # => 1
1060 * ('a'..'d').first # => "a"
1062 * With non-negative integer argument +n+ given,
1063 * returns the first +n+ elements in an array:
1065 * (1..10).first(3) # => [1, 2, 3]
1066 * (1..10).first(0) # => []
1067 * (1..4).first(50) # => [1, 2, 3, 4]
1069 * Raises an exception if there is no first element:
1071 * (..4).first # Raises RangeError
1075 range_first(int argc
, VALUE
*argv
, VALUE range
)
1079 if (NIL_P(RANGE_BEG(range
))) {
1080 rb_raise(rb_eRangeError
, "cannot get the first element of beginless range");
1082 if (argc
== 0) return RANGE_BEG(range
);
1084 rb_scan_args(argc
, argv
, "1", &n
);
1086 ary
[1] = rb_ary_new2(NUM2LONG(n
));
1087 rb_block_call(range
, idEach
, 0, 0, first_i
, (VALUE
)ary
);
1093 rb_int_range_last(int argc
, VALUE
*argv
, VALUE range
)
1095 static const VALUE ONE
= INT2FIX(1);
1097 VALUE b
, e
, len_1
, len
, nv
, ary
;
1103 b
= RANGE_BEG(range
);
1104 e
= RANGE_END(range
);
1105 assert(RB_INTEGER_TYPE_P(b
) && RB_INTEGER_TYPE_P(e
));
1109 len_1
= rb_int_minus(e
, b
);
1110 if (FIXNUM_ZERO_P(len_1
) || rb_num_negative_p(len_1
)) {
1111 return rb_ary_new_capa(0);
1115 e
= rb_int_minus(e
, ONE
);
1119 len
= rb_int_plus(len_1
, ONE
);
1122 rb_scan_args(argc
, argv
, "1", &nv
);
1125 rb_raise(rb_eArgError
, "negative array size");
1129 if (RTEST(rb_int_gt(nv
, len
))) {
1134 ary
= rb_ary_new_capa(n
);
1135 b
= rb_int_minus(e
, nv
);
1137 b
= rb_int_plus(b
, ONE
);
1138 rb_ary_push(ary
, b
);
1150 * With no argument, returns the last element of +self+, if it exists:
1152 * (1..4).last # => 4
1153 * ('a'..'d').last # => "d"
1155 * Note that +last+ with no argument returns the end element of +self+
1156 * even if #exclude_end? is +true+:
1158 * (1...4).last # => 4
1159 * ('a'...'d').last # => "d"
1161 * With non-negative integer argument +n+ given,
1162 * returns the last +n+ elements in an array:
1164 * (1..10).last(3) # => [8, 9, 10]
1165 * (1..10).last(0) # => []
1166 * (1..4).last(50) # => [1, 2, 3, 4]
1168 * Note that +last+ with argument does not return the end element of +self+
1169 * if #exclude_end? it +true+:
1171 * (1...4).last(3) # => [1, 2, 3]
1172 * ('a'...'d').last(3) # => ["a", "b", "c"]
1174 * Raises an exception if there is no last element:
1176 * (1..).last # Raises RangeError
1181 range_last(int argc
, VALUE
*argv
, VALUE range
)
1185 if (NIL_P(RANGE_END(range
))) {
1186 rb_raise(rb_eRangeError
, "cannot get the last element of endless range");
1188 if (argc
== 0) return RANGE_END(range
);
1190 b
= RANGE_BEG(range
);
1191 e
= RANGE_END(range
);
1192 if (RB_INTEGER_TYPE_P(b
) && RB_INTEGER_TYPE_P(e
) &&
1193 RB_LIKELY(rb_method_basic_definition_p(rb_cRange
, idEach
))) {
1194 return rb_int_range_last(argc
, argv
, range
);
1196 return rb_ary_last(argc
, argv
, rb_Array(range
));
1204 * min {|a, b| ... } -> object
1205 * min(n) {|a, b| ... } -> array
1207 * Returns the minimum value in +self+,
1208 * using method <tt><=></tt> or a given block for comparison.
1210 * With no argument and no block given,
1211 * returns the minimum-valued element of +self+.
1214 * ('a'..'d').min # => "a"
1215 * (-4..-1).min # => -4
1217 * With non-negative integer argument +n+ given, and no block given,
1218 * returns the +n+ minimum-valued elements of +self+ in an array:
1220 * (1..4).min(2) # => [1, 2]
1221 * ('a'..'d').min(2) # => ["a", "b"]
1222 * (-4..-1).min(2) # => [-4, -3]
1223 * (1..4).min(50) # => [1, 2, 3, 4]
1225 * If a block is given, it is called:
1227 * - First, with the first two element of +self+.
1228 * - Then, sequentially, with the so-far minimum value and the next element of +self+.
1232 * (1..4).min {|a, b| p [a, b]; a <=> b } # => 1
1240 * With no argument and a block given,
1241 * returns the return value of the last call to the block:
1243 * (1..4).min {|a, b| -(a <=> b) } # => 4
1245 * With non-negative integer argument +n+ given, and a block given,
1246 * returns the return values of the last +n+ calls to the block in an array:
1248 * (1..4).min(2) {|a, b| -(a <=> b) } # => [4, 3]
1249 * (1..4).min(50) {|a, b| -(a <=> b) } # => [4, 3, 2, 1]
1251 * Returns an empty array if +n+ is zero:
1253 * (1..4).min(0) # => []
1254 * (1..4).min(0) {|a, b| -(a <=> b) } # => []
1256 * Returns +nil+ or an empty array if:
1258 * - The begin value of the range is larger than the end value:
1260 * (4..1).min # => nil
1261 * (4..1).min(2) # => []
1262 * (4..1).min {|a, b| -(a <=> b) } # => nil
1263 * (4..1).min(2) {|a, b| -(a <=> b) } # => []
1265 * - The begin value of an exclusive range is equal to the end value:
1267 * (1...1).min # => nil
1268 * (1...1).min(2) # => []
1269 * (1...1).min {|a, b| -(a <=> b) } # => nil
1270 * (1...1).min(2) {|a, b| -(a <=> b) } # => []
1272 * Raises an exception if either:
1274 * - +self+ is a beginless range: <tt>(..4)</tt>.
1275 * - A block is given and +self+ is an endless range.
1277 * Related: Range#max, Range#minmax.
1282 range_min(int argc
, VALUE
*argv
, VALUE range
)
1284 if (NIL_P(RANGE_BEG(range
))) {
1285 rb_raise(rb_eRangeError
, "cannot get the minimum of beginless range");
1288 if (rb_block_given_p()) {
1289 if (NIL_P(RANGE_END(range
))) {
1290 rb_raise(rb_eRangeError
, "cannot get the minimum of endless range with custom comparison method");
1292 return rb_call_super(argc
, argv
);
1294 else if (argc
!= 0) {
1295 return range_first(argc
, argv
, range
);
1298 struct cmp_opt_data cmp_opt
= { 0, 0 };
1299 VALUE b
= RANGE_BEG(range
);
1300 VALUE e
= RANGE_END(range
);
1301 int c
= NIL_P(e
) ? -1 : OPTIMIZED_CMP(b
, e
, cmp_opt
);
1303 if (c
> 0 || (c
== 0 && EXCL(range
)))
1313 * max {|a, b| ... } -> object
1314 * max(n) {|a, b| ... } -> array
1316 * Returns the maximum value in +self+,
1317 * using method <tt><=></tt> or a given block for comparison.
1319 * With no argument and no block given,
1320 * returns the maximum-valued element of +self+.
1323 * ('a'..'d').max # => "d"
1324 * (-4..-1).max # => -1
1326 * With non-negative integer argument +n+ given, and no block given,
1327 * returns the +n+ maximum-valued elements of +self+ in an array:
1329 * (1..4).max(2) # => [4, 3]
1330 * ('a'..'d').max(2) # => ["d", "c"]
1331 * (-4..-1).max(2) # => [-1, -2]
1332 * (1..4).max(50) # => [4, 3, 2, 1]
1334 * If a block is given, it is called:
1336 * - First, with the first two element of +self+.
1337 * - Then, sequentially, with the so-far maximum value and the next element of +self+.
1341 * (1..4).max {|a, b| p [a, b]; a <=> b } # => 4
1349 * With no argument and a block given,
1350 * returns the return value of the last call to the block:
1352 * (1..4).max {|a, b| -(a <=> b) } # => 1
1354 * With non-negative integer argument +n+ given, and a block given,
1355 * returns the return values of the last +n+ calls to the block in an array:
1357 * (1..4).max(2) {|a, b| -(a <=> b) } # => [1, 2]
1358 * (1..4).max(50) {|a, b| -(a <=> b) } # => [1, 2, 3, 4]
1360 * Returns an empty array if +n+ is zero:
1362 * (1..4).max(0) # => []
1363 * (1..4).max(0) {|a, b| -(a <=> b) } # => []
1365 * Returns +nil+ or an empty array if:
1367 * - The begin value of the range is larger than the end value:
1369 * (4..1).max # => nil
1370 * (4..1).max(2) # => []
1371 * (4..1).max {|a, b| -(a <=> b) } # => nil
1372 * (4..1).max(2) {|a, b| -(a <=> b) } # => []
1374 * - The begin value of an exclusive range is equal to the end value:
1376 * (1...1).max # => nil
1377 * (1...1).max(2) # => []
1378 * (1...1).max {|a, b| -(a <=> b) } # => nil
1379 * (1...1).max(2) {|a, b| -(a <=> b) } # => []
1381 * Raises an exception if either:
1383 * - +self+ is a endless range: <tt>(1..)</tt>.
1384 * - A block is given and +self+ is a beginless range.
1386 * Related: Range#min, Range#minmax.
1391 range_max(int argc
, VALUE
*argv
, VALUE range
)
1393 VALUE e
= RANGE_END(range
);
1394 int nm
= FIXNUM_P(e
) || rb_obj_is_kind_of(e
, rb_cNumeric
);
1396 if (NIL_P(RANGE_END(range
))) {
1397 rb_raise(rb_eRangeError
, "cannot get the maximum of endless range");
1400 VALUE b
= RANGE_BEG(range
);
1402 if (rb_block_given_p() || (EXCL(range
) && !nm
) || argc
) {
1404 rb_raise(rb_eRangeError
, "cannot get the maximum of beginless range with custom comparison method");
1406 return rb_call_super(argc
, argv
);
1409 struct cmp_opt_data cmp_opt
= { 0, 0 };
1410 int c
= NIL_P(b
) ? -1 : OPTIMIZED_CMP(b
, e
, cmp_opt
);
1415 if (!RB_INTEGER_TYPE_P(e
)) {
1416 rb_raise(rb_eTypeError
, "cannot exclude non Integer end value");
1418 if (c
== 0) return Qnil
;
1419 if (!RB_INTEGER_TYPE_P(b
)) {
1420 rb_raise(rb_eTypeError
, "cannot exclude end value with non Integer begin value");
1423 return LONG2NUM(FIX2LONG(e
) - 1);
1425 return rb_funcall(e
, '-', 1, INT2FIX(1));
1433 * minmax -> [object, object]
1434 * minmax {|a, b| ... } -> [object, object]
1436 * Returns a 2-element array containing the minimum and maximum value in +self+,
1437 * either according to comparison method <tt><=></tt> or a given block.
1439 * With no block given, returns the minimum and maximum values,
1440 * using <tt><=></tt> for comparison:
1442 * (1..4).minmax # => [1, 4]
1443 * (1...4).minmax # => [1, 3]
1444 * ('a'..'d').minmax # => ["a", "d"]
1445 * (-4..-1).minmax # => [-4, -1]
1447 * With a block given, the block must return an integer:
1449 * - Negative if +a+ is smaller than +b+.
1450 * - Zero if +a+ and +b+ are equal.
1451 * - Positive if +a+ is larger than +b+.
1453 * The block is called <tt>self.size</tt> times to compare elements;
1454 * returns a 2-element Array containing the minimum and maximum values from +self+,
1457 * (1..4).minmax {|a, b| -(a <=> b) } # => [4, 1]
1459 * Returns <tt>[nil, nil]</tt> if:
1461 * - The begin value of the range is larger than the end value:
1463 * (4..1).minmax # => [nil, nil]
1464 * (4..1).minmax {|a, b| -(a <=> b) } # => [nil, nil]
1466 * - The begin value of an exclusive range is equal to the end value:
1468 * (1...1).minmax # => [nil, nil]
1469 * (1...1).minmax {|a, b| -(a <=> b) } # => [nil, nil]
1471 * Raises an exception if +self+ is a beginless or an endless range.
1473 * Related: Range#min, Range#max.
1478 range_minmax(VALUE range
)
1480 if (rb_block_given_p()) {
1481 return rb_call_super(0, NULL
);
1483 return rb_assoc_new(
1484 rb_funcall(range
, id_min
, 0),
1485 rb_funcall(range
, id_max
, 0)
1490 rb_range_values(VALUE range
, VALUE
*begp
, VALUE
*endp
, int *exclp
)
1495 if (rb_obj_is_kind_of(range
, rb_cRange
)) {
1496 b
= RANGE_BEG(range
);
1497 e
= RANGE_END(range
);
1500 else if (RTEST(rb_obj_is_kind_of(range
, rb_cArithSeq
))) {
1505 b
= rb_check_funcall(range
, id_beg
, 0, 0);
1506 if (b
== Qundef
) return (int)Qfalse
;
1507 e
= rb_check_funcall(range
, id_end
, 0, 0);
1508 if (e
== Qundef
) return (int)Qfalse
;
1509 x
= rb_check_funcall(range
, rb_intern("exclude_end?"), 0, 0);
1510 if (x
== Qundef
) return (int)Qfalse
;
1519 /* Extract the components of a Range.
1521 * You can use +err+ to control the behavior of out-of-range and exception.
1523 * When +err+ is 0 or 2, if the begin offset is greater than +len+,
1524 * it is out-of-range. The +RangeError+ is raised only if +err+ is 2,
1525 * in this case. If +err+ is 0, +Qnil+ will be returned.
1527 * When +err+ is 1, the begin and end offsets won't be adjusted even if they
1528 * are greater than +len+. It allows +rb_ary_aset+ extends arrays.
1530 * If the begin component of the given range is negative and is too-large
1531 * abstract value, the +RangeError+ is raised only +err+ is 1 or 2.
1533 * The case of <code>err = 0</code> is used in item accessing methods such as
1534 * +rb_ary_aref+, +rb_ary_slice_bang+, and +rb_str_aref+.
1536 * The case of <code>err = 1</code> is used in Array's methods such as
1537 * +rb_ary_aset+ and +rb_ary_fill+.
1539 * The case of <code>err = 2</code> is used in +rb_str_aset+.
1542 rb_range_component_beg_len(VALUE b
, VALUE e
, int excl
,
1543 long *begp
, long *lenp
, long len
, int err
)
1547 beg
= NIL_P(b
) ? 0 : NUM2LONG(b
);
1548 end
= NIL_P(e
) ? -1 : NUM2LONG(e
);
1549 if (NIL_P(e
)) excl
= 0;
1558 end
++; /* include end point */
1559 if (err
== 0 || err
== 2) {
1578 rb_range_beg_len(VALUE range
, long *begp
, long *lenp
, long len
, int err
)
1583 if (!rb_range_values(range
, &b
, &e
, &excl
))
1586 VALUE res
= rb_range_component_beg_len(b
, e
, excl
, begp
, lenp
, len
, err
);
1587 if (NIL_P(res
) && err
) {
1588 rb_raise(rb_eRangeError
, "%+"PRIsVALUE
" out of range", range
);
1598 * Returns a string representation of +self+,
1599 * including <tt>begin.to_s</tt> and <tt>end.to_s</tt>:
1601 * (1..4).to_s # => "1..4"
1602 * (1...4).to_s # => "1...4"
1603 * (1..).to_s # => "1.."
1604 * (..4).to_s # => "..4"
1606 * Note that returns from #to_s and #inspect may differ:
1608 * ('a'..'d').to_s # => "a..d"
1609 * ('a'..'d').inspect # => "\"a\"..\"d\""
1611 * Related: Range#inspect.
1616 range_to_s(VALUE range
)
1620 str
= rb_obj_as_string(RANGE_BEG(range
));
1621 str2
= rb_obj_as_string(RANGE_END(range
));
1622 str
= rb_str_dup(str
);
1623 rb_str_cat(str
, "...", EXCL(range
) ? 3 : 2);
1624 rb_str_append(str
, str2
);
1630 inspect_range(VALUE range
, VALUE dummy
, int recur
)
1632 VALUE str
, str2
= Qundef
;
1635 return rb_str_new2(EXCL(range
) ? "(... ... ...)" : "(... .. ...)");
1637 if (!NIL_P(RANGE_BEG(range
)) || NIL_P(RANGE_END(range
))) {
1638 str
= rb_str_dup(rb_inspect(RANGE_BEG(range
)));
1641 str
= rb_str_new(0, 0);
1643 rb_str_cat(str
, "...", EXCL(range
) ? 3 : 2);
1644 if (NIL_P(RANGE_BEG(range
)) || !NIL_P(RANGE_END(range
))) {
1645 str2
= rb_inspect(RANGE_END(range
));
1647 if (str2
!= Qundef
) rb_str_append(str
, str2
);
1656 * Returns a string representation of +self+,
1657 * including <tt>begin.inspect</tt> and <tt>end.inspect</tt>:
1659 * (1..4).inspect # => "1..4"
1660 * (1...4).inspect # => "1...4"
1661 * (1..).inspect # => "1.."
1662 * (..4).inspect # => "..4"
1664 * Note that returns from #to_s and #inspect may differ:
1666 * ('a'..'d').to_s # => "a..d"
1667 * ('a'..'d').inspect # => "\"a\"..\"d\""
1669 * Related: Range#to_s.
1675 range_inspect(VALUE range
)
1677 return rb_exec_recursive(inspect_range
, range
, 0);
1680 static VALUE
range_include_internal(VALUE range
, VALUE val
, int string_use_cover
);
1684 * self === object -> true or false
1686 * Returns +true+ if +object+ is between <tt>self.begin</tt> and <tt>self.end</tt>.
1687 * +false+ otherwise:
1689 * (1..4) === 2 # => true
1690 * (1..4) === 5 # => false
1691 * (1..4) === 'a' # => false
1692 * (1..4) === 4 # => true
1693 * (1...4) === 4 # => false
1694 * ('a'..'d') === 'c' # => true
1695 * ('a'..'d') === 'e' # => false
1697 * A case statement uses method <tt>===</tt>, and so:
1711 * when "2.4"..."2.5"
1713 * when "2.5"..."3.0"
1722 range_eqq(VALUE range
, VALUE val
)
1724 VALUE ret
= range_include_internal(range
, val
, 1);
1725 if (ret
!= Qundef
) return ret
;
1726 return r_cover_p(range
, RANGE_BEG(range
), RANGE_END(range
), val
);
1732 * include?(object) -> true or false
1734 * Returns +true+ if +object+ is an element of +self+, +false+ otherwise:
1736 * (1..4).include?(2) # => true
1737 * (1..4).include?(5) # => false
1738 * (1..4).include?(4) # => true
1739 * (1...4).include?(4) # => false
1740 * ('a'..'d').include?('b') # => true
1741 * ('a'..'d').include?('e') # => false
1742 * ('a'..'d').include?('B') # => false
1743 * ('a'..'d').include?('d') # => true
1744 * ('a'...'d').include?('d') # => false
1746 * If begin and end are numeric, #include? behaves like #cover?
1748 * (1..3).include?(1.5) # => true
1749 * (1..3).cover?(1.5) # => true
1751 * But when not numeric, the two methods may differ:
1753 * ('a'..'d').include?('cc') # => false
1754 * ('a'..'d').cover?('cc') # => true
1756 * Related: Range#cover?.
1758 * Range#member? is an alias for Range#include?.
1762 range_include(VALUE range
, VALUE val
)
1764 VALUE ret
= range_include_internal(range
, val
, 0);
1765 if (ret
!= Qundef
) return ret
;
1766 return rb_call_super(1, &val
);
1770 range_include_internal(VALUE range
, VALUE val
, int string_use_cover
)
1772 VALUE beg
= RANGE_BEG(range
);
1773 VALUE end
= RANGE_END(range
);
1774 int nv
= FIXNUM_P(beg
) || FIXNUM_P(end
) ||
1775 linear_object_p(beg
) || linear_object_p(end
);
1778 !NIL_P(rb_check_to_integer(beg
, "to_int")) ||
1779 !NIL_P(rb_check_to_integer(end
, "to_int"))) {
1780 return r_cover_p(range
, beg
, end
, val
);
1782 else if (RB_TYPE_P(beg
, T_STRING
) || RB_TYPE_P(end
, T_STRING
)) {
1783 if (RB_TYPE_P(beg
, T_STRING
) && RB_TYPE_P(end
, T_STRING
)) {
1784 if (string_use_cover
) {
1785 return r_cover_p(range
, beg
, end
, val
);
1788 VALUE
rb_str_include_range_p(VALUE beg
, VALUE end
, VALUE val
, VALUE exclusive
);
1789 return rb_str_include_range_p(beg
, end
, val
, RANGE_EXCL(range
));
1792 else if (NIL_P(beg
)) {
1793 VALUE r
= rb_funcall(val
, id_cmp
, 1, end
);
1794 if (NIL_P(r
)) return Qfalse
;
1795 return RBOOL(rb_cmpint(r
, val
, end
) <= 0);
1797 else if (NIL_P(end
)) {
1798 VALUE r
= rb_funcall(beg
, id_cmp
, 1, val
);
1799 if (NIL_P(r
)) return Qfalse
;
1800 return RBOOL(rb_cmpint(r
, beg
, val
) <= 0);
1806 static int r_cover_range_p(VALUE range
, VALUE beg
, VALUE end
, VALUE val
);
1810 * cover?(object) -> true or false
1811 * cover?(range) -> true or false
1813 * Returns +true+ if the given argument is within +self+, +false+ otherwise.
1815 * With non-range argument +object+, evaluates with <tt><=</tt> and <tt><</tt>.
1817 * For range +self+ with included end value (<tt>#exclude_end? == false</tt>),
1820 * self.begin <= object <= self.end
1825 * r.cover?(1) # => true
1826 * r.cover?(4) # => true
1827 * r.cover?(0) # => false
1828 * r.cover?(5) # => false
1829 * r.cover?('foo') # => false
1832 * r.cover?('a') # => true
1833 * r.cover?('d') # => true
1834 * r.cover?(' ') # => false
1835 * r.cover?('e') # => false
1836 * r.cover?(0) # => false
1838 * For range +r+ with excluded end value (<tt>#exclude_end? == true</tt>),
1841 * r.begin <= object < r.end
1846 * r.cover?(1) # => true
1847 * r.cover?(3) # => true
1848 * r.cover?(0) # => false
1849 * r.cover?(4) # => false
1850 * r.cover?('foo') # => false
1853 * r.cover?('a') # => true
1854 * r.cover?('c') # => true
1855 * r.cover?(' ') # => false
1856 * r.cover?('d') # => false
1857 * r.cover?(0) # => false
1859 * With range argument +range+, compares the first and last
1860 * elements of +self+ and +range+:
1863 * r.cover?(1..4) # => true
1864 * r.cover?(0..4) # => false
1865 * r.cover?(1..5) # => false
1866 * r.cover?('a'..'d') # => false
1869 * r.cover?(1..3) # => true
1870 * r.cover?(1..4) # => false
1872 * If begin and end are numeric, #cover? behaves like #include?
1874 * (1..3).cover?(1.5) # => true
1875 * (1..3).include?(1.5) # => true
1877 * But when not numeric, the two methods may differ:
1879 * ('a'..'d').cover?('cc') # => true
1880 * ('a'..'d').include?('cc') # => false
1882 * Returns +false+ if either:
1884 * - The begin value of +self+ is larger than its end value.
1885 * - An internal call to <tt><=></tt> returns +nil+;
1886 * that is, the operands are not comparable.
1888 * Related: Range#include?.
1893 range_cover(VALUE range
, VALUE val
)
1897 beg
= RANGE_BEG(range
);
1898 end
= RANGE_END(range
);
1900 if (rb_obj_is_kind_of(val
, rb_cRange
)) {
1901 return RBOOL(r_cover_range_p(range
, beg
, end
, val
));
1903 return r_cover_p(range
, beg
, end
, val
);
1909 return rb_funcallv(r
, rb_intern("max"), 0, 0);
1913 r_cover_range_p(VALUE range
, VALUE beg
, VALUE end
, VALUE val
)
1915 VALUE val_beg
, val_end
, val_max
;
1918 val_beg
= RANGE_BEG(val
);
1919 val_end
= RANGE_END(val
);
1921 if (!NIL_P(end
) && NIL_P(val_end
)) return FALSE
;
1922 if (!NIL_P(beg
) && NIL_P(val_beg
)) return FALSE
;
1923 if (!NIL_P(val_beg
) && !NIL_P(val_end
) && r_less(val_beg
, val_end
) > (EXCL(val
) ? -1 : 0)) return FALSE
;
1924 if (!NIL_P(val_beg
) && !r_cover_p(range
, beg
, end
, val_beg
)) return FALSE
;
1926 cmp_end
= r_less(end
, val_end
);
1928 if (EXCL(range
) == EXCL(val
)) {
1929 return cmp_end
>= 0;
1931 else if (EXCL(range
)) {
1934 else if (cmp_end
>= 0) {
1938 val_max
= rb_rescue2(r_call_max
, val
, 0, Qnil
, rb_eTypeError
, (VALUE
)0);
1939 if (NIL_P(val_max
)) return FALSE
;
1941 return r_less(end
, val_max
) >= 0;
1945 r_cover_p(VALUE range
, VALUE beg
, VALUE end
, VALUE val
)
1947 if (NIL_P(beg
) || r_less(beg
, val
) <= 0) {
1948 int excl
= EXCL(range
);
1949 if (NIL_P(end
) || r_less(val
, end
) <= -excl
)
1956 range_dumper(VALUE range
)
1958 VALUE v
= rb_obj_alloc(rb_cObject
);
1960 rb_ivar_set(v
, id_excl
, RANGE_EXCL(range
));
1961 rb_ivar_set(v
, id_beg
, RANGE_BEG(range
));
1962 rb_ivar_set(v
, id_end
, RANGE_END(range
));
1967 range_loader(VALUE range
, VALUE obj
)
1969 VALUE beg
, end
, excl
;
1971 if (!RB_TYPE_P(obj
, T_OBJECT
) || RBASIC(obj
)->klass
!= rb_cObject
) {
1972 rb_raise(rb_eTypeError
, "not a dumped range object");
1975 range_modify(range
);
1976 beg
= rb_ivar_get(obj
, id_beg
);
1977 end
= rb_ivar_get(obj
, id_end
);
1978 excl
= rb_ivar_get(obj
, id_excl
);
1980 range_init(range
, beg
, end
, RBOOL(RTEST(excl
)));
1986 range_alloc(VALUE klass
)
1988 /* rb_struct_alloc_noinit itself should not be used because
1989 * rb_marshal_define_compat uses equality of allocation function */
1990 return rb_struct_alloc_noinit(klass
);
1996 * count(object) -> integer
1997 * count {|element| ... } -> integer
1999 * Returns the count of elements, based on an argument or block criterion, if given.
2001 * With no argument and no block given, returns the number of elements:
2003 * (1..4).count # => 4
2004 * (1...4).count # => 3
2005 * ('a'..'d').count # => 4
2006 * ('a'...'d').count # => 3
2007 * (1..).count # => Infinity
2008 * (..4).count # => Infinity
2010 * With argument +object+, returns the number of +object+ found in +self+,
2011 * which will usually be zero or one:
2013 * (1..4).count(2) # => 1
2014 * (1..4).count(5) # => 0
2015 * (1..4).count('a') # => 0
2017 * With a block given, calls the block with each element;
2018 * returns the number of elements for which the block returns a truthy value:
2020 * (1..4).count {|element| element < 3 } # => 2
2022 * Related: Range#size.
2025 range_count(int argc
, VALUE
*argv
, VALUE range
)
2028 /* It is odd for instance (1...).count(0) to return Infinity. Just let
2030 return rb_call_super(argc
, argv
);
2032 else if (rb_block_given_p()) {
2033 /* Likewise it is odd for instance (1...).count {|x| x == 0 } to return
2034 * Infinity. Just let it loop. */
2035 return rb_call_super(argc
, argv
);
2037 else if (NIL_P(RANGE_END(range
))) {
2038 /* We are confident that the answer is Infinity. */
2039 return DBL2NUM(HUGE_VAL
);
2041 else if (NIL_P(RANGE_BEG(range
))) {
2042 /* We are confident that the answer is Infinity. */
2043 return DBL2NUM(HUGE_VAL
);
2046 return rb_call_super(argc
, argv
);
2050 /* A \Range object represents a collection of values
2051 * that are between given begin and end values.
2053 * You can create an \Range object explicitly with:
2055 * - A {range literal}[doc/syntax/literals_rdoc.html#label-Range+Literals]:
2057 * # Ranges that use '..' to include the given end value.
2058 * (1..4).to_a # => [1, 2, 3, 4]
2059 * ('a'..'d').to_a # => ["a", "b", "c", "d"]
2060 * # Ranges that use '...' to exclude the given end value.
2061 * (1...4).to_a # => [1, 2, 3]
2062 * ('a'...'d').to_a # => ["a", "b", "c"]
2064 * A range may be created using method Range.new:
2066 * # Ranges that by default include the given end value.
2067 * Range.new(1, 4).to_a # => [1, 2, 3, 4]
2068 * Range.new('a', 'd').to_a # => ["a", "b", "c", "d"]
2069 * # Ranges that use third argument +exclude_end+ to exclude the given end value.
2070 * Range.new(1, 4, true).to_a # => [1, 2, 3]
2071 * Range.new('a', 'd', true).to_a # => ["a", "b", "c"]
2073 * == Beginless Ranges
2075 * A _beginless_ _range_ has a definite end value, but a +nil+ begin value.
2076 * Such a range includes all values up to the end value.
2078 * r = (..4) # => nil..4
2080 * r.include?(-50) # => true
2081 * r.include?(4) # => true
2083 * r = (...4) # => nil...4
2084 * r.include?(4) # => false
2086 * Range.new(nil, 4) # => nil..4
2087 * Range.new(nil, 4, true) # => nil...4
2089 * A beginless range may be used to slice an array:
2092 * r = (..2) # => nil...2
2095 * \Method +each+ for a beginless range raises an exception.
2099 * An _endless_ _range_ has a definite begin value, but a +nil+ end value.
2100 * Such a range includes all values from the begin value.
2102 * r = (1..) # => 1..
2104 * r.include?(50) # => true
2106 * Range.new(1, nil) # => 1..
2108 * The literal for an endless range may be written with either two dots
2110 * The range has the same elements, either way.
2111 * But note that the two are not equal:
2113 * r0 = (1..) # => 1..
2114 * r1 = (1...) # => 1...
2115 * r0.begin == r1.begin # => true
2116 * r0.end == r1.end # => true
2117 * r0 == r1 # => false
2119 * An endless range may be used to slice an array:
2122 * r = (2..) # => 2..
2125 * \Method +each+ for an endless range calls the given block indefinitely:
2130 * a.push(i) if i.even?
2133 * a # => [2, 4, 6, 8, 10]
2135 * == Ranges and Other Classes
2137 * An object may be put into a range if its class implements
2138 * instance method <tt><=></tt>.
2139 * Ruby core classes that do so include Array, Complex, File::Stat,
2140 * Float, Integer, Kernel, Module, Numeric, Rational, String, Symbol, and Time.
2144 * t0 = Time.now # => 2021-09-19 09:22:48.4854986 -0500
2145 * t1 = Time.now # => 2021-09-19 09:22:56.0365079 -0500
2146 * t2 = Time.now # => 2021-09-19 09:23:08.5263283 -0500
2147 * (t0..t2).include?(t1) # => true
2148 * (t0..t1).include?(t2) # => false
2150 * A range can be iterated over only if its elements
2151 * implement instance method +succ+.
2152 * Ruby core classes that do so include Integer, String, and Symbol
2153 * (but not the other classes mentioned above).
2155 * Iterator methods include:
2157 * - In \Range itself: #each, #step, and #%
2158 * - Included from module Enumerable: #each_entry, #each_with_index,
2159 * #each_with_object, #each_slice, #each_cons, and #reverse_each.
2164 * (1..4).each {|i| a.push(i) }
2165 * a # => [1, 2, 3, 4]
2167 * == Ranges and User-Defined Classes
2169 * A user-defined class that is to be used in a range
2170 * must implement instance <tt><=></tt>;
2171 * see {Integer#<=>}[Integer.html#label-method-i-3C-3D-3E].
2172 * To make iteration available, it must also implement
2173 * instance method +succ+; see Integer#succ.
2175 * The class below implements both <tt><=></tt> and +succ+,
2176 * and so can be used both to construct ranges and to iterate over them.
2177 * Note that the Comparable module is included
2178 * so the <tt>==</tt> method is defined in terms of <tt><=></tt>.
2180 * # Represent a string of 'X' characters.
2182 * include Comparable
2183 * attr_accessor :length
2188 * Xs.new(@length + 1)
2191 * @length <=> other.length
2194 * sprintf "%2d #{inspect}", @length
2201 * r = Xs.new(3)..Xs.new(6) #=> XXX..XXXXXX
2202 * r.to_a #=> [XXX, XXXX, XXXXX, XXXXXX]
2203 * r.include?(Xs.new(5)) #=> true
2204 * r.include?(Xs.new(7)) #=> false
2208 * First, what's elsewhere. \Class \Range:
2210 * - Inherits from {class Object}[Object.html#class-Object-label-What-27s+Here].
2211 * - Includes {module Enumerable}[Enumerable.html#module-Enumerable-label-What-27s+Here],
2212 * which provides dozens of additional methods.
2214 * Here, class \Range provides methods that are useful for:
2216 * - {Creating a Range}[#class-Range-label-Methods+for+Creating+a+Range]
2217 * - {Querying}[#class-Range-label-Methods+for+Querying]
2218 * - {Comparing}[#class-Range-label-Methods+for+Comparing]
2219 * - {Iterating}[#class-Range-label-Methods+for+Iterating]
2220 * - {Converting}[#class-Range-label-Methods+for+Converting]
2222 * === Methods for Creating a \Range
2224 * - ::new:: Returns a new range.
2226 * === Methods for Querying
2228 * - #begin:: Returns the begin value given for +self+.
2229 * - #bsearch:: Returns an element from +self+ selected by a binary search.
2230 * - #count:: Returns a count of elements in +self+.
2231 * - #end:: Returns the end value given for +self+.
2232 * - #exclude_end?:: Returns whether the end object is excluded.
2233 * - #first:: Returns the first elements of +self+.
2234 * - #hash:: Returns the integer hash code.
2235 * - #last:: Returns the last elements of +self+.
2236 * - #max:: Returns the maximum values in +self+.
2237 * - #min:: Returns the minimum values in +self+.
2238 * - #minmax:: Returns the minimum and maximum values in +self+.
2239 * - #size:: Returns the count of elements in +self+.
2241 * === Methods for Comparing
2243 * - {#==}[#method-i-3D-3D]:: Returns whether a given object is equal to +self+
2245 * - #===:: Returns whether the given object is between the begin and end values.
2246 * - #cover?:: Returns whether a given object is within +self+.
2247 * - #eql?:: Returns whether a given object is equal to +self+ (uses #eql?).
2248 * - #include? (aliased as #member?):: Returns whether a given object
2249 * is an element of +self+.
2251 * === Methods for Iterating
2253 * - #%:: Requires argument +n+; calls the block with each +n+-th element of +self+.
2254 * - #each:: Calls the block with each element of +self+.
2255 * - #step:: Takes optional argument +n+ (defaults to 1);
2256 calls the block with each +n+-th element of +self+.
2258 * === Methods for Converting
2260 * - #inspect:: Returns a string representation of +self+ (uses #inspect).
2261 * - #to_a (aliased as #entries):: Returns elements of +self+ in an array.
2262 * - #to_s:: Returns a string representation of +self+ (uses #to_s).
2269 id_beg
= rb_intern_const("begin");
2270 id_end
= rb_intern_const("end");
2271 id_excl
= rb_intern_const("excl");
2273 rb_cRange
= rb_struct_define_without_accessor(
2274 "Range", rb_cObject
, range_alloc
,
2275 "begin", "end", "excl", NULL
);
2277 rb_include_module(rb_cRange
, rb_mEnumerable
);
2278 rb_marshal_define_compat(rb_cRange
, rb_cObject
, range_dumper
, range_loader
);
2279 rb_define_method(rb_cRange
, "initialize", range_initialize
, -1);
2280 rb_define_method(rb_cRange
, "initialize_copy", range_initialize_copy
, 1);
2281 rb_define_method(rb_cRange
, "==", range_eq
, 1);
2282 rb_define_method(rb_cRange
, "===", range_eqq
, 1);
2283 rb_define_method(rb_cRange
, "eql?", range_eql
, 1);
2284 rb_define_method(rb_cRange
, "hash", range_hash
, 0);
2285 rb_define_method(rb_cRange
, "each", range_each
, 0);
2286 rb_define_method(rb_cRange
, "step", range_step
, -1);
2287 rb_define_method(rb_cRange
, "%", range_percent_step
, 1);
2288 rb_define_method(rb_cRange
, "bsearch", range_bsearch
, 0);
2289 rb_define_method(rb_cRange
, "begin", range_begin
, 0);
2290 rb_define_method(rb_cRange
, "end", range_end
, 0);
2291 rb_define_method(rb_cRange
, "first", range_first
, -1);
2292 rb_define_method(rb_cRange
, "last", range_last
, -1);
2293 rb_define_method(rb_cRange
, "min", range_min
, -1);
2294 rb_define_method(rb_cRange
, "max", range_max
, -1);
2295 rb_define_method(rb_cRange
, "minmax", range_minmax
, 0);
2296 rb_define_method(rb_cRange
, "size", range_size
, 0);
2297 rb_define_method(rb_cRange
, "to_a", range_to_a
, 0);
2298 rb_define_method(rb_cRange
, "entries", range_to_a
, 0);
2299 rb_define_method(rb_cRange
, "to_s", range_to_s
, 0);
2300 rb_define_method(rb_cRange
, "inspect", range_inspect
, 0);
2302 rb_define_method(rb_cRange
, "exclude_end?", range_exclude_end_p
, 0);
2304 rb_define_method(rb_cRange
, "member?", range_include
, 1);
2305 rb_define_method(rb_cRange
, "include?", range_include
, 1);
2306 rb_define_method(rb_cRange
, "cover?", range_cover
, 1);
2307 rb_define_method(rb_cRange
, "count", range_count
, -1);