Add support for foreign types to get()
wren::get() can now be used to get foreign types by pointer. Invoking get<A>() will return an A*. With this change it's now possible to use variables() to get mixed foreign and core types.
This commit is contained in:
parent
90d93d2583
commit
34d2317f11
3 changed files with 49 additions and 16 deletions
|
@ -130,13 +130,13 @@ cale.add_appointment("go get a haircut")
|
|||
} //unnamed namespace
|
||||
|
||||
int main() {
|
||||
typedef wren::ModuleAndName MN;
|
||||
|
||||
MyConf conf;
|
||||
wren::VM vm(&conf, nullptr);
|
||||
vm.interpret("main", g_test_script);
|
||||
|
||||
vm.ensure_slots(1);
|
||||
wren::variable(vm, {"main", "cale"}, 0);
|
||||
const auto cale = wren::foreign<Calendar>(vm, 0);
|
||||
Calendar* const cale = std::get<0>(wren::variables<Calendar>(vm, MN{"main", "cale"}));
|
||||
cale->print_appointments();
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -28,6 +28,9 @@ namespace wren {
|
|||
typedef std::tuple<const char*, const char*> ModuleAndName;
|
||||
|
||||
namespace detail {
|
||||
template <typename T> struct GetTypeToRetType;
|
||||
template <typename T> using GetTypeToRetType_t = typename GetTypeToRetType<T>::type;
|
||||
|
||||
#if __cpp_concepts >= 201907
|
||||
template <typename T>
|
||||
concept ConstCharTuple = requires {
|
||||
|
@ -42,7 +45,7 @@ namespace wren {
|
|||
#else
|
||||
template <typename... Outs, typename... Params>
|
||||
#endif
|
||||
std::tuple<Outs...> variables(VM& vm, Params&&... modules_names);
|
||||
std::tuple<detail::GetTypeToRetType_t<Outs>...> variables(VM& vm, Params&&... modules_names);
|
||||
|
||||
template <typename R, typename... Args>
|
||||
R call (VM& vm, const Handle& object, const Handle& method, const Args&... args);
|
||||
|
@ -74,18 +77,34 @@ namespace wren {
|
|||
void set (VM& vm, int slot_num, const char* beg, const char* end);
|
||||
void set (VM& vm, int slot_num, int value);
|
||||
std::string_view slot_string_view (VM& vm, int slot_num);
|
||||
template <typename 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);
|
||||
void variable(VM& vm, const ModuleAndName& mod_and_name, int slot);
|
||||
void variable(VM& vm, const Handle& handle, int slot);
|
||||
|
||||
namespace detail {
|
||||
template <typename T> struct TType { typedef T type; };
|
||||
|
||||
template<typename T>struct GetTypeToRetType{
|
||||
static_assert(not std::is_fundamental_v<T>, "User type expected");
|
||||
static_assert(not std::is_pointer_v<T>, "Unexpected pointer type");
|
||||
typedef std::remove_cv_t<T>* type;
|
||||
};
|
||||
template<>struct GetTypeToRetType<const char*> : TType<const char*>{};
|
||||
template<>struct GetTypeToRetType<double> : TType<double>{};
|
||||
template<>struct GetTypeToRetType<bool> : TType<bool>{};
|
||||
template<>struct GetTypeToRetType<std::pair<const char*,int>> : TType<std::pair<const char*,int>> {};
|
||||
template<>struct GetTypeToRetType<int> : TType<int>{};
|
||||
template<>struct GetTypeToRetType<std::string> : TType<std::string>{};
|
||||
template<>struct GetTypeToRetType<std::string_view> : TType<std::string_view>{};
|
||||
template<>struct GetTypeToRetType<std::vector<char>> : TType<std::vector<char>>{};
|
||||
|
||||
#if __cpp_concepts >= 201907
|
||||
template <typename... Outs, int... Indices, ConstCharTuple... Params>
|
||||
#else
|
||||
template <typename... Outs, int... Indices, typename... Params>
|
||||
#endif
|
||||
inline std::tuple<Outs...> variables_impl (
|
||||
inline std::tuple<detail::GetTypeToRetType_t<Outs>...> variables_impl (
|
||||
VM& vm,
|
||||
std::integer_sequence<int, Indices...>,
|
||||
Params&&... modules_names
|
||||
|
@ -99,7 +118,7 @@ namespace wren {
|
|||
|
||||
vm.ensure_slots(sizeof...(Params));
|
||||
(variable(vm, modules_names, Indices), ...);
|
||||
return std::tuple<Outs...>(get<Outs>(vm, Indices)...);
|
||||
return std::tuple<detail::GetTypeToRetType_t<Outs>...>(get<Outs>(vm, Indices)...);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -140,7 +159,7 @@ namespace wren {
|
|||
#else
|
||||
template <typename... Outs, typename... Params>
|
||||
#endif
|
||||
inline std::tuple<Outs...> variables(VM& vm, Params&&... modules_names) {
|
||||
inline std::tuple<detail::GetTypeToRetType_t<Outs>...> variables(VM& vm, Params&&... modules_names) {
|
||||
return detail::variables_impl<Outs...>(vm, std::make_integer_sequence<int, sizeof...(Outs)>(), std::forward<Params>(modules_names)...);
|
||||
}
|
||||
|
||||
|
@ -248,4 +267,18 @@ namespace wren {
|
|||
inline foreign_method_t make_method_bindable() {
|
||||
return detail::MakeMethodBindable<V>::make();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline detail::GetTypeToRetType_t<T> get (VM& vm, int slot_num) {
|
||||
return foreign<T>(vm, slot_num);
|
||||
}
|
||||
|
||||
template<> const char* get<const char*> (VM& vm, int slot_num);
|
||||
template <> double get<double> (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<> int get<int> (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::vector<char> get<std::vector<char>> (VM& vm, int slot_num);
|
||||
} //namespace wren
|
||||
|
|
|
@ -34,36 +34,36 @@ namespace wren {
|
|||
return {ptr.first, static_cast<std::size_t>(ptr.second)};
|
||||
}
|
||||
|
||||
template<> const char* get (VM& vm, int slot_num) {
|
||||
template<> const char* get<const char*> (VM& vm, int slot_num) {
|
||||
return vm.slot_string(slot_num);
|
||||
}
|
||||
|
||||
template <> double get (VM& vm, int slot_num) {
|
||||
template <> double get<double> (VM& vm, int slot_num) {
|
||||
return vm.slot_double(slot_num);
|
||||
}
|
||||
|
||||
template <> bool get (VM& vm, int slot_num) {
|
||||
template <> bool get<bool> (VM& vm, int slot_num) {
|
||||
return vm.slot_bool(slot_num);
|
||||
}
|
||||
|
||||
template <> std::pair<const char*, int> get (VM& vm, int slot_num) {
|
||||
template <> std::pair<const char*, int> get<std::pair<const char*,int>> (VM& vm, int slot_num) {
|
||||
return vm.slot_bytes(slot_num);
|
||||
}
|
||||
|
||||
template<> int get (VM& vm, int slot_num) {
|
||||
template<> int get<int> (VM& vm, int slot_num) {
|
||||
return static_cast<int>(vm.slot_double(slot_num));
|
||||
}
|
||||
|
||||
template<> std::string get (VM& vm, int slot_num) {
|
||||
template<> std::string get<std::string> (VM& vm, int slot_num) {
|
||||
return {vm.slot_string(slot_num)};
|
||||
}
|
||||
|
||||
template <> std::string_view get (VM& vm, int slot_num) {
|
||||
template <> std::string_view get<std::string_view> (VM& vm, int slot_num) {
|
||||
auto arr = get<std::pair<const char*, int>>(vm, slot_num);
|
||||
return std::string_view{arr.first, static_cast<std::size_t>(arr.second)};
|
||||
}
|
||||
|
||||
template <> std::vector<char> get (VM& vm, int slot_num) {
|
||||
template <> std::vector<char> get<std::vector<char>> (VM& vm, int slot_num) {
|
||||
auto arr = get<std::pair<const char*, int>>(vm, slot_num);
|
||||
return std::vector<char>{arr.first, arr.first + arr.second};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue