customize LuaBridge
authorRobin Gareus <robin@gareus.org>
Sun, 21 Feb 2016 18:25:42 +0000 (19:25 +0100)
committerRobin Gareus <robin@gareus.org>
Mon, 22 Feb 2016 21:06:47 +0000 (22:06 +0100)
* introduce boost::shared_ptr support
* support enum & const
* allow to add non-class member functions
* STL iterators (vector, list, set, bitset & map)
* support reference arguments (framecnt_t&)
* add support for arrays of basic types (e.g. float*, int*)
* fix compiler warnings

libs/lua/LuaBridge/LuaBridge.h
libs/lua/LuaBridge/detail/CFunctions.h
libs/lua/LuaBridge/detail/LuaRef.h
libs/lua/LuaBridge/detail/Namespace.h
libs/lua/LuaBridge/detail/Stack.h
libs/lua/LuaBridge/detail/TypeTraits.h
libs/lua/LuaBridge/detail/Userdata.h
libs/lua/LuaBridge/detail/dump.h

index 1928e9a1f0334c2ee16cd2607685c21bb08f82d7..fb61340bcc1b419dc32109577c14c82305fce246 100644 (file)
@@ -1,7 +1,8 @@
 //------------------------------------------------------------------------------
 /*
   https://github.com/vinniefalco/LuaBridge
-  
+
+  Copyright 2016, Robin Gareus <robin@gareus.org>
   Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
   Copyright 2007, Nathan Reed
 
 #include <string>
 #include <typeinfo>
 
+#include <bitset>
+#include <list>
+#include <map>
+#include <set>
+#include <vector>
+
+#include <inttypes.h>
+#include <boost/ref.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/shared_ptr.hpp>
+
 #define LUABRIDGE_MAJOR_VERSION 2
 #define LUABRIDGE_MINOR_VERSION 0
 #define LUABRIDGE_VERSION 200
@@ -137,6 +149,6 @@ inline void setHideMetatables (bool shouldHide)
   Security::setHideMetatables (shouldHide);
 }
 
-}
+} // end Namespace
 
 #endif
index ebf962ed15981cc7ce3ab959af1516c3d371b335..1c0caa84ac4fd18f358644609f69e24729b411be 100644 (file)
@@ -1,7 +1,8 @@
 //------------------------------------------------------------------------------
 /*
   https://github.com/vinniefalco/LuaBridge
-  
+
+  Copyright 2016, Robin Gareus <robin@gareus.org>
   Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
 
   License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
@@ -290,6 +291,95 @@ struct CFunc
     }
   };
 
+  template <class MemFnPtr, class T,
+           class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
+  struct CallMemberPtr
+  {
+    typedef typename FuncTraits <MemFnPtr>::Params Params;
+
+    static int f (lua_State* L)
+    {
+      assert (isfulluserdata (L, lua_upvalueindex (1)));
+      boost::shared_ptr<T>* const t = Userdata::get <boost::shared_ptr<T> > (L, 1, false);
+      T* const tt = t->get();
+      if (!tt) {
+        return luaL_error (L, "shared_ptr is nil");
+      }
+      MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
+      assert (fnptr != 0);
+      ArgList <Params, 2> args (L);
+      Stack <ReturnType>::push (L, FuncTraits <MemFnPtr>::call (tt, fnptr, args));
+      return 1;
+    }
+  };
+
+  template <class T, class R>
+  struct CastMemberPtr
+  {
+    static int f (lua_State* L)
+    {
+      boost::shared_ptr<T> t = luabridge::Stack<boost::shared_ptr<T> >::get (L, 1);
+      Stack <boost::shared_ptr<R> >::push (L, boost::dynamic_pointer_cast<R> (t));
+      return 1;
+    }
+  };
+
+  template <class T>
+  struct PtrNullCheck
+  {
+    static int f (lua_State* L)
+    {
+      boost::shared_ptr<T> t = luabridge::Stack<boost::shared_ptr<T> >::get (L, 1);
+      Stack <bool>::push (L, t == 0);
+      return 1;
+    }
+  };
+
+  template <class T>
+  struct WPtrNullCheck
+  {
+    static int f (lua_State* L)
+    {
+      bool rv = true;
+      boost::weak_ptr<T> tw = luabridge::Stack<boost::weak_ptr<T> >::get (L, 1);
+      boost::shared_ptr<T> const t = tw.lock();
+      if (t) {
+        T* const tt = t.get();
+        rv = (tt == 0);
+      }
+      Stack <bool>::push (L, rv);
+      return 1;
+    }
+  };
+
+  template <class MemFnPtr, class T,
+           class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
+  struct CallMemberWPtr
+  {
+    typedef typename FuncTraits <MemFnPtr>::Params Params;
+
+    static int f (lua_State* L)
+    {
+      assert (isfulluserdata (L, lua_upvalueindex (1)));
+      boost::weak_ptr<T>* const tw = Userdata::get <boost::weak_ptr<T> > (L, 1, false);
+      boost::shared_ptr<T> const t = tw->lock();
+      if (!t) {
+        return luaL_error (L, "cannot lock weak_ptr");
+      }
+      T* const tt = t.get();
+      if (!tt) {
+        return luaL_error (L, "weak_ptr is nil");
+      }
+      MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
+      assert (fnptr != 0);
+      ArgList <Params, 2> args (L);
+      Stack <ReturnType>::push (L, FuncTraits <MemFnPtr>::call (tt, fnptr, args));
+      return 1;
+    }
+  };
+
+
+
   //----------------------------------------------------------------------------
   /**
       lua_CFunction to call a class member function with no return value.
@@ -333,6 +423,51 @@ struct CFunc
     }
   };
 
+  template <class MemFnPtr, class T>
+  struct CallMemberPtr <MemFnPtr, T, void>
+  {
+    typedef typename FuncTraits <MemFnPtr>::Params Params;
+
+    static int f (lua_State* L)
+    {
+      assert (isfulluserdata (L, lua_upvalueindex (1)));
+      boost::shared_ptr<T>* const t = Userdata::get <boost::shared_ptr<T> > (L, 1, false);
+      T* const tt = t->get();
+      MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
+      assert (fnptr != 0);
+      ArgList <Params, 2> args (L);
+      FuncTraits <MemFnPtr>::call (tt, fnptr, args);
+      return 0;
+    }
+  };
+
+  template <class MemFnPtr, class T>
+  struct CallMemberWPtr <MemFnPtr, T, void>
+  {
+    typedef typename FuncTraits <MemFnPtr>::Params Params;
+
+    static int f (lua_State* L)
+    {
+      assert (isfulluserdata (L, lua_upvalueindex (1)));
+      boost::weak_ptr<T>* const tw = Userdata::get <boost::weak_ptr<T> > (L, 1, false);
+      boost::shared_ptr<T> const t = tw->lock();
+      if (!t) {
+        return luaL_error (L, "cannot lock weak_ptr");
+      }
+      T* const tt = t.get();
+      if (!tt) {
+        return luaL_error (L, "weak_ptr is nil");
+      }
+      MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
+      assert (fnptr != 0);
+      ArgList <Params, 2> args (L);
+      FuncTraits <MemFnPtr>::call (tt, fnptr, args);
+      return 0;
+    }
+  };
+
+
+
   //--------------------------------------------------------------------------
   /**
       lua_CFunction to call a class member lua_CFunction.
@@ -396,6 +531,30 @@ struct CFunc
     }
   };
 
+  template <class MemFnPtr>
+  struct CallMemberPtrFunctionHelper
+  {
+    typedef typename FuncTraits <MemFnPtr>::ClassType T;
+    static void add (lua_State* L, char const* name, MemFnPtr mf)
+    {
+      new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
+      lua_pushcclosure (L, &CallMemberPtr <MemFnPtr, T>::f, 1);
+      rawsetfield (L, -3, name); // class table
+    }
+  };
+
+  template <class MemFnPtr>
+  struct CallMemberWPtrFunctionHelper
+  {
+    typedef typename FuncTraits <MemFnPtr>::ClassType T;
+    static void add (lua_State* L, char const* name, MemFnPtr mf)
+    {
+      new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
+      lua_pushcclosure (L, &CallMemberWPtr <MemFnPtr, T>::f, 1);
+      rawsetfield (L, -3, name); // class table
+    }
+  };
+
   //--------------------------------------------------------------------------
   /**
       __gc metamethod for a class.
@@ -408,6 +567,11 @@ struct CFunc
     return 0;
   }
 
+  static int gcNOOPMethod (lua_State* L)
+  {
+    return 0;
+  }
+
   //--------------------------------------------------------------------------
   /**
       lua_CFunction to get a class data member.
@@ -424,6 +588,20 @@ struct CFunc
     return 1;
   }
 
+  //--------------------------------------------------------------------------
+
+  /**
+      lua_CFunction to get a constant (enum)
+  */
+  template <typename U>
+  static int getConst (lua_State* L)
+  {
+    U *v = static_cast <U *> (lua_touserdata (L, lua_upvalueindex (1)));
+    assert (v);
+    Stack <U>::push (L, *v);
+    return 1;
+  }
+
   //--------------------------------------------------------------------------
   /**
       lua_CFunction to set a class data member.
@@ -439,4 +617,393 @@ struct CFunc
     c->**mp = Stack <T>::get (L, 2);
     return 0;
   }
+
+  //--------------------------------------------------------------------------
+
+  // metatable callback for "array[index]"
+  template <typename T>
+  static int array_index (lua_State* L) {
+    T** parray = (T**) luaL_checkudata (L, 1, typeid(T).name());
+    int const index = luabridge::Stack<int>::get (L, 2);
+    luabridge::Stack<T>::push (L, (*parray)[index-1]);
+    return 1;
+  }
+
+  // metatable callback for "array[index] = value"
+  template <typename T>
+  static int array_newindex (lua_State* L) {
+    T** parray = (T**) luaL_checkudata (L, 1, typeid(T).name());
+    int const index = luabridge::Stack<int>::get (L, 2);
+    T const value = luabridge::Stack<T>::get (L, 3);
+    (*parray)[index-1] = value;
+    return 0;
+  }
+
+  template <typename T>
+  static int getArray (lua_State* L) {
+    T *v = luabridge::Stack<T*>::get (L, 1);
+    T** parray = (T**) lua_newuserdata(L, sizeof(T**));
+    *parray = v;
+    luaL_getmetatable(L, typeid(T).name());
+    lua_setmetatable(L, -2);
+    return 1;
+  }
+
+  // copy complete c array to lua table
+  template <typename T>
+  static int getTable (lua_State* L) {
+    T *v = luabridge::Stack<T*>::get (L, 1);
+    const int cnt = luabridge::Stack<int>::get (L, 2);
+    LuaRef t (L);
+    t = newTable (L);
+    for (int i = 0; i < cnt; ++i) {
+      t[i + 1] = v[i];
+    }
+    t.push(L);
+    return 1;
+  }
+
+  // copy lua table to c array
+  template <typename T>
+  static int setTable (lua_State* L) {
+    T *v = luabridge::Stack<T*>::get (L, 1);
+    LuaRef t (LuaRef::fromStack(L, 2));
+    const int cnt = luabridge::Stack<int>::get (L, 3);
+    for (int i = 0; i < cnt; ++i) {
+      v[i] = t[i + 1];
+    }
+    return 0;
+  }
+
+
+  //--------------------------------------------------------------------------
+  /**
+    C++ STL iterators
+   */
+
+  // read lua table into C++ std::list
+  template <class T, class C>
+  static int tableToListHelper (lua_State *L, C * const t)
+  {
+    if (!t) { return luaL_error (L, "invalid pointer to std::list<>/std::vector"); }
+    if (!lua_istable (L, -1)) { return luaL_error (L, "argument is not a table"); }
+    lua_pushvalue (L, -1);
+    lua_pushnil (L);
+    while (lua_next (L, -2)) {
+      lua_pushvalue (L, -2);
+      T const value = Stack<T>::get (L, -2);
+      t->push_back (value);
+      lua_pop (L, 2);
+    }
+    lua_pop (L, 1);
+    lua_pop (L, 2);
+    Stack<C>::push (L, *t);
+    return 1;
+  }
+
+  template <class T, class C>
+  static int tableToList (lua_State *L)
+  {
+    C * const t = Userdata::get<C> (L, 1, false);
+    return tableToListHelper<T, C> (L, t);
+  }
+
+  template <class T, class C>
+  static int ptrTableToList (lua_State *L)
+  {
+    boost::shared_ptr<C> const* const t = Userdata::get<boost::shared_ptr<C> > (L, 1, true);
+    if (!t) { return luaL_error (L, "cannot derefencee shared_ptr"); }
+    return tableToListHelper<T, C> (L, t->get());
+  }
+
+  //--------------------------------------------------------------------------
+  template <class T, class C>
+  static int listIterIter (lua_State *L) {
+    typedef typename C::const_iterator IterType;
+    IterType * const end = static_cast <IterType * const> (lua_touserdata (L, lua_upvalueindex (2)));
+    IterType * const iter = static_cast <IterType * const> (lua_touserdata (L, lua_upvalueindex (1)));
+    assert (end);
+    assert (iter);
+    if ((*iter) == (*end)) {
+      return 0;
+    }
+    Stack <T>::push (L, **iter);
+    ++(*iter);
+    return 1;
+  }
+
+  // generate an iterator
+  template <class T, class C>
+  static int listIterHelper (lua_State *L, C * const t)
+  {
+    if (!t) { return luaL_error (L, "invalid pointer to std::list<>/std::vector"); }
+    typedef typename C::const_iterator IterType;
+    new (lua_newuserdata (L, sizeof (IterType*))) IterType (t->begin());
+    new (lua_newuserdata (L, sizeof (IterType*))) IterType (t->end());
+    lua_pushcclosure (L, listIterIter<T, C>, 2);
+    return 1;
+  }
+
+  template <class T, class C>
+  static int listIter (lua_State *L)
+  {
+    C * const t = Userdata::get <C> (L, 1, false);
+    return listIterHelper<T, C> (L, t);
+  }
+
+  template <class T, class C>
+  static int ptrListIter (lua_State *L)
+  {
+    boost::shared_ptr<C> const* const t = Userdata::get <boost::shared_ptr<C> >(L, 1, true);
+    if (!t) { return luaL_error (L, "cannot derefencee shared_ptr"); }
+    return listIterHelper<T, C> (L, t->get());
+  }
+
+  //--------------------------------------------------------------------------
+  // generate table from std::list
+  template <class T, class C>
+  static int listToTableHelper (lua_State *L, C const* const t)
+  {
+    if (!t) { return luaL_error (L, "invalid pointer to std::list<>/std::vector"); }
+#if 0 // direct lua api
+    lua_createtable(L, t->size(), 0);
+    int newTable = lua_gettop(L);
+    int index = 1;
+    for (typename C::const_iterator iter = t->begin(); iter != t->end(); ++iter, ++index) {
+      Stack<T>::push(L, (*iter));
+      lua_rawseti (L, newTable, index);
+    }
+#else // luabridge way
+    LuaRef v (L);
+    v = newTable (L);
+    int index = 1;
+    for (typename C::const_iterator iter = t->begin(); iter != t->end(); ++iter, ++index) {
+      v[index] = (*iter);
+    }
+    v.push(L);
+#endif
+    return 1;
+  }
+
+  template <class T, class C>
+  static int listToTable (lua_State *L)
+  {
+    C const* const t = Userdata::get <C> (L, 1, true);
+    return listToTableHelper<T, C> (L, t);
+  }
+
+  template <class T, class C>
+  static int ptrListToTable (lua_State *L)
+  {
+    boost::shared_ptr<C> const* const t = Userdata::get <boost::shared_ptr<C> > (L, 1, true);
+    if (!t) { return luaL_error (L, "cannot derefencee shared_ptr"); }
+    return listToTableHelper<T, C> (L, t->get());
+  }
+
+  //--------------------------------------------------------------------------
+  // generate std::map from table
+
+  template <class K, class V>
+  static int tableToMap (lua_State *L)
+  {
+    typedef std::map<K, V> C;
+    C * const t = Userdata::get <C> (L, 1, true);
+    if (!t) { return luaL_error (L, "invalid pointer to std::map"); }
+    if (!lua_istable (L, -1)) { return luaL_error (L, "argument is not a table"); }
+
+    lua_pushvalue (L, -1);
+    lua_pushnil (L);
+    while (lua_next (L, -2)) {
+      lua_pushvalue (L, -2);
+      K const key = Stack<K>::get (L, -1);
+      V const value = Stack<V>::get (L, -2);
+      t->insert (std::pair<K,V> (key, value));
+      //(*t)[key] = value;
+      lua_pop (L, 2);
+    }
+    lua_pop (L, 1);
+    lua_pop (L, 2);
+    Stack<C>::push (L, *t);
+    return 1;
+  }
+
+  // iterate over a std::map
+  template <class K, class V>
+  static int mapIterIter (lua_State *L)
+  {
+    typedef std::map<K, V> C;
+    typedef typename C::const_iterator IterType;
+    IterType * const end = static_cast <IterType * const> (lua_touserdata (L, lua_upvalueindex (2)));
+    IterType * const iter = static_cast <IterType * const> (lua_touserdata (L, lua_upvalueindex (1)));
+    assert (end);
+    assert (iter);
+    if ((*iter) == (*end)) {
+      return 0;
+    }
+    Stack <K>::push (L, (*iter)->first);
+    Stack <V>::push (L, (*iter)->second);
+    ++(*iter);
+    return 2;
+  }
+
+  // generate iterator
+  template <class K, class V>
+  static int mapIter (lua_State *L)
+  {
+    typedef std::map<K, V> C;
+    C * const t = Userdata::get <C> (L, 1, false);
+    if (!t) { return luaL_error (L, "invalid pointer to std::map"); }
+    typedef typename C::const_iterator IterType;
+    new (lua_newuserdata (L, sizeof (IterType*))) IterType (t->begin());
+    new (lua_newuserdata (L, sizeof (IterType*))) IterType (t->end());
+    lua_pushcclosure (L, mapIterIter<K, V>, 2);
+    return 1;
+  }
+
+  // generate table from std::map
+  template <class K, class V>
+  static int mapToTable (lua_State *L)
+  {
+    typedef std::map<K, V> C;
+    C const* const t = Userdata::get <C> (L, 1, true);
+    if (!t) { return luaL_error (L, "invalid pointer to std::map"); }
+
+    LuaRef v (L);
+    v = newTable (L);
+    for (typename C::const_iterator iter = t->begin(); iter != t->end(); ++iter) {
+      v[(*iter).first] = (*iter).second;
+    }
+    v.push(L);
+    return 1;
+  }
+
+  //--------------------------------------------------------------------------
+  // generate std::set from table keys ( table[member] = true )
+  // http://www.lua.org/pil/11.5.html
+
+  template <class T>
+  static int tableToSet (lua_State *L)
+  {
+    typedef std::set<T> C;
+    C * const t = Userdata::get <C> (L, 1, true);
+    if (!t) { return luaL_error (L, "invalid pointer to std::set"); }
+    if (!lua_istable (L, -1)) { return luaL_error (L, "argument is not a table"); }
+
+    lua_pushvalue (L, -1);
+    lua_pushnil (L);
+    while (lua_next (L, -2)) {
+      lua_pushvalue (L, -2);
+      T const member = Stack<T>::get (L, -1);
+      bool const v = Stack<bool>::get (L, -2);
+      if (v) {
+        t->insert (member);
+      }
+      lua_pop (L, 2);
+    }
+    lua_pop (L, 1);
+    lua_pop (L, 2);
+    Stack<C>::push (L, *t);
+    return 1;
+  }
+
+  // iterate over a std::set, explicit "true" value.
+  // compare to http://www.lua.org/pil/11.5.html
+  template <class T>
+  static int setIterIter (lua_State *L)
+  {
+    typedef std::set<T> C;
+    typedef typename C::const_iterator IterType;
+    IterType * const end = static_cast <IterType * const> (lua_touserdata (L, lua_upvalueindex (2)));
+    IterType * const iter = static_cast <IterType * const> (lua_touserdata (L, lua_upvalueindex (1)));
+    assert (end);
+    assert (iter);
+    if ((*iter) == (*end)) {
+      return 0;
+    }
+    Stack <T>::push (L, **iter);
+    Stack <bool>::push (L, true);
+    ++(*iter);
+    return 2;
+  }
+
+  // generate iterator
+  template <class T>
+  static int setIter (lua_State *L)
+  {
+    typedef std::set<T> C;
+    C * const t = Userdata::get <C> (L, 1, false);
+    if (!t) { return luaL_error (L, "invalid pointer to std::set"); }
+    typedef typename C::const_iterator IterType;
+    new (lua_newuserdata (L, sizeof (IterType*))) IterType (t->begin());
+    new (lua_newuserdata (L, sizeof (IterType*))) IterType (t->end());
+    lua_pushcclosure (L, setIterIter<T>, 2);
+    return 1;
+  }
+
+  // generate table from std::set
+  template <class T>
+  static int setToTable (lua_State *L)
+  {
+    typedef std::set<T> C;
+    C const* const t = Userdata::get <C> (L, 1, true);
+    if (!t) { return luaL_error (L, "invalid pointer to std::set"); }
+
+    LuaRef v (L);
+    v = newTable (L);
+    for (typename C::const_iterator iter = t->begin(); iter != t->end(); ++iter) {
+      v[(*iter)] = true;
+    }
+    v.push(L);
+    return 1;
+  }
+
+  //--------------------------------------------------------------------------
+  // bitset { num = true }
+  // compare to http://www.lua.org/pil/11.5.html
+  template <unsigned int T>
+  static int tableToBitSet (lua_State *L)
+  {
+    typedef std::bitset<T> C;
+    C * const t = Userdata::get <C> (L, 1, true);
+    if (!t) { return luaL_error (L, "invalid pointer to std::bitset"); }
+    if (!lua_istable (L, -1)) { return luaL_error (L, "argument is not a table"); }
+
+    lua_pushvalue (L, -1);
+    lua_pushnil (L);
+    while (lua_next (L, -2)) {
+      lua_pushvalue (L, -2);
+      unsigned int const member = Stack<unsigned int>::get (L, -1);
+      bool const v = Stack<bool>::get (L, -2);
+      if (member < T && v) {
+        t->set (member);
+      }
+      lua_pop (L, 2);
+    }
+    lua_pop (L, 1);
+    lua_pop (L, 2);
+    Stack<C>::push (L, *t);
+    return 1;
+  }
+
+  // generate table from std::bitset
+  template <unsigned int T>
+  static int bitSetToTable (lua_State *L)
+  {
+    typedef std::bitset<T> C;
+    C const* const t = Userdata::get <C> (L, 1, true);
+    if (!t) { return luaL_error (L, "invalid pointer to std::bitset"); }
+
+    LuaRef v (L);
+    v = newTable (L);
+    for (unsigned int i = 0; i < T; ++i) {
+      if (t->test (i)) {
+        v[i] = true;
+      }
+    }
+    v.push(L);
+    return 1;
+  }
+
 };
+
+/* vim: set et sw=2: */
index d3e3fe6d68d63ea20a6f371480a2972c4f41c14b..8fae1c038ab48f00ad14edf837472055cdf1cd41 100644 (file)
@@ -237,6 +237,7 @@ private:
     }
 
     inline bool isNil () const { return type () == LUA_TNIL; }
+    inline bool isBoolean () const { return type () == LUA_TBOOLEAN; }
     inline bool isNumber () const { return type () == LUA_TNUMBER; }
     inline bool isString () const { return type () == LUA_TSTRING; }
     inline bool isTable () const { return type () == LUA_TTABLE; }
index f7f484b1187f4d039d2d84d2f3cafc6ff777c7d4..464d9d08a00faa0e8cb6c35f3ddc0752f9f83d57 100644 (file)
@@ -2,6 +2,7 @@
 /*
   https://github.com/vinniefalco/LuaBridge
 
+  Copyright 2016, Robin Gareus <robin@gareus.org>
   Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
   Copyright 2007, Nathan Reed
 
@@ -482,6 +483,8 @@ private:
       }
       else
       {
+        lua_pop (L, 1);
+        lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getStaticKey ());
         rawgetfield (L, -1, "__class");
         rawgetfield (L, -1, "__const");
 
@@ -674,6 +677,7 @@ private:
       return *this;
     }
 
+
     //--------------------------------------------------------------------------
     /**
       Add or replace a property member.
@@ -797,6 +801,21 @@ private:
       return *this;
     }
 
+    template <class MemFn>
+    Class <T>& addPtrFunction (char const* name, MemFn mf)
+    {
+      CFunc::CallMemberPtrFunctionHelper <MemFn>::add (L, name, mf);
+      return *this;
+    }
+
+    template <class MemFn>
+    Class <T>& addWPtrFunction (char const* name, MemFn mf)
+    {
+      CFunc::CallMemberWPtrFunctionHelper <MemFn>::add (L, name, mf);
+      return *this;
+    }
+
+
     //--------------------------------------------------------------------------
     /**
         Add or replace a member lua_CFunction.
@@ -812,6 +831,16 @@ private:
       return *this;
     }
 
+    // custom callback - extend existing classes
+    // with non-class member functions (e.g STL iterator)
+    Class <T>& addExtCFunction (char const* name, int (*const fp)(lua_State*))
+    {
+      assert (lua_istable (L, -1));
+      lua_pushcclosure (L, fp, 0);
+      rawsetfield (L, -3, name); // class table
+      return *this;
+    }
+
     //--------------------------------------------------------------------------
     /**
         Add or replace a const member lua_CFunction.
@@ -829,6 +858,28 @@ private:
       return *this;
     }
 
+    /**
+        Add or replace a static const data
+    */
+    template <typename U>
+      Class <T>& addConst (char const* name, const U val)
+      {
+        assert (lua_istable (L, -1));
+
+        rawgetfield (L, -1, "__propget"); // static
+        new (lua_newuserdata (L, sizeof (val))) U (val);
+        lua_pushcclosure (L, &CFunc::getConst <U>, 1);
+        rawsetfield (L, -2, name);
+        lua_pop (L, 1);
+
+        rawgetfield (L, -1, "__propset"); // static
+        lua_pushstring (L, name);
+        lua_pushcclosure (L, &CFunc::readOnlyError, 1);
+        rawsetfield (L, -2, name);
+        lua_pop (L, 1);
+        return *this;
+      }
+
     //--------------------------------------------------------------------------
     /**
       Add or replace a primary Constructor.
@@ -859,8 +910,216 @@ private:
 
       return *this;
     }
+
+    Class <T>& addVoidConstructor ()
+    {
+      return addConstructor <void (*) ()> ();
+    }
+
+  };
+
+  /** C Array to/from table */
+  template <typename T>
+  class Array : public ClassBase
+  {
+  public:
+    Array (char const* name, Namespace const* parent) : ClassBase (parent->L)
+    {
+      m_stackSize = parent->m_stackSize + 3;
+      parent->m_stackSize = 0;
+
+#if 0 // don't allow to duplicates handlers for same array-type
+      assert (lua_istable (L, -1));
+      lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ());
+      if (lua_istable (L, -1)) {
+        lua_pushnil (L);
+        lua_pushnil (L);
+        return;
+      }
+      lua_pop (L, 1);
+#endif
+
+      assert (lua_istable (L, -1));
+      rawgetfield (L, -1, name);
+
+      if (lua_isnil (L, -1))
+      {
+        lua_pop (L, 1);
+
+        // register array access in global namespace
+        luaL_newmetatable (L, typeid(T).name());
+        lua_pushcclosure (L, CFunc::array_index<T>, 0);
+        lua_setfield(L, -2, "__index");
+        lua_pushcclosure (L, CFunc::array_newindex<T>, 0);
+        lua_setfield(L, -2, "__newindex");
+        lua_pop (L, 1);
+
+        createConstTable (name);
+        lua_pushcfunction (L, &CFunc::gcMetaMethod <T>);
+        rawsetfield (L, -2, "__gc");
+
+        createClassTable (name);
+        lua_pushcfunction (L, &CFunc::gcMetaMethod <T>);
+        rawsetfield (L, -2, "__gc");
+
+        createStaticTable (name);
+
+        // Map T back to its tables.
+        lua_pushvalue (L, -1);
+        lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getStaticKey ());
+        lua_pushvalue (L, -2);
+        lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ());
+        lua_pushvalue (L, -3);
+        lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getConstKey ());
+
+        assert (lua_istable (L, -1));
+        lua_pushcclosure (L, &CFunc::getArray <T>, 0);
+        rawsetfield (L, -3, "array"); // class table
+
+        lua_pushcclosure (L, &CFunc::getTable <T>, 0);
+        rawsetfield (L, -3, "get_table"); // class table
+
+        lua_pushcclosure (L, &CFunc::setTable <T>, 0);
+        rawsetfield (L, -3, "set_table"); // class table
+      }
+      else
+      {
+        lua_pushnil (L);
+        lua_pushnil (L);
+      }
+    }
+
+    Namespace endArray ()
+    {
+      return Namespace (this);
+    }
+  };
+
+  /** Boost Weak & Shared Pointer Class Wrapper */
+  template <class T>
+  class WSPtrClass : public ClassBase
+  {
+  public:
+    WSPtrClass (char const* name, Namespace const* parent)
+      : ClassBase (parent->L)
+      , weak (name, parent)
+      , shared (name, parent)
+    {
+      m_stackSize = weak.m_stackSize;
+      parent->m_stackSize = weak.m_stackSize = shared.m_stackSize = 0;
+      lua_pop (L, 3);
+    }
+
+    WSPtrClass (char const* name, Namespace const* parent, void const* const sharedkey, void const* const weakkey)
+      : ClassBase (parent->L)
+      , weak (name, parent, weakkey)
+      , shared (name, parent, sharedkey)
+    {
+      m_stackSize = weak.m_stackSize;
+      parent->m_stackSize = weak.m_stackSize = shared.m_stackSize = 0;
+      lua_pop (L, 3);
+    }
+
+    template <class MemFn>
+    WSPtrClass <T>& addFunction (char const* name, MemFn mf)
+    {
+      set_weak_class ();
+      CFunc::CallMemberWPtrFunctionHelper <MemFn>::add (L, name, mf);
+
+      set_shared_class ();
+      CFunc::CallMemberPtrFunctionHelper <MemFn>::add (L, name, mf);
+      return *this;
+    }
+
+    template <class MemFn>
+    WSPtrClass <T>& addConstructor ()
+    {
+      set_weak_class ();
+      lua_pushcclosure (L,
+          &weak.ctorPlacementProxy <typename FuncTraits <MemFn>::Params, boost::weak_ptr<T> >, 0);
+      rawsetfield(L, -2, "__call");
+
+      set_shared_class ();
+      lua_pushcclosure (L,
+          &shared.ctorPlacementProxy <typename FuncTraits <MemFn>::Params, boost::shared_ptr<T> >, 0);
+      rawsetfield(L, -2, "__call");
+      return *this;
+    }
+
+    WSPtrClass <T>& addVoidConstructor ()
+    {
+      return addConstructor <void (*) ()> ();
+    }
+
+    WSPtrClass <T>& addExtCFunction (char const* name, int (*const fp)(lua_State*))
+    {
+      set_weak_class ();
+      assert (lua_istable (L, -1));
+      lua_pushcclosure (L, fp, 0);
+      rawsetfield (L, -3, name); // class table
+
+      set_shared_class ();
+      assert (lua_istable (L, -1));
+      lua_pushcclosure (L, fp, 0);
+      rawsetfield (L, -3, name); // class table
+
+      return *this;
+    }
+
+    template <class U>
+    WSPtrClass <T>& addCast (char const* name)
+    {
+      // TODO weak ptr
+      set_shared_class ();
+      assert (lua_istable (L, -1));
+      lua_pushcclosure (L, &CFunc::CastMemberPtr <T, U>::f, 0);
+      rawsetfield (L, -3, name); // class table
+      return *this;
+    }
+
+    WSPtrClass <T>& addNullCheck ()
+    {
+      set_weak_class ();
+      assert (lua_istable (L, -1));
+      lua_pushcclosure (L, &CFunc::WPtrNullCheck <T>::f, 0);
+      rawsetfield (L, -3, "isnil"); // class table
+
+      set_shared_class ();
+      assert (lua_istable (L, -1));
+      lua_pushcclosure (L, &CFunc::PtrNullCheck <T>::f, 0);
+      rawsetfield (L, -3, "isnil"); // class table
+
+      return *this;
+    }
+
+
+    Namespace endClass ()
+    {
+      return Namespace (this);
+    }
+
+  private:
+    void set_weak_class () {
+      lua_pop (L, 3);
+      lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <boost::weak_ptr<T> >::getStaticKey ());
+      rawgetfield (L, -1, "__class");
+      rawgetfield (L, -1, "__const");
+      lua_insert (L, -3);
+      lua_insert (L, -2);
+    }
+    void set_shared_class () {
+      lua_pop (L, 3);
+      lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <boost::shared_ptr<T> >::getStaticKey ());
+      rawgetfield (L, -1, "__class");
+      rawgetfield (L, -1, "__const");
+      lua_insert (L, -3);
+      lua_insert (L, -2);
+    }
+    Class<boost::weak_ptr<T> > weak;
+    Class<boost::shared_ptr<T> > shared;
   };
 
+
 private:
   //----------------------------------------------------------------------------
   /**
@@ -1032,6 +1291,25 @@ public:
     return *this;
   }
 
+  template <typename U>
+  Namespace& addConst (char const* name, const U val)
+  {
+    assert (lua_istable (L, -1));
+    rawgetfield (L, -1, "__propget");
+    new (lua_newuserdata (L, sizeof (val))) U (val);
+    lua_pushcclosure (L, &CFunc::getConst <U>, 1);
+    rawsetfield (L, -2, name);
+    lua_pop (L, 1);
+
+    rawgetfield (L, -1, "__propset");
+    assert (lua_istable (L, -1));
+    lua_pushstring (L, name);
+    lua_pushcclosure (L, &CFunc::readOnlyError, 1);
+    rawsetfield (L, -2, name);
+    lua_pop (L, 1);
+    return *this;
+  }
+
   //----------------------------------------------------------------------------
   /**
       Add or replace a property.
@@ -1086,6 +1364,19 @@ public:
     return *this;
   }
 
+
+  //----------------------------------------------------------------------------
+  /**
+      Add or replace a array type
+  */
+
+  template <typename T>
+  Namespace registerArray (char const* name)
+  {
+    return Array <T> (name, this).endArray();
+  }
+
+
   //----------------------------------------------------------------------------
   /**
       Add or replace a lua_CFunction.
@@ -1108,6 +1399,143 @@ public:
     return Class <T> (name, this);
   }
 
+  /** weak & shared pointer class */
+  template <class T>
+  WSPtrClass <T> beginWSPtrClass (char const* name)
+  {
+    return WSPtrClass <T> (name, this)
+      .addNullCheck();
+  }
+
+  //----------------------------------------------------------------------------
+
+  template <class K, class V>
+  Class<std::map<K, V> > beginStdMap (char const* name)
+  {
+    typedef std::map<K, V> LT;
+    typedef std::pair<const K, V> T;
+
+    return beginClass<LT> (name)
+      .addVoidConstructor ()
+      .addFunction ("empty", &LT::empty)
+      .addFunction ("size", &LT::size)
+      .addFunction ("clear", (void (LT::*)())&LT::clear)
+      .addFunction ("count", (void (LT::*)())&LT::count)
+      .addExtCFunction ("add", &CFunc::tableToMap<K, V>)
+      .addExtCFunction ("iter", &CFunc::mapIter<K, V>)
+      .addExtCFunction ("table", &CFunc::mapToTable<K, V>);
+  }
+
+  template <class T>
+  Class<std::set<T> > beginStdSet (char const* name)
+  {
+    typedef std::set<T> LT;
+    return beginClass<LT> (name)
+      .addVoidConstructor ()
+      .addFunction ("clear", (void (LT::*)())&LT::clear)
+      .addFunction ("empty", &LT::empty)
+      .addFunction ("size", &LT::size)
+      .addExtCFunction ("add", &CFunc::tableToSet<T>)
+      .addExtCFunction ("iter", &CFunc::setIter<T>)
+      .addExtCFunction ("table", &CFunc::setToTable<T>);
+  }
+
+  template <unsigned int T>
+  Class<std::bitset<T> > beginStdBitSet (char const* name)
+  {
+    typedef std::bitset<T> BS;
+    return beginClass<BS> (name)
+      .addVoidConstructor ()
+      .addFunction ("reset", (BS& (BS::*)())&BS::reset)
+      .addFunction ("set", (BS& (BS::*)(size_t, bool))&BS::set)
+      .addFunction ("count", &BS::count)
+      .addFunction ("any", &BS::any)
+      .addFunction ("none", &BS::none)
+      .addFunction ("test", &BS::test)
+      .addFunction ("size", &BS::size)
+      .addExtCFunction ("add", &CFunc::tableToBitSet<T>)
+      .addExtCFunction ("table", &CFunc::bitSetToTable<T>);
+  }
+
+  template <class T>
+  Class<std::list<T> > beginConstStdList (char const* name)
+  {
+    typedef std::list<T> LT;
+    return beginClass<LT> (name)
+      .addVoidConstructor ()
+      .addFunction ("empty", &LT::empty)
+      .addFunction ("size", &LT::size)
+      .addFunction ("reverse", &LT::reverse)
+      .addExtCFunction ("iter", &CFunc::listIter<T, LT>)
+      .addExtCFunction ("table", &CFunc::listToTable<T, LT>);
+  }
+
+  template <class T>
+  Class<std::list<T> > beginStdList (char const* name)
+  {
+    typedef std::list<T> LT;
+    return beginConstStdList<T> (name)
+      .addFunction ("unique", (void (LT::*)())&LT::unique)
+      .addFunction ("push_back", (void (LT::*)(const T&))&LT::push_back)
+      .addExtCFunction ("add", &CFunc::tableToList<T, LT>);
+  }
+
+  template <class T>
+  Class<std::vector<T> > beginStdVector (char const* name)
+  {
+    typedef std::vector<T> LT;
+    typedef typename std::vector<T>::reference T_REF;
+    typedef typename std::vector<T>::size_type T_SIZE;
+
+    return beginClass<LT> (name)
+      .addVoidConstructor ()
+      .addFunction ("empty", &LT::empty)
+      .addFunction ("size", &LT::size)
+      .addFunction ("push_back", (void (LT::*)(const T&))&LT::push_back)
+      .addFunction ("at", (T_REF (LT::*)(T_SIZE))&LT::at)
+      .addExtCFunction ("add", &CFunc::tableToList<T, LT>)
+      .addExtCFunction ("iter", &CFunc::listIter<T, LT>)
+      .addExtCFunction ("table", &CFunc::listToTable<T, LT>);
+  }
+
+  //----------------------------------------------------------------------------
+
+  template <class T>
+  Class<boost::shared_ptr<std::list<T> > > beginPtrStdList (char const* name)
+  {
+    typedef std::list<T> LT;
+
+    return beginClass<boost::shared_ptr<LT> > (name)
+      .addVoidConstructor ()
+      .addPtrFunction ("empty", &LT::empty)
+      .addPtrFunction ("size", &LT::size)
+      .addPtrFunction ("reverse", &LT::reverse)
+      .addPtrFunction ("unique", (void (LT::*)())&LT::unique)
+      .addPtrFunction ("push_back", (void (LT::*)(const T&))&LT::push_back)
+      .addExtCFunction ("add", &CFunc::ptrTableToList<T, LT>)
+      .addExtCFunction ("iter", &CFunc::ptrListIter<T, LT>)
+      .addExtCFunction ("table", &CFunc::ptrListToTable<T, LT>);
+  }
+
+  template <class T>
+  Class<boost::shared_ptr<std::vector<T> > > beginPtrStdVector (char const* name)
+  {
+    typedef std::vector<T> LT;
+    typedef typename std::vector<T>::reference T_REF;
+    typedef typename std::vector<T>::size_type T_SIZE;
+
+    return beginClass<boost::shared_ptr<LT> > (name)
+      .addVoidConstructor ()
+      .addPtrFunction ("empty", &LT::empty)
+      .addPtrFunction ("empty", &LT::empty)
+      .addPtrFunction ("size", &LT::size)
+      .addPtrFunction ("push_back", (void (LT::*)(const T&))&LT::push_back)
+      .addPtrFunction ("at", (T_REF (LT::*)(T_SIZE))&LT::at)
+      .addExtCFunction ("add", &CFunc::ptrTableToList<T, LT>)
+      .addExtCFunction ("iter", &CFunc::ptrListIter<T, LT>)
+      .addExtCFunction ("table", &CFunc::ptrListToTable<T, LT>);
+  }
+
   //----------------------------------------------------------------------------
   /**
       Derive a new class for registrations.
@@ -1120,6 +1548,16 @@ public:
   {
     return Class <T> (name, this, ClassInfo <U>::getStaticKey ());
   }
+
+  template <class T, class U>
+  WSPtrClass <T> deriveWSPtrClass (char const* name)
+  {
+    return WSPtrClass <T> (name, this,
+        ClassInfo <boost::shared_ptr<U> >::getStaticKey (),
+        ClassInfo <boost::weak_ptr<U> >::getStaticKey ())
+      .addNullCheck();
+  }
+
 };
 
 //------------------------------------------------------------------------------
@@ -1134,3 +1572,5 @@ inline Namespace getGlobalNamespace (lua_State* L)
 {
   return Namespace::getGlobalNamespace (L);
 }
+
+/* vim: set et sw=2: */
index 2914e7432ebac95a53687a0da0dff882a2071c68..a569093ad13acd591261d79e7dc808637211bcb1 100644 (file)
@@ -2,6 +2,7 @@
 /*
   https://github.com/vinniefalco/LuaBridge
 
+  Copyright 2016, Robin Gareus <robin@gareus.org>
   Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
   Copyright 2007, Nathan Reed
 
@@ -281,6 +282,70 @@ struct Stack <unsigned long const&>
   }
 };
 
+//------------------------------------------------------------------------------
+/**
+    Stack specialization for `long long`.
+*/
+template <>
+struct Stack <long long>
+{
+  static inline void push (lua_State* L, long long value)
+  {
+    lua_pushinteger (L, static_cast <lua_Integer> (value));
+  }
+
+  static inline long long get (lua_State* L, int index)
+  {
+    return static_cast <long long> (luaL_checkinteger (L, index));
+  }
+};
+
+template <>
+struct Stack <long long const&>
+{
+  static inline void push (lua_State* L, long long value)
+  {
+    lua_pushnumber (L, static_cast <lua_Number> (value));
+  }
+
+  static inline long long get (lua_State* L, int index)
+  {
+    return static_cast <long long> (luaL_checknumber (L, index));
+  }
+};
+
+//------------------------------------------------------------------------------
+/**
+    Stack specialization for `unsigned long long`.
+*/
+template <>
+struct Stack <unsigned long long>
+{
+  static inline void push (lua_State* L, unsigned long long value)
+  {
+    lua_pushinteger (L, static_cast <lua_Integer> (value));
+  }
+
+  static inline unsigned long long get (lua_State* L, int index)
+  {
+    return static_cast <unsigned long long> (luaL_checkinteger (L, index));
+  }
+};
+
+template <>
+struct Stack <unsigned long long const&>
+{
+  static inline void push (lua_State* L, unsigned long long value)
+  {
+    lua_pushnumber (L, static_cast <lua_Number> (value));
+  }
+
+  static inline unsigned long long get (lua_State* L, int index)
+  {
+    return static_cast <unsigned long long> (luaL_checknumber (L, index));
+  }
+};
+
 //------------------------------------------------------------------------------
 /**
     Stack specialization for `float`.
index a6b93233932cdb4b99874fc46d57ff5ef28d72bc..ffb437f658d388019e30e7b7293803f2047170a4 100644 (file)
@@ -89,6 +89,16 @@ struct TypeTraits
     static const bool value = sizeof (test <ContainerTraits <T> >(0)) == sizeof (yes);
   };
 
+  /** Determine if T is an enum */
+  template <typename T>
+  class isEnum
+  {
+  public:
+    //static const bool value = std::is_enum<T>::value; // C++11
+    static const bool value = boost::is_enum<T>::value;
+  };
+
+
   /** Determine if T is const qualified.
   */
   /** @{ */
