use new-style print methods
authorChristian Bauer <Christian.Bauer@uni-mainz.de>
Wed, 13 Aug 2003 20:44:07 +0000 (20:44 +0000)
committerChristian Bauer <Christian.Bauer@uni-mainz.de>
Wed, 13 Aug 2003 20:44:07 +0000 (20:44 +0000)
23 files changed:
ginac/clifford.cpp
ginac/color.cpp
ginac/constant.cpp
ginac/expairseq.cpp
ginac/expairseq.h
ginac/fail.cpp
ginac/fderivative.cpp
ginac/fderivative.h
ginac/idx.cpp
ginac/indexed.cpp
ginac/matrix.cpp
ginac/matrix.h
ginac/ncmul.cpp
ginac/ncmul.h
ginac/numeric.cpp
ginac/numeric.h
ginac/power.cpp
ginac/power.h
ginac/pseries.cpp
ginac/symbol.cpp
ginac/symmetry.cpp
ginac/tensor.cpp
ginac/wildcard.cpp

index ff834bc..3dbad50 100644 (file)
@@ -34,7 +34,6 @@
 #include "relational.h"
 #include "operators.h"
 #include "mul.h"
-#include "print.h"
 #include "archive.h"
 #include "utils.h"
 
index 1fb8e97..e84dcdb 100644 (file)
@@ -32,7 +32,6 @@
 #include "mul.h"
 #include "power.h" // for sqrt()
 #include "symbol.h"
-#include "print.h"
 #include "archive.h"
 #include "utils.h"
 
index baf1080..c8c9304 100644 (file)
@@ -27,7 +27,6 @@
 #include "constant.h"
 #include "numeric.h"
 #include "ex.h"
-#include "print.h"
 #include "archive.h"
 #include "utils.h"
 
index fe09681..d2ff8fb 100644 (file)
@@ -31,7 +31,6 @@
 #include "power.h"
 #include "relational.h"
 #include "wildcard.h"
-#include "print.h"
 #include "archive.h"
 #include "operators.h"
 #include "utils.h"
 namespace GiNaC {
 
        
-GINAC_IMPLEMENT_REGISTERED_CLASS(expairseq, basic)
+GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(expairseq, basic,
+  print_func<print_context>(&expairseq::do_print).
+  print_func<print_tree>(&expairseq::do_print_tree))
+
 
 //////////
 // helper classes
@@ -177,88 +179,85 @@ DEFAULT_UNARCHIVE(expairseq)
 
 // public
 
-void expairseq::print(const print_context &c, unsigned level) const
+void expairseq::do_print(const print_context & c, unsigned level) const
 {
-       if (is_a<print_tree>(c)) {
-
-               unsigned delta_indent = static_cast<const print_tree &>(c).delta_indent;
-
-               c.s << std::string(level, ' ') << class_name()
-                   << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
-                   << ", nops=" << nops()
-                   << std::endl;
-               size_t num = seq.size();
-               for (size_t i=0; i<num; ++i) {
-                       seq[i].rest.print(c, level + delta_indent);
-                       seq[i].coeff.print(c, level + delta_indent);
-                       if (i != num - 1)
-                               c.s << std::string(level + delta_indent, ' ') << "-----" << std::endl;
-               }
-               if (!overall_coeff.is_equal(default_overall_coeff())) {
-                       c.s << std::string(level + delta_indent, ' ') << "-----" << std::endl
-                           << std::string(level + delta_indent, ' ') << "overall_coeff" << std::endl;
-                       overall_coeff.print(c, level + delta_indent);
-               }
-               c.s << std::string(level + delta_indent,' ') << "=====" << std::endl;
+       c.s << "[[";
+       printseq(c, ',', precedence(), level);
+       c.s << "]]";
+}
+
+void expairseq::do_print_tree(const print_tree & c, unsigned level) const
+{
+       c.s << std::string(level, ' ') << class_name()
+           << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
+           << ", nops=" << nops()
+           << std::endl;
+       size_t num = seq.size();
+       for (size_t i=0; i<num; ++i) {
+               seq[i].rest.print(c, level + c.delta_indent);
+               seq[i].coeff.print(c, level + c.delta_indent);
+               if (i != num - 1)
+                       c.s << std::string(level + c.delta_indent, ' ') << "-----" << std::endl;
+       }
+       if (!overall_coeff.is_equal(default_overall_coeff())) {
+               c.s << std::string(level + c.delta_indent, ' ') << "-----" << std::endl
+                   << std::string(level + c.delta_indent, ' ') << "overall_coeff" << std::endl;
+               overall_coeff.print(c, level + c.delta_indent);
+       }
+       c.s << std::string(level + c.delta_indent,' ') << "=====" << std::endl;
 #if EXPAIRSEQ_USE_HASHTAB
-               c.s << std::string(level + delta_indent,' ')
-                   << "hashtab size " << hashtabsize << std::endl;
-               if (hashtabsize == 0) return;
+       c.s << std::string(level + c.delta_indent,' ')
+           << "hashtab size " << hashtabsize << std::endl;
+       if (hashtabsize == 0) return;
 #define MAXCOUNT 5
-               unsigned count[MAXCOUNT+1];
-               for (int i=0; i<MAXCOUNT+1; ++i)
-                       count[i] = 0;
-               unsigned this_bin_fill;
-               unsigned cum_fill_sq = 0;
-               unsigned cum_fill = 0;
-               for (unsigned i=0; i<hashtabsize; ++i) {
-                       this_bin_fill = 0;
-                       if (hashtab[i].size() > 0) {
-                               c.s << std::string(level + delta_indent, ' ')
-                                   << "bin " << i << " with entries ";
-                               for (epplist::const_iterator it=hashtab[i].begin();
-                                    it!=hashtab[i].end(); ++it) {
-                                       c.s << *it-seq.begin() << " ";
-                                       ++this_bin_fill;
-                               }
-                               c.s << std::endl;
-                               cum_fill += this_bin_fill;
-                               cum_fill_sq += this_bin_fill*this_bin_fill;
+       unsigned count[MAXCOUNT+1];
+       for (int i=0; i<MAXCOUNT+1; ++i)
+               count[i] = 0;
+       unsigned this_bin_fill;
+       unsigned cum_fill_sq = 0;
+       unsigned cum_fill = 0;
+       for (unsigned i=0; i<hashtabsize; ++i) {
+               this_bin_fill = 0;
+               if (hashtab[i].size() > 0) {
+                       c.s << std::string(level + c.delta_indent, ' ')
+                           << "bin " << i << " with entries ";
+                       for (epplist::const_iterator it=hashtab[i].begin();
+                            it!=hashtab[i].end(); ++it) {
+                               c.s << *it-seq.begin() << " ";
+                               ++this_bin_fill;
                        }
-                       if (this_bin_fill<MAXCOUNT)
-                               ++count[this_bin_fill];
-                       else
-                               ++count[MAXCOUNT];
-               }
-               unsigned fact = 1;
-               double cum_prob = 0;
-               double lambda = (1.0*seq.size()) / hashtabsize;
-               for (int k=0; k<MAXCOUNT; ++k) {
-                       if (k>0)
-                               fact *= k;
-                       double prob = std::pow(lambda,k)/fact * std::exp(-lambda);
-                       cum_prob += prob;
-                       c.s << std::string(level + delta_indent, ' ') << "bins with " << k << " entries: "
-                           << int(1000.0*count[k]/hashtabsize)/10.0 << "% (expected: "
-                           << int(prob*1000)/10.0 << ")" << std::endl;
+                       c.s << std::endl;
+                       cum_fill += this_bin_fill;
+                       cum_fill_sq += this_bin_fill*this_bin_fill;
                }
-               c.s << std::string(level + delta_indent, ' ') << "bins with more entries: "
-                   << int(1000.0*count[MAXCOUNT]/hashtabsize)/10.0 << "% (expected: "
-                   << int((1-cum_prob)*1000)/10.0 << ")" << std::endl;
-       
-               c.s << std::string(level + delta_indent, ' ') << "variance: "
-                   << 1.0/hashtabsize*cum_fill_sq-(1.0/hashtabsize*cum_fill)*(1.0/hashtabsize*cum_fill)
-                   << std::endl;
-               c.s << std::string(level + delta_indent, ' ') << "average fill: "
-                   << (1.0*cum_fill)/hashtabsize
-                   << " (should be equal to " << (1.0*seq.size())/hashtabsize << ")" << std::endl;
-#endif // EXPAIRSEQ_USE_HASHTAB
-
-       } else {
-               c.s << "[[";
-               printseq(c, ',', precedence(), level);
-               c.s << "]]";
+               if (this_bin_fill<MAXCOUNT)
+                       ++count[this_bin_fill];
+               else
+                       ++count[MAXCOUNT];
+       }
+       unsigned fact = 1;
+       double cum_prob = 0;
+       double lambda = (1.0*seq.size()) / hashtabsize;
+       for (int k=0; k<MAXCOUNT; ++k) {
+               if (k>0)
+                       fact *= k;
+               double prob = std::pow(lambda,k)/fact * std::exp(-lambda);
+               cum_prob += prob;
+               c.s << std::string(level + c.delta_indent, ' ') << "bins with " << k << " entries: "
+                   << int(1000.0*count[k]/hashtabsize)/10.0 << "% (expected: "
+                   << int(prob*1000)/10.0 << ")" << std::endl;
        }
+       c.s << std::string(level + c.delta_indent, ' ') << "bins with more entries: "
+           << int(1000.0*count[MAXCOUNT]/hashtabsize)/10.0 << "% (expected: "
+           << int((1-cum_prob)*1000)/10.0 << ")" << std::endl;
+
+       c.s << std::string(level + c.delta_indent, ' ') << "variance: "
+           << 1.0/hashtabsize*cum_fill_sq-(1.0/hashtabsize*cum_fill)*(1.0/hashtabsize*cum_fill)
+           << std::endl;
+       c.s << std::string(level + c.delta_indent, ' ') << "average fill: "
+           << (1.0*cum_fill)/hashtabsize
+           << " (should be equal to " << (1.0*seq.size())/hashtabsize << ")" << std::endl;
+#endif // EXPAIRSEQ_USE_HASHTAB
 }
 
 bool expairseq::info(unsigned inf) const
index b6f9bc7..6f099b4 100644 (file)
@@ -70,7 +70,6 @@ public:
        
        // functions overriding virtual functions from base classes
 public:
-       void print(const print_context & c, unsigned level = 0) const;
        unsigned precedence() const {return 10;}
        bool info(unsigned inf) const;
        size_t nops() const;
@@ -110,6 +109,8 @@ protected:
        
        // non-virtual functions in this class
 protected:
+       void do_print(const print_context & c, unsigned level) const;
+       void do_print_tree(const print_tree & c, unsigned level) const;
        void construct_from_2_ex_via_exvector(const ex & lh, const ex & rh);
        void construct_from_2_ex(const ex & lh, const ex & rh);
        void construct_from_2_expairseq(const expairseq & s1,
index 08ee89a..ab109d7 100644 (file)
@@ -24,7 +24,6 @@
 #include <iostream>
 
 #include "fail.h"
-#include "print.h"
 #include "archive.h"
 #include "utils.h"
 
index 4a93de4..1c76699 100644 (file)
 
 #include "fderivative.h"
 #include "operators.h"
-#include "print.h"
 #include "archive.h"
 #include "utils.h"
 
 namespace GiNaC {
 
-GINAC_IMPLEMENT_REGISTERED_CLASS(fderivative, function)
+GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(fderivative, function,
+  print_func<print_context>(&fderivative::do_print).
+  print_func<print_tree>(&fderivative::do_print_tree))
 
 //////////
 // default constructor
@@ -94,35 +95,32 @@ DEFAULT_UNARCHIVE(fderivative)
 // functions overriding virtual functions from base classes
 //////////
 
-void fderivative::print(const print_context & c, unsigned level) const
-{
-       if (is_a<print_tree>(c)) {
-
-               c.s << std::string(level, ' ') << class_name() << " "
-                   << registered_functions()[serial].name
-                   << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
-                   << ", nops=" << nops()
-                   << ", params=";
-               paramset::const_iterator i = parameter_set.begin(), end = parameter_set.end();
-               --end;
-               while (i != end)
-                       c.s << *i++ << ",";
-               c.s << *i << std::endl;
-               unsigned delta_indent = static_cast<const print_tree &>(c).delta_indent;
-               for (size_t i=0; i<seq.size(); ++i)
-                       seq[i].print(c, level + delta_indent);
-               c.s << std::string(level + delta_indent, ' ') << "=====" << std::endl;
-
-       } else {
-
-               c.s << "D[";
-               paramset::const_iterator i = parameter_set.begin(), end = parameter_set.end();
-               --end;
-               while (i != end)
-                       c.s << *i++ << ",";
-               c.s << *i << "](" << registered_functions()[serial].name << ")";
-               printseq(c, '(', ',', ')', exprseq::precedence(), function::precedence());
-       }
+void fderivative::do_print(const print_context & c, unsigned level) const
+{
+       c.s << "D[";
+       paramset::const_iterator i = parameter_set.begin(), end = parameter_set.end();
+       --end;
+       while (i != end)
+               c.s << *i++ << ",";
+       c.s << *i << "](" << registered_functions()[serial].name << ")";
+       printseq(c, '(', ',', ')', exprseq::precedence(), function::precedence());
+}
+
+void fderivative::do_print_tree(const print_tree & c, unsigned level) const
+{
+       c.s << std::string(level, ' ') << class_name() << " "
+           << registered_functions()[serial].name
+           << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
+           << ", nops=" << nops()
+           << ", params=";
+       paramset::const_iterator i = parameter_set.begin(), end = parameter_set.end();
+       --end;
+       while (i != end)
+               c.s << *i++ << ",";
+       c.s << *i << std::endl;
+       for (size_t i=0; i<seq.size(); ++i)
+               seq[i].print(c, level + c.delta_indent);
+       c.s << std::string(level + c.delta_indent, ' ') << "=====" << std::endl;
 }
 
 ex fderivative::eval(int level) const
index 3e335be..c165d31 100644 (file)
@@ -60,7 +60,6 @@ public:
 
        // functions overriding virtual functions from base classes
 public:
-       void print(const print_context & c, unsigned level = 0) const;
        ex eval(int level = 0) const;
        ex evalf(int level = 0) const;
        ex series(const relational & r, int order, unsigned options = 0) const;
@@ -71,6 +70,11 @@ protected:
        bool is_equal_same_type(const basic & other) const;
        bool match_same_type(const basic & other) const;
 
+       // non-virtual functions in this class
+protected:
+       void do_print(const print_context & c, unsigned level) const;
+       void do_print_tree(const print_tree & c, unsigned level) const;
+
        // member variables
 protected:
        paramset parameter_set; /**< Set of parameter numbers with respect to which to take the derivative */
index 4dd4d1a..be9d6b4 100644 (file)
@@ -29,7 +29,6 @@
 #include "lst.h"
 #include "relational.h"
 #include "operators.h"
-#include "print.h"
 #include "archive.h"
 #include "utils.h"
 
index 48bb142..412aad5 100644 (file)
@@ -34,7 +34,6 @@
 #include "symmetry.h"
 #include "operators.h"
 #include "lst.h"
-#include "print.h"
 #include "archive.h"
 #include "utils.h"
 
index c9b3521..db59161 100644 (file)
@@ -137,7 +137,7 @@ DEFAULT_UNARCHIVE(matrix)
 
 // public
 
-void matrix::print_elements(const print_context & c, const std::string & row_start, const std::string & row_end, const std::string & row_sep, const std::string & col_sep) const
+void matrix::print_elements(const print_context & c, const char *row_start, const char *row_end, const char *row_sep, const char *col_sep) const
 {
        for (unsigned ro=0; ro<row; ++ro) {
                c.s << row_start;
index f5cd5de..99c9abc 100644 (file)
@@ -87,7 +87,7 @@ protected:
        int fraction_free_elimination(const bool det = false);
        int pivot(unsigned ro, unsigned co, bool symbolic = true);
 
-       void print_elements(const print_context & c, const std::string & row_start, const std::string & row_end, const std::string & row_sep, const std::string & col_sep) const;
+       void print_elements(const print_context & c, const char *row_start, const char *row_end, const char *row_sep, const char *col_sep) const;
        void do_print(const print_context & c, unsigned level) const;
        void do_print_latex(const print_latex & c, unsigned level) const;
        void do_print_python_repr(const print_python_repr & c, unsigned level) const;
index dd0c7bd..163c3c8 100644 (file)
 #include "add.h"
 #include "mul.h"
 #include "matrix.h"
-#include "print.h"
 #include "archive.h"
 #include "utils.h"
 
 namespace GiNaC {
 
-GINAC_IMPLEMENT_REGISTERED_CLASS(ncmul, exprseq)
+GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(ncmul, exprseq,
+  print_func<print_context>(&ncmul::do_print).
+  print_func<print_tree>(&basic::do_print_tree).
+  print_func<print_csrc>(&ncmul::do_print_csrc).
+  print_func<print_python_repr>(&ncmul::do_print_csrc))
+
 
 //////////
 // default constructor
@@ -102,26 +106,15 @@ DEFAULT_ARCHIVING(ncmul)
 
 // public
 
-void ncmul::print(const print_context & c, unsigned level) const
+void ncmul::do_print(const print_context & c, unsigned level) const
 {
-       if (is_a<print_tree>(c)) {
-
-               inherited::print(c, level);
-
-       } else if (is_a<print_csrc>(c) || is_a<print_python_repr>(c)) {
-
-               c.s << class_name() << "(";
-               exvector::const_iterator it = seq.begin(), itend = seq.end()-1;
-               while (it != itend) {
-                       it->print(c, precedence());
-                       c.s << ",";
-                       it++;
-               }
-               it->print(c, precedence());
-               c.s << ")";
+       printseq(c, '(', '*', ')', precedence(), level);
+}
 
-       } else
-               printseq(c, '(', '*', ')', precedence(), level);
+void ncmul::do_print_csrc(const print_context & c, unsigned level) const
+{
+       c.s << class_name();
+       printseq(c, '(', ',', ')', precedence(), precedence());
 }
 
 bool ncmul::info(unsigned inf) const
index 072ebfb..57cb08c 100644 (file)
@@ -53,7 +53,6 @@ public:
 
        // functions overriding virtual functions from base classes
 public:
-       void print(const print_context & c, unsigned level = 0) const;
        unsigned precedence() const {return 50;}
        bool info(unsigned inf) const;
        int degree(const ex & s) const;
@@ -76,6 +75,8 @@ protected:
 
        // non-virtual functions in this class
 protected:
+       void do_print(const print_context & c, unsigned level) const;
+       void do_print_csrc(const print_context & c, unsigned level) const;
        size_t count_factors(const ex & e) const;
        void append_factors(exvector & v, const ex & e) const;
        exvector expandchildren(unsigned options) const;
index c69a117..6074aea 100644 (file)
@@ -34,7 +34,6 @@
 
 #include "numeric.h"
 #include "ex.h"
-#include "print.h"
 #include "operators.h"
 #include "archive.h"
 #include "tostring.h"
 
 namespace GiNaC {
 
-GINAC_IMPLEMENT_REGISTERED_CLASS(numeric, basic)
+GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(numeric, basic,
+  print_func<print_context>(&numeric::do_print).
+  print_func<print_latex>(&numeric::do_print_latex).
+  print_func<print_csrc>(&numeric::do_print_csrc).
+  print_func<print_csrc_cl_N>(&numeric::do_print_csrc_cl_N).
+  print_func<print_tree>(&numeric::do_print_tree).
+  print_func<print_python_repr>(&numeric::do_print_python_repr))
 
 //////////
 // default constructor
@@ -410,140 +415,148 @@ static void print_real_cl_N(const print_context & c, const cln::cl_R & x)
        }
 }
 
-/** This method adds to the output so it blends more consistently together
- *  with the other routines and produces something compatible to ginsh input.
- *  
- *  @see print_real_number() */
-void numeric::print(const print_context & c, unsigned level) const
+void numeric::print_numeric(const print_context & c, const char *par_open, const char *par_close, const char *imag_sym, const char *mul_sym, unsigned level) const
 {
-       if (is_a<print_tree>(c)) {
+       const cln::cl_R r = cln::realpart(cln::the<cln::cl_N>(value));
+       const cln::cl_R i = cln::imagpart(cln::the<cln::cl_N>(value));
 
-               c.s << std::string(level, ' ') << cln::the<cln::cl_N>(value)
-                   << " (" << class_name() << ")"
-                   << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
-                   << std::endl;
+       if (cln::zerop(i)) {
 
-       } else if (is_a<print_csrc_cl_N>(c)) {
+               // case 1, real:  x  or  -x
+               if ((precedence() <= level) && (!this->is_nonneg_integer())) {
+                       c.s << par_open;
+                       print_real_number(c, r);
+                       c.s << par_close;
+               } else {
+                       print_real_number(c, r);
+               }
 
-               // CLN output
-               if (this->is_real()) {
+       } else {
+               if (cln::zerop(r)) {
 
-                       // Real number
-                       print_real_cl_N(c, cln::the<cln::cl_R>(value));
+                       // case 2, imaginary:  y*I  or  -y*I
+                       if (i == 1)
+                               c.s << imag_sym;
+                       else {
+                               if (precedence()<=level)
+                                       c.s << par_open;
+                               if (i == -1)
+                                       c.s << "-" << imag_sym;
+                               else {
+                                       print_real_number(c, i);
+                                       c.s << mul_sym << imag_sym;
+                               }
+                               if (precedence()<=level)
+                                       c.s << par_close;
+                       }
 
                } else {
 
-                       // Complex number
-                       c.s << "cln::complex(";
-                       print_real_cl_N(c, cln::realpart(cln::the<cln::cl_N>(value)));
-                       c.s << ",";
-                       print_real_cl_N(c, cln::imagpart(cln::the<cln::cl_N>(value)));
-                       c.s << ")";
+                       // case 3, complex:  x+y*I  or  x-y*I  or  -x+y*I  or  -x-y*I
+                       if (precedence() <= level)
+                               c.s << par_open;
+                       print_real_number(c, r);
+                       if (i < 0) {
+                               if (i == -1) {
+                                       c.s << "-" << imag_sym;
+                               } else {
+                                       print_real_number(c, i);
+                                       c.s << mul_sym << imag_sym;
+                               }
+                       } else {
+                               if (i == 1) {
+                                       c.s << "+" << imag_sym;
+                               } else {
+                                       c.s << "+";
+                                       print_real_number(c, i);
+                                       c.s << mul_sym << imag_sym;
+                               }
+                       }
+                       if (precedence() <= level)
+                               c.s << par_close;
                }
+       }
+}
 
-       } else if (is_a<print_csrc>(c)) {
+void numeric::do_print(const print_context & c, unsigned level) const
+{
+       print_numeric(c, "(", ")", "I", "*", level);
+}
 
-               // C++ source output
-               std::ios::fmtflags oldflags = c.s.flags();
-               c.s.setf(std::ios::scientific);
-               int oldprec = c.s.precision();
+void numeric::do_print_latex(const print_latex & c, unsigned level) const
+{
+       print_numeric(c, "{(", ")}", "i", " ", level);
+}
 
-               // Set precision
-               if (is_a<print_csrc_double>(c))
-                       c.s.precision(std::numeric_limits<double>::digits10 + 1);
-               else
-                       c.s.precision(std::numeric_limits<float>::digits10 + 1);
+void numeric::do_print_csrc(const print_csrc & c, unsigned level) const
+{
+       std::ios::fmtflags oldflags = c.s.flags();
+       c.s.setf(std::ios::scientific);
+       int oldprec = c.s.precision();
 
-               if (this->is_real()) {
+       // Set precision
+       if (is_a<print_csrc_double>(c))
+               c.s.precision(std::numeric_limits<double>::digits10 + 1);
+       else
+               c.s.precision(std::numeric_limits<float>::digits10 + 1);
 
-                       // Real number
-                       print_real_csrc(c, cln::the<cln::cl_R>(value));
+       if (this->is_real()) {
 
-               } else {
+               // Real number
+               print_real_csrc(c, cln::the<cln::cl_R>(value));
 
-                       // Complex number
-                       c.s << "std::complex<";
-                       if (is_a<print_csrc_double>(c))
-                               c.s << "double>(";
-                       else
-                               c.s << "float>(";
+       } else {
 
-                       print_real_csrc(c, cln::realpart(cln::the<cln::cl_N>(value)));
-                       c.s << ",";
-                       print_real_csrc(c, cln::imagpart(cln::the<cln::cl_N>(value)));
-                       c.s << ")";
-               }
+               // Complex number
+               c.s << "std::complex<";
+               if (is_a<print_csrc_double>(c))
+                       c.s << "double>(";
+               else
+                       c.s << "float>(";
+
+               print_real_csrc(c, cln::realpart(cln::the<cln::cl_N>(value)));
+               c.s << ",";
+               print_real_csrc(c, cln::imagpart(cln::the<cln::cl_N>(value)));
+               c.s << ")";
+       }
+
+       c.s.flags(oldflags);
+       c.s.precision(oldprec);
+}
 
-               c.s.flags(oldflags);
-               c.s.precision(oldprec);
+void numeric::do_print_csrc_cl_N(const print_csrc_cl_N & c, unsigned level) const
+{
+       if (this->is_real()) {
+
+               // Real number
+               print_real_cl_N(c, cln::the<cln::cl_R>(value));
 
        } else {
 
-               const std::string par_open  = is_a<print_latex>(c) ? "{(" : "(";
-               const std::string par_close = is_a<print_latex>(c) ? ")}" : ")";
-               const std::string imag_sym  = is_a<print_latex>(c) ? "i" : "I";
-               const std::string mul_sym   = is_a<print_latex>(c) ? " " : "*";
-               const cln::cl_R r = cln::realpart(cln::the<cln::cl_N>(value));
-               const cln::cl_R i = cln::imagpart(cln::the<cln::cl_N>(value));
-
-               if (is_a<print_python_repr>(c))
-                       c.s << class_name() << "('";
-               if (cln::zerop(i)) {
-                       // case 1, real:  x  or  -x
-                       if ((precedence() <= level) && (!this->is_nonneg_integer())) {
-                               c.s << par_open;
-                               print_real_number(c, r);
-                               c.s << par_close;
-                       } else {
-                               print_real_number(c, r);
-                       }
-               } else {
-                       if (cln::zerop(r)) {
-                               // case 2, imaginary:  y*I  or  -y*I
-                               if (i==1)
-                                       c.s << imag_sym;
-                               else {
-                                       if (precedence()<=level)
-                                               c.s << par_open;
-                                       if (i == -1)
-                                               c.s << "-" << imag_sym;
-                                       else {
-                                               print_real_number(c, i);
-                                               c.s << mul_sym+imag_sym;
-                                       }
-                                       if (precedence()<=level)
-                                               c.s << par_close;
-                               }
-                       } else {
-                               // case 3, complex:  x+y*I  or  x-y*I  or  -x+y*I  or  -x-y*I
-                               if (precedence() <= level)
-                                       c.s << par_open;
-                               print_real_number(c, r);
-                               if (i < 0) {
-                                       if (i == -1) {
-                                               c.s << "-"+imag_sym;
-                                       } else {
-                                               print_real_number(c, i);
-                                               c.s << mul_sym+imag_sym;
-                                       }
-                               } else {
-                                       if (i == 1) {
-                                               c.s << "+"+imag_sym;
-                                       } else {
-                                               c.s << "+";
-                                               print_real_number(c, i);
-                                               c.s << mul_sym+imag_sym;
-                                       }
-                               }
-                               if (precedence() <= level)
-                                       c.s << par_close;
-                       }
-               }
-               if (is_a<print_python_repr>(c))
-                       c.s << "')";
+               // Complex number
+               c.s << "cln::complex(";
+               print_real_cl_N(c, cln::realpart(cln::the<cln::cl_N>(value)));
+               c.s << ",";
+               print_real_cl_N(c, cln::imagpart(cln::the<cln::cl_N>(value)));
+               c.s << ")";
        }
 }
 
+void numeric::do_print_tree(const print_tree & c, unsigned level) const
+{
+       c.s << std::string(level, ' ') << cln::the<cln::cl_N>(value)
+           << " (" << class_name() << ")"
+           << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
+           << std::endl;
+}
+
+void numeric::do_print_python_repr(const print_python_repr & c, unsigned level) const
+{
+       c.s << class_name() << "('";
+       print_numeric(c, "(", ")", "I", "*", level);
+       c.s << "')";
+}
+
 bool numeric::info(unsigned inf) const
 {
        switch (inf) {
index 691d7de..b7c1e37 100644 (file)
@@ -95,7 +95,6 @@ public:
        
        // functions overriding virtual functions from base classes
 public:
-       void print(const print_context & c, unsigned level = 0) const;
        unsigned precedence() const {return 30;}
        bool info(unsigned inf) const;
        int degree(const ex & s) const;
@@ -174,6 +173,15 @@ public:
        // converting routines for interfacing with CLN:
        numeric(const cln::cl_N &z);
 
+protected:
+       void print_numeric(const print_context & c, const char *par_open, const char *par_close, const char *imag_sym, const char *mul_sym, unsigned level) const;
+       void do_print(const print_context & c, unsigned level) const;
+       void do_print_latex(const print_latex & c, unsigned level) const;
+       void do_print_csrc(const print_csrc & c, unsigned level) const;
+       void do_print_csrc_cl_N(const print_csrc_cl_N & c, unsigned level) const;
+       void do_print_tree(const print_tree & c, unsigned level) const;
+       void do_print_python_repr(const print_python_repr & c, unsigned level) const;
+
 // member variables
 
 protected:
index fab41d8..1aade2e 100644 (file)
 #include "indexed.h"
 #include "symbol.h"
 #include "lst.h"
-#include "print.h"
 #include "archive.h"
 #include "utils.h"
 
 namespace GiNaC {
 
-GINAC_IMPLEMENT_REGISTERED_CLASS(power, basic)
+GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(power, basic,
+  print_func<print_dflt>(&power::do_print_dflt).
+  print_func<print_latex>(&power::do_print_latex).
+  print_func<print_csrc>(&power::do_print_csrc).
+  print_func<print_python>(&power::do_print_python).
+  print_func<print_python_repr>(&power::do_print_python_repr))
 
 typedef std::vector<int> intvector;
 
@@ -85,6 +89,53 @@ DEFAULT_UNARCHIVE(power)
 
 // public
 
+void power::print_power(const print_context & c, const char *powersymbol, const char *openbrace, const char *closebrace, unsigned level) const
+{
+       // Ordinary output of powers using '^' or '**'
+       if (precedence() <= level)
+               c.s << openbrace << '(';
+       basis.print(c, precedence());
+       c.s << powersymbol;
+       c.s << openbrace;
+       exponent.print(c, precedence());
+       c.s << closebrace;
+       if (precedence() <= level)
+               c.s << closebrace << ')';
+}
+
+void power::do_print_dflt(const print_dflt & c, unsigned level) const
+{
+       if (exponent.is_equal(_ex1_2)) {
+
+               // Square roots are printed in a special way
+               c.s << "sqrt(";
+               basis.print(c);
+               c.s << ')';
+
+       } else
+               print_power(c, "^", "", "", level);
+}
+
+void power::do_print_latex(const print_latex & c, unsigned level) const
+{
+       if (is_exactly_a<numeric>(exponent) && ex_to<numeric>(exponent).is_negative()) {
+
+               // Powers with negative numeric exponents are printed as fractions
+               c.s << "\\frac{1}{";
+               power(basis, -exponent).eval().print(c);
+               c.s << '}';
+
+       } else if (exponent.is_equal(_ex1_2)) {
+
+               // Square roots are printed in a special way
+               c.s << "\\sqrt{";
+               basis.print(c);
+               c.s << '}';
+
+       } else
+               print_power(c, "^", "{", "}", level);
+}
+
 static void print_sym_pow(const print_context & c, const symbol &x, int exp)
 {
        // Optimal output of integer powers of symbols to aid compiler CSE.
@@ -109,96 +160,58 @@ static void print_sym_pow(const print_context & c, const symbol &x, int exp)
        }
 }
 
-void power::print(const print_context & c, unsigned level) const
+void power::do_print_csrc(const print_csrc & c, unsigned level) const
 {
-       if (is_a<print_tree>(c)) {
-
-               inherited::print(c, level);
-
-       } else if (is_a<print_csrc>(c)) {
-
-               // Integer powers of symbols are printed in a special, optimized way
-               if (exponent.info(info_flags::integer)
-                && (is_a<symbol>(basis) || is_a<constant>(basis))) {
-                       int exp = ex_to<numeric>(exponent).to_int();
-                       if (exp > 0)
-                               c.s << '(';
-                       else {
-                               exp = -exp;
-                               if (is_a<print_csrc_cl_N>(c))
-                                       c.s << "recip(";
-                               else
-                                       c.s << "1.0/(";
-                       }
-                       print_sym_pow(c, ex_to<symbol>(basis), exp);
-                       c.s << ')';
-
-               // <expr>^-1 is printed as "1.0/<expr>" or with the recip() function of CLN
-               } else if (exponent.is_equal(_ex_1)) {
+       // Integer powers of symbols are printed in a special, optimized way
+       if (exponent.info(info_flags::integer)
+        && (is_a<symbol>(basis) || is_a<constant>(basis))) {
+               int exp = ex_to<numeric>(exponent).to_int();
+               if (exp > 0)
+                       c.s << '(';
+               else {
+                       exp = -exp;
                        if (is_a<print_csrc_cl_N>(c))
                                c.s << "recip(";
                        else
                                c.s << "1.0/(";
-                       basis.print(c);
-                       c.s << ')';
-
-               // Otherwise, use the pow() or expt() (CLN) functions
-               } else {
-                       if (is_a<print_csrc_cl_N>(c))
-                               c.s << "expt(";
-                       else
-                               c.s << "pow(";
-                       basis.print(c);
-                       c.s << ',';
-                       exponent.print(c);
-                       c.s << ')';
                }
+               print_sym_pow(c, ex_to<symbol>(basis), exp);
+               c.s << ')';
 
-       } else if (is_a<print_python_repr>(c)) {
+       // <expr>^-1 is printed as "1.0/<expr>" or with the recip() function of CLN
+       } else if (exponent.is_equal(_ex_1)) {
+               if (is_a<print_csrc_cl_N>(c))
+                       c.s << "recip(";
+               else
+                       c.s << "1.0/(";
+               basis.print(c);
+               c.s << ')';
 
-               c.s << class_name() << '(';
+       // Otherwise, use the pow() or expt() (CLN) functions
+       } else {
+               if (is_a<print_csrc_cl_N>(c))
+                       c.s << "expt(";
+               else
+                       c.s << "pow(";
                basis.print(c);
                c.s << ',';
                exponent.print(c);
                c.s << ')';
+       }
+}
 
-       } else {
-
-               bool is_tex = is_a<print_latex>(c);
-
-               if (is_tex && is_exactly_a<numeric>(exponent) && ex_to<numeric>(exponent).is_negative()) {
-
-                       // Powers with negative numeric exponents are printed as fractions in TeX
-                       c.s << "\\frac{1}{";
-                       power(basis, -exponent).eval().print(c);
-                       c.s << "}";
-
-               } else if (exponent.is_equal(_ex1_2)) {
-
-                       // Square roots are printed in a special way
-                       c.s << (is_tex ? "\\sqrt{" : "sqrt(");
-                       basis.print(c);
-                       c.s << (is_tex ? '}' : ')');
-
-               } else {
+void power::do_print_python(const print_python & c, unsigned level) const
+{
+       print_power(c, "**", "", "", level);
+}
 
-                       // Ordinary output of powers using '^' or '**'
-                       if (precedence() <= level)
-                               c.s << (is_tex ? "{(" : "(");
-                       basis.print(c, precedence());
-                       if (is_a<print_python>(c))
-                               c.s << "**";
-                       else
-                               c.s << '^';
-                       if (is_tex)
-                               c.s << '{';
-                       exponent.print(c, precedence());
-                       if (is_tex)
-                               c.s << '}';
-                       if (precedence() <= level)
-                               c.s << (is_tex ? ")}" : ")");
-               }
-       }
+void power::do_print_python_repr(const print_python_repr & c, unsigned level) const
+{
+       c.s << class_name() << '(';
+       basis.print(c);
+       c.s << ',';
+       exponent.print(c);
+       c.s << ')';
 }
 
 bool power::info(unsigned inf) const
index f808f97..4fdbf44 100644 (file)
@@ -48,7 +48,6 @@ public:
        
        // functions overriding virtual functions from base classes
 public:
-       void print(const print_context & c, unsigned level = 0) const;
        unsigned precedence() const {return 60;}
        bool info(unsigned inf) const;
        size_t nops() const;
@@ -78,6 +77,13 @@ protected:
        
        // non-virtual functions in this class
 protected:
+       void print_power(const print_context & c, const char *powersymbol, const char *openbrace, const char *closebrace, unsigned level) const;
+       void do_print_dflt(const print_dflt & c, unsigned level) const;
+       void do_print_latex(const print_latex & c, unsigned level) const;
+       void do_print_csrc(const print_csrc & c, unsigned level) const;
+       void do_print_python(const print_python & c, unsigned level) const;
+       void do_print_python_repr(const print_python_repr & c, unsigned level) const;
+
        ex expand_add(const add & a, int n) const;
        ex expand_add_2(const add & a) const;
        ex expand_mul(const mul & m, const numeric & n) const;
index 48dfa1e..224d28d 100644 (file)
@@ -33,7 +33,6 @@
 #include "relational.h"
 #include "operators.h"
 #include "symbol.h"
-#include "print.h"
 #include "archive.h"
 #include "utils.h"
 
index 1ed94f3..31fc1d6 100644 (file)
@@ -25,7 +25,6 @@
 
 #include "symbol.h"
 #include "lst.h"
-#include "print.h"
 #include "archive.h"
 #include "tostring.h"
 #include "utils.h"
index 6a50fe1..7828c27 100644 (file)
@@ -28,7 +28,6 @@
 #include "lst.h"
 #include "numeric.h" // for factorial()
 #include "operators.h"
-#include "print.h"
 #include "archive.h"
 #include "utils.h"
 
index a682f2d..07605e7 100644 (file)
@@ -33,7 +33,6 @@
 #include "lst.h"
 #include "numeric.h"
 #include "matrix.h"
-#include "print.h"
 #include "archive.h"
 #include "utils.h"
 
index a0d5934..a538838 100644 (file)
@@ -23,7 +23,6 @@
 #include <iostream>
 
 #include "wildcard.h"
-#include "print.h"
 #include "archive.h"
 #include "utils.h"