[GiNaC-devel] printing of class power
Richard B. Kreckel
kreckel at in.terlu.de
Mon Jan 6 23:03:06 CET 2025
Hi,
On 1/3/25 3:41 PM, Stefan Weinzierl wrote:
> ex g = pow(x,5);
[...]
> g.print(GiNaC::print_context(std::cout));
> std::cout << std::endl;
>
> will print
[...]
> [power object]
>
> Is that really intentional? The behaviour is the same in GiNaC 1.8.7 and 1.8.8.
Well....
Class 'print_context' is the common base class for 'print_dflt',
'print_latex', 'print_csrc', etc.
I am not sure if it makes sense to use it. After all, there are ostream
manipulator 'dflt', 'latex', and 'csrc' (operators.h), but none for
'print_context'. On the other hand, 'print_context' is totally public.
What happens is: The lookup implemented in basic::print_dispatch()
doesn't find a method in the print dispatch table for print_default for
class 'power'. So it proceeds to class 'basic', the base class of
'power' to look for a dispatch function and this is the one printing
"[power object]".
The fine user manual cares to elaborate (in section 6.3 "GiNaC's
expression output system"):
The method table contains one slot for each possible ‘print_context’
type, indexed by the (internally assigned) serial number of the type.
Slots may be empty, in which case GiNaC will retry the method lookup
with the ‘print_context’ object's parent class, possibly repeating the
process until it reaches the ‘print_context’ base class. If there's
still no method defined, the method table of the algebraic object's
parent class is consulted, and so on, until a matching method is found
(eventually it will reach the combination ‘basic/print_context’, which
prints the object's class name enclosed in square brackets).
You can think of the print methods of all the different classes and
output formats as being arranged in a two-dimensional matrix with one
axis listing the algebraic classes and the other axis listing the
‘print_context’ classes.
And it turns out that class 'power' has all kinds of output methods
except 'print_tree' and 'print_context'! If we change the existing
method for 'print_dflt' to be the one for 'print_context', your code
will work as you expected: The lookup for 'print_dflt' will find the
base method for 'print_context'. One last piece to do would be to add a
method for 'print_tree' because our new method for 'print_context' will
match this one while before we were using the one from class 'basic'.
The attached patch does that.
I'm unsure if this is patch is right. I guess it depends on whether your
code using 'print_context' directly is right or not.
Comments welcome!
-richy.
PS: The patch breaks the ABI, but that ain't grave. I think that the
alternative of making 'print_context' abstract would break the API and
that would be worse.
--
Richard B. Kreckel
<https://in.terlu.de/~kreckel/>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: GiNaC-power-print.diff
Type: text/x-patch
Size: 2272 bytes
Desc: not available
URL: <http://www.ginac.de/pipermail/ginac-devel/attachments/20250106/b55e590f/attachment.bin>
More information about the GiNaC-devel
mailing list