大改
This commit is contained in:
470
csgo2/LuaBridge/luaBridge/detail/CFunctions.h
Normal file
470
csgo2/LuaBridge/luaBridge/detail/CFunctions.h
Normal file
@@ -0,0 +1,470 @@
|
||||
// https://github.com/vinniefalco/LuaBridge
|
||||
// Copyright 2019, Dmitry Tarakanov
|
||||
// Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LuaBridge/detail/Config.h>
|
||||
#include <LuaBridge/detail/FuncTraits.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace luabridge {
|
||||
|
||||
namespace detail {
|
||||
|
||||
// We use a structure so we can define everything in the header.
|
||||
//
|
||||
struct CFunc
|
||||
{
|
||||
static void addGetter(lua_State* L, const char* name, int tableIndex)
|
||||
{
|
||||
assert(lua_istable(L, tableIndex));
|
||||
assert(lua_iscfunction(L, -1)); // Stack: getter
|
||||
|
||||
lua_rawgetp(L, tableIndex, getPropgetKey()); // Stack: getter, propget table (pg)
|
||||
lua_pushvalue(L, -2); // Stack: getter, pg, getter
|
||||
rawsetfield(L, -2, name); // Stack: getter, pg
|
||||
lua_pop(L, 2); // Stack: -
|
||||
}
|
||||
|
||||
static void addSetter(lua_State* L, const char* name, int tableIndex)
|
||||
{
|
||||
assert(lua_istable(L, tableIndex));
|
||||
assert(lua_iscfunction(L, -1)); // Stack: setter
|
||||
|
||||
lua_rawgetp(L, tableIndex, getPropsetKey()); // Stack: setter, propset table (ps)
|
||||
lua_pushvalue(L, -2); // Stack: setter, ps, setter
|
||||
rawsetfield(L, -2, name); // Stack: setter, ps
|
||||
lua_pop(L, 2); // Stack: -
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/**
|
||||
__index metamethod for a namespace or class static and non-static members.
|
||||
Retrieves functions from metatables and properties from propget tables.
|
||||
Looks through the class hierarchy if inheritance is present.
|
||||
*/
|
||||
static int indexMetaMethod(lua_State* L)
|
||||
{
|
||||
assert(lua_istable(L, 1) ||
|
||||
lua_isuserdata(L, 1)); // Stack (further not shown): table | userdata, name
|
||||
|
||||
lua_getmetatable(L, 1); // Stack: class/const table (mt)
|
||||
assert(lua_istable(L, -1));
|
||||
|
||||
for (;;)
|
||||
{
|
||||
lua_pushvalue(L, 2); // Stack: mt, field name
|
||||
lua_rawget(L, -2); // Stack: mt, field | nil
|
||||
|
||||
if (lua_iscfunction(L, -1)) // Stack: mt, field
|
||||
{
|
||||
lua_remove(L, -2); // Stack: field
|
||||
return 1;
|
||||
}
|
||||
|
||||
assert(lua_isnil(L, -1)); // Stack: mt, nil
|
||||
lua_pop(L, 1); // Stack: mt
|
||||
|
||||
lua_rawgetp(L, -1, getPropgetKey()); // Stack: mt, propget table (pg)
|
||||
assert(lua_istable(L, -1));
|
||||
|
||||
lua_pushvalue(L, 2); // Stack: mt, pg, field name
|
||||
lua_rawget(L, -2); // Stack: mt, pg, getter | nil
|
||||
lua_remove(L, -2); // Stack: mt, getter | nil
|
||||
|
||||
if (lua_iscfunction(L, -1)) // Stack: mt, getter
|
||||
{
|
||||
lua_remove(L, -2); // Stack: getter
|
||||
lua_pushvalue(L, 1); // Stack: getter, table | userdata
|
||||
lua_call(L, 1, 1); // Stack: value
|
||||
return 1;
|
||||
}
|
||||
|
||||
assert(lua_isnil(L, -1)); // Stack: mt, nil
|
||||
lua_pop(L, 1); // Stack: mt
|
||||
|
||||
// It may mean that the field may be in const table and it's constness violation.
|
||||
// Don't check that, just return nil
|
||||
|
||||
// Repeat the lookup in the parent metafield,
|
||||
// or return nil if the field doesn't exist.
|
||||
lua_rawgetp(L, -1, getParentKey()); // Stack: mt, parent mt | nil
|
||||
|
||||
if (lua_isnil(L, -1)) // Stack: mt, nil
|
||||
{
|
||||
lua_remove(L, -2); // Stack: nil
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Removethe metatable and repeat the search in the parent one.
|
||||
assert(lua_istable(L, -1)); // Stack: mt, parent mt
|
||||
lua_remove(L, -2); // Stack: parent mt
|
||||
}
|
||||
|
||||
// no return
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/**
|
||||
__newindex metamethod for namespace or class static members.
|
||||
Retrieves properties from propset tables.
|
||||
*/
|
||||
static int newindexStaticMetaMethod(lua_State* L) { return newindexMetaMethod(L, false); }
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/**
|
||||
__newindex metamethod for non-static members.
|
||||
Retrieves properties from propset tables.
|
||||
*/
|
||||
static int newindexObjectMetaMethod(lua_State* L) { return newindexMetaMethod(L, true); }
|
||||
|
||||
static int newindexMetaMethod(lua_State* L, bool pushSelf)
|
||||
{
|
||||
assert(
|
||||
lua_istable(L, 1) ||
|
||||
lua_isuserdata(L, 1)); // Stack (further not shown): table | userdata, name, new value
|
||||
|
||||
lua_getmetatable(L, 1); // Stack: metatable (mt)
|
||||
assert(lua_istable(L, -1));
|
||||
|
||||
for (;;)
|
||||
{
|
||||
lua_rawgetp(L, -1, getPropsetKey()); // Stack: mt, propset table (ps) | nil
|
||||
|
||||
if (lua_isnil(L, -1)) // Stack: mt, nil
|
||||
{
|
||||
lua_pop(L, 2); // Stack: -
|
||||
return luaL_error(L, "No member named '%s'", lua_tostring(L, 2));
|
||||
}
|
||||
|
||||
assert(lua_istable(L, -1));
|
||||
|
||||
lua_pushvalue(L, 2); // Stack: mt, ps, field name
|
||||
lua_rawget(L, -2); // Stack: mt, ps, setter | nil
|
||||
lua_remove(L, -2); // Stack: mt, setter | nil
|
||||
|
||||
if (lua_iscfunction(L, -1)) // Stack: mt, setter
|
||||
{
|
||||
lua_remove(L, -2); // Stack: setter
|
||||
if (pushSelf)
|
||||
{
|
||||
lua_pushvalue(L, 1); // Stack: setter, table | userdata
|
||||
}
|
||||
lua_pushvalue(L, 3); // Stack: setter, table | userdata, new value
|
||||
lua_call(L, pushSelf ? 2 : 1, 0); // Stack: -
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(lua_isnil(L, -1)); // Stack: mt, nil
|
||||
lua_pop(L, 1); // Stack: mt
|
||||
|
||||
lua_rawgetp(L, -1, getParentKey()); // Stack: mt, parent mt | nil
|
||||
|
||||
if (lua_isnil(L, -1)) // Stack: mt, nil
|
||||
{
|
||||
lua_pop(L, 1); // Stack: -
|
||||
return luaL_error(L, "No writable member '%s'", lua_tostring(L, 2));
|
||||
}
|
||||
|
||||
assert(lua_istable(L, -1)); // Stack: mt, parent mt
|
||||
lua_remove(L, -2); // Stack: parent mt
|
||||
// Repeat the search in the parent
|
||||
}
|
||||
|
||||
// no return
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/**
|
||||
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 (lightuserdata) in the first upvalue.
|
||||
*/
|
||||
template<class FnPtr>
|
||||
struct Call
|
||||
{
|
||||
typedef typename FuncTraits<FnPtr>::Params Params;
|
||||
typedef typename FuncTraits<FnPtr>::ReturnType ReturnType;
|
||||
|
||||
static int f(lua_State* L)
|
||||
{
|
||||
assert(lua_islightuserdata(L, lua_upvalueindex(1)));
|
||||
FnPtr fnptr = reinterpret_cast<FnPtr>(lua_touserdata(L, lua_upvalueindex(1)));
|
||||
assert(fnptr != 0);
|
||||
return Invoke<ReturnType, Params, 1>::run(L, fnptr);
|
||||
}
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/**
|
||||
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>
|
||||
struct CallMember
|
||||
{
|
||||
typedef typename FuncTraits<MemFnPtr>::ClassType T;
|
||||
typedef typename FuncTraits<MemFnPtr>::Params Params;
|
||||
typedef typename FuncTraits<MemFnPtr>::ReturnType ReturnType;
|
||||
|
||||
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);
|
||||
return Invoke<ReturnType, Params, 2>::run(L, t, fnptr);
|
||||
}
|
||||
};
|
||||
|
||||
template<class MemFnPtr>
|
||||
struct CallConstMember
|
||||
{
|
||||
typedef typename FuncTraits<MemFnPtr>::ClassType T;
|
||||
typedef typename FuncTraits<MemFnPtr>::Params Params;
|
||||
typedef typename FuncTraits<MemFnPtr>::ReturnType ReturnType;
|
||||
|
||||
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);
|
||||
return Invoke<ReturnType, Params, 2>::run(L, t, fnptr);
|
||||
}
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
/**
|
||||
lua_CFunction to call a class member lua_CFunction.
|
||||
|
||||
The member function pointer is in the first upvalue.
|
||||
The object userdata ('this') value is at top ot 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);
|
||||
}
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
/**
|
||||
lua_CFunction to call on a object.
|
||||
|
||||
The proxy function pointer (lightuserdata) is in the first upvalue.
|
||||
The class userdata object is at the top of the Lua stack.
|
||||
*/
|
||||
template<class FnPtr>
|
||||
struct CallProxyFunction
|
||||
{
|
||||
using Params = typename FuncTraits<FnPtr>::Params;
|
||||
using ReturnType = typename FuncTraits<FnPtr>::ReturnType;
|
||||
|
||||
static int f(lua_State* L)
|
||||
{
|
||||
assert(lua_islightuserdata(L, lua_upvalueindex(1)));
|
||||
auto fnptr = reinterpret_cast<FnPtr>(lua_touserdata(L, lua_upvalueindex(1)));
|
||||
assert(fnptr != 0);
|
||||
return Invoke<ReturnType, Params, 1>::run(L, fnptr);
|
||||
}
|
||||
};
|
||||
|
||||
template<class Functor>
|
||||
struct CallProxyFunctor
|
||||
{
|
||||
using Params = typename FuncTraits<Functor>::Params;
|
||||
using ReturnType = typename FuncTraits<Functor>::ReturnType;
|
||||
|
||||
static int f(lua_State* L)
|
||||
{
|
||||
assert(isfulluserdata(L, lua_upvalueindex(1)));
|
||||
Functor& fn = *static_cast<Functor*>(lua_touserdata(L, lua_upvalueindex(1)));
|
||||
return Invoke<ReturnType, Params, 1>::run(L, fn);
|
||||
}
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
/**
|
||||
__gc metamethod for an arbitrary class.
|
||||
*/
|
||||
template<class T>
|
||||
static int gcMetaMethodAny(lua_State* L)
|
||||
{
|
||||
assert(isfulluserdata(L, 1));
|
||||
T* t = static_cast<T*>(lua_touserdata(L, 1));
|
||||
t->~T();
|
||||
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 c = Userdata::get<C>(L, 1, true);
|
||||
T C::** mp = static_cast<T C::**>(lua_touserdata(L, lua_upvalueindex(1)));
|
||||
try
|
||||
{
|
||||
Stack<T&>::push(L, c->**mp);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
luaL_error(L, e.what());
|
||||
}
|
||||
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)));
|
||||
try
|
||||
{
|
||||
c->** mp = Stack<T>::get(L, 2);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
luaL_error(L, e.what());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace luabridge
|
||||
140
csgo2/LuaBridge/luaBridge/detail/ClassInfo.h
Normal file
140
csgo2/LuaBridge/luaBridge/detail/ClassInfo.h
Normal file
@@ -0,0 +1,140 @@
|
||||
// https://github.com/vinniefalco/LuaBridge
|
||||
// Copyright 2020, Dmitry Tarakanov
|
||||
// Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace luabridge {
|
||||
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
* A unique key for a type name in a metatable.
|
||||
*/
|
||||
inline const void* getTypeKey()
|
||||
{
|
||||
#ifdef _NDEBUG
|
||||
static char value;
|
||||
return &value;
|
||||
#else
|
||||
return reinterpret_cast<void*>(0x71);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* The key of a const table in another metatable.
|
||||
*/
|
||||
inline const void* getConstKey()
|
||||
{
|
||||
#ifdef _NDEBUG
|
||||
static char value;
|
||||
return &value;
|
||||
#else
|
||||
return reinterpret_cast<void*>(0xc07);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* The key of a class table in another metatable.
|
||||
*/
|
||||
inline const void* getClassKey()
|
||||
{
|
||||
#ifdef _NDEBUG
|
||||
static char value;
|
||||
return &value;
|
||||
#else
|
||||
return reinterpret_cast<void*>(0xc1a);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* The key of a propget table in another metatable.
|
||||
*/
|
||||
inline const void* getPropgetKey()
|
||||
{
|
||||
#ifdef _NDEBUG
|
||||
static char value;
|
||||
return &value;
|
||||
#else
|
||||
return reinterpret_cast<void*>(0x6e7);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* The key of a propset table in another metatable.
|
||||
*/
|
||||
inline const void* getPropsetKey()
|
||||
{
|
||||
#ifdef _NDEBUG
|
||||
static char value;
|
||||
return &value;
|
||||
#else
|
||||
return reinterpret_cast<void*>(0x5e7);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* The key of a static table in another metatable.
|
||||
*/
|
||||
inline const void* getStaticKey()
|
||||
{
|
||||
#ifdef _NDEBUG
|
||||
static char value;
|
||||
return &value;
|
||||
#else
|
||||
return reinterpret_cast<void*>(0x57a);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* The key of a parent table in another metatable.
|
||||
*/
|
||||
inline const void* getParentKey()
|
||||
{
|
||||
#ifdef _NDEBUG
|
||||
static char value;
|
||||
return &value;
|
||||
#else
|
||||
return reinterpret_cast<void*>(0xdad);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
Get the key for the static table in the Lua registry.
|
||||
The static table holds the static data members, static properties, and
|
||||
static member functions for a class.
|
||||
*/
|
||||
template<class T>
|
||||
void const* getStaticRegistryKey()
|
||||
{
|
||||
static char value;
|
||||
return &value;
|
||||
}
|
||||
|
||||
/** Get the key for the class table in the Lua registry.
|
||||
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).
|
||||
*/
|
||||
template<class T>
|
||||
void const* getClassRegistryKey()
|
||||
{
|
||||
static char value;
|
||||
return &value;
|
||||
}
|
||||
|
||||
/** Get the key for the const table in the Lua registry.
|
||||
The const table holds read-only data members and properties, and const
|
||||
member functions of a class.
|
||||
*/
|
||||
template<class T>
|
||||
void const* getConstRegistryKey()
|
||||
{
|
||||
static char value;
|
||||
return &value;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace luabridge
|
||||
7
csgo2/LuaBridge/luaBridge/detail/Config.h
Normal file
7
csgo2/LuaBridge/luaBridge/detail/Config.h
Normal file
@@ -0,0 +1,7 @@
|
||||
// https://github.com/vinniefalco/LuaBridge
|
||||
// Copyright 2020, Dmitry Tarakanov
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
// Empty file
|
||||
225
csgo2/LuaBridge/luaBridge/detail/Constructor.h
Normal file
225
csgo2/LuaBridge/luaBridge/detail/Constructor.h
Normal file
@@ -0,0 +1,225 @@
|
||||
// https://github.com/vinniefalco/LuaBridge
|
||||
// Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
// Copyright 2007, Nathan Reed
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace luabridge {
|
||||
|
||||
namespace detail {
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace luabridge
|
||||
435
csgo2/LuaBridge/luaBridge/detail/FuncTraits.h
Normal file
435
csgo2/LuaBridge/luaBridge/detail/FuncTraits.h
Normal file
@@ -0,0 +1,435 @@
|
||||
// https://github.com/vinniefalco/LuaBridge
|
||||
// Copyright 2020, Dmitry Tarakanov
|
||||
// Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LuaBridge/detail/Config.h>
|
||||
#include <LuaBridge/detail/TypeList.h>
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace luabridge {
|
||||
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
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.
|
||||
#define LUABRIDGE_THROWSPEC
|
||||
#else
|
||||
// Visual Studio 10 and earlier pay too much mind to useless throw () spec.
|
||||
//
|
||||
#define LUABRIDGE_THROWSPEC throw()
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
* Traits class for unrolling the type list values into function arguments.
|
||||
*/
|
||||
template<class ReturnType, size_t NUM_PARAMS>
|
||||
struct Caller;
|
||||
|
||||
template<class ReturnType>
|
||||
struct Caller<ReturnType, 0>
|
||||
{
|
||||
template<class Fn, class Params>
|
||||
static ReturnType f(Fn& fn, TypeListValues<Params>&)
|
||||
{
|
||||
return fn();
|
||||
}
|
||||
|
||||
template<class T, class MemFn, class Params>
|
||||
static ReturnType f(T* obj, MemFn& fn, TypeListValues<Params>&)
|
||||
{
|
||||
return (obj->*fn)();
|
||||
}
|
||||
};
|
||||
|
||||
template<class ReturnType>
|
||||
struct Caller<ReturnType, 1>
|
||||
{
|
||||
template<class Fn, class Params>
|
||||
static ReturnType f(Fn& fn, TypeListValues<Params>& tvl)
|
||||
{
|
||||
return fn(tvl.hd);
|
||||
}
|
||||
|
||||
template<class T, class MemFn, class Params>
|
||||
static ReturnType f(T* obj, MemFn& fn, TypeListValues<Params>& tvl)
|
||||
{
|
||||
return (obj->*fn)(tvl.hd);
|
||||
}
|
||||
};
|
||||
|
||||
template<class ReturnType>
|
||||
struct Caller<ReturnType, 2>
|
||||
{
|
||||
template<class Fn, class Params>
|
||||
static ReturnType f(Fn& fn, TypeListValues<Params>& tvl)
|
||||
{
|
||||
return fn(tvl.hd, tvl.tl.hd);
|
||||
}
|
||||
|
||||
template<class T, class MemFn, class Params>
|
||||
static ReturnType f(T* obj, MemFn& fn, TypeListValues<Params>& tvl)
|
||||
{
|
||||
return (obj->*fn)(tvl.hd, tvl.tl.hd);
|
||||
}
|
||||
};
|
||||
|
||||
template<class ReturnType>
|
||||
struct Caller<ReturnType, 3>
|
||||
{
|
||||
template<class Fn, class Params>
|
||||
static ReturnType f(Fn& fn, TypeListValues<Params>& tvl)
|
||||
{
|
||||
return fn(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd);
|
||||
}
|
||||
|
||||
template<class T, class MemFn, class Params>
|
||||
static ReturnType f(T* obj, MemFn& fn, TypeListValues<Params>& tvl)
|
||||
{
|
||||
return (obj->*fn)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd);
|
||||
}
|
||||
};
|
||||
|
||||
template<class ReturnType>
|
||||
struct Caller<ReturnType, 4>
|
||||
{
|
||||
template<class Fn, class Params>
|
||||
static ReturnType f(Fn& fn, TypeListValues<Params>& tvl)
|
||||
{
|
||||
return fn(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd);
|
||||
}
|
||||
|
||||
template<class T, class MemFn, class Params>
|
||||
static ReturnType f(T* obj, MemFn& fn, TypeListValues<Params>& tvl)
|
||||
{
|
||||
return (obj->*fn)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd);
|
||||
}
|
||||
};
|
||||
|
||||
template<class ReturnType>
|
||||
struct Caller<ReturnType, 5>
|
||||
{
|
||||
template<class Fn, class Params>
|
||||
static ReturnType f(Fn& fn, TypeListValues<Params>& tvl)
|
||||
{
|
||||
return fn(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd);
|
||||
}
|
||||
|
||||
template<class T, class MemFn, class Params>
|
||||
static ReturnType f(T* obj, MemFn& fn, TypeListValues<Params>& tvl)
|
||||
{
|
||||
return (obj->*fn)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd);
|
||||
}
|
||||
};
|
||||
|
||||
template<class ReturnType>
|
||||
struct Caller<ReturnType, 6>
|
||||
{
|
||||
template<class Fn, class Params>
|
||||
static ReturnType f(Fn& fn, TypeListValues<Params>& tvl)
|
||||
{
|
||||
return fn(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 MemFn, class Params>
|
||||
static ReturnType f(T* obj, MemFn& fn, TypeListValues<Params>& tvl)
|
||||
{
|
||||
return (obj->*fn)(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 ReturnType>
|
||||
struct Caller<ReturnType, 7>
|
||||
{
|
||||
template<class Fn, class Params>
|
||||
static ReturnType f(Fn& fn, TypeListValues<Params>& tvl)
|
||||
{
|
||||
return fn(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 MemFn, class Params>
|
||||
static ReturnType f(T* obj, MemFn& fn, TypeListValues<Params>& tvl)
|
||||
{
|
||||
return (obj->*fn)(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 ReturnType>
|
||||
struct Caller<ReturnType, 8>
|
||||
{
|
||||
template<class Fn, class Params>
|
||||
static ReturnType f(Fn& fn, TypeListValues<Params>& tvl)
|
||||
{
|
||||
return fn(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);
|
||||
}
|
||||
|
||||
template<class T, class MemFn, class Params>
|
||||
static ReturnType f(T* obj, MemFn& fn, TypeListValues<Params>& tvl)
|
||||
{
|
||||
return (obj->*fn)(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);
|
||||
}
|
||||
};
|
||||
|
||||
template<class ReturnType>
|
||||
struct Caller<ReturnType, 9>
|
||||
{
|
||||
template<class Fn, class Params>
|
||||
static ReturnType f(Fn& fn, TypeListValues<Params>& tvl)
|
||||
{
|
||||
return fn(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,
|
||||
tvl.tl.tl.tl.tl.tl.tl.tl.tl.hd);
|
||||
}
|
||||
|
||||
template<class T, class MemFn, class Params>
|
||||
static ReturnType f(T* obj, MemFn& fn, TypeListValues<Params>& tvl)
|
||||
{
|
||||
return (obj->*fn)(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,
|
||||
tvl.tl.tl.tl.tl.tl.tl.tl.tl.hd);
|
||||
}
|
||||
};
|
||||
|
||||
template<class ReturnType, class Fn, class Params>
|
||||
ReturnType doCall(Fn& fn, TypeListValues<Params>& tvl)
|
||||
{
|
||||
return Caller<ReturnType, TypeListSize<Params>::value>::f(fn, tvl);
|
||||
}
|
||||
|
||||
template<class ReturnType, class T, class MemFn, class Params>
|
||||
ReturnType doCall(T* obj, MemFn& fn, TypeListValues<Params>& tvl)
|
||||
{
|
||||
return Caller<ReturnType, TypeListSize<Params>::value>::f(obj, fn, tvl);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
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... ParamList>
|
||||
struct FuncTraits<R (*)(ParamList...)>
|
||||
{
|
||||
static bool const isMemberFunction = false;
|
||||
using DeclType = R (*)(ParamList...);
|
||||
using ReturnType = R;
|
||||
using Params = typename MakeTypeList<ParamList...>::Result;
|
||||
|
||||
static R call(const DeclType& fp, TypeListValues<Params>& tvl) { return doCall<R>(fp, tvl); }
|
||||
};
|
||||
|
||||
/* Windows: WINAPI (a.k.a. __stdcall) function pointers. */
|
||||
|
||||
#ifdef _M_IX86 // Windows 32bit only
|
||||
|
||||
template<class R, class... ParamList>
|
||||
struct FuncTraits<R(__stdcall*)(ParamList...)>
|
||||
{
|
||||
static bool const isMemberFunction = false;
|
||||
using DeclType = R(__stdcall*)(ParamList...);
|
||||
using ReturnType = R;
|
||||
using Params = typename MakeTypeList<ParamList...>::Result;
|
||||
|
||||
static R call(const DeclType& fp, TypeListValues<Params>& tvl) { return doCall<R>(fp, tvl); }
|
||||
};
|
||||
|
||||
#endif // _M_IX86
|
||||
|
||||
/* Non-const member function pointers. */
|
||||
|
||||
template<class T, class R, class... ParamList>
|
||||
struct FuncTraits<R (T::*)(ParamList...)>
|
||||
{
|
||||
static bool const isMemberFunction = true;
|
||||
static bool const isConstMemberFunction = false;
|
||||
using DeclType = R (T::*)(ParamList...);
|
||||
using ClassType = T;
|
||||
using ReturnType = R;
|
||||
using Params = typename MakeTypeList<ParamList...>::Result;
|
||||
|
||||
static R call(ClassType* obj, const DeclType& fp, TypeListValues<Params>& tvl)
|
||||
{
|
||||
return doCall<R>(obj, fp, tvl);
|
||||
}
|
||||
};
|
||||
|
||||
/* Const member function pointers. */
|
||||
|
||||
template<class T, class R, class... ParamList>
|
||||
struct FuncTraits<R (T::*)(ParamList...) const>
|
||||
{
|
||||
static bool const isMemberFunction = true;
|
||||
static bool const isConstMemberFunction = true;
|
||||
using DeclType = R (T::*)(ParamList...) const;
|
||||
using ClassType = T;
|
||||
using ReturnType = R;
|
||||
using Params = typename MakeTypeList<ParamList...>::Result;
|
||||
|
||||
static R call(const ClassType* obj, const DeclType& fp, TypeListValues<Params>& tvl)
|
||||
{
|
||||
return doCall<R>(obj, fp, tvl);
|
||||
}
|
||||
};
|
||||
|
||||
/* std::function */
|
||||
|
||||
template<class R, class... ParamList>
|
||||
struct FuncTraits<std::function<R(ParamList...)>>
|
||||
{
|
||||
static bool const isMemberFunction = false;
|
||||
static bool const isConstMemberFunction = false;
|
||||
using DeclType = std::function<R(ParamList...)>;
|
||||
using ReturnType = R;
|
||||
using Params = typename MakeTypeList<ParamList...>::Result;
|
||||
|
||||
static ReturnType call(DeclType& fn, TypeListValues<Params>& tvl)
|
||||
{
|
||||
return doCall<ReturnType>(fn, tvl);
|
||||
}
|
||||
};
|
||||
|
||||
template<class ReturnType, class Params, int startParam>
|
||||
struct Invoke
|
||||
{
|
||||
template<class Fn>
|
||||
static int run(lua_State* L, Fn& fn)
|
||||
{
|
||||
try
|
||||
{
|
||||
ArgList<Params, startParam> args(L);
|
||||
Stack<ReturnType>::push(L, FuncTraits<Fn>::call(fn, args));
|
||||
return 1;
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
return luaL_error(L, e.what());
|
||||
}
|
||||
}
|
||||
|
||||
template<class T, class MemFn>
|
||||
static int run(lua_State* L, T* object, const MemFn& fn)
|
||||
{
|
||||
try
|
||||
{
|
||||
ArgList<Params, startParam> args(L);
|
||||
Stack<ReturnType>::push(L, FuncTraits<MemFn>::call(object, fn, args));
|
||||
return 1;
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
return luaL_error(L, e.what());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<class Params, int startParam>
|
||||
struct Invoke<void, Params, startParam>
|
||||
{
|
||||
template<class Fn>
|
||||
static int run(lua_State* L, Fn& fn)
|
||||
{
|
||||
try
|
||||
{
|
||||
ArgList<Params, startParam> args(L);
|
||||
FuncTraits<Fn>::call(fn, args);
|
||||
return 0;
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
return luaL_error(L, e.what());
|
||||
}
|
||||
}
|
||||
|
||||
template<class T, class MemFn>
|
||||
static int run(lua_State* L, T* object, const MemFn& fn)
|
||||
{
|
||||
try
|
||||
{
|
||||
ArgList<Params, startParam> args(L);
|
||||
FuncTraits<MemFn>::call(object, fn, args);
|
||||
return 0;
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
return luaL_error(L, e.what());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace luabridge
|
||||
150
csgo2/LuaBridge/luaBridge/detail/Iterator.h
Normal file
150
csgo2/LuaBridge/luaBridge/detail/Iterator.h
Normal file
@@ -0,0 +1,150 @@
|
||||
// https://github.com/vinniefalco/LuaBridge
|
||||
// Copyright 2018, Dmitry Tarakanov
|
||||
// Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LuaBridge/detail/LuaRef.h>
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace luabridge {
|
||||
|
||||
/** Allows table iteration.
|
||||
*/
|
||||
class Iterator
|
||||
{
|
||||
lua_State* m_L;
|
||||
LuaRef m_table;
|
||||
LuaRef m_key;
|
||||
LuaRef m_value;
|
||||
|
||||
void next()
|
||||
{
|
||||
m_table.push();
|
||||
m_key.push();
|
||||
if (lua_next(m_L, -2))
|
||||
{
|
||||
m_value.pop();
|
||||
m_key.pop();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_key = Nil();
|
||||
m_value = Nil();
|
||||
}
|
||||
lua_pop(m_L, 1);
|
||||
}
|
||||
|
||||
public:
|
||||
explicit Iterator(const LuaRef& table, bool isEnd = false)
|
||||
: m_L(table.state())
|
||||
, m_table(table)
|
||||
, m_key(table.state()) // m_key is nil
|
||||
, m_value(table.state()) // m_value is nil
|
||||
{
|
||||
if (!isEnd)
|
||||
{
|
||||
next(); // get the first (key, value) pair from table
|
||||
}
|
||||
}
|
||||
|
||||
/// Return an associated Lua state.
|
||||
///
|
||||
/// @returns A Lua state.
|
||||
///
|
||||
lua_State* state() const { return m_L; }
|
||||
|
||||
/// Dereference the iterator.
|
||||
///
|
||||
/// @returns A key-value pair for a current table entry.
|
||||
///
|
||||
std::pair<LuaRef, LuaRef> operator*() const { return std::make_pair(m_key, m_value); }
|
||||
|
||||
/// Return the value referred by the iterator.
|
||||
///
|
||||
/// @returns A value for the current table entry.
|
||||
///
|
||||
LuaRef operator->() const { return m_value; }
|
||||
|
||||
/// Compare two iterators.
|
||||
///
|
||||
/// @param rhs Another iterator.
|
||||
/// @returns True if iterators point to the same entry of the same table,
|
||||
/// false otherwise.
|
||||
///
|
||||
bool operator!=(const Iterator& rhs) const
|
||||
{
|
||||
assert(m_L == rhs.m_L);
|
||||
return !m_table.rawequal(rhs.m_table) || !m_key.rawequal(rhs.m_key);
|
||||
}
|
||||
|
||||
/// Move the iterator to the next table entry.
|
||||
///
|
||||
/// @returns This iterator.
|
||||
///
|
||||
Iterator& operator++()
|
||||
{
|
||||
if (isNil())
|
||||
{
|
||||
// if the iterator reaches the end, do nothing
|
||||
return *this;
|
||||
}
|
||||
else
|
||||
{
|
||||
next();
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if the iterator points after the last table entry.
|
||||
///
|
||||
/// @returns True if there are no more table entries to iterate,
|
||||
/// false otherwise.
|
||||
///
|
||||
bool isNil() const { return m_key.isNil(); }
|
||||
|
||||
/// Return the key for the current table entry.
|
||||
///
|
||||
/// @returns A reference to the entry key.
|
||||
///
|
||||
LuaRef key() const { return m_key; }
|
||||
|
||||
/// Return the key for the current table entry.
|
||||
///
|
||||
/// @returns A reference to the entry value.
|
||||
///
|
||||
LuaRef value() const { return m_value; }
|
||||
|
||||
private:
|
||||
// Don't use postfix increment, it is less efficient
|
||||
Iterator operator++(int);
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
class Range
|
||||
{
|
||||
Iterator m_begin;
|
||||
Iterator m_end;
|
||||
|
||||
public:
|
||||
Range(const Iterator& begin, const Iterator& end) : m_begin(begin), m_end(end) {}
|
||||
|
||||
const Iterator& begin() const { return m_begin; }
|
||||
const Iterator& end() const { return m_end; }
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// Return a range for the Lua table reference.
|
||||
///
|
||||
/// @returns A range suitable for range-based for statement.
|
||||
///
|
||||
inline detail::Range pairs(const LuaRef& table)
|
||||
{
|
||||
return detail::Range(Iterator(table, false), Iterator(table, true));
|
||||
}
|
||||
|
||||
} // namespace luabridge
|
||||
104
csgo2/LuaBridge/luaBridge/detail/LuaException.h
Normal file
104
csgo2/LuaBridge/luaBridge/detail/LuaException.h
Normal file
@@ -0,0 +1,104 @@
|
||||
// https://github.com/vinniefalco/LuaBridge
|
||||
// Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
// Copyright 2008, Nigel Atkinson <suprapilot+LuaCode@gmail.com>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <exception>
|
||||
#include <string>
|
||||
|
||||
namespace luabridge {
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/**
|
||||
Initializes error handling. Subsequent Lua errors are translated to C++ exceptions.
|
||||
*/
|
||||
static void enableExceptions(lua_State* L) { lua_atpanic(L, throwAtPanic); }
|
||||
|
||||
/** Retrieve the lua_State associated with the exception.
|
||||
|
||||
@returns A Lua state.
|
||||
*/
|
||||
lua_State* state() const { return m_L; }
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static int throwAtPanic(lua_State* L) { throw LuaException(L, -1); }
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/**
|
||||
Initializes error handling. Subsequent Lua errors are translated to C++ exceptions.
|
||||
*/
|
||||
static void enableExceptions(lua_State* L)
|
||||
{
|
||||
LuaException::enableExceptions(L);
|
||||
}
|
||||
|
||||
} // namespace luabridge
|
||||
126
csgo2/LuaBridge/luaBridge/detail/LuaHelpers.h
Normal file
126
csgo2/LuaBridge/luaBridge/detail/LuaHelpers.h
Normal file
@@ -0,0 +1,126 @@
|
||||
// https://github.com/vinniefalco/LuaBridge
|
||||
// Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
// Copyright 2007, Nathan Reed
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace luabridge {
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
} // namespace luabridge
|
||||
1012
csgo2/LuaBridge/luaBridge/detail/LuaRef.h
Normal file
1012
csgo2/LuaBridge/luaBridge/detail/LuaRef.h
Normal file
File diff suppressed because it is too large
Load Diff
1395
csgo2/LuaBridge/luaBridge/detail/Namespace.h
Normal file
1395
csgo2/LuaBridge/luaBridge/detail/Namespace.h
Normal file
File diff suppressed because it is too large
Load Diff
58
csgo2/LuaBridge/luaBridge/detail/Security.h
Normal file
58
csgo2/LuaBridge/luaBridge/detail/Security.h
Normal file
@@ -0,0 +1,58 @@
|
||||
// https://github.com/vinniefalco/LuaBridge
|
||||
// Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace luabridge {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
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);
|
||||
}
|
||||
|
||||
} // namespace luabridge
|
||||
535
csgo2/LuaBridge/luaBridge/detail/Stack.h
Normal file
535
csgo2/LuaBridge/luaBridge/detail/Stack.h
Normal file
@@ -0,0 +1,535 @@
|
||||
// https://github.com/vinniefalco/LuaBridge
|
||||
// Copyright 2019, Dmitry Tarakanov
|
||||
// Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
// Copyright 2007, Nathan Reed
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LuaBridge/detail/LuaHelpers.h>
|
||||
#include <LuaBridge/detail/Userdata.h>
|
||||
|
||||
#include <string>
|
||||
#ifdef LUABRIDGE_CXX17
|
||||
#include <string_view>
|
||||
#endif
|
||||
|
||||
namespace luabridge {
|
||||
|
||||
/// Lua stack traits for C++ types.
|
||||
///
|
||||
/// @tparam T A C++ type.
|
||||
///
|
||||
template<class T>
|
||||
struct Stack;
|
||||
|
||||
template<>
|
||||
struct Stack<void>
|
||||
{
|
||||
static void push(lua_State*) {}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
Receive the lua_State* as an argument.
|
||||
*/
|
||||
template<>
|
||||
struct Stack<lua_State*>
|
||||
{
|
||||
static lua_State* get(lua_State* L, int) { return L; }
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
Stack specialization for 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); }
|
||||
|
||||
static bool isInstance(lua_State* L, int index) { return lua_iscfunction(L, index); }
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
Stack specialization for `int`.
|
||||
*/
|
||||
template<>
|
||||
struct Stack<int>
|
||||
{
|
||||
static void push(lua_State* L, int value)
|
||||
{
|
||||
lua_pushinteger(L, static_cast<lua_Integer>(value));
|
||||
}
|
||||
|
||||
static int get(lua_State* L, int index)
|
||||
{
|
||||
return static_cast<int>(luaL_checkinteger(L, index));
|
||||
}
|
||||
|
||||
static bool isInstance(lua_State* L, int index)
|
||||
{
|
||||
if (lua_type(L, index) != LUA_TNUMBER)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#if LUA_VERSION_NUM <= 501
|
||||
return true;
|
||||
#else
|
||||
int isNumber;
|
||||
lua_tointegerx(L, index, &isNumber);
|
||||
return isNumber;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
Stack specialization for `unsigned int`.
|
||||
*/
|
||||
template<>
|
||||
struct Stack<unsigned int>
|
||||
{
|
||||
static void push(lua_State* L, unsigned int value)
|
||||
{
|
||||
lua_pushinteger(L, static_cast<lua_Integer>(value));
|
||||
}
|
||||
|
||||
static unsigned int get(lua_State* L, int index)
|
||||
{
|
||||
return static_cast<unsigned int>(luaL_checkinteger(L, index));
|
||||
}
|
||||
|
||||
static bool isInstance(lua_State* L, int index) { return Stack<int>::isInstance(L, index); }
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
Stack specialization for `unsigned char`.
|
||||
*/
|
||||
template<>
|
||||
struct Stack<unsigned char>
|
||||
{
|
||||
static void push(lua_State* L, unsigned char value)
|
||||
{
|
||||
lua_pushinteger(L, static_cast<lua_Integer>(value));
|
||||
}
|
||||
|
||||
static unsigned char get(lua_State* L, int index)
|
||||
{
|
||||
return static_cast<unsigned char>(luaL_checkinteger(L, index));
|
||||
}
|
||||
|
||||
static bool isInstance(lua_State* L, int index) { return Stack<int>::isInstance(L, index); }
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
Stack specialization for `short`.
|
||||
*/
|
||||
template<>
|
||||
struct Stack<short>
|
||||
{
|
||||
static void push(lua_State* L, short value)
|
||||
{
|
||||
lua_pushinteger(L, static_cast<lua_Integer>(value));
|
||||
}
|
||||
|
||||
static short get(lua_State* L, int index)
|
||||
{
|
||||
return static_cast<short>(luaL_checkinteger(L, index));
|
||||
}
|
||||
|
||||
static bool isInstance(lua_State* L, int index) { return Stack<int>::isInstance(L, index); }
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
Stack specialization for `unsigned short`.
|
||||
*/
|
||||
template<>
|
||||
struct Stack<unsigned short>
|
||||
{
|
||||
static void push(lua_State* L, unsigned short value)
|
||||
{
|
||||
lua_pushinteger(L, static_cast<lua_Integer>(value));
|
||||
}
|
||||
|
||||
static unsigned short get(lua_State* L, int index)
|
||||
{
|
||||
return static_cast<unsigned short>(luaL_checkinteger(L, index));
|
||||
}
|
||||
|
||||
static bool isInstance(lua_State* L, int index) { return Stack<int>::isInstance(L, index); }
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
Stack specialization for `long`.
|
||||
*/
|
||||
template<>
|
||||
struct Stack<long>
|
||||
{
|
||||
static void push(lua_State* L, long value)
|
||||
{
|
||||
lua_pushinteger(L, static_cast<lua_Integer>(value));
|
||||
}
|
||||
|
||||
static long get(lua_State* L, int index)
|
||||
{
|
||||
return static_cast<long>(luaL_checkinteger(L, index));
|
||||
}
|
||||
|
||||
static bool isInstance(lua_State* L, int index) { return Stack<int>::isInstance(L, index); }
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
Stack specialization for `unsigned long`.
|
||||
*/
|
||||
template<>
|
||||
struct Stack<unsigned long>
|
||||
{
|
||||
static void push(lua_State* L, unsigned long value)
|
||||
{
|
||||
lua_pushinteger(L, static_cast<lua_Integer>(value));
|
||||
}
|
||||
|
||||
static unsigned long get(lua_State* L, int index)
|
||||
{
|
||||
return static_cast<unsigned long>(luaL_checkinteger(L, index));
|
||||
}
|
||||
|
||||
static bool isInstance(lua_State* L, int index) { return Stack<int>::isInstance(L, index); }
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* Stack specialization for `long long`.
|
||||
*/
|
||||
template<>
|
||||
struct Stack<long long>
|
||||
{
|
||||
static void push(lua_State* L, long long value)
|
||||
{
|
||||
lua_pushinteger(L, static_cast<lua_Integer>(value));
|
||||
}
|
||||
|
||||
static long long get(lua_State* L, int index)
|
||||
{
|
||||
return static_cast<long long>(luaL_checkinteger(L, index));
|
||||
}
|
||||
|
||||
static bool isInstance(lua_State* L, int index) { return Stack<int>::isInstance(L, index); }
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* Stack specialization for `unsigned long long`.
|
||||
*/
|
||||
template<>
|
||||
struct Stack<unsigned long long>
|
||||
{
|
||||
static void push(lua_State* L, unsigned long long value)
|
||||
{
|
||||
lua_pushinteger(L, static_cast<lua_Integer>(value));
|
||||
}
|
||||
static unsigned long long get(lua_State* L, int index)
|
||||
{
|
||||
return static_cast<unsigned long long>(luaL_checkinteger(L, index));
|
||||
}
|
||||
|
||||
static bool isInstance(lua_State* L, int index) { return Stack<int>::isInstance(L, index); }
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
Stack specialization for `float`.
|
||||
*/
|
||||
template<>
|
||||
struct Stack<float>
|
||||
{
|
||||
static void push(lua_State* L, float value)
|
||||
{
|
||||
lua_pushnumber(L, static_cast<lua_Number>(value));
|
||||
}
|
||||
|
||||
static float get(lua_State* L, int index)
|
||||
{
|
||||
return static_cast<float>(luaL_checknumber(L, index));
|
||||
}
|
||||
|
||||
static bool isInstance(lua_State* L, int index) { return lua_type(L, index) == LUA_TNUMBER; }
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
Stack specialization for `double`.
|
||||
*/
|
||||
template<>
|
||||
struct Stack<double>
|
||||
{
|
||||
static void push(lua_State* L, double value)
|
||||
{
|
||||
lua_pushnumber(L, static_cast<lua_Number>(value));
|
||||
}
|
||||
|
||||
static double get(lua_State* L, int index)
|
||||
{
|
||||
return static_cast<double>(luaL_checknumber(L, index));
|
||||
}
|
||||
|
||||
static bool isInstance(lua_State* L, int index) { return lua_type(L, index) == LUA_TNUMBER; }
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
Stack specialization for `bool`.
|
||||
*/
|
||||
template<>
|
||||
struct Stack<bool>
|
||||
{
|
||||
static void push(lua_State* L, bool value) { lua_pushboolean(L, value ? 1 : 0); }
|
||||
|
||||
static bool get(lua_State* L, int index) { return lua_toboolean(L, index) ? true : false; }
|
||||
|
||||
static bool isInstance(lua_State* L, int index) { return lua_isboolean(L, index); }
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
Stack specialization for `char`.
|
||||
*/
|
||||
template<>
|
||||
struct Stack<char>
|
||||
{
|
||||
static void push(lua_State* L, char value) { lua_pushlstring(L, &value, 1); }
|
||||
|
||||
static char get(lua_State* L, int index) { return luaL_checkstring(L, index)[0]; }
|
||||
|
||||
static bool isInstance(lua_State* L, int index) { return lua_type(L, index) == LUA_TSTRING; }
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
Stack specialization for `const char*`.
|
||||
*/
|
||||
template<>
|
||||
struct Stack<char const*>
|
||||
{
|
||||
static void push(lua_State* L, char const* str)
|
||||
{
|
||||
if (str != 0)
|
||||
lua_pushstring(L, str);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
static char const* get(lua_State* L, int index)
|
||||
{
|
||||
return lua_isnil(L, index) ? 0 : luaL_checkstring(L, index);
|
||||
}
|
||||
|
||||
static bool isInstance(lua_State* L, int index)
|
||||
{
|
||||
return lua_isnil(L, index) || lua_type(L, index) == LUA_TSTRING;
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
Stack specialization for `std::string`.
|
||||
*/
|
||||
template<>
|
||||
struct Stack<std::string>
|
||||
{
|
||||
static void push(lua_State* L, std::string const& str)
|
||||
{
|
||||
lua_pushlstring(L, str.data(), str.size());
|
||||
}
|
||||
|
||||
static std::string get(lua_State* L, int index)
|
||||
{
|
||||
size_t len;
|
||||
if (lua_type(L, index) == LUA_TSTRING)
|
||||
{
|
||||
const char* str = lua_tolstring(L, index, &len);
|
||||
return std::string(str, len);
|
||||
}
|
||||
|
||||
// Lua reference manual:
|
||||
// If the value is a number, then lua_tolstring also changes the actual value in the stack
|
||||
// to a string. (This change confuses lua_next when lua_tolstring is applied to keys during
|
||||
// a table traversal.)
|
||||
lua_pushvalue(L, index);
|
||||
const char* str = lua_tolstring(L, -1, &len);
|
||||
std::string string(str, len);
|
||||
lua_pop(L, 1); // Pop the temporary string
|
||||
return string;
|
||||
}
|
||||
|
||||
static bool isInstance(lua_State* L, int index) { return lua_type(L, index) == LUA_TSTRING; }
|
||||
};
|
||||
|
||||
#ifdef LUABRIDGE_CXX17
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
Stack specialization for `std::string`.
|
||||
*/
|
||||
template<>
|
||||
struct Stack<std::string_view>
|
||||
{
|
||||
static void push(lua_State* L, std::string_view str)
|
||||
{
|
||||
lua_pushlstring(L, str.data(), str.size());
|
||||
}
|
||||
|
||||
static std::string_view get(lua_State* L, int index)
|
||||
{
|
||||
size_t len;
|
||||
if (lua_type(L, index) == LUA_TSTRING)
|
||||
{
|
||||
const char* str = lua_tolstring(L, index, &len);
|
||||
return std::string_view(str, len);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
static bool isInstance(lua_State* L, int index) { return lua_type(L, index) == LUA_TSTRING; }
|
||||
};
|
||||
|
||||
#endif // LUABRIDGE_CXX17
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<class T>
|
||||
struct StackOpSelector<T&, false>
|
||||
{
|
||||
typedef T ReturnType;
|
||||
|
||||
static void push(lua_State* L, T& value) { Stack<T>::push(L, value); }
|
||||
|
||||
static ReturnType get(lua_State* L, int index) { return Stack<T>::get(L, index); }
|
||||
|
||||
static bool isInstance(lua_State* L, int index) { return Stack<T>::isInstance(L, index); }
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct StackOpSelector<const T&, false>
|
||||
{
|
||||
typedef T ReturnType;
|
||||
|
||||
static void push(lua_State* L, const T& value) { Stack<T>::push(L, value); }
|
||||
|
||||
static ReturnType get(lua_State* L, int index) { return Stack<T>::get(L, index); }
|
||||
|
||||
static bool isInstance(lua_State* L, int index) { return Stack<T>::isInstance(L, index); }
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct StackOpSelector<T*, false>
|
||||
{
|
||||
typedef T ReturnType;
|
||||
|
||||
static void push(lua_State* L, T* value) { Stack<T>::push(L, *value); }
|
||||
|
||||
static ReturnType get(lua_State* L, int index) { return Stack<T>::get(L, index); }
|
||||
|
||||
static bool isInstance(lua_State* L, int index) { return Stack<T>::isInstance(L, index); }
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct StackOpSelector<const T*, false>
|
||||
{
|
||||
typedef T ReturnType;
|
||||
|
||||
static void push(lua_State* L, const T* value) { Stack<T>::push(L, *value); }
|
||||
|
||||
static ReturnType get(lua_State* L, int index) { return Stack<T>::get(L, index); }
|
||||
|
||||
static bool isInstance(lua_State* L, int index) { return Stack<T>::isInstance(L, index); }
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class T>
|
||||
struct Stack<T&>
|
||||
{
|
||||
typedef detail::StackOpSelector<T&, detail::IsUserdata<T>::value> Helper;
|
||||
typedef typename Helper::ReturnType ReturnType;
|
||||
|
||||
static void push(lua_State* L, T& value) { Helper::push(L, value); }
|
||||
|
||||
static ReturnType get(lua_State* L, int index) { return Helper::get(L, index); }
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct Stack<const T&>
|
||||
{
|
||||
typedef detail::StackOpSelector<const T&, detail::IsUserdata<T>::value> Helper;
|
||||
typedef typename Helper::ReturnType ReturnType;
|
||||
|
||||
static void push(lua_State* L, const T& value) { Helper::push(L, value); }
|
||||
|
||||
static ReturnType get(lua_State* L, int index) { return Helper::get(L, index); }
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct Stack<T*>
|
||||
{
|
||||
typedef detail::StackOpSelector<T*, detail::IsUserdata<T>::value> Helper;
|
||||
typedef typename Helper::ReturnType ReturnType;
|
||||
|
||||
static void push(lua_State* L, T* value) { Helper::push(L, value); }
|
||||
|
||||
static ReturnType get(lua_State* L, int index) { return Helper::get(L, index); }
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct Stack<const T*>
|
||||
{
|
||||
typedef detail::StackOpSelector<const T*, detail::IsUserdata<T>::value> Helper;
|
||||
typedef typename Helper::ReturnType ReturnType;
|
||||
|
||||
static void push(lua_State* L, const T* value) { Helper::push(L, value); }
|
||||
|
||||
static ReturnType get(lua_State* L, int index) { return Helper::get(L, index); }
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* Push an object onto the Lua stack.
|
||||
*/
|
||||
template<class T>
|
||||
void push(lua_State* L, T t)
|
||||
{
|
||||
Stack<T>::push(L, t);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* Get an object from the Lua stack.
|
||||
*/
|
||||
template<class T>
|
||||
T get(lua_State* L, int index)
|
||||
{
|
||||
return Stack<T>::get(L, index);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* Check whether an object on the Lua stack is of type T.
|
||||
*/
|
||||
template<class T>
|
||||
bool isInstance(lua_State* L, int index)
|
||||
{
|
||||
return Stack<T>::isInstance(L, index);
|
||||
}
|
||||
|
||||
} // namespace luabridge
|
||||
183
csgo2/LuaBridge/luaBridge/detail/TypeList.h
Normal file
183
csgo2/LuaBridge/luaBridge/detail/TypeList.h
Normal file
@@ -0,0 +1,183 @@
|
||||
// https://github.com/vinniefalco/LuaBridge
|
||||
// Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
// Copyright 2007, Nathan Reed
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//==============================================================================
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LuaBridge/detail/Config.h>
|
||||
#include <LuaBridge/detail/Stack.h>
|
||||
|
||||
#include <string>
|
||||
#include <typeinfo>
|
||||
|
||||
namespace luabridge {
|
||||
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
None type means void parameters or return value.
|
||||
*/
|
||||
typedef void None;
|
||||
|
||||
template<typename Head, typename Tail = None>
|
||||
struct TypeList
|
||||
{
|
||||
typedef Tail TailType;
|
||||
};
|
||||
|
||||
template<class List>
|
||||
struct TypeListSize
|
||||
{
|
||||
static const size_t value = TypeListSize<typename List::TailType>::value + 1;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct TypeListSize<None>
|
||||
{
|
||||
static const size_t value = 0;
|
||||
};
|
||||
|
||||
template<class... Params>
|
||||
struct MakeTypeList;
|
||||
|
||||
template<class Param, class... Params>
|
||||
struct MakeTypeList<Param, Params...>
|
||||
{
|
||||
using Result = TypeList<Param, typename MakeTypeList<Params...>::Result>;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct MakeTypeList<>
|
||||
{
|
||||
using Result = None;
|
||||
};
|
||||
|
||||
/**
|
||||
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 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))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace luabridge
|
||||
112
csgo2/LuaBridge/luaBridge/detail/TypeTraits.h
Normal file
112
csgo2/LuaBridge/luaBridge/detail/TypeTraits.h
Normal file
@@ -0,0 +1,112 @@
|
||||
// https://github.com/vinniefalco/LuaBridge
|
||||
// Copyright 2019, Dmitry Tarakanov
|
||||
// Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LuaBridge/detail/Config.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace luabridge {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
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;
|
||||
typedef T Type;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
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;
|
||||
};
|
||||
/**@}*/
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace luabridge
|
||||
769
csgo2/LuaBridge/luaBridge/detail/Userdata.h
Normal file
769
csgo2/LuaBridge/luaBridge/detail/Userdata.h
Normal file
@@ -0,0 +1,769 @@
|
||||
// https://github.com/vinniefalco/LuaBridge
|
||||
// Copyright 2019, Dmitry Tarakanov
|
||||
// Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LuaBridge/detail/ClassInfo.h>
|
||||
#include <LuaBridge/detail/TypeTraits.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace luabridge {
|
||||
|
||||
namespace detail {
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Return the identity pointer for our lightuserdata tokens.
|
||||
|
||||
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:
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
Interface to a class pointer retrievable from a userdata.
|
||||
*/
|
||||
class Userdata
|
||||
{
|
||||
protected:
|
||||
void* m_p; // subclasses must set this
|
||||
|
||||
Userdata() : m_p(0) {}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
/**
|
||||
Get an untyped pointer to the contained class.
|
||||
*/
|
||||
void* 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 index, void const* /*classKey*/)
|
||||
{
|
||||
return static_cast<Userdata*>(lua_touserdata(L, lua_absindex(L, index)));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
/**
|
||||
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* registryConstKey,
|
||||
void const* registryClassKey,
|
||||
bool canBeConst)
|
||||
{
|
||||
index = lua_absindex(L, index);
|
||||
|
||||
lua_getmetatable(L, index); // Stack: object metatable (ot) | nil
|
||||
if (!lua_istable(L, -1))
|
||||
{
|
||||
lua_rawgetp(
|
||||
L, LUA_REGISTRYINDEX, registryClassKey); // Stack: registry metatable (rt) | nil
|
||||
return throwBadArg(L, index);
|
||||
}
|
||||
|
||||
lua_rawgetp(L, -1, getConstKey()); // Stack: ot | nil, const table (co) | nil
|
||||
assert(lua_istable(L, -1) || lua_isnil(L, -1));
|
||||
|
||||
// If const table is NOT present, object is const. Use non-const registry table
|
||||
// if object cannot be const, so constness validation is done automatically.
|
||||
// E.g. nonConstFn (constObj)
|
||||
// -> canBeConst = false, isConst = true
|
||||
// -> 'Class' registry table, 'const Class' object table
|
||||
// -> 'expected Class, got const Class'
|
||||
bool isConst = lua_isnil(L, -1); // Stack: ot | nil, nil, rt
|
||||
if (isConst && canBeConst)
|
||||
{
|
||||
lua_rawgetp(L, LUA_REGISTRYINDEX, registryConstKey); // Stack: ot, nil, rt
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_rawgetp(L, LUA_REGISTRYINDEX, registryClassKey); // Stack: ot, co, rt
|
||||
}
|
||||
|
||||
lua_insert(L, -3); // Stack: rt, ot, co | nil
|
||||
lua_pop(L, 1); // Stack: rt, ot
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (lua_rawequal(L, -1, -2)) // Stack: rt, ot
|
||||
{
|
||||
lua_pop(L, 2); // Stack: -
|
||||
return static_cast<Userdata*>(lua_touserdata(L, index));
|
||||
}
|
||||
|
||||
// Replace current metatable with it's base class.
|
||||
lua_rawgetp(L, -1, getParentKey()); // Stack: rt, ot, parent ot (pot) | nil
|
||||
|
||||
if (lua_isnil(L, -1)) // Stack: rt, ot, nil
|
||||
{
|
||||
// Drop the object metatable because it may be some parent metatable
|
||||
lua_pop(L, 2); // Stack: rt
|
||||
return throwBadArg(L, index);
|
||||
}
|
||||
|
||||
lua_remove(L, -2); // Stack: rt, pot
|
||||
}
|
||||
|
||||
// no return
|
||||
}
|
||||
|
||||
static bool isInstance(lua_State* L, int index, void const* registryClassKey)
|
||||
{
|
||||
index = lua_absindex(L, index);
|
||||
|
||||
int result = lua_getmetatable(L, index); // Stack: object metatable (ot) | nothing
|
||||
if (result == 0)
|
||||
{
|
||||
return false; // Nothing was pushed on the stack
|
||||
}
|
||||
if (!lua_istable(L, -1))
|
||||
{
|
||||
lua_pop(L, 1); // Stack: -
|
||||
return false;
|
||||
}
|
||||
|
||||
lua_rawgetp(L, LUA_REGISTRYINDEX, registryClassKey); // Stack: ot, rt
|
||||
lua_insert(L, -2); // Stack: rt, ot
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (lua_rawequal(L, -1, -2)) // Stack: rt, ot
|
||||
{
|
||||
lua_pop(L, 2); // Stack: -
|
||||
return true;
|
||||
}
|
||||
|
||||
// Replace current metatable with it's base class.
|
||||
lua_rawgetp(L, -1, getParentKey()); // Stack: rt, ot, parent ot (pot) | nil
|
||||
|
||||
if (lua_isnil(L, -1)) // Stack: rt, ot, nil
|
||||
{
|
||||
lua_pop(L, 3); // Stack: -
|
||||
return false;
|
||||
}
|
||||
|
||||
lua_remove(L, -2); // Stack: rt, pot
|
||||
}
|
||||
}
|
||||
|
||||
static Userdata* throwBadArg(lua_State* L, int index)
|
||||
{
|
||||
assert(lua_istable(L, -1) || lua_isnil(L, -1)); // Stack: rt | nil
|
||||
|
||||
const char* expected = 0;
|
||||
if (lua_isnil(L, -1)) // Stack: nil
|
||||
{
|
||||
expected = "unregistered class";
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_rawgetp(L, -1, getTypeKey()); // Stack: rt, registry type
|
||||
expected = lua_tostring(L, -1);
|
||||
}
|
||||
|
||||
const char* got = 0;
|
||||
if (lua_isuserdata(L, index))
|
||||
{
|
||||
lua_getmetatable(L, index); // Stack: ..., ot | nil
|
||||
if (lua_istable(L, -1)) // Stack: ..., ot
|
||||
{
|
||||
lua_rawgetp(L, -1, getTypeKey()); // Stack: ..., ot, object type | nil
|
||||
if (lua_isstring(L, -1))
|
||||
{
|
||||
got = lua_tostring(L, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!got)
|
||||
{
|
||||
got = lua_typename(L, lua_type(L, index));
|
||||
}
|
||||
|
||||
luaL_argerror(L, index, lua_pushfstring(L, "%s expected, got %s", expected, got));
|
||||
return 0;
|
||||
}
|
||||
|
||||
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.
|
||||
|
||||
@tparam T A registered user class.
|
||||
@param L A Lua state.
|
||||
@param index The index of an item on the Lua stack.
|
||||
@returns A userdata pointer if the class matches.
|
||||
*/
|
||||
template<class T>
|
||||
static Userdata* getExact(lua_State* L, int index)
|
||||
{
|
||||
return getExactClass(L, index, detail::getClassRegistryKey<T>());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
/**
|
||||
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.
|
||||
|
||||
@tparam T A registered user class.
|
||||
@param L A Lua state.
|
||||
@param index The index of an item on the Lua stack.
|
||||
@param canBeConst TBD
|
||||
@returns A pointer if the class and constness match.
|
||||
*/
|
||||
template<class T>
|
||||
static T* get(lua_State* L, int index, bool canBeConst)
|
||||
{
|
||||
if (lua_isnil(L, index))
|
||||
return 0;
|
||||
|
||||
return static_cast<T*>(getClass(L,
|
||||
index,
|
||||
detail::getConstRegistryKey<T>(),
|
||||
detail::getClassRegistryKey<T>(),
|
||||
canBeConst)
|
||||
->getPointer());
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static bool isInstance(lua_State* L, int index)
|
||||
{
|
||||
return isInstance(L, index, detail::getClassRegistryKey<T>());
|
||||
}
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/**
|
||||
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(UserdataValue<T> const&);
|
||||
UserdataValue<T> operator=(UserdataValue<T> const&);
|
||||
|
||||
char m_storage[sizeof(T)];
|
||||
|
||||
private:
|
||||
/**
|
||||
Used for placement construction.
|
||||
*/
|
||||
UserdataValue() { m_p = 0; }
|
||||
|
||||
~UserdataValue()
|
||||
{
|
||||
if (getPointer() != 0)
|
||||
{
|
||||
getObject()->~T();
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
/**
|
||||
Push a T via placement new.
|
||||
|
||||
The caller is responsible for calling placement new using the
|
||||
returned uninitialized storage.
|
||||
|
||||
@param L A Lua state.
|
||||
@returns An object referring to the newly created userdata value.
|
||||
*/
|
||||
static UserdataValue<T>* place(lua_State* const L)
|
||||
{
|
||||
UserdataValue<T>* const ud =
|
||||
new (lua_newuserdata(L, sizeof(UserdataValue<T>))) UserdataValue<T>();
|
||||
lua_rawgetp(L, LUA_REGISTRYINDEX, detail::getClassRegistryKey<T>());
|
||||
if (!lua_istable(L, -1))
|
||||
{
|
||||
throw std::logic_error("The class is not registered in LuaBridge");
|
||||
}
|
||||
lua_setmetatable(L, -2);
|
||||
return ud;
|
||||
}
|
||||
|
||||
/**
|
||||
Push T via copy construction from U.
|
||||
|
||||
@tparam U A container type.
|
||||
@param L A Lua state.
|
||||
@param u A container object reference.
|
||||
*/
|
||||
template<class U>
|
||||
static inline void push(lua_State* const L, U const& u)
|
||||
{
|
||||
UserdataValue<T>* ud = place(L);
|
||||
new (ud->getObject()) U(u);
|
||||
ud->commit();
|
||||
}
|
||||
|
||||
/**
|
||||
Confirm object construction.
|
||||
*/
|
||||
void commit() { m_p = getObject(); }
|
||||
|
||||
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]);
|
||||
}
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/**
|
||||
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 a pointer to object using metatable key.
|
||||
*/
|
||||
static void push(lua_State* L, const void* p, void const* const key)
|
||||
{
|
||||
new (lua_newuserdata(L, sizeof(UserdataPtr))) UserdataPtr(const_cast<void*>(p));
|
||||
lua_rawgetp(L, LUA_REGISTRYINDEX, key);
|
||||
if (!lua_istable(L, -1))
|
||||
{
|
||||
lua_pop(L, 1); // possibly: a nil
|
||||
throw std::logic_error("The class is not registered in LuaBridge");
|
||||
}
|
||||
lua_setmetatable(L, -2);
|
||||
}
|
||||
|
||||
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.
|
||||
|
||||
@tparam T A user registered class.
|
||||
@param L A Lua state.
|
||||
@param p A pointer to the user class instance.
|
||||
*/
|
||||
template<class T>
|
||||
static void push(lua_State* const L, T* const p)
|
||||
{
|
||||
if (p)
|
||||
push(L, p, getClassRegistryKey<T>());
|
||||
else
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
/** Push const pointer to object.
|
||||
|
||||
@tparam T A user registered class.
|
||||
@param L A Lua state.
|
||||
@param p A pointer to the user class instance.
|
||||
*/
|
||||
template<class T>
|
||||
static void push(lua_State* const L, T const* const p)
|
||||
{
|
||||
if (p)
|
||||
push(L, p, getConstRegistryKey<T>());
|
||||
else
|
||||
lua_pushnil(L);
|
||||
}
|
||||
};
|
||||
|
||||
//============================================================================
|
||||
/**
|
||||
Wraps a container that 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.
|
||||
|
||||
@tparam U A container type.
|
||||
@param u A container object reference.
|
||||
*/
|
||||
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.
|
||||
|
||||
@tparam U A container type.
|
||||
@param u A container object pointer.
|
||||
*/
|
||||
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, getClassRegistryKey<T>());
|
||||
// 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, getClassRegistryKey<T>());
|
||||
// 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, getConstRegistryKey<T>());
|
||||
// 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, getConstRegistryKey<T>());
|
||||
// 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 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 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 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.
|
||||
*/
|
||||
|
||||
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& return_type;
|
||||
|
||||
static void push(lua_State* L, T const& t) { UserdataPtr::push(L, &t); }
|
||||
|
||||
static return_type get(lua_State* L, int index)
|
||||
{
|
||||
T* t = Userdata::get<T>(L, index, true);
|
||||
|
||||
if (!t)
|
||||
luaL_error(L, "nil passed to reference");
|
||||
return *t;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Voider class template. Used to force a compiler to instantiate
|
||||
* an otherwise probably unused template parameter type T.
|
||||
* See the C++20 std::void_t <> for details.
|
||||
*/
|
||||
template<class T>
|
||||
struct Void
|
||||
{
|
||||
typedef void Type;
|
||||
};
|
||||
|
||||
/**
|
||||
* Trait class that selects whether to return a user registered
|
||||
* class object by value or by reference.
|
||||
*/
|
||||
|
||||
template<class T, class Enabler = void>
|
||||
struct UserdataGetter
|
||||
{
|
||||
typedef T* ReturnType;
|
||||
|
||||
static ReturnType get(lua_State* L, int index) { return Userdata::get<T>(L, index, false); }
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct UserdataGetter<T, typename Void<T (*)()>::Type>
|
||||
{
|
||||
typedef T ReturnType;
|
||||
|
||||
static ReturnType get(lua_State* L, int index)
|
||||
{
|
||||
return StackHelper<T, TypeTraits::isContainer<T>::value>::get(L, index);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
//==============================================================================
|
||||
|
||||
/**
|
||||
Lua stack conversions for class objects passed by value.
|
||||
*/
|
||||
template<class T>
|
||||
struct Stack
|
||||
{
|
||||
typedef void IsUserdata;
|
||||
|
||||
typedef detail::UserdataGetter<T> Getter;
|
||||
typedef typename Getter::ReturnType ReturnType;
|
||||
|
||||
static void push(lua_State* L, T const& value)
|
||||
{
|
||||
using namespace detail;
|
||||
StackHelper<T, TypeTraits::isContainer<T>::value>::push(L, value);
|
||||
}
|
||||
|
||||
static ReturnType get(lua_State* L, int index) { return Getter::get(L, index); }
|
||||
|
||||
static bool isInstance(lua_State* L, int index)
|
||||
{
|
||||
return detail::Userdata::isInstance<T>(L, index);
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
* Trait class indicating whether the parameter type must be
|
||||
* a user registered class. The trait checks the existence of
|
||||
* member type Stack::IsUserdata specialization for detection.
|
||||
*/
|
||||
template<class T, class Enable = void>
|
||||
struct IsUserdata
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct IsUserdata<T, typename Void<typename Stack<T>::IsUserdata>::Type>
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Trait class that selects a specific push/get implementation.
|
||||
*/
|
||||
template<class T, bool isUserdata>
|
||||
struct StackOpSelector;
|
||||
|
||||
// pointer
|
||||
template<class T>
|
||||
struct StackOpSelector<T*, true>
|
||||
{
|
||||
typedef T* ReturnType;
|
||||
|
||||
static void push(lua_State* L, T* value) { UserdataPtr::push(L, value); }
|
||||
|
||||
static T* get(lua_State* L, int index) { return Userdata::get<T>(L, index, false); }
|
||||
|
||||
static bool isInstance(lua_State* L, int index) { return Userdata::isInstance<T>(L, index); }
|
||||
};
|
||||
|
||||
// pointer to const
|
||||
template<class T>
|
||||
struct StackOpSelector<const T*, true>
|
||||
{
|
||||
typedef const T* ReturnType;
|
||||
|
||||
static void push(lua_State* L, const T* value) { UserdataPtr::push(L, value); }
|
||||
|
||||
static const T* get(lua_State* L, int index) { return Userdata::get<T>(L, index, true); }
|
||||
|
||||
static bool isInstance(lua_State* L, int index) { return Userdata::isInstance<T>(L, index); }
|
||||
};
|
||||
|
||||
// reference
|
||||
template<class T>
|
||||
struct StackOpSelector<T&, true>
|
||||
{
|
||||
typedef RefStackHelper<T, TypeTraits::isContainer<T>::value> Helper;
|
||||
typedef typename Helper::return_type ReturnType;
|
||||
|
||||
static void push(lua_State* L, T& value) { UserdataPtr::push(L, &value); }
|
||||
|
||||
static ReturnType get(lua_State* L, int index) { return Helper::get(L, index); }
|
||||
|
||||
static bool isInstance(lua_State* L, int index) { return Userdata::isInstance<T>(L, index); }
|
||||
};
|
||||
|
||||
// reference to const
|
||||
template<class T>
|
||||
struct StackOpSelector<const T&, true>
|
||||
{
|
||||
typedef RefStackHelper<T, TypeTraits::isContainer<T>::value> Helper;
|
||||
typedef typename Helper::return_type ReturnType;
|
||||
|
||||
static void push(lua_State* L, const T& value) { Helper::push(L, value); }
|
||||
|
||||
static ReturnType get(lua_State* L, int index) { return Helper::get(L, index); }
|
||||
|
||||
static bool isInstance(lua_State* L, int index) { return Userdata::isInstance<T>(L, index); }
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace luabridge
|
||||
125
csgo2/LuaBridge/luaBridge/detail/dump.h
Normal file
125
csgo2/LuaBridge/luaBridge/detail/dump.h
Normal file
@@ -0,0 +1,125 @@
|
||||
// https://github.com/vinniefalco/LuaBridge
|
||||
// Copyright 2019, Dmitry Tarakanov
|
||||
// Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
// Copyright 2007, Nathan Reed
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "LuaBridge/detail/ClassInfo.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
namespace luabridge {
|
||||
|
||||
namespace debug {
|
||||
|
||||
inline void putIndent(std::ostream& stream, unsigned level)
|
||||
{
|
||||
for (unsigned i = 0; i < level; ++i)
|
||||
{
|
||||
stream << " ";
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
dumpTable(lua_State* L, int index, std::ostream& stream, unsigned level, unsigned maxDepth);
|
||||
|
||||
inline void
|
||||
dumpValue(lua_State* L, int index, std::ostream& stream, unsigned maxDepth = 1, unsigned level = 0)
|
||||
{
|
||||
const int type = lua_type(L, index);
|
||||
switch (type)
|
||||
{
|
||||
case LUA_TNIL:
|
||||
stream << "nil";
|
||||
break;
|
||||
|
||||
case LUA_TBOOLEAN:
|
||||
stream << (lua_toboolean(L, index) ? "true" : "false");
|
||||
break;
|
||||
|
||||
case LUA_TNUMBER:
|
||||
stream << lua_tonumber(L, index);
|
||||
break;
|
||||
|
||||
case LUA_TSTRING:
|
||||
stream << '"' << lua_tostring(L, index) << '"';
|
||||
break;
|
||||
|
||||
case LUA_TFUNCTION:
|
||||
if (lua_iscfunction(L, index))
|
||||
{
|
||||
stream << "cfunction@" << lua_topointer(L, index);
|
||||
}
|
||||
else
|
||||
{
|
||||
stream << "function@" << lua_topointer(L, index);
|
||||
}
|
||||
break;
|
||||
|
||||
case LUA_TTHREAD:
|
||||
stream << "thread@" << lua_tothread(L, index);
|
||||
break;
|
||||
|
||||
case LUA_TLIGHTUSERDATA:
|
||||
stream << "lightuserdata@" << lua_touserdata(L, index);
|
||||
break;
|
||||
|
||||
case LUA_TTABLE:
|
||||
dumpTable(L, index, stream, level, maxDepth);
|
||||
break;
|
||||
|
||||
case LUA_TUSERDATA:
|
||||
stream << "userdata@" << lua_touserdata(L, index);
|
||||
break;
|
||||
|
||||
default:
|
||||
stream << lua_typename(L, type);
|
||||
;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
dumpTable(lua_State* L, int index, std::ostream& stream, unsigned level, unsigned maxDepth)
|
||||
{
|
||||
stream << "table@" << lua_topointer(L, index);
|
||||
|
||||
if (level > maxDepth)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
index = lua_absindex(L, index);
|
||||
stream << " {";
|
||||
lua_pushnil(L); // Initial key
|
||||
while (lua_next(L, index))
|
||||
{
|
||||
stream << "\n";
|
||||
putIndent(stream, level + 1);
|
||||
dumpValue(L, -2, stream, maxDepth, level + 1); // Key
|
||||
stream << ": ";
|
||||
dumpValue(L, -1, stream, maxDepth, level + 1); // Value
|
||||
lua_pop(L, 1); // Value
|
||||
}
|
||||
stream << "\n";
|
||||
putIndent(stream, level);
|
||||
stream << "}";
|
||||
}
|
||||
|
||||
inline void dumpState(lua_State* L, std::ostream& stream = std::cerr, unsigned maxDepth = 1)
|
||||
{
|
||||
int top = lua_gettop(L);
|
||||
for (int i = 1; i <= top; ++i)
|
||||
{
|
||||
stream << "stack #" << i << ": ";
|
||||
dumpValue(L, i, stream, maxDepth, 0);
|
||||
stream << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace debug
|
||||
|
||||
} // namespace luabridge
|
||||
Reference in New Issue
Block a user