From 3282040c0ffa4c50ec7d2a43f25b9972c4b59fed Mon Sep 17 00:00:00 2001
From: Rye Mutt <rye@alchemyviewer.org>
Date: Mon, 28 Sep 2020 18:55:08 -0400
Subject: [PATCH] Convert demangle function to string_view to reduce string
 copy and rewrite to avoid using a loop

---
 indra/llcommon/llcallstack.h |  4 ++--
 indra/llcommon/llerror.cpp   | 23 ++++++++++++++---------
 indra/llcommon/llerror.h     |  2 +-
 3 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/indra/llcommon/llcallstack.h b/indra/llcommon/llcallstack.h
index 63a3ea10a57..663b77eb991 100644
--- a/indra/llcommon/llcallstack.h
+++ b/indra/llcommon/llcallstack.h
@@ -58,8 +58,8 @@ class LLContextStrings
 class LLScopedContextString
 {
 public:
-    LLScopedContextString(const std::string& str):
-        m_str(str)
+    LLScopedContextString(const std::string str):
+        m_str(std::move(str))
     {
         LLContextStrings::addContextString(m_str);
     }
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index 0e318676329..4244e102ae6 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -44,6 +44,7 @@
 # include <io.h>
 #endif // !LL_WINDOWS
 #include <vector>
+#include <string_view>
 #include "string.h"
 #include <absl/container/flat_hash_map.h>
 
@@ -316,7 +317,7 @@ namespace
 
 namespace LLError
 {
-	std::string Log::demangle(const char* mangled)
+	std::string Log::demangle(const std::string_view mangled)
 	{
 #ifdef __GNUC__
 		// GCC: type_info::name() returns a mangled class name,st demangle
@@ -329,21 +330,25 @@ namespace LLError
 		return result;
 
 #elif LL_WINDOWS
+		using namespace std::literals;
 		// Visual Studio: type_info::name() includes the text "class " at the start
-		std::string name = mangled;
-		for (const auto& prefix : std::vector<std::string>{ "class ", "struct " })
+		static constexpr auto class_prefix = "class "sv;
+		static constexpr auto struct_prefix = "struct "sv;
+		if (0 == mangled.compare(0, class_prefix.length(), class_prefix))
 		{
-			if (0 == name.compare(0, prefix.length(), prefix))
-			{
-				return name.substr(prefix.length());
-			}
+			return std::string(mangled.substr(class_prefix.length()));
 		}
+		else if (0 == mangled.compare(0, struct_prefix.length(), struct_prefix))
+		{
+			return std::string(mangled.substr(struct_prefix.length()));
+		}
+
 		// huh, that's odd, we should see one or the other prefix -- but don't
 		// try to log unless logging is already initialized
 		// in Python, " or ".join(vector) -- but in C++, a PITB
 		LL_DEBUGS() << "Did not see 'class' or 'struct' prefix on '"
-			<< name << "'" << LL_ENDL;
-		return name;
+			<< mangled << "'" << LL_ENDL;
+		return std::string(mangled);
 
 #else  // neither GCC nor Visual Studio
 		return mangled;
diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h
index 5905e14f179..2598b41e103 100644
--- a/indra/llcommon/llerror.h
+++ b/indra/llcommon/llerror.h
@@ -203,7 +203,7 @@ namespace LLError
 		static std::ostringstream* out();
 		static void flush(std::ostringstream* out, char* message);
 		static void flush(std::ostringstream*, const CallSite&);
-		static std::string demangle(const char* mangled);
+		static std::string demangle(const std::string_view mangled);
 		/// classname<TYPE>()
 		template <typename T>
 		static std::string classname()             { return demangle(typeid(T).name()); }
-- 
GitLab