1 // Copyright (c) 2003 Daniel Wallin and Arvid Norberg 2 3 // Permission is hereby granted, free of charge, to any person obtaining a 4 // copy of this software and associated documentation files (the "Software"), 5 // to deal in the Software without restriction, including without limitation 6 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 // and/or sell copies of the Software, and to permit persons to whom the 8 // Software is furnished to do so, subject to the following conditions: 9 10 // The above copyright notice and this permission notice shall be included 11 // in all copies or substantial portions of the Software. 12 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 14 // ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 15 // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 16 // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 17 // SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR 18 // ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 19 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 21 // OR OTHER DEALINGS IN THE SOFTWARE. 22 23 #ifndef LUABIND_NO_ERROR_CHECKING 24 25 #if !BOOST_PP_IS_ITERATING 26 27 #ifndef LUABIND_GET_SIGNATURE_HPP_INCLUDED 28 #define LUABIND_GET_SIGNATURE_HPP_INCLUDED 29 30 #include <boost/config.hpp> 31 #include <boost/preprocessor/repeat.hpp> 32 #include <boost/preprocessor/iteration/iterate.hpp> 33 #include <boost/preprocessor/repetition/enum.hpp> 34 #include <boost/preprocessor/repetition/enum_params.hpp> 35 #include <boost/preprocessor/punctuation/comma_if.hpp> 36 #include <boost/preprocessor/cat.hpp> 37 38 #include <luabind/config.hpp> 39 #include <luabind/detail/signature_match.hpp> 40 #include <luabind/typeid.hpp> 41 42 43 namespace luabind { namespace detail 44 { 45 46 std::string LUABIND_API get_class_name(lua_State* L, type_id const& i); 47 48 template<class T> name_of_type(by_value<T>,lua_State * L,int)49 std::string name_of_type(by_value<T>, lua_State* L, int) { return luabind::detail::get_class_name(L, typeid(T)); }; 50 template<class T> name_of_type(by_reference<T>,lua_State * L,int)51 std::string name_of_type(by_reference<T>, lua_State* L, int) { return name_of_type(LUABIND_DECORATE_TYPE(T), L, 0L) + "&"; }; 52 template<class T> name_of_type(by_pointer<T>,lua_State * L,int)53 std::string name_of_type(by_pointer<T>, lua_State* L, int) { return name_of_type(LUABIND_DECORATE_TYPE(T), L, 0L) + "*"; }; 54 template<class T> name_of_type(by_const_reference<T>,lua_State * L,int)55 std::string name_of_type(by_const_reference<T>, lua_State* L, int) { return "const " + name_of_type(LUABIND_DECORATE_TYPE(T), L, 0L) + "&"; }; 56 template<class T> name_of_type(by_const_pointer<T>,lua_State * L,int)57 std::string name_of_type(by_const_pointer<T>, lua_State* L, int) { return "const " + name_of_type(LUABIND_DECORATE_TYPE(T), L, 0L) + "*"; }; 58 name_of_type(by_value<luabind::object>,lua_State *,int)59 inline std::string name_of_type(by_value<luabind::object>, lua_State*, int) { return "object"; }; name_of_type(by_const_reference<luabind::object>,lua_State *,int)60 inline std::string name_of_type(by_const_reference<luabind::object>, lua_State*, int) { return "object"; }; name_of_type(by_value<bool>,lua_State *,int)61 inline std::string name_of_type(by_value<bool>, lua_State*, int) { return "boolean"; } name_of_type(by_value<char>,lua_State *,int)62 inline std::string name_of_type(by_value<char>, lua_State*, int) { return "number"; } name_of_type(by_value<short>,lua_State *,int)63 inline std::string name_of_type(by_value<short>, lua_State*, int) { return "number"; } name_of_type(by_value<int>,lua_State *,int)64 inline std::string name_of_type(by_value<int>, lua_State*, int) { return "number"; } name_of_type(by_value<long>,lua_State *,int)65 inline std::string name_of_type(by_value<long>, lua_State*, int) { return "number"; } name_of_type(by_value<unsigned char>,lua_State *,int)66 inline std::string name_of_type(by_value<unsigned char>, lua_State*, int) { return "number"; } name_of_type(by_value<unsigned short>,lua_State *,int)67 inline std::string name_of_type(by_value<unsigned short>, lua_State*, int) { return "number"; } name_of_type(by_value<unsigned int>,lua_State *,int)68 inline std::string name_of_type(by_value<unsigned int>, lua_State*, int) { return "number"; } name_of_type(by_value<unsigned long>,lua_State *,int)69 inline std::string name_of_type(by_value<unsigned long>, lua_State*, int) { return "number"; } 70 name_of_type(by_value<const bool>,lua_State *,int)71 inline std::string name_of_type(by_value<const bool>, lua_State*, int) { return "boolean"; } name_of_type(by_value<const char>,lua_State *,int)72 inline std::string name_of_type(by_value<const char>, lua_State*, int) { return "number"; } name_of_type(by_value<const short>,lua_State *,int)73 inline std::string name_of_type(by_value<const short>, lua_State*, int) { return "number"; } name_of_type(by_value<const int>,lua_State *,int)74 inline std::string name_of_type(by_value<const int>, lua_State*, int) { return "number"; } name_of_type(by_value<const long>,lua_State *,int)75 inline std::string name_of_type(by_value<const long>, lua_State*, int) { return "number"; } name_of_type(by_value<const unsigned char>,lua_State *,int)76 inline std::string name_of_type(by_value<const unsigned char>, lua_State*, int) { return "number"; } name_of_type(by_value<const unsigned short>,lua_State *,int)77 inline std::string name_of_type(by_value<const unsigned short>, lua_State*, int) { return "number"; } name_of_type(by_value<const unsigned int>,lua_State *,int)78 inline std::string name_of_type(by_value<const unsigned int>, lua_State*, int) { return "number"; } name_of_type(by_value<const unsigned long>,lua_State *,int)79 inline std::string name_of_type(by_value<const unsigned long>, lua_State*, int) { return "number"; } 80 81 // template<class T> 82 // inline std::string name_of_type(by_value<luabind::functor<T> >, lua_State* L, long) { return "function<" + name_of_type(LUABIND_DECORATE_TYPE(T), L, 0L) + ">"; } 83 name_of_type(by_value<std::string>,lua_State *,int)84 inline std::string name_of_type(by_value<std::string>, lua_State*, int) { return "string"; } name_of_type(by_const_pointer<char>,lua_State *,int)85 inline std::string name_of_type(by_const_pointer<char>, lua_State*, int) { return "string"; } name_of_type(by_pointer<lua_State>,lua_State *,int)86 inline std::string name_of_type(by_pointer<lua_State>, lua_State*, int) { return "lua_State*"; } 87 88 template<class T> 89 struct type_name_unless_void 90 { applyluabind::detail::type_name_unless_void91 inline static void apply(std::string& s, lua_State* L, bool first) 92 { 93 if (!first) s += ", "; 94 s += name_of_type(LUABIND_DECORATE_TYPE(T), L, 0L); 95 } 96 }; 97 98 template<> 99 struct type_name_unless_void<null_type> 100 { applyluabind::detail::type_name_unless_void101 inline static void apply(std::string&, lua_State*, bool) {} 102 }; 103 104 #define LUABIND_ADD_LUA_TYPE_NAME(z, n, _) type_name_unless_void<BOOST_PP_CAT(A, BOOST_PP_INC(n))>::apply(s, L, false); 105 106 #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, <luabind/detail/get_signature.hpp>, 1)) 107 #include BOOST_PP_ITERATE() 108 109 template<class F> 110 struct get_member_signature 111 { applyluabind::detail::get_member_signature112 static inline void apply(lua_State* L, std::string& s) 113 { 114 get_member_signature_impl(static_cast<F>(0), L, s); 115 } 116 }; 117 118 template<class F> 119 struct get_free_function_signature 120 { applyluabind::detail::get_free_function_signature121 static inline void apply(lua_State* L, std::string& s) 122 { 123 get_free_function_signature_impl(static_cast<F>(0), L, s); 124 } 125 }; 126 127 128 template<class Sig> 129 struct get_signature 130 { applyluabind::detail::get_signature131 static inline void apply(lua_State* L, std::string& s) 132 { 133 get_signature_impl(static_cast<const Sig*>(0), L, s); 134 } 135 }; 136 137 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A)> get_signature_impl(const constructor<BOOST_PP_ENUM_PARAMS (LUABIND_MAX_ARITY,A)> *,lua_State * L,std::string & s)138 inline void get_signature_impl(const constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>*, lua_State* L, std::string& s) 139 { 140 s += "("; 141 type_name_unless_void<A0>::apply(s, L, true); 142 BOOST_PP_REPEAT(BOOST_PP_DEC(LUABIND_MAX_ARITY), LUABIND_ADD_LUA_TYPE_NAME, _) 143 s += ")"; 144 } 145 146 #undef LUABIND_ADD_LUA_TYPE_NAME 147 148 template<class T> 149 struct get_setter_signature 150 { applyluabind::detail::get_setter_signature151 static void apply(lua_State* L, std::string& s) 152 { 153 s += "("; 154 s += name_of_type(LUABIND_DECORATE_TYPE(T), L, 0L); 155 s += ")"; 156 } 157 }; 158 159 }} 160 161 #endif // LUABIND_GET_SIGNATURE_HPP_INCLUDED 162 163 #else 164 #if BOOST_PP_ITERATION_FLAGS() == 1 165 166 // member functions 167 template<class T, class C BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)> get_member_signature_impl(T (C::*)(BOOST_PP_ENUM_PARAMS (BOOST_PP_ITERATION (),A)),lua_State * L,std::string & s)168 inline void get_member_signature_impl(T(C::*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A)), lua_State* L, std::string& s) 169 { 170 s += "("; 171 #if BOOST_PP_ITERATION() > 0 172 s += name_of_type(LUABIND_DECORATE_TYPE(A0), L, 0L); 173 BOOST_PP_REPEAT(BOOST_PP_DEC(BOOST_PP_ITERATION()), LUABIND_ADD_LUA_TYPE_NAME, _) 174 #endif 175 s += ")"; 176 } 177 178 template<class T, class C BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)> get_member_signature_impl(T (C::*)(BOOST_PP_ENUM_PARAMS (BOOST_PP_ITERATION (),A))const,lua_State * L,std::string & s)179 inline void get_member_signature_impl(T(C::*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A)) const, lua_State* L, std::string& s) 180 { 181 (void)L; 182 s += "("; 183 #if BOOST_PP_ITERATION() > 0 184 s += name_of_type(LUABIND_DECORATE_TYPE(A0), L, 0L); 185 BOOST_PP_REPEAT(BOOST_PP_DEC(BOOST_PP_ITERATION()), LUABIND_ADD_LUA_TYPE_NAME, _) 186 #endif 187 s += ") const"; 188 } 189 190 // const C& obj 191 template<class T BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)> get_member_signature_impl(T (* f)(BOOST_PP_ENUM_PARAMS (BOOST_PP_ITERATION (),A)),lua_State * L,std::string & s)192 inline void get_member_signature_impl(T(*f)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A)), lua_State* L, std::string& s) 193 { 194 s += "("; 195 #if BOOST_PP_ITERATION() > 0 196 s += name_of_type(LUABIND_DECORATE_TYPE(A0), L, 0L); 197 BOOST_PP_REPEAT(BOOST_PP_DEC(BOOST_PP_ITERATION()), LUABIND_ADD_LUA_TYPE_NAME, _) 198 #endif 199 s += ")"; 200 } 201 202 // free functions 203 template<class T BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)> get_free_function_signature_impl(T (* f)(BOOST_PP_ENUM_PARAMS (BOOST_PP_ITERATION (),A)),lua_State * L,std::string & s)204 inline void get_free_function_signature_impl(T(*f)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A)), lua_State* L, std::string& s) 205 { 206 (void)f; 207 s += "("; 208 #if BOOST_PP_ITERATION() > 0 209 s += name_of_type(LUABIND_DECORATE_TYPE(A0), L, 0L); 210 BOOST_PP_REPEAT(BOOST_PP_DEC(BOOST_PP_ITERATION()), LUABIND_ADD_LUA_TYPE_NAME, _) 211 #endif 212 s += ")"; 213 } 214 215 #endif 216 #endif 217 218 #endif // LUABIND_NO_ERROR_CHECKING 219