diff --git a/doc/src/index.dox b/doc/src/index.dox index ce11db4..619ca97 100644 --- a/doc/src/index.dox +++ b/doc/src/index.dox @@ -43,7 +43,7 @@ \li \subpage io_helper - \li \subpage fs_path_patch + \li \subpage std_patch Advanced Features diff --git a/doc/src/fs_path_patch.dox b/doc/src/std_patch.dox similarity index 80% rename from doc/src/fs_path_patch.dox rename to doc/src/std_patch.dox index a30ec79..ed9f98f 100644 --- a/doc/src/fs_path_patch.dox +++ b/doc/src/std_patch.dox @@ -1,7 +1,9 @@ -namespace YYCC::FsPathPatch { +namespace YYCC::StdPatch { /** -\page fs_path_patch std::filesystem::path Patch +\page std_patch Standard Library Patch + +\section std_patch__fs_path std::filesystem::path Patch As you know, the underlying char type of \c std::filesystem::path is \c wchar_t on Windows, and in other platforms, it is simple \c char. @@ -23,17 +25,17 @@ This patch is served for Windows but also works on other plaftoms. If you are in Windows, this patch will perform extra operations to achieve goals, and in other platforms, they just redirect request to corresponding vanilla C++ functions. -\section fs_path_patch__from_utf8_path Create Path from UTF8 String +\subsection std_patch__fs_path__from_utf8_path Create Path from UTF8 String -#FromUTF8Path provides this feature. +#ToStdPath provides this feature. It accepts an string pointer to UTF8 string and try to create \c std::filesystem::path from it. Function will throw exception if encoding convertion or constructor self failed. There are some example: \code -auto foobar_path = YYCC::FsPathPatch::FromUTF8Path(YYCC_U8("/foo/bar")); -auto slashed_path = foobar_path / YYCC::FsPathPatch::FromUTF8Path(YYCC_U8("test")); -auto replaced_ext = foobar_path.replace_extension(YYCC::FsPathPatch::FromUTF8Path(YYCC_U8(".txt"))); +auto foobar_path = YYCC::StdPatch::ToStdPath(YYCC_U8("/foo/bar")); +auto slashed_path = foobar_path / YYCC::StdPatch::ToStdPath(YYCC_U8("test")); +auto replaced_ext = foobar_path.replace_extension(YYCC::StdPatch::ToStdPath(YYCC_U8(".txt"))); \endcode For first line in example, it is obvious that you can create a \c std::filesystem::path from this function. @@ -58,17 +60,17 @@ However it is depracted since C++ 20, because \c std::filesystem::path directly supports UTF8 by \c char8_t since C++ 20. Because C++ standard is volatile, we create this function to have an uniform programming experience. -\section fs_path_patch__to_utf8_path Extract UTF8 Path String from Path +\subsection std_patch__fs_path__to_utf8_path Extract UTF8 Path String from Path #ToUTF8Path provides this feature. -It basically is the reversed operation of #FromUTF8Path. +It basically is the reversed operation of #ToStdPath. It is usually used when you have done all path work in \c std::filesystem::path and want to get the result. There is an example: \code -auto foobar_path = YYCC::FsPathPatch::FromUTF8Path(YYCC_U8("/foo/bar")); -auto result = YYCC::FsPathPatch::ToUTF8Path(foobar_path / YYCC::FsPathPatch::FromUTF8Path(YYCC_U8("test"))); +auto foobar_path = YYCC::StdPatch::ToStdPath(YYCC_U8("/foo/bar")); +auto result = YYCC::StdPatch::ToUTF8Path(foobar_path / YYCC::StdPatch::ToStdPath(YYCC_U8("test"))); \endcode */ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7a67907..dbcf12d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -11,7 +11,7 @@ PRIVATE DialogHelper.cpp EncodingHelper.cpp ExceptionHelper.cpp - FsPathPatch.cpp + StdPatch.cpp IOHelper.cpp StringHelper.cpp WinFctHelper.cpp @@ -32,7 +32,7 @@ FILES DialogHelper.hpp EncodingHelper.hpp ExceptionHelper.hpp - FsPathPatch.hpp + StdPatch.hpp IOHelper.hpp ParserHelper.hpp StringHelper.hpp @@ -71,8 +71,12 @@ PRIVATE $<$:UNICODE> $<$:_UNICODE> ) -# Order build as UTF-8 in MSVC target_compile_options(YYCCommonplace +# Enable new __cplusplus macro in MSVC. +# Because we use it in header, so we need populate it. +PUBLIC + $<$:/Zc:__cplusplus> +# Order build as UTF-8 in MSVC PRIVATE $<$:/utf-8> ) diff --git a/src/ExceptionHelper.cpp b/src/ExceptionHelper.cpp index 467bab8..83888dc 100644 --- a/src/ExceptionHelper.cpp +++ b/src/ExceptionHelper.cpp @@ -6,7 +6,7 @@ #include "StringHelper.hpp" #include "IOHelper.hpp" #include "EncodingHelper.hpp" -#include "FsPathPatch.hpp" +#include "StdPatch.hpp" #include #include #include @@ -459,8 +459,8 @@ namespace YYCC::ExceptionHelper { if (!YYCC::WinFctHelper::GetModuleFileName(NULL, u8_process_path)) return false; // extract file name from full path by std::filesystem::path - std::filesystem::path process_path(FsPathPatch::FromUTF8Path(u8_process_path.c_str())); - u8_process_name = FsPathPatch::ToUTF8Path(process_path.filename()); + std::filesystem::path process_path(StdPatch::ToStdPath(u8_process_path.c_str())); + u8_process_name = StdPatch::ToUTF8Path(process_path.filename()); } // then get process id DWORD process_id = GetCurrentProcessId(); @@ -478,19 +478,19 @@ namespace YYCC::ExceptionHelper { if (!WinFctHelper::GetLocalAppData(u8_localappdata_path)) return false; // convert to std::filesystem::path - std::filesystem::path crash_report_path(FsPathPatch::FromUTF8Path(u8_localappdata_path.c_str())); + std::filesystem::path crash_report_path(StdPatch::ToStdPath(u8_localappdata_path.c_str())); // slash into crash report folder - crash_report_path /= FsPathPatch::FromUTF8Path(YYCC_U8("CrashDumps")); + crash_report_path /= StdPatch::ToStdPath(YYCC_U8("CrashDumps")); // use create function to make sure it is existing std::filesystem::create_directories(crash_report_path); // build log path and coredump path // build std::filesystem::path first - std::filesystem::path log_filepath = crash_report_path / FsPathPatch::FromUTF8Path(u8_log_filename.c_str()); - std::filesystem::path coredump_filepath = crash_report_path / FsPathPatch::FromUTF8Path(u8_coredump_filename.c_str()); + std::filesystem::path log_filepath = crash_report_path / StdPatch::ToStdPath(u8_log_filename.c_str()); + std::filesystem::path coredump_filepath = crash_report_path / StdPatch::ToStdPath(u8_coredump_filename.c_str()); // output to result - log_path = FsPathPatch::ToUTF8Path(log_filepath); - coredump_path = FsPathPatch::ToUTF8Path(coredump_filepath); + log_path = StdPatch::ToUTF8Path(log_filepath); + coredump_path = StdPatch::ToUTF8Path(coredump_filepath); return true; } diff --git a/src/FsPathPatch.hpp b/src/FsPathPatch.hpp deleted file mode 100644 index 77e2b2e..0000000 --- a/src/FsPathPatch.hpp +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once -#include "YYCCInternal.hpp" - -#include - -/** - * @brief \c std::filesystem::path related patches for UTF8 compatibility - * @details - * See also \ref fs_path_patch. -*/ -namespace YYCC::FsPathPatch { - - /** - * @brief Constructs \c std::filesystem::path from UTF8 path. - * @param[in] u8_path UTF8 path string for building. - * @return \c std::filesystem::path instance. - * @exception std::invalid_argument Fail to parse given UTF8 string (maybe invalid?). - */ - std::filesystem::path FromUTF8Path(const yycc_char8_t* u8_path); - - /** - * @brief Returns the UTF8 representation of given \c std::filesystem::path. - * @param[in] path The \c std::filesystem::path instance converting to UTF8 path. - * @return The UTF8 representation of given \c std::filesystem::path. - * @exception std::invalid_argument Fail to convert to UTF8 string. - */ - yycc_u8string ToUTF8Path(const std::filesystem::path& path); - -} diff --git a/src/FsPathPatch.cpp b/src/StdPatch.cpp similarity index 76% rename from src/FsPathPatch.cpp rename to src/StdPatch.cpp index 1251919..04809c5 100644 --- a/src/FsPathPatch.cpp +++ b/src/StdPatch.cpp @@ -1,24 +1,24 @@ -#include "FsPathPatch.hpp" +#include "StdPatch.hpp" #include "EncodingHelper.hpp" #include #include -namespace YYCC::FsPathPatch { +namespace YYCC::StdPatch { - std::filesystem::path FromUTF8Path(const yycc_char8_t* u8_path) { + std::filesystem::path ToStdPath(const yycc_u8string_view& u8_path) { #if YYCC_OS == YYCC_OS_WINDOWS // convert path to wchar std::wstring wpath; if (!YYCC::EncodingHelper::UTF8ToWchar(u8_path, wpath)) throw std::invalid_argument("Fail to convert given UTF8 string."); - // return path with wchar_t ctor return std::filesystem::path(wpath); #else - return std::filesystem::path(EncodingHelper::ToOrdinary(u8_path)); + std::string cache = YYCC::EncodingHelper::ToOrdinary(u8_path); + return std::filesystem::path(cache.c_str()); #endif } diff --git a/src/StdPatch.hpp b/src/StdPatch.hpp new file mode 100644 index 0000000..a2f2a6c --- /dev/null +++ b/src/StdPatch.hpp @@ -0,0 +1,216 @@ +#pragma once +#include "YYCCInternal.hpp" + +#include +#include +#include + +/** + * @brief \c Standard library related patches for UTF8 compatibility and the limitation of C++ standard version. + * @details + * See also \ref std_patch. +*/ +namespace YYCC::StdPatch { + + /** + * @brief Constructs \c std::filesystem::path from UTF8 path. + * @param[in] u8_path UTF8 path string for building. + * @return \c std::filesystem::path instance. + * @exception std::invalid_argument Fail to parse given UTF8 string (maybe invalid?). + */ + std::filesystem::path ToStdPath(const yycc_u8string_view& u8_path); + + /** + * @brief Returns the UTF8 representation of given \c std::filesystem::path. + * @param[in] path The \c std::filesystem::path instance converting to UTF8 path. + * @return The UTF8 representation of given \c std::filesystem::path. + * @exception std::invalid_argument Fail to convert to UTF8 string. + */ + yycc_u8string ToUTF8Path(const std::filesystem::path& path); + +#pragma region StartsWith EndsWith + + // Reference: + // https://en.cppreference.com/w/cpp/string/basic_string_view/starts_with + // https://en.cppreference.com/w/cpp/string/basic_string_view/ends_with + // https://en.cppreference.com/w/cpp/string/basic_string/starts_with + // https://en.cppreference.com/w/cpp/string/basic_string/ends_with + +#pragma region String View + + /** + * @brief Checks if the string view begins with the given prefix + * @param[in] that The string view to find. + * @param[in] sv A string view which may be a result of implicit conversion from \c std::basic_string. + * @return True if the string view begins with the provided prefix, false otherwise. + */ + template> + bool StartsWith(const std::basic_string_view& that, std::basic_string_view sv) noexcept { + return std::basic_string_view(that.data(), std::min(that.size(), sv.size())) == sv; + } + /** + * @brief Checks if the string view begins with the given prefix + * @param[in] that The string view to find. + * @param[in] ch A single character. + * @return True if the string view begins with the provided prefix, false otherwise. + */ + template> + bool StartsWith(const std::basic_string_view& that, CharT ch) noexcept { + return !that.empty() && Traits::eq(that.front(), ch); + } + /** + * @brief Checks if the string view begins with the given prefix + * @param[in] that The string view to find. + * @param[in] s A null-terminated character string. + * @return True if the string view begins with the provided prefix, false otherwise. + */ + template> + bool StartsWith(const std::basic_string_view& that, const CharT* s) noexcept { + return StartsWith(that, std::basic_string_view(s)); + } + + /** + * @brief Checks if the string view ends with the given suffix + * @param[in] that The string view to find. + * @param[in] sv A string view which may be a result of implicit conversion from \c std::basic_string. + * @return True if the string view ends with the provided suffix, false otherwise. + */ + template> + bool EndsWith(const std::basic_string_view& that, std::basic_string_view sv) noexcept { + return that.size() >= sv.size() && that.compare(that.size() - sv.size(), std::basic_string_view::npos, sv); + } + /** + * @brief Checks if the string view ends with the given suffix + * @param[in] that The string view to find. + * @param[in] ch A single character. + * @return True if the string view ends with the provided suffix, false otherwise. + */ + template> + bool EndsWith(const std::basic_string_view& that, CharT ch) noexcept { + return !that.empty() && Traits::eq(that.back(), ch); + } + /** + * @brief Checks if the string view ends with the given suffix + * @param[in] that The string view to find. + * @param[in] s A null-terminated character string. + * @return True if the string view ends with the provided suffix, false otherwise. + */ + template> + bool EndsWith(const std::basic_string_view& that, const CharT* s) noexcept { + return EndsWith(that, std::basic_string_view(s)); + } + +#pragma endregion + +#pragma region String + + /** + * @brief Checks if the string begins with the given prefix + * @param[in] that The string to find. + * @param[in] sv A string view which may be a result of implicit conversion from \c std::basic_string. + * @return True if the string view begins with the provided prefix, false otherwise. + */ + template> + bool StartsWith(const std::basic_string& that, std::basic_string_view sv) noexcept { + return StartsWith(std::basic_string_view(that.data(), that.size()), sv); + } + /** + * @brief Checks if the string begins with the given prefix + * @param[in] that The string to find. + * @param[in] ch A single character. + * @return True if the string view begins with the provided prefix, false otherwise. + */ + template> + bool StartsWith(const std::basic_string& that, CharT ch) noexcept { + return StartsWith(std::basic_string_view(that.data(), that.size()), ch); + } + /** + * @brief Checks if the string begins with the given prefix + * @param[in] that The string to find. + * @param[in] s A null-terminated character string. + * @return True if the string view begins with the provided prefix, false otherwise. + */ + template> + bool StartsWith(const std::basic_string& that, const CharT* s) noexcept { + return StartsWith(std::basic_string_view(that.data(), that.size()), s); + } + + /** + * @brief Checks if the string ends with the given suffix + * @param[in] that The string to find. + * @param[in] sv A string view which may be a result of implicit conversion from \c std::basic_string. + * @return True if the string view ends with the provided suffix, false otherwise. + */ + template> + bool EndsWith(const std::basic_string& that, std::basic_string_view sv) noexcept { + return EndsWith(std::basic_string_view(that.data(), that.size()), sv); + } + /** + * @brief Checks if the string ends with the given suffix + * @param[in] that The string to find. + * @param[in] ch A single character. + * @return True if the string view ends with the provided suffix, false otherwise. + */ + template> + bool EndsWith(const std::basic_string& that, CharT ch) noexcept { + return EndsWith(std::basic_string_view(that.data(), that.size()), ch); + } + /** + * @brief Checks if the string ends with the given suffix + * @param[in] that The string to find. + * @param[in] s A null-terminated character string. + * @return True if the string view ends with the provided suffix, false otherwise. + */ + template> + bool EndsWith(const std::basic_string& that, const CharT* s) noexcept { + return EndsWith(std::basic_string_view(that.data(), that.size()), s); + } + +#pragma endregion + +#pragma endregion + +#pragma region Contain + + /** + * @brief Checks if there is an element with key equivalent to key in the container. + * @details + * The polyfill to \c Contains function of unordered and ordered associative container. + * Because this function only present after C++ 20. + * This function will use our custom polyfill if the version of C++ standard you are using lower than C++ 20. + * Otherwise it will fallback to vanilla standard library function. + * @tparam _TContainer + * The type of container. This container must have \c find() and \c end() member functions. + * @tparam _TKey + * The type of key of container. + * If the container is a set, this type is the type of item in set. + * If the container is a map, this type is the key type of map. + * @param[in] container The reference to container to find. + * @param[in] key Key value of the element to search for + * @return True if there is such an element, otherwise false. + * @remarks + * This template function do not have constraint check. + * If container type has \c find() and \c end() member functions, this template function will be created without any error. + * However, this function should be used for standard library associative container according to its original purpose. + * It means that the type of container usually and should be one of following types: + * \li \c std::set + * \li \c std::multiset + * \li \c std::map + * \li \c std::multimap + * \li \c std::unordered_set + * \li \c std::unordered_multiset + * \li \c std::unordered_map + * \li \c std::unordered_multimap + */ + template + bool Contains(const _TContainer& container, const _TKey& key) { +#if __cplusplus < 202002L + return container.find(key) != container.end(); +#else + return container.contains(key); +#endif + } + +#pragma endregion + +} diff --git a/src/WinFctHelper.cpp b/src/WinFctHelper.cpp index bb6ee55..5d3ebf9 100644 --- a/src/WinFctHelper.cpp +++ b/src/WinFctHelper.cpp @@ -9,7 +9,7 @@ namespace YYCC::WinFctHelper { HMODULE GetCurrentModule() { // Reference: https://stackoverflow.com/questions/557081/how-do-i-get-the-hmodule-for-the-currently-executing-code HMODULE hModule = NULL; - GetModuleHandleExW( + ::GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, // get address and do not inc ref counter. (LPCWSTR)GetCurrentModule, &hModule); @@ -24,7 +24,7 @@ namespace YYCC::WinFctHelper { // fetch temp folder while (true) { - if ((expected_size = GetTempPathW(static_cast(wpath.size()), wpath.data())) == 0) { + if ((expected_size = ::GetTempPathW(static_cast(wpath.size()), wpath.data())) == 0) { // failed, set to empty return false; } @@ -50,13 +50,13 @@ namespace YYCC::WinFctHelper { DWORD copied_size; while (true) { - if ((copied_size = GetModuleFileNameW(hModule, wpath.data(), static_cast(wpath.size()))) == 0) { + if ((copied_size = ::GetModuleFileNameW(hModule, wpath.data(), static_cast(wpath.size()))) == 0) { // failed, return return false; } // check insufficient buffer - if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) { // buffer is not enough, enlarge it and try again. wpath.resize(wpath.size() + MAX_PATH); } else { @@ -87,7 +87,27 @@ namespace YYCC::WinFctHelper { bool IsValidCodePage(UINT code_page) { CPINFOEXW cpinfo; - return GetCPInfoExW(code_page, 0, &cpinfo); + return ::GetCPInfoExW(code_page, 0, &cpinfo); + } + + BOOL CopyFile(const yycc_u8string_view& lpExistingFileName, const yycc_u8string_view& lpNewFileName, BOOL bFailIfExists) { + std::wstring wExistingFileName, wNewFileName; + if (!YYCC::EncodingHelper::UTF8ToWchar(lpExistingFileName, wExistingFileName)) return FALSE; + if (!YYCC::EncodingHelper::UTF8ToWchar(lpNewFileName, wNewFileName)) return FALSE; + return ::CopyFileW(wExistingFileName.c_str(), wNewFileName.c_str(), bFailIfExists); + } + + BOOL MoveFile(const yycc_u8string_view& lpExistingFileName, const yycc_u8string_view& lpNewFileName) { + std::wstring wExistingFileName, wNewFileName; + if (!YYCC::EncodingHelper::UTF8ToWchar(lpExistingFileName, wExistingFileName)) return FALSE; + if (!YYCC::EncodingHelper::UTF8ToWchar(lpNewFileName, wNewFileName)) return FALSE; + return ::MoveFileW(wExistingFileName.c_str(), wNewFileName.c_str()); + } + + BOOL DeleteFile(const yycc_u8string_view& lpFileName) { + std::wstring wFileName; + if (!YYCC::EncodingHelper::UTF8ToWchar(lpFileName, wFileName)) return FALSE; + return ::DeleteFileW(wFileName.c_str()); } } diff --git a/src/WinFctHelper.hpp b/src/WinFctHelper.hpp index 03ac29a..3cbc521 100644 --- a/src/WinFctHelper.hpp +++ b/src/WinFctHelper.hpp @@ -64,6 +64,43 @@ namespace YYCC::WinFctHelper { */ bool IsValidCodePage(UINT code_page); + /** + * @brief Copies an existing file to a new file. + * @param lpExistingFileName The name of an existing file. + * @param lpNewFileName The name of the new file. + * @param bFailIfExists + * If this parameter is TRUE and the new file specified by \c lpNewFileName already exists, the function fails. + * If this parameter is FALSE and the new file already exists, the function overwrites the existing file and succeeds. + * @return + * If the function succeeds, the return value is nonzero. + * If the function fails, the return value is zero. To get extended error information, call \c GetLastError. + * @remarks Same as Windows \c CopyFile: https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-copyfilew + */ + BOOL CopyFile(const yycc_u8string_view& lpExistingFileName, const yycc_u8string_view& lpNewFileName, BOOL bFailIfExists); + + /** + * @brief Moves an existing file or a directory, including its children. + * @param lpExistingFileName The current name of the file or directory on the local computer. + * @param lpNewFileName + * The new name for the file or directory. The new name must not already exist. + * A new file may be on a different file system or drive. A new directory must be on the same drive. + * @return + * If the function succeeds, the return value is nonzero. + * If the function fails, the return value is zero. To get extended error information, call \c GetLastError. + * @remarks Same as Windows \c MoveFile: https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-movefilew + */ + BOOL MoveFile(const yycc_u8string_view& lpExistingFileName, const yycc_u8string_view& lpNewFileName); + + /** + * @brief Deletes an existing file. + * @param lpFileName The name of the file to be deleted. + * @return + * If the function succeeds, the return value is nonzero. + * If the function fails, the return value is zero. To get extended error information, call \c GetLastError. + * @remarks Same as Windows \c DeleteFile: https://learn.microsoft.com/e-us/windows/win32/api/winbase/nf-winbase-deletefile + */ + BOOL DeleteFile(const yycc_u8string_view& lpFileName); + } #endif diff --git a/src/WinImportSuffix.hpp b/src/WinImportSuffix.hpp index 5c36920..8e42d0a 100644 --- a/src/WinImportSuffix.hpp +++ b/src/WinImportSuffix.hpp @@ -16,5 +16,8 @@ #undef LoadImage #undef GetTempPath #undef GetModuleFileName +#undef CopyFile +#undef MoveFile +#undef DeleteFile #endif \ No newline at end of file diff --git a/src/YYCCommonplace.hpp b/src/YYCCommonplace.hpp index d4591e9..7ccc730 100644 --- a/src/YYCCommonplace.hpp +++ b/src/YYCCommonplace.hpp @@ -10,7 +10,7 @@ #include "ParserHelper.hpp" #include "IOHelper.hpp" #include "WinFctHelper.hpp" -#include "FsPathPatch.hpp" +#include "StdPatch.hpp" #include "ExceptionHelper.hpp" #include "ConfigManager.hpp" diff --git a/testbench/main.cpp b/testbench/main.cpp index 96cbab0..ca1b542 100644 --- a/testbench/main.cpp +++ b/testbench/main.cpp @@ -394,13 +394,13 @@ namespace YYCCTestbench { #endif } - static void FsPathPatch() { + static void StdPatch() { std::filesystem::path test_path; for (const auto& strl : c_UTF8TestStrTable) { - test_path /= YYCC::FsPathPatch::FromUTF8Path(strl.c_str()); + test_path /= YYCC::StdPatch::ToStdPath(strl.c_str()); } - YYCC::yycc_u8string test_slashed_path(YYCC::FsPathPatch::ToUTF8Path(test_path)); + YYCC::yycc_u8string test_slashed_path(YYCC::StdPatch::ToUTF8Path(test_path)); #if YYCC_OS == YYCC_OS_WINDOWS std::wstring wdecilmer(1u, std::filesystem::path::preferred_separator); @@ -410,7 +410,7 @@ namespace YYCCTestbench { #endif YYCC::yycc_u8string test_joined_path(YYCC::StringHelper::Join(c_UTF8TestStrTable, decilmer.c_str())); - Assert(test_slashed_path == test_joined_path, YYCC_U8("YYCC::FsPathPatch")); + Assert(test_slashed_path == test_joined_path, YYCC_U8("YYCC::StdPatch")); } @@ -630,7 +630,7 @@ int main(int argc, char* argv[]) { YYCCTestbench::StringTestbench(); YYCCTestbench::ParserTestbench(); YYCCTestbench::WinFctTestbench(); - YYCCTestbench::FsPathPatch(); + YYCCTestbench::StdPatch(); // advanced YYCCTestbench::ConfigManagerTestbench(); YYCCTestbench::ArgParserTestbench(argc, argv);