Use C++17 std::filesystem functions instead of my own.
Use C++17 std::filesystem functions instead of my own.


--- a/src/in_2sf/XSFPlayer_2SF.cpp
+++ b/src/in_2sf/XSFPlayer_2SF.cpp
@@ -10,6 +10,7 @@
  * http://desmume.org/
  */
 
+#include <filesystem>
 #include <memory>
 #include <zlib.h>
 #include "convert.h"
@@ -146,9 +147,9 @@
 	if (level <= 10 && xSFToLoad->GetTagExists("_lib"))
 	{
 #ifdef _WIN32
-		auto libxSF = std::make_unique<XSFFile>(ConvertFuncs::StringToWString(ExtractDirectoryFromPath(xSFToLoad->GetFilename()) + xSFToLoad->GetTagValue("_lib")), 4, 8);
+		auto libxSF = std::make_unique<XSFFile>((std::filesystem::path(xSFToLoad->GetFilename()).parent_path() / xSFToLoad->GetTagValue("_lib")).wstring(), 4, 8);
 #else
-		auto libxSF = std::make_unique<XSFFile>(ExtractDirectoryFromPath(xSFToLoad->GetFilename()) + xSFToLoad->GetTagValue("_lib"), 4, 8);
+		auto libxSF = std::make_unique<XSFFile>((std::filesystem::path(xSFToLoad->GetFilename()).parent_path() / xSFToLoad->GetTagValue("_lib")).string(), 4, 8);
 #endif
 		if (!this->RecursiveLoad2SF(libxSF.get(), level + 1))
 			return false;
@@ -167,9 +168,9 @@
 		{
 			found = true;
 #ifdef _WIN32
-			auto libxSF = std::make_unique<XSFFile>(ConvertFuncs::StringToWString(ExtractDirectoryFromPath(xSFToLoad->GetFilename()) + xSFToLoad->GetTagValue(libTag)), 4, 8);
+			auto libxSF = std::make_unique<XSFFile>((std::filesystem::path(xSFToLoad->GetFilename()).parent_path() / xSFToLoad->GetTagValue(libTag)).wstring(), 4, 8);
 #else
-			auto libxSF = std::make_unique<XSFFile>(ExtractDirectoryFromPath(xSFToLoad->GetFilename()) + xSFToLoad->GetTagValue(libTag), 4, 8);
+			auto libxSF = std::make_unique<XSFFile>((std::filesystem::path(xSFToLoad->GetFilename()).parent_path() / xSFToLoad->GetTagValue(libTag)).string(), 4, 8);
 #endif
 			if (!this->RecursiveLoad2SF(libxSF.get(), level + 1))
 				return false;

--- a/src/in_gsf/XSFPlayer_GSF.cpp
+++ b/src/in_gsf/XSFPlayer_GSF.cpp
@@ -10,6 +10,7 @@
  * http://vba-m.com/
  */
 
+#include <filesystem>
 #include <memory>
 #include <zlib.h>
 #include "convert.h"
@@ -152,9 +153,9 @@
 	if (level <= 10 && xSF->GetTagExists("_lib"))
 	{
 #ifdef _WIN32
-		auto libxSF = std::make_unique<XSFFile>(ConvertFuncs::StringToWString(ExtractDirectoryFromPath(xSF->GetFilename()) + xSF->GetTagValue("_lib")), 8, 12);
+		auto libxSF = std::make_unique<XSFFile>((std::filesystem::path(xSF->GetFilename()).parent_path() / xSF->GetTagValue("_lib")).wstring(), 8, 12);
 #else
-		auto libxSF = std::make_unique<XSFFile>(ExtractDirectoryFromPath(xSF->GetFilename()) + xSF->GetTagValue("_lib"), 8, 12);
+		auto libxSF = std::make_unique<XSFFile>((std::filesystem::path(xSF->GetFilename()).parent_path() / xSF->GetTagValue("_lib")).string(), 8, 12);
 #endif
 		if (!RecursiveLoadGSF(libxSF.get(), level + 1))
 			return false;
@@ -173,9 +174,9 @@
 		{
 			found = true;
 #ifdef _WIN32
-			auto libxSF = std::make_unique<XSFFile>(ConvertFuncs::StringToWString(ExtractDirectoryFromPath(xSF->GetFilename()) + xSF->GetTagValue(libTag)), 8, 12);
+			auto libxSF = std::make_unique<XSFFile>((std::filesystem::path(xSF->GetFilename()).parent_path() / xSF->GetTagValue(libTag)).wstring(), 8, 12);
 #else
-			auto libxSF = std::make_unique<XSFFile>(ExtractDirectoryFromPath(xSF->GetFilename()) + xSF->GetTagValue(libTag), 8, 12);
+			auto libxSF = std::make_unique<XSFFile>((std::filesystem::path(xSF->GetFilename()).parent_path() / xSF->GetTagValue(libTag)).string(), 8, 12);
 #endif
 			if (!RecursiveLoadGSF(libxSF.get(), level + 1))
 				return false;

--- a/src/in_ncsf/XSFPlayer_NCSF.cpp
+++ b/src/in_ncsf/XSFPlayer_NCSF.cpp
@@ -8,6 +8,7 @@
  * https://github.com/fincs/FSS
  */
 
+#include <filesystem>
 #include <memory>
 #include <cstdlib>
 #include <ctime>
@@ -67,9 +68,9 @@
 	if (level <= 10 && xSFToLoad->GetTagExists("_lib"))
 	{
 #ifdef _WIN32
-		auto libxSF = std::make_unique<XSFFile>(ConvertFuncs::StringToWString(ExtractDirectoryFromPath(xSFToLoad->GetFilename()) + xSFToLoad->GetTagValue("_lib")), 8, 12);
+		auto libxSF = std::make_unique<XSFFile>((std::filesystem::path(xSFToLoad->GetFilename()).parent_path() / xSFToLoad->GetTagValue("_lib")).wstring(), 8, 12);
 #else
-		auto libxSF = std::make_unique<XSFFile>(ExtractDirectoryFromPath(xSFToLoad->GetFilename()) + xSFToLoad->GetTagValue("_lib"), 8, 12);
+		auto libxSF = std::make_unique<XSFFile>((std::filesystem::path(xSFToLoad->GetFilename()).parent_path() / xSFToLoad->GetTagValue("_lib")).string(), 8, 12);
 #endif
 		if (!this->RecursiveLoadNCSF(libxSF.get(), level + 1))
 			return false;
@@ -88,9 +89,9 @@
 		{
 			found = true;
 #ifdef _WIN32
-			auto libxSF = std::make_unique<XSFFile>(ConvertFuncs::StringToWString(ExtractDirectoryFromPath(xSFToLoad->GetFilename()) + xSFToLoad->GetTagValue(libTag)), 8, 12);
+			auto libxSF = std::make_unique<XSFFile>((std::filesystem::path(xSFToLoad->GetFilename()).parent_path() / xSFToLoad->GetTagValue(libTag)).wstring(), 8, 12);
 #else
-			auto libxSF = std::make_unique<XSFFile>(ExtractDirectoryFromPath(xSFToLoad->GetFilename()) + xSFToLoad->GetTagValue(libTag), 8, 12);
+			auto libxSF = std::make_unique<XSFFile>((std::filesystem::path(xSFToLoad->GetFilename()).parent_path() / xSFToLoad->GetTagValue(libTag)).string(), 8, 12);
 #endif
 			if (!this->RecursiveLoadNCSF(libxSF.get(), level + 1))
 				return false;

--- a/src/in_snsf/XSFPlayer_SNSF.cpp
+++ b/src/in_snsf/XSFPlayer_SNSF.cpp
@@ -11,6 +11,7 @@
  * http://www.snes9x.com/
  */
 
+#include <filesystem>
 #include <zlib.h>
 #include "convert.h"
 #include "XSFPlayer.h"
@@ -167,9 +168,9 @@
 	if (level <= 10 && xSF->GetTagExists("_lib"))
 	{
 #ifdef _WIN32
-		auto libxSF = std::make_unique<XSFFile>(ConvertFuncs::StringToWString(ExtractDirectoryFromPath(xSF->GetFilename()) + xSF->GetTagValue("_lib")), 4, 8);
+		auto libxSF = std::make_unique<XSFFile>((std::filesystem::path(xSF->GetFilename()).parent_path() / xSF->GetTagValue("_lib")).wstring(), 4, 8);
 #else
-		auto libxSF = std::make_unique<XSFFile>(ExtractDirectoryFromPath(xSF->GetFilename()) + xSF->GetTagValue("_lib"), 4, 8);
+		auto libxSF = std::make_unique<XSFFile>((std::filesystem::path(xSF->GetFilename()).parent_path() / xSF->GetTagValue("_lib")).string(), 4, 8);
 #endif
 		if (!RecursiveLoadSNSF(libxSF.get(), level + 1))
 			return false;
@@ -188,9 +189,9 @@
 		{
 			found = true;
 #ifdef _WIN32
-			auto libxSF = std::make_unique<XSFFile>(ConvertFuncs::StringToWString(ExtractDirectoryFromPath(xSF->GetFilename()) + xSF->GetTagValue(libTag)), 4, 8);
+			auto libxSF = std::make_unique<XSFFile>((std::filesystem::path(xSF->GetFilename()).parent_path() / xSF->GetTagValue(libTag)).wstring(), 4, 8);
 #else
-			auto libxSF = std::make_unique<XSFFile>(ExtractDirectoryFromPath(xSF->GetFilename()) + xSF->GetTagValue(libTag), 4, 8);
+			auto libxSF = std::make_unique<XSFFile>((std::filesystem::path(xSF->GetFilename()).parent_path() / xSF->GetTagValue(libTag)).string(), 4, 8);
 #endif
 			if (!RecursiveLoadSNSF(libxSF.get(), level + 1))
 				return false;

--- a/src/in_xsf_framework/XSFCommon.h
+++ b/src/in_xsf_framework/XSFCommon.h
@@ -9,9 +9,6 @@
 
 #include <limits>
 #include <fstream>
-#if defined(_WIN32) && !defined(_MSC_VER)
-# include "fstream_wfopen.h"
-#endif
 #include <string>
 #define _USE_MATH_DEFINES
 #include <cmath>
@@ -40,24 +37,6 @@
 	return Get32BitsLE(bytes);
 }
 
-// This gets the directory for the path, including the final forward/backward slash
-template<typename T> inline std::basic_string<T> ExtractDirectoryFromPath(const std::basic_string<T> &fullPath)
-{
-	auto lastSlash = fullPath.rfind('\\');
-	if (lastSlash == std::basic_string<T>::npos)
-		lastSlash = fullPath.rfind('/');
-	return lastSlash != std::basic_string<T>::npos ? fullPath.substr(0, lastSlash + 1) : std::basic_string<T>();
-}
-
-// This gets the filename for the path
-template<typename T> inline std::basic_string<T> ExtractFilenameFromPath(const std::basic_string<T> &fullPath)
-{
-	auto lastSlash = fullPath.rfind('\\');
-	if (lastSlash == std::basic_string<T>::npos)
-		lastSlash = fullPath.rfind('/');
-	return lastSlash != std::basic_string<T>::npos ? fullPath.substr(lastSlash + 1) : std::basic_string<T>();
-}
-
 // Code from the following answer on Stack Overflow:
 // http://stackoverflow.com/a/15479212
 template<typename T> inline T NextHighestPowerOf2(T value)
@@ -79,24 +58,6 @@
 		valueToClamp = maxValue;
 }
 
-inline bool FileExists(const std::string &filename)
-{
-	std::ifstream file(filename.c_str());
-	return !!file;
-}
-
-#ifdef _WIN32
-inline bool FileExists(const std::wstring &filename)
-{
-#ifdef _MSC_VER
-	std::ifstream file(filename.c_str());
-#else
-	ifstream_wfopen file(filename.c_str());
-#endif
-	return !!file;
-}
-#endif
-
 inline void CopyToString(const std::wstring &src, wchar_t *dst)
 {
 	wcscpy(dst, src.c_str());

--- a/src/in_xsf_framework/XSFConfig_Winamp.cpp
+++ b/src/in_xsf_framework/XSFConfig_Winamp.cpp
@@ -5,6 +5,7 @@
  * Partially based on the vio*sf framework
  */
 
+#include <filesystem>
 #include "XSFConfig.h"
 #include "XSFCommon.h"
 #include "winamp/in2.h"
@@ -50,7 +51,7 @@
 		if (!result)
 			throw std::runtime_error("Unable to get path to plugin.");
 
-		this->iniFilename = ExtractDirectoryFromPath(std::wstring(executablePath.begin(), executablePath.begin() + result)) + L"plugins.ini";
+		this->iniFilename = (std::filesystem::path(std::wstring(executablePath.begin(), executablePath.begin() + result)).parent_path() / L"plugins.ini").wstring();
 	}
 }
 

--- a/src/in_xsf_framework/XSFFile.cpp
+++ b/src/in_xsf_framework/XSFFile.cpp
@@ -6,8 +6,12 @@
  */
 
 #include <algorithm>
+#include <filesystem>
 #include <functional>
 #include <stdexcept>
+#if defined(_WIN32) && !defined(_MSC_VER)
+# include "fstream_wfopen.h"
+#endif
 #include "zlib.h"
 #include "XSFFile.h"
 #include "XSFCommon.h"
@@ -80,7 +84,7 @@
 
 void XSFFile::ReadXSF(const std::string &filename, uint32_t programSizeOffset, uint32_t programHeaderSize, bool readTagsOnly)
 {
-	if (!FileExists(filename))
+	if (!std::filesystem::is_regular_file(filename))
 		throw std::logic_error("File " + filename + " does not exist.");
 
 	std::ifstream xSF;
@@ -95,7 +99,7 @@
 #ifdef _WIN32
 void XSFFile::ReadXSF(const std::wstring &filename, uint32_t programSizeOffset, uint32_t programHeaderSize, bool readTagsOnly)
 {
-	if (!FileExists(filename))
+	if (!std::filesystem::is_regular_file(filename))
 		throw std::logic_error("File " + ConvertFuncs::WStringToString(filename) + " does not exist.");
 
 #if defined(_WIN32) && !defined(_MSC_VER)
@@ -460,7 +464,7 @@
 
 std::string XSFFile::GetFilenameWithoutPath() const
 {
-	return ExtractFilenameFromPath(this->fileName);
+	return std::filesystem::path(this->fileName).filename().string();
 }
 
 void XSFFile::SaveFile() const