[C++-sig] Boost-python wrapping a vector of vectors?
I'm trying to boost-python a vector-of-vectors, like class A { public A(const std::vector>& my_array); }; and would intuitively write the wrapper: BOOST_PYTHON_MODULE(foo) { using namespace boost::python class_("A") .def(init(std::vector >()) ; but get the error "a call to a constructor cannot appear in a constant expression" Can anyone supply any guidance as to how to wrap this? Thanks Tim Dr Tim Couper ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] Boost-python wrapping a vector of vectors?
Troy Thanks for the prompt reply .. I'm a python expert and a C++ novice ... Apologies for not getting this ... I've seen I can define a python mapping using the vector_indexing suite class_< std::vector< std::vector > >("vector_double2") .def(vector_indexing_suite > > but I can't see how to get that information into the init argument in the C++ class_("A") .def(init( )) as vector_double2 isn't known when the c++ compiles, so this clearly isn't the "type" argument to which you refer. Clearly there's something I'm missing. How do I define a type? Should I be using the named constructors/factories described in http://wiki.python.org/moin/boost.python/HowTo? If so how? Thanks again Tim On 06/01/2010 23:16, troy d. straszheim wrote: Tim Couper wrote: I'm trying to boost-python a vector-of-vectors, like class A { public A(const std::vector>& my_array); }; and would intuitively write the wrapper: BOOST_PYTHON_MODULE(foo) { using namespace boost::python class_("A") .def(init(std::vector >()) ; but get the error "a call to a constructor cannot appear in a constant expression" Syntax error, init takes a type argument: init() -t ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig No virus found in this incoming message. Checked by AVG - www.avg.com Version: 9.0.725 / Virus Database: 270.14.127/2603 - Release Date: 01/06/10 07:35:00 ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] Boost-python wrapping a vector of vectors?
Ah I understand .. so will reply to my own posting for others new to pb ... C++ constructors with one argument behave differently I understand, so taking a 2 argument case: class A { public A(int i, const std::vector>& my_array); }; In the BOOST_PYTHON_MODULE(foo) .. define a type using typedef: typedef std::vector > double_trouble; and add the python wrappers we're going to need - one for wrapping a vector of doubles, and one for the vector of vectors .. class_ > > ("v2_double") .def(vector_indexing_suite > >()); class_ > ("v_double") .def(vector_indexing_suite >()); now define the constructor like Troy said .. class_("A") .def(init()) ; bjam this lot and we then can write out nosetest tests: def test_v_double(): v = foo.v_double() v[:] = [1.4,2.5] assert_equals(len(v),2) assert_almost_equal(v[0],1.4) def test_v2_double(): v2 = foo.v2_double() v1a = foo.v_double() v2a = foo.v_double() v1a[:] = [1.4, 2.5, 5.6] v2a[:] = [3.4, 2.8, 7.8, 12.5] v2[:] = [v1a,v2a] assert_equals(len(v2),2) assert_almost_equal(v2[0][0],1.4) def test_A(): v2 = foo.v2_double() v1a = foo.v_double() v2a = foo.v_double() v1a[:] = [1.4, 2.5, 5.6] v2a[:] = [3.4, 2.8, 7.8, 12.5] v2[:] = [v1a,v2a] res = foo.A(1, v2) assert isinstance(res, foo.A) and there we have it .. I'll be back ... :-) Tim On 07/01/2010 09:21, Tim Couper wrote: Troy Thanks for the prompt reply .. I'm a python expert and a C++ novice ... Apologies for not getting this ... I've seen I can define a python mapping using the vector_indexing suite class_< std::vector< std::vector > >("vector_double2") .def(vector_indexing_suite > > but I can't see how to get that information into the init argument in the C++ class_("A") .def(init( )) as vector_double2 isn't known when the c++ compiles, so this clearly isn't the "type" argument to which you refer. Clearly there's something I'm missing. How do I define a type? Should I be using the named constructors/factories described in http://wiki.python.org/moin/boost.python/HowTo? If so how? Thanks again Tim On 06/01/2010 23:16, troy d. straszheim wrote: Tim Couper wrote: I'm trying to boost-python a vector-of-vectors, like class A { public A(const std::vector>& my_array); }; and would intuitively write the wrapper: BOOST_PYTHON_MODULE(foo) { using namespace boost::python class_("A") .def(init(std::vector >()) ; but get the error "a call to a constructor cannot appear in a constant expression" Syntax error, init takes a type argument: init() -t ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig No virus found in this incoming message. Checked by AVG -www.avg.com Version: 9.0.725 / Virus Database: 270.14.127/2603 - Release Date: 01/06/10 07:35:00 ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig No virus found in this incoming message. Checked by AVG - www.avg.com Version: 9.0.725 / Virus Database: 270.14.128/2604 - Release Date: 01/06/10 19:35:00 ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
[C++-sig] Simple , , I think .. type conversion question C++ -> python
OK. Here's what I've been stuck with all today .. I have a 3rd party C++ program function which returns a boost::variant (and its inverse) my_variant my_variant_of_string(const std::string& str) This one takes a string & returns a variant, and am trying to wrap this in python, so that there I can have >>> my_variant_of_string('hello') 'hello' >>> my_variant_of_string('1.2') 1.2 >>> my_variant_of_string('10') 10 Simple, eh? .. The reduced code below compiles, creating the python function correctly, but I have not successfully defined to_python_value/to_python_converter statement(s), so the python predictably fails with a ".. no to_python .. converter for .. boost::variant .." when run. I can find lots of helpful references to such converters of classes (eg http://misspent.wordpress.com/2009/09/27/how-to-write-boost-python-converters/), but cannot see how I should use the to_python_value functionality to express the "convert the output of this function to a string, int or double as appropriate". Thanks Tim "novice, but learning" Couper -- my_variant.cpp -- #include typedef boost::variant my_variant; template bool from_string(T& t,const std::string& s, std::ios_base& (*f)(std::ios_base&)) { std::istringstream iss(s); return !(iss >> f >> t).fail(); } namespace var { my_variant my_variant_of_string(const std::string& str) // return a float, int or string depending on input parameter content { my_variant param; double dval; int ival; if (str.find(".") != std::string::npos) { if (from_string(dval,str,std::dec)) { param = dval; } } else if (from_string(ival,str,std::dec) ) { param = ival; } else { param= str; } return param; } }// var #include #include BOOST_PYTHON_MODULE(var) { using namespace boost::python; def("my_variant_of_string", &var::my_variant_of_string); } ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] Simple , , I think .. type conversion question C++ -> python
Troy Thanks .. your hints are most helpful .. I'll be back :-) Tim On 13/01/2010 19:10, troy d. straszheim wrote: Tim Couper wrote: OK. Here's what I've been stuck with all today .. I have a 3rd party C++ program function which returns a boost::variant (and its inverse) my_variant my_variant_of_string(const std::string& str) This one takes a string & returns a variant, and am trying to wrap this in python, so that there I can have >>> my_variant_of_string('hello') 'hello' >>> my_variant_of_string('1.2') 1.2 >>> my_variant_of_string('10') 10 Simple, eh? ... How about something like (not tested): using boost::python::object; typedef variant<...> variant_t; variant_t makes_variant_from(string s); // defined elsewhere // // visitor for converting contents of visitor to object // struct vc : boost::static_visitor { template object operator()(const T& v) const { return v; } }; bp::object thunk(string s) { variant_t v = makes_variant_from(s); return boost::apply_visitor(vc(), v); } BOOST_PYTHON_MODULE(mod) { def("f", &thunk); } You could probably use this to just register a converter from variant to vanilla boost::python::object as well, if this is more convenient... -t ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig No virus found in this incoming message. Checked by AVG - www.avg.com Version: 9.0.725 / Virus Database: 270.14.138/2618 - Release Date: 01/13/10 07:35:00 ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig