1#ifndef SYMENGINE_SERIALIZE_CEREAL_H
2#define SYMENGINE_SERIALIZE_CEREAL_H
8#include <symengine/utilities/stream_fmt.h>
10#include <cereal/cereal.hpp>
11#include <cereal/version.hpp>
12#include <cereal/types/polymorphic.hpp>
13#include <cereal/types/string.hpp>
14#include <cereal/details/helpers.hpp>
15#include <cereal/types/map.hpp>
16#include <cereal/types/unordered_map.hpp>
17#include <cereal/types/set.hpp>
18#include <cereal/types/vector.hpp>
19#include <cereal/types/utility.hpp>
20#include <cereal/archives/portable_binary.hpp>
25template <
class Archive>
26inline void save_basic(Archive &ar,
const Basic &b)
28 const auto t_code = b.get_type_code();
29 throw SerializationError(StreamFmt()
30 << __FILE__ <<
":" << __LINE__
32 <<
": " << __PRETTY_FUNCTION__
34 <<
" not supported: " << type_code_name(t_code)
35 <<
" (" << t_code <<
")"
37 <<
", " << b.__str__()
41template <
class Archive>
42inline void save_basic(Archive &ar,
const Symbol &b)
46template <
class Archive>
47inline void save_basic(Archive &ar,
const Mul &b)
52template <
class Archive>
53inline void save_basic(Archive &ar,
const Add &b)
58template <
class Archive>
59inline void save_basic(Archive &ar,
const Pow &b)
64template <
typename Archive>
65void save_helper(Archive &ar,
const integer_class &intgr)
71template <
typename Archive>
72void save_helper(Archive &ar,
const rational_class &rat)
74 integer_class num = get_num(rat);
75 integer_class den = get_den(rat);
81template <
typename Archive>
82void save_basic(Archive &ar,
const URatPoly &b)
85 const URatDict &urd = b.get_poly();
86 size_t l = urd.size();
88 for (
auto &p : urd.dict_) {
89 unsigned int first = p.first;
90 const rational_class &second = p.second;
92 save_helper(ar, second);
95template <
class Archive>
96inline void save_basic(Archive &ar,
const Integer &b)
100template <
class Archive>
101inline void save_basic(Archive &ar,
const RealDouble &b)
105template <
class Archive>
106inline void save_basic(Archive &ar,
const Rational &b)
108 ar(b.get_num(), b.get_den());
110template <
class Archive>
111inline void save_basic(Archive &ar,
const ComplexBase &b)
113 ar(b.real_part(), b.imaginary_part());
115template <
class Archive>
116inline void save_basic(Archive &ar,
const Interval &b)
118 ar(b.get_left_open(), b.get_start(), b.get_right_open(), b.get_end());
120template <
class Archive>
121inline void save_basic(Archive &ar,
const BooleanAtom &b)
125template <
class Archive>
126inline void save_basic(Archive &ar,
const Infty &b)
128 ar(b.get_direction());
131template <
class Archive>
132inline void save_basic(Archive &ar,
const NaN &b)
136template <
class Archive>
137inline void save_basic(Archive &ar,
const Constant &b)
141template <
class Archive>
142inline void save_basic(Archive &ar,
const OneArgFunction &b)
146template <
class Archive>
147inline void save_basic(Archive &ar,
const TwoArgFunction &b)
149 ar(b.get_arg1(), b.get_arg2());
152template <
class Archive>
153inline void save_basic(Archive &ar,
const Relational &b)
155 ar(b.get_arg1(), b.get_arg2());
157template <
class Archive>
158inline void save_basic(Archive &ar,
const And &b)
160 ar(b.get_container());
162template <
class Archive>
163inline void save_basic(Archive &ar,
const Or &b)
165 ar(b.get_container());
167template <
class Archive>
168inline void save_basic(Archive &ar,
const Xor &b)
170 ar(b.get_container());
172template <
class Archive>
173inline void save_basic(Archive &ar,
const Not &b)
177template <
class Archive>
178inline void save_basic(Archive &ar,
const Contains &b)
180 ar(b.get_expr(), b.get_set());
182template <
class Archive>
183inline void save_basic(Archive &ar,
const Piecewise &b)
187template <
class Archive>
188inline void save_basic(Archive &ar,
const Reals &b)
191template <
class Archive>
192inline void save_basic(Archive &ar,
const Rationals &b)
195template <
class Archive>
196inline void save_basic(Archive &ar,
const EmptySet &b)
199template <
class Archive>
200inline void save_basic(Archive &ar,
const Integers &b)
203template <
class Archive>
204inline void save_basic(Archive &ar,
const UniversalSet &b)
207template <
class Archive>
208inline void save_basic(Archive &ar,
const Union &b)
210 ar(b.get_container());
212template <
class Archive>
213inline void save_basic(Archive &ar,
const Complement &b)
215 ar(b.get_universe(), b.get_container());
217template <
class Archive>
218inline void save_basic(Archive &ar,
const ImageSet &b)
220 ar(b.get_symbol(), b.get_expr(), b.get_baseset());
222template <
class Archive>
223inline void save_basic(Archive &ar,
const FiniteSet &b)
225 ar(b.get_container());
227template <
class Archive>
228inline void save_basic(Archive &ar,
const ConditionSet &b)
230 ar(b.get_symbol(), b.get_condition());
232#ifdef HAVE_SYMENGINE_MPFR
233template <
class Archive>
234inline void save_basic(Archive &ar,
const RealMPFR &b)
236 ar(b.__str__(), b.get_prec());
239template <
class Archive>
240inline void save_basic(Archive &ar,
const GaloisField &b)
242 throw NotImplementedError(
"GaloisField saving is not implemented yet.");
244template <
class Archive>
245inline void save_basic(Archive &ar,
const SeriesCoeffInterface &)
247 throw NotImplementedError(
"Series saving is not implemented yet.");
249template <
class Archive>
250inline void save_basic(Archive &ar,
const MultiArgFunction &b)
254template <
class Archive>
255inline void save_basic(Archive &ar,
const FunctionSymbol &b)
257 ar(b.get_name(), b.get_args());
259template <
class Archive>
260inline void save_basic(Archive &ar,
const Derivative &b)
262 ar(b.get_arg(), b.get_symbols());
264template <
class Archive>
265inline void save_basic(Archive &ar,
const Subs &b)
267 ar(b.get_arg(), b.get_dict());
269template <
class Archive>
270inline void save_basic(Archive &ar,
const NumberWrapper &b)
272 throw NotImplementedError(
"NumberWrapper saving is not implemented yet.");
274template <
class Archive>
275inline void save_basic(Archive &ar,
const FunctionWrapper &b)
277 throw NotImplementedError(
"FunctionWrapper saving is not implemented yet.");
280template <
class Archive>
281inline void save_basic(Archive &ar, RCP<const Basic>
const &ptr)
283#if CEREAL_VERSION >= 10301
286 uint32_t
id = ar.registerSharedPointer(sharedPtr);
288 uint32_t
id = ar.registerSharedPointer(ptr.get());
292 if (
id & cereal::detail::msb_32bit) {
293 ar(ptr->get_type_code());
294 switch (ptr->get_type_code()) {
295#define SYMENGINE_ENUM(type, Class) \
297 save_basic(ar, static_cast<const Class &>(*ptr)); \
299#include "symengine/type_codes.inc"
302 save_basic(ar, *ptr);
308template <
class Archive,
class T>
311 save_basic(ar, rcp_static_cast<const Basic>(ptr));
313template <
class Archive>
314RCP<const Basic> load_basic(Archive &ar, RCP<const RealDouble> &)
318 return real_double(val);
320template <
class Archive>
321RCP<const Basic> load_basic(Archive &ar, RCP<const Infty> &)
323 RCP<const Number> direction;
325 return Infty::from_direction(direction);
327template <
class Archive>
328RCP<const Basic> load_basic(Archive &ar, RCP<const NaN> &)
330 return rcp_static_cast<const Basic>(Nan);
332template <
class Archive>
333RCP<const Basic> load_basic(Archive &ar, RCP<const Symbol> &)
339template <
class Archive>
340RCP<const Basic> load_basic(Archive &ar, RCP<const Mul> &)
342 RCP<const Number> coeff;
343 map_basic_basic dict;
346 return make_rcp<const Mul>(coeff,
std::move(dict));
348template <
class Archive>
349RCP<const Basic> load_basic(Archive &ar, RCP<const Add> &)
351 RCP<const Number> coeff;
355 return make_rcp<const Add>(coeff,
std::move(dict));
357template <
class Archive>
358RCP<const Basic> load_basic(Archive &ar, RCP<const Pow> &)
360 RCP<const Basic> base,
exp;
363 return make_rcp<const Pow>(base,
exp);
365template <
typename Archive>
366void load_helper(Archive &ar, integer_class &intgr)
370 intgr = integer_class(
std::move(int_str));
372template <
typename Archive>
373void load_helper(Archive &ar,
const rational_class &rat)
375 integer_class num, den;
376 load_helper(ar, num);
377 load_helper(ar, den);
381template <
typename Archive>
382RCP<const Basic> load_basic(Archive &ar,
const URatPoly &b)
384 RCP<const Basic> var;
389 auto hint = d.
begin();
390 for (
size_t i = 0; i < l; i++) {
392 rational_class second;
394 load_helper(ar, second);
395#if !defined(__clang__) && (__GNUC__ == 4 && __GNUC_MINOR__ <= 7)
401 return make_rcp<const URatPoly>(var, URatDict(
std::move(d)));
403template <
class Archive>
404RCP<const Basic> load_basic(Archive &ar, RCP<const Integer> &)
408 return integer(integer_class(int_str));
410template <
class Archive>
411RCP<const Basic> load_basic(Archive &ar, RCP<const Constant> &)
417template <
class Archive>
418RCP<const Basic> load_basic(Archive &ar, RCP<const Rational> &)
420 RCP<const Integer> num, den;
424template <
class Archive>
425RCP<const Basic> load_basic(Archive &ar, RCP<const Complex> &)
427 RCP<const Number> num, den;
431template <
class Archive,
class T>
433load_basic(Archive &ar, RCP<const T> &,
435 int>::type * =
nullptr)
437 RCP<const Number> num, den;
441template <
class Archive>
442RCP<const Basic> load_basic(Archive &ar, RCP<const Interval> &)
444 RCP<const Number> start,
end;
445 bool left_open, right_open;
446 ar(left_open, start, right_open, end);
447 return make_rcp<const Interval>(start, end, left_open, right_open);
449template <
class Archive>
450RCP<const Basic> load_basic(Archive &ar, RCP<const BooleanAtom> &)
456template <
class Archive>
457RCP<const Basic> load_basic(Archive &ar, RCP<const And> &)
459 set_boolean container;
461 return make_rcp<const And>(
std::move(container));
463template <
class Archive>
464RCP<const Basic> load_basic(Archive &ar, RCP<const Or> &)
466 set_boolean container;
468 return make_rcp<const Or>(
std::move(container));
470template <
class Archive>
471RCP<const Basic> load_basic(Archive &ar, RCP<const Xor> &)
473 vec_boolean container;
475 return make_rcp<const Xor>(
std::move(container));
477template <
class Archive>
478RCP<const Basic> load_basic(Archive &ar, RCP<const Not> &)
480 RCP<const Boolean> arg;
482 return make_rcp<const Not>(arg);
484template <
class Archive>
485RCP<const Basic> load_basic(Archive &ar, RCP<const Piecewise> &)
489 return make_rcp<const Piecewise>(
std::move(vec));
491template <
class Archive>
492RCP<const Basic> load_basic(Archive &ar, RCP<const Contains> &)
494 RCP<const Basic> expr;
495 RCP<const Set> contains_set;
496 ar(expr, contains_set);
497 return make_rcp<const Contains>(expr, contains_set);
499template <
class Archive>
500RCP<const Basic> load_basic(Archive &ar, RCP<const Reals> &)
504template <
class Archive>
505RCP<const Basic> load_basic(Archive &ar, RCP<const Rationals> &)
509template <
class Archive>
510RCP<const Basic> load_basic(Archive &ar, RCP<const EmptySet> &)
514template <
class Archive>
515RCP<const Basic> load_basic(Archive &ar, RCP<const Integers> &)
519template <
class Archive>
520RCP<const Basic> load_basic(Archive &ar, RCP<const UniversalSet> &)
524template <
class Archive>
525RCP<const Basic> load_basic(Archive &ar, RCP<const Union> &)
529 return make_rcp<const Union>(
std::move(union_set));
531template <
class Archive>
532RCP<const Basic> load_basic(Archive &ar, RCP<const Complement> &)
534 RCP<const Set> universe, container;
535 ar(universe, container);
536 return make_rcp<const Complement>(universe, container);
538template <
class Archive>
539RCP<const Basic> load_basic(Archive &ar, RCP<const ImageSet> &)
541 RCP<const Basic> sym, expr;
544 return make_rcp<const ImageSet>(sym, expr, base);
546template <
class Archive>
547RCP<const Basic> load_basic(Archive &ar, RCP<const FiniteSet> &)
551 return make_rcp<const FiniteSet>(set);
553template <
class Archive>
554RCP<const Basic> load_basic(Archive &ar, RCP<const ConditionSet> &)
556 RCP<const Basic> sym;
557 RCP<const Boolean> condition;
559 return make_rcp<const ConditionSet>(sym, condition);
561#ifdef HAVE_SYMENGINE_MPFR
562template <
class Archive>
563RCP<const Basic> load_basic(Archive &ar, RCP<const RealMPFR> &)
568 return make_rcp<const RealMPFR>(mpfr_class(num, prec, 10));
571template <
class Archive>
572RCP<const Basic> load_basic(Archive &ar, RCP<const Derivative> &)
574 RCP<const Basic> arg;
577 return make_rcp<const Derivative>(arg,
std::move(set));
579template <
class Archive>
580RCP<const Basic> load_basic(Archive &ar, RCP<const Subs> &)
582 RCP<const Basic> arg;
583 map_basic_basic dict;
585 return make_rcp<const Subs>(arg,
std::move(dict));
588template <
class Archive,
class T>
590load_basic(Archive &ar, RCP<const T> &,
592 int>::type * =
nullptr)
594 RCP<const Basic> arg;
596 return make_rcp<const T>(arg);
598template <
class Archive,
class T>
600load_basic(Archive &ar, RCP<const T> &,
602 int>::type * =
nullptr)
604 RCP<const Basic> arg1, arg2;
606 return make_rcp<const T>(arg1, arg2);
608template <
class Archive>
609RCP<const Basic> load_basic(Archive &ar, RCP<const FunctionSymbol> &)
614 return make_rcp<const FunctionSymbol>(name,
std::move(vec));
616template <
class Archive>
617RCP<const Basic> load_basic(Archive &ar, RCP<const FunctionWrapper> &)
619 throw SerializationError(StreamFmt()
620 << __FILE__ <<
":" << __LINE__
622 <<
": " << __PRETTY_FUNCTION__
624 <<
"Loading of this type is not implemented.");
626template <
class Archive,
class T>
628load_basic(Archive &ar, RCP<const T> &,
630 int>::type * =
nullptr)
634 return make_rcp<const T>(
std::move(args));
636template <
class Archive,
class T>
638load_basic(Archive &ar, RCP<const T> &,
640 int>::type * =
nullptr)
642 RCP<const Basic> arg1, arg2;
644 return make_rcp<const T>(arg1, arg2);
646template <
class Archive,
class T>
647RCP<const Basic> load_basic(
648 Archive &ar, RCP<const T> &,
654 int>::type * =
nullptr)
656 throw SerializationError(StreamFmt()
657 << __FILE__ <<
":" << __LINE__
659 <<
": " << __PRETTY_FUNCTION__
661 <<
"Loading of this type is not implemented.");
665template <
class Archive,
class T>
671 if (
id & cereal::detail::msb_32bit) {
675#define SYMENGINE_ENUM(type_enum, Class) \
677 if (not std::is_base_of<T, Class>::value) { \
678 throw std::runtime_error("Cannot convert to type."); \
680 RCP<const Class> dummy_ptr; \
681 ptr = rcp_static_cast<const T>( \
682 rcp_static_cast<const Basic>(load_basic(ar, dummy_ptr))); \
686#include "symengine/type_codes.inc"
694 ar.registerSharedPointer(
id, sharedPtr);
697 = std::static_pointer_cast<RCP<const T>>(ar.getSharedPointer(
id));
698 ptr = *sharedPtr.
get();
The base class for SymEngine.
static RCP< const Number > from_two_nums(const Number &re, const Number &im)
static RCP< const Number > from_two_ints(const Integer &n, const Integer &d)
T emplace_hint(T... args)
Main namespace for SymEngine package.
RCP< const Reals > reals()
RCP< const EmptySet > emptyset()
RCP< const UniversalSet > universalset()
RCP< const Integers > integers()
RCP< const Number > addnum(const RCP< const Number > &self, const RCP< const Number > &other)
Add self and other
RCP< const Basic > exp(const RCP< const Basic > &x)
Returns the natural exponential function E**x = pow(E, x)
RCP< const Rationals > rationals()
RCP< const Symbol > symbol(const std::string &name)
inline version to return Symbol
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.
std::enable_if< std::is_integral< T >::value, RCP< constInteger > >::type integer(T i)
RCP< const Constant > constant(const std::string &name)
inline version to return Constant
RCP< const Number > mulnum(const RCP< const Number > &self, const RCP< const Number > &other)
Multiply self and other