#include #include #include #include #include #include #ifdef WITH_SYMENGINE_THREAD_SAFE #include #endif #include namespace SymEngine { Constant::Constant(const std::string &name) : name_{name} {SYMENGINE_ASSIGN_TYPEID()} hash_t Constant::__hash__() const { hash_t seed = SYMENGINE_CONSTANT; hash_combine<:string>(seed, name_); return seed; } bool Constant::__eq__(const Basic &o) const { if (is_a(o)) return name_ == down_cast(o).name_; return false; } int Constant::compare(const Basic &o) const { SYMENGINE_ASSERT(is_a(o)) const Constant &s = down_cast(o); if (name_ == s.name_) return 0; return name_ nifty_counter; #else static int nifty_counter; #endif // Some global variables are declared in functions.cpp // Look over https://github.com/sympy/symengine/issues/272 // for further details #define DEFINE_CONSTANTS \ DEFINE_CONSTANT(Integer, zero, integer(0)); \ DEFINE_CONSTANT(Integer, one, integer(1)); \ DEFINE_CONSTANT(Integer, minus_one, integer(-1)); \ DEFINE_CONSTANT(Integer, two, integer(2)); \ DEFINE_CONSTANT(Number, I, Complex::from_two_nums(*zero, *one)); \ DEFINE_CONSTANT(Constant, pi, constant("pi")); \ DEFINE_CONSTANT(Constant, E, constant("E")); \ DEFINE_CONSTANT(Constant, EulerGamma, constant("EulerGamma")); \ DEFINE_CONSTANT(Constant, Catalan, constant("Catalan")); \ DEFINE_CONSTANT(Constant, GoldenRatio, constant("GoldenRatio")); \ DEFINE_CONSTANT(Infty, Inf, Infty::from_int(1)); \ DEFINE_CONSTANT(Infty, NegInf, Infty::from_int(-1)); \ DEFINE_CONSTANT(Infty, ComplexInf, Infty::from_int(0)); \ DEFINE_CONSTANT(NaN, Nan, make_rcp()); \ DEFINE_CONSTANT(Basic, i2, integer(2)); \ DEFINE_CONSTANT(Basic, i3, integer(3)); \ DEFINE_CONSTANT(Basic, i5, integer(5)); \ DEFINE_CONSTANT(Basic, im2, integer(-2)); \ DEFINE_CONSTANT(Basic, im3, integer(-3)); \ DEFINE_CONSTANT(Basic, im5, integer(-5)); \ DEFINE_CONSTANT(Basic, sq3, sqrt_(i3)); \ DEFINE_CONSTANT(Basic, sq2, sqrt_(i2)); \ DEFINE_CONSTANT(Basic, sq5, sqrt_(i5)); \ DEFINE_CONSTANT(Basic, C0, div(sub(sq3, one), mul(i2, sq2))); \ DEFINE_CONSTANT(Basic, C1, div(one, i2)); \ DEFINE_CONSTANT(Basic, C2, div(sq2, i2)); \ DEFINE_CONSTANT(Basic, C3, div(sq3, i2)); \ DEFINE_CONSTANT(Basic, C4, div(add(sq3, one), mul(i2, sq2))); \ DEFINE_CONSTANT(Basic, C5, div(sqrt_(sub(i5, sqrt_(i5))), integer(8))); \ DEFINE_CONSTANT(Basic, C6, div(sub(sqrt_(i5), one), integer(4))); \ DEFINE_CONSTANT(Basic, mC0, mul(minus_one, C0)); \ DEFINE_CONSTANT(Basic, mC1, mul(minus_one, C1)); \ DEFINE_CONSTANT(Basic, mC2, mul(minus_one, C2)); \ DEFINE_CONSTANT(Basic, mC3, mul(minus_one, C3)); \ DEFINE_CONSTANT(Basic, mC4, mul(minus_one, C4)); \ DEFINE_CONSTANT(Basic, mC5, mul(minus_one, C5)); \ DEFINE_CONSTANT(Basic, mC6, mul(minus_one, C6)); \ DEFINE_CONSTANT(BooleanAtom, boolTrue, make_rcp(true)); \ DEFINE_CONSTANT(BooleanAtom, boolFalse, make_rcp(false)); #if __cplusplus >= 201703L template struct storage_for { alignas(T) std::byte data[sizeof(T)]; }; #else template struct storage_for { typename std::aligned_storage::type data; }; #endif #define DEFINE_CONSTANT(t, n, d) \ static storage_for> n##_buf; \ RCP &n = reinterpret_cast &>(n##_buf); DEFINE_CONSTANTS #undef DEFINE_CONSTANT ConstantInitializer::ConstantInitializer() { if (nifty_counter++ == 0) { #define DEFINE_CONSTANT(t, n, d) new (&n) RCP(d); DEFINE_CONSTANTS #undef DEFINE_CONSTANT } } ConstantInitializer::~ConstantInitializer() { if (--nifty_counter == 0) { #define DEFINE_CONSTANT(t, n, d) n.~RCP(); DEFINE_CONSTANTS #undef DEFINE_CONSTANT } } } // namespace SymEngine