blueloveTH преди 2 години
родител
ревизия
f076ee431f
променени са 1 файла, в които са добавени 18 реда и са изтрити 2 реда
  1. 18 2
      include/pocketpy/vm.h

+ 18 - 2
include/pocketpy/vm.h

@@ -451,6 +451,13 @@ public:
     }
 };
 
+
+template<typename T>
+inline constexpr bool is_immutable_v = std::is_integral_v<T> || std::is_floating_point_v<T>
+    || std::is_same_v<T, Str> || std::is_same_v<T, Tuple> || std::is_same_v<T, Bytes> || std::is_same_v<T, bool>
+    || std::is_same_v<T, Range> || std::is_same_v<T, Slice>
+    || std::is_pointer_v<T> || std::is_enum_v<T>;
+
 constexpr std::pair<const std::type_info*, Type> _const_cxx_typeid_map[] = {
     {&typeid(Str), VM::tp_str},
     {&typeid(List), VM::tp_list},
@@ -518,8 +525,10 @@ PyObject* py_var(VM* vm, __T&& value){
 
 template<typename __T, bool with_check>
 __T _py_cast__internal(VM* vm, PyObject* obj) {
-    using T = std::decay_t<__T>;
+    static_assert(!std::is_rvalue_reference_v<__T>, "rvalue reference is not allowed");
 
+    using T = std::decay_t<__T>;
+    
     if constexpr(std::is_same_v<T, const char*> || std::is_same_v<T, CString>){
         static_assert(!std::is_reference_v<__T>);
         // str (shortcuts)
@@ -563,7 +572,14 @@ __T _py_cast__internal(VM* vm, PyObject* obj) {
     }else{
         constexpr Type const_type = _find_type_in_const_cxx_typeid_map<T>();
         if constexpr(const_type.index >= 0){
-            if constexpr(with_check) vm->check_non_tagged_type(obj, const_type);
+            if constexpr(with_check){
+                if constexpr(std::is_same_v<T, Exception>){
+                    // Exception is `subclass_enabled`
+                    vm->check_compatible_type(obj, const_type);
+                }else{
+                    vm->check_non_tagged_type(obj, const_type);
+                }
+            }
             return PK_OBJ_GET(T, obj);
         }
     }