class.h 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. #pragma once
  2. #include "cpp_function.h"
  3. namespace pybind11 {
  4. class module : public object {
  5. public:
  6. using object::object;
  7. static module import(const char* name) {
  8. if(name == std::string_view{"__main__"}) {
  9. return module{vm->_main, true};
  10. } else {
  11. return module{vm->py_import(name, false), true};
  12. }
  13. }
  14. };
  15. // TODO:
  16. // 1. inheritance
  17. // 2. virtual function
  18. // 3. factory function
  19. template <typename T, typename... Others>
  20. class class_ : public type {
  21. public:
  22. using type::type;
  23. template <typename... Args>
  24. class_(const handle& scope, const char* name, Args&&... args) :
  25. type(vm->new_type_object(scope.ptr(),
  26. name,
  27. vm->tp_object,
  28. false,
  29. pkpy::PyTypeInfo::Vt::get<instance>()),
  30. true) {
  31. pkpy::PyVar mod = scope.ptr();
  32. mod->attr().set(name, m_ptr);
  33. vm->_cxx_typeid_map[typeid(T)] = _builtin_cast<pkpy::Type>(m_ptr);
  34. vm->bind_func(m_ptr, "__new__", -1, [](pkpy::VM* vm, pkpy::ArgsView args) {
  35. auto cls = _builtin_cast<pkpy::Type>(args[0]);
  36. return instance::create<T>(cls);
  37. });
  38. }
  39. /// bind constructor
  40. template <typename... Args, typename... Extra>
  41. class_& def(init<Args...>, const Extra&... extra) {
  42. if constexpr(!std::is_constructible_v<T, Args...>) {
  43. static_assert(std::is_constructible_v<T, Args...>, "Invalid constructor arguments");
  44. } else {
  45. bind_function(
  46. *this,
  47. "__init__",
  48. [](T* self, Args... args) { new (self) T(args...); },
  49. pkpy::BindType::DEFAULT,
  50. extra...);
  51. return *this;
  52. }
  53. }
  54. /// bind member function
  55. template <typename Fn, typename... Extra>
  56. class_& def(const char* name, Fn&& f, const Extra&... extra) {
  57. using first = std::tuple_element_t<0, callable_args_t<remove_cvref_t<Fn>>>;
  58. constexpr bool is_first_base_of_v =
  59. std::is_reference_v<first> && std::is_base_of_v<T, remove_cvref_t<first>>;
  60. if constexpr(!is_first_base_of_v) {
  61. static_assert(
  62. is_first_base_of_v,
  63. "If you want to bind member function, the first argument must be the base class");
  64. } else {
  65. bind_function(*this, name, std::forward<Fn>(f), pkpy::BindType::DEFAULT, extra...);
  66. }
  67. return *this;
  68. }
  69. /// bind operators
  70. template <typename Operator, typename... Extras>
  71. class_& def(Operator op, const Extras&... extras) {
  72. op.execute(*this, extras...);
  73. return *this;
  74. }
  75. // TODO: factory function
  76. /// bind static function
  77. template <typename Fn, typename... Extra>
  78. class_& def_static(const char* name, Fn&& f, const Extra&... extra) {
  79. bind_function(*this, name, std::forward<Fn>(f), pkpy::BindType::STATICMETHOD, extra...);
  80. return *this;
  81. }
  82. template <typename MP, typename... Extras>
  83. class_& def_readwrite(const char* name, MP mp, const Extras&... extras) {
  84. if constexpr(!std::is_member_object_pointer_v<MP>) {
  85. static_assert(std::is_member_object_pointer_v<MP>,
  86. "def_readwrite only supports pointer to data member");
  87. } else {
  88. bind_property(*this, name, mp, mp, extras...);
  89. }
  90. return *this;
  91. }
  92. template <typename MP, typename... Extras>
  93. class_& def_readonly(const char* name, MP mp, const Extras&... extras) {
  94. if constexpr(!std::is_member_object_pointer_v<MP>) {
  95. static_assert(std::is_member_object_pointer_v<MP>,
  96. "def_readonly only supports pointer to data member");
  97. } else {
  98. bind_property(*this, name, mp, nullptr, extras...);
  99. }
  100. return *this;
  101. }
  102. template <typename Getter, typename Setter, typename... Extras>
  103. class_& def_property(const char* name, Getter&& g, Setter&& s, const Extras&... extras) {
  104. bind_property(*this, name, std::forward<Getter>(g), std::forward<Setter>(s), extras...);
  105. return *this;
  106. }
  107. template <typename Getter, typename... Extras>
  108. class_& def_property_readonly(const char* name, Getter&& mp, const Extras&... extras) {
  109. bind_property(*this, name, std::forward<Getter>(mp), nullptr, extras...);
  110. return *this;
  111. }
  112. template <typename Var, typename... Extras>
  113. class_& def_readwrite_static(const char* name, Var& mp, const Extras&... extras) {
  114. static_assert(
  115. dependent_false<Var>,
  116. "define static properties requires metaclass. This is a complex feature with few use cases, so it may never be implemented.");
  117. return *this;
  118. }
  119. template <typename Var, typename... Extras>
  120. class_& def_readonly_static(const char* name, Var& mp, const Extras&... extras) {
  121. static_assert(
  122. dependent_false<Var>,
  123. "define static properties requires metaclass. This is a complex feature with few use cases, so it may never be implemented.");
  124. return *this;
  125. }
  126. template <typename Getter, typename Setter, typename... Extras>
  127. class_&
  128. def_property_static(const char* name, Getter&& g, Setter&& s, const Extras&... extras) {
  129. static_assert(
  130. dependent_false<Getter>,
  131. "define static properties requires metaclass. This is a complex feature with few use cases, so it may never be implemented.");
  132. return *this;
  133. }
  134. };
  135. template <typename T, typename... Others>
  136. class enum_ : public class_<T, Others...> {
  137. std::map<const char*, pkpy::PyVar> m_values;
  138. public:
  139. using class_<T, Others...>::class_;
  140. template <typename... Args>
  141. enum_(const handle& scope, const char* name, Args&&... args) :
  142. class_<T, Others...>(scope, name, std::forward<Args>(args)...) {}
  143. enum_& value(const char* name, T value) {
  144. handle var = type_caster<T>::cast(value, return_value_policy::copy);
  145. this->m_ptr->attr().set(name, var.ptr());
  146. m_values[name] = var.ptr();
  147. return *this;
  148. }
  149. enum_& export_values() {
  150. pkpy::PyVar mod = this->m_ptr->attr("__module__");
  151. for(auto& [name, value]: m_values) {
  152. mod->attr().set(name, value);
  153. }
  154. return *this;
  155. }
  156. };
  157. } // namespace pybind11