Пример #1
0
unsigned long
rb_hash_code(VALUE obj)
{
    switch (TYPE(obj)) {
	case T_FIXNUM:
	case T_FLOAT:
	case T_SYMBOL:
	case T_NIL:
	case T_FALSE:
	case T_TRUE:
	    return (unsigned long)obj;

	case T_STRING:
	    return rb_str_hash(obj);

	case T_ARRAY:
	    return rb_ary_hash(obj);
    }

    VALUE v = rb_vm_call(obj, selHash, 0, NULL);
retry:
    switch (TYPE(v)) {
	case T_FIXNUM:
	    return FIX2LONG(v);
	case T_BIGNUM:
	    return ((unsigned long *)(RBIGNUM_DIGITS(v)))[0];
	default:
	    v = rb_to_int(v);
	    goto retry;
    }
}
Пример #2
0
/*
 * call-seq:
 *   Enumerator.new(size = nil) { |yielder| ... }
 *   Enumerator.new(obj, method = :each, *args)
 *
 * Creates a new Enumerator object, which can be used as an
 * Enumerable.
 *
 * In the first form, iteration is defined by the given block, in
 * which a "yielder" object, given as block parameter, can be used to
 * yield a value by calling the +yield+ method (aliased as +<<+):
 *
 *   fib = Enumerator.new do |y|
 *     a = b = 1
 *     loop do
 *       y << a
 *       a, b = b, a + b
 *     end
 *   end
 *
 *   p fib.take(10) # => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
 *
 * The optional parameter can be used to specify how to calculate the size
 * in a lazy fashion (see Enumerator#size). It can either be a value or
 * a callable object.
 *
 * In the second, deprecated, form, a generated Enumerator iterates over the
 * given object using the given method with the given arguments passed.
 *
 * Use of this form is discouraged.  Use Kernel#enum_for or Kernel#to_enum
 * instead.
 *
 *   e = Enumerator.new(ObjectSpace, :each_object)
 *       #-> ObjectSpace.enum_for(:each_object)
 *
 *   e.select { |obj| obj.is_a?(Class) }  #=> array of all classes
 *
 */
static VALUE
enumerator_initialize(int argc, VALUE *argv, VALUE obj)
{
    VALUE recv, meth = sym_each;
    VALUE size = Qnil;

    if (rb_block_given_p()) {
	rb_check_arity(argc, 0, 1);
	recv = generator_init(generator_allocate(rb_cGenerator), rb_block_proc());
	if (argc) {
            if (NIL_P(argv[0]) || rb_obj_is_proc(argv[0]) ||
                (RB_TYPE_P(argv[0], T_FLOAT) && RFLOAT_VALUE(argv[0]) == INFINITY)) {
                size = argv[0];
            }
            else {
                size = rb_to_int(argv[0]);
            }
            argc = 0;
        }
    }
    else {
	rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
	rb_warn("Enumerator.new without a block is deprecated; use Object#to_enum");
	recv = *argv++;
	if (--argc) {
	    meth = *argv++;
	    --argc;
	}
    }

    return enumerator_init(obj, recv, meth, argc, argv, 0, size);
}
Пример #3
0
static VALUE
rg_s_define_interface(G_GNUC_UNUSED VALUE klass,
                      VALUE rb_gtype, VALUE rb_name, VALUE rb_module)
{
    GType gtype;

    gtype = NUM2ULONG(rb_to_int(rb_gtype));
    return G_DEF_INTERFACE(gtype, RVAL2CSTR(rb_name), rb_module);
}
Пример #4
0
static VALUE
rg_initialize(VALUE self, VALUE rb_gtype, VALUE rb_value)
{
    GValue value = G_VALUE_INIT;

    g_value_init(&value, NUM2INT(rb_to_int(rb_gtype)));
    rbgobj_rvalue_to_gvalue(rb_value, &value);
    G_INITIALIZE(self, g_boxed_copy(G_TYPE_VALUE, &value));
    g_value_unset(&value);

    return Qnil;
}
Пример #5
0
/*
 * call-seq:
 *   e.with_index(offset = 0) {|(*args), idx| ... }
 *   e.with_index(offset = 0)
 *
 * Iterates the given block for each element with an index, which
 * starts from +offset+.  If no block is given, returns a new Enumerator
 * that includes the index, starting from +offset+
 *
 * +offset+:: the starting index to use
 *
 */
