|
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_PRINT_H 00024 #define GINAC_PRINT_H 00025 00026 #include "class_info.h" 00027 00028 #include <iosfwd> 00029 #include <memory> 00030 #include <string> 00031 00032 namespace GiNaC { 00033 00035 class print_context_options { 00036 public: 00037 print_context_options(const char *n, const char *p, unsigned i) 00038 : name(n), parent_name(p), id(i) {} 00039 00040 const char *get_name() const { return name; } 00041 const char *get_parent_name() const { return parent_name; } 00042 unsigned get_id() const { return id; } 00043 00044 private: 00045 const char *name; 00046 const char *parent_name; 00047 unsigned id; 00048 }; 00049 00050 typedef class_info<print_context_options> print_context_class_info; 00051 00052 00054 class print_options { 00055 public: 00056 enum { 00057 print_index_dimensions = 0x0001 00058 }; 00059 }; 00060 00061 00066 #define GINAC_DECLARE_PRINT_CONTEXT(classname, supername) \ 00067 public: \ 00068 typedef supername inherited; \ 00069 friend class function_options; \ 00070 friend class registered_class_options; \ 00071 public: \ 00072 static const GiNaC::print_context_class_info &get_class_info_static(); \ 00073 virtual const GiNaC::print_context_class_info &get_class_info() const { return classname::get_class_info_static(); } \ 00074 virtual const char *class_name() const { return classname::get_class_info_static().options.get_name(); } \ 00075 \ 00076 classname(); \ 00077 virtual classname * duplicate() const { return new classname(*this); } \ 00078 private: 00079 00081 #define GINAC_IMPLEMENT_PRINT_CONTEXT(classname, supername) \ 00082 const GiNaC::print_context_class_info &classname::get_class_info_static() \ 00083 { \ 00084 static GiNaC::print_context_class_info reg_info = GiNaC::print_context_class_info(GiNaC::print_context_options(#classname, #supername, GiNaC::next_print_context_id++)); \ 00085 return reg_info; \ 00086 } 00087 00088 00089 extern unsigned next_print_context_id; 00090 00091 00093 class print_context 00094 { 00095 GINAC_DECLARE_PRINT_CONTEXT(print_context, void) 00096 public: 00097 print_context(std::ostream &, unsigned options = 0); 00098 virtual ~print_context() {} 00099 00100 std::ostream & s; 00101 unsigned options; 00102 }; 00103 00105 class print_dflt : public print_context 00106 { 00107 GINAC_DECLARE_PRINT_CONTEXT(print_dflt, print_context) 00108 public: 00109 print_dflt(std::ostream &, unsigned options = 0); 00110 }; 00111 00113 class print_latex : public print_context 00114 { 00115 GINAC_DECLARE_PRINT_CONTEXT(print_latex, print_context) 00116 public: 00117 print_latex(std::ostream &, unsigned options = 0); 00118 }; 00119 00121 class print_python : public print_context 00122 { 00123 GINAC_DECLARE_PRINT_CONTEXT(print_python, print_context) 00124 public: 00125 print_python(std::ostream &, unsigned options = 0); 00126 }; 00127 00129 class print_python_repr : public print_context 00130 { 00131 GINAC_DECLARE_PRINT_CONTEXT(print_python_repr, print_context) 00132 public: 00133 print_python_repr(std::ostream &, unsigned options = 0); 00134 }; 00135 00137 class print_tree : public print_context 00138 { 00139 GINAC_DECLARE_PRINT_CONTEXT(print_tree, print_context) 00140 public: 00141 print_tree(unsigned d); 00142 print_tree(std::ostream &, unsigned options = 0, unsigned d = 4); 00143 00144 const unsigned delta_indent; 00145 }; 00146 00148 class print_csrc : public print_context 00149 { 00150 GINAC_DECLARE_PRINT_CONTEXT(print_csrc, print_context) 00151 public: 00152 print_csrc(std::ostream &, unsigned options = 0); 00153 }; 00154 00156 class print_csrc_float : public print_csrc 00157 { 00158 GINAC_DECLARE_PRINT_CONTEXT(print_csrc_float, print_csrc) 00159 public: 00160 print_csrc_float(std::ostream &, unsigned options = 0); 00161 }; 00162 00164 class print_csrc_double : public print_csrc 00165 { 00166 GINAC_DECLARE_PRINT_CONTEXT(print_csrc_double, print_csrc) 00167 public: 00168 print_csrc_double(std::ostream &, unsigned options = 0); 00169 }; 00170 00172 class print_csrc_cl_N : public print_csrc 00173 { 00174 GINAC_DECLARE_PRINT_CONTEXT(print_csrc_cl_N, print_csrc) 00175 public: 00176 print_csrc_cl_N(std::ostream &, unsigned options = 0); 00177 }; 00178 00180 template <class T> 00181 inline bool is_a(const print_context & obj) 00182 { return dynamic_cast<const T *>(&obj) != 0; } 00183 00184 00185 class basic; 00186 00188 class print_functor_impl { 00189 public: 00190 virtual ~print_functor_impl() {} 00191 virtual print_functor_impl *duplicate() const = 0; 00192 virtual void operator()(const basic & obj, const print_context & c, unsigned level) const = 0; 00193 }; 00194 00196 template <class T, class C> 00197 class print_ptrfun_handler : public print_functor_impl { 00198 public: 00199 typedef void (*F)(const T &, const C &, unsigned); 00200 00201 print_ptrfun_handler(F f_) : f(f_) {} 00202 print_ptrfun_handler *duplicate() const { return new print_ptrfun_handler(*this); } 00203 00204 void operator()(const basic & obj, const print_context & c, unsigned level) const 00205 { 00206 // Call the supplied function 00207 f(dynamic_cast<const T &>(obj), dynamic_cast<const C &>(c), level); 00208 } 00209 00210 private: 00211 F f; 00212 }; 00213 00215 template <class T, class C> 00216 class print_memfun_handler : public print_functor_impl { 00217 public: 00218 typedef void (T::*F)(const C & c, unsigned level) const; 00219 00220 print_memfun_handler(F f_) : f(f_) {} 00221 print_memfun_handler *duplicate() const { return new print_memfun_handler(*this); } 00222 00223 void operator()(const basic & obj, const print_context & c, unsigned level) const 00224 { 00225 // Call the supplied member function 00226 return (dynamic_cast<const T &>(obj).*f)(dynamic_cast<const C &>(c), level); 00227 } 00228 00229 private: 00230 F f; 00231 }; 00232 00239 class print_functor { 00240 public: 00241 print_functor() : impl(0) {} 00242 print_functor(const print_functor & other) : impl(other.impl.get() ? other.impl->duplicate() : 0) {} 00243 print_functor(std::auto_ptr<print_functor_impl> impl_) : impl(impl_) {} 00244 00245 template <class T, class C> 00246 print_functor(void f(const T &, const C &, unsigned)) : impl(new print_ptrfun_handler<T, C>(f)) {} 00247 00248 template <class T, class C> 00249 print_functor(void (T::*f)(const C &, unsigned) const) : impl(new print_memfun_handler<T, C>(f)) {} 00250 00251 print_functor & operator=(const print_functor & other) 00252 { 00253 if (this != &other) { 00254 print_functor_impl *p = other.impl.get(); 00255 impl.reset(p ? other.impl->duplicate() : 0); 00256 } 00257 return *this; 00258 } 00259 00260 void operator()(const basic & obj, const print_context & c, unsigned level) const 00261 { 00262 (*impl)(obj, c, level); 00263 } 00264 00265 bool is_valid() const { return impl.get(); } 00266 00267 private: 00268 std::auto_ptr<print_functor_impl> impl; 00269 }; 00270 00271 00272 } // namespace GiNaC 00273 00274 #endif // ndef GINAC_BASIC_H