Merge pull request #7 from ThePhD/master

VC++ Compatibility
This commit is contained in:
Danny 2013-12-13 12:05:04 -08:00
commit b2e83d4fca
6 changed files with 96 additions and 161 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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