| 32 | struct qualified_checker { |
| 33 | template <typename Handler> |
| 34 | static bool check(lua_State* L, int index, Handler&& handler, record& tracking) { |
| 35 | using no_cv_X = meta::unqualified_t<X>; |
| 36 | if constexpr (!std::is_reference_v<X> && is_unique_usertype_v<no_cv_X>) { |
| 37 | using element = unique_usertype_element_t<no_cv_X>; |
| 38 | if constexpr (is_actual_type_rebindable_for_v<no_cv_X>) { |
| 39 | using rebound_actual_type = unique_usertype_rebind_actual_t<no_cv_X>; |
| 40 | // we have a unique pointer type that can be |
| 41 | // rebound to a base/derived type |
| 42 | const type indextype = type_of(L, index); |
| 43 | tracking.use(1); |
| 44 | if (indextype != type::userdata) { |
| 45 | handler(L, index, type::userdata, indextype, "value is not a userdata"); |
| 46 | return false; |
| 47 | } |
| 48 | void* memory = lua_touserdata(L, index); |
| 49 | memory = detail::align_usertype_unique_destructor(memory); |
| 50 | detail::unique_destructor& pdx = *static_cast<detail::unique_destructor*>(memory); |
| 51 | if (&detail::usertype_unique_alloc_destroy<element, no_cv_X> == pdx) { |
| 52 | return true; |
| 53 | } |
| 54 | if constexpr (derive<element>::value) { |
| 55 | memory = detail::align_usertype_unique_tag<true, false>(memory); |
| 56 | detail::unique_tag& ic = *reinterpret_cast<detail::unique_tag*>(memory); |
| 57 | string_view ti = usertype_traits<element>::qualified_name(); |
| 58 | string_view rebind_ti = usertype_traits<rebound_actual_type>::qualified_name(); |
| 59 | if (ic(nullptr, nullptr, ti, rebind_ti) != 0) { |
| 60 | return true; |
| 61 | } |
| 62 | } |
| 63 | handler(L, index, type::userdata, indextype, "value is a userdata but is not the correct unique usertype"); |
| 64 | return false; |
| 65 | } |
| 66 | else { |
| 67 | return stack::unqualified_check<X>(L, index, std::forward<Handler>(handler), tracking); |
| 68 | } |
| 69 | } |
| 70 | else if constexpr (!std::is_reference_v<X> && is_container_v<no_cv_X>) { |
| 71 | if (type_of(L, index) == type::userdata) { |
| 72 | return stack::unqualified_check<X>(L, index, std::forward<Handler>(handler), tracking); |
| 73 | } |
| 74 | else { |
| 75 | return stack::unqualified_check<nested<X>>(L, index, std::forward<Handler>(handler), tracking); |
| 76 | } |
| 77 | } |
| 78 | else if constexpr (!std::is_reference_v<X> && meta::is_specialization_of_v<X, nested>) { |
| 79 | using NestedX = typename meta::unqualified_t<X>::nested_type; |
| 80 | return stack::check<NestedX>(L, index, ::std::forward<Handler>(handler), tracking); |
| 81 | } |
| 82 | else { |
| 83 | return stack::unqualified_check<X>(L, index, std::forward<Handler>(handler), tracking); |
| 84 | } |
| 85 | } |
| 86 | }; |
| 87 | }} // namespace sol::stack |
| 88 |
nothing calls this directly
no test coverage detected