Преглед на файлове

Strip user types from qualifiers to prevent generation of uncessary templates

Ole преди 10 години
родител
ревизия
0cf38bcf29
променени са 1 файла, в които са добавени 24 реда и са изтрити 15 реда
  1. 24 15
      lib/luwra/usertypes.hpp

+ 24 - 15
lib/luwra/usertypes.hpp

@@ -33,7 +33,7 @@ namespace internal {
 	 */
 	template <typename T>
 	std::string user_type_reg_name =
-		"UD#" + std::to_string(uintptr_t(&user_type_id<T>));
+		"UD#" + std::to_string(uintptr_t(&user_type_id<StripUserType<T>>));
 
 	/**
 	 * Register a new meta table for a user type T.
@@ -90,12 +90,12 @@ namespace internal {
 	/**
 	 * Lua C function to construct a user type T with parameters A
 	 */
-	template <typename T, typename... A> static inline
+	template <typename U, typename... A> static inline
 	int construct_user_type(State* state) {
 		return internal::Layout<int(A...)>::direct(
 			state,
 			1,
-			&Value<T&>::template push<A...>,
+			&Value<StripUserType<U>&>::template push<A...>,
 			state
 		);
 	}
@@ -103,8 +103,10 @@ namespace internal {
 	/**
 	 * Lua C function to destruct a user type T
 	 */
-	template <typename T> static inline
+	template <typename U> static inline
 	int destruct_user_type(State* state) {
+		using T = StripUserType<U>;
+
 		if (!lua_islightuserdata(state, 1))
 			Value<T&>::read(state, 1).~T();
 
@@ -116,22 +118,26 @@ namespace internal {
 	 */
 	template <typename U> static
 	int stringify_user_type(State* state) {
+		using T = StripUserType<U>;
+
 		return Value<std::string>::push(
 			state,
-			internal::user_type_reg_name<StripUserType<U>>
-			+ "@"
-			+ std::to_string(uintptr_t(Value<U*>::read(state, 1)))
+			internal::user_type_reg_name<T>
+				+ "@"
+				+ std::to_string(uintptr_t(Value<T*>::read(state, 1)))
 		);
 	}
 
 	/**
 	 * Lua C function for a property accessor.
 	 */
-	template <typename T, typename R, R T::* property_pointer> static inline
+	template <typename U, typename R, R U::* property_pointer> static inline
 	int access_user_type_property(State* state) {
+		using T = StripUserType<U>;
+
 		if (lua_gettop(state) > 1) {
 			// Setter
-			(Value<T*>::read(state, 1)->*property_pointer) = Value<R>::read(state, 2);
+			Value<T*>::read(state, 1)->*property_pointer = Value<R>::read(state, 2);
 			return 0;
 		} else {
 			// Getter
@@ -220,10 +226,10 @@ struct Value<U&> {
 			return -1;
 		}
 
-		// Call constructor on instance
+		// Construct
 		new (mem) T(std::forward<A>(args)...);
 
-		// Set metatable for this type
+		// Apply meta table for unqualified type T
 		internal::apply_user_type_meta_table<T>(state);
 
 		return 1;
@@ -240,7 +246,8 @@ struct Value<U*> {
 	using T = internal::StripUserType<U>;
 
 	static inline
-	T* read(State* state, int n) {
+	U* read(State* state, int n) {
+		// T is unqualified, therefore conversion from T* to U* is allowed
 		return internal::check_user_type<T>(state, n);
 	}
 
@@ -249,10 +256,10 @@ struct Value<U*> {
 		if (instance == nullptr)
 			return 0;
 
-		// push instance as light user data
+		// Push instance as light user data
 		lua_pushlightuserdata(state, instance);
 
-		// Set metatable for this type
+		// Apply meta table for unqualified type T
 		internal::apply_user_type_meta_table<T>(state);
 
 		return 1;
@@ -318,12 +325,14 @@ constexpr CFunction wrap_property =
  * which are shared across all instances of this type. A garbage-collector hook is also inserted.
  * Meta-methods can be added and/or overwritten aswell.
  */
-template <typename T> static inline
+template <typename U> static inline
 void register_user_type(
 	State* state,
 	const std::map<const char*, CFunction>& methods,
 	const std::map<const char*, CFunction>& meta_methods = std::map<const char*, CFunction>()
 ) {
+	using T = internal::StripUserType<U>;
+
 	// Setup an appropriate meta table name
 	internal::new_user_type_id<T>(state);