X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Fregistrar.h;h=16f39020d9ec1d1b89834077b8a733de4d78687c;hp=9dc3f24d9f80e6bce4769db892620ab66fa18ae2;hb=4d59c02d51fbf50ff24d616b00296aa4cbb1ea5e;hpb=c8feefe95a6c219195aea22050f17e2294656f32 diff --git a/ginac/registrar.h b/ginac/registrar.h index 9dc3f24d..16f39020 100644 --- a/ginac/registrar.h +++ b/ginac/registrar.h @@ -3,7 +3,7 @@ * GiNaC's class registrar (for class basic and all classes derived from it). */ /* - * GiNaC Copyright (C) 1999-2003 Johannes Gutenberg University Mainz, Germany + * GiNaC Copyright (C) 1999-2005 Johannes Gutenberg University Mainz, Germany * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __GINAC_REGISTRAR_H__ @@ -25,8 +25,10 @@ #include #include +#include #include "class_info.h" +#include "print.h" namespace GiNaC { @@ -51,12 +53,42 @@ public: const char *get_parent_name() const { return parent_name; } unsigned get_id() const { return tinfo_key; } unarch_func get_unarch_func() const { return unarchive; } + const std::vector &get_print_dispatch_table() const { return print_dispatch_table; } + + template + registered_class_options & print_func(void f(const T &, const C & c, unsigned)) + { + set_print_func(Ctx::get_class_info_static().options.get_id(), f); + return *this; + } + + template + registered_class_options & print_func(void (T::*f)(const C &, unsigned)) + { + set_print_func(Ctx::get_class_info_static().options.get_id(), f); + return *this; + } + + template + registered_class_options & print_func(const print_functor & f) + { + set_print_func(Ctx::get_class_info_static().options.get_id(), f); + return *this; + } + + void set_print_func(unsigned id, const print_functor & f) + { + if (id >= print_dispatch_table.size()) + print_dispatch_table.resize(id + 1); + print_dispatch_table[id] = f; + } private: const char *name; /**< Class name. */ const char *parent_name; /**< Name of superclass. */ unsigned tinfo_key; /**< TINFO_* key. */ unarch_func unarchive; /**< Pointer to unarchiving function. */ + std::vector print_dispatch_table; /**< Method table for print() dispatch */ }; typedef class_info registered_class_info; @@ -66,12 +98,13 @@ typedef class_info registered_class_info; #define GINAC_DECLARE_REGISTERED_CLASS_NO_CTORS(classname, supername) \ public: \ typedef supername inherited; \ - template 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 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 GiNaC::registered_class_info &get_class_info() { 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; \ @@ -80,6 +113,7 @@ public: \ class visitor { \ public: \ virtual void visit(const classname &) = 0; \ + virtual ~visitor() {}; \ }; /** Macro for inclusion in the declaration of each registered class. @@ -90,9 +124,9 @@ public: \ 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(&v)) \ p->visit(*this); \ @@ -100,7 +134,7 @@ public: \ 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. */ @@ -120,6 +154,21 @@ extern unsigned find_tinfo_key(const std::string &class_name); extern unarch_func find_unarch_func(const std::string &class_name); +/** Add or replace a print method. */ +template +extern void set_print_func(void f(const T &, const C & c, unsigned)) +{ + Alg::get_class_info_static().options.set_print_func(Ctx::get_class_info_static().options.get_id(), f); +} + +/** Add or replace a print method. */ +template +extern void set_print_func(void (T::*f)(const C &, unsigned)) +{ + Alg::get_class_info_static().options.set_print_func(Ctx::get_class_info_static().options.get_id(), f); +} + + } // namespace GiNaC #endif // ndef __GINAC_REGISTRAR_H__