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
// 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
// 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;
*/
#include <iostream>
-#include <typeinfo>
#include <stdexcept>
#include "basic.h"
#include "symbol.h"
#include "lst.h"
#include "ncmul.h"
+#include "print.h"
#include "archive.h"
#include "utils.h"
#include "debugmsg.h"
// 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.
* 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);
* @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
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;
}
// 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;
// protected
unsigned basic::precedence = 70;
-unsigned basic::delta_indent = 4;
//////////
// global variables
#define __GINAC_BASIC_H__
#include <iostream>
-#include <typeinfo>
#include <vector>
// CINT needs <algorithm> to work properly with <vector>
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.
friend class ex;
-// member functions
-
// default ctor, dtor, copy ctor assignment operator and helpers
public:
basic() : tinfo_key(TINFO_basic), flags(0), refcount(0)
// 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;
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
};
#include "ex.h"
#include "idx.h"
#include "ncmul.h"
+#include "print.h"
#include "archive.h"
#include "debugmsg.h"
#include "utils.h"
// 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;
};
// 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;
};
#include "ncmul.h"
#include "numeric.h"
#include "power.h" // for sqrt()
+#include "print.h"
#include "archive.h"
#include "debugmsg.h"
#include "utils.h"
// 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. */
// 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
// 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;
};
// 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;
};
#include "constant.h"
#include "numeric.h"
#include "ex.h"
+#include "print.h"
#include "archive.h"
#include "debugmsg.h"
#include "utils.h"
// 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
// 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;
${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);
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;
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)
{
#include "${CONTAINER}.h"
#include "ex.h"
+#include "print.h"
#include "archive.h"
#include "debugmsg.h"
// 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";
// 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
unsigned ${CONTAINER}::precedence = 10;
-//////////
-// global constants
-//////////
-
-const ${CONTAINER} some_${CONTAINER};
-const std::type_info & typeid_${CONTAINER} = typeid(some_${CONTAINER});
-
} // namespace GiNaC
END_OF_IMPLEMENTATION
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();
}
/** 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();
}
// 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;
#include "ex.h"
#include "numeric.h"
+#include "print.h"
namespace GiNaC {
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)). */
#include "expairseq.h"
#include "lst.h"
+#include "print.h"
#include "archive.h"
#include "debugmsg.h"
#include "utils.h"
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
// 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);
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 << ")";
}
* 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;
}
}
// 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;
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,
*/
#include "fail.h"
+#include "print.h"
#include "archive.h"
#include "debugmsg.h"
#include "utils.h"
// 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; };
};
};
};
-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 {
// 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;
#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__
#include "function.h"
#include "ex.h"
#include "lst.h"
+#include "print.h"
#include "archive.h"
#include "inifcns.h"
#include "utils.h"
// 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
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
#include "ex.h"
#include "normal.h"
#include "archive.h"
+#include "print.h"
#include "constant.h"
#include "fail.h"
#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)
// 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
// 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);
// 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
#include "ncmul.h"
#include "power.h"
#include "lst.h"
+#include "print.h"
#include "archive.h"
#include "utils.h"
#include "debugmsg.h"
// 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
// 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++;
}
}
// 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;
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
#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 {
// 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. */
// 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);
// 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
(!(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));
// 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;
#include "ex.h"
#include "add.h"
#include "mul.h"
+#include "print.h"
#include "archive.h"
#include "debugmsg.h"
#include "utils.h"
// 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
// 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;
#include "numeric.h"
#include "ex.h"
+#include "print.h"
#include "archive.h"
#include "debugmsg.h"
#include "utils.h"
* 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) {
// 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;
#include "numeric.h"
#include "power.h"
#include "relational.h"
+#include "print.h"
#include "debugmsg.h"
#include "utils.h"
std::ostream & operator<<(std::ostream & os, const ex & e)
{
- e.print(os);
+ e.print(print_context(os));
return os;
}
#include "inifcns.h"
#include "relational.h"
#include "symbol.h"
+#include "print.h"
#include "archive.h"
#include "debugmsg.h"
#include "utils.h"
// 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 << ")";
+ }
}
}
// 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);
--- /dev/null
+/** @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__
#include "power.h"
#include "relational.h"
#include "symbol.h"
+#include "print.h"
#include "archive.h"
#include "utils.h"
#include "debugmsg.h"
// 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
// 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);
#include "relational.h"
#include "numeric.h"
+#include "print.h"
#include "archive.h"
#include "utils.h"
#include "debugmsg.h"
// 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
// 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);
{
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
// 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;
#include <iostream>
#include "${STRUCTURE}.h"
+#include "print.h"
namespace GiNaC {
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
#include "symbol.h"
#include "lst.h"
+#include "print.h"
#include "archive.h"
#include "debugmsg.h"
#include "utils.h"
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
// 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;
#include "relational.h"
#include "lst.h"
#include "numeric.h"
+#include "print.h"
#include "archive.h"
#include "utils.h"
#include "debugmsg.h"
// 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;
};
// 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;
};
// 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
// 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
}
#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