types.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. #pragma once
  2. #include "object.h"
  3. namespace pybind11 {
  4. template <typename T>
  5. handle cast(T&& value, return_value_policy policy = return_value_policy::automatic_reference, handle parent = {});
  6. struct arg {
  7. const char* name;
  8. handle default_;
  9. arg(const char* name) : name(name), default_() {}
  10. template <typename T>
  11. arg& operator= (T&& value) {
  12. default_ = cast(std::forward<T>(value));
  13. return *this;
  14. }
  15. };
  16. // undef in pybind11.h
  17. #define PYBIND11_REGISTER_INIT(func) \
  18. static inline int _register = [] { \
  19. interpreter::register_init(func); \
  20. return 0; \
  21. }();
  22. class none : public object {
  23. #if PK_VERSION_MAJOR == 2
  24. PYBIND11_TYPE_IMPLEMENT(object, empty, vm->tp_none_type);
  25. #else
  26. PYBIND11_TYPE_IMPLEMENT(object, empty, [](const handle& obj) {
  27. return obj.is_none();
  28. });
  29. #endif
  30. public:
  31. none() : object(vm->None) {}
  32. };
  33. /// corresponding to type in Python
  34. class type : public object {
  35. PYBIND11_TYPE_IMPLEMENT(object, pkpy::Type, vm->tp_type);
  36. public:
  37. template <typename T>
  38. static handle handle_of() {
  39. return type_visitor::type<T>();
  40. }
  41. template <typename T>
  42. static type of() {
  43. return type_visitor::type<T>();
  44. }
  45. static type of(const handle& obj) { return type(vm->_t(obj.ptr())); }
  46. };
  47. /// corresponding to bool in Python
  48. class bool_ : public object {
  49. PYBIND11_TYPE_IMPLEMENT(object, bool, vm->tp_bool);
  50. public:
  51. bool_(bool value) : object(create(value)) {}
  52. operator bool () const { return self(); }
  53. };
  54. /// corresponding to int in Python
  55. class int_ : public object {
  56. PYBIND11_TYPE_IMPLEMENT(object, pkpy::i64, vm->tp_int);
  57. public:
  58. int_(int64_t value) : object(create(value)) {}
  59. operator int64_t () const { return self(); }
  60. };
  61. /// corresponding to float in Python
  62. class float_ : public object {
  63. PYBIND11_TYPE_IMPLEMENT(object, pkpy::f64, vm->tp_float);
  64. public:
  65. float_(double value) : object(create(value)) {}
  66. operator double () const { return self(); }
  67. };
  68. class iterable : public object {
  69. PYBIND11_TYPE_IMPLEMENT(object, empty, [](const handle& obj) {
  70. return vm->getattr(obj.ptr(), pkpy::__iter__, false) != nullptr;
  71. });
  72. };
  73. class iterator : public object {
  74. PYBIND11_TYPE_IMPLEMENT(object, empty, [](const handle& obj) {
  75. return vm->getattr(obj.ptr(), pkpy::__next__, false) != nullptr &&
  76. vm->getattr(obj.ptr(), pkpy::__iter__, false) != nullptr;
  77. });
  78. handle m_value;
  79. iterator(pkpy::PyVar n, pkpy::PyVar s) : object(n), m_value(s) {}
  80. public:
  81. iterator(const handle& obj) : object(obj) { m_value = vm->py_next(obj.ptr()); }
  82. iterator operator++ () {
  83. m_value = vm->py_next(m_ptr);
  84. return *this;
  85. }
  86. iterator operator++ (int) {
  87. m_value = vm->py_next(m_ptr);
  88. return *this;
  89. }
  90. const handle& operator* () const { return m_value; }
  91. friend bool operator== (const iterator& lhs, const iterator& rhs) { return lhs.m_value.is(rhs.m_value); }
  92. friend bool operator!= (const iterator& lhs, const iterator& rhs) { return !(lhs == rhs); }
  93. static iterator sentinel() { return iterator(vm->None, vm->StopIteration); }
  94. };
  95. class str : public object {
  96. PYBIND11_TYPE_IMPLEMENT(object, pkpy::Str, vm->tp_str);
  97. public:
  98. str(const char* c, int len) : object(create(c, len)) {};
  99. str(const char* c = "") : str(c, strlen(c)) {}
  100. str(const std::string& s) : str(s.data(), s.size()) {}
  101. str(std::string_view sv) : str(sv.data(), sv.size()) {}
  102. // explicit str(const bytes& b);
  103. explicit str(handle h);
  104. operator std::string_view () const { return self().sv(); }
  105. template <typename... Args>
  106. str format(Args&&... args) const;
  107. };
  108. // class bytes : public object {
  109. // public:
  110. // using object::object;
  111. // };
  112. // class bytearray : public object {
  113. // public:
  114. // using object::object;
  115. // };
  116. class tuple : public object {
  117. PYBIND11_TYPE_IMPLEMENT(object, pkpy::Tuple, vm->tp_tuple);
  118. public:
  119. tuple(int n) : object(create(n)) {}
  120. template <typename... Args, std::enable_if_t<(sizeof...(Args) > 1)>* = nullptr>
  121. tuple(Args&&... args) : object(create(sizeof...(Args))) {
  122. int index = 0;
  123. ((self()[index++] = pybind11::cast(std::forward<Args>(args)).ptr()), ...);
  124. }
  125. int size() const { return self().size(); }
  126. bool empty() const { return size() == 0; }
  127. tuple_accessor operator[] (int i) const;
  128. };
  129. class list : public object {
  130. PYBIND11_TYPE_IMPLEMENT(object, pkpy::List, vm->tp_list)
  131. public:
  132. list() : object(create(0)) {}
  133. list(int n) : object(create(n)) {}
  134. template <typename... Args, std::enable_if_t<(sizeof...(Args) > 1)>* = nullptr>
  135. list(Args&&... args) : object(create(sizeof...(Args))) {
  136. int index = 0;
  137. ((self()[index++] = pybind11::cast(std::forward<Args>(args)).ptr()), ...);
  138. }
  139. int size() const { return self().size(); }
  140. bool empty() const { return size() == 0; }
  141. void clear() { self().clear(); }
  142. list_accessor operator[] (int i) const;
  143. void append(const handle& obj) { self().push_back(obj.ptr()); }
  144. void extend(const handle& iterable) {
  145. for(auto& item: iterable) {
  146. append(item);
  147. }
  148. }
  149. void insert(int index, const handle& obj) {
  150. #if PK_VERSION_MAJOR == 2
  151. const auto pos = self().begin() + index;
  152. self().insert(pos, obj.ptr());
  153. #else
  154. self().insert(index, obj.ptr());
  155. #endif
  156. }
  157. };
  158. class slice : public object {
  159. PYBIND11_TYPE_IMPLEMENT(object, pkpy::Slice, vm->tp_slice);
  160. public:
  161. };
  162. // class set : public object {
  163. // public:
  164. // using object::object;
  165. // // set() : object(vm->new_object<pkpy::Se>(pkpy::VM::tp_set), true) {}
  166. // };
  167. //
  168. class dict : public object {
  169. PYBIND11_TYPE_IMPLEMENT(object, pkpy::Dict, vm->tp_dict);
  170. public:
  171. #if PK_VERSION_MAJOR == 2
  172. dict() : object(create()) {}
  173. template <typename... Args, typename = std::enable_if_t<(std::is_same_v<remove_cvref_t<Args>, arg> && ...)>>
  174. dict(Args&&... args) : object(create()) {
  175. auto foreach_ = [&](pybind11::arg& arg) {
  176. setitem(str(arg.name), arg.default_);
  177. };
  178. (foreach_(args), ...);
  179. }
  180. void setitem(const handle& key, const handle& value) { self().set(vm, key.ptr(), value.ptr()); }
  181. handle getitem(const handle& key) const { return self().try_get(vm, key.ptr()); }
  182. struct iterator {
  183. pkpy_DictIter iter;
  184. std::pair<handle, handle> value;
  185. iterator operator++ () {
  186. bool is_ended = pkpy_DictIter__next(&iter, (PyVar*)&value.first, (PyVar*)&value.second);
  187. if(!is_ended) {
  188. iter._dict = nullptr;
  189. iter._index = -1;
  190. }
  191. return *this;
  192. }
  193. std::pair<handle, handle> operator* () const { return value; }
  194. bool operator== (const iterator& other) const {
  195. return iter._dict == other.iter._dict && iter._index == other.iter._index;
  196. }
  197. bool operator!= (const iterator& other) const { return !(*this == other); }
  198. };
  199. iterator begin() const {
  200. iterator iter{self().iter(), {}};
  201. ++iter;
  202. return iter;
  203. }
  204. iterator end() const { return {nullptr, -1}; }
  205. #else
  206. dict() : object(create(vm)) {}
  207. template <typename... Args, typename = std::enable_if_t<(std::is_same_v<remove_cvref_t<Args>, arg> && ...)>>
  208. dict(Args&&... args) : object(create(vm)) {
  209. auto foreach_ = [&](pybind11::arg& arg) {
  210. setitem(str(arg.name), arg.default_);
  211. };
  212. (foreach_(args), ...);
  213. }
  214. void setitem(const handle& key, const handle& value) { self().set(key.ptr(), value.ptr()); }
  215. handle getitem(const handle& key) const { return self().try_get(key.ptr()); }
  216. struct iterator {
  217. pkpy::Dict::Item* items;
  218. pkpy::Dict::ItemNode* nodes;
  219. int index;
  220. iterator operator++ () {
  221. index = nodes[index].next;
  222. if(index == -1) {
  223. items = nullptr;
  224. nodes = nullptr;
  225. }
  226. return *this;
  227. }
  228. std::pair<handle, handle> operator* () const { return {items[index].first, items[index].second}; }
  229. bool operator== (const iterator& other) const {
  230. return items == other.items && nodes == other.nodes && index == other.index;
  231. }
  232. bool operator!= (const iterator& other) const { return !(*this == other); }
  233. };
  234. iterator begin() const {
  235. auto index = self()._head_idx;
  236. if(index == -1) {
  237. return end();
  238. } else {
  239. return {self()._items, self()._nodes, index};
  240. }
  241. }
  242. iterator end() const { return {nullptr, nullptr, -1}; }
  243. template <typename Key>
  244. bool contains(Key&& key) const {
  245. return self().contains(vm, pybind11::cast(std::forward<Key>(key)).ptr());
  246. }
  247. #endif
  248. int size() const { return self().size(); }
  249. bool empty() const { return size() == 0; }
  250. void clear() { self().clear(); }
  251. dict_accessor operator[] (int index) const;
  252. dict_accessor operator[] (std::string_view) const;
  253. dict_accessor operator[] (const handle& key) const;
  254. };
  255. class function : public object {
  256. PYBIND11_TYPE_IMPLEMENT(object, pkpy::Function, vm->tp_function);
  257. };
  258. //
  259. // class buffer : public object {
  260. // public:
  261. // using object::object;
  262. //};
  263. //
  264. // class memory_view : public object {
  265. // public:
  266. // using object::object;
  267. //};
  268. //
  269. class capsule : public object {
  270. PYBIND11_REGISTER_INIT([] {
  271. type_visitor::create<impl::capsule>(vm->builtins, "capsule", true);
  272. });
  273. PYBIND11_TYPE_IMPLEMENT(object, impl::capsule, handle(vm->builtins->attr("capsule"))._as<pkpy::Type>());
  274. public:
  275. capsule(void* ptr, void (*destructor)(void*) = nullptr) : object(create(ptr, destructor)) {}
  276. void* data() const { return self().ptr; }
  277. template <typename T>
  278. T& cast() const {
  279. return *static_cast<T*>(self().ptr);
  280. }
  281. };
  282. class property : public object {
  283. PYBIND11_TYPE_IMPLEMENT(object, pkpy::Property, vm->tp_property);
  284. public:
  285. #if PK_VERSION_MAJOR == 2
  286. property(handle getter, handle setter) : object(create(getter.ptr(), setter.ptr())) {}
  287. #else
  288. property(handle getter, handle setter) : object(create(pkpy::Property{getter.ptr(), setter.ptr()})) {}
  289. #endif
  290. handle getter() const { return self().getter; }
  291. handle setter() const { return self().setter; }
  292. };
  293. class args : public tuple {
  294. PYBIND11_TYPE_IMPLEMENT(tuple, pybind11::empty, vm->tp_tuple);
  295. };
  296. class kwargs : public dict {
  297. PYBIND11_TYPE_IMPLEMENT(dict, pybind11::empty, vm->tp_dict);
  298. };
  299. } // namespace pybind11