Skip to content

Instantly share code, notes, and snippets.

@Twinklebear
Created April 1, 2013 08:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Twinklebear/5283762 to your computer and use it in GitHub Desktop.
Save Twinklebear/5283762 to your computer and use it in GitHub Desktop.
Lua binding generation fiddling
#include <string>
#include <lua/lua.hpp>
//Our fake DataLib
template<class T>
class DataLib {
public:
static void Push(lua_State *l, const T obj);
static T GetCopy(lua_State *l, int i);
};
//Int specialization
template<>
void DataLib<int>::Push(lua_State *l, const int obj){
lua_pushinteger(l, obj);
}
template<>
int DataLib<int>::GetCopy(lua_State *l, int i){
return luaL_checkint(l, i);
}
//Float specialization
template<>
void DataLib<float>::Push(lua_State *l, const float obj){
lua_pushnumber(l, obj);
}
template<>
float DataLib<float>::GetCopy(lua_State *l, int i){
return luaL_checknumber(l, i);
}
//String specialization
template<>
void DataLib<std::string>::Push(lua_State *l, const std::string obj){
lua_pushstring(l, obj.c_str());
}
template<>
std::string DataLib<std::string>::GetCopy(lua_State *l, int i){
return luaL_checkstring(l, i);
}
#include <iostream>
#include <string>
#include <tuple>
#include <functional>
#include <chrono>
#include <thread>
#include <lua/lua.hpp>
#include "datalib.h"
#define RETURN(x) -> decltype(x){ return x; }
//----------------------------------------------------
// Apply Tuple code
//----------------------------------------------------
//Call a function with a tuple as the parameters
//General recursion step
template<size_t N>
struct apply {
template<class F, class... ArgsT, class... Args>
static inline auto applyTuple(const F &f, std::tuple<ArgsT...> &t, Args&... args)
RETURN(apply<N-1>::applyTuple(f, t, std::get<N-1>(t), args...));
};
//Final recursion level
template<>
struct apply<0> {
template<class F, class... ArgsT, class... Args>
static inline auto applyTuple(const F &f, std::tuple<ArgsT...> &t, Args&... args)
RETURN(f(args...));
};
//Helper to get things started
template<class F, class... ArgsT>
static inline auto applyTuple(const F &f, std::tuple<ArgsT...> &t)
RETURN(apply<sizeof...(ArgsT)>::applyTuple(f, t));
//----------------------------------------------------
// Set Tuple code
//----------------------------------------------------
//Set a tuple's values using those returned by DataLib<type>
template<size_t N>
struct setter {
template<class... ArgsT>
static inline void setTuple(lua_State *l, std::tuple<ArgsT...> &t){
std::get<N>(t) = DataLib<typename std::tuple_element<N, std::tuple<ArgsT...>>::type>::GetCopy(l, N + 1);
//move to next
setter<N-1>::setTuple(l, t);
}
};
//Final recursion level
template<>
struct setter<0> {
template<class... ArgsT>
static inline void setTuple(lua_State *l, std::tuple<ArgsT...> &t){
std::get<0>(t) = DataLib<typename std::tuple_element<0, std::tuple<ArgsT...>>::type>::GetCopy(l, 1);
}
};
//Helper to get things started
template<class... ArgsT>
static inline void setTuple(lua_State *l, std::tuple<ArgsT...> &t){
setter<sizeof...(ArgsT) - 1>::setTuple(l, t);
}
//----------------------------------------------------
//----------------------------------------------------
// Generate a wrapped function
//----------------------------------------------------
//How?
//----------------------------------------------------
int func(int i, float f){
std::cout << "in func, int: " << i << ", float: " << f << std::endl;
return 100;
}
//Need to come up with a way to generate this function somehow
int wrap(lua_State *l){
std::tuple<int, float> args;
setTuple(l, args);
int res = applyTuple(func, args);
DataLib<int>::Push(l, res);
return 1;
}
int speak(lua_State *l){
std::cout << DataLib<std::string>::GetCopy(l, 1) << std::endl;
return 0;
}
const struct luaL_Reg testLib[] = {
{ "speak", speak },
{ "wrap", wrap },
{ NULL, NULL }
};
int luaopen_test(lua_State *l){
luaL_register(l, "Test", testLib);
lua_pop(l, 1);
return 0;
}
int main(int argc, char const **argv){
lua_State *l = luaL_newstate();
luaL_openlibs(l);
luaopen_test(l);
std::string program = std::string("print 'hello!'\n") + std::string("Test.speak('wee!')\n")
+ std::string("q = Test.wrap(10, 4.5)\n") + std::string("print ('q is: ' .. q)\n");
luaL_dostring(l, program.c_str());
lua_close(l);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment