1
0

object.h 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. #pragma once
  2. #include "kernel.h"
  3. namespace pybind11 {
  4. class handle;
  5. class object;
  6. class attr_accessor;
  7. class item_accessor;
  8. class iterator;
  9. class str;
  10. class bytes;
  11. class iterable;
  12. class tuple;
  13. class dict;
  14. class list;
  15. class set;
  16. class function;
  17. class module;
  18. class type;
  19. class bool_;
  20. class int_;
  21. class float_;
  22. class str;
  23. class bytes;
  24. template <typename T>
  25. T& _builtin_cast(const handle& obj);
  26. template <typename T>
  27. T reinterpret_borrow(const handle& h);
  28. template <typename T>
  29. T reinterpret_steal(const handle& h);
  30. class handle {
  31. protected:
  32. pkpy::PyVar m_ptr = nullptr;
  33. mutable int* ref_count = nullptr;
  34. public:
  35. handle() = default;
  36. handle(const handle& h) = default;
  37. handle& operator= (const handle& other) = default;
  38. handle(pkpy::PyVar ptr) : m_ptr(ptr) {}
  39. pkpy::PyVar ptr() const { return m_ptr; }
  40. int reference_count() const { return ref_count == nullptr ? 0 : *ref_count; }
  41. const handle& inc_ref() const {
  42. assert(m_ptr != nullptr);
  43. if(ref_count == nullptr) {
  44. auto iter = _ref_counts_map->find(m_ptr);
  45. if(iter == _ref_counts_map->end()) {
  46. ref_count = ::new int(1);
  47. _ref_counts_map->insert({m_ptr, ref_count});
  48. } else {
  49. ref_count = iter->second;
  50. *ref_count += 1;
  51. }
  52. } else {
  53. *ref_count += 1;
  54. }
  55. return *this;
  56. }
  57. const handle& dec_ref() const {
  58. assert(m_ptr != nullptr);
  59. assert(ref_count != nullptr);
  60. *ref_count -= 1;
  61. try {
  62. if(*ref_count == 0) {
  63. _ref_counts_map->erase(m_ptr);
  64. ::delete ref_count;
  65. ref_count = nullptr;
  66. }
  67. } catch(std::exception& e) { std::cerr << "Error: " << e.what() << std::endl; }
  68. return *this;
  69. }
  70. public:
  71. template <typename T>
  72. T cast() const;
  73. explicit operator bool () const { return m_ptr.operator bool (); }
  74. bool is(const handle& other) const { return m_ptr == other.m_ptr; }
  75. bool is_none() const { return m_ptr == vm->None; }
  76. bool in(const handle& other) const {
  77. return pkpy::py_cast<bool>(vm, vm->call(vm->py_op("contains"), other.m_ptr, m_ptr));
  78. }
  79. bool contains(const handle& other) const {
  80. return pkpy::py_cast<bool>(vm, vm->call(vm->py_op("contains"), m_ptr, other.m_ptr));
  81. }
  82. iterator begin() const;
  83. iterator end() const;
  84. str doc() const;
  85. attr_accessor attr(const char* name) const;
  86. attr_accessor attr(const handle& name) const;
  87. attr_accessor attr(object&& name) const;
  88. item_accessor operator[] (int64_t key) const;
  89. item_accessor operator[] (const char* key) const;
  90. item_accessor operator[] (const handle& key) const;
  91. item_accessor operator[] (object&& key) const;
  92. object operator- () const;
  93. object operator~() const;
  94. template <return_value_policy policy = return_value_policy::automatic, typename... Args>
  95. object operator() (Args&&... args) const;
  96. private:
  97. friend object operator+ (const handle& lhs, const handle& rhs);
  98. friend object operator- (const handle& lhs, const handle& rhs);
  99. friend object operator* (const handle& lhs, const handle& rhs);
  100. friend object operator% (const handle& lhs, const handle& rhs);
  101. friend object operator/ (const handle& lhs, const handle& rhs);
  102. friend object operator| (const handle& lhs, const handle& rhs);
  103. friend object operator& (const handle& lhs, const handle& rhs);
  104. friend object operator^ (const handle& lhs, const handle& rhs);
  105. friend object operator<< (const handle& lhs, const handle& rhs);
  106. friend object operator>> (const handle& lhs, const handle& rhs);
  107. friend object operator+= (const handle& lhs, const handle& rhs);
  108. friend object operator-= (const handle& lhs, const handle& rhs);
  109. friend object operator*= (const handle& lhs, const handle& rhs);
  110. friend object operator/= (const handle& lhs, const handle& rhs);
  111. friend object operator%= (const handle& lhs, const handle& rhs);
  112. friend object operator|= (const handle& lhs, const handle& rhs);
  113. friend object operator&= (const handle& lhs, const handle& rhs);
  114. friend object operator^= (const handle& lhs, const handle& rhs);
  115. friend object operator<<= (const handle& lhs, const handle& rhs);
  116. friend object operator>>= (const handle& lhs, const handle& rhs);
  117. friend object operator== (const handle& lhs, const handle& rhs);
  118. friend object operator!= (const handle& lhs, const handle& rhs);
  119. friend object operator< (const handle& lhs, const handle& rhs);
  120. friend object operator> (const handle& lhs, const handle& rhs);
  121. friend object operator<= (const handle& lhs, const handle& rhs);
  122. friend object operator>= (const handle& lhs, const handle& rhs);
  123. template <typename T>
  124. friend T& _builtin_cast(const handle& obj) {
  125. // FIXME: 2.0 does not use Py_<T> anymore
  126. static_assert(!std::is_reference_v<T>, "T must not be a reference type.");
  127. return obj.ptr().obj_get<T>();
  128. }
  129. };
  130. static_assert(std::is_trivially_copyable_v<handle>);
  131. class object : public handle {
  132. public:
  133. object(const object& other) : handle(other) { inc_ref(); }
  134. object(object&& other) noexcept : handle(other) {
  135. other.m_ptr = nullptr;
  136. other.ref_count = nullptr;
  137. }
  138. object& operator= (const object& other) {
  139. if(this != &other) {
  140. dec_ref();
  141. m_ptr = other.m_ptr;
  142. ref_count = other.ref_count;
  143. inc_ref();
  144. }
  145. return *this;
  146. }
  147. object& operator= (object&& other) noexcept {
  148. if(this != &other) {
  149. dec_ref();
  150. m_ptr = other.m_ptr;
  151. ref_count = other.ref_count;
  152. other.m_ptr = nullptr;
  153. other.ref_count = nullptr;
  154. }
  155. return *this;
  156. }
  157. ~object() {
  158. if(m_ptr != nullptr) { dec_ref(); }
  159. }
  160. protected:
  161. object(const handle& h, bool borrow) : handle(h) {
  162. if(borrow) { inc_ref(); }
  163. }
  164. template <typename T>
  165. friend T reinterpret_borrow(const handle& h) {
  166. return {h, true};
  167. }
  168. template <typename T>
  169. friend T reinterpret_steal(const handle& h) {
  170. return {h, false};
  171. }
  172. };
  173. inline void setattr(const handle& obj, const handle& name, const handle& value);
  174. inline void setitem(const handle& obj, const handle& key, const handle& value);
  175. #define PYBIND11_BINARY_OPERATOR(OP, NAME) \
  176. inline object operator OP (const handle& lhs, const handle& rhs) { \
  177. return reinterpret_borrow<object>(vm->call(vm->py_op(NAME), lhs.m_ptr, rhs.m_ptr)); \
  178. }
  179. PYBIND11_BINARY_OPERATOR(+, "add");
  180. PYBIND11_BINARY_OPERATOR(-, "sub");
  181. PYBIND11_BINARY_OPERATOR(*, "mul");
  182. PYBIND11_BINARY_OPERATOR(/, "truediv");
  183. PYBIND11_BINARY_OPERATOR(%, "mod");
  184. PYBIND11_BINARY_OPERATOR(|, "or_");
  185. PYBIND11_BINARY_OPERATOR(&, "and_");
  186. PYBIND11_BINARY_OPERATOR(^, "xor");
  187. PYBIND11_BINARY_OPERATOR(<<, "lshift");
  188. PYBIND11_BINARY_OPERATOR(>>, "rshift");
  189. PYBIND11_BINARY_OPERATOR(+=, "iadd");
  190. PYBIND11_BINARY_OPERATOR(-=, "isub");
  191. PYBIND11_BINARY_OPERATOR(*=, "imul");
  192. PYBIND11_BINARY_OPERATOR(/=, "itruediv");
  193. PYBIND11_BINARY_OPERATOR(%=, "imod");
  194. PYBIND11_BINARY_OPERATOR(|=, "ior");
  195. PYBIND11_BINARY_OPERATOR(&=, "iand");
  196. PYBIND11_BINARY_OPERATOR(^=, "ixor");
  197. PYBIND11_BINARY_OPERATOR(<<=, "ilshift");
  198. PYBIND11_BINARY_OPERATOR(>>=, "irshift");
  199. PYBIND11_BINARY_OPERATOR(==, "eq");
  200. PYBIND11_BINARY_OPERATOR(!=, "ne");
  201. PYBIND11_BINARY_OPERATOR(<, "lt");
  202. PYBIND11_BINARY_OPERATOR(>, "gt");
  203. PYBIND11_BINARY_OPERATOR(<=, "le");
  204. PYBIND11_BINARY_OPERATOR(>=, "ge");
  205. #undef PYBIND11_BINARY_OPERATOR
  206. } // namespace pybind11