mp_wrapper.h
1 #ifndef SYMENGINE_MP_WRAPPER_H
2 #define SYMENGINE_MP_WRAPPER_H
3 
4 #include <symengine/symengine_rcp.h>
5 #include <gmp.h>
6 
7 #define SYMENGINE_UI(f) f##_ui
8 #define SYMENGINE_SI(f) f##_si
9 
10 #define SYMENGINE_MPZ_WRAPPER_IMPLEMENT_RELATIONAL(op, func, val, rev_op) \
11  template <typename T, \
12  typename std::enable_if<std::is_integral<T>::value \
13  && std::is_unsigned<T>::value, \
14  int>::type \
15  = 0> \
16  inline friend bool operator op(const mpz_wrapper &a, const T b) \
17  { \
18  return SYMENGINE_UI(func)(a.get_mpz_t(), b) op val; \
19  } \
20  template <typename T, \
21  typename std::enable_if<std::is_integral<T>::value, int>::type \
22  = 0> \
23  inline friend bool operator op(const T a, const mpz_wrapper &b) \
24  { \
25  return b rev_op a; \
26  } \
27  template < \
28  typename T, \
29  typename std::enable_if< \
30  std::is_integral<T>::value && std::is_signed<T>::value, int>::type \
31  = 0> \
32  inline friend bool operator op(const mpz_wrapper &a, const T b) \
33  { \
34  return SYMENGINE_SI(func)(a.get_mpz_t(), b) op val; \
35  } \
36  inline friend bool operator op(const mpz_wrapper &a, const mpz_wrapper &b) \
37  { \
38  return func(a.get_mpz_t(), b.get_mpz_t()) op val; \
39  }
40 
41 #define SYMENGINE_MPZ_WRAPPER_IMPLEMENT_IN_PLACE(op, func) \
42  inline mpz_wrapper operator op(const mpz_wrapper &a) \
43  { \
44  func(get_mpz_t(), get_mpz_t(), a.get_mpz_t()); \
45  return *this; \
46  } \
47  template <typename T, \
48  typename std::enable_if<std::is_integral<T>::value \
49  && std::is_unsigned<T>::value, \
50  int>::type \
51  = 0> \
52  inline mpz_wrapper operator op(const T a) \
53  { \
54  SYMENGINE_UI(func)(get_mpz_t(), get_mpz_t(), a); \
55  return *this; \
56  }
57 
58 #define SYMENGINE_MPZ_WRAPPER_IMPLEMENT_NON_COMMUTATIVE(op, func, op_eq) \
59  template <typename T, \
60  typename std::enable_if<std::is_integral<T>::value \
61  && std::is_unsigned<T>::value, \
62  int>::type \
63  = 0> \
64  inline friend mpz_wrapper operator op(const mpz_wrapper &a, const T b) \
65  { \
66  mpz_wrapper res; \
67  SYMENGINE_UI(func)(res.get_mpz_t(), a.get_mpz_t(), b); \
68  return res; \
69  } \
70  inline friend mpz_wrapper operator op(const mpz_wrapper &a, \
71  const mpz_wrapper &b) \
72  { \
73  mpz_wrapper res; \
74  func(res.get_mpz_t(), a.get_mpz_t(), b.get_mpz_t()); \
75  return res; \
76  } \
77  SYMENGINE_MPZ_WRAPPER_IMPLEMENT_IN_PLACE(op_eq, func)
78 
79 #define SYMENGINE_MPZ_WRAPPER_IMPLEMENT_COMMUTATIVE(op, func, op_eq) \
80  SYMENGINE_MPZ_WRAPPER_IMPLEMENT_NON_COMMUTATIVE(op, func, op_eq) \
81  template <typename T, \
82  typename std::enable_if<std::is_integral<T>::value, int>::type \
83  = 0> \
84  inline friend mpz_wrapper operator op(const T a, mpz_wrapper &b) \
85  { \
86  return b op a; \
87  }
88 
89 #if SYMENGINE_INTEGER_CLASS == SYMENGINE_FLINT
90 
91 #include <symengine/flint_wrapper.h>
92 
93 #elif SYMENGINE_INTEGER_CLASS == SYMENGINE_GMP
94 
95 namespace SymEngine
96 {
97 
98 class mpz_wrapper
99 {
100 private:
101  mpz_t mp;
102 
103 public:
104  template <
105  typename T,
106  typename std::enable_if<
108  = 0>
109  mpz_wrapper(const T i)
110  {
111  mpz_init_set_ui(mp, i);
112  }
113  template <
114  typename T,
115  typename std::enable_if<
117  = 0>
118  mpz_wrapper(const T i)
119  {
120  mpz_init_set_si(mp, i);
121  }
122  inline mpz_wrapper()
123  {
124  mpz_init(mp);
125  }
126  inline mpz_wrapper(const mpz_t m)
127  {
128  mpz_init_set(mp, m);
129  }
130  inline mpz_wrapper(const std::string &s, unsigned base = 10)
131  {
132  mpz_init_set_str(mp, s.c_str(), base);
133  }
134  inline mpz_wrapper(const mpz_wrapper &other)
135  {
136  mpz_init_set(mp, other.get_mpz_t());
137  }
138  inline mpz_wrapper(mpz_wrapper &&other) SYMENGINE_NOEXCEPT
139  {
140  mp->_mp_d = nullptr;
141  mpz_swap(mp, other.get_mpz_t());
142  }
143  inline mpz_wrapper &operator=(const mpz_wrapper &other)
144  {
145  if (mp->_mp_d == nullptr) {
146  mpz_init_set(mp, other.get_mpz_t());
147  } else {
148  mpz_set(mp, other.get_mpz_t());
149  }
150  return *this;
151  }
152  inline mpz_wrapper &operator=(mpz_wrapper &&other) SYMENGINE_NOEXCEPT
153  {
154  mpz_swap(mp, other.get_mpz_t());
155  return *this;
156  }
157  template <
158  typename T,
159  typename std::enable_if<
161  = 0>
162  inline mpz_wrapper &operator=(T other)
163  {
164  if (mp->_mp_d == nullptr) {
165  mpz_init_set_ui(mp, other);
166  } else {
167  mpz_set_ui(mp, other);
168  }
169  return *this;
170  }
171  template <
172  typename T,
173  typename std::enable_if<
175  = 0>
176  inline mpz_wrapper &operator=(T other)
177  {
178  if (mp->_mp_d == nullptr) {
179  mpz_init_set_si(mp, other);
180  } else {
181  mpz_set_si(mp, other);
182  }
183  return *this;
184  }
185  inline ~mpz_wrapper() SYMENGINE_NOEXCEPT
186  {
187  if (mp->_mp_d != nullptr) {
188  mpz_clear(mp);
189  }
190  }
191  inline mpz_ptr get_mpz_t()
192  {
193  return mp;
194  }
195  inline mpz_srcptr get_mpz_t() const
196  {
197  return mp;
198  }
199 
201  SYMENGINE_MPZ_WRAPPER_IMPLEMENT_COMMUTATIVE(+, mpz_add, +=)
203  SYMENGINE_MPZ_WRAPPER_IMPLEMENT_COMMUTATIVE(*, mpz_mul, *=)
205  SYMENGINE_MPZ_WRAPPER_IMPLEMENT_NON_COMMUTATIVE(-, mpz_sub, -=)
206 
207  template <
208  typename T,
209  typename std::enable_if<
210  std::is_integral<T>::value && std::is_unsigned<T>::value, int>::type
211  = 0>
212  inline friend mpz_wrapper operator-(const T b, const mpz_wrapper &a)
213  {
214  mpz_wrapper res;
215  mpz_ui_sub(res.get_mpz_t(), b, a.get_mpz_t());
216  return res;
217  }
219  SYMENGINE_MPZ_WRAPPER_IMPLEMENT_NON_COMMUTATIVE(/, mpz_tdiv_q, /=)
221  SYMENGINE_MPZ_WRAPPER_IMPLEMENT_NON_COMMUTATIVE(%, mpz_tdiv_r, %=)
222 
223  inline mpz_wrapper operator-() const
224  {
225  mpz_wrapper res;
226  mpz_neg(res.get_mpz_t(), mp);
227  return res;
228  }
229 
230  inline mpz_wrapper operator++()
231  {
232  mpz_add_ui(mp, mp, 1);
233  return *this;
234  }
235  inline mpz_wrapper operator++(int)
236  {
237  mpz_wrapper orig = *this;
238  ++(*this);
239  return orig;
240  }
241  inline mpz_wrapper operator--()
242  {
243  mpz_sub_ui(mp, mp, 1);
244  return *this;
245  }
246  inline mpz_wrapper operator--(int)
247  {
248  mpz_wrapper orig = *this;
249  --(*this);
250  return orig;
251  }
252 
254  SYMENGINE_MPZ_WRAPPER_IMPLEMENT_RELATIONAL(<, mpz_cmp, 0, >)
256  SYMENGINE_MPZ_WRAPPER_IMPLEMENT_RELATIONAL(<=, mpz_cmp, 0, >=)
258  SYMENGINE_MPZ_WRAPPER_IMPLEMENT_RELATIONAL(>, mpz_cmp, 0, <)
260  SYMENGINE_MPZ_WRAPPER_IMPLEMENT_RELATIONAL(>=, mpz_cmp, 0, <=)
262  SYMENGINE_MPZ_WRAPPER_IMPLEMENT_RELATIONAL(==, mpz_cmp, 0, ==)
264  SYMENGINE_MPZ_WRAPPER_IMPLEMENT_RELATIONAL(!=, mpz_cmp, 0, !=)
265 
266  inline mpz_wrapper operator<<=(unsigned long u)
267  {
268  mpz_mul_2exp(mp, mp, u);
269  return *this;
270  }
271  inline mpz_wrapper operator<<(unsigned long u) const
272  {
273  mpz_wrapper res;
274  mpz_mul_2exp(res.get_mpz_t(), mp, u);
275  return res;
276  }
277  inline mpz_wrapper operator>>=(unsigned long u)
278  {
279  mpz_tdiv_q_2exp(mp, mp, u);
280  return *this;
281  }
282  inline mpz_wrapper operator>>(unsigned long u) const
283  {
284  mpz_wrapper res;
285  mpz_tdiv_q_2exp(res.get_mpz_t(), mp, u);
286  return res;
287  }
288  inline unsigned long get_ui() const
289  {
290  return mpz_get_ui(mp);
291  }
292  inline signed long get_si() const
293  {
294  return mpz_get_si(mp);
295  }
296  inline double long get_d() const
297  {
298  return mpz_get_d(mp);
299  }
300  inline int fits_ulong_p() const
301  {
302  return mpz_fits_ulong_p(mp);
303  }
304  inline int fits_slong_p() const
305  {
306  return mpz_fits_slong_p(mp);
307  }
308 };
309 
310 class mpq_wrapper
311 {
312 private:
313  mpq_t mp;
314 
315 public:
316  mpq_ptr get_mpq_t()
317  {
318  return mp;
319  }
320  mpq_srcptr get_mpq_t() const
321  {
322  return mp;
323  }
324  mpq_wrapper()
325  {
326  mpq_init(mp);
327  }
328  mpq_wrapper(const mpz_t m)
329  {
330  mpq_init(mp);
331  mpz_set(mpq_numref(mp), m);
332  }
333  mpq_wrapper(const mpq_t m)
334  {
335  mpq_init(mp);
336  mpq_set(mp, m);
337  }
338  template <
339  typename T,
340  typename std::enable_if<
342  = 0>
343  mpq_wrapper(const T i)
344  {
345  mpq_init(mp);
346  mpz_set_ui(mpq_numref(mp), i);
347  }
348  template <
349  typename T,
350  typename std::enable_if<
352  = 0>
353  mpq_wrapper(const T i)
354  {
355  mpq_init(mp);
356  mpz_set_si(mpq_numref(mp), i);
357  }
358  mpq_wrapper(const mpz_wrapper &n, const mpz_wrapper &d = 1)
359  {
360  mpq_init(mp);
361  mpz_set(mpq_numref(mp), n.get_mpz_t());
362  mpz_set(mpq_denref(mp), d.get_mpz_t());
363  mpq_canonicalize(mp);
364  }
365  mpq_wrapper(const mpq_wrapper &other)
366  {
367  mpq_init(mp);
368  mpq_set(mp, other.get_mpq_t());
369  }
370  mpq_wrapper(mpq_wrapper &&other) SYMENGINE_NOEXCEPT
371  {
372  mpq_init(mp);
373  mpq_swap(mp, other.get_mpq_t());
374  }
375  mpq_wrapper &operator=(const mpq_wrapper &other)
376  {
377  mpq_set(mp, other.get_mpq_t());
378  return *this;
379  }
380  mpq_wrapper &operator=(mpq_wrapper &&other) SYMENGINE_NOEXCEPT
381  {
382  mpq_swap(mp, other.get_mpq_t());
383  return *this;
384  }
385  ~mpq_wrapper() SYMENGINE_NOEXCEPT
386  {
387  mpq_clear(mp);
388  }
389  const mpz_wrapper &get_den() const
390  {
391  return reinterpret_cast<const mpz_wrapper &>(*mpq_denref(mp));
392  }
393  const mpz_wrapper &get_num() const
394  {
395  return reinterpret_cast<const mpz_wrapper &>(*mpq_numref(mp));
396  }
397  mpz_wrapper &get_den()
398  {
399  return reinterpret_cast<mpz_wrapper &>(*mpq_denref(mp));
400  }
401  mpz_wrapper &get_num()
402  {
403  return reinterpret_cast<mpz_wrapper &>(*mpq_numref(mp));
404  }
405  friend mpq_wrapper operator+(const mpq_wrapper &a, const mpq_wrapper &b)
406  {
407  mpq_wrapper res;
408  mpq_add(res.get_mpq_t(), a.get_mpq_t(), b.get_mpq_t());
409  return res;
410  }
411  mpq_wrapper operator+=(const mpq_wrapper &a)
412  {
413  mpq_add(mp, mp, a.get_mpq_t());
414  return *this;
415  }
416  friend mpq_wrapper operator-(const mpq_wrapper &a, const mpq_wrapper &b)
417  {
418  mpq_wrapper res;
419  mpq_sub(res.get_mpq_t(), a.get_mpq_t(), b.get_mpq_t());
420  return res;
421  }
422  mpq_wrapper operator-=(const mpq_wrapper &a)
423  {
424  mpq_sub(mp, mp, a.get_mpq_t());
425  return *this;
426  }
427  mpq_wrapper operator-() const
428  {
429  mpq_wrapper res;
430  mpq_neg(res.get_mpq_t(), mp);
431  return res;
432  }
433  friend mpq_wrapper operator*(const mpq_wrapper &a, const mpq_wrapper &b)
434  {
435  mpq_wrapper res;
436  mpq_mul(res.get_mpq_t(), a.get_mpq_t(), b.get_mpq_t());
437  return res;
438  }
439  mpq_wrapper operator*=(const mpq_wrapper &a)
440  {
441  mpq_mul(mp, mp, a.get_mpq_t());
442  return *this;
443  }
444  friend mpq_wrapper operator/(const mpq_wrapper &a, const mpq_wrapper &b)
445  {
446  mpq_wrapper res;
447  mpq_div(res.get_mpq_t(), a.get_mpq_t(), b.get_mpq_t());
448  return res;
449  }
450  mpq_wrapper operator/=(const mpq_wrapper &a)
451  {
452  mpq_div(mp, mp, a.get_mpq_t());
453  return *this;
454  }
455  bool operator==(const mpq_wrapper &other) const
456  {
457  return mpq_cmp(mp, other.get_mpq_t()) == 0;
458  }
459  bool operator!=(const mpq_wrapper &other) const
460  {
461  return not(*this == other);
462  }
463  bool operator<(const mpq_wrapper &other) const
464  {
465  return mpq_cmp(mp, other.get_mpq_t()) < 0;
466  }
467  bool operator<=(const mpq_wrapper &other) const
468  {
469  return mpq_cmp(mp, other.get_mpq_t()) <= 0;
470  }
471  bool operator>(const mpq_wrapper &other) const
472  {
473  return mpq_cmp(mp, other.get_mpq_t()) > 0;
474  }
475  bool operator>=(const mpq_wrapper &other) const
476  {
477  return mpq_cmp(mp, other.get_mpq_t()) >= 0;
478  }
479  double get_d() const
480  {
481  return mpq_get_d(mp);
482  }
483  void canonicalize()
484  {
485  mpq_canonicalize(mp);
486  }
487 };
488 
489 } // namespace SymEngine
490 
491 #endif
492 
493 namespace SymEngine
494 {
495 
496 #if SYMENGINE_INTEGER_CLASS == SYMENGINE_FLINT
499 #elif SYMENGINE_INTEGER_CLASS == SYMENGINE_GMP
500 std::ostream &operator<<(std::ostream &os, const SymEngine::mpq_wrapper &f);
501 std::ostream &operator<<(std::ostream &os, const SymEngine::mpz_wrapper &f);
502 #endif
503 
504 } // namespace SymEngine
505 
506 #endif // SYMENGINE_MP_WRAPPER_H
T c_str(T... args)
Main namespace for SymEngine package.
Definition: add.cpp:19
std::ostream & operator<<(std::ostream &out, const SymEngine::Basic &p)
<< Operator
Definition: basic-inl.h:53
STL namespace.
T operator!=(T... args)