@@ -3432,6 +3432,18 @@ static inline constexpr bool is_base_of_template_v = is_base_of_template<T, C>::
34323432template <class ... Args>
34333433constexpr bool dependent_false = false ;
34343434
3435+ template <class T >
3436+ struct is_tuple : std::false_type
3437+ {
3438+ };
3439+
3440+ template <class ... Ts>
3441+ struct is_tuple <std::tuple<Ts...>> : std::true_type
3442+ {
3443+ };
3444+
3445+ template <class T >
3446+ constexpr bool is_tuple_v = is_tuple<T>::value;
34353447}
34363448
34373449template <class T >
@@ -3706,19 +3718,28 @@ class Userdata
37063718 const auto classId = detail::getClassRegistryKey<T>();
37073719 const auto constId = detail::getConstRegistryKey<T>();
37083720
3709- if (lua_getmetatable (L, absIndex) && lua_istable (L, - 1 ))
3721+ if (lua_getmetatable (L, absIndex))
37103722 {
3711- lua_rawgetp_x (L, -1 , detail::getTypeIdentityKey ());
3712- const void * identity = lua_touserdata (L, -1 );
3713- lua_pop (L, 1 );
3714-
3715- if (identity == classId || (canBeConst && identity == constId))
3723+ lua_rawgetp_x (L, LUA_REGISTRYINDEX , classId);
3724+ if (lua_rawequal (L, -2 , -1 ))
37163725 {
3717- lua_pop (L, 1 );
3726+ lua_pop (L, 2 );
37183727 return static_cast <T*>(static_cast <Userdata*>(lua_touserdata (L, absIndex))->getPointer ());
37193728 }
3729+ lua_pop (L, 1 );
37203730
3721- lua_pop (L, 1 );
3731+ if (canBeConst)
3732+ {
3733+ lua_rawgetp_x (L, LUA_REGISTRYINDEX , constId);
3734+ if (lua_rawequal (L, -2 , -1 ))
3735+ {
3736+ lua_pop (L, 2 );
3737+ return static_cast <T*>(static_cast <Userdata*>(lua_touserdata (L, absIndex))->getPointer ());
3738+ }
3739+ lua_pop (L, 1 );
3740+ }
3741+
3742+ lua_pop (L, 1 );
37223743 }
37233744
37243745 auto clazz = getClass (L, absIndex, constId, classId, canBeConst);
@@ -6273,6 +6294,20 @@ auto pop_arguments(lua_State* L, std::tuple<Types...>& t)
62736294 return pop_arguments<Start, Index + 1 , Types...>(L, t);
62746295}
62756296
6297+ template <class Tuple , std::size_t ... Is>
6298+ Result push_tuple_impl (lua_State* L, const Tuple& value, std::index_sequence<Is...>)
6299+ {
6300+ Result result;
6301+ (void )((result = Stack<std::decay_t <std::tuple_element_t <Is, Tuple>>>::push (L, std::get<Is>(value)), bool (result)) && ...);
6302+ return result;
6303+ }
6304+
6305+ template <class ... Ts>
6306+ Result push_tuple (lua_State* L, const std::tuple<Ts...>& value)
6307+ {
6308+ return push_tuple_impl (L, value, std::index_sequence_for<Ts...>{});
6309+ }
6310+
62766311template <class T = void , class ... Args>
62776312constexpr auto make_array (Args&&... args)
62786313{
@@ -7567,13 +7602,21 @@ struct function
75677602 static int call (lua_State* L, F&& func)
75687603 {
75697604 Result result;
7605+ int numResults = 1 ;
75707606
75717607#if LUABRIDGE_HAS_EXCEPTIONS
75727608 try
75737609 {
75747610#endif
7575- result = Stack<ReturnType>::push (L, invoke_callable_from_stack<ArgsPack, Start>(L, std::forward<F>(func)));
7576-
7611+ if constexpr (detail::is_tuple_v<ReturnType>)
7612+ {
7613+ numResults = static_cast <int >(std::tuple_size_v<ReturnType>);
7614+ result = detail::push_tuple (L, invoke_callable_from_stack<ArgsPack, Start>(L, std::forward<F>(func)));
7615+ }
7616+ else
7617+ {
7618+ result = Stack<ReturnType>::push (L, invoke_callable_from_stack<ArgsPack, Start>(L, std::forward<F>(func)));
7619+ }
75777620#if LUABRIDGE_HAS_EXCEPTIONS
75787621 }
75797622 catch (const std::exception& e)
@@ -7585,20 +7628,28 @@ struct function
75857628 if (! result)
75867629 raise_lua_error (L, " %s" , result.error_cstr ());
75877630
7588- return 1 ;
7631+ return numResults ;
75897632 }
75907633
75917634 template <class T , class F >
75927635 static int call (lua_State* L, T* ptr, F&& func)
75937636 {
75947637 Result result;
7638+ int numResults = 1 ;
75957639
75967640#if LUABRIDGE_HAS_EXCEPTIONS
75977641 try
75987642 {
75997643#endif
7600- result = Stack<ReturnType>::push (L, invoke_member_callable_from_stack<ArgsPack, Start>(L, ptr, std::forward<F>(func)));
7601-
7644+ if constexpr (detail::is_tuple_v<ReturnType>)
7645+ {
7646+ numResults = static_cast <int >(std::tuple_size_v<ReturnType>);
7647+ result = detail::push_tuple (L, invoke_member_callable_from_stack<ArgsPack, Start>(L, ptr, std::forward<F>(func)));
7648+ }
7649+ else
7650+ {
7651+ result = Stack<ReturnType>::push (L, invoke_member_callable_from_stack<ArgsPack, Start>(L, ptr, std::forward<F>(func)));
7652+ }
76027653#if LUABRIDGE_HAS_EXCEPTIONS
76037654 }
76047655 catch (const std::exception& e)
@@ -7610,7 +7661,51 @@ struct function
76107661 if (! result)
76117662 raise_lua_error (L, " %s" , result.error_cstr ());
76127663
7613- return 1 ;
7664+ return numResults;
7665+ }
7666+ };
7667+
7668+ template <class ArgsPack , std::size_t Start>
7669+ struct function <std::tuple<>, ArgsPack, Start> : function<void , ArgsPack, Start>
7670+ {
7671+ template <class F >
7672+ static int call (lua_State* L, F&& func)
7673+ {
7674+ #if LUABRIDGE_HAS_EXCEPTIONS
7675+ try
7676+ {
7677+ #endif
7678+ invoke_callable_from_stack<ArgsPack, Start>(L, std::forward<F>(func));
7679+
7680+ #if LUABRIDGE_HAS_EXCEPTIONS
7681+ }
7682+ catch (const std::exception& e)
7683+ {
7684+ raise_lua_error (L, " %s" , e.what ());
7685+ }
7686+ #endif
7687+
7688+ return 0 ;
7689+ }
7690+
7691+ template <class T , class F >
7692+ static int call (lua_State* L, T* ptr, F&& func)
7693+ {
7694+ #if LUABRIDGE_HAS_EXCEPTIONS
7695+ try
7696+ {
7697+ #endif
7698+ invoke_member_callable_from_stack<ArgsPack, Start>(L, ptr, std::forward<F>(func));
7699+
7700+ #if LUABRIDGE_HAS_EXCEPTIONS
7701+ }
7702+ catch (const std::exception& e)
7703+ {
7704+ raise_lua_error (L, " %s" , e.what ());
7705+ }
7706+ #endif
7707+
7708+ return 0 ;
76147709 }
76157710};
76167711
@@ -9929,18 +10024,8 @@ bool is_handler_valid(const F& f) noexcept
992910024 return true ;
993010025}
993110026
9932- template <class T >
9933- struct IsTuple : std::false_type
9934- {
9935- };
9936-
9937- template <class ... Ts>
9938- struct IsTuple <std::tuple<Ts...>> : std::true_type
9939- {
9940- };
9941-
994210027template <class Tuple , std::size_t ... Indices>
9943- TypeResult<Tuple> decodeTupleResult (lua_State* L, int firstResultIndex , std::index_sequence<Indices...>)
10028+ TypeResult<Tuple> decode_tuple_result (lua_State* L, int first_result_index , std::index_sequence<Indices...>)
994410029{
994510030 Tuple value;
994610031 std::error_code ec;
@@ -9950,7 +10035,7 @@ TypeResult<Tuple> decodeTupleResult(lua_State* L, int firstResultIndex, std::ind
995010035 {
995110036 using ElementType = std::tuple_element_t <Indices, Tuple>;
995210037
9953- auto element = Stack<ElementType>::get (L, firstResultIndex + static_cast <int >(Indices));
10038+ auto element = Stack<ElementType>::get (L, first_result_index + static_cast <int >(Indices));
995410039 if (! element)
995510040 {
995610041 ec = element.error ();
@@ -9969,30 +10054,29 @@ TypeResult<Tuple> decodeTupleResult(lua_State* L, int firstResultIndex, std::ind
996910054}
997010055
997110056template <class R >
9972- TypeResult<R> decodeCallResult (lua_State* L, int firstResultIndex , int numReturnedValues )
10057+ TypeResult<R> decode_call_result (lua_State* L, int first_result_index , int num_returned_values )
997310058{
997410059 if constexpr (std::is_same_v<R, void > || std::is_same_v<R, std::tuple<>>)
997510060 {
9976- if (numReturnedValues != 0 )
10061+ if (num_returned_values != 0 )
997710062 return makeErrorCode (ErrorCode::InvalidTableSizeInCast);
997810063
997910064 return {};
998010065 }
9981- else
9982- if constexpr (IsTuple<R>::value)
10066+ else if constexpr (is_tuple_v<R>)
998310067 {
9984- constexpr auto expectedSize = static_cast <int >(std::tuple_size_v<R>);
9985- if (numReturnedValues != expectedSize )
10068+ constexpr auto expected_size = static_cast <int >(std::tuple_size_v<R>);
10069+ if (num_returned_values != expected_size )
998610070 return makeErrorCode (ErrorCode::InvalidTableSizeInCast);
998710071
9988- return decodeTupleResult <R>(L, firstResultIndex , std::make_index_sequence<std::tuple_size_v<R> >{});
10072+ return decode_tuple_result <R>(L, first_result_index , std::make_index_sequence<expected_size >{});
998910073 }
999010074 else
999110075 {
9992- if (numReturnedValues < 1 )
10076+ if (num_returned_values < 1 )
999310077 return makeErrorCode (ErrorCode::InvalidTypeCast);
999410078
9995- return Stack<R>::get (L, firstResultIndex );
10079+ return Stack<R>::get (L, first_result_index );
999610080 }
999710081}
999810082
@@ -10049,7 +10133,7 @@ TypeResult<R> callWithHandler(const Ref& object, F&& errorHandler, Args&&... arg
1004910133
1005010134 const int firstResultIndex = initialTop + 1 ;
1005110135 const int numReturnedValues = lua_gettop (L) - initialTop;
10052- return detail::decodeCallResult <R>(L, firstResultIndex, numReturnedValues);
10136+ return detail::decode_call_result <R>(L, firstResultIndex, numReturnedValues);
1005310137}
1005410138
1005510139template <class Ref , class F , class ... Args>
0 commit comments