From 91ba0c22d6f20dfacbf4904cffcad72357d28aba Mon Sep 17 00:00:00 2001 From: yyc12345 Date: Fri, 28 Jun 2024 11:38:19 +0800 Subject: [PATCH] doc: update documentation --- doc/src/encoding_helper.dox | 11 ++++++ doc/src/index.dox | 42 +++++++++++++++++++-- doc/src/intro.dox | 71 +++++++++++++++++++++++++++++++++-- doc/src/library_encoding.dox | 24 ++++++------ doc/src/string_helper.dox | 6 +++ doc/src/yycc_icon.png | Bin 0 -> 20818 bytes 6 files changed, 136 insertions(+), 18 deletions(-) create mode 100644 doc/src/encoding_helper.dox create mode 100644 doc/src/string_helper.dox create mode 100644 doc/src/yycc_icon.png diff --git a/doc/src/encoding_helper.dox b/doc/src/encoding_helper.dox new file mode 100644 index 0000000..765004b --- /dev/null +++ b/doc/src/encoding_helper.dox @@ -0,0 +1,11 @@ +/** + +\page encoding_helper Encoding Helper + +YYCC::EncodingHelper namespace include all encoding related functions: + +\li The convertion between native string and UTF8 string which has been introduced in chapter \ref library_encoding. +\li Windows specific convertion between \c WCHAR, UTF8 string and string encoded by other encoding. +\li The convertion among UTF8, UTF16 and UTF32. + +*/ \ No newline at end of file diff --git a/doc/src/index.dox b/doc/src/index.dox index 2bad68c..2779413 100644 --- a/doc/src/index.dox +++ b/doc/src/index.dox @@ -1,11 +1,45 @@ /** -\mainpage YYCCommonplace Library Manual +\mainpage YYCCommonplace Programming Manual -This manual is organized into the following chapters and appendices: + + + + + +
+ \image html yycc_icon.png +
+ YYCCommonplace Programming Manual -\li \subpage intro + Copyright 2024 by yyc12345. +
+ + + + +
+ This software and manual are provided under the terms of the MIT License. +
+ + + + + +
-\li \subpage library_encoding + \subpage intro + + \subpage library_encoding + + \subpage encoding_helper + + \subpage string_helper + + + + placeholder + +
*/ diff --git a/doc/src/intro.dox b/doc/src/intro.dox index cfbf0ca..aa43b28 100644 --- a/doc/src/intro.dox +++ b/doc/src/intro.dox @@ -2,10 +2,75 @@ \page intro Introduction to YYCCommonplace -work in progress +YYCCommonplace, or YYC Commonplace (abbr. YYCC), is a static library providing various useful C++ functions when programming with standard library or Windows environment. -\section intro_wip Work in Progress +Actually YYCC provides the functions which I frequently used in my personal projects. +Thus I do not need copy these functions from one project to another project. +I can write them once and use them everywhere. +It's also good for bug fix. +If I found bug in these code, I only need to fix it in this project. +Otherwise I need to fix them one by one in each project because they share the same code. -work in progress +\section intro_why Why YYCCommonplace + +\subsection intro_why_windows Windows Issues + +I frequently program on Windows environment because the software I programming for, Virtools, is Windows-only software. +During programming, I found Windows is super lack in UTF8 supports. +Programmer loves UTF8, because it can handle all charcaters over the world in one encoding and is still compatible with C-Style string. +However, Windows use a weird way to achieve internationalization, 2 different function trailing, A and W for legacy code and modern code respectively. +The worst things is that the char type W trailing function used, \c WCHAR, is defined as 2 bytes long, not 4 bytes long as Linux does (\c wchar_t). +It mean that one emoji charcater will be torn into 2 \c WCHAR on Windows because emoji code unit is higher than the manimum value of \c WCHAR. + +Also, there are various issues which should not be presented. +For example, Microsoft invents various \e safe standard library functions to prevent possible overflow issues raised by \c std::fgets and etc. +also, MSVC may throw weird error when you using some specific standard library functions. +You need to define some weird macro to disable this shitty behavior. + +There are various non-standard issue you may faced on Windows programming. +All in all, programming on Windows is a tough work. +This is one of the reasons why I create this library. +I create much wrappers for these weird Windows functions. +Thus I can have a similar Linux C++ programming experience on Windows. + +\subsection intro_why_std Standard Library Issues + +The eccentric decision of standard commission also is the reason why I create this library. + +\li C++ standard commission loves to bring one feature with N concepts and P assistant classes. +\li C++ standard commission seems doesn't want to bring any features the programmer urgent needed. +\li C++ standard commission loves delete programmer loved convenient functions and classes. +\li etc... + +There is not a proper way to \e format a string in C++ until C++ 20 (\c std::format). +String related functions, such as split, lower, higher, replace, now still not be included in standard library. +Programmer loved, easy to used UTF8 procession functions and classes was deprecate now and will be removed in future. + +That's why I create this library. +I bring these function in this library. +Not industrial level, but easy to use and have enough performance in my project. + +\subsection intro_why_boost Boost Issues + +Bosst is a powerful C++ library. But the shortcoming is overt. It's tooooo big. +This drawback will be more obvious considering the bad dependency mechanism of C++. +Although the most of Boost sub-library is header-only, but some library still need to link with Boost. +It order you download the whole Boost library and extract it in your hard disk. +Cost more than half hours, 5+ GB disk space and the life time of your disk. + +The functions belonging to Boost is industrial level. +But what I want is not industrial level functions. +I only need a function which can barely finish my work. That's enough. +I don't need extreme performance. I just want my code works. + +So I create this library, bring some Boost functions with ordinary but not bad implementation. + +\section intro_usage Library Usage + +Before using this library, I suggest you read this manual fully to have a full overview of this library. +Otherwise you may make mistake during using this library. +I suggest you read this manual from top to bottom in the left tree panel, one by one. + +This library is a static library. */ diff --git a/doc/src/library_encoding.dox b/doc/src/library_encoding.dox index 0d19472..1b10d8c 100644 --- a/doc/src/library_encoding.dox +++ b/doc/src/library_encoding.dox @@ -32,7 +32,7 @@ That's unacceptable! So I create my own UTF8 type to avoid the scenario that sta \section library_encoding_utf8_literal UTF8 Literal -C++ standard allows programmer declare a UTF8 literal explicitly by writing code like this: +C++ standard allows programmer declare an UTF8 literal explicitly by writing code like this: \code u8"foo bar" @@ -41,11 +41,10 @@ u8"foo bar" This is okey. But it may incompatible with YYCC UTF8 char type. According to C++ standard, this UTF8 literal syntax will only return \c const \c char8_t* if your C++ standard higher or equal to C++ 20, otherwise it will return \c const \c char*. -This behavior cause that you can not assign this UTF8 literal to yycc_u8string if you are in the environment which do not support \c char8_t, +This behavior cause that you can not assign this UTF8 literal to \c yycc_u8string if you are in the environment which do not support \c char8_t, because their types are different. Thereas you can not use the functions provided by this library because they are all use YYCC defined UTF8 char type. - -So I will tell you how to create UTF8 literal in following content of this section. +So I will tell you how to correctly create UTF8 literal in the following content. YYCC provides a macro \c YYCC_U8 to resolve this issue. You can declare UTF8 literal like this: @@ -58,11 +57,12 @@ You don't need add extra \c u8 prefix in string given to the macro. This macro will do this automatically. In detail, this macro do a \c reinterpret_cast to change the type of given argument to \c const \c yycc_char8_t* forcely. -This ensure that declared UTF8 literal is compatible with YYCC defined UTF8 types. +This ensure that declared UTF8 literal is compatible with YYCC UTF8 types. \section library_encoding_utf8_pointer UTF8 String Pointer -Besides UTF8 literal, another issue you may be faced is how to convert native UTF8 string pointer to YYCC UTF8 type. +Besides UTF8 literal, another issue you may be faced is how to convert native UTF8 string pointer to YYCC UTF8 type +(\e native means \c const \c char* or \c char*, the string using char as its char type). Many legacy code assume \c char* is encoded with UTF8 (the exception is Windows). But \c char* is incompatible with yycc_char8_t. YYCC provides YYCC::EncodingHelper::ToUTF8 to resolve this issue. There is an exmaple: @@ -75,7 +75,7 @@ char* mutable_utf8 = const_cast(absolutely_is_utf8); // This is not safe. yycc_char8_t* mutable_converted = YYCC::EncodingHelper::ToUTF8(mutable_utf8); \endcode -YYCC::EncodingHelper::ToUTF8 has 2 overloads which can handle const and non-const stirng pointer convertion respectively. +YYCC::EncodingHelper::ToUTF8 has 2 overloads which can handle const and mutable stirng pointer convertion respectively. YYCC also provide ability that convert YYCC UTF8 char type to native char type by YYCC::EncodingHelper::ToNative. Here is an exmaple: @@ -88,12 +88,12 @@ yycc_char8_t* mutable_yycc_utf8 = const_cast(yycc_utf8); // Not safe. Als char* mutable_converted = YYCC::EncodingHelper::ToNative(mutable_yycc_utf8); \endcode -Same as YYCC::EncodingHelper::ToUTF8, YYCC::EncodingHelper::ToNative also has 2 overloads to handle const and non-const string pointer. +Same as YYCC::EncodingHelper::ToUTF8, YYCC::EncodingHelper::ToNative also has 2 overloads to handle const and mutable string pointer. \section library_encoding_utf8_container UTF8 String Container The final issue you faced is string container. -In many personal project, you may use \c std::string everywhere because \c std::u8string may not be presented when you writing your peoject. +In many personal project, programmer may use \c std::string everywhere because \c std::u8string may not be presented when writing peoject. How to do convertion between native string container and YYCC UTF8 string container? It is definitely illegal that directly do force convertion. Because they may have different class layout. @@ -108,12 +108,12 @@ yycc_u8string yycc_string = YYCC::EncodingHelper::ToUTF8(native_string); auto result = YYCC::EncodingHelper::UTF8ToUTF32(yycc_string); \endcode -Actually, YYCC::EncodingHelper::ToUTF8 accept one \c std::string_view as argument. +Actually, YYCC::EncodingHelper::ToUTF8 accepts a reference to \c std::string_view as argument. However, there is a implicit convertion from \c std::string to \c std::string_view, so you can directly pass a \c std::string instance to it. String view will reduce unnecessary memory copy. -If you just want to pass native string container to function, and this function accept yycc_u8string_view as its argument, +If you just want to pass native string container to function, and this function accepts \c yycc_u8string_view as its argument, you can use alternative YYCC::EncodingHelper::ToUTF8View. \code @@ -126,6 +126,8 @@ Comparing with previous one, this example use less memory. The reduced memory is the content of \c yycc_string because string view is a view, not the copy of original string. Same as UTF8 string pointer, we also have YYCC::EncodingHelper::ToNative and YYCC::EncodingHelper::ToNativeView do correspondant reverse convertion. +Try to do your own research and figure out how to use them. +It's pretty easy. \section library_encoding_windows Warnings to Windows Programmer diff --git a/doc/src/string_helper.dox b/doc/src/string_helper.dox new file mode 100644 index 0000000..bfd93c5 --- /dev/null +++ b/doc/src/string_helper.dox @@ -0,0 +1,6 @@ +/** + +\page string_helper String Helper + + +*/ diff --git a/doc/src/yycc_icon.png b/doc/src/yycc_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..81a207cba5a5a9ce72ef5b8de819a3a1874adc82 GIT binary patch literal 20818 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 literal 0 HcmV?d00001