lua.h
Go to the documentation of this file.
00001 /* 00002 * Copyright 2006-2009 Savarese Software Research Corporation 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * https://www.savarese.com/software/ApacheLicense-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00022 #ifndef __SSRC_WSPR_LUA_LUA_H 00023 #define __SSRC_WSPR_LUA_LUA_H 00024 00030 namespace Lua { 00031 #include <lua.hpp> 00032 } 00033 00034 #include <ssrc/wispers-packages.h> 00035 00036 #include <string> 00037 #include <stdexcept> 00038 00039 __BEGIN_NS_SSRC_WSPR_LUA 00040 00041 using namespace Lua; 00042 using std::string; 00043 00044 template<typename R> inline R convert(lua_State *state, int index = -1); 00045 00046 template<> inline bool convert<bool>(lua_State *state, int index) { 00047 return lua_toboolean(state, index); 00048 } 00049 00050 template<> inline int convert<int>(lua_State *state, int index) { 00051 return lua_tointeger(state, index); 00052 } 00053 00054 template<> inline 00055 unsigned int convert<unsigned int>(lua_State *state, int index) { 00056 return static_cast<unsigned int>(lua_tointeger(state, index)); 00057 } 00058 00059 template<> inline string convert<string>(lua_State *state, int index) { 00060 const char *str = lua_tolstring(state, index, static_cast<size_t*>(0)); 00061 return (str != 0 ? str : string()); 00062 } 00063 00064 template<> 00065 inline const char * convert<const char *>(lua_State *state, int index) { 00066 return lua_tolstring(state, index, static_cast<size_t*>(0)); 00067 } 00068 00069 template<> inline lua_Number convert<lua_Number>(lua_State *state, int index) { 00070 return lua_tonumber(state, index); 00071 } 00072 00073 inline void push_value(lua_State *state, const bool value) { 00074 lua_pushboolean(state, value); 00075 } 00076 00077 inline void push_value(lua_State *state, const int value) { 00078 lua_pushinteger(state, value); 00079 } 00080 00081 inline void push_value(lua_State *state, const lua_Number value) { 00082 lua_pushnumber(state, value); 00083 } 00084 00085 inline void push_value(lua_State *state, const char *value) { 00086 lua_pushstring(state, value); 00087 } 00088 00089 inline void push_value(lua_State *state, const string & value) { 00090 lua_pushlstring(state, value.c_str(), value.size()); 00091 } 00092 00093 inline void push_value(lua_State *state, void *value) { 00094 lua_pushlightuserdata(state, value); 00095 } 00096 00097 inline void push_value(lua_State *state, const void *value) { 00098 lua_pushlightuserdata(state, const_cast<void *>(value)); 00099 } 00100 00101 // This version is in order to support zero-arg pcall. 00102 inline void push_values(lua_State *) { } 00103 00104 template<typename P> 00105 inline void push_values(lua_State *state, const P & p) { 00106 push_value(state, p); 00107 } 00108 00109 template<typename T, typename... P> 00110 inline void push_values(lua_State *state, const T & t, const P & ...p) { 00111 push_value(state, t); 00112 push_values(state, p...); 00113 } 00114 00115 template<typename V> 00116 inline void set_field(lua_State* state, int index, const V & value, 00117 const char * const field) 00118 { 00119 push_value(state, value); 00120 lua_setfield(state, (index < 0 ? index - 1 : index), field); 00121 } 00122 00123 template<typename V> 00124 inline void set_field(lua_State* state, int index, const V & value, 00125 const string & field) 00126 { 00127 push_value(state, field); 00128 push_value(state, value); 00129 lua_settable(state, (index < 0 ? index - 2 : index)); 00130 } 00131 00132 template<typename V> 00133 inline void set_field(lua_State* state, int index, const V & value, int n) { 00134 push_value(state, value); 00135 lua_rawseti(state, (index < 0 ? index - 1 : index), n); 00136 } 00137 00138 namespace detail { 00139 inline 00140 void _get_field(lua_State* state, int index, const char * const field) { 00141 lua_getfield(state, index, field); 00142 } 00143 00144 inline void _get_field(lua_State* state, int index, const string & field) { 00145 push_value(state, field); 00146 lua_gettable(state, (index < 0 ? index - 1 : index)); 00147 } 00148 00149 template<typename V> 00150 inline void _create_value(lua_State* state, const V & value, 00151 const char * const field) 00152 { 00153 set_field(state, -1, value, field); 00154 } 00155 00156 template<typename V> 00157 inline void _create_value(lua_State* state, const V & value, 00158 const string & field) 00159 { 00160 set_field(state, -1, value, field); 00161 } 00162 00163 template<typename V, typename... P> 00164 inline void _create_value(lua_State* state, const V & value, 00165 const char * const field, P...p) 00166 { 00167 lua_newtable(state); 00168 _create_value(state, value, p...); 00169 lua_setfield(state, -2, field); 00170 } 00171 00172 template<typename V> 00173 inline void _set_value(lua_State* state, const V & value, 00174 const char * const field) 00175 { 00176 set_field(state, -1, value, field); 00177 } 00178 00179 template<typename V> 00180 inline void _set_value(lua_State* state, const V & value, 00181 const string & field) 00182 { 00183 set_field(state, -1, value, field); 00184 } 00185 00186 template<typename V, typename... P> 00187 inline void _set_value(lua_State* state, const V & value, 00188 const char * const field, P...p) 00189 { 00190 _get_field(state, -1, field); 00191 _set_value(state, value, p...); 00192 lua_pop(state, 1); 00193 } 00194 } 00195 00196 inline void get_global(lua_State* state, const char * const field) { 00197 lua_getglobal(state, field); 00198 } 00199 00200 inline void get_global(lua_State* state, const string & field) { 00201 push_value(state, field); 00202 lua_gettable(state, LUA_GLOBALSINDEX); 00203 } 00204 00205 template<typename V> 00206 inline void set_global(lua_State* state, const V & value, 00207 const char * const field) 00208 { 00209 push_value(state, value); 00210 lua_setglobal(state, field); 00211 } 00212 00213 template<typename V> 00214 inline void set_global(lua_State* state, const V & value, const string & field) 00215 { 00216 push_value(state, field); 00217 push_value(state, value); 00218 lua_settable(state, LUA_GLOBALSINDEX); 00219 } 00220 00221 template<typename R> 00222 inline const R get_field(const R & default_value, 00223 lua_State* state, 00224 int index, 00225 const char * const field) 00226 { 00227 lua_getfield(state, index, field); 00228 const R & result = 00229 (lua_isnoneornil(state, -1) ? default_value : convert<R>(state)); 00230 lua_pop(state, 1); 00231 return result; 00232 } 00233 00234 template<typename R> 00235 inline const R get_field(const R & default_value, 00236 lua_State* state, 00237 int index, 00238 const string & field) 00239 { 00240 detail::_get_field(state, index, field); 00241 const R & result = 00242 (lua_isnoneornil(state, -1) ? default_value : convert<R>(state)); 00243 lua_pop(state, 1); 00244 return result; 00245 } 00246 00247 template<typename R> 00248 inline const R get_field(const R & default_value, 00249 lua_State* state, 00250 int index, 00251 int n) 00252 { 00253 lua_rawgeti(state, index, n); 00254 const R & result = 00255 (lua_isnoneornil(state, -1) ? default_value : convert<R>(state)); 00256 lua_pop(state, 1); 00257 return result; 00258 } 00259 00260 template<typename R, typename... P> 00261 inline const R get_field(const R & default_value, 00262 lua_State* state, 00263 int index, 00264 const char * const field, 00265 P ...p) 00266 { 00267 lua_getfield(state, index, field); 00268 const R & result = 00269 (lua_isnoneornil(state, -1) ? 00270 default_value : get_field<R>(default_value, state, -1, p...)); 00271 lua_pop(state, 1); 00272 return result; 00273 } 00274 00275 template<typename R> inline 00276 const R get_field(lua_State* state, int index, const char * const field) { 00277 return get_field(R(), state, index, field); 00278 } 00279 00280 template<typename R> inline 00281 const R get_field(lua_State* state, int index, const string & field) { 00282 return get_field(R(), state, index, field); 00283 } 00284 00285 template<typename R> inline 00286 const R get_field(lua_State* state, int index, int n) { 00287 return get_field(R(), state, index, n); 00288 } 00289 00290 template<typename R, typename... P> 00291 inline const R get_field(lua_State* state, 00292 int index, 00293 const char * const field, 00294 P ...p) 00295 { 00296 return get_field(R(), state, index, field, p...); 00297 } 00298 00299 template<typename R> 00300 inline const R get_value(const R & default_value, 00301 lua_State* state, 00302 const char * const var) 00303 { 00304 get_global(state, var); 00305 const R & result = 00306 (lua_isnoneornil(state, -1) ? default_value : convert<R>(state)); 00307 lua_pop(state, 1); 00308 return result; 00309 } 00310 00311 template<typename R> 00312 inline const R get_value(const R & default_value, 00313 lua_State* state, 00314 const string & var) 00315 { 00316 get_global(state, var); 00317 const R & result = 00318 (lua_isnoneornil(state, -1) ? default_value : convert<R>(state)); 00319 lua_pop(state, 1); 00320 return result; 00321 } 00322 00323 template<typename R, typename... P> 00324 inline const R get_value(const R & default_value, 00325 lua_State* state, 00326 const char * const var, 00327 P ...p) 00328 { 00329 get_global(state, var); 00330 const R & result = 00331 (lua_isnoneornil(state, -1) ? default_value : get_field<R>(state, -1, p...)); 00332 lua_pop(state, 1); 00333 return result; 00334 } 00335 00336 template<typename R> 00337 inline const R get_value(lua_State* state, const char * const var) { 00338 return get_value(R(), state, var); 00339 } 00340 00341 template<typename R> 00342 inline const R get_value(lua_State* state, const string & var) { 00343 return get_value(R(), state, var); 00344 } 00345 00346 template<typename R, typename... P> 00347 inline const R get_value(lua_State* state, const char * const var, P ...p) { 00348 return get_value(R(), state, var, p...); 00349 } 00350 00351 template<typename V> 00352 inline void create_value(lua_State* state, const V & value, 00353 const char * const var) 00354 { 00355 set_global(state, value, var); 00356 } 00357 00358 template<typename V> 00359 inline void create_value(lua_State* state, const V & value, 00360 const string & var) 00361 { 00362 set_global(state, value, var); 00363 } 00364 00365 template<typename V, typename... P> 00366 inline void create_value(lua_State* state, const V & value, 00367 const char * const var, P ...p) 00368 { 00369 lua_newtable(state); 00370 detail::_create_value(state, value, p...); 00371 lua_setglobal(state, var); 00372 } 00373 00374 template<typename V, typename... P> 00375 inline void set_field(lua_State* state, int index, const V & value, 00376 const char * const field, P ...p) 00377 { 00378 lua_getfield(state, index, field); 00379 if(!lua_istable(state, -1)) { 00380 lua_pop(state, 1); 00381 lua_newtable(state); 00382 lua_setfield(state, (index < 0 ? index - 1 : index), field); 00383 lua_getfield(state, index, field); 00384 } 00385 set_field(state, -1, value, p...); 00386 lua_pop(state, 1); 00387 } 00388 00389 template<typename V> 00390 inline void set_value(lua_State* state, const V & value, 00391 const char * const var) 00392 { 00393 set_global(state, value, var); 00394 } 00395 00396 template<typename V> 00397 inline void set_value(lua_State* state, const V & value, const string & var) { 00398 set_global(state, value, var); 00399 } 00400 00401 template<typename V, typename... P> 00402 inline void set_value(lua_State* state, const V & value, 00403 const char * const var, P ...p) 00404 { 00405 get_global(state, var); 00406 detail::_set_value(state, value, p...); 00407 lua_pop(state, 1); 00408 } 00409 00410 template<typename I> 00411 inline void 00412 prepend_package_path(lua_State* state, const I & begin, const I & end) { 00413 string lua_path_str; 00414 lua_path_str.reserve(256); 00415 00416 for(I it = begin; it != end; ++it) { 00417 lua_path_str.append(*it).append("/?.lua;"); 00418 } 00419 00420 get_global(state, "package"); 00421 lua_getfield(state, -1, "path"); 00422 lua_path_str.append(lua_tostring(state, -1)); 00423 set_field(state, -2, lua_path_str, "path"); 00424 lua_pop(state, 2); 00425 } 00426 00427 struct LuaCallError : std::runtime_error { 00428 int lua_error; 00429 00430 explicit LuaCallError(const string & message, const int lua_error) : 00431 std::runtime_error(message), lua_error(lua_error) 00432 {} 00433 }; 00434 00439 template<typename... P> 00440 inline 00441 void pcall_nopop(const int nargs, const int nresults, lua_State* state, P ...p) 00442 SSRC_DECL_THROW(LuaCallError) 00443 { 00444 push_values(state, p...); 00445 00446 int err = lua_pcall(state, nargs, nresults, 0); 00447 00448 if(err) { 00449 string msg(lua_tostring(state, -1)); 00450 lua_pop(state, 1); 00451 throw LuaCallError(msg, err); 00452 } 00453 } 00454 00455 template<typename... P> 00456 inline void pcall_nopop(const int nresults, lua_State* state, P ...p) 00457 SSRC_DECL_THROW(LuaCallError) 00458 { 00459 pcall_nopop(sizeof...(P), nresults, state, p...); 00460 } 00461 00467 template<typename R, typename... P> 00468 inline R pcall_ret(lua_State* state, const P & ...p) 00469 SSRC_DECL_THROW(LuaCallError) 00470 { 00471 pcall_nopop(1, state, p...); 00472 const R & result = convert<R>(state); 00473 lua_pop(state, 1); 00474 return result; 00475 } 00476 00477 template<typename... P> 00478 inline void pcall(lua_State* state, const P & ...p) 00479 SSRC_DECL_THROW(LuaCallError) 00480 { 00481 pcall_nopop(0, state, p...); 00482 } 00483 00484 __END_NS_SSRC_WSPR_LUA 00485 00486 #endif
Copyright © 2006-2011 Savarese Software Research Corporation. All rights reserved.