#ifndef __rf_integer_ih__ #define __rf_integer_ih__ #include "rf_integer.hh" #include "rf_expr.ih" #include "rf_term.ih" #include "pxx_chunk_allocator.ih" #include "pxx_string.ih" namespace rftype { using namespace rfrt; inline Integer::Integer (intptr_t _n) : Term(type_int) { mpz_t* p = mpz_allocator.allocate(); ptr_data2 = p; mpz_init_set_si(*p, _n); } inline Integer::Integer (char const* _str) : Term(type_int) { mpz_t* p = mpz_allocator.allocate(); ptr_data2 = p; mpz_init_set_str(*p, _str, 0); } inline Integer::Integer (wchar_t const* _str) : Term(type_int) { mpz_t* p = mpz_allocator.allocate(); ptr_data2 = p; size_t len = wcstombs(null, _str, 0); char* s = static_cast(alloca(len + 1)); wcstombs(s, _str, len); s[len] = 0; mpz_init_set_str(*p, s, 0); } inline Integer::Integer (pxx::WString& _str) : Term(type_int) { mpz_t* p = mpz_allocator.allocate(); ptr_data2 = p; size_t len = wcstombs(null, _str.get_data(), 0); char* s = static_cast(alloca(len + 1)); wcstombs(s, _str.get_data(), len); s[len] = 0; mpz_init_set_str(*p, s, 0); } inline Integer::Integer (Integer const& _n) : Term(type_int) { mpz_t* p = mpz_allocator.allocate(); ptr_data2 = p; mpz_t* q = static_cast(_n.ptr_data2); mpz_init_set(*p, *q); } inline Integer::~Integer () { // // As Integer destructor implicitly calls Term destructor and that calls // Integer::dtor() method which really destroys an Integer object, we should // not put any actions into Integer destructor body // mpz_t* p = static_cast(ptr_data2); // mpz_clear(*p); // mpz_allocator.deallocate(p); } inline Integer& Integer::operator = (Integer const& _n) { mpz_t* p = static_cast(ptr_data2); mpz_clear(*p); mpz_t* q = static_cast(_n.ptr_data2); mpz_init_set(*p, *q); return self; } inline bool Integer::operator == (Integer const& _n) const { mpz_t* p = static_cast(ptr_data2); mpz_t* q = static_cast(_n.ptr_data2); return mpz_cmp(*p, *q) == 0; } inline bool Integer::operator == (unsigned long _n) const { mpz_t* p = static_cast(ptr_data2); return mpz_cmp_ui(*p, _n) == 0; } inline bool Integer::operator == (long _n) const { mpz_t* p = static_cast(ptr_data2); return mpz_cmp_si(*p, _n) == 0; } inline bool Integer::operator == (unsigned int _n) const { mpz_t* p = static_cast(ptr_data2); return mpz_cmp_ui(*p, _n) == 0; } inline bool Integer::operator == (int _n) const { mpz_t* p = static_cast(ptr_data2); return mpz_cmp_si(*p, _n) == 0; } inline int Integer::cmp (Integer const& _n) const { mpz_t* p = static_cast(ptr_data2); mpz_t* q = static_cast(_n.ptr_data2); return mpz_cmp(*p, *q); } inline int Integer::cmp (unsigned long _n) const { mpz_t* p = static_cast(ptr_data2); return mpz_cmp_ui(*p, _n); } inline int Integer::cmp (long _n) const { mpz_t* p = static_cast(ptr_data2); return mpz_cmp_si(*p, _n); } inline int Integer::cmp (unsigned int _n) const { mpz_t* p = static_cast(ptr_data2); return mpz_cmp_ui(*p, _n); } inline int Integer::cmp (int _n) const { mpz_t* p = static_cast(ptr_data2); return mpz_cmp_si(*p, _n); } inline Integer Integer::operator + (Integer const& _n) const { Integer res(self); mpz_t* resp = res.get_mpz_ptr(); mpz_add(*resp, *resp, *(_n.get_mpz_ptr())); return res; } inline Integer Integer::operator + (intptr_t _n) const { Integer res(self); mpz_t* resp = res.get_mpz_ptr(); _n >= 0 ? mpz_add_ui(*resp, *resp, _n) : mpz_sub_ui(*resp, *resp, -_n); return res; } inline Integer operator + (intptr_t _n1, Integer const& _n2) { Integer res(_n2); mpz_t* resp = res.get_mpz_ptr(); _n1 >= 0 ? mpz_add_ui(*resp, *resp, _n1) : mpz_sub_ui(*resp, *resp, -_n1); return res; } inline Integer Integer::operator - (Integer const& _n) const { Integer res(self); mpz_t* resp = res.get_mpz_ptr(); mpz_sub(*resp, *resp, *(_n.get_mpz_ptr())); return res; } inline Integer Integer::operator - (intptr_t _n) const { Integer res(self); mpz_t* resp = res.get_mpz_ptr(); _n >= 0 ? mpz_sub_ui(*resp, *resp, _n) : mpz_add_ui(*resp, *resp, -_n); return res; } inline Integer operator - (intptr_t _n1, Integer const& _n2) { Integer res(_n2); mpz_t* resp = res.get_mpz_ptr(); mpz_neg(*resp, *resp); _n1 >= 0 ? mpz_add_ui(*resp, *resp, _n1) : mpz_sub_ui(*resp, *resp, -_n1); return res; } inline Integer Integer::operator * (Integer const& _n) const { Integer res(self); mpz_t* resp = res.get_mpz_ptr(); mpz_mul(*resp, *resp, *(_n.get_mpz_ptr())); return res; } inline Integer Integer::operator * (intptr_t _n) const { Integer res(self); mpz_t* resp = res.get_mpz_ptr(); mpz_mul_si(*resp, *resp, _n); return res; } inline Integer operator * (intptr_t _n1, Integer const& _n2) { Integer res(_n2); mpz_t* resp = res.get_mpz_ptr(); mpz_mul_si(*resp, *resp, _n1); return res; } inline Integer Integer::operator / (Integer const& _n) const { Integer res(self); mpz_t* resp = res.get_mpz_ptr(); mpz_tdiv_q(*resp, *resp, *(_n.get_mpz_ptr())); return res; } inline Integer Integer::operator / (intptr_t _n) const { Integer res(self); mpz_t* resp = res.get_mpz_ptr(); if (_n >= 0 ) { mpz_tdiv_q_ui(*resp, *resp, _n); } else { mpz_tdiv_q_ui(*resp, *resp, -_n); mpz_neg(*resp, *resp); } return res; } inline Integer operator / (intptr_t _n1, Integer const& _n2) { return Integer(_n1) / _n2; } inline Integer Integer::operator % (Integer const& _n) const { Integer res(self); mpz_t* resp = res.get_mpz_ptr(); mpz_tdiv_r(*resp, *resp, *(_n.get_mpz_ptr())); return res; } inline Integer Integer::operator % (intptr_t _n) const { Integer res(self); mpz_t* resp = res.get_mpz_ptr(); if (_n >= 0 ) { mpz_tdiv_r_ui(*resp, *resp, _n); } else { mpz_tdiv_r_ui(*resp, *resp, -_n); } return res; } inline Integer operator % (intptr_t _n1, Integer const& _n2) { return Integer(_n1) % _n2; } inline Integer Integer::div_rem (Integer const& _n, Integer* _remp) const { Integer res(self); mpz_t* resp = res.get_mpz_ptr(); if (_remp != null) { mpz_tdiv_qr(*resp, *(_remp->get_mpz_ptr()), *resp, *(_n.get_mpz_ptr())); } else { mpz_tdiv_q(*resp, *resp, *(_n.get_mpz_ptr())); } return res; } inline Integer Integer::div_rem (intptr_t _n, Integer* _remp) const { Integer res(self); mpz_t* resp = res.get_mpz_ptr(); if (_remp != null) { if (_n >= 0 ) { mpz_tdiv_qr_ui(*resp, *(_remp->get_mpz_ptr()), *resp, _n); } else { mpz_tdiv_qr_ui(*resp, *(_remp->get_mpz_ptr()), *resp, -_n); mpz_neg(*resp, *resp); } } else { if (_n >= 0 ) { mpz_tdiv_r_ui(*resp, *resp, _n); } else { mpz_tdiv_r_ui(*resp, *resp, -_n); mpz_neg(*resp, *resp); } } return res; } inline Integer div_rem (intptr_t _n1, Integer const& _n2, Integer* _remp) { return Integer(_n1).div_rem(_n2, _remp); } inline Integer Integer::operator - () const { Integer res(self); mpz_t* resp = res.get_mpz_ptr(); mpz_neg(*resp, *resp); return res; } inline int Integer::sign () const { return mpz_sgn(*(get_mpz_ptr())); } inline long Integer::to_int () const { return mpz_get_si(*(get_mpz_ptr())); } inline Integer::operator pxx::WString () const { mpz_t* p = static_cast(ptr_data2); size_t len = mpz_sizeinbase(*p, 10) + 2; char* s = static_cast(alloca(len)); mpz_get_str(s, 10, *p); len = strlen(s) + 1; wchar_t* ws = static_cast(alloca((len + 1)* sizeof(wchar_t))); len = mbstowcs(ws, s, len); ws[len] = 0; return pxx::WString(ws, len); } inline Expr Integer::create_expr (intptr_t _n) { Expr e = Term::create_expr(1); new(e.get_first()) Integer(_n); return e; } inline Expr Integer::create_expr (Integer const& _n) { Expr e = Term::create_expr(1); new(e.get_first()) Integer(_n); return e; } inline Expr Integer::create_expr (char const* _str) { Expr e = Term::create_expr(1); new(e.get_first()) Integer(_str); return e; } inline Expr Integer::create_expr (wchar_t const* _str) { Expr e = Term::create_expr(1); new(e.get_first()) Integer(_str); return e; } inline Expr Integer::create_expr (pxx::WString& _str) { wchar_t const* data = _str.get_data(); return Integer::create_expr(data); } inline mpz_t* Integer::get_mpz_ptr () const { return static_cast(ptr_data2); } } #endif // __rf_integer_ih__