decay to std::string instead of char*, as its both safer (protects against early stack pops) and is handled better by g++'s new std::string conversion constructors

Make sure we're only using C++11 features (no decltype(auto))
This commit is contained in:
ThePhD 2015-10-25 06:48:19 -04:00
parent 34af96214b
commit e84cf66683
4 changed files with 30 additions and 27 deletions

View File

@ -60,25 +60,25 @@ public:
function_result& operator=(const function_result&) = default; function_result& operator=(const function_result&) = default;
function_result(function_result&& o) : L(o.L), index(o.index), returncount(o.returncount), error(o.error) { function_result(function_result&& o) : L(o.L), index(o.index), returncount(o.returncount), error(o.error) {
// Must be manual, otherwise destructor will screw us // Must be manual, otherwise destructor will screw us
// return count being 0 is enough to keep things clean // return count being 0 is enough to keep things clean
// but will be thorough // but will be thorough
o.L = nullptr; o.L = nullptr;
o.index = 0; o.index = 0;
o.returncount = 0; o.returncount = 0;
o.error = call_error::runtime; o.error = call_error::runtime;
} }
function_result& operator=(function_result&& o) { function_result& operator=(function_result&& o) {
L = o.L; L = o.L;
index = o.index; index = o.index;
returncount = o.returncount; returncount = o.returncount;
error = o.error; error = o.error;
// Must be manual, otherwise destructor will screw us // Must be manual, otherwise destructor will screw us
// return count being 0 is enough to keep things clean // return count being 0 is enough to keep things clean
// but will be thorough // but will be thorough
o.L = nullptr; o.L = nullptr;
o.index = 0; o.index = 0;
o.returncount = 0; o.returncount = 0;
o.error = call_error::runtime; o.error = call_error::runtime;
} }
bool valid() const { bool valid() const {
@ -91,8 +91,8 @@ public:
return get(tr, tr); return get(tr, tr);
} }
operator const char* () const { operator std::string() const {
return get<const char*>(); return get<std::string>();
} }
template<typename T, EnableIf<Not<std::is_same<Unqualified<T>, const char*>>, Not<std::is_same<Unqualified<T>, char>>, Not<std::is_same<Unqualified<T>, std::string>>, Not<std::is_same<Unqualified<T>, std::initializer_list<char>>>> = 0> template<typename T, EnableIf<Not<std::is_same<Unqualified<T>, const char*>>, Not<std::is_same<Unqualified<T>, char>>, Not<std::is_same<Unqualified<T>, std::string>>, Not<std::is_same<Unqualified<T>, std::initializer_list<char>>>> = 0>
@ -210,13 +210,13 @@ public:
template<typename... Ret, typename... Args> template<typename... Ret, typename... Args>
auto operator()(types<Ret...>, Args&&... args) const auto operator()(types<Ret...>, Args&&... args) const
-> decltype(call<Ret...>(std::forward<Args>(args)...)) { -> decltype(invoke(types<Ret...>(), types<Ret...>(), 0, std::declval<handler&>())) {
return call<Ret...>(std::forward<Args>(args)...); return call<Ret...>(std::forward<Args>(args)...);
} }
template<typename... Ret, typename... Args> template<typename... Ret, typename... Args>
auto call(Args&&... args) const auto call(Args&&... args) const
-> decltype(invoke(types<Ret...>(), types<Ret...>(), 0, std::declval<handler>())) { -> decltype(invoke(types<Ret...>(), types<Ret...>(), 0, std::declval<handler&>())) {
handler h(error_handler); handler h(error_handler);
push(); push();
int pushcount = stack::push_args(state(), std::forward<Args>(args)...); int pushcount = stack::push_args(state(), std::forward<Args>(args)...);

View File

@ -168,7 +168,8 @@ struct static_function {
template<typename... Ret, typename... Args> template<typename... Ret, typename... Args>
static int typed_call(types<Ret...>, types<Args...> ta, function_type* fx, lua_State* L) { static int typed_call(types<Ret...>, types<Args...> ta, function_type* fx, lua_State* L) {
typedef typename return_type<Ret...>::type return_type; typedef typename return_type<Ret...>::type return_type;
decltype(auto) r = stack::call(L, 0, types<return_type>(), ta, fx); 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);
int nargs = static_cast<int>(sizeof...(Args)); int nargs = static_cast<int>(sizeof...(Args));
lua_pop(L, nargs); lua_pop(L, nargs);
return stack::push(L, std::forward<decltype(r)>(r)); return stack::push(L, std::forward<decltype(r)>(r));
@ -392,7 +393,8 @@ struct member_function : public base_function {
template<typename... Ret, typename... Args> template<typename... Ret, typename... Args>
int operator()(types<Ret...> tr, types<Args...> ta, lua_State* L) { int operator()(types<Ret...> tr, types<Args...> ta, lua_State* L) {
decltype(auto) r = stack::call(L, 0, tr, ta, fx); typedef decltype(stack::call(L, 0, tr, ta, fx)) ret_t;
ret_t r = stack::call(L, 0, tr, ta, fx);
int nargs = static_cast<int>(sizeof...(Args)); int nargs = static_cast<int>(sizeof...(Args));
lua_pop(L, nargs); lua_pop(L, nargs);
return stack::push(L, std::forward<decltype(r)>(r)); return stack::push(L, std::forward<decltype(r)>(r));
@ -458,7 +460,8 @@ struct usertype_function_core : public base_function {
template<typename... Ret, typename... Args> template<typename... Ret, typename... Args>
int call(types<Ret...> tr, types<Args...> ta, lua_State* L) { int call(types<Ret...> tr, types<Args...> ta, lua_State* L) {
decltype(auto) r = stack::call(L, 0, tr, ta, fx); typedef decltype(stack::call(L, 0, tr, ta, fx)) ret_t;
ret_t r = stack::call(L, 0, tr, ta, fx);
int nargs = static_cast<int>(sizeof...(Args)); int nargs = static_cast<int>(sizeof...(Args));
lua_pop(L, nargs); lua_pop(L, nargs);
int pushcount = push(L, std::forward<decltype(r)>(r)); int pushcount = push(L, std::forward<decltype(r)>(r));

View File

@ -67,8 +67,8 @@ public:
return tbl.template get<T>( key ); return tbl.template get<T>( key );
} }
operator const char* () const { operator std::string() const {
return get<const char*>(); return get<std::string>();
} }
template<typename T, EnableIf<Not<std::is_same<Unqualified<T>, const char*>>, Not<std::is_same<Unqualified<T>, char>>, Not<std::is_same<Unqualified<T>, std::string>>, Not<std::is_same<Unqualified<T>, std::initializer_list<char>>>> = 0> template<typename T, EnableIf<Not<std::is_same<Unqualified<T>, const char*>>, Not<std::is_same<Unqualified<T>, char>>, Not<std::is_same<Unqualified<T>, std::string>>, Not<std::is_same<Unqualified<T>, std::initializer_list<char>>>> = 0>

View File

@ -1009,7 +1009,7 @@ TEST_CASE( "functions/sol::function_result", "Function result should be the beef
// Some function; just using a lambda to be cheap // Some function; just using a lambda to be cheap
auto doom = []() { auto doom = []() {
// Bypasses handler function: puts information directly into lua error // Bypasses handler function: puts information directly into lua error
throw std::exception( errormessage1 ); throw std::runtime_error( errormessage1 );
}; };
auto luadoom = [&lua]() { auto luadoom = [&lua]() {
// Does not bypass error function, will call it // Does not bypass error function, will call it