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:
King_DuckZ 2020-05-03 11:32:43 +02:00
parent 90d93d2583
commit 34d2317f11
3 changed files with 49 additions and 16 deletions

View file

@ -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;

View file

@ -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

View file

@ -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};
}