Preparing for overload support

Preparing to benchmarking of several different lua frameworks
This commit is contained in:
ThePhD 2016-02-09 03:38:11 -05:00
parent 540438baec
commit 9372b54b02
12 changed files with 173 additions and 206 deletions

1
.gitignore vendored
View File

@ -43,3 +43,4 @@ main2.cpp
lua-5.3.2/
lua-5.2.4/
bench/
*.props

View File

@ -50,7 +50,7 @@ args = parser.parse_args()
# general variables
include = [ '.', os.path.join('Catch', 'include')]
depends = []
cxxflags = [ '-Wall', '-Wextra', '-pedantic', '-pedantic-errors', '-std=c++11', '-Wno-unused-variable' ]
cxxflags = [ '-Wall', '-Wextra', '-pedantic', '-pedantic-errors', '-std=c++14', '-Wno-unused-variable' ]
ldflags = []
script_dir = os.path.dirname(os.path.realpath(sys.argv[0]))
sol_dir = os.path.join(script_dir, 'sol')

View File

@ -226,7 +226,7 @@ struct pusher<function_sig<Sigs...>> {
template<typename R, typename... Args, typename Fx, typename = std::result_of_t<Fx(Args...)>>
static void set_memfx(types<R(Args...)> t, lua_State* L, Fx&& fx) {
typedef Decay<Unwrap<Unqualified<Fx>>> raw_fx_t;
typedef std::decay_t<Unwrapped<Unqualified<Fx>>> raw_fx_t;
typedef R(* fx_ptr_t)(Args...);
typedef std::is_convertible<raw_fx_t, fx_ptr_t> is_convertible;
set_isconvertible_fx(is_convertible(), t, L, std::forward<Fx>(fx));
@ -234,7 +234,7 @@ struct pusher<function_sig<Sigs...>> {
template<typename Fx>
static void set_memfx(types<>, lua_State* L, Fx&& fx) {
typedef Unwrap<Unqualified<Fx>> fx_t;
typedef Unwrapped<Unqualified<Fx>> fx_t;
typedef decltype(&fx_t::operator()) Sig;
set_memfx(types<function_signature_t<Sig>>(), L, std::forward<Fx>(fx));
}
@ -269,13 +269,13 @@ struct pusher<function_sig<Sigs...>> {
template<typename Fx, typename R, typename... Args>
static void set_isconvertible_fx(std::true_type, types<R(Args...)>, lua_State* L, Fx&& fx) {
typedef R(* fx_ptr_t)(Args...);
fx_ptr_t fxptr = unwrapper(std::forward<Fx>(fx));
fx_ptr_t fxptr = unwrap(std::forward<Fx>(fx));
set(L, fxptr);
}
template<typename Fx, typename R, typename... Args>
static void set_isconvertible_fx(std::false_type, types<R(Args...)>, lua_State* L, Fx&& fx) {
typedef Unwrap<Decay<Fx>> fx_t;
typedef Unwrapped<std::decay_t<Fx>> fx_t;
std::unique_ptr<base_function> sptr(new functor_function<fx_t>(std::forward<Fx>(fx)));
set_fx<Fx>(L, std::move(sptr));
}
@ -287,7 +287,7 @@ struct pusher<function_sig<Sigs...>> {
template<typename Fx, typename T>
static void set_reference_fx(std::false_type, lua_State* L, Fx&& fx, T&& obj) {
typedef std::remove_pointer_t<Decay<Fx>> clean_fx;
typedef std::remove_pointer_t<std::decay_t<Fx>> clean_fx;
std::unique_ptr<base_function> sptr(new member_function<clean_fx, Unqualified<T>>(std::forward<T>(obj), std::forward<Fx>(fx)));
return set_fx<Fx>(L, std::move(sptr));
}
@ -299,12 +299,12 @@ struct pusher<function_sig<Sigs...>> {
// idx n + 1: is the object's void pointer
// We don't need to store the size, because the other side is templated
// with the same member function pointer type
typedef Decay<Fx> dFx;
typedef std::decay_t<Fx> dFx;
typedef Unqualified<Fx> uFx;
dFx memfxptr(std::forward<Fx>(fx));
auto userptr = sol::detail::get_ptr(obj);
void* userobjdata = static_cast<void*>(userptr);
lua_CFunction freefunc = &static_member_function<Decay<decltype(*userptr)>, uFx>::call;
lua_CFunction freefunc = &static_member_function<std::decay_t<decltype(*userptr)>, uFx>::call;
int upvalues = stack::detail::push_as_upvalues(L, memfxptr);
upvalues += stack::push(L, userobjdata);
@ -314,7 +314,7 @@ struct pusher<function_sig<Sigs...>> {
template<typename Fx>
static void set_fx(std::false_type, lua_State* L, Fx&& fx) {
Decay<Fx> target(std::forward<Fx>(fx));
std::decay_t<Fx> target(std::forward<Fx>(fx));
lua_CFunction freefunc = &static_function<Fx>::call;
int upvalues = stack::detail::push_as_upvalues(L, target);

View File

@ -28,12 +28,19 @@
namespace sol {
namespace detail {
struct ref_call_t {
ref_call_t() {}
struct ref_call_t {} const ref_call = ref_call_t{};
template <typename T>
struct implicit_wrapper {
T& item;
implicit_wrapper(T& item) : item(item) {}
operator T& () {
return item;
}
operator T* () {
return std::addressof(item);
}
};
const auto ref_call = ref_call_t{};
template <typename Sig, typename... Args>
struct function_packer : std::tuple<Args...> { using std::tuple<Args...>::tuple; };
@ -51,8 +58,8 @@ struct functor {
T* item;
Func invocation;
template<typename... FxArgs>
functor(FxArgs&&... fxargs): item(nullptr), invocation(std::forward<FxArgs>(fxargs)...) {}
template<typename... Args>
functor(Args&&... args): item(nullptr), invocation(std::forward<Args>(args)...) {}
bool check () const {
return invocation != nullptr;
@ -71,7 +78,7 @@ struct functor {
}
template<typename... Args>
auto operator()(Args&&... args) -> decltype(std::declval<functor>().call(types<return_type>{}, std::forward<Args>(args)...)) {
decltype(auto) operator()(Args&&... args) {
return this->call(types<return_type>{}, std::forward<Args>(args)...);
}
};
@ -138,13 +145,13 @@ public:
template<typename... Args>
void call(types<void>, Args&&... args) {
T& member = *item;
invocation(member, std::forward<Args>(args)...);
invocation(implicit_wrapper<T>(member), std::forward<Args>(args)...);
}
template<typename Ret, typename... Args>
Ret call(types<Ret>, Args&&... args) {
T& member = *item;
return invocation(member, std::forward<Args>(args)...);
return invocation(implicit_wrapper<T>(member), std::forward<Args>(args)...);
}
template<typename... Args>
@ -154,7 +161,6 @@ public:
};
} // detail
template<typename Function>
struct static_function {
typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
@ -168,16 +174,10 @@ struct static_function {
return 0;
}
template<typename... Args>
static int typed_call(types<>, types<Args...> t, function_type* fx, lua_State* L) {
return typed_call(types<void>(), t, fx, L);
}
template<typename... Ret, typename... Args>
static int typed_call(types<Ret...>, types<Args...> ta, function_type* fx, lua_State* L) {
typedef return_type_t<Ret...> return_type;
typedef decltype(stack::call(L, 0, types<return_type>(), ta, fx)) ret_t;
ret_t r = stack::call(L, 0, types<return_type>(), ta, fx);
decltype(auto) r = stack::call(L, 0, types<return_type>(), ta, fx);
int nargs = static_cast<int>(sizeof...(Args));
lua_pop(L, nargs);
return stack::push(L, std::forward<decltype(r)>(r));
@ -209,19 +209,13 @@ struct static_member_function {
return 0;
}
template<typename... Args>
static int typed_call(types<>, types<Args...> t, T& item, function_type& ifx, lua_State* L) {
return typed_call(types<void>(), t, item, ifx, L);
}
template<typename... Ret, typename... Args>
static int typed_call(types<Ret...> tr, types<Args...> ta, T& item, function_type& ifx, lua_State* L) {
typedef return_type_t<Ret...> return_type;
auto fx = [&item, &ifx](Args&&... args) -> return_type { return (item.*ifx)(std::forward<Args>(args)...); };
return_type r = stack::call(L, 0, tr, ta, fx);
decltype(auto) r = stack::call(L, 0, tr, ta, fx);
int nargs = static_cast<int>(sizeof...(Args));
lua_pop(L, nargs);
return stack::push(L, std::forward<return_type>(r));
return stack::push(L, std::forward<decltype(r)>(r));
}
static int call(lua_State* L) {
@ -311,7 +305,7 @@ struct base_function {
}
static int gc(lua_State* L) {
func_gc<I>(std::integral_constant<bool, (I < 1)>(), L);
func_gc<I>(Bool<(I < 1)>(), L);
return 0;
}
};
@ -334,8 +328,8 @@ struct functor_function : public base_function {
typedef function_args_t<function_type> args_type;
Function fx;
template<typename... FxArgs>
functor_function(FxArgs&&... fxargs): fx(std::forward<FxArgs>(fxargs)...) {}
template<typename... Args>
functor_function(Args&&... args): fx(std::forward<Args>(args)...) {}
template<typename... Args>
int operator()(types<void> r, types<Args...> t, lua_State* L) {
@ -345,11 +339,6 @@ struct functor_function : public base_function {
return 0;
}
template<typename... Args>
int operator()(types<>, types<Args...> t, lua_State* L) {
return (*this)(types<void>(), t, L);
}
template<typename... Ret, typename... Args>
int operator()(types<Ret...> tr, types<Args...> ta, lua_State* L) {
return_type r = stack::call(L, 0, tr, ta, fx);
@ -376,18 +365,18 @@ struct member_function : public base_function {
T member;
function_type invocation;
template<typename Tm, typename... FxArgs>
functor(Tm&& m, FxArgs&&... fxargs): member(std::forward<Tm>(m)), invocation(std::forward<FxArgs>(fxargs)...) {}
template<typename Tm, typename... Args>
functor(Tm&& m, Args&&... args): member(std::forward<Tm>(m)), invocation(std::forward<Args>(args)...) {}
template<typename... Args>
return_type operator()(Args&&... args) {
auto& mem = unwrapper(unref(member));
auto& mem = unwrap(deref(member));
return (mem.*invocation)(std::forward<Args>(args)...);
}
} fx;
template<typename Tm, typename... FxArgs>
member_function(Tm&& m, FxArgs&&... fxargs): fx(std::forward<Tm>(m), std::forward<FxArgs>(fxargs)...) {}
template<typename Tm, typename... Args>
member_function(Tm&& m, Args&&... args): fx(std::forward<Tm>(m), std::forward<Args>(args)...) {}
template<typename... Args>
int operator()(types<void> tr, types<Args...> ta, lua_State* L) {
@ -395,15 +384,9 @@ struct member_function : public base_function {
return 0;
}
template<typename... Args>
int operator()(types<>, types<Args...> t, lua_State* L) {
return (*this)(types<void>(), t, L);
}
template<typename... Ret, typename... Args>
int operator()(types<Ret...> tr, types<Args...> ta, lua_State* L) {
typedef decltype(stack::call(L, 0, tr, ta, fx)) ret_t;
ret_t r = stack::call(L, 0, tr, ta, fx);
decltype(auto) r = stack::call(L, 0, tr, ta, fx);
int nargs = static_cast<int>(sizeof...(Args));
lua_pop(L, nargs);
return stack::push(L, std::forward<decltype(r)>(r));
@ -429,12 +412,12 @@ struct usertype_function_core : public base_function {
fx_t fx;
template<typename... FxArgs>
usertype_function_core(FxArgs&&... fxargs): fx(std::forward<FxArgs>(fxargs)...) {}
template<typename... Args>
usertype_function_core(Args&&... args): fx(std::forward<Args>(args)...) {}
template<typename Return, typename Raw = Unqualified<Return>>
std::enable_if_t<std::is_same<T, Raw>::value, int> push(lua_State* L, Return&& r) {
if(detail::get_ptr(r) == fx.item) {
if(ptr(unwrap(r)) == fx.item) {
// push nothing
// note that pushing nothing with the ':'
// syntax means we leave the instance of what
@ -454,33 +437,22 @@ struct usertype_function_core : public base_function {
}
template<typename... Args>
int call(types<void> r, types<Args...> t, lua_State* L) {
int operator()(types<void> tr, types<Args...> ta, lua_State* L) {
//static const std::size_t skew = static_cast<std::size_t>(std::is_member_object_pointer<function_type>::value);
stack::call(L, 0, r, t, fx);
stack::call(L, 0, tr, ta, fx);
int nargs = static_cast<int>(sizeof...(Args));
lua_pop(L, nargs);
return 0;
}
template<typename... Args>
int call(types<>, types<Args...> t, lua_State* L) {
return this->call(types<void>(), t, L);
}
template<typename... Ret, typename... Args>
int call(types<Ret...> tr, types<Args...> ta, lua_State* L) {
typedef decltype(stack::call(L, 0, tr, ta, fx)) ret_t;
ret_t r = stack::call(L, 0, tr, ta, fx);
int operator()(types<Ret...> tr, types<Args...> ta, lua_State* L) {
decltype(auto) r = stack::call(L, 0, tr, ta, fx);
int nargs = static_cast<int>(sizeof...(Args));
lua_pop(L, nargs);
int pushcount = push(L, std::forward<decltype(r)>(r));
return pushcount;
}
template<typename... Ret, typename... Args>
int operator()(types<Ret...> r, types<Args...> t, lua_State* L) {
return this->call(r, t, L);
}
};
template<typename Function, typename Tp>
@ -494,9 +466,8 @@ struct usertype_function : public usertype_function_core<Function, Tp> {
template<typename... FxArgs>
usertype_function(FxArgs&&... fxargs): base_t(std::forward<FxArgs>(fxargs)...) {}
template<typename Tx>
int fx_call(lua_State* L) {
this->fx.item = detail::get_ptr(stack::get<Tx>(L, 1));
int prelude(lua_State* L) {
this->fx.item = ptr(stack::get<T>(L, 1));
if(this->fx.item == nullptr) {
throw error("userdata for function call is null: are you using the wrong syntax? (use item:function/variable(...) syntax)");
}
@ -504,11 +475,11 @@ struct usertype_function : public usertype_function_core<Function, Tp> {
}
virtual int operator()(lua_State* L) override {
return fx_call<T>(L);
return prelude(L);
}
virtual int operator()(lua_State* L, detail::ref_call_t) override {
return fx_call<T*>(L);
return prelude(L);
}
};
@ -523,9 +494,8 @@ struct usertype_variable_function : public usertype_function_core<Function, Tp>
template<typename... FxArgs>
usertype_variable_function(FxArgs&&... fxargs): base_t(std::forward<FxArgs>(fxargs)...) {}
template<typename Tx>
int fx_call(lua_State* L) {
this->fx.item = detail::get_ptr(stack::get<Tx>(L, 1));
int prelude(lua_State* L) {
this->fx.item = ptr(stack::get<T>(L, 1));
if(this->fx.item == nullptr) {
throw error("userdata for member variable is null");
}
@ -543,11 +513,11 @@ struct usertype_variable_function : public usertype_function_core<Function, Tp>
}
virtual int operator()(lua_State* L) override {
return fx_call<T>(L);
return prelude(L);
}
virtual int operator()(lua_State* L, detail::ref_call_t) override {
return fx_call<T*>(L);
return prelude(L);
}
};
@ -565,41 +535,30 @@ struct usertype_indexing_function : public usertype_function_core<Function, Tp>
template<typename... FxArgs>
usertype_indexing_function(std::string name, FxArgs&&... fxargs): base_t(std::forward<FxArgs>(fxargs)...), name(std::move(name)) {}
template<typename Tx>
int fx_call(lua_State* L) {
int prelude(lua_State* L) {
std::string accessor = stack::get<std::string>(L, 1 - lua_gettop(L));
auto function = functions.find(accessor);
if(function != functions.end()) {
if(function->second.second) {
stack::push<upvalue>(L, function->second.first.get());
if(std::is_same<T*, Tx>::value) {
stack::push(L, &base_function::usertype<0>::ref_call, 1);
}
else {
stack::push(L, &base_function::usertype<0>::call, 1);
}
stack::push(L, &base_function::usertype<0>::ref_call, 1);
return 1;
}
else if(std::is_same<T*, Tx>::value) {
return (*function->second.first)(L, detail::ref_call);
}
else {
return (*function->second.first)(L);
}
return (*function->second.first)(L, detail::ref_call);
}
if (!this->fx.check()) {
throw error("invalid indexing \"" + accessor + "\" on type: " + name);
}
this->fx.item = detail::get_ptr(stack::get<Tx>(L, 1));
this->fx.item = ptr(stack::get<T>(L, 1));
return static_cast<base_t&>(*this)(tuple_types<return_type>(), args_type(), L);
}
virtual int operator()(lua_State* L) override {
return fx_call<T>(L);
return prelude(L);
}
virtual int operator()(lua_State* L, detail::ref_call_t) override {
return fx_call<T*>(L);
return prelude(L);
}
};

View File

@ -86,22 +86,22 @@ public:
template<typename Table, typename Key, typename T>
inline bool operator==(T&& left, const proxy<Table, Key>& right) {
return left == right.template get<Decay<T>>();
return left == right.template get<std::decay_t<T>>();
}
template<typename Table, typename Key, typename T>
inline bool operator==(const proxy<Table, Key>& right, T&& left) {
return right.template get<Decay<T>>() == left;
return right.template get<std::decay_t<T>>() == left;
}
template<typename Table, typename Key, typename T>
inline bool operator!=(T&& left, const proxy<Table, Key>& right) {
return right.template get<Decay<T>>() != left;
return right.template get<std::decay_t<T>>() != left;
}
template<typename Table, typename Key, typename T>
inline bool operator!=(const proxy<Table, Key>& right, T&& left) {
return right.template get<Decay<T>>() != left;
return right.template get<std::decay_t<T>>() != left;
}
} // sol

View File

@ -33,23 +33,6 @@
#include <functional>
namespace sol {
namespace detail {
template<typename T>
inline T* get_ptr(T& val) {
return std::addressof(val);
}
template<typename T>
inline T* get_ptr(std::reference_wrapper<T> val) {
return std::addressof(val.get());
}
template<typename T>
inline T* get_ptr(T* val) {
return val;
}
} // detail
namespace stack {
template<typename T, typename = void>
@ -137,10 +120,10 @@ template <typename T>
struct userdata_pusher {
template <typename Key, typename... Args>
static void push (lua_State* L, Key&& metatablekey, Args&&... args) {
// Basically, we store all data like this:
// If it's a new value (no std::ref(x)), then we store the pointer to the new
// Basically, we store all user0data like this:
// If it's a movable/copyable value (no std::ref(x)), then we store the pointer to the new
// data in the first sizeof(T*) bytes, and then however many bytes it takes to
// do the actual object. Things that are just references/pointers are stored as
// do the actual object. Things that are std::ref or plain T* are stored as
// just the sizeof(T*), and nothing else.
T** pdatum = static_cast<T**>(lua_newuserdata(L, sizeof(T*) + sizeof(T)));
T** referencepointer = pdatum;
@ -624,12 +607,12 @@ inline void remove( lua_State* L, int index, int count ) {
}
}
template <bool checkargs = detail::default_check_arguments, typename R, typename... Args, typename Fx, typename... FxArgs, typename = typename std::enable_if<!std::is_void<R>::value>::type>
template <bool checkargs = detail::default_check_arguments, typename R, typename... Args, typename Fx, typename... FxArgs, typename = std::enable_if_t<!std::is_void<R>::value>>
inline R call(lua_State* L, int start, types<R> tr, types<Args...> ta, Fx&& fx, FxArgs&&... args) {
return detail::call<checkargs>(L, start, ta, tr, ta, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
}
template <bool checkargs = detail::default_check_arguments, typename R, typename... Args, typename Fx, typename... FxArgs, typename = typename std::enable_if<!std::is_void<R>::value>::type>
template <bool checkargs = detail::default_check_arguments, typename R, typename... Args, typename Fx, typename... FxArgs, typename = std::enable_if_t<!std::is_void<R>::value>>
inline R call(lua_State* L, types<R> tr, types<Args...> ta, Fx&& fx, FxArgs&&... args) {
return call<checkargs>(L, 0, ta, tr, ta, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
}

View File

@ -150,9 +150,9 @@ public:
return globals.get<Args...>(std::forward<Keys>(keys)...);
}
template<typename... Tn>
state_view& set(Tn&&... argn) {
globals.set(std::forward<Tn>(argn)...);
template<typename... Args>
state_view& set(Args&&... args) {
globals.set(std::forward<Args>(args)...);
return *this;
}
@ -214,11 +214,11 @@ public:
return result;
}
template <typename... Tn>
table create_table(int narr = 0, int nrec = sizeof...(Tn), Tn&&... argn) {
template <typename... Args>
table create_table(int narr = 0, int nrec = sizeof...(Args), Args&&... args) {
lua_createtable(L, narr, nrec);
table result(L);
result.set(std::forward<Tn>(argn)...);
result.set(std::forward<Args>(args)...);
lua_pop(L, 1);
return result;
}

View File

@ -114,9 +114,9 @@ public:
return tuple_get( types<Ret...>( ), build_indices<sizeof...( Ret )>( ), std::forward_as_tuple(std::forward<Keys>(keys)...));
}
template<typename... Tn>
table_core& set( Tn&&... argn ) {
tuple_set(build_indices<sizeof...(Tn) / 2>(), std::forward_as_tuple(std::forward<Tn>(argn)...));
template<typename... Args>
table_core& set( Args&&... args ) {
tuple_set(build_indices<sizeof...(Args) / 2>(), std::forward_as_tuple(std::forward<Args>(args)...));
return *this;
}
@ -214,7 +214,7 @@ private:
template<typename Fx, typename Key>
void set_fx( types<>, Key&& key, Fx&& fx ) {
typedef Unqualified<Unwrap<Fx>> fx_t;
typedef Unwrapped<Unqualified<Fx>> fx_t;
typedef decltype( &fx_t::operator() ) Sig;
set_fx( types<function_signature_t<Sig>>( ), std::forward<Key>( key ), std::forward<Fx>( fx ) );
}

View File

@ -31,6 +31,9 @@ namespace sol {
template<typename T>
struct identity { typedef T type; };
template<typename T>
using identity_t = typename identity<T>::type;
template<typename... Args>
struct is_tuple : std::false_type{ };
@ -38,12 +41,12 @@ template<typename... Args>
struct is_tuple<std::tuple<Args...>> : std::true_type{ };
template<typename T>
struct unwrap {
struct unwrapped {
typedef T type;
};
template<typename T>
struct unwrap<std::reference_wrapper<T>> {
struct unwrapped<std::reference_wrapper<T>> {
typedef T type;
};
@ -55,6 +58,14 @@ struct remove_member_pointer<R T::*> {
typedef R type;
};
template<typename R, typename T>
struct remove_member_pointer<R T::* const> {
typedef R type;
};
template<typename T>
using remove_member_pointer_t = remove_member_pointer<T>;
template<typename T, template<typename...> class Templ>
struct is_specialization_of : std::false_type { };
template<typename... T, template<typename...> class Templ>
@ -100,13 +111,10 @@ template<typename... Args>
using DisableIf = typename std::enable_if<Not<And<Args...>>::value, int>::type;
template<typename T>
using Unqualified = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
using Unqualified = std::remove_cv_t<std::remove_reference_t<T>>;
template<typename T>
using Decay = typename std::decay<T>::type;
template<typename T>
using Unwrap = typename unwrap<T>::type;
using Unwrapped = typename unwrapped<T>::type;
template<typename... Args>
struct return_type {
@ -126,16 +134,16 @@ struct return_type<> {
template <typename... Args>
using return_type_t = typename return_type<Args...>::type;
template <typename Empty, typename... Tn>
using ReturnTypeOr = typename std::conditional<(sizeof...(Tn) < 1), Empty, typename return_type<Tn...>::type>::type;
template <typename Empty, typename... Args>
using ReturnTypeOr = typename std::conditional<(sizeof...(Args) < 1), Empty, typename return_type<Args...>::type>::type;
template <typename... Tn>
using ReturnType = ReturnTypeOr<void, Tn...>;
template <typename... Args>
using ReturnType = ReturnTypeOr<void, Args...>;
namespace detail {
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<std::remove_pointer_t<T>> {};
template<typename T>
struct is_function_impl<T, true> {
@ -192,12 +200,12 @@ struct fx_traits<R(T::*)(Args...), false> {
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 std::remove_pointer_t<function_pointer_type> function_type;
typedef R(*free_function_pointer_type)(Args...);
typedef R return_type;
typedef typename std::remove_pointer<free_function_pointer_type>::type signature_type;
typedef std::remove_pointer_t<free_function_pointer_type> signature_type;
template<std::size_t i>
using arg = typename std::tuple_element<i, arg_tuple_type>::type;
using arg = std::tuple_element_t<i, arg_tuple_type>;
};
template<typename T, typename R, typename... Args>
@ -207,12 +215,12 @@ struct fx_traits<R(T::*)(Args...) const, false> {
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 std::remove_pointer_t<function_pointer_type> function_type;
typedef R(*free_function_pointer_type)(Args...);
typedef R return_type;
typedef typename std::remove_pointer<free_function_pointer_type>::type signature_type;
typedef std::remove_pointer_t<free_function_pointer_type> signature_type;
template<std::size_t i>
using arg = typename std::tuple_element<i, arg_tuple_type>::type;
using arg = std::tuple_element_t<i, arg_tuple_type>;
};
template<typename R, typename... Args>
@ -225,9 +233,9 @@ struct fx_traits<R(Args...), false> {
typedef R(*function_pointer_type)(Args...);
typedef R(*free_function_pointer_type)(Args...);
typedef R return_type;
typedef typename std::remove_pointer<free_function_pointer_type>::type signature_type;
typedef std::remove_pointer_t<free_function_pointer_type> signature_type;
template<std::size_t i>
using arg = typename std::tuple_element<i, arg_tuple_type>::type;
using arg = std::tuple_element_t<i, arg_tuple_type>;
};
template<typename R, typename... Args>
@ -240,9 +248,9 @@ struct fx_traits<R(*)(Args...), false> {
typedef R(*function_pointer_type)(Args...);
typedef R(*free_function_pointer_type)(Args...);
typedef R return_type;
typedef typename std::remove_pointer<free_function_pointer_type>::type signature_type;
typedef std::remove_pointer_t<free_function_pointer_type> signature_type;
template<std::size_t i>
using arg = typename std::tuple_element<i, arg_tuple_type>::type;
using arg = std::tuple_element_t<i, arg_tuple_type>;
};
} // detail
@ -279,7 +287,7 @@ struct member_traits<Signature, true> {
typedef R(*function_pointer_type)(Arg);
typedef R(*free_function_pointer_type)(Arg);
template<std::size_t i>
using arg = typename std::tuple_element<i, arg_tuple_type>::type;
using arg = std::tuple_element_t<i, arg_tuple_type>;
};
} // detail
@ -322,43 +330,58 @@ template <typename T>
using is_c_str = Or<std::is_same<std::decay_t<Unqualified<T>>, char*>, std::is_same<Unqualified<T>, std::string>>;
template<typename T>
auto unwrapper(T&& item) -> decltype(std::forward<T>(item)) {
auto unwrap(T&& item) -> decltype(std::forward<T>(item)) {
return std::forward<T>(item);
}
template<typename Arg>
Arg& unwrapper(std::reference_wrapper<Arg> arg) {
template<typename T>
T& unwrap(std::reference_wrapper<T> arg) {
return arg.get();
}
template<typename T>
T& unref(T& item) {
T& deref(T& item) {
return item;
}
template<typename T>
T& unref(T* item) {
T& deref(T* item) {
return *item;
}
template<typename T, typename Dx>
decltype(auto) deref(std::unique_ptr<T, Dx>& item) {
return *item;
}
template<typename T>
T& unref(std::unique_ptr<T>& item) {
T& deref(std::shared_ptr<T>& item) {
return *item;
}
template<typename T, typename Dx>
decltype(auto) deref(const std::unique_ptr<T, Dx>& item) {
return *item;
}
template<typename T>
T& unref(std::shared_ptr<T>& item) {
T& deref(const std::shared_ptr<T>& item) {
return *item;
}
template<typename T>
T& unref(const std::unique_ptr<T>& item) {
return *item;
inline T* ptr(T& val) {
return std::addressof(val);
}
template<typename T>
T& unref(const std::shared_ptr<T>& item) {
return *item;
inline T* ptr(std::reference_wrapper<T> val) {
return std::addressof(val.get());
}
template<typename T>
inline T* ptr(T* val) {
return val;
}
} // sol

View File

@ -29,6 +29,9 @@ namespace sol {
template<typename... Ts>
struct reverse_tuple;
template<typename... Ts>
using reverse_tuple_t = typename reverse_tuple<Ts...>::type;
template<>
struct reverse_tuple<std::tuple<>> {
using type = std::tuple<>;
@ -57,7 +60,7 @@ template<size_t... Ns>
struct build_reverse_indices<0, Ns...> : indices<Ns...> {};
template<typename... Args>
struct types : build_indices<sizeof...(Args)> { typedef types type; };
struct types : build_indices<sizeof...(Args)> { typedef types type; static constexpr std::size_t size() { return sizeof...(Args); } };
namespace detail {
template<class Acc, class... Args>
@ -91,8 +94,8 @@ using tuple_types_t = typename tuple_types<Args...>::type;
template<typename Arg>
struct remove_one_type : detail::chop_one<Arg> {};
template<typename... Tn>
struct constructors {};
template<typename... Args>
using constructors = sol::types<Args...>;
const auto default_constructor = constructors<types<>>{};

View File

@ -25,7 +25,6 @@
#include "compatibility.hpp"
#include "traits.hpp"
#include <string>
#include "traits.hpp"
namespace sol {
struct nil_t {};
@ -172,7 +171,7 @@ template <typename T>
struct lua_type_of<T*> : std::integral_constant<type, type::userdata> {};
template <typename T>
struct lua_type_of<T, typename std::enable_if<std::is_arithmetic<T>::value>::type> : std::integral_constant<type, type::number> {};
struct lua_type_of<T, std::enable_if_t<std::is_arithmetic<T>::value>> : std::integral_constant<type, type::number> {};
template<typename T>
inline type type_of() {
@ -186,7 +185,7 @@ inline type type_of(lua_State* L, int index) {
// All enumerations are given and taken from lua
// as numbers as well
template <typename T>
struct lua_type_of<T, typename std::enable_if<std::is_enum<T>::value>::type> : std::integral_constant<type, type::number> {
struct lua_type_of<T, std::enable_if_t<std::is_enum<T>::value>> : std::integral_constant<type, type::number> {
};
@ -199,8 +198,8 @@ struct is_proxy_primitive : is_lua_primitive<T> { };
template <typename T>
struct is_proxy_primitive<std::reference_wrapper<T>> : std::true_type { };
template <typename... Tn>
struct is_proxy_primitive<std::tuple<Tn...>> : std::true_type { };
template <typename... Args>
struct is_proxy_primitive<std::tuple<Args...>> : std::true_type { };
} // sol
#endif // SOL_TYPES_HPP

View File

@ -129,7 +129,7 @@ private:
T*& referencereference = *referencepointer;
T* obj = reinterpret_cast<T*>(referencepointer + 1);
referencereference = obj;
match_constructor(L, obj, syntax, argcount - static_cast<int>(syntax), typename identity<TTypes>::type()...);
match_constructor(L, obj, syntax, argcount - static_cast<int>(syntax), identity_t<TTypes>()...);
if(luaL_newmetatable(L, std::addressof(meta[0])) == 1) {
lua_pop(L, 1);
@ -143,17 +143,16 @@ private:
}
};
struct destructor {
static int destruct(lua_State* L) {
userdata udata = stack::get<userdata>(L, 1);
// The first sizeof(T*) bytes are the reference: the rest is
// the actual data itself
T* obj = static_cast<T*>(static_cast<void*>(reinterpret_cast<char*>(udata.value) + sizeof(T*)));
std::allocator<T> alloc{};
alloc.destroy(obj);
return 0;
}
};
static int destruct(lua_State* L) {
userdata udata = stack::get<userdata>(L, 1);
// The first sizeof(T*) bytes are the reference: the rest is
// the actual data itself (if there is a reference at all)
T** pobj = reinterpret_cast<T**>(udata.value);
T*& obj = *pobj;
std::allocator<T> alloc{};
alloc.destroy(obj);
return 0;
}
template<std::size_t N>
void build_cleanup() {
@ -218,7 +217,7 @@ private:
template<std::size_t N, typename Base, typename Ret>
bool build_function(std::true_type, function_map_t*&, function_map_t*&, std::string funcname, Ret Base::* func) {
static_assert(std::is_base_of<Base, T>::value, "Any registered function must be part of the class");
typedef typename std::decay<decltype(func)>::type function_type;
typedef std::decay_t<decltype(func)> function_type;
indexmetafunctions.emplace(funcname, std::make_pair(detail::make_unique<usertype_variable_function<function_type, T>>(func), false));
newindexmetafunctions.emplace(funcname, std::make_pair(detail::make_unique<usertype_variable_function<function_type, T>>(func), false));
return false;
@ -228,43 +227,43 @@ private:
std::unique_ptr<base_function> make_function(const std::string&, Ret(*func)(Arg, Args...)) {
typedef Unqualified<Arg> Argu;
static_assert(std::is_base_of<Argu, T>::value, "Any non-member-function must have a first argument which is covariant with the desired userdata type.");
typedef typename std::decay<decltype(func)>::type function_type;
return detail::make_unique<usertype_function<function_type, T>>(func);
typedef std::decay_t<decltype(func)> function_type;
return std::make_unique<usertype_function<function_type, T>>(func);
}
template<typename Base, typename Ret>
std::unique_ptr<base_function> make_variable_function(std::true_type, const std::string&, Ret Base::* func) {
static_assert(std::is_base_of<Base, T>::value, "Any registered function must be part of the class");
typedef typename std::decay<decltype(func)>::type function_type;
return detail::make_unique<usertype_variable_function<function_type, T>>(func);
typedef std::decay_t<decltype(func)> function_type;
return std::make_unique<usertype_variable_function<function_type, T>>(func);
}
template<typename Base, typename Ret>
std::unique_ptr<base_function> make_variable_function(std::false_type, const std::string&, Ret Base::* func) {
static_assert(std::is_base_of<Base, T>::value, "Any registered function must be part of the class");
typedef typename std::decay<decltype(func)>::type function_type;
return detail::make_unique<usertype_function<function_type, T>>(func);
typedef std::decay_t<decltype(func)> function_type;
return std::make_unique<usertype_function<function_type, T>>(func);
}
template<typename Base, typename Ret>
std::unique_ptr<base_function> make_function(const std::string& name, Ret Base::* func) {
typedef typename std::decay<decltype(func)>::type function_type;
typedef std::decay_t<decltype(func)> function_type;
return make_variable_function(std::is_member_object_pointer<function_type>(), name, func);
}
template<typename Fx>
std::unique_ptr<base_function> make_function(const std::string&, Fx&& func) {
typedef Unqualified<Fx> Fxu;
typedef typename std::tuple_element<0, typename function_traits<Fxu>::arg_tuple_type>::type TArg;
typedef Unqualified<TArg> TArgu;
static_assert(std::is_base_of<TArgu, T>::value, "Any non-member-function must have a first argument which is covariant with the desired userdata type.");
typedef typename std::decay<decltype(func)>::type function_type;
return detail::make_unique<usertype_function<function_type, T>>(func);
typedef std::tuple_element_t<0, typename function_traits<Fxu>::arg_tuple_type> Arg;
typedef Unqualified<Arg> Argu;
static_assert(std::is_base_of<Argu, T>::value, "Any non-member-function must have a first argument which is covariant with the desired usertype.");
typedef std::decay_t<Fxu> function_type;
return std::make_unique<usertype_function<function_type, T>>(func);
}
template<std::size_t N, typename Fx>
bool build_function(std::false_type, function_map_t*& index, function_map_t*& newindex, std::string funcname, Fx&& func) {
typedef typename std::decay<Fx>::type function_type;
typedef std::decay_t<Fx> function_type;
auto metamethod = std::find(meta_function_names.begin(), meta_function_names.end(), funcname);
if(metamethod != meta_function_names.end()) {
functionnames.push_back(std::move(funcname));
@ -300,7 +299,7 @@ private:
template<std::size_t N, typename Fx, typename... Args>
void build_function_tables(function_map_t*& index, function_map_t*& newindex, std::string funcname, Fx&& func, Args&&... args) {
typedef typename std::is_member_object_pointer<Unqualified<Fx>>::type is_variable;
typedef std::is_member_object_pointer<Unqualified<Fx>> is_variable;
static const std::size_t V = static_cast<std::size_t>(!is_variable::value);
if(build_function<N>(is_variable(), index, newindex, std::move(funcname), std::forward<Fx>(func))) {
build_function_tables<N + V>(index, newindex, std::forward<Args>(args)...);
@ -347,7 +346,7 @@ public:
functionnames.push_back("new");
metafunctiontable.push_back({ functionnames.back().c_str(), &constructor<CArgs...>::construct });
functionnames.push_back("__gc");
metafunctiontable.push_back({ functionnames.back().c_str(), &destructor::destruct });
metafunctiontable.push_back({ functionnames.back().c_str(), destruct });
// ptr_functions does not participate in garbage collection/new,
// as all pointered types are considered
// to be references. This makes returns of
@ -384,7 +383,7 @@ private:
void set_global_deleter(lua_State* L) {
// Automatic deleter table -- stays alive until lua VM dies
// even if the user calls collectgarbage()
// even if the user calls collectgarbage(), weirdly enough
lua_createtable(L, 0, 0);
lua_createtable(L, 0, 1);
int up = push_upvalues<true>(L, metafunctions);