index d87c1b0306bcaf44bcbbc9b663c5446759ba2281..c7ee3bac3ebd46a0621295eec4fb78ec6d9aa85c 100644 (file)
@@ -1,7 +1,8 @@
 //------------------------------------------------------------------------------
 /*
   https://github.com/vinniefalco/LuaBridge
-  
+
+  Copyright 2016, Robin Gareus <robin@gareus.org>
   Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
 
   License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
@@ -68,7 +69,7 @@ protected:
   /**
     Get an untyped pointer to the contained class.
   */
-  inline void* const getPointer ()
+  inline void* getPointer () const
   {
     return m_p;
   }
@@ -610,7 +611,7 @@ struct UserdataSharedHelper <C, true>
   either be of the intrusive variety, or in the style of the RefCountedPtr
   type provided by LuaBridge (that uses a global hash table).
 */
-template <class C, bool byContainer>
+template <class C, bool byContainer, bool isEnum>
 struct StackHelper
 {
   static inline void push (lua_State* L, C const& c)
@@ -636,7 +637,7 @@ struct StackHelper
   retrieved may result in undefined behavior if Lua garbage collected it.
 */
 template <class T>
-struct StackHelper <T, false>
+struct StackHelper <T, false, false>
 {
   static inline void push (lua_State* L, T const& t)
   {
@@ -649,6 +650,22 @@ struct StackHelper <T, false>
   }
 };
 
+template <class T>
+struct StackHelper <T, false, true>
+{
+  static inline void push (lua_State* L, T const& t)
+  {
+    int v = static_cast <int> (t);
+    lua_pushinteger (L, static_cast <lua_Integer> (v));
+  }
+
+  static inline T get (lua_State* L, int index)
+  {
+    int v = static_cast <int> (luaL_checkinteger (L, index));
+    return T (v);
+  }
+};
+
 //==============================================================================
 
 /**
@@ -661,13 +678,15 @@ public:
   static inline void push (lua_State* L, T const& t)
   {
     StackHelper <T,
-      TypeTraits::isContainer <T>::value>::push (L, t);
+      TypeTraits::isContainer <T>::value,
+      TypeTraits::isEnum<T>::value>::push (L, t);
   }
 
   static inline T get (lua_State* L, int index)
   {
     return StackHelper <T,
-      TypeTraits::isContainer <T>::value>::get (L, index);
+      TypeTraits::isContainer <T>::value,
+      TypeTraits::isEnum<T>::value>::get (L, index);
   }
 };
 
@@ -689,7 +708,7 @@ struct Stack <T*>
     UserdataPtr::push (L, p);
   }
 
-  static inline T* const get (lua_State* L, int index)
+  static inline T* get (lua_State* L, int index)
   {
     return Userdata::get <T> (L, index, false);
   }
@@ -704,7 +723,7 @@ struct Stack <T* const>
     UserdataPtr::push (L, p);
   }
 
-  static inline T* const get (lua_State* L, int index)
+  static inline T* get (lua_State* L, int index)
   {
     return Userdata::get <T> (L, index, false);
   }
@@ -719,7 +738,7 @@ struct Stack <T const*>
     UserdataPtr::push (L, p);
   }
 
-  static inline T const* const get (lua_State* L, int index)
+  static inline T const* get (lua_State* L, int index)
   {
     return Userdata::get <T> (L, index, true);
   }
@@ -734,7 +753,7 @@ struct Stack <T const* const>
     UserdataPtr::push (L, p);
   }
 
-  static inline T const* const get (lua_State* L, int index)
+  static inline T const* get (lua_State* L, int index)
   {
     return Userdata::get <T> (L, index, true);
   }
@@ -761,8 +780,8 @@ struct Stack <T&>
 template <class C, bool byContainer>
 struct RefStackHelper
 {
-  typedef C return_type;  
-       
+  typedef C return_type;
+
   static inline void push (lua_State* L, C const& t)
   {
     UserdataSharedHelper <C,
@@ -781,12 +800,12 @@ struct RefStackHelper
 template <class T>
 struct RefStackHelper <T, false>
 {
-  typedef T const& return_type;  
-       
-       static inline void push (lua_State* L, T const& t)
-       {
-         UserdataPtr::push (L, &t);
-       }
+  typedef T const& return_type;
+
+  static inline void push (lua_State* L, T const& t)
+  {
+    UserdataPtr::push (L, &t);
+  }
 
   static return_type get (lua_State* L, int index)
   {
index 82f6a45ac1da56a066a467d01b316dc34c947b2f..b9b79ce19d82ad4dff4b0743ef352b256b9e7420 100644 (file)
@@ -1,7 +1,7 @@
 #include <sstream>
 #include <string>
 
-std::string dumpLuaState(lua_State *L) {
+static std::string dumpLuaState(lua_State *L) {
        std::stringstream ostr;
        int i;
        int top = lua_gettop(L);
@@ -20,7 +20,7 @@ std::string dumpLuaState(lua_State *L) {
                        ostr << "  " << i << ": " << lua_tonumber(L, i) << "\n";
                        break;
                default:
-                       ostr << "  " << i << ": TYPE=" << lua_typename(L, t) << "\n";
+                       ostr << "  " << i << ": TYPE=" << lua_typename(L, t) << ": " << lua_topointer(L, i)<< "\n";
                        break;
                }
        }