- replaced the various print*() member functions by a single print() that
authorChristian Bauer <Christian.Bauer@uni-mainz.de>
Fri, 6 Apr 2001 23:02:58 +0000 (23:02 +0000)
committerChristian Bauer <Christian.Bauer@uni-mainz.de>
Fri, 6 Apr 2001 23:02:58 +0000 (23:02 +0000)
  takes a print_context object that determines the output formatting; this
  should make it easier to add more output types
- print_tree output of indexed objects looks better

49 files changed:
ginac/Makefile.am
ginac/add.cpp
ginac/add.h
ginac/basic.cpp
ginac/basic.h
ginac/clifford.cpp
ginac/clifford.h
ginac/color.cpp
ginac/color.h
ginac/constant.cpp
ginac/constant.h
ginac/container.pl
ginac/ex.cpp
ginac/ex.h
ginac/expair.h
ginac/expairseq.cpp
ginac/expairseq.h
ginac/fail.cpp
ginac/fail.h
ginac/flags.h
ginac/function.pl
ginac/ginac.h
ginac/idx.cpp
ginac/idx.h
ginac/indexed.cpp
ginac/indexed.h
ginac/matrix.cpp
ginac/matrix.h
ginac/mul.cpp
ginac/mul.h
ginac/ncmul.cpp
ginac/ncmul.h
ginac/numeric.cpp
ginac/numeric.h
ginac/operators.cpp
ginac/power.cpp
ginac/power.h
ginac/print.h [new file with mode: 0644]
ginac/pseries.cpp
ginac/pseries.h
ginac/relational.cpp
ginac/relational.h
ginac/structure.cpp
ginac/structure.pl
ginac/symbol.cpp
ginac/symbol.h
ginac/tensor.cpp
ginac/tensor.h
ginac/utils.h

index 45fe861..faaa66e 100644 (file)
@@ -16,7 +16,7 @@ ginacinclude_HEADERS = ginac.h add.h archive.h basic.h constant.h ex.h \
   expair.h expairseq.h exprseq.h fail.h flags.h function.h inifcns.h \
   lst.h matrix.h mul.h ncmul.h normal.h numeric.h operators.h power.h \
   registrar.h relational.h pseries.h structure.h symbol.h tinfos.h assertion.h \
-  version.h idx.h indexed.h tensor.h color.h clifford.h
+  version.h idx.h indexed.h tensor.h color.h clifford.h print.h
 LFLAGS = -Pginac_yy -olex.yy.c
 YFLAGS = -p ginac_yy -d
 EXTRA_DIST = container.pl function.pl structure.pl input_parser.h version.h.in
index 7d73c30..0dd7dc9 100644 (file)
@@ -111,107 +111,105 @@ DEFAULT_ARCHIVING(add)
 
 // public
 
-void add::print(std::ostream & os, unsigned upper_precedence) const
+void add::print(const print_context & c, unsigned level) const
 {
-       debugmsg("add print",LOGLEVEL_PRINT);
-       if (precedence<=upper_precedence) os << "(";
-       numeric coeff;
-       bool first = true;
-       // first print the overall numeric coefficient, if present:
-       if (!overall_coeff.is_zero()) {
-               os << overall_coeff;
-               first = false;
-       }
-       // then proceed with the remaining factors:
-       for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
-               coeff = ex_to_numeric(cit->coeff);
-               if (!first) {
-                       if (coeff.csgn()==-1) os << '-'; else os << '+';
-               } else {
-                       if (coeff.csgn()==-1) os << '-';
-                       first = false;
-               }
-               if (!coeff.is_equal(_num1()) &&
-                   !coeff.is_equal(_num_1())) {
-                       if (coeff.is_rational()) {
-                               if (coeff.is_negative())
-                                       os << -coeff;
-                               else
-                                       os << coeff;
-                       } else {
-                               if (coeff.csgn()==-1)
-                                       (-coeff).print(os, precedence);
-                               else
-                                       coeff.print(os, precedence);
-                       }
-                       os << '*';
-               }
-               cit->rest.print(os, precedence);
-       }
-       if (precedence<=upper_precedence) os << ")";
-}
+       debugmsg("add print", LOGLEVEL_PRINT);
 
-void add::printraw(std::ostream & os) const
-{
-       debugmsg("add printraw",LOGLEVEL_PRINT);
-
-       os << "+(";
-       for (epvector::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
-               os << "(";
-               (*it).rest.bp->printraw(os);
-               os << ",";
-               (*it).coeff.bp->printraw(os);        
-               os << "),";
-       }
-       os << ",hash=" << hashvalue << ",flags=" << flags;
-       os << ")";
-}
+       if (is_of_type(c, print_tree)) {
 
-void add::printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence) const
-{
-       debugmsg("add print csrc", LOGLEVEL_PRINT);
-       if (precedence <= upper_precedence)
-               os << "(";
+               inherited::print(c, level);
+
+       } else if (is_of_type(c, print_csrc)) {
+
+               if (precedence <= level)
+                       c.s << "(";
        
-       // Print arguments, separated by "+"
-       epvector::const_iterator it = seq.begin();
-       epvector::const_iterator itend = seq.end();
-       while (it != itend) {
+               // Print arguments, separated by "+"
+               epvector::const_iterator it = seq.begin(), itend = seq.end();
+               while (it != itend) {
                
-               // If the coefficient is -1, it is replaced by a single minus sign
-               if (it->coeff.compare(_num1()) == 0) {
-                       it->rest.bp->printcsrc(os, type, precedence);
-               } else if (it->coeff.compare(_num_1()) == 0) {
-                       os << "-";
-                       it->rest.bp->printcsrc(os, type, precedence);
-               } else if (ex_to_numeric(it->coeff).numer().compare(_num1()) == 0) {
-                       it->rest.bp->printcsrc(os, type, precedence);
-                       os << "/";
-                       ex_to_numeric(it->coeff).denom().printcsrc(os, type, precedence);
-               } else if (ex_to_numeric(it->coeff).numer().compare(_num_1()) == 0) {
-                       os << "-";
-                       it->rest.bp->printcsrc(os, type, precedence);
-                       os << "/";
-                       ex_to_numeric(it->coeff).denom().printcsrc(os, type, precedence);
-               } else {
-                       it->coeff.bp->printcsrc(os, type, precedence);
-                       os << "*";
-                       it->rest.bp->printcsrc(os, type, precedence);
-               }
+                       // If the coefficient is -1, it is replaced by a single minus sign
+                       if (it->coeff.compare(_num1()) == 0) {
+                               it->rest.bp->print(c, precedence);
+                       } else if (it->coeff.compare(_num_1()) == 0) {
+                               c.s << "-";
+                               it->rest.bp->print(c, precedence);
+                       } else if (ex_to_numeric(it->coeff).numer().compare(_num1()) == 0) {
+                               it->rest.bp->print(c, precedence);
+                               c.s << "/";
+                               ex_to_numeric(it->coeff).denom().print(c, precedence);
+                       } else if (ex_to_numeric(it->coeff).numer().compare(_num_1()) == 0) {
+                               c.s << "-";
+                               it->rest.bp->print(c, precedence);
+                               c.s << "/";
+                               ex_to_numeric(it->coeff).denom().print(c, precedence);
+                       } else {
+                               it->coeff.bp->print(c, precedence);
+                               c.s << "*";
+                               it->rest.bp->print(c, precedence);
+                       }
                
-               // Separator is "+", except if the following expression would have a leading minus sign
-               it++;
-               if (it != itend && !(it->coeff.compare(_num0()) < 0 || (it->coeff.compare(_num1()) == 0 && is_ex_exactly_of_type(it->rest, numeric) && it->rest.compare(_num0()) < 0)))
-                       os << "+";
-       }
+                       // Separator is "+", except if the following expression would have a leading minus sign
+                       it++;
+                       if (it != itend && !(it->coeff.compare(_num0()) < 0 || (it->coeff.compare(_num1()) == 0 && is_ex_exactly_of_type(it->rest, numeric) && it->rest.compare(_num0()) < 0)))
+                               c.s << "+";
+               }
        
-       if (!overall_coeff.is_zero()) {
-               if (overall_coeff.info(info_flags::positive)) os << '+';
-               overall_coeff.bp->printcsrc(os,type,precedence);
-       }
+               if (!overall_coeff.is_zero()) {
+                       if (overall_coeff.info(info_flags::positive))
+                               c.s << '+';
+                       overall_coeff.bp->print(c, precedence);
+               }
        
-       if (precedence <= upper_precedence)
-               os << ")";
+               if (precedence <= level)
+                       c.s << ")";
+
+       } else {
+
+               if (precedence <= level)
+                       c.s << "(";
+
+               numeric coeff;
+               bool first = true;
+
+               // First print the overall numeric coefficient, if present
+               if (!overall_coeff.is_zero()) {
+                       overall_coeff.print(c, precedence);
+                       first = false;
+               }
+
+               // Then proceed with the remaining factors
+               epvector::const_iterator it = seq.begin(), itend = seq.end();
+               while (it != itend) {
+                       coeff = ex_to_numeric(it->coeff);
+                       if (!first) {
+                               if (coeff.csgn() == -1) c.s << '-'; else c.s << '+';
+                       } else {
+                               if (coeff.csgn() == -1) c.s << '-';
+                               first = false;
+                       }
+                       if (!coeff.is_equal(_num1()) &&
+                           !coeff.is_equal(_num_1())) {
+                               if (coeff.is_rational()) {
+                                       if (coeff.is_negative())
+                                               (-coeff).print(c, precedence);
+                                       else
+                                               coeff.print(c, precedence);
+                               } else {
+                                       if (coeff.csgn() == -1)
+                                               (-coeff).print(c, precedence);
+                                       else
+                                               coeff.print(c, precedence);
+                               }
+                               c.s << '*';
+                       }
+                       it->rest.print(c, precedence);
+                       it++;
+               }
+
+               if (precedence <= level)
+                       c.s << ")";
+       }
 }
 
 bool add::info(unsigned inf) const
index 738d09b..c6d04d0 100644 (file)
@@ -46,9 +46,7 @@ public:
        
        // functions overriding virtual functions from bases classes
 public:
-       void print(std::ostream & os, unsigned upper_precedence=0) const;
-       void printraw(std::ostream & os) const;
-       void printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence=0) const;
+       void print(const print_context & c, unsigned level = 0) const;
        bool info(unsigned inf) const;
        int degree(const ex & s) const;
        int ldegree(const ex & s) const;
index c4e17cd..8040e4a 100644 (file)
@@ -21,7 +21,6 @@
  */
 
 #include <iostream>
-#include <typeinfo>
 #include <stdexcept>
 
 #include "basic.h"
@@ -31,6 +30,7 @@
 #include "symbol.h"
 #include "lst.h"
 #include "ncmul.h"
+#include "print.h"
 #include "archive.h"
 #include "utils.h"
 #include "debugmsg.h"
@@ -109,46 +109,25 @@ void basic::archive(archive_node &n) const
 
 // public
 
-/** Output to ostream formatted as parsable (as in ginsh) input.
- *  Generally, superfluous parenthesis should be avoided as far as possible. */
-void basic::print(std::ostream & os, unsigned upper_precedence) const
+/** Output to stream.
+ *  @param c print context object that describes the output formatting
+ *  @param level value that is used to identify the precedence or indentation
+ *               level for placing parentheses and formatting */
+void basic::print(const print_context & c, unsigned level) const
 {
-       debugmsg("basic print",LOGLEVEL_PRINT);
-       os << "[" << class_name() << " object]";
-}
+       debugmsg("basic print", LOGLEVEL_PRINT);
 
