|
GiNaC
1.6.2
|
00001 00005 /* 00006 * GiNaC Copyright (C) 1999-2011 Johannes Gutenberg University Mainz, Germany 00007 * 00008 * This program is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation; either version 2 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License 00019 * along with this program; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00021 */ 00022 00023 #ifndef GINAC_REGISTRAR_H 00024 #define GINAC_REGISTRAR_H 00025 00026 #include "class_info.h" 00027 #include "print.h" 00028 00029 #include <list> 00030 #include <string> 00031 #include <typeinfo> 00032 #include <vector> 00033 00034 namespace GiNaC { 00035 00036 class ex; 00037 class archive_node; 00038 00039 template <template <class T, class = std::allocator<T> > class> class container; 00040 typedef container<std::list> lst; 00041 00043 struct return_type_t 00044 { 00046 std::type_info const* tinfo; 00049 unsigned rl; 00050 00053 inline bool operator<(const return_type_t& other) const 00054 { 00055 if (tinfo->before(*other.tinfo)) 00056 return true; 00057 return rl < other.rl; 00058 } 00059 inline bool operator==(const return_type_t& other) const 00060 { 00061 if (*tinfo != *(other.tinfo)) 00062 return false; 00063 return rl == other.rl; 00064 } 00065 inline bool operator!=(const return_type_t& other) const 00066 { 00067 return ! (operator==(other)); 00068 } 00069 }; 00070 00071 template<typename T> inline return_type_t make_return_type_t(const unsigned rl = 0) 00072 { 00073 return_type_t ret; 00074 ret.rl = rl; 00075 ret.tinfo = &typeid(T); 00076 return ret; 00077 } 00078 00080 class registered_class_options { 00081 public: 00082 registered_class_options(const char *n, const char *p, 00083 const std::type_info& ti) 00084 : name(n), parent_name(p), tinfo_key(&ti) { } 00085 00086 const char *get_name() const { return name; } 00087 const char *get_parent_name() const { return parent_name; } 00088 std::type_info const* get_id() const { return tinfo_key; } 00089 const std::vector<print_functor> &get_print_dispatch_table() const { return print_dispatch_table; } 00090 00091 template <class Ctx, class T, class C> 00092 registered_class_options & print_func(void f(const T &, const C & c, unsigned)) 00093 { 00094 set_print_func(Ctx::get_class_info_static().options.get_id(), f); 00095 return *this; 00096 } 00097 00098 template <class Ctx, class T, class C> 00099 registered_class_options & print_func(void (T::*f)(const C &, unsigned)) 00100 { 00101 set_print_func(Ctx::get_class_info_static().options.get_id(), f); 00102 return *this; 00103 } 00104 00105 template <class Ctx> 00106 registered_class_options & print_func(const print_functor & f) 00107 { 00108 set_print_func(Ctx::get_class_info_static().options.get_id(), f); 00109 return *this; 00110 } 00111 00112 void set_print_func(unsigned id, const print_functor & f) 00113 { 00114 if (id >= print_dispatch_table.size()) 00115 print_dispatch_table.resize(id + 1); 00116 print_dispatch_table[id] = f; 00117 } 00118 00119 private: 00120 const char *name; 00121 const char *parent_name; 00122 std::type_info const* tinfo_key; 00123 std::vector<print_functor> print_dispatch_table; 00124 }; 00125 00126 typedef class_info<registered_class_options> registered_class_info; 00127 00128 00130 #define GINAC_DECLARE_REGISTERED_CLASS_NO_CTORS(classname, supername) \ 00131 public: \ 00132 typedef supername inherited; \ 00133 private: \ 00134 static GiNaC::registered_class_info reg_info; \ 00135 public: \ 00136 static GiNaC::registered_class_info &get_class_info_static() { return reg_info; } \ 00137 virtual const GiNaC::registered_class_info &get_class_info() const { return classname::get_class_info_static(); } \ 00138 virtual GiNaC::registered_class_info &get_class_info() { return classname::get_class_info_static(); } \ 00139 virtual const char *class_name() const { return classname::get_class_info_static().options.get_name(); } \ 00140 class visitor { \ 00141 public: \ 00142 virtual void visit(const classname &) = 0; \ 00143 virtual ~visitor() {}; \ 00144 }; 00145 00150 #define GINAC_DECLARE_REGISTERED_CLASS(classname, supername) \ 00151 GINAC_DECLARE_REGISTERED_CLASS_NO_CTORS(classname, supername) \ 00152 public: \ 00153 classname(); \ 00154 virtual classname * duplicate() const { return new classname(*this); } \ 00155 \ 00156 virtual void accept(GiNaC::visitor & v) const \ 00157 { \ 00158 if (visitor *p = dynamic_cast<visitor *>(&v)) \ 00159 p->visit(*this); \ 00160 else \ 00161 inherited::accept(v); \ 00162 } \ 00163 protected: \ 00164 virtual int compare_same_type(const GiNaC::basic & other) const; \ 00165 private: 00166 00167 00169 #define GINAC_IMPLEMENT_REGISTERED_CLASS(classname, supername) \ 00170 GiNaC::registered_class_info classname::reg_info = GiNaC::registered_class_info(GiNaC::registered_class_options(#classname, #supername, typeid(classname))); 00171 00174 #define GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(classname, supername, options) \ 00175 GiNaC::registered_class_info classname::reg_info = GiNaC::registered_class_info(GiNaC::registered_class_options(#classname, #supername, typeid(classname)).options); 00176 00179 #define GINAC_IMPLEMENT_REGISTERED_CLASS_OPT_T(classname, supername, options) \ 00180 GiNaC::registered_class_info classname::reg_info = GiNaC::registered_class_info(GiNaC::registered_class_options(#classname, #supername, typeid(classname)).options); 00181 00182 00184 template <class Alg, class Ctx, class T, class C> 00185 extern void set_print_func(void f(const T &, const C & c, unsigned)) 00186 { 00187 Alg::get_class_info_static().options.set_print_func(Ctx::get_class_info_static().options.get_id(), f); 00188 } 00189 00191 template <class Alg, class Ctx, class T, class C> 00192 extern void set_print_func(void (T::*f)(const C &, unsigned)) 00193 { 00194 Alg::get_class_info_static().options.set_print_func(Ctx::get_class_info_static().options.get_id(), f); 00195 } 00196 00197 00198 } // namespace GiNaC 00199 00200 #endif // ndef GINAC_REGISTRAR_H