Ejemplo n.º 1
0
Archivo: range.c Proyecto: DashYang/sim
static VALUE
range_max(int argc, VALUE *argv, VALUE range)
{
    VALUE e = RANGE_END(range);
    int nm = FIXNUM_P(e) || rb_obj_is_kind_of(e, rb_cNumeric);

    if (rb_block_given_p() || (EXCL(range) && !nm) || argc) {
	return rb_call_super(argc, argv);
    }
    else {
	VALUE b = RANGE_BEG(range);
	int c = rb_cmpint(rb_funcall(b, id_cmp, 1, e), b, e);

	if (c > 0)
	    return Qnil;
	if (EXCL(range)) {
	    if (!FIXNUM_P(e) && !rb_obj_is_kind_of(e, rb_cInteger)) {
		rb_raise(rb_eTypeError, "cannot exclude non Integer end value");
	    }
	    if (c == 0) return Qnil;
	    if (!FIXNUM_P(b) && !rb_obj_is_kind_of(b,rb_cInteger)) {
		rb_raise(rb_eTypeError, "cannot exclude end value with non Integer begin value");
	    }
	    if (FIXNUM_P(e)) {
		return LONG2NUM(FIX2LONG(e) - 1);
	    }
	    return rb_funcall(e, '-', 1, INT2FIX(1));
	}
	return e;
    }
}
Ejemplo n.º 2
0
static VALUE
range_max(VALUE range)
{
    VALUE e = RANGE_END(range);
    int ip = FIXNUM_P(e) || rb_obj_is_kind_of(e, rb_cInteger);

    if (rb_block_given_p() || (EXCL(range) && !ip)) {
	return rb_call_super(0, 0);
    }
    else {
	VALUE b = RANGE_BEG(range);
	int c = rb_cmpint(rb_funcall(b, id_cmp, 1, e), b, e);

	if (c > 0)
	    return Qnil;
	if (EXCL(range)) {
	    if (c == 0) return Qnil;
	    if (FIXNUM_P(e)) {
		return LONG2NUM(FIX2LONG(e) - 1);
	    }
	    return rb_funcall(e, '-', 1, INT2FIX(1));
	}
	return e;
    }
}
Ejemplo n.º 3
0
static VALUE
range_max(VALUE range, SEL sel)
{
    VALUE e = RANGE_END(range);
    int nm = FIXNUM_P(e) || rb_obj_is_kind_of(e, rb_cNumeric);

    if (rb_block_given_p() || (EXCL(range) && !nm)) {
	if (sel == NULL) {
	    sel = sel_registerName("max");
	}
	return rb_vm_call_super(range, sel, 0, NULL);
    }
    else {
	VALUE b = RANGE_BEG(range);
	int c = rb_cmpint(rb_objs_cmp(b, e), b, e);

	if (c > 0)
	    return Qnil;
	if (EXCL(range)) {
	    if (!FIXNUM_P(e) && !rb_obj_is_kind_of(e, rb_cInteger)) {
		rb_raise(rb_eTypeError, "cannot exclude non Integer end value");
	    }
	    if (c == 0) {
		return Qnil;
	    }
	    if (FIXNUM_P(e)) {
		return LONG2NUM(FIX2LONG(e) - 1);
	    }
	    VALUE one = INT2FIX(1);
	    return rb_vm_call(e, selMINUS, 1, &one);
	}
	return e;
    }
}
Ejemplo n.º 4
0
static VALUE
cmp_gt(VALUE x, VALUE y)
{
    VALUE c = rb_funcall(x, cmp, 1, y);

    if (rb_cmpint(c, x, y) > 0) return Qtrue;
    return Qfalse;
}
Ejemplo n.º 5
0
static VALUE
cmp_eq(VALUE *a)
{
    VALUE c = rb_exec_recursive_paired_outer(cmp_eq_recursive, a[0], a[1], a[1]);

    if (NIL_P(c)) return Qfalse;
    if (rb_cmpint(c, a[0], a[1]) == 0) return Qtrue;
    return Qfalse;
}
Ejemplo n.º 6
0
static int
cmp_1(const void *ap, const void *bp, void *dummy)
{
    struct sort_data *d = dummy;
    VALUE a = rb_enc_str_new(ap, d->elsize, d->enc);
    VALUE b = rb_enc_str_new(bp, d->elsize, d->enc);
    VALUE retval = rb_yield_values(2, a, b);
    return rb_cmpint(retval, a, b);
}
Ejemplo n.º 7
0
static VALUE
cmp_eq(VALUE *a)
{
    VALUE c = rb_funcall(a[0], cmp, 1, a[1]);

    if (NIL_P(c)) return Qfalse;
    if (rb_cmpint(c, a[0], a[1]) == 0) return Qtrue;
    return Qfalse;
}
Ejemplo n.º 8
0
static VALUE
cmp_gt(VALUE x, SEL sel, VALUE y)
{
    VALUE c = rb_vm_call(x, cmp, 1, &y);
    if (rb_cmpint(c, x, y) > 0) {
	return Qtrue;
    }
    return Qfalse;
}
Ejemplo n.º 9
0
Archivo: range.c Proyecto: DashYang/sim
static int
r_lt(VALUE a, VALUE b)
{
    VALUE r = rb_funcall(a, id_cmp, 1, b);

    if (NIL_P(r))
	return (int)Qfalse;
    if (rb_cmpint(r, a, b) < 0)
	return (int)Qtrue;
    return (int)Qfalse;
}
Ejemplo n.º 10
0
static int
r_lt(VALUE a, VALUE b)
{
    VALUE r = rb_objs_cmp(a, b);

    if (NIL_P(r))
	return Qfalse;
    if (rb_cmpint(r, a, b) < 0)
	return Qtrue;
    return Qfalse;
}
Ejemplo n.º 11
0
VALUE
rb_invcmp(VALUE x, VALUE y)
{
    VALUE invcmp = rb_exec_recursive(invcmp_recursive, x, y);
    if (invcmp == Qundef || NIL_P(invcmp)) {
	return Qnil;
    }
    else {
	int result = -rb_cmpint(invcmp, x, y);
	return INT2FIX(result);
    }
}
Ejemplo n.º 12
0
static VALUE
cmp_eq(VALUE *a)
{
    VALUE c = rb_vm_call(a[0], cmp, 1, &a[1]);
    if (NIL_P(c)) {
	return Qfalse;
    }
    if (rb_cmpint(c, a[0], a[1]) == 0) {
	return Qtrue;
    }
    return Qfalse;
}
Ejemplo n.º 13
0
static VALUE
cmp_equal(VALUE x, VALUE y)
{
    VALUE c;
    if (x == y) return Qtrue;

    c = rb_exec_recursive_paired_outer(cmp_eq_recursive, x, y, y);

    if (NIL_P(c)) return Qfalse;
    if (rb_cmpint(c, x, y) == 0) return Qtrue;
    return Qfalse;
}
Ejemplo n.º 14
0
static int
r_le(VALUE a, VALUE b)
{
    int c;
    VALUE r = rb_objs_cmp(a, b);

    if (NIL_P(r))
	return Qfalse;
    c = rb_cmpint(r, a, b);
    if (c == 0)
	return INT2FIX(0);
    if (c < 0)
	return Qtrue;
    return Qfalse;
}
Ejemplo n.º 15
0
Archivo: range.c Proyecto: DashYang/sim
static int
r_le(VALUE a, VALUE b)
{
    int c;
    VALUE r = rb_funcall(a, id_cmp, 1, b);

    if (NIL_P(r))
	return (int)Qfalse;
    c = rb_cmpint(r, a, b);
    if (c == 0)
	return (int)INT2FIX(0);
    if (c < 0)
	return (int)Qtrue;
    return (int)Qfalse;
}
Ejemplo n.º 16
0
static VALUE
range_min(VALUE range)
{
    if (rb_block_given_p()) {
	return rb_call_super(0, 0);
    }
    else {
	VALUE b = RANGE_BEG(range);
	VALUE e = RANGE_END(range);
	int c = rb_cmpint(rb_funcall(b, id_cmp, 1, e), b, e);

	if (c > 0 || (c == 0 && EXCL(range)))
	    return Qnil;
	return b;
    }
}
Ejemplo n.º 17
0
static VALUE
range_min(VALUE range, SEL sel)
{
    if (rb_block_given_p()) {
	if (sel == NULL) {
	    sel = sel_registerName("min");
	}
	return rb_vm_call_super(range, sel, 0, NULL);
    }
    else {
	VALUE b = RANGE_BEG(range);
	VALUE e = RANGE_END(range);
	int c = rb_cmpint(rb_objs_cmp(b, e), b, e);

	if (c > 0 || (c == 0 && EXCL(range)))
	    return Qnil;
	return b;
    }
}
Ejemplo n.º 18
0
Archivo: range.c Proyecto: DashYang/sim
static VALUE
range_min(int argc, VALUE *argv, VALUE range)
{
    if (rb_block_given_p()) {
	return rb_call_super(argc, argv);
    }
    else if (argc != 0) {
	return range_first(argc, argv, range);
    }
    else {
	VALUE b = RANGE_BEG(range);
	VALUE e = RANGE_END(range);
	int c = rb_cmpint(rb_funcall(b, id_cmp, 1, e), b, e);

	if (c > 0 || (c == 0 && EXCL(range)))
	    return Qnil;
	return b;
    }
}
Ejemplo n.º 19
0
static int
cmpint(VALUE x, VALUE y)
{
    return rb_cmpint(rb_cmp(x, y), x, y);
}
Ejemplo n.º 20
0
static VALUE
range_step(int argc, VALUE *argv, VALUE range)
{
    VALUE b, e, step;
    long unit;

    RETURN_ENUMERATOR(range, argc, argv);

    b = RANGE_BEG(range);
    e = RANGE_END(range);
    if (rb_scan_args(argc, argv, "01", &step) == 0) {
	step = INT2FIX(1);
	unit = 1;
    }
    else if (FIXNUM_P(step)) {
	unit = NUM2LONG(step);
    }
    else {
	VALUE tmp = rb_to_int(step);
	unit = rb_cmpint(tmp, step, INT2FIX(0));
	step = tmp;
    }
    if (unit < 0) {
	rb_raise(rb_eArgError, "step can't be negative");
    }
    if (unit == 0)
	rb_raise(rb_eArgError, "step can't be 0");
    if (FIXNUM_P(b) && FIXNUM_P(e) && FIXNUM_P(step)) { /* fixnums are special */
	long end = FIX2LONG(e);
	long i;

	if (!EXCL(range))
	    end += 1;
	i = FIX2LONG(b);	
	while (i < end) {
	    rb_yield(LONG2NUM(i));
	    if (i + unit < i) break;
	    i += unit;
	}
    }
    else {
	VALUE tmp = rb_check_string_type(b);

	if (!NIL_P(tmp)) {
	    VALUE args[2], iter[2];

	    b = tmp;
	    args[0] = e;
	    args[1] = EXCL(range) ? Qtrue : Qfalse;
	    iter[0] = INT2FIX(1);
	    iter[1] = step;
	    rb_block_call(b, rb_intern("upto"), 2, args, step_i, (VALUE)iter);
	}
	else if (rb_obj_is_kind_of(b, rb_cNumeric)) {
	    ID c = rb_intern(EXCL(range) ? "<" : "<=");

	    if (rb_equal(step, INT2FIX(0)))
		rb_raise(rb_eArgError, "step can't be 0");
	    while (RTEST(rb_funcall(b, c, 1, e))) {
		rb_yield(b);
		b = rb_funcall(b, '+', 1, step);
	    }
	}
	else {
	    VALUE args[2];

	    if (!rb_respond_to(b, id_succ)) {
		rb_raise(rb_eTypeError, "can't iterate from %s",
			 rb_obj_classname(b));
	    }
	    args[0] = INT2FIX(1);
	    args[1] = step;
	    range_each_func(range, step_i, b, e, args);
	}
    }
    return range;
}
Ejemplo n.º 21
0
Archivo: range.c Proyecto: DashYang/sim
static VALUE
range_bsearch(VALUE range)
{
    VALUE beg, end;
    int smaller, satisfied = 0;

    /* Implementation notes:
     * Floats are handled by mapping them to 64 bits integers.
     * Apart from sign issues, floats and their 64 bits integer have the
     * same order, assuming they are represented as exponent followed
     * by the mantissa. This is true with or without implicit bit.
     *
     * Finding the average of two ints needs to be careful about
     * potential overflow (since float to long can use 64 bits)
     * as well as the fact that -1/2 can be 0 or -1 in C89.
     *
     * Note that -0.0 is mapped to the same int as 0.0 as we don't want
     * (-1...0.0).bsearch to yield -0.0.
     */

#define BSEARCH_CHECK(val) \
    do { \
	VALUE v = rb_yield(val); \
	if (FIXNUM_P(v)) { \
	    if (FIX2INT(v) == 0) return val; \
	    smaller = FIX2INT(v) < 0; \
	} \
	else if (v == Qtrue) { \
	    satisfied = 1; \
	    smaller = 1; \
	} \
	else if (v == Qfalse || v == Qnil) { \
	    smaller = 0; \
	} \
	else if (rb_obj_is_kind_of(v, rb_cNumeric)) { \
	    int cmp = rb_cmpint(rb_funcall(v, id_cmp, 1, INT2FIX(0)), v, INT2FIX(0)); \
	    if (!cmp) return val; \
	    smaller = cmp < 0; \
	} \
	else { \
	    rb_raise(rb_eTypeError, "wrong argument type %s" \
		" (must be numeric, true, false or nil)", \
		rb_obj_classname(v)); \
	} \
    } while (0)

#define BSEARCH(conv) \
    do { \
	RETURN_ENUMERATOR(range, 0, 0); \
	if (EXCL(range)) high--; \
	org_high = high; \
	while (low < high) { \
	    mid = ((high < 0) == (low < 0)) ? low + ((high - low) / 2) \
		: (low < -high) ? -((-1 - low - high)/2 + 1) : (low + high) / 2; \
	    BSEARCH_CHECK(conv(mid)); \
	    if (smaller) { \
		high = mid; \
	    } \
	    else { \
		low = mid + 1; \
	    } \
	} \
	if (low == org_high) { \
	    BSEARCH_CHECK(conv(low)); \
	    if (!smaller) return Qnil; \
	} \
	if (!satisfied) return Qnil; \
	return conv(low); \
    } while (0)


    beg = RANGE_BEG(range);
    end = RANGE_END(range);

    if (FIXNUM_P(beg) && FIXNUM_P(end)) {
	long low = FIX2LONG(beg);
	long high = FIX2LONG(end);
	long mid, org_high;
	BSEARCH(INT2FIX);
    }
#if SIZEOF_DOUBLE == 8 && defined(HAVE_INT64_T)
    else if (RB_TYPE_P(beg, T_FLOAT) || RB_TYPE_P(end, T_FLOAT)) {
	int64_t low  = double_as_int64(RFLOAT_VALUE(rb_Float(beg)));
	int64_t high = double_as_int64(RFLOAT_VALUE(rb_Float(end)));
	int64_t mid, org_high;
	BSEARCH(int64_as_double_to_num);
    }
#endif
    else if (is_integer_p(beg) && is_integer_p(end)) {
	VALUE low = rb_to_int(beg);
	VALUE high = rb_to_int(end);
	VALUE mid, org_high;
	RETURN_ENUMERATOR(range, 0, 0);
	if (EXCL(range)) high = rb_funcall(high, '-', 1, INT2FIX(1));
	org_high = high;

	while (rb_cmpint(rb_funcall(low, id_cmp, 1, high), low, high) < 0) {
	    mid = rb_funcall(rb_funcall(high, '+', 1, low), id_div, 1, INT2FIX(2));
	    BSEARCH_CHECK(mid);
	    if (smaller) {
		high = mid;
	    }
	    else {
		low = rb_funcall(mid, '+', 1, INT2FIX(1));
	    }
	}
	if (rb_equal(low, org_high)) {
	    BSEARCH_CHECK(low);
	    if (!smaller) return Qnil;
	}
	if (!satisfied) return Qnil;
	return low;
    }
    else {
	rb_raise(rb_eTypeError, "can't do binary search for %s", rb_obj_classname(beg));
    }
    return range;
}
Ejemplo n.º 22
0
static VALUE numeric_spec_rb_cmpint(VALUE self, VALUE val, VALUE b) {
  return INT2FIX(rb_cmpint(val, val, b));
}