Univariate Hensel lifting now uses upoly.
[ginac.git] / ginac / print.h
1 /** @file print.h
2  *
3  *  Definition of helper classes for expression output. */
4
5 /*
6  *  GiNaC Copyright (C) 1999-2008 Johannes Gutenberg University Mainz, Germany
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21  */
22
23 #ifndef __GINAC_PRINT_H__
24 #define __GINAC_PRINT_H__
25
26 #include <iosfwd>
27 #include <string>
28 #include <memory>
29
30 #include "class_info.h"
31
32 namespace GiNaC {
33
34
35 /** This class stores information about a registered print_context class. */
36 class print_context_options {
37 public:
38         print_context_options(const char *n, const char *p, unsigned i)
39          : name(n), parent_name(p), id(i) {}
40
41         const char *get_name() const { return name; }
42         const char *get_parent_name() const { return parent_name; }
43         unsigned get_id() const { return id; }
44
45 private:
46         const char *name;         /**< Class name. */
47         const char *parent_name;  /**< Name of superclass. */
48         unsigned id;              /**< ID number (assigned automatically). */
49 };
50
51 typedef class_info<print_context_options> print_context_class_info;
52
53
54 /** Flags to control the behavior of a print_context. */
55 class print_options {
56 public:
57         enum {
58                 print_index_dimensions = 0x0001 ///< print the dimensions of indices
59         };
60 };
61
62
63 /** Macro for inclusion in the declaration of a print_context class.
64  *  It declares some functions that are common to all classes derived
65  *  from 'print_context' as well as all required stuff for the GiNaC
66  *  registry. */
67 #define GINAC_DECLARE_PRINT_CONTEXT(classname, supername) \
68 public: \
69         typedef supername inherited; \
70         friend class function_options; \
71         friend class registered_class_options; \
72 public: \
73         static const GiNaC::print_context_class_info &get_class_info_static(); \
74         virtual const GiNaC::print_context_class_info &get_class_info() const { return classname::get_class_info_static(); } \
75         virtual const char *class_name() const { return classname::get_class_info_static().options.get_name(); } \
76         \
77         classname(); \
78         virtual classname * duplicate() const { return new classname(*this); } \
79 private:
80
81 /** Macro for inclusion in the implementation of each print_context class. */
82 #define GINAC_IMPLEMENT_PRINT_CONTEXT(classname, supername) \
83 const GiNaC::print_context_class_info &classname::get_class_info_static() \
84 { \
85         static GiNaC::print_context_class_info reg_info = GiNaC::print_context_class_info(GiNaC::print_context_options(#classname, #supername, GiNaC::next_print_context_id++)); \
86         return reg_info; \
87 }
88
89
90 extern unsigned next_print_context_id;
91
92
93 /** Base class for print_contexts. */
94 class print_context
95 {
96         GINAC_DECLARE_PRINT_CONTEXT(print_context, void)
97 public:
98         print_context(std::ostream &, unsigned options = 0);
99         virtual ~print_context() {}
100
101         std::ostream & s; /**< stream to output to */
102         unsigned options; /**< option flags */
103 };
104
105 /** Context for default (ginsh-parsable) output. */
106 class print_dflt : public print_context
107 {
108         GINAC_DECLARE_PRINT_CONTEXT(print_dflt, print_context)
109 public:
110         print_dflt(std::ostream &, unsigned options = 0);
111 };
112
113 /** Context for latex-parsable output. */
114 class print_latex : public print_context
115 {
116         GINAC_DECLARE_PRINT_CONTEXT(print_latex, print_context)
117 public:
118         print_latex(std::ostream &, unsigned options = 0);
119 };
120
121 /** Context for python pretty-print output. */
122 class print_python : public print_context
123 {
124         GINAC_DECLARE_PRINT_CONTEXT(print_python, print_context)
125 public:
126         print_python(std::ostream &, unsigned options = 0);
127 };
128
129 /** Context for python-parsable output. */
130 class print_python_repr : public print_context
131 {
132         GINAC_DECLARE_PRINT_CONTEXT(print_python_repr, print_context)
133 public:
134         print_python_repr(std::ostream &, unsigned options = 0);
135 };
136
137 /** Context for tree-like output for debugging. */
138 class print_tree : public print_context
139 {
140         GINAC_DECLARE_PRINT_CONTEXT(print_tree, print_context)
141 public:
142         print_tree(unsigned d);
143         print_tree(std::ostream &, unsigned options = 0, unsigned d = 4);
144
145         const unsigned delta_indent; /**< size of indentation step */
146 };
147
148 /** Base context for C source output. */
149 class print_csrc : public print_context
150 {
151         GINAC_DECLARE_PRINT_CONTEXT(print_csrc, print_context)
152 public:
153         print_csrc(std::ostream &, unsigned options = 0);
154 };
155
156 /** Context for C source output using float precision. */
157 class print_csrc_float : public print_csrc
158 {
159         GINAC_DECLARE_PRINT_CONTEXT(print_csrc_float, print_csrc)
160 public:
161         print_csrc_float(std::ostream &, unsigned options = 0);
162 };
163
164 /** Context for C source output using double precision. */
165 class print_csrc_double : public print_csrc
166 {
167         GINAC_DECLARE_PRINT_CONTEXT(print_csrc_double, print_csrc)
168 public:
169         print_csrc_double(std::ostream &, unsigned options = 0);
170 };
171
172 /** Context for C source output using CLN numbers. */
173 class print_csrc_cl_N : public print_csrc
174 {
175         GINAC_DECLARE_PRINT_CONTEXT(print_csrc_cl_N, print_csrc)
176 public:
177         print_csrc_cl_N(std::ostream &, unsigned options = 0);
178 };
179
180 /** Check if obj is a T, including base classes. */
181 template <class T>
182 inline bool is_a(const print_context & obj)
183 { return dynamic_cast<const T *>(&obj) != 0; }
184
185
186 class basic;
187
188 /** Base class for print_functor handlers */
189 class print_functor_impl {
190 public:
191         virtual ~print_functor_impl() {}
192         virtual print_functor_impl *duplicate() const = 0;
193         virtual void operator()(const basic & obj, const print_context & c, unsigned level) const = 0;
194 };
195
196 /** print_functor handler for pointer-to-functions of class T, context type C */
197 template <class T, class C>
198 class print_ptrfun_handler : public print_functor_impl {
199 public:
200         typedef void (*F)(const T &, const C &, unsigned);
201
202         print_ptrfun_handler(F f_) : f(f_) {}
203         print_ptrfun_handler *duplicate() const { return new print_ptrfun_handler(*this); }
204
205         void operator()(const basic & obj, const print_context & c, unsigned level) const
206         {
207                 // Call the supplied function
208                 f(dynamic_cast<const T &>(obj), dynamic_cast<const C &>(c), level);
209         }
210
211 private:
212         F f;
213 };
214
215 /** print_functor handler for member functions of class T, context type C */
216 template <class T, class C>
217 class print_memfun_handler : public print_functor_impl {
218 public:
219         typedef void (T::*F)(const C & c, unsigned level) const;
220
221         print_memfun_handler(F f_) : f(f_) {}
222         print_memfun_handler *duplicate() const { return new print_memfun_handler(*this); }
223
224         void operator()(const basic & obj, const print_context & c, unsigned level) const
225         {
226                 // Call the supplied member function
227                 return (dynamic_cast<const T &>(obj).*f)(dynamic_cast<const C &>(c), level);
228         }
229
230 private:
231         F f;
232 };
233
234 /** This class represents a print method for a certain algebraic class and
235  *  print_context type. Its main purpose is to hide the difference between
236  *  member functions and nonmember functions behind one unified operator()
237  *  interface. print_functor has value semantics and acts as a smart pointer
238  *  (with deep copy) to a class derived from print_functor_impl which
239  *  implements the actual function call. */
240 class print_functor {
241 public:
242         print_functor() : impl(0) {}
243         print_functor(const print_functor & other) : impl(other.impl.get() ? other.impl->duplicate() : 0) {}
244         print_functor(std::auto_ptr<print_functor_impl> impl_) : impl(impl_) {}
245
246         template <class T, class C>
247         print_functor(void f(const T &, const C &, unsigned)) : impl(new print_ptrfun_handler<T, C>(f)) {}
248
249         template <class T, class C>
250         print_functor(void (T::*f)(const C &, unsigned) const) : impl(new print_memfun_handler<T, C>(f)) {}
251
252         print_functor & operator=(const print_functor & other)
253         {
254                 if (this != &other) {
255                         print_functor_impl *p = other.impl.get();
256                         impl.reset(p ? other.impl->duplicate() : 0);
257                 }
258                 return *this;
259         }
260
261         void operator()(const basic & obj, const print_context & c, unsigned level) const
262         {
263                 (*impl)(obj, c, level);
264         }
265
266         bool is_valid() const { return impl.get(); }
267
268 private:
269         std::auto_ptr<print_functor_impl> impl;
270 };
271
272
273 } // namespace GiNaC
274
275 #endif // ndef __GINAC_BASIC_H__