00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef LUAXX_H
00026 #define LUAXX_H
00027
00028 #include <lua.hpp>
00029 #include <string>
00030 #include <vector>
00031 #include <new>
00032 #include <exception>
00033
00055 namespace lua
00056 {
00059 class exception : public std::exception {
00060 public:
00062 exception() : std::exception() { }
00064 explicit exception(const char* desc) : std::exception(), description(desc) { }
00065 virtual ~exception() throw() { }
00069 virtual const char* what() const throw() {
00070 return description.c_str();
00071 }
00072 private:
00073 std::string description;
00074 };
00075
00080 class runtime_error : public exception {
00081 public:
00083 runtime_error() : exception() { }
00085 explicit runtime_error(const char* desc) : exception(desc) { }
00086 virtual ~runtime_error() throw() { }
00087 };
00088
00091 class syntax_error : public exception {
00092 public:
00094 syntax_error() : exception() { }
00096 explicit syntax_error(const char* desc) : exception(desc) { }
00097 virtual ~syntax_error() throw() { }
00098 };
00099
00104 class file_error : public exception {
00105 public:
00107 file_error() : exception() { }
00109 explicit file_error(const char* desc) : exception(desc) { }
00110 virtual ~file_error() throw() { }
00111 };
00112
00115 class bad_alloc : public exception, std::bad_alloc {
00116 public:
00118 bad_alloc() : lua::exception(), std::bad_alloc() { }
00120 explicit bad_alloc(const char* desc) : lua::exception(desc), std::bad_alloc() { }
00121 virtual ~bad_alloc() throw() { }
00122 };
00123
00126 class bad_conversion : public exception {
00127 public:
00129 bad_conversion() : exception() { }
00131 explicit bad_conversion(const char* desc) : exception(desc) { }
00132 virtual ~bad_conversion() throw() { }
00133 };
00134
00136 class table { };
00138 class nil { };
00140 class function { };
00142 class userdata { };
00144 class lightuserdata { };
00145
00146 typedef lua_CFunction cfunction;
00147 typedef lua_Integer integer;
00148 typedef lua_Number number;
00149 typedef lua_Reader reader;
00150 const int multiret = LUA_MULTRET;
00151
00156 class state {
00157 public:
00158 state();
00159 state(lua_State* L);
00160 ~state();
00161
00162 operator lua_State*();
00163
00164 state& push();
00165 state& push(nil);
00166 state& push(bool boolean);
00167 template<typename T> state& push(T number);
00168 state& push(const char* s, size_t length);
00169 state& push(const char* s);
00170 state& push(const std::string& s);
00171 state& push(cfunction f);
00172 state& push(table);
00173 state& push(void* p);
00174 template<typename T> state& pushlightuserdata(T p);
00175
00176 template<typename T> state& to(T& number, int index = -1);
00177 template<typename T> state& touserdata(T& p, int index = -1);
00178
00179 template<typename T> T as(T default_value, int index = -1);
00180 template<typename T> T as(int index = -1);
00181
00182 template<typename T> bool is(int index = -1);
00183
00184 state& check(int narg);
00185 #if lua_Integer != int
00186 state& check(int& i, int narg);
00187 #endif
00188 state& check(integer& i, int narg);
00189 #if lua_Integer != long
00190 state& check(long& l, int narg);
00191 #endif
00192 state& check(std::string& s, int narg);
00193 state& check(number& n, int narg);
00194
00195 template<typename msg_t> void error(msg_t message);
00196 #if 0
00197 template<> void error(const std::string& message);
00198 #endif
00199
00200 state& pcall(int nargs = 0, int nresults = 0, int on_error = 0);
00201 state& call(int nargs = 0, int nresults = 0);
00202
00203 state& checkstack(int size);
00204 state& settop(int index);
00205 int gettop();
00206 int size();
00207 bool empty();
00208
00209 state& insert(int index);
00210 state& replace(int index);
00211 state& remove(int index);
00212 state& pop(int elements = 1);
00213
00214 state& pushvalue(int index);
00215
00216 state& newtable();
00217 bool newmetatable(const std::string& tname);
00218 template<typename userdata_t> userdata_t* newuserdata();
00219 void* newuserdata(size_t nbytes);
00220
00221 state& gettable(int index = -2);
00222 state& getfield(const std::string& k, int index = -1);
00223 state& settable(int index = -3);
00224 state& setfield(const std::string& k, int index = -2);
00225 state& getmetatable(const std::string& tname);
00226 bool getmetatable(int index);
00227
00228 bool next(int index = -2);
00229
00230 state& getglobal(const std::string& name);
00231 state& setglobal(const std::string& name);
00232
00233 state& loadfile(const std::string& filename);
00234 state& loadstring(const std::string& s);
00235
00236 template<typename iterator_t> state& load(iterator_t begin, iterator_t end);
00237
00238 size_t objlen(int index = -1);
00239
00240 private:
00241 lua_State* L;
00242 bool managed;
00243
00244
00245 state(const state&);
00246 state& operator = (const state&);
00247
00248 int throw_error(int code);
00249 };
00250
00251
00252
00260 template<typename T>
00261 state& state::push(T number) {
00262 lua_pushnumber(L, number);
00263 return *this;
00264 }
00265
00271 template<typename T>
00272 state& state::pushlightuserdata(T p) {
00273 lua_pushlightuserdata(L, p);
00274 return *this;
00275 }
00276
00286 template<typename T>
00287 bool state::is(int index) {
00288 return lua_isnumber(L, index);
00289 }
00290
00303 template<typename T>
00304 state& state::to(T& number, int index) {
00305 if (lua_isnumber(L, index))
00306 number = static_cast<T>(lua_tonumber(L, index));
00307 else
00308 throw bad_conversion("Cannot convert non 'number' value to number");
00309
00310 return *this;
00311 }
00312
00325 template<typename T>
00326 state& state::touserdata(T& p, int index) {
00327 if (lua_isuserdata(L, index))
00328 p = reinterpret_cast<T>(lua_touserdata(L, index));
00329 else
00330 throw bad_conversion("Cannot convert non 'userdata' or 'lightuserdata' value to userdata");
00331
00332 return *this;
00333 }
00334
00345 template<typename T>
00346 T state::as(T default_value, int index) {
00347 if (lua_isnumber(L, index))
00348 return static_cast<T>(lua_tonumber(L, index));
00349 else
00350 return default_value;
00351 }
00352
00377 template<typename T>
00378 T state::as(int index) {
00379 if (lua_isnumber(L, index))
00380 return static_cast<T>(lua_tonumber(L, index));
00381 else
00382 throw bad_conversion("Cannot convert non 'number' value to number");
00383 }
00384
00392 template<typename userdata_t>
00393 userdata_t* state::newuserdata() {
00394 return reinterpret_cast<userdata_t*>(lua_newuserdata(L, sizeof(userdata_t)));
00395 }
00396
00405 template<typename msg_t>
00406 void state::error(msg_t message) {
00407 push(message);
00408 lua_error(L);
00409 }
00410
00427 template<typename iterator_t>
00428 state& state::load(iterator_t begin, iterator_t end) {
00429
00430 std::vector<char> chunk(begin, end);
00431
00432
00433
00434 throw_error(luaL_loadbuffer(L, &(*chunk.begin()), chunk.size(), NULL));
00435 return *this;
00436 }
00437
00438
00439
00440 template<> state& state::to(bool& boolean, int index);
00441 template<> state& state::to(std::string& string, int index);
00442
00443 template<> bool state::as(bool default_value, int index);
00444 template<> std::string state::as(std::string default_value, int index);
00445 template<> bool state::as(int index);
00446 template<> std::string state::as(int index);
00447
00448 template<> bool state::is<nil>(int index);
00449 template<> bool state::is<bool>(int index);
00450 template<> bool state::is<std::string>(int index);
00451 template<> bool state::is<table>(int index);
00452 template<> bool state::is<cfunction>(int index);
00453 template<> bool state::is<function>(int index);
00454 template<> bool state::is<userdata>(int index);
00455 template<> bool state::is<lightuserdata>(int index);
00456
00457
00458
00459
00467 inline state::operator lua_State*() {
00468 return L;
00469 }
00470
00482 inline int state::throw_error(int code) {
00483 std::string error;
00484
00485
00486 switch (code) {
00487 case 0:
00488 break;
00489 case LUA_ERRSYNTAX:
00490 to(error).pop();
00491 throw syntax_error(error.c_str());
00492 case LUA_ERRMEM:
00493 to(error).pop();
00494 throw bad_alloc(error.c_str());
00495 case LUA_ERRRUN:
00496 to(error).pop();
00497 throw runtime_error(error.c_str());
00498 case LUA_ERRFILE:
00499 to(error).pop();
00500 throw file_error(error.c_str());
00501 default:
00502 to(error).pop();
00503 throw exception(error.c_str());
00504 }
00505 return code;
00506 }
00507
00508 }
00509
00510 #endif