mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
Make sure resolve works and provide some protection against deleting the handler that originates from a specific sol::state
. sol::state_view
users will be left out in the dark, though.
This commit is contained in:
parent
3aa42c5db8
commit
26b85c8136
|
@ -5,15 +5,21 @@ getting good final product out of sol2
|
||||||
|
|
||||||
For individiauls who use :doc:`usertypes<api/usertype>` a lot, they can find their compilation times increase. This is due to C++11 and C++14 not having very good facilities for handling template parameters and variadic template parameters. There are a few things in cutting-edge C++17 and C++Next that sol can use, but the problem is many people cannot work with the latest and greatest: therefore, we have to use older techniques that result in a fair amount of redundant function specializations that can be subject to the pickiness of the compiler's inlining and other such techniques.
|
For individiauls who use :doc:`usertypes<api/usertype>` a lot, they can find their compilation times increase. This is due to C++11 and C++14 not having very good facilities for handling template parameters and variadic template parameters. There are a few things in cutting-edge C++17 and C++Next that sol can use, but the problem is many people cannot work with the latest and greatest: therefore, we have to use older techniques that result in a fair amount of redundant function specializations that can be subject to the pickiness of the compiler's inlining and other such techniques.
|
||||||
|
|
||||||
|
what to do
|
||||||
|
----------
|
||||||
|
|
||||||
Here are some notes on achieving better compile-times without sacrificing too much performance:
|
Here are some notes on achieving better compile-times without sacrificing too much performance:
|
||||||
|
|
||||||
* When you bind lots of usertypes, put them all in a *single* translation unit (one C++ file) so that it is not recompiled multiple times over, only to be discarded later by the linker.
|
* When you bind lots of usertypes, put them all in a *single* translation unit (one C++ file) so that it is not recompiled multiple times over, only to be discarded later by the linker.
|
||||||
- Remember that the usertype binding ends up being serialized into the Lua state, so you never need them to appear in a header and cause that same compilation overhead for every compiled unit in your project.
|
- Remember that the usertype binding ends up being serialized into the Lua state, so you never need them to appear in a header and cause that same compilation overhead for every compiled unit in your project.
|
||||||
* For extremely large usertypes, consider using :doc:`simple_usertype<api/simple_usertype>`.
|
* For extremely large usertypes, consider using :doc:`simple_usertype<api/simple_usertype>`.
|
||||||
- It performs much more work at runtime rather than compile-time, and should still give comparative performance (but it loses out in some cases for variable bindings or when you bind all functions to a usertype).
|
- It performs much more work at runtime rather than compile-time, and should still give comparative performance (but it loses out in some cases for variable bindings or when you bind all functions to a usertype).
|
||||||
* If you are developing a shared library, restrict your overall surface area by specifically and explicitly marking functions as visible and exported and letting everything else as hidden or invisible by default
|
* If you are developing a shared library, restrict your overall surface area by specifically and explicitly marking functions as visible and exported and leaving everything else as hidden or invisible by default
|
||||||
|
|
||||||
|
|
||||||
|
next steps
|
||||||
|
----------
|
||||||
|
|
||||||
The next step for Sol from a developer standpoint is to formally make the library a C++17 one. This would mean using Fold Expressions and several other things which will reduce compilation time drastically. Unfortunately, that means also boosting compiler requirements. While most wouldn't care, others are very slow to upgrade: finding the balance is difficult, and often we have to opt for backwards compatibility and fixes for bad / older compilers (of which there are many in the codebase already).
|
The next step for Sol from a developer standpoint is to formally make the library a C++17 one. This would mean using Fold Expressions and several other things which will reduce compilation time drastically. Unfortunately, that means also boosting compiler requirements. While most wouldn't care, others are very slow to upgrade: finding the balance is difficult, and often we have to opt for backwards compatibility and fixes for bad / older compilers (of which there are many in the codebase already).
|
||||||
|
|
||||||
Hopefully, as things progress, we move things forward.
|
Hopefully, as things progress, we move things forward.
|
||||||
|
|
|
@ -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 2016-12-16 10:31:09.106965 UTC
|
// Generated 2016-12-26 18:50:00.916890 UTC
|
||||||
// This header was generated with sol v2.15.5 (revision 87f8456)
|
// This header was generated with sol v2.15.5 (revision 3aa42c5)
|
||||||
// https://github.com/ThePhD/sol2
|
// https://github.com/ThePhD/sol2
|
||||||
|
|
||||||
#ifndef SOL_SINGLE_INCLUDE_HPP
|
#ifndef SOL_SINGLE_INCLUDE_HPP
|
||||||
|
@ -8531,9 +8531,10 @@ namespace sol {
|
||||||
// beginning of sol/resolve.hpp
|
// beginning of sol/resolve.hpp
|
||||||
|
|
||||||
namespace sol {
|
namespace sol {
|
||||||
// Clang has distinct problems with constexpr arguments,
|
|
||||||
// so don't use the constexpr versions inside of clang.
|
|
||||||
#ifndef __clang__
|
#ifndef __clang__
|
||||||
|
// constexpr is fine for not-clang
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename R, typename... Args, typename F, typename = std::result_of_t<meta::unqualified_t<F>(Args...)>>
|
template<typename R, typename... Args, typename F, typename = std::result_of_t<meta::unqualified_t<F>(Args...)>>
|
||||||
inline constexpr auto resolve_i(types<R(Args...)>, F&&)->R(meta::unqualified_t<F>::*)(Args...) {
|
inline constexpr auto resolve_i(types<R(Args...)>, F&&)->R(meta::unqualified_t<F>::*)(Args...) {
|
||||||
|
@ -8600,6 +8601,10 @@ namespace sol {
|
||||||
return detail::resolve_i(types<Sig...>(), std::forward<F>(f));
|
return detail::resolve_i(types<Sig...>(), std::forward<F>(f));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
// Clang has distinct problems with constexpr arguments,
|
||||||
|
// so don't use the constexpr versions inside of clang.
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename R, typename... Args, typename F, typename = std::result_of_t<meta::unqualified_t<F>(Args...)>>
|
template<typename R, typename... Args, typename F, typename = std::result_of_t<meta::unqualified_t<F>(Args...)>>
|
||||||
inline auto resolve_i(types<R(Args...)>, F&&)->R(meta::unqualified_t<F>::*)(Args...) {
|
inline auto resolve_i(types<R(Args...)>, F&&)->R(meta::unqualified_t<F>::*)(Args...) {
|
||||||
|
@ -8665,7 +8670,9 @@ namespace sol {
|
||||||
inline auto resolve(F&& f) -> decltype(detail::resolve_i(types<Sig...>(), std::forward<F>(f))) {
|
inline auto resolve(F&& f) -> decltype(detail::resolve_i(types<Sig...>(), std::forward<F>(f))) {
|
||||||
return detail::resolve_i(types<Sig...>(), std::forward<F>(f));
|
return detail::resolve_i(types<Sig...>(), std::forward<F>(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // sol
|
} // sol
|
||||||
|
|
||||||
// end of sol/resolve.hpp
|
// end of sol/resolve.hpp
|
||||||
|
@ -12829,7 +12836,19 @@ namespace sol {
|
||||||
stack::luajit_exception_handler(unique_base::get());
|
stack::luajit_exception_handler(unique_base::get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
state(const state&) = delete;
|
||||||
|
state(state&&) = default;
|
||||||
|
state& operator=(const state&) = delete;
|
||||||
|
state& operator=(state&&) = default;
|
||||||
|
|
||||||
using state_view::get;
|
using state_view::get;
|
||||||
|
|
||||||
|
~state() {
|
||||||
|
auto& handler = protected_function::get_default_handler();
|
||||||
|
if (handler.lua_state() == this->lua_state()) {
|
||||||
|
protected_function::set_default_handler(reference());
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
} // sol
|
} // sol
|
||||||
|
|
||||||
|
|
339
sol/resolve.hpp
339
sol/resolve.hpp
|
@ -1,166 +1,173 @@
|
||||||
// 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_RESOLVE_HPP
|
#ifndef SOL_RESOLVE_HPP
|
||||||
#define SOL_RESOLVE_HPP
|
#define SOL_RESOLVE_HPP
|
||||||
|
|
||||||
#include "traits.hpp"
|
#include "traits.hpp"
|
||||||
#include "tuple.hpp"
|
#include "tuple.hpp"
|
||||||
|
|
||||||
namespace sol {
|
namespace sol {
|
||||||
// Clang has distinct problems with constexpr arguments,
|
|
||||||
// so don't use the constexpr versions inside of clang.
|
#ifndef __clang__
|
||||||
#ifndef __clang__
|
// constexpr is fine for not-clang
|
||||||
namespace detail {
|
|
||||||
template<typename R, typename... Args, typename F, typename = std::result_of_t<meta::unqualified_t<F>(Args...)>>
|
namespace detail {
|
||||||
inline constexpr auto resolve_i(types<R(Args...)>, F&&)->R(meta::unqualified_t<F>::*)(Args...) {
|
template<typename R, typename... Args, typename F, typename = std::result_of_t<meta::unqualified_t<F>(Args...)>>
|
||||||
using Sig = R(Args...);
|
inline constexpr auto resolve_i(types<R(Args...)>, F&&)->R(meta::unqualified_t<F>::*)(Args...) {
|
||||||
typedef meta::unqualified_t<F> Fu;
|
using Sig = R(Args...);
|
||||||
return static_cast<Sig Fu::*>(&Fu::operator());
|
typedef meta::unqualified_t<F> Fu;
|
||||||
}
|
return static_cast<Sig Fu::*>(&Fu::operator());
|
||||||
|
}
|
||||||
template<typename F, typename U = meta::unqualified_t<F>>
|
|
||||||
inline constexpr auto resolve_f(std::true_type, F&& f)
|
template<typename F, typename U = meta::unqualified_t<F>>
|
||||||
-> decltype(resolve_i(types<meta::function_signature_t<decltype(&U::operator())>>(), std::forward<F>(f))) {
|
inline constexpr auto resolve_f(std::true_type, F&& f)
|
||||||
return resolve_i(types<meta::function_signature_t<decltype(&U::operator())>>(), std::forward<F>(f));
|
-> decltype(resolve_i(types<meta::function_signature_t<decltype(&U::operator())>>(), std::forward<F>(f))) {
|
||||||
}
|
return resolve_i(types<meta::function_signature_t<decltype(&U::operator())>>(), std::forward<F>(f));
|
||||||
|
}
|
||||||
template<typename F>
|
|
||||||
inline constexpr void resolve_f(std::false_type, F&&) {
|
template<typename F>
|
||||||
static_assert(meta::has_deducible_signature<F>::value,
|
inline constexpr void resolve_f(std::false_type, F&&) {
|
||||||
"Cannot use no-template-parameter call with an overloaded functor: specify the signature");
|
static_assert(meta::has_deducible_signature<F>::value,
|
||||||
}
|
"Cannot use no-template-parameter call with an overloaded functor: specify the signature");
|
||||||
|
}
|
||||||
template<typename F, typename U = meta::unqualified_t<F>>
|
|
||||||
inline constexpr auto resolve_i(types<>, F&& f) -> decltype(resolve_f(meta::has_deducible_signature<U>(), std::forward<F>(f))) {
|
template<typename F, typename U = meta::unqualified_t<F>>
|
||||||
return resolve_f(meta::has_deducible_signature<U> {}, std::forward<F>(f));
|
inline constexpr auto resolve_i(types<>, F&& f) -> decltype(resolve_f(meta::has_deducible_signature<U>(), std::forward<F>(f))) {
|
||||||
}
|
return resolve_f(meta::has_deducible_signature<U> {}, std::forward<F>(f));
|
||||||
|
}
|
||||||
template<typename... Args, typename F, typename R = std::result_of_t<F&(Args...)>>
|
|
||||||
inline constexpr auto resolve_i(types<Args...>, F&& f) -> decltype(resolve_i(types<R(Args...)>(), std::forward<F>(f))) {
|
template<typename... Args, typename F, typename R = std::result_of_t<F&(Args...)>>
|
||||||
return resolve_i(types<R(Args...)>(), std::forward<F>(f));
|
inline constexpr auto resolve_i(types<Args...>, F&& f) -> decltype(resolve_i(types<R(Args...)>(), std::forward<F>(f))) {
|
||||||
}
|
return resolve_i(types<R(Args...)>(), std::forward<F>(f));
|
||||||
|
}
|
||||||
template<typename Sig, typename C>
|
|
||||||
inline constexpr Sig C::* resolve_v(std::false_type, Sig C::* mem_func_ptr) {
|
template<typename Sig, typename C>
|
||||||
return mem_func_ptr;
|
inline constexpr Sig C::* resolve_v(std::false_type, Sig C::* mem_func_ptr) {
|
||||||
}
|
return mem_func_ptr;
|
||||||
|
}
|
||||||
template<typename Sig, typename C>
|
|
||||||
inline constexpr Sig C::* resolve_v(std::true_type, Sig C::* mem_variable_ptr) {
|
template<typename Sig, typename C>
|
||||||
return mem_variable_ptr;
|
inline constexpr Sig C::* resolve_v(std::true_type, Sig C::* mem_variable_ptr) {
|
||||||
}
|
return mem_variable_ptr;
|
||||||
} // detail
|
}
|
||||||
|
} // detail
|
||||||
template<typename... Args, typename R>
|
|
||||||
inline constexpr auto resolve(R fun_ptr(Args...))->R(*)(Args...) {
|
template<typename... Args, typename R>
|
||||||
return fun_ptr;
|
inline constexpr auto resolve(R fun_ptr(Args...))->R(*)(Args...) {
|
||||||
}
|
return fun_ptr;
|
||||||
|
}
|
||||||
template<typename Sig>
|
|
||||||
inline constexpr Sig* resolve(Sig* fun_ptr) {
|
template<typename Sig>
|
||||||
return fun_ptr;
|
inline constexpr Sig* resolve(Sig* fun_ptr) {
|
||||||
}
|
return fun_ptr;
|
||||||
|
}
|
||||||
template<typename... Args, typename R, typename C>
|
|
||||||
inline constexpr auto resolve(R(C::*mem_ptr)(Args...))->R(C::*)(Args...) {
|
template<typename... Args, typename R, typename C>
|
||||||
return mem_ptr;
|
inline constexpr auto resolve(R(C::*mem_ptr)(Args...))->R(C::*)(Args...) {
|
||||||
}
|
return mem_ptr;
|
||||||
|
}
|
||||||
template<typename Sig, typename C>
|
|
||||||
inline constexpr Sig C::* resolve(Sig C::* mem_ptr) {
|
template<typename Sig, typename C>
|
||||||
return detail::resolve_v(std::is_member_object_pointer<Sig C::*>(), mem_ptr);
|
inline constexpr Sig C::* resolve(Sig C::* mem_ptr) {
|
||||||
}
|
return detail::resolve_v(std::is_member_object_pointer<Sig C::*>(), mem_ptr);
|
||||||
|
}
|
||||||
template<typename... Sig, typename F, meta::disable<std::is_function<meta::unqualified_t<F>>> = meta::enabler>
|
|
||||||
inline constexpr auto resolve(F&& f) -> decltype(detail::resolve_i(types<Sig...>(), std::forward<F>(f))) {
|
template<typename... Sig, typename F, meta::disable<std::is_function<meta::unqualified_t<F>>> = meta::enabler>
|
||||||
return detail::resolve_i(types<Sig...>(), std::forward<F>(f));
|
inline constexpr auto resolve(F&& f) -> decltype(detail::resolve_i(types<Sig...>(), std::forward<F>(f))) {
|
||||||
}
|
return detail::resolve_i(types<Sig...>(), std::forward<F>(f));
|
||||||
#else
|
}
|
||||||
namespace detail {
|
#else
|
||||||
template<typename R, typename... Args, typename F, typename = std::result_of_t<meta::unqualified_t<F>(Args...)>>
|
|
||||||
inline auto resolve_i(types<R(Args...)>, F&&)->R(meta::unqualified_t<F>::*)(Args...) {
|
// Clang has distinct problems with constexpr arguments,
|
||||||
using Sig = R(Args...);
|
// so don't use the constexpr versions inside of clang.
|
||||||
typedef meta::unqualified_t<F> Fu;
|
|
||||||
return static_cast<Sig Fu::*>(&Fu::operator());
|
namespace detail {
|
||||||
}
|
template<typename R, typename... Args, typename F, typename = std::result_of_t<meta::unqualified_t<F>(Args...)>>
|
||||||
|
inline auto resolve_i(types<R(Args...)>, F&&)->R(meta::unqualified_t<F>::*)(Args...) {
|
||||||
template<typename F, typename U = meta::unqualified_t<F>>
|
using Sig = R(Args...);
|
||||||
inline auto resolve_f(std::true_type, F&& f)
|
typedef meta::unqualified_t<F> Fu;
|
||||||
-> decltype(resolve_i(types<meta::function_signature_t<decltype(&U::operator())>>(), std::forward<F>(f))) {
|
return static_cast<Sig Fu::*>(&Fu::operator());
|
||||||
return resolve_i(types<meta::function_signature_t<decltype(&U::operator())>>(), std::forward<F>(f));
|
}
|
||||||
}
|
|
||||||
|
template<typename F, typename U = meta::unqualified_t<F>>
|
||||||
template<typename F>
|
inline auto resolve_f(std::true_type, F&& f)
|
||||||
inline void resolve_f(std::false_type, F&&) {
|
-> decltype(resolve_i(types<meta::function_signature_t<decltype(&U::operator())>>(), std::forward<F>(f))) {
|
||||||
static_assert(meta::has_deducible_signature<F>::value,
|
return resolve_i(types<meta::function_signature_t<decltype(&U::operator())>>(), std::forward<F>(f));
|
||||||
"Cannot use no-template-parameter call with an overloaded functor: specify the signature");
|
}
|
||||||
}
|
|
||||||
|
template<typename F>
|
||||||
template<typename F, typename U = meta::unqualified_t<F>>
|
inline void resolve_f(std::false_type, F&&) {
|
||||||
inline auto resolve_i(types<>, F&& f) -> decltype(resolve_f(meta::has_deducible_signature<U>(), std::forward<F>(f))) {
|
static_assert(meta::has_deducible_signature<F>::value,
|
||||||
return resolve_f(meta::has_deducible_signature<U> {}, std::forward<F>(f));
|
"Cannot use no-template-parameter call with an overloaded functor: specify the signature");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Args, typename F, typename R = std::result_of_t<F&(Args...)>>
|
template<typename F, typename U = meta::unqualified_t<F>>
|
||||||
inline auto resolve_i(types<Args...>, F&& f) -> decltype(resolve_i(types<R(Args...)>(), std::forward<F>(f))) {
|
inline auto resolve_i(types<>, F&& f) -> decltype(resolve_f(meta::has_deducible_signature<U>(), std::forward<F>(f))) {
|
||||||
return resolve_i(types<R(Args...)>(), std::forward<F>(f));
|
return resolve_f(meta::has_deducible_signature<U> {}, std::forward<F>(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Sig, typename C>
|
template<typename... Args, typename F, typename R = std::result_of_t<F&(Args...)>>
|
||||||
inline Sig C::* resolve_v(std::false_type, Sig C::* mem_func_ptr) {
|
inline auto resolve_i(types<Args...>, F&& f) -> decltype(resolve_i(types<R(Args...)>(), std::forward<F>(f))) {
|
||||||
return mem_func_ptr;
|
return resolve_i(types<R(Args...)>(), std::forward<F>(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Sig, typename C>
|
template<typename Sig, typename C>
|
||||||
inline Sig C::* resolve_v(std::true_type, Sig C::* mem_variable_ptr) {
|
inline Sig C::* resolve_v(std::false_type, Sig C::* mem_func_ptr) {
|
||||||
return mem_variable_ptr;
|
return mem_func_ptr;
|
||||||
}
|
}
|
||||||
} // detail
|
|
||||||
|
template<typename Sig, typename C>
|
||||||
template<typename... Args, typename R>
|
inline Sig C::* resolve_v(std::true_type, Sig C::* mem_variable_ptr) {
|
||||||
inline auto resolve(R fun_ptr(Args...))->R(*)(Args...) {
|
return mem_variable_ptr;
|
||||||
return fun_ptr;
|
}
|
||||||
}
|
} // detail
|
||||||
|
|
||||||
template<typename Sig>
|
template<typename... Args, typename R>
|
||||||
inline Sig* resolve(Sig* fun_ptr) {
|
inline auto resolve(R fun_ptr(Args...))->R(*)(Args...) {
|
||||||
return fun_ptr;
|
return fun_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Args, typename R, typename C>
|
template<typename Sig>
|
||||||
inline auto resolve(R(C::*mem_ptr)(Args...))->R(C::*)(Args...) {
|
inline Sig* resolve(Sig* fun_ptr) {
|
||||||
return mem_ptr;
|
return fun_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Sig, typename C>
|
template<typename... Args, typename R, typename C>
|
||||||
inline Sig C::* resolve(Sig C::* mem_ptr) {
|
inline auto resolve(R(C::*mem_ptr)(Args...))->R(C::*)(Args...) {
|
||||||
return detail::resolve_v(std::is_member_object_pointer<Sig C::*>(), mem_ptr);
|
return mem_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Sig, typename F>
|
template<typename Sig, typename C>
|
||||||
inline auto resolve(F&& f) -> decltype(detail::resolve_i(types<Sig...>(), std::forward<F>(f))) {
|
inline Sig C::* resolve(Sig C::* mem_ptr) {
|
||||||
return detail::resolve_i(types<Sig...>(), std::forward<F>(f));
|
return detail::resolve_v(std::is_member_object_pointer<Sig C::*>(), mem_ptr);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
} // sol
|
template<typename... Sig, typename F>
|
||||||
|
inline auto resolve(F&& f) -> decltype(detail::resolve_i(types<Sig...>(), std::forward<F>(f))) {
|
||||||
#endif // SOL_RESOLVE_HPP
|
return detail::resolve_i(types<Sig...>(), std::forward<F>(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // sol
|
||||||
|
|
||||||
|
#endif // SOL_RESOLVE_HPP
|
||||||
|
|
176
sol/state.hpp
176
sol/state.hpp
|
@ -1,82 +1,94 @@
|
||||||
// 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_STATE_HPP
|
#ifndef SOL_STATE_HPP
|
||||||
#define SOL_STATE_HPP
|
#define SOL_STATE_HPP
|
||||||
|
|
||||||
#include "state_view.hpp"
|
#include "state_view.hpp"
|
||||||
|
|
||||||
namespace sol {
|
namespace sol {
|
||||||
inline int default_at_panic(lua_State* L) {
|
inline int default_at_panic(lua_State* L) {
|
||||||
#ifdef SOL_NO_EXCEPTIONS
|
#ifdef SOL_NO_EXCEPTIONS
|
||||||
(void)L;
|
(void)L;
|
||||||
return -1;
|
return -1;
|
||||||
#else
|
#else
|
||||||
const char* message = lua_tostring(L, -1);
|
const char* message = lua_tostring(L, -1);
|
||||||
if (message) {
|
if (message) {
|
||||||
std::string err = message;
|
std::string err = message;
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
throw error(err);
|
throw error(err);
|
||||||
}
|
}
|
||||||
throw error(std::string("An unexpected error occurred and forced the lua state to call atpanic"));
|
throw error(std::string("An unexpected error occurred and forced the lua state to call atpanic"));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int default_error_handler(lua_State*L) {
|
inline int default_error_handler(lua_State*L) {
|
||||||
using namespace sol;
|
using namespace sol;
|
||||||
std::string msg = "An unknown error has triggered the default error handler";
|
std::string msg = "An unknown error has triggered the default error handler";
|
||||||
optional<string_detail::string_shim> maybetopmsg = stack::check_get<string_detail::string_shim>(L, 1);
|
optional<string_detail::string_shim> maybetopmsg = stack::check_get<string_detail::string_shim>(L, 1);
|
||||||
if (maybetopmsg) {
|
if (maybetopmsg) {
|
||||||
const string_detail::string_shim& topmsg = maybetopmsg.value();
|
const string_detail::string_shim& topmsg = maybetopmsg.value();
|
||||||
msg.assign(topmsg.c_str(), topmsg.size());
|
msg.assign(topmsg.c_str(), topmsg.size());
|
||||||
}
|
}
|
||||||
luaL_traceback(L, L, msg.c_str(), 1);
|
luaL_traceback(L, L, msg.c_str(), 1);
|
||||||
optional<string_detail::string_shim> maybetraceback = stack::check_get<string_detail::string_shim>(L, -1);
|
optional<string_detail::string_shim> maybetraceback = stack::check_get<string_detail::string_shim>(L, -1);
|
||||||
if (maybetraceback) {
|
if (maybetraceback) {
|
||||||
const string_detail::string_shim& traceback = maybetraceback.value();
|
const string_detail::string_shim& traceback = maybetraceback.value();
|
||||||
msg.assign(traceback.c_str(), traceback.size());
|
msg.assign(traceback.c_str(), traceback.size());
|
||||||
}
|
}
|
||||||
return stack::push(L, msg);
|
return stack::push(L, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class state : private std::unique_ptr<lua_State, void(*)(lua_State*)>, public state_view {
|
class state : private std::unique_ptr<lua_State, void(*)(lua_State*)>, public state_view {
|
||||||
private:
|
private:
|
||||||
typedef std::unique_ptr<lua_State, void(*)(lua_State*)> unique_base;
|
typedef std::unique_ptr<lua_State, void(*)(lua_State*)> unique_base;
|
||||||
public:
|
public:
|
||||||
state(lua_CFunction panic = default_at_panic) : unique_base(luaL_newstate(), lua_close),
|
state(lua_CFunction panic = default_at_panic) : unique_base(luaL_newstate(), lua_close),
|
||||||
state_view(unique_base::get()) {
|
state_view(unique_base::get()) {
|
||||||
set_panic(panic);
|
set_panic(panic);
|
||||||
stack::luajit_exception_handler(unique_base::get());
|
stack::luajit_exception_handler(unique_base::get());
|
||||||
}
|
}
|
||||||
|
|
||||||
state(lua_CFunction panic, lua_Alloc alfunc, void* alpointer = nullptr) : unique_base(lua_newstate(alfunc, alpointer), lua_close),
|
state(lua_CFunction panic, lua_Alloc alfunc, void* alpointer = nullptr) : unique_base(lua_newstate(alfunc, alpointer), lua_close),
|
||||||
state_view(unique_base::get()) {
|
state_view(unique_base::get()) {
|
||||||
set_panic(panic);
|
set_panic(panic);
|
||||||
sol::protected_function::set_default_handler(sol::object(lua_state(), in_place, default_error_handler));
|
sol::protected_function::set_default_handler(sol::object(lua_state(), in_place, default_error_handler));
|
||||||
stack::luajit_exception_handler(unique_base::get());
|
stack::luajit_exception_handler(unique_base::get());
|
||||||
}
|
}
|
||||||
|
|
||||||
using state_view::get;
|
state(const state&) = delete;
|
||||||
};
|
state(state&&) = default;
|
||||||
} // sol
|
state& operator=(const state&) = delete;
|
||||||
|
state& operator=(state&&) = default;
|
||||||
#endif // SOL_STATE_HPP
|
|
||||||
|
using state_view::get;
|
||||||
|
|
||||||
|
~state() {
|
||||||
|
auto& handler = protected_function::get_default_handler();
|
||||||
|
if (handler.lua_state() == this->lua_state()) {
|
||||||
|
protected_function::set_default_handler(reference());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // sol
|
||||||
|
|
||||||
|
#endif // SOL_STATE_HPP
|
||||||
|
|
Loading…
Reference in New Issue
Block a user