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
|
} //unnamed namespace
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
typedef wren::ModuleAndName MN;
|
||||||
|
|
||||||
MyConf conf;
|
MyConf conf;
|
||||||
wren::VM vm(&conf, nullptr);
|
wren::VM vm(&conf, nullptr);
|
||||||
vm.interpret("main", g_test_script);
|
vm.interpret("main", g_test_script);
|
||||||
|
|
||||||
vm.ensure_slots(1);
|
Calendar* const cale = std::get<0>(wren::variables<Calendar>(vm, MN{"main", "cale"}));
|
||||||
wren::variable(vm, {"main", "cale"}, 0);
|
|
||||||
const auto cale = wren::foreign<Calendar>(vm, 0);
|
|
||||||
cale->print_appointments();
|
cale->print_appointments();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -28,6 +28,9 @@ namespace wren {
|
||||||
typedef std::tuple<const char*, const char*> ModuleAndName;
|
typedef std::tuple<const char*, const char*> ModuleAndName;
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
template <typename T> struct GetTypeToRetType;
|
||||||
|
template <typename T> using GetTypeToRetType_t = typename GetTypeToRetType<T>::type;
|
||||||
|
|
||||||
#if __cpp_concepts >= 201907
|
#if __cpp_concepts >= 201907
|
||||||
template <typename T>
|
template <typename T>
|
||||||
concept ConstCharTuple = requires {
|
concept ConstCharTuple = requires {
|
||||||
|
@ -42,7 +45,7 @@ namespace wren {
|
||||||
#else
|
#else
|
||||||
template <typename... Outs, typename... Params>
|
template <typename... Outs, typename... Params>
|
||||||
#endif
|
#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>
|
template <typename R, typename... Args>
|
||||||
R call (VM& vm, const Handle& object, const Handle& method, const Args&... 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, const char* beg, const char* end);
|
||||||
void set (VM& vm, int slot_num, int value);
|
void set (VM& vm, int slot_num, int 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> 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);
|
||||||
void variable(VM& vm, const ModuleAndName& mod_and_name, int slot);
|
void variable(VM& vm, const ModuleAndName& mod_and_name, int slot);
|
||||||
void variable(VM& vm, const Handle& handle, int slot);
|
void variable(VM& vm, const Handle& handle, int slot);
|
||||||
|
|
||||||
namespace detail {
|
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
|
#if __cpp_concepts >= 201907
|
||||||
template <typename... Outs, int... Indices, ConstCharTuple... Params>
|
template <typename... Outs, int... Indices, ConstCharTuple... Params>
|
||||||
#else
|
#else
|
||||||
template <typename... Outs, int... Indices, typename... Params>
|
template <typename... Outs, int... Indices, typename... Params>
|
||||||
#endif
|
#endif
|
||||||
inline std::tuple<Outs...> variables_impl (
|
inline std::tuple<detail::GetTypeToRetType_t<Outs>...> variables_impl (
|
||||||
VM& vm,
|
VM& vm,
|
||||||
std::integer_sequence<int, Indices...>,
|
std::integer_sequence<int, Indices...>,
|
||||||
Params&&... modules_names
|
Params&&... modules_names
|
||||||
|
@ -99,7 +118,7 @@ namespace wren {
|
||||||
|
|
||||||
vm.ensure_slots(sizeof...(Params));
|
vm.ensure_slots(sizeof...(Params));
|
||||||
(variable(vm, modules_names, Indices), ...);
|
(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
|
#else
|
||||||
template <typename... Outs, typename... Params>
|
template <typename... Outs, typename... Params>
|
||||||
#endif
|
#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)...);
|
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() {
|
inline foreign_method_t make_method_bindable() {
|
||||||
return detail::MakeMethodBindable<V>::make();
|
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
|
} //namespace wren
|
||||||
|
|
|
@ -34,36 +34,36 @@ namespace wren {
|
||||||
return {ptr.first, static_cast<std::size_t>(ptr.second)};
|
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);
|
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);
|
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);
|
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);
|
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));
|
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)};
|
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);
|
auto arr = get<std::pair<const char*, int>>(vm, slot_num);
|
||||||
return std::string_view{arr.first, static_cast<std::size_t>(arr.second)};
|
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);
|
auto arr = get<std::pair<const char*, int>>(vm, slot_num);
|
||||||
return std::vector<char>{arr.first, arr.first + arr.second};
|
return std::vector<char>{arr.first, arr.first + arr.second};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue