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) {
|
function(lua_State* L, int index = -1): reference(L, index) {
|
||||||
type_assert(L, index, type::function);
|
type_assert(L, index, type::function);
|
||||||
}
|
}
|
||||||
|
function(const function&) = default;
|
||||||
|
function& operator=(const function&) = default;
|
||||||
|
|
||||||
template<typename... Ret, typename... Args>
|
template<typename... Ret, typename... Args>
|
||||||
auto call(Args&&... args) -> decltype(invoke(types<Ret...>(), sizeof...(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
|
#ifndef SOL_LUA_FUNC_HPP
|
||||||
#define SOL_LUA_FUNC_HPP
|
#define SOL_LUA_FUNC_HPP
|
||||||
|
|
||||||
#include "functional.hpp"
|
|
||||||
#include "stack.hpp"
|
#include "stack.hpp"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
@ -62,7 +61,7 @@ void get_upvalue(lua_State* L, T& data, int& upvalue) {
|
||||||
template<typename TFx>
|
template<typename TFx>
|
||||||
struct static_lua_func {
|
struct static_lua_func {
|
||||||
typedef typename std::remove_pointer<typename std::decay<TFx>::type>::type fx_t;
|
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>
|
template<typename... Args>
|
||||||
static int typed_call(types<void>, types<Args...> t, fx_t* fx, lua_State* L) {
|
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>
|
template<typename T, typename TFx>
|
||||||
struct static_object_lua_func {
|
struct static_object_lua_func {
|
||||||
typedef typename std::decay<TFx>::type fx_t;
|
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>
|
template<typename... Args>
|
||||||
static int typed_call(types<void>, types<Args...>, T& item, fx_t& ifx, lua_State* L) {
|
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>
|
template<typename TFx>
|
||||||
struct lambda_lua_func : public lua_func {
|
struct lambda_lua_func : public lua_func {
|
||||||
typedef decltype(&TFx::operator()) fx_t;
|
typedef decltype(&TFx::operator()) fx_t;
|
||||||
typedef detail::function_traits<fx_t> fx_traits;
|
typedef function_traits<fx_t> fx_traits;
|
||||||
TFx fx;
|
TFx fx;
|
||||||
|
|
||||||
template<typename... FxArgs>
|
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>
|
template<typename TFx, typename T = TFx, bool is_member_pointer = std::is_member_function_pointer<TFx>::value>
|
||||||
struct explicit_lua_func : public lua_func {
|
struct explicit_lua_func : public lua_func {
|
||||||
typedef typename std::remove_pointer<typename std::decay<TFx>::type>::type fx_t;
|
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;
|
TFx fx;
|
||||||
|
|
||||||
template<typename... FxArgs>
|
template<typename... FxArgs>
|
||||||
|
@ -227,7 +226,7 @@ struct explicit_lua_func : public lua_func {
|
||||||
template<typename TFx, typename T>
|
template<typename TFx, typename T>
|
||||||
struct explicit_lua_func<TFx, T, true> : public lua_func {
|
struct explicit_lua_func<TFx, T, true> : public lua_func {
|
||||||
typedef typename std::remove_pointer<typename std::decay<TFx>::type>::type fx_t;
|
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 {
|
struct lambda {
|
||||||
T member;
|
T member;
|
||||||
TFx invocation;
|
TFx invocation;
|
||||||
|
|
|
@ -91,6 +91,30 @@ public:
|
||||||
return lua_rawlen(state(), -1);
|
return lua_rawlen(state(), -1);
|
||||||
}
|
}
|
||||||
private:
|
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>
|
template<typename T, typename TFx>
|
||||||
table& set_isfunction_fx(std::true_type, T&& key, TFx&& fx) {
|
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));
|
return set_fx(std::false_type(), std::forward<T>(key), std::forward<TFx>(fx));
|
||||||
|
@ -99,7 +123,7 @@ private:
|
||||||
template<typename T, typename TFx>
|
template<typename T, typename TFx>
|
||||||
table& set_isfunction_fx(std::false_type, T&& key, TFx&& fx) {
|
table& set_isfunction_fx(std::false_type, T&& key, TFx&& fx) {
|
||||||
typedef Decay<TFx> clean_lambda;
|
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;
|
typedef std::is_convertible<clean_lambda, raw_func_t> isconvertible;
|
||||||
return set_isconvertible_fx(isconvertible(), std::forward<T>(key), std::forward<TFx>(fx));
|
return set_isconvertible_fx(isconvertible(), std::forward<T>(key), std::forward<TFx>(fx));
|
||||||
}
|
}
|
||||||
|
@ -107,7 +131,7 @@ private:
|
||||||
template<typename T, typename TFx>
|
template<typename T, typename TFx>
|
||||||
table& set_isconvertible_fx(std::true_type, T&& key, TFx&& fx) {
|
table& set_isconvertible_fx(std::true_type, T&& key, TFx&& fx) {
|
||||||
typedef Decay<TFx> clean_lambda;
|
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)));
|
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);
|
lua_pop(state(), 1);
|
||||||
return *this;
|
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
|
} // sol
|
||||||
|
|
||||||
|
|
|
@ -40,11 +40,11 @@ using Decay = typename std::decay<T>::type;
|
||||||
namespace detail {
|
namespace detail {
|
||||||
// code borrowed from Gears
|
// code borrowed from Gears
|
||||||
// https://github.com/Rapptz/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> {};
|
struct is_function_impl : std::is_function<typename std::remove_pointer<T>::type> {};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct is_function_impl<T, EnableIf<std::is_class<Unqualified<T>>>> {
|
struct is_function_impl<T, true> {
|
||||||
using yes = char;
|
using yes = char;
|
||||||
using no = struct { char s[2]; };
|
using no = struct { char s[2]; };
|
||||||
|
|
||||||
|
@ -67,6 +67,65 @@ using Bool = std::integral_constant<bool, B>;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct Function : Bool<detail::is_function_impl<T>::value> {};
|
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
|
} // sol
|
||||||
|
|
||||||
#endif // SOL_TRAITS_HPP
|
#endif // SOL_TRAITS_HPP
|
Loading…
Reference in New Issue
Block a user