Closed mrzv closed 8 years ago
Can you write a short example of what you mean?
#include <boost/operators.hpp>
#include <boost/array.hpp>
template<size_t D, typename Real = double>
struct Point:
boost::addable< Point<D,Real>,
boost::subtractable< Point<D,Real>,
boost::dividable2< Point<D, Real>, Real,
boost::multipliable2< Point<D, Real>, Real > > > >,
public boost::array<Real, D>
{
public:
Point& operator+=(const Point& p) { for (size_t i = 0; i < D; ++i) (*this)[i] += p[i]; return *this; }
Point& operator-=(const Point& p) { for (size_t i = 0; i < D; ++i) (*this)[i] -= p[i]; return *this; }
Point& operator/=(Real r) { for (size_t i = 0; i < D; ++i) (*this)[i] /= r; return *this; }
Point& operator*=(Real r) { for (size_t i = 0; i < D; ++i) (*this)[i] *= r; return *this; }
};
int main()
{
Point<2> p;
p[1] = 0;
}
Now stopping at the second line of main
in the debugger, and saying print p
, I get:
(gdb) print p
$1 = {<boost::addable<Point<2, double>, boost::subtractable<Point<2, double>, boost::dividable2<Point<2, double>, double, boost::multipliable2<Point
<2, double>, double, boost::detail::empty_base<Point<2, double> > > >, boost::detail::empty_base<Point<2, double> >, boost::detail::true_t>, boost::
detail::empty_base<Point<2, double> >, boost::detail::true_t>> = {<boost::addable1<Point<2, double>, boost::subtractable<Point<2, double>, boost::di
vidable2<Point<2, double>, double, boost::multipliable2<Point<2, double>, double, boost::detail::empty_base<Point<2, double> > > >, boost::detail::e
mpty_base<Point<2, double> >, boost::detail::true_t> >> = {<boost::subtractable<Point<2, double>, boost::dividable2<Point<2, double>, double, boost:
:multipliable2<Point<2, double>, double, boost::detail::empty_base<Point<2, double> > > >, boost::detail::empty_base<Point<2, double> >, boost::deta
il::true_t>> = {<boost::subtractable1<Point<2, double>, boost::dividable2<Point<2, double>, double, boost::multipliable2<Point<2, double>, double, b
oost::detail::empty_base<Point<2, double> > > > >> = {<boost::dividable2<Point<2, double>, double, boost::multipliable2<Point<2, double>, double, bo
ost::detail::empty_base<Point<2, double> > > >> = {<boost::multipliable2<Point<2, double>, double, boost::detail::empty_base<Point<2, double> > >> =
{<boost::detail::empty_base<Point<2, double> >> = {<No data fields>}, <No data fields>}, <No data fields>}, <No data fields>}, <No data fields>}, <
No data fields>}, <No data fields>}, <boost::array<double, 2>> = {6.9533558074895536e-310, 0}, <No data fields>}
Everything but the final {6.9533558074895536e-310, 0}
is noise.
So one way would be to print only the 2nd subclass of Point
. With the latest pull request, you could try:
py boost.add_trivial_printer('Point', lambda x: x.cast(x.type.fields()[1].type))
This avoids dealing with boost::addable
and so on, but achieves what you need.
This looks like a customized solution for my specific example. It's helpful, but from the point of view of your pretty printer, a generic solution would be much nicer. (Not sure if it's possible though.)
I'm not sure it's possible either. I don't know how to control how gdb
prints the type of the base class while printing a given value. Initially I thought that's what type printers do. But look at this:
# file a.cpp
struct A {};
struct B : public A {};
A a;
B b;
void done() {}
int main() { done(); }
# file a.gdb
b done
r
ptype a
ptype b
p a
p b
py boost.add_trivial_printer("A", lambda x: str())
py boost.add_trivial_type_printer("A", lambda t: "xoxo")
ptype a
ptype b
p a
p b
q
g++ -std=c++11 -O0 -g3 -ggdb -Wall -Wextra -pedantic a.cpp -o a
gdb a -x a.gdb
The output I get:
type = struct A {
<no data fields>
}
type = struct B : public A {
}
$1 = {<No data fields>}
$2 = {<A> = {<No data fields>}, <No data fields>}
type = xoxo
type = struct B : public xoxo {
}
$3 =
$4 = {<A> = , <No data fields>}
So it looks like gdb
uses the type printer for ptype a
, and for ptype b
because A
is a base class of B
. However, it still prints A
, ignoring the type printer, when printing the value b
. This could be a deficiency of the API.
Note: I added add_trivial_type_printer
to the pull request.
Hm, that is unfortunate. I wonder if it's worth bringing to the attention of gdb developers.
This generated no reaction on the mailing list.
I don't know if it's possible, but it would be great to suppress printing Boost.Operators types. Right now if one creates a class that inherits from
boost::addable
,boost::multipliable
, etc, all those classes show up when pretty printing an instance of the class. But that information is practically useless.