doc: update documentation

This commit is contained in:
yyc12345 2024-07-30 22:13:59 +08:00
parent e167479de3
commit 656495f22e
5 changed files with 112 additions and 29 deletions

View File

@ -1,8 +1,9 @@
namespace YYCC::ArgParser {
/**
\page arg_parser Universal Argument Parser
Universal argument parser provides an universal way to parsing command line arguments.
YYCC::ArgParser provides an universal way to parsing command line arguments.
Universal argument parser has similar design with universal config manager,
it is highly recommand that read \ref config_manager chapter first,
@ -11,6 +12,54 @@ because you will have a clear understanding of this namespace after reading univ
There is an example about how to use universal argument parser.
In following content, we will describe it in detail.
\code{.cpp}
class TestArgParser {
public:
TestArgParser() :
m_IntArgument(YYCC_U8("int"), YYCC_U8_CHAR('i'), YYCC_U8("integral argument"), YYCC_U8("114514")),
m_FloatArgument(nullptr, YYCC_U8_CHAR('f'), nullptr, nullptr, true),
m_StringArgument(YYCC_U8("string"), YYCC::ArgParser::AbstractArgument::NO_SHORT_NAME, nullptr, nullptr, true),
m_BoolArgument(nullptr, YYCC_U8_CHAR('b'), nullptr),
m_ClampedFloatArgument(YYCC_U8("clamped-float"), YYCC::ArgParser::AbstractArgument::NO_SHORT_NAME, nullptr, nullptr, true, YYCC::Constraints::GetMinMaxRangeConstraint<float>(-1.0f, 1.0f)),
m_OptionContext(YYCC_U8("TestArgParser"), YYCC_U8("This is the testbench of argument parser."), {
&m_IntArgument, &m_FloatArgument, &m_StringArgument,
&m_BoolArgument, &m_ClampedFloatArgument
}) {}
~TestArgParser() {}
YYCC::ArgParser::NumberArgument<int32_t> m_IntArgument;
YYCC::ArgParser::NumberArgument<float> m_FloatArgument;
YYCC::ArgParser::StringArgument m_StringArgument;
YYCC::ArgParser::SwitchArgument m_BoolArgument;
YYCC::ArgParser::NumberArgument<float> m_ClampedFloatArgument;
YYCC::ArgParser::OptionContext m_OptionContext;
};
// Initialize argument parser.
TestArgParser test;
// Get argument list for parsing from standard C main function.
auto al = YYCC::ArgParser::ArgumentList::CreateFromStd(argc, argv);
// Start parsing
test.Parse(al);
// Get captured string argument
if (test.m_StringArgument.IsCaptured())
auto val = test.m_StringArgument.Get();
\endcode
These code can resolve following command line
\code{.sh}
exec -i 114514 -f 2.0 --string fuck -b --clamped-float 0.5
\endcode
For convenience, we define following terms used in this article.
\li Every items in command line: Argument.
\li \c -i, \c --clamped-float: \b Switch / \b Option. the argument starts with dash or double dash.
\li \c 114514: \b Value. the value of switch.
\section arg_parser__argument Argument
\subsection arg_parser__argument__presets Argument Presets
@ -35,6 +84,18 @@ It can not hold any value.
\section arg_parser__option_context Option Context
Please note any unknow argument will let the parser return false.
This is different with other argument parsers.
In other common argument parsers,
they will collect all unknow argument ad positional argument,
or just simply ignore them.
OptionContext also will not add \c -h or \c --help switch automatically.
This is also differnent with other parsers.
You should manually add it.
However, OptionContext provide a universal help print function.
You can directly call it to output help text if you needed (fail to parse or user order help).
\section arg_parser__limitation Limitation
This universal argument parser is a tiny parser.
@ -44,7 +105,7 @@ In following content I will tell you some syntaxes which this parser \b not acce
\subsection arg_parser__limitation__flag_combination Flag Combination
\code{sh}
\code{.sh}
exec -l -s -h
exec -lsh
\endcode
@ -54,7 +115,7 @@ You must write these flags independently.
\subsection arg_parser__limitation__equal_symbol Equal Symbol
\code
\code{.sh}
exec --value 114514
exec --value=114514
exec --value:114514
@ -66,7 +127,7 @@ You must write value after the argument immediately please.
\subsection arg_parser__limitation__variable_argument Variable Argument
\code
\code{.sh}
exec -DSOME_VARABLE=SOME_VALUE
exec -D SOME_VARIABLE=SOME_VALUE
\endcode
@ -74,4 +135,22 @@ exec -D SOME_VARIABLE=SOME_VALUE
Parser only accept second line.
However you nned to write a custom argument or constraint to holding this value.
*/
\subsection arg_parser__limitation__switch_dependency Switch Dependency
\code{.sh}
exec --action-a --action-b
\endcode
For command line written above,
if you hope \c --action-a and \c --action-b is exclusive,
or \c --action-b only be valid if \c --action-a specified,
you should manually implement this.
Parser don't have such features to process this switch dependency.
The thing you need to do is set these switches are \b not optional.
And after parser do a success parsing,
manually calling AbstractArgument::IsCaptured to fetch whether corresponding switches are captured,
then do your personal dependency check.
*/
}

View File

