summaryrefslogtreecommitdiff
path: root/libs/lua
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2016-01-11 11:50:50 +0100
committerRobin Gareus <robin@gareus.org>2016-02-22 22:06:47 +0100
commite98f21dd297819fcb4931bd5a87474736c7a450e (patch)
tree018a17a9f67c206cea1394c3f4012c58a1a2f6d4 /libs/lua
parentc8973f67a65d911d1b08e1121d1c7da57c58b182 (diff)
add LuaBridge
https://github.com/vinniefalco/LuaBridge
Diffstat (limited to 'libs/lua')
-rw-r--r--libs/lua/LuaBridge/LuaBridge.h142
-rw-r--r--libs/lua/LuaBridge/README28
-rw-r--r--libs/lua/LuaBridge/detail/CFunctions.h442
-rw-r--r--libs/lua/LuaBridge/detail/ClassInfo.h73
-rw-r--r--libs/lua/LuaBridge/detail/Constructor.h204
-rw-r--r--libs/lua/LuaBridge/detail/FuncTraits.h852
-rw-r--r--libs/lua/LuaBridge/detail/Iterator.h114
-rw-r--r--libs/lua/LuaBridge/detail/LuaException.h113
-rw-r--r--libs/lua/LuaBridge/detail/LuaHelpers.h143
-rw-r--r--libs/lua/LuaBridge/detail/LuaRef.h1215
-rw-r--r--libs/lua/LuaBridge/detail/Namespace.h1136
-rw-r--r--libs/lua/LuaBridge/detail/Stack.h469
-rw-r--r--libs/lua/LuaBridge/detail/TypeList.h174
-rw-r--r--libs/lua/LuaBridge/detail/TypeTraits.h125
-rw-r--r--libs/lua/LuaBridge/detail/Userdata.h817
-rw-r--r--libs/lua/LuaBridge/detail/dump.h28
16 files changed, 6075 insertions, 0 deletions
diff --git a/libs/lua/LuaBridge/LuaBridge.h b/libs/lua/LuaBridge/LuaBridge.h
new file mode 100644
index 0000000000..1928e9a1f0
--- /dev/null
+++ b/libs/lua/LuaBridge/LuaBridge.h
@@ -0,0 +1,142 @@
+//------------------------------------------------------------------------------
+/*
+ https://github.com/vinniefalco/LuaBridge
+
+ Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
+ Copyright 2007, Nathan Reed
+
+ License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+*/
+//==============================================================================
+
+#ifndef LUABRIDGE_LUABRIDGE_HEADER
+#define LUABRIDGE_LUABRIDGE_HEADER
+
+// All #include dependencies are listed here
+// instead of in the individual header files.
+//
+#include <cassert>
+#include <sstream>
+#include <stdexcept>
+#include <string>
+#include <typeinfo>
+
+#define LUABRIDGE_MAJOR_VERSION 2
+#define LUABRIDGE_MINOR_VERSION 0
+#define LUABRIDGE_VERSION 200
+
+namespace luabridge
+{
+
+// Forward declaration
+//
+template <class T>
+struct Stack;
+
+#include "detail/LuaHelpers.h"
+
+#include "detail/TypeTraits.h"
+#include "detail/TypeList.h"
+#include "detail/FuncTraits.h"
+#include "detail/Constructor.h"
+#include "detail/Stack.h"
+#include "detail/ClassInfo.h"
+
+class LuaRef;
+
+#include "detail/LuaException.h"
+#include "detail/LuaRef.h"
+#include "detail/Iterator.h"
+
+//------------------------------------------------------------------------------
+/**
+ security options.
+*/
+class Security
+{
+public:
+ static bool hideMetatables ()
+ {
+ return getSettings().hideMetatables;
+ }
+
+ static void setHideMetatables (bool shouldHide)
+ {
+ getSettings().hideMetatables = shouldHide;
+ }
+
+private:
+ struct Settings
+ {
+ Settings () : hideMetatables (true)
+ {
+ }
+
+ bool hideMetatables;
+ };
+
+ static Settings& getSettings ()
+ {
+ static Settings settings;
+ return settings;
+ }
+};
+
+#include "detail/Userdata.h"
+#include "detail/CFunctions.h"
+#include "detail/Namespace.h"
+
+//------------------------------------------------------------------------------
+/**
+ Push an object onto the Lua stack.
+*/
+template <class T>
+inline void push (lua_State* L, T t)
+{
+ Stack <T>::push (L, t);
+}
+
+//------------------------------------------------------------------------------
+/**
+ Set a global value in the lua_State.
+
+ @note This works on any type specialized by `Stack`, including `LuaRef` and
+ its table proxies.
+*/
+template <class T>
+inline void setGlobal (lua_State* L, T t, char const* name)
+{
+ push (L, t);
+ lua_setglobal (L, name);
+}
+
+//------------------------------------------------------------------------------
+/**
+ Change whether or not metatables are hidden (on by default).
+*/
+inline void setHideMetatables (bool shouldHide)
+{
+ Security::setHideMetatables (shouldHide);
+}
+
+}
+
+#endif
diff --git a/libs/lua/LuaBridge/README b/libs/lua/LuaBridge/README
new file mode 100644
index 0000000000..82cbd534c4
--- /dev/null
+++ b/libs/lua/LuaBridge/README
@@ -0,0 +1,28 @@
+https://github.com/vinniefalco/LuaBridge -- 1.0.2-111-g04b47d7
+
+LuaBridge is published under the terms of the MIT License.
+
+ Copyright 2012, Vinnie Falco (<vinnie.falco@gmail.com>)
+ Copyright 2008, Nigel Atkinson
+ Copyright 2007, Nathan Reed
+
+ Portions from The Loki Library:
+ Copyright (C) 2001 by Andrei Alexandrescu
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/libs/lua/LuaBridge/detail/CFunctions.h b/libs/lua/LuaBridge/detail/CFunctions.h
new file mode 100644
index 0000000000..0497b6bb4b
--- /dev/null
+++ b/libs/lua/LuaBridge/detail/CFunctions.h
@@ -0,0 +1,442 @@
+//------------------------------------------------------------------------------
+/*
+ https://github.com/vinniefalco/LuaBridge
+
+ Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
+
+ License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+*/
+//==============================================================================
+
+// We use a structure so we can define everything in the header.
+//
+struct CFunc
+{
+ //----------------------------------------------------------------------------
+ /**
+ __index metamethod for a namespace or class static members.
+
+ This handles:
+ Retrieving functions and class static methods, stored in the metatable.
+ Reading global and class static data, stored in the __propget table.
+ Reading global and class properties, stored in the __propget table.
+ */
+ static int indexMetaMethod (lua_State* L)
+ {
+ int result = 0;
+ lua_getmetatable (L, 1); // push metatable of arg1
+ for (;;)
+ {
+ lua_pushvalue (L, 2); // push key arg2
+ lua_rawget (L, -2); // lookup key in metatable
+ if (lua_isnil (L, -1)) // not found
+ {
+ lua_pop (L, 1); // discard nil
+ rawgetfield (L, -1, "__propget"); // lookup __propget in metatable
+ lua_pushvalue (L, 2); // push key arg2
+ lua_rawget (L, -2); // lookup key in __propget
+ lua_remove (L, -2); // discard __propget
+ if (lua_iscfunction (L, -1))
+ {
+ lua_remove (L, -2); // discard metatable
+ lua_pushvalue (L, 1); // push arg1
+ lua_call (L, 1, 1); // call cfunction
+ result = 1;
+ break;
+ }
+ else
+ {
+ assert (lua_isnil (L, -1));
+ lua_pop (L, 1); // discard nil and fall through
+ }
+ }
+ else
+ {
+ assert (lua_istable (L, -1) || lua_iscfunction (L, -1));
+ lua_remove (L, -2);
+ result = 1;
+ break;
+ }
+
+ rawgetfield (L, -1, "__parent");
+ if (lua_istable (L, -1))
+ {
+ // Remove metatable and repeat the search in __parent.
+ lua_remove (L, -2);
+ }
+ else
+ {
+ // Discard metatable and return nil.
+ assert (lua_isnil (L, -1));
+ lua_remove (L, -2);
+ result = 1;
+ break;
+ }
+ }
+
+ return result;
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ __newindex metamethod for a namespace or class static members.
+
+ The __propset table stores proxy functions for assignment to:
+ Global and class static data.
+ Global and class properties.
+ */
+ static int newindexMetaMethod (lua_State* L)
+ {
+ int result = 0;
+ lua_getmetatable (L, 1); // push metatable of arg1
+ for (;;)
+ {
+ rawgetfield (L, -1, "__propset"); // lookup __propset in metatable
+ assert (lua_istable (L, -1));
+ lua_pushvalue (L, 2); // push key arg2
+ lua_rawget (L, -2); // lookup key in __propset
+ lua_remove (L, -2); // discard __propset
+ if (lua_iscfunction (L, -1)) // ensure value is a cfunction
+ {
+ lua_remove (L, -2); // discard metatable
+ lua_pushvalue (L, 3); // push new value arg3
+ lua_call (L, 1, 0); // call cfunction
+ result = 0;
+ break;
+ }
+ else
+ {
+ assert (lua_isnil (L, -1));
+ lua_pop (L, 1);
+ }
+
+ rawgetfield (L, -1, "__parent");
+ if (lua_istable (L, -1))
+ {
+ // Remove metatable and repeat the search in __parent.
+ lua_remove (L, -2);
+ }
+ else
+ {
+ assert (lua_isnil (L, -1));
+ lua_pop (L, 2);
+ result = luaL_error (L,"no writable variable '%s'", lua_tostring (L, 2));
+ }
+ }
+
+ return result;
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ lua_CFunction to report an error writing to a read-only value.
+
+ The name of the variable is in the first upvalue.
+ */
+ static int readOnlyError (lua_State* L)
+ {
+ std::string s;
+
+ s = s + "'" + lua_tostring (L, lua_upvalueindex (1)) + "' is read-only";
+
+ return luaL_error (L, s.c_str ());
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ lua_CFunction to get a variable.
+
+ This is used for global variables or class static data members.
+
+ The pointer to the data is in the first upvalue.
+ */
+ template <class T>
+ static int getVariable (lua_State* L)
+ {
+ assert (lua_islightuserdata (L, lua_upvalueindex (1)));
+ T const* ptr = static_cast <T const*> (lua_touserdata (L, lua_upvalueindex (1)));
+ assert (ptr != 0);
+ Stack <T>::push (L, *ptr);
+ return 1;
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ lua_CFunction to set a variable.
+
+ This is used for global variables or class static data members.
+
+ The pointer to the data is in the first upvalue.
+ */
+ template <class T>
+ static int setVariable (lua_State* L)
+ {
+ assert (lua_islightuserdata (L, lua_upvalueindex (1)));
+ T* ptr = static_cast <T*> (lua_touserdata (L, lua_upvalueindex (1)));
+ assert (ptr != 0);
+ *ptr = Stack <T>::get (L, 1);
+ return 0;
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ lua_CFunction to call a function with a return value.
+
+ This is used for global functions, global properties, class static methods,
+ and class static properties.
+
+ The function pointer is in the first upvalue.
+ */
+ template <class FnPtr,
+ class ReturnType = typename FuncTraits <FnPtr>::ReturnType>
+ struct Call
+ {
+ typedef typename FuncTraits <FnPtr>::Params Params;
+ static int f (lua_State* L)
+ {
+ assert (isfulluserdata (L, lua_upvalueindex (1)));
+ FnPtr const& fnptr = *static_cast <FnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
+ assert (fnptr != 0);
+ ArgList <Params> args (L);
+ Stack <typename FuncTraits <FnPtr>::ReturnType>::push (L, FuncTraits <FnPtr>::call (fnptr, args));
+ return 1;
+ }
+ };
+
+ //----------------------------------------------------------------------------
+ /**
+ lua_CFunction to call a function with no return value.
+
+ This is used for global functions, global properties, class static methods,
+ and class static properties.
+
+ The function pointer is in the first upvalue.
+ */
+ template <class FnPtr>
+ struct Call <FnPtr, void>
+ {
+ typedef typename FuncTraits <FnPtr>::Params Params;
+ static int f (lua_State* L)
+ {
+ assert (isfulluserdata (L, lua_upvalueindex (1)));
+ FnPtr const& fnptr = *static_cast <FnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
+ assert (fnptr != 0);
+ ArgList <Params> args (L);
+ FuncTraits <FnPtr>::call (fnptr, args);
+ return 0;
+ }
+ };
+
+ //----------------------------------------------------------------------------
+ /**
+ lua_CFunction to call a class member function with a return value.
+
+ The member function pointer is in the first upvalue.
+ The class userdata object is at the top of the Lua stack.
+ */
+ template <class MemFnPtr,
+ class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
+ struct CallMember
+ {
+ typedef typename FuncTraits <MemFnPtr>::ClassType T;
+ typedef typename FuncTraits <MemFnPtr>::Params Params;
+
+ static int f (lua_State* L)
+ {
+ assert (isfulluserdata (L, lua_upvalueindex (1)));
+ T* const t = Userdata::get <T> (L, 1, false);
+ 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 (t, fnptr, args));
+ return 1;
+ }
+ };
+
+ template <class MemFnPtr,
+ class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
+ struct CallConstMember
+ {
+ typedef typename FuncTraits <MemFnPtr>::ClassType T;
+ typedef typename FuncTraits <MemFnPtr>::Params Params;
+
+ static int f (lua_State* L)
+ {
+ assert (isfulluserdata (L, lua_upvalueindex (1)));
+ T const* const t = Userdata::get <T> (L, 1, true);
+ 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 (t, fnptr, args));
+ return 1;
+ }
+ };
+
+ //----------------------------------------------------------------------------
+ /**
+ lua_CFunction to call a class member function with no return value.
+
+ The member function pointer is in the first upvalue.
+ The class userdata object is at the top of the Lua stack.
+ */
+ template <class MemFnPtr>
+ struct CallMember <MemFnPtr, void>
+ {
+ typedef typename FuncTraits <MemFnPtr>::ClassType T;
+ typedef typename FuncTraits <MemFnPtr>::Params Params;
+
+ static int f (lua_State* L)
+ {
+ assert (isfulluserdata (L, lua_upvalueindex (1)));
+ T* const t = Userdata::get <T> (L, 1, false);
+ MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
+ assert (fnptr != 0);
+ ArgList <Params, 2> args (L);
+ FuncTraits <MemFnPtr>::call (t, fnptr, args);
+ return 0;
+ }
+ };
+
+ template <class MemFnPtr>
+ struct CallConstMember <MemFnPtr, void>
+ {
+ typedef typename FuncTraits <MemFnPtr>::ClassType T;
+ typedef typename FuncTraits <MemFnPtr>::Params Params;
+
+ static int f (lua_State* L)
+ {
+ assert (isfulluserdata (L, lua_upvalueindex (1)));
+ T const* const t = Userdata::get <T> (L, 1, true);
+ MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
+ assert (fnptr != 0);
+ ArgList <Params, 2> args (L);
+ FuncTraits <MemFnPtr>::call (t, fnptr, args);
+ return 0;
+ }
+ };
+
+ //--------------------------------------------------------------------------
+ /**
+ lua_CFunction to call a class member lua_CFunction.
+
+ The member function pointer is in the first upvalue.
+ The class userdata object is at the top of the Lua stack.
+ */
+ template <class T>
+ struct CallMemberCFunction
+ {
+ static int f (lua_State* L)
+ {
+ assert (isfulluserdata (L, lua_upvalueindex (1)));
+ typedef int (T::*MFP)(lua_State* L);
+ T* const t = Userdata::get <T> (L, 1, false);
+ MFP const& fnptr = *static_cast <MFP const*> (lua_touserdata (L, lua_upvalueindex (1)));
+ assert (fnptr != 0);
+ return (t->*fnptr) (L);
+ }
+ };
+
+ template <class T>
+ struct CallConstMemberCFunction
+ {
+ static int f (lua_State* L)
+ {
+ assert (isfulluserdata (L, lua_upvalueindex (1)));
+ typedef int (T::*MFP)(lua_State* L);
+ T const* const t = Userdata::get <T> (L, 1, true);
+ MFP const& fnptr = *static_cast <MFP const*> (lua_touserdata (L, lua_upvalueindex (1)));
+ assert (fnptr != 0);
+ return (t->*fnptr) (L);
+ }
+ };
+
+ //--------------------------------------------------------------------------
+
+ // SFINAE Helpers
+
+ template <class MemFnPtr, bool isConst>
+ struct CallMemberFunctionHelper
+ {
+ static void add (lua_State* L, char const* name, MemFnPtr mf)
+ {
+ new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
+ lua_pushcclosure (L, &CallConstMember <MemFnPtr>::f, 1);
+ lua_pushvalue (L, -1);
+ rawsetfield (L, -5, name); // const table
+ rawsetfield (L, -3, name); // class table
+ }
+ };
+
+ template <class MemFnPtr>
+ struct CallMemberFunctionHelper <MemFnPtr, false>
+ {
+ static void add (lua_State* L, char const* name, MemFnPtr mf)
+ {
+ new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
+ lua_pushcclosure (L, &CallMember <MemFnPtr>::f, 1);
+ rawsetfield (L, -3, name); // class table
+ }
+ };
+
+ //--------------------------------------------------------------------------
+ /**
+ __gc metamethod for a class.
+ */
+ template <class C>
+ static int gcMetaMethod (lua_State* L)
+ {
+ Userdata* const ud = Userdata::getExact <C> (L, 1);
+ ud->~Userdata ();
+ return 0;
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ lua_CFunction to get a class data member.
+
+ The pointer-to-member is in the first upvalue.
+ The class userdata object is at the top of the Lua stack.
+ */
+ template <class C, typename T>
+ static int getProperty (lua_State* L)
+ {
+ C const* const c = Userdata::get <C> (L, 1, true);
+ T C::** mp = static_cast <T C::**> (lua_touserdata (L, lua_upvalueindex (1)));
+ Stack <T>::push (L, c->**mp);
+ return 1;
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ lua_CFunction to set a class data member.
+
+ The pointer-to-member is in the first upvalue.
+ The class userdata object is at the top of the Lua stack.
+ */
+ template <class C, typename T>
+ static int setProperty (lua_State* L)
+ {
+ C* const c = Userdata::get <C> (L, 1, false);
+ T C::** mp = static_cast <T C::**> (lua_touserdata (L, lua_upvalueindex (1)));
+ c->**mp = Stack <T>::get (L, 2);
+ return 0;
+ }
+};
diff --git a/libs/lua/LuaBridge/detail/ClassInfo.h b/libs/lua/LuaBridge/detail/ClassInfo.h
new file mode 100644
index 0000000000..8d58069477
--- /dev/null
+++ b/libs/lua/LuaBridge/detail/ClassInfo.h
@@ -0,0 +1,73 @@
+//------------------------------------------------------------------------------
+/*
+ https://github.com/vinniefalco/LuaBridge
+
+ Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
+
+ License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+*/
+//==============================================================================
+
+/** Unique Lua registry keys for a class.
+
+ Each registered class inserts three keys into the registry, whose
+ values are the corresponding static, class, and const metatables. This
+ allows a quick and reliable lookup for a metatable from a template type.
+*/
+template <class T>
+class ClassInfo
+{
+public:
+ /** Get the key for the static table.
+
+ The static table holds the static data members, static properties, and
+ static member functions for a class.
+ */
+ static void const* getStaticKey ()
+ {
+ static char value;
+ return &value;
+ }
+
+ /** Get the key for the class table.
+
+ The class table holds the data members, properties, and member functions
+ of a class. Read-only data and properties, and const member functions are
+ also placed here (to save a lookup in the const table).
+ */
+ static void const* getClassKey ()
+ {
+ static char value;
+ return &value;
+ }
+
+ /** Get the key for the const table.
+
+ The const table holds read-only data members and properties, and const
+ member functions of a class.
+ */
+ static void const* getConstKey ()
+ {
+ static char value;
+ return &value;
+ }
+};
+
diff --git a/libs/lua/LuaBridge/detail/Constructor.h b/libs/lua/LuaBridge/detail/Constructor.h
new file mode 100644
index 0000000000..7b2dad0598
--- /dev/null
+++ b/libs/lua/LuaBridge/detail/Constructor.h
@@ -0,0 +1,204 @@
+//------------------------------------------------------------------------------
+/*
+ https://github.com/vinniefalco/LuaBridge
+
+ Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
+ Copyright 2007, Nathan Reed
+
+ License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+*/
+//==============================================================================
+
+#ifndef LUABRIDGE_CONSTRUCTOR_HEADER
+#define LUABRIDGE_CONSTRUCTOR_HEADER
+
+/*
+* Constructor generators. These templates allow you to call operator new and
+* pass the contents of a type/value list to the Constructor. Like the
+* function pointer containers, these are only defined up to 8 parameters.
+*/
+
+/** Constructor generators.
+
+ These templates call operator new with the contents of a type/value
+ list passed to the Constructor with up to 8 parameters. Two versions
+ of call() are provided. One performs a regular new, the other performs
+ a placement new.
+*/
+template <class T, typename List>
+struct Constructor {};
+
+template <class T>
+struct Constructor <T, None>
+{
+ static T* call (TypeListValues <None> const&)
+ {
+ return new T;
+ }
+ static T* call (void* mem, TypeListValues <None> const&)
+ {
+ return new (mem) T;
+ }
+};
+
+template <class T, class P1>
+struct Constructor <T, TypeList <P1> >
+{
+ static T* call (const TypeListValues<TypeList <P1> > &tvl)
+ {
+ return new T(tvl.hd);
+ }
+ static T* call (void* mem, const TypeListValues<TypeList <P1> > &tvl)
+ {
+ return new (mem) T(tvl.hd);
+ }
+};
+
+template <class T, class P1, class P2>
+struct Constructor <T, TypeList <P1, TypeList <P2> > >
+{
+ static T* call (const TypeListValues<TypeList <P1, TypeList <P2> > > &tvl)
+ {
+ return new T(tvl.hd, tvl.tl.hd);
+ }
+ static T* call (void* mem, const TypeListValues<TypeList <P1, TypeList <P2> > > &tvl)
+ {
+ return new (mem) T(tvl.hd, tvl.tl.hd);
+ }
+};
+
+template <class T, class P1, class P2, class P3>
+struct Constructor <T, TypeList <P1, TypeList <P2, TypeList <P3> > > >
+{
+ static T* call (const TypeListValues<TypeList <P1, TypeList <P2,
+ TypeList <P3> > > > &tvl)
+ {
+ return new T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd);
+ }
+ static T* call (void* mem, const TypeListValues<TypeList <P1, TypeList <P2,
+ TypeList <P3> > > > &tvl)
+ {
+ return new (mem) T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd);
+ }
+};
+
+template <class T, class P1, class P2, class P3, class P4>
+struct Constructor <T, TypeList <P1, TypeList <P2, TypeList <P3,
+ TypeList <P4> > > > >
+{
+ static T* call (const TypeListValues<TypeList <P1, TypeList <P2,
+ TypeList <P3, TypeList <P4> > > > > &tvl)
+ {
+ return new T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd);
+ }
+ static T* call (void* mem, const TypeListValues<TypeList <P1, TypeList <P2,
+ TypeList <P3, TypeList <P4> > > > > &tvl)
+ {
+ return new (mem) T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd);
+ }
+};
+
+template <class T, class P1, class P2, class P3, class P4,
+ class P5>
+struct Constructor <T, TypeList <P1, TypeList <P2, TypeList <P3,
+ TypeList <P4, TypeList <P5> > > > > >
+{
+ static T* call (const TypeListValues<TypeList <P1, TypeList <P2,
+ TypeList <P3, TypeList <P4, TypeList <P5> > > > > > &tvl)
+ {
+ return new T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd,
+ tvl.tl.tl.tl.tl.hd);
+ }
+ static T* call (void* mem, const TypeListValues<TypeList <P1, TypeList <P2,
+ TypeList <P3, TypeList <P4, TypeList <P5> > > > > > &tvl)
+ {
+ return new (mem) T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd,
+ tvl.tl.tl.tl.tl.hd);
+ }
+};
+
+template <class T, class P1, class P2, class P3, class P4,
+ class P5, class P6>
+struct Constructor <T, TypeList <P1, TypeList <P2, TypeList <P3,
+ TypeList <P4, TypeList <P5, TypeList <P6> > > > > > >
+{
+ static T* call (const TypeListValues<TypeList <P1, TypeList <P2,
+ TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6> > > > > > > &tvl)
+ {
+ return new T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd,
+ tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd);
+ }
+ static T* call (void* mem, const TypeListValues<TypeList <P1, TypeList <P2,
+ TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6> > > > > > > &tvl)
+ {
+ return new (mem) T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd,
+ tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd);
+ }
+};
+
+template <class T, class P1, class P2, class P3, class P4,
+ class P5, class P6, class P7>
+struct Constructor <T, TypeList <P1, TypeList <P2, TypeList <P3,
+ TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7> > > > > > > >
+{
+ static T* call (const TypeListValues<TypeList <P1, TypeList <P2,
+ TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6,
+ TypeList <P7> > > > > > > > &tvl)
+ {
+ return new T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd,
+ tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd,
+ tvl.tl.tl.tl.tl.tl.tl.hd);
+ }
+ static T* call (void* mem, const TypeListValues<TypeList <P1, TypeList <P2,
+ TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6,
+ TypeList <P7> > > > > > > > &tvl)
+ {
+ return new (mem) T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd,
+ tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd,
+ tvl.tl.tl.tl.tl.tl.tl.hd);
+ }
+};
+
+template <class T, class P1, class P2, class P3, class P4,
+ class P5, class P6, class P7, class P8>
+struct Constructor <T, TypeList <P1, TypeList <P2, TypeList <P3,
+ TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7,
+ TypeList <P8> > > > > > > > >
+{
+ static T* call (const TypeListValues<TypeList <P1, TypeList <P2,
+ TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6,
+ TypeList <P7, TypeList <P8> > > > > > > > > &tvl)
+ {
+ return new T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd,
+ tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd,
+ tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd);
+ }
+ static T* call (void* mem, const TypeListValues<TypeList <P1, TypeList <P2,
+ TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6,
+ TypeList <P7, TypeList <P8> > > > > > > > > &tvl)
+ {
+ return new (mem) T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd,
+ tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd,
+ tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd);
+ }
+};
+
+#endif
diff --git a/libs/lua/LuaBridge/detail/FuncTraits.h b/libs/lua/LuaBridge/detail/FuncTraits.h
new file mode 100644
index 0000000000..7eccb61832
--- /dev/null
+++ b/libs/lua/LuaBridge/detail/FuncTraits.h
@@ -0,0 +1,852 @@
+//------------------------------------------------------------------------------
+/*
+ https://github.com/vinniefalco/LuaBridge
+
+ Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
+
+ License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+*/
+//==============================================================================
+
+/**
+ Since the throw specification is part of a function signature, the FuncTraits
+ family of templates needs to be specialized for both types. The
+ LUABRIDGE_THROWSPEC macro controls whether we use the 'throw ()' form, or
+ 'noexcept' (if C++11 is available) to distinguish the functions.
+*/
+#if defined (__APPLE_CPP__) || defined(__APPLE_CC__) || defined(__clang__) || defined(__GNUC__) || \
+ (defined (_MSC_VER) && (_MSC_VER >= 1700))
+// Do not define LUABRIDGE_THROWSPEC since the Xcode and gcc compilers do not
+// distinguish the throw specification in the function signature.
+#else
+// Visual Studio 10 and earlier pay too much mind to useless throw() spec.
+//
+# define LUABRIDGE_THROWSPEC throw()
+#endif
+
+//==============================================================================
+/**
+ Traits for function pointers.
+
+ There are three types of functions: global, non-const member, and const
+ member. These templates determine the type of function, which class type it
+ belongs to if it is a class member, the const-ness if it is a member
+ function, and the type information for the return value and argument list.
+
+ Expansions are provided for functions with up to 8 parameters. This can be
+ manually extended, or expanded to an arbitrary amount using C++11 features.
+*/
+template <class MemFn, class D = MemFn>
+struct FuncTraits
+{
+};
+
+/* Ordinary function pointers. */
+
+template <class R, class D>
+struct FuncTraits <R (*) (), D>
+{
+ static bool const isMemberFunction = false;
+ typedef D DeclType;
+ typedef R ReturnType;
+ typedef None Params;
+ static R call (D fp, TypeListValues <Params>)
+ {
+ return fp ();
+ }
+};
+
+template <class R, class P1, class D>
+struct FuncTraits <R (*) (P1), D>
+{
+ static bool const isMemberFunction = false;
+ typedef D DeclType;
+ typedef R ReturnType;
+ typedef TypeList <P1> Params;
+ static R call (D fp, TypeListValues <Params> tvl)
+ {
+ return fp (tvl.hd);
+ }
+};
+
+template <class R, class P1, class P2, class D>
+struct FuncTraits <R (*) (P1, P2), D>
+{
+ static bool const isMemberFunction = false;
+ typedef D DeclType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2> > Params;
+ static R call (D fp, TypeListValues <Params> tvl)
+ {
+ return fp (tvl.hd, tvl.tl.hd);
+ }
+};
+
+template <class R, class P1, class P2, class P3, class D>
+struct FuncTraits <R (*) (P1, P2, P3), D>
+{
+ static bool const isMemberFunction = false;
+ typedef D DeclType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2, TypeList <P3> > > Params;
+ static R call (D fp, TypeListValues <Params> tvl)
+ {
+ return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd);
+ }
+};
+
+template <class R, class P1, class P2, class P3, class P4, class D>
+struct FuncTraits <R (*) (P1, P2, P3, P4), D>
+{
+ static bool const isMemberFunction = false;
+ typedef D DeclType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4> > > > Params;
+ static R call (D fp, TypeListValues <Params> tvl)
+ {
+ return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd);
+ }
+};
+
+template <class R, class P1, class P2, class P3, class P4, class P5, class D>
+struct FuncTraits <R (*) (P1, P2, P3, P4, P5), D>
+{
+ static bool const isMemberFunction = false;
+ typedef D DeclType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5> > > > > Params;
+ static R call (D fp, TypeListValues <Params> tvl)
+ {
+ return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd);
+ }
+};
+
+template <class R, class P1, class P2, class P3, class P4, class P5, class P6, class D>
+struct FuncTraits <R (*) (P1, P2, P3, P4, P5, P6), D>
+{
+ static bool const isMemberFunction = false;
+ typedef D DeclType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6> > > > > > Params;
+ static R call (D fp, TypeListValues <Params> tvl)
+ {
+ return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd);
+ }
+};
+
+template <class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class D>
+struct FuncTraits <R (*) (P1, P2, P3, P4, P5, P6, P7), D>
+{
+ static bool const isMemberFunction = false;
+ typedef D DeclType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7> > > > > > > Params;
+ static R call (D fp, TypeListValues <Params> tvl)
+ {
+ return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd);
+ }
+};
+
+template <class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class D>
+struct FuncTraits <R (*) (P1, P2, P3, P4, P5, P6, P7, P8), D>
+{
+ static bool const isMemberFunction = false;
+ typedef D DeclType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7, TypeList <P8> > > > > > > > Params;
+ static R call (D fp, TypeListValues <Params> tvl)
+ {
+ return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd);
+ }
+};
+
+/* Non-const member function pointers. */
+
+template <class T, class R, class D>
+struct FuncTraits <R (T::*) (), D>
+{
+ static bool const isMemberFunction = true;
+ static bool const isConstMemberFunction = false;
+ typedef D DeclType;
+ typedef T ClassType;
+ typedef R ReturnType;
+ typedef None Params;
+ static R call (T* obj, D fp, TypeListValues <Params>)
+ {
+ return (obj->*fp)();
+ }
+};
+
+template <class T, class R, class P1, class D>
+struct FuncTraits <R (T::*) (P1), D>
+{
+ static bool const isMemberFunction = true;
+ static bool const isConstMemberFunction = false;
+ typedef D DeclType;
+ typedef T ClassType;
+ typedef R ReturnType;
+ typedef TypeList <P1> Params;
+ static R call (T* obj, D fp, TypeListValues <Params> tvl)
+ {
+ return (obj->*fp)(tvl.hd);
+ }
+};
+
+template <class T, class R, class P1, class P2, class D>
+struct FuncTraits <R (T::*) (P1, P2), D>
+{
+ static bool const isMemberFunction = true;
+ static bool const isConstMemberFunction = false;
+ typedef D DeclType;
+ typedef T ClassType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2> > Params;
+ static R call (T* obj, D fp, TypeListValues <Params> tvl)
+ {
+ return (obj->*fp)(tvl.hd, tvl.tl.hd);
+ }
+};
+
+template <class T, class R, class P1, class P2, class P3, class D>
+struct FuncTraits <R (T::*) (P1, P2, P3), D>
+{
+ static bool const isMemberFunction = true;
+ static bool const isConstMemberFunction = false;
+ typedef D DeclType;
+ typedef T ClassType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2, TypeList <P3> > > Params;
+ static R call (T* obj, D fp, TypeListValues <Params> tvl)
+ {
+ return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd);
+ }
+};
+
+template <class T, class R, class P1, class P2, class P3, class P4, class D>
+struct FuncTraits <R (T::*) (P1, P2, P3, P4), D>
+{
+ static bool const isMemberFunction = true;
+ static bool const isConstMemberFunction = false;
+ typedef D DeclType;
+ typedef T ClassType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4> > > > Params;
+ static R call (T* obj, D fp, TypeListValues <Params> tvl)
+ {
+ return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd);
+ }
+};
+
+template <class T, class R, class P1, class P2, class P3, class P4, class P5, class D>
+struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5), D>
+{
+ static bool const isMemberFunction = true;
+ static bool const isConstMemberFunction = false;
+ typedef D DeclType;
+ typedef T ClassType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5> > > > > Params;
+ static R call (T* obj, D fp, TypeListValues <Params> tvl)
+ {
+ return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd);
+ }
+};
+
+template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class D>
+struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6), D>
+{
+ static bool const isMemberFunction = true;
+ static bool const isConstMemberFunction = false;
+ typedef D DeclType;
+ typedef T ClassType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6> > > > > > Params;
+ static R call (T* obj, D fp, TypeListValues <Params> tvl)
+ {
+ return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd);
+ }
+};
+
+template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class D>
+struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6, P7), D>
+{
+ static bool const isMemberFunction = true;
+ static bool const isConstMemberFunction = false;
+ typedef D DeclType;
+ typedef T ClassType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7> > > > > > > Params;
+ static R call (T* obj, D fp, TypeListValues <Params> tvl)
+ {
+ return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd);
+ }
+};
+
+template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class D>
+struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6, P7, P8), D>
+{
+ static bool const isMemberFunction = true;
+ static bool const isConstMemberFunction = false;
+ typedef D DeclType;
+ typedef T ClassType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7, TypeList <P8> > > > > > > > Params;
+ static R call (T* obj, D fp, TypeListValues <Params> tvl)
+ {
+ return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd);
+ }
+};
+
+/* Const member function pointers. */
+
+template <class T, class R, class D>
+struct FuncTraits <R (T::*) () const, D>
+{
+ static bool const isMemberFunction = true;
+ static bool const isConstMemberFunction = true;
+ typedef D DeclType;
+ typedef T ClassType;
+ typedef R ReturnType;
+ typedef None Params;
+ static R call (T const* obj, D fp, TypeListValues <Params>)
+ {
+ return (obj->*fp)();
+ }
+};
+
+template <class T, class R, class P1, class D>
+struct FuncTraits <R (T::*) (P1) const, D>
+{
+ static bool const isMemberFunction = true;
+ static bool const isConstMemberFunction = true;
+ typedef D DeclType;
+ typedef T ClassType;
+ typedef R ReturnType;
+ typedef TypeList <P1> Params;
+ static R call (T const* obj, D fp, TypeListValues <Params> tvl)
+ {
+ return (obj->*fp)(tvl.hd);
+ }
+};
+
+template <class T, class R, class P1, class P2, class D>
+struct FuncTraits <R (T::*) (P1, P2) const, D>
+{
+ static bool const isMemberFunction = true;
+ static bool const isConstMemberFunction = true;
+ typedef D DeclType;
+ typedef T ClassType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2> > Params;
+ static R call (T const* obj, R (T::*fp) (P1, P2) const,
+ TypeListValues <Params> tvl)
+ {
+ return (obj->*fp)(tvl.hd, tvl.tl.hd);
+ }
+};
+
+template <class T, class R, class P1, class P2, class P3, class D>
+struct FuncTraits <R (T::*) (P1, P2, P3) const, D>
+{
+ static bool const isMemberFunction = true;
+ static bool const isConstMemberFunction = true;
+ typedef D DeclType;
+ typedef T ClassType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2, TypeList <P3> > > Params;
+ static R call (T const* obj, D fp, TypeListValues <Params> tvl)
+ {
+ return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd);
+ }
+};
+
+template <class T, class R, class P1, class P2, class P3, class P4, class D>
+struct FuncTraits <R (T::*) (P1, P2, P3, P4) const, D>
+{
+ static bool const isMemberFunction = true;
+ static bool const isConstMemberFunction = true;
+ typedef D DeclType;
+ typedef T ClassType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4> > > > Params;
+ static R call (T const* obj, D fp, TypeListValues <Params> tvl)
+ {
+ return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd);
+ }
+};
+
+template <class T, class R, class P1, class P2, class P3, class P4, class P5, class D>
+struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5) const, D>
+{
+ static bool const isMemberFunction = true;
+ static bool const isConstMemberFunction = true;
+ typedef D DeclType;
+ typedef T ClassType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5> > > > > Params;
+ static R call (T const* obj, D fp, TypeListValues <Params> tvl)
+ {
+ return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd);
+ }
+};
+
+template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class D>
+struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6) const, D>
+{
+ static bool const isMemberFunction = true;
+ static bool const isConstMemberFunction = true;
+ typedef D DeclType;
+ typedef T ClassType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6> > > > > > Params;
+ static R call (T const* obj, D fp, TypeListValues <Params> tvl)
+ {
+ return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd);
+ }
+};
+
+template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class D>
+struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6, P7) const, D>
+{
+ static bool const isMemberFunction = true;
+ static bool const isConstMemberFunction = true;
+ typedef D DeclType;
+ typedef T ClassType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7> > > > > > > Params;
+ static R call (T const* obj, D fp, TypeListValues <Params> tvl)
+ {
+ return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd);
+ }
+};
+
+template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class D>
+struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6, P7, P8) const, D>
+{
+ static bool const isMemberFunction = true;
+ static bool const isConstMemberFunction = true;
+ typedef D DeclType;
+ typedef T ClassType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7, TypeList <P8> > > > > > > > Params;
+ static R call (T const* obj, D fp, TypeListValues <Params> tvl)
+ {
+ return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd);
+ }
+};
+
+#if defined (LUABRIDGE_THROWSPEC)
+
+/* Ordinary function pointers. */
+
+template <class R, class D>
+struct FuncTraits <R (*) () LUABRIDGE_THROWSPEC, D>
+{
+ static bool const isMemberFunction = false;
+ typedef D DeclType;
+ typedef R ReturnType;
+ typedef None Params;
+ static R call (D fp, TypeListValues <Params> const&)
+ {
+ return fp ();
+ }
+};
+
+template <class R, class P1, class D>
+struct FuncTraits <R (*) (P1) LUABRIDGE_THROWSPEC, D>
+{
+ static bool const isMemberFunction = false;
+ typedef D DeclType;
+ typedef R ReturnType;
+ typedef TypeList <P1> Params;
+ static R call (D fp, TypeListValues <Params> tvl)
+ {
+ return fp (tvl.hd);
+ }
+};
+
+template <class R, class P1, class P2, class D>
+struct FuncTraits <R (*) (P1, P2) LUABRIDGE_THROWSPEC, D>
+{
+ static bool const isMemberFunction = false;
+ typedef D DeclType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2> > Params;
+ static R call (D fp, TypeListValues <Params> tvl)
+ {
+ return fp (tvl.hd, tvl.tl.hd);
+ }
+};
+
+template <class R, class P1, class P2, class P3, class D>
+struct FuncTraits <R (*) (P1, P2, P3) LUABRIDGE_THROWSPEC, D>
+{
+ static bool const isMemberFunction = false;
+ typedef D DeclType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2, TypeList <P3> > > Params;
+ static R call (D fp, TypeListValues <Params> tvl)
+ {
+ return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd);
+ }
+};
+
+template <class R, class P1, class P2, class P3, class P4, class D>
+struct FuncTraits <R (*) (P1, P2, P3, P4) LUABRIDGE_THROWSPEC, D>
+{
+ static bool const isMemberFunction = false;
+ typedef D DeclType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4> > > > Params;
+ static R call (D fp, TypeListValues <Params> tvl)
+ {
+ return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd);
+ }
+};
+
+template <class R, class P1, class P2, class P3, class P4, class P5, class D>
+struct FuncTraits <R (*) (P1, P2, P3, P4, P5) LUABRIDGE_THROWSPEC, D>
+{
+ static bool const isMemberFunction = false;
+ typedef D DeclType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5> > > > > Params;
+ static R call (D fp, TypeListValues <Params> tvl)
+ {
+ return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd);
+ }
+};
+
+template <class R, class P1, class P2, class P3, class P4, class P5, class P6, class D>
+struct FuncTraits <R (*) (P1, P2, P3, P4, P5, P6) LUABRIDGE_THROWSPEC, D>
+{
+ static bool const isMemberFunction = false;
+ typedef D DeclType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6> > > > > > Params;
+ static R call (D fp, TypeListValues <Params> tvl)
+ {
+ return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd);
+ }
+};
+
+template <class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class D>
+struct FuncTraits <R (*) (P1, P2, P3, P4, P5, P6, P7) LUABRIDGE_THROWSPEC, D>
+{
+ static bool const isMemberFunction = false;
+ typedef D DeclType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7> > > > > > > Params;
+ static R call (D fp, TypeListValues <Params> tvl)
+ {
+ return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd);
+ }
+};
+
+template <class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class D>
+struct FuncTraits <R (*) (P1, P2, P3, P4, P5, P6, P7, P8) LUABRIDGE_THROWSPEC, D>
+{
+ static bool const isMemberFunction = false;
+ typedef D DeclType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7, TypeList <P8> > > > > > > > Params;
+ static R call (D fp, TypeListValues <Params> tvl)
+ {
+ return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd);
+ }
+};
+
+/* Non-const member function pointers with THROWSPEC. */
+
+template <class T, class R, class D>
+struct FuncTraits <R (T::*) () LUABRIDGE_THROWSPEC, D>
+{
+ static bool const isMemberFunction = true;
+ static bool const isConstMemberFunction = false;
+ typedef D DeclType;
+ typedef T ClassType;
+ typedef R ReturnType;
+ typedef None Params;
+ static R call (T* obj, D fp, TypeListValues <Params> const&)
+ {
+ return (obj->*fp)();
+ }
+};
+
+template <class T, class R, class P1, class D>
+struct FuncTraits <R (T::*) (P1) LUABRIDGE_THROWSPEC, D>
+{
+ static bool const isMemberFunction = true;
+ static bool const isConstMemberFunction = false;
+ typedef D DeclType;
+ typedef T ClassType;
+ typedef R ReturnType;
+ typedef TypeList <P1> Params;
+ static R call (T* obj, D fp, TypeListValues <Params> tvl)
+ {
+ return (obj->*fp)(tvl.hd);
+ }
+};
+
+template <class T, class R, class P1, class P2, class D>
+struct FuncTraits <R (T::*) (P1, P2) LUABRIDGE_THROWSPEC, D>
+{
+ static bool const isMemberFunction = true;
+ static bool const isConstMemberFunction = false;
+ typedef D DeclType;
+ typedef T ClassType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2> > Params;
+ static R call (T* obj, D fp, TypeListValues <Params> tvl)
+ {
+ return (obj->*fp)(tvl.hd, tvl.tl.hd);
+ }
+};
+
+template <class T, class R, class P1, class P2, class P3, class D>
+struct FuncTraits <R (T::*) (P1, P2, P3) LUABRIDGE_THROWSPEC, D>
+{
+ static bool const isMemberFunction = true;
+ static bool const isConstMemberFunction = false;
+ typedef D DeclType;
+ typedef T ClassType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2, TypeList <P3> > > Params;
+ static R call (T* obj, D fp, TypeListValues <Params> tvl)
+ {
+ return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd);
+ }
+};
+
+template <class T, class R, class P1, class P2, class P3, class P4, class D>
+struct FuncTraits <R (T::*) (P1, P2, P3, P4) LUABRIDGE_THROWSPEC, D>
+{
+ static bool const isMemberFunction = true;
+ static bool const isConstMemberFunction = false;
+ typedef D DeclType;
+ typedef T ClassType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4> > > > Params;
+ static R call (T* obj, D fp, TypeListValues <Params> tvl)
+ {
+ return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd);
+ }
+};
+
+template <class T, class R, class P1, class P2, class P3, class P4, class P5, class D>
+struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5) LUABRIDGE_THROWSPEC, D>
+{
+ static bool const isMemberFunction = true;
+ static bool const isConstMemberFunction = false;
+ typedef D DeclType;
+ typedef T ClassType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5> > > > > Params;
+ static R call (T* obj, D fp, TypeListValues <Params> tvl)
+ {
+ return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd);
+ }
+};
+
+template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class D>
+struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6) LUABRIDGE_THROWSPEC, D>
+{
+ static bool const isMemberFunction = true;
+ static bool const isConstMemberFunction = false;
+ typedef D DeclType;
+ typedef T ClassType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6> > > > > > Params;
+ static R call (T* obj, D fp, TypeListValues <Params> tvl)
+ {
+ return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd);
+ }
+};
+
+template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class D>
+struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6, P7) LUABRIDGE_THROWSPEC, D>
+{
+ static bool const isMemberFunction = true;
+ static bool const isConstMemberFunction = false;
+ typedef D DeclType;
+ typedef T ClassType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7> > > > > > > Params;
+ static R call (T* obj, D fp, TypeListValues <Params> tvl)
+ {
+ return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd);
+ }
+};
+
+template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class D>
+struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6, P7, P8) LUABRIDGE_THROWSPEC, D>
+{
+ static bool const isMemberFunction = true;
+ static bool const isConstMemberFunction = false;
+ typedef D DeclType;
+ typedef T ClassType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7, TypeList <P8> > > > > > > > Params;
+ static R call (T* obj, D fp, TypeListValues <Params> tvl)
+ {
+ return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd);
+ }
+};
+
+/* Const member function pointers with THROWSPEC. */
+
+template <class T, class R, class D>
+struct FuncTraits <R (T::*) () const LUABRIDGE_THROWSPEC, D>
+{
+ static bool const isMemberFunction = true;
+ static bool const isConstMemberFunction = true;
+ typedef D DeclType;
+ typedef T ClassType;
+ typedef R ReturnType;
+ typedef None Params;
+ static R call (T const* obj, D fp, TypeListValues <Params>)
+ {
+ return (obj->*fp)();
+ }
+};
+
+template <class T, class R, class P1, class D>
+struct FuncTraits <R (T::*) (P1) const LUABRIDGE_THROWSPEC, D>
+{
+ static bool const isMemberFunction = true;
+ static bool const isConstMemberFunction = true;
+ typedef D DeclType;
+ typedef T ClassType;
+ typedef R ReturnType;
+ typedef TypeList <P1> Params;
+ static R call (T const* obj, D fp, TypeListValues <Params> tvl)
+ {
+ return (obj->*fp)(tvl.hd);
+ }
+};
+
+template <class T, class R, class P1, class P2, class D>
+struct FuncTraits <R (T::*) (P1, P2) const LUABRIDGE_THROWSPEC, D>
+{
+ static bool const isMemberFunction = true;
+ static bool const isConstMemberFunction = true;
+ typedef D DeclType;
+ typedef T ClassType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2> > Params;
+ static R call (T const* obj, D fp, TypeListValues <Params> tvl)
+ {
+ return (obj->*fp)(tvl.hd, tvl.tl.hd);
+ }
+};
+
+template <class T, class R, class P1, class P2, class P3, class D>
+struct FuncTraits <R (T::*) (P1, P2, P3) const LUABRIDGE_THROWSPEC, D>
+{
+ static bool const isMemberFunction = true;
+ static bool const isConstMemberFunction = true;
+ typedef D DeclType;
+ typedef T ClassType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2, TypeList <P3> > > Params;
+ static R call (T const* obj, D fp, TypeListValues <Params> tvl)
+ {
+ return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd);
+ }
+};
+
+template <class T, class R, class P1, class P2, class P3, class P4, class D>
+struct FuncTraits <R (T::*) (P1, P2, P3, P4) const LUABRIDGE_THROWSPEC, D>
+{
+ static bool const isMemberFunction = true;
+ static bool const isConstMemberFunction = true;
+ typedef D DeclType;
+ typedef T ClassType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4> > > > Params;
+ static R call (T const* obj, D fp, TypeListValues <Params> tvl)
+ {
+ return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd);
+ }
+};
+
+template <class T, class R, class P1, class P2, class P3, class P4, class P5, class D>
+struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5) const LUABRIDGE_THROWSPEC, D>
+{
+ static bool const isMemberFunction = true;
+ static bool const isConstMemberFunction = true;
+ typedef D DeclType;
+ typedef T ClassType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5> > > > > Params;
+ static R call (T const* obj, D fp, TypeListValues <Params> tvl)
+ {
+ return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd,
+ tvl.tl.tl.tl.tl.hd);
+ }
+};
+
+template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class D>
+struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6) const LUABRIDGE_THROWSPEC, D>
+{
+ static bool const isMemberFunction = true;
+ static bool const isConstMemberFunction = true;
+ typedef D DeclType;
+ typedef T ClassType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6> > > > > > Params;
+ static R call (T const* obj, D fp, TypeListValues <Params> tvl)
+ {
+ return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd);
+ }
+};
+
+template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class D>
+struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6, P7) const LUABRIDGE_THROWSPEC, D>
+{
+ static bool const isMemberFunction = true;
+ static bool const isConstMemberFunction = true;
+ typedef D DeclType;
+ typedef T ClassType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7> > > > > > > Params;
+ static R call (T const* obj, D fp, TypeListValues <Params> tvl)
+ {
+ return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd);
+ }
+};
+
+template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class D>
+struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6, P7, P8) const LUABRIDGE_THROWSPEC, D>
+{
+ static bool const isMemberFunction = true;
+ static bool const isConstMemberFunction = true;
+ typedef D DeclType;
+ typedef T ClassType;
+ typedef R ReturnType;
+ typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7, TypeList <P8> > > > > > > > Params;
+ static R call (T const* obj, D fp, TypeListValues <Params> tvl)
+ {
+ return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd);
+ }
+};
+
+#endif
diff --git a/libs/lua/LuaBridge/detail/Iterator.h b/libs/lua/LuaBridge/detail/Iterator.h
new file mode 100644
index 0000000000..d883fb3989
--- /dev/null
+++ b/libs/lua/LuaBridge/detail/Iterator.h
@@ -0,0 +1,114 @@
+//------------------------------------------------------------------------------
+/*
+ https://github.com/vinniefalco/LuaBridge
+
+ Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
+
+ License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+*/
+//==============================================================================
+
+/** Allows table iteration.
+*/
+class Iterator
+{
+private:
+ lua_State* m_L;
+ LuaRef m_table;
+ LuaRef m_key;
+ LuaRef m_value;
+
+ void next ()
+ {
+ m_table.push(m_L);
+ m_key.push (m_L);
+ if (lua_next (m_L, -2))
+ {
+ m_value.pop (m_L);
+ m_key.pop (m_L);
+ }
+ else
+ {
+ m_key = Nil();
+ m_value = Nil();
+ }
+ lua_pop(m_L, 1);
+ }
+
+public:
+ explicit Iterator (LuaRef table)
+ : m_L (table.state ())
+ , m_table (table)
+ , m_key (table.state ()) // m_key is nil
+ , m_value (table.state ()) // m_value is nil
+ {
+ next (); // get the first (key, value) pair from table
+ }
+
+ lua_State* state () const
+ {
+ return m_L;
+ }
+
+ LuaRef operator* () const
+ {
+ return m_value;
+ }
+
+ LuaRef operator-> () const
+ {
+ return m_value;
+ }
+
+ Iterator& operator++ ()
+ {
+ if (isNil())
+ {
+ // if the iterator reaches the end, do nothing
+ return *this;
+ }
+ else
+ {
+ next();
+ return *this;
+ }
+ }
+
+ inline bool isNil () const
+ {
+ return m_key.isNil ();
+ }
+
+ inline LuaRef key () const
+ {
+ return m_key;
+ }
+
+ inline LuaRef value () const
+ {
+ return m_value;
+ }
+
+private:
+ // Don't use postfix increment, it is less efficient
+ Iterator operator++ (int);
+};
+
diff --git a/libs/lua/LuaBridge/detail/LuaException.h b/libs/lua/LuaBridge/detail/LuaException.h
new file mode 100644
index 0000000000..a0944961ce
--- /dev/null
+++ b/libs/lua/LuaBridge/detail/LuaException.h
@@ -0,0 +1,113 @@
+//------------------------------------------------------------------------------
+/*
+ https://github.com/vinniefalco/LuaBridge
+
+ Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
+ Copyright 2008, Nigel Atkinson <suprapilot+LuaCode@gmail.com>
+
+ License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+*/
+//==============================================================================
+
+class LuaException : public std::exception
+{
+private:
+ lua_State* m_L;
+ std::string m_what;
+
+public:
+ //----------------------------------------------------------------------------
+ /**
+ Construct a LuaException after a lua_pcall().
+ */
+ LuaException (lua_State* L, int /*code*/)
+ : m_L (L)
+ {
+ whatFromStack ();
+ }
+
+ //----------------------------------------------------------------------------
+
+ LuaException (lua_State *L,
+ char const*,
+ char const*,
+ long)
+ : m_L (L)
+ {
+ whatFromStack ();
+ }
+
+ //----------------------------------------------------------------------------
+
+ ~LuaException() throw ()
+ {
+ }
+
+ //----------------------------------------------------------------------------
+
+ char const* what() const throw ()
+ {
+ return m_what.c_str();
+ }
+
+ //============================================================================
+ /**
+ Throw an exception.
+
+ This centralizes all the exceptions thrown, so that we can set
+ breakpoints before the stack is unwound, or otherwise customize the
+ behavior.
+ */
+ template <class Exception>
+ static void Throw (Exception e)
+ {
+ throw e;
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ Wrapper for lua_pcall that throws.
+ */
+ static void pcall (lua_State* L, int nargs = 0, int nresults = 0, int msgh = 0)
+ {
+ int code = lua_pcall (L, nargs, nresults, msgh);
+
+ if (code != LUABRIDGE_LUA_OK)
+ Throw (LuaException (L, code));
+ }
+
+ //----------------------------------------------------------------------------
+
+protected:
+ void whatFromStack ()
+ {
+ if (lua_gettop (m_L) > 0)
+ {
+ char const* s = lua_tostring (m_L, -1);
+ m_what = s ? s : "";
+ }
+ else
+ {
+ // stack is empty
+ m_what = "missing error";
+ }
+ }
+};
diff --git a/libs/lua/LuaBridge/detail/LuaHelpers.h b/libs/lua/LuaBridge/detail/LuaHelpers.h
new file mode 100644
index 0000000000..7bc84eb164
--- /dev/null
+++ b/libs/lua/LuaBridge/detail/LuaHelpers.h
@@ -0,0 +1,143 @@
+//------------------------------------------------------------------------------
+/*
+ https://github.com/vinniefalco/LuaBridge
+
+ Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
+ Copyright 2007, Nathan Reed
+
+ License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+*/
+//==============================================================================
+
+// These are for Lua versions prior to 5.2.0.
+//
+#if LUA_VERSION_NUM < 502
+inline int lua_absindex (lua_State* L, int idx)
+{
+ if (idx > LUA_REGISTRYINDEX && idx < 0)
+ return lua_gettop (L) + idx + 1;
+ else
+ return idx;
+}
+
+inline void lua_rawgetp (lua_State* L, int idx, void const* p)
+{
+ idx = lua_absindex (L, idx);
+ lua_pushlightuserdata (L, const_cast <void*> (p));
+ lua_rawget (L,idx);
+}
+
+inline void lua_rawsetp (lua_State* L, int idx, void const* p)
+{
+ idx = lua_absindex (L, idx);
+ lua_pushlightuserdata (L, const_cast <void*> (p));
+ // put key behind value
+ lua_insert (L, -2);
+ lua_rawset (L, idx);
+}
+
+#define LUA_OPEQ 1
+#define LUA_OPLT 2
+#define LUA_OPLE 3
+
+inline int lua_compare (lua_State* L, int idx1, int idx2, int op)
+{
+ switch (op)
+ {
+ case LUA_OPEQ:
+ return lua_equal (L, idx1, idx2);
+ break;
+
+ case LUA_OPLT:
+ return lua_lessthan (L, idx1, idx2);
+ break;
+
+ case LUA_OPLE:
+ return lua_equal (L, idx1, idx2) || lua_lessthan (L, idx1, idx2);
+ break;
+
+ default:
+ return 0;
+ };
+}
+
+inline int get_length (lua_State* L, int idx)
+{
+ return int (lua_objlen (L, idx));
+}
+
+#else
+inline int get_length (lua_State* L, int idx)
+{
+ lua_len (L, idx);
+ int len = int (luaL_checknumber (L, -1));
+ lua_pop (L, 1);
+ return len;
+}
+
+#endif
+
+#ifndef LUA_OK
+# define LUABRIDGE_LUA_OK 0
+#else
+# define LUABRIDGE_LUA_OK LUA_OK
+#endif
+
+/** Get a table value, bypassing metamethods.
+*/
+inline void rawgetfield (lua_State* L, int index, char const* key)
+{
+ assert (lua_istable (L, index));
+ index = lua_absindex (L, index);
+ lua_pushstring (L, key);
+ lua_rawget (L, index);
+}
+
+/** Set a table value, bypassing metamethods.
+*/
+inline void rawsetfield (lua_State* L, int index, char const* key)
+{
+ assert (lua_istable (L, index));
+ index = lua_absindex (L, index);
+ lua_pushstring (L, key);
+ lua_insert (L, -2);
+ lua_rawset (L, index);
+}
+
+/** Returns true if the value is a full userdata (not light).
+*/
+inline bool isfulluserdata (lua_State* L, int index)
+{
+ return lua_isuserdata (L, index) && !lua_islightuserdata (L, index);
+}
+
+/** Test lua_State objects for global equality.
+
+ This can determine if two different lua_State objects really point
+ to the same global state, such as when using coroutines.
+
+ @note This is used for assertions.
+*/
+inline bool equalstates (lua_State* L1, lua_State* L2)
+{
+ return lua_topointer (L1, LUA_REGISTRYINDEX) ==
+ lua_topointer (L2, LUA_REGISTRYINDEX);
+}
diff --git a/libs/lua/LuaBridge/detail/LuaRef.h b/libs/lua/LuaBridge/detail/LuaRef.h
new file mode 100644
index 0000000000..e726bcafe7
--- /dev/null
+++ b/libs/lua/LuaBridge/detail/LuaRef.h
@@ -0,0 +1,1215 @@
+//------------------------------------------------------------------------------
+/*
+ https://github.com/vinniefalco/LuaBridge
+
+ Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
+ Copyright 2008, Nigel Atkinson <suprapilot+LuaCode@gmail.com>
+
+ License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+*/
+//==============================================================================
+
+//------------------------------------------------------------------------------
+/**
+ Type tag for representing LUA_TNIL.
+
+ Construct one of these using `Nil()` to represent a Lua nil. This is faster
+ than creating a reference in the registry to nil. Example:
+
+ LuaRef t (LuaRef::createTable (L));
+ ...
+ t ["k"] = Nil(); // assign nil
+*/
+struct Nil
+{
+};
+
+//------------------------------------------------------------------------------
+/**
+ Lightweight reference to a Lua object.
+
+ The reference is maintained for the lifetime of the C++ object.
+*/
+class LuaRef
+{
+private:
+ class Proxy;
+ friend struct Stack <Proxy>;
+
+ //----------------------------------------------------------------------------
+ /**
+ Pop the Lua stack.
+
+ Pops the specified number of stack items on destruction. We use this
+ when returning objects, to avoid an explicit temporary variable, since
+ the destructor executes after the return statement. For example:
+
+ template <class U>
+ U cast (lua_State* L)
+ {
+ StackPop p (L, 1);
+ ...
+ return U (); // dtor called after this line
+ }
+
+ @note The `StackPop` object must always be a named local variable.
+ */
+ class StackPop
+ {
+ public:
+ /** Create a StackPop object.
+
+ @param count The number of stack entries to pop on destruction.
+ */
+ StackPop (lua_State* L, int count)
+ : m_L (L)
+ , m_count (count)
+ {
+ }
+
+ ~StackPop ()
+ {
+ lua_pop (m_L, m_count);
+ }
+
+ private:
+ lua_State* m_L;
+ int m_count;
+ };
+
+ //----------------------------------------------------------------------------
+ /**
+ A proxy for representing table values.
+ */
+ class Proxy
+ {
+ private:
+ lua_State* m_L;
+ int m_tableRef;
+ int m_keyRef;
+
+ public:
+ //--------------------------------------------------------------------------
+ /**
+ Construct a Proxy from a table value.
+
+ The table is in the registry, and the key is at the top of the stack.
+ The key is popped off the stack.
+ */
+ Proxy (lua_State* L, int tableRef)
+ : m_L (L)
+ , m_tableRef (tableRef)
+ , m_keyRef (luaL_ref (L, LUA_REGISTRYINDEX))
+ {
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ Create a Proxy via copy constructor.
+
+ It is best to avoid code paths that invoke this, because it creates
+ an extra temporary Lua reference. Typically this is done by passing
+ the Proxy parameter as a `const` reference.
+ */
+ Proxy (Proxy const& other)
+ : m_L (other.m_L)
+ , m_tableRef (other.m_tableRef)
+ {
+ // If this assert goes off it means code is taking this path,
+ // which is better avoided.
+ //
+ assert (0);
+
+ lua_rawgeti (m_L, LUA_REGISTRYINDEX, other.m_keyRef);
+ m_keyRef = luaL_ref (m_L, LUA_REGISTRYINDEX);
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ Destroy the proxy.
+
+ This does not destroy the table value.
+ */
+ ~Proxy ()
+ {
+ luaL_unref (m_L, LUA_REGISTRYINDEX, m_keyRef);
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ Return a reference to the table value.
+ */
+ int createRef () const
+ {
+ push (m_L);
+ return luaL_ref (m_L, LUA_REGISTRYINDEX);
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ Assign a new value to this table key.
+
+ This may invoke metamethods.
+ */
+ template <class T>
+ Proxy& operator= (T v)
+ {
+ StackPop p (m_L, 1);
+ lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_tableRef);
+ lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_keyRef);
+ Stack <T>::push (m_L, v);
+ lua_rawset (m_L, -3);
+ return *this;
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ Assign a new value to this table key.
+
+ The assignment is raw, no metamethods are invoked.
+ */
+ template <class T>
+ Proxy& rawset (T v)
+ {
+ StackPop p (m_L, 1);
+ lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_tableRef);
+ lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_keyRef);
+ Stack <T>::push (m_L, v);
+ lua_settable (m_L, -3);
+ return *this;
+ }
+
+ //==========================================================================
+ //
+ // This group of member functions mirrors the member functions in LuaRef.
+
+ /** Retrieve the lua_State associated with the table value.
+ */
+ lua_State* state () const
+ {
+ return m_L;
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ Push the value onto the Lua stack.
+ */
+ void push (lua_State* L) const
+ {
+ assert (equalstates (L, m_L));
+ lua_rawgeti (L, LUA_REGISTRYINDEX, m_tableRef);
+ lua_rawgeti (L, LUA_REGISTRYINDEX, m_keyRef);
+ lua_gettable (L, -2);
+ lua_remove (L, -2); // remove the table
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ Determine the object type.
+
+ The return values are the same as for `lua_type`.
+ */
+ int type () const
+ {
+ int result;
+ push (m_L);
+ result = lua_type (m_L, -1);
+ lua_pop (m_L, 1);
+ return result;
+ }
+
+ inline bool isNil () const { return type () == LUA_TNIL; }
+ inline bool isNumber () const { return type () == LUA_TNUMBER; }
+ inline bool isString () const { return type () == LUA_TSTRING; }
+ inline bool isTable () const { return type () == LUA_TTABLE; }
+ inline bool isFunction () const { return type () == LUA_TFUNCTION; }
+ inline bool isUserdata () const { return type () == LUA_TUSERDATA; }
+ inline bool isThread () const { return type () == LUA_TTHREAD; }
+ inline bool isLightUserdata () const { return type () == LUA_TLIGHTUSERDATA; }
+
+ //--------------------------------------------------------------------------
+ /**
+ Perform an explicit conversion.
+ */
+ template <class T>
+ T cast () const
+ {
+ StackPop p (m_L, 1);
+ push (m_L);
+
+ // lua_gettop is used because Userdata::getClass() doesn't handle
+ // negative stack indexes.
+ //
+ return Stack <T>::get (m_L, lua_gettop (m_L));
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ Universal implicit conversion operator.
+
+ NOTE: Visual Studio 2010 and 2012 have a bug where this function
+ is not used. See:
+
+ http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/e30b2664-a92d-445c-9db2-e8e0fbde2014
+ https://connect.microsoft.com/VisualStudio/feedback/details/771509/correct-code-doesnt-compile
+
+ // This code snippet fails to compile in vs2010,vs2012
+ struct S {
+ template <class T> inline operator T () const { return T (); }
+ };
+ int main () {
+ S () || false;
+ return 0;
+ }
+ */
+ template <class T>
+ inline operator T () const
+ {
+ return cast <T> ();
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ Universal comparison operators.
+ */
+ /** @{ */
+ template <class T>
+ bool operator== (T rhs) const
+ {
+ StackPop p (m_L, 2);
+ push (m_L);
+ Stack <T>::push (m_L, rhs);
+ return lua_compare (m_L, -2, -1, LUA_OPEQ) == 1;
+ }
+
+ template <class T>
+ bool operator< (T rhs) const
+ {
+ StackPop p (m_L, 2);
+ push (m_L);
+ Stack <T>::push (m_L, rhs);
+ return lua_compare (m_L, -2, -1, LUA_OPLT) == 1;
+ }
+
+ template <class T>
+ bool operator<= (T rhs) const
+ {
+ StackPop p (m_L, 2);
+ push (m_L);
+ Stack <T>::push (m_L, rhs);
+ return lua_compare (m_L, -2, -1, LUA_OPLE) == 1;
+ }
+
+ template <class T>
+ bool operator> (T rhs) const
+ {
+ StackPop p (m_L, 2);
+ push (m_L);
+ Stack <T>::push (m_L, rhs);
+ return lua_compare (m_L, -1, -2, LUA_OPLT) == 1;
+ }
+
+ template <class T>
+ bool operator>= (T rhs) const
+ {
+ StackPop p (m_L, 2);
+ push (m_L);
+ Stack <T>::push (m_L, rhs);
+ return lua_compare (m_L, -1, -2, LUA_OPLE) == 1;
+ }
+
+ template <class T>
+ bool rawequal (T rhs) const
+ {
+ StackPop p (m_L, 2);
+ push (m_L);
+ Stack <T>::push (m_L, rhs);
+ return lua_rawequal (m_L, -1, -2) == 1;
+ }
+ /** @} */
+
+ //--------------------------------------------------------------------------
+ /**
+ Access a table value using a key.
+
+ This invokes metamethods.
+ */
+ template <class T>
+ Proxy operator[] (T key) const
+ {
+ return LuaRef (*this) [key];
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ Access a table value using a key.
+
+ The operation is raw, metamethods are not invoked. The result is
+ passed by value and may not be modified.
+ */
+ template <class T>
+ LuaRef rawget (T key) const
+ {
+ StackPop (m_L, 1);
+ push (m_L);
+ Stack <T>::push (m_L, key);
+ lua_rawget (m_L, -2);
+ return LuaRef (m_L, FromStack ());
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ Append a value to the table.
+
+ If the table is a sequence this will add another element to it.
+ */
+ template <class T>
+ void append (T v) const
+ {
+ push (m_L);
+ Stack <T>::push (m_L, v);
+ luaL_ref (m_L, -2);
+ lua_pop (m_L, 1);
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ Call the length operator.
+
+ This is identical to applying the Lua # operator.
+ */
+ int length () const
+ {
+ StackPop p (m_L, 1);
+ push (m_L);
+ return get_length (m_L, -1);
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ Call Lua code.
+
+ These overloads allow Lua code to be called with up to 8 parameters.
+ The return value is provided as a LuaRef (which may be LUA_REFNIL).
+ If an error occurs, a LuaException is thrown.
+ */
+ /** @{ */
+ LuaRef const operator() () const
+ {
+ push (m_L);
+ LuaException::pcall (m_L, 0, 1);
+ return LuaRef (m_L, FromStack ());
+ }
+
+ template <class P1>
+ LuaRef const operator() (P1 p1) const
+ {
+ push (m_L);
+ Stack <P1>::push (m_L, p1);
+ LuaException::pcall (m_L, 1, 1);
+ return LuaRef (m_L, FromStack ());
+ }
+
+ template <class P1, class P2>
+ LuaRef const operator() (P1 p1, P2 p2) const
+ {
+ push (m_L);
+ Stack <P1>::push (m_L, p1);
+ Stack <P2>::push (m_L, p2);
+ LuaException::pcall (m_L, 2, 1);
+ return LuaRef (m_L, FromStack ());
+ }
+
+ template <class P1, class P2, class P3>
+ LuaRef const operator() (P1 p1, P2 p2, P3 p3) const
+ {
+ push (m_L);
+ Stack <P1>::push (m_L, p1);
+ Stack <P2>::push (m_L, p2);
+ Stack <P3>::push (m_L, p3);
+ LuaException::pcall (m_L, 3, 1);
+ return LuaRef (m_L, FromStack ());
+ }
+
+ template <class P1, class P2, class P3, class P4>
+ LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4) const
+ {
+ push (m_L);
+ Stack <P1>::push (m_L, p1);
+ Stack <P2>::push (m_L, p2);
+ Stack <P3>::push (m_L, p3);
+ Stack <P4>::push (m_L, p4);
+ LuaException::pcall (m_L, 4, 1);
+ return LuaRef (m_L, FromStack ());
+ }
+
+ template <class P1, class P2, class P3, class P4, class P5>
+ LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const
+ {
+ push (m_L);
+ Stack <P1>::push (m_L, p1);
+ Stack <P2>::push (m_L, p2);
+ Stack <P3>::push (m_L, p3);
+ Stack <P4>::push (m_L, p4);
+ Stack <P5>::push (m_L, p5);
+ LuaException::pcall (m_L, 5, 1);
+ return LuaRef (m_L, FromStack ());
+ }
+
+ template <class P1, class P2, class P3, class P4, class P5, class P6>
+ LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) const
+ {
+ push (m_L);
+ Stack <P1>::push (m_L, p1);
+ Stack <P2>::push (m_L, p2);
+ Stack <P3>::push (m_L, p3);
+ Stack <P4>::push (m_L, p4);
+ Stack <P5>::push (m_L, p5);
+ Stack <P6>::push (m_L, p6);
+ LuaException::pcall (m_L, 6, 1);
+ return LuaRef (m_L, FromStack ());
+ }
+
+ template <class P1, class P2, class P3, class P4, class P5, class P6, class P7>
+ LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) const
+ {
+ push (m_L);
+ Stack <P1>::push (m_L, p1);
+ Stack <P2>::push (m_L, p2);
+ Stack <P3>::push (m_L, p3);
+ Stack <P4>::push (m_L, p4);
+ Stack <P5>::push (m_L, p5);
+ Stack <P6>::push (m_L, p6);
+ Stack <P7>::push (m_L, p7);
+ LuaException::pcall (m_L, 7, 1);
+ return LuaRef (m_L, FromStack ());
+ }
+
+ template <class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
+ LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) const
+ {
+ push (m_L);
+ Stack <P1>::push (m_L, p1);
+ Stack <P2>::push (m_L, p2);
+ Stack <P3>::push (m_L, p3);
+ Stack <P4>::push (m_L, p4);
+ Stack <P5>::push (m_L, p5);
+ Stack <P6>::push (m_L, p6);
+ Stack <P7>::push (m_L, p7);
+ Stack <P8>::push (m_L, p8);
+ LuaException::pcall (m_L, 8, 1);
+ return LuaRef (m_L, FromStack ());
+ }
+ /** @} */
+
+ //==========================================================================
+ };
+
+private:
+ friend struct Stack <LuaRef>;
+
+ //----------------------------------------------------------------------------
+ /**
+ Type tag for stack construction.
+ */
+ struct FromStack { };
+
+ //----------------------------------------------------------------------------
+ /**
+ Create a reference to an object at the top of the Lua stack and pop it.
+
+ This constructor is private and not invoked directly.
+ Instead, use the `fromStack` function.
+
+ @note The object is popped.
+ */
+ LuaRef (lua_State* L, FromStack)
+ : m_L (L)
+ {
+ m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX);
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ Create a reference to an object on the Lua stack.
+
+ This constructor is private and not invoked directly.
+ Instead, use the `fromStack` function.
+
+ @note The object is not popped.
+ */
+ LuaRef (lua_State* L, int index, FromStack)
+ : m_L (L)
+ {
+ lua_pushvalue (m_L, index);
+ m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX);
+ }
+
+ //----------------------------------------------------------------------------
+
+ // This type of construction is disallowed, since we don't have a `lua_State`.
+ //
+ template <class T>
+ LuaRef (T)
+ {
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ Create a reference to this ref.
+
+ This is used internally.
+ */
+ int createRef () const
+ {
+ if (m_ref != LUA_REFNIL)
+ {
+ push (m_L);
+ return luaL_ref (m_L, LUA_REGISTRYINDEX);
+ }
+ else
+ {
+ return LUA_REFNIL;
+ }
+ }
+
+public:
+ //----------------------------------------------------------------------------
+ /**
+ Create a nil reference.
+
+ The LuaRef may be assigned later.
+ */
+ LuaRef (lua_State* L)
+ : m_L (L)
+ , m_ref (LUA_REFNIL)
+ {
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ Create a reference to a value.
+ */
+ template <class T>
+ LuaRef (lua_State* L, T v)
+ : m_L (L)
+ {
+ Stack <T>::push (m_L, v);
+ m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX);
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ Create a reference to a table value.
+ */
+ LuaRef (Proxy const& v)
+ : m_L (v.state ())
+ , m_ref (v.createRef ())
+ {
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ Create a new reference to an existing reference.
+ */
+ LuaRef (LuaRef const& other)
+ : m_L (other.m_L)
+ , m_ref (other.createRef ())
+ {
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ Destroy a reference.
+
+ The corresponding Lua registry reference will be released.
+
+ @note If the state refers to a thread, it is the responsibility of the
+ caller to ensure that the thread still exists when the LuaRef
+ is destroyed.
+ */
+ ~LuaRef ()
+ {
+ luaL_unref (m_L, LUA_REGISTRYINDEX, m_ref);
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ Return a LuaRef from a stack item.
+
+ The stack item is not popped.
+ */
+ static LuaRef fromStack (lua_State* L, int index)
+ {
+ lua_pushvalue (L, index);
+ return LuaRef (L, FromStack ());
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ Create a new empty table and return a reference to it.
+
+ It is also possible to use the free function `newTable`.
+
+ @see ::getGlobal
+ */
+ static LuaRef newTable (lua_State* L)
+ {
+ lua_newtable (L);
+ return LuaRef (L, FromStack ());
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ Return a reference to a named global.
+
+ It is also possible to use the free function `getGlobal`.
+
+ @see ::getGlobal
+ */
+ static LuaRef getGlobal (lua_State *L, char const* name)
+ {
+ lua_getglobal (L, name);
+ return LuaRef (L, FromStack ());
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ Assign a different value to this LuaRef.
+ */
+ template <class T>
+ LuaRef& operator= (T rhs)
+ {
+ luaL_unref (m_L, LUA_REGISTRYINDEX, m_ref);
+ Stack <T>::push (m_L, rhs);
+ m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX);
+ return *this;
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ Assign another LuaRef to this LuaRef.
+ */
+ LuaRef& operator= (LuaRef const& rhs)
+ {
+ luaL_unref (m_L, LUA_REGISTRYINDEX, m_ref);
+ rhs.push (m_L);
+ m_L = rhs.state ();
+ m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX);
+ return *this;
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ converts to a string using luas tostring function
+ */
+ std::string tostring() const
+ {
+ lua_getglobal (m_L, "tostring");
+ push (m_L);
+ lua_call (m_L, 1, 1);
+ const char* str = lua_tostring(m_L, 1);
+ lua_pop(m_L, 1);
+ return std::string(str);
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ Print a text description of the value to a stream.
+
+ This is used for diagnostics.
+ */
+ void print (std::ostream& os) const
+ {
+ switch (type ())
+ {
+ case LUA_TNIL:
+ os << "nil";
+ break;
+
+ case LUA_TNUMBER:
+ os << cast <lua_Number> ();
+ break;
+
+ case LUA_TBOOLEAN:
+ os << (cast <bool> () ? "true" : "false");
+ break;
+
+ case LUA_TSTRING:
+ os << '"' << cast <std::string> () << '"';
+ break;
+
+ case LUA_TTABLE:
+ os << "table: " << tostring();
+ break;
+
+ case LUA_TFUNCTION:
+ os << "function: " << tostring();
+ break;
+
+ case LUA_TUSERDATA:
+ os << "userdata: " << tostring();
+ break;
+
+ case LUA_TTHREAD:
+ os << "thread: " << tostring();
+ break;
+
+ case LUA_TLIGHTUSERDATA:
+ os << "lightuserdata: " << tostring();
+ break;
+
+ default:
+ os << "unknown";
+ break;
+ }
+ }
+
+ //============================================================================
+ //
+ // This group of member functions is mirrored in Proxy
+ //
+
+ /** Retrieve the lua_State associated with the reference.
+ */
+ lua_State* state () const
+ {
+ return m_L;
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ Place the object onto the Lua stack.
+ */
+ void push (lua_State* L) const
+ {
+ assert (equalstates (L, m_L));
+ lua_rawgeti (L, LUA_REGISTRYINDEX, m_ref);
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ Pop the top of Lua stack and assign the ref to m_ref
+ */
+ void pop (lua_State* L)
+ {
+ assert (equalstates (L, m_L));
+ luaL_unref (m_L, LUA_REGISTRYINDEX, m_ref);
+ m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX);
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ Determine the object type.
+
+ The return values are the same as for `lua_type`.
+ */
+ /** @{ */
+ int type () const
+ {
+ int result;
+ if (m_ref != LUA_REFNIL)
+ {
+ push (m_L);
+ result = lua_type (m_L, -1);
+ lua_pop (m_L, 1);
+ }
+ else
+ {
+ result = LUA_TNIL;
+ }
+
+ return result;
+ }
+
+ // should never happen
+ //inline bool isNone () const { return m_ref == LUA_NOREF; }
+
+ inline bool isNil () const { return type () == LUA_TNIL; }
+ inline bool isNumber () const { return type () == LUA_TNUMBER; }
+ inline bool isString () const { return type () == LUA_TSTRING; }
+ inline bool isTable () const { return type () == LUA_TTABLE; }
+ inline bool isFunction () const { return type () == LUA_TFUNCTION; }
+ inline bool isUserdata () const { return type () == LUA_TUSERDATA; }
+ inline bool isThread () const { return type () == LUA_TTHREAD; }
+ inline bool isLightUserdata () const { return type () == LUA_TLIGHTUSERDATA; }
+ /** @} */
+
+ //----------------------------------------------------------------------------
+ /**
+ Perform an explicit conversion.
+ */
+ template <class T>
+ T cast () const
+ {
+ StackPop p (m_L, 1);
+ push (m_L);
+
+ // lua_gettop is used because Userdata::getClass() doesn't handle
+ // negative stack indexes.
+ //
+ return Stack <T>::get (m_L, lua_gettop (m_L));
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ Universal implicit conversion operator.
+
+ NOTE: Visual Studio 2010 and 2012 have a bug where this function
+ is not used. See:
+
+ http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/e30b2664-a92d-445c-9db2-e8e0fbde2014
+ https://connect.microsoft.com/VisualStudio/feedback/details/771509/correct-code-doesnt-compile
+
+ // This code snippet fails to compile in vs2010,vs2012
+ struct S {
+ template <class T> inline operator T () const { return T (); }
+ };
+ int main () {
+ S () || false;
+ return 0;
+ }
+ */
+ template <class T>
+ inline operator T () const
+ {
+ return cast <T> ();
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ Universal comparison operators.
+ */
+ /** @{ */
+ template <class T>
+ bool operator== (T rhs) const
+ {
+ StackPop p (m_L, 2);
+ push (m_L);
+ Stack <T>::push (m_L, rhs);
+ return lua_compare (m_L, -2, -1, LUA_OPEQ) == 1;
+ }
+
+ template <class T>
+ bool operator< (T rhs) const
+ {
+ StackPop p (m_L, 2);
+ push (m_L);
+ Stack <T>::push (m_L, rhs);
+ return lua_compare (m_L, -2, -1, LUA_OPLT) == 1;
+ }
+
+ template <class T>
+ bool operator<= (T rhs) const
+ {
+ StackPop p (m_L, 2);
+ push (m_L);
+ Stack <T>::push (m_L, rhs);
+ return lua_compare (m_L, -2, -1, LUA_OPLE) == 1;
+ }
+
+ template <class T>
+ bool operator> (T rhs) const
+ {
+ StackPop p (m_L, 2);
+ push (m_L);
+ Stack <T>::push (m_L, rhs);
+ return lua_compare (m_L, -1, -2, LUA_OPLT) == 1;
+ }
+
+ template <class T>
+ bool operator>= (T rhs) const
+ {
+ StackPop p (m_L, 2);
+ push (m_L);
+ Stack <T>::push (m_L, rhs);
+ return lua_compare (m_L, -1, -2, LUA_OPLE) == 1;
+ }
+
+ template <class T>
+ bool rawequal (T rhs) const
+ {
+ StackPop p (m_L, 2);
+ push (m_L);
+ Stack <T>::push (m_L, rhs);
+ return lua_rawequal (m_L, -1, -2) == 1;
+ }
+ /** @} */
+
+ //----------------------------------------------------------------------------
+ /**
+ Append a value to the table.
+
+ If the table is a sequence this will add another element to it.
+ */
+ template <class T>
+ void append (T v) const
+ {
+ push (m_L);
+ Stack <T>::push (m_L, v);
+ luaL_ref (m_L, -2);
+ lua_pop (m_L, 1);
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ Call the length operator.
+
+ This is identical to applying the Lua # operator.
+ */
+ int length () const
+ {
+ StackPop p (m_L, 1);
+ push (m_L);
+ return get_length (m_L, -1);
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ Access a table value using a key.
+
+ This invokes metamethods.
+ */
+ template <class T>
+ Proxy operator[] (T key) const
+ {
+ Stack <T>::push (m_L, key);
+ return Proxy (m_L, m_ref);
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ Call Lua code.
+
+ These overloads allow Lua code to be called with up to 8 parameters.
+ The return value is provided as a LuaRef (which may be LUA_REFNIL).
+ If an error occurs, a LuaException is thrown.
+ */
+ /** @{ */
+ LuaRef const operator() () const
+ {
+ push (m_L);
+ LuaException::pcall (m_L, 0, 1);
+ return LuaRef (m_L, FromStack ());
+ }
+
+ template <class P1>
+ LuaRef const operator() (P1 p1) const
+ {
+ push (m_L);
+ Stack <P1>::push (m_L, p1);
+ LuaException::pcall (m_L, 1, 1);
+ return LuaRef (m_L, FromStack ());
+ }
+
+ template <class P1, class P2>
+ LuaRef const operator() (P1 p1, P2 p2) const
+ {
+ push (m_L);
+ Stack <P1>::push (m_L, p1);
+ Stack <P2>::push (m_L, p2);
+ LuaException::pcall (m_L, 2, 1);
+ return LuaRef (m_L, FromStack ());
+ }
+
+ template <class P1, class P2, class P3>
+ LuaRef const operator() (P1 p1, P2 p2, P3 p3) const
+ {
+ push (m_L);
+ Stack <P1>::push (m_L, p1);
+ Stack <P2>::push (m_L, p2);
+ Stack <P3>::push (m_L, p3);
+ LuaException::pcall (m_L, 3, 1);
+ return LuaRef (m_L, FromStack ());
+ }
+
+ template <class P1, class P2, class P3, class P4>
+ LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4) const
+ {
+ push (m_L);
+ Stack <P1>::push (m_L, p1);
+ Stack <P2>::push (m_L, p2);
+ Stack <P3>::push (m_L, p3);
+ Stack <P4>::push (m_L, p4);
+ LuaException::pcall (m_L, 4, 1);
+ return LuaRef (m_L, FromStack ());
+ }
+
+ template <class P1, class P2, class P3, class P4, class P5>
+ LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const
+ {
+ push (m_L);
+ Stack <P1>::push (m_L, p1);
+ Stack <P2>::push (m_L, p2);
+ Stack <P3>::push (m_L, p3);
+ Stack <P4>::push (m_L, p4);
+ Stack <P5>::push (m_L, p5);
+ LuaException::pcall (m_L, 5, 1);
+ return LuaRef (m_L, FromStack ());
+ }
+
+ template <class P1, class P2, class P3, class P4, class P5, class P6>
+ LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) const
+ {
+ push (m_L);
+ Stack <P1>::push (m_L, p1);
+ Stack <P2>::push (m_L, p2);
+ Stack <P3>::push (m_L, p3);
+ Stack <P4>::push (m_L, p4);
+ Stack <P5>::push (m_L, p5);
+ Stack <P6>::push (m_L, p6);
+ LuaException::pcall (m_L, 6, 1);
+ return LuaRef (m_L, FromStack ());
+ }
+
+ template <class P1, class P2, class P3, class P4, class P5, class P6, class P7>
+ LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) const
+ {
+ push (m_L);
+ Stack <P1>::push (m_L, p1);
+ Stack <P2>::push (m_L, p2);
+ Stack <P3>::push (m_L, p3);
+ Stack <P4>::push (m_L, p4);
+ Stack <P5>::push (m_L, p5);
+ Stack <P6>::push (m_L, p6);
+ Stack <P7>::push (m_L, p7);
+ LuaException::pcall (m_L, 7, 1);
+ return LuaRef (m_L, FromStack ());
+ }
+
+ template <class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
+ LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) const
+ {
+ push (m_L);
+ Stack <P1>::push (m_L, p1);
+ Stack <P2>::push (m_L, p2);
+ Stack <P3>::push (m_L, p3);
+ Stack <P4>::push (m_L, p4);
+ Stack <P5>::push (m_L, p5);
+ Stack <P6>::push (m_L, p6);
+ Stack <P7>::push (m_L, p7);
+ Stack <P8>::push (m_L, p8);
+ LuaException::pcall (m_L, 8, 1);
+ return LuaRef (m_L, FromStack ());
+ }
+ /** @} */
+
+ //============================================================================
+
+private:
+ lua_State* m_L;
+ int m_ref;
+};
+
+//------------------------------------------------------------------------------
+/**
+ Stack specialization for Nil
+*/
+template <>
+struct Stack <Nil>
+{
+public:
+ static inline void push (lua_State* L, Nil)
+ {
+ lua_pushnil (L);
+ }
+};
+
+//------------------------------------------------------------------------------
+/**
+ Stack specialization for LuaRef.
+*/
+template <>
+struct Stack <LuaRef>
+{
+public:
+ // The value is const& to prevent a copy construction.
+ //
+ static inline void push (lua_State* L, LuaRef const& v)
+ {
+ v.push (L);
+ }
+
+ static inline LuaRef get (lua_State* L, int index)
+ {
+ return LuaRef (L, index, LuaRef::FromStack ());
+ }
+};
+
+//------------------------------------------------------------------------------
+/**
+ Stack specialization for Proxy.
+*/
+template <>
+struct Stack <LuaRef::Proxy>
+{
+public:
+ // The value is const& to prevent a copy construction.
+ //
+ static inline void push (lua_State* L, LuaRef::Proxy const& v)
+ {
+ v.push (L);
+ }
+};
+
+//------------------------------------------------------------------------------
+/**
+ Create a reference to a new, empty table.
+
+ This is a syntactic abbreviation for LuaRef::newTable().
+*/
+inline LuaRef newTable (lua_State* L)
+{
+ return LuaRef::newTable (L);
+}
+
+//------------------------------------------------------------------------------
+/**
+ Create a reference to a value in the global table.
+
+ This is a syntactic abbreviation for LuaRef::getGlobal().
+*/
+inline LuaRef getGlobal (lua_State *L, char const* name)
+{
+ return LuaRef::getGlobal (L, name);
+}
+
+//------------------------------------------------------------------------------
+/**
+ Write a LuaRef to a stream.
+
+ This allows LuaRef and table proxies to work with streams.
+*/
+inline std::ostream& operator<< (std::ostream& os, LuaRef const& ref)
+{
+ ref.print (os);
+ return os;
+}
+
+//------------------------------------------------------------------------------
+
+// more C++-like cast syntax
+//
+template<class T>
+inline T LuaRef_cast(LuaRef const& lr)
+{
+ return lr.cast<T>();
+}
diff --git a/libs/lua/LuaBridge/detail/Namespace.h b/libs/lua/LuaBridge/detail/Namespace.h
new file mode 100644
index 0000000000..ff22e6b092
--- /dev/null
+++ b/libs/lua/LuaBridge/detail/Namespace.h
@@ -0,0 +1,1136 @@
+//------------------------------------------------------------------------------
+/*
+ https://github.com/vinniefalco/LuaBridge
+
+ Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
+ Copyright 2007, Nathan Reed
+
+ License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+*/
+//==============================================================================
+
+/** Provides C++ to Lua registration capabilities.
+
+ This class is not instantiated directly, call `getGlobalNamespace` to start
+ the registration process.
+*/
+class Namespace
+{
+private:
+ Namespace& operator= (Namespace const& other);
+
+ lua_State* const L;
+ int mutable m_stackSize;
+
+private:
+ //============================================================================
+ /**
+ Error reporting.
+
+ VF: This function looks handy, why aren't we using it?
+ */
+#if 0
+ static int luaError (lua_State* L, std::string message)
+ {
+ assert (lua_isstring (L, lua_upvalueindex (1)));
+ std::string s;
+
+ // Get information on the caller's caller to format the message,
+ // so the error appears to originate from the Lua source.
+ lua_Debug ar;
+ int result = lua_getstack (L, 2, &ar);
+ if (result != 0)
+ {
+ lua_getinfo (L, "Sl", &ar);
+ s = ar.short_src;
+ if (ar.currentline != -1)
+ {
+ // poor mans int to string to avoid <strstrream>.
+ lua_pushnumber (L, ar.currentline);
+ s = s + ":" + lua_tostring (L, -1) + ": ";
+ lua_pop (L, 1);
+ }
+ }
+
+ s = s + message;
+
+ return luaL_error (L, s.c_str ());
+ }
+#endif
+
+ //----------------------------------------------------------------------------
+ /**
+ Pop the Lua stack.
+ */
+ void pop (int n) const
+ {
+ if (m_stackSize >= n && lua_gettop (L) >= n)
+ {
+ lua_pop (L, n);
+ m_stackSize -= n;
+ }
+ else
+ {
+ throw std::logic_error ("invalid stack");
+ }
+ }
+
+private:
+ /**
+ Factored base to reduce template instantiations.
+ */
+ class ClassBase
+ {
+ private:
+ ClassBase& operator= (ClassBase const& other);
+
+ protected:
+ friend class Namespace;
+
+ lua_State* const L;
+ int mutable m_stackSize;
+
+ protected:
+ //--------------------------------------------------------------------------
+ /**
+ __index metamethod for a class.
+
+ This implements member functions, data members, and property members.
+ Functions are stored in the metatable and const metatable. Data members
+ and property members are in the __propget table.
+
+ If the key is not found, the search proceeds up the hierarchy of base
+ classes.
+ */
+ static int indexMetaMethod (lua_State* L)
+ {
+ int result = 0;
+
+ assert (lua_isuserdata (L, 1)); // warn on security bypass
+ lua_getmetatable (L, 1); // get metatable for object
+ for (;;)
+ {
+ lua_pushvalue (L, 2); // push key arg2
+ lua_rawget (L, -2); // lookup key in metatable
+ if (lua_iscfunction (L, -1)) // ensure its a cfunction
+ {
+ lua_remove (L, -2); // remove metatable
+ result = 1;
+ break;
+ }
+ else if (lua_isnil (L, -1))
+ {
+ lua_pop (L, 1);
+ }
+ else
+ {
+ lua_pop (L, 2);
+ throw std::logic_error ("not a cfunction");
+ }
+
+ rawgetfield (L, -1, "__propget"); // get __propget table
+ if (lua_istable (L, -1)) // ensure it is a table
+ {
+ lua_pushvalue (L, 2); // push key arg2
+ lua_rawget (L, -2); // lookup key in __propget
+ lua_remove (L, -2); // remove __propget
+ if (lua_iscfunction (L, -1)) // ensure its a cfunction
+ {
+ lua_remove (L, -2); // remove metatable
+ lua_pushvalue (L, 1); // push class arg1
+ lua_call (L, 1, 1);
+ result = 1;
+ break;
+ }
+ else if (lua_isnil (L, -1))
+ {
+ lua_pop (L, 1);
+ }
+ else
+ {
+ lua_pop (L, 2);
+
+ // We only put cfunctions into __propget.
+ throw std::logic_error ("not a cfunction");
+ }
+ }
+ else
+ {
+ lua_pop (L, 2);
+
+ // __propget is missing, or not a table.
+ throw std::logic_error ("missing __propget table");
+ }
+
+ // Repeat the lookup in the __parent metafield,
+ // or return nil if the field doesn't exist.
+ rawgetfield (L, -1, "__parent");
+ if (lua_istable (L, -1))
+ {
+ // Remove metatable and repeat the search in __parent.
+ lua_remove (L, -2);
+ }
+ else if (lua_isnil (L, -1))
+ {
+ result = 1;
+ break;
+ }
+ else
+ {
+ lua_pop (L, 2);
+
+ throw std::logic_error ("__parent is not a table");
+ }
+ }
+
+ return result;
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ __newindex metamethod for classes.
+
+ This supports writable variables and properties on class objects. The
+ corresponding object is passed in the first parameter to the set function.
+ */
+ static int newindexMetaMethod (lua_State* L)
+ {
+ int result = 0;
+
+ lua_getmetatable (L, 1);
+
+ for (;;)
+ {
+ // Check __propset
+ rawgetfield (L, -1, "__propset");
+ if (!lua_isnil (L, -1))
+ {
+ lua_pushvalue (L, 2);
+ lua_rawget (L, -2);
+ if (!lua_isnil (L, -1))
+ {
+ // found it, call the setFunction.
+ assert (lua_isfunction (L, -1));
+ lua_pushvalue (L, 1);
+ lua_pushvalue (L, 3);
+ lua_call (L, 2, 0);
+ result = 0;
+ break;
+ }
+ lua_pop (L, 1);
+ }
+ lua_pop (L, 1);
+
+ // Repeat the lookup in the __parent metafield.
+ rawgetfield (L, -1, "__parent");
+ if (lua_isnil (L, -1))
+ {
+ // Either the property or __parent must exist.
+ result = luaL_error (L,
+ "no member named '%s'", lua_tostring (L, 2));
+ }
+ lua_remove (L, -2);
+ }
+
+ return result;
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ Create the const table.
+ */
+ void createConstTable (char const* name)
+ {
+ lua_newtable (L);
+ lua_pushvalue (L, -1);
+ lua_setmetatable (L, -2);
+ lua_pushboolean (L, 1);
+ lua_rawsetp (L, -2, getIdentityKey ());
+ lua_pushstring (L, (std::string ("const ") + name).c_str ());
+ rawsetfield (L, -2, "__type");
+ lua_pushcfunction (L, &indexMetaMethod);
+ rawsetfield (L, -2, "__index");
+ lua_pushcfunction (L, &newindexMetaMethod);
+ rawsetfield (L, -2, "__newindex");
+ lua_newtable (L);
+ rawsetfield (L, -2, "__propget");
+
+ if (Security::hideMetatables ())
+ {
+ lua_pushnil (L);
+ rawsetfield (L, -2, "__metatable");
+ }
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ Create the class table.
+
+ The Lua stack should have the const table on top.
+ */
+ void createClassTable (char const* name)
+ {
+ lua_newtable (L);
+ lua_pushvalue (L, -1);
+ lua_setmetatable (L, -2);
+ lua_pushboolean (L, 1);
+ lua_rawsetp (L, -2, getIdentityKey ());
+ lua_pushstring (L, name);
+ rawsetfield (L, -2, "__type");
+ lua_pushcfunction (L, &indexMetaMethod);
+ rawsetfield (L, -2, "__index");
+ lua_pushcfunction (L, &newindexMetaMethod);
+ rawsetfield (L, -2, "__newindex");
+ lua_newtable (L);
+ rawsetfield (L, -2, "__propget");
+ lua_newtable (L);
+ rawsetfield (L, -2, "__propset");
+
+ lua_pushvalue (L, -2);
+ rawsetfield (L, -2, "__const"); // point to const table
+
+ lua_pushvalue (L, -1);
+ rawsetfield (L, -3, "__class"); // point const table to class table
+
+ if (Security::hideMetatables ())
+ {
+ lua_pushnil (L);
+ rawsetfield (L, -2, "__metatable");
+ }
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ Create the static table.
+
+ The Lua stack should have:
+ -1 class table
+ -2 const table
+ -3 enclosing namespace
+ */
+ void createStaticTable (char const* name)
+ {
+ lua_newtable (L);
+ lua_newtable (L);
+ lua_pushvalue (L, -1);
+ lua_setmetatable (L, -3);
+ lua_insert (L, -2);
+ rawsetfield (L, -5, name);
+
+#if 0
+ lua_pushlightuserdata (L, this);
+ lua_pushcclosure (L, &tostringMetaMethod, 1);
+ rawsetfield (L, -2, "__tostring");
+#endif
+ lua_pushcfunction (L, &CFunc::indexMetaMethod);
+ rawsetfield (L, -2, "__index");
+ lua_pushcfunction (L, &CFunc::newindexMetaMethod);
+ rawsetfield (L, -2, "__newindex");
+ lua_newtable (L);
+ rawsetfield (L, -2, "__propget");
+ lua_newtable (L);
+ rawsetfield (L, -2, "__propset");
+
+ lua_pushvalue (L, -2);
+ rawsetfield (L, -2, "__class"); // point to class table
+
+ if (Security::hideMetatables ())
+ {
+ lua_pushnil (L);
+ rawsetfield (L, -2, "__metatable");
+ }
+ }
+
+ //==========================================================================
+ /**
+ lua_CFunction to construct a class object wrapped in a container.
+ */
+ template <class Params, class C>
+ static int ctorContainerProxy (lua_State* L)
+ {
+ typedef typename ContainerTraits <C>::Type T;
+ ArgList <Params, 2> args (L);
+ T* const p = Constructor <T, Params>::call (args);
+ UserdataSharedHelper <C, false>::push (L, p);
+ return 1;
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ lua_CFunction to construct a class object in-place in the userdata.
+ */
+ template <class Params, class T>
+ static int ctorPlacementProxy (lua_State* L)
+ {
+ ArgList <Params, 2> args (L);
+ Constructor <T, Params>::call (UserdataValue <T>::place (L), args);
+ return 1;
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ Pop the Lua stack.
+ */
+ void pop (int n) const
+ {
+ if (m_stackSize >= n && lua_gettop (L) >= n)
+ {
+ lua_pop (L, n);
+ m_stackSize -= n;
+ }
+ else
+ {
+ throw std::logic_error ("invalid stack");
+ }
+ }
+
+ public:
+ //--------------------------------------------------------------------------
+ explicit ClassBase (lua_State* L_)
+ : L (L_)
+ , m_stackSize (0)
+ {
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ Copy Constructor.
+ */
+ ClassBase (ClassBase const& other)
+ : L (other.L)
+ , m_stackSize (0)
+ {
+ m_stackSize = other.m_stackSize;
+ other.m_stackSize = 0;
+ }
+
+ ~ClassBase ()
+ {
+ pop (m_stackSize);
+ }
+ };
+
+ //============================================================================
+ //
+ // Class
+ //
+ //============================================================================
+ /**
+ Provides a class registration in a lua_State.
+
+ After contstruction the Lua stack holds these objects:
+ -1 static table
+ -2 class table
+ -3 const table
+ -4 (enclosing namespace)
+ */
+ template <class T>
+ class Class : public ClassBase
+ {
+ public:
+ //==========================================================================
+ /**
+ Register a new class or add to an existing class registration.
+ */
+ Class (char const* name, Namespace const* parent) : ClassBase (parent->L)
+ {
+ m_stackSize = parent->m_stackSize + 3;
+ parent->m_stackSize = 0;
+
+ assert (lua_istable (L, -1));
+ rawgetfield (L, -1, name);
+
+ if (lua_isnil (L, -1))
+ {
+ 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 ());
+ }
+ else
+ {
+ rawgetfield (L, -1, "__class");
+ rawgetfield (L, -1, "__const");
+
+ // Reverse the top 3 stack elements
+ lua_insert (L, -3);
+ lua_insert (L, -2);
+ }
+ }
+
+ //==========================================================================
+ /**
+ Derive a new class.
+ */
+ Class (char const* name, Namespace const* parent, void const* const staticKey)
+ : ClassBase (parent->L)
+ {
+ m_stackSize = parent->m_stackSize + 3;
+ parent->m_stackSize = 0;
+
+ assert (lua_istable (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);
+
+ lua_rawgetp (L, LUA_REGISTRYINDEX, staticKey);
+ assert (lua_istable (L, -1));
+ rawgetfield (L, -1, "__class");
+ assert (lua_istable (L, -1));
+ rawgetfield (L, -1, "__const");
+ assert (lua_istable (L, -1));
+
+ rawsetfield (L, -6, "__parent");
+ rawsetfield (L, -4, "__parent");
+ rawsetfield (L, -2, "__parent");
+
+ 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 ());
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ Continue registration in the enclosing namespace.
+ */
+ Namespace endClass ()
+ {
+ return Namespace (this);
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ Add or replace a static data member.
+ */
+ template <class U>
+ Class <T>& addStaticData (char const* name, U* pu, bool isWritable = true)
+ {
+ assert (lua_istable (L, -1));
+
+ rawgetfield (L, -1, "__propget");
+ assert (lua_istable (L, -1));
+ lua_pushlightuserdata (L, pu);
+ lua_pushcclosure (L, &CFunc::getVariable <U>, 1);
+ rawsetfield (L, -2, name);
+ lua_pop (L, 1);
+
+ rawgetfield (L, -1, "__propset");
+ assert (lua_istable (L, -1));
+ if (isWritable)
+ {
+ lua_pushlightuserdata (L, pu);
+ lua_pushcclosure (L, &CFunc::setVariable <U>, 1);
+ }
+ else
+ {
+ lua_pushstring (L, name);
+ lua_pushcclosure (L, &CFunc::readOnlyError, 1);
+ }
+ rawsetfield (L, -2, name);
+ lua_pop (L, 1);
+
+ return *this;
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ Add or replace a static property member.
+
+ If the set function is null, the property is read-only.
+ */
+ template <class U>
+ Class <T>& addStaticProperty (char const* name, U (*get)(), void (*set)(U) = 0)
+ {
+ typedef U (*get_t)();
+ typedef void (*set_t)(U);
+
+ assert (lua_istable (L, -1));
+
+ rawgetfield (L, -1, "__propget");
+ assert (lua_istable (L, -1));
+ new (lua_newuserdata (L, sizeof (get))) get_t (get);
+ lua_pushcclosure (L, &CFunc::Call <U (*) (void)>::f, 1);
+ rawsetfield (L, -2, name);
+ lua_pop (L, 1);
+
+ rawgetfield (L, -1, "__propset");
+ assert (lua_istable (L, -1));
+ if (set != 0)
+ {
+ new (lua_newuserdata (L, sizeof (set))) set_t (set);
+ lua_pushcclosure (L, &CFunc::Call <void (*) (U)>::f, 1);
+ }
+ else
+ {
+ lua_pushstring (L, name);
+ lua_pushcclosure (L, &CFunc::readOnlyError, 1);
+ }
+ rawsetfield (L, -2, name);
+ lua_pop (L, 1);
+
+ return *this;
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ Add or replace a static member function.
+ */
+ template <class FP>
+ Class <T>& addStaticFunction (char const* name, FP const fp)
+ {
+ new (lua_newuserdata (L, sizeof (fp))) FP (fp);
+ lua_pushcclosure (L, &CFunc::Call <FP>::f, 1);
+ rawsetfield (L, -2, name);
+
+ return *this;
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ Add or replace a lua_CFunction.
+ */
+ Class <T>& addStaticCFunction (char const* name, int (*const fp)(lua_State*))
+ {
+ lua_pushcfunction (L, fp);
+ rawsetfield (L, -2, name);
+ return *this;
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ Add or replace a data member.
+ */
+ template <class U>
+ Class <T>& addData (char const* name, const U T::* mp, bool isWritable = true)
+ {
+ typedef const U T::*mp_t;
+
+ // Add to __propget in class and const tables.
+ {
+ rawgetfield (L, -2, "__propget");
+ rawgetfield (L, -4, "__propget");
+ new (lua_newuserdata (L, sizeof (mp_t))) mp_t (mp);
+ lua_pushcclosure (L, &CFunc::getProperty <T,U>, 1);
+ lua_pushvalue (L, -1);
+ rawsetfield (L, -4, name);
+ rawsetfield (L, -2, name);
+ lua_pop (L, 2);
+ }
+
+ if (isWritable)
+ {
+ // Add to __propset in class table.
+ rawgetfield (L, -2, "__propset");
+ assert (lua_istable (L, -1));
+ new (lua_newuserdata (L, sizeof (mp_t))) mp_t (mp);
+ lua_pushcclosure (L, &CFunc::setProperty <T,U>, 1);
+ rawsetfield (L, -2, name);
+ lua_pop (L, 1);
+ }
+
+ return *this;
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ Add or replace a property member.
+ */
+ template <class TG, class TS>
+ Class <T>& addProperty (char const* name, TG (T::* get) () const, void (T::* set) (TS))
+ {
+ // Add to __propget in class and const tables.
+ {
+ rawgetfield (L, -2, "__propget");
+ rawgetfield (L, -4, "__propget");
+ typedef TG (T::*get_t) () const;
+ new (lua_newuserdata (L, sizeof (get_t))) get_t (get);
+ lua_pushcclosure (L, &CFunc::CallConstMember <get_t>::f, 1);
+ lua_pushvalue (L, -1);
+ rawsetfield (L, -4, name);
+ rawsetfield (L, -2, name);
+ lua_pop (L, 2);
+ }
+
+ {
+ // Add to __propset in class table.
+ rawgetfield (L, -2, "__propset");
+ assert (lua_istable (L, -1));
+ typedef void (T::* set_t) (TS);
+ new (lua_newuserdata (L, sizeof (set_t))) set_t (set);
+ lua_pushcclosure (L, &CFunc::CallMember <set_t>::f, 1);
+ rawsetfield (L, -2, name);
+ lua_pop (L, 1);
+ }
+
+ return *this;
+ }
+
+ // read-only
+ template <class TG>
+ Class <T>& addProperty (char const* name, TG (T::* get) () const)
+ {
+ // Add to __propget in class and const tables.
+ rawgetfield (L, -2, "__propget");
+ rawgetfield (L, -4, "__propget");
+ typedef TG (T::*get_t) () const;
+ new (lua_newuserdata (L, sizeof (get_t))) get_t (get);
+ lua_pushcclosure (L, &CFunc::CallConstMember <get_t>::f, 1);
+ lua_pushvalue (L, -1);
+ rawsetfield (L, -4, name);
+ rawsetfield (L, -2, name);
+ lua_pop (L, 2);
+
+ return *this;
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ Add or replace a property member, by proxy.
+
+ When a class is closed for modification and does not provide (or cannot
+ provide) the function signatures necessary to implement get or set for
+ a property, this will allow non-member functions act as proxies.
+
+ Both the get and the set functions require a T const* and T* in the first
+ argument respectively.
+ */
+ template <class TG, class TS>
+ Class <T>& addProperty (char const* name, TG (*get) (T const*), void (*set) (T*, TS))
+ {
+ // Add to __propget in class and const tables.
+ {
+ rawgetfield (L, -2, "__propget");
+ rawgetfield (L, -4, "__propget");
+ typedef TG (*get_t) (T const*);
+ new (lua_newuserdata (L, sizeof (get_t))) get_t (get);
+ lua_pushcclosure (L, &CFunc::Call <get_t>::f, 1);
+ lua_pushvalue (L, -1);
+ rawsetfield (L, -4, name);
+ rawsetfield (L, -2, name);
+ lua_pop (L, 2);
+ }
+
+ if (set != 0)
+ {
+ // Add to __propset in class table.
+ rawgetfield (L, -2, "__propset");
+ assert (lua_istable (L, -1));
+ typedef void (*set_t) (T*, TS);
+ new (lua_newuserdata (L, sizeof (set_t))) set_t (set);
+ lua_pushcclosure (L, &CFunc::Call <set_t>::f, 1);
+ rawsetfield (L, -2, name);
+ lua_pop (L, 1);
+ }
+
+ return *this;
+ }
+
+ // read-only
+ template <class TG, class TS>
+ Class <T>& addProperty (char const* name, TG (*get) (T const*))
+ {
+ // Add to __propget in class and const tables.
+ rawgetfield (L, -2, "__propget");
+ rawgetfield (L, -4, "__propget");
+ typedef TG (*get_t) (T const*);
+ new (lua_newuserdata (L, sizeof (get_t))) get_t (get);
+ lua_pushcclosure (L, &CFunc::Call <get_t>::f, 1);
+ lua_pushvalue (L, -1);
+ rawsetfield (L, -4, name);
+ rawsetfield (L, -2, name);
+ lua_pop (L, 2);
+
+ return *this;
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ Add or replace a member function.
+ */
+ template <class MemFn>
+ Class <T>& addFunction (char const* name, MemFn mf)
+ {
+ CFunc::CallMemberFunctionHelper <MemFn, FuncTraits <MemFn>::isConstMemberFunction>::add (L, name, mf);
+ return *this;
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ Add or replace a member lua_CFunction.
+ */
+ Class <T>& addCFunction (char const* name, int (T::*mfp)(lua_State*))
+ {
+ typedef int (T::*MFP)(lua_State*);
+ assert (lua_istable (L, -1));
+ new (lua_newuserdata (L, sizeof (mfp))) MFP (mfp);
+ lua_pushcclosure (L, &CFunc::CallMemberCFunction <T>::f, 1);
+ rawsetfield (L, -3, name); // class table
+
+ return *this;
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ Add or replace a const member lua_CFunction.
+ */
+ Class <T>& addCFunction (char const* name, int (T::*mfp)(lua_State*) const)
+ {
+ typedef int (T::*MFP)(lua_State*) const;
+ assert (lua_istable (L, -1));
+ new (lua_newuserdata (L, sizeof (mfp))) MFP (mfp);
+ lua_pushcclosure (L, &CFunc::CallConstMemberCFunction <T>::f, 1);
+ lua_pushvalue (L, -1);
+ rawsetfield (L, -5, name); // const table
+ rawsetfield (L, -3, name); // class table
+
+ return *this;
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ Add or replace a primary Constructor.
+
+ The primary Constructor is invoked when calling the class type table
+ like a function.
+
+ The template parameter should be a function pointer type that matches
+ the desired Constructor (since you can't take the address of a Constructor
+ and pass it as an argument).
+ */
+ template <class MemFn, class C>
+ Class <T>& addConstructor ()
+ {
+ lua_pushcclosure (L,
+ &ctorContainerProxy <typename FuncTraits <MemFn>::Params, C>, 0);
+ rawsetfield(L, -2, "__call");
+
+ return *this;
+ }
+
+ template <class MemFn>
+ Class <T>& addConstructor ()
+ {
+ lua_pushcclosure (L,
+ &ctorPlacementProxy <typename FuncTraits <MemFn>::Params, T>, 0);
+ rawsetfield(L, -2, "__call");
+
+ return *this;
+ }
+ };
+
+private:
+ //----------------------------------------------------------------------------
+ /**
+ Open the global namespace for registrations.
+ */
+ explicit Namespace (lua_State* L_)
+ : L (L_)
+ , m_stackSize (0)
+ {
+ lua_getglobal (L, "_G");
+ ++m_stackSize;
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ Open a namespace for registrations.
+
+ The namespace is created if it doesn't already exist.
+ The parent namespace is at the top of the Lua stack.
+ */
+ Namespace (char const* name, Namespace const* parent)
+ : L (parent->L)
+ , m_stackSize (0)
+ {
+ m_stackSize = parent->m_stackSize + 1;
+ parent->m_stackSize = 0;
+
+ assert (lua_istable (L, -1));
+ rawgetfield (L, -1, name);
+ if (lua_isnil (L, -1))
+ {
+ lua_pop (L, 1);
+
+ lua_newtable (L);
+ lua_pushvalue (L, -1);
+ lua_setmetatable (L, -2);
+ lua_pushcfunction (L, &CFunc::indexMetaMethod);
+ rawsetfield (L, -2, "__index");
+ lua_pushcfunction (L, &CFunc::newindexMetaMethod);
+ rawsetfield (L, -2, "__newindex");
+ lua_newtable (L);
+ rawsetfield (L, -2, "__propget");
+ lua_newtable (L);
+ rawsetfield (L, -2, "__propset");
+ lua_pushvalue (L, -1);
+ rawsetfield (L, -3, name);
+#if 0
+ lua_pushcfunction (L, &tostringMetaMethod);
+ rawsetfield (L, -2, "__tostring");
+#endif
+ }
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ Creates a continued registration from a child namespace.
+ */
+ explicit Namespace (Namespace const* child)
+ : L (child->L)
+ , m_stackSize (0)
+ {
+ m_stackSize = child->m_stackSize - 1;
+ child->m_stackSize = 1;
+ child->pop (1);
+
+ // It is not necessary or valid to call
+ // endNamespace() for the global namespace!
+ //
+ assert (m_stackSize != 0);
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ Creates a continued registration from a child class.
+ */
+ explicit Namespace (ClassBase const* child)
+ : L (child->L)
+ , m_stackSize (0)
+ {
+ m_stackSize = child->m_stackSize - 3;
+ child->m_stackSize = 3;
+ child->pop (3);
+ }
+
+public:
+ //----------------------------------------------------------------------------
+ /**
+ Copy Constructor.
+
+ Ownership of the stack is transferred to the new object. This happens
+ when the compiler emits temporaries to hold these objects while chaining
+ registrations across namespaces.
+ */
+ Namespace (Namespace const& other) : L (other.L)
+ {
+ m_stackSize = other.m_stackSize;
+ other.m_stackSize = 0;
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ Closes this namespace registration.
+ */
+ ~Namespace ()
+ {
+ pop (m_stackSize);
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ Open the global namespace.
+ */
+ static Namespace getGlobalNamespace (lua_State* L)
+ {
+ return Namespace (L);
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ Open a new or existing namespace for registrations.
+ */
+ Namespace beginNamespace (char const* name)
+ {
+ return Namespace (name, this);
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ Continue namespace registration in the parent.
+
+ Do not use this on the global namespace.
+ */
+ Namespace endNamespace ()
+ {
+ return Namespace (this);
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ Add or replace a variable.
+ */
+ template <class T>
+ Namespace& addVariable (char const* name, T* pt, bool isWritable = true)
+ {
+ assert (lua_istable (L, -1));
+
+ rawgetfield (L, -1, "__propget");
+ assert (lua_istable (L, -1));
+ lua_pushlightuserdata (L, pt);
+ lua_pushcclosure (L, &CFunc::getVariable <T>, 1);
+ rawsetfield (L, -2, name);
+ lua_pop (L, 1);
+
+ rawgetfield (L, -1, "__propset");
+ assert (lua_istable (L, -1));
+ if (isWritable)
+ {
+ lua_pushlightuserdata (L, pt);
+ lua_pushcclosure (L, &CFunc::setVariable <T>, 1);
+ }
+ else
+ {
+ 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.
+
+ If the set function is omitted or null, the property is read-only.
+ */
+ template <class TG, class TS>
+ Namespace& addProperty (char const* name, TG (*get) (), void (*set)(TS) = 0)
+ {
+ assert (lua_istable (L, -1));
+
+ rawgetfield (L, -1, "__propget");
+ assert (lua_istable (L, -1));
+ typedef TG (*get_t) ();
+ new (lua_newuserdata (L, sizeof (get_t))) get_t (get);
+ lua_pushcclosure (L, &CFunc::Call <TG (*) (void)>::f, 1);
+ rawsetfield (L, -2, name);
+ lua_pop (L, 1);
+
+ rawgetfield (L, -1, "__propset");
+ assert (lua_istable (L, -1));
+ if (set != 0)
+ {
+ typedef void (*set_t) (TS);
+ new (lua_newuserdata (L, sizeof (set_t))) set_t (set);
+ lua_pushcclosure (L, &CFunc::Call <void (*) (TS)>::f, 1);
+ }
+ else
+ {
+ lua_pushstring (L, name);
+ lua_pushcclosure (L, &CFunc::readOnlyError, 1);
+ }
+ rawsetfield (L, -2, name);
+ lua_pop (L, 1);
+
+ return *this;
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ Add or replace a free function.
+ */
+ template <class FP>
+ Namespace& addFunction (char const* name, FP const fp)
+ {
+ assert (lua_istable (L, -1));
+
+ new (lua_newuserdata (L, sizeof (fp))) FP (fp);
+ lua_pushcclosure (L, &CFunc::Call <FP>::f, 1);
+ rawsetfield (L, -2, name);
+
+ return *this;
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ Add or replace a lua_CFunction.
+ */
+ Namespace& addCFunction (char const* name, int (*const fp)(lua_State*))
+ {
+ lua_pushcfunction (L, fp);
+ rawsetfield (L, -2, name);
+
+ return *this;
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ Open a new or existing class for registrations.
+ */
+ template <class T>
+ Class <T> beginClass (char const* name)
+ {
+ return Class <T> (name, this);
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ Derive a new class for registrations.
+
+ To continue registrations for the class later, use beginClass().
+ Do not call deriveClass() again.
+ */
+ template <class T, class U>
+ Class <T> deriveClass (char const* name)
+ {
+ return Class <T> (name, this, ClassInfo <U>::getStaticKey ());
+ }
+};
+
+//------------------------------------------------------------------------------
+/**
+ Retrieve the global namespace.
+
+ It is recommended to put your namespace inside the global namespace, and
+ then add your classes and functions to it, rather than adding many classes
+ and functions directly to the global namespace.
+*/
+inline Namespace getGlobalNamespace (lua_State* L)
+{
+ return Namespace::getGlobalNamespace (L);
+}
diff --git a/libs/lua/LuaBridge/detail/Stack.h b/libs/lua/LuaBridge/detail/Stack.h
new file mode 100644
index 0000000000..1a0aae7c29
--- /dev/null
+++ b/libs/lua/LuaBridge/detail/Stack.h
@@ -0,0 +1,469 @@
+//------------------------------------------------------------------------------
+/*
+ https://github.com/vinniefalco/LuaBridge
+
+ Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
+ Copyright 2007, Nathan Reed
+
+ License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+*/
+//==============================================================================
+
+//------------------------------------------------------------------------------
+/**
+ Receive the lua_State* as an argument.
+*/
+template <>
+struct Stack <lua_State*>
+{
+ static lua_State* get (lua_State* L, int)
+ {
+ return L;
+ }
+};
+
+//------------------------------------------------------------------------------
+/**
+ Push a lua_CFunction.
+*/
+template <>
+struct Stack <lua_CFunction>
+{
+ static void push (lua_State* L, lua_CFunction f)
+ {
+ lua_pushcfunction (L, f);
+ }
+
+ static lua_CFunction get (lua_State* L, int index)
+ {
+ return lua_tocfunction (L, index);
+ }
+};
+
+//------------------------------------------------------------------------------
+/**
+ Stack specialization for `int`.
+*/
+template <>
+struct Stack <int>
+{
+ static inline void push (lua_State* L, int value)
+ {
+ lua_pushinteger (L, static_cast <lua_Integer> (value));
+ }
+
+ static inline int get (lua_State* L, int index)
+ {
+ return static_cast <int> (luaL_checkinteger (L, index));
+ }
+};
+
+template <>
+struct Stack <int const&>
+{
+ static inline void push (lua_State* L, int value)
+ {
+ lua_pushnumber (L, static_cast <lua_Number> (value));
+ }
+
+ static inline int get (lua_State* L, int index)
+ {
+ return static_cast <int > (luaL_checknumber (L, index));
+ }
+};
+//------------------------------------------------------------------------------
+/**
+ Stack specialization for `unsigned int`.
+*/
+template <>
+struct Stack <unsigned int>
+{
+ static inline void push (lua_State* L, unsigned int value)
+ {
+ lua_pushinteger (L, static_cast <lua_Integer> (value));
+ }
+
+ static inline unsigned int get (lua_State* L, int index)
+ {
+ return static_cast <unsigned int> (luaL_checkinteger (L, index));
+ }
+};
+
+template <>
+struct Stack <unsigned int const&>
+{
+ static inline void push (lua_State* L, unsigned int value)
+ {
+ lua_pushnumber (L, static_cast <lua_Number> (value));
+ }
+
+ static inline unsigned int get (lua_State* L, int index)
+ {
+ return static_cast <unsigned int > (luaL_checknumber (L, index));
+ }
+};
+
+//------------------------------------------------------------------------------
+/**
+ Stack specialization for `unsigned char`.
+*/
+template <>
+struct Stack <unsigned char>
+{
+ static inline void push (lua_State* L, unsigned char value)
+ {
+ lua_pushinteger (L, static_cast <lua_Integer> (value));
+ }
+
+ static inline unsigned char get (lua_State* L, int index)
+ {
+ return static_cast <unsigned char> (luaL_checkinteger (L, index));
+ }
+};
+
+template <>
+struct Stack <unsigned char const&>
+{
+ static inline void push (lua_State* L, unsigned char value)
+ {
+ lua_pushnumber (L, static_cast <lua_Number> (value));
+ }
+
+ static inline unsigned char get (lua_State* L, int index)
+ {
+ return static_cast <unsigned char> (luaL_checknumber (L, index));
+ }
+};
+
+//------------------------------------------------------------------------------
+/**
+ Stack specialization for `short`.
+*/
+template <>
+struct Stack <short>
+{
+ static inline void push (lua_State* L, short value)
+ {
+ lua_pushinteger (L, static_cast <lua_Integer> (value));
+ }
+
+ static inline short get (lua_State* L, int index)
+ {
+ return static_cast <short> (luaL_checkinteger (L, index));
+ }
+};
+
+template <>
+struct Stack <short const&>
+{
+ static inline void push (lua_State* L, short value)
+ {
+ lua_pushnumber (L, static_cast <lua_Number> (value));
+ }
+
+ static inline short get (lua_State* L, int index)
+ {
+ return static_cast <short> (luaL_checknumber (L, index));
+ }
+};
+
+//------------------------------------------------------------------------------
+/**
+ Stack specialization for `unsigned short`.
+*/
+template <>
+struct Stack <unsigned short>
+{
+ static inline void push (lua_State* L, unsigned short value)
+ {
+ lua_pushinteger (L, static_cast <lua_Integer> (value));
+ }
+
+ static inline unsigned short get (lua_State* L, int index)
+ {
+ return static_cast <unsigned short> (luaL_checkinteger (L, index));
+ }
+};
+
+template <>
+struct Stack <unsigned short const&>
+{
+ static inline void push (lua_State* L, unsigned short value)
+ {
+ lua_pushnumber (L, static_cast <lua_Number> (value));
+ }
+
+ static inline unsigned short get (lua_State* L, int index)
+ {
+ return static_cast <unsigned short> (luaL_checknumber (L, index));
+ }
+};
+
+//------------------------------------------------------------------------------
+/**
+ Stack specialization for `long`.
+*/
+template <>
+struct Stack <long>
+{
+ static inline void push (lua_State* L, long value)
+ {
+ lua_pushinteger (L, static_cast <lua_Integer> (value));
+ }
+
+ static inline long get (lua_State* L, int index)
+ {
+ return static_cast <long> (luaL_checkinteger (L, index));
+ }
+};
+
+template <>
+struct Stack <long const&>
+{
+ static inline void push (lua_State* L, long value)
+ {
+ lua_pushnumber (L, static_cast <lua_Number> (value));
+ }
+
+ static inline long get (lua_State* L, int index)
+ {
+ return static_cast <long> (luaL_checknumber (L, index));
+ }
+};
+
+//------------------------------------------------------------------------------
+/**
+ Stack specialization for `unsigned long`.
+*/
+template <>
+struct Stack <unsigned long>
+{
+ static inline void push (lua_State* L, unsigned long value)
+ {
+ lua_pushinteger (L, static_cast <lua_Integer> (value));
+ }
+
+ static inline unsigned long get (lua_State* L, int index)
+ {
+ return static_cast <unsigned long> (luaL_checkinteger (L, index));
+ }
+};
+
+template <>
+struct Stack <unsigned long const&>
+{
+ static inline void push (lua_State* L, unsigned long value)
+ {
+ lua_pushnumber (L, static_cast <lua_Number> (value));
+ }
+
+ static inline unsigned long get (lua_State* L, int index)
+ {
+ return static_cast <unsigned long> (luaL_checknumber (L, index));
+ }
+};
+
+//------------------------------------------------------------------------------
+/**
+ Stack specialization for `float`.
+*/
+template <>
+struct Stack <float>
+{
+ static inline void push (lua_State* L, float value)
+ {
+ lua_pushnumber (L, static_cast <lua_Number> (value));
+ }
+
+ static inline float get (lua_State* L, int index)
+ {
+ return static_cast <float> (luaL_checknumber (L, index));
+ }
+};
+
+template <>
+struct Stack <float const&>
+{
+ static inline void push (lua_State* L, float value)
+ {
+ lua_pushnumber (L, static_cast <lua_Number> (value));
+ }
+
+ static inline float get (lua_State* L, int index)
+ {
+ return static_cast <float> (luaL_checknumber (L, index));
+ }
+};
+
+//------------------------------------------------------------------------------
+/**
+ Stack specialization for `double`.
+*/
+template <> struct Stack <double>
+{
+ static inline void push (lua_State* L, double value)
+ {
+ lua_pushnumber (L, static_cast <lua_Number> (value));
+ }
+
+ static inline double get (lua_State* L, int index)
+ {
+ return static_cast <double> (luaL_checknumber (L, index));
+ }
+};
+
+template <> struct Stack <double const&>
+{
+ static inline void push (lua_State* L, double value)
+ {
+ lua_pushnumber (L, static_cast <lua_Number> (value));
+ }
+
+ static inline double get (lua_State* L, int index)
+ {
+ return static_cast <double> (luaL_checknumber (L, index));
+ }
+};
+
+//------------------------------------------------------------------------------
+/**
+ Stack specialization for `bool`.
+*/
+template <>
+struct Stack <bool> {
+ static inline void push (lua_State* L, bool value)
+ {
+ lua_pushboolean (L, value ? 1 : 0);
+ }
+
+ static inline bool get (lua_State* L, int index)
+ {
+ return lua_toboolean (L, index) ? true : false;
+ }
+};
+
+template <>
+struct Stack <bool const&> {
+ static inline void push (lua_State* L, bool value)
+ {
+ lua_pushboolean (L, value ? 1 : 0);
+ }
+
+ static inline bool get (lua_State* L, int index)
+ {
+ return lua_toboolean (L, index) ? true : false;
+ }
+};
+
+//------------------------------------------------------------------------------
+/**
+ Stack specialization for `char`.
+*/
+template <>
+struct Stack <char>
+{
+ static inline void push (lua_State* L, char value)
+ {
+ char str [2] = { value, 0 };
+ lua_pushstring (L, str);
+ }
+
+ static inline char get (lua_State* L, int index)
+ {
+ return luaL_checkstring (L, index) [0];
+ }
+};
+
+template <>
+struct Stack <char const&>
+{
+ static inline void push (lua_State* L, char value)
+ {
+ char str [2] = { value, 0 };
+ lua_pushstring (L, str);
+ }
+
+ static inline char get (lua_State* L, int index)
+ {
+ return luaL_checkstring (L, index) [0];
+ }
+};
+
+//------------------------------------------------------------------------------
+/**
+ Stack specialization for `float`.
+*/
+template <>
+struct Stack <char const*>
+{
+ static inline void push (lua_State* L, char const* str)
+ {
+ if (str != 0)
+ lua_pushstring (L, str);
+ else
+ lua_pushnil (L);
+ }
+
+ static inline char const* get (lua_State* L, int index)
+ {
+ return lua_isnil (L, index) ? 0 : luaL_checkstring (L, index);
+ }
+};
+
+//------------------------------------------------------------------------------
+/**
+ Stack specialization for `std::string`.
+*/
+template <>
+struct Stack <std::string>
+{
+ static inline void push (lua_State* L, std::string const& str)
+ {
+ lua_pushlstring (L, str.c_str (), str.size());
+ }
+
+ static inline std::string get (lua_State* L, int index)
+ {
+ size_t len;
+ const char *str = luaL_checklstring(L, index, &len);
+ return std::string (str, len);
+ }
+};
+
+//------------------------------------------------------------------------------
+/**
+ Stack specialization for `std::string const&`.
+*/
+template <>
+struct Stack <std::string const&>
+{
+ static inline void push (lua_State* L, std::string const& str)
+ {
+ lua_pushstring (L, str.c_str());
+ }
+
+ static inline std::string get (lua_State* L, int index)
+ {
+ size_t len;
+ const char *str = luaL_checklstring(L, index, &len);
+ return std::string (str, len);
+ }
+};
diff --git a/libs/lua/LuaBridge/detail/TypeList.h b/libs/lua/LuaBridge/detail/TypeList.h
new file mode 100644
index 0000000000..21f850e89d
--- /dev/null
+++ b/libs/lua/LuaBridge/detail/TypeList.h
@@ -0,0 +1,174 @@
+//------------------------------------------------------------------------------
+/*
+ https://github.com/vinniefalco/LuaBridge
+
+ Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
+ Copyright 2007, Nathan Reed
+
+ License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+
+ This file incorporates work covered by the following copyright and
+ permission notice:
+
+ The Loki Library
+ Copyright (c) 2001 by Andrei Alexandrescu
+ This code accompanies the book:
+ Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
+ Patterns Applied". Copyright (c) 2001. Addison-Wesley.
+ Permission to use, copy, modify, distribute and sell this software for any
+ purpose is hereby granted without fee, provided that the above copyright
+ notice appear in all copies and that both that copyright notice and this
+ permission notice appear in supporting documentation.
+ The author or Addison-Welsey Longman make no representations about the
+ suitability of this software for any purpose. It is provided "as is"
+ without express or implied warranty.
+*/
+//==============================================================================
+
+/**
+ None type means void parameters or return value.
+*/
+typedef void None;
+
+template <typename Head, typename Tail = None>
+struct TypeList
+{
+};
+
+/**
+ A TypeList with actual values.
+*/
+template <typename List>
+struct TypeListValues
+{
+ static std::string const tostring (bool)
+ {
+ return "";
+ }
+};
+
+/**
+ TypeListValues recursive template definition.
+*/
+template <typename Head, typename Tail>
+struct TypeListValues <TypeList <Head, Tail> >
+{
+ Head hd;
+ TypeListValues <Tail> tl;
+
+ TypeListValues (Head hd_, TypeListValues <Tail> const& tl_)
+ : hd (hd_), tl (tl_)
+ {
+ }
+
+ static std::string const tostring (bool comma = false)
+ {
+ std::string s;
+
+ if (comma)
+ s = ", ";
+
+ s = s + typeid (Head).name ();
+
+ return s + TypeListValues <Tail>::tostring (true);
+ }
+};
+
+// Specializations of type/value list for head types that are references and
+// const-references. We need to handle these specially since we can't count
+// on the referenced object hanging around for the lifetime of the list.
+
+template <typename Head, typename Tail>
+struct TypeListValues <TypeList <Head&, Tail> >
+{
+ Head hd;
+ TypeListValues <Tail> tl;
+
+ TypeListValues (Head& hd_, TypeListValues <Tail> const& tl_)
+ : hd (hd_), tl (tl_)
+ {
+ }
+
+ static std::string const tostring (bool comma = false)
+ {
+ std::string s;
+
+ if (comma)
+ s = ", ";
+
+ s = s + typeid (Head).name () + "&";
+
+ return s + TypeListValues <Tail>::tostring (true);
+ }
+};
+
+template <typename Head, typename Tail>
+struct TypeListValues <TypeList <Head const&, Tail> >
+{
+ Head hd;
+ TypeListValues <Tail> tl;
+
+ TypeListValues (Head const& hd_, const TypeListValues <Tail>& tl_)
+ : hd (hd_), tl (tl_)
+ {
+ }
+
+ static std::string const tostring (bool comma = false)
+ {
+ std::string s;
+
+ if (comma)
+ s = ", ";
+
+ s = s + typeid (Head).name () + " const&";
+
+ return s + TypeListValues <Tail>::tostring (true);
+ }
+};
+
+//==============================================================================
+/**
+ Subclass of a TypeListValues constructable from the Lua stack.
+*/
+
+template <typename List, int Start = 1>
+struct ArgList
+{
+};
+
+template <int Start>
+struct ArgList <None, Start> : public TypeListValues <None>
+{
+ ArgList (lua_State*)
+ {
+ }
+};
+
+template <typename Head, typename Tail, int Start>
+struct ArgList <TypeList <Head, Tail>, Start>
+ : public TypeListValues <TypeList <Head, Tail> >
+{
+ ArgList (lua_State* L)
+ : TypeListValues <TypeList <Head, Tail> > (Stack <Head>::get (L, Start),
+ ArgList <Tail, Start + 1> (L))
+ {
+ }
+};
diff --git a/libs/lua/LuaBridge/detail/TypeTraits.h b/libs/lua/LuaBridge/detail/TypeTraits.h
new file mode 100644
index 0000000000..5dd077194f
--- /dev/null
+++ b/libs/lua/LuaBridge/detail/TypeTraits.h
@@ -0,0 +1,125 @@
+//------------------------------------------------------------------------------
+/*
+ https://github.com/vinniefalco/LuaBridge
+
+ Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
+
+ License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+*/
+//==============================================================================
+
+#ifndef LUABRIDGE_TYPEINFO_HEADER
+#define LUABRIDGE_TYPEINFO_HEADER
+
+//------------------------------------------------------------------------------
+/**
+ Container traits.
+
+ Unspecialized ContainerTraits has the isNotContainer typedef for SFINAE.
+ All user defined containers must supply an appropriate specialization for
+ ContinerTraits (without the typedef isNotContainer). The containers that
+ come with LuaBridge also come with the appropriate ContainerTraits
+ specialization. See the corresponding declaration for details.
+
+ A specialization of ContainerTraits for some generic type ContainerType
+ looks like this:
+
+ template <class T>
+ struct ContainerTraits <ContainerType <T> >
+ {
+ typedef typename T Type;
+
+ static T* get (ContainerType <T> const& c)
+ {
+ return c.get (); // Implementation-dependent on ContainerType
+ }
+ };
+*/
+template <class T>
+struct ContainerTraits
+{
+ typedef bool isNotContainer;
+};
+
+//------------------------------------------------------------------------------
+/**
+ Type traits.
+
+ Specializations return information about a type.
+*/
+struct TypeTraits
+{
+ /** Determine if type T is a container.
+
+ To be considered a container, there must be a specialization of
+ ContainerTraits with the required fields.
+ */
+ template <typename T>
+ class isContainer
+ {
+ private:
+ typedef char yes[1]; // sizeof (yes) == 1
+ typedef char no [2]; // sizeof (no) == 2
+
+ template <typename C>
+ static no& test (typename C::isNotContainer*);
+
+ template <typename>
+ static yes& test (...);
+
+ public:
+ static const bool value = sizeof (test <ContainerTraits <T> >(0)) == sizeof (yes);
+ };
+
+ /** Determine if T is const qualified.
+ */
+ /** @{ */
+ template <class T>
+ struct isConst
+ {
+ static bool const value = false;
+ };
+
+ template <class T>
+ struct isConst <T const>
+ {
+ static bool const value = true;
+ };
+ /** @} */
+
+ /** Remove the const qualifier from T.
+ */
+ /** @{ */
+ template <class T>
+ struct removeConst
+ {
+ typedef T Type;
+ };
+
+ template <class T>
+ struct removeConst <T const>
+ {
+ typedef T Type;
+ };
+ /**@}*/
+};
+
+#endif
diff --git a/libs/lua/LuaBridge/detail/Userdata.h b/libs/lua/LuaBridge/detail/Userdata.h
new file mode 100644
index 0000000000..19451bd7d3
--- /dev/null
+++ b/libs/lua/LuaBridge/detail/Userdata.h
@@ -0,0 +1,817 @@
+//------------------------------------------------------------------------------
+/*
+ https://github.com/vinniefalco/LuaBridge
+
+ Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
+
+ License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+*/
+//==============================================================================
+
+//==============================================================================
+/**
+ Return the identity pointer for our lightuserdata tokens.
+
+ LuaBridge metatables are tagged with a security "token." The token is a
+ lightuserdata created from the identity pointer, used as a key in the
+ metatable. The value is a boolean = true, although any value could have been
+ used.
+
+ Because of Lua's dynamic typing and our improvised system of imposing C++
+ class structure, there is the possibility that executing scripts may
+ knowingly or unknowingly cause invalid data to get passed to the C functions
+ created by LuaBridge. In particular, our security model addresses the
+ following:
+
+ Notes:
+ 1. Scripts cannot create a userdata (ignoring the debug lib).
+ 2. Scripts cannot create a lightuserdata (ignoring the debug lib).
+ 3. Scripts cannot set the metatable on a userdata.
+ 4. Our identity key is a unique pointer in the process.
+ 5. Our metatables have a lightuserdata identity key / value pair.
+ 6. Our metatables have "__metatable" set to a boolean = false.
+ 7. Our lightuserdata is unique.
+*/
+inline void* getIdentityKey ()
+{
+ static char value;
+ return &value;
+}
+
+/**
+ Interface to a class pointer retrievable from a userdata.
+*/
+class Userdata
+{
+protected:
+ void* m_p; // subclasses must set this
+
+ //--------------------------------------------------------------------------
+ /**
+ Get an untyped pointer to the contained class.
+ */
+ inline void* const getPointer ()
+ {
+ return m_p;
+ }
+
+private:
+ //--------------------------------------------------------------------------
+ /**
+ Validate and retrieve a Userdata on the stack.
+
+ The Userdata must exactly match the corresponding class table or
+ const table, or else a Lua error is raised. This is used for the
+ __gc metamethod.
+ */
+ static Userdata* getExactClass (lua_State* L,
+ int narg,
+ void const* classKey)
+ {
+ Userdata* ud = 0;
+ int const index = lua_absindex (L, narg);
+
+ bool mismatch = false;
+ char const* got = 0;
+
+ lua_rawgetp (L, LUA_REGISTRYINDEX, classKey);
+ assert (lua_istable (L, -1));
+
+ // Make sure we have a userdata.
+ if (!lua_isuserdata (L, index))
+ mismatch = true;
+
+ // Make sure it's metatable is ours.
+ if (!mismatch)
+ {
+ lua_getmetatable (L, index);
+ lua_rawgetp (L, -1, getIdentityKey ());
+ if (lua_isboolean (L, -1))
+ {
+ lua_pop (L, 1);
+ }
+ else
+ {
+ lua_pop (L, 2);
+ mismatch = true;
+ }
+ }
+
+ if (!mismatch)
+ {
+ if (lua_rawequal (L, -1, -2))
+ {
+ // Matches class table.
+ lua_pop (L, 2);
+ ud = static_cast <Userdata*> (lua_touserdata (L, index));
+ }
+ else
+ {
+ rawgetfield (L, -2, "__const");
+ if (lua_rawequal (L, -1, -2))
+ {
+ // Matches const table
+ lua_pop (L, 3);
+ ud = static_cast <Userdata*> (lua_touserdata (L, index));
+ }
+ else
+ {
+ // Mismatch, but its one of ours so get a type name.
+ rawgetfield (L, -2, "__type");
+ lua_insert (L, -4);
+ lua_pop (L, 2);
+ got = lua_tostring (L, -2);
+ mismatch = true;
+ }
+ }
+ }
+
+ if (mismatch)
+ {
+ rawgetfield (L, -1, "__type");
+ assert (lua_type (L, -1) == LUA_TSTRING);
+ char const* const expected = lua_tostring (L, -1);
+
+ if (got == 0)
+ got = lua_typename (L, lua_type (L, index));
+
+ char const* const msg = lua_pushfstring (
+ L, "%s expected, got %s", expected, got);
+
+ if (narg > 0)
+ luaL_argerror (L, narg, msg);
+ else
+ lua_error (L);
+ }
+
+ return ud;
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ Validate and retrieve a Userdata on the stack.
+
+ The Userdata must be derived from or the same as the given base class,
+ identified by the key. If canBeConst is false, generates an error if
+ the resulting Userdata represents to a const object. We do the type check
+ first so that the error message is informative.
+ */
+ static Userdata* getClass (lua_State* L,
+ int index,
+ void const* baseClassKey,
+ bool canBeConst)
+ {
+ assert (index > 0);
+ Userdata* ud = 0;
+
+ bool mismatch = false;
+ char const* got = 0;
+
+ lua_rawgetp (L, LUA_REGISTRYINDEX, baseClassKey);
+ assert (lua_istable (L, -1));
+
+ // Make sure we have a userdata.
+ if (lua_isuserdata (L, index))
+ {
+ // Make sure it's metatable is ours.
+ lua_getmetatable (L, index);
+ lua_rawgetp (L, -1, getIdentityKey ());
+ if (lua_isboolean (L, -1))
+ {
+ lua_pop (L, 1);
+
+ // If __const is present, object is NOT const.
+ rawgetfield (L, -1, "__const");
+ assert (lua_istable (L, -1) || lua_isnil (L, -1));
+ bool const isConst = lua_isnil (L, -1);
+ lua_pop (L, 1);
+
+ // Replace the class table with the const table if needed.
+ if (isConst)
+ {
+ rawgetfield (L, -2, "__const");
+ assert (lua_istable (L, -1));
+ lua_replace (L, -3);
+ }
+
+ for (;;)
+ {
+ if (lua_rawequal (L, -1, -2))
+ {
+ lua_pop (L, 2);
+
+ // Match, now check const-ness.
+ if (isConst && !canBeConst)
+ {
+ luaL_argerror (L, index, "cannot be const");
+ }
+ else
+ {
+ ud = static_cast <Userdata*> (lua_touserdata (L, index));
+ break;
+ }
+ }
+ else
+ {
+ // Replace current metatable with it's base class.
+ rawgetfield (L, -1, "__parent");
+/*
+ud
+class metatable
+ud metatable
+ud __parent (nil)
+*/
+
+ if (lua_isnil (L, -1))
+ {
+ lua_remove (L, -1);
+ // Mismatch, but its one of ours so get a type name.
+ rawgetfield (L, -1, "__type");
+ lua_insert (L, -3);
+ lua_pop (L, 1);
+ got = lua_tostring (L, -2);
+ mismatch = true;
+ break;
+ }
+ else
+ {
+ lua_remove (L, -2);
+ }
+ }
+ }
+ }
+ else
+ {
+ lua_pop (L, 2);
+ mismatch = true;
+ }
+ }
+ else
+ {
+ mismatch = true;
+ }
+
+ if (mismatch)
+ {
+ assert (lua_type (L, -1) == LUA_TTABLE);
+ rawgetfield (L, -1, "__type");
+ assert (lua_type (L, -1) == LUA_TSTRING);
+ char const* const expected = lua_tostring (L, -1);
+
+ if (got == 0)
+ got = lua_typename (L, lua_type (L, index));
+
+ char const* const msg = lua_pushfstring (
+ L, "%s expected, got %s", expected, got);
+
+ luaL_argerror (L, index, msg);
+ }
+
+ return ud;
+ }
+
+public:
+ virtual ~Userdata () { }
+
+ //--------------------------------------------------------------------------
+ /**
+ Returns the Userdata* if the class on the Lua stack matches.
+
+ If the class does not match, a Lua error is raised.
+ */
+ template <class T>
+ static inline Userdata* getExact (lua_State* L, int index)
+ {
+ return getExactClass (L, index, ClassInfo <T>::getClassKey ());
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ Get a pointer to the class from the Lua stack.
+
+ If the object is not the class or a subclass, or it violates the
+ const-ness, a Lua error is raised.
+ */
+ template <class T>
+ static inline T* get (lua_State* L, int index, bool canBeConst)
+ {
+ if (lua_isnil (L, index))
+ return 0;
+ else
+ return static_cast <T*> (getClass (L, index,
+ ClassInfo <T>::getClassKey (), canBeConst)->getPointer ());
+ }
+};
+
+//----------------------------------------------------------------------------
+/**
+ Wraps a class object stored in a Lua userdata.
+
+ The lifetime of the object is managed by Lua. The object is constructed
+ inside the userdata using placement new.
+*/
+template <class T>
+class UserdataValue : public Userdata
+{
+private:
+ UserdataValue <T> (UserdataValue <T> const&);
+ UserdataValue <T> operator= (UserdataValue <T> const&);
+
+ char m_storage [sizeof (T)];
+
+ inline T* getObject ()
+ {
+ // If this fails to compile it means you forgot to provide
+ // a Container specialization for your container!
+ //
+ return reinterpret_cast <T*> (&m_storage [0]);
+ }
+
+private:
+ /**
+ Used for placement construction.
+ */
+ UserdataValue ()
+ {
+ m_p = getObject ();
+ }
+
+ ~UserdataValue ()
+ {
+ getObject ()->~T ();
+ }
+
+public:
+ /**
+ Push a T via placement new.
+
+ The caller is responsible for calling placement new using the
+ returned uninitialized storage.
+ */
+ static void* place (lua_State* const L)
+ {
+ UserdataValue <T>* const ud = new (
+ lua_newuserdata (L, sizeof (UserdataValue <T>))) UserdataValue <T> ();
+ lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ());
+ // If this goes off it means you forgot to register the class!
+ assert (lua_istable (L, -1));
+ lua_setmetatable (L, -2);
+ return ud->getPointer ();
+ }
+
+ /**
+ Push T via copy construction from U.
+ */
+ template <class U>
+ static inline void push (lua_State* const L, U const& u)
+ {
+ new (place (L)) U (u);
+ }
+};
+
+//----------------------------------------------------------------------------
+/**
+ Wraps a pointer to a class object inside a Lua userdata.
+
+ The lifetime of the object is managed by C++.
+*/
+class UserdataPtr : public Userdata
+{
+private:
+ UserdataPtr (UserdataPtr const&);
+ UserdataPtr operator= (UserdataPtr const&);
+
+private:
+ /** Push non-const pointer to object using metatable key.
+ */
+ static void push (lua_State* L, void* const p, void const* const key)
+ {
+ if (p)
+ {
+ new (lua_newuserdata (L, sizeof (UserdataPtr))) UserdataPtr (p);
+ lua_rawgetp (L, LUA_REGISTRYINDEX, key);
+ // If this goes off it means you forgot to register the class!
+ assert (lua_istable (L, -1));
+ lua_setmetatable (L, -2);
+ }
+ else
+ {
+ lua_pushnil (L);
+ }
+ }
+
+ /** Push const pointer to object using metatable key.
+ */
+ static void push (lua_State* L, void const* const p, void const* const key)
+ {
+ if (p)
+ {
+ new (lua_newuserdata (L, sizeof (UserdataPtr)))
+ UserdataPtr (const_cast <void*> (p));
+ lua_rawgetp (L, LUA_REGISTRYINDEX, key);
+ // If this goes off it means you forgot to register the class!
+ assert (lua_istable (L, -1));
+ lua_setmetatable (L, -2);
+ }
+ else
+ {
+ lua_pushnil (L);
+ }
+ }
+
+ explicit UserdataPtr (void* const p)
+ {
+ m_p = p;
+
+ // Can't construct with a null pointer!
+ //
+ assert (m_p != 0);
+ }
+
+public:
+ /** Push non-const pointer to object.
+ */
+ template <class T>
+ static inline void push (lua_State* const L, T* const p)
+ {
+ if (p)
+ push (L, p, ClassInfo <T>::getClassKey ());
+ else
+ lua_pushnil (L);
+ }
+
+ /** Push const pointer to object.
+ */
+ template <class T>
+ static inline void push (lua_State* const L, T const* const p)
+ {
+ if (p)
+ push (L, p, ClassInfo <T>::getConstKey ());
+ else
+ lua_pushnil (L);
+ }
+};
+
+//============================================================================
+/**
+ Wraps a container thet references a class object.
+
+ The template argument C is the container type, ContainerTraits must be
+ specialized on C or else a compile error will result.
+*/
+template <class C>
+class UserdataShared : public Userdata
+{
+private:
+ UserdataShared (UserdataShared <C> const&);
+ UserdataShared <C>& operator= (UserdataShared <C> const&);
+
+ typedef typename TypeTraits::removeConst <
+ typename ContainerTraits <C>::Type>::Type T;
+
+ C m_c;
+
+private:
+ ~UserdataShared ()
+ {
+ }
+
+public:
+ /**
+ Construct from a container to the class or a derived class.
+ */
+ template <class U>
+ explicit UserdataShared (U const& u) : m_c (u)
+ {
+ m_p = const_cast <void*> (reinterpret_cast <void const*> (
+ (ContainerTraits <C>::get (m_c))));
+ }
+
+ /**
+ Construct from a pointer to the class or a derived class.
+ */
+ template <class U>
+ explicit UserdataShared (U* u) : m_c (u)
+ {
+ m_p = const_cast <void*> (reinterpret_cast <void const*> (
+ (ContainerTraits <C>::get (m_c))));
+ }
+};
+
+//----------------------------------------------------------------------------
+//
+// SFINAE helpers.
+//
+
+// non-const objects
+template <class C, bool makeObjectConst>
+struct UserdataSharedHelper
+{
+ typedef typename TypeTraits::removeConst <
+ typename ContainerTraits <C>::Type>::Type T;
+
+ static void push (lua_State* L, C const& c)
+ {
+ if (ContainerTraits <C>::get (c) != 0)
+ {
+ new (lua_newuserdata (L, sizeof (UserdataShared <C>))) UserdataShared <C> (c);
+ lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ());
+ // If this goes off it means the class T is unregistered!
+ assert (lua_istable (L, -1));
+ lua_setmetatable (L, -2);
+ }
+ else
+ {
+ lua_pushnil (L);
+ }
+ }
+
+ static void push (lua_State* L, T* const t)
+ {
+ if (t)
+ {
+ new (lua_newuserdata (L, sizeof (UserdataShared <C>))) UserdataShared <C> (t);
+ lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ());
+ // If this goes off it means the class T is unregistered!
+ assert (lua_istable (L, -1));
+ lua_setmetatable (L, -2);
+ }
+ else
+ {
+ lua_pushnil (L);
+ }
+ }
+};
+
+// const objects
+template <class C>
+struct UserdataSharedHelper <C, true>
+{
+ typedef typename TypeTraits::removeConst <
+ typename ContainerTraits <C>::Type>::Type T;
+
+ static void push (lua_State* L, C const& c)
+ {
+ if (ContainerTraits <C>::get (c) != 0)
+ {
+ new (lua_newuserdata (L, sizeof (UserdataShared <C>))) UserdataShared <C> (c);
+ lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getConstKey ());
+ // If this goes off it means the class T is unregistered!
+ assert (lua_istable (L, -1));
+ lua_setmetatable (L, -2);
+ }
+ else
+ {
+ lua_pushnil (L);
+ }
+ }
+
+ static void push (lua_State* L, T* const t)
+ {
+ if (t)
+ {
+ new (lua_newuserdata (L, sizeof (UserdataShared <C>))) UserdataShared <C> (t);
+ lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getConstKey ());
+ // If this goes off it means the class T is unregistered!
+ assert (lua_istable (L, -1));
+ lua_setmetatable (L, -2);
+ }
+ else
+ {
+ lua_pushnil (L);
+ }
+ }
+};
+
+/**
+ Pass by container.
+
+ The container controls the object lifetime. Typically this will be a
+ lifetime shared by C++ and Lua using a reference count. Because of type
+ erasure, containers like std::shared_ptr will not work. Containers must
+ 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>
+struct StackHelper
+{
+ static inline void push (lua_State* L, C const& c)
+ {
+ UserdataSharedHelper <C,
+ TypeTraits::isConst <typename ContainerTraits <C>::Type>::value>::push (L, c);
+ }
+
+ typedef typename TypeTraits::removeConst <
+ typename ContainerTraits <C>::Type>::Type T;
+
+ static inline C get (lua_State* L, int index)
+ {
+ return Userdata::get <T> (L, index, true);
+ }
+};
+
+/**
+ Pass by value.
+
+ Lifetime is managed by Lua. A C++ function which accesses a pointer or
+ reference to an object outside the activation record in which it was
+ retrieved may result in undefined behavior if Lua garbage collected it.
+*/
+template <class T>
+struct StackHelper <T, false>
+{
+ static inline void push (lua_State* L, T const& t)
+ {
+ UserdataValue <T>::push (L, t);
+ }
+
+ static inline T const& get (lua_State* L, int index)
+ {
+ return *Userdata::get <T> (L, index, true);
+ }
+};
+
+//==============================================================================
+
+/**
+ Lua stack conversions for class objects passed by value.
+*/
+template <class T>
+struct Stack
+{
+public:
+ static inline void push (lua_State* L, T const& t)
+ {
+ StackHelper <T,
+ TypeTraits::isContainer <T>::value>::push (L, t);
+ }
+
+ static inline T get (lua_State* L, int index)
+ {
+ return StackHelper <T,
+ TypeTraits::isContainer <T>::value>::get (L, index);
+ }
+};
+
+//------------------------------------------------------------------------------
+/**
+ Lua stack conversions for pointers and references to class objects.
+
+ Lifetime is managed by C++. Lua code which remembers a reference to the
+ value may result in undefined behavior if C++ destroys the object. The
+ handling of the const and volatile qualifiers happens in UserdataPtr.
+*/
+
+// pointer
+template <class T>
+struct Stack <T*>
+{
+ static inline void push (lua_State* L, T* const p)
+ {
+ UserdataPtr::push (L, p);
+ }
+
+ static inline T* const get (lua_State* L, int index)
+ {
+ return Userdata::get <T> (L, index, false);
+ }
+};
+
+// Strips the const off the right side of *
+template <class T>
+struct Stack <T* const>
+{
+ static inline void push (lua_State* L, T* const p)
+ {
+ UserdataPtr::push (L, p);
+ }
+
+ static inline T* const get (lua_State* L, int index)
+ {
+ return Userdata::get <T> (L, index, false);
+ }
+};
+
+// pointer to const
+template <class T>
+struct Stack <T const*>
+{
+ static inline void push (lua_State* L, T const* const p)
+ {
+ UserdataPtr::push (L, p);
+ }
+
+ static inline T const* const get (lua_State* L, int index)
+ {
+ return Userdata::get <T> (L, index, true);
+ }
+};
+
+// Strips the const off the right side of *
+template <class T>
+struct Stack <T const* const>
+{
+ static inline void push (lua_State* L, T const* const p)
+ {
+ UserdataPtr::push (L, p);
+ }
+
+ static inline T const* const get (lua_State* L, int index)
+ {
+ return Userdata::get <T> (L, index, true);
+ }
+};
+
+// reference
+template <class T>
+struct Stack <T&>
+{
+ static inline void push (lua_State* L, T& t)
+ {
+ UserdataPtr::push (L, &t);
+ }
+
+ static T& get (lua_State* L, int index)
+ {
+ T* const t = Userdata::get <T> (L, index, false);
+ if (!t)
+ luaL_error (L, "nil passed to reference");
+ return *t;
+ }
+};
+
+template <class C, bool byContainer>
+struct RefStackHelper
+{
+ typedef C return_type;
+
+ static inline void push (lua_State* L, C const& t)
+ {
+ UserdataSharedHelper <C,
+ TypeTraits::isConst <typename ContainerTraits <C>::Type>::value>::push (L, t);
+ }
+
+ typedef typename TypeTraits::removeConst <
+ typename ContainerTraits <C>::Type>::Type T;
+
+ static return_type get (lua_State* L, int index)
+ {
+ return Userdata::get <T> (L, index, true);
+ }
+};
+
+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);
+ }
+
+ static return_type get (lua_State* L, int index)
+ {
+ T const* const t = Userdata::get <T> (L, index, true);
+
+ if (!t)
+ luaL_error (L, "nil passed to reference");
+ return *t;
+ }
+
+};
+
+// reference to const
+template <class T>
+struct Stack <T const&>
+{
+ typedef RefStackHelper <T, TypeTraits::isContainer <T>::value> helper_t;
+
+ static inline void push (lua_State* L, T const& t)
+ {
+ helper_t::push (L, t);
+ }
+
+ static typename helper_t::return_type get (lua_State* L, int index)
+ {
+ return helper_t::get (L, index);
+ }
+};
diff --git a/libs/lua/LuaBridge/detail/dump.h b/libs/lua/LuaBridge/detail/dump.h
new file mode 100644
index 0000000000..c066803573
--- /dev/null
+++ b/libs/lua/LuaBridge/detail/dump.h
@@ -0,0 +1,28 @@
+#include <sstream>
+#include <string>
+
+std::string dumpLuaState(lua_State *L) {
+ std::stringstream ostr;
+ int i;
+ int top = lua_gettop(L);
+ ostr << "top=" << top << ":\n";
+ for (i = 1; i <= top; ++i) {
+ int t = lua_type(L, i);
+ switch(t) {
+ case LUA_TSTRING:
+ ostr << " " << i << ": '" << lua_tostring(L, i) << "'\n";
+ break;
+ case LUA_TBOOLEAN:
+ ostr << " " << i << ": " <<
+ (lua_toboolean(L, i) ? "true" : "false") << "\n";
+ break;
+ case LUA_TNUMBER:
+ ostr << " " << i << ": " << lua_tonumber(L, i) << "\n";
+ break;
+ default:
+ ostr << " " << i << ": TYPE=" << lua_typename(L, t) << "\n";
+ break;
+ }
+ }
+ return ostr.str();
+}