// // SqratOverloadMethods: Overload Methods // // // Copyright (c) 2009 Brandon Jones // // This software is provided 'as-is', without any express or implied // warranty. In no event will the authors be held liable for any damages // arising from the use of this software. // // Permission is granted to anyone to use this software for any purpose, // including commercial applications, and to alter it and redistribute it // freely, subject to the following restrictions: // // 1. The origin of this software must not be misrepresented; you must not // claim that you wrote the original software. If you use this software // in a product, an acknowledgment in the product documentation would be // appreciated but is not required. // // 2. Altered source versions must be plainly marked as such, and must not be // misrepresented as being the original software. // // 3. This notice may not be removed or altered from any source // distribution. // #if !defined(_SQRAT_OVERLOAD_METHODS_H_) #define _SQRAT_OVERLOAD_METHODS_H_ #ifdef SQMOD_PLUGIN_API #include #else #include #endif // SQMOD_PLUGIN_API #include #include "sqratTypes.h" #include "sqratUtil.h" #include "sqratGlobalMethods.h" #include "sqratMemberMethods.h" namespace Sqrat { /// @cond DEV // // Overload name generator // class SqOverloadName { public: static string Get(const SQChar* name, int args) { std::basic_stringstream overloadName; overloadName << _SC("__overload_") << name << args; return overloadName.str(); } }; // // Squirrel Overload Functions // template class SqOverload { public: static SQInteger Func(HSQUIRRELVM vm) { // Get the arg count int argCount = sq_gettop(vm) - 2; const SQChar* funcName; sq_getstring(vm, -1, &funcName); // get the function name (free variable) string overloadName = SqOverloadName::Get(funcName, argCount); sq_pushstring(vm, overloadName.c_str(), -1); #if !defined (SCRAT_NO_ERROR_CHECKING) if (SQ_FAILED(sq_get(vm, 1))) { // Lookup the proper overload return sq_throwerror(vm, _SC("wrong number of parameters")); } #else sq_get(vm, 1); #endif // Push the args again for (int i = 1; i <= argCount + 1; ++i) { sq_push(vm, i); } #if !defined (SCRAT_NO_ERROR_CHECKING) SQRESULT result = sq_call(vm, argCount + 1, true, ErrorHandling::IsEnabled()); if (SQ_FAILED(result)) { return sq_throwerror(vm, LastErrorString(vm).c_str()); } #else sq_call(vm, argCount + 1, true, ErrorHandling::IsEnabled()); #endif return 1; } }; // // void return specialization // template <> class SqOverload { public: static SQInteger Func(HSQUIRRELVM vm) { // Get the arg count int argCount = sq_gettop(vm) - 2; const SQChar* funcName; sq_getstring(vm, -1, &funcName); // get the function name (free variable) string overloadName = SqOverloadName::Get(funcName, argCount); sq_pushstring(vm, overloadName.c_str(), -1); #if !defined (SCRAT_NO_ERROR_CHECKING) if (SQ_FAILED(sq_get(vm, 1))) { // Lookup the proper overload return sq_throwerror(vm, _SC("wrong number of parameters")); } #else sq_get(vm, 1); #endif // Push the args again for (int i = 1; i <= argCount + 1; ++i) { sq_push(vm, i); } #if !defined (SCRAT_NO_ERROR_CHECKING) SQRESULT result = sq_call(vm, argCount + 1, false, ErrorHandling::IsEnabled()); if (SQ_FAILED(result)) { return sq_throwerror(vm, LastErrorString(vm).c_str()); } #else sq_call(vm, argCount + 1, false, ErrorHandling::IsEnabled()); #endif return 0; } }; // Global Overloaded Function Resolver template SQFUNCTION SqGlobalOverloadedFunc(R (* /*method*/)(A...)) noexcept { return SqGlobal::template GetProxy<2, true, A...>(); } // Global Overloaded Function Resolver template SQFUNCTION SqGlobalOverloadedFunc(R& (* /*method*/)(A...)) noexcept { return SqGlobal::template GetProxy<2, true, A...>(); } // Member Global Overloaded Function Resolver template SQFUNCTION SqMemberGlobalOverloadedFunc(R (* /*method*/)(T, A...)) noexcept { return SqGlobal::template GetProxy<1, true, T, A...>(); } // Member Global Overloaded Function Resolver template SQFUNCTION SqMemberGlobalOverloadedFunc(R& (* /*method*/)(T, A...)) noexcept { return SqGlobal::template GetProxy<1, true, T, A...>(); } // // Member Overloaded Function Resolvers // // Arg Count 0 template inline SQFUNCTION SqMemberOverloadedFunc(R (C::* /*method*/)()) { return &SqMember::template Func0; } template inline SQFUNCTION SqMemberOverloadedFunc(R (C::* /*method*/)() const) { return &SqMember::template Func0C; } template inline SQFUNCTION SqMemberOverloadedFunc(R& (C::* /*method*/)()) { return &SqMember::template Func0; } template inline SQFUNCTION SqMemberOverloadedFunc(R& (C::* /*method*/)() const) { return &SqMember::template Func0C; } // Arg Count 1 template inline SQFUNCTION SqMemberOverloadedFunc(R (C::* /*method*/)(A1)) { return &SqMember::template Func1; } template inline SQFUNCTION SqMemberOverloadedFunc(R (C::* /*method*/)(A1) const) { return &SqMember::template Func1C; } template inline SQFUNCTION SqMemberOverloadedFunc(R& (C::* /*method*/)(A1)) { return &SqMember::template Func1; } template inline SQFUNCTION SqMemberOverloadedFunc(R& (C::* /*method*/)(A1) const) { return &SqMember::template Func1C; } // Arg Count 2 template inline SQFUNCTION SqMemberOverloadedFunc(R (C::* /*method*/)(A1, A2)) { return &SqMember::template Func2; } template inline SQFUNCTION SqMemberOverloadedFunc(R (C::* /*method*/)(A1, A2) const) { return &SqMember::template Func2C; } template inline SQFUNCTION SqMemberOverloadedFunc(R& (C::* /*method*/)(A1, A2)) { return &SqMember::template Func2; } template inline SQFUNCTION SqMemberOverloadedFunc(R& (C::* /*method*/)(A1, A2) const) { return &SqMember::template Func2C; } // Arg Count 3 template inline SQFUNCTION SqMemberOverloadedFunc(R (C::* /*method*/)(A1, A2, A3)) { return &SqMember::template Func3; } template inline SQFUNCTION SqMemberOverloadedFunc(R (C::* /*method*/)(A1, A2, A3) const) { return &SqMember::template Func3C; } template inline SQFUNCTION SqMemberOverloadedFunc(R& (C::* /*method*/)(A1, A2, A3)) { return &SqMember::template Func3; } template inline SQFUNCTION SqMemberOverloadedFunc(R& (C::* /*method*/)(A1, A2, A3) const) { return &SqMember::template Func3C; } // Arg Count 4 template inline SQFUNCTION SqMemberOverloadedFunc(R (C::* /*method*/)(A1, A2, A3, A4)) { return &SqMember::template Func4; } template inline SQFUNCTION SqMemberOverloadedFunc(R (C::* /*method*/)(A1, A2, A3, A4) const) { return &SqMember::template Func4C; } template inline SQFUNCTION SqMemberOverloadedFunc(R& (C::* /*method*/)(A1, A2, A3, A4)) { return &SqMember::template Func4; } template inline SQFUNCTION SqMemberOverloadedFunc(R& (C::* /*method*/)(A1, A2, A3, A4) const) { return &SqMember::template Func4C; } // Arg Count 5 template inline SQFUNCTION SqMemberOverloadedFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5)) { return &SqMember::template Func5; } template inline SQFUNCTION SqMemberOverloadedFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5) const) { return &SqMember::template Func5C; } template inline SQFUNCTION SqMemberOverloadedFunc(R& (C::* /*method*/)(A1, A2, A3, A4, A5)) { return &SqMember::template Func5; } template inline SQFUNCTION SqMemberOverloadedFunc(R& (C::* /*method*/)(A1, A2, A3, A4, A5) const) { return &SqMember::template Func5C; } // Arg Count 6 template inline SQFUNCTION SqMemberOverloadedFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6)) { return &SqMember::template Func6; } template inline SQFUNCTION SqMemberOverloadedFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6) const) { return &SqMember::template Func6C; } template inline SQFUNCTION SqMemberOverloadedFunc(R& (C::* /*method*/)(A1, A2, A3, A4, A5, A6)) { return &SqMember::template Func6; } template inline SQFUNCTION SqMemberOverloadedFunc(R& (C::* /*method*/)(A1, A2, A3, A4, A5, A6) const) { return &SqMember::template Func6C; } // Arg Count 7 template inline SQFUNCTION SqMemberOverloadedFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7)) { return &SqMember::template Func7; } template inline SQFUNCTION SqMemberOverloadedFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7) const) { return &SqMember::template Func7C; } template inline SQFUNCTION SqMemberOverloadedFunc(R& (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7)) { return &SqMember::template Func7; } template inline SQFUNCTION SqMemberOverloadedFunc(R& (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7) const) { return &SqMember::template Func7C; } // Arg Count 8 template inline SQFUNCTION SqMemberOverloadedFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8)) { return &SqMember::template Func8; } template inline SQFUNCTION SqMemberOverloadedFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8) const) { return &SqMember::template Func8C; } template inline SQFUNCTION SqMemberOverloadedFunc(R& (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8)) { return &SqMember::template Func8; } template inline SQFUNCTION SqMemberOverloadedFunc(R& (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8) const) { return &SqMember::template Func8C; } // Arg Count 9 template inline SQFUNCTION SqMemberOverloadedFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9)) { return &SqMember::template Func9; } template inline SQFUNCTION SqMemberOverloadedFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9) const) { return &SqMember::template Func9C; } template inline SQFUNCTION SqMemberOverloadedFunc(R& (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9)) { return &SqMember::template Func9; } template inline SQFUNCTION SqMemberOverloadedFunc(R& (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9) const) { return &SqMember::template Func9C; } // Arg Count 10 template inline SQFUNCTION SqMemberOverloadedFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)) { return &SqMember::template Func10; } template inline SQFUNCTION SqMemberOverloadedFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) const) { return &SqMember::template Func10C; } template inline SQFUNCTION SqMemberOverloadedFunc(R& (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)) { return &SqMember::template Func10; } template inline SQFUNCTION SqMemberOverloadedFunc(R& (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) const) { return &SqMember::template Func10C; } // Arg Count 11 template inline SQFUNCTION SqMemberOverloadedFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11)) { return &SqMember::template Func11; } template inline SQFUNCTION SqMemberOverloadedFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11) const) { return &SqMember::template Func11C; } template inline SQFUNCTION SqMemberOverloadedFunc(R& (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11)) { return &SqMember::template Func11; } template inline SQFUNCTION SqMemberOverloadedFunc(R& (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11) const) { return &SqMember::template Func11C; } // Arg Count 12 template inline SQFUNCTION SqMemberOverloadedFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12)) { return &SqMember::template Func12; } template inline SQFUNCTION SqMemberOverloadedFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12) const) { return &SqMember::template Func12C; } template inline SQFUNCTION SqMemberOverloadedFunc(R& (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12)) { return &SqMember::template Func12; } template inline SQFUNCTION SqMemberOverloadedFunc(R& (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12) const) { return &SqMember::template Func12C; } // Arg Count 13 template inline SQFUNCTION SqMemberOverloadedFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13)) { return &SqMember::template Func13; } template inline SQFUNCTION SqMemberOverloadedFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13) const) { return &SqMember::template Func13C; } template inline SQFUNCTION SqMemberOverloadedFunc(R& (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13)) { return &SqMember::template Func13; } template inline SQFUNCTION SqMemberOverloadedFunc(R& (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13) const) { return &SqMember::template Func13C; } // Arg Count 14 template inline SQFUNCTION SqMemberOverloadedFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14)) { return &SqMember::template Func14; } template inline SQFUNCTION SqMemberOverloadedFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14) const) { return &SqMember::template Func14C; } template inline SQFUNCTION SqMemberOverloadedFunc(R& (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14)) { return &SqMember::template Func14; } template inline SQFUNCTION SqMemberOverloadedFunc(R& (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14) const) { return &SqMember::template Func14C; } // // Overload handler resolver // template inline SQFUNCTION SqOverloadFunc(R (* /*method*/)) { return &SqOverload::Func; } template inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)) { return &SqOverload::Func; } template inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)() const ) { return &SqOverload::Func; } template inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1) const ) { return &SqOverload::Func; } template inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2) const ) { return &SqOverload::Func; } template inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2, A3) const ) { return &SqOverload::Func; } template inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2, A3, A4) const ) { return &SqOverload::Func; } template inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5) const ) { return &SqOverload::Func; } template inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6) const ) { return &SqOverload::Func; } template inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7) const ) { return &SqOverload::Func; } template inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8) const ) { return &SqOverload::Func; } template inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9) const ) { return &SqOverload::Func; } template inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) const ) { return &SqOverload::Func; } template inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11) const ) { return &SqOverload::Func; } template inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12) const ) { return &SqOverload::Func; } template inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13) const ) { return &SqOverload::Func; } template inline SQFUNCTION SqOverloadFunc(R (C::* /*method*/)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14) const ) { return &SqOverload::Func; } // // Query argument count // template inline int SqGetArgCount(R (* /*method*/)(Args...)) { return sizeof...(Args); } // // Query member function argument count // template inline int SqGetArgCount(R (C::* /*method*/)(Args...)) { return sizeof...(Args); } // // Query const member function argument count // template inline int SqGetArgCount(R (C::* /*method*/)(Args...) const) { return sizeof...(Args); } /// @endcond } #endif