fix: add testbench for new added code. fix issues.
- add testbench for new added code in StdPatch. - add documentation for new added code. - fix the old usage of StdPatch::ToStdPath in ExceptionHelper.
This commit is contained in:
parent
59c185a424
commit
f3a88e951c
|
@ -3,6 +3,41 @@ namespace YYCC::StdPatch {
|
||||||
|
|
||||||
\page std_patch Standard Library Patch
|
\page std_patch Standard Library Patch
|
||||||
|
|
||||||
|
\section std_patch__starts_with_ends_with Starts With & Ends With
|
||||||
|
|
||||||
|
\c std::basic_string::starts_with and \c std::basic_string::ends_with (also available in \c std::basic_string_view)
|
||||||
|
are functions introduced in C++ 20 and unavailable in C++ 17.
|
||||||
|
YYCC::StdPatch provides a patch for these function in C++ 17 environment.
|
||||||
|
Please note these implementations are following implementation instruction presented by CppReference website.
|
||||||
|
And it should have the same performance with vanilla functions because Microsoft STL use the same way to implement.
|
||||||
|
These implementations will not fallback to vanilla function even they are available.
|
||||||
|
Because their performance are good.
|
||||||
|
|
||||||
|
To use these functions, you just need to call them like corresponding vanilla functions.
|
||||||
|
Our implementations provide all necessary overloads.
|
||||||
|
The only thing you need to do is provide the string self as the first argument,
|
||||||
|
because our implementations can not be inserted as a class member of string.
|
||||||
|
There is an example:
|
||||||
|
|
||||||
|
\code
|
||||||
|
YYCC::StdPatch::StartsWith(YYCC_U8("aabbcc"), YYCC_U8("aa"));
|
||||||
|
YYCC::StdPatch::EndsWith(YYCC_U8("aabbcc"), YYCC_U8("cc"));
|
||||||
|
\endcode
|
||||||
|
|
||||||
|
\section std_patch__contains Contains
|
||||||
|
|
||||||
|
\c Contains function in standard library ordered and unordered successive container are also introduced in C++ 20.
|
||||||
|
YYCC::StdPatch provides a patch for this function in C++ 17 environment.
|
||||||
|
|
||||||
|
Please note this implementation will fallback to vanilla function if it is available.
|
||||||
|
Because our implementation is a remedy (there is no way to use public class member to have the same performance of vanilla function).
|
||||||
|
There is an example about how to use it:
|
||||||
|
|
||||||
|
\code
|
||||||
|
std::set<int> test { 1, 5 };
|
||||||
|
YYCC::StdPatch::Contains(test, static_cast<int>(5));
|
||||||
|
\endcode
|
||||||
|
|
||||||
\section std_patch__fs_path std::filesystem::path 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,
|
As you know, the underlying char type of \c std::filesystem::path is \c wchar_t on Windows,
|
||||||
|
|
|
@ -15,6 +15,9 @@ Currently this namespace has following functions:
|
||||||
\li #GetModuleFileName: Get the path to module in file system by given handle.
|
\li #GetModuleFileName: Get the path to module in file system by given handle.
|
||||||
\li #GetLocalAppData: Get the path inside \%LOCALAPPDATA\%
|
\li #GetLocalAppData: Get the path inside \%LOCALAPPDATA\%
|
||||||
\li #IsValidCodePage: Check whether given code page number is valid.
|
\li #IsValidCodePage: Check whether given code page number is valid.
|
||||||
|
\li #CopyFile: The UTF8 version of Win32 \c CopyFile.
|
||||||
|
\li #MoveFile: The UTF8 version of Win32 \c MoveFile.
|
||||||
|
\li #DeleteFile: The UTF8 version of Win32 \c DeleteFile.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
}
|
}
|
|
@ -459,7 +459,7 @@ namespace YYCC::ExceptionHelper {
|
||||||
if (!YYCC::WinFctHelper::GetModuleFileName(NULL, u8_process_path))
|
if (!YYCC::WinFctHelper::GetModuleFileName(NULL, u8_process_path))
|
||||||
return false;
|
return false;
|
||||||
// extract file name from full path by std::filesystem::path
|
// extract file name from full path by std::filesystem::path
|
||||||
std::filesystem::path process_path(StdPatch::ToStdPath(u8_process_path.c_str()));
|
std::filesystem::path process_path(StdPatch::ToStdPath(u8_process_path));
|
||||||
u8_process_name = StdPatch::ToUTF8Path(process_path.filename());
|
u8_process_name = StdPatch::ToUTF8Path(process_path.filename());
|
||||||
}
|
}
|
||||||
// then get process id
|
// then get process id
|
||||||
|
@ -478,7 +478,7 @@ namespace YYCC::ExceptionHelper {
|
||||||
if (!WinFctHelper::GetLocalAppData(u8_localappdata_path))
|
if (!WinFctHelper::GetLocalAppData(u8_localappdata_path))
|
||||||
return false;
|
return false;
|
||||||
// convert to std::filesystem::path
|
// convert to std::filesystem::path
|
||||||
std::filesystem::path crash_report_path(StdPatch::ToStdPath(u8_localappdata_path.c_str()));
|
std::filesystem::path crash_report_path(StdPatch::ToStdPath(u8_localappdata_path));
|
||||||
// slash into crash report folder
|
// slash into crash report folder
|
||||||
crash_report_path /= StdPatch::ToStdPath(YYCC_U8("CrashDumps"));
|
crash_report_path /= StdPatch::ToStdPath(YYCC_U8("CrashDumps"));
|
||||||
// use create function to make sure it is existing
|
// use create function to make sure it is existing
|
||||||
|
@ -486,8 +486,8 @@ namespace YYCC::ExceptionHelper {
|
||||||
|
|
||||||
// build log path and coredump path
|
// build log path and coredump path
|
||||||
// build std::filesystem::path first
|
// build std::filesystem::path first
|
||||||
std::filesystem::path log_filepath = crash_report_path / StdPatch::ToStdPath(u8_log_filename.c_str());
|
std::filesystem::path log_filepath = crash_report_path / StdPatch::ToStdPath(u8_log_filename);
|
||||||
std::filesystem::path coredump_filepath = crash_report_path / StdPatch::ToStdPath(u8_coredump_filename.c_str());
|
std::filesystem::path coredump_filepath = crash_report_path / StdPatch::ToStdPath(u8_coredump_filename);
|
||||||
// output to result
|
// output to result
|
||||||
log_path = StdPatch::ToUTF8Path(log_filepath);
|
log_path = StdPatch::ToUTF8Path(log_filepath);
|
||||||
coredump_path = StdPatch::ToUTF8Path(coredump_filepath);
|
coredump_path = StdPatch::ToUTF8Path(coredump_filepath);
|
||||||
|
|
|
@ -77,7 +77,7 @@ namespace YYCC::StdPatch {
|
||||||
*/
|
*/
|
||||||
template<class CharT, class Traits = std::char_traits<CharT>>
|
template<class CharT, class Traits = std::char_traits<CharT>>
|
||||||
bool EndsWith(const std::basic_string_view<CharT, Traits>& that, std::basic_string_view<CharT, Traits> sv) noexcept {
|
bool EndsWith(const std::basic_string_view<CharT, Traits>& that, std::basic_string_view<CharT, Traits> sv) noexcept {
|
||||||
return that.size() >= sv.size() && that.compare(that.size() - sv.size(), std::basic_string_view<CharT, Traits>::npos, sv);
|
return that.size() >= sv.size() && that.compare(that.size() - sv.size(), std::basic_string_view<CharT, Traits>::npos, sv) == 0;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @brief Checks if the string view ends with the given suffix
|
* @brief Checks if the string view ends with the given suffix
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#include <YYCCommonplace.hpp>
|
#include <YYCCommonplace.hpp>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <set>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
namespace Console = YYCC::ConsoleHelper;
|
namespace Console = YYCC::ConsoleHelper;
|
||||||
|
|
||||||
|
@ -346,7 +348,8 @@ namespace YYCCTestbench {
|
||||||
).c_str(),
|
).c_str(),
|
||||||
L"Fatal Error", MB_OK + MB_ICONERROR
|
L"Fatal Error", MB_OK + MB_ICONERROR
|
||||||
);
|
);
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// Perform a div zero exception.
|
// Perform a div zero exception.
|
||||||
#if defined (YYCC_DEBUG_UE_FILTER)
|
#if defined (YYCC_DEBUG_UE_FILTER)
|
||||||
|
@ -355,8 +358,7 @@ namespace YYCCTestbench {
|
||||||
// all of code normally inside of main or WinMain here...
|
// all of code normally inside of main or WinMain here...
|
||||||
int i = 1, j = 0;
|
int i = 1, j = 0;
|
||||||
int k = i / j;
|
int k = i / j;
|
||||||
}
|
} __except (YYCC::ExceptionHelper::DebugCallUExceptionImpl(GetExceptionInformation())) {
|
||||||
__except (YYCC::ExceptionHelper::DebugCallUExceptionImpl(GetExceptionInformation())) {
|
|
||||||
OutputDebugStringW(L"executed filter function\n");
|
OutputDebugStringW(L"executed filter function\n");
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -388,29 +390,50 @@ namespace YYCCTestbench {
|
||||||
Assert(YYCC::WinFctHelper::GetLocalAppData(test_localappdata_path), YYCC_U8("YYCC::WinFctHelper::GetLocalAppData"));
|
Assert(YYCC::WinFctHelper::GetLocalAppData(test_localappdata_path), YYCC_U8("YYCC::WinFctHelper::GetLocalAppData"));
|
||||||
Console::FormatLine(YYCC_U8("Local AppData: %s"), test_localappdata_path.c_str());
|
Console::FormatLine(YYCC_U8("Local AppData: %s"), test_localappdata_path.c_str());
|
||||||
|
|
||||||
Assert(YYCC::WinFctHelper::IsValidCodePage(static_cast<UINT>(1252)) == true, YYCC_U8("YYCC::WinFctHelper::IsValidCodePage"));
|
Assert(YYCC::WinFctHelper::IsValidCodePage(static_cast<UINT>(1252)), YYCC_U8("YYCC::WinFctHelper::IsValidCodePage"));
|
||||||
Assert(YYCC::WinFctHelper::IsValidCodePage(static_cast<UINT>(114514)) == false, YYCC_U8("YYCC::WinFctHelper::IsValidCodePage"));
|
Assert(!YYCC::WinFctHelper::IsValidCodePage(static_cast<UINT>(114514)), YYCC_U8("YYCC::WinFctHelper::IsValidCodePage"));
|
||||||
|
|
||||||
|
// MARK: There is no testbench for MoveFile, CopyFile DeleteFile.
|
||||||
|
// Because they can operate file system files.
|
||||||
|
// And may cause test environment entering unstable status.
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void StdPatch() {
|
static void StdPatch() {
|
||||||
|
|
||||||
|
// Std Path
|
||||||
|
|
||||||
std::filesystem::path test_path;
|
std::filesystem::path test_path;
|
||||||
for (const auto& strl : c_UTF8TestStrTable) {
|
for (const auto& strl : c_UTF8TestStrTable) {
|
||||||
test_path /= YYCC::StdPatch::ToStdPath(strl.c_str());
|
test_path /= YYCC::StdPatch::ToStdPath(strl);
|
||||||
}
|
}
|
||||||
YYCC::yycc_u8string test_slashed_path(YYCC::StdPatch::ToUTF8Path(test_path));
|
YYCC::yycc_u8string test_slashed_path(YYCC::StdPatch::ToUTF8Path(test_path));
|
||||||
|
|
||||||
#if YYCC_OS == YYCC_OS_WINDOWS
|
#if YYCC_OS == YYCC_OS_WINDOWS
|
||||||
std::wstring wdecilmer(1u, std::filesystem::path::preferred_separator);
|
std::wstring wdecilmer(1u, std::filesystem::path::preferred_separator);
|
||||||
YYCC::yycc_u8string decilmer(YYCC::EncodingHelper::WcharToUTF8(wdecilmer.c_str()));
|
YYCC::yycc_u8string decilmer(YYCC::EncodingHelper::WcharToUTF8(wdecilmer));
|
||||||
#else
|
#else
|
||||||
YYCC::yycc_u8string decilmer(1u, std::filesystem::path::preferred_separator);
|
YYCC::yycc_u8string decilmer(1u, std::filesystem::path::preferred_separator);
|
||||||
#endif
|
#endif
|
||||||
YYCC::yycc_u8string test_joined_path(YYCC::StringHelper::Join(c_UTF8TestStrTable, decilmer.c_str()));
|
YYCC::yycc_u8string test_joined_path(YYCC::StringHelper::Join(c_UTF8TestStrTable, decilmer.c_str()));
|
||||||
|
|
||||||
Assert(test_slashed_path == test_joined_path, YYCC_U8("YYCC::StdPatch"));
|
Assert(test_slashed_path == test_joined_path, YYCC_U8("YYCC::StdPatch::ToStdPath, YYCC::StdPatch::ToUTF8Path"));
|
||||||
|
|
||||||
|
// StartsWith, EndsWith
|
||||||
|
YYCC::yycc_u8string test_starts_ends_with(YYCC_U8("aaabbbccc"));
|
||||||
|
Assert(YYCC::StdPatch::StartsWith(test_starts_ends_with, YYCC_U8("aaa")), YYCC_U8("YYCC::StdPatch::StartsWith"));
|
||||||
|
Assert(!YYCC::StdPatch::StartsWith(test_starts_ends_with, YYCC_U8("ccc")), YYCC_U8("YYCC::StdPatch::StartsWith"));
|
||||||
|
Assert(!YYCC::StdPatch::EndsWith(test_starts_ends_with, YYCC_U8("aaa")), YYCC_U8("YYCC::StdPatch::EndsWith"));
|
||||||
|
Assert(YYCC::StdPatch::EndsWith(test_starts_ends_with, YYCC_U8("ccc")), YYCC_U8("YYCC::StdPatch::EndsWith"));
|
||||||
|
|
||||||
|
// Contains
|
||||||
|
std::set<int> test_set { 1, 2, 3, 4, 6, 7 };
|
||||||
|
Assert(YYCC::StdPatch::Contains(test_set, static_cast<int>(1)), YYCC_U8("YYCC::StdPatch::Contains"));
|
||||||
|
Assert(!YYCC::StdPatch::Contains(test_set, static_cast<int>(5)), YYCC_U8("YYCC::StdPatch::Contains"));
|
||||||
|
std::map<int, float> test_map { { 1, 1.0f }, { 4, 4.0f } };
|
||||||
|
Assert(YYCC::StdPatch::Contains(test_map, static_cast<int>(1)), YYCC_U8("YYCC::StdPatch::Contains"));
|
||||||
|
Assert(!YYCC::StdPatch::Contains(test_map, static_cast<int>(5)), YYCC_U8("YYCC::StdPatch::Contains"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user