Reputation: 27684
I have a C++ function which takes a vector< pair< pair<string,string>, string > >
which I wish to call from python.
I wrote a wrapper as below:
bool create_cache_wrapper(boost::python::tuple tup_)
{
vector< pair< pair<string,string>, string > > rbv;
for(int i=0;i<py::len(tup_);++i)
{
std::string start,end,bucket;
bucket = py::extract<std::string>(tup_[i][1]);
start = py::extract<std::string>(tup_[i][0][0]);
end = py::extract<std::string>(tup_[i][0][1]);
rbv.push_back(make_pair(make_pair(start,end),bucket));
}
return create_cache(rbv);
}
I have registered this function with python as below:
BOOST_PYTHON_MODULE(my_lib)
{
using namespace boost::python;
def("create_cache", create_cache_wrapper);
}
This works fine but the issue is, it accepts only a tuple but not a list. How do I write the wrapper such that it works any sequence container in python? Is there a better way to do this without having to write a wrapper? I want the python api to be simple like
create_cache( ( (('',''),'b1'), ) )
create_cache( [ (('',''),'b1') ] )
Upvotes: 3
Views: 382
Reputation: 5309
I normally use boost python iterator wrappers to achieve what you described - it works with any type of iterable. I adapted your code below so you have an idea on how to do it yourself:
#include <boost/python.hpp>
#include <boost/python/stl_iterator.hpp>
using namespace boost::python;
bool create_cache_wrapper(object iterable)
{
stl_input_iterator<object> end;
for(std_input_iterator<object> i(iterable); i!=end; ++i)
{
std::string start,end,bucket;
bucket = py::extract<std::string>((*i)[1]);
start = py::extract<std::string>((*i)[0][0]);
end = py::extract<std::string>((*i)[0][1]);
rbv.push_back(make_pair(make_pair(start,end),bucket));
}
return create_cache(rbv);
}
You can go all the way using stl_input_iterator
, even for the your pairs inside the first iterable.
Upvotes: 1
Reputation: 169403
This could be accomplished by making the wrapper take an object instead:
bool create_cache_wrapper(boost::python::object tup_)
{
// ...
}
py::len()
and the indexing operators should work on objects, and they should raise a Python error if the type in question does not support len()
or indexing. This should allow the caller to provide any indexable type, even user-defined ones!
Upvotes: 2