Sign in to follow this  
BigJim

Wrapping std::map using Boost::Python

Recommended Posts

Hi, I'm trying to wrap std::map using boost::python so my embedded python code can access maps. I have the following wrapper class:
//Map - takes e.g std::map<std::string,thing*> as MapType
template<class MapType>
struct MapItem
{
	//Typedefine the key and value types for ease
	typedef typename MapType::key_type KeyType;
	typedef typename MapType::mapped_type ValueType;
	
	static ValueType& Get(MapType & x,KeyType const& i)
	{
		if( x.find(i) != x.end() ) 
			return x[i];
		//Some kind of error!
	}
	static void Set(MapType & x,KeyType const& i,ValueType const& v)
	{
		x[i]=v; // use map autocreation feature
	}
	static void Del(MapType & x,KeyType const& i)
	{
		if( x.find(i) != x.end() ) 
			x.erase(i);

	}
}


And the following Boost::Python class definition to wrap a particular map:
boost::python::class_<std::map<std::string,SubGrid> >("SubGridMap")
	.def("__len__",&std::map<std::string,SubGrid>::size)
	.def("clear",&std::map<std::string,SubGrid>::clear)
	.def("__getitem__",&MapItem<std::map<std::string,SubGrid> >::Get,boost::python::return_value_policy<boost::python::copy_non_const_reference>())
	.def("__setitem__",&MapItem<std::map<std::string,SubGrid> >::Set,boost::python::with_custodian_and_ward<1,2>()) // to let container keep value
	.def("__delitem__",&MapItem<std::map<std::string,SubGrid> >::Del)
;

I really need iterator support and following the Python Wiki entry, have written a function like this to convert the std::map to a std::list of tuples as boost::python::iterator doesn't seem to be compatible with std::map (which seems a bit icky but makes sense):
static std::list<boost::tuple<KeyType,ValueType> > Items(MapType const& x)
{
	std::list<boost::tuple<KeyType,ValueType> > t;
	typename MapType::const_iterator it;
			
	for(it=x.begin(); it!=x.end(); ++it)
		t.push_back(boost::make_tuple(it->first,it->second));
			
	return t;
}

But the wiki entry irritatingly stops short of telling you how the hell you wrap it into an __iter__ and the attachement to the wiki entry seems to be empty...Has anyone done this or have any ideas? Cheers Jamie

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this