|
@@ -121,6 +121,35 @@ namespace internal {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+/**
|
|
|
|
|
+ * Construct a user type value on the stack.
|
|
|
|
|
+ * \note Instances created using this specialization are allocated and constructed as full user
|
|
|
|
|
+ * data types in Lua. The default garbage-collecting hook will destruct the user type,
|
|
|
|
|
+ * once it has been marked.
|
|
|
|
|
+ * \param state Lua state
|
|
|
|
|
+ * \param args Constructor arguments
|
|
|
|
|
+ * \returns Reference to the constructed value
|
|
|
|
|
+ */
|
|
|
|
|
+template <typename U, typename... A> static inline
|
|
|
|
|
+internal::StripUserType<U>& construct(State* state, A&&... args) {
|
|
|
|
|
+ using T = internal::StripUserType<U>;
|
|
|
|
|
+
|
|
|
|
|
+ void* mem = lua_newuserdata(state, sizeof(T));
|
|
|
|
|
+
|
|
|
|
|
+ if (!mem) {
|
|
|
|
|
+ luaL_error(state, "Failed to allocate user type");
|
|
|
|
|
+ // 'luaL_error' will not return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Construct
|
|
|
|
|
+ T* value = new (mem) T {std::forward<A>(args)...};
|
|
|
|
|
+
|
|
|
|
|
+ // Apply metatable for unqualified type T
|
|
|
|
|
+ internal::apply_user_type_meta_table<T>(state);
|
|
|
|
|
+
|
|
|
|
|
+ return *value;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* User type
|
|
* User type
|
|
|
*/
|
|
*/
|
|
@@ -151,52 +180,11 @@ struct Value<U&> {
|
|
|
*/
|
|
*/
|
|
|
template <typename... A> static inline
|
|
template <typename... A> static inline
|
|
|
size_t push(State* state, A&&... args) {
|
|
size_t push(State* state, A&&... args) {
|
|
|
- void* mem = lua_newuserdata(state, sizeof(T));
|
|
|
|
|
-
|
|
|
|
|
- if (!mem) {
|
|
|
|
|
- luaL_error(state, "Failed to allocate user type");
|
|
|
|
|
- return -1;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Construct
|
|
|
|
|
- new (mem) T {std::forward<A>(args)...};
|
|
|
|
|
-
|
|
|
|
|
- // Apply metatable for unqualified type T
|
|
|
|
|
- internal::apply_user_type_meta_table<T>(state);
|
|
|
|
|
-
|
|
|
|
|
|
|
+ construct<T>(state, std::forward<A>(args)...);
|
|
|
return 1;
|
|
return 1;
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-/**
|
|
|
|
|
- * Construct a user type value on the stack.
|
|
|
|
|
- * \note Instances created using this specialization are allocated and constructed as full user
|
|
|
|
|
- * data types in Lua. The default garbage-collecting hook will destruct the user type,
|
|
|
|
|
- * once it has been marked.
|
|
|
|
|
- * \param state Lua state
|
|
|
|
|
- * \param args Constructor arguments
|
|
|
|
|
- * \returns Reference to the constructed value
|
|
|
|
|
- */
|
|
|
|
|
-template <typename U, typename... A> static inline
|
|
|
|
|
-internal::StripUserType<U>& construct(State* state, A&&... args) {
|
|
|
|
|
- using T = internal::StripUserType<U>;
|
|
|
|
|
-
|
|
|
|
|
- void* mem = lua_newuserdata(state, sizeof(T));
|
|
|
|
|
-
|
|
|
|
|
- if (!mem) {
|
|
|
|
|
- luaL_error(state, "Failed to allocate user type");
|
|
|
|
|
- // 'luaL_error' will not return
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Construct
|
|
|
|
|
- T* value = new (mem) T {std::forward<A>(args)...};
|
|
|
|
|
-
|
|
|
|
|
- // Apply metatable for unqualified type T
|
|
|
|
|
- internal::apply_user_type_meta_table<T>(state);
|
|
|
|
|
-
|
|
|
|
|
- return *value;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
/**
|
|
/**
|
|
|
* User type
|
|
* User type
|
|
|
*/
|
|
*/
|