-/** Output to ostream in ugly raw format, so brave developers can have a look
- *  at the underlying structure. */
-void basic::printraw(std::ostream & os) const
-{
-       debugmsg("basic printraw",LOGLEVEL_PRINT);
-       os << "[" << class_name() << " object]";
-}
+       if (is_of_type(c, print_tree)) {
 
-/** Output to ostream formatted in tree- (indented-) form, so developers can
- *  have a look at the underlying structure. */
-void basic::printtree(std::ostream & os, unsigned indent) const
-{
-       debugmsg("basic printtree",LOGLEVEL_PRINT);
-       os << std::string(indent,' ') << "type=" << class_name()
-          << ", hash=" << hashvalue
-          << " (0x" << std::hex << hashvalue << std::dec << ")"
-          << ", flags=" << flags
-          << ", nops=" << nops() << std::endl;
-       for (unsigned i=0; i<nops(); ++i) {
-               op(i).printtree(os,indent+delta_indent);
-       }
-}
+               c.s << std::string(level, ' ') << class_name()
+                   << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
+                   << ", nops=" << nops()
+                   << std::endl;
+               for (unsigned i=0; i<nops(); ++i)
+                       op(i).print(c, level + static_cast<const print_tree &>(c).delta_indent);
 
-/** Output to ostream formatted as C-source.
- *
- *  @param os a stream for output
- *  @param type variable type (one of the csrc_types)
- *  @param upper_precedence operator precedence of caller
- *  @see ex::printcsrc */
-void basic::printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence) const
-{
-       debugmsg("basic print csrc", LOGLEVEL_PRINT);
+       } else
+               c.s << "[" << class_name() << " object]";
 }
 
 /** Little wrapper arount print to be called within a debugger.
@@ -156,7 +135,7 @@ void basic::printcsrc(std::ostream & os, unsigned type, unsigned upper_precedenc
  *  debugger because it might not know what cout is.  This method can be
  *  invoked with no argument and it will simply print to stdout.
  *
- *  @see basic::print*/
+ *  @see basic::print */
 void basic::dbgprint(void) const
 {
        this->print(std::cerr);
@@ -169,7 +148,7 @@ void basic::dbgprint(void) const
  *  @see basic::printtree */
 void basic::dbgprinttree(void) const
 {
-       this->printtree(std::cerr,0);
+       this->print(print_tree(std::cerr));
 }
 
 /** Create a new copy of this on the heap.  One can think of this as simulating
@@ -512,18 +491,18 @@ int basic::compare(const basic & other) const
        if (typeid_this<typeid_other) {
 //             std::cout << "hash collision, different types: " 
 //                       << *this << " and " << other << std::endl;
-//             this->printraw(std::cout);
+//             this->print(print_tree(std::cout));
 //             std::cout << " and ";
-//             other.printraw(std::cout);
+//             other.print(print_tree(std::cout));
 //             std::cout << std::endl;
                return -1;
        }
        if (typeid_this>typeid_other) {
 //             std::cout << "hash collision, different types: " 
 //                       << *this << " and " << other << std::endl;
-//             this->printraw(std::cout);
+//             this->print(print_tree(std::cout));
 //             std::cout << " and ";
-//             other.printraw(std::cout);
+//             other.print(print_tree(std::cout));
 //             std::cout << std::endl;
                return 1;
        }
@@ -534,9 +513,9 @@ int basic::compare(const basic & other) const
 //     if ((cmpval!=0) && (hash_this<0x80000000U)) {
 //             std::cout << "hash collision, same type: " 
 //                       << *this << " and " << other << std::endl;
-//             this->printraw(std::cout);
+//             this->print(print_tree(std::cout));
 //             std::cout << " and ";
-//             other.printraw(std::cout);
+//             other.print(print_tree(std::cout));
 //             std::cout << std::endl;
 //     }
 //     return cmpval;
@@ -587,7 +566,6 @@ void basic::ensure_if_modifiable(void) const
 // protected
 
 unsigned basic::precedence = 70;
-unsigned basic::delta_indent = 4;
 
 //////////
 // global variables
index 1f4a4fd..a37e84d 100644 (file)
@@ -24,7 +24,6 @@
 #define __GINAC_BASIC_H__
 
 #include <iostream>
-#include <typeinfo>
 #include <vector>
 
 // CINT needs <algorithm> to work properly with <vector>
@@ -44,6 +43,7 @@ class lst;
 class numeric;
 class relational;
 class archive_node;
+class print_context;
 
 // Cint doesn't like vector<..,default_alloc> but malloc_alloc is
 // unstandardized and not supported by newer GCCs.
@@ -61,8 +61,6 @@ class basic
        
        friend class ex;
        
-// member functions
-       
        // default ctor, dtor, copy ctor assignment operator and helpers
 public:
        basic() : tinfo_key(TINFO_basic), flags(0), refcount(0)
@@ -101,10 +99,7 @@ protected:
        // new virtual functions which can be overridden by derived classes
 public: // only const functions please (may break reference counting)
        virtual basic * duplicate() const;
-       virtual void print(std::ostream & os,unsigned upper_precedence = 0) const;
-       virtual void printraw(std::ostream & os) const;
-       virtual void printtree(std::ostream & os, unsigned indent) const;
-       virtual void printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence = 0) const;
+       virtual void print(const print_context & c, unsigned level = 0) const;
        virtual void dbgprint(void) const;
        virtual void dbgprinttree(void) const;
        virtual bool info(unsigned inf) const;
@@ -158,14 +153,12 @@ public:
 protected:
        void ensure_if_modifiable(void) const;
        
-// member variables
-       
+       // member variables
 protected:
        unsigned tinfo_key;                 ///< typeinfo
        mutable unsigned flags;             ///< of type status_flags
        mutable unsigned hashvalue;         ///< hash value
        static unsigned precedence;         ///< precedence for printing parens
-       static unsigned delta_indent;       ///< precedence for printtree
 private:
        unsigned refcount;                  ///< Number of reference counts
 };
index c1c069d..ecd95b7 100644 (file)
@@ -24,6 +24,7 @@
 #include "ex.h"
 #include "idx.h"
 #include "ncmul.h"
+#include "print.h"
 #include "archive.h"
 #include "debugmsg.h"
 #include "utils.h"
index 0feef3f..50893c8 100644 (file)
@@ -62,7 +62,7 @@ class diracone : public tensor
 
        // functions overriding virtual functions from bases classes
 public:
-       void print(std::ostream & os, unsigned upper_precedence=0) const;
+       void print(const print_context & c, unsigned level = 0) const;
 };
 
 
@@ -73,7 +73,7 @@ class diracgamma : public tensor
 
        // functions overriding virtual functions from bases classes
 public:
-       void print(std::ostream & os, unsigned upper_precedence=0) const;
+       void print(const print_context & c, unsigned level = 0) const;
        bool contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const;
 };
 
index 675d327..c31a83c 100644 (file)
@@ -29,6 +29,7 @@
 #include "ncmul.h"
 #include "numeric.h"
 #include "power.h" // for sqrt()
+#include "print.h"
 #include "archive.h"
 #include "debugmsg.h"
 #include "utils.h"
index c5c57c5..e5baa85 100644 (file)
@@ -71,7 +71,7 @@ class su3one : public tensor
 
        // functions overriding virtual functions from bases classes
 public:
-       void print(std::ostream & os, unsigned upper_precedence=0) const;
+       void print(const print_context & c, unsigned level = 0) const;
 };
 
 /** This class represents an su(3) generator. */
@@ -81,7 +81,7 @@ class su3t : public tensor
 
        // functions overriding virtual functions from bases classes
 public:
-       void print(std::ostream & os, unsigned upper_precedence=0) const;
+       void print(const print_context & c, unsigned level = 0) const;
 };
 
 /** This class represents the tensor of antisymmetric su(3) structure
@@ -92,7 +92,7 @@ class su3f : public tensor
 
        // functions overriding virtual functions from bases classes
 public:
-       void print(std::ostream & os, unsigned upper_precedence=0) const;
+       void print(const print_context & c, unsigned level = 0) const;
        ex eval_indexed(const basic & i) const;
        bool contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const;
 };
@@ -104,7 +104,7 @@ class su3d : public tensor
 
        // functions overriding virtual functions from bases classes
 public:
-       void print(std::ostream & os, unsigned upper_precedence=0) const;
+       void print(const print_context & c, unsigned level = 0) const;
        ex eval_indexed(const basic & i) const;
        bool contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const;
 };
index 5aad78d..7afc35b 100644 (file)
@@ -26,6 +26,7 @@
 #include "constant.h"
 #include "numeric.h"
 #include "ex.h"
+#include "print.h"
 #include "archive.h"
 #include "debugmsg.h"
 #include "utils.h"
@@ -126,32 +127,18 @@ void constant::archive(archive_node &n) const
 
 // public
 
-void constant::print(std::ostream & os, unsigned upper_precedence) const
+void constant::print(const print_context & c, unsigned level) const
 {
-       debugmsg("constant print",LOGLEVEL_PRINT);
-       os << name;
-}
+       debugmsg("constant print", LOGLEVEL_PRINT);
 
-void constant::printraw(std::ostream & os) const
-{
-       debugmsg("constant printraw",LOGLEVEL_PRINT);
-       os << class_name() << "(" << name << ")";
-}
+       if (is_of_type(c, print_tree)) {
 
-void constant::printtree(std::ostream & os, unsigned indent) const
-{
-       debugmsg("constant printtree",LOGLEVEL_PRINT);
-       os << std::string(indent,' ') << name
-          << ", type=" << class_name()
-          << ", hash=" << hashvalue
-          << " (0x" << std::hex << hashvalue << std::dec << ")"
-          << ", flags=" << flags << std::endl;
-}
+               c.s << std::string(level, ' ') << name << " (" << class_name() << ")"
+                   << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
+                   << std::endl;
 
-void constant::printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence) const
-{
-       debugmsg("constant print csrc",LOGLEVEL_PRINT);
-       os << name;
+       } else
+               c.s << name;
 }
 
 int constant::degree(const ex & s) const
index d56f2bc..fdf0661 100644 (file)
@@ -48,10 +48,7 @@ public:
        
        // functions overriding virtual functions from bases classes
 public:
-       void print(std::ostream & os, unsigned upper_precedence = 0) const;
-       void printraw(std::ostream & os) const;
-       void printtree(std::ostream & os, unsigned indent) const;
-       void printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence = 0) const;
+       void print(const print_context & c, unsigned level = 0) const;
        int degree(const ex & s) const;
        int ldegree(const ex & s) const;
        ex coeff(const ex & s, int n = 1) const;
index 1a591ab..55da47c 100755 (executable)
@@ -204,9 +204,7 @@ public:
 ${constructors_interface}
 
 public:
-       void printraw(std::ostream & os) const;
-       void print(std::ostream & os, unsigned upper_precedence=0) const;
-       void printtree(std::ostream & os, unsigned indent) const;
+       void print(const print_context & c, unsigned level = 0) const;
        bool info(unsigned inf) const;
        unsigned nops() const;
        ex & let_op(int i);
@@ -226,9 +224,9 @@ public:
        virtual ${CONTAINER} & append(const ex & b);
 ${PREPEND_INTERFACE}
 protected:
-       virtual void printseq(std::ostream & os, char openbracket, char delim,
+       virtual void printseq(const print_context & c, char openbracket, char delim,
                              char closebracket, unsigned this_precedence,
-                             unsigned upper_precedence=0) const;
+                             unsigned upper_precedence = 0) const;
        virtual ex this${CONTAINER}(${STLT} const & v) const;
        virtual ex this${CONTAINER}(${STLT} * vp) const;
 
@@ -245,11 +243,6 @@ protected:
        static unsigned precedence;
 };
 
-// global constants
-
-extern const ${CONTAINER} some_${CONTAINER};
-extern const std::type_info & typeid_${CONTAINER};
-
 // utility functions
 inline const ${CONTAINER} &ex_to_${CONTAINER}(const ex &e)
 {
@@ -306,6 +299,7 @@ $implementation=<<END_OF_IMPLEMENTATION;
 
 #include "${CONTAINER}.h"
 #include "ex.h"
+#include "print.h"
 #include "archive.h"
 #include "debugmsg.h"
 
@@ -406,38 +400,25 @@ void ${CONTAINER}::archive(archive_node &n) const
 
 // public
 
-void ${CONTAINER}::printraw(std::ostream & os) const
+void ${CONTAINER}::print(const print_context & c, unsigned level) const
 {
-       debugmsg("${CONTAINER} printraw",LOGLEVEL_PRINT);
-
-       os << class_name() << "(";
-       for (${STLT}::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
-               (*cit).bp->printraw(os);
-               os << ",";
-       }
-       os << ")";
-}
+       debugmsg("${CONTAINER} print", LOGLEVEL_PRINT);
 
-void ${CONTAINER}::print(std::ostream & os, unsigned upper_precedence) const
-{
-       debugmsg("${CONTAINER} print",LOGLEVEL_PRINT);
-       // always print brackets around seq, ignore upper_precedence
-       printseq(os,'${open_bracket}',',','${close_bracket}',precedence,precedence+1);
-}
+       if (is_of_type(c, print_tree)) {
 
-void ${CONTAINER}::printtree(std::ostream & os, unsigned indent) const
-{
-       debugmsg("${CONTAINER} printtree",LOGLEVEL_PRINT);
+               c.s << std::string(level, ' ') << class_name()
+                   << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
+                   << ", nops=" << nops()
+                   << std::endl;
+               unsigned delta_indent = static_cast<const print_tree &>(c).delta_indent;
+               for (${STLT}::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit)
+                       cit->print(c, level + delta_indent);
+               c.s << std::string(level + delta_indent,' ') << "=====" << std::endl;
 
-       os << std::string(indent,' ') << "type=" << class_name()
-          << ", hash=" << hashvalue 
-          << " (0x" << std::hex << hashvalue << std::dec << ")"
-          << ", flags=" << flags
-          << ", nops=" << nops() << std::endl;
-       for (${STLT}::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
-               (*cit).printtree(os,indent+delta_indent);
+       } else {
+               // always print brackets around seq, ignore upper_precedence
+               printseq(c, '${open_bracket}', ',', '${close_bracket}', precedence, precedence+1);
        }
-       os << std::string(indent+delta_indent,' ') << "=====" << std::endl;
 }
 
 // ${CONTAINER}::info() will be implemented by user elsewhere";
@@ -570,23 +551,26 @@ ${PREPEND_IMPLEMENTATION}
 
 // protected
 
-void ${CONTAINER}::printseq(std::ostream & os, char openbracket, char delim,
+void ${CONTAINER}::printseq(const print_context & c, char openbracket, char delim,
                             char closebracket, unsigned this_precedence,
                             unsigned upper_precedence) const
 {
-       if (this_precedence<=upper_precedence) os << openbracket;
-       if (seq.size()!=0) {
-               ${STLT}::const_iterator it,it_last;
-               it=seq.begin();
-               it_last=seq.end();
-               --it_last;
-               for (; it!=it_last; ++it) {
-                       (*it).bp->print(os,this_precedence);
-                       os << delim;
+       if (this_precedence <= upper_precedence)
+               c.s << openbracket;
+
+       if (seq.size() != 0) {
+               ${STLT}::const_iterator it = seq.begin(), itend = seq.end();
+               --itend;
+               while (it != itend) {
+                       it->print(c, this_precedence);
+                       c.s << delim;
+                       it++;
                }
-               (*it).bp->print(os,this_precedence);
+               it->print(c, this_precedence);
        }
-       if (this_precedence<=upper_precedence) os << closebracket;
+
+       if (this_precedence <= upper_precedence)
+               c.s << closebracket;
 }
 
 ex ${CONTAINER}::this${CONTAINER}(${STLT} const & v) const
@@ -749,13 +733,6 @@ ${STLT} * ${CONTAINER}::subschildren(const lst & ls, const lst & lr) const
 
 unsigned ${CONTAINER}::precedence = 10;
 
-//////////
-// global constants
-//////////
-
-const ${CONTAINER} some_${CONTAINER};
-const std::type_info & typeid_${CONTAINER} = typeid(some_${CONTAINER});
-
 } // namespace GiNaC
 
 END_OF_IMPLEMENTATION
index 521ee1e..42cde03 100644 (file)
@@ -76,64 +76,30 @@ void ex::swap(ex & other)
        other.bp = tmpbp;
 }
 
-/** Output formatted to be useful as ginsh input. */
-void ex::print(std::ostream & os, unsigned upper_precedence) const
-{
-       debugmsg("ex print",LOGLEVEL_PRINT);
-       GINAC_ASSERT(bp!=0);
-       bp->print(os,upper_precedence);
-}
-
-/** Unreadable output with detailed type information. */
-void ex::printraw(std::ostream & os) const
-{
-       debugmsg("ex printraw",LOGLEVEL_PRINT);
+/** Print expression to stream. The formatting of the output is determined
+ *  by the kind of print_context object that is passed. Possible formattings
+ *  include ginsh-parsable output (the default), tree-like output for
+ *  debugging, and C++ source.
+ *  @see print_context */
+void ex::print(const print_context & c, unsigned level) const
+{
+       debugmsg("ex print", LOGLEVEL_PRINT);
        GINAC_ASSERT(bp!=0);
-       os << "ex(";
-       bp->printraw(os);
-       os << ")";
+       bp->print(c, level);
 }
 
-/** Very detailed and unreadable output with type information and all this. */
-void ex::printtree(std::ostream & os, unsigned indent) const
+/** Print expression to stream in a tree-like format suitable for debugging. */
+void ex::printtree(std::ostream & os) const
 {
-       debugmsg("ex printtree",LOGLEVEL_PRINT);
+       debugmsg("ex printtree", LOGLEVEL_PRINT);
        GINAC_ASSERT(bp!=0);
-       // os << "refcount=" << bp->refcount << " ";
-       bp->printtree(os,indent);
-}
-
-/** Print expression as a C++ statement. The output looks like
- *  "<type> <var_name> = <expression>;". The "type" parameter has an effect
- *  on how number literals are printed.
- *
- *  @param os output stream
- *  @param type variable type (one of the csrc_types)
- *  @param var_name variable name to be printed */
-void ex::printcsrc(std::ostream & os, unsigned type, const char *var_name) const
-{
-       debugmsg("ex print csrc", LOGLEVEL_PRINT);
-       GINAC_ASSERT(bp!=0);
-       switch (type) {
-               case csrc_types::ctype_float:
-                       os << "float ";
-                       break;
-               case csrc_types::ctype_double:
-                       os << "double ";
-                       break;
-               case csrc_types::ctype_cl_N:
-                       os << "cl_N ";
-                       break;
-       }
-       os << var_name << " = ";
-       bp->printcsrc(os, type, 0);
-       os << ";\n";
+       bp->print(print_tree(os));
 }
 
 /** Little wrapper arount print to be called within a debugger. */
 void ex::dbgprint(void) const
 {
-       debugmsg("ex dbgprint",LOGLEVEL_PRINT);
+       debugmsg("ex dbgprint", LOGLEVEL_PRINT);
        GINAC_ASSERT(bp!=0);
        bp->dbgprint();
 }
@@ -141,7 +107,7 @@ void ex::dbgprint(void) const
 /** Little wrapper arount printtree to be called within a debugger. */
 void ex::dbgprinttree(void) const
 {
-       debugmsg("ex dbgprinttree",LOGLEVEL_PRINT);
+       debugmsg("ex dbgprinttree", LOGLEVEL_PRINT);
        GINAC_ASSERT(bp!=0);
        bp->dbgprinttree();
 }
index 3358c28..accac21 100644 (file)
@@ -76,10 +76,8 @@ public:
        // non-virtual functions in this class
 public:
        void swap(ex & other);
-       void printraw(std::ostream & os) const;
-       void printtree(std::ostream & os, unsigned indent=0) const;
-       void print(std::ostream & os, unsigned upper_precedence=0) const;
-       void printcsrc(std::ostream & os, unsigned type, const char *var_name) const;
+       void print(const print_context & c, unsigned level = 0) const;
+       void printtree(std::ostream & os) const;
        void dbgprint(void) const;
        void dbgprinttree(void) const;
        bool info(unsigned inf) const;
index 2f34b4b..74744e0 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "ex.h"
 #include "numeric.h"
+#include "print.h"
 
 namespace GiNaC {
 
@@ -81,14 +82,12 @@ public:
                        return coeff.compare(other.coeff);
        }
        
-       /** Output to ostream in ugly raw format. */
-       void printraw(std::ostream & os) const
+       void print(std::ostream & os) const
        {
-               os << "expair(";
-               rest.printraw(os);
-               os << ",";
-               coeff.printraw(os);
-               os << ")";
+               os << "expair:";
+               print_tree c(os);
+               rest.print(c, c.delta_indent);
+               coeff.print(c, c.delta_indent);
        }
        
        /** True if this is of the form (numeric,ex(1)). */
index 09a38af..997fabd 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "expairseq.h"
 #include "lst.h"
+#include "print.h"
 #include "archive.h"
 #include "debugmsg.h"
 #include "utils.h"
@@ -186,102 +187,89 @@ basic *expairseq::duplicate() const
        return new expairseq(*this);
 }
 
-void expairseq::print(std::ostream &os, unsigned upper_precedence) const
+void expairseq::print(const print_context & c, unsigned level) const
 {
        debugmsg("expairseq print",LOGLEVEL_PRINT);
-       os << "[[";
-       printseq(os,',',precedence,upper_precedence);
-       os << "]]";
-}
 
-void expairseq::printraw(std::ostream &os) const
-{
-       debugmsg("expairseq printraw",LOGLEVEL_PRINT);
-       os << class_name() << "(";
-       for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
-               os << "(";
-               (*cit).rest.printraw(os);
-               os << ",";
-               (*cit).coeff.printraw(os);
-               os << "),";
-       }
-       os << ")";
-}
+       if (is_of_type(c, print_tree)) {
 
-void expairseq::printtree(std::ostream &os, unsigned indent) const
-{
-       debugmsg("expairseq printtree",LOGLEVEL_PRINT);
+               unsigned delta_indent = static_cast<const print_tree &>(c).delta_indent;
 
-       os << std::string(indent,' ') << "type=" << class_name()
-          << ", hash=" << hashvalue
-          << " (0x" << std::hex << hashvalue << std::dec << ")"
-          << ", flags=" << flags
-          << ", nops=" << nops() << std::endl;
-       for (unsigned i=0; i<seq.size(); ++i) {
-               seq[i].rest.printtree(os,indent+delta_indent);
-               seq[i].coeff.printtree(os,indent+delta_indent);
-               if (i!=seq.size()-1)
-                       os << std::string(indent+delta_indent,' ') << "-----" << std::endl;
-       }
-       if (!overall_coeff.is_equal(default_overall_coeff())) {
-               os << std::string(indent+delta_indent,' ') << "-----" << std::endl;
-               os << std::string(indent+delta_indent,' ') << "overall_coeff" << std::endl;
-               overall_coeff.printtree(os,indent+delta_indent);
-       }
-       os << std::string(indent+delta_indent,' ') << "=====" << std::endl;
+               c.s << std::string(level, ' ') << class_name()
+                   << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
+                   << ", nops=" << nops()
+                   << std::endl;
+               for (unsigned i=0; i<seq.size(); ++i) {
+                       seq[i].rest.print(c, level + delta_indent);
+                       seq[i].coeff.print(c, level + delta_indent);
+                       if (i != seq.size()-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;
 #if EXPAIRSEQ_USE_HASHTAB
-       os << std::string(indent+delta_indent,' ')
-          << "hashtab size " << hashtabsize << std::endl;
-       if (hashtabsize==0) return;
+               c.s << std::string(level + 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) {
-                       os << std::string(indent+delta_indent,' ') 
-                          << "bin " << i << " with entries ";
-                       for (epplist::const_iterator it=hashtab[i].begin();
-                            it!=hashtab[i].end(); ++it) {
-                               os << *it-seq.begin() << " ";
-                               ++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 + 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;
+                               }
+                               os << std::endl;
+                               cum_fill += this_bin_fill;
+                               cum_fill_sq += this_bin_fill*this_bin_fill;
                        }
-                       os << std::endl;
-                       cum_fill += this_bin_fill;
-                       cum_fill_sq += this_bin_fill*this_bin_fill;
+                       if (this_bin_fill<MAXCOUNT)
+                               ++count[this_bin_fill];
+                       else
+                               ++count[MAXCOUNT];
                }
-               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;
-               os << std::string(indent+delta_indent,' ') << "bins with " << k << " entries: "
-                  << int(1000.0*count[k]/hashtabsize)/10.0 << "% (expected: "
-                  << int(prob*1000)/10.0 << ")" << std::endl;
-       }
-       os << std::string(indent+delta_indent,' ') << "bins with more entries: "
-          << int(1000.0*count[MAXCOUNT]/hashtabsize)/10.0 << "% (expected: "
-          << int((1-cum_prob)*1000)/10.0 << ")" << std::endl;
-       
-       os << std::string(indent+delta_indent,' ') << "variance: "
-          << 1.0/hashtabsize*cum_fill_sq-(1.0/hashtabsize*cum_fill)*(1.0/hashtabsize*cum_fill)
-          << std::endl;
-       os << std::string(indent+delta_indent,' ') << "average fill: "
-          << (1.0*cum_fill)/hashtabsize
-          << " (should be equal to " << (1.0*seq.size())/hashtabsize << ")" << std::endl;
+               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::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 << "]]";
+       }
 }
 
 bool expairseq::info(unsigned inf) const
@@ -434,9 +422,9 @@ bool expairseq::is_equal_same_type(const basic &other) const
        // compare number of elements in each hashtab entry
        if (hashtabsize!=o.hashtabsize) {
                std::cout << "this:" << std::endl;
-               printtree(std::cout,0);
+               print(print_tree(std::cout));
                std::cout << "other:" << std::endl;
-               other.printtree(std::cout,0);
+               other.print(print_tree(std::cout));
        }
                
        GINAC_ASSERT(hashtabsize==o.hashtabsize);
@@ -549,34 +537,34 @@ ex expairseq::thisexpairseq(epvector *vp, const ex &oc) const
        return expairseq(vp,oc);
 }
 
-void expairseq::printpair(std::ostream &os, const expair &p, unsigned upper_precedence) const
+void expairseq::printpair(const print_context & c, const expair & p, unsigned upper_precedence) const
 {
-       os << "[[";
-       p.rest.bp->print(os,precedence);
-       os << ",";
-       p.coeff.bp->print(os,precedence);
-       os << "]]";
+       c.s << "[[";
+       p.rest.bp->print(c, precedence);
+       c.s << ",";
+       p.coeff.bp->print(c, precedence);
+       c.s << "]]";
 }
 
