source: to-imperative/trunk/runtime/rf_integer.ih @ 1082

Last change on this file since 1082 was 1082, checked in by pooh, 18 years ago
  • Added comment on used trick.
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.2 KB
Line 
1#ifndef __rf_integer_ih__
2#define __rf_integer_ih__
3
4#include "rf_integer.hh"
5#include "rf_expr.ih"
6#include "rf_term.ih"
7#include "pxx_chunk_allocator.ih"
8#include "pxx_string.ih"
9
10namespace rftype
11{
12
13using namespace rfrt;
14
15inline Integer::Integer (intptr_t _n) :
16  Term(type_int)
17{
18  mpz_t* p = mpz_allocator.allocate();
19  ptr_data2 = p;
20  mpz_init_set_si(*p, _n);
21}
22
23inline Integer::Integer (char const* _str) :
24  Term(type_int)
25{
26  mpz_t* p = mpz_allocator.allocate();
27  ptr_data2 = p;
28  mpz_init_set_str(*p, _str, 0);
29}
30
31inline Integer::Integer (wchar_t const* _str) :
32  Term(type_int)
33{
34  mpz_t* p = mpz_allocator.allocate();
35  ptr_data2 = p;
36  size_t len = wcstombs(null, _str, 0);
37  char* s = static_cast<char*>(alloca(len + 1));
38  wcstombs(s, _str, len);
39  s[len] = 0;
40  mpz_init_set_str(*p, s, 0);
41}
42
43inline Integer::Integer (pxx::WString& _str) :
44  Term(type_int)
45{
46  mpz_t* p = mpz_allocator.allocate();
47  ptr_data2 = p;
48  size_t len = wcstombs(null, _str.get_data(), 0);
49  char* s = static_cast<char*>(alloca(len + 1));
50  wcstombs(s, _str.get_data(), len);
51  s[len] = 0;
52  mpz_init_set_str(*p, s, 0);
53}
54
55inline Integer::Integer (Integer const& _n) :
56  Term(type_int)
57{
58  mpz_t* p = mpz_allocator.allocate();
59  ptr_data2 = p;
60  mpz_t* q = static_cast<mpz_t*>(_n.ptr_data2);
61  mpz_init_set(*p, *q);
62}
63
64inline Integer::~Integer ()
65{
66//
67// As Integer destructor implicitly calls Term destructor and that calls
68// Integer::dtor() method which really destroys an Integer object, we should
69// not put any actions into Integer destructor body
70//  mpz_t* p = static_cast<mpz_t*>(ptr_data2);
71//  mpz_clear(*p);
72//  mpz_allocator.deallocate(p);
73}
74
75inline Integer& Integer::operator = (Integer const& _n)
76{
77  mpz_t* p = static_cast<mpz_t*>(ptr_data2);
78  mpz_clear(*p);
79  mpz_t* q = static_cast<mpz_t*>(_n.ptr_data2);
80  mpz_init_set(*p, *q);
81  return self;
82}
83
84inline bool Integer::operator == (Integer const& _n) const
85{
86  mpz_t* p = static_cast<mpz_t*>(ptr_data2);
87  mpz_t* q = static_cast<mpz_t*>(_n.ptr_data2);
88  return mpz_cmp(*p, *q) == 0;
89}
90
91inline int Integer::cmp (Integer const& _n) const
92{
93  mpz_t* p = static_cast<mpz_t*>(ptr_data2);
94  mpz_t* q = static_cast<mpz_t*>(_n.ptr_data2);
95  return mpz_cmp(*p, *q);
96}
97
98inline Integer Integer::operator + (Integer const& _n) const
99{
100  Integer res(self);
101  mpz_t* resp = res.get_mpz_ptr();
102  mpz_add(*resp, *resp, *(_n.get_mpz_ptr()));
103  return res;
104}
105
106inline Integer Integer::operator + (intptr_t _n) const
107{
108  Integer res(self);
109  mpz_t* resp = res.get_mpz_ptr();
110  _n >= 0 ? mpz_add_ui(*resp, *resp, _n) : mpz_sub_ui(*resp, *resp, -_n);
111  return res;
112}
113
114inline Integer operator + (intptr_t _n1, Integer const& _n2)
115{
116  Integer res(_n2);
117  mpz_t* resp = res.get_mpz_ptr();
118  _n1 >= 0 ? mpz_add_ui(*resp, *resp, _n1) : mpz_sub_ui(*resp, *resp, -_n1);
119  return res;
120}
121
122inline Integer Integer::operator - (Integer const& _n) const
123{
124  Integer res(self);
125  mpz_t* resp = res.get_mpz_ptr();
126  mpz_sub(*resp, *resp, *(_n.get_mpz_ptr()));
127  return res;
128}
129
130inline Integer Integer::operator - (intptr_t _n) const
131{
132  Integer res(self);
133  mpz_t* resp = res.get_mpz_ptr();
134  _n >= 0 ? mpz_sub_ui(*resp, *resp, _n) : mpz_add_ui(*resp, *resp, -_n);
135  return res;
136}
137
138inline Integer operator - (intptr_t _n1, Integer const& _n2)
139{
140  Integer res(_n2);
141  mpz_t* resp = res.get_mpz_ptr();
142  mpz_neg(*resp, *resp);
143  _n1 >= 0 ? mpz_add_ui(*resp, *resp, _n1) : mpz_sub_ui(*resp, *resp, -_n1);
144  return res;
145}
146
147inline Integer Integer::operator * (Integer const& _n) const
148{
149  Integer res(self);
150  mpz_t* resp = res.get_mpz_ptr();
151  mpz_mul(*resp, *resp, *(_n.get_mpz_ptr()));
152  return res;
153}
154
155inline Integer Integer::operator * (intptr_t _n) const
156{
157  Integer res(self);
158  mpz_t* resp = res.get_mpz_ptr();
159  mpz_mul_si(*resp, *resp, _n);
160  return res;
161}
162
163inline Integer operator * (intptr_t _n1, Integer const& _n2)
164{
165  Integer res(_n2);
166  mpz_t* resp = res.get_mpz_ptr();
167  mpz_mul_si(*resp, *resp, _n1);
168  return res;
169}
170
171inline Integer Integer::operator / (Integer const& _n) const
172{
173  Integer res(self);
174  mpz_t* resp = res.get_mpz_ptr();
175  mpz_tdiv_q(*resp, *resp, *(_n.get_mpz_ptr()));
176  return res;
177}
178
179inline Integer Integer::operator / (intptr_t _n) const
180{
181  Integer res(self);
182  mpz_t* resp = res.get_mpz_ptr();
183  if (_n >= 0 ) {
184    mpz_tdiv_q_ui(*resp, *resp, _n);
185  } else {
186    mpz_tdiv_q_ui(*resp, *resp, -_n);
187    mpz_neg(*resp, *resp);
188  }
189  return res;
190}
191
192inline Integer operator / (intptr_t _n1, Integer const& _n2)
193{
194  return Integer(_n1) / _n2;
195}
196
197inline Integer Integer::operator % (Integer const& _n) const
198{
199  Integer res(self);
200  mpz_t* resp = res.get_mpz_ptr();
201  mpz_tdiv_r(*resp, *resp, *(_n.get_mpz_ptr()));
202  return res;
203}
204
205inline Integer Integer::operator % (intptr_t _n) const
206{
207  Integer res(self);
208  mpz_t* resp = res.get_mpz_ptr();
209  if (_n >= 0 ) {
210    mpz_tdiv_r_ui(*resp, *resp, _n);
211  } else {
212    mpz_tdiv_r_ui(*resp, *resp, -_n);
213  }
214  return res;
215}
216
217inline Integer operator % (intptr_t _n1, Integer const& _n2)
218{
219  return Integer(_n1) % _n2;
220}
221
222inline Integer Integer::div_rem (Integer const& _n, Integer* _remp) const
223{
224  Integer res(self);
225  mpz_t* resp = res.get_mpz_ptr();
226  if (_remp != null) {
227    mpz_tdiv_qr(*resp, *(_remp->get_mpz_ptr()), *resp, *(_n.get_mpz_ptr()));
228  } else {
229    mpz_tdiv_q(*resp, *resp, *(_n.get_mpz_ptr()));
230  }
231  return res;
232}
233
234inline Integer Integer::div_rem (intptr_t _n, Integer* _remp) const
235{
236  Integer res(self);
237  mpz_t* resp = res.get_mpz_ptr();
238  if (_remp != null) {
239    if (_n >= 0 ) {
240      mpz_tdiv_qr_ui(*resp, *(_remp->get_mpz_ptr()), *resp, _n);
241    } else {
242      mpz_tdiv_qr_ui(*resp, *(_remp->get_mpz_ptr()), *resp, -_n);
243      mpz_neg(*resp, *resp);
244    }
245  } else {
246    if (_n >= 0 ) {
247      mpz_tdiv_r_ui(*resp, *resp, _n);
248    } else {
249      mpz_tdiv_r_ui(*resp, *resp, -_n);
250      mpz_neg(*resp, *resp);
251    }
252  }
253  return res;
254}
255
256inline Integer div_rem (intptr_t _n1, Integer const& _n2, Integer* _remp)
257{
258  return Integer(_n1).div_rem(_n2, _remp);
259}
260
261inline Integer Integer::operator - () const
262{
263  Integer res(self);
264  mpz_t* resp = res.get_mpz_ptr();
265  mpz_neg(*resp, *resp);
266  return res;
267}
268
269inline int Integer::sign () const
270{
271  return mpz_sgn(*(get_mpz_ptr()));
272}
273
274inline Integer::operator pxx::WString () const
275{
276  mpz_t* p = static_cast<mpz_t*>(ptr_data2);
277  size_t len = mpz_sizeinbase(*p, 10) + 2;
278  char* s = static_cast<char*>(alloca(len));
279  mpz_get_str(s, 10, *p);
280  len = strlen(s) + 1;
281  wchar_t* ws = static_cast<wchar_t*>(alloca((len + 1)* sizeof(wchar_t)));
282  len = mbstowcs(ws, s, len);
283  ws[len] = 0;
284  return pxx::WString(ws, len);
285}
286
287inline Expr Integer::create_expr (intptr_t _n)
288{
289  Expr e = Term::create_expr(1);
290  new(e.get_first()) Integer(_n);
291  return e;
292}
293
294inline Expr Integer::create_expr (Integer const& _n)
295{
296  Expr e = Term::create_expr(1);
297  new(e.get_first()) Integer(_n);
298  return e;
299}
300
301inline Expr Integer::create_expr (char const* _str)
302{
303  Expr e = Term::create_expr(1);
304  new(e.get_first()) Integer(_str);
305  return e;
306}
307
308inline Expr Integer::create_expr (wchar_t const* _str)
309{
310  Expr e = Term::create_expr(1);
311  new(e.get_first()) Integer(_str);
312  return e;
313}
314
315inline Expr Integer::create_expr (pxx::WString& _str)
316{
317  wchar_t const* data = _str.get_data();
318  return Integer::create_expr(data);
319}
320
321inline mpz_t* Integer::get_mpz_ptr () const
322{
323  return static_cast<mpz_t*>(ptr_data2);
324}
325
326}
327
328#endif // __rf_integer_ih__
Note: See TracBrowser for help on using the repository browser.