GiNaC  1.6.2
registrar.h
Go to the documentation of this file.
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

This page is part of the GiNaC developer's reference. It was generated automatically by doxygen. For an introduction, see the tutorial.