X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Fregistrar.h;h=fd237fbcbfa92e1fd990f35882b253bb77cd8df2;hp=e6c083f32f98f72e60824ed3f20b892ab10c6374;hb=e57bc3416eb45606d6cfff40d64e03b6b9decc92;hpb=ef66dd715490d714cbc32f3ba74bd7386835cb4e diff --git a/ginac/registrar.h b/ginac/registrar.h index e6c083f3..fd237fbc 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-2004 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 @@ -25,8 +25,10 @@ #include #include +#include #include "class_info.h" +#include "print.h" namespace GiNaC { @@ -41,7 +43,7 @@ typedef container lst; typedef ex (*unarch_func)(const archive_node &n, lst &sym_lst); -/** This structure stores information about a registered GiNaC class. */ +/** This class stores information about a registered GiNaC class. */ class registered_class_options { public: registered_class_options(const char *n, const char *p, unsigned ti, unarch_func f) @@ -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; \ @@ -90,9 +123,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 +133,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 +153,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__