#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