Ruby  3.1.4p223 (2023-03-30 revision HEAD)
range.c
1 /**********************************************************************
2 
3  range.c -
4 
5  $Author$
6  created at: Thu Aug 19 17:46:47 JST 1993
7 
8  Copyright (C) 1993-2007 Yukihiro Matsumoto
9 
10 **********************************************************************/
11 
12 #include "ruby/internal/config.h"
13 
14 #include <assert.h>
15 #include <math.h>
16 
17 #ifdef HAVE_FLOAT_H
18 #include <float.h>
19 #endif
20 
21 #include "id.h"
22 #include "internal.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"
30 
32 static ID id_beg, id_end, id_excl;
33 #define id_cmp idCmp
34 #define id_succ idSucc
35 #define id_min idMin
36 #define id_max idMax
37 
38 static VALUE r_cover_p(VALUE, VALUE, VALUE, VALUE);
39 
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))
43 
44 #define EXCL(r) RTEST(RANGE_EXCL(r))
45 
46 static void
47 range_init(VALUE range, VALUE beg, VALUE end, VALUE exclude_end)
48 {
49  if ((!FIXNUM_P(beg) || !FIXNUM_P(end)) && !NIL_P(beg) && !NIL_P(end)) {
50  VALUE v;
51 
52  v = rb_funcall(beg, id_cmp, 1, end);
53  if (NIL_P(v))
54  rb_raise(rb_eArgError, "bad value for range");
55  }
56 
57  RANGE_SET_EXCL(range, exclude_end);
58  RANGE_SET_BEG(range, beg);
59  RANGE_SET_END(range, end);
60 
61  if (CLASS_OF(range) == rb_cRange) {
62  rb_obj_freeze(range);
63  }
64 }
65 
66 VALUE
67 rb_range_new(VALUE beg, VALUE end, int exclude_end)
68 {
69  VALUE range = rb_obj_alloc(rb_cRange);
70 
71  range_init(range, beg, end, RBOOL(exclude_end));
72  return range;
73 }
74 
75 static void
76 range_modify(VALUE range)
77 {
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));
82  }
83 }
84 
85 /*
86  * call-seq:
87  * Range.new(begin, end, exclude_end = false) -> new_range
88  *
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:
92  *
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"]
97  *
98  */
99 
100 static VALUE
101 range_initialize(int argc, VALUE *argv, VALUE range)
102 {
103  VALUE beg, end, flags;
104 
105  rb_scan_args(argc, argv, "21", &beg, &end, &flags);
106  range_modify(range);
107  range_init(range, beg, end, RBOOL(RTEST(flags)));
108  return Qnil;
109 }
110 
111 /* :nodoc: */
112 static VALUE
113 range_initialize_copy(VALUE range, VALUE orig)
114 {
115  range_modify(range);
116  rb_struct_init_copy(range, orig);
117  return range;
118 }
119 
120 /*
121  * call-seq:
122  * exclude_end? -> true or false
123  *
124  * Returns +true+ if +self+ excludes its end value; +false+ otherwise:
125  *
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
130  */
131 
132 static VALUE
133 range_exclude_end_p(VALUE range)
134 {
135  return RBOOL(EXCL(range));
136 }
137 
138 static VALUE
139 recursive_equal(VALUE range, VALUE obj, int recur)
140 {
141  if (recur) return Qtrue; /* Subtle! */
142  if (!rb_equal(RANGE_BEG(range), RANGE_BEG(obj)))
143  return Qfalse;
144  if (!rb_equal(RANGE_END(range), RANGE_END(obj)))
145  return Qfalse;
146 
147  return RBOOL(EXCL(range) == EXCL(obj));
148 }
149 
150 
151 /*
152  * call-seq:
153  * self == other -> true or false
154  *
155  * Returns +true+ if and only if:
156  *
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>.
161  *
162  * Otherwise returns +false+.
163  *
164  * r = (1..5)
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
172  *
173  * Note that even with the same argument, the return values of #== and #eql? can differ:
174  *
175  * (1..2) == (1..2.0) # => true
176  * (1..2).eql? (1..2.0) # => false
177  *
178  * Related: Range#eql?.
179  *
180  */
181 
182 static VALUE
183 range_eq(VALUE range, VALUE obj)
184 {
185  if (range == obj)
186  return Qtrue;
187  if (!rb_obj_is_kind_of(obj, rb_cRange))
188  return Qfalse;
189 
190  return rb_exec_recursive_paired(recursive_equal, range, obj, obj);
191 }
192 
193 /* compares _a_ and _b_ and returns:
194  * < 0: a < b
195  * = 0: a = b
196  * > 0: a > b or non-comparable
197  */
198 static int
199 r_less(VALUE a, VALUE b)
200 {
201  VALUE r = rb_funcall(a, id_cmp, 1, b);
202 
203  if (NIL_P(r))
204  return INT_MAX;
205  return rb_cmpint(r, a, b);
206 }
207 
208 static VALUE
209 recursive_eql(VALUE range, VALUE obj, int recur)
210 {
211  if (recur) return Qtrue; /* Subtle! */
212  if (!rb_eql(RANGE_BEG(range), RANGE_BEG(obj)))
213  return Qfalse;
214  if (!rb_eql(RANGE_END(range), RANGE_END(obj)))
215  return Qfalse;
216 
217  return RBOOL(EXCL(range) == EXCL(obj));
218 }
219 
220 /*
221  * call-seq:
222  * eql?(other) -> true or false
223  *
224  * Returns +true+ if and only if:
225  *
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>.
230  *
231  * Otherwise returns +false+.
232  *
233  * r = (1..5)
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
241  *
242  * Note that even with the same argument, the return values of #== and #eql? can differ:
243  *
244  * (1..2) == (1..2.0) # => true
245  * (1..2).eql? (1..2.0) # => false
246  *
247  * Related: Range#==.
248  */
249 
250 static VALUE
251 range_eql(VALUE range, VALUE obj)
252 {
253  if (range == obj)
254  return Qtrue;
255  if (!rb_obj_is_kind_of(obj, rb_cRange))
256  return Qfalse;
257  return rb_exec_recursive_paired(recursive_eql, range, obj, obj);
258 }
259 
260 /*
261  * call-seq:
262  * hash -> integer
263  *
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>.
267  *
268  * Related: Range#eql?, Object#hash.
269  */
270 
271 static VALUE
272 range_hash(VALUE range)
273 {
274  st_index_t hash = EXCL(range);
275  VALUE v;
276 
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);
284 
285  return ST2FIX(hash);
286 }
287 
288 static void
289 range_each_func(VALUE range, int (*func)(VALUE, VALUE), VALUE arg)
290 {
291  int c;
292  VALUE b = RANGE_BEG(range);
293  VALUE e = RANGE_END(range);
294  VALUE v = b;
295 
296  if (EXCL(range)) {
297  while (r_less(v, e) < 0) {
298  if ((*func)(v, arg)) break;
299  v = rb_funcallv(v, id_succ, 0, 0);
300  }
301  }
302  else {
303  while ((c = r_less(v, e)) <= 0) {
304  if ((*func)(v, arg)) break;
305  if (!c) break;
306  v = rb_funcallv(v, id_succ, 0, 0);
307  }
308  }
309 }
310 
311 static bool
312 step_i_iter(VALUE arg)
313 {
314  VALUE *iter = (VALUE *)arg;
315 
316  if (FIXNUM_P(iter[0])) {
317  iter[0] -= INT2FIX(1) & ~FIXNUM_FLAG;
318  }
319  else {
320  iter[0] = rb_funcall(iter[0], '-', 1, INT2FIX(1));
321  }
322  if (iter[0] != INT2FIX(0)) return false;
323  iter[0] = iter[1];
324  return true;
325 }
326 
327 static int
328 sym_step_i(VALUE i, VALUE arg)
329 {
330  if (step_i_iter(arg)) {
332  }
333  return 0;
334 }
335 
336 static int
337 step_i(VALUE i, VALUE arg)
338 {
339  if (step_i_iter(arg)) {
340  rb_yield(i);
341  }
342  return 0;
343 }
344 
345 static int
346 discrete_object_p(VALUE obj)
347 {
348  return rb_respond_to(obj, id_succ);
349 }
350 
351 static int
352 linear_object_p(VALUE obj)
353 {
354  if (FIXNUM_P(obj) || FLONUM_P(obj)) return TRUE;
355  if (SPECIAL_CONST_P(obj)) return FALSE;
356  switch (BUILTIN_TYPE(obj)) {
357  case T_FLOAT:
358  case T_BIGNUM:
359  return TRUE;
360  default:
361  break;
362  }
363  if (rb_obj_is_kind_of(obj, rb_cNumeric)) return TRUE;
364  if (rb_obj_is_kind_of(obj, rb_cTime)) return TRUE;
365  return FALSE;
366 }
367 
368 static VALUE
369 check_step_domain(VALUE step)
370 {
371  VALUE zero = INT2FIX(0);
372  int cmp;
373  if (!rb_obj_is_kind_of(step, rb_cNumeric)) {
374  step = rb_to_int(step);
375  }
376  cmp = rb_cmpint(rb_funcallv(step, idCmp, 1, &zero), step, zero);
377  if (cmp < 0) {
378  rb_raise(rb_eArgError, "step can't be negative");
379  }
380  else if (cmp == 0) {
381  rb_raise(rb_eArgError, "step can't be 0");
382  }
383  return step;
384 }
385 
386 static VALUE
387 range_step_size(VALUE range, VALUE args, VALUE eobj)
388 {
389  VALUE b = RANGE_BEG(range), e = RANGE_END(range);
390  VALUE step = INT2FIX(1);
391  if (args) {
392  step = check_step_domain(RARRAY_AREF(args, 0));
393  }
394 
396  return ruby_num_interval_step_size(b, e, step, EXCL(range));
397  }
398  return Qnil;
399 }
400 
401 /*
402  * call-seq:
403  * step(n = 1) {|element| ... } -> self
404  * step(n = 1) -> enumerator
405  *
406  * Iterates over the elements of +self+.
407  *
408  * With a block given and no argument,
409  * calls the block each element of the range; returns +self+:
410  *
411  * a = []
412  * (1..5).step {|element| a.push(element) } # => 1..5
413  * a # => [1, 2, 3, 4, 5]
414  * a = []
415  * ('a'..'e').step {|element| a.push(element) } # => "a".."e"
416  * a # => ["a", "b", "c", "d", "e"]
417  *
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:
420  *
421  * a = []
422  * (1..5).step(2) {|element| a.push(element) } # => 1..5
423  * a # => [1, 3, 5]
424  * a = []
425  * ('a'..'e').step(2) {|element| a.push(element) } # => "a".."e"
426  * a # => ["a", "c", "e"]
427  *
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:
431  *
432  * e = (1..5).step(2) # => ((1..5).step(2))
433  * e.class # => Enumerator::ArithmeticSequence
434  * ('a'..'e').step # => #<Enumerator: ...>
435  *
436  * Related: Range#%.
437  */
438 static VALUE
439 range_step(int argc, VALUE *argv, VALUE range)
440 {
441  VALUE b, e, step, tmp;
442 
443  b = RANGE_BEG(range);
444  e = RANGE_END(range);
445  step = (!rb_check_arity(argc, 0, 1) ? INT2FIX(1) : argv[0]);
446 
447  if (!rb_block_given_p()) {
448  if (!rb_obj_is_kind_of(step, rb_cNumeric)) {
449  step = rb_to_int(step);
450  }
451  if (rb_equal(step, INT2FIX(0))) {
452  rb_raise(rb_eArgError, "step can't be 0");
453  }
454 
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));
460  }
461 
462  RETURN_SIZED_ENUMERATOR(range, argc, argv, range_step_size);
463  }
464 
465  step = check_step_domain(step);
466  VALUE iter[2] = {INT2FIX(1), step};
467 
468  if (FIXNUM_P(b) && NIL_P(e) && FIXNUM_P(step)) {
469  long i = FIX2LONG(b), unit = FIX2LONG(step);
470  do {
471  rb_yield(LONG2FIX(i));
472  i += unit; /* FIXABLE+FIXABLE never overflow */
473  } while (FIXABLE(i));
474  b = LONG2NUM(i);
475 
476  for (;; b = rb_big_plus(b, step))
477  rb_yield(b);
478  }
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);
482 
483  if (!EXCL(range))
484  end += 1;
485  i = FIX2LONG(b);
486  while (i < end) {
487  rb_yield(LONG2NUM(i));
488  if (i + unit < i) break;
489  i += unit;
490  }
491 
492  }
493  else if (SYMBOL_P(b) && (NIL_P(e) || SYMBOL_P(e))) { /* symbols are special */
494  b = rb_sym2str(b);
495  if (NIL_P(e)) {
496  rb_str_upto_endless_each(b, sym_step_i, (VALUE)iter);
497  }
498  else {
499  rb_str_upto_each(b, rb_sym2str(e), EXCL(range), sym_step_i, (VALUE)iter);
500  }
501  }
502  else if (ruby_float_step(b, e, step, EXCL(range), TRUE)) {
503  /* done */
504  }
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;
509  VALUE v = b;
510  int i = 0;
511 
512  while (NIL_P(e) || RTEST(rb_funcall(v, op, 1, e))) {
513  rb_yield(v);
514  i++;
515  v = rb_funcall(b, '+', 1, rb_funcall(INT2NUM(i), '*', 1, step));
516  }
517  }
518  else {
519  tmp = rb_check_string_type(b);
520 
521  if (!NIL_P(tmp)) {
522  b = tmp;
523  if (NIL_P(e)) {
524  rb_str_upto_endless_each(b, step_i, (VALUE)iter);
525  }
526  else {
527  rb_str_upto_each(b, e, EXCL(range), step_i, (VALUE)iter);
528  }
529  }
530  else {
531  if (!discrete_object_p(b)) {
532  rb_raise(rb_eTypeError, "can't iterate from %s",
533  rb_obj_classname(b));
534  }
535  range_each_func(range, step_i, (VALUE)iter);
536  }
537  }
538  return range;
539 }
540 
541 /*
542  * call-seq:
543  * %(n) {|element| ... } -> self
544  * %(n) -> enumerator
545  *
546  * Iterates over the elements of +self+.
547  *
548  * With a block given, calls the block with selected elements of the range;
549  * returns +self+:
550  *
551  * a = []
552  * (1..5).%(2) {|element| a.push(element) } # => 1..5
553  * a # => [1, 3, 5]
554  * a = []
555  * ('a'..'e').%(2) {|element| a.push(element) } # => "a".."e"
556  * a # => ["a", "c", "e"]
557  *
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:
561  *
562  * e = (1..5) % 2 # => ((1..5).%(2))
563  * e.class # => Enumerator::ArithmeticSequence
564  * ('a'..'e') % 2 # => #<Enumerator: ...>
565  *
566  * Related: Range#step.
567  */
568 static VALUE
569 range_percent_step(VALUE range, VALUE step)
570 {
571  return range_step(1, &step, range);
572 }
573 
574 #if SIZEOF_DOUBLE == 8 && defined(HAVE_INT64_T)
575 union int64_double {
576  int64_t i;
577  double d;
578 };
579 
580 static VALUE
581 int64_as_double_to_num(int64_t i)
582 {
583  union int64_double convert;
584  if (i < 0) {
585  convert.i = -i;
586  return DBL2NUM(-convert.d);
587  }
588  else {
589  convert.i = i;
590  return DBL2NUM(convert.d);
591  }
592 }
593 
594 static int64_t
595 double_as_int64(double d)
596 {
597  union int64_double convert;
598  convert.d = fabs(d);
599  return d < 0 ? -convert.i : convert.i;
600 }
601 #endif
602 
603 static int
604 is_integer_p(VALUE v)
605 {
606  ID id_integer_p;
607  VALUE is_int;
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;
611 }
612 
613 static VALUE
614 bsearch_integer_range(VALUE beg, VALUE end, int excl)
615 {
616  VALUE satisfied = Qnil;
617  int smaller;
618 
619 #define BSEARCH_CHECK(expr) \
620  do { \
621  VALUE val = (expr); \
622  VALUE v = rb_yield(val); \
623  if (FIXNUM_P(v)) { \
624  if (v == INT2FIX(0)) return val; \
625  smaller = (SIGNED_VALUE)v < 0; \
626  } \
627  else if (v == Qtrue) { \
628  satisfied = val; \
629  smaller = 1; \
630  } \
631  else if (!RTEST(v)) { \
632  smaller = 0; \
633  } \
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; \
637  smaller = cmp < 0; \
638  } \
639  else { \
640  rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE \
641  " (must be numeric, true, false or nil)", \
642  rb_obj_class(v)); \
643  } \
644  } while (0)
645 
646  VALUE low = rb_to_int(beg);
647  VALUE high = rb_to_int(end);
648  VALUE mid, org_high;
649  ID id_div;
650  CONST_ID(id_div, "div");
651 
652  if (excl) high = rb_funcall(high, '-', 1, INT2FIX(1));
653  org_high = high;
654 
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));
657  BSEARCH_CHECK(mid);
658  if (smaller) {
659  high = mid;
660  }
661  else {
662  low = rb_funcall(mid, '+', 1, INT2FIX(1));
663  }
664  }
665  if (rb_equal(low, org_high)) {
666  BSEARCH_CHECK(low);
667  if (!smaller) return Qnil;
668  }
669  return satisfied;
670 }
671 
672 /*
673  * call-seq:
674  * bsearch {|obj| block } -> value
675  *
676  * Returns an element from +self+ selected by a binary search.
677  *
678  * See {Binary Searching}[rdoc-ref:bsearch.rdoc].
679  *
680  */
681 
682 static VALUE
683 range_bsearch(VALUE range)
684 {
685  VALUE beg, end, satisfied = Qnil;
686  int smaller;
687 
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.
693  *
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.
697  *
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.
700  */
701 
702 #define BSEARCH(conv) \
703  do { \
704  RETURN_ENUMERATOR(range, 0, 0); \
705  if (EXCL(range)) high--; \
706  org_high = 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)); \
711  if (smaller) { \
712  high = mid; \
713  } \
714  else { \
715  low = mid + 1; \
716  } \
717  } \
718  if (low == org_high) { \
719  BSEARCH_CHECK(conv(low)); \
720  if (!smaller) return Qnil; \
721  } \
722  return satisfied; \
723  } while (0)
724 
725 
726  beg = RANGE_BEG(range);
727  end = RANGE_END(range);
728 
729  if (FIXNUM_P(beg) && FIXNUM_P(end)) {
730  long low = FIX2LONG(beg);
731  long high = FIX2LONG(end);
732  long mid, org_high;
733  BSEARCH(INT2FIX);
734  }
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);
741  }
742 #endif
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));
746  }
747  else if (is_integer_p(beg) && NIL_P(end)) {
748  VALUE diff = LONG2FIX(1);
749  RETURN_ENUMERATOR(range, 0, 0);
750  while (1) {
751  VALUE mid = rb_funcall(beg, '+', 1, diff);
752  BSEARCH_CHECK(mid);
753  if (smaller) {
754  return bsearch_integer_range(beg, mid, 0);
755  }
756  diff = rb_funcall(diff, '*', 1, LONG2FIX(2));
757  }
758  }
759  else if (NIL_P(beg) && is_integer_p(end)) {
760  VALUE diff = LONG2FIX(-1);
761  RETURN_ENUMERATOR(range, 0, 0);
762  while (1) {
763  VALUE mid = rb_funcall(end, '+', 1, diff);
764  BSEARCH_CHECK(mid);
765  if (!smaller) {
766  return bsearch_integer_range(mid, end, 0);
767  }
768  diff = rb_funcall(diff, '*', 1, LONG2FIX(2));
769  }
770  }
771  else {
772  rb_raise(rb_eTypeError, "can't do binary search for %s", rb_obj_classname(beg));
773  }
774  return range;
775 }
776 
777 static int
778 each_i(VALUE v, VALUE arg)
779 {
780  rb_yield(v);
781  return 0;
782 }
783 
784 static int
785 sym_each_i(VALUE v, VALUE arg)
786 {
787  return each_i(rb_str_intern(v), arg);
788 }
789 
790 /*
791  * call-seq:
792  * size -> non_negative_integer or Infinity or nil
793  *
794  * Returns the count of elements in +self+
795  * if both begin and end values are numeric;
796  * otherwise, returns +nil+:
797  *
798  * (1..4).size # => 4
799  * (1...4).size # => 3
800  * (1..).size # => Infinity
801  * ('a'..'z').size #=> nil
802  *
803  * Related: Range#count.
804  */
805 
806 static VALUE
807 range_size(VALUE range)
808 {
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));
813  }
814  if (NIL_P(e)) {
815  return DBL2NUM(HUGE_VAL);
816  }
817  }
818  else if (NIL_P(b)) {
819  return DBL2NUM(HUGE_VAL);
820  }
821 
822  return Qnil;
823 }
824 
825 /*
826  * call-seq:
827  * to_a -> array
828  *
829  * Returns an array containing the elements in +self+, if a finite collection;
830  * raises an exception otherwise.
831  *
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"]
835  *
836  * Range#entries is an alias for Range#to_a.
837  */
838 
839 static VALUE
840 range_to_a(VALUE range)
841 {
842  if (NIL_P(RANGE_END(range))) {
843  rb_raise(rb_eRangeError, "cannot convert endless range to an array");
844  }
845  return rb_call_super(0, 0);
846 }
847 
848 static VALUE
849 range_enum_size(VALUE range, VALUE args, VALUE eobj)
850 {
851  return range_size(range);
852 }
853 
855 static void
856 range_each_bignum_endless(VALUE beg)
857 {
858  for (;; beg = rb_big_plus(beg, INT2FIX(1))) {
859  rb_yield(beg);
860  }
861  UNREACHABLE;
862 }
863 
865 static void
866 range_each_fixnum_endless(VALUE beg)
867 {
868  for (long i = FIX2LONG(beg); FIXABLE(i); i++) {
869  rb_yield(LONG2FIX(i));
870  }
871 
872  range_each_bignum_endless(LONG2NUM(RUBY_FIXNUM_MAX + 1));
873  UNREACHABLE;
874 }
875 
876 static VALUE
877 range_each_fixnum_loop(VALUE beg, VALUE end, VALUE range)
878 {
879  long lim = FIX2LONG(end) + !EXCL(range);
880  for (long i = FIX2LONG(beg); i < lim; i++) {
881  rb_yield(LONG2FIX(i));
882  }
883  return range;
884 }
885 
886 /*
887  * call-seq:
888  * each {|element| ... } -> self
889  * each -> an_enumerator
890  *
891  * With a block given, passes each element of +self+ to the block:
892  *
893  * a = []
894  * (1..4).each {|element| a.push(element) } # => 1..4
895  * a # => [1, 2, 3, 4]
896  *
897  * Raises an exception unless <tt>self.first.respond_to?(:succ)</tt>.
898  *
899  * With no block given, returns an enumerator.
900  *
901  */
902 
903 static VALUE
904 range_each(VALUE range)
905 {
906  VALUE beg, end;
907  long i;
908 
909  RETURN_SIZED_ENUMERATOR(range, 0, 0, range_enum_size);
910 
911  beg = RANGE_BEG(range);
912  end = RANGE_END(range);
913 
914  if (FIXNUM_P(beg) && NIL_P(end)) {
915  range_each_fixnum_endless(beg);
916  }
917  else if (FIXNUM_P(beg) && FIXNUM_P(end)) { /* fixnums are special */
918  return range_each_fixnum_loop(beg, end, range);
919  }
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)) {
924  do {
925  rb_yield(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);
929  }
930  else {
931  if (NIL_P(end)) range_each_bignum_endless(beg);
932  if (FIXNUM_P(end)) return range;
933  }
934  }
935  if (FIXNUM_P(beg)) {
936  i = FIX2LONG(beg);
937  do {
938  rb_yield(LONG2FIX(i));
939  } while (POSFIXABLE(++i));
940  beg = LONG2NUM(i);
941  }
942  ASSUME(!FIXNUM_P(beg));
943  ASSUME(!SPECIAL_CONST_P(end));
944  }
945  if (!FIXNUM_P(beg) && RBIGNUM_SIGN(beg) == RBIGNUM_SIGN(end)) {
946  if (EXCL(range)) {
947  while (rb_big_cmp(beg, end) == INT2FIX(-1)) {
948  rb_yield(beg);
949  beg = rb_big_plus(beg, INT2FIX(1));
950  }
951  }
952  else {
953  VALUE c;
954  while ((c = rb_big_cmp(beg, end)) != INT2FIX(1)) {
955  rb_yield(beg);
956  if (c == INT2FIX(0)) break;
957  beg = rb_big_plus(beg, INT2FIX(1));
958  }
959  }
960  }
961  }
962  else if (SYMBOL_P(beg) && (NIL_P(end) || SYMBOL_P(end))) { /* symbols are special */
963  beg = rb_sym2str(beg);
964  if (NIL_P(end)) {
965  rb_str_upto_endless_each(beg, sym_each_i, 0);
966  }
967  else {
968  rb_str_upto_each(beg, rb_sym2str(end), EXCL(range), sym_each_i, 0);
969  }
970  }
971  else {
972  VALUE tmp = rb_check_string_type(beg);
973 
974  if (!NIL_P(tmp)) {
975  if (!NIL_P(end)) {
976  rb_str_upto_each(tmp, end, EXCL(range), each_i, 0);
977  }
978  else {
979  rb_str_upto_endless_each(tmp, each_i, 0);
980  }
981  }
982  else {
983  if (!discrete_object_p(beg)) {
984  rb_raise(rb_eTypeError, "can't iterate from %s",
985  rb_obj_classname(beg));
986  }
987  if (!NIL_P(end))
988  range_each_func(range, each_i, 0);
989  else
990  for (;; beg = rb_funcallv(beg, id_succ, 0, 0))
991  rb_yield(beg);
992  }
993  }
994  return range;
995 }
996 
997 /*
998  * call-seq:
999  * self.begin -> object
1000  *
1001  * Returns the object that defines the beginning of +self+.
1002  *
1003  * (1..4).begin # => 1
1004  * (..2).begin # => nil
1005  *
1006  * Related: Range#first, Range#end.
1007  */
1008 
1009 static VALUE
1010 range_begin(VALUE range)
1011 {
1012  return RANGE_BEG(range);
1013 }
1014 
1015 
1016 /*
1017  * call-seq:
1018  * self.end -> object
1019  *
1020  * Returns the object that defines the end of +self+.
1021  *
1022  * (1..4).end # => 4
1023  * (1...4).end # => 4
1024  * (1..).end # => nil
1025  *
1026  * Related: Range#begin, Range#last.
1027  */
1028 
1029 
1030 static VALUE
1031 range_end(VALUE range)
1032 {
1033  return RANGE_END(range);
1034 }
1035 
1036 
1037 static VALUE
1038 first_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, cbarg))
1039 {
1040  VALUE *ary = (VALUE *)cbarg;
1041  long n = NUM2LONG(ary[0]);
1042 
1043  if (n <= 0) {
1044  rb_iter_break();
1045  }
1046  rb_ary_push(ary[1], i);
1047  n--;
1048  ary[0] = LONG2NUM(n);
1049  return Qnil;
1050 }
1051 
1052 /*
1053  * call-seq:
1054  * first -> object
1055  * first(n) -> array
1056  *
1057  * With no argument, returns the first element of +self+, if it exists:
1058  *
1059  * (1..4).first # => 1
1060  * ('a'..'d').first # => "a"
1061  *
1062  * With non-negative integer argument +n+ given,
1063  * returns the first +n+ elements in an array:
1064  *
1065  * (1..10).first(3) # => [1, 2, 3]
1066  * (1..10).first(0) # => []
1067  * (1..4).first(50) # => [1, 2, 3, 4]
1068  *
1069  * Raises an exception if there is no first element:
1070  *
1071  * (..4).first # Raises RangeError
1072  */
1073 
1074 static VALUE
1075 range_first(int argc, VALUE *argv, VALUE range)
1076 {
1077  VALUE n, ary[2];
1078 
1079  if (NIL_P(RANGE_BEG(range))) {
1080  rb_raise(rb_eRangeError, "cannot get the first element of beginless range");
1081  }
1082  if (argc == 0) return RANGE_BEG(range);
1083 
1084  rb_scan_args(argc, argv, "1", &n);
1085  ary[0] = n;
1086  ary[1] = rb_ary_new2(NUM2LONG(n));
1087  rb_block_call(range, idEach, 0, 0, first_i, (VALUE)ary);
1088 
1089  return ary[1];
1090 }
1091 
1092 static VALUE
1093 rb_int_range_last(int argc, VALUE *argv, VALUE range)
1094 {
1095  static const VALUE ONE = INT2FIX(1);
1096 
1097  VALUE b, e, len_1, len, nv, ary;
1098  int x;
1099  long n;
1100 
1101  assert(argc > 0);
1102 
1103  b = RANGE_BEG(range);
1104  e = RANGE_END(range);
1105  assert(RB_INTEGER_TYPE_P(b) && RB_INTEGER_TYPE_P(e));
1106 
1107  x = EXCL(range);
1108 
1109  len_1 = rb_int_minus(e, b);
1110  if (x) {
1111  e = rb_int_minus(e, ONE);
1112  len = len_1;
1113  }
1114  else {
1115  len = rb_int_plus(len_1, ONE);
1116  }
1117 
1118  if (FIXNUM_ZERO_P(len) || rb_num_negative_p(len)) {
1119  return rb_ary_new_capa(0);
1120  }
1121 
1122  rb_scan_args(argc, argv, "1", &nv);
1123  n = NUM2LONG(nv);
1124  if (n < 0) {
1125  rb_raise(rb_eArgError, "negative array size");
1126  }
1127 
1128  nv = LONG2NUM(n);
1129  if (RTEST(rb_int_gt(nv, len))) {
1130  nv = len;
1131  n = NUM2LONG(nv);
1132  }
1133 
1134  ary = rb_ary_new_capa(n);
1135  b = rb_int_minus(e, nv);
1136  while (n) {
1137  b = rb_int_plus(b, ONE);
1138  rb_ary_push(ary, b);
1139  --n;
1140  }
1141 
1142  return ary;
1143 }
1144 
1145 /*
1146  * call-seq:
1147  * last -> object
1148  * last(n) -> array
1149  *
1150  * With no argument, returns the last element of +self+, if it exists:
1151  *
1152  * (1..4).last # => 4
1153  * ('a'..'d').last # => "d"
1154  *
1155  * Note that +last+ with no argument returns the end element of +self+
1156  * even if #exclude_end? is +true+:
1157  *
1158  * (1...4).last # => 4
1159  * ('a'...'d').last # => "d"
1160  *
1161  * With non-negative integer argument +n+ given,
1162  * returns the last +n+ elements in an array:
1163  *
1164  * (1..10).last(3) # => [8, 9, 10]
1165  * (1..10).last(0) # => []
1166  * (1..4).last(50) # => [1, 2, 3, 4]
1167  *
1168  * Note that +last+ with argument does not return the end element of +self+
1169  * if #exclude_end? it +true+:
1170  *
1171  * (1...4).last(3) # => [1, 2, 3]
1172  * ('a'...'d').last(3) # => ["a", "b", "c"]
1173  *
1174  * Raises an exception if there is no last element:
1175  *
1176  * (1..).last # Raises RangeError
1177  *
1178  */
1179 
1180 static VALUE
1181 range_last(int argc, VALUE *argv, VALUE range)
1182 {
1183  VALUE b, e;
1184 
1185  if (NIL_P(RANGE_END(range))) {
1186  rb_raise(rb_eRangeError, "cannot get the last element of endless range");
1187  }
1188  if (argc == 0) return RANGE_END(range);
1189 
1190  b = RANGE_BEG(range);
1191  e = RANGE_END(range);
1192  if (RB_INTEGER_TYPE_P(b) && RB_INTEGER_TYPE_P(e) &&
1194  return rb_int_range_last(argc, argv, range);
1195  }
1196  return rb_ary_last(argc, argv, rb_Array(range));
1197 }
1198 
1199 
1200 /*
1201  * call-seq:
1202  * min -> object
1203  * min(n) -> array
1204  * min {|a, b| ... } -> object
1205  * min(n) {|a, b| ... } -> array
1206  *
1207  * Returns the minimum value in +self+,
1208  * using method <tt><=></tt> or a given block for comparison.
1209  *
1210  * With no argument and no block given,
1211  * returns the minimum-valued element of +self+.
1212  *
1213  * (1..4).min # => 1
1214  * ('a'..'d').min # => "a"
1215  * (-4..-1).min # => -4
1216  *
1217  * With non-negative integer argument +n+ given, and no block given,
1218  * returns the +n+ minimum-valued elements of +self+ in an array:
1219  *
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]
1224  *
1225  * If a block is given, it is called:
1226  *
1227  * - First, with the first two element of +self+.
1228  * - Then, sequentially, with the so-far minimum value and the next element of +self+.
1229  *
1230  * To illustrate:
1231  *
1232  * (1..4).min {|a, b| p [a, b]; a <=> b } # => 1
1233  *
1234  * Output:
1235  *
1236  * [2, 1]
1237  * [3, 1]
1238  * [4, 1]
1239  *
1240  * With no argument and a block given,
1241  * returns the return value of the last call to the block:
1242  *
1243  * (1..4).min {|a, b| -(a <=> b) } # => 4
1244  *
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:
1247  *
1248  * (1..4).min(2) {|a, b| -(a <=> b) } # => [4, 3]
1249  * (1..4).min(50) {|a, b| -(a <=> b) } # => [4, 3, 2, 1]
1250  *
1251  * Returns an empty array if +n+ is zero:
1252  *
1253  * (1..4).min(0) # => []
1254  * (1..4).min(0) {|a, b| -(a <=> b) } # => []
1255  *
1256  * Returns +nil+ or an empty array if:
1257  *
1258  * - The begin value of the range is larger than the end value:
1259  *
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) } # => []
1264  *
1265  * - The begin value of an exclusive range is equal to the end value:
1266  *
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) } # => []
1271  *
1272  * Raises an exception if either:
1273  *
1274  * - +self+ is a beginless range: <tt>(..4)</tt>.
1275  * - A block is given and +self+ is an endless range.
1276  *
1277  * Related: Range#max, Range#minmax.
1278  */
1279 
1280 
1281 static VALUE
1282 range_min(int argc, VALUE *argv, VALUE range)
1283 {
1284  if (NIL_P(RANGE_BEG(range))) {
1285  rb_raise(rb_eRangeError, "cannot get the minimum of beginless range");
1286  }
1287 
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");
1291  }
1292  return rb_call_super(argc, argv);
1293  }
1294  else if (argc != 0) {
1295  return range_first(argc, argv, range);
1296  }
1297  else {
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);
1302 
1303  if (c > 0 || (c == 0 && EXCL(range)))
1304  return Qnil;
1305  return b;
1306  }
1307 }
1308 
1309 /*
1310  * call-seq:
1311  * max -> object
1312  * max(n) -> array
1313  * max {|a, b| ... } -> object
1314  * max(n) {|a, b| ... } -> array
1315  *
1316  * Returns the maximum value in +self+,
1317  * using method <tt><=></tt> or a given block for comparison.
1318  *
1319  * With no argument and no block given,
1320  * returns the maximum-valued element of +self+.
1321  *
1322  * (1..4).max # => 4
1323  * ('a'..'d').max # => "d"
1324  * (-4..-1).max # => -1
1325  *
1326  * With non-negative integer argument +n+ given, and no block given,
1327  * returns the +n+ maximum-valued elements of +self+ in an array:
1328  *
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]
1333  *
1334  * If a block is given, it is called:
1335  *
1336  * - First, with the first two element of +self+.
1337  * - Then, sequentially, with the so-far maximum value and the next element of +self+.
1338  *
1339  * To illustrate:
1340  *
1341  * (1..4).max {|a, b| p [a, b]; a <=> b } # => 4
1342  *
1343  * Output:
1344  *
1345  * [2, 1]
1346  * [3, 2]
1347  * [4, 3]
1348  *
1349  * With no argument and a block given,
1350  * returns the return value of the last call to the block:
1351  *
1352  * (1..4).max {|a, b| -(a <=> b) } # => 1
1353  *
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:
1356  *
1357  * (1..4).max(2) {|a, b| -(a <=> b) } # => [1, 2]
1358  * (1..4).max(50) {|a, b| -(a <=> b) } # => [1, 2, 3, 4]
1359  *
1360  * Returns an empty array if +n+ is zero:
1361  *
1362  * (1..4).max(0) # => []
1363  * (1..4).max(0) {|a, b| -(a <=> b) } # => []
1364  *
1365  * Returns +nil+ or an empty array if:
1366  *
1367  * - The begin value of the range is larger than the end value:
1368  *
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) } # => []
1373  *
1374  * - The begin value of an exclusive range is equal to the end value:
1375  *
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) } # => []
1380  *
1381  * Raises an exception if either:
1382  *
1383  * - +self+ is a endless range: <tt>(1..)</tt>.
1384  * - A block is given and +self+ is a beginless range.
1385  *
1386  * Related: Range#min, Range#minmax.
1387  *
1388  */
1389 
1390 static VALUE
1391 range_max(int argc, VALUE *argv, VALUE range)
1392 {
1393  VALUE e = RANGE_END(range);
1394  int nm = FIXNUM_P(e) || rb_obj_is_kind_of(e, rb_cNumeric);
1395 
1396  if (NIL_P(RANGE_END(range))) {
1397  rb_raise(rb_eRangeError, "cannot get the maximum of endless range");
1398  }
1399 
1400  VALUE b = RANGE_BEG(range);
1401 
1402  if (rb_block_given_p() || (EXCL(range) && !nm) || argc) {
1403  if (NIL_P(b)) {
1404  rb_raise(rb_eRangeError, "cannot get the maximum of beginless range with custom comparison method");
1405  }
1406  return rb_call_super(argc, argv);
1407  }
1408  else {
1409  struct cmp_opt_data cmp_opt = { 0, 0 };
1410  int c = NIL_P(b) ? -1 : OPTIMIZED_CMP(b, e, cmp_opt);
1411 
1412  if (c > 0)
1413  return Qnil;
1414  if (EXCL(range)) {
1415  if (!RB_INTEGER_TYPE_P(e)) {
1416  rb_raise(rb_eTypeError, "cannot exclude non Integer end value");
1417  }
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");
1421  }
1422  if (FIXNUM_P(e)) {
1423  return LONG2NUM(FIX2LONG(e) - 1);
1424  }
1425  return rb_funcall(e, '-', 1, INT2FIX(1));
1426  }
1427  return e;
1428  }
1429 }
1430 
1431 /*
1432  * call-seq:
1433  * minmax -> [object, object]
1434  * minmax {|a, b| ... } -> [object, object]
1435  *
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.
1438  *
1439  * With no block given, returns the minimum and maximum values,
1440  * using <tt><=></tt> for comparison:
1441  *
1442  * (1..4).minmax # => [1, 4]
1443  * (1...4).minmax # => [1, 3]
1444  * ('a'..'d').minmax # => ["a", "d"]
1445  * (-4..-1).minmax # => [-4, -1]
1446  *
1447  * With a block given, the block must return an integer:
1448  *
1449  * - Negative if +a+ is smaller than +b+.
1450  * - Zero if +a+ and +b+ are equal.
1451  * - Positive if +a+ is larger than +b+.
1452  *
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+,
1455  * per the block:
1456  *
1457  * (1..4).minmax {|a, b| -(a <=> b) } # => [4, 1]
1458  *
1459  * Returns <tt>[nil, nil]</tt> if:
1460  *
1461  * - The begin value of the range is larger than the end value:
1462  *
1463  * (4..1).minmax # => [nil, nil]
1464  * (4..1).minmax {|a, b| -(a <=> b) } # => [nil, nil]
1465  *
1466  * - The begin value of an exclusive range is equal to the end value:
1467  *
1468  * (1...1).minmax # => [nil, nil]
1469  * (1...1).minmax {|a, b| -(a <=> b) } # => [nil, nil]
1470  *
1471  * Raises an exception if +self+ is a beginless or an endless range.
1472  *
1473  * Related: Range#min, Range#max.
1474  *
1475  */
1476 
1477 static VALUE
1478 range_minmax(VALUE range)
1479 {
1480  if (rb_block_given_p()) {
1481  return rb_call_super(0, NULL);
1482  }
1483  return rb_assoc_new(
1484  rb_funcall(range, id_min, 0),
1485  rb_funcall(range, id_max, 0)
1486  );
1487 }
1488 
1489 int
1490 rb_range_values(VALUE range, VALUE *begp, VALUE *endp, int *exclp)
1491 {
1492  VALUE b, e;
1493  int excl;
1494 
1495  if (rb_obj_is_kind_of(range, rb_cRange)) {
1496  b = RANGE_BEG(range);
1497  e = RANGE_END(range);
1498  excl = EXCL(range);
1499  }
1500  else if (RTEST(rb_obj_is_kind_of(range, rb_cArithSeq))) {
1501  return (int)Qfalse;
1502  }
1503  else {
1504  VALUE x;
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;
1511  excl = RTEST(x);
1512  }
1513  *begp = b;
1514  *endp = e;
1515  *exclp = excl;
1516  return (int)Qtrue;
1517 }
1518 
1519 /* Extract the components of a Range.
1520  *
1521  * You can use +err+ to control the behavior of out-of-range and exception.
1522  *
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.
1526  *
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.
1529  *
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.
1532  *
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+.
1535  *
1536  * The case of <code>err = 1</code> is used in Array's methods such as
1537  * +rb_ary_aset+ and +rb_ary_fill+.
1538  *
1539  * The case of <code>err = 2</code> is used in +rb_str_aset+.
1540  */
1541 VALUE
1542 rb_range_component_beg_len(VALUE b, VALUE e, int excl,
1543  long *begp, long *lenp, long len, int err)
1544 {
1545  long beg, end;
1546 
1547  beg = NIL_P(b) ? 0 : NUM2LONG(b);
1548  end = NIL_P(e) ? -1 : NUM2LONG(e);
1549  if (NIL_P(e)) excl = 0;
1550  if (beg < 0) {
1551  beg += len;
1552  if (beg < 0)
1553  goto out_of_range;
1554  }
1555  if (end < 0)
1556  end += len;
1557  if (!excl)
1558  end++; /* include end point */
1559  if (err == 0 || err == 2) {
1560  if (beg > len)
1561  goto out_of_range;
1562  if (end > len)
1563  end = len;
1564  }
1565  len = end - beg;
1566  if (len < 0)
1567  len = 0;
1568 
1569  *begp = beg;
1570  *lenp = len;
1571  return Qtrue;
1572 
1573  out_of_range:
1574  return Qnil;
1575 }
1576 
1577 VALUE
1578 rb_range_beg_len(VALUE range, long *begp, long *lenp, long len, int err)
1579 {
1580  VALUE b, e;
1581  int excl;
1582 
1583  if (!rb_range_values(range, &b, &e, &excl))
1584  return Qfalse;
1585 
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);
1589  }
1590 
1591  return res;
1592 }
1593 
1594 /*
1595  * call-seq:
1596  * to_s -> string
1597  *
1598  * Returns a string representation of +self+,
1599  * including <tt>begin.to_s</tt> and <tt>end.to_s</tt>:
1600  *
1601  * (1..4).to_s # => "1..4"
1602  * (1...4).to_s # => "1...4"
1603  * (1..).to_s # => "1.."
1604  * (..4).to_s # => "..4"
1605  *
1606  * Note that returns from #to_s and #inspect may differ:
1607  *
1608  * ('a'..'d').to_s # => "a..d"
1609  * ('a'..'d').inspect # => "\"a\"..\"d\""
1610  *
1611  * Related: Range#inspect.
1612  *
1613  */
1614 
1615 static VALUE
1616 range_to_s(VALUE range)
1617 {
1618  VALUE str, str2;
1619 
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);
1625 
1626  return str;
1627 }
1628 
1629 static VALUE
1630 inspect_range(VALUE range, VALUE dummy, int recur)
1631 {
1632  VALUE str, str2 = Qundef;
1633 
1634  if (recur) {
1635  return rb_str_new2(EXCL(range) ? "(... ... ...)" : "(... .. ...)");
1636  }
1637  if (!NIL_P(RANGE_BEG(range)) || NIL_P(RANGE_END(range))) {
1638  str = rb_str_dup(rb_inspect(RANGE_BEG(range)));
1639  }
1640  else {
1641  str = rb_str_new(0, 0);
1642  }
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));
1646  }
1647  if (str2 != Qundef) rb_str_append(str, str2);
1648 
1649  return str;
1650 }
1651 
1652 /*
1653  * call-seq:
1654  * inspect -> string
1655  *
1656  * Returns a string representation of +self+,
1657  * including <tt>begin.inspect</tt> and <tt>end.inspect</tt>:
1658  *
1659  * (1..4).inspect # => "1..4"
1660  * (1...4).inspect # => "1...4"
1661  * (1..).inspect # => "1.."
1662  * (..4).inspect # => "..4"
1663  *
1664  * Note that returns from #to_s and #inspect may differ:
1665  *
1666  * ('a'..'d').to_s # => "a..d"
1667  * ('a'..'d').inspect # => "\"a\"..\"d\""
1668  *
1669  * Related: Range#to_s.
1670  *
1671  */
1672 
1673 
1674 static VALUE
1675 range_inspect(VALUE range)
1676 {
1677  return rb_exec_recursive(inspect_range, range, 0);
1678 }
1679 
1680 static VALUE range_include_internal(VALUE range, VALUE val, int string_use_cover);
1681 
1682 /*
1683  * call-seq:
1684  * self === object -> true or false
1685  *
1686  * Returns +true+ if +object+ is between <tt>self.begin</tt> and <tt>self.end</tt>.
1687  * +false+ otherwise:
1688  *
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
1696  *
1697  * A case statement uses method <tt>===</tt>, and so:
1698  *
1699  * case 79
1700  * when (1..50)
1701  * "low"
1702  * when (51..75)
1703  * "medium"
1704  * when (76..100)
1705  * "high"
1706  * end # => "high"
1707  *
1708  * case "2.6.5"
1709  * when ..."2.4"
1710  * "EOL"
1711  * when "2.4"..."2.5"
1712  * "maintenance"
1713  * when "2.5"..."3.0"
1714  * "stable"
1715  * when "3.1"..
1716  * "upcoming"
1717  * end # => "stable"
1718  *
1719  */
1720 
1721 static VALUE
1722 range_eqq(VALUE range, VALUE val)
1723 {
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);
1727 }
1728 
1729 
1730 /*
1731  * call-seq:
1732  * include?(object) -> true or false
1733  *
1734  * Returns +true+ if +object+ is an element of +self+, +false+ otherwise:
1735  *
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
1745  *
1746  * If begin and end are numeric, #include? behaves like #cover?
1747  *
1748  * (1..3).include?(1.5) # => true
1749  * (1..3).cover?(1.5) # => true
1750  *
1751  * But when not numeric, the two methods may differ:
1752  *
1753  * ('a'..'d').include?('cc') # => false
1754  * ('a'..'d').cover?('cc') # => true
1755  *
1756  * Related: Range#cover?.
1757  *
1758  * Range#member? is an alias for Range#include?.
1759  */
1760 
1761 static VALUE
1762 range_include(VALUE range, VALUE val)
1763 {
1764  VALUE ret = range_include_internal(range, val, 0);
1765  if (ret != Qundef) return ret;
1766  return rb_call_super(1, &val);
1767 }
1768 
1769 static VALUE
1770 range_include_internal(VALUE range, VALUE val, int string_use_cover)
1771 {
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);
1776 
1777  if (nv ||
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);
1781  }
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);
1786  }
1787  else {
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));
1790  }
1791  }
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);
1796  }
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);
1801  }
1802  }
1803  return Qundef;
1804 }
1805 
1806 static int r_cover_range_p(VALUE range, VALUE beg, VALUE end, VALUE val);
1807 
1808 /*
1809  * call-seq:
1810  * cover?(object) -> true or false
1811  * cover?(range) -> true or false
1812  *
1813  * Returns +true+ if the given argument is within +self+, +false+ otherwise.
1814  *
1815  * With non-range argument +object+, evaluates with <tt><=</tt> and <tt><</tt>.
1816  *
1817  * For range +self+ with included end value (<tt>#exclude_end? == false</tt>),
1818  * evaluates thus:
1819  *
1820  * self.begin <= object <= self.end
1821  *
1822  * Examples:
1823  *
1824  * r = (1..4)
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
1830 
1831  * r = ('a'..'d')
1832  * r.cover?('a') # => true
1833  * r.cover?('d') # => true
1834  * r.cover?(' ') # => false
1835  * r.cover?('e') # => false
1836  * r.cover?(0) # => false
1837  *
1838  * For range +r+ with excluded end value (<tt>#exclude_end? == true</tt>),
1839  * evaluates thus:
1840  *
1841  * r.begin <= object < r.end
1842  *
1843  * Examples:
1844  *
1845  * r = (1...4)
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
1851 
1852  * r = ('a'...'d')
1853  * r.cover?('a') # => true
1854  * r.cover?('c') # => true
1855  * r.cover?(' ') # => false
1856  * r.cover?('d') # => false
1857  * r.cover?(0) # => false
1858  *
1859  * With range argument +range+, compares the first and last
1860  * elements of +self+ and +range+:
1861  *
1862  * r = (1..4)
1863  * r.cover?(1..4) # => true
1864  * r.cover?(0..4) # => false
1865  * r.cover?(1..5) # => false
1866  * r.cover?('a'..'d') # => false
1867 
1868  * r = (1...4)
1869  * r.cover?(1..3) # => true
1870  * r.cover?(1..4) # => false
1871  *
1872  * If begin and end are numeric, #cover? behaves like #include?
1873  *
1874  * (1..3).cover?(1.5) # => true
1875  * (1..3).include?(1.5) # => true
1876  *
1877  * But when not numeric, the two methods may differ:
1878  *
1879  * ('a'..'d').cover?('cc') # => true
1880  * ('a'..'d').include?('cc') # => false
1881  *
1882  * Returns +false+ if either:
1883  *
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.
1887  *
1888  * Beginless ranges cover all values of the same type before the end,
1889  * excluding the end for exclusive ranges. Beginless ranges cover
1890  * ranges that end before the end of the beginless range, or at the
1891  * end of the beginless range for inclusive ranges.
1892  *
1893  * (..2).cover?(1) # => true
1894  * (..2).cover?(2) # => true
1895  * (..2).cover?(3) # => false
1896  * (...2).cover?(2) # => false
1897  * (..2).cover?("2") # => false
1898  * (..2).cover?(..2) # => true
1899  * (..2).cover?(...2) # => true
1900  * (..2).cover?(.."2") # => false
1901  * (...2).cover?(..2) # => false
1902  *
1903  * Endless ranges cover all values of the same type after the
1904  * beginning. Endless exclusive ranges do not cover endless
1905  * inclusive ranges.
1906  *
1907  * (2..).cover?(1) # => false
1908  * (2..).cover?(3) # => true
1909  * (2...).cover?(3) # => true
1910  * (2..).cover?(2) # => true
1911  * (2..).cover?("2") # => false
1912  * (2..).cover?(2..) # => true
1913  * (2..).cover?(2...) # => true
1914  * (2..).cover?("2"..) # => false
1915  * (2...).cover?(2..) # => false
1916  * (2...).cover?(3...) # => true
1917  * (2...).cover?(3..) # => false
1918  * (3..).cover?(2..) # => false
1919  *
1920  * Ranges that are both beginless and endless cover all values and
1921  * ranges, and return true for all arguments, with the exception that
1922  * beginless and endless exclusive ranges do not cover endless
1923  * inclusive ranges.
1924  *
1925  * (nil...).cover?(Object.new) # => true
1926  * (nil...).cover?(nil...) # => true
1927  * (nil..).cover?(nil...) # => true
1928  * (nil...).cover?(nil..) # => false
1929  * (nil...).cover?(1..) # => false
1930  *
1931  * Related: Range#include?.
1932  *
1933  */
1934 
1935 static VALUE
1936 range_cover(VALUE range, VALUE val)
1937 {
1938  VALUE beg, end;
1939 
1940  beg = RANGE_BEG(range);
1941  end = RANGE_END(range);
1942 
1943  if (rb_obj_is_kind_of(val, rb_cRange)) {
1944  return RBOOL(r_cover_range_p(range, beg, end, val));
1945  }
1946  return r_cover_p(range, beg, end, val);
1947 }
1948 
1949 static VALUE
1950 r_call_max(VALUE r)
1951 {
1952  return rb_funcallv(r, rb_intern("max"), 0, 0);
1953 }
1954 
1955 static int
1956 r_cover_range_p(VALUE range, VALUE beg, VALUE end, VALUE val)
1957 {
1958  VALUE val_beg, val_end, val_max;
1959  int cmp_end;
1960 
1961  val_beg = RANGE_BEG(val);
1962  val_end = RANGE_END(val);
1963 
1964  if (!NIL_P(end) && NIL_P(val_end)) return FALSE;
1965  if (!NIL_P(beg) && NIL_P(val_beg)) return FALSE;
1966  if (!NIL_P(val_beg) && !NIL_P(val_end) && r_less(val_beg, val_end) > (EXCL(val) ? -1 : 0)) return FALSE;
1967  if (!NIL_P(val_beg) && !r_cover_p(range, beg, end, val_beg)) return FALSE;
1968 
1969 
1970  if (!NIL_P(val_end) && !NIL_P(end)) {
1971  VALUE r_cmp_end = rb_funcall(end, id_cmp, 1, val_end);
1972  if (NIL_P(r_cmp_end)) return FALSE;
1973  cmp_end = rb_cmpint(r_cmp_end, end, val_end);
1974  }
1975  else {
1976  cmp_end = r_less(end, val_end);
1977  }
1978 
1979 
1980  if (EXCL(range) == EXCL(val)) {
1981  return cmp_end >= 0;
1982  }
1983  else if (EXCL(range)) {
1984  return cmp_end > 0;
1985  }
1986  else if (cmp_end >= 0) {
1987  return TRUE;
1988  }
1989 
1990  val_max = rb_rescue2(r_call_max, val, 0, Qnil, rb_eTypeError, (VALUE)0);
1991  if (NIL_P(val_max)) return FALSE;
1992 
1993  return r_less(end, val_max) >= 0;
1994 }
1995 
1996 static VALUE
1997 r_cover_p(VALUE range, VALUE beg, VALUE end, VALUE val)
1998 {
1999  if (NIL_P(beg) || r_less(beg, val) <= 0) {
2000  int excl = EXCL(range);
2001  if (NIL_P(end) || r_less(val, end) <= -excl)
2002  return Qtrue;
2003  }
2004  return Qfalse;
2005 }
2006 
2007 static VALUE
2008 range_dumper(VALUE range)
2009 {
2010  VALUE v = rb_obj_alloc(rb_cObject);
2011 
2012  rb_ivar_set(v, id_excl, RANGE_EXCL(range));
2013  rb_ivar_set(v, id_beg, RANGE_BEG(range));
2014  rb_ivar_set(v, id_end, RANGE_END(range));
2015  return v;
2016 }
2017 
2018 static VALUE
2019 range_loader(VALUE range, VALUE obj)
2020 {
2021  VALUE beg, end, excl;
2022 
2023  if (!RB_TYPE_P(obj, T_OBJECT) || RBASIC(obj)->klass != rb_cObject) {
2024  rb_raise(rb_eTypeError, "not a dumped range object");
2025  }
2026 
2027  range_modify(range);
2028  beg = rb_ivar_get(obj, id_beg);
2029  end = rb_ivar_get(obj, id_end);
2030  excl = rb_ivar_get(obj, id_excl);
2031  if (!NIL_P(excl)) {
2032  range_init(range, beg, end, RBOOL(RTEST(excl)));
2033  }
2034  return range;
2035 }
2036 
2037 static VALUE
2038 range_alloc(VALUE klass)
2039 {
2040  /* rb_struct_alloc_noinit itself should not be used because
2041  * rb_marshal_define_compat uses equality of allocation function */
2042  return rb_struct_alloc_noinit(klass);
2043 }
2044 
2045 /*
2046  * call-seq:
2047  * count -> integer
2048  * count(object) -> integer
2049  * count {|element| ... } -> integer
2050  *
2051  * Returns the count of elements, based on an argument or block criterion, if given.
2052  *
2053  * With no argument and no block given, returns the number of elements:
2054  *
2055  * (1..4).count # => 4
2056  * (1...4).count # => 3
2057  * ('a'..'d').count # => 4
2058  * ('a'...'d').count # => 3
2059  * (1..).count # => Infinity
2060  * (..4).count # => Infinity
2061  *
2062  * With argument +object+, returns the number of +object+ found in +self+,
2063  * which will usually be zero or one:
2064  *
2065  * (1..4).count(2) # => 1
2066  * (1..4).count(5) # => 0
2067  * (1..4).count('a') # => 0
2068  *
2069  * With a block given, calls the block with each element;
2070  * returns the number of elements for which the block returns a truthy value:
2071  *
2072  * (1..4).count {|element| element < 3 } # => 2
2073  *
2074  * Related: Range#size.
2075  */
2076 static VALUE
2077 range_count(int argc, VALUE *argv, VALUE range)
2078 {
2079  if (argc != 0) {
2080  /* It is odd for instance (1...).count(0) to return Infinity. Just let
2081  * it loop. */
2082  return rb_call_super(argc, argv);
2083  }
2084  else if (rb_block_given_p()) {
2085  /* Likewise it is odd for instance (1...).count {|x| x == 0 } to return
2086  * Infinity. Just let it loop. */
2087  return rb_call_super(argc, argv);
2088  }
2089  else if (NIL_P(RANGE_END(range))) {
2090  /* We are confident that the answer is Infinity. */
2091  return DBL2NUM(HUGE_VAL);
2092  }
2093  else if (NIL_P(RANGE_BEG(range))) {
2094  /* We are confident that the answer is Infinity. */
2095  return DBL2NUM(HUGE_VAL);
2096  }
2097  else {
2098  return rb_call_super(argc, argv);
2099  }
2100 }
2101 
2102 /* A \Range object represents a collection of values
2103  * that are between given begin and end values.
2104  *
2105  * You can create an \Range object explicitly with:
2106  *
2107  * - A {range literal}[doc/syntax/literals_rdoc.html#label-Range+Literals]:
2108  *
2109  * # Ranges that use '..' to include the given end value.
2110  * (1..4).to_a # => [1, 2, 3, 4]
2111  * ('a'..'d').to_a # => ["a", "b", "c", "d"]
2112  * # Ranges that use '...' to exclude the given end value.
2113  * (1...4).to_a # => [1, 2, 3]
2114  * ('a'...'d').to_a # => ["a", "b", "c"]
2115  *
2116  * A range may be created using method Range.new:
2117  *
2118  * # Ranges that by default include the given end value.
2119  * Range.new(1, 4).to_a # => [1, 2, 3, 4]
2120  * Range.new('a', 'd').to_a # => ["a", "b", "c", "d"]
2121  * # Ranges that use third argument +exclude_end+ to exclude the given end value.
2122  * Range.new(1, 4, true).to_a # => [1, 2, 3]
2123  * Range.new('a', 'd', true).to_a # => ["a", "b", "c"]
2124  *
2125  * == Beginless Ranges
2126  *
2127  * A _beginless_ _range_ has a definite end value, but a +nil+ begin value.
2128  * Such a range includes all values up to the end value.
2129  *
2130  * r = (..4) # => nil..4
2131  * r.begin # => nil
2132  * r.include?(-50) # => true
2133  * r.include?(4) # => true
2134  *
2135  * r = (...4) # => nil...4
2136  * r.include?(4) # => false
2137  *
2138  * Range.new(nil, 4) # => nil..4
2139  * Range.new(nil, 4, true) # => nil...4
2140  *
2141  * A beginless range may be used to slice an array:
2142  *
2143  * a = [1, 2, 3, 4]
2144  * r = (..2) # => nil...2
2145  * a[r] # => [1, 2]
2146  *
2147  * \Method +each+ for a beginless range raises an exception.
2148  *
2149  * == Endless Ranges
2150  *
2151  * An _endless_ _range_ has a definite begin value, but a +nil+ end value.
2152  * Such a range includes all values from the begin value.
2153  *
2154  * r = (1..) # => 1..
2155  * r.end # => nil
2156  * r.include?(50) # => true
2157  *
2158  * Range.new(1, nil) # => 1..
2159  *
2160  * The literal for an endless range may be written with either two dots
2161  * or three.
2162  * The range has the same elements, either way.
2163  * But note that the two are not equal:
2164  *
2165  * r0 = (1..) # => 1..
2166  * r1 = (1...) # => 1...
2167  * r0.begin == r1.begin # => true
2168  * r0.end == r1.end # => true
2169  * r0 == r1 # => false
2170  *
2171  * An endless range may be used to slice an array:
2172  *
2173  * a = [1, 2, 3, 4]
2174  * r = (2..) # => 2..
2175  * a[r] # => [3, 4]
2176  *
2177  * \Method +each+ for an endless range calls the given block indefinitely:
2178  *
2179  * a = []
2180  * r = (1..)
2181  * r.each do |i|
2182  * a.push(i) if i.even?
2183  * break if i > 10
2184  * end
2185  * a # => [2, 4, 6, 8, 10]
2186  *
2187  * == Ranges and Other Classes
2188  *
2189  * An object may be put into a range if its class implements
2190  * instance method <tt><=></tt>.
2191  * Ruby core classes that do so include Array, Complex, File::Stat,
2192  * Float, Integer, Kernel, Module, Numeric, Rational, String, Symbol, and Time.
2193  *
2194  * Example:
2195  *
2196  * t0 = Time.now # => 2021-09-19 09:22:48.4854986 -0500
2197  * t1 = Time.now # => 2021-09-19 09:22:56.0365079 -0500
2198  * t2 = Time.now # => 2021-09-19 09:23:08.5263283 -0500
2199  * (t0..t2).include?(t1) # => true
2200  * (t0..t1).include?(t2) # => false
2201  *
2202  * A range can be iterated over only if its elements
2203  * implement instance method +succ+.
2204  * Ruby core classes that do so include Integer, String, and Symbol
2205  * (but not the other classes mentioned above).
2206  *
2207  * Iterator methods include:
2208  *
2209  * - In \Range itself: #each, #step, and #%
2210  * - Included from module Enumerable: #each_entry, #each_with_index,
2211  * #each_with_object, #each_slice, #each_cons, and #reverse_each.
2212  *
2213  * Example:
2214  *
2215  * a = []
2216  * (1..4).each {|i| a.push(i) }
2217  * a # => [1, 2, 3, 4]
2218  *
2219  * == Ranges and User-Defined Classes
2220  *
2221  * A user-defined class that is to be used in a range
2222  * must implement instance <tt><=></tt>;
2223  * see {Integer#<=>}[Integer.html#label-method-i-3C-3D-3E].
2224  * To make iteration available, it must also implement
2225  * instance method +succ+; see Integer#succ.
2226  *
2227  * The class below implements both <tt><=></tt> and +succ+,
2228  * and so can be used both to construct ranges and to iterate over them.
2229  * Note that the Comparable module is included
2230  * so the <tt>==</tt> method is defined in terms of <tt><=></tt>.
2231  *
2232  * # Represent a string of 'X' characters.
2233  * class Xs
2234  * include Comparable
2235  * attr_accessor :length
2236  * def initialize(n)
2237  * @length = n
2238  * end
2239  * def succ
2240  * Xs.new(@length + 1)
2241  * end
2242  * def <=>(other)
2243  * @length <=> other.length
2244  * end
2245  * def to_s
2246  * sprintf "%2d #{inspect}", @length
2247  * end
2248  * def inspect
2249  * 'X' * @length
2250  * end
2251  * end
2252  *
2253  * r = Xs.new(3)..Xs.new(6) #=> XXX..XXXXXX
2254  * r.to_a #=> [XXX, XXXX, XXXXX, XXXXXX]
2255  * r.include?(Xs.new(5)) #=> true
2256  * r.include?(Xs.new(7)) #=> false
2257  *
2258  * == What's Here
2259  *
2260  * First, what's elsewhere. \Class \Range:
2261  *
2262  * - Inherits from {class Object}[Object.html#class-Object-label-What-27s+Here].
2263  * - Includes {module Enumerable}[Enumerable.html#module-Enumerable-label-What-27s+Here],
2264  * which provides dozens of additional methods.
2265  *
2266  * Here, class \Range provides methods that are useful for:
2267  *
2268  * - {Creating a Range}[#class-Range-label-Methods+for+Creating+a+Range]
2269  * - {Querying}[#class-Range-label-Methods+for+Querying]
2270  * - {Comparing}[#class-Range-label-Methods+for+Comparing]
2271  * - {Iterating}[#class-Range-label-Methods+for+Iterating]
2272  * - {Converting}[#class-Range-label-Methods+for+Converting]
2273  *
2274  * === Methods for Creating a \Range
2275  *
2276  * - ::new:: Returns a new range.
2277  *
2278  * === Methods for Querying
2279  *
2280  * - #begin:: Returns the begin value given for +self+.
2281  * - #bsearch:: Returns an element from +self+ selected by a binary search.
2282  * - #count:: Returns a count of elements in +self+.
2283  * - #end:: Returns the end value given for +self+.
2284  * - #exclude_end?:: Returns whether the end object is excluded.
2285  * - #first:: Returns the first elements of +self+.
2286  * - #hash:: Returns the integer hash code.
2287  * - #last:: Returns the last elements of +self+.
2288  * - #max:: Returns the maximum values in +self+.
2289  * - #min:: Returns the minimum values in +self+.
2290  * - #minmax:: Returns the minimum and maximum values in +self+.
2291  * - #size:: Returns the count of elements in +self+.
2292  *
2293  * === Methods for Comparing
2294  *
2295  * - {#==}[#method-i-3D-3D]:: Returns whether a given object is equal to +self+
2296  * (uses #==).
2297  * - #===:: Returns whether the given object is between the begin and end values.
2298  * - #cover?:: Returns whether a given object is within +self+.
2299  * - #eql?:: Returns whether a given object is equal to +self+ (uses #eql?).
2300  * - #include? (aliased as #member?):: Returns whether a given object
2301  * is an element of +self+.
2302  *
2303  * === Methods for Iterating
2304  *
2305  * - #%:: Requires argument +n+; calls the block with each +n+-th element of +self+.
2306  * - #each:: Calls the block with each element of +self+.
2307  * - #step:: Takes optional argument +n+ (defaults to 1);
2308  calls the block with each +n+-th element of +self+.
2309  *
2310  * === Methods for Converting
2311  *
2312  * - #inspect:: Returns a string representation of +self+ (uses #inspect).
2313  * - #to_a (aliased as #entries):: Returns elements of +self+ in an array.
2314  * - #to_s:: Returns a string representation of +self+ (uses #to_s).
2315  *
2316  */
2317 
2318 void
2319 Init_Range(void)
2320 {
2321  id_beg = rb_intern_const("begin");
2322  id_end = rb_intern_const("end");
2323  id_excl = rb_intern_const("excl");
2324 
2326  "Range", rb_cObject, range_alloc,
2327  "begin", "end", "excl", NULL);
2328 
2330  rb_marshal_define_compat(rb_cRange, rb_cObject, range_dumper, range_loader);
2331  rb_define_method(rb_cRange, "initialize", range_initialize, -1);
2332  rb_define_method(rb_cRange, "initialize_copy", range_initialize_copy, 1);
2333  rb_define_method(rb_cRange, "==", range_eq, 1);
2334  rb_define_method(rb_cRange, "===", range_eqq, 1);
2335  rb_define_method(rb_cRange, "eql?", range_eql, 1);
2336  rb_define_method(rb_cRange, "hash", range_hash, 0);
2337  rb_define_method(rb_cRange, "each", range_each, 0);
2338  rb_define_method(rb_cRange, "step", range_step, -1);
2339  rb_define_method(rb_cRange, "%", range_percent_step, 1);
2340  rb_define_method(rb_cRange, "bsearch", range_bsearch, 0);
2341  rb_define_method(rb_cRange, "begin", range_begin, 0);
2342  rb_define_method(rb_cRange, "end", range_end, 0);
2343  rb_define_method(rb_cRange, "first", range_first, -1);
2344  rb_define_method(rb_cRange, "last", range_last, -1);
2345  rb_define_method(rb_cRange, "min", range_min, -1);
2346  rb_define_method(rb_cRange, "max", range_max, -1);
2347  rb_define_method(rb_cRange, "minmax", range_minmax, 0);
2348  rb_define_method(rb_cRange, "size", range_size, 0);
2349  rb_define_method(rb_cRange, "to_a", range_to_a, 0);
2350  rb_define_method(rb_cRange, "entries", range_to_a, 0);
2351  rb_define_method(rb_cRange, "to_s", range_to_s, 0);
2352  rb_define_method(rb_cRange, "inspect", range_inspect, 0);
2353 
2354  rb_define_method(rb_cRange, "exclude_end?", range_exclude_end_p, 0);
2355 
2356  rb_define_method(rb_cRange, "member?", range_include, 1);
2357  rb_define_method(rb_cRange, "include?", range_include, 1);
2358  rb_define_method(rb_cRange, "cover?", range_cover, 1);
2359  rb_define_method(rb_cRange, "count", range_count, -1);
2360 }
#define RB_LIKELY(x)
Asserts that the given Boolean expression likely holds.
Definition: assume.h:45
void rb_include_module(VALUE klass, VALUE module)
Includes a module to a class.
Definition: class.c:1043
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Retrieves argument from argc and argv to given VALUE references according to the format string.
Definition: class.c:2406
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a method.
Definition: class.c:1914
int rb_block_given_p(void)
Determines if the current method is given a block.
Definition: eval.c:854
#define rb_str_new2
Old name of rb_str_new_cstr.
Definition: string.h:1738
#define RB_INTEGER_TYPE_P
Old name of rb_integer_type_p.
Definition: value_type.h:87
#define RFLOAT_VALUE
Old name of rb_float_value.
Definition: double.h:28
#define T_STRING
Old name of RUBY_T_STRING.
Definition: value_type.h:78
#define Qundef
Old name of RUBY_Qundef.
#define INT2FIX
Old name of RB_INT2FIX.
Definition: long.h:48
#define UNREACHABLE
Old name of RBIMPL_UNREACHABLE.
Definition: assume.h:30
#define T_FLOAT
Old name of RUBY_T_FLOAT.
Definition: value_type.h:64
#define ID2SYM
Old name of RB_ID2SYM.
Definition: symbol.h:44
#define T_BIGNUM
Old name of RUBY_T_BIGNUM.
Definition: value_type.h:57
#define SPECIAL_CONST_P
Old name of RB_SPECIAL_CONST_P.
#define FIXNUM_FLAG
Old name of RUBY_FIXNUM_FLAG.
#define CLASS_OF
Old name of rb_class_of.
Definition: globals.h:203
#define FIXABLE
Old name of RB_FIXABLE.
Definition: fixnum.h:25
#define LONG2FIX
Old name of RB_INT2FIX.
Definition: long.h:49
#define ASSUME
Old name of RBIMPL_ASSUME.
Definition: assume.h:29
#define LONG2NUM
Old name of RB_LONG2NUM.
Definition: long.h:50
#define FLONUM_P
Old name of RB_FLONUM_P.
#define Qtrue
Old name of RUBY_Qtrue.
#define ST2FIX
Old name of RB_ST2FIX.
Definition: st_data_t.h:33
#define INT2NUM
Old name of RB_INT2NUM.
Definition: int.h:43
#define Qnil
Old name of RUBY_Qnil.
#define Qfalse
Old name of RUBY_Qfalse.
#define FIX2LONG
Old name of RB_FIX2LONG.
Definition: long.h:46
#define T_OBJECT
Old name of RUBY_T_OBJECT.
Definition: value_type.h:75
#define NIL_P
Old name of RB_NIL_P.
#define POSFIXABLE
Old name of RB_POSFIXABLE.
Definition: fixnum.h:29
#define DBL2NUM
Old name of rb_float_new.
Definition: double.h:29
#define BUILTIN_TYPE
Old name of RB_BUILTIN_TYPE.
Definition: value_type.h:85
#define NUM2LONG
Old name of RB_NUM2LONG.
Definition: long.h:51
#define FIXNUM_P
Old name of RB_FIXNUM_P.
#define CONST_ID
Old name of RUBY_CONST_ID.
Definition: symbol.h:47
#define rb_ary_new2
Old name of rb_ary_new_capa.
Definition: array.h:651
#define SYMBOL_P
Old name of RB_SYMBOL_P.
Definition: value_type.h:88
void rb_raise(VALUE exc, const char *fmt,...)
Exception entry point.
Definition: error.c:3025
VALUE rb_rescue2(VALUE(*b_proc)(VALUE), VALUE data1, VALUE(*r_proc)(VALUE, VALUE), VALUE data2,...)
An equivalent of rescue clause.
Definition: eval.c:883
void rb_iter_break(void)
Breaks from a block.
Definition: vm.c:1821
VALUE rb_eRangeError
RangeError exception.
Definition: error.c:1103
VALUE rb_eTypeError
TypeError exception.
Definition: error.c:1099
VALUE rb_eArgError
ArgumentError exception.
Definition: error.c:1100
VALUE rb_cTime
Time class.
Definition: time.c:647
VALUE rb_Float(VALUE val)
This is the logic behind Kernel#Float.
Definition: object.c:3441
VALUE rb_obj_alloc(VALUE klass)
Allocates an instance of the given class.
Definition: object.c:1909
VALUE rb_mEnumerable
Enumerable module.
Definition: enum.c:27
int rb_eql(VALUE lhs, VALUE rhs)
Checks for equality of the passed objects, in terms of Object#eql?.
Definition: object.c:133
VALUE rb_cNumeric
Numeric class.
Definition: numeric.c:190
VALUE rb_Array(VALUE val)
This is the logic behind Kernel#Array.
Definition: object.c:3593
VALUE rb_inspect(VALUE obj)
Generates a human-readable textual representation of the given object.
Definition: object.c:564
VALUE rb_cRange
Range class.
Definition: range.c:31
VALUE rb_equal(VALUE lhs, VALUE rhs)
This function is an optimised version of calling #==.
Definition: object.c:120
VALUE rb_obj_is_kind_of(VALUE obj, VALUE klass)
Queries if the given object is an instance (of possibly descendants) of the given class.
Definition: object.c:731
VALUE rb_obj_freeze(VALUE obj)
Just calls rb_obj_freeze_inline() inside.
Definition: object.c:1161
VALUE rb_check_to_integer(VALUE val, const char *mid)
Identical to rb_check_convert_type(), except the return value type is fixed to rb_cInteger.
Definition: object.c:2985
VALUE rb_to_int(VALUE val)
Identical to rb_check_to_int(), except it raises in case of conversion mismatch.
Definition: object.c:2998
#define RUBY_FIXNUM_MAX
Maximum possible value that a fixnum can represent.
Definition: fixnum.h:55
VALUE rb_funcall(VALUE recv, ID mid, int n,...)
Calls a method.
Definition: vm_eval.c:1102
VALUE rb_funcallv(VALUE recv, ID mid, int argc, const VALUE *argv)
Identical to rb_funcall(), except it takes the method arguments as a C array.
Definition: vm_eval.c:1061
VALUE rb_call_super(int argc, const VALUE *argv)
This resembles ruby's super.
Definition: vm_eval.c:338
VALUE rb_ary_new_capa(long capa)
Identical to rb_ary_new(), except it additionally specifies how many rooms of objects it should alloc...
Definition: array.c:744
VALUE rb_ary_push(VALUE ary, VALUE elem)
Special case of rb_ary_cat() that it adds only one element.
Definition: array.c:1308
VALUE rb_assoc_new(VALUE car, VALUE cdr)
Identical to rb_ary_new_from_values(), except it expects exactly two parameters.
Definition: array.c:976
VALUE rb_big_plus(VALUE x, VALUE y)
Performs addition of the passed two objects.
Definition: bignum.c:5821
VALUE rb_big_cmp(VALUE lhs, VALUE rhs)
Compares the passed two bignums.
Definition: bignum.c:5418
int rb_cmpint(VALUE val, VALUE a, VALUE b)
Canonicalises the passed val, which is the return value of a <=> b, into C's {-1, 0,...
Definition: bignum.c:2935
#define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn)
This roughly resembles return enum_for(__callee__) unless block_given?.
Definition: enumerator.h:206
#define RETURN_ENUMERATOR(obj, argc, argv)
Identical to RETURN_SIZED_ENUMERATOR(), except its size is unknown.
Definition: enumerator.h:239
#define rb_check_frozen
Just another name of rb_check_frozen.
Definition: error.h:278
static int rb_check_arity(int argc, int min, int max)
Ensures that the passed integer is in the passed range.
Definition: error.h:294
ID rb_frame_this_func(void)
Queries the name of the Ruby level method that is calling this function.
Definition: eval.c:1039
VALUE rb_hash(VALUE obj)
Calculates a message authentication code of the passed object.
Definition: hash.c:227
int rb_range_values(VALUE range, VALUE *begp, VALUE *endp, int *exclp)
Deconstructs a range into its components.
Definition: range.c:1490
VALUE rb_range_new(VALUE beg, VALUE end, int excl)
Creates a new Range.
Definition: range.c:67
VALUE rb_range_beg_len(VALUE range, long *begp, long *lenp, long len, int err)
Deconstructs a numerical range.
Definition: range.c:1578
#define rb_hash_uint(h, i)
Just another name of st_hash_uint.
Definition: string.h:973
#define rb_hash_end(h)
Just another name of st_hash_end.
Definition: string.h:976
VALUE rb_str_append(VALUE dst, VALUE src)
Identical to rb_str_buf_append(), except it converts the right hand side before concatenating.
Definition: string.c:3317
VALUE rb_str_dup(VALUE str)
Duplicates a string.
Definition: string.c:1808
VALUE rb_str_cat(VALUE dst, const char *src, long srclen)
Destructively appends the passed contents to the string.
Definition: string.c:3161
st_index_t rb_hash_start(st_index_t i)
Starts a series of hashing.
Definition: random.c:1714
VALUE rb_str_new(const char *ptr, long len)
Allocates an instance of rb_cString.
Definition: string.c:918
VALUE rb_check_string_type(VALUE obj)
Try converting an object to its stringised representation using its to_str method,...
Definition: string.c:2659
VALUE rb_str_intern(VALUE str)
Identical to rb_to_symbol(), except it assumes the receiver being an instance of RString.
Definition: symbol.c:837
VALUE rb_obj_as_string(VALUE obj)
Try converting an object to its stringised representation using its to_s method, if any.
Definition: string.c:1657
VALUE rb_struct_define_without_accessor(const char *name, VALUE super, rb_alloc_func_t func,...)
Identical to rb_struct_define(), except it does not define accessor methods.
Definition: struct.c:422
VALUE rb_struct_alloc_noinit(VALUE klass)
Allocates an instance of the given class.
Definition: struct.c:352
VALUE rb_exec_recursive(VALUE(*f)(VALUE g, VALUE h, int r), VALUE g, VALUE h)
"Recursion" API entry point.
VALUE rb_exec_recursive_paired(VALUE(*f)(VALUE g, VALUE h, int r), VALUE g, VALUE p, VALUE h)
Identical to rb_exec_recursive(), except it checks for the recursion on the ordered pair of { g,...
VALUE rb_ivar_set(VALUE obj, ID name, VALUE val)
Identical to rb_iv_set(), except it accepts the name as an ID instead of a C string.
Definition: variable.c:1575
VALUE rb_ivar_get(VALUE obj, ID name)
Identical to rb_iv_get(), except it accepts the name as an ID instead of a C string.
Definition: variable.c:1285
int rb_respond_to(VALUE obj, ID mid)
Queries if the object responds to the method.
Definition: vm_method.c:2765
int rb_method_basic_definition_p(VALUE klass, ID mid)
Well...
Definition: vm_method.c:2643
VALUE rb_check_funcall(VALUE recv, ID mid, int argc, const VALUE *argv)
Identical to rb_funcallv(), except it returns RUBY_Qundef instead of raising rb_eNoMethodError.
Definition: vm_eval.c:664
static ID rb_intern_const(const char *str)
This is a "tiny optimisation" over rb_intern().
Definition: symbol.h:276
ID rb_intern(const char *name)
Finds or creates a symbol of the given name.
Definition: symbol.c:782
VALUE rb_sym2str(VALUE id)
Identical to rb_id2str(), except it takes an instance of rb_cSymbol rather than an ID.
Definition: symbol.c:924
RBIMPL_ATTR_NORETURN() void rb_eof_error(void)
Utility function to raise rb_eEOFError.
#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg)
Shim for block function parameters.
Definition: iterator.h:58
VALUE rb_block_call(VALUE obj, ID mid, int argc, const VALUE *argv, rb_block_call_func_t proc, VALUE data2)
Identical to rb_funcallv(), except it additionally passes a function as a block.
Definition: vm_eval.c:1595
VALUE rb_yield(VALUE val)
Yields the block.
Definition: vm_eval.c:1357
void rb_marshal_define_compat(VALUE newclass, VALUE oldclass, VALUE(*dumper)(VALUE), VALUE(*loader)(VALUE, VALUE))
Marshal format compatibility layer.
Definition: marshal.c:148
#define RARRAY_AREF(a, i)
Definition: rarray.h:588
#define RBASIC(obj)
Convenient casting macro.
Definition: rbasic.h:40
#define RBIGNUM_SIGN
Just another name of rb_big_sign.
Definition: rbignum.h:29
static bool RBIGNUM_NEGATIVE_P(VALUE b)
Checks if the bignum is negative.
Definition: rbignum.h:74
static bool RBIGNUM_POSITIVE_P(VALUE b)
Checks if the bignum is positive.
Definition: rbignum.h:61
const char * rb_obj_classname(VALUE obj)
Queries the name of the class of the passed object.
Definition: variable.c:309
#define RTEST
This is an old name of RB_TEST.
uintptr_t ID
Type that represents a Ruby identifier such as a variable name.
Definition: value.h:52
uintptr_t VALUE
Type that represents a Ruby object.
Definition: value.h:40
static bool RB_FLOAT_TYPE_P(VALUE obj)
Queries if the object is an instance of rb_cFloat.
Definition: value_type.h:263
static bool RB_TYPE_P(VALUE obj, enum ruby_value_type t)
Queries if the given object is of given type.
Definition: value_type.h:375