]> www.ginac.de Git - ginac.git/blobdiff - ginac/print.h
- added registry for print_context classes (use print_context_class_info::dump_hierar...
[ginac.git] / ginac / print.h
index 8d4fc2f8612eeebe0367a2b4bf71bea454bd8bd9..54b6ca719531b0349174278cd630806c5730618b 100644 (file)
 #include <iosfwd>
 #include <string>
 
+#include "class_info.h"
+
 namespace GiNaC {
 
 
-/*
- *  The following classes remain publicly visible for compatibility
- *  reasons only. New code should use the iostream manipulators defined
- *  in operators.h instead.
- */
+/** This class stores information about a registered print_context class. */
+class print_context_options {
+public:
+       print_context_options(const char *n, const char *p, unsigned i)
+        : name(n), parent_name(p), id(i) {}
+
+       const char *get_name() const { return name; }
+       const char *get_parent_name() const { return parent_name; }
+       unsigned get_id() const { return id; }
+
+private:
+       const char *name;         /**< Class name. */
+       const char *parent_name;  /**< Name of superclass. */
+       unsigned id;              /**< ID number (assigned automatically). */
+};
+
+typedef class_info<print_context_options> print_context_class_info;
 
 
 /** Flags to control the behavior of a print_context. */
@@ -45,53 +59,82 @@ public:
 };
 
 
-/** Context for default (ginsh-parsable) output. */
+/** Macro for inclusion in the declaration of a print_context class.
+ *  It declares some functions that are common to all classes derived
+ *  from 'print_context' as well as all required stuff for the GiNaC
+ *  registry. */
+#define GINAC_DECLARE_PRINT_CONTEXT(classname, supername) \
+public: \
+       typedef supername inherited; \
+       friend class function_options; \
+private: \
+       static GiNaC::print_context_class_info reg_info; \
+public: \
+       virtual const GiNaC::print_context_class_info &get_class_info() const { return reg_info; } \
+       virtual const char *class_name() const { return reg_info.options.get_name(); } \
+       \
+       classname(); \
+       classname * duplicate() const { return new classname(*this); } \
+private:
+
+/** Macro for inclusion in the implementation of each print_context class. */
+#define GINAC_IMPLEMENT_PRINT_CONTEXT(classname, supername) \
+       GiNaC::print_context_class_info classname::reg_info = GiNaC::print_context_class_info(print_context_options(#classname, #supername, next_print_context_id++));
+
+extern unsigned next_print_context_id;
+
+
+/** Base class for print_contexts. */
 class print_context
 {
+       GINAC_DECLARE_PRINT_CONTEXT(print_context, void)
 public:
-       print_context();
        print_context(std::ostream &, unsigned options = 0);
        virtual ~print_context() {}
-       virtual print_context * duplicate() const {return new print_context(*this);}
 
        std::ostream & s; /**< stream to output to */
        unsigned options; /**< option flags */
 };
 
+/** Context for default (ginsh-parsable) output. */
+class print_dflt : public print_context
+{
+       GINAC_DECLARE_PRINT_CONTEXT(print_dflt, print_context)
+public:
+       print_dflt(std::ostream &, unsigned options = 0);
+};
+
 /** Context for latex-parsable output. */
 class print_latex : public print_context
 {
+       GINAC_DECLARE_PRINT_CONTEXT(print_latex, print_context)
 public:
-       print_latex();
        print_latex(std::ostream &, unsigned options = 0);
-       print_context * duplicate() const {return new print_latex(*this);}
 };
 
 /** Context for python pretty-print output. */
 class print_python : public print_context
 {
+       GINAC_DECLARE_PRINT_CONTEXT(print_python, print_context)
 public:
-       print_python();
        print_python(std::ostream &, unsigned options = 0);
-       print_context * duplicate() const {return new print_python(*this);}
 };
 
 /** Context for python-parsable output. */
 class print_python_repr : public print_context
 {
+       GINAC_DECLARE_PRINT_CONTEXT(print_python_repr, print_context)
 public:
-       print_python_repr();
        print_python_repr(std::ostream &, unsigned options = 0);
-       print_context * duplicate() const {return new print_python_repr(*this);}
 };
 
 /** Context for tree-like output for debugging. */
 class print_tree : public print_context
 {
+       GINAC_DECLARE_PRINT_CONTEXT(print_tree, print_context)
 public:
-       print_tree(unsigned d = 4);
+       print_tree(unsigned d);
        print_tree(std::ostream &, unsigned options = 0, unsigned d = 4);
-       print_context * duplicate() const {return new print_tree(*this);}
 
        const unsigned delta_indent; /**< size of indentation step */
 };
@@ -99,43 +142,39 @@ public:
 /** Base context for C source output. */
 class print_csrc : public print_context
 {
+       GINAC_DECLARE_PRINT_CONTEXT(print_csrc, print_context)
 public:
-       print_csrc();
        print_csrc(std::ostream &, unsigned options = 0);
-       print_context * duplicate() const {return new print_csrc(*this);}
 };
 
 /** Context for C source output using float precision. */
 class print_csrc_float : public print_csrc
 {
+       GINAC_DECLARE_PRINT_CONTEXT(print_csrc_float, print_csrc)
 public:
-       print_csrc_float();
        print_csrc_float(std::ostream &, unsigned options = 0);
-       print_context * duplicate() const {return new print_csrc_float(*this);}
 };
 
 /** Context for C source output using double precision. */
 class print_csrc_double : public print_csrc
 {
+       GINAC_DECLARE_PRINT_CONTEXT(print_csrc_double, print_csrc)
 public:
-       print_csrc_double();
        print_csrc_double(std::ostream &, unsigned options = 0);
-       print_context * duplicate() const {return new print_csrc_double(*this);}
 };
 
 /** Context for C source output using CLN numbers. */
 class print_csrc_cl_N : public print_csrc
 {
+       GINAC_DECLARE_PRINT_CONTEXT(print_csrc_cl_N, print_csrc)
 public:
-       print_csrc_cl_N();
        print_csrc_cl_N(std::ostream &, unsigned options = 0);
-       print_context * duplicate() const {return new print_csrc_cl_N(*this);}
 };
 
 /** Check if obj is a T, including base classes. */
 template <class T>
 inline bool is_a(const print_context & obj)
-{ return dynamic_cast<const T *>(&obj)!=0; }
+{ return dynamic_cast<const T *>(&obj) != 0; }
 
 } // namespace GiNaC