[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: user data with pointer template
- From: "Panagiotis Vossos" <pavossos@...>
- Date: Wed, 17 Oct 2007 01:11:40 +0300
I have written the following template to help me when wrapping C/C++
pointers in lua userdata. Any comments or ideas?
regards,
panagiotis.
/*
User Data With Pointer AUXiliary template.
Mostly inspired by `User Data With Pointer Example' on the lua wiki,
provides definitions for various almost-always-used functions. The
second argument is a trait that has only one method `name', that
returns a string for the wrapped type. Note that `alloc' does not
allocate anything (we do not know if the wrapped type has a default
constructor), just sets up the passed pointer on the lua stack.
*/
#ifndef PAVUDWPAUX_HPP
#define PAVUDWPAUX_HPP
#include <cassert>
#include <string>
#include <cstdio>
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
namespace pav {
template<typename T, typename Tr>
struct udwpaux
{
typedef T* ptr;
typedef T** pptr;
static int setup(lua_State *L, const luaL_reg *m, const luaL_reg *f) {
const std::string name = Tr::name();
luaL_newmetatable(L, name.c_str());
lua_pushstring(L, "__index");
lua_pushvalue(L, -2);
lua_settable(L, -3);
luaL_register(L, NULL, m);
luaL_register(L, name.c_str(), f);
return 1;
}
static ptr check(lua_State *L, int index) {
const std::string name = Tr::name();
luaL_checktype(L, index, LUA_TUSERDATA);
pptr v = (pptr) luaL_checkudata(L, index, name.c_str());
if (!v) luaL_typerror(L, index, name.c_str());
ptr p = *v;
if (!p) {
char buf[100];
std::sprintf(buf, "NULL %s", name.c_str());
luaL_error(L, buf);
}
return p;
}
static pptr alloc(lua_State *L, ptr p) {
const std::string name = Tr::name();
pptr v = (pptr) lua_newuserdata(L, sizeof(ptr));
*v = p;
luaL_getmetatable(L, name.c_str());
lua_setmetatable(L, -2);
#ifdef SHOWNEWDELETE
std::printf("NEW %s [%p]\n", name.c_str(), v);
#endif
return v;
}
static int gc(lua_State *L) {
const std::string name = Tr::name();
pptr p = (pptr) lua_touserdata(L, 1);
if (!p) luaL_typerror(L, 1, name.c_str());
assert(*p);
delete *p;
#ifdef SHOWNEWDELETE
std::printf("DELETE %s [%p]!\n", name.c_str(), p);
#endif
return 0;
}
};
}
#endif // PAVUDWPAUX_HPP