Savarese Software Research Corporation
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

Savarese Software Research Corporation
Copyright © 2006-2011 Savarese Software Research Corporation. All rights reserved.