のんびりしているエンジニアの日記

ソフトウェアなどのエンジニア的な何かを書きます。

boost::python(2) STLの活用 vectorとmap(Suiteも活用)

Sponsored Links

こんにちは
皆さんお元気ですか?私は面白い遊びを探しています。

さて、先日に引き続きboost::pythonについて
本日はC++STLについて取り扱ってみたいと思います。

さて、STLを使用する時に普通のものと違い少々めんどくさくなります。

通常の実装方法

C++

#include <vector>
#include <boost/python.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>

using namespace std;

class Foo{
public:
	vector<int> vect;

	vector<int> get_list(){
		return vect;
	}

	void add(int a){
		vect.push_back(a);
	}
};

BOOST_PYTHON_MODULE(basic_vector){
	using namespace boost::python;

	class_<Foo>("Foo")
	.def("get_list",&Foo::get_list)
	.def("add",&Foo::add);


	class_<vector<int> >("vector<int>")
	.def("__getitem__", (int const&(vector<int>::*)(vector<int>::size_type) const)&vector<int>::at, return_value_policy<copy_const_reference>())
	.def("__len__", &vector<int>::size)
	;
}

単純に書くと
class_ >("vector") 以下でいろいろと複雑なソースコードをかかないといけないようです。
実行は以下のような感じ

Python

python
>>> import basic_vector
>>> foo = basic_vector.Foo()
>>> foo.add(2)
>>> foo.add(3)
>>> list = foo.get_list()
>>> list
<basic_vector.vector<int> object at 0x1019ae7d0>
>>> list[0]
2
>>> list[1]
3
>>> len(list)
2

このようなことを書くのはとてもめんどくさい。
そんなラッパーを追加できるような仕組みがあるようです。それがsuiteです。

Suiteを活用した実装方法

C++

#include <vector>
#include <map>
#include <boost/python.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <boost/python/suite/indexing/map_indexing_suite.hpp>

using namespace std;

class Foo{
public:
	vector<int> vect;
	map<string,int> mp;

	vector<int> get_list(){
		return vect;
	}

	void add(int a){
		vect.push_back(a);
	}

	void mp_add(string a,int b){
		mp[a] = b;
	}

	map<string,int> get_map(){
		return mp;
	}
};

BOOST_PYTHON_MODULE(basic_vector){
	using namespace boost::python;

	class_<Foo>("Foo")
	.def("get_list",&Foo::get_list)
	.def("add",&Foo::add)
	.def("mp_add",&Foo::mp_add)
	.def("get_map",&Foo::get_map);

	class_<vector<int> >("vector<int>")
	.def(vector_indexing_suite<vector<int> >());

	class_<map<string,int> >("map<string,int>")
	.def(map_indexing_suite<map<string,int> >());
}

こんな感じで書くことができます。
うん、だいぶ楽になった。

>>> import basic_vector_suite
>>> foo = basic_vector_suite.Foo()
>>> foo.add(2)
>>> foo.add(3)
>>> list = foo.get_list()
>>> list
<basic_vector_suite.vector<int> object at 0x107b1b7d0>
>>> list[0]
2
>>> list[1]
3
>>> foo.mp_add("temp",3)
>>> dict = foo.get_map()
>>> dict["temp"]
3

更に加速、君もboostしよう!
次回はpythonのListとかpythonのdictとかで返す方法を載せますね。