#include <boost/type_traits.hpp>
#include <lua.hpp>
-#ifdef _MSC_VER
+#if defined(_MSC_VER) && _MSC_VER < 1900
# include "misc/exception.hpp"
#endif
template<typename TFunctionType>
class LuaFunctionCaller;
+ /**
+ * Opaque type that identifies a Lua object
+ */
+ struct LuaObject {
+ LuaObject() = default;
+ LuaObject(lua_State* state, int index=-1) {
+ this->objectInRegistry = std::make_shared<LuaContext::ValueInRegistry>(state, index);
+ }
+ std::shared_ptr<LuaContext::ValueInRegistry> objectInRegistry;
+ };
+
/**
* Opaque type that identifies a Lua thread
*/
* @tparam TType Type whose function belongs to
*/
template<typename TType>
- void unregisterFunction(const std::string& functionName)
+ void unregisterFunction(const std::string& /*functionName*/)
{
lua_pushlightuserdata(mState, const_cast<std::type_info*>(&typeid(TType)));
lua_pushnil(mState);
result.threadInRegistry = std::unique_ptr<ValueInRegistry>(new ValueInRegistry(mState));
lua_pop(mState, 1);
- return std::move(result);
+ return result;
}
/**
PushedObject& operator=(PushedObject&& other) { std::swap(state, other.state); std::swap(num, other.num); return *this; }
PushedObject(PushedObject&& other) : state(other.state), num(other.num) { other.num = 0; }
- PushedObject operator+(PushedObject&& other) && { PushedObject obj(state, num + other.num); num = 0; other.num = 0; return std::move(obj); }
+ PushedObject operator+(PushedObject&& other) && { PushedObject obj(state, num + other.num); num = 0; other.num = 0; return obj; }
void operator+=(PushedObject&& other) { assert(state == other.state); num += other.num; other.num = 0; }
auto getState() const -> lua_State* { return state; }
std::array<char,512> buffer;
// read function ; "data" must be an instance of Reader
- static const char* read(lua_State* l, void* data, size_t* size) {
+ static const char* read(lua_State* /*l*/, void* data, size_t* size) {
assert(size != nullptr);
assert(data != nullptr);
Reader& me = *static_cast<Reader*>(data);
RealReturnType;
// we push the parameters on the stack
- auto inArguments = Pusher<std::tuple<TParameters...>>::push(state, std::forward_as_tuple((input)...));
+ auto inArguments = Pusher<std::tuple<TParameters&&...>>::push(state, std::forward_as_tuple(std::forward<TParameters>(input)...));
//
const int outArgumentsCount = std::tuple_size<RealReturnType>::value;
lua_setmetatable(state, -2);
pushedTable.release();
- return std::move(obj);
+ return obj;
}
};
* This functions reads multiple values starting at "index" and passes them to the callback
*/
template<typename TRetValue, typename TCallback>
- static auto readIntoFunction(lua_State* state, tag<TRetValue>, TCallback&& callback, int index)
+ static auto readIntoFunction(lua_State* /*state*/, tag<TRetValue>, TCallback&& callback, int /*index*/)
-> TRetValue
{
return callback();
const auto& firstElem = Reader<typename std::decay<TFirstType>::type>::read(state, index);
if (!firstElem)
- throw WrongTypeException(lua_typename(state, index), typeid(TFirstType));
+ throw WrongTypeException(lua_typename(state, lua_type(state, index)), typeid(TFirstType));
Binder<TCallback, const TFirstType&> binder{ callback, *firstElem };
return readIntoFunction(state, retValueTag, binder, index + 1, othersTags...);
const auto& firstElem = Reader<typename std::decay<TFirstType>::type>::read(state, index);
if (!firstElem)
- throw WrongTypeException(lua_typename(state, index), typeid(TFirstType));
+ throw WrongTypeException(lua_typename(state, lua_type(state, index)), typeid(TFirstType));
Binder<TCallback, const TFirstType&> binder{ callback, *firstElem };
return readIntoFunction(state, retValueTag, binder, index + 1, othersTags...);
/* PARTIAL IMPLEMENTATIONS */
/**************************************************/
template<>
-inline auto LuaContext::readTopAndPop<void>(lua_State* state, PushedObject obj)
+inline auto LuaContext::readTopAndPop<void>(lua_State* /*state*/, PushedObject /*obj*/)
-> void
{
}
/**************************************************/
// specializations of the Pusher structure
+// opaque Lua references
+template<>
+struct LuaContext::Pusher<LuaContext::LuaObject> {
+ static const int minSize = 1;
+ static const int maxSize = 1;
+
+ static PushedObject push(lua_State* state, const LuaContext::LuaObject& value) noexcept {
+ if (value.objectInRegistry.get()) {
+ PushedObject obj = value.objectInRegistry->pop();
+ return obj;
+ } else {
+ lua_pushnil(state);
+ return PushedObject{state, 1};
+ }
+ }
+};
+
// boolean
template<>
struct LuaContext::Pusher<bool> {
static const int minSize = 1;
static const int maxSize = 1;
- static PushedObject push(lua_State* state, std::nullptr_t value) noexcept {
- assert(value == nullptr);
+ static PushedObject push(lua_State* state, std::nullptr_t) noexcept {
lua_pushnil(state);
return PushedObject{state, 1};
}
for (auto i = value.begin(), e = value.end(); i != e; ++i)
setTable<TValue>(state, obj, i->first, i->second);
- return std::move(obj);
+ return obj;
}
};
for (auto i = value.begin(), e = value.end(); i != e; ++i)
setTable<TValue>(state, obj, i->first, i->second);
- return std::move(obj);
+ return obj;
}
};
for (auto i = value.begin(), e = value.end(); i != e; ++i)
setTable<TType2>(state, obj, i->first, i->second);
- return std::move(obj);
+ return obj;
}
};
for (unsigned int i = 0; i < value.size(); ++i)
setTable<TType>(state, obj, i + 1, value[i]);
- return std::move(obj);
+ return obj;
}
};
PushedObject obj{state, 0};
VariantWriter writer{state, obj};
value.apply_visitor(writer);
- return std::move(obj);
+ return obj;
}
private:
push2(state, std::move(value), std::integral_constant<int,N+1>{});
}
- static int push2(lua_State* state, const std::tuple<TTypes...>&, std::integral_constant<int,sizeof...(TTypes)>) noexcept {
+ static int push2(lua_State* /*state*/, const std::tuple<TTypes...>&, std::integral_constant<int,sizeof...(TTypes)>) noexcept {
return 0;
}
- static int push2(lua_State* state, std::tuple<TTypes...>&&, std::integral_constant<int,sizeof...(TTypes)>) noexcept {
+ static int push2(lua_State* /*state*/, std::tuple<TTypes...>&&, std::integral_constant<int,sizeof...(TTypes)>) noexcept {
return 0;
}
};
/**************************************************/
// specializations of the Reader structures
+// opaque Lua references
+template<>
+struct LuaContext::Reader<LuaContext::LuaObject>
+{
+ static auto read(lua_State* state, int index)
+ -> boost::optional<LuaContext::LuaObject>
+ {
+ LuaContext::LuaObject obj(state, index);
+ return obj;
+ }
+};
+
// reading null
template<>
struct LuaContext::Reader<std::nullptr_t>
return {};
}
- result.push_back({ std::move(val1.get()), std::move(val2.get()) });
+ result.push_back({ val1.get(), val2.get() });
lua_pop(state, 1); // we remove the value but keep the key for the next iteration
} catch(...) {
return {};
}
- result.insert({ std::move(key.get()), std::move(value.get()) });
+ result.insert({ key.get(), value.get() });
lua_pop(state, 1); // we remove the value but keep the key for the next iteration
} catch(...) {
return {};
}
- result.insert({ std::move(key.get()), std::move(value.get()) });
+ result.insert({ key.get(), value.get() });
lua_pop(state, 1); // we remove the value but keep the key for the next iteration
} catch(...) {
template<typename TIterBegin, typename TIterEnd>
struct VariantReader<TIterBegin, TIterEnd, typename std::enable_if<boost::mpl::distance<TIterBegin, TIterEnd>::type::value == 0>::type>
{
- static auto read(lua_State* state, int index)
+ static auto read(lua_State* /*state*/, int /*index*/)
-> boost::optional<ReturnType>
{
return boost::none;
template<>
struct LuaContext::Reader<std::tuple<>>
{
- static auto read(lua_State* state, int index, int maxSize = 0)
+ static auto read(lua_State* /*state*/, int /*index*/, int /*maxSize*/ = 0)
-> boost::optional<std::tuple<>>
{
return std::tuple<>{};