Program Listing for File basic.h¶
↰ Return to documentation for file (symengine/symengine/basic.h)
#ifndef SYMENGINE_BASIC_H
#define SYMENGINE_BASIC_H
// Include all C++ headers here
#include <sstream>
#include <typeinfo>
#include <map>
#include <vector>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <cassert>
#include <cmath>
#include <complex>
#include <vector>
#include <type_traits>
#include <functional>
#include <algorithm>
#include <symengine/symengine_config.h>
#include <symengine/symengine_exception.h>
#ifdef WITH_SYMENGINE_THREAD_SAFE
#include <atomic>
#endif
#include <symengine/dict.h>
namespace SymEngine
{
enum TypeID {
#define SYMENGINE_INCLUDE_ALL
#define SYMENGINE_ENUM(type, Class) type,
#include "symengine/type_codes.inc"
#undef SYMENGINE_ENUM
#undef SYMENGINE_INCLUDE_ALL
// The 'TypeID_Count' returns the number of elements in 'TypeID'. For this
// to work, do not assign numbers to the elements above (or if you do, you
// must assign the correct count below).
TypeID_Count
};
#include "basic-methods.inc"
class Visitor;
class Symbol;
class Basic : public EnableRCPFromThis<Basic>
{
private:
// The hash_ is defined as mutable, because its value is initialized to 0
// in the constructor and then it can be changed in Basic::hash() to the
// current hash (which is always the same for the given instance). The
// state of the instance does not change, so we define hash_ as mutable.
#if defined(WITH_SYMENGINE_THREAD_SAFE)
mutable std::atomic<hash_t> hash_; // This holds the hash value
#else
mutable hash_t hash_; // This holds the hash value
#endif // WITH_SYMENGINE_THREAD_SAFE
public:
#ifdef WITH_SYMENGINE_VIRTUAL_TYPEID
virtual TypeID get_type_code() const = 0;
#else
TypeID type_code_;
inline TypeID get_type_code() const
{
return type_code_;
};
#endif
Basic() : hash_{0}
{
}
// Destructor must be explicitly defined as virtual here to avoid problems
// with undefined behavior while deallocating derived classes.
virtual ~Basic()
{
}
Basic(const Basic &) = delete;
Basic &operator=(const Basic &) = delete;
Basic(Basic &&) = delete;
Basic &operator=(Basic &&) = delete;
virtual hash_t __hash__() const = 0;
hash_t hash() const;
virtual bool __eq__(const Basic &o) const = 0;
bool __neq__(const Basic &o) const;
int __cmp__(const Basic &o) const;
virtual int compare(const Basic &o) const = 0;
std::string __str__() const;
RCP<const Basic> subs(const map_basic_basic &subs_dict) const;
RCP<const Basic> xreplace(const map_basic_basic &subs_dict) const;
virtual RCP<const Basic> expand_as_exp() const
{
throw NotImplementedError("Not Implemented");
}
virtual vec_basic get_args() const = 0;
SYMENGINE_INCLUDE_METHODS(= 0;)
RCP<const Basic> diff(const RCP<const Symbol> &x, bool cache = true) const;
};
struct RCPBasicHash {
size_t operator()(const RCP<const Basic> &k) const
{
return static_cast<size_t>(k->hash());
}
};
struct RCPBasicKeyEq {
bool operator()(const RCP<const Basic> &x, const RCP<const Basic> &y) const
{
return eq(*x, *y);
}
};
struct RCPBasicKeyLess {
bool operator()(const RCP<const Basic> &x, const RCP<const Basic> &y) const
{
hash_t xh = x->hash(), yh = y->hash();
if (xh != yh)
return xh < yh;
if (eq(*x, *y))
return false;
return x->__cmp__(*y) == -1;
}
};
enum tribool { indeterminate = -1, trifalse = 0, tritrue = 1 };
inline bool is_true(tribool x)
{
return x == tribool::tritrue;
};
// Convenience functions
bool eq(const Basic &a, const Basic &b);
bool neq(const Basic &a, const Basic &b);
template <class T>
bool is_a(const Basic &b);
bool is_a_Atom(const Basic &b);
template <class T>
bool is_a_sub(const Basic &b);
bool is_same_type(const Basic &a, const Basic &b);
RCP<const Basic> expand(const RCP<const Basic> &self, bool deep = true);
void as_numer_denom(const RCP<const Basic> &x,
const Ptr<RCP<const Basic>> &numer,
const Ptr<RCP<const Basic>> &denom);
void as_real_imag(const RCP<const Basic> &x, const Ptr<RCP<const Basic>> &real,
const Ptr<RCP<const Basic>> &imag);
RCP<const Basic> rewrite_as_exp(const RCP<const Basic> &x);
// Common subexpression elimination of symbolic expressions
// Return a vector of replacement pairs and a vector of reduced exprs
void cse(vec_pair &replacements, vec_basic &reduced_exprs,
const vec_basic &exprs);
std::ostream &operator<<(std::ostream &out, const SymEngine::Basic &p);
template <class T>
void hash_combine(hash_t &seed, const T &v);
const char *get_version();
} // SymEngine
namespace std
{
template <>
struct hash<SymEngine::Basic>;
}
#include "basic-inl.h"
// Macro to define the type_code_id variable and its getter method
#ifdef WITH_SYMENGINE_VIRTUAL_TYPEID
#define IMPLEMENT_TYPEID(SYMENGINE_ID) \
\
const static TypeID type_code_id = SYMENGINE_ID; \
\
virtual TypeID get_type_code() const \
{ \
return type_code_id; \
}; \
SYMENGINE_INCLUDE_METHODS(;)
#else
#define IMPLEMENT_TYPEID(SYMENGINE_ID) \
\
const static TypeID type_code_id = SYMENGINE_ID; \
SYMENGINE_INCLUDE_METHODS(;)
#endif
#ifdef WITH_SYMENGINE_VIRTUAL_TYPEID
#define SYMENGINE_ASSIGN_TYPEID()
#else
#define SYMENGINE_ASSIGN_TYPEID() this->type_code_ = type_code_id;
#endif
#endif