namespace YYCC::StdPatch { /** \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 test { 1, 5 }; YYCC::StdPatch::Contains(test, static_cast(5)); \endcode \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. Due to this, if you try to create a \c std::filesystem::path instance by calling constructor with an UTF8 char sequence on Windows, the library implementation will assume your input is based on current Windows code page, not UTF8. And the final path stored in \c std::filesystem::path is not what you expcected. This patch gives you a way to create \c std::filesystem::path and extract path string stored in \c std::filesystem::path with UTF8 encoding. This patch namespace always use UTF8 as its argument. You should use the functions provided by this namespace on any platforms instead of vanilla \c std::filesystem::path functions. However, if your C++ standard is higher than C++ 20, you can directly use UTF8 string pointer and string container in \c std::filesystem::path, because standard library has supported them. This patch only just want to provide an uniform programming experience. 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. \subsection std_patch__fs_path__from_utf8_path Create Path from UTF8 String #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::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. However, for the second and third line in example, what we want to tell you is that you should always use this function in other \c std::filesystem::path functions requiring path string. \c std::filesystem::path is a very \e conservative class. Most of its functions only accept \c std::filesystem::path self as argument. For example, \c std::filesystem::path::replace_extension do not accept string as argument. It accepts a reference to \c std::filesystem::path as argument. (it still is possible that pass string pointer or string container to it because they can be converted to \c std::filesystem::path implicitly.) It's great. This is what we expected! We now can safely deliver the result generated by our function to these functions, and don't need to worry about the encoding of we provided string. Because all strings have been converted to \c std::filesystem::path by our function before passing them. So, the second line will produce \c "/foo/bar/test" and the third line will produce \c "/foo/bar.txt" in any platforms. You may notice std::filesystem::u8path. 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. \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 #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::StdPatch::ToStdPath(YYCC_U8("/foo/bar")); auto result = YYCC::StdPatch::ToUTF8Path(foobar_path / YYCC::StdPatch::ToStdPath(YYCC_U8("test"))); \endcode */ }