mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
commit
b2e83d4fca
|
@ -58,6 +58,8 @@ public:
|
|||
function(lua_State* L, int index = -1): reference(L, index) {
|
||||
type_assert(L, index, type::function);
|
||||
}
|
||||
function(const function&) = default;
|
||||
function& operator=(const function&) = default;
|
||||
|
||||
template<typename... Ret, typename... Args>
|
||||
auto call(Args&&... args) -> decltype(invoke(types<Ret...>(), sizeof...(Args))) {
|
||||
|
|
|
@ -1,125 +0,0 @@
|
|||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013 Danny Y., Rapptz
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_FUNCTIONAL_HPP
|
||||
#define SOL_FUNCTIONAL_HPP
|
||||
|
||||
#include "tuple.hpp"
|
||||
|
||||
namespace sol {
|
||||
namespace detail {
|
||||
|
||||
template<typename TFuncSignature>
|
||||
struct function_traits;
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct function_traits<R(T::*)(Args...)> {
|
||||
static const std::size_t arity = sizeof...(Args);
|
||||
static const bool is_member_function = true;
|
||||
typedef std::tuple<Args...> arg_tuple_type;
|
||||
typedef types<Args...> args_type;
|
||||
typedef R(T::* function_pointer_type)(Args...);
|
||||
typedef typename std::remove_pointer<function_pointer_type>::type function_type;
|
||||
typedef R(* free_function_pointer_type)(Args...);
|
||||
typedef R return_type;
|
||||
template<std::size_t i>
|
||||
using arg = typename std::tuple_element<i, arg_tuple_type>::type;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct function_traits<R(T::*)(Args...) const> {
|
||||
static const std::size_t arity = sizeof...(Args);
|
||||
static const bool is_member_function = true;
|
||||
typedef std::tuple<Args...> arg_tuple_type;
|
||||
typedef types<Args...> args_type;
|
||||
typedef R(T::* function_pointer_type)(Args...);
|
||||
typedef typename std::remove_pointer<function_pointer_type>::type function_type;
|
||||
typedef R(* free_function_pointer_type)(Args...);
|
||||
typedef R return_type;
|
||||
template<std::size_t i>
|
||||
using arg = typename std::tuple_element<i, arg_tuple_type>::type;
|
||||
};
|
||||
|
||||
template<typename R, typename... Args>
|
||||
struct function_traits<R(Args...)> {
|
||||
static const std::size_t arity = sizeof...(Args);
|
||||
static const bool is_member_function = false;
|
||||
typedef std::tuple<Args...> arg_tuple_type;
|
||||
typedef types<Args...> args_type;
|
||||
typedef R(function_type)(Args...);
|
||||
typedef R(*function_pointer_type)(Args...);
|
||||
typedef R(* free_function_pointer_type)(Args...);
|
||||
typedef R return_type;
|
||||
template<std::size_t i>
|
||||
using arg = typename std::tuple_element<i, arg_tuple_type>::type;
|
||||
};
|
||||
|
||||
template<typename R, typename... Args>
|
||||
struct function_traits<R(*)(Args...)> {
|
||||
static const std::size_t arity = sizeof...(Args);
|
||||
static const bool is_member_function = false;
|
||||
typedef std::tuple<Args...> arg_tuple_type;
|
||||
typedef types<Args...> args_type;
|
||||
typedef R(function_type)(Args...);
|
||||
typedef R(*function_pointer_type)(Args...);
|
||||
typedef R(* free_function_pointer_type)(Args...);
|
||||
typedef R return_type;
|
||||
template<std::size_t i>
|
||||
using arg = typename std::tuple_element<i, arg_tuple_type>::type;
|
||||
};
|
||||
|
||||
using std::get;
|
||||
|
||||
template<typename Function, typename Tuple, size_t... Indices>
|
||||
inline auto call(Function&& f, const Tuple& t, indices<Indices...>) -> decltype(f(get<Indices>(t)...)) {
|
||||
return f(get<Indices>(t)...);
|
||||
}
|
||||
} // detail
|
||||
|
||||
template<typename... Ret>
|
||||
struct lua_return_type {
|
||||
typedef std::tuple<Ret...> type;
|
||||
};
|
||||
|
||||
template<typename Ret>
|
||||
struct lua_return_type<Ret> {
|
||||
typedef Ret type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct lua_return_type<> {
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct lua_return_type<void> {
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
template<typename Function, typename... Args>
|
||||
inline auto call(Function&& f, const std::tuple<Args...>& t) -> decltype(detail::call(std::forward<Function>(f), t, build_indices<sizeof...(Args)>{})) {
|
||||
return call(std::forward<Function>(f), t, build_indices<sizeof...(Args)>{});
|
||||
}
|
||||
|
||||
} // sol
|
||||
|
||||
|
||||
#endif // SOL_FUNCTIONAL_HPP
|
|
@ -22,7 +22,6 @@
|
|||
#ifndef SOL_LUA_FUNC_HPP
|
||||
#define SOL_LUA_FUNC_HPP
|
||||
|
||||
#include "functional.hpp"
|
||||
#include "stack.hpp"
|
||||
#include <memory>
|
||||
|
||||
|
@ -62,7 +61,7 @@ void get_upvalue(lua_State* L, T& data, int& upvalue) {
|
|||
template<typename TFx>
|
||||
struct static_lua_func {
|
||||
typedef typename std::remove_pointer<typename std::decay<TFx>::type>::type fx_t;
|
||||
typedef detail::function_traits<fx_t> fx_traits;
|
||||
typedef function_traits<fx_t> fx_traits;
|
||||
|
||||
template<typename... Args>
|
||||
static int typed_call(types<void>, types<Args...> t, fx_t* fx, lua_State* L) {
|
||||
|
@ -93,7 +92,7 @@ struct static_lua_func {
|
|||
template<typename T, typename TFx>
|
||||
struct static_object_lua_func {
|
||||
typedef typename std::decay<TFx>::type fx_t;
|
||||
typedef detail::function_traits<fx_t> fx_traits;
|
||||
typedef function_traits<fx_t> fx_traits;
|
||||
|
||||
template<typename... Args>
|
||||
static int typed_call(types<void>, types<Args...>, T& item, fx_t& ifx, lua_State* L) {
|
||||
|
@ -173,7 +172,7 @@ struct lua_func {
|
|||
template<typename TFx>
|
||||
struct lambda_lua_func : public lua_func {
|
||||
typedef decltype(&TFx::operator()) fx_t;
|
||||
typedef detail::function_traits<fx_t> fx_traits;
|
||||
typedef function_traits<fx_t> fx_traits;
|
||||
TFx fx;
|
||||
|
||||
template<typename... FxArgs>
|
||||
|
@ -200,7 +199,7 @@ struct lambda_lua_func : public lua_func {
|
|||
template<typename TFx, typename T = TFx, bool is_member_pointer = std::is_member_function_pointer<TFx>::value>
|
||||
struct explicit_lua_func : public lua_func {
|
||||
typedef typename std::remove_pointer<typename std::decay<TFx>::type>::type fx_t;
|
||||
typedef detail::function_traits<fx_t> fx_traits;
|
||||
typedef function_traits<fx_t> fx_traits;
|
||||
TFx fx;
|
||||
|
||||
template<typename... FxArgs>
|
||||
|
@ -227,7 +226,7 @@ struct explicit_lua_func : public lua_func {
|
|||
template<typename TFx, typename T>
|
||||
struct explicit_lua_func<TFx, T, true> : public lua_func {
|
||||
typedef typename std::remove_pointer<typename std::decay<TFx>::type>::type fx_t;
|
||||
typedef detail::function_traits<fx_t> fx_traits;
|
||||
typedef function_traits<fx_t> fx_traits;
|
||||
struct lambda {
|
||||
T member;
|
||||
TFx invocation;
|
||||
|
|
|
@ -91,6 +91,30 @@ public:
|
|||
return lua_rawlen(state(), -1);
|
||||
}
|
||||
private:
|
||||
template<typename T>
|
||||
struct proxy {
|
||||
private:
|
||||
table& t;
|
||||
T& key;
|
||||
public:
|
||||
proxy(table& t, T& key) : t(t), key(key) {}
|
||||
|
||||
template<typename U>
|
||||
EnableIf<Function<Unqualified<U>>> operator=(U&& other) {
|
||||
t.set_function(key, std::forward<U>(other));
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
DisableIf<Function<Unqualified<U>>> operator=(U&& other) {
|
||||
t.set(key, std::forward<U>(other));
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
operator U() const {
|
||||
return t.get<U>(key);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, typename TFx>
|
||||
table& set_isfunction_fx(std::true_type, T&& key, TFx&& fx) {
|
||||
return set_fx(std::false_type(), std::forward<T>(key), std::forward<TFx>(fx));
|
||||
|
@ -99,7 +123,7 @@ private:
|
|||
template<typename T, typename TFx>
|
||||
table& set_isfunction_fx(std::false_type, T&& key, TFx&& fx) {
|
||||
typedef Decay<TFx> clean_lambda;
|
||||
typedef typename detail::function_traits<decltype(&clean_lambda::operator())>::free_function_pointer_type raw_func_t;
|
||||
typedef typename function_traits<decltype(&clean_lambda::operator())>::free_function_pointer_type raw_func_t;
|
||||
typedef std::is_convertible<clean_lambda, raw_func_t> isconvertible;
|
||||
return set_isconvertible_fx(isconvertible(), std::forward<T>(key), std::forward<TFx>(fx));
|
||||
}
|
||||
|
@ -107,7 +131,7 @@ private:
|
|||
template<typename T, typename TFx>
|
||||
table& set_isconvertible_fx(std::true_type, T&& key, TFx&& fx) {
|
||||
typedef Decay<TFx> clean_lambda;
|
||||
typedef typename detail::function_traits<decltype(&clean_lambda::operator())>::free_function_pointer_type raw_func_t;
|
||||
typedef typename function_traits<decltype(&clean_lambda::operator())>::free_function_pointer_type raw_func_t;
|
||||
return set_isfunction_fx(std::true_type(), std::forward<T>(key), raw_func_t(std::forward<TFx>(fx)));
|
||||
}
|
||||
|
||||
|
@ -207,30 +231,6 @@ private:
|
|||
lua_pop(state(), 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct proxy {
|
||||
private:
|
||||
table& t;
|
||||
T& key;
|
||||
public:
|
||||
proxy(table& t, T& key): t(t), key(key) {}
|
||||
|
||||
template<typename U>
|
||||
DisableIf<Function<Unqualified<U>>> operator=(U&& other) {
|
||||
t.set(key, std::forward<U>(other));
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
EnableIf<Function<Unqualified<U>>> operator=(U&& other) {
|
||||
t.set_function(key, std::forward<U>(other));
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
operator U() const {
|
||||
return t.get<U>(key);
|
||||
}
|
||||
};
|
||||
};
|
||||
} // sol
|
||||
|
||||
|
|
|
@ -40,11 +40,11 @@ using Decay = typename std::decay<T>::type;
|
|||
namespace detail {
|
||||
// code borrowed from Gears
|
||||
// https://github.com/Rapptz/Gears/
|
||||
template<typename T, typename = void>
|
||||
template<typename T, bool isclass = std::is_class<Unqualified<T>>::value>
|
||||
struct is_function_impl : std::is_function<typename std::remove_pointer<T>::type> {};
|
||||
|
||||
template<typename T>
|
||||
struct is_function_impl<T, EnableIf<std::is_class<Unqualified<T>>>> {
|
||||
struct is_function_impl<T, true> {
|
||||
using yes = char;
|
||||
using no = struct { char s[2]; };
|
||||
|
||||
|
@ -67,6 +67,65 @@ using Bool = std::integral_constant<bool, B>;
|
|||
|
||||
template<typename T>
|
||||
struct Function : Bool<detail::is_function_impl<T>::value> {};
|
||||
|
||||
template<typename TFuncSignature>
|
||||
struct function_traits;
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct function_traits<R( T::* )( Args... )> {
|
||||
static const std::size_t arity = sizeof...( Args );
|
||||
static const bool is_member_function = true;
|
||||
typedef std::tuple<Args...> arg_tuple_type;
|
||||
typedef types<Args...> args_type;
|
||||
typedef R( T::* function_pointer_type )( Args... );
|
||||
typedef typename std::remove_pointer<function_pointer_type>::type function_type;
|
||||
typedef R( *free_function_pointer_type )( Args... );
|
||||
typedef R return_type;
|
||||
template<std::size_t i>
|
||||
using arg = typename std::tuple_element<i, arg_tuple_type>::type;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct function_traits<R( T::* )( Args... ) const> {
|
||||
static const std::size_t arity = sizeof...( Args );
|
||||
static const bool is_member_function = true;
|
||||
typedef std::tuple<Args...> arg_tuple_type;
|
||||
typedef types<Args...> args_type;
|
||||
typedef R( T::* function_pointer_type )( Args... );
|
||||
typedef typename std::remove_pointer<function_pointer_type>::type function_type;
|
||||
typedef R( *free_function_pointer_type )( Args... );
|
||||
typedef R return_type;
|
||||
template<std::size_t i>
|
||||
using arg = typename std::tuple_element<i, arg_tuple_type>::type;
|
||||
};
|
||||
|
||||
template<typename R, typename... Args>
|
||||
struct function_traits<R( Args... )> {
|
||||
static const std::size_t arity = sizeof...( Args );
|
||||
static const bool is_member_function = false;
|
||||
typedef std::tuple<Args...> arg_tuple_type;
|
||||
typedef types<Args...> args_type;
|
||||
typedef R( function_type )( Args... );
|
||||
typedef R( *function_pointer_type )( Args... );
|
||||
typedef R( *free_function_pointer_type )( Args... );
|
||||
typedef R return_type;
|
||||
template<std::size_t i>
|
||||
using arg = typename std::tuple_element<i, arg_tuple_type>::type;
|
||||
};
|
||||
|
||||
template<typename R, typename... Args>
|
||||
struct function_traits<R( *)( Args... )> {
|
||||
static const std::size_t arity = sizeof...( Args );
|
||||
static const bool is_member_function = false;
|
||||
typedef std::tuple<Args...> arg_tuple_type;
|
||||
typedef types<Args...> args_type;
|
||||
typedef R( function_type )( Args... );
|
||||
typedef R( *function_pointer_type )( Args... );
|
||||
typedef R( *free_function_pointer_type )( Args... );
|
||||
typedef R return_type;
|
||||
template<std::size_t i>
|
||||
using arg = typename std::tuple_element<i, arg_tuple_type>::type;
|
||||
};
|
||||
} // sol
|
||||
|
||||
#endif // SOL_TRAITS_HPP
|
|
@ -165,7 +165,7 @@ TEST_CASE("tables/functions_variables", "Check if tables and function calls work
|
|||
std::cout << "stateless lambda()" << std::endl;
|
||||
return "test";
|
||||
}
|
||||
);
|
||||
);
|
||||
REQUIRE_NOTHROW(run_script(lua));
|
||||
|
||||
lua.get<sol::table>("os").set_function("fun", &free_function);
|
||||
|
@ -183,7 +183,7 @@ TEST_CASE("tables/functions_variables", "Check if tables and function calls work
|
|||
std::cout << "stateless lambda()" << std::endl;
|
||||
return "test";
|
||||
}
|
||||
);
|
||||
);
|
||||
REQUIRE_NOTHROW(run_script(lua));
|
||||
|
||||
// r-value, cannot optomize
|
||||
|
|
Loading…
Reference in New Issue
Block a user