diff --git a/include/sqrat/sqratGlobalMethods.h b/include/sqrat/sqratGlobalMethods.h index 319fe1fe..5ee86644 100644 --- a/include/sqrat/sqratGlobalMethods.h +++ b/include/sqrat/sqratGlobalMethods.h @@ -46,18 +46,15 @@ namespace Sqrat { // template struct SqGlobalProxy { template static SQInteger Run(HSQUIRRELVM vm, SQInteger idx) { - ArgPop a(vm, idx); - if (SQ_FAILED(a.Proc(sq_gettop(vm) == idx - 1 + static_cast< SQInteger >(sizeof...(A))))) { - return a.ProcRes(); - } - a.Call(vm, [](HSQUIRRELVM vm, A... a) { + ArgFwd a{SQ_OK}; + a.Call(vm, idx, [](HSQUIRRELVM vm, A... a) { typedef R(*M)(A...); M* method; sq_getuserdata(vm, -1, reinterpret_cast(&method), nullptr); R ret = (*method)(a...); PushVar(vm, ret); }); - return 1; + return SQ_FAILED(a.mRes) ? a.mRes : 1; } }; @@ -67,18 +64,15 @@ template struct SqGlobalProxy { template struct SqGlobalProxy { template static SQInteger Run(HSQUIRRELVM vm, SQInteger idx) { - ArgPop a(vm, idx); - if (SQ_FAILED(a.Proc(sq_gettop(vm) == idx - 1 + static_cast< SQInteger >(sizeof...(A))))) { - return a.ProcRes(); - } - a.Call(vm, [](HSQUIRRELVM vm, A... a) { + ArgFwd a{SQ_OK}; + a.Call(vm, idx, [](HSQUIRRELVM vm, A... a) { typedef R&(*M)(A...); M* method; sq_getuserdata(vm, -1, reinterpret_cast(&method), nullptr); R& ret = (*method)(a...); PushVarR(vm, ret); }); - return 1; + return SQ_FAILED(a.mRes) ? a.mRes : 1; } }; @@ -88,27 +82,24 @@ template struct SqGlobalProxy { template <> struct SqGlobalProxy { template static SQInteger Run(HSQUIRRELVM vm, SQInteger idx) { - ArgPop a(vm, idx); - if (SQ_FAILED(a.Proc(sq_gettop(vm) == idx - 1 + static_cast< SQInteger >(sizeof...(A))))) { - return a.ProcRes(); - } - a.Call(vm, [](HSQUIRRELVM vm, A... a) { + ArgFwd a{SQ_OK}; + a.Call(vm, idx, [](HSQUIRRELVM vm, A... a) { typedef void(*M)(A...); M* method; sq_getuserdata(vm, -1, reinterpret_cast(&method), nullptr); (*method)(a...); }); - return 0; + return SQ_FAILED(a.mRes) ? a.mRes : 0; } }; template struct SqGlobalParamCheck { - static inline bool Invalid(SQInteger top, SQInteger count) { + static inline bool Invalid(SQInteger top, SQInteger count) noexcept { return top != count; } }; template<> struct SqGlobalParamCheck { - static inline bool Invalid(SQInteger top, SQInteger count) { + static inline bool Invalid(SQInteger top, SQInteger count) noexcept { return top < (count - 1); } }; @@ -122,7 +113,7 @@ template struct SqGlobal { return +[](HSQUIRRELVM vm) noexcept -> SQInteger { #if !defined (SCRAT_NO_ERROR_CHECKING) if (!SQRAT_CONST_CONDITION(overloaded) && - SqGlobalParamCheck< ArgPop::HASFMT >::Invalid(sq_gettop(vm), startIdx + sizeof...(A))) { + SqGlobalParamCheck< ArgFwd::HASFMT >::Invalid(sq_gettop(vm), startIdx + sizeof...(A))) { return sq_throwerror(vm, _SC("wrong number of parameters")); } #endif @@ -130,6 +121,8 @@ template struct SqGlobal { return SqGlobalProxy::template Run(vm, startIdx); } catch (const Exception& e) { return sq_throwerror(vm, e.what()); + } catch (...) { + return sq_throwerror(vm, _SC("unknown exception occured")); } SQ_UNREACHABLE }; @@ -146,7 +139,7 @@ template struct SqGlobal { return +[](HSQUIRRELVM vm) noexcept -> SQInteger { #if !defined (SCRAT_NO_ERROR_CHECKING) if (!SQRAT_CONST_CONDITION(overloaded) && - SqGlobalParamCheck< ArgPop::HASFMT >::Invalid(sq_gettop(vm), startIdx + sizeof...(A))) { + SqGlobalParamCheck< ArgFwd::HASFMT >::Invalid(sq_gettop(vm), startIdx + sizeof...(A))) { return sq_throwerror(vm, _SC("wrong number of parameters")); } #endif @@ -154,6 +147,8 @@ template struct SqGlobal { return SqGlobalProxy::template Run(vm, startIdx); } catch (const Exception& e) { return sq_throwerror(vm, e.what()); + } catch (...) { + return sq_throwerror(vm, _SC("unknown exception occured")); } SQ_UNREACHABLE }; @@ -170,7 +165,7 @@ template <> struct SqGlobal { return +[](HSQUIRRELVM vm) noexcept -> SQInteger { #if !defined (SCRAT_NO_ERROR_CHECKING) if (!SQRAT_CONST_CONDITION(overloaded) && - SqGlobalParamCheck< ArgPop::HASFMT >::Invalid(sq_gettop(vm), startIdx + sizeof...(A))) { + SqGlobalParamCheck< ArgFwd::HASFMT >::Invalid(sq_gettop(vm), startIdx + sizeof...(A))) { return sq_throwerror(vm, _SC("wrong number of parameters")); } #endif @@ -178,6 +173,8 @@ template <> struct SqGlobal { return SqGlobalProxy::Run(vm, startIdx); } catch (const Exception& e) { return sq_throwerror(vm, e.what()); + } catch (...) { + return sq_throwerror(vm, _SC("unknown exception occured")); } SQ_UNREACHABLE }; diff --git a/include/sqrat/sqratMemberMethods.h b/include/sqrat/sqratMemberMethods.h index ec675a8b..5eae8817 100644 --- a/include/sqrat/sqratMemberMethods.h +++ b/include/sqrat/sqratMemberMethods.h @@ -46,11 +46,8 @@ namespace Sqrat { // template struct SqMemberProxy { template static SQInteger Run(HSQUIRRELVM vm) noexcept { - ArgPop a(vm, 2); - if (SQ_FAILED(a.Proc(sizeof...(A) == 0 && sq_gettop(vm) == 2))) { - return a.ProcRes(); - } - a.Call(vm, [](HSQUIRRELVM vm, A... a) { + ArgFwd a{SQ_OK}; + a.Call(vm, 2, [](HSQUIRRELVM vm, A... a) { typedef R(C::*M)(A...); C* inst = Var(vm, 1).value; M* methodPtr; @@ -59,14 +56,11 @@ template struct SqMemberProxy { R ret = (inst->*method)(a...); PushVar(vm, ret); }); - return 1; + return SQ_FAILED(a.mRes) ? a.mRes : 1; } template static SQInteger RunC(HSQUIRRELVM vm) noexcept { - ArgPop a(vm, 2); - if (SQ_FAILED(a.Proc(sizeof...(A) == 0 && sq_gettop(vm) == 2))) { - return a.ProcRes(); - } - a.Call(vm, [](HSQUIRRELVM vm, A... a) { + ArgFwd a{SQ_OK}; + a.Call(vm, 2, [](HSQUIRRELVM vm, A... a) { typedef R(C::*M)(A...) const; C* inst = Var(vm, 1).value; M* methodPtr; @@ -75,7 +69,7 @@ template struct SqMemberProxy { R ret = (inst->*method)(a...); PushVar(vm, ret); }); - return 1; + return SQ_FAILED(a.mRes) ? a.mRes : 1; } }; @@ -85,11 +79,8 @@ template struct SqMemberProxy { template struct SqMemberProxy { template static SQInteger Run(HSQUIRRELVM vm) noexcept { - ArgPop a(vm, 2); - if (SQ_FAILED(a.Proc(sizeof...(A) == 0 && sq_gettop(vm) == 2))) { - return a.ProcRes(); - } - a.Call(vm, [](HSQUIRRELVM vm, A... a) { + ArgFwd a{SQ_OK}; + a.Call(vm, 2, [](HSQUIRRELVM vm, A... a) { typedef R&(C::*M)(A...); C* inst = Var(vm, 1).value; M* methodPtr; @@ -98,14 +89,11 @@ template struct SqMemberProxy { R& ret = (inst->*method)(a...); PushVarR(vm, ret); }); - return 1; + return SQ_FAILED(a.mRes) ? a.mRes : 1; } template static SQInteger RunC(HSQUIRRELVM vm) noexcept { - ArgPop a(vm, 2); - if (SQ_FAILED(a.Proc(sizeof...(A) == 0 && sq_gettop(vm) == 2))) { - return a.ProcRes(); - } - a.Call(vm, [](HSQUIRRELVM vm, A... a) { + ArgFwd a{SQ_OK}; + a.Call(vm, 2, [](HSQUIRRELVM vm, A... a) { typedef R&(C::*M)(A...) const; C* inst = Var(vm, 1).value; M* methodPtr; @@ -114,7 +102,7 @@ template struct SqMemberProxy { R& ret = (inst->*method)(a...); PushVarR(vm, ret); }); - return 1; + return SQ_FAILED(a.mRes) ? a.mRes : 1; } }; @@ -124,11 +112,8 @@ template struct SqMemberProxy { template struct SqMemberProxy { template static SQInteger Run(HSQUIRRELVM vm) noexcept { - ArgPop a(vm, 2); - if (SQ_FAILED(a.Proc(sizeof...(A) == 0 && sq_gettop(vm) == 2))) { - return a.ProcRes(); - } - a.Call(vm, [](HSQUIRRELVM vm, A... a) { + ArgFwd a{SQ_OK}; + a.Call(vm, 2, [](HSQUIRRELVM vm, A... a) { typedef void(C::*M)(A...); C* inst = Var(vm, 1).value; M* methodPtr; @@ -136,14 +121,11 @@ template struct SqMemberProxy { M method = *methodPtr; (inst->*method)(a...); }); - return 0; + return SQ_FAILED(a.mRes) ? a.mRes : 0; } template static SQInteger RunC(HSQUIRRELVM vm) noexcept { - ArgPop a(vm, 2); - if (SQ_FAILED(a.Proc(sizeof...(A) == 0 && sq_gettop(vm) == 2))) { - return a.ProcRes(); - } - a.Call(vm, [](HSQUIRRELVM vm, A... a) { + ArgFwd a{SQ_OK}; + a.Call(vm, 2, [](HSQUIRRELVM vm, A... a) { typedef void(C::*M)(A...) const; C* inst = Var(vm, 1).value; M* methodPtr; @@ -151,17 +133,17 @@ template struct SqMemberProxy { M method = *methodPtr; (inst->*method)(a...); }); - return 0; + return SQ_FAILED(a.mRes) ? a.mRes : 0; } }; template struct SqMemberParamCheck { - static inline bool Invalid(SQInteger top, SQInteger count) { + static inline bool Invalid(SQInteger top, SQInteger count) noexcept { return top != count; } }; template<> struct SqMemberParamCheck { - static inline bool Invalid(SQInteger top, SQInteger count) { + static inline bool Invalid(SQInteger top, SQInteger count) noexcept { return top < count; } }; @@ -175,7 +157,7 @@ template struct SqMember { return +[](HSQUIRRELVM vm) noexcept -> SQInteger { #if !defined (SCRAT_NO_ERROR_CHECKING) if (!SQRAT_CONST_CONDITION(overloaded) && - SqGlobalParamCheck< ArgPop::HASFMT >::Invalid(sq_gettop(vm), 2 + sizeof...(A))) { + SqGlobalParamCheck< ArgFwd::HASFMT >::Invalid(sq_gettop(vm), 2 + sizeof...(A))) { return sq_throwerror(vm, _SC("wrong number of parameters")); } #endif @@ -183,6 +165,8 @@ template struct SqMember { return SqMemberProxy:: template Run(vm); } catch (const Exception& e) { return sq_throwerror(vm, e.what()); + } catch (...) { + return sq_throwerror(vm, _SC("unknown exception occured")); } SQ_UNREACHABLE }; @@ -192,7 +176,7 @@ template struct SqMember { return +[](HSQUIRRELVM vm) noexcept -> SQInteger { #if !defined (SCRAT_NO_ERROR_CHECKING) if (!SQRAT_CONST_CONDITION(overloaded) && - SqGlobalParamCheck< ArgPop::HASFMT >::Invalid(sq_gettop(vm), 2 + sizeof...(A))) { + SqGlobalParamCheck< ArgFwd::HASFMT >::Invalid(sq_gettop(vm), 2 + sizeof...(A))) { return sq_throwerror(vm, _SC("wrong number of parameters")); } #endif @@ -200,6 +184,8 @@ template struct SqMember { return SqMemberProxy::template RunC(vm); } catch (const Exception& e) { return sq_throwerror(vm, e.what()); + } catch (...) { + return sq_throwerror(vm, _SC("unknown exception occured")); } SQ_UNREACHABLE }; @@ -216,7 +202,7 @@ template struct SqMember { return +[](HSQUIRRELVM vm) noexcept -> SQInteger { #if !defined (SCRAT_NO_ERROR_CHECKING) if (!SQRAT_CONST_CONDITION(overloaded) && - SqGlobalParamCheck< ArgPop::HASFMT >::Invalid(sq_gettop(vm), 2 + sizeof...(A))) { + SqGlobalParamCheck< ArgFwd::HASFMT >::Invalid(sq_gettop(vm), 2 + sizeof...(A))) { return sq_throwerror(vm, _SC("wrong number of parameters")); } #endif @@ -224,6 +210,8 @@ template struct SqMember { return SqMemberProxy::template Run(vm); } catch (const Exception& e) { return sq_throwerror(vm, e.what()); + } catch (...) { + return sq_throwerror(vm, _SC("unknown exception occured")); } SQ_UNREACHABLE }; @@ -233,7 +221,7 @@ template struct SqMember { return +[](HSQUIRRELVM vm) noexcept -> SQInteger { #if !defined (SCRAT_NO_ERROR_CHECKING) if (!SQRAT_CONST_CONDITION(overloaded) && - SqGlobalParamCheck< ArgPop::HASFMT >::Invalid(sq_gettop(vm), 2 + sizeof...(A))) { + SqGlobalParamCheck< ArgFwd::HASFMT >::Invalid(sq_gettop(vm), 2 + sizeof...(A))) { return sq_throwerror(vm, _SC("wrong number of parameters")); } #endif @@ -241,6 +229,8 @@ template struct SqMember { return SqMemberProxy::template RunC(vm); } catch (const Exception& e) { return sq_throwerror(vm, e.what()); + } catch (...) { + return sq_throwerror(vm, _SC("unknown exception occured")); } SQ_UNREACHABLE }; @@ -258,7 +248,7 @@ template struct SqMember { return +[](HSQUIRRELVM vm) noexcept -> SQInteger { #if !defined (SCRAT_NO_ERROR_CHECKING) if (!SQRAT_CONST_CONDITION(overloaded) && - SqGlobalParamCheck< ArgPop::HASFMT >::Invalid(sq_gettop(vm), 2 + sizeof...(A))) { + SqGlobalParamCheck< ArgFwd::HASFMT >::Invalid(sq_gettop(vm), 2 + sizeof...(A))) { return sq_throwerror(vm, _SC("wrong number of parameters")); } #endif @@ -266,6 +256,8 @@ template struct SqMember { return SqMemberProxy::template Run(vm); } catch (const Exception& e) { return sq_throwerror(vm, e.what()); + } catch (...) { + return sq_throwerror(vm, _SC("unknown exception occured")); } SQ_UNREACHABLE }; @@ -275,7 +267,7 @@ template struct SqMember { return +[](HSQUIRRELVM vm) noexcept -> SQInteger { #if !defined (SCRAT_NO_ERROR_CHECKING) if (!SQRAT_CONST_CONDITION(overloaded) && - SqGlobalParamCheck< ArgPop::HASFMT >::Invalid(sq_gettop(vm), 2 + sizeof...(A))) { + SqGlobalParamCheck< ArgFwd::HASFMT >::Invalid(sq_gettop(vm), 2 + sizeof...(A))) { return sq_throwerror(vm, _SC("wrong number of parameters")); } #endif @@ -283,6 +275,8 @@ template struct SqMember { return SqMemberProxy::template RunC(vm); } catch (const Exception& e) { return sq_throwerror(vm, e.what()); + } catch (...) { + return sq_throwerror(vm, _SC("unknown exception occured")); } SQ_UNREACHABLE }; diff --git a/include/sqrat/sqratTypes.h b/include/sqrat/sqratTypes.h index 0b62a6e7..53b0e99a 100644 --- a/include/sqrat/sqratTypes.h +++ b/include/sqrat/sqratTypes.h @@ -1177,52 +1177,40 @@ inline void PushVarR(HSQUIRRELVM vm, T& value) { ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// Helper used to process formatted arguments when necessary. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -template struct ArgPopHasFmt { static constexpr bool value = false; }; -template<> struct ArgPopHasFmt { static constexpr bool value = true; }; -template<> struct ArgPopHasFmt { static constexpr bool value = true; }; -template<> struct ArgPopHasFmt { static constexpr bool value = true; }; -template<> struct ArgPopHasFmt { static constexpr bool value = true; }; +template struct ArgFwdHasFmt { static constexpr bool value = false; }; +template<> struct ArgFwdHasFmt { static constexpr bool value = true; }; +template<> struct ArgFwdHasFmt { static constexpr bool value = true; }; +template<> struct ArgFwdHasFmt { static constexpr bool value = true; }; +template<> struct ArgFwdHasFmt { static constexpr bool value = true; }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// Helper used to process formatted arguments when necessary. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -template struct ArgPopFmt { - template static inline SQInteger Proc(T &, bool) { - return SQ_OK; - } - template static inline SQInteger Get(T &) { - return SQ_OK; - } +template struct ArgFwdFmt { + template static inline SQInteger Proc(T &, bool) noexcept { return SQ_OK; } + template static inline SQInteger Get(T &) noexcept { return SQ_OK; } }; -template<> struct ArgPopFmt { - static inline SQInteger Proc(StackStrF & s, bool dummy = false) { - return s.Proc(true, dummy); - } - static inline SQInteger Get(StackStrF & s) { - return s.mRes; - } +template<> struct ArgFwdFmt { + static inline SQInteger Proc(StackStrF & s, bool dummy = false) noexcept { return s.Proc(true, dummy); } + static inline SQInteger Get(StackStrF & s) noexcept { return s.mRes; } }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// Helper used to pop multiple variables from the stack and forward them to a functor. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -template struct ArgPop; +template struct ArgFwd; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// Special case for when nothing has to be popped. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// template<> -struct ArgPop<> { +struct ArgFwd<> { // Used to tell whether the last template parameter is a StackStrF type static constexpr bool HASFMT = false; - // Base constructor. Does nothing. - ArgPop(HSQUIRRELVM /*vm*/, SQInteger /*idx*/) - { } - // Process formatted arguments if necessary - SQInteger Proc(bool dummy = false) { (void)(dummy); return SQ_OK; } - SQInteger ProcRes() { return SQ_OK; } + // Where Squirrel result codes can be stored + SQInteger mRes; // Forward the arguments to a function object - template void Call(HSQUIRRELVM vm, F f) { + template inline void Call(HSQUIRRELVM vm, SQInteger /*idx*/, F f) { f(vm); } }; @@ -1231,443 +1219,308 @@ struct ArgPop<> { /// Incremental specialization for when types are actually specified. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// template -struct ArgPop { +struct ArgFwd { // Used to tell whether the last template parameter is a StackStrF type - static constexpr bool HASFMT = ArgPopHasFmt::value; - // Implement ours - Var V1; - // Base constructor. Can also pass extra parameters to the last popped argument. - ArgPop(HSQUIRRELVM vm, SQInteger idx) - : V1(vm, idx) - { } - // Retrieve the last popped variable - Var & Last() { return V1; } - const Var & Last() const { return V1; } - // Process formatted arguments if necessary - SQInteger Proc(bool dummy = false) { return ArgPopFmt::Proc(V1.value, dummy); } - SQInteger ProcRes() { return ArgPopFmt::Get(V1.value); } + static constexpr bool HASFMT = ArgFwdHasFmt::value; + // Where Squirrel result codes can be stored + SQInteger mRes; // Forward the arguments to a function object - template void Call(HSQUIRRELVM vm, F f) { - f(vm,V1.value); + template inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { + Var a1(vm, idx); + mRes = ArgFwdFmt::Proc(a1.value, sq_gettop(vm) < idx); + if (SQ_SUCCEEDED(mRes)) + f(vm,a1.value); } }; template -struct ArgPop : public ArgPop { - using Base = ArgPop; +struct ArgFwd { // Used to tell whether the last template parameter is a StackStrF type - static constexpr bool HASFMT = ArgPopHasFmt::value; - // Import from base classes - using Base::V1; - // Implement ours - Var V2; - // Base constructor. Can also pass extra parameters to the last popped argument. - ArgPop(HSQUIRRELVM vm, SQInteger idx) - : ArgPop(vm, idx) - , V2(vm, idx+1) - { } - // Retrieve the last popped variable - Var & Last() { return V2; } - const Var & Last() const { return V2; } - // Process formatted arguments if necessary - SQInteger Proc(bool dummy = false) { return ArgPopFmt::Proc(V2.value, dummy); } - SQInteger ProcRes() { return ArgPopFmt::Get(V2.value); } + static constexpr bool HASFMT = ArgFwdHasFmt::value; + // Where Squirrel result codes can be stored + SQInteger mRes; // Forward the arguments to a function object - template void Call(HSQUIRRELVM vm, F f) { - f(vm,V1.value,V2.value); + template inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { + Var a1(vm, idx); + Var a2(vm, idx+1); + mRes = ArgFwdFmt::Proc(a2.value, sq_gettop(vm) < idx); + if (SQ_SUCCEEDED(mRes)) + f(vm,a1.value,a2.value); } }; template -struct ArgPop : public ArgPop { - using Base = ArgPop; +struct ArgFwd { // Used to tell whether the last template parameter is a StackStrF type - static constexpr bool HASFMT = ArgPopHasFmt::value; - // Import from base classes - using Base::V1; - using Base::V2; - // Implement ours - Var V3; - // Base constructor. Can also pass extra parameters to the last popped argument. - ArgPop(HSQUIRRELVM vm, SQInteger idx) - : ArgPop(vm, idx) - , V3(vm, idx+2) - { } - // Retrieve the last popped variable - Var & Last() { return V3; } - const Var & Last() const { return V3; } - // Process formatted arguments if necessary - SQInteger Proc(bool dummy = false) { return ArgPopFmt::Proc(V3.value, dummy); } - SQInteger ProcRes() { return ArgPopFmt::Get(V3.value); } + static constexpr bool HASFMT = ArgFwdHasFmt::value; + // Where Squirrel result codes can be stored + SQInteger mRes; // Forward the arguments to a function object - template void Call(HSQUIRRELVM vm, F f) { - f(vm,V1.value,V2.value,V3.value); + template inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { + Var a1(vm, idx); + Var a2(vm, idx+1); + Var a3(vm, idx+2); + mRes = ArgFwdFmt::Proc(a3.value, sq_gettop(vm) < idx); + if (SQ_SUCCEEDED(mRes)) + f(vm,a1.value,a2.value,a3.value); } }; + template -struct ArgPop : public ArgPop { - using Base = ArgPop; +struct ArgFwd { // Used to tell whether the last template parameter is a StackStrF type - static constexpr bool HASFMT = ArgPopHasFmt::value; - // Import from base classes - using Base::V1; - using Base::V2; - using Base::V3; - // Implement ours - Var V4; - // Base constructor. Can also pass extra parameters to the last popped argument. - ArgPop(HSQUIRRELVM vm, SQInteger idx) - : ArgPop(vm, idx) - , V4(vm, idx+3) - { } - // Retrieve the last popped variable - Var & Last() { return V4; } - const Var & Last() const { return V4; } - // Process formatted arguments if necessary - SQInteger Proc(bool dummy = false) { return ArgPopFmt::Proc(V4.value, dummy); } - SQInteger ProcRes() { return ArgPopFmt::Get(V4.value); } + static constexpr bool HASFMT = ArgFwdHasFmt::value; + // Where Squirrel result codes can be stored + SQInteger mRes; // Forward the arguments to a function object - template void Call(HSQUIRRELVM vm, F f) { - f(vm,V1.value,V2.value,V3.value,V4.value); + template inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { + Var a1(vm, idx); + Var a2(vm, idx+1); + Var a3(vm, idx+2); + Var a4(vm, idx+3); + mRes = ArgFwdFmt::Proc(a4.value, sq_gettop(vm) < idx); + if (SQ_SUCCEEDED(mRes)) + f(vm,a1.value,a2.value,a3.value,a4.value); } }; template -struct ArgPop : public ArgPop { - using Base = ArgPop; +struct ArgFwd { // Used to tell whether the last template parameter is a StackStrF type - static constexpr bool HASFMT = ArgPopHasFmt::value; - // Import from base classes - using Base::V1; - using Base::V2; - using Base::V3; - using Base::V4; - // Implement ours - Var V5; - // Base constructor. Can also pass extra parameters to the last popped argument. - ArgPop(HSQUIRRELVM vm, SQInteger idx) - : ArgPop(vm, idx) - , V5(vm, idx+4) - { } - // Retrieve the last popped variable - Var & Last() { return V5; } - const Var & Last() const { return V5; } - // Process formatted arguments if necessary - SQInteger Proc(bool dummy = false) { return ArgPopFmt::Proc(V5.value, dummy); } - SQInteger ProcRes() { return ArgPopFmt::Get(V5.value); } + static constexpr bool HASFMT = ArgFwdHasFmt::value; + // Where Squirrel result codes can be stored + SQInteger mRes; // Forward the arguments to a function object - template void Call(HSQUIRRELVM vm, F f) { - f(vm,V1.value,V2.value,V3.value,V4.value,V5.value); + template inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { + Var a1(vm, idx); + Var a2(vm, idx+1); + Var a3(vm, idx+2); + Var a4(vm, idx+3); + Var a5(vm, idx+4); + mRes = ArgFwdFmt::Proc(a5.value, sq_gettop(vm) < idx); + if (SQ_SUCCEEDED(mRes)) + f(vm,a1.value,a2.value,a3.value,a4.value,a5.value); } }; template -struct ArgPop : public ArgPop { - using Base = ArgPop; +struct ArgFwd { // Used to tell whether the last template parameter is a StackStrF type - static constexpr bool HASFMT = ArgPopHasFmt::value; - // Import from base classes - using Base::V1; - using Base::V2; - using Base::V3; - using Base::V4; - using Base::V5; - // Implement ours - Var V6; - // Base constructor. Can also pass extra parameters to the last popped argument. - ArgPop(HSQUIRRELVM vm, SQInteger idx) - : ArgPop(vm, idx) - , V6(vm, idx+5) - { } - // Retrieve the last popped variable - Var & Last() { return V6; } - const Var & Last() const { return V6; } - // Process formatted arguments if necessary - SQInteger Proc(bool dummy = false) { return ArgPopFmt::Proc(V6.value, dummy); } - SQInteger ProcRes() { return ArgPopFmt::Get(V6.value); } + static constexpr bool HASFMT = ArgFwdHasFmt::value; + // Where Squirrel result codes can be stored + SQInteger mRes; // Forward the arguments to a function object - template void Call(HSQUIRRELVM vm, F f) { - f(vm,V1.value,V2.value,V3.value,V4.value,V5.value,V6.value); + template inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { + Var a1(vm, idx); + Var a2(vm, idx+1); + Var a3(vm, idx+2); + Var a4(vm, idx+3); + Var a5(vm, idx+4); + Var a6(vm, idx+5); + mRes = ArgFwdFmt::Proc(a6.value, sq_gettop(vm) < idx); + if (SQ_SUCCEEDED(mRes)) + f(vm,a1.value,a2.value,a3.value,a4.value,a5.value,a6.value); } }; template -struct ArgPop : public ArgPop { - using Base = ArgPop; +struct ArgFwd { // Used to tell whether the last template parameter is a StackStrF type - static constexpr bool HASFMT = ArgPopHasFmt::value; - // Import from base classes - using Base::V1; - using Base::V2; - using Base::V3; - using Base::V4; - using Base::V5; - using Base::V6; - // Implement ours - Var V7; - // Base constructor. Can also pass extra parameters to the last popped argument. - ArgPop(HSQUIRRELVM vm, SQInteger idx) - : ArgPop(vm, idx) - , V7(vm, idx+6) - { } - // Retrieve the last popped variable - Var & Last() { return V7; } - const Var & Last() const { return V7; } - // Process formatted arguments if necessary - SQInteger Proc(bool dummy = false) { return ArgPopFmt::Proc(V7.value, dummy); } - SQInteger ProcRes() { return ArgPopFmt::Get(V7.value); } + static constexpr bool HASFMT = ArgFwdHasFmt::value; + // Where Squirrel result codes can be stored + SQInteger mRes; // Forward the arguments to a function object - template void Call(HSQUIRRELVM vm, F f) { - f(vm,V1.value,V2.value,V3.value,V4.value,V5.value,V6.value,V7.value); + template inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { + Var a1(vm, idx); + Var a2(vm, idx+1); + Var a3(vm, idx+2); + Var a4(vm, idx+3); + Var a5(vm, idx+4); + Var a6(vm, idx+5); + Var a7(vm, idx+6); + mRes = ArgFwdFmt::Proc(a7.value, sq_gettop(vm) < idx); + if (SQ_SUCCEEDED(mRes)) + f(vm,a1.value,a2.value,a3.value,a4.value,a5.value,a6.value,a7.value); } }; template -struct ArgPop : public ArgPop { - using Base = ArgPop; +struct ArgFwd { // Used to tell whether the last template parameter is a StackStrF type - static constexpr bool HASFMT = ArgPopHasFmt::value; - // Import from base classes - using Base::V1; - using Base::V2; - using Base::V3; - using Base::V4; - using Base::V5; - using Base::V6; - using Base::V7; - // Implement ours - Var V8; - // Base constructor. Can also pass extra parameters to the last popped argument. - ArgPop(HSQUIRRELVM vm, SQInteger idx) - : ArgPop(vm, idx) - , V8(vm, idx+7) - { } - // Retrieve the last popped variable - Var & Last() { return V8; } - const Var & Last() const { return V8; } - // Process formatted arguments if necessary - SQInteger Proc(bool dummy = false) { return ArgPopFmt::Proc(V8.value, dummy); } - SQInteger ProcRes() { return ArgPopFmt::Get(V8.value); } + static constexpr bool HASFMT = ArgFwdHasFmt::value; + // Where Squirrel result codes can be stored + SQInteger mRes; // Forward the arguments to a function object - template void Call(HSQUIRRELVM vm, F f) { - f(vm,V1.value,V2.value,V3.value,V4.value,V5.value,V6.value,V7.value,V8.value); + template inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { + Var a1(vm, idx); + Var a2(vm, idx+1); + Var a3(vm, idx+2); + Var a4(vm, idx+3); + Var a5(vm, idx+4); + Var a6(vm, idx+5); + Var a7(vm, idx+6); + Var a8(vm, idx+7); + mRes = ArgFwdFmt::Proc(a8.value, sq_gettop(vm) < idx); + if (SQ_SUCCEEDED(mRes)) + f(vm,a1.value,a2.value,a3.value,a4.value,a5.value,a6.value,a7.value,a8.value); } }; template -struct ArgPop : public ArgPop { - using Base = ArgPop; +struct ArgFwd { // Used to tell whether the last template parameter is a StackStrF type - static constexpr bool HASFMT = ArgPopHasFmt::value; - // Import from base classes - using Base::V1; - using Base::V2; - using Base::V3; - using Base::V4; - using Base::V5; - using Base::V6; - using Base::V7; - using Base::V8; - // Implement ours - Var V9; - // Base constructor. Can also pass extra parameters to the last popped argument. - ArgPop(HSQUIRRELVM vm, SQInteger idx) - : ArgPop(vm, idx) - , V9(vm, idx+8) - { } - // Retrieve the last popped variable - Var & Last() { return V9; } - const Var & Last() const { return V9; } - // Process formatted arguments if necessary - SQInteger Proc(bool dummy = false) { return ArgPopFmt::Proc(V9.value, dummy); } - SQInteger ProcRes() { return ArgPopFmt::Get(V9.value); } + static constexpr bool HASFMT = ArgFwdHasFmt::value; + // Where Squirrel result codes can be stored + SQInteger mRes; // Forward the arguments to a function object - template void Call(HSQUIRRELVM vm, F f) { - f(vm,V1.value,V2.value,V3.value,V4.value,V5.value,V6.value,V7.value,V8.value,V9.value); + template inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { + Var a1(vm, idx); + Var a2(vm, idx+1); + Var a3(vm, idx+2); + Var a4(vm, idx+3); + Var a5(vm, idx+4); + Var a6(vm, idx+5); + Var a7(vm, idx+6); + Var a8(vm, idx+7); + Var a9(vm, idx+8); + mRes = ArgFwdFmt::Proc(a9.value, sq_gettop(vm) < idx); + if (SQ_SUCCEEDED(mRes)) + f(vm,a1.value,a2.value,a3.value,a4.value,a5.value,a6.value,a7.value,a8.value,a9.value); } }; template -struct ArgPop : public ArgPop { - using Base = ArgPop; +struct ArgFwd { // Used to tell whether the last template parameter is a StackStrF type - static constexpr bool HASFMT = ArgPopHasFmt::value; - // Import from base classes - using Base::V1; - using Base::V2; - using Base::V3; - using Base::V4; - using Base::V5; - using Base::V6; - using Base::V7; - using Base::V8; - using Base::V9; - // Implement ours - Var V10; - // Base constructor. Can also pass extra parameters to the last popped argument. - ArgPop(HSQUIRRELVM vm, SQInteger idx) - : ArgPop(vm, idx) - , V10(vm, idx+9) - { } - // Retrieve the last popped variable - Var & Last() { return V10; } - const Var & Last() const { return V10; } - // Process formatted arguments if necessary - SQInteger Proc(bool dummy = false) { return ArgPopFmt::Proc(V10.value, dummy); } - SQInteger ProcRes() { return ArgPopFmt::Get(V10.value); } + static constexpr bool HASFMT = ArgFwdHasFmt::value; + // Where Squirrel result codes can be stored + SQInteger mRes; // Forward the arguments to a function object - template void Call(HSQUIRRELVM vm, F f) { - f(vm,V1.value,V2.value,V3.value,V4.value,V5.value,V6.value,V7.value,V8.value,V9.value,V10.value); + template inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { + Var a1(vm, idx); + Var a2(vm, idx+1); + Var a3(vm, idx+2); + Var a4(vm, idx+3); + Var a5(vm, idx+4); + Var a6(vm, idx+5); + Var a7(vm, idx+6); + Var a8(vm, idx+7); + Var a9(vm, idx+8); + Var a10(vm, idx+9); + mRes = ArgFwdFmt::Proc(a10.value, sq_gettop(vm) < idx); + if (SQ_SUCCEEDED(mRes)) + f(vm,a1.value,a2.value,a3.value,a4.value,a5.value,a6.value,a7.value,a8.value,a9.value,a10.value); } }; template -struct ArgPop : public ArgPop { - using Base = ArgPop; +struct ArgFwd { // Used to tell whether the last template parameter is a StackStrF type - static constexpr bool HASFMT = ArgPopHasFmt::value; - // Import from base classes - using Base::V1; - using Base::V2; - using Base::V3; - using Base::V4; - using Base::V5; - using Base::V6; - using Base::V7; - using Base::V8; - using Base::V9; - using Base::V10; - // Implement ours - Var V11; - // Base constructor. Can also pass extra parameters to the last popped argument. - ArgPop(HSQUIRRELVM vm, SQInteger idx) - : ArgPop(vm, idx) - , V11(vm, idx+10) - { } - // Retrieve the last popped variable - Var & Last() { return V11; } - const Var & Last() const { return V11; } - // Process formatted arguments if necessary - SQInteger Proc(bool dummy = false) { return ArgPopFmt::Proc(V11.value, dummy); } - SQInteger ProcRes() { return ArgPopFmt::Get(V11.value); } + static constexpr bool HASFMT = ArgFwdHasFmt::value; + // Where Squirrel result codes can be stored + SQInteger mRes; // Forward the arguments to a function object - template void Call(HSQUIRRELVM vm, F f) { - f(vm,V1.value,V2.value,V3.value,V4.value,V5.value,V6.value,V7.value,V8.value,V9.value,V10.value,V11.value); + template inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { + Var a1(vm, idx); + Var a2(vm, idx+1); + Var a3(vm, idx+2); + Var a4(vm, idx+3); + Var a5(vm, idx+4); + Var a6(vm, idx+5); + Var a7(vm, idx+6); + Var a8(vm, idx+7); + Var a9(vm, idx+8); + Var a10(vm, idx+9); + Var a11(vm, idx+10); + mRes = ArgFwdFmt::Proc(a11.value, sq_gettop(vm) < idx); + if (SQ_SUCCEEDED(mRes)) + f(vm,a1.value,a2.value,a3.value,a4.value,a5.value,a6.value,a7.value,a8.value,a9.value,a10.value,a11.value); } }; template -struct ArgPop : public ArgPop { - using Base = ArgPop; +struct ArgFwd { // Used to tell whether the last template parameter is a StackStrF type - static constexpr bool HASFMT = ArgPopHasFmt::value; - // Import from base classes - using Base::V1; - using Base::V2; - using Base::V3; - using Base::V4; - using Base::V5; - using Base::V6; - using Base::V7; - using Base::V8; - using Base::V9; - using Base::V10; - using Base::V11; - // Implement ours - Var V12; - // Base constructor. Can also pass extra parameters to the last popped argument. - ArgPop(HSQUIRRELVM vm, SQInteger idx) - : ArgPop(vm, idx) - , V12(vm, idx+11) - { } - // Retrieve the last popped variable - Var & Last() { return V12; } - const Var & Last() const { return V12; } - // Process formatted arguments if necessary - SQInteger Proc(bool dummy = false) { return ArgPopFmt::Proc(V12.value, dummy); } - SQInteger ProcRes() { return ArgPopFmt::Get(V12.value); } + static constexpr bool HASFMT = ArgFwdHasFmt::value; + // Where Squirrel result codes can be stored + SQInteger mRes; // Forward the arguments to a function object - template void Call(HSQUIRRELVM vm, F f) { - f(vm,V1.value,V2.value,V3.value,V4.value,V5.value,V6.value,V7.value,V8.value,V9.value,V10.value,V11.value,V12.value); + template inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { + Var a1(vm, idx); + Var a2(vm, idx+1); + Var a3(vm, idx+2); + Var a4(vm, idx+3); + Var a5(vm, idx+4); + Var a6(vm, idx+5); + Var a7(vm, idx+6); + Var a8(vm, idx+7); + Var a9(vm, idx+8); + Var a10(vm, idx+9); + Var a11(vm, idx+10); + Var a12(vm, idx+11); + mRes = ArgFwdFmt::Proc(a12.value, sq_gettop(vm) < idx); + if (SQ_SUCCEEDED(mRes)) + f(vm,a1.value,a2.value,a3.value,a4.value,a5.value,a6.value,a7.value,a8.value,a9.value,a10.value,a11.value,a12.value); } }; template -struct ArgPop : public ArgPop { - using Base = ArgPop; +struct ArgFwd { // Used to tell whether the last template parameter is a StackStrF type - static constexpr bool HASFMT = ArgPopHasFmt::value; - // Import from base classes - using Base::V1; - using Base::V2; - using Base::V3; - using Base::V4; - using Base::V5; - using Base::V6; - using Base::V7; - using Base::V8; - using Base::V9; - using Base::V10; - using Base::V11; - using Base::V12; - // Implement ours - Var V13; - // Base constructor. Can also pass extra parameters to the last popped argument. - ArgPop(HSQUIRRELVM vm, SQInteger idx) - : ArgPop(vm, idx) - , V13(vm, idx+12) - { } - // Retrieve the last popped variable - Var & Last() { return V13; } - const Var & Last() const { return V13; } - // Process formatted arguments if necessary - SQInteger Proc(bool dummy = false) { return ArgPopFmt::Proc(V13.value, dummy); } - SQInteger ProcRes() { return ArgPopFmt::Get(V13.value); } + static constexpr bool HASFMT = ArgFwdHasFmt::value; + // Where Squirrel result codes can be stored + SQInteger mRes; // Forward the arguments to a function object - template void Call(HSQUIRRELVM vm, F f) { - f(vm,V1.value,V2.value,V3.value,V4.value,V5.value,V6.value,V7.value,V8.value,V9.value,V10.value,V11.value,V12.value,V13.value); + template inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { + Var a1(vm, idx); + Var a2(vm, idx+1); + Var a3(vm, idx+2); + Var a4(vm, idx+3); + Var a5(vm, idx+4); + Var a6(vm, idx+5); + Var a7(vm, idx+6); + Var a8(vm, idx+7); + Var a9(vm, idx+8); + Var a10(vm, idx+9); + Var a11(vm, idx+10); + Var a12(vm, idx+11); + Var a13(vm, idx+12); + mRes = ArgFwdFmt::Proc(a13.value, sq_gettop(vm) < idx); + if (SQ_SUCCEEDED(mRes)) + f(vm,a1.value,a2.value,a3.value,a4.value,a5.value,a6.value,a7.value,a8.value,a9.value,a10.value,a11.value,a12.value,a13.value); } }; template -struct ArgPop : public ArgPop { - using Base = ArgPop; +struct ArgFwd { // Used to tell whether the last template parameter is a StackStrF type - static constexpr bool HASFMT = ArgPopHasFmt::value; - // Import from base classes - using Base::V1; - using Base::V2; - using Base::V3; - using Base::V4; - using Base::V5; - using Base::V6; - using Base::V7; - using Base::V8; - using Base::V9; - using Base::V10; - using Base::V11; - using Base::V12; - using Base::V13; - // Implement ours - Var V14; - // Base constructor. Can also pass extra parameters to the last popped argument. - ArgPop(HSQUIRRELVM vm, SQInteger idx) - : ArgPop(vm, idx) - , V14(vm, idx+13) - { } - // Retrieve the last popped variable - Var & Last() { return V14; } - const Var & Last() const { return V14; } - // Process formatted arguments if necessary - SQInteger Proc(bool dummy = false) { return ArgPopFmt::Proc(V14.value, dummy); } - SQInteger ProcRes() { return ArgPopFmt::Get(V14.value); } + static constexpr bool HASFMT = ArgFwdHasFmt::value; + // Where Squirrel result codes can be stored + SQInteger mRes; // Forward the arguments to a function object - template void Call(HSQUIRRELVM vm, F f) { - f(vm,V1.value,V2.value,V3.value,V4.value,V5.value,V6.value,V7.value,V8.value,V9.value,V10.value,V11.value,V12.value,V13.value,V14.value); + template inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { + Var a1(vm, idx); + Var a2(vm, idx+1); + Var a3(vm, idx+2); + Var a4(vm, idx+3); + Var a5(vm, idx+4); + Var a6(vm, idx+5); + Var a7(vm, idx+6); + Var a8(vm, idx+7); + Var a9(vm, idx+8); + Var a10(vm, idx+9); + Var a11(vm, idx+10); + Var a12(vm, idx+11); + Var a13(vm, idx+12); + Var a14(vm, idx+13); + mRes = ArgFwdFmt::Proc(a14.value, sq_gettop(vm) < idx); + if (SQ_SUCCEEDED(mRes)) + f(vm,a1.value,a2.value,a3.value,a4.value,a5.value,a6.value,a7.value,a8.value,a9.value,a10.value,a11.value,a12.value,a13.value,a14.value); } }; + } #endif diff --git a/include/sqrat/sqratUtil.h b/include/sqrat/sqratUtil.h index 010d019f..4da01336 100644 --- a/include/sqrat/sqratUtil.h +++ b/include/sqrat/sqratUtil.h @@ -1563,7 +1563,7 @@ struct StackStrF ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// Default constructor. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - StackStrF() + StackStrF() noexcept : mPtr(_SC("")) , mLen(0) , mRes(SQ_OK) @@ -1577,7 +1577,7 @@ struct StackStrF ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// Compile time string constructor. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - template < size_t N > StackStrF(const SQChar(&str)[N]) + template < size_t N > StackStrF(const SQChar(&str)[N]) noexcept : mPtr(str) , mLen(N) , mRes(SQ_OK) @@ -1591,7 +1591,7 @@ struct StackStrF ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// Base constructor. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - StackStrF(HSQUIRRELVM vm, SQInteger idx) + StackStrF(HSQUIRRELVM vm, SQInteger idx) noexcept : mPtr(nullptr) , mLen(SQ_ERROR) , mRes(SQ_OK) @@ -1609,7 +1609,7 @@ struct StackStrF ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// Move constructor. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - StackStrF(StackStrF && o) + StackStrF(StackStrF && o) noexcept : mPtr(o.mPtr) , mLen(o.mLen) , mRes(o.mRes) @@ -1628,7 +1628,7 @@ struct StackStrF ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// Destructor. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - ~StackStrF() + ~StackStrF() noexcept { if (mVM && !sq_isnull(mObj)) {