Add arbitrary method to foreign_method_t conversion helper
It might not work in every case, you still are restricted to types that set() and get() understand.
This commit is contained in:
parent
34d2317f11
commit
6a30725a62
3 changed files with 49 additions and 2 deletions
|
@ -31,6 +31,7 @@ namespace {
|
||||||
construct new() {}
|
construct new() {}
|
||||||
foreign static today()
|
foreign static today()
|
||||||
foreign add_appointment(desc)
|
foreign add_appointment(desc)
|
||||||
|
foreign appointment_count()
|
||||||
}
|
}
|
||||||
)script";
|
)script";
|
||||||
|
|
||||||
|
@ -39,6 +40,7 @@ R"script(import "calendar" for Calendar
|
||||||
var cale = Calendar.new()
|
var cale = Calendar.new()
|
||||||
System.print("Today is %(Calendar.today())")
|
System.print("Today is %(Calendar.today())")
|
||||||
cale.add_appointment("go get a haircut")
|
cale.add_appointment("go get a haircut")
|
||||||
|
System.print("You have %(cale.appointment_count()) appointment(s)")
|
||||||
)script";
|
)script";
|
||||||
|
|
||||||
auto today_unique_str() {
|
auto today_unique_str() {
|
||||||
|
@ -69,8 +71,8 @@ cale.add_appointment("go get a haircut")
|
||||||
vm.set_slot_string(0, today_unique_str().get());
|
vm.set_slot_string(0, today_unique_str().get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_appointment (wren::VM& vm) {
|
void add_appointment (std::string&& appointment) {
|
||||||
m_appointments.push_back(wren::get<std::string>(vm, 1));
|
m_appointments.push_back(std::move(appointment));
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_appointments() const {
|
void print_appointments() const {
|
||||||
|
@ -85,6 +87,10 @@ cale.add_appointment("go get a haircut")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::size_t appointment_count() const {
|
||||||
|
return m_appointments.size();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<std::string> m_appointments;
|
std::vector<std::string> m_appointments;
|
||||||
};
|
};
|
||||||
|
@ -111,6 +117,8 @@ cale.add_appointment("go get a haircut")
|
||||||
return &Calendar::today;
|
return &Calendar::today;
|
||||||
else if (not is_static and signature == "add_appointment(_)")
|
else if (not is_static and signature == "add_appointment(_)")
|
||||||
return wren::make_method_bindable<&Calendar::add_appointment>();
|
return wren::make_method_bindable<&Calendar::add_appointment>();
|
||||||
|
else if (not is_static and signature == "appointment_count()")
|
||||||
|
return wren::make_method_bindable<&Calendar::appointment_count>();
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
namespace wren {
|
namespace wren {
|
||||||
typedef std::tuple<const char*, const char*> ModuleAndName;
|
typedef std::tuple<const char*, const char*> ModuleAndName;
|
||||||
|
@ -76,6 +77,7 @@ namespace wren {
|
||||||
void set (VM& vm, int slot_num, const std::vector<char>& value);
|
void set (VM& vm, int slot_num, const std::vector<char>& value);
|
||||||
void set (VM& vm, int slot_num, const char* beg, const char* end);
|
void set (VM& vm, int slot_num, const char* beg, const char* end);
|
||||||
void set (VM& vm, int slot_num, int value);
|
void set (VM& vm, int slot_num, int value);
|
||||||
|
void set (VM& vm, int slot_num, std::size_t value);
|
||||||
std::string_view slot_string_view (VM& vm, int slot_num);
|
std::string_view slot_string_view (VM& vm, int slot_num);
|
||||||
template <typename T> detail::GetTypeToRetType_t<T> get (VM& vm, int slot_num);
|
template <typename T> detail::GetTypeToRetType_t<T> get (VM& vm, int slot_num);
|
||||||
template <typename T> T* foreign (VM& vm, int slot_num);
|
template <typename T> T* foreign (VM& vm, int slot_num);
|
||||||
|
@ -95,6 +97,7 @@ namespace wren {
|
||||||
template<>struct GetTypeToRetType<bool> : TType<bool>{};
|
template<>struct GetTypeToRetType<bool> : TType<bool>{};
|
||||||
template<>struct GetTypeToRetType<std::pair<const char*,int>> : TType<std::pair<const char*,int>> {};
|
template<>struct GetTypeToRetType<std::pair<const char*,int>> : TType<std::pair<const char*,int>> {};
|
||||||
template<>struct GetTypeToRetType<int> : TType<int>{};
|
template<>struct GetTypeToRetType<int> : TType<int>{};
|
||||||
|
template<>struct GetTypeToRetType<std::size_t> : TType<std::size_t>{};
|
||||||
template<>struct GetTypeToRetType<std::string> : TType<std::string>{};
|
template<>struct GetTypeToRetType<std::string> : TType<std::string>{};
|
||||||
template<>struct GetTypeToRetType<std::string_view> : TType<std::string_view>{};
|
template<>struct GetTypeToRetType<std::string_view> : TType<std::string_view>{};
|
||||||
template<>struct GetTypeToRetType<std::vector<char>> : TType<std::vector<char>>{};
|
template<>struct GetTypeToRetType<std::vector<char>> : TType<std::vector<char>>{};
|
||||||
|
@ -143,6 +146,30 @@ namespace wren {
|
||||||
(set_single_for_call(vm, Indices + 1, args), ...);
|
(set_single_for_call(vm, Indices + 1, args), ...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, typename R, auto Method, typename... Args> struct MakeMethodBindableConstNonConst {
|
||||||
|
private:
|
||||||
|
template <int... Indices>
|
||||||
|
static R call_implem (std::integer_sequence<int, Indices...>, VM& vm) {
|
||||||
|
static_assert(sizeof...(Indices) == sizeof...(Args), "Mismatching argument count");
|
||||||
|
T* obj = foreign<T>(vm, 0);
|
||||||
|
return (obj->*Method)(get<std::decay_t<Args>>(vm, Indices + 1)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
static foreign_method_t make() {
|
||||||
|
return [](VM& vm) {
|
||||||
|
if constexpr (std::is_same_v<R, void>) {
|
||||||
|
call_implem(std::make_integer_sequence<int, sizeof...(Args)>(), vm);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
auto ret = call_implem(std::make_integer_sequence<int, sizeof...(Args)>(), vm);
|
||||||
|
vm.ensure_slots(1);
|
||||||
|
set(vm, 0, ret);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <auto V> struct MakeMethodBindable;
|
template <auto V> struct MakeMethodBindable;
|
||||||
template <typename T, void(T::*Method)(VM&)> struct MakeMethodBindable<Method> {
|
template <typename T, void(T::*Method)(VM&)> struct MakeMethodBindable<Method> {
|
||||||
static foreign_method_t make() {
|
static foreign_method_t make() {
|
||||||
|
@ -152,6 +179,9 @@ namespace wren {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T, typename R, typename... Args, R(T::*Method)(Args...)> struct MakeMethodBindable<Method> : MakeMethodBindableConstNonConst<T, R, Method, Args...> {};
|
||||||
|
template <typename T, typename R, typename... Args, R(T::*Method)(Args...)const> struct MakeMethodBindable<Method> : MakeMethodBindableConstNonConst<T, R, Method, Args...> {};
|
||||||
} //namespace detail
|
} //namespace detail
|
||||||
|
|
||||||
#if __cpp_concepts >= 201907
|
#if __cpp_concepts >= 201907
|
||||||
|
@ -203,6 +233,10 @@ namespace wren {
|
||||||
vm.set_slot_double(slot_num, static_cast<double>(value));
|
vm.set_slot_double(slot_num, static_cast<double>(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void set (VM& vm, int slot_num, std::size_t value) {
|
||||||
|
vm.set_slot_double(slot_num, static_cast<double>(value));
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T* foreign (VM& vm, int slot_num) {
|
inline T* foreign (VM& vm, int slot_num) {
|
||||||
T* obj = static_cast<T*>(vm.slot_foreign(slot_num));
|
T* obj = static_cast<T*>(vm.slot_foreign(slot_num));
|
||||||
|
@ -278,6 +312,7 @@ namespace wren {
|
||||||
template <> bool get<bool> (VM& vm, int slot_num);
|
template <> bool get<bool> (VM& vm, int slot_num);
|
||||||
template <> std::pair<const char*, int> get<std::pair<const char*,int>> (VM& vm, int slot_num);
|
template <> std::pair<const char*, int> get<std::pair<const char*,int>> (VM& vm, int slot_num);
|
||||||
template<> int get<int> (VM& vm, int slot_num);
|
template<> int get<int> (VM& vm, int slot_num);
|
||||||
|
template<> std::size_t get<std::size_t> (VM& vm, int slot_num);
|
||||||
template<> std::string get<std::string> (VM& vm, int slot_num);
|
template<> std::string get<std::string> (VM& vm, int slot_num);
|
||||||
template <> std::string_view get<std::string_view> (VM& vm, int slot_num);
|
template <> std::string_view get<std::string_view> (VM& vm, int slot_num);
|
||||||
template <> std::vector<char> get<std::vector<char>> (VM& vm, int slot_num);
|
template <> std::vector<char> get<std::vector<char>> (VM& vm, int slot_num);
|
||||||
|
|
|
@ -54,6 +54,10 @@ namespace wren {
|
||||||
return static_cast<int>(vm.slot_double(slot_num));
|
return static_cast<int>(vm.slot_double(slot_num));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<> std::size_t get<std::size_t> (VM& vm, int slot_num) {
|
||||||
|
return static_cast<std::size_t>(vm.slot_double(slot_num));
|
||||||
|
}
|
||||||
|
|
||||||
template<> std::string get<std::string> (VM& vm, int slot_num) {
|
template<> std::string get<std::string> (VM& vm, int slot_num) {
|
||||||
return {vm.slot_string(slot_num)};
|
return {vm.slot_string(slot_num)};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue