builtins.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #pragma once
  2. #include "types.h"
  3. namespace pybind11 {
  4. inline void exec(const char* code, handle global = {}, handle local = {}) {
  5. vm->py_exec(code, global.ptr(), local.ptr());
  6. }
  7. // wrapper for builtin functions in Python
  8. inline bool hasattr(const handle& obj, const handle& name) {
  9. auto& key = _builtin_cast<pkpy::Str>(name);
  10. return vm->getattr(obj.ptr(), key, false) != nullptr;
  11. }
  12. inline bool hasattr(const handle& obj, const char* name) {
  13. return vm->getattr(obj.ptr(), name, false) != nullptr;
  14. }
  15. inline void delattr(const handle& obj, const handle& name) {
  16. auto& key = _builtin_cast<pkpy::Str>(name);
  17. vm->delattr(obj.ptr(), key);
  18. }
  19. inline void delattr(const handle& obj, const char* name) { vm->delattr(obj.ptr(), name); }
  20. inline object getattr(const handle& obj, const handle& name) {
  21. auto& key = _builtin_cast<pkpy::Str>(name);
  22. return reinterpret_borrow<object>(vm->getattr(obj.ptr(), key));
  23. }
  24. inline object getattr(const handle& obj, const char* name) {
  25. return reinterpret_borrow<object>(vm->getattr(obj.ptr(), name));
  26. }
  27. inline object getattr(const handle& obj, const handle& name, const handle& default_) {
  28. if(!hasattr(obj, name)) {
  29. return reinterpret_borrow<object>(default_);
  30. }
  31. return getattr(obj, name);
  32. }
  33. inline object getattr(const handle& obj, const char* name, const handle& default_) {
  34. if(!hasattr(obj, name)) {
  35. return reinterpret_borrow<object>(default_);
  36. }
  37. return getattr(obj, name);
  38. }
  39. inline void setattr(const handle& obj, const handle& name, const handle& value) {
  40. auto& key = _builtin_cast<pkpy::Str>(name);
  41. vm->setattr(obj.ptr(), key, value.ptr());
  42. }
  43. inline void setattr(const handle& obj, const char* name, const handle& value) {
  44. vm->setattr(obj.ptr(), name, value.ptr());
  45. }
  46. template <typename T>
  47. inline bool isinstance(const handle& obj) {
  48. pkpy::Type cls = _builtin_cast<pkpy::Type>(type::handle_of<T>().ptr());
  49. return vm->isinstance(obj.ptr(), cls);
  50. }
  51. template <>
  52. inline bool isinstance<handle>(const handle&) = delete;
  53. template <>
  54. inline bool isinstance<iterable>(const handle& obj) {
  55. return hasattr(obj, "__iter__");
  56. }
  57. template <>
  58. inline bool isinstance<iterator>(const handle& obj) {
  59. return hasattr(obj, "__iter__") && hasattr(obj, "__next__");
  60. }
  61. inline bool isinstance(const handle& obj, const handle& type) {
  62. return vm->isinstance(obj.ptr(), _builtin_cast<pkpy::Type>(type));
  63. }
  64. inline int64_t hash(const handle& obj) { return vm->py_hash(obj.ptr()); }
  65. template <typename T, typename SFINAE = void>
  66. struct type_caster;
  67. template <typename T>
  68. handle _cast(T&& value,
  69. return_value_policy policy = return_value_policy::automatic_reference,
  70. handle parent = handle()) {
  71. using U = std::remove_pointer_t<std::remove_cv_t<std::remove_reference_t<T>>>;
  72. return type_caster<U>::cast(std::forward<T>(value), policy, parent);
  73. }
  74. template <typename T>
  75. object cast(T&& value,
  76. return_value_policy policy = return_value_policy::automatic_reference,
  77. handle parent = handle()) {
  78. return reinterpret_borrow<object>(_cast(std::forward<T>(value), policy, parent));
  79. }
  80. template <typename T>
  81. T cast(handle obj, bool convert = false) {
  82. using Caster =
  83. type_caster<std::remove_pointer_t<std::remove_cv_t<std::remove_reference_t<T>>>>;
  84. Caster caster;
  85. if(caster.load(obj, convert)) {
  86. if constexpr(std::is_rvalue_reference_v<T>) {
  87. return std::move(caster.value);
  88. } else {
  89. return caster.value;
  90. }
  91. }
  92. throw std::runtime_error("Unable to cast Python instance to C++ type");
  93. }
  94. } // namespace pybind11