class.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. #include "test.h"
  2. namespace {
  3. struct Point {
  4. int x;
  5. int y;
  6. private:
  7. int z;
  8. public:
  9. inline static int constructor_calls = 0;
  10. inline static int copy_constructor_calls = 0;
  11. inline static int move_constructor_calls = 0;
  12. inline static int destructor_calls = 0;
  13. Point() : x(0), y(0), z(0) { constructor_calls++; }
  14. Point(int x, int y, int z) : x(x), y(y), z(z) { constructor_calls++; }
  15. Point(const Point& p) : x(p.x), y(p.y), z(p.z) {
  16. copy_constructor_calls++;
  17. constructor_calls++;
  18. }
  19. Point(Point&& p) noexcept : x(p.x), y(p.y), z(p.z) {
  20. move_constructor_calls++;
  21. constructor_calls++;
  22. }
  23. Point& operator= (const Point& p) {
  24. x = p.x;
  25. y = p.y;
  26. z = p.z;
  27. return *this;
  28. }
  29. ~Point() { destructor_calls++; }
  30. int& get_z() { return z; }
  31. void set_z(int z) { this->z = z; }
  32. std::string stringfy() const {
  33. return "(" + std::to_string(x) + ", " + std::to_string(y) + ", " + std::to_string(z) + ")";
  34. }
  35. void set_pointer(Point* p) {
  36. this->x = p->x;
  37. this->y = p->y;
  38. this->z = p->z;
  39. }
  40. };
  41. struct Line {
  42. Point start;
  43. Point end;
  44. };
  45. TEST_F(PYBIND11_TEST, class) {
  46. py::module m = py::module::import("__main__");
  47. py::class_<Point>(m, "Point")
  48. .def(py::init<>())
  49. .def(py::init<int, int, int>())
  50. .def_readwrite("x", &Point::x)
  51. .def_readwrite("y", &Point::y)
  52. .def_property("z", &Point::get_z, &Point::set_z)
  53. .def("stringfy", &Point::stringfy)
  54. .def("set_pointer", &Point::set_pointer);
  55. py::exec(R"(
  56. p = Point()
  57. assert p.stringfy() == '(0, 0, 0)'
  58. p = Point(1, 2, 3)
  59. assert p.x == 1
  60. assert p.y == 2
  61. assert p.z == 3
  62. assert p.stringfy() == '(1, 2, 3)'
  63. p.x = 10
  64. p.y = 20
  65. p.z = 30
  66. assert p.stringfy() == '(10, 20, 30)'
  67. p.set_pointer(Point(4,5,6))
  68. assert p.stringfy() == '(4, 5, 6)'
  69. )");
  70. py::class_<Line> line(m, "Line");
  71. line // not bind constructor
  72. .def_readwrite("start", &Line::start)
  73. .def_readwrite("end", &Line::end);
  74. // bind constructor
  75. line.def(py::init<>());
  76. py::exec(R"(
  77. l = Line()
  78. l.start = Point(1, 2, 3)
  79. l.end = Point(4, 5, 6)
  80. p = l.start
  81. assert l.start.stringfy() == '(1, 2, 3)'
  82. assert l.end.stringfy() == '(4, 5, 6)'
  83. )");
  84. py::finalize(true);
  85. EXPECT_EQ(Point::constructor_calls, Point::destructor_calls);
  86. EXPECT_EQ(Point::copy_constructor_calls, 0);
  87. EXPECT_EQ(Point::move_constructor_calls, 0);
  88. }
  89. TEST_F(PYBIND11_TEST, inheritance) {
  90. static int constructor_calls = 0;
  91. struct Point {
  92. int x;
  93. int y;
  94. Point() : x(0), y(0) { constructor_calls++; }
  95. Point(int x, int y) : x(x), y(y) { constructor_calls++; }
  96. };
  97. struct Point3D : Point {
  98. int z;
  99. Point3D() : Point(), z(0) { constructor_calls++; }
  100. Point3D(int x, int y, int z) : Point(x, y), z(z) { constructor_calls++; }
  101. };
  102. py::module m = py::module::import("__main__");
  103. py::class_<Point>(m, "Point")
  104. .def(py::init<>())
  105. .def(py::init<int, int>())
  106. .def_readwrite("x", &Point::x)
  107. .def_readwrite("y", &Point::y);
  108. py::class_<Point3D, Point>(m, "Point3D")
  109. .def(py::init<>())
  110. .def(py::init<int, int, int>())
  111. .def_readwrite("z", &Point3D::z);
  112. py::exec(R"(
  113. p = Point3D()
  114. assert type(p) == Point3D
  115. assert p.x == 0
  116. assert p.y == 0
  117. assert p.z == 0
  118. p = Point3D(1, 2, 3)
  119. assert p.x == 1
  120. assert p.y == 2
  121. assert p.z == 3
  122. p.x = 10
  123. p.y = 20
  124. p.z = 30
  125. assert p.x == 10
  126. assert p.y == 20
  127. assert p.z == 30
  128. )");
  129. py::finalize(true);
  130. EXPECT_EQ(constructor_calls, 4);
  131. }
  132. TEST_F(PYBIND11_TEST, dynamic_attr) {
  133. py::module m = py::module::import("__main__");
  134. struct Point {
  135. int x;
  136. int y;
  137. Point(int x, int y) : x(x), y(y) {}
  138. };
  139. py::class_<Point>(m, "Point", py::dynamic_attr())
  140. .def(py::init<int, int>())
  141. .def_readwrite("x", &Point::x)
  142. .def_readwrite("y", &Point::y);
  143. py::object p = py::eval("Point(1, 2)");
  144. EXPECT_EQ(p.attr("x").cast<int>(), 1);
  145. EXPECT_EQ(p.attr("y").cast<int>(), 2);
  146. p.attr("z") = py::int_(3);
  147. EXPECT_EQ(p.attr("z").cast<int>(), 3);
  148. }
  149. TEST_F(PYBIND11_TEST, enum) {
  150. enum class Color { RED, Yellow, GREEN, BLUE };
  151. py::module m = py::module::import("__main__");
  152. py::enum_<Color> color(m, "Color");
  153. color.value("RED", Color::RED)
  154. .value("Yellow", Color::Yellow)
  155. .value("GREEN", Color::GREEN)
  156. .value("BLUE", Color::BLUE);
  157. EXPECT_EVAL_EQ("Color.RED", Color::RED);
  158. EXPECT_EVAL_EQ("Color.Yellow", Color::Yellow);
  159. EXPECT_EVAL_EQ("Color.GREEN", Color::GREEN);
  160. EXPECT_EVAL_EQ("Color.BLUE", Color::BLUE);
  161. EXPECT_EVAL_EQ("Color(0)", Color::RED);
  162. EXPECT_EVAL_EQ("Color(1)", Color::Yellow);
  163. EXPECT_EVAL_EQ("Color(2)", Color::GREEN);
  164. EXPECT_EVAL_EQ("Color(3)", Color::BLUE);
  165. EXPECT_EXEC_EQ("Color(0)", "Color.RED");
  166. EXPECT_EXEC_EQ("Color(1)", "Color.Yellow");
  167. EXPECT_EXEC_EQ("Color(2)", "Color.GREEN");
  168. EXPECT_EXEC_EQ("Color(3)", "Color.BLUE");
  169. EXPECT_EVAL_EQ("Color.RED.value", static_cast<int>(Color::RED));
  170. EXPECT_EVAL_EQ("Color.Yellow.value", static_cast<int>(Color::Yellow));
  171. EXPECT_EVAL_EQ("Color.GREEN.value", static_cast<int>(Color::GREEN));
  172. EXPECT_EVAL_EQ("Color.BLUE.value", static_cast<int>(Color::BLUE));
  173. color.export_values();
  174. EXPECT_EVAL_EQ("RED", Color::RED);
  175. EXPECT_EVAL_EQ("Yellow", Color::Yellow);
  176. EXPECT_EVAL_EQ("GREEN", Color::GREEN);
  177. EXPECT_EVAL_EQ("BLUE", Color::BLUE);
  178. }
  179. } // namespace