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