Ruby  2.4.2p198(2017-09-14revision59899)
range.c
Go to the documentation of this file.
1 /**********************************************************************
2 
3  range.c -
4 
5  $Author: nobu $
6  created at: Thu Aug 19 17:46:47 JST 1993
7 
8  Copyright (C) 1993-2007 Yukihiro Matsumoto
9 
10 **********************************************************************/
11 
12 #include "internal.h"
13 #include "id.h"
14 
15 #ifdef HAVE_FLOAT_H
16 #include <float.h>
17 #endif
18 #include <math.h>
19 
22 #define id_cmp idCmp
23 #define id_succ idSucc
24 
26 
27 #define RANGE_BEG(r) (RSTRUCT(r)->as.ary[0])
28 #define RANGE_END(r) (RSTRUCT(r)->as.ary[1])
29 #define RANGE_EXCL(r) (RSTRUCT(r)->as.ary[2])
30 #define RANGE_SET_BEG(r, v) (RSTRUCT_SET(r, 0, v))
31 #define RANGE_SET_END(r, v) (RSTRUCT_SET(r, 1, v))
32 #define RANGE_SET_EXCL(r, v) (RSTRUCT_SET(r, 2, v))
33 #define RBOOL(v) ((v) ? Qtrue : Qfalse)
34 
35 #define EXCL(r) RTEST(RANGE_EXCL(r))
36 
37 static VALUE
39 {
40  rb_raise(rb_eArgError, "bad value for range");
41  return Qnil; /* dummy */
42 }
43 
44 static VALUE
46 {
47  return rb_funcall(args[0], id_cmp, 1, args[1]);
48 }
49 
50 static void
51 range_init(VALUE range, VALUE beg, VALUE end, VALUE exclude_end)
52 {
53  VALUE args[2];
54 
55  args[0] = beg;
56  args[1] = end;
57 
58  if (!FIXNUM_P(beg) || !FIXNUM_P(end)) {
59  VALUE v;
60 
61  v = rb_rescue(range_check, (VALUE)args, range_failed, 0);
62  if (NIL_P(v))
63  range_failed();
64  }
65 
66  RANGE_SET_EXCL(range, exclude_end);
67  RANGE_SET_BEG(range, beg);
68  RANGE_SET_END(range, end);
69 }
70 
71 VALUE
72 rb_range_new(VALUE beg, VALUE end, int exclude_end)
73 {
75 
76  range_init(range, beg, end, RBOOL(exclude_end));
77  return range;
78 }
79 
80 static void
82 {
83  rb_check_frozen(range);
84  /* Ranges are immutable, so that they should be initialized only once. */
85  if (RANGE_EXCL(range) != Qnil) {
86  rb_name_err_raise("`initialize' called twice", range, ID2SYM(idInitialize));
87  }
88 }
89 
90 /*
91  * call-seq:
92  * Range.new(begin, end, exclude_end=false) -> rng
93  *
94  * Constructs a range using the given +begin+ and +end+. If the +exclude_end+
95  * parameter is omitted or is <code>false</code>, the +rng+ will include
96  * the end object; otherwise, it will be excluded.
97  */
98 
99 static VALUE
101 {
102  VALUE beg, end, flags;
103 
104  rb_scan_args(argc, argv, "21", &beg, &end, &flags);
105  range_modify(range);
106  range_init(range, beg, end, RBOOL(RTEST(flags)));
107  return Qnil;
108 }
109 
110 /* :nodoc: */
111 static VALUE
113 {
114  range_modify(range);
115  rb_struct_init_copy(range, orig);
116  return range;
117 }
118 
119 /*
120  * call-seq:
121  * rng.exclude_end? -> true or false
122  *
123  * Returns <code>true</code> if the range excludes its end value.
124  *
125  * (1..5).exclude_end? #=> false
126  * (1...5).exclude_end? #=> true
127  */
128 
129 static VALUE
131 {
132  return EXCL(range) ? Qtrue : Qfalse;
133 }
134 
135 static VALUE
137 {
138  if (recur) return Qtrue; /* Subtle! */
139  if (!rb_equal(RANGE_BEG(range), RANGE_BEG(obj)))
140  return Qfalse;
141  if (!rb_equal(RANGE_END(range), RANGE_END(obj)))
142  return Qfalse;
143 
144  if (EXCL(range) != EXCL(obj))
145  return Qfalse;
146  return Qtrue;
147 }
148 
149 
150 /*
151  * call-seq:
152  * rng == obj -> true or false
153  *
154  * Returns <code>true</code> only if +obj+ is a Range, has equivalent
155  * begin and end items (by comparing them with <code>==</code>), and has
156  * the same #exclude_end? setting as the range.
157  *
158  * (0..2) == (0..2) #=> true
159  * (0..2) == Range.new(0,2) #=> true
160  * (0..2) == (0...2) #=> false
161  *
162  */
163 
164 static VALUE
166 {
167  if (range == obj)
168  return Qtrue;
169  if (!rb_obj_is_kind_of(obj, rb_cRange))
170  return Qfalse;
171 
172  return rb_exec_recursive_paired(recursive_equal, range, obj, obj);
173 }
174 
175 /* compares _a_ and _b_ and returns:
176  * < 0: a < b
177  * = 0: a = b
178  * > 0: a > b or non-comparable
179  */
180 static int
182 {
183  VALUE r = rb_funcall(a, id_cmp, 1, b);
184 
185  if (NIL_P(r))
186  return INT_MAX;
187  return rb_cmpint(r, a, b);
188 }
189 
190 static VALUE
192 {
193  if (recur) return Qtrue; /* Subtle! */
194  if (!rb_eql(RANGE_BEG(range), RANGE_BEG(obj)))
195  return Qfalse;
196  if (!rb_eql(RANGE_END(range), RANGE_END(obj)))
197  return Qfalse;
198 
199  if (EXCL(range) != EXCL(obj))
200  return Qfalse;
201  return Qtrue;
202 }
203 
204 /*
205  * call-seq:
206  * rng.eql?(obj) -> true or false
207  *
208  * Returns <code>true</code> only if +obj+ is a Range, has equivalent
209  * begin and end items (by comparing them with <code>eql?</code>),
210  * and has the same #exclude_end? setting as the range.
211  *
212  * (0..2).eql?(0..2) #=> true
213  * (0..2).eql?(Range.new(0,2)) #=> true
214  * (0..2).eql?(0...2) #=> false
215  *
216  */
217 
218 static VALUE
220 {
221  if (range == obj)
222  return Qtrue;
223  if (!rb_obj_is_kind_of(obj, rb_cRange))
224  return Qfalse;
225  return rb_exec_recursive_paired(recursive_eql, range, obj, obj);
226 }
227 
228 /*
229  * call-seq:
230  * rng.hash -> integer
231  *
232  * Compute a hash-code for this range. Two ranges with equal
233  * begin and end points (using <code>eql?</code>), and the same
234  * #exclude_end? value will generate the same hash-code.
235  *
236  * See also Object#hash.
237  */
238 
239 static VALUE
241 {
242  st_index_t hash = EXCL(range);
243  VALUE v;
244 
245  hash = rb_hash_start(hash);
246  v = rb_hash(RANGE_BEG(range));
247  hash = rb_hash_uint(hash, NUM2LONG(v));
248  v = rb_hash(RANGE_END(range));
249  hash = rb_hash_uint(hash, NUM2LONG(v));
250  hash = rb_hash_uint(hash, EXCL(range) << 24);
251  hash = rb_hash_end(hash);
252 
253  return LONG2FIX(hash);
254 }
255 
256 static void
258 {
259  int c;
260  VALUE b = RANGE_BEG(range);
261  VALUE e = RANGE_END(range);
262  VALUE v = b;
263 
264  if (EXCL(range)) {
265  while (r_less(v, e) < 0) {
266  (*func) (v, arg, 0, 0, 0);
267  v = rb_funcallv(v, id_succ, 0, 0);
268  }
269  }
270  else {
271  while ((c = r_less(v, e)) <= 0) {
272  (*func) (v, arg, 0, 0, 0);
273  if (!c) break;
274  v = rb_funcallv(v, id_succ, 0, 0);
275  }
276  }
277 }
278 
279 static VALUE
281 {
282  VALUE *iter = (VALUE *)arg;
283 
284  if (FIXNUM_P(iter[0])) {
285  iter[0] -= INT2FIX(1) & ~FIXNUM_FLAG;
286  }
287  else {
288  iter[0] = rb_funcall(iter[0], '-', 1, INT2FIX(1));
289  }
290  if (iter[0] == INT2FIX(0)) {
292  iter[0] = iter[1];
293  }
294  return Qnil;
295 }
296 
297 static VALUE
299 {
300  VALUE *iter = (VALUE *)arg;
301 
302  if (FIXNUM_P(iter[0])) {
303  iter[0] -= INT2FIX(1) & ~FIXNUM_FLAG;
304  }
305  else {
306  iter[0] = rb_funcall(iter[0], '-', 1, INT2FIX(1));
307  }
308  if (iter[0] == INT2FIX(0)) {
309  rb_yield(i);
310  iter[0] = iter[1];
311  }
312  return Qnil;
313 }
314 
315 static int
317 {
318  if (rb_obj_is_kind_of(obj, rb_cTime)) return FALSE; /* until Time#succ removed */
319  return rb_respond_to(obj, id_succ);
320 }
321 
322 static int
324 {
325  if (FIXNUM_P(obj) || FLONUM_P(obj)) return TRUE;
326  if (SPECIAL_CONST_P(obj)) return FALSE;
327  switch (BUILTIN_TYPE(obj)) {
328  case T_FLOAT:
329  case T_BIGNUM:
330  return TRUE;
331  }
332  if (rb_obj_is_kind_of(obj, rb_cNumeric)) return TRUE;
333  if (rb_obj_is_kind_of(obj, rb_cTime)) return TRUE;
334  return FALSE;
335 }
336 
337 static VALUE
339 {
340  VALUE zero = INT2FIX(0);
341  int cmp;
342  if (!rb_obj_is_kind_of(step, rb_cNumeric)) {
343  step = rb_to_int(step);
344  }
345  cmp = rb_cmpint(rb_funcallv(step, idCmp, 1, &zero), step, zero);
346  if (cmp < 0) {
347  rb_raise(rb_eArgError, "step can't be negative");
348  }
349  else if (cmp == 0) {
350  rb_raise(rb_eArgError, "step can't be 0");
351  }
352  return step;
353 }
354 
355 static VALUE
357 {
358  VALUE b = RANGE_BEG(range), e = RANGE_END(range);
359  VALUE step = INT2FIX(1);
360  if (args) {
361  step = check_step_domain(RARRAY_AREF(args, 0));
362  }
363 
365  return ruby_num_interval_step_size(b, e, step, EXCL(range));
366  }
367  return Qnil;
368 }
369 
370 /*
371  * call-seq:
372  * rng.step(n=1) {| obj | block } -> rng
373  * rng.step(n=1) -> an_enumerator
374  *
375  * Iterates over the range, passing each <code>n</code>th element to the block.
376  * If begin and end are numeric, +n+ is added for each iteration.
377  * Otherwise <code>step</code> invokes <code>succ</code> to iterate through
378  * range elements.
379  *
380  * If no block is given, an enumerator is returned instead.
381  *
382  * range = Xs.new(1)..Xs.new(10)
383  * range.step(2) {|x| puts x}
384  * puts
385  * range.step(3) {|x| puts x}
386  *
387  * <em>produces:</em>
388  *
389  * 1 x
390  * 3 xxx
391  * 5 xxxxx
392  * 7 xxxxxxx
393  * 9 xxxxxxxxx
394  *
395  * 1 x
396  * 4 xxxx
397  * 7 xxxxxxx
398  * 10 xxxxxxxxxx
399  *
400  * See Range for the definition of class Xs.
401  */
402 
403 
404 static VALUE
406 {
407  VALUE b, e, step, tmp;
408 
409  RETURN_SIZED_ENUMERATOR(range, argc, argv, range_step_size);
410 
411  b = RANGE_BEG(range);
412  e = RANGE_END(range);
413  if (argc == 0) {
414  step = INT2FIX(1);
415  }
416  else {
417  rb_scan_args(argc, argv, "01", &step);
418  step = check_step_domain(step);
419  }
420 
421  if (FIXNUM_P(b) && FIXNUM_P(e) && FIXNUM_P(step)) { /* fixnums are special */
422  long end = FIX2LONG(e);
423  long i, unit = FIX2LONG(step);
424 
425  if (!EXCL(range))
426  end += 1;
427  i = FIX2LONG(b);
428  while (i < end) {
429  rb_yield(LONG2NUM(i));
430  if (i + unit < i) break;
431  i += unit;
432  }
433 
434  }
435  else if (SYMBOL_P(b) && SYMBOL_P(e)) { /* symbols are special */
436  VALUE args[2], iter[2];
437 
438  args[0] = rb_sym2str(e);
439  args[1] = EXCL(range) ? Qtrue : Qfalse;
440  iter[0] = INT2FIX(1);
441  iter[1] = step;
442  rb_block_call(rb_sym2str(b), rb_intern("upto"), 2, args, sym_step_i, (VALUE)iter);
443  }
444  else if (ruby_float_step(b, e, step, EXCL(range))) {
445  /* done */
446  }
447  else if (rb_obj_is_kind_of(b, rb_cNumeric) ||
448  !NIL_P(rb_check_to_integer(b, "to_int")) ||
449  !NIL_P(rb_check_to_integer(e, "to_int"))) {
450  ID op = EXCL(range) ? '<' : idLE;
451  VALUE v = b;
452  int i = 0;
453 
454  while (RTEST(rb_funcall(v, op, 1, e))) {
455  rb_yield(v);
456  i++;
457  v = rb_funcall(b, '+', 1, rb_funcall(INT2NUM(i), '*', 1, step));
458  }
459  }
460  else {
461  tmp = rb_check_string_type(b);
462 
463  if (!NIL_P(tmp)) {
464  VALUE args[2], iter[2];
465 
466  b = tmp;
467  args[0] = e;
468  args[1] = EXCL(range) ? Qtrue : Qfalse;
469  iter[0] = INT2FIX(1);
470  iter[1] = step;
471  rb_block_call(b, rb_intern("upto"), 2, args, step_i, (VALUE)iter);
472  }
473  else {
474  VALUE args[2];
475 
476  if (!discrete_object_p(b)) {
477  rb_raise(rb_eTypeError, "can't iterate from %s",
478  rb_obj_classname(b));
479  }
480  args[0] = INT2FIX(1);
481  args[1] = step;
482  range_each_func(range, step_i, (VALUE)args);
483  }
484  }
485  return range;
486 }
487 
488 #if SIZEOF_DOUBLE == 8 && defined(HAVE_INT64_T)
489 union int64_double {
490  int64_t i;
491  double d;
492 };
493 
494 static VALUE
495 int64_as_double_to_num(int64_t i)
496 {
497  union int64_double convert;
498  if (i < 0) {
499  convert.i = -i;
500  return DBL2NUM(-convert.d);
501  }
502  else {
503  convert.i = i;
504  return DBL2NUM(convert.d);
505  }
506 }
507 
508 static int64_t
509 double_as_int64(double d)
510 {
511  union int64_double convert;
512  convert.d = fabs(d);
513  return d < 0 ? -convert.i : convert.i;
514 }
515 #endif
516 
517 static int
519 {
520  VALUE is_int = rb_check_funcall(v, id_integer_p, 0, 0);
521  return RTEST(is_int) && is_int != Qundef;
522 }
523 
524 /*
525  * call-seq:
526  * rng.bsearch {|obj| block } -> value
527  *
528  * By using binary search, finds a value in range which meets the given
529  * condition in O(log n) where n is the size of the range.
530  *
531  * You can use this method in two use cases: a find-minimum mode and
532  * a find-any mode. In either case, the elements of the range must be
533  * monotone (or sorted) with respect to the block.
534  *
535  * In find-minimum mode (this is a good choice for typical use case),
536  * the block must return true or false, and there must be a value x
537  * so that:
538  *
539  * - the block returns false for any value which is less than x, and
540  * - the block returns true for any value which is greater than or
541  * equal to x.
542  *
543  * If x is within the range, this method returns the value x.
544  * Otherwise, it returns nil.
545  *
546  * ary = [0, 4, 7, 10, 12]
547  * (0...ary.size).bsearch {|i| ary[i] >= 4 } #=> 1
548  * (0...ary.size).bsearch {|i| ary[i] >= 6 } #=> 2
549  * (0...ary.size).bsearch {|i| ary[i] >= 8 } #=> 3
550  * (0...ary.size).bsearch {|i| ary[i] >= 100 } #=> nil
551  *
552  * (0.0...Float::INFINITY).bsearch {|x| Math.log(x) >= 0 } #=> 1.0
553  *
554  * In find-any mode (this behaves like libc's bsearch(3)), the block
555  * must return a number, and there must be two values x and y (x <= y)
556  * so that:
557  *
558  * - the block returns a positive number for v if v < x,
559  * - the block returns zero for v if x <= v < y, and
560  * - the block returns a negative number for v if y <= v.
561  *
562  * This method returns any value which is within the intersection of
563  * the given range and x...y (if any). If there is no value that
564  * satisfies the condition, it returns nil.
565  *
566  * ary = [0, 100, 100, 100, 200]
567  * (0..4).bsearch {|i| 100 - ary[i] } #=> 1, 2 or 3
568  * (0..4).bsearch {|i| 300 - ary[i] } #=> nil
569  * (0..4).bsearch {|i| 50 - ary[i] } #=> nil
570  *
571  * You must not mix the two modes at a time; the block must always
572  * return either true/false, or always return a number. It is
573  * undefined which value is actually picked up at each iteration.
574  */
575 
576 static VALUE
578 {
579  VALUE beg, end, satisfied = Qnil;
580  int smaller;
581 
582  /* Implementation notes:
583  * Floats are handled by mapping them to 64 bits integers.
584  * Apart from sign issues, floats and their 64 bits integer have the
585  * same order, assuming they are represented as exponent followed
586  * by the mantissa. This is true with or without implicit bit.
587  *
588  * Finding the average of two ints needs to be careful about
589  * potential overflow (since float to long can use 64 bits)
590  * as well as the fact that -1/2 can be 0 or -1 in C89.
591  *
592  * Note that -0.0 is mapped to the same int as 0.0 as we don't want
593  * (-1...0.0).bsearch to yield -0.0.
594  */
595 
596 #define BSEARCH_CHECK(expr) \
597  do { \
598  VALUE val = (expr); \
599  VALUE v = rb_yield(val); \
600  if (FIXNUM_P(v)) { \
601  if (v == INT2FIX(0)) return val; \
602  smaller = (SIGNED_VALUE)v < 0; \
603  } \
604  else if (v == Qtrue) { \
605  satisfied = val; \
606  smaller = 1; \
607  } \
608  else if (v == Qfalse || v == Qnil) { \
609  smaller = 0; \
610  } \
611  else if (rb_obj_is_kind_of(v, rb_cNumeric)) { \
612  int cmp = rb_cmpint(rb_funcall(v, id_cmp, 1, INT2FIX(0)), v, INT2FIX(0)); \
613  if (!cmp) return val; \
614  smaller = cmp < 0; \
615  } \
616  else { \
617  rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE \
618  " (must be numeric, true, false or nil)", \
619  rb_obj_class(v)); \
620  } \
621  } while (0)
622 
623 #define BSEARCH(conv) \
624  do { \
625  RETURN_ENUMERATOR(range, 0, 0); \
626  if (EXCL(range)) high--; \
627  org_high = high; \
628  while (low < high) { \
629  mid = ((high < 0) == (low < 0)) ? low + ((high - low) / 2) \
630  : (low < -high) ? -((-1 - low - high)/2 + 1) : (low + high) / 2; \
631  BSEARCH_CHECK(conv(mid)); \
632  if (smaller) { \
633  high = mid; \
634  } \
635  else { \
636  low = mid + 1; \
637  } \
638  } \
639  if (low == org_high) { \
640  BSEARCH_CHECK(conv(low)); \
641  if (!smaller) return Qnil; \
642  } \
643  return satisfied; \
644  } while (0)
645 
646 
647  beg = RANGE_BEG(range);
648  end = RANGE_END(range);
649 
650  if (FIXNUM_P(beg) && FIXNUM_P(end)) {
651  long low = FIX2LONG(beg);
652  long high = FIX2LONG(end);
653  long mid, org_high;
654  BSEARCH(INT2FIX);
655  }
656 #if SIZEOF_DOUBLE == 8 && defined(HAVE_INT64_T)
657  else if (RB_TYPE_P(beg, T_FLOAT) || RB_TYPE_P(end, T_FLOAT)) {
658  int64_t low = double_as_int64(RFLOAT_VALUE(rb_Float(beg)));
659  int64_t high = double_as_int64(RFLOAT_VALUE(rb_Float(end)));
660  int64_t mid, org_high;
661  BSEARCH(int64_as_double_to_num);
662  }
663 #endif
664  else if (is_integer_p(beg) && is_integer_p(end)) {
665  VALUE low = rb_to_int(beg);
666  VALUE high = rb_to_int(end);
667  VALUE mid, org_high;
668  RETURN_ENUMERATOR(range, 0, 0);
669  if (EXCL(range)) high = rb_funcall(high, '-', 1, INT2FIX(1));
670  org_high = high;
671 
672  while (rb_cmpint(rb_funcall(low, id_cmp, 1, high), low, high) < 0) {
673  mid = rb_funcall(rb_funcall(high, '+', 1, low), id_div, 1, INT2FIX(2));
674  BSEARCH_CHECK(mid);
675  if (smaller) {
676  high = mid;
677  }
678  else {
679  low = rb_funcall(mid, '+', 1, INT2FIX(1));
680  }
681  }
682  if (rb_equal(low, org_high)) {
683  BSEARCH_CHECK(low);
684  if (!smaller) return Qnil;
685  }
686  return satisfied;
687  }
688  else {
689  rb_raise(rb_eTypeError, "can't do binary search for %s", rb_obj_classname(beg));
690  }
691  return range;
692 }
693 
694 static VALUE
696 {
697  rb_yield(v);
698  return Qnil;
699 }
700 
701 static VALUE
703 {
705  return Qnil;
706 }
707 
708 /*
709  * call-seq:
710  * rng.size -> num
711  *
712  * Returns the number of elements in the range. Both the begin and the end of
713  * the Range must be Numeric, otherwise nil is returned.
714  *
715  * (10..20).size #=> 11
716  * ('a'..'z').size #=> nil
717  * (-Float::INFINITY..Float::INFINITY).size #=> Infinity
718  */
719 
720 static VALUE
722 {
723  VALUE b = RANGE_BEG(range), e = RANGE_END(range);
725  return ruby_num_interval_step_size(b, e, INT2FIX(1), EXCL(range));
726  }
727  return Qnil;
728 }
729 
730 static VALUE
732 {
733  return range_size(range);
734 }
735 
736 /*
737  * call-seq:
738  * rng.each {| i | block } -> rng
739  * rng.each -> an_enumerator
740  *
741  * Iterates over the elements of range, passing each in turn to the
742  * block.
743  *
744  * The +each+ method can only be used if the begin object of the range
745  * supports the +succ+ method. A TypeError is raised if the object
746  * does not have +succ+ method defined (like Float).
747  *
748  * If no block is given, an enumerator is returned instead.
749  *
750  * (10..15).each {|n| print n, ' ' }
751  * # prints: 10 11 12 13 14 15
752  *
753  * (2.5..5).each {|n| print n, ' ' }
754  * # raises: TypeError: can't iterate from Float
755  */
756 
757 static VALUE
759 {
760  VALUE beg, end;
761 
763 
764  beg = RANGE_BEG(range);
765  end = RANGE_END(range);
766 
767  if (FIXNUM_P(beg) && FIXNUM_P(end)) { /* fixnums are special */
768  long lim = FIX2LONG(end);
769  long i;
770 
771  if (!EXCL(range))
772  lim += 1;
773  for (i = FIX2LONG(beg); i < lim; i++) {
774  rb_yield(LONG2FIX(i));
775  }
776  }
777  else if (SYMBOL_P(beg) && SYMBOL_P(end)) { /* symbols are special */
778  VALUE args[2];
779 
780  args[0] = rb_sym2str(end);
781  args[1] = EXCL(range) ? Qtrue : Qfalse;
782  rb_block_call(rb_sym2str(beg), rb_intern("upto"), 2, args, sym_each_i, 0);
783  }
784  else {
785  VALUE tmp = rb_check_string_type(beg);
786 
787  if (!NIL_P(tmp)) {
788  VALUE args[2];
789 
790  args[0] = end;
791  args[1] = EXCL(range) ? Qtrue : Qfalse;
792  rb_block_call(tmp, rb_intern("upto"), 2, args, each_i, 0);
793  }
794  else {
795  if (!discrete_object_p(beg)) {
796  rb_raise(rb_eTypeError, "can't iterate from %s",
797  rb_obj_classname(beg));
798  }
799  range_each_func(range, each_i, 0);
800  }
801  }
802  return range;
803 }
804 
805 /*
806  * call-seq:
807  * rng.begin -> obj
808  *
809  * Returns the object that defines the beginning of the range.
810  *
811  * (1..10).begin #=> 1
812  */
813 
814 static VALUE
816 {
817  return RANGE_BEG(range);
818 }
819 
820 
821 /*
822  * call-seq:
823  * rng.end -> obj
824  *
825  * Returns the object that defines the end of the range.
826  *
827  * (1..10).end #=> 10
828  * (1...10).end #=> 10
829  */
830 
831 
832 static VALUE
834 {
835  return RANGE_END(range);
836 }
837 
838 
839 static VALUE
841 {
842  VALUE *ary = (VALUE *)cbarg;
843  long n = NUM2LONG(ary[0]);
844 
845  if (n <= 0) {
846  rb_iter_break();
847  }
848  rb_ary_push(ary[1], i);
849  n--;
850  ary[0] = INT2NUM(n);
851  return Qnil;
852 }
853 
854 /*
855  * call-seq:
856  * rng.first -> obj
857  * rng.first(n) -> an_array
858  *
859  * Returns the first object in the range, or an array of the first +n+
860  * elements.
861  *
862  * (10..20).first #=> 10
863  * (10..20).first(3) #=> [10, 11, 12]
864  */
865 
866 static VALUE
868 {
869  VALUE n, ary[2];
870 
871  if (argc == 0) return RANGE_BEG(range);
872 
873  rb_scan_args(argc, argv, "1", &n);
874  ary[0] = n;
875  ary[1] = rb_ary_new2(NUM2LONG(n));
876  rb_block_call(range, idEach, 0, 0, first_i, (VALUE)ary);
877 
878  return ary[1];
879 }
880 
881 
882 /*
883  * call-seq:
884  * rng.last -> obj
885  * rng.last(n) -> an_array
886  *
887  * Returns the last object in the range,
888  * or an array of the last +n+ elements.
889  *
890  * Note that with no arguments +last+ will return the object that defines
891  * the end of the range even if #exclude_end? is +true+.
892  *
893  * (10..20).last #=> 20
894  * (10...20).last #=> 20
895  * (10..20).last(3) #=> [18, 19, 20]
896  * (10...20).last(3) #=> [17, 18, 19]
897  */
898 
899 static VALUE
901 {
902  if (argc == 0) return RANGE_END(range);
903  return rb_ary_last(argc, argv, rb_Array(range));
904 }
905 
906 
907 /*
908  * call-seq:
909  * rng.min -> obj
910  * rng.min {| a,b | block } -> obj
911  * rng.min(n) -> array
912  * rng.min(n) {| a,b | block } -> array
913  *
914  * Returns the minimum value in the range. Returns +nil+ if the begin
915  * value of the range is larger than the end value. Returns +nil+ if
916  * the begin value of an exclusive range is equal to the end value.
917  *
918  * Can be given an optional block to override the default comparison
919  * method <code>a <=> b</code>.
920  *
921  * (10..20).min #=> 10
922  */
923 
924 
925 static VALUE
927 {
928  if (rb_block_given_p()) {
929  return rb_call_super(argc, argv);
930  }
931  else if (argc != 0) {
932  return range_first(argc, argv, range);
933  }
934  else {
935  VALUE b = RANGE_BEG(range);
936  VALUE e = RANGE_END(range);
937  int c = rb_cmpint(rb_funcall(b, id_cmp, 1, e), b, e);
938 
939  if (c > 0 || (c == 0 && EXCL(range)))
940  return Qnil;
941  return b;
942  }
943 }
944 
945 /*
946  * call-seq:
947  * rng.max -> obj
948  * rng.max {| a,b | block } -> obj
949  * rng.max(n) -> obj
950  * rng.max(n) {| a,b | block } -> obj
951  *
952  * Returns the maximum value in the range. Returns +nil+ if the begin
953  * value of the range larger than the end value. Returns +nil+ if
954  * the begin value of an exclusive range is equal to the end value.
955  *
956  * Can be given an optional block to override the default comparison
957  * method <code>a <=> b</code>.
958  *
959  * (10..20).max #=> 20
960  */
961 
962 static VALUE
964 {
965  VALUE e = RANGE_END(range);
966  int nm = FIXNUM_P(e) || rb_obj_is_kind_of(e, rb_cNumeric);
967 
968  if (rb_block_given_p() || (EXCL(range) && !nm) || argc) {
969  return rb_call_super(argc, argv);
970  }
971  else {
972  VALUE b = RANGE_BEG(range);
973  int c = rb_cmpint(rb_funcall(b, id_cmp, 1, e), b, e);
974 
975  if (c > 0)
976  return Qnil;
977  if (EXCL(range)) {
978  if (!FIXNUM_P(e) && !rb_obj_is_kind_of(e, rb_cInteger)) {
979  rb_raise(rb_eTypeError, "cannot exclude non Integer end value");
980  }
981  if (c == 0) return Qnil;
982  if (!FIXNUM_P(b) && !rb_obj_is_kind_of(b,rb_cInteger)) {
983  rb_raise(rb_eTypeError, "cannot exclude end value with non Integer begin value");
984  }
985  if (FIXNUM_P(e)) {
986  return LONG2NUM(FIX2LONG(e) - 1);
987  }
988  return rb_funcall(e, '-', 1, INT2FIX(1));
989  }
990  return e;
991  }
992 }
993 
994 int
995 rb_range_values(VALUE range, VALUE *begp, VALUE *endp, int *exclp)
996 {
997  VALUE b, e;
998  int excl;
999 
1000  if (rb_obj_is_kind_of(range, rb_cRange)) {
1001  b = RANGE_BEG(range);
1002  e = RANGE_END(range);
1003  excl = EXCL(range);
1004  }
1005  else {
1006  if (!rb_respond_to(range, id_beg)) return (int)Qfalse;
1007  if (!rb_respond_to(range, id_end)) return (int)Qfalse;
1008  b = rb_funcall(range, id_beg, 0);
1009  e = rb_funcall(range, id_end, 0);
1010  excl = RTEST(rb_funcall(range, rb_intern("exclude_end?"), 0));
1011  }
1012  *begp = b;
1013  *endp = e;
1014  *exclp = excl;
1015  return (int)Qtrue;
1016 }
1017 
1018 VALUE
1019 rb_range_beg_len(VALUE range, long *begp, long *lenp, long len, int err)
1020 {
1021  long beg, end, origbeg, origend;
1022  VALUE b, e;
1023  int excl;
1024 
1025  if (!rb_range_values(range, &b, &e, &excl))
1026  return Qfalse;
1027  beg = NUM2LONG(b);
1028  end = NUM2LONG(e);
1029  origbeg = beg;
1030  origend = end;
1031  if (beg < 0) {
1032  beg += len;
1033  if (beg < 0)
1034  goto out_of_range;
1035  }
1036  if (end < 0)
1037  end += len;
1038  if (!excl)
1039  end++; /* include end point */
1040  if (err == 0 || err == 2) {
1041  if (beg > len)
1042  goto out_of_range;
1043  if (end > len)
1044  end = len;
1045  }
1046  len = end - beg;
1047  if (len < 0)
1048  len = 0;
1049 
1050  *begp = beg;
1051  *lenp = len;
1052  return Qtrue;
1053 
1054  out_of_range:
1055  if (err) {
1056  rb_raise(rb_eRangeError, "%ld..%s%ld out of range",
1057  origbeg, excl ? "." : "", origend);
1058  }
1059  return Qnil;
1060 }
1061 
1062 /*
1063  * call-seq:
1064  * rng.to_s -> string
1065  *
1066  * Convert this range object to a printable form (using #to_s to convert the
1067  * begin and end objects).
1068  */
1069 
1070 static VALUE
1072 {
1073  VALUE str, str2;
1074 
1075  str = rb_obj_as_string(RANGE_BEG(range));
1076  str2 = rb_obj_as_string(RANGE_END(range));
1077  str = rb_str_dup(str);
1078  rb_str_cat(str, "...", EXCL(range) ? 3 : 2);
1079  rb_str_append(str, str2);
1080  OBJ_INFECT(str, range);
1081 
1082  return str;
1083 }
1084 
1085 static VALUE
1087 {
1088  VALUE str, str2;
1089 
1090  if (recur) {
1091  return rb_str_new2(EXCL(range) ? "(... ... ...)" : "(... .. ...)");
1092  }
1093  str = rb_inspect(RANGE_BEG(range));
1094  str2 = rb_inspect(RANGE_END(range));
1095  str = rb_str_dup(str);
1096  rb_str_cat(str, "...", EXCL(range) ? 3 : 2);
1097  rb_str_append(str, str2);
1098  OBJ_INFECT(str, range);
1099 
1100  return str;
1101 }
1102 
1103 /*
1104  * call-seq:
1105  * rng.inspect -> string
1106  *
1107  * Convert this range object to a printable form (using
1108  * <code>inspect</code> to convert the begin and end
1109  * objects).
1110  */
1111 
1112 
1113 static VALUE
1115 {
1116  return rb_exec_recursive(inspect_range, range, 0);
1117 }
1118 
1119 /*
1120  * call-seq:
1121  * rng === obj -> true or false
1122  *
1123  * Returns <code>true</code> if +obj+ is an element of the range,
1124  * <code>false</code> otherwise. Conveniently, <code>===</code> is the
1125  * comparison operator used by <code>case</code> statements.
1126  *
1127  * case 79
1128  * when 1..50 then print "low\n"
1129  * when 51..75 then print "medium\n"
1130  * when 76..100 then print "high\n"
1131  * end
1132  *
1133  * <em>produces:</em>
1134  *
1135  * high
1136  */
1137 
1138 static VALUE
1140 {
1141  return rb_funcall(range, rb_intern("include?"), 1, val);
1142 }
1143 
1144 
1145 /*
1146  * call-seq:
1147  * rng.member?(obj) -> true or false
1148  * rng.include?(obj) -> true or false
1149  *
1150  * Returns <code>true</code> if +obj+ is an element of
1151  * the range, <code>false</code> otherwise. If begin and end are
1152  * numeric, comparison is done according to the magnitude of the values.
1153  *
1154  * ("a".."z").include?("g") #=> true
1155  * ("a".."z").include?("A") #=> false
1156  * ("a".."z").include?("cc") #=> false
1157  */
1158 
1159 static VALUE
1161 {
1162  VALUE beg = RANGE_BEG(range);
1163  VALUE end = RANGE_END(range);
1164  int nv = FIXNUM_P(beg) || FIXNUM_P(end) ||
1165  linear_object_p(beg) || linear_object_p(end);
1166 
1167  if (nv ||
1168  !NIL_P(rb_check_to_integer(beg, "to_int")) ||
1169  !NIL_P(rb_check_to_integer(end, "to_int"))) {
1170  return r_cover_p(range, beg, end, val);
1171  }
1172  else if (RB_TYPE_P(beg, T_STRING) && RB_TYPE_P(end, T_STRING)) {
1173  VALUE rb_str_include_range_p(VALUE beg, VALUE end, VALUE val, VALUE exclusive);
1174  return rb_str_include_range_p(beg, end, val, RANGE_EXCL(range));
1175  }
1176  /* TODO: ruby_frame->this_func = rb_intern("include?"); */
1177  return rb_call_super(1, &val);
1178 }
1179 
1180 
1181 /*
1182  * call-seq:
1183  * rng.cover?(obj) -> true or false
1184  *
1185  * Returns <code>true</code> if +obj+ is between the begin and end of
1186  * the range.
1187  *
1188  * This tests <code>begin <= obj <= end</code> when #exclude_end? is +false+
1189  * and <code>begin <= obj < end</code> when #exclude_end? is +true+.
1190  *
1191  * ("a".."z").cover?("c") #=> true
1192  * ("a".."z").cover?("5") #=> false
1193  * ("a".."z").cover?("cc") #=> true
1194  */
1195 
1196 static VALUE
1198 {
1199  VALUE beg, end;
1200 
1201  beg = RANGE_BEG(range);
1202  end = RANGE_END(range);
1203  return r_cover_p(range, beg, end, val);
1204 }
1205 
1206 static VALUE
1208 {
1209  if (r_less(beg, val) <= 0) {
1210  int excl = EXCL(range);
1211  if (r_less(val, end) <= -excl)
1212  return Qtrue;
1213  }
1214  return Qfalse;
1215 }
1216 
1217 static VALUE
1219 {
1220  VALUE v;
1222 
1223  v = (VALUE)m;
1224 
1225  rb_ivar_set(v, id_excl, RANGE_EXCL(range));
1226  rb_ivar_set(v, id_beg, RANGE_BEG(range));
1227  rb_ivar_set(v, id_end, RANGE_END(range));
1228  return v;
1229 }
1230 
1231 static VALUE
1233 {
1234  VALUE beg, end, excl;
1235 
1236  if (!RB_TYPE_P(obj, T_OBJECT) || RBASIC(obj)->klass != rb_cObject) {
1237  rb_raise(rb_eTypeError, "not a dumped range object");
1238  }
1239 
1240  range_modify(range);
1241  beg = rb_ivar_get(obj, id_beg);
1242  end = rb_ivar_get(obj, id_end);
1243  excl = rb_ivar_get(obj, id_excl);
1244  if (!NIL_P(excl)) {
1245  range_init(range, beg, end, RBOOL(RTEST(excl)));
1246  }
1247  return range;
1248 }
1249 
1250 static VALUE
1252 {
1253  /* rb_struct_alloc_noinit itself should not be used because
1254  * rb_marshal_define_compat uses equality of allocation function */
1255  return rb_struct_alloc_noinit(klass);
1256 }
1257 
1258 /* A <code>Range</code> represents an interval---a set of values with a
1259  * beginning and an end. Ranges may be constructed using the
1260  * <em>s</em><code>..</code><em>e</em> and
1261  * <em>s</em><code>...</code><em>e</em> literals, or with
1262  * Range::new. Ranges constructed using <code>..</code>
1263  * run from the beginning to the end inclusively. Those created using
1264  * <code>...</code> exclude the end value. When used as an iterator,
1265  * ranges return each value in the sequence.
1266  *
1267  * (-1..-5).to_a #=> []
1268  * (-5..-1).to_a #=> [-5, -4, -3, -2, -1]
1269  * ('a'..'e').to_a #=> ["a", "b", "c", "d", "e"]
1270  * ('a'...'e').to_a #=> ["a", "b", "c", "d"]
1271  *
1272  * == Custom Objects in Ranges
1273  *
1274  * Ranges can be constructed using any objects that can be compared
1275  * using the <code><=></code> operator.
1276  * Methods that treat the range as a sequence (#each and methods inherited
1277  * from Enumerable) expect the begin object to implement a
1278  * <code>succ</code> method to return the next object in sequence.
1279  * The #step and #include? methods require the begin
1280  * object to implement <code>succ</code> or to be numeric.
1281  *
1282  * In the <code>Xs</code> class below both <code><=></code> and
1283  * <code>succ</code> are implemented so <code>Xs</code> can be used
1284  * to construct ranges. Note that the Comparable module is included
1285  * so the <code>==</code> method is defined in terms of <code><=></code>.
1286  *
1287  * class Xs # represent a string of 'x's
1288  * include Comparable
1289  * attr :length
1290  * def initialize(n)
1291  * @length = n
1292  * end
1293  * def succ
1294  * Xs.new(@length + 1)
1295  * end
1296  * def <=>(other)
1297  * @length <=> other.length
1298  * end
1299  * def to_s
1300  * sprintf "%2d #{inspect}", @length
1301  * end
1302  * def inspect
1303  * 'x' * @length
1304  * end
1305  * end
1306  *
1307  * An example of using <code>Xs</code> to construct a range:
1308  *
1309  * r = Xs.new(3)..Xs.new(6) #=> xxx..xxxxxx
1310  * r.to_a #=> [xxx, xxxx, xxxxx, xxxxxx]
1311  * r.member?(Xs.new(5)) #=> true
1312  *
1313  */
1314 
1315 void
1317 {
1318 #undef rb_intern
1319 #define rb_intern(str) rb_intern_const(str)
1320 
1321  id_beg = rb_intern("begin");
1322  id_end = rb_intern("end");
1323  id_excl = rb_intern("excl");
1324  id_integer_p = rb_intern("integer?");
1325  id_div = rb_intern("div");
1326 
1328  "Range", rb_cObject, range_alloc,
1329  "begin", "end", "excl", NULL);
1330 
1333  rb_define_method(rb_cRange, "initialize", range_initialize, -1);
1334  rb_define_method(rb_cRange, "initialize_copy", range_initialize_copy, 1);
1335  rb_define_method(rb_cRange, "==", range_eq, 1);
1336  rb_define_method(rb_cRange, "===", range_eqq, 1);
1337  rb_define_method(rb_cRange, "eql?", range_eql, 1);
1338  rb_define_method(rb_cRange, "hash", range_hash, 0);
1339  rb_define_method(rb_cRange, "each", range_each, 0);
1340  rb_define_method(rb_cRange, "step", range_step, -1);
1341  rb_define_method(rb_cRange, "bsearch", range_bsearch, 0);
1342  rb_define_method(rb_cRange, "begin", range_begin, 0);
1343  rb_define_method(rb_cRange, "end", range_end, 0);
1344  rb_define_method(rb_cRange, "first", range_first, -1);
1345  rb_define_method(rb_cRange, "last", range_last, -1);
1346  rb_define_method(rb_cRange, "min", range_min, -1);
1347  rb_define_method(rb_cRange, "max", range_max, -1);
1348  rb_define_method(rb_cRange, "size", range_size, 0);
1349  rb_define_method(rb_cRange, "to_s", range_to_s, 0);
1350  rb_define_method(rb_cRange, "inspect", range_inspect, 0);
1351 
1352  rb_define_method(rb_cRange, "exclude_end?", range_exclude_end_p, 0);
1353 
1354  rb_define_method(rb_cRange, "member?", range_include, 1);
1355  rb_define_method(rb_cRange, "include?", range_include, 1);
1356  rb_define_method(rb_cRange, "cover?", range_cover, 1);
1357 }
VALUE rb_hash(VALUE obj)
Definition: hash.c:126
#define T_OBJECT
Definition: ruby.h:491
static int is_integer_p(VALUE v)
Definition: range.c:518
static int cmp(VALUE x, VALUE y)
Definition: time.c:57
#define RANGE_BEG(r)
Definition: range.c:27
VALUE rb_ary_last(int argc, const VALUE *argv, VALUE ary)
Definition: array.c:1361
static double zero(void)
Definition: isinf.c:51
static VALUE check_step_domain(VALUE step)
Definition: range.c:338
#define FALSE
Definition: nkf.h:174
#define INT2NUM(x)
Definition: ruby.h:1538
void Init_Range(void)
Definition: range.c:1316
int rb_range_values(VALUE range, VALUE *begp, VALUE *endp, int *exclp)
Definition: range.c:995
static unsigned int hash(str, len) register const char *str
#define FIXNUM_FLAG
Definition: ruby.h:441
static VALUE range_dumper(VALUE range)
Definition: range.c:1218
VALUE rb_str_cat(VALUE, const char *, long)
Definition: string.c:2664
static VALUE range_include(VALUE range, VALUE val)
Definition: range.c:1160
#define Qtrue
Definition: ruby.h:437
static VALUE each_i(RB_BLOCK_CALL_FUNC_ARGLIST(v, arg))
Definition: range.c:695
#define RBOOL(v)
Definition: range.c:33
st_index_t rb_hash_end(st_index_t)
static int linear_object_p(VALUE obj)
Definition: range.c:323
Definition: id.h:85
static VALUE range_bsearch(VALUE range)
Definition: range.c:577
VALUE rb_struct_init_copy(VALUE copy, VALUE s)
Definition: struct.c:809
static int r_less(VALUE a, VALUE b)
Definition: range.c:181
static VALUE range_loader(VALUE range, VALUE obj)
Definition: range.c:1232
static void range_modify(VALUE range)
Definition: range.c:81
static VALUE sym_each_i(RB_BLOCK_CALL_FUNC_ARGLIST(v, arg))
Definition: range.c:702
VALUE rb_eTypeError
Definition: error.c:762
VALUE rb_struct_alloc_noinit(VALUE)
Definition: struct.c:328
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:905
SSL_METHOD *(* func)(void)
Definition: ossl_ssl.c:54
static ID id_excl
Definition: range.c:21
static VALUE step_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, arg))
Definition: range.c:298
static VALUE inspect_range(VALUE range, VALUE dummy, int recur)
Definition: range.c:1086
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:821
VALUE rb_to_int(VALUE)
Definition: object.c:2687
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2207
VALUE rb_ivar_get(VALUE, ID)
Definition: variable.c:1260
#define EXCL(r)
Definition: range.c:35
VALUE rb_exec_recursive(VALUE(*)(VALUE, VALUE, int), VALUE, VALUE)
Definition: thread.c:4697
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Definition: object.c:690
void rb_include_module(VALUE klass, VALUE module)
Definition: class.c:864
VALUE rb_block_call(VALUE, ID, int, const VALUE *, rb_block_call_func_t, VALUE)
#define BSEARCH_CHECK(expr)
st_data_t st_index_t
Definition: st.h:50
#define RGENGC_WB_PROTECTED_OBJECT
Definition: ruby.h:783
static VALUE range_to_s(VALUE range)
Definition: range.c:1071
#define FIXNUM_P(f)
Definition: ruby.h:365
VALUE rb_Float(VALUE)
Definition: object.c:2961
VALUE rb_range_new(VALUE beg, VALUE end, int exclude_end)
Definition: range.c:72
VALUE rb_check_to_integer(VALUE, const char *)
Definition: object.c:2673
int rb_cmpint(VALUE val, VALUE a, VALUE b)
Definition: bignum.c:2909
#define rb_name_err_raise(mesg, recv, name)
Definition: internal.h:1024
VALUE rb_eRangeError
Definition: error.c:766
const char * rb_obj_classname(VALUE)
Definition: variable.c:458
#define rb_ary_new2
Definition: intern.h:90
static void range_each_func(VALUE range, rb_block_call_func *func, VALUE arg)
Definition: range.c:257
#define NEWOBJ_OF(obj, type, klass, flags)
Definition: ruby.h:754
#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg)
Definition: ruby.h:1830
static VALUE recursive_eql(VALUE range, VALUE obj, int recur)
Definition: range.c:191
#define RB_TYPE_P(obj, type)
Definition: ruby.h:527
static VALUE range_eql(VALUE range, VALUE obj)
Definition: range.c:219
static VALUE range_size(VALUE range)
Definition: range.c:721
VALUE rb_block_call_func(RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg))
Definition: ruby.h:1832
void rb_iter_break(void)
Definition: vm.c:1468
VALUE rb_rescue(VALUE(*b_proc)(ANYARGS), VALUE data1, VALUE(*r_proc)(ANYARGS), VALUE data2)
Definition: eval.c:883
static VALUE range_step(int argc, VALUE *argv, VALUE range)
Definition: range.c:405
VALUE rb_Array(VALUE)
Definition: object.c:3126
static VALUE range_initialize_copy(VALUE range, VALUE orig)
Definition: range.c:112
int rb_block_given_p(void)
Definition: eval.c:797
#define val
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:1872
VALUE rb_exec_recursive_paired(VALUE(*)(VALUE, VALUE, int), VALUE, VALUE, VALUE)
Definition: thread.c:4708
#define BSEARCH(conv)
static ID id_div
Definition: range.c:21
static VALUE range_enum_size(VALUE range, VALUE args, VALUE eobj)
Definition: range.c:731
VALUE rb_obj_as_string(VALUE)
Definition: string.c:1364
VALUE ruby_num_interval_step_size(VALUE from, VALUE to, VALUE step, int excl)
Definition: numeric.c:2525
#define NIL_P(v)
Definition: ruby.h:451
static VALUE range_initialize(int argc, VALUE *argv, VALUE range)
Definition: range.c:100
static VALUE first_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, cbarg))
Definition: range.c:840
#define FLONUM_P(x)
Definition: ruby.h:399
#define T_FLOAT
Definition: ruby.h:495
int argc
Definition: ruby.c:183
#define Qfalse
Definition: ruby.h:436
static VALUE range_step_size(VALUE range, VALUE args, VALUE eobj)
Definition: range.c:356
#define T_BIGNUM
Definition: ruby.h:501
#define range(low, item, hi)
Definition: date_strftime.c:21
#define rb_str_new2
Definition: intern.h:857
VALUE rb_obj_alloc(VALUE)
Definition: object.c:1845
int err
Definition: win32.c:135
static VALUE range_first(int argc, VALUE *argv, VALUE range)
Definition: range.c:867
int ruby_float_step(VALUE from, VALUE to, VALUE step, int excl)
Definition: numeric.c:2494
static ID id_end
Definition: range.c:21
Definition: id.h:76
#define id_succ
Definition: range.c:23
#define rb_intern(str)
VALUE rb_yield(VALUE)
Definition: vm_eval.c:1020
#define TRUE
Definition: nkf.h:175
static VALUE range_check(VALUE *args)
Definition: range.c:45
static VALUE range_hash(VALUE range)
Definition: range.c:240
VALUE rb_mEnumerable
Definition: enum.c:18
int rb_eql(VALUE, VALUE)
Definition: object.c:97
static void range_init(VALUE range, VALUE beg, VALUE end, VALUE exclude_end)
Definition: range.c:51
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1919
static VALUE range_exclude_end_p(VALUE range)
Definition: range.c:130
VALUE rb_ivar_set(VALUE, ID, VALUE)
Definition: variable.c:1364
unsigned long ID
Definition: ruby.h:86
#define Qnil
Definition: ruby.h:438
static int discrete_object_p(VALUE obj)
Definition: range.c:316
#define id_cmp
Definition: range.c:22
#define RANGE_END(r)
Definition: range.c:28
#define RANGE_SET_END(r, v)
Definition: range.c:31
#define BUILTIN_TYPE(x)
Definition: ruby.h:518
unsigned long VALUE
Definition: ruby.h:85
#define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn)
Definition: intern.h:236
#define RBASIC(obj)
Definition: ruby.h:1204
RUBY_EXTERN VALUE rb_cInteger
Definition: ruby.h:1891
VALUE rb_check_funcall(VALUE, ID, int, const VALUE *)
Definition: vm_eval.c:439
VALUE rb_call_super(int, const VALUE *)
Definition: vm_eval.c:287
RUBY_EXTERN VALUE rb_cNumeric
Definition: ruby.h:1898
static VALUE r_cover_p(VALUE, VALUE, VALUE, VALUE)
Definition: range.c:1207
static VALUE sym_step_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, arg))
Definition: range.c:280
VALUE rb_str_dup(VALUE)
Definition: string.c:1436
#define RANGE_SET_EXCL(r, v)
Definition: range.c:32
#define LONG2NUM(x)
Definition: ruby.h:1573
#define rb_funcallv
Definition: console.c:21
int rb_respond_to(VALUE, ID)
Definition: vm_method.c:1995
register unsigned int len
Definition: zonetab.h:51
VALUE rb_range_beg_len(VALUE range, long *begp, long *lenp, long len, int err)
Definition: range.c:1019
static VALUE recursive_equal(VALUE range, VALUE obj, int recur)
Definition: range.c:136
#define recur(fmt)
VALUE rb_equal(VALUE, VALUE)
Definition: object.c:86
static VALUE range_end(VALUE range)
Definition: range.c:833
#define RFLOAT_VALUE(v)
Definition: ruby.h:940
static VALUE range_inspect(VALUE range)
Definition: range.c:1114
#define INT2FIX(i)
Definition: ruby.h:232
#define RARRAY_AREF(a, i)
Definition: ruby.h:1040
static VALUE range_begin(VALUE range)
Definition: range.c:815
VALUE rb_cRange
Definition: range.c:20
static VALUE range_last(int argc, VALUE *argv, VALUE range)
Definition: range.c:900
static ID id_beg
Definition: range.c:21
#define FL_WB_PROTECTED
Definition: ruby.h:1216
VALUE rb_check_string_type(VALUE)
Definition: string.c:2164
#define RANGE_EXCL(r)
Definition: range.c:29
#define LONG2FIX(i)
Definition: ruby.h:234
#define RTEST(v)
Definition: ruby.h:450
void rb_marshal_define_compat(VALUE newclass, VALUE oldclass, VALUE(*dumper)(VALUE), VALUE(*loader)(VALUE, VALUE))
Definition: marshal.c:134
#define T_STRING
Definition: ruby.h:496
#define OBJ_INFECT(x, s)
Definition: ruby.h:1304
static VALUE range_max(int argc, VALUE *argv, VALUE range)
Definition: range.c:963
st_index_t rb_hash_uint(st_index_t, st_index_t)
static VALUE range_min(int argc, VALUE *argv, VALUE range)
Definition: range.c:926
static VALUE range_alloc(VALUE klass)
Definition: range.c:1251
#define RETURN_ENUMERATOR(obj, argc, argv)
Definition: intern.h:240
static VALUE range_each(VALUE range)
Definition: range.c:758
#define ID2SYM(x)
Definition: ruby.h:383
Definition: ruby.h:889
VALUE rb_struct_define_without_accessor(const char *, VALUE, rb_alloc_func_t,...)
Definition: struct.c:397
VALUE rb_inspect(VALUE)
Definition: object.c:519
VALUE rb_str_include_range_p(VALUE beg, VALUE end, VALUE val, VALUE exclusive)
Definition: string.c:4156
#define rb_check_frozen(obj)
Definition: intern.h:276
VALUE rb_str_intern(VALUE)
Definition: symbol.c:661
#define SPECIAL_CONST_P(x)
Definition: ruby.h:1249
static VALUE range_eqq(VALUE range, VALUE val)
Definition: range.c:1139
static VALUE range_eq(VALUE range, VALUE obj)
Definition: range.c:165
#define SYMBOL_P(x)
Definition: ruby.h:382
#define NULL
Definition: _sdbm.c:102
#define FIX2LONG(x)
Definition: ruby.h:363
#define Qundef
Definition: ruby.h:439
RUBY_EXTERN VALUE rb_cTime
Definition: ruby.h:1910
static VALUE range_cover(VALUE range, VALUE val)
Definition: range.c:1197
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1515
VALUE rb_str_append(VALUE, VALUE)
Definition: string.c:2818
static ID id_integer_p
Definition: range.c:21
#define RANGE_SET_BEG(r, v)
Definition: range.c:30
VALUE rb_eArgError
Definition: error.c:763
#define NUM2LONG(x)
Definition: ruby.h:648
static VALUE range_failed(void)
Definition: range.c:38
st_index_t rb_hash_start(st_index_t)
Definition: random.c:1496
char ** argv
Definition: ruby.c:184
#define DBL2NUM(dbl)
Definition: ruby.h:941
#define rb_sym2str(sym)
Definition: console.c:107