blueloveTH пре 1 година
родитељ
комит
d3fd70a98d

+ 37 - 36
include/pocketpy/bindings.h

@@ -123,43 +123,44 @@ template<typename Ret, typename T, typename... Params>
     return vm->bind(obj, sig, func);
 }
 /*****************************************************************/
-#define PY_FIELD(T, NAME, EXPR)       \
+
+#define PY_FIELD(T, NAME, EXPR)                     \
         vm->bind_property(type, NAME,               \
             [](VM* vm, ArgsView args){              \
-                T& self = PK_OBJ_GET(T, args[0]);   \
-                return VAR(self.EXPR);       \
+                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]);   \
-                self.EXPR = CAST(decltype(self.EXPR), args[1]);       \
+                obj_get_t<T> self = PK_OBJ_GET(T, args[0]); \
+                self.EXPR = CAST(decltype(self.EXPR), args[1]);                     \
                 return vm->None;                                                    \
             });
 
-#define PY_READONLY_FIELD(T, NAME, EXPR)            \
+#define PY_READONLY_FIELD(T, NAME, EXPR)                    \
         vm->bind_property(type, NAME,                       \
             [](VM* vm, ArgsView args){                      \
-                T& self = PK_OBJ_GET(T, args[0]);           \
-                return VAR(self.EXPR);               \
+                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]);       \
-                return VAR(self.FGET());         \
-            },                                          \
-            [](VM* vm, ArgsView args){                  \
-                T& self = _CAST(T&, args[0]);           \
-                using __NT = decltype(self.FGET());   \
-                self.FSET(CAST(__NT, args[1]));       \
+#define PY_PROPERTY(T, NAME, FGET, FSET)                    \
+        vm->bind_property(type, NAME,                       \
+            [](VM* vm, ArgsView args){                      \
+                obj_get_t<T> self = PK_OBJ_GET(T, args[0]); \
+                return VAR(self.FGET());                    \
+            },                                              \
+            [](VM* vm, ArgsView args){                      \
+                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;                            \
             });
 
-#define PY_READONLY_PROPERTY(T, NAME, FGET)  \
-        vm->bind_property(type, NAME,                   \
-            [](VM* vm, ArgsView args){                  \
-                T& self = PK_OBJ_GET(T, args[0]);       \
-                return VAR(self.FGET());                \
+#define PY_READONLY_PROPERTY(T, NAME, FGET)                 \
+        vm->bind_property(type, NAME,                       \
+            [](VM* vm, ArgsView args){                      \
+                obj_get_t<T> self = PK_OBJ_GET(T, args[0]); \
+                return VAR(self.FGET());                    \
             });
 /*****************************************************************/
 #define PY_STRUCT_LIKE(wT)   \
@@ -173,22 +174,22 @@ template<typename Ret, typename T, typename... Params>
             memcpy(&_CAST(wT&, obj), s.p, sizeof(wT));                              \
             return obj;                                                             \
         }, {}, BindType::STATICMETHOD);                                             \
-        vm->bind_func(type, "tostruct", 1, [](VM* vm, ArgsView args){             \
+        vm->bind_func(type, "tostruct", 1, [](VM* vm, ArgsView args){               \
             wT& self = _CAST(wT&, args[0]);                                         \
             return vm->new_user_object<Struct>(&self, sizeof(wT));                  \
         });                                                                         \
-        vm->bind_func(type, "addr", 1, [](VM* vm, ArgsView args){                 \
+        vm->bind_func(type, "addr", 1, [](VM* vm, ArgsView args){                   \
             wT& self = _CAST(wT&, args[0]);                                         \
             return vm->new_user_object<VoidP>(&self);                               \
         });                                                                         \
-        vm->bind_func(type, "copy", 1, [](VM* vm, ArgsView args){                 \
+        vm->bind_func(type, "copy", 1, [](VM* vm, ArgsView args){                   \
             wT& self = _CAST(wT&, args[0]);                                         \
             return vm->new_user_object<wT>(self);                                   \
         });                                                                         \
-        vm->bind_func(type, "sizeof", 1, [](VM* vm, ArgsView args){               \
+        vm->bind_func(type, "sizeof", 1, [](VM* vm, ArgsView args){                 \
             return VAR(sizeof(wT));                                                 \
         });                                                                         \
-        vm->bind__eq__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar _0, PyVar _1){  \
+        vm->bind__eq__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar _0, PyVar _1){      \
             wT& self = _CAST(wT&, _0);                                              \
             if(!vm->isinstance(_1, vm->_tp_user<wT>())) return vm->NotImplemented;  \
             wT& other = _CAST(wT&, _1);                                             \
@@ -196,17 +197,17 @@ template<typename Ret, typename T, typename... Params>
         });                                                                         \
 
 #define PY_POINTER_SETGETITEM(T) \
-        vm->bind__getitem__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar _0, PyVar _1){  \
-            VoidP& self = PK_OBJ_GET(VoidP, _0);                                       \
+        vm->bind__getitem__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar _0, PyVar _1){     \
+            VoidP& self = PK_OBJ_GET(VoidP, _0);                                        \
             i64 i = CAST(i64, _1);                                                      \
             T* tgt = reinterpret_cast<T*>(self.ptr);                                    \
             return VAR(tgt[i]);                                                         \
         });                                                                             \
-        vm->bind__setitem__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar _0, PyVar _1, PyVar _2){  \
-            VoidP& self = PK_OBJ_GET(VoidP, _0);                                       \
-            i64 i = CAST(i64, _1);                                                      \
-            T* tgt = reinterpret_cast<T*>(self.ptr);                                    \
-            tgt[i] = CAST(T, _2);                                                       \
-        });                                                                         \
+        vm->bind__setitem__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar _0, PyVar _1, PyVar _2){   \
+            VoidP& self = PK_OBJ_GET(VoidP, _0);                                                \
+            i64 i = CAST(i64, _1);                                                              \
+            T* tgt = reinterpret_cast<T*>(self.ptr);                                            \
+            tgt[i] = CAST(T, _2);                                                               \
+        });                                                                                     \
 
 }   // namespace pkpy

+ 11 - 8
include/pocketpy/common.h

@@ -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
 
 

+ 9 - 5
include/pocketpy/obj.h

@@ -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,11 +166,14 @@ 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>();
-    return ((Py_<T>*)(get()))->_value;
+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>()

+ 1 - 1
include/pocketpy/tuplelist.h

@@ -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;

+ 4 - 2
include/pocketpy/vm.h

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

+ 0 - 2
src/linalg.cpp

@@ -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);                                                      \