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:
ThePhD 2016-12-26 13:50:08 -05:00
parent 3aa42c5db8
commit 26b85c8136
4 changed files with 297 additions and 253 deletions

View File

@ -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.

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 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

View File

@ -26,9 +26,10 @@
#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 { 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...) {
@ -95,6 +96,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...) {
@ -160,7 +165,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
#endif // SOL_RESOLVE_HPP #endif // SOL_RESOLVE_HPP

View File

@ -75,7 +75,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