Fix leak issues and some ordering in state(view) move operations. Closes #336.

This commit is contained in:
ThePhD 2017-02-15 05:42:44 -05:00
parent fe8b1c1c10
commit 85194e0135
7 changed files with 1279 additions and 1183 deletions

1
.gitignore vendored
View File

@ -71,3 +71,4 @@ LuaJIT-2.1.0/
lua-5.3.3-cxx/ lua-5.3.3-cxx/
lua-5.3.3.vcxproj-cxx.filters lua-5.3.3.vcxproj-cxx.filters
sol.pyproj sol.pyproj
lua-5.3.3.dll

View File

@ -20,8 +20,8 @@
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// This file was generated with a script. // This file was generated with a script.
// Generated 2017-02-01 11:49:07.483904 UTC // Generated 2017-02-15 10:41:27.152230 UTC
// This header was generated with sol v2.15.7 (revision 8d6f304) // This header was generated with sol v2.15.7 (revision fe8b1c1)
// https://github.com/ThePhD/sol2 // https://github.com/ThePhD/sol2
#ifndef SOL_SINGLE_INCLUDE_HPP #ifndef SOL_SINGLE_INCLUDE_HPP
@ -3953,6 +3953,9 @@ namespace sol {
} }
reference& operator=(reference&& o) noexcept { reference& operator=(reference&& o) noexcept {
if (valid()) {
deref();
}
luastate = o.luastate; luastate = o.luastate;
ref = o.ref; ref = o.ref;
@ -4610,7 +4613,39 @@ namespace sol {
namespace sol { namespace sol {
namespace detail { namespace detail {
#ifdef _MSC_VER #if defined(__GNUC__) || defined(__clang__)
template <typename T, class seperator_mark = int>
inline std::string ctti_get_type_name() {
const static std::array<std::string, 2> removals = { { "{anonymous}", "(anonymous namespace)" } };
std::string name = __PRETTY_FUNCTION__;
std::size_t start = name.find_first_of('[');
start = name.find_first_of('=', start);
std::size_t end = name.find_last_of(']');
if (end == std::string::npos)
end = name.size();
if (start == std::string::npos)
start = 0;
if (start < name.size() - 1)
start += 1;
name = name.substr(start, end - start);
start = name.rfind("seperator_mark");
if (start != std::string::npos) {
name.erase(start - 2, name.length());
}
while (!name.empty() && std::isblank(name.front())) name.erase(name.begin());
while (!name.empty() && std::isblank(name.back())) name.pop_back();
for (std::size_t r = 0; r < removals.size(); ++r) {
auto found = name.find(removals[r]);
while (found != std::string::npos) {
name.erase(found, removals[r].size());
found = name.find(removals[r]);
}
}
return name;
}
#elif defined(_MSC_VER)
template <typename T> template <typename T>
inline std::string ctti_get_type_name() { inline std::string ctti_get_type_name() {
const static std::array<std::string, 7> removals = { { "public:", "private:", "protected:", "struct ", "class ", "`anonymous-namespace'", "`anonymous namespace'" } }; const static std::array<std::string, 7> removals = { { "public:", "private:", "protected:", "struct ", "class ", "`anonymous-namespace'", "`anonymous namespace'" } };
@ -4641,38 +4676,6 @@ namespace sol {
} }
} }
return name;
}
#elif defined(__GNUC__) || defined(__clang__)
template <typename T, class seperator_mark = int>
inline std::string ctti_get_type_name() {
const static std::array<std::string, 2> removals = { { "{anonymous}", "(anonymous namespace)" } };
std::string name = __PRETTY_FUNCTION__;
std::size_t start = name.find_first_of('[');
start = name.find_first_of('=', start);
std::size_t end = name.find_last_of(']');
if (end == std::string::npos)
end = name.size();
if (start == std::string::npos)
start = 0;
if (start < name.size() - 1)
start += 1;
name = name.substr(start, end - start);
start = name.rfind("seperator_mark");
if (start != std::string::npos) {
name.erase(start - 2, name.length());
}
while (!name.empty() && std::isblank(name.front())) name.erase(name.begin());
while (!name.empty() && std::isblank(name.back())) name.pop_back();
for (std::size_t r = 0; r < removals.size(); ++r) {
auto found = name.find(removals[r]);
while (found != std::string::npos) {
name.erase(found, removals[r].size());
found = name.find(removals[r]);
}
}
return name; return name;
} }
#else #else
@ -12885,7 +12888,11 @@ namespace sol {
state(const state&) = delete; state(const state&) = delete;
state(state&&) = default; state(state&&) = default;
state& operator=(const state&) = delete; state& operator=(const state&) = delete;
state& operator=(state&&) = default; state& operator=(state&& that) {
state_view::operator=(std::move(that));
unique_base::operator=(std::move(that));
return *this;
}
using state_view::get; using state_view::get;

View File

@ -1,158 +1,158 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors // Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in // this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to // the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so, // the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions: // subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all // The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software. // copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_DEMANGLE_HPP #ifndef SOL_DEMANGLE_HPP
#define SOL_DEMANGLE_HPP #define SOL_DEMANGLE_HPP
#include <string> #include <string>
#include <array> #include <array>
#include <cctype> #include <cctype>
namespace sol { namespace sol {
namespace detail { namespace detail {
#ifdef _MSC_VER #if defined(__GNUC__) || defined(__clang__)
template <typename T> template <typename T, class seperator_mark = int>
inline std::string ctti_get_type_name() { inline std::string ctti_get_type_name() {
const static std::array<std::string, 7> removals = { { "public:", "private:", "protected:", "struct ", "class ", "`anonymous-namespace'", "`anonymous namespace'" } }; const static std::array<std::string, 2> removals = { { "{anonymous}", "(anonymous namespace)" } };
std::string name = __FUNCSIG__; std::string name = __PRETTY_FUNCTION__;
std::size_t start = name.find("get_type_name"); std::size_t start = name.find_first_of('[');
if (start == std::string::npos) start = name.find_first_of('=', start);
start = 0; std::size_t end = name.find_last_of(']');
else if (end == std::string::npos)
start += 13; end = name.size();
if (start < name.size() - 1) if (start == std::string::npos)
start += 1; start = 0;
std::size_t end = name.find_last_of('>'); if (start < name.size() - 1)
if (end == std::string::npos) start += 1;
end = name.size(); name = name.substr(start, end - start);
name = name.substr(start, end - start); start = name.rfind("seperator_mark");
if (name.find("struct", 0) == 0) if (start != std::string::npos) {
name.replace(0, 6, "", 0); name.erase(start - 2, name.length());
if (name.find("class", 0) == 0) }
name.replace(0, 5, "", 0); while (!name.empty() && std::isblank(name.front())) name.erase(name.begin());
while (!name.empty() && std::isblank(name.front())) name.erase(name.begin()); while (!name.empty() && std::isblank(name.back())) name.pop_back();
while (!name.empty() && std::isblank(name.back())) name.pop_back();
for (std::size_t r = 0; r < removals.size(); ++r) {
for (std::size_t r = 0; r < removals.size(); ++r) { auto found = name.find(removals[r]);
auto found = name.find(removals[r]); while (found != std::string::npos) {
while (found != std::string::npos) { name.erase(found, removals[r].size());
name.erase(found, removals[r].size()); found = name.find(removals[r]);
found = name.find(removals[r]); }
} }
}
return name;
return name; }
} #elif defined(_MSC_VER)
#elif defined(__GNUC__) || defined(__clang__) template <typename T>
template <typename T, class seperator_mark = int> inline std::string ctti_get_type_name() {
inline std::string ctti_get_type_name() { const static std::array<std::string, 7> removals = { { "public:", "private:", "protected:", "struct ", "class ", "`anonymous-namespace'", "`anonymous namespace'" } };
const static std::array<std::string, 2> removals = { { "{anonymous}", "(anonymous namespace)" } }; std::string name = __FUNCSIG__;
std::string name = __PRETTY_FUNCTION__; std::size_t start = name.find("get_type_name");
std::size_t start = name.find_first_of('['); if (start == std::string::npos)
start = name.find_first_of('=', start); start = 0;
std::size_t end = name.find_last_of(']'); else
if (end == std::string::npos) start += 13;
end = name.size(); if (start < name.size() - 1)
if (start == std::string::npos) start += 1;
start = 0; std::size_t end = name.find_last_of('>');
if (start < name.size() - 1) if (end == std::string::npos)
start += 1; end = name.size();
name = name.substr(start, end - start); name = name.substr(start, end - start);
start = name.rfind("seperator_mark"); if (name.find("struct", 0) == 0)
if (start != std::string::npos) { name.replace(0, 6, "", 0);
name.erase(start - 2, name.length()); if (name.find("class", 0) == 0)
} name.replace(0, 5, "", 0);
while (!name.empty() && std::isblank(name.front())) name.erase(name.begin()); while (!name.empty() && std::isblank(name.front())) name.erase(name.begin());
while (!name.empty() && std::isblank(name.back())) name.pop_back(); while (!name.empty() && std::isblank(name.back())) name.pop_back();
for (std::size_t r = 0; r < removals.size(); ++r) { for (std::size_t r = 0; r < removals.size(); ++r) {
auto found = name.find(removals[r]); auto found = name.find(removals[r]);
while (found != std::string::npos) { while (found != std::string::npos) {
name.erase(found, removals[r].size()); name.erase(found, removals[r].size());
found = name.find(removals[r]); found = name.find(removals[r]);
} }
} }
return name; return name;
} }
#else #else
#error Compiler not supported for demangling #error Compiler not supported for demangling
#endif // compilers #endif // compilers
template <typename T> template <typename T>
inline std::string demangle_once() { inline std::string demangle_once() {
std::string realname = ctti_get_type_name<T>(); std::string realname = ctti_get_type_name<T>();
return realname; return realname;
} }
template <typename T> template <typename T>
inline std::string short_demangle_once() { inline std::string short_demangle_once() {
std::string realname = ctti_get_type_name<T>(); std::string realname = ctti_get_type_name<T>();
// This isn't the most complete but it'll do for now...? // This isn't the most complete but it'll do for now...?
static const std::array<std::string, 10> ops = { { "operator<", "operator<<", "operator<<=", "operator<=", "operator>", "operator>>", "operator>>=", "operator>=", "operator->", "operator->*" } }; static const std::array<std::string, 10> ops = { { "operator<", "operator<<", "operator<<=", "operator<=", "operator>", "operator>>", "operator>>=", "operator>=", "operator->", "operator->*" } };
int level = 0; int level = 0;
std::ptrdiff_t idx = 0; std::ptrdiff_t idx = 0;
for (idx = static_cast<std::ptrdiff_t>(realname.empty() ? 0 : realname.size() - 1); idx > 0; --idx) { for (idx = static_cast<std::ptrdiff_t>(realname.empty() ? 0 : realname.size() - 1); idx > 0; --idx) {
if (level == 0 && realname[idx] == ':') { if (level == 0 && realname[idx] == ':') {
break; break;
} }
bool isleft = realname[idx] == '<'; bool isleft = realname[idx] == '<';
bool isright = realname[idx] == '>'; bool isright = realname[idx] == '>';
if (!isleft && !isright) if (!isleft && !isright)
continue; continue;
bool earlybreak = false; bool earlybreak = false;
for (const auto& op : ops) { for (const auto& op : ops) {
std::size_t nisop = realname.rfind(op, idx); std::size_t nisop = realname.rfind(op, idx);
if (nisop == std::string::npos) if (nisop == std::string::npos)
continue; continue;
std::size_t nisopidx = idx - op.size() + 1; std::size_t nisopidx = idx - op.size() + 1;
if (nisop == nisopidx) { if (nisop == nisopidx) {
idx = static_cast<std::ptrdiff_t>(nisopidx); idx = static_cast<std::ptrdiff_t>(nisopidx);
earlybreak = true; earlybreak = true;
} }
break; break;
} }
if (earlybreak) { if (earlybreak) {
continue; continue;
} }
level += isleft ? -1 : 1; level += isleft ? -1 : 1;
} }
if (idx > 0) { if (idx > 0) {
realname.erase(0, realname.length() < static_cast<std::size_t>(idx) ? realname.length() : idx + 1); realname.erase(0, realname.length() < static_cast<std::size_t>(idx) ? realname.length() : idx + 1);
} }
return realname; return realname;
} }
template <typename T> template <typename T>
inline const std::string& demangle() { inline const std::string& demangle() {
static const std::string d = demangle_once<T>(); static const std::string d = demangle_once<T>();
return d; return d;
} }
template <typename T> template <typename T>
inline const std::string& short_demangle() { inline const std::string& short_demangle() {
static const std::string d = short_demangle_once<T>(); static const std::string d = short_demangle_once<T>();
return d; return d;
} }
} // detail } // detail
} // sol } // sol
#endif // SOL_DEMANGLE_HPP #endif // SOL_DEMANGLE_HPP

View File

@ -1,191 +1,194 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors // Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in // this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to // the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so, // the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions: // subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all // The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software. // copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_REFERENCE_HPP #ifndef SOL_REFERENCE_HPP
#define SOL_REFERENCE_HPP #define SOL_REFERENCE_HPP
#include "types.hpp" #include "types.hpp"
#include "stack_reference.hpp" #include "stack_reference.hpp"
namespace sol { namespace sol {
namespace stack { namespace stack {
template <bool top_level> template <bool top_level>
struct push_popper_n { struct push_popper_n {
lua_State* L; lua_State* L;
int t; int t;
push_popper_n(lua_State* luastate, int x) : L(luastate), t(x) { } push_popper_n(lua_State* luastate, int x) : L(luastate), t(x) { }
~push_popper_n() { lua_pop(L, t); } ~push_popper_n() { lua_pop(L, t); }
}; };
template <> template <>
struct push_popper_n<true> { struct push_popper_n<true> {
push_popper_n(lua_State*, int) { } push_popper_n(lua_State*, int) { }
}; };
template <bool top_level, typename T> template <bool top_level, typename T>
struct push_popper { struct push_popper {
T t; T t;
push_popper(T x) : t(x) { t.push(); } push_popper(T x) : t(x) { t.push(); }
~push_popper() { t.pop(); } ~push_popper() { t.pop(); }
}; };
template <typename T> template <typename T>
struct push_popper<true, T> { struct push_popper<true, T> {
push_popper(T) {} push_popper(T) {}
~push_popper() {} ~push_popper() {}
}; };
template <bool top_level = false, typename T> template <bool top_level = false, typename T>
push_popper<top_level, T> push_pop(T&& x) { push_popper<top_level, T> push_pop(T&& x) {
return push_popper<top_level, T>(std::forward<T>(x)); return push_popper<top_level, T>(std::forward<T>(x));
} }
template <bool top_level = false> template <bool top_level = false>
push_popper_n<top_level> pop_n(lua_State* L, int x) { push_popper_n<top_level> pop_n(lua_State* L, int x) {
return push_popper_n<top_level>(L, x); return push_popper_n<top_level>(L, x);
} }
} // stack } // stack
namespace detail { namespace detail {
struct global_tag { } const global_{}; struct global_tag { } const global_{};
} // detail } // detail
class reference { class reference {
private: private:
lua_State* luastate = nullptr; // non-owning lua_State* luastate = nullptr; // non-owning
int ref = LUA_NOREF; int ref = LUA_NOREF;
int copy() const noexcept { int copy() const noexcept {
if (ref == LUA_NOREF) if (ref == LUA_NOREF)
return LUA_NOREF; return LUA_NOREF;
push(); push();
return luaL_ref(lua_state(), LUA_REGISTRYINDEX); return luaL_ref(lua_state(), LUA_REGISTRYINDEX);
} }
protected: protected:
reference(lua_State* L, detail::global_tag) noexcept : luastate(L) { reference(lua_State* L, detail::global_tag) noexcept : luastate(L) {
lua_pushglobaltable(lua_state()); lua_pushglobaltable(lua_state());
ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX); ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
} }
int stack_index() const noexcept { int stack_index() const noexcept {
return -1; return -1;
} }
void deref() const noexcept { void deref() const noexcept {
luaL_unref(lua_state(), LUA_REGISTRYINDEX, ref); luaL_unref(lua_state(), LUA_REGISTRYINDEX, ref);
} }
public: public:
reference() noexcept = default; reference() noexcept = default;
reference(lua_nil_t) noexcept : reference() {} reference(lua_nil_t) noexcept : reference() {}
reference(const stack_reference& r) noexcept : reference(r.lua_state(), r.stack_index()) {} reference(const stack_reference& r) noexcept : reference(r.lua_state(), r.stack_index()) {}
reference(stack_reference&& r) noexcept : reference(r.lua_state(), r.stack_index()) {} reference(stack_reference&& r) noexcept : reference(r.lua_state(), r.stack_index()) {}
reference(lua_State* L, int index = -1) noexcept : luastate(L) { reference(lua_State* L, int index = -1) noexcept : luastate(L) {
lua_pushvalue(lua_state(), index); lua_pushvalue(lua_state(), index);
ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX); ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
} }
reference(lua_State* L, ref_index index) noexcept : luastate(L) { reference(lua_State* L, ref_index index) noexcept : luastate(L) {
lua_rawgeti(L, LUA_REGISTRYINDEX, index.index); lua_rawgeti(L, LUA_REGISTRYINDEX, index.index);
ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX); ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
} }
~reference() noexcept { ~reference() noexcept {
deref(); deref();
} }
reference(reference&& o) noexcept { reference(reference&& o) noexcept {
luastate = o.luastate; luastate = o.luastate;
ref = o.ref; ref = o.ref;
o.luastate = nullptr; o.luastate = nullptr;
o.ref = LUA_NOREF; o.ref = LUA_NOREF;
} }
reference& operator=(reference&& o) noexcept { reference& operator=(reference&& o) noexcept {
luastate = o.luastate; if (valid()) {
ref = o.ref; deref();
}
o.luastate = nullptr; luastate = o.luastate;
o.ref = LUA_NOREF; ref = o.ref;
return *this; o.luastate = nullptr;
} o.ref = LUA_NOREF;
reference(const reference& o) noexcept { return *this;
luastate = o.luastate; }
ref = o.copy();
} reference(const reference& o) noexcept {
luastate = o.luastate;
reference& operator=(const reference& o) noexcept { ref = o.copy();
luastate = o.luastate; }
deref();
ref = o.copy(); reference& operator=(const reference& o) noexcept {
return *this; luastate = o.luastate;
} deref();
ref = o.copy();
int push() const noexcept { return *this;
return push(lua_state()); }
}
int push() const noexcept {
int push(lua_State* Ls) const noexcept { return push(lua_state());
lua_rawgeti(Ls, LUA_REGISTRYINDEX, ref); }
return 1;
} int push(lua_State* Ls) const noexcept {
lua_rawgeti(Ls, LUA_REGISTRYINDEX, ref);
void pop() const noexcept { return 1;
pop(lua_state()); }
}
void pop() const noexcept {
void pop(lua_State* Ls, int n = 1) const noexcept { pop(lua_state());
lua_pop(Ls, n); }
}
void pop(lua_State* Ls, int n = 1) const noexcept {
int registry_index() const noexcept { lua_pop(Ls, n);
return ref; }
}
int registry_index() const noexcept {
bool valid() const noexcept { return ref;
return !(ref == LUA_NOREF || ref == LUA_REFNIL); }
}
bool valid() const noexcept {
explicit operator bool() const noexcept { return !(ref == LUA_NOREF || ref == LUA_REFNIL);
return valid(); }
}
explicit operator bool() const noexcept {
type get_type() const noexcept { return valid();
auto pp = stack::push_pop(*this); }
int result = lua_type(lua_state(), -1);
return static_cast<type>(result); type get_type() const noexcept {
} auto pp = stack::push_pop(*this);
int result = lua_type(lua_state(), -1);
lua_State* lua_state() const noexcept { return static_cast<type>(result);
return luastate; }
}
}; lua_State* lua_state() const noexcept {
return luastate;
inline bool operator== (const reference& l, const reference& r) { }
auto ppl = stack::push_pop(l); };
auto ppr = stack::push_pop(r);
return lua_compare(l.lua_state(), -1, -2, LUA_OPEQ) == 1; inline bool operator== (const reference& l, const reference& r) {
} auto ppl = stack::push_pop(l);
auto ppr = stack::push_pop(r);
inline bool operator!= (const reference& l, const reference& r) { return lua_compare(l.lua_state(), -1, -2, LUA_OPEQ) == 1;
return !operator==(l, r); }
}
} // sol inline bool operator!= (const reference& l, const reference& r) {
return !operator==(l, r);
#endif // SOL_REFERENCE_HPP }
} // sol
#endif // SOL_REFERENCE_HPP

View File

@ -78,7 +78,11 @@ namespace sol {
state(const state&) = delete; state(const state&) = delete;
state(state&&) = default; state(state&&) = default;
state& operator=(const state&) = delete; state& operator=(const state&) = delete;
state& operator=(state&&) = default; state& operator=(state&& that) {
state_view::operator=(std::move(that));
unique_base::operator=(std::move(that));
return *this;
}
using state_view::get; using state_view::get;

View File

@ -1246,10 +1246,10 @@ TEST_CASE("usertype/shared-ptr-regression", "usertype metatables should not scre
REQUIRE(destroyed == 1); REQUIRE(destroyed == 1);
} }
TEST_CASE("usertype/double-deleter-guards", "usertype metatables internally must not rely on internal ") { TEST_CASE("usertype/double-deleter-guards", "usertype metatables internally must not rely on C++ state") {
struct c_a { int x; }; struct c_a { int x; };
struct c_b { int y; }; struct c_b { int y; };
REQUIRE_NOTHROW( { auto routine = []() {
sol::state lua; sol::state lua;
lua.new_usertype<c_a>("c_a", "x", &c_a::x); lua.new_usertype<c_a>("c_a", "x", &c_a::x);
lua.new_usertype<c_b>("c_b", "y", &c_b::y); lua.new_usertype<c_b>("c_b", "y", &c_b::y);
@ -1257,7 +1257,8 @@ TEST_CASE("usertype/double-deleter-guards", "usertype metatables internally must
lua.new_usertype<c_a>("c_a", "x", &c_a::x); lua.new_usertype<c_a>("c_a", "x", &c_a::x);
lua.new_usertype<c_b>("c_b", "y", &c_b::y); lua.new_usertype<c_b>("c_b", "y", &c_b::y);
lua = sol::state(); lua = sol::state();
}); };
REQUIRE_NOTHROW(routine());
} }
TEST_CASE("usertype/vars", "usertype vars can bind various class items") { TEST_CASE("usertype/vars", "usertype vars can bind various class items") {

1668
tests.cpp

File diff suppressed because it is too large Load Diff