doc: update documentation

- rename Constrain to Constraint in code and documentation.
- remove massive annotation of encoding helper because the documentation is enough.
- fix doxygen character shift warnings.
This commit is contained in:
yyc12345 2024-07-05 22:25:14 +08:00
parent 65b81f5cfa
commit a1699f13db
5 changed files with 26 additions and 59 deletions

View File

@ -30,6 +30,6 @@ blabla();
#endif #endif
\endcode \endcode
It's enough and simple that use \c #if to bracket the Windows specified code. It's enough and simple that use \c \#if to bracket the Windows specified code.
*/ */

View File

@ -36,7 +36,7 @@ This guard can solve following issues:
Programmer will not be affected by the automatical rename of \c GetObject, \c GetClassName and etc. Programmer will not be affected by the automatical rename of \c GetObject, \c GetClassName and etc.
<UL> <UL>
<LI>These are all macros for Windows personal use to automatically redirect calling to A function and W function by compiling environment.</LI> <LI>These are all macros for Windows personal use to automatically redirect calling to A function and W function by compiling environment.</LI>
<LI>Guard \c #undef these annoy macros.</LI> <LI>Guard \c \#undef these annoy macros.</LI>
</UL> </UL>
</LI> </LI>
<LI> <LI>
@ -56,13 +56,13 @@ Because this guard operate some Windows macros as we introduced above.
The headers depending on Windows may throw error if you put them outside of this pair. The headers depending on Windows may throw error if you put them outside of this pair.
Please note WinImportPrefix.hpp and WinImportSuffix.hpp can be included multiple times. Please note WinImportPrefix.hpp and WinImportSuffix.hpp can be included multiple times.
Because they do not have the proprocessor command like <I>#pragma once</I> or etc to make sure they only can be included once. Because they do not have the proprocessor command like <I>\#pragma once</I> or etc to make sure they only can be included once.
That's by design. Because we actually may use this pair multiple times. That's by design. Because we actually may use this pair multiple times.
The only thing you should pledge is that you must make sure they are presented by pair. The only thing you should pledge is that you must make sure they are presented by pair.
This guard is Windows specific. This guard is Windows specific.
It does nothing if you accidently use it in other platforms such as Linux, It does nothing if you accidently use it in other platforms such as Linux,
because the headers use \c #if to check environment out and will do nothing in non-Windows environment. because the headers use \c \#if to check environment out and will do nothing in non-Windows environment.
However, we still highly recommend you use this pair with platform checker bracket like example does, However, we still highly recommend you use this pair with platform checker bracket like example does,
if your program need to be run on multiple platforms. if your program need to be run on multiple platforms.

View File

