More templated fixes.

Closes #131
Closes #126, for the time being -- we can't make it go any faster without fundamentally breaking the system, and I can't do that to users rn
This commit is contained in:
ThePhD 2016-06-29 14:08:26 -04:00
parent 833be87011
commit 09ee4db1ed
9 changed files with 108 additions and 31 deletions

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-06-27 16:44:52.053533 UTC // Generated 2016-06-29 18:04:02.541304 UTC
// This header was generated with sol v2.8.9 (revision 4a0bfe1) // This header was generated with sol v2.8.9 (revision 833be87)
// https://github.com/ThePhD/sol2 // https://github.com/ThePhD/sol2
#ifndef SOL_SINGLE_INCLUDE_HPP #ifndef SOL_SINGLE_INCLUDE_HPP
@ -385,6 +385,12 @@ namespace sol {
template<typename T> template<typename T>
using unwrapped_t = typename unwrapped<T>::type; using unwrapped_t = typename unwrapped<T>::type;
template <typename T>
struct unwrap_unqualified : unwrapped<unqualified_t<T>> {};
template <typename T>
using unwrap_unqualified_t = typename unwrap_unqualified<T>::type;
template<typename T> template<typename T>
struct remove_member_pointer; struct remove_member_pointer;
@ -5142,6 +5148,18 @@ namespace sol {
destroy(std::forward<T>(obj)); destroy(std::forward<T>(obj));
} }
}; };
struct deleter {
template <typename T>
void operator()(T* p) const {
delete p;
}
};
template <typename T, typename Dx, typename... Args>
inline std::unique_ptr<T, Dx> make_unique_deleter(Args&&... args) {
return std::unique_ptr<T, Dx>(new T(std::forward<Args>(args)...));
}
} // detail } // detail
template <typename... Args> template <typename... Args>
@ -6811,21 +6829,21 @@ namespace sol {
template <bool is_index, bool is_variable, typename C> template <bool is_index, bool is_variable, typename C>
struct agnostic_lua_call_wrapper<no_prop, is_index, is_variable, C> { struct agnostic_lua_call_wrapper<no_prop, is_index, is_variable, C> {
static int call(lua_State* L, no_prop&) { static int call(lua_State* L, const no_prop&) {
return luaL_error(L, is_index ? "sol: cannot read from a writeonly property" : "sol: cannot write to a readonly property"); return luaL_error(L, is_index ? "sol: cannot read from a writeonly property" : "sol: cannot write to a readonly property");
} }
}; };
template <bool is_index, bool is_variable, typename C> template <bool is_index, bool is_variable, typename C>
struct agnostic_lua_call_wrapper<no_construction, is_index, is_variable, C> { struct agnostic_lua_call_wrapper<no_construction, is_index, is_variable, C> {
static int call(lua_State* L, no_construction&) { static int call(lua_State* L, const no_construction&) {
return luaL_error(L, "sol: cannot call this constructor (tagged as non-constructible)"); return luaL_error(L, "sol: cannot call this constructor (tagged as non-constructible)");
} }
}; };
template <typename... Args, bool is_index, bool is_variable, typename C> template <typename... Args, bool is_index, bool is_variable, typename C>
struct agnostic_lua_call_wrapper<bases<Args...>, is_index, is_variable, C> { struct agnostic_lua_call_wrapper<bases<Args...>, is_index, is_variable, C> {
static int call(lua_State*, bases<Args...>&) { static int call(lua_State*, const bases<Args...>&) {
// Uh. How did you even call this, lul // Uh. How did you even call this, lul
return 0; return 0;
} }
@ -6997,7 +7015,7 @@ namespace sol {
struct lua_call_wrapper<T, sol::destructor_wrapper<Fx>, is_index, is_variable, std::enable_if_t<std::is_void<Fx>::value>> { struct lua_call_wrapper<T, sol::destructor_wrapper<Fx>, is_index, is_variable, std::enable_if_t<std::is_void<Fx>::value>> {
typedef sol::destructor_wrapper<Fx> F; typedef sol::destructor_wrapper<Fx> F;
static int call(lua_State* L, F&) { static int call(lua_State* L, const F&) {
return destruct<T>(L); return destruct<T>(L);
} }
}; };
@ -7006,8 +7024,8 @@ namespace sol {
struct lua_call_wrapper<T, sol::destructor_wrapper<Fx>, is_index, is_variable, std::enable_if_t<!std::is_void<Fx>::value>> { struct lua_call_wrapper<T, sol::destructor_wrapper<Fx>, is_index, is_variable, std::enable_if_t<!std::is_void<Fx>::value>> {
typedef sol::destructor_wrapper<Fx> F; typedef sol::destructor_wrapper<Fx> F;
static int call(lua_State* L, F& f) { static int call(lua_State* L, const F& f) {
T* obj = stack::get<non_null<T*>>(L); T& obj = stack::get<T>(L);
f.fx(detail::implicit_wrapper<T>(obj)); f.fx(detail::implicit_wrapper<T>(obj));
return 0; return 0;
} }
@ -8583,12 +8601,12 @@ namespace sol {
return *this; return *this;
} }
template<typename U, meta::enable<meta::is_callable<meta::unqualified_t<U>>> = meta::enabler> template<typename U, meta::enable<meta::is_callable<meta::unwrap_unqualified_t<U>>> = meta::enabler>
proxy& operator=(U&& other) { proxy& operator=(U&& other) {
return set_function(std::forward<U>(other)); return set_function(std::forward<U>(other));
} }
template<typename U, meta::disable<meta::is_callable<meta::unqualified_t<U>>> = meta::enabler> template<typename U, meta::disable<meta::is_callable<meta::unwrap_unqualified_t<U>>> = meta::enabler>
proxy& operator=(U&& other) { proxy& operator=(U&& other) {
return set(std::forward<U>(other)); return set(std::forward<U>(other));
} }
@ -8775,9 +8793,16 @@ namespace sol {
else else
return luaL_error(L, "sol: attempt to index (set) nil value \"%s\" on userdata (bad (misspelled?) key name or does not exist)", accessor.data()); return luaL_error(L, "sol: attempt to index (set) nil value \"%s\" on userdata (bad (misspelled?) key name or does not exist)", accessor.data());
} }
} // usertype_detail } // usertype_detail
template <typename T>
struct clean_type {
typedef std::conditional_t<std::is_array<meta::unqualified_t<T>>::value, T&, std::decay_t<T>> type;
};
template <typename T>
using clean_type_t = typename clean_type<T>::type;
template <typename T, typename IndexSequence, typename... Tn> template <typename T, typename IndexSequence, typename... Tn>
struct usertype_metatable : usertype_detail::registrar {}; struct usertype_metatable : usertype_detail::registrar {};
@ -8786,7 +8811,8 @@ namespace sol {
typedef std::make_index_sequence<sizeof...(I) * 2> indices; typedef std::make_index_sequence<sizeof...(I) * 2> indices;
typedef std::index_sequence<I...> half_indices; typedef std::index_sequence<I...> half_indices;
typedef std::array<luaL_Reg, sizeof...(Tn) / 2 + 1> regs_t; typedef std::array<luaL_Reg, sizeof...(Tn) / 2 + 1> regs_t;
typedef std::tuple<Tn...> Tuple; typedef std::tuple<Tn...> RawTuple;
typedef std::tuple<clean_type_t<Tn> ...> Tuple;
template <std::size_t Idx> template <std::size_t Idx>
struct check_binding : is_variable_binding<meta::unqualified_tuple_element_t<Idx, Tuple>> {}; struct check_binding : is_variable_binding<meta::unqualified_tuple_element_t<Idx, Tuple>> {};
Tuple functions; Tuple functions;
@ -8799,12 +8825,12 @@ namespace sol {
bool mustindex; bool mustindex;
bool secondarymeta; bool secondarymeta;
template <std::size_t Idx, meta::enable<std::is_same<lua_CFunction, meta::unqualified_tuple_element<Idx + 1, Tuple>>> = meta::enabler> template <std::size_t Idx, meta::enable<std::is_same<lua_CFunction, meta::unqualified_tuple_element<Idx + 1, RawTuple>>> = meta::enabler>
inline lua_CFunction make_func() { inline lua_CFunction make_func() {
return std::get<Idx + 1>(functions); return std::get<Idx + 1>(functions);
} }
template <std::size_t Idx, meta::disable<std::is_same<lua_CFunction, meta::unqualified_tuple_element<Idx + 1, Tuple>>> = meta::enabler> template <std::size_t Idx, meta::disable<std::is_same<lua_CFunction, meta::unqualified_tuple_element<Idx + 1, RawTuple>>> = meta::enabler>
inline lua_CFunction make_func() { inline lua_CFunction make_func() {
return call<Idx + 1>; return call<Idx + 1>;
} }
@ -9111,10 +9137,10 @@ using has_destructor = meta::any<is_destructor<meta::unqualified_t<Args>>...>;
template<typename T> template<typename T>
class usertype { class usertype {
private: private:
std::unique_ptr<usertype_detail::registrar> metatableregister; std::unique_ptr<usertype_detail::registrar, detail::deleter> metatableregister;
template<typename... Args> template<typename... Args>
usertype(usertype_detail::verified_tag, Args&&... args) : metatableregister( std::make_unique<usertype_metatable<T, std::make_index_sequence<sizeof...(Args) / 2>, std::decay_t<Args>...>>(std::forward<Args>(args)...) ) {} usertype(usertype_detail::verified_tag, Args&&... args) : metatableregister( detail::make_unique_deleter<usertype_metatable<T, std::make_index_sequence<sizeof...(Args) / 2>, Args...>, detail::deleter>(std::forward<Args>(args)...) ) {}
template<typename... Args> template<typename... Args>
usertype(usertype_detail::add_destructor_tag, Args&&... args) : usertype(usertype_detail::verified, std::forward<Args>(args)..., "__gc", default_destructor) {} usertype(usertype_detail::add_destructor_tag, Args&&... args) : usertype(usertype_detail::verified, std::forward<Args>(args)..., "__gc", default_destructor) {}

View File

@ -182,21 +182,21 @@ namespace sol {
template <bool is_index, bool is_variable, typename C> template <bool is_index, bool is_variable, typename C>
struct agnostic_lua_call_wrapper<no_prop, is_index, is_variable, C> { struct agnostic_lua_call_wrapper<no_prop, is_index, is_variable, C> {
static int call(lua_State* L, no_prop&) { static int call(lua_State* L, const no_prop&) {
return luaL_error(L, is_index ? "sol: cannot read from a writeonly property" : "sol: cannot write to a readonly property"); return luaL_error(L, is_index ? "sol: cannot read from a writeonly property" : "sol: cannot write to a readonly property");
} }
}; };
template <bool is_index, bool is_variable, typename C> template <bool is_index, bool is_variable, typename C>
struct agnostic_lua_call_wrapper<no_construction, is_index, is_variable, C> { struct agnostic_lua_call_wrapper<no_construction, is_index, is_variable, C> {
static int call(lua_State* L, no_construction&) { static int call(lua_State* L, const no_construction&) {
return luaL_error(L, "sol: cannot call this constructor (tagged as non-constructible)"); return luaL_error(L, "sol: cannot call this constructor (tagged as non-constructible)");
} }
}; };
template <typename... Args, bool is_index, bool is_variable, typename C> template <typename... Args, bool is_index, bool is_variable, typename C>
struct agnostic_lua_call_wrapper<bases<Args...>, is_index, is_variable, C> { struct agnostic_lua_call_wrapper<bases<Args...>, is_index, is_variable, C> {
static int call(lua_State*, bases<Args...>&) { static int call(lua_State*, const bases<Args...>&) {
// Uh. How did you even call this, lul // Uh. How did you even call this, lul
return 0; return 0;
} }
@ -368,7 +368,7 @@ namespace sol {
struct lua_call_wrapper<T, sol::destructor_wrapper<Fx>, is_index, is_variable, std::enable_if_t<std::is_void<Fx>::value>> { struct lua_call_wrapper<T, sol::destructor_wrapper<Fx>, is_index, is_variable, std::enable_if_t<std::is_void<Fx>::value>> {
typedef sol::destructor_wrapper<Fx> F; typedef sol::destructor_wrapper<Fx> F;
static int call(lua_State* L, F&) { static int call(lua_State* L, const F&) {
return destruct<T>(L); return destruct<T>(L);
} }
}; };
@ -377,8 +377,8 @@ namespace sol {
struct lua_call_wrapper<T, sol::destructor_wrapper<Fx>, is_index, is_variable, std::enable_if_t<!std::is_void<Fx>::value>> { struct lua_call_wrapper<T, sol::destructor_wrapper<Fx>, is_index, is_variable, std::enable_if_t<!std::is_void<Fx>::value>> {
typedef sol::destructor_wrapper<Fx> F; typedef sol::destructor_wrapper<Fx> F;
static int call(lua_State* L, F& f) { static int call(lua_State* L, const F& f) {
T* obj = stack::get<non_null<T*>>(L); T& obj = stack::get<T>(L);
f.fx(detail::implicit_wrapper<T>(obj)); f.fx(detail::implicit_wrapper<T>(obj));
return 0; return 0;
} }

View File

@ -63,12 +63,12 @@ namespace sol {
return *this; return *this;
} }
template<typename U, meta::enable<meta::is_callable<meta::unqualified_t<U>>> = meta::enabler> template<typename U, meta::enable<meta::is_callable<meta::unwrap_unqualified_t<U>>> = meta::enabler>
proxy& operator=(U&& other) { proxy& operator=(U&& other) {
return set_function(std::forward<U>(other)); return set_function(std::forward<U>(other));
} }
template<typename U, meta::disable<meta::is_callable<meta::unqualified_t<U>>> = meta::enabler> template<typename U, meta::disable<meta::is_callable<meta::unwrap_unqualified_t<U>>> = meta::enabler>
proxy& operator=(U&& other) { proxy& operator=(U&& other) {
return set(std::forward<U>(other)); return set(std::forward<U>(other));
} }

View File

@ -52,6 +52,18 @@ namespace sol {
destroy(std::forward<T>(obj)); destroy(std::forward<T>(obj));
} }
}; };
struct deleter {
template <typename T>
void operator()(T* p) const {
delete p;
}
};
template <typename T, typename Dx, typename... Args>
inline std::unique_ptr<T, Dx> make_unique_deleter(Args&&... args) {
return std::unique_ptr<T, Dx>(new T(std::forward<Args>(args)...));
}
} // detail } // detail
template <typename... Args> template <typename... Args>

View File

@ -58,6 +58,12 @@ namespace sol {
template<typename T> template<typename T>
using unwrapped_t = typename unwrapped<T>::type; using unwrapped_t = typename unwrapped<T>::type;
template <typename T>
struct unwrap_unqualified : unwrapped<unqualified_t<T>> {};
template <typename T>
using unwrap_unqualified_t = typename unwrap_unqualified<T>::type;
template<typename T> template<typename T>
struct remove_member_pointer; struct remove_member_pointer;

View File

@ -60,10 +60,10 @@ using has_destructor = meta::any<is_destructor<meta::unqualified_t<Args>>...>;
template<typename T> template<typename T>
class usertype { class usertype {
private: private:
std::unique_ptr<usertype_detail::registrar> metatableregister; std::unique_ptr<usertype_detail::registrar, detail::deleter> metatableregister;
template<typename... Args> template<typename... Args>
usertype(usertype_detail::verified_tag, Args&&... args) : metatableregister( std::make_unique<usertype_metatable<T, std::make_index_sequence<sizeof...(Args) / 2>, std::decay_t<Args>...>>(std::forward<Args>(args)...) ) {} usertype(usertype_detail::verified_tag, Args&&... args) : metatableregister( detail::make_unique_deleter<usertype_metatable<T, std::make_index_sequence<sizeof...(Args) / 2>, Args...>, detail::deleter>(std::forward<Args>(args)...) ) {}
template<typename... Args> template<typename... Args>
usertype(usertype_detail::add_destructor_tag, Args&&... args) : usertype(usertype_detail::verified, std::forward<Args>(args)..., "__gc", default_destructor) {} usertype(usertype_detail::add_destructor_tag, Args&&... args) : usertype(usertype_detail::verified, std::forward<Args>(args)..., "__gc", default_destructor) {}

View File

@ -86,9 +86,16 @@ namespace sol {
else else
return luaL_error(L, "sol: attempt to index (set) nil value \"%s\" on userdata (bad (misspelled?) key name or does not exist)", accessor.data()); return luaL_error(L, "sol: attempt to index (set) nil value \"%s\" on userdata (bad (misspelled?) key name or does not exist)", accessor.data());
} }
} // usertype_detail } // usertype_detail
template <typename T>
struct clean_type {
typedef std::conditional_t<std::is_array<meta::unqualified_t<T>>::value, T&, std::decay_t<T>> type;
};
template <typename T>
using clean_type_t = typename clean_type<T>::type;
template <typename T, typename IndexSequence, typename... Tn> template <typename T, typename IndexSequence, typename... Tn>
struct usertype_metatable : usertype_detail::registrar {}; struct usertype_metatable : usertype_detail::registrar {};
@ -97,7 +104,8 @@ namespace sol {
typedef std::make_index_sequence<sizeof...(I) * 2> indices; typedef std::make_index_sequence<sizeof...(I) * 2> indices;
typedef std::index_sequence<I...> half_indices; typedef std::index_sequence<I...> half_indices;
typedef std::array<luaL_Reg, sizeof...(Tn) / 2 + 1> regs_t; typedef std::array<luaL_Reg, sizeof...(Tn) / 2 + 1> regs_t;
typedef std::tuple<Tn...> Tuple; typedef std::tuple<Tn...> RawTuple;
typedef std::tuple<clean_type_t<Tn> ...> Tuple;
template <std::size_t Idx> template <std::size_t Idx>
struct check_binding : is_variable_binding<meta::unqualified_tuple_element_t<Idx, Tuple>> {}; struct check_binding : is_variable_binding<meta::unqualified_tuple_element_t<Idx, Tuple>> {};
Tuple functions; Tuple functions;
@ -110,12 +118,12 @@ namespace sol {
bool mustindex; bool mustindex;
bool secondarymeta; bool secondarymeta;
template <std::size_t Idx, meta::enable<std::is_same<lua_CFunction, meta::unqualified_tuple_element<Idx + 1, Tuple>>> = meta::enabler> template <std::size_t Idx, meta::enable<std::is_same<lua_CFunction, meta::unqualified_tuple_element<Idx + 1, RawTuple>>> = meta::enabler>
inline lua_CFunction make_func() { inline lua_CFunction make_func() {
return std::get<Idx + 1>(functions); return std::get<Idx + 1>(functions);
} }
template <std::size_t Idx, meta::disable<std::is_same<lua_CFunction, meta::unqualified_tuple_element<Idx + 1, Tuple>>> = meta::enabler> template <std::size_t Idx, meta::disable<std::is_same<lua_CFunction, meta::unqualified_tuple_element<Idx + 1, RawTuple>>> = meta::enabler>
inline lua_CFunction make_func() { inline lua_CFunction make_func() {
return call<Idx + 1>; return call<Idx + 1>;
} }

View File

@ -1033,4 +1033,4 @@ nocopy = NoCopy.new()
nocopy.val = 5 nocopy.val = 5
)__") )__")
); );
} }

View File

@ -511,3 +511,28 @@ TEST_CASE("features/multiple-inheritance", "Ensure that multiple inheritance wor
REQUIRE(cb1->a1 == 250); REQUIRE(cb1->a1 == 250);
REQUIRE(cb2->a2 == 500); REQUIRE(cb2->a2 == 500);
} }
TEST_CASE("regressions/std::ref", "Ensure that std::reference_wrapper<> isn't considered as a function by using unwrap_unqualified_t trait") {
struct base1 {
int a1 = 250;
};
sol::state lua;
base1 v;
lua["vp"] = &v;
lua["vr"] = std::ref(v);
base1* vp = lua["vp"];
base1& vr = lua["vr"];
REQUIRE(vp != nullptr);
REQUIRE(vp == &v);
REQUIRE(vp->a1 == 250);
REQUIRE(vr.a1 == 250);
v.a1 = 568;
REQUIRE(vp->a1 == 568);
REQUIRE(vr.a1 == 568);
}