#include "test.h" #include "pybind11/stl.h" namespace { int constructor_calls = 0; int destructor_calls = 0; struct Point { int x; int y; Point() : x(0), y(0) { constructor_calls++; } Point(int x, int y) : x(x), y(y) { constructor_calls++; } Point(const Point& p) : x(p.x), y(p.y) { constructor_calls++; } Point(Point&& p) noexcept : x(p.x), y(p.y) { constructor_calls++; } Point& operator= (const Point& p) { x = p.x; y = p.y; return *this; } ~Point() { destructor_calls++; } bool operator== (const Point& p) const { return x == p.x && y == p.y; } }; } // namespace TEST_F(PYBIND11_TEST, vector_bool) { std::vector v = {true, false, true}; py::object obj = py::cast(v); EXPECT_EVAL_EQ("[True, False, True]", obj); std::vector v2 = obj.cast>(); EXPECT_EQ(v, v2); } TEST_F(PYBIND11_TEST, list_like) { py::class_(py::module::__main__(), "Point") .def(py::init()) .def_readwrite("x", &Point::x) .def_readwrite("y", &Point::y) .def("__eq__", &Point::operator==); // array { std::array a = {Point(1, 2), Point(3, 4)}; py::object obj = py::eval("[Point(1, 2), Point(3, 4)]"); EXPECT_EVAL_EQ("[Point(1, 2), Point(3, 4)]", obj); std::array a2 = obj.cast>(); EXPECT_EQ(a, a2); } // vector { std::vector v = {Point(1, 2), Point(3, 4)}; py::object obj = py::cast(v); EXPECT_EVAL_EQ("[Point(1, 2), Point(3, 4)]", obj); std::vector v2 = obj.cast>(); EXPECT_EQ(v, v2); } // list { std::list l = {Point(1, 2), Point(3, 4)}; py::object obj = py::cast(l); EXPECT_EVAL_EQ("[Point(1, 2), Point(3, 4)]", obj); std::list l2 = obj.cast>(); EXPECT_EQ(l, l2); } // deque { std::deque d = {Point(1, 2), Point(3, 4)}; py::object obj = py::cast(d); EXPECT_EVAL_EQ("[Point(1, 2), Point(3, 4)]", obj); std::deque d2 = obj.cast>(); EXPECT_EQ(d, d2); } } TEST_F(PYBIND11_TEST, dict_like) { py::class_(py::module::__main__(), "Point") .def(py::init()) .def_readwrite("x", &Point::x) .def_readwrite("y", &Point::y) .def("__eq__", &Point::operator==); // map { std::map m = { {"a", Point(1, 2)}, {"b", Point(3, 4)} }; py::object obj = py::cast(m); EXPECT_EVAL_EQ("{'a': Point(1, 2), 'b': Point(3, 4)}", obj); std::map m2 = obj.cast>(); EXPECT_EQ(m, m2); } // unordered_map { std::unordered_map m = { {"a", Point(1, 2)}, {"b", Point(3, 4)} }; py::object obj = py::cast(m); EXPECT_EVAL_EQ("{'a': Point(1, 2), 'b': Point(3, 4)}", obj); std::unordered_map m2 = obj.cast>(); EXPECT_EQ(m, m2); } }