mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
Fix leak issues and some ordering in state(view) move operations. Closes #336.
This commit is contained in:
parent
fe8b1c1c10
commit
85194e0135
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
316
sol/demangle.hpp
316
sol/demangle.hpp
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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") {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user