* ext/bigdecimal/bigdecimal.c (BigDecimal_s_allocate): follow
Allocation Framework. [Bug #5775] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@34089 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
1c6226b67d
commit
f9a4d5717c
@ -1,3 +1,8 @@
|
|||||||
|
Wed Dec 21 12:35:24 2011 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* ext/bigdecimal/bigdecimal.c (BigDecimal_s_allocate): follow
|
||||||
|
Allocation Framework. [Bug #5775]
|
||||||
|
|
||||||
Wed Dec 21 02:25:36 2011 Aaron Patterson <aaron@tenderlovemaking.com>
|
Wed Dec 21 02:25:36 2011 Aaron Patterson <aaron@tenderlovemaking.com>
|
||||||
|
|
||||||
* ext/psych/emitter.c: fixing clang warnings. Thanks Joey!
|
* ext/psych/emitter.c: fixing clang warnings. Thanks Joey!
|
||||||
|
@ -131,7 +131,7 @@ static unsigned short VpGetException(void);
|
|||||||
static void VpSetException(unsigned short f);
|
static void VpSetException(unsigned short f);
|
||||||
static void VpInternalRound(Real *c, size_t ixDigit, BDIGIT vPrev, BDIGIT v);
|
static void VpInternalRound(Real *c, size_t ixDigit, BDIGIT vPrev, BDIGIT v);
|
||||||
static int VpLimitRound(Real *c, size_t ixDigit);
|
static int VpLimitRound(Real *c, size_t ixDigit);
|
||||||
static Real *VpDup(Real const* const x);
|
static Real *VpCopy(Real *pv, Real const* const x);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* **** BigDecimal part ****
|
* **** BigDecimal part ****
|
||||||
@ -561,15 +561,14 @@ VpCreateRbObject(size_t mx, const char *str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define VpAllocReal(prec) (Real *)VpMemAlloc(offsetof(Real, frac) + (prec) * sizeof(BDIGIT))
|
#define VpAllocReal(prec) (Real *)VpMemAlloc(offsetof(Real, frac) + (prec) * sizeof(BDIGIT))
|
||||||
|
#define VpReallocReal(ptr, prec) (Real *)VpMemRealloc((ptr), offsetof(Real, frac) + (prec) * sizeof(BDIGIT))
|
||||||
|
|
||||||
static Real *
|
static Real *
|
||||||
VpDup(Real const* const x)
|
VpCopy(Real *pv, Real const* const x)
|
||||||
{
|
{
|
||||||
Real *pv;
|
|
||||||
|
|
||||||
assert(x != NULL);
|
assert(x != NULL);
|
||||||
|
|
||||||
pv = VpAllocReal(x->MaxPrec);
|
pv = VpReallocReal(pv, x->MaxPrec);
|
||||||
pv->MaxPrec = x->MaxPrec;
|
pv->MaxPrec = x->MaxPrec;
|
||||||
pv->Prec = x->Prec;
|
pv->Prec = x->Prec;
|
||||||
pv->exponent = x->exponent;
|
pv->exponent = x->exponent;
|
||||||
@ -577,9 +576,6 @@ VpDup(Real const* const x)
|
|||||||
pv->flag = x->flag;
|
pv->flag = x->flag;
|
||||||
MEMCPY(pv->frac, x->frac, BDIGIT, pv->MaxPrec);
|
MEMCPY(pv->frac, x->frac, BDIGIT, pv->MaxPrec);
|
||||||
|
|
||||||
pv->obj = TypedData_Wrap_Struct(
|
|
||||||
rb_obj_class(x->obj), &BigDecimal_data_type, pv);
|
|
||||||
|
|
||||||
return pv;
|
return pv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2254,6 +2250,14 @@ BigDecimal_power_op(VALUE self, VALUE exp)
|
|||||||
return BigDecimal_power(1, &exp, self);
|
return BigDecimal_power(1, &exp, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
BigDecimal_s_allocate(VALUE klass)
|
||||||
|
{
|
||||||
|
return VpNewRbClass(0, NULL, klass)->obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Real *BigDecimal_new(int argc, VALUE *argv);
|
||||||
|
|
||||||
/* call-seq:
|
/* call-seq:
|
||||||
* new(initial, digits)
|
* new(initial, digits)
|
||||||
*
|
*
|
||||||
@ -2272,10 +2276,36 @@ BigDecimal_power_op(VALUE self, VALUE exp)
|
|||||||
* larger than the specified number.
|
* larger than the specified number.
|
||||||
*/
|
*/
|
||||||
static VALUE
|
static VALUE
|
||||||
BigDecimal_new(int argc, VALUE *argv, VALUE self)
|
BigDecimal_initialize(int argc, VALUE *argv, VALUE self)
|
||||||
|
{
|
||||||
|
Real *pv = rb_check_typeddata(self, &BigDecimal_data_type);
|
||||||
|
Real *x = BigDecimal_new(argc, argv);
|
||||||
|
|
||||||
|
if (ToValue(x)) {
|
||||||
|
pv = VpCopy(pv, x);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
VpFree(pv);
|
||||||
|
pv = x;
|
||||||
|
}
|
||||||
|
DATA_PTR(self) = pv;
|
||||||
|
pv->obj = self;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
BigDecimal_initialize_copy(VALUE self, VALUE other)
|
||||||
|
{
|
||||||
|
Real *pv = rb_check_typeddata(self, &BigDecimal_data_type);
|
||||||
|
Real *x = rb_check_typeddata(other, &BigDecimal_data_type);
|
||||||
|
|
||||||
|
DATA_PTR(self) = VpCopy(pv, x);
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Real *
|
||||||
|
BigDecimal_new(int argc, VALUE *argv)
|
||||||
{
|
{
|
||||||
ENTER(5);
|
|
||||||
Real *pv;
|
|
||||||
size_t mf;
|
size_t mf;
|
||||||
VALUE nFig;
|
VALUE nFig;
|
||||||
VALUE iniValue;
|
VALUE iniValue;
|
||||||
@ -2290,15 +2320,14 @@ BigDecimal_new(int argc, VALUE *argv, VALUE self)
|
|||||||
switch (TYPE(iniValue)) {
|
switch (TYPE(iniValue)) {
|
||||||
case T_DATA:
|
case T_DATA:
|
||||||
if (is_kind_of_BigDecimal(iniValue)) {
|
if (is_kind_of_BigDecimal(iniValue)) {
|
||||||
pv = VpDup(DATA_PTR(iniValue));
|
return DATA_PTR(iniValue);
|
||||||
return ToValue(pv);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_FIXNUM:
|
case T_FIXNUM:
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case T_BIGNUM:
|
case T_BIGNUM:
|
||||||
return ToValue(GetVpValue(iniValue, 1));
|
return GetVpValue(iniValue, 1);
|
||||||
|
|
||||||
case T_FLOAT:
|
case T_FLOAT:
|
||||||
if (mf > DBL_DIG+1) {
|
if (mf > DBL_DIG+1) {
|
||||||
@ -2309,23 +2338,25 @@ BigDecimal_new(int argc, VALUE *argv, VALUE self)
|
|||||||
if (NIL_P(nFig)) {
|
if (NIL_P(nFig)) {
|
||||||
rb_raise(rb_eArgError, "can't omit precision for a Rational.");
|
rb_raise(rb_eArgError, "can't omit precision for a Rational.");
|
||||||
}
|
}
|
||||||
return ToValue(GetVpValueWithPrec(iniValue, mf, 1));
|
return GetVpValueWithPrec(iniValue, mf, 1);
|
||||||
|
|
||||||
case T_STRING:
|
case T_STRING:
|
||||||
/* fall through */
|
/* fall through */
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
SafeStringValue(iniValue);
|
StringValueCStr(iniValue);
|
||||||
GUARD_OBJ(pv, VpNewRbClass(mf, RSTRING_PTR(iniValue),self));
|
rb_check_safe_obj(iniValue);
|
||||||
|
return VpAlloc(mf, RSTRING_PTR(iniValue));
|
||||||
return ToValue(pv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
BigDecimal_global_new(int argc, VALUE *argv, VALUE self)
|
BigDecimal_global_new(int argc, VALUE *argv, VALUE self)
|
||||||
{
|
{
|
||||||
return BigDecimal_new(argc, argv, rb_cBigDecimal);
|
Real *pv = BigDecimal_new(argc, argv);
|
||||||
|
if (ToValue(pv)) pv = VpCopy(NULL, pv);
|
||||||
|
pv->obj = TypedData_Wrap_Struct(rb_cBigDecimal, &BigDecimal_data_type, pv);
|
||||||
|
return pv->obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* call-seq:
|
/* call-seq:
|
||||||
@ -2830,16 +2861,12 @@ Init_bigdecimal(void)
|
|||||||
|
|
||||||
/* Class and method registration */
|
/* Class and method registration */
|
||||||
rb_cBigDecimal = rb_define_class("BigDecimal",rb_cNumeric);
|
rb_cBigDecimal = rb_define_class("BigDecimal",rb_cNumeric);
|
||||||
rb_undef_alloc_func(rb_cBigDecimal); /* TODO: define alloc func */
|
rb_define_alloc_func(rb_cBigDecimal, BigDecimal_s_allocate);
|
||||||
|
|
||||||
/* Global function */
|
/* Global function */
|
||||||
rb_define_global_function("BigDecimal", BigDecimal_global_new, -1);
|
rb_define_global_function("BigDecimal", BigDecimal_global_new, -1);
|
||||||
|
|
||||||
/* Class methods */
|
/* Class methods */
|
||||||
#if 1
|
|
||||||
/* TODO: follow allocation framework */
|
|
||||||
rb_define_singleton_method(rb_cBigDecimal, "new", BigDecimal_new, -1);
|
|
||||||
#endif
|
|
||||||
rb_define_singleton_method(rb_cBigDecimal, "mode", BigDecimal_mode, -1);
|
rb_define_singleton_method(rb_cBigDecimal, "mode", BigDecimal_mode, -1);
|
||||||
rb_define_singleton_method(rb_cBigDecimal, "limit", BigDecimal_limit, -1);
|
rb_define_singleton_method(rb_cBigDecimal, "limit", BigDecimal_limit, -1);
|
||||||
rb_define_singleton_method(rb_cBigDecimal, "double_fig", BigDecimal_double_fig, 0);
|
rb_define_singleton_method(rb_cBigDecimal, "double_fig", BigDecimal_double_fig, 0);
|
||||||
@ -2963,6 +2990,8 @@ Init_bigdecimal(void)
|
|||||||
|
|
||||||
|
|
||||||
/* instance methods */
|
/* instance methods */
|
||||||
|
rb_define_method(rb_cBigDecimal, "initialize", BigDecimal_initialize, -1);
|
||||||
|
rb_define_method(rb_cBigDecimal, "initialize_copy", BigDecimal_initialize_copy, 1);
|
||||||
rb_define_method(rb_cBigDecimal, "precs", BigDecimal_prec, 0);
|
rb_define_method(rb_cBigDecimal, "precs", BigDecimal_prec, 0);
|
||||||
|
|
||||||
rb_define_method(rb_cBigDecimal, "add", BigDecimal_add2, 2);
|
rb_define_method(rb_cBigDecimal, "add", BigDecimal_add2, 2);
|
||||||
@ -3093,6 +3122,16 @@ VpMemAlloc(size_t mb)
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VP_EXPORT void *
|
||||||
|
VpMemRealloc(void *ptr, size_t mb)
|
||||||
|
{
|
||||||
|
void *p = xrealloc(ptr, mb);
|
||||||
|
if (!p) {
|
||||||
|
VpException(VP_EXCEPTION_MEMORY, "failed to allocate memory", 1);
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
VP_EXPORT void
|
VP_EXPORT void
|
||||||
VpFree(Real *pv)
|
VpFree(Real *pv)
|
||||||
{
|
{
|
||||||
|
@ -21,6 +21,9 @@
|
|||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
#if 0
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_LABS
|
#ifndef HAVE_LABS
|
||||||
@ -197,6 +200,7 @@ VP_EXPORT int VpIsNegDoubleZero(double v);
|
|||||||
VP_EXPORT size_t VpNumOfChars(Real *vp,const char *pszFmt);
|
VP_EXPORT size_t VpNumOfChars(Real *vp,const char *pszFmt);
|
||||||
VP_EXPORT size_t VpInit(BDIGIT BaseVal);
|
VP_EXPORT size_t VpInit(BDIGIT BaseVal);
|
||||||
VP_EXPORT void *VpMemAlloc(size_t mb);
|
VP_EXPORT void *VpMemAlloc(size_t mb);
|
||||||
|
VP_EXPORT void *VpMemRealloc(void *ptr, size_t mb);
|
||||||
VP_EXPORT void VpFree(Real *pv);
|
VP_EXPORT void VpFree(Real *pv);
|
||||||
VP_EXPORT Real *VpAlloc(size_t mx, const char *szVal);
|
VP_EXPORT Real *VpAlloc(size_t mx, const char *szVal);
|
||||||
VP_EXPORT size_t VpAsgn(Real *c, Real *a, int isw);
|
VP_EXPORT size_t VpAsgn(Real *c, Real *a, int isw);
|
||||||
@ -279,6 +283,9 @@ VP_EXPORT int VPrint(FILE *fp,const char *cntl_chr,Real *a);
|
|||||||
#endif /* BIGDECIMAL_DEBUG */
|
#endif /* BIGDECIMAL_DEBUG */
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
|
#if 0
|
||||||
|
{
|
||||||
|
#endif
|
||||||
} /* extern "C" { */
|
} /* extern "C" { */
|
||||||
#endif
|
#endif
|
||||||
#endif /* RUBY_BIG_DECIMAL_H */
|
#endif /* RUBY_BIG_DECIMAL_H */
|
||||||
|
@ -19,10 +19,6 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||||||
[ BigDecimal::ROUND_FLOOR, :floor],
|
[ BigDecimal::ROUND_FLOOR, :floor],
|
||||||
]
|
]
|
||||||
|
|
||||||
def assert_allocate
|
|
||||||
assert_raise(TypeError) {BigDecimal.allocate}
|
|
||||||
end
|
|
||||||
|
|
||||||
def assert_nan(x)
|
def assert_nan(x)
|
||||||
assert(x.nan?, "Expected #{x.inspect} to be NaN")
|
assert(x.nan?, "Expected #{x.inspect} to be NaN")
|
||||||
end
|
end
|
||||||
@ -47,6 +43,10 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||||||
"Expected #{x.inspect} to be negative zero")
|
"Expected #{x.inspect} to be negative zero")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_not_equal
|
||||||
|
assert_not_equal BigDecimal("1"), BigDecimal.allocate
|
||||||
|
end
|
||||||
|
|
||||||
def test_global_new
|
def test_global_new
|
||||||
assert_equal(1, BigDecimal("1"))
|
assert_equal(1, BigDecimal("1"))
|
||||||
assert_equal(1, BigDecimal("1", 1))
|
assert_equal(1, BigDecimal("1", 1))
|
||||||
@ -1288,4 +1288,19 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_dup
|
||||||
|
[1, -1, 2**100, -2**100].each do |i|
|
||||||
|
x = BigDecimal(i)
|
||||||
|
assert_equal(x, x.dup)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_dup_subclass
|
||||||
|
c = Class.new(BigDecimal)
|
||||||
|
x = c.new(1)
|
||||||
|
y = x.dup
|
||||||
|
assert_equal(1, y)
|
||||||
|
assert_kind_of(c, y)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user