This commit is contained in:
blueloveTH 2024-05-13 23:34:05 +08:00
parent 979364f274
commit d3fd70a98d
6 changed files with 62 additions and 54 deletions

View File

@ -123,14 +123,15 @@ template<typename Ret, typename T, typename... Params>
return vm->bind(obj, sig, func);
}
/*****************************************************************/
#define PY_FIELD(T, NAME, EXPR) \
vm->bind_property(type, NAME, \
[](VM* vm, ArgsView args){ \
T& self = PK_OBJ_GET(T, args[0]); \
obj_get_t<T> self = PK_OBJ_GET(T, args[0]); \
return VAR(self.EXPR); \
}, \
[](VM* vm, ArgsView args){ \
T& self = PK_OBJ_GET(T, args[0]); \
obj_get_t<T> self = PK_OBJ_GET(T, args[0]); \
self.EXPR = CAST(decltype(self.EXPR), args[1]); \
return vm->None; \
});
@ -138,18 +139,18 @@ template<typename Ret, typename T, typename... Params>
#define PY_READONLY_FIELD(T, NAME, EXPR) \
vm->bind_property(type, NAME, \
[](VM* vm, ArgsView args){ \
T& self = PK_OBJ_GET(T, args[0]); \
obj_get_t<T> self = PK_OBJ_GET(T, args[0]); \
return VAR(self.EXPR); \
});
#define PY_PROPERTY(T, NAME, FGET, FSET) \
vm->bind_property(type, NAME, \
[](VM* vm, ArgsView args){ \
T& self = PK_OBJ_GET(T, args[0]); \
obj_get_t<T> self = PK_OBJ_GET(T, args[0]); \
return VAR(self.FGET()); \
}, \
[](VM* vm, ArgsView args){ \
T& self = _CAST(T&, args[0]); \
obj_get_t<T> self = PK_OBJ_GET(T, args[0]); \
using __NT = decltype(self.FGET()); \
self.FSET(CAST(__NT, args[1])); \
return vm->None; \
@ -158,7 +159,7 @@ template<typename Ret, typename T, typename... Params>
#define PY_READONLY_PROPERTY(T, NAME, FGET) \
vm->bind_property(type, NAME, \
[](VM* vm, ArgsView args){ \
T& self = PK_OBJ_GET(T, args[0]); \
obj_get_t<T> self = PK_OBJ_GET(T, args[0]); \
return VAR(self.FGET()); \
});
/*****************************************************************/

View File

@ -166,7 +166,16 @@ inline constexpr bool is_floating_point_v = std::is_same_v<T, float> || std::is_
inline const char* PK_HEX_TABLE = "0123456789abcdef";
struct PyObject;
// using PyVar = PyObject *;
// by default, only `int` and `float` enable SSO
// users can specialize this template to enable SSO for other types
// SSO types cannot have instance dict
template<typename T>
inline constexpr bool is_sso_v = is_integral_v<T> || is_floating_point_v<T>;
// make a obj_get_t<T> for a given type T, if is_sso_v<T> is true, return T, else return T&
template<typename T>
using obj_get_t = std::conditional_t<is_sso_v<T>, T, T&>;
struct PyVar final{
Type type;
@ -224,17 +233,11 @@ struct PyVar final{
i64 hash() const { return _1; }
template<typename T>
T& obj_get();
obj_get_t<T> obj_get();
};
static_assert(sizeof(PyVar) == 16 && is_pod_v<PyVar>);
// by default, only `int` and `float` enable SSO
// users can specialize this template to enable SSO for other types
// SSO types cannot have instance dict
template<typename T>
inline constexpr bool is_sso_v = is_integral_v<T> || is_floating_point_v<T>;
} // namespace pkpy

View File

@ -141,7 +141,8 @@ template <typename T> struct has_gc_marker<T, std::void_t<decltype(&T::_gc_mark)
template <typename T>
struct Py_ final: PyObject {
static_assert(!std::is_reference_v<T>, "T must not be a reference type. Are you using `PK_OBJ_GET(T&, ...)`?");
static_assert(!std::is_reference_v<T>);
static_assert(!is_sso_v<T>);
T _value;
void _obj_gc_mark() override {
@ -165,12 +166,15 @@ StrName _type_name(VM* vm, Type type);
template<typename T> T to_void_p(VM*, PyVar);
PyVar from_void_p(VM*, void*);
template<typename T>
T& PyVar::obj_get(){
static_assert(!std::is_reference_v<T>);
if(is_sso) return as<T>();
obj_get_t<T> PyVar::obj_get(){
if constexpr(is_sso_v<T>){
return as<T>();
}else{
return ((Py_<T>*)(get()))->_value;
}
}
#define PK_OBJ_GET(T, obj) (obj).obj_get<T>()

View File

@ -49,7 +49,7 @@ struct ArgsView{
PyVar* end() const { return _end; }
int size() const { return _end - _begin; }
bool empty() const { return _begin == _end; }
PyVar& operator[](int i) const { return _begin[i]; }
PyVar operator[](int i) const { return _begin[i]; }
List to_list() const;
Tuple to_tuple() const;

View File

@ -562,8 +562,10 @@ __T _py_cast__internal(VM* vm, PyVar obj) {
return PK_OBJ_GET(T, obj);
}
}
if constexpr(with_check){
Type type = vm->_find_type_in_cxx_typeid_map<T>();
if constexpr(with_check) vm->check_compatible_type(obj, type);
vm->check_compatible_type(obj, type);
}
return PK_OBJ_GET(T, obj);
}

View File

@ -34,8 +34,6 @@ namespace pkpy{
Vec##D self = _CAST(Vec##D, _0); \
if(vm->is_user_type<Vec##D>(_1)){ \
Vec##D other = _CAST(Vec##D, _1); \
std::cout << self.x << ',' << self.y << '\n';\
std::cout << other.x << ',' << other.y << '\n';\
return VAR(self * other); \
} \
f64 other = CAST(f64, _1); \