mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
remove any
This commit is contained in:
parent
6167cb4a43
commit
3d72ca0cc6
14
build_g.sh
14
build_g.sh
@ -2,9 +2,17 @@ python prebuild.py
|
|||||||
|
|
||||||
SRC_C=$(find src/ -name "*.c")
|
SRC_C=$(find src/ -name "*.c")
|
||||||
SRC_CPP=$(find src/ -name "*.cpp")
|
SRC_CPP=$(find src/ -name "*.cpp")
|
||||||
SRC="$SRC_C $SRC_CPP"
|
|
||||||
|
|
||||||
FLAGS="-std=c++17 -O0 -stdlib=libc++ -Iinclude -frtti -Wfatal-errors -g -DDEBUG -DPK_ENABLE_OS=1"
|
COMMON_FLAGS="-Iinclude -O0 -Wfatal-errors -g -DDEBUG -DPK_ENABLE_OS=1"
|
||||||
|
|
||||||
clang++ $FLAGS -o main src2/main.cpp $SRC
|
FLAGS_C="-std=c11 $COMMON_FLAGS"
|
||||||
|
FLAGS_CPP="-std=c++17 -stdlib=libc++ -frtti $COMMON_FLAGS"
|
||||||
|
|
||||||
|
echo "Compiling C files..."
|
||||||
|
clang $FLAGS_C -c $SRC_C
|
||||||
|
ar rcs libpocketpy_c.a *.o
|
||||||
|
rm *.o
|
||||||
|
|
||||||
|
echo "Compiling C++ files..."
|
||||||
|
clang++ $FLAGS_CPP -o main src2/main.cpp $SRC_CPP libpocketpy_c.a
|
||||||
|
rm libpocketpy_c.a
|
||||||
|
33
include/pocketpy/common/any.h
Normal file
33
include/pocketpy/common/any.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct c11_userdata{
|
||||||
|
void* _0;
|
||||||
|
void* _1;
|
||||||
|
} c11_userdata;
|
||||||
|
|
||||||
|
void c11_userdata__ctor(c11_userdata* self, void* ptr, int size);
|
||||||
|
#define c11_userdata__as(T, self) (*( (T*)(self) ))
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace pkpy{
|
||||||
|
struct any: c11_userdata{
|
||||||
|
template<typename T>
|
||||||
|
any(T value){
|
||||||
|
c11_userdata__ctor(this, &value, sizeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
any(){ }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T as(){
|
||||||
|
return c11_userdata__as(T, this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace pkpy
|
||||||
|
#endif
|
@ -1,113 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "pocketpy/common/traits.hpp"
|
|
||||||
|
|
||||||
#include <typeindex>
|
|
||||||
#include <cassert>
|
|
||||||
#include <utility>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
namespace pkpy {
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
constexpr inline bool is_any_sso_v = is_pod_v<T> && sizeof(T) <= sizeof(void*);
|
|
||||||
|
|
||||||
struct any {
|
|
||||||
struct vtable {
|
|
||||||
const std::type_index type;
|
|
||||||
void (*deleter)(void*);
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline static vtable* get() {
|
|
||||||
static_assert(std::is_same_v<T, std::decay_t<T>>);
|
|
||||||
if constexpr(is_any_sso_v<T>) {
|
|
||||||
static vtable vt{typeid(T), nullptr};
|
|
||||||
return &vt;
|
|
||||||
} else {
|
|
||||||
static vtable vt{typeid(T), [](void* ptr) {
|
|
||||||
delete static_cast<T*>(ptr);
|
|
||||||
}};
|
|
||||||
return &vt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void* data;
|
|
||||||
vtable* _vt;
|
|
||||||
|
|
||||||
any() : data(nullptr), _vt(nullptr) {}
|
|
||||||
|
|
||||||
explicit operator bool () const { return _vt != nullptr; }
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
any(T&& value) {
|
|
||||||
using U = std::decay_t<T>;
|
|
||||||
static_assert(!std::is_same_v<U, any>, "any(const any&) is deleted");
|
|
||||||
static_assert(sizeof(U) == sizeof(T));
|
|
||||||
if constexpr(is_any_sso_v<U>) {
|
|
||||||
std::memcpy(&data, &value, sizeof(U));
|
|
||||||
} else {
|
|
||||||
data = new U(std::forward<T>(value));
|
|
||||||
}
|
|
||||||
_vt = vtable::get<U>();
|
|
||||||
}
|
|
||||||
|
|
||||||
any(any&& other) noexcept;
|
|
||||||
any& operator= (any&& other) noexcept;
|
|
||||||
|
|
||||||
const std::type_index type_id() const { return _vt ? _vt->type : typeid(void); }
|
|
||||||
|
|
||||||
any(const any& other) = delete;
|
|
||||||
any& operator= (const any& other) = delete;
|
|
||||||
|
|
||||||
~any() {
|
|
||||||
if(_vt && _vt->deleter) _vt->deleter(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T& _cast() const noexcept {
|
|
||||||
static_assert(std::is_same_v<T, std::decay_t<T>>);
|
|
||||||
if constexpr(is_any_sso_v<T>) {
|
|
||||||
return *((T*)(&data));
|
|
||||||
} else {
|
|
||||||
return *(static_cast<T*>(data));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct function;
|
|
||||||
|
|
||||||
template <typename Ret, typename... Params>
|
|
||||||
struct function<Ret(Params...)> {
|
|
||||||
any _impl;
|
|
||||||
Ret (*_wrapper)(const any&, Params...);
|
|
||||||
|
|
||||||
function() : _impl(), _wrapper(nullptr) {}
|
|
||||||
|
|
||||||
explicit operator bool () const { return _wrapper != nullptr; }
|
|
||||||
|
|
||||||
template <typename F>
|
|
||||||
function(F&& f) : _impl(std::forward<F>(f)) {
|
|
||||||
_wrapper = [](const any& impl, Params... params) -> Ret {
|
|
||||||
return impl._cast<std::decay_t<F>>()(std::forward<Params>(params)...);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
Ret operator() (Params... params) const {
|
|
||||||
assert(_wrapper);
|
|
||||||
return _wrapper(_impl, std::forward<Params>(params)...);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace pkpy
|
|
@ -9,6 +9,8 @@
|
|||||||
#include "pocketpy/interpreter/frame.hpp"
|
#include "pocketpy/interpreter/frame.hpp"
|
||||||
#include "pocketpy/interpreter/profiler.hpp"
|
#include "pocketpy/interpreter/profiler.hpp"
|
||||||
|
|
||||||
|
#include <typeindex>
|
||||||
|
|
||||||
namespace pkpy {
|
namespace pkpy {
|
||||||
|
|
||||||
/* Stack manipulation macros */
|
/* Stack manipulation macros */
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "pocketpy/common/any.hpp"
|
#include "pocketpy/common/any.h"
|
||||||
#include "pocketpy/objects/tuplelist.hpp"
|
#include "pocketpy/objects/tuplelist.hpp"
|
||||||
#include "pocketpy/objects/namedict.hpp"
|
#include "pocketpy/objects/namedict.hpp"
|
||||||
#include "pocketpy/objects/sourcedata.hpp"
|
#include "pocketpy/objects/sourcedata.hpp"
|
||||||
@ -171,10 +171,12 @@ struct Function {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T& lambda_get_userdata(PyVar* p) {
|
T lambda_get_userdata(PyVar* p) {
|
||||||
static_assert(std::is_same_v<T, std::decay_t<T>>);
|
static_assert(std::is_same_v<T, std::decay_t<T>>);
|
||||||
|
static_assert(is_pod_v<T>);
|
||||||
int offset = p[-1] != nullptr ? -1 : -2;
|
int offset = p[-1] != nullptr ? -1 : -2;
|
||||||
return p[offset].obj_get<NativeFunc>()._userdata.cast<T>();
|
NativeFunc& nf = p[offset].obj_get<NativeFunc>();
|
||||||
|
return nf._userdata.as<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace pkpy
|
} // namespace pkpy
|
||||||
|
7
src/common/any.c
Normal file
7
src/common/any.c
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#include "pocketpy/common/any.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
void c11_userdata__ctor(c11_userdata* self, void* ptr, int size){
|
||||||
|
memcpy(self, ptr, size);
|
||||||
|
}
|
@ -1,26 +0,0 @@
|
|||||||
#include "pocketpy/common/any.hpp"
|
|
||||||
#include "pocketpy/common/utils.h"
|
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
|
|
||||||
namespace pkpy {
|
|
||||||
|
|
||||||
void any::__bad_any_cast(const std::type_index expected, const std::type_index actual) {
|
|
||||||
PK_FATAL_ERROR("bad_any_cast: expected %s, got %s\n", expected.name(), actual.name())
|
|
||||||
}
|
|
||||||
|
|
||||||
any::any(any&& other) noexcept : data(other.data), _vt(other._vt) {
|
|
||||||
other.data = nullptr;
|
|
||||||
other._vt = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
any& any::operator= (any&& other) noexcept {
|
|
||||||
if(data) _vt->deleter(data);
|
|
||||||
data = other.data;
|
|
||||||
_vt = other._vt;
|
|
||||||
other.data = nullptr;
|
|
||||||
other._vt = nullptr;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace pkpy
|
|
Loading…
x
Reference in New Issue
Block a user