From c0a6fa5dcc5a1335ee9eeb940bdfc6934ed01656 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Fri, 21 Jun 2019 18:07:59 +0200 Subject: [PATCH] Work around C++20 std::filesystem changes related to u8string --- Source/Core/Common/FileSearch.cpp | 7 ++++--- Source/Core/Common/StringUtil.cpp | 23 +++++++++++++++++++++++ Source/Core/Common/StringUtil.h | 10 ++++++++++ Source/Core/Core/Boot/Boot.cpp | 2 +- 4 files changed, 38 insertions(+), 4 deletions(-) diff --git a/Source/Core/Common/FileSearch.cpp b/Source/Core/Common/FileSearch.cpp index b37e0cc5cd..6b28b93b4c 100644 --- a/Source/Core/Common/FileSearch.cpp +++ b/Source/Core/Common/FileSearch.cpp @@ -7,6 +7,7 @@ #include "Common/CommonPaths.h" #include "Common/FileSearch.h" +#include "Common/StringUtil.h" #ifdef _MSC_VER #include @@ -74,7 +75,7 @@ std::vector DoFileSearch(const std::vector& directorie std::vector native_exts; for (const auto& ext : exts) - native_exts.push_back(fs::u8path(ext)); + native_exts.push_back(StringToPath(ext)); // N.B. This avoids doing any copies auto ext_matches = [&native_exts](const fs::path& path) { @@ -93,11 +94,11 @@ std::vector DoFileSearch(const std::vector& directorie auto add_filtered = [&](const fs::directory_entry& entry) { auto& path = entry.path(); if (accept_all || (ext_matches(path) && !fs::is_directory(path))) - result.emplace_back(path.u8string()); + result.emplace_back(PathToString(path)); }; for (const auto& directory : directories) { - const fs::path directory_path = fs::u8path(directory); + const fs::path directory_path = StringToPath(directory); if (fs::is_directory(directory_path)) // Can't create iterators for non-existant directories { if (recursive) diff --git a/Source/Core/Common/StringUtil.cpp b/Source/Core/Common/StringUtil.cpp index 0df4b595cd..275c1e2af0 100644 --- a/Source/Core/Common/StringUtil.cpp +++ b/Source/Core/Common/StringUtil.cpp @@ -623,3 +623,26 @@ std::string UTF16BEToUTF8(const char16_t* str, size_t max_size) } #endif + +#ifdef HAS_STD_FILESYSTEM +// This is a replacement for path::u8path, which is deprecated starting with C++20. +std::filesystem::path StringToPath(std::string_view path) +{ +#ifdef _MSC_VER + return std::filesystem::path(UTF8ToUTF16(std::string(path))); +#else + return std::filesystem::path(path); +#endif +} + +// This is a replacement for path::u8string that always has the return type std::string. +// path::u8string returns std::u8string starting with C++20, which is annoying to convert. +std::string PathToString(const std::filesystem::path& path) +{ +#ifdef _MSC_VER + return UTF16ToUTF8(path.native()); +#else + return path.native(); +#endif +} +#endif diff --git a/Source/Core/Common/StringUtil.h b/Source/Core/Common/StringUtil.h index 0ee2391e7c..a1adf70b28 100644 --- a/Source/Core/Common/StringUtil.h +++ b/Source/Core/Common/StringUtil.h @@ -14,6 +14,11 @@ #include "Common/CommonTypes.h" +#ifdef _MSC_VER +#include +#define HAS_STD_FILESYSTEM +#endif + std::string StringFromFormatV(const char* format, va_list args); std::string StringFromFormat(const char* format, ...) @@ -153,6 +158,11 @@ inline std::string UTF8ToTStr(const std::string& str) #endif +#ifdef HAS_STD_FILESYSTEM +std::filesystem::path StringToPath(std::string_view path); +std::string PathToString(const std::filesystem::path& path); +#endif + // Thousand separator. Turns 12345678 into 12,345,678 template std::string ThousandSeparate(I value, int spaces = 0) diff --git a/Source/Core/Core/Boot/Boot.cpp b/Source/Core/Core/Boot/Boot.cpp index 50fb2f7282..6803ddd413 100644 --- a/Source/Core/Core/Boot/Boot.cpp +++ b/Source/Core/Core/Boot/Boot.cpp @@ -88,7 +88,7 @@ static std::vector ReadM3UFile(const std::string& m3u_path, if (!line.empty() && line.front() != '#') // Comments start with # { #ifdef HAS_STD_FILESYSTEM - const std::string path_to_add = (fs::u8path(folder_path) / fs::u8path(line)).u8string(); + const std::string path_to_add = PathToString(StringToPath(folder_path) / StringToPath(line)); #else const std::string path_to_add = line.front() != '/' ? folder_path + line : line; #endif