From b11720af459d44a553cb5d23ef776a632fb30a65 Mon Sep 17 00:00:00 2001
From: Rogier-5 <rogier777@gmail.com>
Date: Thu, 11 Aug 2016 19:22:40 +0200
Subject: Use the standard to_string() functions for C++11 (#4279)

If compiling according to a C++ version before C++11, then define
std::to_string ourselves.

Add a to_wstring version as well

As std::to_string() for floating point types uses %.6f as floating
point format converter, instead of %G, it needs special care.

To preserve ftos() behavior (which is expected to use the %G format
converter), it no longer uses to_string().
---
 src/client.cpp    |  2 +-
 src/util/string.h | 47 +++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 42 insertions(+), 7 deletions(-)

(limited to 'src')

diff --git a/src/client.cpp b/src/client.cpp
index 4ffcec6ba..483b22caa 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -820,7 +820,7 @@ void Client::initLocalMapSaving(const Address &address,
 	const std::string world_path = porting::path_user
 		+ DIR_DELIM + "worlds"
 		+ DIR_DELIM + "server_"
-		+ hostname + "_" + to_string(address.getPort());
+		+ hostname + "_" + std::to_string(address.getPort());
 
 	fs::CreateAllDirs(world_path);
 
diff --git a/src/util/string.h b/src/util/string.h
index 8f4ef4711..724543a36 100644
--- a/src/util/string.h
+++ b/src/util/string.h
@@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <vector>
 #include <map>
 #include <sstream>
+#include <iomanip>
 #include <cctype>
 
 #define STRINGIFY(x) #x
@@ -350,23 +351,57 @@ inline T from_string(const std::string &str)
 /// Returns a 64-bit signed value represented by the string \p str (decimal).
 inline s64 stoi64(const std::string &str) { return from_string<s64>(str); }
 
-// TODO: Replace with C++11 std::to_string.
+#if __cplusplus < 201103L
+namespace std {
 
 /// Returns a string representing the value \p val.
 template <typename T>
-inline std::string to_string(T val)
+inline string to_string(T val)
 {
-	std::ostringstream oss;
+	ostringstream oss;
 	oss << val;
 	return oss.str();
 }
+#define DEFINE_STD_TOSTRING_FLOATINGPOINT(T)		\
+	template <>					\
+	inline string to_string<T>(T val)		\
+	{						\
+		ostringstream oss;			\
+		oss << std::fixed			\
+			<< std::setprecision(6)		\
+			<< val;				\
+		return oss.str();			\
+	}
+DEFINE_STD_TOSTRING_FLOATINGPOINT(float)
+DEFINE_STD_TOSTRING_FLOATINGPOINT(double)
+DEFINE_STD_TOSTRING_FLOATINGPOINT(long double)
+
+#undef DEFINE_STD_TOSTRING_FLOATINGPOINT
+
+/// Returns a wide string representing the value \p val
+template <typename T>
+inline wstring to_wstring(T val)
+{
+      return utf8_to_wide(to_string(val));
+}
+}
+#endif
 
 /// Returns a string representing the decimal value of the 32-bit value \p i.
-inline std::string itos(s32 i) { return to_string(i); }
+inline std::string itos(s32 i) { return std::to_string(i); }
 /// Returns a string representing the decimal value of the 64-bit value \p i.
-inline std::string i64tos(s64 i) { return to_string(i); }
+inline std::string i64tos(s64 i) { return std::to_string(i); }
+
+// std::to_string uses the '%.6f' conversion, which is inconsistent with
+// std::ostream::operator<<() and impractical too.  ftos() uses the
+// more generic and std::ostream::operator<<()-compatible '%G' format.
 /// Returns a string representing the decimal value of the float value \p f.
-inline std::string ftos(float f) { return to_string(f); }
+inline std::string ftos(float f)
+{
+	std::ostringstream oss;
+	oss << f;
+	return oss.str();
+}
 
 
 /**
-- 
cgit v1.2.3