-void expairseq::printseq(std::ostream &os, char delim,
+void expairseq::printseq(const print_context & c, char delim,
                          unsigned this_precedence,
                          unsigned upper_precedence) const
 {
-       if (this_precedence<=upper_precedence)
-               os << "(";
-       epvector::const_iterator it,it_last;
-       it_last=seq.end();
-       --it_last;
+       if (this_precedence <= upper_precedence)
+               c.s << "(";
+       epvector::const_iterator it, it_last = seq.end() - 1;
        for (it=seq.begin(); it!=it_last; ++it) {
-               printpair(os,*it,this_precedence);
-               os << delim;
+               printpair(c, *it, this_precedence);
+               c.s << delim;
+       }
+       printpair(c, *it, this_precedence);
+       if (!overall_coeff.is_equal(default_overall_coeff())) {
+               c.s << delim;
+               overall_coeff.print(c, this_precedence);
        }
-       printpair(os,*it,this_precedence);
-       if (!overall_coeff.is_equal(default_overall_coeff()))
-               os << delim << overall_coeff;
        
-       if (this_precedence<=upper_precedence)
-               os << ")";
+       if (this_precedence <= upper_precedence)
+               c.s << ")";
 }
 
 
@@ -1399,32 +1387,32 @@ void expairseq::combine_same_terms(void)
  *  debugging or in assertions since being sorted is an invariance. */
 bool expairseq::is_canonical() const
 {
-       if (seq.size()<=1)
+       if (seq.size() <= 1)
                return 1;
        
 #if EXPAIRSEQ_USE_HASHTAB
-       if (hashtabsize>0) return 1; // not canoncalized
+       if (hashtabsize > 0) return 1; // not canoncalized
 #endif // EXPAIRSEQ_USE_HASHTAB
        
        epvector::const_iterator it = seq.begin();
        epvector::const_iterator it_last = it;
        for (++it; it!=seq.end(); it_last=it, ++it) {
-               if (!((*it_last).is_less(*it)||(*it_last).is_equal(*it))) {
-                       if (!is_ex_exactly_of_type((*it_last).rest,numeric)||
+               if (!((*it_last).is_less(*it) || (*it_last).is_equal(*it))) {
+                       if (!is_ex_exactly_of_type((*it_last).rest,numeric) ||
                                !is_ex_exactly_of_type((*it).rest,numeric)) {
                                // double test makes it easier to set a breakpoint...
-                               if (!is_ex_exactly_of_type((*it_last).rest,numeric)||
+                               if (!is_ex_exactly_of_type((*it_last).rest,numeric) ||
                                        !is_ex_exactly_of_type((*it).rest,numeric)) {
-                                       printpair(std::clog,*it_last,0);
+                                       printpair(std::clog, *it_last, 0);
                                        std::clog << ">";
-                                       printpair(std::clog,*it,0);
+                                       printpair(std::clog, *it, 0);
                                        std::clog << "\n";
                                        std::clog << "pair1:" << std::endl;
-                                       (*it_last).rest.printtree(std::clog);
-                                       (*it_last).coeff.printtree(std::clog);
+                                       (*it_last).rest.print(print_tree(std::clog));
+                                       (*it_last).coeff.print(print_tree(std::clog));
                                        std::clog << "pair2:" << std::endl;
-                                       (*it).rest.printtree(std::clog);
-                                       (*it).coeff.printtree(std::clog);
+                                       (*it).rest.print(print_tree(std::clog));
+                                       (*it).coeff.print(print_tree(std::clog));
                                        return 0;
                                }
                        }
index 665daed..e4e3465 100644 (file)
@@ -87,9 +87,7 @@ public:
        // functions overriding virtual functions from bases classes
 public:
        basic * duplicate() const;
-       void print(std::ostream & os, unsigned upper_precedence=0) const;
-       void printraw(std::ostream & os) const;
-       void printtree(std::ostream & os, unsigned indent) const;
+       void print(const print_context & c, unsigned level = 0) const;
        bool info(unsigned inf) const;
        unsigned nops() const;
        ex op(int i) const;
@@ -111,10 +109,10 @@ protected:
 protected:
        virtual ex thisexpairseq(const epvector & v, const ex & oc) const;
        virtual ex thisexpairseq(epvector * vp, const ex & oc) const;
-       virtual void printseq(std::ostream & os, char delim,
+       virtual void printseq(const print_context & c, char delim,
                              unsigned this_precedence,
                              unsigned upper_precedence) const;
-       virtual void printpair(std::ostream & os, const expair & p,
+       virtual void printpair(const print_context & c, const expair & p,
                               unsigned upper_precedence) const;
        virtual expair split_ex_to_pair(const ex & e) const;
        virtual expair combine_ex_with_coeff_to_pair(const ex & e,
index 7de656a..3818538 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include "fail.h"
+#include "print.h"
 #include "archive.h"
 #include "debugmsg.h"
 #include "utils.h"
index 415aba5..fdab60c 100644 (file)
@@ -34,7 +34,7 @@ class fail : public basic
        
        // functions overriding virtual functions from bases classes
 public:
-       void print(std::ostream & os, unsigned upper_precedence=0) const;
+       void print(const print_context & c, unsigned level = 0) const;
 protected:
        unsigned return_type(void) const { return return_types::noncommutative_composite; };
 };
index 987a4df..96838ce 100644 (file)
@@ -142,15 +142,6 @@ public:
        };
 };
 
-class csrc_types {
-public:
-       enum {
-               ctype_float,
-               ctype_double,
-               ctype_cl_N
-       };
-};
-
 /** Strategies how to clean up the function remember cache.
  *  @see remember_table */
 class remember_strategies {
index b36df87..947830c 100755 (executable)
@@ -333,10 +333,7 @@ $constructors_interface
 
        // functions overriding virtual functions from bases classes
 public:
-       void printraw(std::ostream & os) const; 
-       void print(std::ostream & os, unsigned upper_precedence=0) const;
-       void printtree(std::ostream & os, unsigned indent) const;
-       void printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence=0) const;
+       void print(const print_context & c, unsigned level = 0) const;
        int degree(const ex & s) const;
        int ldegree(const ex & s) const;
        ex coeff(const ex & s, int n = 1) const;
@@ -382,11 +379,6 @@ inline const function &ex_to_function(const ex &e)
 #define is_ex_the_function(OBJ, FUNCNAME) \\
        (is_ex_exactly_of_type(OBJ, function) && static_cast<GiNaC::function *>(OBJ.bp)->getserial() == function_index_##FUNCNAME)
 
-// global constants
-
-extern const function some_function;
-extern const std::type_info & typeid_function;
-
 } // namespace GiNaC
 
 #endif // ndef __GINAC_FUNCTION_H__
@@ -427,6 +419,7 @@ $implementation=<<END_OF_IMPLEMENTATION;
 #include "function.h"
 #include "ex.h"
 #include "lst.h"
+#include "print.h"
 #include "archive.h"
 #include "inifcns.h"
 #include "utils.h"
@@ -639,71 +632,46 @@ void function::archive(archive_node &n) const
 
 // public
 
-void function::printraw(std::ostream & os) const
-{
-       debugmsg("function printraw",LOGLEVEL_PRINT);
-
-       GINAC_ASSERT(serial<registered_functions().size());
-
-       os << class_name() << "(name=" << registered_functions()[serial].name;
-       for (exvector::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
-               os << ",";
-               (*it).bp->print(os);
-       }
-       os << ")";
-}
-
-void function::print(std::ostream & os, unsigned upper_precedence) const
-{
-       debugmsg("function print",LOGLEVEL_PRINT);
-
-       GINAC_ASSERT(serial<registered_functions().size());
-
-       os << registered_functions()[serial].name;
-       printseq(os,'(',',',')',exprseq::precedence,function::precedence);
-}
-
-void function::printtree(std::ostream & os, unsigned indent) const
+void function::print(const print_context & c, unsigned level) const
 {
-       debugmsg("function printtree",LOGLEVEL_PRINT);
+       debugmsg("function print", LOGLEVEL_PRINT);
 
        GINAC_ASSERT(serial<registered_functions().size());
 
-       os << std::string(indent,' ') << class_name() << " "
-          << registered_functions()[serial].name
-          << ", hash=" << hashvalue 
-          << " (0x" << std::hex << hashvalue << std::dec << ")"
-          << ", flags=" << flags
-          << ", nops=" << nops() << std::endl;
-       for (unsigned i=0; i<nops(); ++i) {
-               seq[i].printtree(os,indent+delta_indent);
-       }
-       os << std::string(indent+delta_indent,' ') << "=====" << std::endl;
-}
-
-void function::printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence) const
-{
-       debugmsg("function print csrc",LOGLEVEL_PRINT);
-
-       GINAC_ASSERT(serial<registered_functions().size());
+       if (is_of_type(c, print_tree)) {
+
+               c.s << std::string(level, ' ') << class_name() << " "
+                   << registered_functions()[serial].name
+                   << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
+                   << ", nops=" << nops()
+                   << std::endl;
+               unsigned delta_indent = static_cast<const print_tree &>(c).delta_indent;
+               for (unsigned i=0; i<nops(); ++i)
+                       seq[i].print(c, level + delta_indent);
+               c.s << std::string(level + delta_indent, ' ') << "=====" << std::endl;
+
+       } else if (is_of_type(c, print_csrc)) {
+
+               // Print function name in lowercase
+               std::string lname = registered_functions()[serial].name;
+               for (unsigned i=0; i<lname.size(); i++)
+                       lname[i] = tolower(lname[i]);
+               c.s << lname << "(";
+
+               // Print arguments, separated by commas
+               exvector::const_iterator it = seq.begin(), itend = seq.end();
+               while (it != itend) {
+                       it->print(c);
+                       it++;
+                       if (it != itend)
+                               c.s << ",";
+               }
+               c.s << ")";
 
-       // Print function name in lowercase
-       std::string lname;
-       lname=registered_functions()[serial].name;
-       for (unsigned i=0; i<lname.size(); i++)
-               lname[i] = tolower(lname[i]);
-       os << lname << "(";
-
-       // Print arguments, separated by commas
-       exvector::const_iterator it = seq.begin();
-       exvector::const_iterator itend = seq.end();
-       while (it != itend) {
-               it->bp->printcsrc(os, type, 0);
-               it++;
-               if (it != itend)
-                       os << ",";
+       } else {
+               c.s << registered_functions()[serial].name;
+               printseq(c, '(', ',', ')', exprseq::precedence, function::precedence);
        }
-       os << ")";
 }
 
 ex function::expand(unsigned options) const
@@ -989,19 +957,6 @@ unsigned function::find_function(const std::string &name, unsigned nparams)
        throw (std::runtime_error("no function '" + name + "' with " + ToString(nparams) + " parameters defined"));
 }
 
-//////////
-// static member variables
-//////////
-
-// none
-
-//////////
-// global constants
-//////////
-
-const function some_function;
-const std::type_info & typeid_function=typeid(some_function);
-
 } // namespace GiNaC
 
 END_OF_IMPLEMENTATION
index a21eb1c..1dc48fe 100644 (file)
@@ -30,6 +30,7 @@
 #include "ex.h"
 #include "normal.h"
 #include "archive.h"
+#include "print.h"
 
 #include "constant.h"
 #include "fail.h"
index 0a8686d..9f31a9a 100644 (file)
 #include "idx.h"
 #include "symbol.h"
 #include "lst.h"
+#include "print.h"
 #include "archive.h"
 #include "utils.h"
 #include "debugmsg.h"
 
-#include "exprseq.h" // !!
-
 namespace GiNaC {
 
 GINAC_IMPLEMENT_REGISTERED_CLASS(idx, basic)
@@ -122,59 +121,58 @@ DEFAULT_UNARCHIVE(varidx)
 // functions overriding virtual functions from bases classes
 //////////
 
-void idx::printraw(std::ostream & os) const
+void idx::print(const print_context & c, unsigned level) const
 {
-       debugmsg("idx printraw", LOGLEVEL_PRINT);
-
-       os << class_name() << "(";
-       value.printraw(os);
-       os << ",dim=";
-       dim.printraw(os);
-       os << ",hash=" << hashvalue << ",flags=" << flags;
-       os << ")";
-}
+       debugmsg("idx print", LOGLEVEL_PRINT);
 
-void idx::printtree(std::ostream & os, unsigned indent) const
-{
-       debugmsg("idx printtree",LOGLEVEL_PRINT);
-
-       os << std::string(indent, ' ') << "type=" << class_name();
-       value.printtree(os, indent + delta_indent);
-       os << std::string(indent, ' ');
-       os << ", hash=" << hashvalue
-          << " (0x" << std::hex << hashvalue << std::dec << ")"
-          << ", flags=" << flags << std::endl;
-}
+       if (is_of_type(c, print_tree)) {
 
-void idx::print(std::ostream & os, unsigned upper_precedence) const
-{
-       debugmsg("idx print", LOGLEVEL_PRINT);
+               c.s << std::string(level, ' ') << class_name()
+                   << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
+                   << std::endl;
+               unsigned delta_indent = static_cast<const print_tree &>(c).delta_indent;
+               value.print(c, level + delta_indent);
+               dim.print(c, level + delta_indent);
 
-       os << ".";
+       } else {
 
-       bool need_parens = !(is_ex_exactly_of_type(value, numeric) || is_ex_of_type(value, symbol));
-       if (need_parens)
-               os << "(";
-       os << value;
-       if (need_parens)
-               os << ")";
+               c.s << ".";
+               bool need_parens = !(is_ex_exactly_of_type(value, numeric) || is_ex_of_type(value, symbol));
+               if (need_parens)
+                       c.s << "(";
+               c.s << value;
+               if (need_parens)
+                       c.s << ")";
+       }
 }
 
-void varidx::print(std::ostream & os, unsigned upper_precedence) const
+void varidx::print(const print_context & c, unsigned level) const
 {
        debugmsg("varidx print", LOGLEVEL_PRINT);
 
-       if (covariant)
-               os << ".";
-       else
-               os << "~";
-
-       bool need_parens = !(is_ex_exactly_of_type(value, numeric) || is_ex_of_type(value, symbol));
-       if (need_parens)
-               os << "(";
-       os << value;
-       if (need_parens)
-               os << ")";
+       if (is_of_type(c, print_tree)) {
+
+               c.s << std::string(level, ' ') << class_name()
+                   << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
+                   << (covariant ? ", covariant" : ", contravariant")
+                   << std::endl;
+               unsigned delta_indent = static_cast<const print_tree &>(c).delta_indent;
+               value.print(c, level + delta_indent);
+               dim.print(c, level + delta_indent);
+
+       } else {
+
+               if (covariant)
+                       c.s << ".";
+               else
+                       c.s << "~";
+               bool need_parens = !(is_ex_exactly_of_type(value, numeric) || is_ex_of_type(value, symbol));
+               if (need_parens)
+                       c.s << "(";
+               c.s << value;
+               if (need_parens)
+                       c.s << ")";
+       }
 }
 
 bool idx::info(unsigned inf) const
index a54ad7c..4981fef 100644 (file)
@@ -47,9 +47,7 @@ public:
 
        // functions overriding virtual functions from bases classes
 public:
-       void printraw(std::ostream & os) const;
-       void printtree(std::ostream & os, unsigned indent) const;
-       void print(std::ostream & os, unsigned upper_precedence=0) const;
+       void print(const print_context & c, unsigned level = 0) const;
        bool info(unsigned inf) const;
        unsigned nops() const;
        ex & let_op(int i);
@@ -106,7 +104,7 @@ public:
 
        // functions overriding virtual functions from bases classes
 public:
-       void print(std::ostream & os, unsigned upper_precedence=0) const;
+       void print(const print_context & c, unsigned level = 0) const;
        bool is_dummy_pair_same_type(const basic & other) const;
 
        // non-virtual functions in this class
index 5277bf8..6fbe40b 100644 (file)
@@ -29,6 +29,7 @@
 #include "ncmul.h"
 #include "power.h"
 #include "lst.h"
+#include "print.h"
 #include "archive.h"
 #include "utils.h"
 #include "debugmsg.h"
@@ -176,42 +177,38 @@ DEFAULT_UNARCHIVE(indexed)
 // functions overriding virtual functions from bases classes
 //////////
 
-void indexed::printraw(std::ostream & os) const
+void indexed::print(const print_context & c, unsigned level) const
 {
-       debugmsg("indexed printraw", LOGLEVEL_PRINT);
+       debugmsg("indexed print", LOGLEVEL_PRINT);
        GINAC_ASSERT(seq.size() > 0);
 
-       os << class_name() << "(";
-       seq[0].printraw(os);
-       os << ",indices=";
-       printrawindices(os);
-       os << ",hash=" << hashvalue << ",flags=" << flags << ")";
-}
-
-void indexed::printtree(std::ostream & os, unsigned indent) const
-{
-       debugmsg("indexed printtree", LOGLEVEL_PRINT);
-       GINAC_ASSERT(seq.size() > 0);
+       if (is_of_type(c, print_tree)) {
 
-       os << std::string(indent, ' ') << class_name() << ", " << seq.size()-1 << " indices";
-       os << ",hash=" << hashvalue << ",flags=" << flags << std::endl;
-       printtreeindices(os, indent);
-}
+               c.s << std::string(level, ' ') << class_name()
+                   << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
+                   << ", " << seq.size()-1 << " indices";
+               switch (symmetry) {
+                       case symmetric: c.s << ", symmetric"; break;
+                       case antisymmetric: c.s << ", antisymmetric"; break;
+                       default: break;
+               }
+               c.s << std::endl;
+               unsigned delta_indent = static_cast<const print_tree &>(c).delta_indent;
+               seq[0].print(c, level + delta_indent);
+               printindices(c, level + delta_indent);
 
-void indexed::print(std::ostream & os, unsigned upper_precedence) const
-{
-       debugmsg("indexed print", LOGLEVEL_PRINT);
-       GINAC_ASSERT(seq.size() > 0);
+       } else {
 
-       const ex & base = seq[0];
-       bool need_parens = is_ex_exactly_of_type(base, add) || is_ex_exactly_of_type(base, mul)
-                       || is_ex_exactly_of_type(base, ncmul) || is_ex_exactly_of_type(base, power);
-       if (need_parens)
-               os << "(";
-       os << base;
-       if (need_parens)
-               os << ")";
-       printindices(os);
+               const ex & base = seq[0];
+               bool need_parens = is_ex_exactly_of_type(base, add) || is_ex_exactly_of_type(base, mul)
+                               || is_ex_exactly_of_type(base, ncmul) || is_ex_exactly_of_type(base, power);
+               if (need_parens)
+                       c.s << "(";
+               base.print(c);
+               if (need_parens)
+                       c.s << ")";
+               printindices(c, level);
+       }
 }
 
 bool indexed::info(unsigned inf) const
@@ -409,38 +406,12 @@ ex indexed::expand(unsigned options) const
 // non-virtual functions in this class
 //////////
 
-void indexed::printrawindices(std::ostream & os) const
-{
-       if (seq.size() > 1) {
-               exvector::const_iterator it=seq.begin() + 1, itend = seq.end();
-               while (it != itend) {
-                       it->printraw(os);
-                       it++;
-                       if (it != itend)
-                               os << ",";
-               }
-       }
-}
-
-void indexed::printtreeindices(std::ostream & os, unsigned indent) const
-{
-       if (seq.size() > 1) {
-               exvector::const_iterator it=seq.begin() + 1, itend = seq.end();
-               while (it != itend) {
-                       os << std::string(indent + delta_indent, ' ');
-                       it->printraw(os);
-                       os << std::endl;
-                       it++;
-               }
-       }
-}
-
-void indexed::printindices(std::ostream & os) const
+void indexed::printindices(const print_context & c, unsigned level) const
 {
        if (seq.size() > 1) {
                exvector::const_iterator it=seq.begin() + 1, itend = seq.end();
                while (it != itend) {
-                       it->print(os);
+                       it->print(c, level);
                        it++;
                }
        }
index e98375d..cba48c8 100644 (file)
@@ -151,9 +151,7 @@ public:
 
        // functions overriding virtual functions from base classes
 public:
-       void printraw(std::ostream & os) const;
-       void printtree(std::ostream & os, unsigned indent) const;
-       void print(std::ostream & os, unsigned upper_precedence=0) const;
+       void print(const print_context & c, unsigned level = 0) const;
        bool info(unsigned inf) const;
        ex eval(int level = 0) const;
        int degree(const ex & s) const;
@@ -187,9 +185,7 @@ public:
        exvector get_dummy_indices(const indexed & other) const;
 
 protected:
-       void printrawindices(std::ostream & os) const;
-       void printtreeindices(std::ostream & os, unsigned indent) const;
-       void printindices(std::ostream & os) const;
+       void printindices(const print_context & c, unsigned level) const;
        void assert_all_indices_of_type_idx(void) const;
 
        // member variables
index 380a45e..25de42b 100644 (file)
 #include <stdexcept>
 
 #include "matrix.h"
-#include "archive.h"
 #include "numeric.h"
 #include "lst.h"
 #include "idx.h"
 #include "indexed.h"
-#include "utils.h"
-#include "debugmsg.h"
 #include "power.h"
 #include "symbol.h"
 #include "normal.h"
+#include "print.h"
+#include "archive.h"
+#include "utils.h"
+#include "debugmsg.h"
 
 namespace GiNaC {
 
@@ -145,36 +146,35 @@ DEFAULT_UNARCHIVE(matrix)
 
 // public
 
-void matrix::print(std::ostream & os, unsigned upper_precedence) const
+void matrix::print(const print_context & c, unsigned level) const
 {
-       debugmsg("matrix print",LOGLEVEL_PRINT);
-       os << "[[ ";
-       for (unsigned r=0; r<row-1; ++r) {
-               os << "[[";
-               for (unsigned c=0; c<col-1; ++c)
-                       os << m[r*col+c] << ",";
-               os << m[col*(r+1)-1] << "]], ";
-       }
-       os << "[[";
-       for (unsigned c=0; c<col-1; ++c)
-               os << m[(row-1)*col+c] << ",";
-       os << m[row*col-1] << "]] ]]";
-}
+       debugmsg("matrix print", LOGLEVEL_PRINT);
+
+       if (is_of_type(c, print_tree)) {
+
+               inherited::print(c, level);
+
+       } else {
+
+               c.s << "[[ ";
+               for (unsigned y=0; y<row-1; ++y) {
+                       c.s << "[[";
+                       for (unsigned x=0; x<col-1; ++x) {
+                               m[y*col+x].print(c);
+                               c.s << ",";
+                       }
+                       m[col*(y+1)-1].print(c);
+                       c.s << "]], ";
+               }
+               c.s << "[[";
+               for (unsigned x=0; x<col-1; ++x) {
+                       m[(row-1)*col+x].print(c);
+                       c.s << ",";
+               }
+               m[row*col-1].print(c);
+               c.s << "]] ]]";
 
-void matrix::printraw(std::ostream & os) const
-{
-       debugmsg("matrix printraw",LOGLEVEL_PRINT);
-       os << class_name() << "(" << row << "," << col <<",";
-       for (unsigned r=0; r<row-1; ++r) {
-               os << "(";
-               for (unsigned c=0; c<col-1; ++c)
-                       os << m[r*col+c] << ",";
-               os << m[col*(r-1)-1] << "),";
        }
-       os << "(";
-       for (unsigned c=0; c<col-1; ++c)
-               os << m[(row-1)*col+c] << ",";
-       os << m[row*col-1] << "))";
 }
 
 /** nops is defined to be rows x columns. */
index 1041c64..8831ada 100644 (file)
@@ -42,8 +42,7 @@ public:
        
        // functions overriding virtual functions from bases classes
 public:
-       void print(std::ostream & os, unsigned upper_precedence=0) const;
-       void printraw(std::ostream & os) const;
+       void print(const print_context & c, unsigned level = 0) const;
        unsigned nops() const;
        ex op(int i) const;
        ex & let_op(int i);
index a00c9c9..82b721e 100644 (file)
@@ -126,99 +126,99 @@ DEFAULT_ARCHIVING(mul)
 
 // public
 
-void mul::print(std::ostream & os, unsigned upper_precedence) const
-{
-       debugmsg("mul print",LOGLEVEL_PRINT);
-       if (precedence<=upper_precedence) os << "(";
-       bool first = true;
-       // first print the overall numeric coefficient:
-       numeric coeff = ex_to_numeric(overall_coeff);
-       if (coeff.csgn()==-1) os << '-';
-       if (!coeff.is_equal(_num1()) &&
-               !coeff.is_equal(_num_1())) {
-               if (coeff.is_rational()) {
-                       if (coeff.is_negative())
-                               os << -coeff;
-                       else
-                               os << coeff;
-               } else {
-                       if (coeff.csgn()==-1)
-                               (-coeff).print(os, precedence);
-                       else
-                               coeff.print(os, precedence);
-               }
-               os << '*';
-       }
-       // then proceed with the remaining factors:
-       for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
-               if (!first) {
-                       os << '*';
-               } else {
-                       first=false;
-               }
-               recombine_pair_to_ex(*cit).print(os,precedence);
-       }
-       if (precedence<=upper_precedence) os << ")";
-}
-
-void mul::printraw(std::ostream & os) const
+void mul::print(const print_context & c, unsigned level) const
 {
-       debugmsg("mul printraw",LOGLEVEL_PRINT);
+       debugmsg("mul print", LOGLEVEL_PRINT);
 
-       os << "*(";
-       for (epvector::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
-               os << "(";
-               (*it).rest.bp->printraw(os);
-               os << ",";
-               (*it).coeff.bp->printraw(os);
-               os << "),";
-       }
-       os << ",hash=" << hashvalue << ",flags=" << flags;
-       os << ")";
-}
+       if (is_of_type(c, print_tree)) {
 
-void mul::printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence) const
-{
-       debugmsg("mul print csrc", LOGLEVEL_PRINT);
-       if (precedence <= upper_precedence)
-               os << "(";
+               inherited::print(c, level);
 
-       if (!overall_coeff.is_equal(_ex1())) {
-               overall_coeff.bp->printcsrc(os,type,precedence);
-               os << "*";
-       }
+       } else if (is_of_type(c, print_csrc)) {
+
+               if (precedence <= level)
+                       c.s << "(";
+
+               if (!overall_coeff.is_equal(_ex1())) {
+                       overall_coeff.bp->print(c, precedence);
+                       c.s << "*";
+               }
        
-       // Print arguments, separated by "*" or "/"
-       epvector::const_iterator it = seq.begin();
-       epvector::const_iterator itend = seq.end();
-       while (it != itend) {
-
-               // If the first argument is a negative integer power, it gets printed as "1.0/<expr>"
-               if (it == seq.begin() && ex_to_numeric(it->coeff).is_integer() && it->coeff.compare(_num0()) < 0) {
-                       if (type == csrc_types::ctype_cl_N)
-                               os << "recip(";
-                       else
-                               os << "1.0/";
+               // Print arguments, separated by "*" or "/"
+               epvector::const_iterator it = seq.begin(), itend = seq.end();
+               while (it != itend) {
+
+                       // If the first argument is a negative integer power, it gets printed as "1.0/<expr>"
+                       if (it == seq.begin() && ex_to_numeric(it->coeff).is_integer() && it->coeff.compare(_num0()) < 0) {
+                               if (is_of_type(c, print_csrc_cl_N))
+                                       c.s << "recip(";
+                               else
+                                       c.s << "1.0/";
+                       }
+
+                       // If the exponent is 1 or -1, it is left out
+                       if (it->coeff.compare(_ex1()) == 0 || it->coeff.compare(_num_1()) == 0)
+                               it->rest.print(c, precedence);
+                       else {
+                               // Outer parens around ex needed for broken gcc-2.95 parser:
+                               (ex(power(it->rest, abs(ex_to_numeric(it->coeff))))).print(c, level);
+                       }
+
+                       // Separator is "/" for negative integer powers, "*" otherwise
+                       ++it;
+                       if (it != itend) {
+                               if (ex_to_numeric(it->coeff).is_integer() && it->coeff.compare(_num0()) < 0)
+                                       c.s << "/";
+                               else
+                                       c.s << "*";
+                       }
                }
 
-               // If the exponent is 1 or -1, it is left out
-               if (it->coeff.compare(_ex1()) == 0 || it->coeff.compare(_num_1()) == 0)
-                       it->rest.bp->printcsrc(os, type, precedence);
-               else
-                       // outer parens around ex needed for broken gcc-2.95 parser:
-                       (ex(power(it->rest, abs(ex_to_numeric(it->coeff))))).bp->printcsrc(os, type, upper_precedence);
+               if (precedence <= level)
+                       c.s << ")";
 
-               // Separator is "/" for negative integer powers, "*" otherwise
-               ++it;
-               if (it != itend) {
-                       if (ex_to_numeric(it->coeff).is_integer() && it->coeff.compare(_num0()) < 0)
-                               os << "/";
-                       else
-                               os << "*";
+       } else {
+
+               if (precedence <= level)
+                       c.s << "(";
+
+               bool first = true;
+
+               // First print the overall numeric coefficient
+               numeric coeff = ex_to_numeric(overall_coeff);
+               if (coeff.csgn() == -1)
+                       c.s << '-';
+               if (!coeff.is_equal(_num1()) &&
+                       !coeff.is_equal(_num_1())) {
+                       if (coeff.is_rational()) {
+                               if (coeff.is_negative())
+                                       (-coeff).print(c, precedence);
+                               else
+                                       coeff.print(c, precedence);
+                       } else {
+                               if (coeff.csgn() == -1)
+                                       (-coeff).print(c, precedence);
+                               else
+                                       coeff.print(c, precedence);
+                       }
+                       c.s << '*';
+               }
+
+               // Then proceed with the remaining factors
+               epvector::const_iterator it = seq.begin(), itend = seq.end();
+               while (it != itend) {
+                       if (!first) {
+                               c.s << '*';
+                       } else {
+                               first = false;
+                       }
+                       recombine_pair_to_ex(*it).print(c, precedence);
+                       it++;
                }
+
+               if (precedence <= level)
+                       c.s << ")";
        }
-       if (precedence <= upper_precedence)
-               os << ")";
 }
 
 bool mul::info(unsigned inf) const
@@ -327,7 +327,7 @@ ex mul::eval(int level) const
                             (!(ex_to_numeric((*cit).coeff).is_integer())));
                GINAC_ASSERT(!(cit->is_canonical_numeric()));
                if (is_ex_exactly_of_type(recombine_pair_to_ex(*cit),numeric))
-                   printtree(std::cerr,0);
+                   print(print_tree(std::cerr));
                GINAC_ASSERT(!is_ex_exactly_of_type(recombine_pair_to_ex(*cit),numeric));
                /* for paranoia */
                expair p = split_ex_to_pair(recombine_pair_to_ex(*cit));
index 81459a4..affef3b 100644 (file)
@@ -47,9 +47,7 @@ public:
        
        // functions overriding virtual functions from bases classes
 public:
-       void print(std::ostream & os, unsigned upper_precedence) const;
-       void printraw(std::ostream & os) const;
-       void printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence) const;
+       void print(const print_context & c, unsigned level) const;
        bool info(unsigned inf) const;
        int degree(const ex & s) const;
        int ldegree(const ex & s) const;
index 9892670..e775d82 100644 (file)
@@ -28,6 +28,7 @@
 #include "ex.h"
 #include "add.h"
 #include "mul.h"
+#include "print.h"
 #include "archive.h"
 #include "debugmsg.h"
 #include "utils.h"
@@ -112,36 +113,28 @@ DEFAULT_ARCHIVING(ncmul)
 
 // public
 
-void ncmul::print(std::ostream & os, unsigned upper_precedence) const
+void ncmul::print(const print_context & c, unsigned level) const
 {
-       debugmsg("ncmul print",LOGLEVEL_PRINT);
-       printseq(os,'(','*',')',precedence,upper_precedence);
-}
+       debugmsg("ncmul print", LOGLEVEL_PRINT);
 
-void ncmul::printraw(std::ostream & os) const
-{
-       debugmsg("ncmul printraw",LOGLEVEL_PRINT);
-       os << "ncmul(";
-       for (exvector::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
-               (*it).bp->printraw(os);
-               os << ",";
-       }
-       os << ",hash=" << hashvalue << ",flags=" << flags;
-       os << ")";
-}
+       if (is_of_type(c, print_tree)) {
 
-void ncmul::printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence) const
-{
-       debugmsg("ncmul print csrc",LOGLEVEL_PRINT);
-       exvector::const_iterator it;
-       exvector::const_iterator itend = seq.end()-1;
-       os << "ncmul(";
-       for (it=seq.begin(); it!=itend; ++it) {
-               (*it).bp->printcsrc(os,precedence);
-               os << ",";
-       }
-       (*it).bp->printcsrc(os,precedence);
-       os << ")";
+               inherited::print(c, level);
+
+       } else if (is_of_type(c, print_csrc)) {
+
+               c.s << "ncmul(";
+               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 << ")";
+
+       } else
+               printseq(c, '(', '*', ')', precedence, level);
 }
 
 bool ncmul::info(unsigned inf) const
index ec8e561..05f9994 100644 (file)
@@ -53,9 +53,7 @@ public:
 
        // functions overriding virtual functions from bases classes
 public:
-       void print(std::ostream & os, unsigned upper_precedence) const;
-       void printraw(std::ostream & os) const;
-       void printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence = 0) const;
+       void print(const print_context & c, unsigned level = 0) const;
        bool info(unsigned inf) const;
        int degree(const ex & s) const;
        int ldegree(const ex & s) const;
index a4a40c8..1308c9e 100644 (file)
@@ -40,6 +40,7 @@
 
 #include "numeric.h"
 #include "ex.h"
+#include "print.h"
 #include "archive.h"
 #include "debugmsg.h"
 #include "utils.h"
@@ -365,126 +366,113 @@ static void print_real_number(std::ostream &os, const cln::cl_R &num)
  *  with the other routines and produces something compatible to ginsh input.
  *  
  *  @see print_real_number() */
-void numeric::print(std::ostream &os, unsigned upper_precedence) const
+void numeric::print(const print_context & c, unsigned level) const
 {
        debugmsg("numeric print", LOGLEVEL_PRINT);
-       cln::cl_R r = cln::realpart(cln::the<cln::cl_N>(value));
-       cln::cl_R i = cln::imagpart(cln::the<cln::cl_N>(value));
-       if (cln::zerop(i)) {
-               // case 1, real:  x  or  -x
-               if ((precedence<=upper_precedence) && (!this->is_nonneg_integer())) {
-                       os << "(";
-                       print_real_number(os, r);
-                       os << ")";
+
+       if (is_of_type(c, print_tree)) {
+
+               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;
+
+       } else if (is_of_type(c, print_csrc)) {
+
+               std::ios::fmtflags oldflags = c.s.flags();
+               c.s.setf(std::ios::scientific);
+               if (this->is_rational() && !this->is_integer()) {
+                       if (compare(_num0()) > 0) {
+                               c.s << "(";
+                               if (is_of_type(c, print_csrc_cl_N))
+                                       c.s << "cln::cl_F(\"" << numer().evalf() << "\")";
+                               else
+                                       c.s << numer().to_double();
+                       } else {
+                               c.s << "-(";
+                               if (is_of_type(c, print_csrc_cl_N))
+                                       c.s << "cln::cl_F(\"" << -numer().evalf() << "\")";
+                               else
+                                       c.s << -numer().to_double();
+                       }
+                       c.s << "/";
+                       if (is_of_type(c, print_csrc_cl_N))
+                               c.s << "cln::cl_F(\"" << denom().evalf() << "\")";
+                       else
+                               c.s << denom().to_double();
+                       c.s << ")";
                } else {
-                       print_real_number(os, r);
+                       if (is_of_type(c, print_csrc_cl_N))
+                               c.s << "cln::cl_F(\"" << evalf() << "\")";
+                       else
+                               c.s << to_double();
                }
+               c.s.flags(oldflags);
+
        } else {
-               if (cln::zerop(r)) {
-                       // case 2, imaginary:  y*I  or  -y*I
-                       if ((precedence<=upper_precedence) && (i < 0)) {
-                               if (i == -1) {
-                                       os << "(-I)";
-                               } else {
-                                       os << "(";
-                                       print_real_number(os, i);
-                                       os << "*I)";
-                               }
+
+               cln::cl_R r = cln::realpart(cln::the<cln::cl_N>(value));
+               cln::cl_R i = cln::imagpart(cln::the<cln::cl_N>(value));
+               if (cln::zerop(i)) {
+                       // case 1, real:  x  or  -x
+                       if ((precedence <= level) && (!this->is_nonneg_integer())) {
+                               c.s << "(";
+                               print_real_number(c.s, r);
+                               c.s << ")";
                        } else {
-                               if (i == 1) {
-                                       os << "I";
-                               } else {
+                               print_real_number(c.s, r);
+                       }
+               } else {
+                       if (cln::zerop(r)) {
+                               // case 2, imaginary:  y*I  or  -y*I
+                               if ((precedence <= level) && (i < 0)) {
                                        if (i == -1) {
-                                               os << "-I";
+                                               c.s << "(-I)";
                                        } else {
-                                               print_real_number(os, i);
-                                               os << "*I";
+                                               c.s << "(";
+                                               print_real_number(c.s, i);
+                                               c.s << "*I)";
                                        }
-                               }
-                       }
-               } else {
-                       // case 3, complex:  x+y*I  or  x-y*I  or  -x+y*I  or  -x-y*I
-                       if (precedence <= upper_precedence)
-                               os << "(";
-                       print_real_number(os, r);
-                       if (i < 0) {
-                               if (i == -1) {
-                                       os << "-I";
                                } else {
-                                       print_real_number(os, i);
-                                       os << "*I";
+                                       if (i == 1) {
+                                               c.s << "I";
+                                       } else {
+                                               if (i == -1) {
+                                                       c.s << "-I";
+                                               } else {
+                                                       print_real_number(c.s, i);
+                                                       c.s << "*I";
+                                               }
+                                       }
                                }
                        } else {
-                               if (i == 1) {
-                                       os << "+I";
+                               // case 3, complex:  x+y*I  or  x-y*I  or  -x+y*I  or  -x-y*I
+                               if (precedence <= level)
+                                       c.s << "(";
+                               print_real_number(c.s, r);
+                               if (i < 0) {
+                                       if (i == -1) {
+                                               c.s << "-I";
+                                       } else {
+                                               print_real_number(c.s, i);
+                                               c.s << "*I";
+                                       }
                                } else {
-                                       os << "+";
-                                       print_real_number(os, i);
-                                       os << "*I";
+                                       if (i == 1) {
+                                               c.s << "+I";
+                                       } else {
+                                               c.s << "+";
+                                               print_real_number(c.s, i);
+                                               c.s << "*I";
+                                       }
                                }
+                               if (precedence <= level)
+                                       c.s << ")";
                        }
-                       if (precedence <= upper_precedence)
-                               os << ")";
                }
        }
 }
 
-
-void numeric::printraw(std::ostream &os) const
-{
-       // The method printraw doesn't do much, it simply uses CLN's operator<<()
-       // for output, which is ugly but reliable. e.g: 2+2i
-       debugmsg("numeric printraw", LOGLEVEL_PRINT);
-       os << class_name() << "(" << cln::the<cln::cl_N>(value) << ")";
-}
-
-
-void numeric::printtree(std::ostream &os, unsigned indent) const
-{
-       debugmsg("numeric printtree", LOGLEVEL_PRINT);
-       os << std::string(indent,' ') << cln::the<cln::cl_N>(value)
-          << " (numeric): "
-          << "hash=" << hashvalue
-          << " (0x" << std::hex << hashvalue << std::dec << ")"
-          << ", flags=" << flags << std::endl;
-}
-
-
-void numeric::printcsrc(std::ostream &os, unsigned type, unsigned upper_precedence) const
-{
-       debugmsg("numeric print csrc", LOGLEVEL_PRINT);
-       std::ios::fmtflags oldflags = os.flags();
-       os.setf(std::ios::scientific);
-       if (this->is_rational() && !this->is_integer()) {
-               if (compare(_num0()) > 0) {
-                       os << "(";
-                       if (type == csrc_types::ctype_cl_N)
-                               os << "cln::cl_F(\"" << numer().evalf() << "\")";
-                       else
-                               os << numer().to_double();
-               } else {
-                       os << "-(";
-                       if (type == csrc_types::ctype_cl_N)
-                               os << "cln::cl_F(\"" << -numer().evalf() << "\")";
-                       else
-                               os << -numer().to_double();
-               }
-               os << "/";
-               if (type == csrc_types::ctype_cl_N)
-                       os << "cln::cl_F(\"" << denom().evalf() << "\")";
-               else
-                       os << denom().to_double();
-               os << ")";
-       } else {
-               if (type == csrc_types::ctype_cl_N)
-                       os << "cln::cl_F(\"" << evalf() << "\")";
-               else
-                       os << to_double();
-       }
-       os.flags(oldflags);
-}
-
-
 bool numeric::info(unsigned inf) const
 {
        switch (inf) {
index ce50406..2d856aa 100644 (file)
@@ -85,10 +85,7 @@ public:
        
        // functions overriding virtual functions from bases classes
 public:
-       void print(std::ostream &os, unsigned precedence = 0) const;
-       void printraw(std::ostream &os) const;
-       void printtree(std::ostream &os, unsigned indent) const;
-       void printcsrc(std::ostream &os, unsigned type, unsigned precedence=0) const;
+       void print(const print_context & c, unsigned level = 0) const;
        bool info(unsigned inf) const;
        bool has(const ex &other) const;
        ex eval(int level = 0) const;
index bd9a442..ee24017 100644 (file)
@@ -24,6 +24,7 @@
 #include "numeric.h"
 #include "power.h"
 #include "relational.h"
+#include "print.h"
 #include "debugmsg.h"
 #include "utils.h"
 
@@ -240,7 +241,7 @@ relational operator>=(const ex & lh, const ex & rh)
 
 std::ostream & operator<<(std::ostream & os, const ex & e)
 {
-       e.print(os);
+       e.print(print_context(os));
        return os;
 }
 
index c288556..109eacf 100644 (file)
@@ -32,6 +32,7 @@
 #include "inifcns.h"
 #include "relational.h"
 #include "symbol.h"
+#include "print.h"
 #include "archive.h"
 #include "debugmsg.h"
 #include "utils.h"
@@ -102,106 +103,92 @@ DEFAULT_UNARCHIVE(power)
 
 // public
 
-void power::print(std::ostream & os, unsigned upper_precedence) const
-{
-       debugmsg("power print",LOGLEVEL_PRINT);
-       if (exponent.is_equal(_ex1_2())) {
-               os << "sqrt(" << basis << ")";
-       } else {
-               if (precedence<=upper_precedence) os << "(";
-               basis.print(os,precedence);
-               os << "^";
-               exponent.print(os,precedence);
-               if (precedence<=upper_precedence) os << ")";
-       }
-}
-
-void power::printraw(std::ostream & os) const
-{
-       debugmsg("power printraw",LOGLEVEL_PRINT);
-
-       os << class_name() << "(";
-       basis.printraw(os);
-       os << ",";
-       exponent.printraw(os);
-       os << ",hash=" << hashvalue << ",flags=" << flags << ")";
-}
-
-void power::printtree(std::ostream & os, unsigned indent) const
-{
-       debugmsg("power printtree",LOGLEVEL_PRINT);
-
-       os << std::string(indent,' ') << class_name()
-          << ", hash=" << hashvalue
-          << " (0x" << std::hex << hashvalue << std::dec << ")"
-          << ", flags=" << flags << std::endl;
-       basis.printtree(os, indent+delta_indent);
-       exponent.printtree(os, indent+delta_indent);
-}
-
-static void print_sym_pow(std::ostream & os, unsigned type, const symbol &x, int exp)
+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.
        // C.f. ISO/IEC 14882:1998, section 1.9 [intro execution], paragraph 15
        // to learn why such a hack is really necessary.
        if (exp == 1) {
-               x.printcsrc(os, type, 0);
+               x.print(c);
        } else if (exp == 2) {
-               x.printcsrc(os, type, 0);
-               os << "*";
-               x.printcsrc(os, type, 0);
+               x.print(c);
+               c.s << "*";
+               x.print(c);
        } else if (exp & 1) {
-               x.printcsrc(os, 0);
-               os << "*";
-               print_sym_pow(os, type, x, exp-1);
+               x.print(c);
+               c.s << "*";
+               print_sym_pow(c, x, exp-1);
        } else {
-               os << "(";
-               print_sym_pow(os, type, x, exp >> 1);
-               os << ")*(";
-               print_sym_pow(os, type, x, exp >> 1);
-               os << ")";
+               c.s << "(";
+               print_sym_pow(c, x, exp >> 1);
+               c.s << ")*(";
+               print_sym_pow(c, x, exp >> 1);
+               c.s << ")";
        }
 }
 
-void power::printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence) const
+void power::print(const print_context & c, unsigned level) const
 {
-       debugmsg("power print csrc", LOGLEVEL_PRINT);
-       
-       // Integer powers of symbols are printed in a special, optimized way
-       if (exponent.info(info_flags::integer)
-        && (is_ex_exactly_of_type(basis, symbol) || is_ex_exactly_of_type(basis, constant))) {
-               int exp = ex_to_numeric(exponent).to_int();
-               if (exp > 0)
-                       os << "(";
-               else {
-                       exp = -exp;
-                       if (type == csrc_types::ctype_cl_N)
-                               os << "recip(";
+       debugmsg("power print", LOGLEVEL_PRINT);
+
+       if (is_of_type(c, print_tree)) {
+
+               inherited::print(c, level);
+
+       } else if (is_of_type(c, print_csrc)) {
+
+               // Integer powers of symbols are printed in a special, optimized way
+               if (exponent.info(info_flags::integer)
+                && (is_ex_exactly_of_type(basis, symbol) || is_ex_exactly_of_type(basis, constant))) {
+                       int exp = ex_to_numeric(exponent).to_int();
+                       if (exp > 0)
+                               c.s << "(";
+                       else {
+                               exp = -exp;
+                               if (is_of_type(c, print_csrc_cl_N))
+                                       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.compare(_num_1()) == 0) {
+                       if (is_of_type(c, print_csrc_cl_N))
+                               c.s << "recip(";
                        else
-                               os << "1.0/(";
-               }
-               print_sym_pow(os, type, static_cast<const symbol &>(*basis.bp), exp);
-               os << ")";
+                               c.s << "1.0/(";
+                       basis.print(c);
+                       c.s << ")";
 
-       // <expr>^-1 is printed as "1.0/<expr>" or with the recip() function of CLN
-       } else if (exponent.compare(_num_1()) == 0) {
-               if (type == csrc_types::ctype_cl_N)
-                       os << "recip(";
-               else
-                       os << "1.0/(";
-               basis.bp->printcsrc(os, type, 0);
-               os << ")";
+               // Otherwise, use the pow() or expt() (CLN) functions
+               } else {
+                       if (is_of_type(c, print_csrc_cl_N))
+                               c.s << "expt(";
+                       else
+                               c.s << "pow(";
+                       basis.print(c);
+                       c.s << ",";
+                       exponent.print(c);
+                       c.s << ")";
+               }
 
-       // Otherwise, use the pow() or expt() (CLN) functions
        } else {
-               if (type == csrc_types::ctype_cl_N)
-                       os << "expt(";
-               else
-                       os << "pow(";
-               basis.bp->printcsrc(os, type, 0);
-               os << ",";
-               exponent.bp->printcsrc(os, type, 0);
-               os << ")";
+
+               if (exponent.is_equal(_ex1_2())) {
+                       c.s << "sqrt(";
+                       basis.print(c);
+                       c.s << ")";
+               } else {
+                       if (precedence <= level)
+                               c.s << "(";
+                       basis.print(c, precedence);
+                       c.s << "^";
+                       exponent.print(c, precedence);
+                       if (precedence <= level)
+                               c.s << ")";
+               }
        }
 }
 
index 9460291..d9748ef 100644 (file)
@@ -48,10 +48,7 @@ public:
        
        // functions overriding virtual functions from bases classes
 public:
-       void print(std::ostream & os, unsigned upper_precedence = 0) const;
-       void printraw(std::ostream & os) const;
-       void printtree(std::ostream & os, unsigned indent) const;
-       void printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence = 0) const;
+       void print(const print_context & c, unsigned level = 0) const;
        bool info(unsigned inf) const;
        unsigned nops() const;
        ex & let_op(int i);
diff --git a/ginac/print.h b/ginac/print.h
new file mode 100644 (file)
index 0000000..4fdbeb8
--- /dev/null
@@ -0,0 +1,85 @@
+/** @file print.h
+ *
+ *  Helper classes for expression output. */
+
+/*
+ *  GiNaC Copyright (C) 1999-2001 Johannes Gutenberg University Mainz, Germany
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __GINAC_PRINT_H__
+#define __GINAC_PRINT_H__
+
+#include <iostream>
+#include <string>
+
+namespace GiNaC {
+
+/** Context for default (ginsh-parsable) output. */
+class print_context
+{
+public:
+       print_context(std::ostream & os = std::cout) : s(os) {}
+       std::ostream & s; /**< stream to output to */
+
+       // dummy virtual function to make the class polymorphic
+       virtual void dummy(void) {}
+};
+
+/** Context for tree-like output for debugging. */
+class print_tree : public print_context
+{
+public:
+       print_tree(std::ostream & os = std::cout, unsigned d = 4)
+         : print_context(os), delta_indent(d) {}
+       unsigned delta_indent; /**< size of indentation step */
+};
+
+/** Base context for C source output. */
+class print_csrc : public print_context
+{
+public:
+       print_csrc(std::ostream & os = std::cout)
+         : print_context(os) {}
+};
+
+/** Context for C source output using float numbers. */
+class print_csrc_float : public print_csrc
+{
+public:
+       print_csrc_float(std::ostream & os = std::cout)
+         : print_csrc(os) {}
+};
+
+/** Context for C source output using double numbers. */
+class print_csrc_double : public print_csrc
+{
+public:
+       print_csrc_double(std::ostream & os = std::cout)
+         : print_csrc(os) {}
+};
+
+/** Context for C source output using CLN numbers. */
+class print_csrc_cl_N : public print_csrc
+{
+public:
+       print_csrc_cl_N(std::ostream & os = std::cout)
+         : print_csrc(os) {}
+};
+
+} // namespace GiNaC
+
+#endif // ndef __GINAC_BASIC_H__
index 7264d93..a4f96d9 100644 (file)
@@ -31,6 +31,7 @@
 #include "power.h"
 #include "relational.h"
 #include "symbol.h"
+#include "print.h"
 #include "archive.h"
 #include "utils.h"
 #include "debugmsg.h"
@@ -121,73 +122,73 @@ DEFAULT_UNARCHIVE(pseries)
 // functions overriding virtual functions from bases classes
 //////////
 
-void pseries::print(std::ostream &os, unsigned upper_precedence) const
+void pseries::print(const print_context & c, unsigned level) const
 {
        debugmsg("pseries print", LOGLEVEL_PRINT);
-       if (precedence<=upper_precedence) os << "(";
-       // objects of type pseries must not have any zero entries, so the
-       // trivial (zero) pseries needs a special treatment here:
-       if (seq.size()==0)
-               os << '0';
-       for (epvector::const_iterator i=seq.begin(); i!=seq.end(); ++i) {
-               // print a sign, if needed
-               if (i!=seq.begin())
-                       os << '+';
-               if (!is_order_function(i->rest)) {
-                       // print 'rest', i.e. the expansion coefficient
-                       if (i->rest.info(info_flags::numeric) &&
-                               i->rest.info(info_flags::positive)) {
-                               os << i->rest;
-                       } else
-                               os << "(" << i->rest << ')';
-                       // print 'coeff', something like (x-1)^42
-                       if (!i->coeff.is_zero()) {
-                               os << '*';
-                               if (!point.is_zero())
-                                       os << '(' << var-point << ')';
-                               else
-                                       os << var;
-                               if (i->coeff.compare(_ex1())) {
-                                       os << '^';
-                                       if (i->coeff.info(info_flags::negative))
-                                               os << '(' << i->coeff << ')';
-                                       else
-                                               os << i->coeff;
-                               }
-                       }
-               } else {
-                       os << Order(power(var-point,i->coeff));
+
+       if (is_of_type(c, print_tree)) {
+
+               c.s << std::string(level, ' ') << class_name()
+                   << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
+                   << std::endl;
+               unsigned delta_indent = static_cast<const print_tree &>(c).delta_indent;
+               for (unsigned i=0; i<seq.size(); ++i) {
+                       seq[i].rest.print(c, level + delta_indent);
+                       seq[i].coeff.print(c, level + delta_indent);
+                       c.s << std::string(level + delta_indent, ' ') << "-----" << std::endl;
                }
-       }
-       if (precedence<=upper_precedence) os << ")";
-}
+               var.print(c, level + delta_indent);
+               point.print(c, level + delta_indent);
 
+       } else {
 
-void pseries::printraw(std::ostream &os) const
-{
-       debugmsg("pseries printraw", LOGLEVEL_PRINT);
-       os << class_name() << "(" << var << ";" << point << ";";
-       for (epvector::const_iterator i=seq.begin(); i!=seq.end(); ++i)
-               os << "(" << (*i).rest << "," << (*i).coeff << "),";
-       os << ")";
-}
+               if (precedence <= level)
+                       c.s << "(";
 
+               // objects of type pseries must not have any zero entries, so the
+               // trivial (zero) pseries needs a special treatment here:
+               if (seq.size() == 0)
+                       c.s << '0';
+               for (epvector::const_iterator i=seq.begin(); i!=seq.end(); ++i) {
+                       // print a sign, if needed
+                       if (i != seq.begin())
+                               c.s << '+';
+                       if (!is_order_function(i->rest)) {
+                               // print 'rest', i.e. the expansion coefficient
+                               if (i->rest.info(info_flags::numeric) &&
+                                       i->rest.info(info_flags::positive)) {
+                                       i->rest.print(c);
+                               } else {
+                                       c.s << '(';
+                                       i->rest.print(c);
+                                       c.s << ')';
+                               }
+                               // print 'coeff', something like (x-1)^42
+                               if (!i->coeff.is_zero()) {
+                                       c.s << '*';
+                                       if (!point.is_zero()) {
+                                               c.s << '(';
+                                               (var-point).print(c);
+                                               c.s << ')';
+                                       } else
+                                               var.print(c);
+                                       if (i->coeff.compare(_ex1())) {
+                                               c.s << '^';
+                                               if (i->coeff.info(info_flags::negative)) {
+                                                       c.s << '(';
+                                                       i->coeff.print(c);
+                                                       c.s << ')';
+                                               } else
+                                                       i->coeff.print(c);
+                                       }
+                               }
+                       } else
+                               Order(power(var-point,i->coeff)).print(c);
+               }
 
-void pseries::printtree(std::ostream & os, unsigned indent) const
-{
-       debugmsg("pseries printtree",LOGLEVEL_PRINT);
-       os << std::string(indent,' ') << class_name()
-          << ", hash=" << hashvalue
-          << " (0x" << std::hex << hashvalue << std::dec << ")"
-          << ", flags=" << flags << std::endl;
-       for (unsigned i=0; i<seq.size(); ++i) {
-               seq[i].rest.printtree(os,indent+delta_indent);
-               seq[i].coeff.printtree(os,indent+delta_indent);
-               if (i!=seq.size()-1)
-                       os << std::string(indent+delta_indent,' ') << "-----" << std::endl;
+               if (precedence <= level)
+                       c.s << ")";
        }
-       var.printtree(os, indent+delta_indent);
-       point.printtree(os, indent+delta_indent);
 }
 
 int pseries::compare_same_type(const basic & other) const
index 1dd37ff..77b55fe 100644 (file)
@@ -42,9 +42,7 @@ public:
 
        // functions overriding virtual functions from base classes
 public:
-       void print(std::ostream &os, unsigned upper_precedence = 0) const;
-       void printraw(std::ostream &os) const;
-       void printtree(std::ostream & os, unsigned indent) const;
+       void print(const print_context & c, unsigned level = 0) const;
        unsigned nops(void) const;
        ex op(int i) const;
        ex &let_op(int i);
index 6c417de..51fd0f1 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "relational.h"
 #include "numeric.h"
+#include "print.h"
 #include "archive.h"
 #include "utils.h"
 #include "debugmsg.h"
@@ -96,109 +97,45 @@ DEFAULT_UNARCHIVE(relational)
 
 // public
 
-void relational::print(std::ostream & os, unsigned upper_precedence) const
+void relational::print(const print_context & c, unsigned level) const
 {
        debugmsg("relational print",LOGLEVEL_PRINT);
-       if (precedence<=upper_precedence) os << "(";
-       lh.print(os,precedence);
-       switch (o) {
-       case equal:
-               os << "==";
-               break;
-       case not_equal:
-               os << "!=";
-               break;
-       case less:
-               os << "<";
-               break;
-       case less_or_equal:
-               os << "<=";
-               break;
-       case greater:
-               os << ">";
-               break;
-       case greater_or_equal:
-               os << ">=";
-               break;
-       default:
-               os << "(INVALID RELATIONAL OPERATOR)";
-       }
-       rh.print(os,precedence);
-       if (precedence<=upper_precedence) os << ")";
-}
 
-void relational::printraw(std::ostream & os) const
-{
-       debugmsg("relational printraw",LOGLEVEL_PRINT);
-       os << class_name() << "(";
-       lh.printraw(os);
-       os << ",";
-       rh.printraw(os);
-       os << ",";
-       switch (o) {
-       case equal:
-               os << "==";
-               break;
-       case not_equal:
-               os << "!=";
-               break;
-       case less:
-               os << "<";
-               break;
-       case less_or_equal:
-               os << "<=";
-               break;
-       case greater:
-               os << ">";
-               break;
-       case greater_or_equal:
-               os << ">=";
-               break;
-       default:
-               os << "(INVALID RELATIONAL OPERATOR)";
-       }
-       os << ")";
-}
+       if (is_of_type(c, print_tree)) {
 
-void relational::printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence) const
-{
-       debugmsg("relational print csrc", LOGLEVEL_PRINT);
-       if (precedence<=upper_precedence)
-               os << "(";
+               inherited::print(c, level);
 
-       // Print left-hand expression
-       lh.bp->printcsrc(os, type, precedence);
+       } else {
 
-       // Print relational operator
-       switch (o) {
+               if (precedence <= level)
+                       c.s << "(";
+               lh.print(c, precedence);
+               switch (o) {
                case equal:
-                       os << "==";
+                       c.s << "==";
                        break;
                case not_equal:
-                       os << "!=";
+                       c.s << "!=";
                        break;
                case less:
-                       os << "<";
+                       c.s << "<";
                        break;
                case less_or_equal:
-                       os << "<=";
+                       c.s << "<=";
                        break;
                case greater:
-                       os << ">";
+                       c.s << ">";
                        break;
                case greater_or_equal:
-                       os << ">=";
+                       c.s << ">=";
                        break;
                default:
-                       os << "(INVALID RELATIONAL OPERATOR)";
-                       break;
+                       c.s << "(INVALID RELATIONAL OPERATOR)";
+               }
+               rh.print(c, precedence);
+               if (precedence <= level)
+                       c.s << ")";
        }
-
-       // Print right-hand operator
-       rh.bp->printcsrc(os, type, precedence);
-
-       if (precedence <= upper_precedence)
-               os << ")";
 }
 
 bool relational::info(unsigned inf) const
index 15bda58..dcbcacc 100644 (file)
@@ -51,9 +51,7 @@ public:
        
        // functions overriding virtual functions from bases classes
 public:
-       void print(std::ostream & os, unsigned upper_precedence=0) const;
-       void printraw(std::ostream & os) const;
-       void printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence=0) const;
+       void print(const print_context & c, unsigned level = 0) const;
        bool info(unsigned inf) const;
        unsigned nops() const;
        ex & let_op(int i);
index 0bd1d4f..c084096 100644 (file)
@@ -65,10 +65,8 @@ void structure::printtree(std::ostream & os, unsigned indent) const
 {
        debugmsg("structure printtree",LOGLEVEL_PRINT);
 
-       os << std::string(indent,' ') << "structure "
-          << "hash=" << hashvalue
-          << " (0x" << std::hex << hashvalue << std::dec << ")"
-          << ", flags=" << flags << std::endl;
+       os << std::string(indent,' ') << class_name() << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
+          << std::endl;
 }
 
 void structure::printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence) const
index 9a734c9..1455825 100755 (executable)
@@ -173,9 +173,7 @@ public:
        // functions overriding virtual functions from bases classes
 public:
        basic * duplicate() const;
-       void printraw(ostream & os) const;
-       void print(ostream & os, unsigned upper_precedence=0) const;
-       void printtree(ostream & os, unsigned indent) const;
+       void print(const print_context & c, unsigned level = 0) const;
        int nops() const;
        ex & let_op(int i);
        ex expand(unsigned options=0) const;
@@ -253,6 +251,7 @@ ${input_structure}
 #include <iostream>
 
 #include "${STRUCTURE}.h"
+#include "print.h"
 
 namespace GiNaC {
 
@@ -328,22 +327,10 @@ basic * ${STRUCTURE}::duplicate() const
        return new ${STRUCTURE}(*this);
 }
 
-void ${STRUCTURE}::printraw(ostream & os) const
+void ${STRUCTURE}::print(const print_context & c, unsigned level) const
 {
-       debugmsg("${STRUCTURE} printraw",LOGLEVEL_PRINT);
-       os << class_name() << "()";
-}
-
-void ${STRUCTURE}::print(ostream & os, unsigned upper_precedence) const
-{
-       debugmsg("${STRUCTURE} print",LOGLEVEL_PRINT);
-       os << class_name() << "()";
-}
-
-void ${STRUCTURE}::printtree(ostream & os, unsigned indent) const
-{
-       debugmsg("${STRUCTURE} printtree",LOGLEVEL_PRINT);
-       os << "${STRUCTURE}()";
+       debugmsg("${STRUCTURE} print", LOGLEVEL_PRINT);
+       c.s << class_name() << "()";
 }
 
 int ${STRUCTURE}::nops() const
index 09e4192..e093e6c 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "symbol.h"
 #include "lst.h"
+#include "print.h"
 #include "archive.h"
 #include "debugmsg.h"
 #include "utils.h"
@@ -131,33 +132,19 @@ basic *symbol::duplicate() const
        return new symbol(*this);
 }
 
-void symbol::print(std::ostream & os, unsigned upper_precedence) const
+void symbol::print(const print_context & c, unsigned level) const
 {
-       debugmsg("symbol print",LOGLEVEL_PRINT);
-       os << name;
-}
+       debugmsg("symbol print", LOGLEVEL_PRINT);
 
-void symbol::printraw(std::ostream & os) const
-{
-       debugmsg("symbol printraw",LOGLEVEL_PRINT);
-       os << class_name() << "(" << "name=" << name << ",serial=" << serial
-          << ",hash=" << hashvalue << ",flags=" << flags << ")";
-}
+       if (is_of_type(c, print_tree)) {
 
-void symbol::printtree(std::ostream & os, unsigned indent) const
-{
-       debugmsg("symbol printtree",LOGLEVEL_PRINT);
-       os << std::string(indent,' ') << name << " (symbol): "
-          << "serial=" << serial
-          << ", hash=" << hashvalue
-          << " (0x" << std::hex << hashvalue << std::dec << ")"
-          << ", flags=" << flags << std::endl;
-}
+               c.s << std::string(level, ' ') << name << " (" << class_name() << ")"
+                   << ", serial=" << serial
+                   << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
+                   << std::endl;
 
-void symbol::printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence) const
-{
-       debugmsg("symbol print csrc", LOGLEVEL_PRINT);
-       os << name;
+       } else
+               c.s << name;
 }
 
 bool symbol::info(unsigned inf) const
index c147c89..cda3e73 100644 (file)
@@ -72,10 +72,7 @@ public:
        // functions overriding virtual functions from base classes
 public:
        basic * duplicate() const;
-       void print(std::ostream & os, unsigned upper_precedence = 0) const;
-       void printraw(std::ostream & os) const;
-       void printtree(std::ostream & os, unsigned indent) const;
-       void printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence = 0) const;
+       void print(const print_context & c, unsigned level = 0) const;
        bool info(unsigned inf) const;
        ex expand(unsigned options = 0) const;
        bool has(const ex & other) const;
index c7a68bf..c14b50d 100644 (file)
@@ -29,6 +29,7 @@
 #include "relational.h"
 #include "lst.h"
 #include "numeric.h"
+#include "print.h"
 #include "archive.h"
 #include "utils.h"
 #include "debugmsg.h"
index 65c86c4..7396aca 100644 (file)
@@ -53,7 +53,7 @@ class tensdelta : public tensor
 
        // functions overriding virtual functions from bases classes
 public:
-       void print(std::ostream & os, unsigned upper_precedence=0) const;
+       void print(const print_context & c, unsigned level = 0) const;
        ex eval_indexed(const basic & i) const;
        bool contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const;
 };
@@ -68,7 +68,7 @@ class tensmetric : public tensor
 
        // functions overriding virtual functions from bases classes
 public:
-       void print(std::ostream & os, unsigned upper_precedence=0) const;
+       void print(const print_context & c, unsigned level = 0) const;
        ex eval_indexed(const basic & i) const;
        bool contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const;
 };
@@ -88,7 +88,7 @@ public:
 
        // functions overriding virtual functions from bases classes
 public:
-       void print(std::ostream & os, unsigned upper_precedence=0) const;
+       void print(const print_context & c, unsigned level = 0) const;
        ex eval_indexed(const basic & i) const;
 
        // member variables
@@ -110,7 +110,7 @@ public:
 
        // functions overriding virtual functions from bases classes
 public:
-       void print(std::ostream & os, unsigned upper_precedence=0) const;
+       void print(const print_context & c, unsigned level = 0) const;
        ex eval_indexed(const basic & i) const;
 
        // member variables
index 6e1d3ae..c2a5f23 100644 (file)
@@ -292,10 +292,13 @@ int classname::compare_same_type(const basic & other) const \
 }
 
 #define DEFAULT_PRINT(classname, text) \
-void classname::print(std::ostream & os, unsigned upper_precedence) const \
+void classname::print(const print_context & c, unsigned level) const \
 { \
        debugmsg(#classname " print", LOGLEVEL_PRINT); \
-       os << text; \
+       if (is_of_type(c, print_tree)) \
+               inherited::print(c, level); \
+       else \
+               c.s << text; \
 }
 
 } // namespace GiNaC