serialize-cereal.h
1 #ifndef SYMENGINE_SERIALIZE_CEREAL_H
2 #define SYMENGINE_SERIALIZE_CEREAL_H
3 
4 #include <cctype>
5 
6 #include <symengine/basic.h>
7 #include <symengine/number.h>
8 #include <symengine/integer.h>
9 #include <symengine/symbol.h>
10 #include <symengine/visitor.h>
11 #include <symengine/utilities/stream_fmt.h>
12 
13 #include <cereal/cereal.hpp>
14 #include <cereal/version.hpp>
15 #include <cereal/types/polymorphic.hpp>
16 #include <cereal/types/string.hpp>
17 #include <cereal/details/helpers.hpp>
18 #include <cereal/types/map.hpp>
19 #include <cereal/types/unordered_map.hpp>
20 #include <cereal/types/set.hpp>
21 #include <cereal/types/vector.hpp>
22 #include <cereal/types/utility.hpp>
23 #include <cereal/archives/portable_binary.hpp>
24 
25 namespace SymEngine
26 {
27 
28 template <class Archive>
29 inline void save_basic(Archive &ar, const Basic &b)
30 {
31  const auto t_code = b.get_type_code();
32  throw SerializationError(StreamFmt()
33  << __FILE__ << ":" << __LINE__
34 #ifndef _MSC_VER
35  << ": " << __PRETTY_FUNCTION__
36 #endif
37  << " not supported: " << type_code_name(t_code)
38  << " (" << t_code << ")"
39 #if !defined(NDEBUG)
40  << ", " << b.__str__()
41 #endif
42  );
43 }
44 template <class Archive>
45 inline void save_basic(Archive &ar, const Symbol &b)
46 {
47  ar(b.__str__());
48 }
49 template <class Archive>
50 inline void save_basic(Archive &ar, const Mul &b)
51 {
52  ar(b.get_coef());
53  ar(b.get_dict());
54 }
55 template <class Archive>
56 inline void save_basic(Archive &ar, const Add &b)
57 {
58  ar(b.get_coef());
59  ar(b.get_dict());
60 }
61 template <class Archive>
62 inline void save_basic(Archive &ar, const Pow &b)
63 {
64  ar(b.get_base());
65  ar(b.get_exp());
66 }
67 template <typename Archive>
68 void save_helper(Archive &ar, const integer_class &intgr)
69 {
71  s << intgr; // stream to string
72  ar(s.str());
73 }
74 template <typename Archive>
75 void save_helper(Archive &ar, const rational_class &rat)
76 {
77  integer_class num = get_num(rat);
78  integer_class den = get_den(rat);
79  save_helper(ar, num);
80  save_helper(ar, den);
81 }
82 // Following is an ugly hack for templated integer classes
83 // Not sure why a direct version doesn't work
84 template <typename Archive>
85 void save_basic(Archive &ar, const URatPoly &b)
86 {
87  ar(b.get_var());
88  const URatDict &urd = b.get_poly();
89  size_t l = urd.size();
90  ar(l);
91  for (auto &p : urd.dict_) {
92  unsigned int first = p.first;
93  const rational_class &second = p.second;
94  ar(first);
95  save_helper(ar, second);
96  }
97 }
98 template <class Archive>
99 inline void save_basic(Archive &ar, const Integer &b)
100 {
101  ar(b.__str__());
102 }
103 template <class Archive>
104 inline void save_basic(Archive &ar, const RealDouble &b)
105 {
106  ar(b.i);
107 }
108 template <class Archive>
109 inline void save_basic(Archive &ar, const Rational &b)
110 {
111  ar(b.get_num(), b.get_den());
112 }
113 template <class Archive>
114 inline void save_basic(Archive &ar, const ComplexBase &b)
115 {
116  ar(b.real_part(), b.imaginary_part());
117 }
118 template <class Archive>
119 inline void save_basic(Archive &ar, const Interval &b)
120 {
121  ar(b.get_left_open(), b.get_start(), b.get_right_open(), b.get_end());
122 }
123 template <class Archive>
124 inline void save_basic(Archive &ar, const BooleanAtom &b)
125 {
126  ar(b.get_val());
127 }
128 template <class Archive>
129 inline void save_basic(Archive &ar, const Infty &b)
130 {
131  ar(b.get_direction());
132 }
133 
134 template <class Archive>
135 inline void save_basic(Archive &ar, const NaN &b)
136 {
137 }
138 
139 template <class Archive>
140 inline void save_basic(Archive &ar, const Constant &b)
141 {
142  ar(b.get_name());
143 }
144 template <class Archive>
145 inline void save_basic(Archive &ar, const OneArgFunction &b)
146 {
147  ar(b.get_arg());
148 }
149 template <class Archive>
150 inline void save_basic(Archive &ar, const TwoArgFunction &b)
151 {
152  ar(b.get_arg1(), b.get_arg2());
153 }
154 
155 template <class Archive>
156 inline void save_basic(Archive &ar, const Relational &b)
157 {
158  ar(b.get_arg1(), b.get_arg2());
159 }
160 template <class Archive>
161 inline void save_basic(Archive &ar, const And &b)
162 {
163  ar(b.get_container());
164 }
165 template <class Archive>
166 inline void save_basic(Archive &ar, const Or &b)
167 {
168  ar(b.get_container());
169 }
170 template <class Archive>
171 inline void save_basic(Archive &ar, const Xor &b)
172 {
173  ar(b.get_container());
174 }
175 template <class Archive>
176 inline void save_basic(Archive &ar, const Not &b)
177 {
178  ar(b.get_arg());
179 }
180 template <class Archive>
181 inline void save_basic(Archive &ar, const Contains &b)
182 {
183  ar(b.get_expr(), b.get_set());
184 }
185 template <class Archive>
186 inline void save_basic(Archive &ar, const Piecewise &b)
187 {
188  ar(b.get_vec());
189 }
190 template <class Archive>
191 inline void save_basic(Archive &ar, const Reals &b)
192 {
193 }
194 template <class Archive>
195 inline void save_basic(Archive &ar, const Rationals &b)
196 {
197 }
198 template <class Archive>
199 inline void save_basic(Archive &ar, const EmptySet &b)
200 {
201 }
202 template <class Archive>
203 inline void save_basic(Archive &ar, const Integers &b)
204 {
205 }
206 template <class Archive>
207 inline void save_basic(Archive &ar, const UniversalSet &b)
208 {
209 }
210 template <class Archive>
211 inline void save_basic(Archive &ar, const Union &b)
212 {
213  ar(b.get_container());
214 }
215 template <class Archive>
216 inline void save_basic(Archive &ar, const Complement &b)
217 {
218  ar(b.get_universe(), b.get_container());
219 }
220 template <class Archive>
221 inline void save_basic(Archive &ar, const ImageSet &b)
222 {
223  ar(b.get_symbol(), b.get_expr(), b.get_baseset());
224 }
225 template <class Archive>
226 inline void save_basic(Archive &ar, const FiniteSet &b)
227 {
228  ar(b.get_container());
229 }
230 template <class Archive>
231 inline void save_basic(Archive &ar, const ConditionSet &b)
232 {
233  ar(b.get_symbol(), b.get_condition());
234 }
235 #ifdef HAVE_SYMENGINE_MPFR
236 template <class Archive>
237 inline void save_basic(Archive &ar, const RealMPFR &b)
238 {
239  ar(b.__str__(), b.get_prec());
240 }
241 #endif
242 template <class Archive>
243 inline void save_basic(Archive &ar, const GaloisField &b)
244 {
245  throw NotImplementedError("GaloisField saving is not implemented yet.");
246 }
247 template <class Archive>
248 inline void save_basic(Archive &ar, const SeriesCoeffInterface &)
249 {
250  throw NotImplementedError("Series saving is not implemented yet.");
251 }
252 template <class Archive>
253 inline void save_basic(Archive &ar, const MultiArgFunction &b)
254 {
255  ar(b.get_args());
256 }
257 template <class Archive>
258 inline void save_basic(Archive &ar, const FunctionSymbol &b)
259 {
260  ar(b.get_name(), b.get_args());
261 }
262 template <class Archive>
263 inline void save_basic(Archive &ar, const Derivative &b)
264 {
265  ar(b.get_arg(), b.get_symbols());
266 }
267 template <class Archive>
268 inline void save_basic(Archive &ar, const Subs &b)
269 {
270  ar(b.get_arg(), b.get_dict());
271 }
272 template <class Archive>
273 inline void save_basic(Archive &ar, const NumberWrapper &b)
274 {
275  throw NotImplementedError("NumberWrapper saving is not implemented yet.");
276 }
277 template <class Archive>
278 inline void save_basic(Archive &ar, const FunctionWrapper &b)
279 {
280  throw NotImplementedError("FunctionWrapper saving is not implemented yet.");
281 }
282 
283 template <class Archive>
284 inline void save_basic(Archive &ar, RCP<const Basic> const &ptr)
285 {
286 #if CEREAL_VERSION >= 10301
287  std::shared_ptr<void> sharedPtr = std::static_pointer_cast<void>(
288  std::make_shared<RCP<const Basic>>(ptr));
289  uint32_t id = ar.registerSharedPointer(sharedPtr);
290 #else
291  uint32_t id = ar.registerSharedPointer(ptr.get());
292 #endif
293  ar(CEREAL_NVP(id));
294 
295  if (id & cereal::detail::msb_32bit) {
296  TypeID type_code = ptr->get_type_code();
297  save_typeid(ar, type_code);
298  switch (type_code) {
299 #define SYMENGINE_ENUM(type, Class) \
300  case type: \
301  save_basic(ar, static_cast<const Class &>(*ptr)); \
302  break;
303 #include "symengine/type_codes.inc"
304 #undef SYMENGINE_ENUM
305  default:
306  save_basic(ar, *ptr);
307  }
308  }
309 }
310 
312 template <class Archive, class T>
313 inline void CEREAL_SAVE_FUNCTION_NAME(Archive &ar, RCP<const T> const &ptr)
314 {
315  save_basic(ar, rcp_static_cast<const Basic>(ptr));
316 }
317 template <class Archive>
318 RCP<const Basic> load_basic(Archive &ar, RCP<const RealDouble> &)
319 {
320  double val;
321  ar(val);
322  return real_double(val);
323 }
324 template <class Archive>
325 RCP<const Basic> load_basic(Archive &ar, RCP<const Infty> &)
326 {
327  RCP<const Number> direction;
328  ar(direction);
329  return Infty::from_direction(direction);
330 }
331 template <class Archive>
332 RCP<const Basic> load_basic(Archive &ar, RCP<const NaN> &)
333 {
334  return rcp_static_cast<const Basic>(Nan);
335 }
336 template <class Archive>
337 RCP<const Basic> load_basic(Archive &ar, RCP<const Symbol> &)
338 {
339  std::string name;
340  ar(name);
341  return symbol(name);
342 }
343 template <class Archive>
344 RCP<const Basic> load_basic(Archive &ar, RCP<const Mul> &)
345 {
346  RCP<const Number> coeff;
347  map_basic_basic dict;
348  ar(coeff);
349  ar(dict);
350  return make_rcp<const Mul>(coeff, std::move(dict));
351 }
352 template <class Archive>
353 RCP<const Basic> load_basic(Archive &ar, RCP<const Add> &)
354 {
355  RCP<const Number> coeff;
356  umap_basic_num dict;
357  ar(coeff);
358  ar(dict);
359  return make_rcp<const Add>(coeff, std::move(dict));
360 }
361 template <class Archive>
362 RCP<const Basic> load_basic(Archive &ar, RCP<const Pow> &)
363 {
364  RCP<const Basic> base, exp;
365  ar(base);
366  ar(exp);
367  return make_rcp<const Pow>(base, exp);
368 }
369 template <typename Archive>
370 void load_helper(Archive &ar, integer_class &intgr)
371 {
372  std::string int_str;
373  ar(int_str);
374  if (int_str.size() == 0) {
375  throw SerializationError("invalid integer");
376  }
377  if (not(int_str[0] == '-' or std::isdigit(int_str[0]))) {
378  throw SerializationError("invalid integer");
379  }
380  for (auto it = ++int_str.begin(); it < int_str.end(); it++) {
381  if (not std::isdigit(*it)) {
382  throw SerializationError("invalid integer");
383  }
384  }
385  intgr = integer_class(std::move(int_str));
386 }
387 template <typename Archive>
388 void load_helper(Archive &ar, const rational_class &rat)
389 {
390  integer_class num, den;
391  load_helper(ar, num);
392  load_helper(ar, den);
393 }
394 // Following is an ugly hack for templated integer classes
395 // Not sure why the other clean version doesn't work
396 template <typename Archive>
397 RCP<const Basic> load_basic(Archive &ar, const URatPoly &b)
398 {
399  RCP<const Basic> var;
400  size_t l;
401  ar(var);
402  ar(l);
404  auto hint = d.begin();
405  for (size_t i = 0; i < l; i++) {
406  unsigned int first;
407  rational_class second;
408  ar(first);
409  load_helper(ar, second);
410 #if !defined(__clang__) && (__GNUC__ == 4 && __GNUC_MINOR__ <= 7)
411  d.insert(hint, std::make_pair(std::move(first), std::move(second)));
412 #else
413  d.emplace_hint(hint, std::move(first), std::move(second));
414 #endif
415  }
416  return make_rcp<const URatPoly>(var, URatDict(std::move(d)));
417 }
418 template <class Archive>
419 RCP<const Basic> load_basic(Archive &ar, RCP<const Integer> &)
420 {
421  integer_class c;
422  load_helper(ar, c);
423  return integer(std::move(c));
424 }
425 template <class Archive>
426 RCP<const Basic> load_basic(Archive &ar, RCP<const Constant> &)
427 {
428  std::string name;
429  ar(name);
430  return constant(name);
431 }
432 template <class Archive>
433 RCP<const Basic> load_basic(Archive &ar, RCP<const Rational> &)
434 {
435  RCP<const Integer> num, den;
436  ar(num, den);
437  return Rational::from_two_ints(*num, *den);
438 }
439 template <class Archive>
440 RCP<const Basic> load_basic(Archive &ar, RCP<const Complex> &)
441 {
442  RCP<const Number> num, den;
443  ar(num, den);
444  return Complex::from_two_nums(*num, *den);
445 }
446 template <class Archive, class T>
447 RCP<const Basic>
448 load_basic(Archive &ar, RCP<const T> &,
450  int>::type * = nullptr)
451 {
452  RCP<const Number> num, den;
453  ar(num, den);
454  return addnum(num, mulnum(I, den));
455 }
456 template <class Archive>
457 RCP<const Basic> load_basic(Archive &ar, RCP<const Interval> &)
458 {
459  RCP<const Number> start, end;
460  bool left_open, right_open;
461  ar(left_open, start, right_open, end);
462  return make_rcp<const Interval>(start, end, left_open, right_open);
463 }
464 template <class Archive>
465 RCP<const Basic> load_basic(Archive &ar, RCP<const BooleanAtom> &)
466 {
467  bool val;
468  ar(val);
469  return boolean(val);
470 }
471 template <class Archive>
472 RCP<const Basic> load_basic(Archive &ar, RCP<const And> &)
473 {
474  set_boolean container;
475  ar(container);
476  return make_rcp<const And>(std::move(container));
477 }
478 template <class Archive>
479 RCP<const Basic> load_basic(Archive &ar, RCP<const Or> &)
480 {
481  set_boolean container;
482  ar(container);
483  return make_rcp<const Or>(std::move(container));
484 }
485 template <class Archive>
486 RCP<const Basic> load_basic(Archive &ar, RCP<const Xor> &)
487 {
488  vec_boolean container;
489  ar(container);
490  return make_rcp<const Xor>(std::move(container));
491 }
492 template <class Archive>
493 RCP<const Basic> load_basic(Archive &ar, RCP<const Not> &)
494 {
495  RCP<const Boolean> arg;
496  ar(arg);
497  return make_rcp<const Not>(arg);
498 }
499 template <class Archive>
500 RCP<const Basic> load_basic(Archive &ar, RCP<const Piecewise> &)
501 {
502  PiecewiseVec vec;
503  ar(vec);
504  return make_rcp<const Piecewise>(std::move(vec));
505 }
506 template <class Archive>
507 RCP<const Basic> load_basic(Archive &ar, RCP<const Contains> &)
508 {
509  RCP<const Basic> expr;
510  RCP<const Set> contains_set;
511  ar(expr, contains_set);
512  return make_rcp<const Contains>(expr, contains_set);
513 }
514 template <class Archive>
515 RCP<const Basic> load_basic(Archive &ar, RCP<const Reals> &)
516 {
517  return reals();
518 }
519 template <class Archive>
520 RCP<const Basic> load_basic(Archive &ar, RCP<const Rationals> &)
521 {
522  return rationals();
523 }
524 template <class Archive>
525 RCP<const Basic> load_basic(Archive &ar, RCP<const EmptySet> &)
526 {
527  return emptyset();
528 }
529 template <class Archive>
530 RCP<const Basic> load_basic(Archive &ar, RCP<const Integers> &)
531 {
532  return integers();
533 }
534 template <class Archive>
535 RCP<const Basic> load_basic(Archive &ar, RCP<const UniversalSet> &)
536 {
537  return universalset();
538 }
539 template <class Archive>
540 RCP<const Basic> load_basic(Archive &ar, RCP<const Union> &)
541 {
542  set_set union_set;
543  ar(union_set);
544  return make_rcp<const Union>(std::move(union_set));
545 }
546 template <class Archive>
547 RCP<const Basic> load_basic(Archive &ar, RCP<const Complement> &)
548 {
549  RCP<const Set> universe, container;
550  ar(universe, container);
551  return make_rcp<const Complement>(universe, container);
552 }
553 template <class Archive>
554 RCP<const Basic> load_basic(Archive &ar, RCP<const ImageSet> &)
555 {
556  RCP<const Basic> sym, expr;
557  RCP<const Set> base;
558  ar(sym, expr, base);
559  return make_rcp<const ImageSet>(sym, expr, base);
560 }
561 template <class Archive>
562 RCP<const Basic> load_basic(Archive &ar, RCP<const FiniteSet> &)
563 {
564  set_basic set;
565  ar(set);
566  return make_rcp<const FiniteSet>(set);
567 }
568 template <class Archive>
569 RCP<const Basic> load_basic(Archive &ar, RCP<const ConditionSet> &)
570 {
571  RCP<const Basic> sym;
572  RCP<const Boolean> condition;
573  ar(sym, condition);
574  return make_rcp<const ConditionSet>(sym, condition);
575 }
576 #ifdef HAVE_SYMENGINE_MPFR
577 template <class Archive>
578 RCP<const Basic> load_basic(Archive &ar, RCP<const RealMPFR> &)
579 {
580  std::string num;
581  mpfr_prec_t prec;
582  ar(num, prec);
583  return make_rcp<const RealMPFR>(mpfr_class(num, prec, 10));
584 }
585 #endif
586 template <class Archive>
587 RCP<const Basic> load_basic(Archive &ar, RCP<const Derivative> &)
588 {
589  RCP<const Basic> arg;
590  multiset_basic set;
591  ar(arg, set);
592  return make_rcp<const Derivative>(arg, std::move(set));
593 }
594 template <class Archive>
595 RCP<const Basic> load_basic(Archive &ar, RCP<const Subs> &)
596 {
597  RCP<const Basic> arg;
598  map_basic_basic dict;
599  ar(arg, dict);
600  return make_rcp<const Subs>(arg, std::move(dict));
601 }
602 
603 template <class Archive, class T>
604 RCP<const Basic>
605 load_basic(Archive &ar, RCP<const T> &,
607  int>::type * = nullptr)
608 {
609  RCP<const Basic> arg;
610  ar(arg);
611  return make_rcp<const T>(arg);
612 }
613 template <class Archive, class T>
614 RCP<const Basic>
615 load_basic(Archive &ar, RCP<const T> &,
617  int>::type * = nullptr)
618 {
619  RCP<const Basic> arg1, arg2;
620  ar(arg1, arg2);
621  return make_rcp<const T>(arg1, arg2);
622 }
623 template <class Archive>
624 RCP<const Basic> load_basic(Archive &ar, RCP<const FunctionSymbol> &)
625 {
626  std::string name;
627  vec_basic vec;
628  ar(name, vec);
629  return make_rcp<const FunctionSymbol>(name, std::move(vec));
630 }
631 template <class Archive>
632 RCP<const Basic> load_basic(Archive &ar, RCP<const FunctionWrapper> &)
633 {
634  throw SerializationError(StreamFmt()
635  << __FILE__ << ":" << __LINE__
636 #ifndef _MSC_VER
637  << ": " << __PRETTY_FUNCTION__
638 #endif
639  << "Loading of this type is not implemented.");
640 }
641 template <class Archive, class T>
642 RCP<const Basic>
643 load_basic(Archive &ar, RCP<const T> &,
645  int>::type * = nullptr)
646 {
647  vec_basic args;
648  ar(args);
649  return make_rcp<const T>(std::move(args));
650 }
651 template <class Archive, class T>
652 RCP<const Basic>
653 load_basic(Archive &ar, RCP<const T> &,
655  int>::type * = nullptr)
656 {
657  RCP<const Basic> arg1, arg2;
658  ar(arg1, arg2);
659  return make_rcp<const T>(arg1, arg2);
660 }
661 template <class Archive, class T>
662 RCP<const Basic> load_basic(
663  Archive &ar, RCP<const T> &,
669  int>::type * = nullptr)
670 {
671  throw SerializationError(StreamFmt()
672  << __FILE__ << ":" << __LINE__
673 #ifndef _MSC_VER
674  << ": " << __PRETTY_FUNCTION__
675 #endif
676  << "Loading of this type is not implemented.");
677 }
678 
679 template <class Archive>
680 inline void save_typeid(Archive &ar, TypeID &t)
681 {
682  uint8_t i = t;
683  static_assert(TypeID::TypeID_Count < (1 << 8),
684  "TypeID cannot be saved to a 8 bit int.");
685  ar(i);
686 }
687 
688 template <class Archive>
689 inline void load_typeid(Archive &ar, TypeID &t)
690 {
691  uint8_t i;
692  ar(i);
693  if (i >= TypeID::TypeID_Count) {
694  throw SerializationError("TypeID out of range");
695  }
696  t = static_cast<TypeID>(i);
697 }
698 
700 template <class Archive, class T>
701 inline void CEREAL_LOAD_FUNCTION_NAME(Archive &ar, RCP<const T> &ptr)
702 {
703  try {
704  uint32_t id;
705  ar(CEREAL_NVP(id));
706 
707  if (id & cereal::detail::msb_32bit) {
708  TypeID type_code;
709  load_typeid(ar, type_code);
710  switch (type_code) {
711 #define SYMENGINE_ENUM(type_enum, Class) \
712  case type_enum: { \
713  if (not std::is_base_of<T, Class>::value) { \
714  throw SerializationError("Cannot convert to given type"); \
715  } else { \
716  RCP<const Class> dummy_ptr; \
717  RCP<const Basic> basic_ptr = load_basic(ar, dummy_ptr); \
718  ptr = rcp_dynamic_cast<const T>(basic_ptr); \
719  break; \
720  } \
721  }
722 #include "symengine/type_codes.inc"
723 #undef SYMENGINE_ENUM
724  default:
725  throw SerializationError("Unknown typeID");
726  }
727  std::shared_ptr<void> sharedPtr = std::static_pointer_cast<void>(
728  std::make_shared<RCP<const Basic>>(
729  rcp_static_cast<const Basic>(ptr)));
730 
731  ar.registerSharedPointer(id, sharedPtr);
732  } else if (id == 0) {
733  throw SerializationError("Unknown serialization error");
734  } else {
736  = std::static_pointer_cast<RCP<const Basic>>(
737  ar.getSharedPointer(id));
738  RCP<const Basic> basic_ptr = *sharedPtr.get();
739  ptr = rcp_dynamic_cast<const T>(basic_ptr);
740  }
741  } catch (cereal::Exception &e) {
742  throw SerializationError(e.what());
743  }
744 }
745 } // namespace SymEngine
746 #endif // SYMENGINE_SERIALIZE_CEREAL_H
The base class for SymEngine.
T begin(T... args)
static RCP< const Number > from_two_nums(const Number &re, const Number &im)
Definition: complex.cpp:109
static RCP< const Number > from_two_ints(const Integer &n, const Integer &d)
Definition: rational.cpp:44
T emplace_hint(T... args)
T end(T... args)
T get(T... args)
T insert(T... args)
T isdigit(T... args)
T make_pair(T... args)
T make_shared(T... args)
T move(T... args)
Main namespace for SymEngine package.
Definition: add.cpp:19
std::enable_if< std::is_integral< T >::value, RCP< const Integer > >::type integer(T i)
Definition: integer.h:197
RCP< const Symbol > symbol(const std::string &name)
inline version to return Symbol
Definition: symbol.h:82
RCP< const Number > mulnum(const RCP< const Number > &self, const RCP< const Number > &other)
Multiply self and other
Definition: number.h:93
RCP< const Reals > reals()
Definition: sets.h:560
RCP< const EmptySet > emptyset()
Definition: sets.h:590
RCP< const Integers > integers()
Definition: sets.h:572
RCP< const Basic > exp(const RCP< const Basic > &x)
Returns the natural exponential function E**x = pow(E, x)
Definition: pow.cpp:271
RCP< const UniversalSet > universalset()
Definition: sets.h:596
TypeID
Definition: basic.h:43
@ TypeID_Count
Definition: basic.h:52
RCP< const Constant > constant(const std::string &name)
inline version to return Constant
Definition: constants.h:53
void CEREAL_SAVE_FUNCTION_NAME(Archive &ar, RCP< const T > const &ptr)
Saving for SymEngine::RCP.
void CEREAL_LOAD_FUNCTION_NAME(Archive &ar, RCP< const T > &ptr)
Loading for SymEngine::RCP.
RCP< const Rationals > rationals()
Definition: sets.h:566
RCP< const Number > addnum(const RCP< const Number > &self, const RCP< const Number > &other)
Add self and other
Definition: number.h:81
T size(T... args)
T str(T... args)