class.h 6.1 KB

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