[C++-sig] Re: long long unsigned issue...

Milind Patil milind_patil at hotmail.com
Thu May 29 04:31:51 CEST 2003


"David Abrahams" <dave at boost-consulting.com> wrote in message
news:ud6i4xtz2.fsf at boost-consulting.com...
> David Abrahams <dave at boost-consulting.com> writes:
>
> One more note about this stuff: you have so many constructors and so
> much potential for ambiguity it's hard to make sense of what you're
> actually trying to achieve.  Maybe if you could say a little more
> about that it would be easier to help you.
>
> -- 
> Dave Abrahams
> Boost Consulting
> www.boost-consulting.com

The C++ library that I am wrapping is part of a testbench library for verification of
RTL designs of ASICs. The library has bit vector signal (to connect to rtl signals)
classes, concurrency classes, randomization classes etc. Supporting scripting
in the verification environment is going to be a great productivity booster, I think.
And hence the attempt to use boost python.

I used pyste (thanks to Nicodemus) to jump start the wrapping process. I have a
use case model in mind that I am hand crafting the wrappers to now.

Looking at just the signal class, it has constructors for
a) Constructing signals of given width eg. signal(23,0) -- a 24 bit signal,
    signal(23,0, 0xffffff) -- a 24 bit signal with value 0xffffff,
b) Constructors for constants eg. signal(0x00ffffff) -- 24 bit signal, etc.
c) Constructors from character representation, long long, long, and
    int representations of numbers.
d) copy, default etc.

Other requirements of python signal class are:
a) handling 4state: bits can be 0, 1, X or Z.
b) slice set and get ie. sig[18:4] = 2; sig[:] = 4;
c) ability to convert from and to python long.

Anyway the above was a little introduction to
the big picture at my end.

Coming to issue with long_ conversion that I have had.
I constructed a toy example to experiment with the long_
conversion issue. Recapping, given the class

class Y {
   public:
     Y() : y(0L) { }
     Y(int y) : y(y) { }
     Y(long long unsigned int y) : y(y) { }
     Y(int s, const Y & y) : y(y << s) { }
     Y(Y const& rhs) : y(rhs.y) { }
     virtual ~Y() { }

     operator int() const { return y; }

     void operator=(Y const& y) {
         this->y = y.y;
     }

     long long unsigned int y;
 };

that I would like to wrap to python:

BOOST_PYTHON_MODULE(hello)
{
    class_< Y, Y_Wrapper >("Y", init<  >())
        .def(init< const Y & >())
        .def(init< int, const Y & >())
        .def(init< int >())
        .def(init< long long unsigned int >())
        .def_readwrite("y", &Y::y)
        .def("__int__", &Y::operator int)
     ;
     impilcitly_convertible<int, Y>();
}

The implicitly_converitble above is to facilitate conversion
to Y(int, &Y) for python x = hello.Y(2, 24) etc.
I wanted to add conversion capability from and to python
long_ which was possible via a wrapper class (again, something
that pyste originally generated):

 namespace {
 struct Y_Wrapper: Y {
     Y_Wrapper (PyObject* self_) : Y(), self(self_) {}
     Y_Wrapper (PyObject* self_, int y) : Y(y), self(self_) {}
     Y_Wrapper (PyObject* self_, long long unsigned int y) : Y(y), self(self_) {}
     Y_Wrapper (PyObject* self_, int s,  const Y& y) : Y(s,y), self(self_) {}
     Y_Wrapper (PyObject* self_, const Y& y) : Y(y), self(self_) {}
     Y_Wrapper (PyObject* self_, boost::python::long_ y) : Y(0), self(self_) {printf("hello
long_");}

     PyObject* self;
 };
}

and adding

         .def(init< long_ >())

to module definition.

So far so good. With your recent fixes it works perfectly for python construction
of Y from long  eg. x = hello.Y(4294967295) -- this is the type b constructor in the
constructors I enumerated above. But if I want to construct signals of given width,
then I would have x = signal(127,0, 4294967295), or x = hello.Y(127, 4294967295)
for the toy example. This statement will cause a runtime exception fault
saying that "OverflowError: long int too large to convert to int", probably because it
is trying construct to Y(int s,  const Y& y) and does not know how to make long_
to Y! My question here was :

Now that we have a long_ to Y_Wrapper constructor
and that class_ Y has Y_Wrapper as one of the bases, is it possible to use an
implicity_convertible<long_, Y_Wrapper>(); to be able to facilitate the conversion?

I am not comletely dead in water:
I have added a .def(init<int, long_>) to module definition and a
Y_Wrapper(PyObject* self_, int s,  boost::python::long_ y)
to Y_Wrapper to get around the inability to do a
implicitly_convertible<long_ Y_Wrapper>() to effect the conversion.
This works for me right now. I once again thank you for helping me
with the issue I had.

If you have read so far, I had some more observations as a user:

Some of the use case scenarios for boost python are:

a) Expose C++ classes as python classes alone. User will not derive
    from the exposed classes.
b) Expose C++ classes as derivable classes in python.
c) Embedded scenarios with above two where it goes c++ to python to c++
    back etc.
d) Expose C++ classes as derived or as convertible to python types (numeric,
    tuples, str etc.)

My particular use case is a) and d). And there is adequate
documentation/information to be able to be able to figure it out but it is
difficult. Perhaps the document can handle c) and d) a little more?
Anything I can help with?

Thanks again,
Milind







More information about the Cplusplus-sig mailing list