Allllll the fixes. All the time. Mostly to make sure constructors don't fight with each other and safety is respected. And documentation updates.

This commit is contained in:
ThePhD 2016-10-01 01:27:40 -04:00
parent ca28f8577e
commit b05ce97247
10 changed files with 184 additions and 39 deletions

View File

@ -7,13 +7,7 @@ Lua function calls that trap errors and provide error handling
class protected_function : public reference; class protected_function : public reference;
Inspired by a request from `starwing<https://github.com/starwing>` in the old repository, this class provides the same interface as :doc:`function<function>` but with heavy protection and a potential error handler for any Lua errors and C++ exceptions. Grab a function directly off the stack using the constructor: Inspired by a request from `starwing<https://github.com/starwing>` in the old repository, this class provides the same interface as :doc:`function<function>` but with heavy protection and a potential error handler for any Lua errors and C++ exceptions. You can grab a function directly off the stack using the constructor, or pass to it 2 valid functions, which we'll demonstrate a little later.
.. code-block:: cpp
:caption: constructor: protected_function
protected_function(lua_State* L, int index = -1);
When called without the return types being specified by either a ``sol::types<...>`` list or a ``call<Ret...>( ... )`` template type list, it generates a :doc:`protected_function_result<proxy>` class that gets implicitly converted to the requested return type. For example: When called without the return types being specified by either a ``sol::types<...>`` list or a ``call<Ret...>( ... )`` template type list, it generates a :doc:`protected_function_result<proxy>` class that gets implicitly converted to the requested return type. For example:
@ -34,6 +28,13 @@ When called without the return types being specified by either a ``sol::types<..
return (bark_energy * (bark_power / 4)) return (bark_energy * (bark_power / 4))
end end
function woofers ( bark_energy )
if bark_energy < 10
error("*whine*")
end
return (bark_energy * (bark_power / 4))
end
The following C++ code will call this function from this file and retrieve the return value, unless an error occurs, in which case you can bind an error handling function like so: The following C++ code will call this function from this file and retrieve the return value, unless an error occurs, in which case you can bind an error handling function like so:
.. code-block:: cpp .. code-block:: cpp
@ -86,7 +87,7 @@ Alternatively, with a bad or good function call, you can use ``sol::optional`` t
problematicwoof.error_handler = lua["got_problems"]; problematicwoof.error_handler = lua["got_problems"];
sol::optional<double> maybevalue = problematicwoof(19); sol::optional<double> maybevalue = problematicwoof(19);
if (value) { if (maybevalue) {
// Have a value, use it // Have a value, use it
double numwoof = maybevalue.value(); double numwoof = maybevalue.value();
} }
@ -94,11 +95,56 @@ Alternatively, with a bad or good function call, you can use ``sol::optional`` t
// No value! // No value!
} }
That makes the code a bit more concise and easy to reason about if you don't want to bother with reading the error. Thankfully, unlike ``sol::function_result``, you can save ``sol::protected_function_result`` in a variable and push/pop things above it on the stack where its returned values are. This makes it a bit more flexible than the rigid, performant ``sol::function_result`` type that comes from calling :doc:`sol::function<function>`. If you're confident the result succeeded, you can also just put the type you want (like ``double`` or ``std::string`` right there and it will get it. But, if it doesn't work out, sol can throw and/or panic if you have the :doc:`safety<../safety>` features turned on. That makes the code a bit more concise and easy to reason about if you don't want to bother with reading the error. Thankfully, unlike ``sol::function_result``, you can save ``sol::protected_function_result`` in a variable and push/pop things above it on the stack where its returned values are. This makes it a bit more flexible than the rigid, performant ``sol::function_result`` type that comes from calling :doc:`sol::function<function>`.
If you're confident the result succeeded, you can also just put the type you want (like ``double`` or ``std::string`` right there and it will get it. But, if it doesn't work out, sol can throw and/or panic if you have the :doc:`safety<../safety>` features turned on:
.. code-block:: cpp
:linenos:
sol::state lua;
lua.open_file( "pfunc_barks.lua" );
// construct with function + error handler
// shorter than old syntax
sol::protected_function problematicwoof(lua["woof"], lua["got_problems"]);
// dangerous if things go wrong!
double value = problematicwoof(19);
Finally, it is *important* to note you can set a default handler. The function is described below: please use it to avoid having to constantly set error handlers:
.. code-block:: cpp
:linenos:
sol::state lua;
lua.open_file( "pfunc_barks.lua" );
// sets got_problems as the default
// handler for all protected_function errors
sol::protected_function::set_default_handler(lua["got_problems"]);
sol::protected_function problematicwoof = lua["woof"];
sol::protected_function problematicwoofers = lua["woofers"];
double value = problematicwoof(19);
double value2 = problematicwoof(9);
members members
------- -------
.. code-block:: cpp
:caption: constructor: protected_function
template <typename T>
protected_function( T&& func, reference handler = sol::protected_function::get_default_handler() );
protected_function( lua_State* L, int index = -1, reference handler = sol::protected_function::get_default_handler() );
Constructs a ``protected_function``. Use the 2-argument version to pass a custom error handling function more easily. You can also set the :ref:`member variable error_handler<protected-function-error-handler>` after construction later. ``protected_function`` will always use the latest error handler set on the variable, which is either what you passed to it or the default *at the time of construction*.
.. code-block:: cpp .. code-block:: cpp
:caption: function: call operator / protected function call :caption: function: call operator / protected function call

View File

@ -61,7 +61,7 @@ author = 'ThePhD'
# The short X.Y version. # The short X.Y version.
version = '2.14' version = '2.14'
# The full version, including alpha/beta/rc tags. # The full version, including alpha/beta/rc tags.
release = '2.14.2' release = '2.14.8'
# The language for content autogenerated by Sphinx. Refer to documentation # The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages. # for a list of supported languages.

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-09-30 05:42:33.802337 UTC // Generated 2016-10-01 05:27:09.914197 UTC
// This header was generated with sol v2.14.8 (revision 6c34a2a) // This header was generated with sol v2.14.8 (revision ca28f85)
// https://github.com/ThePhD/sol2 // https://github.com/ThePhD/sol2
#ifndef SOL_SINGLE_INCLUDE_HPP #ifndef SOL_SINGLE_INCLUDE_HPP
@ -3558,10 +3558,26 @@ namespace sol {
template <typename T> template <typename T>
struct is_table : std::false_type {}; struct is_table : std::false_type {};
template <bool x, typename T> template <bool x, typename T>
struct is_table<basic_table_core<x, T>> : std::true_type {}; struct is_table<basic_table_core<x, T>> : std::true_type {};
template <typename T>
struct is_function : std::false_type {};
template <typename T>
struct is_function<basic_function<T>> : std::true_type {};
template <typename T>
struct is_function<basic_protected_function<T>> : std::true_type {};
template <typename T>
struct is_lightuserdata : std::false_type {};
template <typename T>
struct is_lightuserdata<basic_lightuserdata<T>> : std::true_type {};
template <typename T>
struct is_userdata : std::false_type {};
template <typename T>
struct is_userdata<basic_userdata<T>> : std::true_type {};
template<typename T> template<typename T>
inline type type_of() { inline type type_of() {
return lua_type_of<meta::unqualified_t<T>>::value; return lua_type_of<meta::unqualified_t<T>>::value;
@ -3792,6 +3808,15 @@ namespace sol {
class basic_userdata : public base_t { class basic_userdata : public base_t {
public: public:
basic_userdata() noexcept = default; basic_userdata() noexcept = default;
template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_userdata>>, meta::neg<std::is_same<base_t, stack_reference>>, std::is_base_of<base_t, meta::unqualified_t<T>>> = meta::enabler>
basic_userdata(T&& r) noexcept : base_t(std::forward<T>(r)) {
#ifdef SOL_CHECK_ARGUMENTS
if (!is_userdata<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this);
type_assert(base_t::lua_state(), -1, type::userdata);
}
#endif // Safety
}
basic_userdata(const basic_userdata&) = default; basic_userdata(const basic_userdata&) = default;
basic_userdata(basic_userdata&&) = default; basic_userdata(basic_userdata&&) = default;
basic_userdata& operator=(const basic_userdata&) = default; basic_userdata& operator=(const basic_userdata&) = default;
@ -3809,6 +3834,15 @@ namespace sol {
class basic_lightuserdata : public base_t { class basic_lightuserdata : public base_t {
public: public:
basic_lightuserdata() noexcept = default; basic_lightuserdata() noexcept = default;
template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_lightuserdata>>, meta::neg<std::is_same<base_t, stack_reference>>, std::is_base_of<base_t, meta::unqualified_t<T>>> = meta::enabler>
basic_lightuserdata(T&& r) noexcept : base_t(std::forward<T>(r)) {
#ifdef SOL_CHECK_ARGUMENTS
if (!is_userdata<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this);
type_assert(base_t::lua_state(), -1, type::lightuserdata);
}
#endif // Safety
}
basic_lightuserdata(const basic_lightuserdata&) = default; basic_lightuserdata(const basic_lightuserdata&) = default;
basic_lightuserdata(basic_lightuserdata&&) = default; basic_lightuserdata(basic_lightuserdata&&) = default;
basic_lightuserdata& operator=(const basic_lightuserdata&) = default; basic_lightuserdata& operator=(const basic_lightuserdata&) = default;
@ -8529,6 +8563,15 @@ namespace sol {
public: public:
basic_function() = default; basic_function() = default;
template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_function>>, meta::neg<std::is_same<base_t, stack_reference>>, std::is_base_of<base_t, meta::unqualified_t<T>>> = meta::enabler>
basic_function(T&& r) noexcept : base_t(std::forward<T>(r)) {
#ifdef SOL_CHECK_ARGUMENTS
if (!is_function<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this);
stack::check<basic_function>(base_t::lua_state(), -1, type_panic);
}
#endif // Safety
}
basic_function(const basic_function&) = default; basic_function(const basic_function&) = default;
basic_function& operator=(const basic_function&) = default; basic_function& operator=(const basic_function&) = default;
basic_function(basic_function&&) = default; basic_function(basic_function&&) = default;
@ -8823,6 +8866,15 @@ namespace sol {
reference error_handler; reference error_handler;
basic_protected_function() = default; basic_protected_function() = default;
template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_protected_function>>, meta::neg<std::is_same<base_t, stack_reference>>, std::is_base_of<base_t, meta::unqualified_t<T>>> = meta::enabler>
basic_protected_function(T&& r) noexcept : base_t(std::forward<T>(r)) {
#ifdef SOL_CHECK_ARGUMENTS
if (!is_function<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this);
stack::check<basic_protected_function>(base_t::lua_state(), -1, type_panic);
}
#endif // Safety
}
basic_protected_function(const basic_protected_function&) = default; basic_protected_function(const basic_protected_function&) = default;
basic_protected_function& operator=(const basic_protected_function&) = default; basic_protected_function& operator=(const basic_protected_function&) = default;
basic_protected_function(basic_protected_function&&) = default; basic_protected_function(basic_protected_function&&) = default;
@ -8831,6 +8883,10 @@ namespace sol {
basic_protected_function(basic_function<base_t>&& b, reference eh = get_default_handler()) : base_t(std::move(b)), error_handler(std::move(eh)) {} basic_protected_function(basic_function<base_t>&& b, reference eh = get_default_handler()) : base_t(std::move(b)), error_handler(std::move(eh)) {}
basic_protected_function(const stack_reference& r, reference eh = get_default_handler()) : basic_protected_function(r.lua_state(), r.stack_index(), std::move(eh)) {} basic_protected_function(const stack_reference& r, reference eh = get_default_handler()) : basic_protected_function(r.lua_state(), r.stack_index(), std::move(eh)) {}
basic_protected_function(stack_reference&& r, reference eh = get_default_handler()) : basic_protected_function(r.lua_state(), r.stack_index(), std::move(eh)) {} basic_protected_function(stack_reference&& r, reference eh = get_default_handler()) : basic_protected_function(r.lua_state(), r.stack_index(), std::move(eh)) {}
template <typename Super>
basic_protected_function(proxy_base<Super>&& p, reference eh = get_default_handler()) : basic_protected_function(p.operator basic_function<base_t>(), std::move(eh)) {}
template <typename Super>
basic_protected_function(const proxy_base<Super>& p, reference eh = get_default_handler()) : basic_protected_function(static_cast<basic_function<base_t>>(p), std::move(eh)) {}
basic_protected_function(lua_State* L, int index = -1, reference eh = get_default_handler()) : base_t(L, index), error_handler(std::move(eh)) { basic_protected_function(lua_State* L, int index = -1, reference eh = get_default_handler()) : base_t(L, index), error_handler(std::move(eh)) {
#ifdef SOL_CHECK_ARGUMENTS #ifdef SOL_CHECK_ARGUMENTS
stack::check<basic_protected_function>(L, index, type_panic); stack::check<basic_protected_function>(L, index, type_panic);
@ -9222,21 +9278,15 @@ namespace sol {
public: public:
basic_object() noexcept = default; basic_object() noexcept = default;
template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_object>>, std::is_base_of<base_t, meta::unqualified_t<T>>> = meta::enabler> template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_object>>, meta::neg<std::is_same<base_t, stack_reference>>, std::is_base_of<base_t, meta::unqualified_t<T>>> = meta::enabler>
basic_object(T&& r) : base_t(std::forward<T>(r)) {} basic_object(T&& r) : base_t(std::forward<T>(r)) {}
basic_object(nil_t r) : base_t(r) {} basic_object(nil_t r) : base_t(r) {}
basic_object(const basic_object&) = default; basic_object(const basic_object&) = default;
basic_object(basic_object&&) = default; basic_object(basic_object&&) = default;
basic_object& operator=(const basic_object&) = default; basic_object& operator=(const basic_object&) = default;
basic_object& operator=(basic_object&&) = default; basic_object& operator=(basic_object&&) = default;
basic_object& operator=(const base_t& b) { basic_object& operator=(const base_t& b) { base_t::operator=(b); return *this; }
base_t::operator=(b); basic_object& operator=(base_t&& b) { base_t::operator=(std::move(b)); return *this; }
return *this;
}
basic_object& operator=(base_t&& b) {
base_t::operator=(std::move(b));
return *this;
}
basic_object(const stack_reference& r) noexcept : basic_object(r.lua_state(), r.stack_index()) {} basic_object(const stack_reference& r) noexcept : basic_object(r.lua_state(), r.stack_index()) {}
basic_object(stack_reference&& r) noexcept : basic_object(r.lua_state(), r.stack_index()) {} basic_object(stack_reference&& r) noexcept : basic_object(r.lua_state(), r.stack_index()) {}
basic_object(lua_State* L, int index = -1) noexcept : base_t(L, index) {} basic_object(lua_State* L, int index = -1) noexcept : base_t(L, index) {}
@ -11162,7 +11212,7 @@ namespace sol {
typedef iterator const_iterator; typedef iterator const_iterator;
basic_table_core() noexcept : base_t() { } basic_table_core() noexcept : base_t() { }
template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_table_core>>, std::is_base_of<base_t, meta::unqualified_t<T>>> = meta::enabler> template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_table_core>>, meta::neg<std::is_same<base_t, stack_reference>>, std::is_base_of<base_t, meta::unqualified_t<T>>> = meta::enabler>
basic_table_core(T&& r) noexcept : base_t(std::forward<T>(r)) { basic_table_core(T&& r) noexcept : base_t(std::forward<T>(r)) {
#ifdef SOL_CHECK_ARGUMENTS #ifdef SOL_CHECK_ARGUMENTS
if (!is_table<meta::unqualified_t<T>>::value) { if (!is_table<meta::unqualified_t<T>>::value) {

View File

@ -66,6 +66,15 @@ namespace sol {
public: public:
basic_function() = default; basic_function() = default;
template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_function>>, meta::neg<std::is_same<base_t, stack_reference>>, std::is_base_of<base_t, meta::unqualified_t<T>>> = meta::enabler>
basic_function(T&& r) noexcept : base_t(std::forward<T>(r)) {
#ifdef SOL_CHECK_ARGUMENTS
if (!is_function<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this);
stack::check<basic_function>(base_t::lua_state(), -1, type_panic);
}
#endif // Safety
}
basic_function(const basic_function&) = default; basic_function(const basic_function&) = default;
basic_function& operator=(const basic_function&) = default; basic_function& operator=(const basic_function&) = default;
basic_function(basic_function&&) = default; basic_function(basic_function&&) = default;

View File

@ -84,21 +84,15 @@ namespace sol {
public: public:
basic_object() noexcept = default; basic_object() noexcept = default;
template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_object>>, std::is_base_of<base_t, meta::unqualified_t<T>>> = meta::enabler> template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_object>>, meta::neg<std::is_same<base_t, stack_reference>>, std::is_base_of<base_t, meta::unqualified_t<T>>> = meta::enabler>
basic_object(T&& r) : base_t(std::forward<T>(r)) {} basic_object(T&& r) : base_t(std::forward<T>(r)) {}
basic_object(nil_t r) : base_t(r) {} basic_object(nil_t r) : base_t(r) {}
basic_object(const basic_object&) = default; basic_object(const basic_object&) = default;
basic_object(basic_object&&) = default; basic_object(basic_object&&) = default;
basic_object& operator=(const basic_object&) = default; basic_object& operator=(const basic_object&) = default;
basic_object& operator=(basic_object&&) = default; basic_object& operator=(basic_object&&) = default;
basic_object& operator=(const base_t& b) { basic_object& operator=(const base_t& b) { base_t::operator=(b); return *this; }
base_t::operator=(b); basic_object& operator=(base_t&& b) { base_t::operator=(std::move(b)); return *this; }
return *this;
}
basic_object& operator=(base_t&& b) {
base_t::operator=(std::move(b));
return *this;
}
basic_object(const stack_reference& r) noexcept : basic_object(r.lua_state(), r.stack_index()) {} basic_object(const stack_reference& r) noexcept : basic_object(r.lua_state(), r.stack_index()) {}
basic_object(stack_reference&& r) noexcept : basic_object(r.lua_state(), r.stack_index()) {} basic_object(stack_reference&& r) noexcept : basic_object(r.lua_state(), r.stack_index()) {}
basic_object(lua_State* L, int index = -1) noexcept : base_t(L, index) {} basic_object(lua_State* L, int index = -1) noexcept : base_t(L, index) {}

View File

@ -140,6 +140,15 @@ namespace sol {
reference error_handler; reference error_handler;
basic_protected_function() = default; basic_protected_function() = default;
template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_protected_function>>, meta::neg<std::is_same<base_t, stack_reference>>, std::is_base_of<base_t, meta::unqualified_t<T>>> = meta::enabler>
basic_protected_function(T&& r) noexcept : base_t(std::forward<T>(r)) {
#ifdef SOL_CHECK_ARGUMENTS
if (!is_function<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this);
stack::check<basic_protected_function>(base_t::lua_state(), -1, type_panic);
}
#endif // Safety
}
basic_protected_function(const basic_protected_function&) = default; basic_protected_function(const basic_protected_function&) = default;
basic_protected_function& operator=(const basic_protected_function&) = default; basic_protected_function& operator=(const basic_protected_function&) = default;
basic_protected_function(basic_protected_function&&) = default; basic_protected_function(basic_protected_function&&) = default;
@ -148,6 +157,10 @@ namespace sol {
basic_protected_function(basic_function<base_t>&& b, reference eh = get_default_handler()) : base_t(std::move(b)), error_handler(std::move(eh)) {} basic_protected_function(basic_function<base_t>&& b, reference eh = get_default_handler()) : base_t(std::move(b)), error_handler(std::move(eh)) {}
basic_protected_function(const stack_reference& r, reference eh = get_default_handler()) : basic_protected_function(r.lua_state(), r.stack_index(), std::move(eh)) {} basic_protected_function(const stack_reference& r, reference eh = get_default_handler()) : basic_protected_function(r.lua_state(), r.stack_index(), std::move(eh)) {}
basic_protected_function(stack_reference&& r, reference eh = get_default_handler()) : basic_protected_function(r.lua_state(), r.stack_index(), std::move(eh)) {} basic_protected_function(stack_reference&& r, reference eh = get_default_handler()) : basic_protected_function(r.lua_state(), r.stack_index(), std::move(eh)) {}
template <typename Super>
basic_protected_function(proxy_base<Super>&& p, reference eh = get_default_handler()) : basic_protected_function(p.operator basic_function<base_t>(), std::move(eh)) {}
template <typename Super>
basic_protected_function(const proxy_base<Super>& p, reference eh = get_default_handler()) : basic_protected_function(static_cast<basic_function<base_t>>(p), std::move(eh)) {}
basic_protected_function(lua_State* L, int index = -1, reference eh = get_default_handler()) : base_t(L, index), error_handler(std::move(eh)) { basic_protected_function(lua_State* L, int index = -1, reference eh = get_default_handler()) : base_t(L, index), error_handler(std::move(eh)) {
#ifdef SOL_CHECK_ARGUMENTS #ifdef SOL_CHECK_ARGUMENTS
stack::check<basic_protected_function>(L, index, type_panic); stack::check<basic_protected_function>(L, index, type_panic);

View File

@ -159,7 +159,7 @@ namespace sol {
typedef iterator const_iterator; typedef iterator const_iterator;
basic_table_core() noexcept : base_t() { } basic_table_core() noexcept : base_t() { }
template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_table_core>>, std::is_base_of<base_t, meta::unqualified_t<T>>> = meta::enabler> template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_table_core>>, meta::neg<std::is_same<base_t, stack_reference>>, std::is_base_of<base_t, meta::unqualified_t<T>>> = meta::enabler>
basic_table_core(T&& r) noexcept : base_t(std::forward<T>(r)) { basic_table_core(T&& r) noexcept : base_t(std::forward<T>(r)) {
#ifdef SOL_CHECK_ARGUMENTS #ifdef SOL_CHECK_ARGUMENTS
if (!is_table<meta::unqualified_t<T>>::value) { if (!is_table<meta::unqualified_t<T>>::value) {

View File

@ -727,10 +727,26 @@ namespace sol {
template <typename T> template <typename T>
struct is_table : std::false_type {}; struct is_table : std::false_type {};
template <bool x, typename T> template <bool x, typename T>
struct is_table<basic_table_core<x, T>> : std::true_type {}; struct is_table<basic_table_core<x, T>> : std::true_type {};
template <typename T>
struct is_function : std::false_type {};
template <typename T>
struct is_function<basic_function<T>> : std::true_type {};
template <typename T>
struct is_function<basic_protected_function<T>> : std::true_type {};
template <typename T>
struct is_lightuserdata : std::false_type {};
template <typename T>
struct is_lightuserdata<basic_lightuserdata<T>> : std::true_type {};
template <typename T>
struct is_userdata : std::false_type {};
template <typename T>
struct is_userdata<basic_userdata<T>> : std::true_type {};
template<typename T> template<typename T>
inline type type_of() { inline type type_of() {
return lua_type_of<meta::unqualified_t<T>>::value; return lua_type_of<meta::unqualified_t<T>>::value;

View File

@ -29,6 +29,15 @@ namespace sol {
class basic_userdata : public base_t { class basic_userdata : public base_t {
public: public:
basic_userdata() noexcept = default; basic_userdata() noexcept = default;
template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_userdata>>, meta::neg<std::is_same<base_t, stack_reference>>, std::is_base_of<base_t, meta::unqualified_t<T>>> = meta::enabler>
basic_userdata(T&& r) noexcept : base_t(std::forward<T>(r)) {
#ifdef SOL_CHECK_ARGUMENTS
if (!is_userdata<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this);
type_assert(base_t::lua_state(), -1, type::userdata);
}
#endif // Safety
}
basic_userdata(const basic_userdata&) = default; basic_userdata(const basic_userdata&) = default;
basic_userdata(basic_userdata&&) = default; basic_userdata(basic_userdata&&) = default;
basic_userdata& operator=(const basic_userdata&) = default; basic_userdata& operator=(const basic_userdata&) = default;
@ -46,6 +55,15 @@ namespace sol {
class basic_lightuserdata : public base_t { class basic_lightuserdata : public base_t {
public: public:
basic_lightuserdata() noexcept = default; basic_lightuserdata() noexcept = default;
template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_lightuserdata>>, meta::neg<std::is_same<base_t, stack_reference>>, std::is_base_of<base_t, meta::unqualified_t<T>>> = meta::enabler>
basic_lightuserdata(T&& r) noexcept : base_t(std::forward<T>(r)) {
#ifdef SOL_CHECK_ARGUMENTS
if (!is_userdata<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this);
type_assert(base_t::lua_state(), -1, type::lightuserdata);
}
#endif // Safety
}
basic_lightuserdata(const basic_lightuserdata&) = default; basic_lightuserdata(const basic_lightuserdata&) = default;
basic_lightuserdata(basic_lightuserdata&&) = default; basic_lightuserdata(basic_lightuserdata&&) = default;
basic_lightuserdata& operator=(const basic_lightuserdata&) = default; basic_lightuserdata& operator=(const basic_lightuserdata&) = default;

View File

@ -302,14 +302,13 @@ TEST_CASE("functions/function_result-protected_function_result", "Function resul
lua.set("nontrampoline", c_nontrampolinefx); lua.set("nontrampoline", c_nontrampolinefx);
lua.set_function("bark", []() -> int {return 100; }); lua.set_function("bark", []() -> int {return 100; });
sol::protected_function doom = lua["doom"]; sol::function luahandler = lua["luahandler"];
sol::protected_function luadoom = lua["luadoom"]; sol::function cpphandler = lua["cpphandler"];
sol::protected_function doom(lua["doom"], luahandler);
sol::protected_function luadoom(lua["luadoom"]);
sol::protected_function nontrampoline = lua["nontrampoline"]; sol::protected_function nontrampoline = lua["nontrampoline"];
sol::protected_function justfine = lua["bark"]; sol::protected_function justfine = lua["bark"];
sol::protected_function justfinewithhandler = lua["bark"]; sol::protected_function justfinewithhandler = lua["bark"];
sol::function luahandler = lua["luahandler"];
sol::function cpphandler = lua["cpphandler"];
doom.error_handler = luahandler;
luadoom.error_handler = cpphandler; luadoom.error_handler = cpphandler;
nontrampoline.error_handler = cpphandler; nontrampoline.error_handler = cpphandler;
justfinewithhandler.error_handler = luahandler; justfinewithhandler.error_handler = luahandler;