include/wrenbind17/caller.hpp #
Namespaces #
Name |
---|
wrenbind17 |
Source code #
#pragma once
#include <wren.hpp>
#include <memory>
#include "index.hpp"
#include "pop.hpp"
#include "push.hpp"
namespace wrenbind17 {
#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace detail {
template <typename R> struct ForeginMethodReturnHelper {
static inline void push(WrenVM* vm, int index, R ret) {
PushHelper<R>::f(vm, index, ret);
}
};
template <typename R> struct ForeginMethodReturnHelper<R&> {
static inline void push(WrenVM* vm, int index, R& ret) {
PushHelper<R*>::f(vm, index, &ret);
}
};
template <typename R> struct ForeginMethodReturnHelper<const R&> {
static inline void push(WrenVM* vm, int index, const R& ret) {
PushHelper<R*>::f(vm, index, &const_cast<R&>(ret));
}
};
template <typename R> struct ForeginMethodReturnHelper<R*> {
static inline void push(WrenVM* vm, int index, R* ret) {
PushHelper<R*>::f(vm, index, ret);
}
};
template <typename R> struct ForeginMethodReturnHelper<const R*> {
static inline void push(WrenVM* vm, int index, const R* ret) {
PushHelper<const R*>::f(vm, index, ret);
}
};
template <typename R> struct ForeginMethodReturnHelper<R&&> {
static inline void push(WrenVM* vm, int index, R&& ret) {
PushHelper<R>::f(vm, index, std::move(ret));
}
};
template <typename R> struct ForeginMethodReturnHelper<const std::shared_ptr<R>&> {
static inline void push(WrenVM* vm, int index, const std::shared_ptr<R>& ret) {
PushHelper<const std::shared_ptr<R>&>::f(vm, index, ret);
}
};
template <typename R> struct ForeginMethodReturnHelper<std::shared_ptr<R>&> {
static inline void push(WrenVM* vm, int index, std::shared_ptr<R>& ret) {
PushHelper<std::shared_ptr<R>&>::f(vm, index, ret);
}
};
template <typename R> struct ForeginMethodReturnHelper<const std::variant<R>&> {
static inline void push(WrenVM* vm, int index, const std::variant<R>& ret) {
PushHelper<const std::variant<R>&>::f(vm, index, ret);
}
};
template <typename R> struct ForeginMethodReturnHelper<std::variant<R>&> {
static inline void push(WrenVM* vm, int index, std::variant<R>& ret) {
PushHelper<std::variant<R>&>::f(vm, index, ret);
}
};
template <>
inline void ForeginMethodReturnHelper<const std::string&>::push(WrenVM* vm, int index, const std::string& ret) {
PushHelper<const std::string&>::f(vm, index, ret);
}
template <> inline void ForeginMethodReturnHelper<std::string&>::push(WrenVM* vm, int index, std::string& ret) {
PushHelper<std::string&>::f(vm, index, ret);
}
template <typename R, typename T, typename... Args> struct ForeignMethodCaller {
template <R (T::*Fn)(Args...), size_t... Is> static void callFrom(WrenVM* vm, detail::index_list<Is...>) {
auto self = PopHelper<T*>::f(vm, 0);
// R ret = (self->*Fn)(PopHelper<typename std::remove_const<Args>::type>::f(vm, Is + 1)...);
// PushHelper<R>::f(vm, 0, ret);
ForeginMethodReturnHelper<R>::push(
vm, 0, (self->*Fn)(PopHelper<typename std::remove_const<Args>::type>::f(vm, Is + 1)...));
}
template <R (T::*Fn)(Args...)> static void call(WrenVM* vm) {
try {
callFrom<Fn>(vm, detail::index_range<0, sizeof...(Args)>());
} catch (...) {
exceptionHandler(vm, std::current_exception());
}
}
template <R (T::*Fn)(Args...) const, size_t... Is>
static void callFrom(WrenVM* vm, detail::index_list<Is...>) {
auto self = PopHelper<T*>::f(vm, 0);
// R ret = (self->*Fn)(PopHelper<typename std::remove_const<Args>::type>::f(vm, Is + 1)...);
// PushHelper<R>::f(vm, 0, ret);
ForeginMethodReturnHelper<R>::push(
vm, 0, (self->*Fn)(PopHelper<typename std::remove_const<Args>::type>::f(vm, Is + 1)...));
}
template <R (T::*Fn)(Args...) const> static void call(WrenVM* vm) {
try {
callFrom<Fn>(vm, detail::index_range<0, sizeof...(Args)>());
} catch (...) {
exceptionHandler(vm, std::current_exception());
}
}
};
template <typename T, typename... Args> struct ForeignMethodCaller<void, T, Args...> {
template <void (T::*Fn)(Args...), size_t... Is>
static void callFrom(WrenVM* vm, detail::index_list<Is...>) {
auto self = PopHelper<T*>::f(vm, 0);
(self->*Fn)(PopHelper<typename std::remove_const<Args>::type>::f(vm, Is + 1)...);
}
template <void (T::*Fn)(Args...)> static void call(WrenVM* vm) {
try {
callFrom<Fn>(vm, detail::index_range<0, sizeof...(Args)>());
} catch (...) {
exceptionHandler(vm, std::current_exception());
}
}
template <void (T::*Fn)(Args...) const, size_t... Is>
static void callFrom(WrenVM* vm, detail::index_list<Is...>) {
auto self = PopHelper<T*>::f(vm, 0);
(self->*Fn)(PopHelper<typename std::remove_const<Args>::type>::f(vm, Is + 1)...);
}
template <void (T::*Fn)(Args...) const> static void call(WrenVM* vm) {
try {
callFrom<Fn>(vm, detail::index_range<0, sizeof...(Args)>());
} catch (...) {
exceptionHandler(vm, std::current_exception());
}
}
};
template <typename R, typename T, typename... Args> struct ForeignMethodExtCaller {
template <R (*Fn)(T&, Args...), size_t... Is> static void callFrom(WrenVM* vm, detail::index_list<Is...>) {
auto self = PopHelper<T*>::f(vm, 0);
// R ret = (*Fn)(*self, PopHelper<typename std::remove_const<Args>::type>::f(vm, Is + 1)...);
// PushHelper<R>::f(vm, 0, ret);
ForeginMethodReturnHelper<R>::push(
vm, 0, (*Fn)(*self, PopHelper<typename std::remove_const<Args>::type>::f(vm, Is + 1)...));
}
template <R (*Fn)(T&, Args...)> static void call(WrenVM* vm) {
try {
callFrom<Fn>(vm, detail::index_range<0, sizeof...(Args)>());
} catch (...) {
exceptionHandler(vm, std::current_exception());
}
}
};
template <typename T, typename... Args> struct ForeignMethodExtCaller<void, T, Args...> {
template <void (*Fn)(T&, Args...), size_t... Is>
static void callFrom(WrenVM* vm, detail::index_list<Is...>) {
auto self = PopHelper<T*>::f(vm, 0);
(*Fn)(*self, PopHelper<typename std::remove_const<Args>::type>::f(vm, Is + 1)...);
}
template <void (*Fn)(T&, Args...)> static void call(WrenVM* vm) {
try {
callFrom<Fn>(vm, detail::index_range<0, sizeof...(Args)>());
} catch (...) {
exceptionHandler(vm, std::current_exception());
}
}
};
template <typename R, typename... Args> struct ForeignFunctionCaller {
template <R (*Fn)(Args...), size_t... Is> static void callFrom(WrenVM* vm, detail::index_list<Is...>) {
// R ret = (*Fn)(PopHelper<typename std::remove_const<Args>::type>::f(vm, Is + 1)...);
// PushHelper<R>::f(vm, 0, ret);
ForeginMethodReturnHelper<R>::push(
vm, 0, (*Fn)(PopHelper<typename std::remove_const<Args>::type>::f(vm, Is + 1)...));
}
template <R (*Fn)(Args...)> static void call(WrenVM* vm) {
try {
callFrom<Fn>(vm, detail::index_range<0, sizeof...(Args)>());
} catch (...) {
exceptionHandler(vm, std::current_exception());
}
}
};
template <typename... Args> struct ForeignFunctionCaller<void, Args...> {
template <void (*Fn)(Args...), size_t... Is> static void callFrom(WrenVM* vm, detail::index_list<Is...>) {
(*Fn)(PopHelper<typename std::remove_const<Args>::type>::f(vm, Is + 1)...);
}
template <void (*Fn)(Args...)> static void call(WrenVM* vm) {
try {
callFrom<Fn>(vm, detail::index_range<0, sizeof...(Args)>());
} catch (...) {
exceptionHandler(vm, std::current_exception());
}
}
};
template <typename T, typename V, V T::*Ptr> struct ForeignPropCaller {
static void setter(WrenVM* vm) {
auto self = PopHelper<T*>::f(vm, 0);
self->*Ptr = PopHelper<V>::f(vm, 1);
}
static void getter(WrenVM* vm) {
auto self = PopHelper<T*>::f(vm, 0);
PushHelper<V*>::f(vm, 0, &(self->*Ptr));
}
};
} // namespace detail
#endif
} // namespace wrenbind17
Updated on 17 October 2023 at 12:26:25 UTC