From cc5e6239ba4fdd0f3b3136428db06ba58a483aa1 Mon Sep 17 00:00:00 2001 From: yyc12345 Date: Tue, 23 Dec 2025 13:59:14 +0800 Subject: [PATCH] doc: add doc for code, mainly for clap --- src/yycc/carton/clap/application.hpp | 31 +++++++-- src/yycc/carton/clap/manual.hpp | 38 +++++++--- src/yycc/carton/clap/option.hpp | 100 ++++++++++++++++++++++++--- src/yycc/carton/clap/parser.hpp | 43 ++++++++++++ src/yycc/carton/clap/resolver.hpp | 43 ++++++++++++ src/yycc/carton/clap/summary.hpp | 24 +++++++ src/yycc/carton/clap/variable.hpp | 84 ++++++++++++++++++++-- src/yycc/carton/ironpad.cpp | 3 +- src/yycc/carton/pycodec.hpp | 8 +++ src/yycc/carton/tabulate.hpp | 21 +++++- src/yycc/patch/stream.hpp | 4 +- 11 files changed, 361 insertions(+), 38 deletions(-) diff --git a/src/yycc/carton/clap/application.hpp b/src/yycc/carton/clap/application.hpp index cddefc7..cef15ea 100644 --- a/src/yycc/carton/clap/application.hpp +++ b/src/yycc/carton/clap/application.hpp @@ -7,9 +7,16 @@ #define NS_YYCC_CLAP ::yycc::carton::clap namespace yycc::carton::clap::application { - + + /// @brief Represents a complete command line application with its summary, options, and environment variables. class Application { public: + /** + * @brief Constructs a new Application object with the given summary, options, and variables. + * @param[in] summary The summary information for the application + * @param[in] options The collection of command line options + * @param[in] variables The collection of command line variables + */ Application(NS_YYCC_CLAP::summary::Summary&& summary, NS_YYCC_CLAP::option::OptionCollection&& options, NS_YYCC_CLAP::variable::VariableCollection&& variables); @@ -17,16 +24,28 @@ namespace yycc::carton::clap::application { YYCC_DEFAULT_COPY_MOVE(Application) public: + /** + * @brief Gets the summary information for this application. + * @return A constant reference to the application's summary + */ const NS_YYCC_CLAP::summary::Summary& get_summary() const; + /** + * @brief Gets the collection of command line options for this application. + * @return A constant reference to the application's options + */ const NS_YYCC_CLAP::option::OptionCollection& get_options() const; + /** + * @brief Gets the collection of environment variables for this application. + * @return A constant reference to the application's variables + */ const NS_YYCC_CLAP::variable::VariableCollection& get_variables() const; private: - NS_YYCC_CLAP::summary::Summary summary; - NS_YYCC_CLAP::option::OptionCollection options; - NS_YYCC_CLAP::variable::VariableCollection variables; + NS_YYCC_CLAP::summary::Summary summary; ///< The summary information for the application + NS_YYCC_CLAP::option::OptionCollection options; ///< The collection of command line options + NS_YYCC_CLAP::variable::VariableCollection variables; ///< The collection of environment variables }; -} +} // namespace yycc::carton::clap::application -#undef NS_YYCC_CLAP +#undef NS_YYCC_CLAP \ No newline at end of file diff --git a/src/yycc/carton/clap/manual.hpp b/src/yycc/carton/clap/manual.hpp index 925a277..ab3dc8e 100644 --- a/src/yycc/carton/clap/manual.hpp +++ b/src/yycc/carton/clap/manual.hpp @@ -9,41 +9,57 @@ namespace yycc::carton::clap::manual { + /// @brief Structure containing translation context for manual generation. struct ManualTr { public: + /// @brief Constructs a new ManualTr object with default values. ManualTr(); ~ManualTr(); YYCC_DEFAULT_COPY_MOVE(ManualTr) public: - std::u8string author_and_version; - std::u8string usage_title, usage_body; - std::u8string avail_opt, avail_var; + std::u8string author_and_version; ///< Translated string for author and version + std::u8string usage_title, usage_body; ///< Translated strings for usage title and body + std::u8string avail_opt, avail_var; ///< Translated strings for available options and variables }; + /// @brief Class responsible for generating help and version information for command line applications. class Manual { public: + /** + * @brief Constructs a new Manual object for the given application. + * @param[in] app The application to generate manual for + * @param[in] trctx Translation context for manual generation (default if not provided) + */ Manual(const NS_YYCC_CLAP::application::Application& app, ManualTr&& trctx = ManualTr()); ~Manual(); YYCC_DEFAULT_COPY_MOVE(Manual) private: - void setup_table(); - void fill_opt_table(); - void fill_var_table(); + void setup_table(); ///< Sets up the tables for displaying options and variables + void fill_opt_table(); ///< Fills the options table with available options + void fill_var_table(); ///< Fills the variables table with available variables public: + /** + * @brief Prints the version information of the application. + * @param[in] dst The output stream to print to (defaults to std::cout) + */ void print_version(std::ostream& dst = std::cout) const; + /** + * @brief Prints the help information of the application. + * @param[in] dst The output stream to print to (defaults to std::cout) + */ void print_help(std::ostream& dst = std::cout) const; private: - ManualTr trctx; - NS_YYCC_CLAP::application::Application app; - NS_YYCC_TABULATE::Tabulate opt_printer; - NS_YYCC_TABULATE::Tabulate var_printer; + ManualTr trctx; ///< Translation context for manual generation + NS_YYCC_CLAP::application::Application app; ///< The application to generate manual for + NS_YYCC_TABULATE::Tabulate opt_printer; ///< Tabulate object for printing options + NS_YYCC_TABULATE::Tabulate var_printer; ///< Tabulate object for printing variables }; } // namespace yycc::carton::clap::manual #undef NS_YYCC_TABULATE -#undef NS_YYCC_CLAP +#undef NS_YYCC_CLAP \ No newline at end of file diff --git a/src/yycc/carton/clap/option.hpp b/src/yycc/carton/clap/option.hpp index 792491c..533ef5a 100644 --- a/src/yycc/carton/clap/option.hpp +++ b/src/yycc/carton/clap/option.hpp @@ -10,8 +10,16 @@ namespace yycc::carton::clap::option { + /// @brief Represents a command line option that can be parsed from user input. class Option { public: + /** + * @brief Constructs a new Option object with the specified parameters. + * @param[in] short_name Optional short name for the option (e.g., "h" for "-h") + * @param[in] long_name Optional long name for the option (e.g., "help" for "--help") + * @param[in] value_hint Optional hint for the expected value type (e.g., "FILE") + * @param[in] description A description of the option's purpose + */ Option(std::optional short_name, std::optional long_name, std::optional value_hint, @@ -20,10 +28,30 @@ namespace yycc::carton::clap::option { YYCC_DEFAULT_COPY_MOVE(Option) public: + /** + * @brief Checks if the option expects a value. + * @return true if the option expects a value, false otherwise + */ bool has_value() const; + /** + * @brief Gets the short name of the option. + * @return An optional containing the short name if it exists, std::nullopt otherwise + */ std::optional get_short_name() const; + /** + * @brief Gets the long name of the option. + * @return An optional containing the long name if it exists, std::nullopt otherwise + */ std::optional get_long_name() const; + /** + * @brief Gets the value hint for the option. + * @return An optional containing the value hint if it exists, std::nullopt otherwise + */ std::optional get_value_hint() const; + /** + * @brief Gets the description of the option. + * @return The option's description as a u8string_view + */ std::u8string_view get_description() const; std::u8string to_showcase_name() const; @@ -34,47 +62,101 @@ namespace yycc::carton::clap::option { static bool legal_long_name(const std::u8string_view& name); private: - std::optional short_name; - std::optional long_name; - std::optional value_hint; - std::u8string description; + std::optional short_name; ///< The short name of the option (if any) + std::optional long_name; ///< The long name of the option (if any) + std::optional value_hint; ///< Hint for the expected value type (if any) + std::u8string description; ///< Description of the option's purpose }; + /// @brief Represents an option that has been registered with a token for identification. class RegisteredOption { public: + /** + * @private + * @brief Constructs a new RegisteredOption object with the given token and option. + * @param[in] token The unique token associated with the option + * @param[in] option The option to register + */ RegisteredOption(NS_YYCC_CLAP_TYPES::Token token, Option&& option); ~RegisteredOption(); YYCC_DEFAULT_COPY_MOVE(RegisteredOption) public: + /** + * @brief Gets the token associated with this registered option. + * @return The token identifying this option + */ NS_YYCC_CLAP_TYPES::Token get_token() const; + /** + * @brief Gets the option associated with this registration. + * @return A constant reference to the option + */ const Option& get_option() const; private: - NS_YYCC_CLAP_TYPES::Token token; - Option option; + NS_YYCC_CLAP_TYPES::Token token; ///< The unique token identifying this option + Option option; ///< The registered option }; + /// @brief A collection of options with methods to manage them by token or name. class OptionCollection { public: + /// @brief Constructs a new, empty OptionCollection object. OptionCollection(); ~OptionCollection(); YYCC_DEFAULT_COPY_MOVE(OptionCollection) public: + /** + * @brief Adds a new option to the collection and returns a token for it. + * @param[in] opt The option to add to the collection + * @return A token that uniquely identifies the added option + */ NS_YYCC_CLAP_TYPES::Token add_option(Option&& opt); + /** + * @brief Finds the token associated with an option by its long name. + * @param[in] long_name The long name of the option to find + * @return An optional token if the option exists, std::nullopt otherwise + */ std::optional find_long_name(const std::u8string_view& long_name) const; + /** + * @brief Finds the token associated with an option by its short name. + * @param[in] short_name The short name of the option to find + * @return An optional token if the option exists, std::nullopt otherwise + */ std::optional find_short_name(const std::u8string_view& short_name) const; + /** + * @brief Checks if an option with the given token exists in the collection. + * @param[in] token The token to check for + * @return true if an option with the token exists, false otherwise + */ bool has_option(NS_YYCC_CLAP_TYPES::Token token) const; + /** + * @brief Gets the option associated with the given token. + * @param[in] token The token identifying the option + * @return A constant reference to the option + */ const Option& get_option(NS_YYCC_CLAP_TYPES::Token token) const; + /** + * @brief Gets all registered options in the collection. + * @return A constant reference to the vector of registered options + */ const std::vector& all_options() const; + /** + * @brief Gets the number of options in the collection. + * @return The count of options in the collection + */ size_t length() const; + /** + * @brief Checks if the collection is empty. + * @return true if the collection contains no options, false otherwise + */ bool empty() const; private: - std::map short_names; - std::map long_names; - std::vector options; + std::map short_names; ///< Map from short option names to tokens + std::map long_names; ///< Map from long option names to tokens + std::vector options; ///< Vector of registered options }; } // namespace yycc::carton::clap::option diff --git a/src/yycc/carton/clap/parser.hpp b/src/yycc/carton/clap/parser.hpp index 67c72f6..826fa9b 100644 --- a/src/yycc/carton/clap/parser.hpp +++ b/src/yycc/carton/clap/parser.hpp @@ -16,6 +16,7 @@ namespace yycc::carton::clap::parser { + /// @brief Parses command line arguments and provides access to parsed values. class Parser { private: /** @@ -27,8 +28,19 @@ namespace yycc::carton::clap::parser { std::map> values; public: + /** + * @brief Creates a Parser from user-provided command line arguments. + * @param[in] app The application to parse arguments for + * @param[in] args Vector of command line argument strings to parse + * @return A ClapResult containing either a Parser object or an error + */ static NS_YYCC_CLAP_TYPES::ClapResult from_user(const NS_YYCC_CLAP_APPLICATION::Application& app, const std::vector& args); + /** + * @brief Creates a Parser from system command line arguments (argc/argv). + * @param[in] app The application to parse arguments for + * @return A ClapResult containing either a Parser object or an error + */ static NS_YYCC_CLAP_TYPES::ClapResult from_system(const NS_YYCC_CLAP_APPLICATION::Application& app); private: @@ -39,11 +51,42 @@ namespace yycc::carton::clap::parser { YYCC_DEFAULT_COPY_MOVE(Parser) private: + /** + * @brief Gets the raw value of an option as a string view. + * @param[in] token The token identifying the option + * @return A ClapResult containing either the raw value as a string view or an error + */ NS_YYCC_CLAP_TYPES::ClapResult get_raw_value_option(NS_YYCC_CLAP_TYPES::Token token) const; public: + /** + * @brief Checks if an option with the given token was provided in the command line. + * @param[in] token The token identifying the option + * @remark + * Do not use this function for checking whether some options are specified. + * Please use get_flag_option or get_value_option instead. + * Because this function can not distinguish flag option and value option. + * This function onlt suit for user defined check, + * for example, checking the constraint between some options. + * @return true if the option was provided, false otherwise + */ bool has_option(NS_YYCC_CLAP_TYPES::Token token) const; + /** + * @brief Get the capture status of flag options. + * @param[in] token The token identifying the option + * @return A ClapResult containing either the boolean value + * representing whether user specify it or an error + * @exception std::logic_error Get value option as flag option. + */ NS_YYCC_CLAP_TYPES::ClapResult get_flag_option(NS_YYCC_CLAP_TYPES::Token token) const; + /** + * @brief Get the capture status of value options. + * @tparam T The validator of this value. + * @param[in] token The token identifying the option. + * @param[in] validator The validator instance for checking or leave blank for default. + * @return A ClapResult containing either the converted user input value or an error + * @exception std::logic_error Get flag option as value option. + */ template NS_YYCC_CLAP_TYPES::ClapResult> get_value_option(NS_YYCC_CLAP_TYPES::Token token, const T& validator = T{}) const { diff --git a/src/yycc/carton/clap/resolver.hpp b/src/yycc/carton/clap/resolver.hpp index b3a8987..5461604 100644 --- a/src/yycc/carton/clap/resolver.hpp +++ b/src/yycc/carton/clap/resolver.hpp @@ -16,6 +16,7 @@ namespace yycc::carton::clap::resolver { + /// @brief Resolves environment variables and provides access to resolved values. class Resolver { private: /** @@ -27,8 +28,19 @@ namespace yycc::carton::clap::resolver { std::map> values; public: + /** + * @brief Creates a Resolver from user-provided environment variables. + * @param[in] app The application to resolve variables for + * @param[in] vars Vector of key-value pairs representing environment variables + * @return A ClapResult containing either a Resolver object or an error + */ static NS_YYCC_CLAP_TYPES::ClapResult from_user( const NS_YYCC_CLAP_APPLICATION::Application& app, const std::vector>& vars); + /** + * @brief Creates a Resolver from system environment variables. + * @param[in] app The application to resolve variables for + * @return A ClapResult containing either a Resolver object or an error + */ static NS_YYCC_CLAP_TYPES::ClapResult from_system(const NS_YYCC_CLAP_APPLICATION::Application& app); private: @@ -39,11 +51,42 @@ namespace yycc::carton::clap::resolver { YYCC_DEFAULT_COPY_MOVE(Resolver) private: + /** + * @brief Gets the raw value of a variable as a string view. + * @param[in] token The token identifying the variable + * @return A ClapResult containing either the raw value as a string view or an error + */ NS_YYCC_CLAP_TYPES::ClapResult get_raw_value_variable(NS_YYCC_CLAP_TYPES::Token token) const; public: + /** + * @brief Checks if a variable with the given token was provided in the environment. + * @param[in] token The token identifying the variable + * @remark + * Do not use this function for checking whether some variables are specified. + * Please use get_flag_variable or get_value_variable instead. + * Because this function can not distinguish flag variable and value variable. + * This function onlt suit for user defined check, + * for example, checking the constraint between some variables. + * @return true if the variable was provided, false otherwise + */ bool has_variable(NS_YYCC_CLAP_TYPES::Token token) const; + /** + * @brief Gets the boolean value of a flag variable. + * @param[in] token The token identifying the variable + * @return A ClapResult containing either the boolean value + * representing whether user specify it or an error + * @exception std::logic_error Get value variable as flag variable. + */ NS_YYCC_CLAP_TYPES::ClapResult get_flag_variable(NS_YYCC_CLAP_TYPES::Token token) const; + /** + * @brief Get the capture status of value variable. + * @tparam T The validator of this value. + * @param[in] token The token identifying the variable. + * @param[in] validator The validator instance for checking or leave blank for default. + * @return A ClapResult containing either the converted user input value or an error + * @exception std::logic_error Get flag variable as value variable. + */ template NS_YYCC_CLAP_TYPES::ClapResult> get_value_variable( NS_YYCC_CLAP_TYPES::Token token, const T& validator = T()) const { diff --git a/src/yycc/carton/clap/summary.hpp b/src/yycc/carton/clap/summary.hpp index 2098d9d..ffac1e8 100644 --- a/src/yycc/carton/clap/summary.hpp +++ b/src/yycc/carton/clap/summary.hpp @@ -5,8 +5,16 @@ namespace yycc::carton::clap::summary { + /// @brief Represents summary information for a command line application. class Summary { public: + /** + * @brief Constructs a new Summary object with the specified parameters. + * @param[in] name The name of the application + * @param[in] author The author of the application + * @param[in] version The version of the application + * @param[in] description A description of the application's purpose + */ Summary(const std::u8string_view& name, const std::u8string_view& author, const std::u8string_view& version, @@ -15,9 +23,25 @@ namespace yycc::carton::clap::summary { YYCC_DEFAULT_COPY_MOVE(Summary) public: + /** + * @brief Gets the name of the application. + * @return The application's name as a string view + */ std::u8string_view get_name() const; + /** + * @brief Gets the author of the application. + * @return The application's author as a string view + */ std::u8string_view get_author() const; + /** + * @brief Gets the version of the application. + * @return The application's version as a string view + */ std::u8string_view get_version() const; + /** + * @brief Gets the description of the application. + * @return The application's description as a string view + */ std::u8string_view get_description() const; private: diff --git a/src/yycc/carton/clap/variable.hpp b/src/yycc/carton/clap/variable.hpp index 0bb0282..512af02 100644 --- a/src/yycc/carton/clap/variable.hpp +++ b/src/yycc/carton/clap/variable.hpp @@ -10,56 +10,126 @@ namespace yycc::carton::clap::variable { + /// @brief Represents a command line variable that can be captured from user input. class Variable { public: + /** + * @brief Constructs a new Variable object with the specified parameters. + * @param[in] name The name of the variable + * @param[in] description A description of the variable's purpose + * @param[in] care_value Whether the variable expects a value or not + */ Variable(const std::u8string_view& name, const std::u8string_view& description, bool care_value); ~Variable(); YYCC_DEFAULT_COPY_MOVE(Variable) public: + /** + * @brief Checks if the variable cares about having a value associated with it. + * @return true if the variable expects a value, false otherwise + */ bool is_care_value() const; + /** + * @brief Gets the name of the variable. + * @return The variable's name as a u8string_view + */ std::u8string_view get_name() const; + /** + * @brief Gets the description of the variable. + * @return The variable's description as a u8string_view + */ std::u8string_view get_description() const; private: - bool care_value; - std::u8string name; - std::u8string description; + bool care_value; ///< Flag indicating whether the variable expects a value + std::u8string name; ///< The name of the variable + std::u8string description; ///< A description of the variable's purpose }; + /// @brief Represents a variable that has been registered with a token for identification. class RegisteredVariable { public: + /** + * @private + * @brief Constructs a new RegisteredVariable object with the given token and variable. + * @param[in] token The unique token associated with the variable + * @param[in] variable The variable to register + */ RegisteredVariable(NS_YYCC_CLAP_TYPES::Token token, Variable&& variable); ~RegisteredVariable(); YYCC_DEFAULT_COPY_MOVE(RegisteredVariable) public: + /** + * @brief Gets the token associated with this registered variable. + * @return The token identifying this variable + */ NS_YYCC_CLAP_TYPES::Token get_token() const; + /** + * @brief Gets the variable associated with this registration. + * @return A constant reference to the variable + */ const Variable& get_variable() const; private: - NS_YYCC_CLAP_TYPES::Token token; - Variable variable; + NS_YYCC_CLAP_TYPES::Token token; ///< The unique token identifying this variable + Variable variable; ///< The registered variable }; + /// @brief A collection of variables with methods to manage them by token or name. class VariableCollection { public: + /** + * @brief Constructs a new, empty VariableCollection object. + */ VariableCollection(); ~VariableCollection(); YYCC_DEFAULT_COPY_MOVE(VariableCollection) public: + /** + * @brief Adds a new variable to the collection and returns a token for it. + * @param[in] var The variable to add to the collection + * @return A token that uniquely identifies the added variable + */ NS_YYCC_CLAP_TYPES::Token add_variable(Variable&& var); + /** + * @brief Finds the token associated with a variable by its name. + * @param[in] name The name of the variable to find + * @return An optional token if the variable exists, std::nullopt otherwise + */ std::optional find_name(const std::u8string_view& name) const; + /** + * @brief Checks if a variable with the given token exists in the collection. + * @param[in] token The token to check for + * @return true if a variable with the token exists, false otherwise + */ bool has_variable(NS_YYCC_CLAP_TYPES::Token token) const; + /** + * @brief Gets the variable associated with the given token. + * @param[in] token The token identifying the variable + * @return A constant reference to the variable + */ const Variable& get_variable(NS_YYCC_CLAP_TYPES::Token token) const; + /** + * @brief Gets all registered variables in the collection. + * @return A constant reference to the vector of registered variables + */ const std::vector& all_variables() const; + /** + * @brief Gets the number of variables in the collection. + * @return The count of variables in the collection + */ size_t length() const; + /** + * @brief Checks if the collection is empty. + * @return true if the collection contains no variables, false otherwise + */ bool empty() const; private: - std::map names; - std::vector variables; + std::map names; ///< Map from variable names to tokens + std::vector variables; ///< Vector of registered variables }; } // namespace yycc::carton::clap::variable diff --git a/src/yycc/carton/ironpad.cpp b/src/yycc/carton/ironpad.cpp index f825a0b..77a4def 100644 --- a/src/yycc/carton/ironpad.cpp +++ b/src/yycc/carton/ironpad.cpp @@ -422,7 +422,8 @@ namespace yycc::carton::ironpad { IMAGEHLP_LINE64 winline; winline.SizeOfStruct = sizeof(IMAGEHLP_LINE64); if (SymGetLineFromAddr64(process, frame.AddrPC.Offset, &dwDisplacement, &winline)) { - source_file = REINTERPRET::as_utf8(winline.FileName); // TODO: check whether there is UNICODE file name. + // TODO: check whether this field is a valid UNICODE file name. + source_file = REINTERPRET::as_utf8(winline.FileName); source_file_line = winline.LineNumber; } diff --git a/src/yycc/carton/pycodec.hpp b/src/yycc/carton/pycodec.hpp index 849101a..f6ea50b 100644 --- a/src/yycc/carton/pycodec.hpp +++ b/src/yycc/carton/pycodec.hpp @@ -24,6 +24,14 @@ #error "Can not find viable encoding convertion solution in current environment for PyCodec module." #endif +/** + * @brief A module providing encoding conversion utilities between various character encodings. + * @details + * This module provides a unified interface for converting between different character encodings, + * with backend implementations that may use Iconv or Windows-specific APIs depending on the + * available features and platform. The module supports conversions between char, UTF-8, UTF-16, + * UTF-32, and wide character encodings. + */ namespace yycc::carton::pycodec { /// @brief The universal name of encoding. diff --git a/src/yycc/carton/tabulate.hpp b/src/yycc/carton/tabulate.hpp index 7c8cb3b..fae2145 100644 --- a/src/yycc/carton/tabulate.hpp +++ b/src/yycc/carton/tabulate.hpp @@ -6,6 +6,12 @@ #include #include +/** + * @brief The tabulate namespace provides utilities for creating formatted tables in console output. + * @details This namespace contains classes for managing table structure, cell data, column widths, + * and rendering tables with customizable headers, separators, and formatting options. + * It supports Unicode text (using u8string) and calculates proper column widths for correct display. + */ namespace yycc::carton::tabulate { /** @@ -100,7 +106,20 @@ namespace yycc::carton::tabulate { using Rows = std::vector; /** - * @brief Main class of Tabulate + * @brief Main class for creating and managing formatted console tables. + * @details The Tabulate class provides a complete interface for building tables with + * customizable headers, data rows, column widths, and display options. It supports + * Unicode text via u8string and handles proper column width calculation to ensure + * correct table formatting in console output. + * + * Features include: + * - Configurable column count + * - Optional header display + * - Customizable separator bars + * - Prefix string support (for indentation) + * - Automatic column width calculation + * - Unicode text support + * - Stream output with customizable destination */ class Tabulate { public: diff --git a/src/yycc/patch/stream.hpp b/src/yycc/patch/stream.hpp index 5faf09e..38ae42a 100644 --- a/src/yycc/patch/stream.hpp +++ b/src/yycc/patch/stream.hpp @@ -10,10 +10,8 @@ */ namespace yycc::patch::stream { - // TODO: replace all old way (C-style output) with this new way if possible. - std::ostream& operator<<(std::ostream& os, const std::u8string_view& u8str); std::ostream& operator<<(std::ostream& os, const char8_t* u8str); std::ostream& operator<<(std::ostream& os, char8_t u8chr); -} +} // namespace yycc::patch::stream