27#include "internal/error.h"
32static ID id_beg, id_end, id_excl;
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#define RBOOL(v) ((v) ? Qtrue : Qfalse)
45#define EXCL(r) RTEST(RANGE_EXCL(r))
72 range_init(
range, beg, end,
RBOOL(exclude_end));
82 rb_name_err_raise(
"`initialize' called twice",
range,
ID2SYM(idInitialize));
98 VALUE beg, end, flags;
261 while (r_less(v, e) < 0) {
262 if ((*func)(v, arg))
break;
267 while ((c = r_less(v, e)) <= 0) {
268 if ((*func)(v, arg))
break;
281 iter[0] -=
INT2FIX(1) & ~FIXNUM_FLAG;
299 iter[0] -=
INT2FIX(1) & ~FIXNUM_FLAG;
312discrete_object_p(
VALUE obj)
319linear_object_p(
VALUE obj)
336check_step_domain(
VALUE step)
411 VALUE b, e, step, tmp;
413 b = RANGE_BEG(
range);
414 e = RANGE_END(
range);
427 if ((b_num_p && (
NIL_P(e) || e_num_p)) || (
NIL_P(b) && e_num_p)) {
429 range_step_size, b, e, step,
EXCL(
range));
435 step = check_step_domain(step);
457 if (i + unit < i)
break;
511 if (!discrete_object_p(b)) {
526 return range_step(1, &step,
range);
529#if SIZEOF_DOUBLE == 8 && defined(HAVE_INT64_T)
536int64_as_double_to_num(int64_t i)
538 union int64_double convert;
550double_as_int64(
double d)
552 union int64_double convert;
554 return d < 0 ? -convert.i : convert.i;
569bsearch_integer_range(
VALUE beg,
VALUE end,
int excl)
574#define BSEARCH_CHECK(expr) \
576 VALUE val = (expr); \
577 VALUE v = rb_yield(val); \
579 if (v == INT2FIX(0)) return val; \
580 smaller = (SIGNED_VALUE)v < 0; \
582 else if (v == Qtrue) { \
586 else if (v == Qfalse || v == Qnil) { \
589 else if (rb_obj_is_kind_of(v, rb_cNumeric)) { \
590 int cmp = rb_cmpint(rb_funcall(v, id_cmp, 1, INT2FIX(0)), v, INT2FIX(0)); \
591 if (!cmp) return val; \
595 rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE \
596 " (must be numeric, true, false or nil)", \
699#define BSEARCH(conv) \
701 RETURN_ENUMERATOR(range, 0, 0); \
702 if (EXCL(range)) high--; \
704 while (low < high) { \
705 mid = ((high < 0) == (low < 0)) ? low + ((high - low) / 2) \
706 : (low < -high) ? -((-1 - low - high)/2 + 1) : (low + high) / 2; \
707 BSEARCH_CHECK(conv(mid)); \
715 if (low == org_high) { \
716 BSEARCH_CHECK(conv(low)); \
717 if (!smaller) return Qnil; \
723 beg = RANGE_BEG(
range);
724 end = RANGE_END(
range);
732#if SIZEOF_DOUBLE == 8 && defined(HAVE_INT64_T)
736 int64_t mid, org_high;
737 BSEARCH(int64_as_double_to_num);
740 else if (is_integer_p(beg) && is_integer_p(end)) {
742 return bsearch_integer_range(beg, end,
EXCL(
range));
744 else if (is_integer_p(beg) &&
NIL_P(end)) {
751 return bsearch_integer_range(beg, mid, 0);
756 else if (
NIL_P(beg) && is_integer_p(end)) {
763 return bsearch_integer_range(mid, end, 0);
842 return range_size(
range);
847range_each_bignum_endless(
VALUE beg)
857range_each_fixnum_endless(
VALUE beg)
871 for (
long i =
FIX2LONG(beg); i < lim; i++) {
906 beg = RANGE_BEG(
range);
907 end = RANGE_END(
range);
910 range_each_fixnum_endless(beg);
913 return range_each_fixnum_loop(beg, end,
range);
918 if (RBIGNUM_NEGATIVE_P(beg)) {
922 if (
NIL_P(end)) range_each_fixnum_endless(beg);
923 if (
FIXNUM_P(end))
return range_each_fixnum_loop(beg, end,
range);
926 if (
NIL_P(end)) range_each_bignum_endless(beg);
978 if (!discrete_object_p(beg)) {
983 range_each_func(
range, each_i, 0);
1004 return RANGE_BEG(
range);
1022 return RANGE_END(
range);
1082 b = RANGE_BEG(
range);
1083 e = RANGE_END(
range);
1151 b = RANGE_BEG(
range);
1152 e = RANGE_END(
range);
1192 else if (
argc != 0) {
1272 if (c == 0)
return Qnil;
1316 b = RANGE_BEG(
range);
1317 e = RANGE_END(
range);
1363 long *begp,
long *lenp,
long len,
int err)
1369 if (
NIL_P(e)) excl = 0;
1379 if (
err == 0 ||
err == 2) {
1505 VALUE ret = range_include_internal(
range, val, 1);
1506 if (ret !=
Qundef)
return ret;
1535 VALUE ret = range_include_internal(
range, val, 0);
1536 if (ret !=
Qundef)
return ret;
1546 linear_object_p(beg) || linear_object_p(end);
1551 return r_cover_p(
range, beg, end, val);
1555 if (string_use_cover) {
1556 return r_cover_p(
range, beg, end, val);
1563 else if (
NIL_P(beg)) {
1569 else if (
NIL_P(end)) {
1618 beg = RANGE_BEG(
range);
1619 end = RANGE_END(
range);
1622 return RBOOL(r_cover_range_p(
range, beg, end, val));
1624 return r_cover_p(
range, beg, end, val);
1636 VALUE val_beg, val_end, val_max;
1639 val_beg = RANGE_BEG(val);
1640 val_end = RANGE_END(val);
1644 if (!
NIL_P(val_beg) && !
NIL_P(val_end) && r_less(val_beg, val_end) > (
EXCL(val) ? -1 : 0))
return FALSE;
1645 if (!
NIL_P(val_beg) && !r_cover_p(
range, beg, end, val_beg))
return FALSE;
1647 cmp_end = r_less(end, val_end);
1650 return cmp_end >= 0;
1655 else if (cmp_end >= 0) {
1662 return r_less(end, val_max) >= 0;
1668 if (
NIL_P(beg) || r_less(beg, val) <= 0) {
1670 if (
NIL_P(end) || r_less(val, end) <= -excl)
1690 VALUE beg, end, excl;
1696 range_modify(
range);
1707range_alloc(
VALUE klass)
1846 id_beg = rb_intern_const(
"begin");
1847 id_end = rb_intern_const(
"end");
1848 id_excl = rb_intern_const(
"excl");
1852 "begin",
"end",
"excl",
NULL);
VALUE rb_ary_push(VALUE ary, VALUE item)
VALUE rb_ary_last(int argc, const VALUE *argv, VALUE ary)
VALUE rb_ary_new_capa(long capa)
VALUE rb_assoc_new(VALUE car, VALUE cdr)
VALUE rb_big_plus(VALUE x, VALUE y)
VALUE rb_big_cmp(VALUE x, VALUE y)
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
#define range(low, item, hi)
#define rb_cmpint(cmp, a, b)
VALUE rb_arith_seq_new(VALUE obj, VALUE meth, int argc, VALUE const *argv, rb_enumerator_size_func *size_fn, VALUE beg, VALUE end, VALUE step, int excl)
char str[HTML_ESCAPE_MAX_LEN+1]
void rb_include_module(VALUE klass, VALUE module)
ID rb_frame_this_func(void)
The original name of the current method.
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
int rb_block_given_p(void)
Determines if the current method is given a block.
void rb_raise(VALUE exc, const char *fmt,...)
VALUE rb_rescue2(VALUE(*b_proc)(VALUE), VALUE data1, VALUE(*r_proc)(VALUE, VALUE), VALUE data2,...)
An equivalent of rescue clause.
VALUE rb_Float(VALUE)
Equivalent to Kernel#Float in Ruby.
VALUE rb_cObject
Object class.
VALUE rb_obj_alloc(VALUE)
Allocates an instance of klass.
int rb_eql(VALUE, VALUE)
Determines if obj1 and obj2 are equal in terms of Object::eql?.
VALUE rb_Array(VALUE)
Equivalent to Kernel#Array in Ruby.
VALUE rb_inspect(VALUE)
Convenient wrapper of Object::inspect.
VALUE rb_equal(VALUE, VALUE)
This function is an optimized version of calling #==.
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Determines if obj is a kind of c.
VALUE rb_obj_freeze(VALUE)
Make the object unmodifiable.
VALUE rb_check_to_integer(VALUE, const char *)
Tries to convert val into Integer.
VALUE rb_to_int(VALUE)
Converts val into Integer.
Thin wrapper to ruby/config.h.
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
VALUE rb_call_super(int, const VALUE *)
#define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn)
#define RETURN_ENUMERATOR(obj, argc, argv)
#define rb_hash_uint(h, i)
#define rb_str_new(str, len)
VALUE rb_str_cat(VALUE, const char *, long)
st_index_t rb_hash_start(st_index_t)
VALUE rb_check_string_type(VALUE)
VALUE rb_str_append(VALUE, VALUE)
VALUE rb_str_intern(VALUE)
VALUE rb_obj_as_string(VALUE)
VALUE rb_struct_alloc_noinit(VALUE)
VALUE rb_struct_define_without_accessor(const char *, VALUE, rb_alloc_func_t,...)
VALUE rb_exec_recursive_paired(VALUE(*)(VALUE, VALUE, int), VALUE, VALUE, VALUE)
VALUE rb_exec_recursive(VALUE(*)(VALUE, VALUE, int), VALUE, VALUE)
VALUE rb_ivar_get(VALUE, ID)
VALUE rb_ivar_set(VALUE, ID, VALUE)
VALUE rb_check_funcall(VALUE, ID, int, const VALUE *)
int rb_respond_to(VALUE, ID)
ID rb_intern(const char *)
Internal header for Array.
Internal header for Comparable.
#define OPTIMIZED_CMP(a, b, data)
Internal header for Enumerable.
Internal header for Enumerator.
Internal header for Numeric.
int rb_num_negative_p(VALUE)
VALUE ruby_num_interval_step_size(VALUE from, VALUE to, VALUE step, int excl)
int ruby_float_step(VALUE from, VALUE to, VALUE step, int excl, int allow_endless)
VALUE rb_int_minus(VALUE x, VALUE y)
VALUE rb_int_plus(VALUE x, VALUE y)
VALUE rb_int_gt(VALUE x, VALUE y)
Internal header for Range.
VALUE rb_str_upto_each(VALUE, VALUE, int, int(*each)(VALUE, VALUE), VALUE)
VALUE rb_str_upto_endless_each(VALUE, int(*each)(VALUE, VALUE), VALUE)
VALUE rb_struct_init_copy(VALUE copy, VALUE s)
#define rb_method_basic_definition_p(...)
#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg)
void rb_marshal_define_compat(VALUE newclass, VALUE oldclass, VALUE(*dumper)(VALUE), VALUE(*loader)(VALUE, VALUE))
Internal header for Math.
VALUE rb_block_call(VALUE q, ID w, int e, const VALUE *r, type *t, VALUE y)
Call a method with a block.
#define RBIMPL_ATTR_NORETURN()
Wraps (or simulates) [[noreturn]]
#define RARRAY_AREF(a, i)
#define RANGE_SET_BEG(r, v)
#define RANGE_SET_EXCL(r, v)
int rb_range_values(VALUE range, VALUE *begp, VALUE *endp, int *exclp)
VALUE rb_range_new(VALUE beg, VALUE end, int exclude_end)
VALUE rb_range_beg_len(VALUE range, long *begp, long *lenp, long len, int err)
#define BSEARCH_CHECK(expr)
VALUE rb_range_component_beg_len(VALUE b, VALUE e, int excl, long *begp, long *lenp, long len, int err)
#define RANGE_SET_END(r, v)
const char * rb_obj_classname(VALUE)
#define RB_INTEGER_TYPE_P(obj)
VALUE rb_str_include_range_p(VALUE beg, VALUE end, VALUE val, VALUE exclusive)
#define smaller(tree, n, m, depth)