1 #ifndef SYMENGINE_SERIALIZE_CEREAL_H
2 #define SYMENGINE_SERIALIZE_CEREAL_H
11 #include <symengine/utilities/stream_fmt.h>
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>
28 template <
class Archive>
29 inline void save_basic(Archive &ar,
const Basic &b)
31 const auto t_code = b.get_type_code();
32 throw SerializationError(StreamFmt()
33 << __FILE__ <<
":" << __LINE__
35 <<
": " << __PRETTY_FUNCTION__
37 <<
" not supported: " << type_code_name(t_code)
38 <<
" (" << t_code <<
")"
40 <<
", " << b.__str__()
44 template <
class Archive>
45 inline void save_basic(Archive &ar,
const Symbol &b)
49 template <
class Archive>
50 inline void save_basic(Archive &ar,
const Mul &b)
55 template <
class Archive>
56 inline void save_basic(Archive &ar,
const Add &b)
61 template <
class Archive>
62 inline void save_basic(Archive &ar,
const Pow &b)
67 template <
typename Archive>
68 void save_helper(Archive &ar,
const integer_class &intgr)
74 template <
typename Archive>
75 void save_helper(Archive &ar,
const rational_class &rat)
77 integer_class num = get_num(rat);
78 integer_class den = get_den(rat);
84 template <
typename Archive>
85 void save_basic(Archive &ar,
const URatPoly &b)
88 const URatDict &urd = b.get_poly();
89 size_t l = urd.size();
91 for (
auto &p : urd.dict_) {
92 unsigned int first = p.first;
93 const rational_class &second = p.second;
95 save_helper(ar, second);
98 template <
class Archive>
99 inline void save_basic(Archive &ar,
const Integer &b)
103 template <
class Archive>
104 inline void save_basic(Archive &ar,
const RealDouble &b)
108 template <
class Archive>
109 inline void save_basic(Archive &ar,
const Rational &b)
111 ar(b.get_num(), b.get_den());
113 template <
class Archive>
114 inline void save_basic(Archive &ar,
const ComplexBase &b)
116 ar(b.real_part(), b.imaginary_part());
118 template <
class Archive>
119 inline void save_basic(Archive &ar,
const Interval &b)
121 ar(b.get_left_open(), b.get_start(), b.get_right_open(), b.get_end());
123 template <
class Archive>
124 inline void save_basic(Archive &ar,
const BooleanAtom &b)
128 template <
class Archive>
129 inline void save_basic(Archive &ar,
const Infty &b)
131 ar(b.get_direction());
134 template <
class Archive>
135 inline void save_basic(Archive &ar,
const NaN &b)
139 template <
class Archive>
140 inline void save_basic(Archive &ar,
const Constant &b)
144 template <
class Archive>
145 inline void save_basic(Archive &ar,
const OneArgFunction &b)
149 template <
class Archive>
150 inline void save_basic(Archive &ar,
const TwoArgFunction &b)
152 ar(b.get_arg1(), b.get_arg2());
155 template <
class Archive>
156 inline void save_basic(Archive &ar,
const Relational &b)
158 ar(b.get_arg1(), b.get_arg2());
160 template <
class Archive>
161 inline void save_basic(Archive &ar,
const And &b)
163 ar(b.get_container());
165 template <
class Archive>
166 inline void save_basic(Archive &ar,
const Or &b)
168 ar(b.get_container());
170 template <
class Archive>
171 inline void save_basic(Archive &ar,
const Xor &b)
173 ar(b.get_container());
175 template <
class Archive>
176 inline void save_basic(Archive &ar,
const Not &b)
180 template <
class Archive>
181 inline void save_basic(Archive &ar,
const Contains &b)
183 ar(b.get_expr(), b.get_set());
185 template <
class Archive>
186 inline void save_basic(Archive &ar,
const Piecewise &b)
190 template <
class Archive>
191 inline void save_basic(Archive &ar,
const Reals &b)
194 template <
class Archive>
195 inline void save_basic(Archive &ar,
const Rationals &b)
198 template <
class Archive>
199 inline void save_basic(Archive &ar,
const EmptySet &b)
202 template <
class Archive>
203 inline void save_basic(Archive &ar,
const Integers &b)
206 template <
class Archive>
207 inline void save_basic(Archive &ar,
const UniversalSet &b)
210 template <
class Archive>
211 inline void save_basic(Archive &ar,
const Union &b)
213 ar(b.get_container());
215 template <
class Archive>
216 inline void save_basic(Archive &ar,
const Complement &b)
218 ar(b.get_universe(), b.get_container());
220 template <
class Archive>
221 inline void save_basic(Archive &ar,
const ImageSet &b)
223 ar(b.get_symbol(), b.get_expr(), b.get_baseset());
225 template <
class Archive>
226 inline void save_basic(Archive &ar,
const FiniteSet &b)
228 ar(b.get_container());
230 template <
class Archive>
231 inline void save_basic(Archive &ar,
const ConditionSet &b)
233 ar(b.get_symbol(), b.get_condition());
235 #ifdef HAVE_SYMENGINE_MPFR
236 template <
class Archive>
237 inline void save_basic(Archive &ar,
const RealMPFR &b)
239 ar(b.__str__(), b.get_prec());
242 template <
class Archive>
243 inline void save_basic(Archive &ar,
const GaloisField &b)
245 throw NotImplementedError(
"GaloisField saving is not implemented yet.");
247 template <
class Archive>
248 inline void save_basic(Archive &ar,
const SeriesCoeffInterface &)
250 throw NotImplementedError(
"Series saving is not implemented yet.");
252 template <
class Archive>
253 inline void save_basic(Archive &ar,
const MultiArgFunction &b)
257 template <
class Archive>
258 inline void save_basic(Archive &ar,
const FunctionSymbol &b)
260 ar(b.get_name(), b.get_args());
262 template <
class Archive>
263 inline void save_basic(Archive &ar,
const Derivative &b)
265 ar(b.get_arg(), b.get_symbols());
267 template <
class Archive>
268 inline void save_basic(Archive &ar,
const Subs &b)
270 ar(b.get_arg(), b.get_dict());
272 template <
class Archive>
273 inline void save_basic(Archive &ar,
const NumberWrapper &b)
275 throw NotImplementedError(
"NumberWrapper saving is not implemented yet.");
277 template <
class Archive>
278 inline void save_basic(Archive &ar,
const FunctionWrapper &b)
280 throw NotImplementedError(
"FunctionWrapper saving is not implemented yet.");
283 template <
class Archive>
284 inline void save_basic(Archive &ar, RCP<const Basic>
const &ptr)
286 #if CEREAL_VERSION >= 10301
289 uint32_t
id = ar.registerSharedPointer(sharedPtr);
291 uint32_t
id = ar.registerSharedPointer(ptr.get());
295 if (
id & cereal::detail::msb_32bit) {
296 TypeID type_code = ptr->get_type_code();
297 save_typeid(ar, type_code);
299 #define SYMENGINE_ENUM(type, Class) \
301 save_basic(ar, static_cast<const Class &>(*ptr)); \
303 #include "symengine/type_codes.inc"
304 #undef SYMENGINE_ENUM
306 save_basic(ar, *ptr);
312 template <
class Archive,
class T>
315 save_basic(ar, rcp_static_cast<const Basic>(ptr));
317 template <
class Archive>
318 RCP<const Basic> load_basic(Archive &ar, RCP<const RealDouble> &)
322 return real_double(val);
324 template <
class Archive>
325 RCP<const Basic> load_basic(Archive &ar, RCP<const Infty> &)
327 RCP<const Number> direction;
329 return Infty::from_direction(direction);
331 template <
class Archive>
332 RCP<const Basic> load_basic(Archive &ar, RCP<const NaN> &)
334 return rcp_static_cast<const Basic>(Nan);
336 template <
class Archive>
337 RCP<const Basic> load_basic(Archive &ar, RCP<const Symbol> &)
343 template <
class Archive>
344 RCP<const Basic> load_basic(Archive &ar, RCP<const Mul> &)
346 RCP<const Number> coeff;
347 map_basic_basic dict;
350 return make_rcp<const Mul>(coeff,
std::move(dict));
352 template <
class Archive>
353 RCP<const Basic> load_basic(Archive &ar, RCP<const Add> &)
355 RCP<const Number> coeff;
359 return make_rcp<const Add>(coeff,
std::move(dict));
361 template <
class Archive>
362 RCP<const Basic> load_basic(Archive &ar, RCP<const Pow> &)
364 RCP<const Basic> base,
exp;
367 return make_rcp<const Pow>(base,
exp);
369 template <
typename Archive>
370 void load_helper(Archive &ar, integer_class &intgr)
374 if (int_str.
size() == 0) {
375 throw SerializationError(
"invalid integer");
377 if (not(int_str[0] ==
'-' or
std::isdigit(int_str[0]))) {
378 throw SerializationError(
"invalid integer");
380 for (
auto it = ++int_str.
begin(); it < int_str.
end(); it++) {
382 throw SerializationError(
"invalid integer");
385 intgr = integer_class(
std::move(int_str));
387 template <
typename Archive>
388 void load_helper(Archive &ar,
const rational_class &rat)
390 integer_class num, den;
391 load_helper(ar, num);
392 load_helper(ar, den);
396 template <
typename Archive>
397 RCP<const Basic> load_basic(Archive &ar,
const URatPoly &b)
399 RCP<const Basic> var;
404 auto hint = d.
begin();
405 for (
size_t i = 0; i < l; i++) {
407 rational_class second;
409 load_helper(ar, second);
410 #if !defined(__clang__) && (__GNUC__ == 4 && __GNUC_MINOR__ <= 7)
416 return make_rcp<const URatPoly>(var, URatDict(
std::move(d)));
418 template <
class Archive>
419 RCP<const Basic> load_basic(Archive &ar, RCP<const Integer> &)
425 template <
class Archive>
426 RCP<const Basic> load_basic(Archive &ar, RCP<const Constant> &)
432 template <
class Archive>
433 RCP<const Basic> load_basic(Archive &ar, RCP<const Rational> &)
435 RCP<const Integer> num, den;
439 template <
class Archive>
440 RCP<const Basic> load_basic(Archive &ar, RCP<const Complex> &)
442 RCP<const Number> num, den;
446 template <
class Archive,
class T>
448 load_basic(Archive &ar, RCP<const T> &,
450 int>::type * =
nullptr)
452 RCP<const Number> num, den;
456 template <
class Archive>
457 RCP<const Basic> load_basic(Archive &ar, RCP<const Interval> &)
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);
464 template <
class Archive>
465 RCP<const Basic> load_basic(Archive &ar, RCP<const BooleanAtom> &)
471 template <
class Archive>
472 RCP<const Basic> load_basic(Archive &ar, RCP<const And> &)
474 set_boolean container;
476 return make_rcp<const And>(
std::move(container));
478 template <
class Archive>
479 RCP<const Basic> load_basic(Archive &ar, RCP<const Or> &)
481 set_boolean container;
483 return make_rcp<const Or>(
std::move(container));
485 template <
class Archive>
486 RCP<const Basic> load_basic(Archive &ar, RCP<const Xor> &)
488 vec_boolean container;
490 return make_rcp<const Xor>(
std::move(container));
492 template <
class Archive>
493 RCP<const Basic> load_basic(Archive &ar, RCP<const Not> &)
495 RCP<const Boolean> arg;
497 return make_rcp<const Not>(arg);
499 template <
class Archive>
500 RCP<const Basic> load_basic(Archive &ar, RCP<const Piecewise> &)
504 return make_rcp<const Piecewise>(
std::move(vec));
506 template <
class Archive>
507 RCP<const Basic> load_basic(Archive &ar, RCP<const Contains> &)
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);
514 template <
class Archive>
515 RCP<const Basic> load_basic(Archive &ar, RCP<const Reals> &)
519 template <
class Archive>
520 RCP<const Basic> load_basic(Archive &ar, RCP<const Rationals> &)
524 template <
class Archive>
525 RCP<const Basic> load_basic(Archive &ar, RCP<const EmptySet> &)
529 template <
class Archive>
530 RCP<const Basic> load_basic(Archive &ar, RCP<const Integers> &)
534 template <
class Archive>
535 RCP<const Basic> load_basic(Archive &ar, RCP<const UniversalSet> &)
539 template <
class Archive>
540 RCP<const Basic> load_basic(Archive &ar, RCP<const Union> &)
544 return make_rcp<const Union>(
std::move(union_set));
546 template <
class Archive>
547 RCP<const Basic> load_basic(Archive &ar, RCP<const Complement> &)
549 RCP<const Set> universe, container;
550 ar(universe, container);
551 return make_rcp<const Complement>(universe, container);
553 template <
class Archive>
554 RCP<const Basic> load_basic(Archive &ar, RCP<const ImageSet> &)
556 RCP<const Basic> sym, expr;
559 return make_rcp<const ImageSet>(sym, expr, base);
561 template <
class Archive>
562 RCP<const Basic> load_basic(Archive &ar, RCP<const FiniteSet> &)
566 return make_rcp<const FiniteSet>(set);
568 template <
class Archive>
569 RCP<const Basic> load_basic(Archive &ar, RCP<const ConditionSet> &)
571 RCP<const Basic> sym;
572 RCP<const Boolean> condition;
574 return make_rcp<const ConditionSet>(sym, condition);
576 #ifdef HAVE_SYMENGINE_MPFR
577 template <
class Archive>
578 RCP<const Basic> load_basic(Archive &ar, RCP<const RealMPFR> &)
583 return make_rcp<const RealMPFR>(mpfr_class(num, prec, 10));
586 template <
class Archive>
587 RCP<const Basic> load_basic(Archive &ar, RCP<const Derivative> &)
589 RCP<const Basic> arg;
592 return make_rcp<const Derivative>(arg,
std::move(set));
594 template <
class Archive>
595 RCP<const Basic> load_basic(Archive &ar, RCP<const Subs> &)
597 RCP<const Basic> arg;
598 map_basic_basic dict;
600 return make_rcp<const Subs>(arg,
std::move(dict));
603 template <
class Archive,
class T>
605 load_basic(Archive &ar, RCP<const T> &,
607 int>::type * =
nullptr)
609 RCP<const Basic> arg;
611 return make_rcp<const T>(arg);
613 template <
class Archive,
class T>
615 load_basic(Archive &ar, RCP<const T> &,
617 int>::type * =
nullptr)
619 RCP<const Basic> arg1, arg2;
621 return make_rcp<const T>(arg1, arg2);
623 template <
class Archive>
624 RCP<const Basic> load_basic(Archive &ar, RCP<const FunctionSymbol> &)
629 return make_rcp<const FunctionSymbol>(name,
std::move(vec));
631 template <
class Archive>
632 RCP<const Basic> load_basic(Archive &ar, RCP<const FunctionWrapper> &)
634 throw SerializationError(StreamFmt()
635 << __FILE__ <<
":" << __LINE__
637 <<
": " << __PRETTY_FUNCTION__
639 <<
"Loading of this type is not implemented.");
641 template <
class Archive,
class T>
643 load_basic(Archive &ar, RCP<const T> &,
645 int>::type * =
nullptr)
649 return make_rcp<const T>(
std::move(args));
651 template <
class Archive,
class T>
653 load_basic(Archive &ar, RCP<const T> &,
655 int>::type * =
nullptr)
657 RCP<const Basic> arg1, arg2;
659 return make_rcp<const T>(arg1, arg2);
661 template <
class Archive,
class T>
662 RCP<const Basic> load_basic(
663 Archive &ar, RCP<const T> &,
669 int>::type * =
nullptr)
671 throw SerializationError(StreamFmt()
672 << __FILE__ <<
":" << __LINE__
674 <<
": " << __PRETTY_FUNCTION__
676 <<
"Loading of this type is not implemented.");
679 template <
class Archive>
680 inline void save_typeid(Archive &ar, TypeID &t)
684 "TypeID cannot be saved to a 8 bit int.");
688 template <
class Archive>
689 inline void load_typeid(Archive &ar, TypeID &t)
694 throw SerializationError(
"TypeID out of range");
696 t =
static_cast<TypeID
>(i);
700 template <
class Archive,
class T>
707 if (
id & cereal::detail::msb_32bit) {
709 load_typeid(ar, type_code);
711 #define SYMENGINE_ENUM(type_enum, Class) \
713 if (not std::is_base_of<T, Class>::value) { \
714 throw SerializationError("Cannot convert to given type"); \
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); \
722 #include "symengine/type_codes.inc"
723 #undef SYMENGINE_ENUM
725 throw SerializationError(
"Unknown typeID");
729 rcp_static_cast<const Basic>(ptr)));
731 ar.registerSharedPointer(
id, sharedPtr);
732 }
else if (
id == 0) {
733 throw SerializationError(
"Unknown serialization error");
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);
741 }
catch (cereal::Exception &e) {
742 throw SerializationError(e.what());
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.
std::enable_if< std::is_integral< T >::value, RCP< const Integer > >::type integer(T i)
RCP< const Symbol > symbol(const std::string &name)
inline version to return Symbol
RCP< const Number > mulnum(const RCP< const Number > &self, const RCP< const Number > &other)
Multiply self and other
RCP< const Reals > reals()
RCP< const EmptySet > emptyset()
RCP< const Integers > integers()
RCP< const Basic > exp(const RCP< const Basic > &x)
Returns the natural exponential function E**x = pow(E, x)
RCP< const UniversalSet > universalset()
RCP< const Constant > constant(const std::string &name)
inline version to return Constant
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()
RCP< const Number > addnum(const RCP< const Number > &self, const RCP< const Number > &other)
Add self and other