* @param level value that is used to identify the precedence or indentation
* level for placing parentheses and formatting */
void basic::print(const print_context & c, unsigned level) const
+{
+ print_dispatch(get_class_info(), c, level);
+}
+
+/** Like print(), but dispatch to the specified class. Can be used by
+ * implementations of print methods to dispatch to the method of the
+ * superclass.
+ *
+ * @see basic::print */
+void basic::print_dispatch(const registered_class_info & ri, const print_context & c, unsigned level) const
{
// Double dispatch on object type and print_context type
- const registered_class_info * reg_info = &get_class_info();
+ const registered_class_info * reg_info = &ri;
const print_context_class_info * pc_info = &c.get_class_info();
next_class:
+std::clog << "searching class " << reg_info->options.get_name() << std::endl;
const std::vector<print_functor> & pdt = reg_info->options.get_print_dispatch_table();
next_context:
+std::clog << "searching context " << pc_info->options.get_name() << ", ID " << pc_info->options.get_id() << std::endl;
unsigned id = pc_info->options.get_id();
if (id >= pdt.size() || !(pdt[id].is_valid())) {
} else {
// Call method
+std::clog << "method found, calling" << std::endl;
+std::clog << " this = " << class_name() << ", context = " << c.class_name() << std::endl;
pdt[id](*this, c, level);
}
}
// non-virtual functions in this class
public:
+ /** Like print(), but dispatch to the specified class. Can be used by
+ * implementations of print methods to dispatch to the method of the
+ * superclass.
+ *
+ * @see basic::print */
+ template <class T>
+ void print_dispatch(const print_context & c, unsigned level) const
+ {
+ print_dispatch(T::get_class_info_static(), c, level);
+ }
+
+ void print_dispatch(const registered_class_info & ri, const print_context & c, unsigned level) const;
+
ex subs_one_level(const exmap & m, unsigned options) const;
ex diff(const symbol & s, unsigned nth = 1) const;
int compare(const basic & other) const;
protected:
void ensure_if_modifiable() const;
-private:
void do_print(const print_context & c, unsigned level) const;
void do_print_tree(const print_tree & c, unsigned level) const;
void do_print_python_repr(const print_python_repr & c, unsigned level) const;
template <class T>
inline bool is_exactly_a(const basic &obj)
{
- return obj.tinfo() == T::reg_info.options.get_id();
+ return obj.tinfo() == T::get_class_info_static().options.get_id();
}
} // namespace GiNaC
template <class Ctx> function_options & print_func(print_funcp_${N} p)
{
test_and_set_nparams(${N});
- set_print_func(Ctx::reg_info.options.get_id(), print_funcp(p));
+ set_print_func(Ctx::get_class_info_static().options.get_id(), print_funcp(p));
return *this;
}
END_OF_PRINT_FUNC_INTERFACE
template <class Ctx> function_options & print_func(print_funcp_exvector p)
{
print_use_exvector_args = true;
- set_print_func(Ctx::reg_info.options.get_id(), print_funcp(p));
+ set_print_func(Ctx::get_class_info_static().options.get_id(), print_funcp(p));
return *this;
}
typedef supername inherited; \
friend class function_options; \
friend class registered_class_options; \
-private: \
- static GiNaC::print_context_class_info reg_info; \
public: \
- virtual const GiNaC::print_context_class_info &get_class_info() const { return reg_info; } \
- virtual const char *class_name() const { return reg_info.options.get_name(); } \
+ static const GiNaC::print_context_class_info &get_class_info_static(); \
+ virtual const GiNaC::print_context_class_info &get_class_info() const { return classname::get_class_info_static(); } \
+ virtual const char *class_name() const { return classname::get_class_info_static().options.get_name(); } \
\
classname(); \
- classname * duplicate() const { return new classname(*this); } \
+ virtual classname * duplicate() const { return new classname(*this); } \
private:
/** Macro for inclusion in the implementation of each print_context class. */
#define GINAC_IMPLEMENT_PRINT_CONTEXT(classname, supername) \
- GiNaC::print_context_class_info classname::reg_info = GiNaC::print_context_class_info(print_context_options(#classname, #supername, next_print_context_id++));
+const GiNaC::print_context_class_info &classname::get_class_info_static() \
+{ \
+ static GiNaC::print_context_class_info reg_info = GiNaC::print_context_class_info(GiNaC::print_context_options(#classname, #supername, GiNaC::next_print_context_id++)); \
+ return reg_info; \
+}
+
extern unsigned next_print_context_id;
template <class Ctx, class T, class C>
registered_class_options & print_func(void f(const T &, const C & c, unsigned))
{
- set_print_func(Ctx::reg_info.options.get_id(), f);
+ set_print_func(Ctx::get_class_info_static().options.get_id(), f);
return *this;
}
template <class Ctx, class T, class C>
registered_class_options & print_func(void (T::*f)(const C &, unsigned))
{
- set_print_func(Ctx::reg_info.options.get_id(), f);
+ set_print_func(Ctx::get_class_info_static().options.get_id(), f);
return *this;
}
template <class Ctx>
registered_class_options & print_func(const print_functor & f)
{
- set_print_func(Ctx::reg_info.options.get_id(), f);
+ set_print_func(Ctx::get_class_info_static().options.get_id(), f);
return *this;
}
#define GINAC_DECLARE_REGISTERED_CLASS_NO_CTORS(classname, supername) \
public: \
typedef supername inherited; \
- template <class isexaclass> friend bool is_exactly_a(const GiNaC::basic &obj); \
private: \
static GiNaC::registered_class_info reg_info; \
public: \
- virtual const GiNaC::registered_class_info &get_class_info() const { return reg_info; } \
- virtual const char *class_name() const { return reg_info.options.get_name(); } \
+ static const GiNaC::registered_class_info &get_class_info_static() { return reg_info; } \
+ virtual const GiNaC::registered_class_info &get_class_info() const { return classname::get_class_info_static(); } \
+ virtual const char *class_name() const { return classname::get_class_info_static().options.get_name(); } \
\
classname(const GiNaC::archive_node &n, GiNaC::lst &sym_lst); \
virtual void archive(GiNaC::archive_node &n) const; \
GINAC_DECLARE_REGISTERED_CLASS_NO_CTORS(classname, supername) \
public: \
classname(); \
- classname * duplicate() const { return new classname(*this); } \
+ virtual classname * duplicate() const { return new classname(*this); } \
\
- void accept(GiNaC::visitor & v) const \
+ virtual void accept(GiNaC::visitor & v) const \
{ \
if (visitor *p = dynamic_cast<visitor *>(&v)) \
p->visit(*this); \
inherited::accept(v); \
} \
protected: \
- int compare_same_type(const GiNaC::basic & other) const; \
+ virtual int compare_same_type(const GiNaC::basic & other) const; \
private:
/** Macro for inclusion in the implementation of each registered class. */