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