manpagez: man pages & more
info ginac
Home | html | info | man
[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6.3.1 Print methods for classes

The method table for a class is set up either in the definition of the class, by passing the appropriate print_func<C>() option to GINAC_IMPLEMENT_REGISTERED_CLASS_OPT() (See section Adding classes, for an example), or at run-time using set_print_func<T, C>(). The latter can also be used to override existing methods dynamically.

The argument to print_func<C>() and set_print_func<T, C>() can be a member function of the class (or one of its parent classes), a static member function, or an ordinary (global) C++ function. The C template parameter specifies the appropriate print_context type for which the method should be invoked, while, in the case of set_print_func<>(), the T parameter specifies the algebraic class (for print_func<>(), the class is the one being implemented by GINAC_IMPLEMENT_REGISTERED_CLASS_OPT).

For print methods that are member functions, their first argument must be of a type convertible to a const C &, and the second argument must be an unsigned.

For static members and global functions, the first argument must be of a type convertible to a const T &, the second argument must be of a type convertible to a const C &, and the third argument must be an unsigned. A global function will, of course, not have access to private and protected members of T.

The unsigned argument of the print methods (and of ex::print() and basic::print()) is used for proper parenthesizing of the output (and by print_tree for proper indentation). It can be used for similar purposes if you write your own output formats.

The explanations given above may seem complicated, but in practice it's really simple, as shown in the following example. Suppose that we want to display exponents in LaTeX output not as superscripts but with little upwards-pointing arrows. This can be achieved in the following way:

 
void my_print_power_as_latex(const power & p,
                             const print_latex & c,
                             unsigned level)
{
    // get the precedence of the 'power' class
    unsigned power_prec = p.precedence();

    // if the parent operator has the same or a higher precedence
    // we need parentheses around the power
    if (level >= power_prec)
        c.s << '(';

    // print the basis and exponent, each enclosed in braces, and
    // separated by an uparrow
    c.s << '{';
    p.op(0).print(c, power_prec);
    c.s << "}\\uparrow{";
    p.op(1).print(c, power_prec);
    c.s << '}';

    // don't forget the closing parenthesis
    if (level >= power_prec)
        c.s << ')';
}
                                                                                
int main()
{
    // a sample expression
    symbol x("x"), y("y");
    ex e = -3*pow(x, 3)*pow(y, -2) + pow(x+y, 2) - 1;

    // switch to LaTeX mode
    cout << latex;

    // this prints "-1+{(y+x)}^{2}-3 \frac{x^{3}}{y^{2}}"
    cout << e << endl;

    // now we replace the method for the LaTeX output of powers with
    // our own one
    set_print_func<power, print_latex>(my_print_power_as_latex);

    // this prints "-1+{{(y+x)}}\uparrow{2}-3 \frac{{x}\uparrow{3}}{{y}
    //              \uparrow{2}}"
    cout << e << endl;
}

Some notes:

It's not possible to restore a method table entry to its previous or default value. Once you have called set_print_func(), you can only override it with another call to set_print_func(), but you can't easily go back to the default behavior again (you can, of course, dig around in the GiNaC sources, find the method that is installed at startup (power::do_print_latex in this case), and set_print_func that one; that is, after you circumvent the C++ member access control…).


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]
© manpagez.com 2000-2024
Individual documents may contain additional copyright information.