Parcourir la Source

Make use of perfect forwarding

Ole il y a 9 ans
Parent
commit
63e73d2a0d
3 fichiers modifiés avec 25 ajouts et 44 suppressions
  1. 6 6
      lib/luwra/auxiliary.hpp
  2. 7 7
      lib/luwra/tables.hpp
  3. 12 31
      lib/luwra/types.hpp

+ 6 - 6
lib/luwra/auxiliary.hpp

@@ -52,8 +52,8 @@ void setMetatable(State* state, const char* name) {
  * \param value Global value
  */
 template <typename V> static inline
-void setGlobal(State* state, const std::string& name, V value) {
-	push(state, value);
+void setGlobal(State* state, const std::string& name, V&& value) {
+	push(state, std::forward<V>(value));
 	lua_setglobal(state, name.c_str());
 }
 
@@ -87,8 +87,8 @@ namespace internal {
 	struct EntryPusher<K, V> {
 		static inline
 		void push(State* state, int index, K&& key, V&& value) {
-			luwra::push(state, key);
-			luwra::push(state, value);
+			luwra::push(state, std::forward<K>(key));
+			luwra::push(state, std::forward<V>(value));
 			lua_rawset(state, index < 0 ? index - 2 : index);
 		}
 	};
@@ -146,11 +146,11 @@ struct Value<FieldVector> {
  * Retrieve a field from a table.
  */
 template <typename V, typename K> static inline
-V getField(State* state, int index, K key) {
+V getField(State* state, int index, K&& key) {
 	if (index < 0)
 		index = lua_gettop(state) + (index + 1);
 
-	push<K>(state, key);
+	push(state, std::forward<K>(key));
 	lua_rawget(state, index);
 
 	V value = read<V>(state, -1);

+ 7 - 7
lib/luwra/tables.hpp

@@ -55,7 +55,7 @@ struct Table {
 
 		push(state, ref);
 
-		size_t pushedKeys = push(state, key);
+		size_t pushedKeys = push(state, std::forward<K>(key));
 		if (pushedKeys > 1)
 			lua_pop(state, static_cast<int>(pushedKeys - 1));
 
@@ -71,11 +71,11 @@ struct Table {
 		State* state = ref.impl->state;
 		push(state, ref);
 
-		size_t pushedKeys = push(state, key);
+		size_t pushedKeys = push(state, std::forward<K>(key));
 		if (pushedKeys > 1)
 			lua_pop(state, static_cast<int>(pushedKeys - 1));
 
-		size_t pushedValues = push(state, value);
+		size_t pushedValues = push(state, std::forward<V>(value));
 		if (pushedValues > 1)
 			lua_pop(state, static_cast<int>(pushedValues - 1));
 
@@ -89,7 +89,7 @@ struct Table {
 
 		push(state, ref);
 
-		size_t pushedKeys = push(state, key);
+		size_t pushedKeys = push(state, std::forward<K>(key));
 		if (pushedKeys > 1)
 			lua_pop(state, static_cast<int>(pushedKeys - 1));
 
@@ -131,12 +131,12 @@ namespace internal {
 
 		template <typename T> inline
 		TableAccessor<T> access(T&& subkey) {
-			return {read<Table>(), subkey};
+			return {read<Table>(), std::forward<T>(subkey)};
 		}
 
 		template <typename T> inline
 		TableAccessor<T> operator [](T&& subkey) {
-			return {read<Table>(), subkey};
+			return {read<Table>(), std::forward<T>(subkey)};
 		}
 	};
 }
@@ -146,7 +146,7 @@ namespace internal {
  */
 template <typename K> inline
 internal::TableAccessor<K> Table::access(K&& key) {
-	return {*this, key};
+	return {*this, std::forward<K>(key)};
 }
 
 /**

+ 12 - 31
lib/luwra/types.hpp

@@ -29,28 +29,7 @@ using CFunction = lua_CFunction;
  * User type
  */
 template <typename T>
-struct Value {
-	/**
-	 * Copy a user type value from the stack.
-	 * \param state Lua state
-	 * \param index Position of the value
-	 */
-	static
-	T read(State* state, int index) {
-		return Value<T&>::read(state, index);
-	}
-
-	/**
-	 * Copy a user type value onto the stack.
-	 * \param state Lua state
-	 * \param value Value you want to push
-	 * \returns Number of values pushed
-	 */
-	static
-	size_t push(State* state, const T& value) {
-		return Value<T&>::push(state, value);
-	}
-};
+struct Value: Value<T&> {};
 
 // Nil
 template <>
@@ -71,16 +50,19 @@ struct Value<std::nullptr_t> {
  * Convenient wrapped for [Value<T>::push](@ref Value<T>::push).
  */
 template <typename T> static inline
-size_t push(State* state, T value) {
-	return Value<T>::push(state, value);
+size_t push(State* state, T&& value) {
+	using U = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
+	return Value<U>::push(state, std::forward<T>(value));
 }
 
 /**
  * Allows you to push multiple values at once.
  */
 template <typename T1, typename T2, typename... TR>
-size_t push(State* state, T1 value, T2&& head, TR&&... rest) {
-	return push(state, value) + push(state, std::forward<T2>(head), std::forward<TR>(rest)...);
+size_t push(State* state, T1&& value, T2&& head, TR&&... rest) {
+	return
+		push(state, std::forward<T1>(value)) +
+		push(state, std::forward<T2>(head), std::forward<TR>(rest)...);
 }
 
 /**
@@ -385,8 +367,7 @@ namespace internal {
 	struct StackPusher<IndexSequence<I>> {
 		template <typename... T> static inline
 		size_t push(State* state, const std::tuple<T...>& package) {
-			using R = typename std::tuple_element<I, std::tuple<T...>>::type;
-			return Value<R>::push(state, std::get<I>(package));
+			return luwra::push(state, std::get<I>(package));
 		}
 	};
 
@@ -395,8 +376,8 @@ namespace internal {
 		template <typename... T> static inline
 		size_t push(State* state, const std::tuple<T...>& package) {
 			return
-				StackPusher<IndexSequence<I>>::push(state, package)
-				+ StackPusher<IndexSequence<Is...>>::push(state, package);
+				StackPusher<IndexSequence<I>>::push(state, package) +
+				StackPusher<IndexSequence<Is...>>::push(state, package);
 		}
 	};
 }
@@ -446,7 +427,7 @@ namespace internal {
 
 		virtual
 		size_t push(State* state) const {
-			return Value<T>::push(state, value);
+			return luwra::push(state, value);
 		}
 
 		virtual