From 6cfff2c3f6487a45561ee49617141159745cd6eb Mon Sep 17 00:00:00 2001
From: David Marcec <dmarcecguzman@gmail.com>
Date: Mon, 3 Aug 2020 20:39:19 +1000
Subject: [PATCH 1/2] loader: Make IdentifyFile typesafe

Relies on #4465 for concept.h Common::IsBaseOf
---
 src/core/loader/loader.cpp | 52 +++++++++++++++++++++++---------------
 1 file changed, 32 insertions(+), 20 deletions(-)

diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp
index 59ca7091a9..c4905550a5 100644
--- a/src/core/loader/loader.cpp
+++ b/src/core/loader/loader.cpp
@@ -3,8 +3,10 @@
 // Refer to the license.txt file included.
 
 #include <memory>
+#include <optional>
 #include <ostream>
 #include <string>
+#include "common/concepts.h"
 #include "common/file_util.h"
 #include "common/logging/log.h"
 #include "common/string_util.h"
@@ -21,27 +23,37 @@
 
 namespace Loader {
 
+template <Common::IsBaseOf<AppLoader> T>
+std::optional<FileType> IdentifyFileLoader(FileSys::VirtualFile file) {
+    const auto file_type = T::IdentifyType(file);
+    if (file_type != FileType::Error) {
+        return file_type;
+    }
+    return std::nullopt;
+}
+
 FileType IdentifyFile(FileSys::VirtualFile file) {
-    FileType type;
-
-#define CHECK_TYPE(loader)                                                                         \
-    type = AppLoader_##loader::IdentifyType(file);                                                 \
-    if (FileType::Error != type)                                                                   \
-        return type;
-
-    CHECK_TYPE(DeconstructedRomDirectory)
-    CHECK_TYPE(ELF)
-    CHECK_TYPE(NSO)
-    CHECK_TYPE(NRO)
-    CHECK_TYPE(NCA)
-    CHECK_TYPE(XCI)
-    CHECK_TYPE(NAX)
-    CHECK_TYPE(NSP)
-    CHECK_TYPE(KIP)
-
-#undef CHECK_TYPE
-
-    return FileType::Unknown;
+    if (const auto romdir_type = IdentifyFileLoader<AppLoader_DeconstructedRomDirectory>(file)) {
+        return *romdir_type;
+    } else if (const auto elf_type = IdentifyFileLoader<AppLoader_ELF>(file)) {
+        return *elf_type;
+    } else if (const auto nso_type = IdentifyFileLoader<AppLoader_NSO>(file)) {
+        return *nso_type;
+    } else if (const auto nro_type = IdentifyFileLoader<AppLoader_NRO>(file)) {
+        return *nro_type;
+    } else if (const auto nca_type = IdentifyFileLoader<AppLoader_NCA>(file)) {
+        return *nca_type;
+    } else if (const auto xci_type = IdentifyFileLoader<AppLoader_XCI>(file)) {
+        return *xci_type;
+    } else if (const auto nax_type = IdentifyFileLoader<AppLoader_NAX>(file)) {
+        return *nax_type;
+    } else if (const auto nsp_type = IdentifyFileLoader<AppLoader_NSP>(file)) {
+        return *nsp_type;
+    } else if (const auto kip_type = IdentifyFileLoader<AppLoader_KIP>(file)) {
+        return *kip_type;
+    } else {
+        return FileType::Unknown;
+    }
 }
 
 FileType GuessFromFilename(const std::string& name) {

From a5af1161c9a58616739ddaedcb900bcd7cc995f8 Mon Sep 17 00:00:00 2001
From: David Marcec <dmarcecguzman@gmail.com>
Date: Mon, 3 Aug 2020 20:44:04 +1000
Subject: [PATCH 2/2] Place in anonymous namespace

---
 src/core/loader/loader.cpp | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp
index c4905550a5..b8f8f14486 100644
--- a/src/core/loader/loader.cpp
+++ b/src/core/loader/loader.cpp
@@ -23,6 +23,8 @@
 
 namespace Loader {
 
+namespace {
+
 template <Common::IsBaseOf<AppLoader> T>
 std::optional<FileType> IdentifyFileLoader(FileSys::VirtualFile file) {
     const auto file_type = T::IdentifyType(file);
@@ -32,6 +34,8 @@ std::optional<FileType> IdentifyFileLoader(FileSys::VirtualFile file) {
     return std::nullopt;
 }
 
+} // namespace
+
 FileType IdentifyFile(FileSys::VirtualFile file) {
     if (const auto romdir_type = IdentifyFileLoader<AppLoader_DeconstructedRomDirectory>(file)) {
         return *romdir_type;