@ -1,8 +1,9 @@
namespace YYCC::ConfigManager {
/**
\page config_manager Universal Config Manager
Universal config manager give programmer an universal way to manage its program settings.
YYCC::ConfigManager give programmer an universal way to manage its program settings.
There is an example about how to use universal config manager.
In following content, we will describe it in detail.
@ -32,11 +33,11 @@ public:
YYCC::ConfigManager::CoreManager m_CoreManager;
};
// init cfg manager
// Initialize config manager
TestConfigManager test;
// load string
// Load settings.
test.m_CoreManager.Load()
// get string value
// Get string setting value.
auto val = test.m_StringSetting.Get();
\endcode
@ -49,9 +50,9 @@ Each setting describe a single configuration entry.
We currently provide 2 setting preset classes which you can directly use.
\li YYCC::ConfigManager::NumberSetting: The setting storing a number inside.
\li NumberSetting: The setting storing a number inside.
It is a template class. Support all arithmetic and enum types (integral, floating point, bool, enum).
\li YYCC::ConfigManager::StringSetting: The setting storing a string inside.
\li StringSetting: The setting storing a string inside.
When constructing these settings,
you need to provide its unique name which will be used when saving to file or reading from file.
@ -67,13 +68,13 @@ See \ref constraints chapters to know how we provide constraints.
In most cases, the combination use of setting presets and constraints is enough.
However, if you still are urge to create your personal setting,
please inherit YYCC::ConfigManager::AbstractSetting and implement essential class functions.
please inherit AbstractSetting and implement essential class functions.
For the class functions you need to implement,
please refer to our setting presets, YYCC::ConfigManager::NumberSetting and YYCC::ConfigManager::StringSetting.
please refer to our setting presets, NumberSetting and StringSetting.
\section config_manager__core_manager Core Manager
YYCC::ConfigManager::CoreManager manage a collection of settings.
CoreManager manage a collection of settings.
And have responsibility to reading and writing config file.
We highly suggest that you create a personal config manager class like example does.
@ -92,4 +93,5 @@ Core manager will reject reading and use default value for all settings.
Otherwise, core manager will try to read config file and do proper migration if possible.
The last argument is an initializer list which contain the \b pointer to all settings this manager managed.
*/
*/
}

View File

@ -1,8 +1,9 @@
namespace YYCC::Constraints {
/**
\page constraints Constraints
YYCC::Constraints namespace provide YYCC::Constraints::Constraint struct declaration
YYCC::Constraints namespace provide Constraint struct declaration
and various common constraint generator function.
This namespace is specifically used by YYCC::ConfigManager and YYCC::ArgParser namespaces.
@ -10,12 +11,12 @@ See \ref config_manager chapter and \ref arg_parser chapter for how to utlize th
\section constraints__prototype Prototype
YYCC::Constraints::Constraint instruct library how check whether given value is in range,
Constraint instruct library how check whether given value is in range,
and how to clamp it if it is invalid.
For example, you can use constraint to limit a number in given minimum maximum value,
or limit a string in specific format by using regex and etc.
YYCC::Constraints::Constraint is a template struct.
Constraint is a template struct.
The argument of template is the underlying data type which need to be checked.
The struct with different template argument is not compatible.
@ -25,23 +26,24 @@ which is used for detecting whether given value is in range / valid.
\subsection constraints__presets Constraint Presets
YYCC::Constraints provides some constraint presets which are commonly used.
All functions inside this namespace will return a YYCC::Constraints::Constraint instance,
All functions inside this namespace will return a Constraint instance,
and you can directly use it.
There is a list of all provided functions:
\li YYCC::Constraints::GetMinMaxRangeConstraint: Limit the number value in given minimum maximum value range (inclusive).
\li YYCC::Constraints::GetEnumEnumerationConstraint: Limit the enum value by given all possible value set.
\li YYCC::Constraints::GetStringEnumerationConstraint: Limit the string by given all possible value set.
\li GetMinMaxRangeConstraint(): Limit the number value in given minimum maximum value range (inclusive).
\li GetEnumEnumerationConstraint(): Limit the enum value by given all possible value set.
\li GetStringEnumerationConstraint(): Limit the string by given all possible value set.
\subsection config_manager__constraint__custom Custom Constraint
For creating your personal constraint,
you need to create YYCC::Constraints::Constraint instance manually.
you need to create Constraint instance manually.
You can browse all existing constraint preset functions code for know how to write it.
The things you need to do is simple.
First, you need decide the template argument of YYCC::Constraints::Constraint.
Second, you need assign class member of YYCC::Constraints::Constraint by C++ lambda syntax.
First, you need decide the template argument of Constraint.
Second, you need assign class member of Constraint by C++ lambda syntax.
*/
*/
}

View File

@ -29,12 +29,12 @@ 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.
It mean that one emoji charcater will be torn into 2 \c WCHAR on Windows because emoji code unit is higher than the maximum 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.
You need to define some weird macros 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.

View File

@ -14,7 +14,7 @@ namespace YYCC::Constraints {
/**
* @brief The constraint applied to settings to limit its stored value.
* @tparam _Ty The internal data type stroed in corresponding setting.
* @tparam _Ty The data type this constraint need to be processed with.
*/
template<typename _Ty>
struct Constraint {