1
0

object.h 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. #pragma once
  2. #include "kernel.h"
  3. namespace pkbind {
  4. class handle;
  5. class object;
  6. class iterator;
  7. class str;
  8. struct arg;
  9. struct arg_with_default;
  10. struct args_proxy;
  11. enum class return_value_policy : uint8_t {
  12. /**
  13. * This is the default return value policy, which falls back to the policy
  14. * return_value_policy::take_ownership when the return value is a pointer.
  15. * Otherwise, it uses return_value::move or return_value::copy for rvalue
  16. * and lvalue references, respectively. See below for a description of what
  17. * all of these different policies do.
  18. */
  19. automatic = 0,
  20. /**
  21. * As above, but use policy return_value_policy::reference when the return
  22. * value is a pointer. This is the default conversion policy for function
  23. * arguments when calling Python functions manually from C++ code (i.e. via
  24. * handle::operator()). You probably won't need to use this.
  25. */
  26. automatic_reference,
  27. /**
  28. * Reference an existing object (i.e. do not create a new copy) and take
  29. * ownership. Python will call the destructor and delete operator when the
  30. * object's reference count reaches zero. Undefined behavior ensues when
  31. * the C++ side does the same..
  32. */
  33. take_ownership,
  34. /**
  35. * Create a new copy of the returned object, which will be owned by
  36. * Python. This policy is comparably safe because the lifetimes of the two
  37. * instances are decoupled.
  38. */
  39. copy,
  40. /**
  41. * Use std::move to move the return value contents into a new instance
  42. * that will be owned by Python. This policy is comparably safe because the
  43. * lifetimes of the two instances (move source and destination) are
  44. * decoupled.
  45. */
  46. move,
  47. /**
  48. * Reference an existing object, but do not take ownership. The C++ side
  49. * is responsible for managing the object's lifetime and deallocating it
  50. * when it is no longer used. Warning: undefined behavior will ensue when
  51. * the C++ side deletes an object that is still referenced and used by
  52. * Python.
  53. */
  54. reference,
  55. /**
  56. * This policy only applies to methods and properties. It references the
  57. * object without taking ownership similar to the above
  58. * return_value_policy::reference policy. In contrast to that policy, the
  59. * function or property's implicit this argument (called the parent) is
  60. * considered to be the the owner of the return value (the child).
  61. * pybind11 then couples the lifetime of the parent to the child via a
  62. * reference relationship that ensures that the parent cannot be garbage
  63. * collected while Python is still using the child. More advanced
  64. * variations of this scheme are also possible using combinations of
  65. * return_value_policy::reference and the keep_alive call policy
  66. */
  67. reference_internal
  68. };
  69. template <typename policy>
  70. class accessor;
  71. namespace policy {
  72. struct attr;
  73. template <typename Key>
  74. struct item;
  75. struct tuple;
  76. struct list;
  77. template <typename Key>
  78. struct dict;
  79. } // namespace policy
  80. using attr_accessor = accessor<policy::attr>;
  81. template <typename Key>
  82. using item_accessor = accessor<policy::item<Key>>;
  83. using tuple_accessor = accessor<policy::tuple>;
  84. using list_accessor = accessor<policy::list>;
  85. template <typename Key>
  86. using dict_accessor = accessor<policy::dict<Key>>;
  87. /// call a pkpy function which may raise a python exception.
  88. template <auto Fn, typename... Args>
  89. auto raise_call(Args&&... args);
  90. /// an effective representation of a python small string.
  91. class name {
  92. public:
  93. name() = default;
  94. name(const name&) = default;
  95. name& operator= (const name&) = default;
  96. explicit name(py_Name data) : data(data) {}
  97. name(const char* str) : data(py_name(str)) {}
  98. name(const char* data, int size) : data(py_namev({data, size})) {}
  99. name(std::string_view str) : name(str.data(), static_cast<int>(str.size())) {}
  100. name(handle h);
  101. py_Name index() const { return data; }
  102. const char* c_str() const { return py_name2str(data); }
  103. operator std::string_view () const {
  104. auto temp = py_name2sv(data);
  105. return std::string_view(temp.data, temp.size);
  106. }
  107. private:
  108. py_Name data;
  109. };
  110. template <typename Derived>
  111. class interface {
  112. public:
  113. /// equal to `self is None` in python.
  114. bool is_none() const { return py_isnone(ptr()); }
  115. /// equal to `self is other` in python.
  116. bool is(const interface& other) const { return py_isidentical(ptr(), other.ptr()); }
  117. void assign(const interface& other) { py_assign(ptr(), other.ptr()); }
  118. iterator begin() const;
  119. iterator end() const;
  120. attr_accessor attr(name key) const;
  121. object operator- () const;
  122. object operator~() const;
  123. args_proxy operator* () const;
  124. item_accessor<int> operator[] (int index) const;
  125. item_accessor<name> operator[] (name key) const;
  126. item_accessor<handle> operator[] (handle key) const;
  127. template <return_value_policy policy = return_value_policy::automatic, typename... Args>
  128. object operator() (Args&&... args) const;
  129. auto doc() const { return attr("__doc__"); }
  130. template <typename T>
  131. T cast() const;
  132. private:
  133. py_Ref ptr() const { return static_cast<const Derived*>(this)->ptr(); }
  134. };
  135. /// a simple wrapper to py_Ref.
  136. /// Note that it does not manage the lifetime of the object.
  137. class handle : public interface<handle> {
  138. public:
  139. handle() = default;
  140. handle(const handle&) = default;
  141. handle& operator= (const handle&) = default;
  142. handle(py_Ref ptr) : m_ptr(ptr) {}
  143. auto ptr() const { return m_ptr; }
  144. explicit operator bool () const { return m_ptr != nullptr; }
  145. protected:
  146. py_Ref m_ptr = nullptr;
  147. };
  148. class object : public handle {
  149. public:
  150. object() = default;
  151. object(const object& other) : handle(other), m_index(other.m_index) {
  152. if(other.in_pool()) { object_pool::inc_ref(other); }
  153. }
  154. object(object&& other) : handle(other), m_index(other.m_index) {
  155. other.m_ptr = nullptr;
  156. other.m_index = -1;
  157. }
  158. object& operator= (const object& other) {
  159. if(this != &other) {
  160. if(in_pool()) { object_pool::dec_ref(*this); }
  161. if(other.in_pool()) { object_pool::inc_ref(other); }
  162. m_ptr = other.m_ptr;
  163. m_index = other.m_index;
  164. }
  165. return *this;
  166. }
  167. object& operator= (object&& other) {
  168. if(this != &other) {
  169. if(in_pool()) { object_pool::dec_ref(*this); }
  170. m_ptr = other.m_ptr;
  171. m_index = other.m_index;
  172. other.m_ptr = nullptr;
  173. other.m_index = -1;
  174. }
  175. return *this;
  176. }
  177. ~object() {
  178. if(in_pool()) { object_pool::dec_ref(*this); }
  179. }
  180. bool is_singleton() const { return m_ptr && m_index == -1; }
  181. bool empty() const { return m_ptr == nullptr && m_index == -1; }
  182. /// return whether the object is in the object pool.
  183. bool in_pool() const { return m_ptr && m_index != -1; }
  184. public:
  185. static auto type_or_check() { return tp_object; }
  186. struct alloc_t {};
  187. struct realloc_t {};
  188. struct ref_t {};
  189. object(alloc_t) {
  190. auto ref = object_pool::alloc();
  191. m_ptr = ref.data;
  192. m_index = ref.index;
  193. }
  194. object(handle h, realloc_t) {
  195. auto ref = object_pool::realloc(h.ptr());
  196. m_ptr = ref.data;
  197. m_index = ref.index;
  198. }
  199. object(handle h, ref_t) : handle(h) {}
  200. static object from_ret() { return object(py_retval(), realloc_t{}); }
  201. operator object_pool::object_ref () const { return {m_ptr, m_index}; }
  202. explicit operator bool () const;
  203. protected:
  204. int m_index = -1;
  205. };
  206. template <typename T = object>
  207. T steal(handle h) {
  208. return T(h, object::ref_t{});
  209. }
  210. template <typename T = object>
  211. T borrow(handle h) {
  212. return T(h, object::realloc_t{});
  213. }
  214. static_assert(std::is_trivially_copyable_v<name>);
  215. static_assert(std::is_trivially_copyable_v<handle>);
  216. } // namespace pkbind