static VALUE
enumerator_with_index(int argc, VALUE *argv, VALUE obj)
{
    VALUE memo;

    rb_scan_args(argc, argv, "01", &memo);
    RETURN_SIZED_ENUMERATOR(obj, argc, argv, enumerator_enum_size);
    if (NIL_P(memo))
	memo = INT2FIX(0);
    else
	memo = rb_to_int(memo);
    return enumerator_block_call(obj, enumerator_with_index_i, (VALUE)&memo);
}
Пример #6
0
static VALUE
rg_initialize(int argc, VALUE *argv, VALUE self)
{
    GValue value = G_VALUE_INIT;
    VALUE rb_gtype;
    VALUE rb_value;

    rb_scan_args(argc, argv, "11", &rb_gtype, &rb_value);

    g_value_init(&value, NUM2ULONG(rb_to_int(rb_gtype)));
    if (argc == 2) {
        rbgobj_rvalue_to_gvalue(rb_value, &value);
    }
    G_INITIALIZE(self, g_boxed_copy(G_TYPE_VALUE, &value));
    g_value_unset(&value);

    return Qnil;
}
Пример #7
0
static VALUE
rg_s_define_struct(int argc, VALUE *argv, G_GNUC_UNUSED VALUE klass)
{
    VALUE rb_size, rb_name, rb_module;
    VALUE rb_options, rb_parent;
    VALUE rb_class;

    rb_scan_args(argc, argv, "31", &rb_size, &rb_name, &rb_module, &rb_options);
    rbg_scan_options(rb_options,
                     "parent", &rb_parent,
                     NULL);

    rb_size = rb_to_int(rb_size);
    if (NIL_P(rb_parent)) {
        rb_parent = rb_cObject;
    }
    rb_class = rb_define_class_under(rb_module, RVAL2CSTR(rb_name), rb_parent);
    rb_iv_set(rb_class, "@size", rb_size);
    rb_define_alloc_func(rb_class, struct_alloc);
    return rb_class;
}
Пример #8
0
static VALUE
rg_s_define_class(int argc, VALUE *argv, G_GNUC_UNUSED VALUE klass)
{
    VALUE rb_class;
    VALUE rb_gtype, rb_name, rb_module;
    VALUE rb_options, rb_parent, rb_size;
    GType gtype;

    rb_scan_args(argc, argv, "31", &rb_gtype, &rb_name, &rb_module, &rb_options);
    rbg_scan_options(rb_options,
                     "parent", &rb_parent,
                     "size", &rb_size,
                     NULL);

    gtype = NUM2ULONG(rb_to_int(rb_gtype));
    rb_class = G_DEF_CLASS_WITH_PARENT(gtype, RVAL2CSTR(rb_name),
                                       rb_module, rb_parent);
    if (!NIL_P(rb_size)) {
        rb_iv_set(rb_class, "@size", rb_size);
    }
    return rb_class;
}
Пример #9
0
static VALUE
range_step_size(VALUE range, VALUE args, VALUE eobj)
{
    VALUE b = RANGE_BEG(range), e = RANGE_END(range);
    VALUE step = INT2FIX(1);
    if (args) {
	step = RARRAY_AREF(args, 0);
	if (!rb_obj_is_kind_of(step, rb_cNumeric)) {
	    step = rb_to_int(step);
	}
    }
    if (rb_funcall(step, '<', 1, INT2FIX(0))) {
	rb_raise(rb_eArgError, "step can't be negative");
    }
    else if (!rb_funcall(step, '>', 1, INT2FIX(0))) {
	rb_raise(rb_eArgError, "step can't be 0");
    }

    if (rb_obj_is_kind_of(b, rb_cNumeric) && rb_obj_is_kind_of(e, rb_cNumeric)) {
	return ruby_num_interval_step_size(b, e, step, EXCL(range));
    }
    return Qnil;
}
Пример #10
0
static VALUE
range_step(VALUE range, SEL sel, int argc, VALUE *argv)
{
    VALUE b, e, step, tmp;

    RETURN_ENUMERATOR(range, argc, argv);

    b = RANGE_BEG(range);
    e = RANGE_END(range);
    if (argc == 0) {
	step = INT2FIX(1);
    }
    else {
	rb_scan_args(argc, argv, "01", &step);
	if (!rb_obj_is_kind_of(step, rb_cNumeric)) {
	    step = rb_to_int(step);
	}
	VALUE zero = INT2FIX(0);
	if (rb_vm_call(step, selLT, 1, &zero)) {
	    rb_raise(rb_eArgError, "step can't be negative");
	}
	else if (!rb_vm_call(step, selGT, 1, &zero)) {
	    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, unit = FIX2LONG(step);

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

    }
    else if (SYMBOL_P(b) && SYMBOL_P(e)) { /* symbols are special */
	VALUE args[2];
	VALUE iter[2];

	args[0] = rb_sym_to_s(e);
	args[1] = EXCL(range) ? Qtrue : Qfalse;
	iter[0] = INT2FIX(1);
	iter[1] = step;
	rb_objc_block_call(rb_sym_to_s(b), selUpto, 2, args, sym_step_i, (VALUE)iter);
    }
    else if (ruby_float_step(b, e, step, EXCL(range))) {
	/* done */
    }
    else if (rb_obj_is_kind_of(b, rb_cNumeric) ||
	     !NIL_P(rb_check_to_integer(b, "to_int")) ||
	     !NIL_P(rb_check_to_integer(e, "to_int"))) {
	SEL op = EXCL(range) ? selLT : selLE;
	VALUE v = b;
	int i = 0;

	while (RTEST(rb_vm_call(v, op, 1, &e))) {
	    rb_yield(v);
	    RETURN_IF_BROKEN();
	    i++;
	    VALUE tmp = rb_vm_call(INT2NUM(i), selMULT, 1, &step);
	    v = rb_vm_call(b, selPLUS, 1, &tmp);
	}
    }
    else {
	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_objc_block_call(b, selUpto, 2, args, step_i, (VALUE)iter);
	}
	else {
	    VALUE args[2];

	    if (!discrete_object_p(b)) {
		rb_raise(rb_eTypeError, "can't iterate from %s",
			 rb_obj_classname(b));
	    }
	    args[0] = INT2FIX(1);
	    args[1] = step;
	    return range_each_func(range, step_i, args);
	}
    }
    return range;
}
Пример #11
0
static VALUE object_spec_rb_to_int(VALUE self, VALUE obj) {
  return rb_to_int(obj);
}
Пример #12
0
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;
}
Пример #13
0
static VALUE
range_step(int argc, VALUE *argv, VALUE range)
{
    VALUE b, e, step, tmp;

    RETURN_SIZED_ENUMERATOR(range, argc, argv, range_step_size);

    b = RANGE_BEG(range);
    e = RANGE_END(range);
    if (argc == 0) {
	step = INT2FIX(1);
    }
    else {
	rb_scan_args(argc, argv, "01", &step);
	if (!rb_obj_is_kind_of(step, rb_cNumeric)) {
	    step = rb_to_int(step);
	}
	if (rb_funcall(step, '<', 1, INT2FIX(0))) {
	    rb_raise(rb_eArgError, "step can't be negative");
	}
	else if (!rb_funcall(step, '>', 1, INT2FIX(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, unit = FIX2LONG(step);

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

    }
    else if (SYMBOL_P(b) && SYMBOL_P(e)) { /* symbols are special */
	VALUE args[2], iter[2];

	args[0] = rb_sym_to_s(e);
	args[1] = EXCL(range) ? Qtrue : Qfalse;
	iter[0] = INT2FIX(1);
	iter[1] = step;
	rb_block_call(rb_sym_to_s(b), rb_intern("upto"), 2, args, sym_step_i, (VALUE)iter);
    }
    else if (ruby_float_step(b, e, step, EXCL(range))) {
	/* done */
    }
    else if (rb_obj_is_kind_of(b, rb_cNumeric) ||
	     !NIL_P(rb_check_to_integer(b, "to_int")) ||
	     !NIL_P(rb_check_to_integer(e, "to_int"))) {
	ID op = EXCL(range) ? '<' : idLE;
	VALUE v = b;
	int i = 0;

	while (RTEST(rb_funcall(v, op, 1, e))) {
	    rb_yield(v);
	    i++;
	    v = rb_funcall(b, '+', 1, rb_funcall(INT2NUM(i), '*', 1, step));
	}
    }
    else {
	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 {
	    VALUE args[2];

	    if (!discrete_object_p(b)) {
		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, (VALUE)args);
	}
    }
    return range;
}
Пример #14
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;
}
Пример #15
0
static VALUE
gcd_normal(VALUE x, VALUE y)
{
    return rb_big_norm(rb_gcd_normal(rb_to_int(x), rb_to_int(y)));
}
Пример #16
0
 VALUE newPointerObj(long *d)
 {
   return rb_to_int(rb_float_new(*d));
 }