void support

This commit is contained in:
ThePhD 2019-01-28 12:33:21 -05:00
parent e1f3e5f009
commit fbf5b48dc8
No known key found for this signature in database
GPG Key ID: 1509DB1C0F702BFA
6 changed files with 105 additions and 104 deletions

View File

@ -330,13 +330,15 @@ namespace sol {
void* pointer_adjusted; void* pointer_adjusted;
void* data_adjusted; void* data_adjusted;
bool result = attempt_alloc(L, std::alignment_of_v<T*>, sizeof(T*), std::alignment_of_v<T>, sizeof(T), initial_size, pointer_adjusted, data_adjusted); bool result
= attempt_alloc(L, std::alignment_of_v<T*>, sizeof(T*), std::alignment_of_v<T>, sizeof(T), initial_size, pointer_adjusted, data_adjusted);
if (!result) { if (!result) {
// we're likely to get something that fails to perform the proper allocation a second time, // we're likely to get something that fails to perform the proper allocation a second time,
// so we use the suggested_new_size bump to help us out here // so we use the suggested_new_size bump to help us out here
pointer_adjusted = nullptr; pointer_adjusted = nullptr;
data_adjusted = nullptr; data_adjusted = nullptr;
result = attempt_alloc(L, std::alignment_of_v<T*>, sizeof(T*), std::alignment_of_v<T>, sizeof(T), misaligned_size, pointer_adjusted, data_adjusted); result = attempt_alloc(
L, std::alignment_of_v<T*>, sizeof(T*), std::alignment_of_v<T>, sizeof(T), misaligned_size, pointer_adjusted, data_adjusted);
if (!result) { if (!result) {
if (pointer_adjusted == nullptr) { if (pointer_adjusted == nullptr) {
luaL_error(L, "aligned allocation of userdata block (pointer section) for '%s' failed", detail::demangle<T>().c_str()); luaL_error(L, "aligned allocation of userdata block (pointer section) for '%s' failed", detail::demangle<T>().c_str());
@ -1343,30 +1345,35 @@ namespace sol {
template <typename T, typename Op> template <typename T, typename Op>
int comparsion_operator_wrap(lua_State* L) { int comparsion_operator_wrap(lua_State* L) {
auto maybel = stack::unqualified_check_get<T&>(L, 1); if constexpr (std::is_void_v<T>) {
if (!maybel) {
return stack::push(L, false); return stack::push(L, false);
} }
auto mayber = stack::unqualified_check_get<T&>(L, 2);
if (!mayber) {
return stack::push(L, false);
}
decltype(auto) l = *maybel;
decltype(auto) r = *mayber;
if constexpr (std::is_same_v<no_comp, Op>) {
std::equal_to<> op;
return stack::push(L, op(detail::ptr(l), detail::ptr(r)));
}
else { else {
if constexpr (std::is_same_v<std::equal_to<>, Op> // cf-hack auto maybel = stack::unqualified_check_get<T&>(L, 1);
|| std::is_same_v<std::less_equal<>, Op> // if (!maybel) {
|| std::is_same_v<std::less_equal<>, Op>) { // return stack::push(L, false);
if (detail::ptr(l) == detail::ptr(r)) { }
return stack::push(L, true); auto mayber = stack::unqualified_check_get<T&>(L, 2);
} if (!mayber) {
return stack::push(L, false);
}
decltype(auto) l = *maybel;
decltype(auto) r = *mayber;
if constexpr (std::is_same_v<no_comp, Op>) {
std::equal_to<> op;
return stack::push(L, op(detail::ptr(l), detail::ptr(r)));
}
else {
if constexpr (std::is_same_v<std::equal_to<>, Op> // cf-hack
|| std::is_same_v<std::less_equal<>, Op> //
|| std::is_same_v<std::less_equal<>, Op>) { //
if (detail::ptr(l) == detail::ptr(r)) {
return stack::push(L, true);
}
}
Op op;
return stack::push(L, op(detail::deref(l), detail::deref(r)));
} }
Op op;
return stack::push(L, op(detail::deref(l), detail::deref(r)));
} }
} }

View File

@ -38,6 +38,11 @@
namespace sol { namespace sol {
namespace detail {
struct unchecked_t {};
const unchecked_t unchecked = unchecked_t{};
} // namespace detail
namespace meta { namespace meta {
using sfinae_yes_t = std::true_type; using sfinae_yes_t = std::true_type;
using sfinae_no_t = std::false_type; using sfinae_no_t = std::false_type;
@ -513,39 +518,24 @@ namespace sol {
struct is_matched_lookup_impl : std::false_type {}; struct is_matched_lookup_impl : std::false_type {};
template <typename T> template <typename T>
struct is_matched_lookup_impl<T, true> : std::is_same<typename T::key_type, typename T::value_type> {}; struct is_matched_lookup_impl<T, true> : std::is_same<typename T::key_type, typename T::value_type> {};
template <typename T>
using non_void_t = std::conditional_t<std::is_void_v<T>, ::sol::detail::unchecked_t, T>;
} // namespace meta_detail } // namespace meta_detail
template <typename T, typename U = T> template <typename T, typename U = T>
struct supports_op_less : decltype(meta_detail::supports_op_less_test(std::declval<T&>(), std::declval<U&>())) {}; using supports_op_less = decltype(meta_detail::supports_op_less_test(std::declval<meta_detail::non_void_t<T>&>(), std::declval<meta_detail::non_void_t<U>&>()));
template <typename T>
struct supports_op_less<void, T> : std::false_type {};
template <typename T>
struct supports_op_less<T, void> : std::false_type {};
template <typename T, typename U = T> template <typename T, typename U = T>
struct supports_op_equal : decltype(meta_detail::supports_op_equal_test(std::declval<T&>(), std::declval<U&>())) {}; using supports_op_equal = decltype(meta_detail::supports_op_equal_test(std::declval<meta_detail::non_void_t<T>&>(), std::declval<meta_detail::non_void_t<U>&>()));
template <typename T>
struct supports_op_equal<void, T> : std::false_type {};
template <typename T>
struct supports_op_equal<T, void> : std::false_type {};
template <typename T, typename U = T> template <typename T, typename U = T>
struct supports_op_less_equal : decltype(meta_detail::supports_op_less_equal_test(std::declval<T&>(), std::declval<U&>())) {}; using supports_op_less_equal = decltype(meta_detail::supports_op_less_equal_test(std::declval<meta_detail::non_void_t<T>&>(), std::declval<meta_detail::non_void_t<U>&>()));
template <typename T>
struct supports_op_less_equal<void, T> : std::false_type {};
template <typename T>
struct supports_op_less_equal<T, void> : std::false_type {};
template <typename T, typename U = std::ostream> template <typename T, typename U = std::ostream>
struct supports_ostream_op : decltype(meta_detail::supports_ostream_op(std::declval<T&>(), std::declval<U&>())) {}; using supports_ostream_op = decltype(meta_detail::supports_ostream_op(std::declval<meta_detail::non_void_t<T>&>(), std::declval<meta_detail::non_void_t<U>&>()));
template <typename T> template <typename T>
struct supports_ostream_op<void, T> : std::false_type {}; using supports_adl_to_string = decltype(meta_detail::supports_adl_to_string(std::declval<meta_detail::non_void_t<T>&>()));
template <typename T> template <typename T>
struct supports_ostream_op<T, void> : std::false_type {}; using supports_to_string_member = meta::boolean<meta_detail::has_to_string_test<meta_detail::non_void_t<T>>::value>;
template <typename T>
struct supports_adl_to_string : decltype(meta_detail::supports_adl_to_string(std::declval<T&>())) {};
template <>
struct supports_adl_to_string<void> : std::false_type {};
template <typename T>
using supports_to_string_member = meta::boolean<meta_detail::has_to_string_test<T>::value>;
template <typename T> template <typename T>
struct is_callable : boolean<meta_detail::is_callable<T>::value> {}; struct is_callable : boolean<meta_detail::is_callable<T>::value> {};

View File

@ -93,9 +93,6 @@ namespace sol {
} }
}; };
struct unchecked_t {};
const unchecked_t unchecked = unchecked_t{};
struct yield_tag_t {}; struct yield_tag_t {};
const yield_tag_t yield_tag = yield_tag_t{}; const yield_tag_t yield_tag = yield_tag_t{};
} // namespace detail } // namespace detail

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 2019-01-28 16:32:19.530572 UTC // Generated 2019-01-28 17:33:06.880854 UTC
// This header was generated with sol v2.20.6 (revision ad494bd) // This header was generated with sol v2.20.6 (revision e1f3e5f)
// https://github.com/ThePhD/sol2 // https://github.com/ThePhD/sol2
#ifndef SOL_SINGLE_INCLUDE_FORWARD_HPP #ifndef SOL_SINGLE_INCLUDE_FORWARD_HPP

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 2019-01-28 16:32:19.243332 UTC // Generated 2019-01-28 17:33:06.587638 UTC
// This header was generated with sol v2.20.6 (revision ad494bd) // This header was generated with sol v2.20.6 (revision e1f3e5f)
// https://github.com/ThePhD/sol2 // https://github.com/ThePhD/sol2
#ifndef SOL_SINGLE_INCLUDE_HPP #ifndef SOL_SINGLE_INCLUDE_HPP
@ -1230,6 +1230,11 @@ namespace sol {
#include <iosfwd> #include <iosfwd>
namespace sol { namespace sol {
namespace detail {
struct unchecked_t {};
const unchecked_t unchecked = unchecked_t{};
} // namespace detail
namespace meta { namespace meta {
using sfinae_yes_t = std::true_type; using sfinae_yes_t = std::true_type;
using sfinae_no_t = std::false_type; using sfinae_no_t = std::false_type;
@ -1705,39 +1710,24 @@ namespace sol {
struct is_matched_lookup_impl : std::false_type {}; struct is_matched_lookup_impl : std::false_type {};
template <typename T> template <typename T>
struct is_matched_lookup_impl<T, true> : std::is_same<typename T::key_type, typename T::value_type> {}; struct is_matched_lookup_impl<T, true> : std::is_same<typename T::key_type, typename T::value_type> {};
template <typename T>
using non_void_t = std::conditional_t<std::is_void_v<T>, ::sol::detail::unchecked_t, T>;
} // namespace meta_detail } // namespace meta_detail
template <typename T, typename U = T> template <typename T, typename U = T>
struct supports_op_less : decltype(meta_detail::supports_op_less_test(std::declval<T&>(), std::declval<U&>())) {}; using supports_op_less = decltype(meta_detail::supports_op_less_test(std::declval<meta_detail::non_void_t<T>&>(), std::declval<meta_detail::non_void_t<U>&>()));
template <typename T>
struct supports_op_less<void, T> : std::false_type {};
template <typename T>
struct supports_op_less<T, void> : std::false_type {};
template <typename T, typename U = T> template <typename T, typename U = T>
struct supports_op_equal : decltype(meta_detail::supports_op_equal_test(std::declval<T&>(), std::declval<U&>())) {}; using supports_op_equal = decltype(meta_detail::supports_op_equal_test(std::declval<meta_detail::non_void_t<T>&>(), std::declval<meta_detail::non_void_t<U>&>()));
template <typename T>
struct supports_op_equal<void, T> : std::false_type {};
template <typename T>
struct supports_op_equal<T, void> : std::false_type {};
template <typename T, typename U = T> template <typename T, typename U = T>
struct supports_op_less_equal : decltype(meta_detail::supports_op_less_equal_test(std::declval<T&>(), std::declval<U&>())) {}; using supports_op_less_equal = decltype(meta_detail::supports_op_less_equal_test(std::declval<meta_detail::non_void_t<T>&>(), std::declval<meta_detail::non_void_t<U>&>()));
template <typename T>
struct supports_op_less_equal<void, T> : std::false_type {};
template <typename T>
struct supports_op_less_equal<T, void> : std::false_type {};
template <typename T, typename U = std::ostream> template <typename T, typename U = std::ostream>
struct supports_ostream_op : decltype(meta_detail::supports_ostream_op(std::declval<T&>(), std::declval<U&>())) {}; using supports_ostream_op = decltype(meta_detail::supports_ostream_op(std::declval<meta_detail::non_void_t<T>&>(), std::declval<meta_detail::non_void_t<U>&>()));
template <typename T> template <typename T>
struct supports_ostream_op<void, T> : std::false_type {}; using supports_adl_to_string = decltype(meta_detail::supports_adl_to_string(std::declval<meta_detail::non_void_t<T>&>()));
template <typename T> template <typename T>
struct supports_ostream_op<T, void> : std::false_type {}; using supports_to_string_member = meta::boolean<meta_detail::has_to_string_test<meta_detail::non_void_t<T>>::value>;
template <typename T>
struct supports_adl_to_string : decltype(meta_detail::supports_adl_to_string(std::declval<T&>())) {};
template <>
struct supports_adl_to_string<void> : std::false_type {};
template <typename T>
using supports_to_string_member = meta::boolean<meta_detail::has_to_string_test<T>::value>;
template <typename T> template <typename T>
struct is_callable : boolean<meta_detail::is_callable<T>::value> {}; struct is_callable : boolean<meta_detail::is_callable<T>::value> {};
@ -5888,9 +5878,6 @@ namespace sol {
} }
}; };
struct unchecked_t {};
const unchecked_t unchecked = unchecked_t{};
struct yield_tag_t {}; struct yield_tag_t {};
const yield_tag_t yield_tag = yield_tag_t{}; const yield_tag_t yield_tag = yield_tag_t{};
} // namespace detail } // namespace detail
@ -8923,13 +8910,15 @@ namespace sol {
void* pointer_adjusted; void* pointer_adjusted;
void* data_adjusted; void* data_adjusted;
bool result = attempt_alloc(L, std::alignment_of_v<T*>, sizeof(T*), std::alignment_of_v<T>, sizeof(T), initial_size, pointer_adjusted, data_adjusted); bool result
= attempt_alloc(L, std::alignment_of_v<T*>, sizeof(T*), std::alignment_of_v<T>, sizeof(T), initial_size, pointer_adjusted, data_adjusted);
if (!result) { if (!result) {
// we're likely to get something that fails to perform the proper allocation a second time, // we're likely to get something that fails to perform the proper allocation a second time,
// so we use the suggested_new_size bump to help us out here // so we use the suggested_new_size bump to help us out here
pointer_adjusted = nullptr; pointer_adjusted = nullptr;
data_adjusted = nullptr; data_adjusted = nullptr;
result = attempt_alloc(L, std::alignment_of_v<T*>, sizeof(T*), std::alignment_of_v<T>, sizeof(T), misaligned_size, pointer_adjusted, data_adjusted); result = attempt_alloc(
L, std::alignment_of_v<T*>, sizeof(T*), std::alignment_of_v<T>, sizeof(T), misaligned_size, pointer_adjusted, data_adjusted);
if (!result) { if (!result) {
if (pointer_adjusted == nullptr) { if (pointer_adjusted == nullptr) {
luaL_error(L, "aligned allocation of userdata block (pointer section) for '%s' failed", detail::demangle<T>().c_str()); luaL_error(L, "aligned allocation of userdata block (pointer section) for '%s' failed", detail::demangle<T>().c_str());
@ -9934,30 +9923,35 @@ namespace sol {
template <typename T, typename Op> template <typename T, typename Op>
int comparsion_operator_wrap(lua_State* L) { int comparsion_operator_wrap(lua_State* L) {
auto maybel = stack::unqualified_check_get<T&>(L, 1); if constexpr (std::is_void_v<T>) {
if (!maybel) {
return stack::push(L, false); return stack::push(L, false);
} }
auto mayber = stack::unqualified_check_get<T&>(L, 2);
if (!mayber) {
return stack::push(L, false);
}
decltype(auto) l = *maybel;
decltype(auto) r = *mayber;
if constexpr (std::is_same_v<no_comp, Op>) {
std::equal_to<> op;
return stack::push(L, op(detail::ptr(l), detail::ptr(r)));
}
else { else {
if constexpr (std::is_same_v<std::equal_to<>, Op> // cf-hack auto maybel = stack::unqualified_check_get<T&>(L, 1);
|| std::is_same_v<std::less_equal<>, Op> // if (!maybel) {
|| std::is_same_v<std::less_equal<>, Op>) { // return stack::push(L, false);
if (detail::ptr(l) == detail::ptr(r)) { }
return stack::push(L, true); auto mayber = stack::unqualified_check_get<T&>(L, 2);
} if (!mayber) {
return stack::push(L, false);
}
decltype(auto) l = *maybel;
decltype(auto) r = *mayber;
if constexpr (std::is_same_v<no_comp, Op>) {
std::equal_to<> op;
return stack::push(L, op(detail::ptr(l), detail::ptr(r)));
}
else {
if constexpr (std::is_same_v<std::equal_to<>, Op> // cf-hack
|| std::is_same_v<std::less_equal<>, Op> //
|| std::is_same_v<std::less_equal<>, Op>) { //
if (detail::ptr(l) == detail::ptr(r)) {
return stack::push(L, true);
}
}
Op op;
return stack::push(L, op(detail::deref(l), detail::deref(r)));
} }
Op op;
return stack::push(L, op(detail::deref(l), detail::deref(r)));
} }
} }

View File

@ -158,3 +158,16 @@ TEST_CASE("usertype/unique_usertype-check", "make sure unique usertypes don't ge
my_func(std::make_shared<Entity>()); my_func(std::make_shared<Entity>());
}()); }());
} }
TEST_CASE("usertype/unique void pointers", "can compile shared_ptr<void> types and not trip the compiler or sol2's internals") {
sol::state lua;
lua.set_function("f", [](std::shared_ptr<void> d) {
int* pi = static_cast<int*>(d.get());
REQUIRE(*pi == 567);
});
std::shared_ptr<void> s = std::make_shared<int>(567);
lua["s"] = std::move(s);
auto result = lua.safe_script("f(s)", sol::script_pass_on_error);
REQUIRE(result.valid());
}