@ -13,7 +13,7 @@
namespace YYCC::ConfigManager { namespace YYCC::ConfigManager {
template<typename _Ty> template<typename _Ty>
struct Constrain { struct Constraint {
using CheckFct_t = std::function<bool(const _Ty&)>; using CheckFct_t = std::function<bool(const _Ty&)>;
//using CorrectFct_t = std::function<_Ty(const _Ty&)>; //using CorrectFct_t = std::function<_Ty(const _Ty&)>;
CheckFct_t m_CheckFct; CheckFct_t m_CheckFct;
@ -24,13 +24,13 @@ namespace YYCC::ConfigManager {
} }
}; };
namespace ConstrainPresets { namespace ConstraintPresets {
template<typename _Ty, std::enable_if_t<std::is_arithmetic_v<_Ty> && !std::is_enum_v<_Ty> && !std::is_same_v<_Ty, bool>, int> = 0> template<typename _Ty, std::enable_if_t<std::is_arithmetic_v<_Ty> && !std::is_enum_v<_Ty> && !std::is_same_v<_Ty, bool>, int> = 0>
Constrain<_Ty> GetNumberRangeConstrain(_Ty min_value, _Ty max_value) { Constraint<_Ty> GetNumberRangeConstraint(_Ty min_value, _Ty max_value) {
if (min_value > max_value) if (min_value > max_value)
throw std::invalid_argument("invalid min max value for NumberRangeConstrain"); throw std::invalid_argument("invalid min max value for NumberRangeConstraint");
return Constrain<_Ty> { return Constraint<_Ty> {
[min_value, max_value](const _Ty& val) -> bool { return (val <= max_value) && (val >= min_value); } [min_value, max_value](const _Ty& val) -> bool { return (val <= max_value) && (val >= min_value); }
/*[min_value, max_value](const _Ty& val) -> _Ty { return std::clamp(val, min_value, max_value); }*/ /*[min_value, max_value](const _Ty& val) -> _Ty { return std::clamp(val, min_value, max_value); }*/
}; };
@ -96,14 +96,14 @@ namespace YYCC::ConfigManager {
template<typename _Ty, std::enable_if_t<std::is_arithmetic_v<_Ty> || std::is_enum_v<_Ty>, int> = 0> template<typename _Ty, std::enable_if_t<std::is_arithmetic_v<_Ty> || std::is_enum_v<_Ty>, int> = 0>
class NumberSetting : public AbstractSetting { class NumberSetting : public AbstractSetting {
public: public:
NumberSetting(const yycc_char8_t* name, _Ty default_value, Constrain<_Ty> constrain = Constrain<_Ty> {}) : NumberSetting(const yycc_char8_t* name, _Ty default_value, Constraint<_Ty> constraint = Constraint<_Ty> {}) :
AbstractSetting(name), m_Data(default_value), m_DefaultData(default_value), m_Constrain(constrain) {} AbstractSetting(name), m_Data(default_value), m_DefaultData(default_value), m_Constraint(constraint) {}
virtual ~NumberSetting() {} virtual ~NumberSetting() {}
_Ty Get() const { return m_Data; } _Ty Get() const { return m_Data; }
bool Set(_Ty new_data) { bool Set(_Ty new_data) {
// validate data // validate data
if (m_Constrain.IsValid() && !m_Constrain.m_CheckFct(new_data)) if (m_Constraint.IsValid() && !m_Constraint.m_CheckFct(new_data))
return false; return false;
// assign data // assign data
m_Data = new_data; m_Data = new_data;
@ -117,7 +117,7 @@ namespace YYCC::ConfigManager {
return false; return false;
m_Data = *reinterpret_cast<const _Ty*>(GetDataPtr()); m_Data = *reinterpret_cast<const _Ty*>(GetDataPtr());
// check data // check data
if (m_Constrain.IsValid() && !m_Constrain.m_CheckFct(m_Data)) if (m_Constraint.IsValid() && !m_Constraint.m_CheckFct(m_Data))
return false; return false;
return true; return true;
} }
@ -132,13 +132,13 @@ namespace YYCC::ConfigManager {
} }
_Ty m_Data, m_DefaultData; _Ty m_Data, m_DefaultData;
Constrain<_Ty> m_Constrain; Constraint<_Ty> m_Constraint;
}; };
class StringSetting : public AbstractSetting { class StringSetting : public AbstractSetting {
public: public:
StringSetting(const yycc_char8_t* name, const yycc_char8_t* default_value, Constrain<yycc_u8string> constrain = Constrain<yycc_u8string> {}) : StringSetting(const yycc_char8_t* name, const yycc_char8_t* default_value, Constraint<yycc_u8string> constraint = Constraint<yycc_u8string> {}) :
AbstractSetting(name), m_Data(), m_DefaultData(), m_Constrain(constrain) { AbstractSetting(name), m_Data(), m_DefaultData(), m_Constraint(constraint) {
if (default_value != nullptr) { if (default_value != nullptr) {
m_Data = default_value; m_Data = default_value;
m_DefaultData = default_value; m_DefaultData = default_value;
@ -151,7 +151,7 @@ namespace YYCC::ConfigManager {
// check data validation // check data validation
if (new_data == nullptr) if (new_data == nullptr)
return false; return false;
if (m_Constrain.IsValid() && !m_Constrain.m_CheckFct(m_Data)) if (m_Constraint.IsValid() && !m_Constraint.m_CheckFct(m_Data))
return false; return false;
// assign data // assign data
m_Data = new_data; m_Data = new_data;
@ -173,7 +173,7 @@ namespace YYCC::ConfigManager {
string_length string_length
); );
// check data // check data
if (m_Constrain.IsValid() && !m_Constrain.m_CheckFct(m_Data)) if (m_Constraint.IsValid() && !m_Constraint.m_CheckFct(m_Data))
return false; return false;
return true; return true;
} }
@ -194,7 +194,7 @@ namespace YYCC::ConfigManager {
} }
yycc_u8string m_Data, m_DefaultData; yycc_u8string m_Data, m_DefaultData;
Constrain<yycc_u8string> m_Constrain; Constraint<yycc_u8string> m_Constraint;
}; };
#pragma endregion #pragma endregion

View File

@ -10,48 +10,15 @@
#endif #endif
/** /**
* @brief The namespace handling encoding issues. * @brief The helper for all encoding aspects.
* @details * @details
* \par Windows Encoding Convertion * For more infomations about how to use the functions provided by this namespace,
* This namespace provides the convertion between wchar_t, UTF8 and code-page-based string: * please see \ref library_encoding and \ref encoding_helper.
* The function name has following format: \c AAAToBBB.
* AAA is the source string and BBB is target string.
* AAA and BBB has following possible value:
* \li \c Char: Code-page-based string. Usually it will add a code page parameter for function to get the code page of this string. For code page, please see Microsoft document.
* \li \c UTF8: UTF8 string.
* \li \c Wchar: wchar_t string.
* \par
* For example: \c WcharToUTF8 will perform the convertion from wchar_t to UTF8,
* and \c CharToChar will perform the convertion between 2 code-page-based string and caller can specify individual code page for these 2 string.
* \par
* These functions are Windows specific and are unavailable on other platforms.
* Becasue Windows use wchar_t string as its function arguments for globalization, and this library use UTF8 everywhere.
* So it should have a bidirectional way to do convertion between wchar_t string and UTF8 string.
*
* \par UTF32, UTF16 and UTF8 Convertion
* This namespace also provide the convertion among UTF32, UTF16 and UTF8.
* These convertion functions are suit for all platforms, not Windows oriented.
* \par
* Due to implementation, this library assume all non-Windows system use UTF8 as their C locale.
* Otherwise these functions will produce wrong result.
*
* \par Function Parameters
* We provide these encoding convertion functions with following 2 types:
* \li Function returns \c bool and its parameter order source string pointer and a corresponding \c std::basic_string container for receiving result.
* \li Function returns corresponding \c std::basic_string result, and its parameter only order source string pointer.
* \par
* For these 2 declarations, both of them will not throw any exception and do not accept nullptr as source string.
* The only difference is that the way to indicate convertion error.
* \par
* First declaration will return false to indicate there is an error when doing convertion. Please note that the content of string container passing in may still be changed!
* Last declaration will return empty string to indicate error. Please note if you pass empty string in, they still will output empty string but it doesn't mean an error.
* So last declaration is used in the scenario that we don't care whether the convertion success did. For example, output something to console.
*
*/ */
namespace YYCC::EncodingHelper { namespace YYCC::EncodingHelper {
#define _YYCC_U8(strl) u8 ## strl #define _YYCC_U8(strl) u8 ## strl ///< The assistant macro for YYCC_U8.
#define YYCC_U8(strl) (reinterpret_cast<const ::YYCC::yycc_char8_t*>(_YYCC_U8(strl))) #define YYCC_U8(strl) (reinterpret_cast<const ::YYCC::yycc_char8_t*>(_YYCC_U8(strl))) ///< The macro for creating UTF8 string literal. See \ref library_encoding.
const yycc_char8_t* ToUTF8(const char* src); const yycc_char8_t* ToUTF8(const char* src);
yycc_char8_t* ToUTF8(char* src); yycc_char8_t* ToUTF8(char* src);

View File

@ -401,7 +401,7 @@ namespace YYCCTestbench {
m_FloatSetting(YYCC_U8("float-setting"), 0.0f), m_FloatSetting(YYCC_U8("float-setting"), 0.0f),
m_StringSetting(YYCC_U8("string-setting"), YYCC_U8("")), m_StringSetting(YYCC_U8("string-setting"), YYCC_U8("")),
m_BoolSetting(YYCC_U8("bool-setting"), false), m_BoolSetting(YYCC_U8("bool-setting"), false),
m_ClampedFloatSetting(YYCC_U8("clamped-float-setting"), 0.0f, YYCC::ConfigManager::ConstrainPresets::GetNumberRangeConstrain<float>(-1.0f, 1.0f)), m_ClampedFloatSetting(YYCC_U8("clamped-float-setting"), 0.0f, YYCC::ConfigManager::ConstraintPresets::GetNumberRangeConstraint<float>(-1.0f, 1.0f)),
m_EnumSetting(YYCC_U8("enum-setting"), TestEnum::Test1), m_EnumSetting(YYCC_U8("enum-setting"), TestEnum::Test1),
m_CoreManager(YYCC_U8("test.cfg"), UINT64_C(0), { m_CoreManager(YYCC_U8("test.cfg"), UINT64_C(0), {
&m_IntSetting, &m_FloatSetting, &m_StringSetting, &m_BoolSetting, &m_ClampedFloatSetting, &m_EnumSetting &m_IntSetting, &m_FloatSetting, &m_StringSetting, &m_BoolSetting, &m_ClampedFloatSetting, &m_EnumSetting
@ -436,7 +436,7 @@ namespace YYCCTestbench {
// init cfg manager // init cfg manager
TestConfigManager test; TestConfigManager test;
// test constrain works // test constraint works
Assert(!test.m_ClampedFloatSetting.Set(2.0f), YYCC_U8("YYCC::ConfigManager::Constraint")); Assert(!test.m_ClampedFloatSetting.Set(2.0f), YYCC_U8("YYCC::ConfigManager::Constraint"));
Assert(test.m_ClampedFloatSetting.Get() == 0.0f, YYCC_U8("YYCC::ConfigManager::Constraint")); Assert(test.m_ClampedFloatSetting.Get() == 0.0f, YYCC_U8("YYCC::ConfigManager::Constraint"));