Loading...
Searching...
No Matches
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
95namespace SymEngine
96{
97
98class mpz_wrapper
99{
100private:
101 mpz_t mp;
102
103public:
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
310class mpq_wrapper
311{
312private:
313 mpq_t mp;
314
315public:
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
493namespace SymEngine
494{
495
496#if SYMENGINE_INTEGER_CLASS == SYMENGINE_FLINT
499#elif SYMENGINE_INTEGER_CLASS == SYMENGINE_GMP
500std::ostream &operator<<(std::ostream &os, const SymEngine::mpq_wrapper &f);
501std::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:104
STL namespace.
T operator!=(T... args)