2024-05-30 23:14:31 +08:00

118 lines
3.9 KiB
C++

#pragma once
#include "types.h"
namespace pybind11 {
inline void exec(const char* code, handle global = {}, handle local = {}) {
vm->py_exec(code, global.ptr(), local.ptr());
}
// wrapper for builtin functions in Python
inline bool hasattr(const handle& obj, const handle& name) {
auto& key = _builtin_cast<pkpy::Str>(name);
return vm->getattr(obj.ptr(), key, false) != nullptr;
}
inline bool hasattr(const handle& obj, const char* name) {
return vm->getattr(obj.ptr(), name, false) != nullptr;
}
inline void delattr(const handle& obj, const handle& name) {
auto& key = _builtin_cast<pkpy::Str>(name);
vm->delattr(obj.ptr(), key);
}
inline void delattr(const handle& obj, const char* name) { vm->delattr(obj.ptr(), name); }
inline object getattr(const handle& obj, const handle& name) {
auto& key = _builtin_cast<pkpy::Str>(name);
return reinterpret_borrow<object>(vm->getattr(obj.ptr(), key));
}
inline object getattr(const handle& obj, const char* name) {
return reinterpret_borrow<object>(vm->getattr(obj.ptr(), name));
}
inline object getattr(const handle& obj, const handle& name, const handle& default_) {
if(!hasattr(obj, name)) {
return reinterpret_borrow<object>(default_);
}
return getattr(obj, name);
}
inline object getattr(const handle& obj, const char* name, const handle& default_) {
if(!hasattr(obj, name)) {
return reinterpret_borrow<object>(default_);
}
return getattr(obj, name);
}
inline void setattr(const handle& obj, const handle& name, const handle& value) {
auto& key = _builtin_cast<pkpy::Str>(name);
vm->setattr(obj.ptr(), key, value.ptr());
}
inline void setattr(const handle& obj, const char* name, const handle& value) {
vm->setattr(obj.ptr(), name, value.ptr());
}
template <typename T>
inline bool isinstance(const handle& obj) {
pkpy::Type cls = _builtin_cast<pkpy::Type>(type::handle_of<T>().ptr());
return vm->isinstance(obj.ptr(), cls);
}
template <>
inline bool isinstance<handle>(const handle&) = delete;
template <>
inline bool isinstance<iterable>(const handle& obj) {
return hasattr(obj, "__iter__");
}
template <>
inline bool isinstance<iterator>(const handle& obj) {
return hasattr(obj, "__iter__") && hasattr(obj, "__next__");
}
inline bool isinstance(const handle& obj, const handle& type) {
return vm->isinstance(obj.ptr(), _builtin_cast<pkpy::Type>(type));
}
inline int64_t hash(const handle& obj) { return vm->py_hash(obj.ptr()); }
template <typename T, typename SFINAE = void>
struct type_caster;
template <typename T>
handle _cast(T&& value,
return_value_policy policy = return_value_policy::automatic_reference,
handle parent = handle()) {
using U = std::remove_pointer_t<std::remove_cv_t<std::remove_reference_t<T>>>;
return type_caster<U>::cast(std::forward<T>(value), policy, parent);
}
template <typename T>
object cast(T&& value,
return_value_policy policy = return_value_policy::automatic_reference,
handle parent = handle()) {
return reinterpret_borrow<object>(_cast(std::forward<T>(value), policy, parent));
}
template <typename T>
T cast(handle obj, bool convert = false) {
using Caster =
type_caster<std::remove_pointer_t<std::remove_cv_t<std::remove_reference_t<T>>>>;
Caster caster;
if(caster.load(obj, convert)) {
if constexpr(std::is_rvalue_reference_v<T>) {
return std::move(caster.value);
} else {
return caster.value;
}
}
throw std::runtime_error("Unable to cast Python instance to C++ type");
}
} // namespace pybind11