change any APIs

This commit is contained in:
blueloveTH 2024-05-08 20:34:51 +08:00
parent 1003f3a6df
commit 182177482f
4 changed files with 28 additions and 24 deletions

View File

@ -6,7 +6,7 @@ with open("include/pocketpy/opcodes.h", "rt", encoding='utf-8') as f:
OPCODES_TEXT = '\n' + f.read() + '\n'
pipeline = [
["config.h", "export.h", "_generated.h", "common.h", "memory.h", "any.h", "vector.h", "str.h", "tuplelist.h", "namedict.h", "error.h"],
["config.h", "export.h", "_generated.h", "common.h", "memory.h", "vector.h", "str.h", "tuplelist.h", "namedict.h", "error.h", "any.h"],
["obj.h", "dict.h", "codeobject.h", "frame.h", "profiler.h"],
["gc.h", "vm.h", "ceval.h", "lexer.h", "expr.h", "compiler.h", "repl.h"],
["cffi.h", "bindings.h", "iter.h", "base64.h", "csv.h", "collections.h", "array2d.h", "dataclasses.h", "random.h", "linalg.h", "easing.h", "io.h", "modules.h"],

View File

@ -1,6 +1,7 @@
#pragma once
#include "common.h"
#include "str.h"
namespace pkpy {
@ -52,18 +53,25 @@ struct any{
any& operator=(const any& other) = delete;
~any() { if(data) _vt->deleter(data); }
};
template<typename T>
bool any_cast(const any& a, T** out){
T& _cast() const noexcept{
static_assert(std::is_same_v<T, std::decay_t<T>>);
if(a.type_id() != typeid(T)) return false;
if constexpr (is_sso_v<T>){
*out = (T*)(&a.data);
return *((T*)(&data));
}else{
*out = static_cast<T*>(a.data);
return *(static_cast<T*>(data));
}
return true;
}
template<typename T>
T& cast() const{
static_assert(std::is_same_v<T, std::decay_t<T>>);
if(type_id() != typeid(T)) __bad_any_cast(typeid(T), type_id());
return _cast<T>();
}
static void __bad_any_cast(const std::type_index expected, const std::type_index actual);
};
} // namespace pkpy

View File

@ -186,17 +186,8 @@ struct Py_<NativeFunc> final: PyObject {
template<typename T>
T& lambda_get_userdata(PyObject** p){
static_assert(std::is_same_v<T, std::decay_t<T>>);
any* ud;
if(p[-1] != PY_NULL) ud = &PK_OBJ_GET(NativeFunc, p[-1])._userdata;
else ud = &PK_OBJ_GET(NativeFunc, p[-2])._userdata;
T* out;
if(!any_cast(*ud, &out)){
const char* expected = typeid(T).name();
const char* actual = ud->type_id().name();
Str error = _S("lambda_get_userdata: any_cast failed: expected ", expected, ", got ", actual);
throw std::runtime_error(error.c_str());
}
return *out;
int offset = p[-1] != PY_NULL ? -1 : -2;
return PK_OBJ_GET(NativeFunc, p[offset])._userdata.cast<T>();
}
} // namespace pkpy

View File

@ -2,6 +2,11 @@
namespace pkpy{
void any::__bad_any_cast(const std::type_index expected, const std::type_index actual){
Str error = _S("bad_any_cast: expected ", expected.name(), ", got ", actual.name());
throw std::runtime_error(error.c_str());
}
any::any(any&& other) noexcept: data(other.data), _vt(other._vt){
other.data = nullptr;
other._vt = nullptr;