• R/O
  • SSH

YSLib: Commit

The YSLib project - main repository


Commit MetaInfo

Revisión74e1025f0a02da2590b2578c8adad8008f60d581 (tree)
Tiempo2024-04-19 23:42:25
AutorFrankHB <frankhb1989@gmai...>
CommiterFrankHB

Log Message

更新主分支版本: build 983 rev 10 。

Cambiar Resumen

    Diferencia incremental

    diff -r 3fe9fa0c6127 -r 74e1025f0a02 YBase/YBase.vcxproj
    --- a/YBase/YBase.vcxproj Tue Feb 27 00:28:20 2024 +0800
    +++ b/YBase/YBase.vcxproj Fri Apr 19 22:42:25 2024 +0800
    @@ -17,6 +17,7 @@
    1717 <ClInclude Include="include\libdefect\cmath.h" />
    1818 <ClInclude Include="include\libdefect\cstdio.h" />
    1919 <ClInclude Include="include\libdefect\exception.h" />
    20+ <ClInclude Include="include\libdefect\limits.hpp" />
    2021 <ClInclude Include="include\libdefect\string.h" />
    2122 <ClInclude Include="include\stdinc.h" />
    2223 <ClInclude Include="include\ydef.h" />
    @@ -26,6 +27,7 @@
    2627 <ClInclude Include="include\ystdex\any.h" />
    2728 <ClInclude Include="include\ystdex\any_iterator.hpp" />
    2829 <ClInclude Include="include\ystdex\apply.hpp" />
    30+ <ClInclude Include="include\ystdex\arithmetic.hpp" />
    2931 <ClInclude Include="include\ystdex\array.hpp" />
    3032 <ClInclude Include="include\ystdex\base.h" />
    3133 <ClInclude Include="include\ystdex\bind.hpp" />
    @@ -35,6 +37,8 @@
    3537 <ClInclude Include="include\ystdex\cassert.h" />
    3638 <ClInclude Include="include\ystdex\cast.hpp" />
    3739 <ClInclude Include="include\ystdex\cctype.h" />
    40+ <ClInclude Include="include\ystdex\charconv.h" />
    41+ <ClInclude Include="include\ystdex\chrono.hpp" />
    3842 <ClInclude Include="include\ystdex\compose.hpp" />
    3943 <ClInclude Include="include\ystdex\compressed_pair.hpp" />
    4044 <ClInclude Include="include\ystdex\concurrency.h" />
    @@ -68,6 +72,7 @@
    6872 <ClInclude Include="include\ystdex\iterator.hpp" />
    6973 <ClInclude Include="include\ystdex\iterator_op.hpp" />
    7074 <ClInclude Include="include\ystdex\iterator_trait.hpp" />
    75+ <ClInclude Include="include\ystdex\limits.hpp" />
    7176 <ClInclude Include="include\ystdex\list.hpp" />
    7277 <ClInclude Include="include\ystdex\map.hpp" />
    7378 <ClInclude Include="include\ystdex\memory.hpp" />
    diff -r 3fe9fa0c6127 -r 74e1025f0a02 YBase/YBase.vcxproj.filters
    --- a/YBase/YBase.vcxproj.filters Tue Feb 27 00:28:20 2024 +0800
    +++ b/YBase/YBase.vcxproj.filters Fri Apr 19 22:42:25 2024 +0800
    @@ -320,6 +320,21 @@
    320320 <ClInclude Include="include\ystdex\flat_set.hpp">
    321321 <Filter>include\ystdex</Filter>
    322322 </ClInclude>
    323+ <ClInclude Include="include\ystdex\chrono.hpp">
    324+ <Filter>include\ystdex</Filter>
    325+ </ClInclude>
    326+ <ClInclude Include="include\libdefect\limits.hpp">
    327+ <Filter>include\libdefect</Filter>
    328+ </ClInclude>
    329+ <ClInclude Include="include\ystdex\limits.hpp">
    330+ <Filter>include\ystdex</Filter>
    331+ </ClInclude>
    332+ <ClInclude Include="include\ystdex\arithmetic.hpp">
    333+ <Filter>include\ystdex</Filter>
    334+ </ClInclude>
    335+ <ClInclude Include="include\ystdex\charconv.h">
    336+ <Filter>include\ystdex</Filter>
    337+ </ClInclude>
    323338 </ItemGroup>
    324339 <ItemGroup>
    325340 <ClCompile Include="source\ystdex\cstdio.cpp">
    diff -r 3fe9fa0c6127 -r 74e1025f0a02 YBase/include/libdefect/limits.hpp
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/YBase/include/libdefect/limits.hpp Fri Apr 19 22:42:25 2024 +0800
    @@ -0,0 +1,236 @@
    1+/*
    2+ © 2024 FrankHB.
    3+
    4+ This file is part of the YSLib project, and may only be used, modified,
    5+ and distributed under the terms of the YSLib project license.
    6+ By continuing to use, modify, or distribute this file you indicate that
    7+ you have read the license and understand and accept it fully.
    8+*/
    9+
    10+/*! \file limits.hpp
    11+\ingroup LibDefect
    12+\brief 标准库实现 \c \<limits> 修正。
    13+\version r235
    14+\author FrankHB <frankhb1989@gmail.com>
    15+\since build 983
    16+\par 创建时间:
    17+ 2024-04-06 13:26:40 +0800
    18+\par 修改时间:
    19+ 2024-04-06 15:05 +0800
    20+\par 文本编码:
    21+ UTF-8
    22+\par 模块名称:
    23+ LibDefect::Limits
    24+*/
    25+
    26+
    27+#ifndef YB_INC_libdefect_limits_hpp_
    28+#define YB_INC_libdefect_limits_hpp_ 1
    29+
    30+#include <limits>
    31+
    32+// See See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96042.
    33+// NOTE: Fixed @ 10.3.
    34+
    35+// NOTE: See https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_macros.html.
    36+#if defined __GLIBCXX__ && (__GLIBCXX__ < 20200819 || _GLIBCXX_RELEASE < 10)
    37+
    38+namespace std _GLIBCXX_VISIBILITY(default)
    39+{
    40+
    41+#if defined __STRICT_ANSI__ && defined __SIZEOF_INT128__
    42+__extension__
    43+template<>
    44+struct numeric_limits<__int128>
    45+{
    46+ static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true;
    47+
    48+ static _GLIBCXX_CONSTEXPR __int128
    49+ min() _GLIBCXX_USE_NOEXCEPT
    50+ {
    51+ // XXX: Assume this uses a 2's complement representation.
    52+ return -((__int128(1) << 126) - 1 << 1) - 2;
    53+ }
    54+
    55+ static _GLIBCXX_CONSTEXPR __int128
    56+ max() _GLIBCXX_USE_NOEXCEPT
    57+ {
    58+ return ((__int128(1) << 126) - 1 << 1) + 1;
    59+ }
    60+
    61+#if __cplusplus >= 201103L
    62+ static constexpr __int128
    63+ lowest() noexcept
    64+ {
    65+ return min();
    66+ }
    67+#endif
    68+
    69+ static _GLIBCXX_USE_CONSTEXPR int digits = 127;
    70+ static _GLIBCXX_USE_CONSTEXPR int digits10 = 127 * 643L / 2136;
    71+#if __cplusplus >= 201103L
    72+ static constexpr int max_digits10 = 0;
    73+#endif
    74+ static _GLIBCXX_USE_CONSTEXPR bool is_signed = true;
    75+ static _GLIBCXX_USE_CONSTEXPR bool is_integer = true;
    76+ static _GLIBCXX_USE_CONSTEXPR bool is_exact = true;
    77+ static _GLIBCXX_USE_CONSTEXPR int radix = 2;
    78+
    79+ static _GLIBCXX_CONSTEXPR __int128
    80+ epsilon() _GLIBCXX_USE_NOEXCEPT
    81+ {
    82+ return 0;
    83+ }
    84+
    85+ static _GLIBCXX_CONSTEXPR __int128
    86+ round_error() _GLIBCXX_USE_NOEXCEPT
    87+ {
    88+ return 0;
    89+ }
    90+
    91+ static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0;
    92+ static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0;
    93+ static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0;
    94+ static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0;
    95+
    96+ static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false;
    97+ static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false;
    98+ static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false;
    99+ static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
    100+ static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false;
    101+
    102+ static _GLIBCXX_CONSTEXPR __int128
    103+ infinity() _GLIBCXX_USE_NOEXCEPT
    104+ {
    105+ return static_cast<__int128>(0);
    106+ }
    107+
    108+ static _GLIBCXX_CONSTEXPR __int128
    109+ quiet_NaN() _GLIBCXX_USE_NOEXCEPT
    110+ {
    111+ return static_cast<__int128>(0);
    112+ }
    113+
    114+ static _GLIBCXX_CONSTEXPR __int128
    115+ signaling_NaN() _GLIBCXX_USE_NOEXCEPT
    116+ {
    117+ return static_cast<__int128>(0);
    118+ }
    119+
    120+ static _GLIBCXX_CONSTEXPR __int128
    121+ denorm_min() _GLIBCXX_USE_NOEXCEPT
    122+ {
    123+ return static_cast<__int128>(0);
    124+ }
    125+
    126+ static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false;
    127+ static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;
    128+ static _GLIBCXX_USE_CONSTEXPR bool is_modulo = false;
    129+
    130+ static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_integral_traps;
    131+ static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false;
    132+ static _GLIBCXX_USE_CONSTEXPR float_round_style round_style
    133+ = round_toward_zero;
    134+};
    135+
    136+__extension__
    137+template<>
    138+struct numeric_limits<unsigned __int128>
    139+{
    140+ static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true;
    141+
    142+ static _GLIBCXX_CONSTEXPR unsigned __int128
    143+ min() _GLIBCXX_USE_NOEXCEPT
    144+ {
    145+ return 0;
    146+ }
    147+
    148+ static _GLIBCXX_CONSTEXPR unsigned __int128
    149+ max() _GLIBCXX_USE_NOEXCEPT
    150+ {
    151+ return ~static_cast<unsigned __int128>(0);
    152+ }
    153+
    154+#if __cplusplus >= 201103L
    155+ static constexpr unsigned __int128
    156+ lowest() noexcept
    157+ {
    158+ return min();
    159+ }
    160+
    161+#endif
    162+ static _GLIBCXX_USE_CONSTEXPR int digits = 128;
    163+ static _GLIBCXX_USE_CONSTEXPR int digits10 = 128 * 643L / 2136;
    164+#if __cplusplus >= 201103L
    165+ static constexpr int max_digits10 = 0;
    166+#endif
    167+ static _GLIBCXX_USE_CONSTEXPR bool is_signed = false;
    168+ static _GLIBCXX_USE_CONSTEXPR bool is_integer = true;
    169+ static _GLIBCXX_USE_CONSTEXPR bool is_exact = true;
    170+ static _GLIBCXX_USE_CONSTEXPR int radix = 2;
    171+
    172+ static _GLIBCXX_CONSTEXPR unsigned __int128
    173+ epsilon() _GLIBCXX_USE_NOEXCEPT
    174+ {
    175+ return 0;
    176+ }
    177+
    178+ static _GLIBCXX_CONSTEXPR unsigned __int128
    179+ round_error() _GLIBCXX_USE_NOEXCEPT
    180+ {
    181+ return 0;
    182+ }
    183+
    184+ static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0;
    185+ static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0;
    186+ static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0;
    187+ static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0;
    188+
    189+ static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false;
    190+ static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false;
    191+ static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false;
    192+ static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm
    193+ = denorm_absent;
    194+ static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false;
    195+
    196+ static _GLIBCXX_CONSTEXPR unsigned __int128
    197+ infinity() _GLIBCXX_USE_NOEXCEPT
    198+ {
    199+ return static_cast<unsigned __int128>(0);
    200+ }
    201+
    202+ static _GLIBCXX_CONSTEXPR unsigned __int128
    203+ quiet_NaN() _GLIBCXX_USE_NOEXCEPT
    204+ {
    205+ return static_cast<unsigned __int128>(0);
    206+ }
    207+
    208+ static _GLIBCXX_CONSTEXPR unsigned __int128
    209+ signaling_NaN() _GLIBCXX_USE_NOEXCEPT
    210+ {
    211+ return static_cast<unsigned __int128>(0);
    212+ }
    213+
    214+ static _GLIBCXX_CONSTEXPR unsigned __int128
    215+ denorm_min() _GLIBCXX_USE_NOEXCEPT
    216+ {
    217+ return static_cast<unsigned __int128>(0);
    218+ }
    219+
    220+ static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false;
    221+ static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;
    222+ static _GLIBCXX_USE_CONSTEXPR bool is_modulo = true;
    223+
    224+ static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_integral_traps;
    225+ static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false;
    226+ static _GLIBCXX_USE_CONSTEXPR float_round_style round_style
    227+ = round_toward_zero;
    228+};
    229+#endif
    230+
    231+} // namespace std;
    232+
    233+#endif
    234+
    235+#endif
    236+
    diff -r 3fe9fa0c6127 -r 74e1025f0a02 YBase/include/ydef.h
    --- a/YBase/include/ydef.h Tue Feb 27 00:28:20 2024 +0800
    +++ b/YBase/include/ydef.h Fri Apr 19 22:42:25 2024 +0800
    @@ -1,5 +1,5 @@
    11 /*
    2- © 2009-2023 FrankHB.
    2+ © 2009-2024 FrankHB.
    33
    44 This file is part of the YSLib project, and may only be used, modified,
    55 and distributed under the terms of the YSLib project license.
    @@ -18,13 +18,13 @@
    1818 /*! \file ydef.h
    1919 \ingroup YBase
    2020 \brief 语言实现和系统环境相关特性及公用类型和宏的基础定义。
    21-\version r4589
    21+\version r4704
    2222 \author FrankHB <frankhb1989@gmail.com>
    2323 \since 早于 build 132
    2424 \par 创建时间:
    2525 2009-12-02 21:42:44 +0800
    2626 \par 修改时间:
    27- 2023-05-27 20:26 +0800
    27+ 2024-04-05 23:51 +0800
    2828 \par 文本编码:
    2929 UTF-8
    3030 \par 模块名称:
    @@ -152,6 +152,14 @@
    152152 # define _SILENCE_CXX23_ALIGNED_UNION_DEPRECATION_WARNING
    153153 # endif
    154154 #endif
    155+
    156+#if YB_IMPL_MSCPP >= 1937
    157+// NOTE: See https://github.com/microsoft/STL/commit/522149cff1132b1bf70bee38ca5edbe4d7ce11a5.
    158+//! \since bulid 980
    159+# ifndef _SILENCE_CXX23_DENORM_DEPRECATION_WARNING
    160+# define _SILENCE_CXX23_DENORM_DEPRECATION_WARNING
    161+# endif
    162+#endif
    155163 //!@}
    156164
    157165 /*!
    @@ -161,7 +169,7 @@
    161169 //!@{
    162170 /*!
    163171 \note 检测的属性不是标准属性。
    164-\see http://clang.llvm.org/docs/LanguageExtensions.html#has-attribute 。
    172+\see https://clang.llvm.org/docs/LanguageExtensions.html#has-attribute 。
    165173 \see https://github.com/cplusplus/nbballot/issues/128 。
    166174 \since build 628
    167175 */
    @@ -170,7 +178,7 @@
    170178 #endif
    171179
    172180 /*!
    173-\see http://clang.llvm.org/docs/LanguageExtensions.html#has-builtin 。
    181+\see https://clang.llvm.org/docs/LanguageExtensions.html#has-builtin 。
    174182 \see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66970 。
    175183 \since build 535
    176184 */
    @@ -179,7 +187,15 @@
    179187 #endif
    180188
    181189 /*!
    182-\see http://clang.llvm.org/docs/LanguageExtensions.html#has-cpp-attribute 。
    190+\see https://clang.llvm.org/docs/LanguageExtensions.html#feature-checking-macros 。
    191+\since build 983
    192+*/
    193+#ifndef __has_constepxr_builtin
    194+# define __has_constepxr_builtin(...) 0
    195+#endif
    196+
    197+/*!
    198+\see https://clang.llvm.org/docs/LanguageExtensions.html#has-cpp-attribute 。
    183199 \see https://releases.llvm.org/10.0.0/tools/clang/docs/LanguageExtensions.html 。
    184200 \since build 591
    185201 */
    @@ -187,7 +203,10 @@
    187203 # define __has_cpp_attribute(...) 0
    188204 #endif
    189205
    190-//! \see http://clang.llvm.org/docs/LanguageExtensions.html#has-feature-and-has-extension 。
    206+/*!
    207+\see https://clang.llvm.org/docs/LanguageExtensions.html#has-feature-and-has-extension 。
    208+\see https://github.com/llvm/llvm-project/blob/main/clang/include/clang/Basic/Features.def 。
    209+*/
    191210 //!@{
    192211 #ifndef __has_extension
    193212 # define __has_extension(...) __has_feature(__VA_ARGS__)
    @@ -199,7 +218,7 @@
    199218 //!@}
    200219
    201220 /*!
    202-\see http://clang.llvm.org/docs/LanguageExtensions.html#has-include 。
    221+\see https://clang.llvm.org/docs/LanguageExtensions.html#has-include 。
    203222 \since build 831
    204223 */
    205224 #ifndef __has_include
    @@ -340,7 +359,7 @@
    340359 /*!
    341360 \brief 带宏替换的记号连接。
    342361 \see WG21 N4140 16.3.3[cpp.concat]/3 。
    343-\see http://gcc.gnu.org/onlinedocs/cpp/Concatenation.html 。
    362+\see https://gcc.gnu.org/onlinedocs/cpp/Concatenation.html 。
    344363 \see https://www.securecoding.cert.org/confluence/display/cplusplus/PRE05-CPP.+Understand+macro+replacement+when+concatenating+tokens+or+performing+stringification 。
    345364
    346365 注意 ISO C++ 未确定宏定义内 # 和 ## 操作符求值顺序。
    @@ -441,7 +460,7 @@
    441460 /*! \defgroup lang_impl_features Language Implementation Features
    442461 \brief 语言实现的特性。
    443462 \see https://blogs.msdn.microsoft.com/vcblog/2015/06/19/c111417-features-in-vs-2015-rtm/ 。
    444-\see http://clang.llvm.org/docs/LanguageExtensions.html 。
    463+\see https://clang.llvm.org/docs/LanguageExtensions.html 。
    445464 \since build 294
    446465 */
    447466 //!@{
    @@ -506,6 +525,34 @@
    506525
    507526
    508527 /*!
    528+\def YB_HAS_int128
    529+\brief 128 位整数类型支持。
    530+\note 对 GCC 和 Clang 可能需使用 \c __extension__ 在严格标准模式下避免警告。
    531+\see https://gcc.gnu.org/onlinedocs/gcc-4.6.0/gcc/C-Extensions.html#C-Extensions 。
    532+\see https://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html 。
    533+\since build 983
    534+*/
    535+#undef YB_HAS_int128
    536+// NOTE: This is available since GCC 4.6 for specific targets.
    537+// XXX: Since the support is specific to targets, the detection via additional
    538+// macro %__SIZEOF_INT128__ is needed. However, it is still not precise, e.g.
    539+// Clang++ may support 128-bit integer types (since 3.1) without such macro
    540+// definition (before 3.3). Just not bother on architecture other than x86_64
    541+// as now. See also https://stackoverflow.com/a/54815033 for more details
    542+// about detecting the support. However, it may even broken on some other
    543+// platforms not formally supported by this project, e.g. NVCC does not support
    544+// it even when the macro is defined (see
    545+// https://svn.boost.org/trac10/ticket/10418).
    546+// TODO: Support %__INTEL_COMPILER?
    547+#if (YB_IMPL_CLANGPP >= 30100 && defined __x86_64__) \
    548+ || (__SIZEOF_INT128__ == 16 && YB_IMPL_GNUC && !defined __CUDACC__)
    549+# define YB_HAS_int128 true
    550+#else
    551+# define YB_HAS_int128 false
    552+#endif
    553+
    554+
    555+/*!
    509556 \def YB_ABORT
    510557 \brief 非正常终止程序。
    511558 \note 可能使用体系结构相关实现或标准库 std::abort 函数等。
    @@ -823,9 +870,9 @@
    823870 \brief 修饰类定义要求实现不生成初始化动态类型信息。
    824871 \note 只适用于定义不在初始化派生类对象时的动态类型的类,否则行为未定义。
    825872 \see https://docs.microsoft.com/cpp/cpp/novtable 。
    826-\see http://releases.llvm.org/3.7.0/tools/clang/docs/AttributeReference.html 。
    873+\see https://releases.llvm.org/3.7.0/tools/clang/docs/AttributeReference.html 。
    827874 \see https://clang.llvm.org/docs/AttributeReference.html#novtable 。
    828-\see http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20150720/133747.html 。
    875+\see https://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20150720/133747.html 。
    829876 \since build 842
    830877 \todo 确认可忽略不支持情形的 Clang++ 最近可用的版本。
    831878
    @@ -854,8 +901,8 @@
    854901 \brief 指示返回非空属性。
    855902 \since build 676
    856903 \see https://clang.llvm.org/docs/AttributeReference.html#returns-nonnull 。
    857-\see http://reviews.llvm.org/rL199626 。
    858-\see http://reviews.llvm.org/rL199790 。
    904+\see https://reviews.llvm.org/rL199626 。
    905+\see https://reviews.llvm.org/rL199790 。
    859906 \todo 确认 Clang++ 最低可用的版本。
    860907 */
    861908 #if __has_attribute(__returns_nonnull__) || YB_IMPL_GNUCPP >= 40900 \
    @@ -1158,6 +1205,56 @@
    11581205 #endif
    11591206 //!@}
    11601207
    1208+/*!
    1209+\def YB_Use_int128
    1210+\brief 使用 128 位(有符号和无符号)整数类型。
    1211+\since build 983
    1212+
    1213+检查 \c std::uintmax_t 的值并确定 128 位整数支持。替换的值有:
    1214+ \li \c 4 :\c std::uintmax_t 大于 128 位无符号整数的最大值。
    1215+ \li \c 3 :\c std::uintmax_t 等于 128 位无符号整数的最大值。
    1216+ \li \c 2 :\c std::uintmax_t 大于 64 位但小于 128 位的无符号整数的最大值。
    1217+ \li \c 1 :\c std::uintmax_t 等于 64 位无符号整数的最大值。
    1218+ \li \c 0 :不存在 128 位整数支持。
    1219+*/
    1220+// NOTE: A conforming implementation uses %std::uintmax_t for all unsigned
    1221+// arithmetic types here. Extended integer-like types may be excluded from
    1222+// integer types (e.g. in libstdc++ with strict standard modes).
    1223+#ifndef YB_Use_int128
    1224+# if YB_HAS_int128
    1225+// XXX: Bit width shall not greater than the width of %std::uintmax_t, otherwise
    1226+// the behavior is undefined. 64 is safe because it is the least bets of
    1227+// 'unsigned long long' which is in turn not greater than %std::uintmax_t in
    1228+// bit width for the value representation.
    1229+# if ~0U >> 63 >> 63 >> 2!= 0
    1230+# define YB_Use_int128 4
    1231+# elif ((~0U >> 1) + 1) >> 63 >> 1 == 1U << 63
    1232+# define YB_Use_int128 3
    1233+# elif (~0U >> 1) + 1 > 1U << 63
    1234+# define YB_Use_int128 2
    1235+# elif (~0U >> 1) + 1 == 1U << 63
    1236+# define YB_Use_int128 1
    1237+# else
    1238+// NOTE: The type %std::uintmax_t shall be at least as the greatest standard
    1239+// unsigned integer type, i.e. 'unsigned long long', which is at least 64-bit.
    1240+# error "Nonconforming implementation found."
    1241+# endif
    1242+# else
    1243+# define YB_Use_int128 0
    1244+# endif
    1245+#endif
    1246+
    1247+/*!
    1248+\def YB_MaxIntBits
    1249+\brief YBase 实现支持的最大整数位宽。
    1250+*/
    1251+
    1252+#if YB_Use_int128 > 0
    1253+# define YB_MaxIntBits 128U
    1254+#else
    1255+# define YB_MaxIntBits 64U
    1256+#endif
    1257+
    11611258
    11621259 /*! \defgroup YBase_pseudo_keyword YBase Specified Pseudo-Keywords
    11631260 \brief YBase 指定的替代关键字。
    @@ -1554,6 +1651,22 @@
    15541651 */
    15551652 #define yunseq ystdex::unsequenced
    15561653
    1654+
    1655+/*!
    1656+\brief 128 位整数类型。
    1657+\note 可避免直接使用内建支持的类型时需要 \c __extension__ 。
    1658+\since build 983
    1659+*/
    1660+//!@{
    1661+#if YB_Use_int128 > 0
    1662+__extension__ using int128_t = __int128;
    1663+__extension__ using uint128_t = unsigned __int128;
    1664+# define YB_MaxIntBits 128U
    1665+#else
    1666+# define YB_MaxIntBits 64U
    1667+#endif
    1668+//!@}
    1669+
    15571670 } // namespace ystdex;
    15581671
    15591672 #endif
    diff -r 3fe9fa0c6127 -r 74e1025f0a02 YBase/include/ystdex/allocator.hpp
    --- a/YBase/include/ystdex/allocator.hpp Tue Feb 27 00:28:20 2024 +0800
    +++ b/YBase/include/ystdex/allocator.hpp Fri Apr 19 22:42:25 2024 +0800
    @@ -1,23 +1,22 @@
    11 /*
    22 © 2014-2023 FrankHB.
    33
    4- This file is part of the YSLib project, and may only be used,
    5- modified, and distributed under the terms of the YSLib project
    6- license, LICENSE.TXT. By continuing to use, modify, or distribute
    7- this file you indicate that you have read the license and
    8- understand and accept it fully.
    4+ This file is part of the YSLib project, and may only be used, modified,
    5+ and distributed under the terms of the YSLib project license.
    6+ By continuing to use, modify, or distribute this file you indicate that
    7+ you have read the license and understand and accept it fully.
    98 */
    109
    1110 /*! \file allocator.hpp
    1211 \ingroup YStandardEx
    1312 \brief 分配器接口。
    14-\version r6303
    13+\version r6319
    1514 \author FrankHB <frankhb1989@gmail.com>
    1615 \since build 882
    1716 \par 创建时间:
    1817 2020-02-10 21:34:28 +0800
    1918 \par 修改时间:
    20- 2023-04-11 03:40 +0800
    19+ 2023-04-16 20:10 +0800
    2120 \par 文本编码:
    2221 UTF-8
    2322 \par 模块名称:
    @@ -79,13 +78,15 @@
    7978 #endif
    8079
    8180
    82-#if __cplusplus >= 202002L && (!defined(__GLIBCXX__) || __GLIBCXX__ > 20190731)
    83-// XXX: See https://github.com/cplusplus/draft/issues/3111.
    84-// XXX: See https://gcc.gnu.org/git/?p=gcc.git;a=blobdiff;f=libstdc%2B%2B-v3/include/std/memory;h=0a483d2d8d1a1287685cb5cc8a7d338a14e7fef3;hp=3036802f8c3eb1c3013dc1720ad85087e5202694;hb=3090082cbefd8b1374f237bd4242b554490b2933;hpb=e6c847fb8f90b1c119a677b81cfc294b13eb7772.
    81+// NOTE: See https://github.com/cplusplus/draft/issues/3111.
    82+// NOTE: See https://gcc.gnu.org/git/?p=gcc.git;a=blobdiff;f=libstdc%2B%2B-v3/include/std/memory;h=0a483d2d8d1a1287685cb5cc8a7d338a14e7fef3;hp=3036802f8c3eb1c3013dc1720ad85087e5202694;hb=3090082cbefd8b1374f237bd4242b554490b2933;hpb=e6c847fb8f90b1c119a677b81cfc294b13eb7772.
    8583 // XXX: The source of libstdc++ uses '__cpp_lib_make_obj_using_allocator'
    8684 // internally in headers like <memory_resource> and <scoped_allocator> to
    8785 // detect the existence of the features. This is not in ISO C++ or proposals
    8886 // and not used here.
    87+// NOTE: See https://reviews.llvm.org/D131898.
    88+#if __cplusplus >= 202002L && (!defined __GLIBCXX__ || __GLIBCXX__ > 20190731) \
    89+ && (!defined _LIBCPP_VERSION || _LIBCPP_VERSION > 160000)
    8990 //! \since build 863
    9091 //!@{
    9192 using std::uses_allocator_construction_args;
    @@ -290,7 +291,7 @@
    290291 };
    291292
    292293 // XXX: This is a workaround to implementation without support of WG21 N4387.
    293-# if (defined(__GLIBCXX__) && (__GLIBCXX__ <= 20150630 \
    294+# if (defined __GLIBCXX__ && (__GLIBCXX__ <= 20150630 \
    294295 || YB_IMPL_GNUCPP < 60000)) && !(_LIBCPP_VERSION > 4000 \
    295296 || __cplusplus >= 201703L)
    296297 // NOTE: See https://gcc.gnu.org/git/?p=gcc.git;a=blobdiff;f=libstdc%2B%2B-v3/include/bits/stl_pair.h;h=6672ecb227377d199df830bc475f6ebecd03beed;hp=490b00565a0560f9f15f86bb706fa8f3800ee026;hb=bf7818bfb0c70e626f8b71501ada3263f306a476;hpb=ddb63209a8dc059a7b2a137d7a1859222bb43dd6,
    @@ -910,7 +911,7 @@
    910911 operator=(const allocator_guard_delete& d) ynothrow
    911912 {
    912913 ystdex::copy_assign(get_allocator(), d.first());
    913- return *this;
    914+ return *this;
    914915 }
    915916 // XXX: No 'ynothrow' is specified because the underlying assignment
    916917 // operator might be deleted.
    @@ -1047,7 +1048,7 @@
    10471048 operator=(const allocator_delete& d) ynothrow
    10481049 {
    10491050 ystdex::copy_assign(get_allocator(), d.get());
    1050- return *this;
    1051+ return *this;
    10511052 }
    10521053 allocator_delete&
    10531054 operator=(allocator_delete&&) = default;
    @@ -1321,8 +1322,7 @@
    13211322 //! \since build 941
    13221323 //!@{
    13231324 /*!
    1324-\ingroup customization_points
    1325-\ingroup traits
    1325+\ingroup customization_points traits
    13261326 \note 可定制和分配器的定义中不同的操作。
    13271327 */
    13281328 //! \brief 分配器在容器中的使用复制构造的传播特征。
    diff -r 3fe9fa0c6127 -r 74e1025f0a02 YBase/include/ystdex/arithmetic.hpp
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/YBase/include/ystdex/arithmetic.hpp Fri Apr 19 22:42:25 2024 +0800
    @@ -0,0 +1,840 @@
    1+/*
    2+ © 2024 FrankHB.
    3+
    4+ This file is part of the YSLib project, and may only be used, modified,
    5+ and distributed under the terms of the YSLib project license.
    6+ By continuing to use, modify, or distribute this file you indicate that
    7+ you have read the license and understand and accept it fully.
    8+*/
    9+
    10+/*! \file arithmetic.hpp
    11+\ingroup YStandardEx
    12+\brief 算术类型和操作。
    13+\version r839
    14+\author FrankHB <frankhb1989@gmail.com>
    15+\since build 983
    16+\par 创建时间:
    17+ 2024-04-08 04:41:56 +0800
    18+\par 修改时间:
    19+ 2024-04-18 22:10 +0800
    20+\par 文本编码:
    21+ UTF-8
    22+\par 模块名称:
    23+ YStandardEx::Arithmetic
    24+*/
    25+
    26+
    27+#ifndef YB_INC_ystdex_arithmetic_hpp_
    28+#define YB_INC_ystdex_arithmetic_hpp_ 1
    29+
    30+#include "cstdint.hpp" // for "cstdint.hpp", enable_if_t, integer_width,
    31+// make_width_int, is_same, is_integral, std::intmax_t, identity,
    32+// std::uintmax_t, _t, cond_t, is_signed, make_signed, remove_cv_t,
    33+// is_unsigned, std::numeric_limits (with fixes), bool_, __has_builtin,
    34+// is_unbounded_number;
    35+#include <cmath> // for <cmath>, std::float_t;
    36+#include "exception.h" // for "exception.h", throw_overflow_error,
    37+// throw_underflow_error;
    38+#include "allocator.hpp" // for ystdex::make_obj_using_allocator;
    39+
    40+namespace ystdex
    41+{
    42+
    43+//! \brief 正整数幂。
    44+template<typename _type, typename _type2>
    45+YB_ATTR_nodiscard YB_STATELESS yconstfn
    46+ yimpl(enable_if_unsigned_t)<_type2, _type>
    47+upow(_type x, _type2 e) ynothrow
    48+{
    49+ return e == 0 ? _type(1) : e == 1
    50+ ? x : ystdex::upow(x * x, e >> 1) * ((e & 1) != 0 ? x : _type(1));
    51+}
    52+
    53+
    54+//! \since build 983
    55+//!@{
    56+namespace details
    57+{
    58+
    59+template<typename _type, typename = void>
    60+struct extend_int_map;
    61+
    62+// XXX: This is needed to non-standard types with width not greater than 64,
    63+// e.g. %__int64 in Microsoft VC++. For width greater than 64, it also seems
    64+// more consistent to have this way (to be filter by %integer_width and
    65+// %make_width_int).
    66+template<typename _type>
    67+struct extend_int_map<_type, enable_if_t<(integer_width<_type>()
    68+ <= YB_MaxIntBits)>> : make_width_int<integer_width<_type>{}>
    69+{
    70+ static_assert(!is_same<bool, _type>(), "Boolean types found.");
    71+ static_assert(is_integral<_type>(), "Unsupported type found.");
    72+};
    73+
    74+
    75+template<typename>
    76+struct ext_add_overflow;
    77+
    78+// NOTE: This is only enabled when %std::intmax_t is greater than 'long long',
    79+// to prevent violation of ODR.
    80+#if ULLONG_MAX < ~0U
    81+// NOTE: Prefer %intmax_t if greater than %std::intmax_t.
    82+template<>
    83+struct ext_add_overflow<std::intmax_t>
    84+ : yimpl(conditional)<(integer_width<std::intmax_t>() < integer_width<
    85+ intmax_t>()), identity<intmax_t>, ext_add_overflow<std::uintmax_t>>
    86+{};
    87+#endif
    88+
    89+// NOTE: It is guarnteed that %intmax_t is not less than %std::intmax_t. Prefer
    90+// %std::intmax_t if greater than 'long long'; otherwise prefer %intmax_t.
    91+template<>
    92+struct ext_add_overflow<long long> : yimpl(conditional)<(
    93+ integer_width<long long>() < integer_width<std::intmax_t>()), std::intmax_t,
    94+ conditional_t<(integer_width<long long>() < integer_width<intmax_t>()),
    95+ intmax_t, unsigned long long>>
    96+{};
    97+
    98+template<>
    99+struct ext_add_overflow<long>
    100+ : yimpl(conditional)<(integer_width<long>() < integer_width<long long>()),
    101+ long long, _t<ext_add_overflow<long long>>>
    102+{};
    103+
    104+template<>
    105+struct ext_add_overflow<unsigned long long> : yimpl(identity)<std::float_t>
    106+{};
    107+
    108+template<>
    109+struct ext_add_overflow<int>
    110+ : yimpl(conditional_t)<(integer_width<int>() < integer_width<long>()),
    111+ identity<long>, ext_add_overflow<long>>
    112+{};
    113+
    114+template<>
    115+struct ext_add_overflow<short>
    116+ : yimpl(conditional_t)<(integer_width<short>() < integer_width<int>()),
    117+ identity<int>, ext_add_overflow<int>>
    118+{};
    119+
    120+template<>
    121+struct ext_add_overflow<signed char> : yimpl(identity)<short>
    122+{};
    123+
    124+// XXX: For non standard integer types not having same width of standard ones,
    125+// results are unspecified.
    126+template<typename _type>
    127+struct ext_add_overflow
    128+ : ext_add_overflow<_t<details::extend_int_map<_type>>>
    129+{};
    130+
    131+
    132+// NOTE: Unsigned underflow only happens in cases where an unsigned value is
    133+// subtracted by a value with lower rank, so there is no extension of the bit
    134+// width.
    135+template<typename _type>
    136+struct ext_add_underflow
    137+ : cond_t<is_signed<_type>, ext_add_overflow<_type>, make_signed<_type>>
    138+{};
    139+// XXX: Given that the unsigned integer types all have the exact same width as
    140+// their signed counterpart, there is no need to add specialization to test the
    141+// sizes here, except that for cases of 'unsigned long long' result which shall
    142+// be alterted to 'std::float_t' (which has been also handled in the primary
    143+// template in this implementation).
    144+
    145+} // namespace details;
    146+
    147+/*!
    148+\ingroup transformation_traits
    149+\pre 静态断言:参数是整数。
    150+*/
    151+//!@{
    152+/*!
    153+\brief 扩展能避免算术上溢的整数加法结果类型。
    154+
    155+取避免计算整数类型的和或差时的上溢的结果类型,可包括以下情形:
    156+ 对两个相同的整数类型,两个正整数值相加。
    157+ 对两个相同的有符号整数类型,非负整数值减有符号整数的最小值。
    158+ 对两个相同的有符号整数类型,正整数值减负整数值。
    159+结果升阶作为两个相同整数类型的加法结果的整数:
    160+ 若参数是 cv 限定的类型,则结果同无 cv 限定的类型添加相同的 cv 限定。
    161+ 否则,若参数是最大的无符号整数类型,结果是 \c std::float_t 。
    162+ 否则,若没有对应参数更大的有符号整数类型,则结果为对应的无符号整数类型。
    163+ 否则,结果是具有最小的更大的算术转换阶的有符号整数类型。
    164+结果选取支持的类型中能保证可表示计算结果中阶最小的。
    165+因此,除最大的无符号整数类型,其它结果是有符号类型。
    166+*/
    167+//!@{
    168+template<typename _type>
    169+struct extend_additive_overflow
    170+ : copy_cv<_t<details::ext_add_overflow<remove_cv_t<_type>>>, _type>
    171+{};
    172+
    173+template<typename _type>
    174+using extend_additive_overflow_t = _t<extend_additive_overflow<_type>>;
    175+//!@}
    176+
    177+
    178+/*!
    179+\brief 扩展能避免算术下溢的整数加减法结果类型。
    180+\sa extend_additive_overflow
    181+
    182+取避免计算整数类型的和或差时的下溢的结果类型,可包括以下情形:
    183+ 对两个相同的有符号整数类型,两个负整数值相加。
    184+ 对两个相同的有符号整数类型,负整数值相加。
    185+ 对两个相同的有符号整数类型,负整数值减正整数值。
    186+ 对整数类型,整数值减一个任意的更小的转换阶的正整数值。
    187+结果升阶作为两个相同整数类型的加法或减法结果的整数:
    188+ 若参数是 cv 限定的类型,则结果同无 cv 限定的类型添加相同的 cv 限定。
    189+ 否则,若 extend_additive_overflow 对相同参数类型的结果是有符号数,
    190+ 则同 extend_additive_overflow 。
    191+ 否则,若参数是最大的有符号或无符号整数类型,结果是 \c std::float_t 。
    192+ 否则,若参数是有符号类型,结果同 extend_additive_overflow 。
    193+ 否则,参数是对应的有符号类型。
    194+结果选取支持的类型中能保证可表示计算结果。因此,结果总是有符号类型。
    195+无符号数参数不扩展位宽,因为转换阶较小。这可支持自减等操作。
    196+若需要支持转换阶更大的减数,结果即减数的类型。这不需要基于被减数的类型扩展位宽。
    197+*/
    198+//!@{
    199+template<typename _type>
    200+struct extend_additive_underflow
    201+ : copy_cv<_t<details::ext_add_underflow<remove_cv_t<_type>>>, _type>
    202+{};
    203+
    204+template<typename _type>
    205+using extend_additive_underflow_t = _t<extend_additive_underflow<_type>>;
    206+//!@}
    207+
    208+
    209+/*!
    210+\brief 扩展能避免算术溢出的整数乘法结果类型。
    211+
    212+取避免计算整数类型的积时的溢出的结果类型,可包括以下情形:
    213+ 两个相同的有符号整数类型相乘。
    214+ 两个相同的无符号整数类型相乘。
    215+结果升阶作为两个相同整数类型的加法或减法结果的整数:
    216+ 若参数是 cv 限定的类型,则结果同无 cv 限定的类型添加相同的 cv 限定。
    217+ 否则,若参数是最大的有符号或无符号整数类型,结果是 \c std::float_t 。
    218+ 否则,结果同 make_widen_int 。
    219+结果总是 \c std::float_t 或与参数类型相同符号的整数类型。
    220+*/
    221+//!@{
    222+template<typename _type>
    223+struct extend_product : conditional_t<integer_width<_type>() == YB_MaxIntBits,
    224+ identity<std::float_t>, make_widen_int<_type>>
    225+{
    226+ static_assert(!is_same<bool, _type>(), "Boolean types found.");
    227+ static_assert(is_integral<_type>(), "Unsupported type found.");
    228+};
    229+
    230+template<typename _type>
    231+using extend_product_t = _t<extend_product<_type>>;
    232+//!@}
    233+//!@}
    234+
    235+
    236+namespace details
    237+{
    238+
    239+template<typename _tTo, typename _tFrom, bool = is_unsigned<_tTo>{}>
    240+struct int_min_check final
    241+{
    242+ static void
    243+ check_underflow(const _tFrom& x)
    244+ {
    245+ if(YB_UNLIKELY(x < std::numeric_limits<_tTo>::min()))
    246+ throw_underflow_error("Value underflow detected in cast.");
    247+ }
    248+};
    249+
    250+template<typename _tTo, typename _tFrom>
    251+struct int_min_check<_tTo, _tFrom, true> final
    252+{
    253+ static void
    254+ check_overflow(const _tFrom& x)
    255+ {
    256+ if(YB_UNLIKELY(x < _tFrom(0)))
    257+ throw_overflow_error();
    258+ }
    259+};
    260+
    261+
    262+template<typename _tTo, typename _tFrom>
    263+struct int_max_check final
    264+{
    265+ static void
    266+ check_overflow(const _tFrom& x)
    267+ {
    268+ if(YB_UNLIKELY(x > std::numeric_limits<_tTo>::max()))
    269+ throw_overflow_error();
    270+ }
    271+};
    272+
    273+
    274+//! \ingroup functors
    275+//!@{
    276+template<typename _tTo, typename _tFrom, bool, bool>
    277+struct checked_conv_int
    278+{
    279+ YB_ATTR_nodiscard YB_PURE _tTo
    280+ operator()(const _tFrom& x) const
    281+ {
    282+ int_max_check<_tTo, _tFrom>::check_overflow(x);
    283+ int_min_check<_tTo, _tFrom>::check_underflow(x);
    284+ return static_cast<_tTo>(x);
    285+ }
    286+};
    287+
    288+template<typename _tTo, typename _tFrom>
    289+struct checked_conv_int<_tTo, _tFrom, true, false>
    290+{
    291+ YB_ATTR_nodiscard YB_PURE _tTo
    292+ operator()(const _tFrom& x) const
    293+ {
    294+ int_max_check<_tTo, _tFrom>::check_overflow(x);
    295+ return static_cast<_tTo>(x);
    296+ }
    297+};
    298+
    299+template<typename _tTo, typename _tFrom>
    300+struct checked_conv_int<_tTo, _tFrom, false, true>
    301+{
    302+ YB_ATTR_nodiscard YB_PURE _tTo
    303+ operator()(const _tFrom& x) const
    304+ {
    305+ int_min_check<_tTo, _tFrom>::check_underflow(x);
    306+ return static_cast<_tTo>(x);
    307+ }
    308+};
    309+
    310+template<typename _tTo, typename _tFrom>
    311+struct checked_conv_int<_tTo, _tFrom, false, false>
    312+{
    313+ YB_ATTR_nodiscard YB_PURE _tTo
    314+ operator()(const _tFrom& x) const ynothrow
    315+ {
    316+ return static_cast<_tTo>(x);
    317+ }
    318+};
    319+//!@}
    320+
    321+
    322+//! \ingroup traits
    323+//!@{
    324+template<typename _type, bool = std::numeric_limits<_type>::is_signed,
    325+ bool = __has_builtin(__builtin_add_overflow) && is_integral<_type>{}>
    326+struct ext_plus;
    327+
    328+template<typename _type>
    329+struct ext_plus<_type, false, false>
    330+{
    331+ template<typename _tRes, typename _tExt, typename = _tExt>
    332+ YB_ATTR_nodiscard YB_PURE static inline _tRes
    333+ extended_plus(const _type& x, const _type& y)
    334+ {
    335+ // NOTE: Wrapped integers are generally more efficient.
    336+#if true
    337+ const _type r(x + y);
    338+
    339+ return r >= x ? _tRes(r) : _tRes(_tExt(x) + _tExt(y));
    340+#else
    341+ return y <= numeric_limits<_type>::max() - x ? _tRes(x + y)
    342+ : _tRes(_tExt(x) + _tExt(y));
    343+#endif
    344+ }
    345+ template<typename _tRes, typename _tExt, typename = _tExt, class _tAlloc>
    346+ YB_ATTR_nodiscard YB_PURE static inline _tRes
    347+ extended_plus(const _type& x, const _type& y, const _tAlloc& a)
    348+ {
    349+#if true
    350+ const _type r(x + y);
    351+
    352+ return r >= x ? ystdex::make_obj_using_allocator<_tRes>(a, r)
    353+ : ystdex::make_obj_using_allocator<_tRes>(a, _tExt(x) + _tExt(y));
    354+#else
    355+ return y <= numeric_limits<_type>::max() - x
    356+ ? ystdex::make_obj_using_allocator<_tRes>(a, x + y)
    357+ : ystdex::make_obj_using_allocator<_tRes>(a, _tExt(x) + _tExt(y));
    358+#endif
    359+ }
    360+};
    361+
    362+template<typename _type>
    363+struct ext_plus<_type, true, false>
    364+{
    365+ using limits_t = std::numeric_limits<_type>;
    366+
    367+ template<typename _tRes, typename _tExt, typename _tExt2>
    368+ YB_ATTR_nodiscard YB_PURE static inline _tRes
    369+ extended_plus(const _type& x, const _type& y)
    370+ {
    371+ if(x > 0 && y > limits_t::max() - x)
    372+ return _tRes(_tExt(x) + _tExt(y));
    373+ if(x < 0 && y < limits_t::min() - x)
    374+ return _tRes(_tExt2(x) + _tExt2(y));
    375+ return _tRes(x + y);
    376+ }
    377+ template<typename _tRes, typename _tExt, typename _tExt2, class _tAlloc>
    378+ YB_ATTR_nodiscard YB_PURE static inline _tRes
    379+ extended_plus(const _type& x, const _type& y, const _tAlloc& a)
    380+ {
    381+ if(x > 0 && y > limits_t::max() - x)
    382+ return
    383+ ystdex::make_obj_using_allocator<_tRes>(a, _tExt(x) + _tExt(y));
    384+ if(x < 0 && y < limits_t::min() - x)
    385+ return ystdex::make_obj_using_allocator<_tRes>(a,
    386+ _tExt2(x) + _tExt2(y));
    387+ return ystdex::make_obj_using_allocator<_tRes>(a, x + y);
    388+ }
    389+};
    390+
    391+#if __has_builtin(__builtin_add_overflow)
    392+template<typename _type>
    393+struct ext_plus<_type, false, true>
    394+{
    395+ template<typename _tRes, typename _tExt, typename = _tExt>
    396+ YB_ATTR_nodiscard YB_PURE static inline _tRes
    397+ extended_plus(const _type& x, const _type& y)
    398+ {
    399+ _type r;
    400+
    401+ return !__builtin_add_overflow(x, y, &r) ? _tRes(r)
    402+ : _tRes(_tExt(x) + _tExt(y));
    403+ }
    404+ template<typename _tRes, typename _tExt, typename = _tExt, class _tAlloc>
    405+ YB_ATTR_nodiscard YB_PURE static inline _tRes
    406+ extended_plus(const _type& x, const _type& y, const _tAlloc& a)
    407+ {
    408+ _type r;
    409+
    410+ return !__builtin_add_overflow(x, y, &r)
    411+ ? ystdex::make_obj_using_allocator<_tRes>(a, r)
    412+ : ystdex::make_obj_using_allocator<_tRes>(a, _tExt(x) + _tExt(y));
    413+ }
    414+};
    415+
    416+template<typename _type>
    417+struct ext_plus<_type, true, true>
    418+{
    419+ using limits_t = std::numeric_limits<_type>;
    420+
    421+ template<typename _tRes, typename _tExt, typename _tExt2>
    422+ YB_ATTR_nodiscard YB_PURE static inline _tRes
    423+ extended_plus(const _type& x, const _type& y)
    424+ {
    425+ _type r;
    426+
    427+ if(!__builtin_add_overflow(x, y, &r))
    428+ return _tRes(r);
    429+ return x > 0 && y > limits_t::max() - x ? _tRes(_tExt(x) + _tExt(y))
    430+ : _tRes(_tExt2(x) + _tExt2(y));
    431+ }
    432+ template<typename _tRes, typename _tExt, typename _tExt2, class _tAlloc>
    433+ YB_ATTR_nodiscard YB_PURE static inline _tRes
    434+ extended_plus(const _type& x, const _type& y, const _tAlloc& a)
    435+ {
    436+ _type r;
    437+
    438+ if(!__builtin_add_overflow(x, y, &r))
    439+ return ystdex::make_obj_using_allocator<_tRes>(a, r);
    440+ return x > 0 && y > limits_t::max() - x
    441+ ? ystdex::make_obj_using_allocator<_tRes>(a, _tExt(x) + _tExt(y))
    442+ : ystdex::make_obj_using_allocator<_tRes>(a, _tExt2(x) + _tExt2(y));
    443+ }
    444+};
    445+#endif
    446+
    447+
    448+template<typename _type, bool = std::numeric_limits<_type>::is_signed,
    449+ bool = __has_builtin(__builtin_sub_overflow) && is_integral<_type>{}>
    450+struct ext_minus;
    451+
    452+template<typename _type>
    453+struct ext_minus<_type, false, false>
    454+{
    455+ // XXX: This is efficient enough to avoid builtins.
    456+ template<typename _tRes, typename _tExt, typename = _tExt>
    457+ YB_ATTR_nodiscard YB_PURE static inline _tRes
    458+ extended_minus(const _type& x, const _type& y)
    459+ {
    460+ return y <= x ? _tRes(x - y) : _tRes(_tExt(x) - _tExt(y));
    461+ }
    462+ template<typename _tRes, typename _tExt, typename = _tExt, class _tAlloc>
    463+ YB_ATTR_nodiscard YB_PURE static inline _tRes
    464+ extended_minus(const _type& x, const _type& y, const _tAlloc& a)
    465+ {
    466+ return y <= x ? ystdex::make_obj_using_allocator<_tRes>(a, x - y)
    467+ : ystdex::make_obj_using_allocator<_tRes>(a, _tExt(x) - _tExt(y));
    468+ }
    469+};
    470+
    471+template<typename _type>
    472+struct ext_minus<_type, true, false>
    473+{
    474+ using limits_t = std::numeric_limits<_type>;
    475+
    476+ template<typename _tRes, typename _tExt, typename _tExt2>
    477+ YB_ATTR_nodiscard YB_PURE static inline _tRes
    478+ extended_minus(const _type& x, const _type& y)
    479+ {
    480+ if((x >= 0 && (YB_UNLIKELY(y == limits_t::min())
    481+ || -y > limits_t::max() - x)))
    482+ return _tRes(_tExt(x) - _tExt(y));
    483+ return x < 0 && -y < limits_t::min() - x ? _tRes(_tExt2(x) - _tExt2(y))
    484+ : _tRes(x - y);
    485+ }
    486+ template<typename _tRes, typename _tExt, typename _tExt2, class _tAlloc>
    487+ YB_ATTR_nodiscard YB_PURE static inline _tRes
    488+ extended_minus(const _type& x, const _type& y, const _tAlloc& a)
    489+ {
    490+ if((x >= 0 && (YB_UNLIKELY(y == limits_t::min())
    491+ || -y > limits_t::max() - x)))
    492+ return
    493+ ystdex::make_obj_using_allocator<_tRes>(a, _tExt(x) - _tExt(y));
    494+ return x < 0 && -y < limits_t::min() - x
    495+ ? ystdex::make_obj_using_allocator<_tRes>(a, _tExt2(x) - _tExt2(y))
    496+ : ystdex::make_obj_using_allocator<_tRes>(a, x - y);
    497+ }
    498+};
    499+
    500+#if __has_builtin(__builtin_sub_overflow)
    501+template<typename _type>
    502+// XXX: This is efficient enough to avoid builtins.
    503+struct ext_minus<_type, false, true> : ext_minus<_type, false, false>
    504+{};
    505+
    506+template<typename _type>
    507+struct ext_minus<_type, true, true>
    508+{
    509+ using limits_t = std::numeric_limits<_type>;
    510+
    511+ template<typename _tRes, typename _tExt, typename _tExt2>
    512+ YB_ATTR_nodiscard YB_PURE static inline _tRes
    513+ extended_minus(const _type& x, const _type& y)
    514+ {
    515+ _type r;
    516+
    517+ if(!__builtin_sub_overflow(x, y, &r))
    518+ return _tRes(r);
    519+ return YB_UNLIKELY(y == limits_t::min())
    520+ || (x > 0 && -y > limits_t::max() - x)
    521+ ? _tRes(_tExt(x) - _tExt(y)) : _tRes(_tExt2(x) - _tExt2(y));
    522+ }
    523+ template<typename _tRes, typename _tExt, typename _tExt2, class _tAlloc>
    524+ YB_ATTR_nodiscard YB_PURE static inline _tRes
    525+ extended_minus(const _type& x, const _type& y, const _tAlloc& a)
    526+ {
    527+ _type r;
    528+
    529+ if(!__builtin_sub_overflow(x, y, &r))
    530+ return ystdex::make_obj_using_allocator<_tRes>(a, r);
    531+ return YB_UNLIKELY(y == limits_t::min())
    532+ || (x > 0 && -y > limits_t::max() - x)
    533+ ? ystdex::make_obj_using_allocator<_tRes>(a, _tExt(x) - _tExt(y))
    534+ : ystdex::make_obj_using_allocator<_tRes>(a, _tExt2(x) - _tExt2(y));
    535+ }
    536+};
    537+#endif
    538+
    539+
    540+template<typename _type,
    541+ bool = __has_builtin(__builtin_mul_overflow) && is_integral<_type>{}>
    542+struct ext_multiply;
    543+
    544+template<typename _type>
    545+struct ext_multiply<_type, false>
    546+{
    547+ using limits_t = std::numeric_limits<_type>;
    548+
    549+ template<typename _tRes, typename _tExt>
    550+ YB_ATTR_nodiscard YB_PURE static inline _tRes
    551+ extended_multiply(const _type& x, const _type& y)
    552+ {
    553+ const _tExt r(_tExt(x) * _tExt(y));
    554+
    555+ return r <= _tExt(limits_t::max()) ? _tRes(_type(r)) : _tRes(r);
    556+ }
    557+ template<typename _tRes, typename _tExt, class _tAlloc>
    558+ YB_ATTR_nodiscard YB_PURE static inline _tRes
    559+ extended_multiply(const _type& x, const _type& y, const _tAlloc& a)
    560+ {
    561+ const _tExt r(_tExt(x) * _tExt(y));
    562+
    563+ return r <= _tExt(limits_t::max()) ? ystdex::make_obj_using_allocator<
    564+ _tRes>(a, _type(r)) : ystdex::make_obj_using_allocator<_tRes>(a, r);
    565+ }
    566+};
    567+
    568+#if __has_builtin(__builtin_mul_overflow)
    569+template<typename _type>
    570+struct ext_multiply<_type, true>
    571+{
    572+ template<typename _tRes, typename _tExt>
    573+ YB_ATTR_nodiscard YB_PURE static inline _tRes
    574+ extended_multiply(const _type& x, const _type& y)
    575+ {
    576+ _type r;
    577+
    578+ return !__builtin_mul_overflow(x, y, &r) ? _tRes(r)
    579+ : _tRes(_tExt(x) * _tExt(y));
    580+ }
    581+ template<typename _tRes, typename _tExt, class _tAlloc>
    582+ YB_ATTR_nodiscard YB_PURE static inline _tRes
    583+ extended_multiply(const _type& x, const _type& y, const _tAlloc& a)
    584+ {
    585+ _type r;
    586+
    587+ return !__builtin_mul_overflow(x, y, &r) ? _tRes(r)
    588+ : ystdex::make_obj_using_allocator<_tRes>(a, _tExt(x) * _tExt(y));
    589+ }
    590+};
    591+#endif
    592+//!@}
    593+
    594+
    595+//! \warning 非虚析构。
    596+struct ext_noreturn
    597+{
    598+ template<typename _type>
    599+ YB_NORETURN friend inline _type
    600+ operator+(const _type&, const _type&)
    601+ {
    602+ YB_ASSUME(false);
    603+ }
    604+
    605+ template<typename _type>
    606+ YB_NORETURN friend inline _type
    607+ operator-(const _type&, const _type&)
    608+ {
    609+ YB_ASSUME(false);
    610+ }
    611+
    612+ template<typename _type>
    613+ YB_NORETURN friend inline _type
    614+ operator*(const _type&, const _type&)
    615+ {
    616+ YB_ASSUME(false);
    617+ }
    618+
    619+ template<typename _type>
    620+ YB_NORETURN inline
    621+ operator _type()
    622+ {
    623+ YB_ASSUME(false);
    624+ }
    625+};
    626+
    627+
    628+struct ext_overflow final : ext_noreturn
    629+{
    630+ template<typename _type>
    631+ inline
    632+ ext_overflow(const _type&)
    633+ {
    634+ throw_overflow_error();
    635+ }
    636+};
    637+
    638+
    639+struct ext_underflow final : ext_noreturn
    640+{
    641+ template<typename _type>
    642+ inline
    643+ ext_underflow(const _type&)
    644+ {
    645+ throw_underflow_error();
    646+ }
    647+};
    648+
    649+} // namespace details;
    650+
    651+/*!
    652+\note 不使用 common_type_t 以允许另行单独检查转换时可能的溢出。
    653+\exception std::overflow 上溢:转换的中间计算或结果的不能被最大值表示。
    654+*/
    655+//!@{
    656+//! \exception std::overflow 下溢:转换的中间计算或结果的不能被最小值表示。
    657+//!@{
    658+//! \brief 检查溢出的加法。
    659+template<typename _type, typename = enable_if_t<!is_unbounded_number<_type>{}>>
    660+YB_ATTR_nodiscard YB_PURE _type
    661+checked_plus(const _type& x, const _type& y)
    662+{
    663+ return details::ext_plus<_type>::template extended_plus<_type,
    664+ details::ext_overflow, details::ext_underflow>(x, y);
    665+}
    666+
    667+//! \brief 检查溢出的减法。
    668+template<typename _type, typename = enable_if_t<!is_unbounded_number<_type>{}>>
    669+YB_ATTR_nodiscard YB_PURE _type
    670+checked_minus(const _type& x, const _type& y)
    671+{
    672+ return details::ext_minus<_type>::template extended_minus<_type,
    673+ details::ext_overflow, details::ext_underflow>(x, y);
    674+}
    675+//!@}
    676+
    677+//! \brief 检查溢出的乘法。
    678+template<typename _type, typename = enable_if_t<!is_unbounded_number<_type>{}>>
    679+YB_ATTR_nodiscard YB_PURE _type
    680+checked_multiply(const _type& x, const _type& y)
    681+{
    682+ return details::ext_multiply<_type>::template extended_minus<_type,
    683+ details::ext_overflow>(x, y);
    684+}
    685+//!@}
    686+
    687+
    688+/*!
    689+\pre 静态断言:第三模板参数应具有 \c numeric_limits 特化且为有界类型。
    690+\return 指定第一参数类型的保存结果的值。
    691+\sa ystdex::make_obj_using_allocator
    692+
    693+第一模板参数指定保存可通过不同结果类型初始化的结果类型,如 any 。
    694+第二模板参数指定保存扩展类型。
    695+最后一个模板参数是操作数的类型。
    696+前两个函数参数指定操作数。
    697+可选的第三个函数参数指定分配器。
    698+计算时,结果被检查以确定是否可在操作数类型的值域中表示。
    699+若可以表示,则中间结果类型是操作数的类型;否则,中间结果类型是扩展类型。
    700+结果是结果类型通过中间结果类型的中间值显式初始化得到的值。
    701+若指定分配器,使用 ystdex::make_obj_using_allocator 初始化结果;
    702+ 否则,直接初始化结果。
    703+*/
    704+//!@{
    705+/*!
    706+\sa extend_additive_overflow
    707+\sa extend_additive_underflow
    708+
    709+第二模板参数指定保存可能上溢时的扩展类型。
    710+第三模板参数指定保存可能下溢时的扩展类型。
    711+为避免有符号整数溢出的未定义行为或错误的计算结果,
    712+ 使用 extend_additive_overflow 等方式确定扩展类型能保存任意计算结果。
    713+*/
    714+//!@{
    715+/*!
    716+\brief 可扩展中间结果类型的加法。
    717+
    718+计算函数参数指定的数值作为乘数的加法。
    719+若操作数是整数类型,则可选使用实现支持的 \c __builtin_add_overflow 。
    720+*/
    721+//!@{
    722+template<typename _tRes, typename _tExt, typename _tExt2 = _tExt,
    723+ typename _type, typename = enable_if_t<!is_unbounded_number<_type>{}>>
    724+YB_ATTR_nodiscard YB_PURE inline auto
    725+extended_plus(const _type& x, const _type& y)
    726+ -> enable_if_t<is_constructible<_tRes, decltype(x + y)>{}, _tRes>
    727+{
    728+ return details::ext_plus<_type>::template
    729+ extended_plus<_tRes, _tExt, _tExt2>(x, y);
    730+}
    731+template<typename _tRes, typename _tExt, typename _tExt2 = _tExt,
    732+ typename _type, class _tAlloc,
    733+ typename = enable_if_t<!is_unbounded_number<_type>{}>>
    734+YB_ATTR_nodiscard YB_PURE inline auto
    735+extended_plus(const _type& x, const _type& y, const _tAlloc& a)
    736+ -> enable_if_t<is_constructible<_tRes, decltype(x * y)>{}, _tRes>
    737+{
    738+ return details::ext_plus<_type>::template
    739+ extended_plus<_tRes, _tExt, _tExt2>(x, y, a);
    740+}
    741+//!@}
    742+
    743+/*!
    744+\brief 可扩展中间结果类型的减法。
    745+\sa extend_additive_overflow
    746+
    747+计算函数参数指定的数值作为乘数的减法。
    748+若操作数是整数类型,则可选使用实现支持的 \c __builtin_sub_overflow 。
    749+*/
    750+//!@{
    751+template<typename _tRes, typename _tExt, typename _tExt2 = _tExt,
    752+ typename _type, typename = enable_if_t<!is_unbounded_number<_type>{}>>
    753+YB_ATTR_nodiscard YB_PURE inline auto
    754+extended_minus(const _type& x, const _type& y)
    755+ -> enable_if_t<is_constructible<_tRes, decltype(x + y)>{}, _tRes>
    756+{
    757+ return details::ext_minus<_type>::template
    758+ extended_minus<_tRes, _tExt, _tExt2>(x, y);
    759+}
    760+template<typename _tRes, typename _tExt, typename _tExt2 = _tExt,
    761+ typename _type, class _tAlloc,
    762+ typename = enable_if_t<!is_unbounded_number<_type>{}>>
    763+YB_ATTR_nodiscard YB_PURE inline auto
    764+extended_minus(const _type& x, const _type& y, const _tAlloc& a)
    765+ -> enable_if_t<is_constructible<_tRes, decltype(x * y)>{}, _tRes>
    766+{
    767+ return details::ext_minus<_type>::template
    768+ extended_minus<_tRes, _tExt, _tExt2>(x, y, a);
    769+}
    770+//!@}
    771+//!@}
    772+
    773+/*!
    774+\brief 可扩展中间结果类型的乘法。
    775+\sa extend_product
    776+
    777+计算函数参数指定的数值作为乘数的乘法。
    778+若操作数是整数类型,则可选使用实现支持的 \c __builtin_mul_overflow 。
    779+为避免有符号整数溢出的未定义行为或错误的计算结果,
    780+ 使用 extend_product 等方式确定扩展类型能保存任意计算结果。
    781+*/
    782+//!@{
    783+template<typename _tRes, typename _tExt, typename _type,
    784+ typename = enable_if_t<!is_unbounded_number<_type>{}>>
    785+YB_ATTR_nodiscard YB_PURE inline auto
    786+extended_multiply(const _type& x, const _type& y)
    787+ -> enable_if_t<is_constructible<_tRes, decltype(x * y)>{}, _tRes>
    788+{
    789+ return details::ext_multiply<_type>::template
    790+ extended_multiply<_tRes, _tExt>(x, y);
    791+}
    792+template<typename _tRes, typename _tExt, typename _type, class _tAlloc,
    793+ typename = enable_if_t<!is_unbounded_number<_type>{}>>
    794+YB_ATTR_nodiscard YB_PURE inline auto
    795+extended_multiply(const _type& x, const _type& y, const _tAlloc& a)
    796+ -> enable_if_t<is_constructible<_tRes, decltype(x * y)>{}, _tRes>
    797+{
    798+ return details::ext_multiply<_type>::template
    799+ extended_multiply<_tRes, _tExt>(x, y, a);
    800+}
    801+//!@}
    802+//!@}
    803+
    804+/*!
    805+\brief 检查模板参数指定的值作为乘数的整数乘法结果。
    806+\return 在结果类型中能表示的积。
    807+\throw std::overflow 上溢:结果超出可表示的范围上界。
    808+\throw std::underflow 下溢:结果超出可表示的范围下界。
    809+*/
    810+// XXX: This does not use %std::intmax_t as the multiplier constant type because
    811+// this can have smaller than %__int128_t besides the signedness problem. Note
    812+// libstdc++ in GNU extension modes and libc++ also treats %__int128_t as
    813+// integral types, while libstdc++ in the standard modes does not, see
    814+// https://quuxplusone.github.io/blog/2019/02/28/is-int128-integral/. Just use
    815+// it as-is here for simplicity.
    816+template<typename _tDst, _tDst _vMul, typename _tSrc>
    817+auto
    818+checked_constant_multiply(_tSrc x) -> decltype(x * _vMul)
    819+{
    820+ // XXX: This should be usable for all integer-like types, not only the
    821+ // fundamental types.
    822+#if false
    823+ static_assert(std::is_integral<_tDst>(), "Invalid destination type found.");
    824+ static_assert(std::is_integral<_tSrc>(), "Invalid source type found.");
    825+#endif
    826+ using limits_t = std::numeric_limits<_tDst>;
    827+ const auto r(x * _vMul);
    828+ using _tRes = decltype(r);
    829+ using limits_r_t = std::numeric_limits<_tRes>;
    830+
    831+ return details::checked_conv_int<_tDst, _tRes, (std::float_t(
    832+ limits_t::max()) < std::float_t(limits_r_t::max())),
    833+ (std::float_t(limits_t::min()) > std::float_t(limits_r_t::min()))>()(r);
    834+}
    835+//!@}
    836+
    837+} // namespace ystdex;
    838+
    839+#endif
    840+
    diff -r 3fe9fa0c6127 -r 74e1025f0a02 YBase/include/ystdex/bit.hpp
    --- a/YBase/include/ystdex/bit.hpp Tue Feb 27 00:28:20 2024 +0800
    +++ b/YBase/include/ystdex/bit.hpp Fri Apr 19 22:42:25 2024 +0800
    @@ -1,5 +1,5 @@
    11 /*
    2- © 2015-2016, 2018-2023 FrankHB.
    2+ © 2015-2016, 2018-2024 FrankHB.
    33
    44 This file is part of the YSLib project, and may only be used, modified,
    55 and distributed under the terms of the YSLib project license.
    @@ -10,13 +10,13 @@
    1010 /*! \file bit.hpp
    1111 \ingroup YStandardEx
    1212 \brief 位操作。
    13-\version r1428
    13+\version r1432
    1414 \author FrankHB <frankhb1989@gmail.com>
    1515 \since build 245
    1616 \par 创建时间:
    1717 2021-12-18 22:57:19 +0800
    1818 \par 修改时间:
    19- 2023-12-20 20:45 +0800
    19+ 2024-04-06 15:23 +0800
    2020 \par 文本编码:
    2121 UTF-8
    2222 \par 模块名称:
    @@ -40,7 +40,7 @@
    4040 // std::uint_fast8_t, std::uint64_t, yconstraint;
    4141 #include "meta.hpp" // for CHAR_BIT, byte, enable_if_unsigned_t, size_t,
    4242 // size_t_;
    43-#include <limits> // for std::numeric_limits;
    43+#include <libdefect/limits.hpp> // for std::numeric_limits (with fixes);
    4444 // NOTE: See https://docs.microsoft.com/cpp/visual-cpp-language-conformance and
    4545 // https://docs.microsoft.com/cpp/preprocessor/predefined-macros.
    4646 #if (YB_IMPL_MSCPP >= 1925 && _MSVC_LANG >= 201907L) \
    @@ -478,7 +478,7 @@
    478478 yimpl(enable_if_unsigned_t)<_type, size_t>
    479479 floor_lb(_type x) ynothrowv
    480480 {
    481- return details::floor_lb_w(x, size_t_<sizeof(x) * CHAR_BIT>());
    481+ return details::floor_lb_w(x, bit_width_t<_type>());
    482482 }
    483483
    484484 /*!
    @@ -490,7 +490,7 @@
    490490 yimpl(enable_if_unsigned_t)<_type, size_t>
    491491 ceiling_lb(_type x) ynothrowv
    492492 {
    493- return 1 + details::floor_lb_w(x - 1, size_t_<sizeof(x) * CHAR_BIT>());
    493+ return 1 + details::floor_lb_w(x - 1, bit_width_t<_type>());
    494494 }
    495495
    496496
    diff -r 3fe9fa0c6127 -r 74e1025f0a02 YBase/include/ystdex/cast.hpp
    --- a/YBase/include/ystdex/cast.hpp Tue Feb 27 00:28:20 2024 +0800
    +++ b/YBase/include/ystdex/cast.hpp Fri Apr 19 22:42:25 2024 +0800
    @@ -1,5 +1,5 @@
    11 /*
    2- © 2010-2017, 2019-2023 FrankHB.
    2+ © 2010-2017, 2019-2024 FrankHB.
    33
    44 This file is part of the YSLib project, and may only be used, modified,
    55 and distributed under the terms of the YSLib project license.
    @@ -10,13 +10,13 @@
    1010 /*! \file cast.hpp
    1111 \ingroup YStandardEx
    1212 \brief C++ 转换模板。
    13-\version r1500
    13+\version r1503
    1414 \author FrankHB <frankhb1989@gmail.com>
    1515 \since build 175
    1616 \par 创建时间:
    1717 2010-12-15 08:13:18 +0800
    1818 \par 修改时间:
    19- 2023-12-17 00:07 +0800
    19+ 2024-04-06 15:27 +0800
    2020 \par 文本编码:
    2121 UTF-8
    2222 \par 模块名称:
    @@ -30,7 +30,7 @@
    3030 #include "type_op.hpp" // for decay_t, is_same, false_, true_, is_polymorphic,
    3131 // is_pointer, is_base_of, remove_cv_t, remove_pointer_t, and_, not_,
    3232 // have_common_nonempty_virtual_base, remove_rp, _t;
    33-#include <limits> // for std::numeric_limits;
    33+#include <libdefect/limits.hpp> // for std::numeric_limits (with fixes);
    3434 #include "exception.h" // for narrowing_error, std::addressof;
    3535 #include <typeinfo> // for std::bad_cast;
    3636 #include "cassert.h" // for yassume, YAssert;
    @@ -444,8 +444,8 @@
    444444
    445445 /*!
    446446 \brief 一般类型转换。
    447+\tparam _tDst 目标类型。
    447448 \tparam _tSrc 源类型。
    448-\tparam _tDst 目标类型。
    449449 \since build 175
    450450 \todo 扩展接受右值引用参数。
    451451
    diff -r 3fe9fa0c6127 -r 74e1025f0a02 YBase/include/ystdex/charconv.h
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/YBase/include/ystdex/charconv.h Fri Apr 19 22:42:25 2024 +0800
    @@ -0,0 +1,581 @@
    1+/*
    2+ © 2015, 2018, 2019, 2021, 2024 FrankHB.
    3+
    4+ This file is part of the YSLib project, and may only be used, modified,
    5+ and distributed under the terms of the YSLib project license.
    6+ By continuing to use, modify, or distribute this file you indicate that
    7+ you have read the license and understand and accept it fully.
    8+*/
    9+
    10+/*! \file charconv.h
    11+\ingroup YStandardEx
    12+\brief 数值的字符表示和转换操作。
    13+\version r1461
    14+\author FrankHB <frankhb1989@gmail.com>
    15+\since build 983
    16+\par 创建时间:
    17+ 2024-04-14 21:16:46 +0800
    18+\par 修改时间:
    19+ 2024-04-19 22:25 +0800
    20+\par 文本编码:
    21+ UTF-8
    22+\par 模块名称:
    23+ YStandardEx::CharacterConversion
    24+*/
    25+
    26+
    27+#ifndef YB_INC_ystdex_charconv_h_
    28+#define YB_INC_ystdex_charconv_h_ 1
    29+
    30+#include "arithmetic.hpp" // for internal "cstdint.hpp" (implying
    31+// <libdefect/limits.hpp>), make_width_int, std::numeric_limits (with fixes),
    32+// size_t, YB_VerifyIterator, yconstraint, ystdex::make_reverse_iterator,
    33+// enable_if_rep_in_digits10, ystdex::upow;
    34+#include <numeric> // for std::accumulate;
    35+
    36+namespace ystdex
    37+{
    38+
    39+//! \pre 静态断言:整数宽度非零且为 byte 类型宽度的整数倍。
    40+//!@{
    41+/*!
    42+\brief 使用迭代器对指定的范围中的字节表示的序列构造无符号整数。
    43+\pre 范围中的迭代器可解引用。
    44+\since build 603
    45+*/
    46+template<size_t _vWidth, typename _tIn>
    47+YB_ATTR_nodiscard YB_PURE typename make_width_int<_vWidth>::unsigned_type
    48+pack_uint(_tIn first, _tIn last) ynothrowv
    49+{
    50+ static_assert(_vWidth != 0 && _vWidth % std::numeric_limits<
    51+ unsigned char>::digits == 0, "Invalid integer width found.");
    52+ using utype = typename make_width_int<_vWidth>::unsigned_type;
    53+
    54+ YB_VerifyIterator(first);
    55+ return std::accumulate(first, last, utype(),
    56+ [] YB_LAMBDA_ANNOTATE((utype x, byte y), ynothrow, pure){
    57+ return
    58+ utype(x << std::numeric_limits<unsigned char>::digits | utype(y));
    59+ });
    60+}
    61+
    62+/*!
    63+\brief 分解无符号整数到迭代器对指定的字节范围。
    64+\pre 断言:范围中的迭代器可解引用。
    65+\since build 604
    66+*/
    67+template<size_t _vWidth, typename _tOut>
    68+void
    69+unpack_uint(typename ystdex::make_width_int<_vWidth>::unsigned_type value,
    70+ _tOut result) ynothrow
    71+{
    72+ static_assert(_vWidth != 0 && _vWidth % std::numeric_limits<
    73+ unsigned char>::digits == 0, "Invalid integer width found.");
    74+ auto n(_vWidth);
    75+
    76+ while(!(_vWidth < (n -= std::numeric_limits<unsigned char>::digits)))
    77+ {
    78+ YB_VerifyIterator(result);
    79+ *result = byte(value >> n);
    80+ ++result;
    81+ }
    82+}
    83+//!@}
    84+
    85+//! \pre 指针参数非空。
    86+//!@{
    87+/*!
    88+\brief 从字节缓冲区读取指定宽的大端序无符号整数。
    89+\since build 623
    90+*/
    91+template<size_t _vWidth>
    92+YB_ATTR_nodiscard YB_NONNULL(1) YB_PURE inline
    93+ typename make_width_int<_vWidth>::unsigned_type
    94+read_uint_be(const byte* buf) ynothrowv
    95+{
    96+ yconstraint(buf);
    97+ return ystdex::pack_uint<_vWidth>(buf,
    98+ buf + _vWidth / std::numeric_limits<unsigned char>::digits);
    99+}
    100+
    101+//! \since build 608
    102+//!@{
    103+//! \brief 从字节缓冲区读取指定宽的小端序无符号整数。
    104+template<size_t _vWidth>
    105+YB_ATTR_nodiscard YB_NONNULL(1) YB_PURE inline
    106+ typename make_width_int<_vWidth>::unsigned_type
    107+read_uint_le(const byte* buf) ynothrowv
    108+{
    109+ yconstraint(buf);
    110+ return ystdex::pack_uint<_vWidth>(ystdex::make_reverse_iterator(
    111+ buf + _vWidth / std::numeric_limits<unsigned char>::digits),
    112+ ystdex::make_reverse_iterator(buf));
    113+}
    114+
    115+/*!
    116+\brief 向字节缓冲区写入指定宽的大端序无符号整数。
    117+\since build 623
    118+*/
    119+template<size_t _vWidth>
    120+YB_NONNULL(1) inline void
    121+write_uint_be(byte* buf, typename make_width_int<_vWidth>::unsigned_type val)
    122+ ynothrowv
    123+{
    124+ yconstraint(buf);
    125+ ystdex::unpack_uint<_vWidth>(val, buf);
    126+}
    127+
    128+//! \brief 向字节缓冲区写入指定宽的小端序无符号整数。
    129+template<size_t _vWidth>
    130+YB_NONNULL(1) inline void
    131+write_uint_le(byte* buf, typename make_width_int<_vWidth>::unsigned_type val)
    132+ ynothrowv
    133+{
    134+ yconstraint(buf);
    135+ ystdex::unpack_uint<_vWidth>(val, ystdex::make_reverse_iterator(buf
    136+ + _vWidth / std::numeric_limits<unsigned char>::digits));
    137+}
    138+//!@}
    139+//!@}
    140+
    141+
    142+//! \since build 983
    143+//!@{
    144+/*!
    145+\ingroup traits
    146+\brief 倍增位数的数值写入特征。
    147+
    148+第一参数指定正整数值的位宽。
    149+第二参数指定整数类型。
    150+第三参数指定半数位宽的写入数值特征。
    151+第三参数应具有本特征相同种类的相同名称的可公开访问的成员。
    152+*/
    153+template<size_t _vLen, typename _type, class _tHalfTraits>
    154+struct double_digits_write_traits
    155+{
    156+ using value_type = _type;
    157+ using half_traits = _tHalfTraits;
    158+
    159+ //! \brief 除数:表示写入时使用的数值进位制。
    160+ static yconstexpr const value_type divisor
    161+ = value_type(half_traits::divisor) * half_traits::divisor;
    162+
    163+ /*!
    164+ \brief 写入第二参数的值的表示到第一参数指定的起始位置的缓冲区。
    165+
    166+ 第二参数应支持相同类型操作数的乘法、除法和模操作,且乘法操作结果可和值比较;
    167+ 但特化的实现可提供不同的 \c write 实现,不要求支持这些操作。
    168+ */
    169+ template<typename _tRandom>
    170+ YB_ATTR_always_inline static _tRandom
    171+ write(_tRandom buf, value_type val) ynothrowv
    172+ {
    173+ using half_type = typename half_traits::value_type;
    174+
    175+ yconstraint(val < divisor * divisor);
    176+ yunseq(half_traits::write(buf, half_type(val / divisor)),
    177+ half_traits::write(buf + _vLen / 2, half_type(val % divisor)));
    178+ return buf + _vLen;
    179+ }
    180+};
    181+
    182+
    183+/*!
    184+\ingroup transformation_traits
    185+\brief 取表示参数指定十进制数值位数需要的最小无符号整数类型。
    186+
    187+直接写入的 \c write 成员支持 8 、16 、32 和 64 位整数,可选支持 128 位整数。
    188+不在支持的类型中可表示的结果是非整数。
    189+*/
    190+template<size_t _vLen>
    191+using decimal_min_uint_t = conditional_t<_vLen <= 2, std::uint_fast8_t,
    192+ conditional_t<_vLen <= 4, std::uint16_t, conditional_t<_vLen <= 8,
    193+ std::uint32_t, conditional_t<_vLen <= 19, std::uint64_t,
    194+#if YB_Use_int128 > 0
    195+ conditional_t<_vLen <= 38, uint128_t, yimpl(void)>
    196+#else
    197+ yimpl(void)
    198+#endif
    199+ >>>>;
    200+
    201+
    202+namespace details
    203+{
    204+
    205+template<size_t, typename>
    206+struct decimal_write_traits;
    207+
    208+template<typename _type>
    209+struct decimal_write_traits<1, _type>
    210+{
    211+ using value_type = _type;
    212+};
    213+
    214+template<typename _type>
    215+struct decimal_write_traits<2, _type>
    216+{
    217+ using value_type = _type;
    218+
    219+ static yconstexpr const value_type divisor = 10;
    220+
    221+ template<typename _tRandom>
    222+ YB_ATTR_always_inline static _tRandom
    223+ write(_tRandom buf, value_type val) ynothrowv
    224+ {
    225+ yconstraint(val < divisor * divisor);
    226+ yunseq(buf[0] = '0' + char(val / divisor),
    227+ buf[1] = '0' + char(val % divisor));
    228+ return buf + 2;
    229+ }
    230+};
    231+
    232+// XXX: Many '% 10000' in LLVM/Clang is not optimal. See
    233+// https://bugs.llvm.org/show_bug.cgi?id=38217. No workaround is applied yet
    234+// for the QoI issue.
    235+template<size_t _vLen, typename _type>
    236+struct decimal_write_traits
    237+ : double_digits_write_traits<_vLen, decimal_min_uint_t<(_vLen + 1) / 2>,
    238+ decimal_write_traits<(_vLen + 1) / 2, _type>>
    239+{
    240+ using value_type = _type;
    241+};
    242+
    243+#define YB_Impl_charconv_decimal_write_func_head(_n, _q) \
    244+ _tRandom \
    245+ _n(_tRandom buf, _type val) _q
    246+#define YB_Impl_charconv_decimal_write_tmpl_vtype(_t) \
    247+ typename _type = typename _t::value_type, \
    248+ yimpl(typename = enable_if_rep_in_digits10<_t::width, _type>)
    249+
    250+template<class _tWriter, size_t _vBase, typename _tRandom,
    251+ YB_Impl_charconv_decimal_write_tmpl_vtype(_tWriter::traits_type)>
    252+YB_Impl_charconv_decimal_write_func_head(write_decimal_base_addend, ynothrowv)
    253+{
    254+ static_assert(_tWriter::traits_type::width > _vBase,
    255+ "Invalid widths found.");
    256+ using write_a_t = typename _tWriter::template
    257+ rebind_t<_tWriter::traits_type::width - _vBase>;
    258+ using write_b_t = typename _tWriter::template rebind_t<_vBase>;
    259+ using traits_b_t = typename write_b_t::traits_type;
    260+ using value_b_t = typename traits_b_t::value_type;
    261+
    262+ static yconstexpr const _type d(ystdex::upow(_type(10), _vBase));
    263+
    264+ return val < d ? write_b_t()(buf, value_b_t(val))
    265+ : traits_b_t::write(write_a_t()(buf, typename
    266+ write_a_t::traits_type::value_type(val / d)), value_b_t(val % d));
    267+}
    268+
    269+} // namespace details;
    270+
    271+/*!
    272+\ingroup traits
    273+\brief 十进制连续数值写入特征。
    274+
    275+第一参数为 decimal_min_uint_t 支持位数的正整数。
    276+*/
    277+template<size_t _vLen, typename _type = decimal_min_uint_t<_vLen>>
    278+struct decimal_write_traits : details::decimal_write_traits<_vLen, _type>
    279+{
    280+ template<size_t _vOther>
    281+ using rebind_t = decimal_write_traits<_vOther>;
    282+
    283+ static yconstexpr const size_t width = _vLen;
    284+};
    285+
    286+
    287+/*!
    288+\brief 写十进制到第一参数指定的输出随机迭代器作为起始位置的缓冲区中。
    289+
    290+第一模板参数指定十进制数字的个数,即输出的最大长度。
    291+当前使用默认特征支持的特化范围是 1~17 。
    292+可能需要指定特征支持的特化范围是 19 、21 、32 、36 和 38 。
    293+这些范围可涵盖以下格式转换后的蕴含连续十进制数字序列的输出需求:
    294+ 不大于 64 位的二进制浮点数尾数。
    295+ 113 位的二进制浮点数尾数。
    296+ 128 位整数。
    297+*/
    298+//!@{
    299+template<size_t _vLen, class = decimal_write_traits<_vLen>>
    300+struct decimal_write;
    301+
    302+#define YB_Impl_charconv_decimal_write_tmpl_head(_v) \
    303+ template<class _tTraits> \
    304+ struct decimal_write<_v, _tTraits> \
    305+ { \
    306+ using traits_type = _tTraits; \
    307+ template<size_t _vOther> \
    308+ using rebind_t = decimal_write<_vOther, \
    309+ typename traits_type::template rebind_t<_vOther>>;
    310+
    311+#define YB_Impl_charconv_decimal_write_head(_v) \
    312+ YB_Impl_charconv_decimal_write_tmpl_head(_v) \
    313+ template<typename _tRandom, \
    314+ YB_Impl_charconv_decimal_write_tmpl_vtype(_tTraits)> \
    315+ YB_Impl_charconv_decimal_write_func_head(operator(), const ynothrowv) \
    316+ {
    317+#define YB_Impl_charconv_decimal_write_tail } \
    318+ };
    319+
    320+//! \since functors
    321+//!@{
    322+YB_Impl_charconv_decimal_write_head(1)
    323+ yconstraint(val < 10);
    324+ *buf = '0' + char(val);
    325+ return ++buf;
    326+YB_Impl_charconv_decimal_write_tail
    327+
    328+YB_Impl_charconv_decimal_write_head(2)
    329+ using write1_t = rebind_t<1>;
    330+
    331+ yconstraint(val < 100);
    332+ return YB_UNLIKELY(val < 10)
    333+ ? write1_t()(buf, typename write1_t ::traits_type::value_type(val))
    334+ : _tTraits::write(buf, typename _tTraits::value_type(val));
    335+YB_Impl_charconv_decimal_write_tail
    336+
    337+YB_Impl_charconv_decimal_write_head(3)
    338+ yconstraint(val < 1000);
    339+ return details::write_decimal_base_addend<rebind_t<3>, 2>(buf, val);
    340+YB_Impl_charconv_decimal_write_tail
    341+
    342+YB_Impl_charconv_decimal_write_head(4)
    343+ using write2_t = rebind_t<2>;
    344+ using traits2_t = typename write2_t::traits_type;
    345+ using value2_t = typename traits2_t::value_type;
    346+
    347+ yconstraint(val < 10000);
    348+ if(val < 100)
    349+ return write2_t()(buf, value2_t(val));
    350+#if true
    351+ // NOTE: 3-4 digits: aabb.
    352+ const auto aa(val / 100);
    353+
    354+ if(aa < 10)
    355+ {
    356+ using write1_t = rebind_t<1>;
    357+
    358+ write1_t()(buf, typename write1_t::traits_type::value_type(aa));
    359+ }
    360+ else
    361+ {
    362+ traits2_t::write(buf, aa);
    363+ ++buf;
    364+ }
    365+ return traits2_t::write(++buf, val % 100);
    366+#else
    367+ // NOTE: Any optimized implemenations shall be equivalent to this.
    368+ return traits2_t::write(write2_t()(buf, typename
    369+ write2_t::traits_type::value_type(val / 100)), value2_t(val % 100));
    370+#endif
    371+YB_Impl_charconv_decimal_write_tail
    372+
    373+YB_Impl_charconv_decimal_write_head(5)
    374+ yconstraint(val < 100000);
    375+ return details::write_decimal_base_addend<rebind_t<5>, 4>(buf, val);
    376+YB_Impl_charconv_decimal_write_tail
    377+
    378+YB_Impl_charconv_decimal_write_head(6)
    379+ yconstraint(val < 1000000);
    380+ return details::write_decimal_base_addend<rebind_t<6>, 4>(buf, val);
    381+YB_Impl_charconv_decimal_write_tail
    382+
    383+YB_Impl_charconv_decimal_write_head(7)
    384+ yconstraint(val < 10000000);
    385+ return details::write_decimal_base_addend<rebind_t<7>, 4>(buf, val);
    386+YB_Impl_charconv_decimal_write_tail
    387+
    388+YB_Impl_charconv_decimal_write_head(8)
    389+ yconstraint(val < 100000000);
    390+ return details::write_decimal_base_addend<rebind_t<8>, 4>(buf, val);
    391+YB_Impl_charconv_decimal_write_tail
    392+
    393+YB_Impl_charconv_decimal_write_head(9)
    394+ yconstraint(val < 1000000000);
    395+ return details::write_decimal_base_addend<rebind_t<9>, 8>(buf, val);
    396+YB_Impl_charconv_decimal_write_tail
    397+
    398+YB_Impl_charconv_decimal_write_head(10)
    399+ yconstraint(val < 10000000009);
    400+ return details::write_decimal_base_addend<rebind_t<10>, 8>(buf, val);
    401+YB_Impl_charconv_decimal_write_tail
    402+
    403+YB_Impl_charconv_decimal_write_head(11)
    404+ yconstraint(val < 100000000000);
    405+ return details::write_decimal_base_addend<rebind_t<11>, 8>(buf, val);
    406+YB_Impl_charconv_decimal_write_tail
    407+
    408+YB_Impl_charconv_decimal_write_head(12)
    409+ yconstraint(val < 1000000000000);
    410+ return details::write_decimal_base_addend<rebind_t<12>, 8>(buf, val);
    411+YB_Impl_charconv_decimal_write_tail
    412+
    413+YB_Impl_charconv_decimal_write_head(13)
    414+ yconstraint(val < 10000000000000);
    415+ return details::write_decimal_base_addend<rebind_t<13>, 8>(buf, val);
    416+YB_Impl_charconv_decimal_write_tail
    417+
    418+YB_Impl_charconv_decimal_write_head(14)
    419+ yconstraint(val < 100000000000000);
    420+ return details::write_decimal_base_addend<rebind_t<14>, 8>(buf, val);
    421+YB_Impl_charconv_decimal_write_tail
    422+
    423+YB_Impl_charconv_decimal_write_head(15)
    424+ yconstraint(val < 1000000000000000);
    425+ return details::write_decimal_base_addend<rebind_t<15>, 8>(buf, val);
    426+YB_Impl_charconv_decimal_write_tail
    427+
    428+YB_Impl_charconv_decimal_write_head(16)
    429+ yconstraint(val < 10000000000000000);
    430+ return details::write_decimal_base_addend<rebind_t<16>, 8>(buf, val);
    431+YB_Impl_charconv_decimal_write_tail
    432+
    433+YB_Impl_charconv_decimal_write_head(17)
    434+ yconstraint(val < 100000000000000000);
    435+
    436+#if true
    437+ using write1_t = rebind_t<1>;
    438+ using write16_t = rebind_t<16>;
    439+
    440+ if(val < 10000000000000000)
    441+ return
    442+ write16_t()(buf, typename write16_t::traits_type::value_type(val));
    443+
    444+ // NOTE: This prevents 64-bit divisions with more than 32-bit divisors as
    445+ // possible.
    446+ using traits8_t = typename rebind_t<8>::traits_type;
    447+ using value8_t = typename traits8_t::value_type;
    448+ // NOTE: 17 digits.
    449+ const auto hi(val / 100000000);
    450+ const auto one(typename traits8_t::value_type(hi / 100000000));
    451+
    452+ write1_t()(buf, typename write1_t::traits_type::value_type(one));
    453+ buf += one > 0 ? 1 : 0;
    454+ yunseq(traits8_t::write(buf, value8_t(hi % 100000000)),
    455+ traits8_t::write(buf + 8, value8_t(val % 100000000)));
    456+ return buf + 16;
    457+#else
    458+ // NOTE: Any optimized implemenations shall be equivalent to this.
    459+ return details::write_decimal_base_addend<rebind_t<17>, 16>(buf, val);
    460+#endif
    461+YB_Impl_charconv_decimal_write_tail
    462+
    463+// XXX: The following specializations may require non-defualt traits due to
    464+// probably lacking of support of integers greater than 64-bit. Nevertheless,
    465+// the constant division only uses divisors representable in 64-bit.
    466+// NOTE: This can be used for 64-bit unsigned integers and 55~64-bit binary
    467+// floating-point mantissas.
    468+YB_Impl_charconv_decimal_write_head(19)
    469+ using write8_t = rebind_t<8>;
    470+ using traits8_t = typename write8_t::traits_type;
    471+ using value8_t = typename traits8_t::value_type;
    472+
    473+ if(val < 100000000)
    474+ return write8_t()(buf, value8_t(val));
    475+
    476+ const auto hi(val / 100000000);
    477+
    478+ return traits8_t::write(hi < 100000000 ? write8_t()(buf, value8_t(hi))
    479+ : traits8_t::write(write8_t()(buf, value8_t(hi / 100000000)),
    480+ value8_t(hi % 100000000)), value8_t(val % 100000000));
    481+YB_Impl_charconv_decimal_write_tail
    482+
    483+// XXX: The following specializations may require additional trait functions to
    484+// support divisions wider than 64-bit.
    485+// NOTE: Requires %_tTraits::div10<4> to support division of type (e.g. 128-bit
    486+// unsigned integer) divided by 10000.
    487+// NOTE: This can be used for 64-bit binary floating-point mantissas.
    488+YB_Impl_charconv_decimal_write_head(21)
    489+ using write17_t = rebind_t<17>;
    490+ using traits4_t = typename rebind_t<4>::traits_type;
    491+ using value17_t = typename write17_t::traits_type::value_type;
    492+
    493+ yconstraint(val
    494+ < typename _tTraits::value_type(100000000000U) * 10000000000U);
    495+ if(val < 100000000000000000)
    496+ return write17_t()(buf, value17_t(val));
    497+
    498+ // NOTE: 18-21 digits.
    499+ const auto hi(_tTraits::template div10<4>(val));
    500+
    501+ return traits4_t::write(write17_t()(buf, value17_t(hi)),
    502+ typename traits4_t::value_type(val - hi * 10000));
    503+YB_Impl_charconv_decimal_write_tail
    504+
    505+// NOTE: This can be used for 36-bit sequences below.
    506+YB_Impl_charconv_decimal_write_head(32)
    507+ using write16_t = rebind_t<16>;
    508+ using traits16_t = typename write16_t::traits_type;
    509+ using value16_t = typename traits16_t::value_type;
    510+
    511+ yconstraint(val
    512+ < typename _tTraits::value_type(10000000000000000) * 10000000000000000);
    513+ return val < 100000000000000000 ? write16_t()(buf, value16_t(val))
    514+ : traits16_t::write(write16_t()(buf, value16_t(val
    515+ / 10000000000000000)), value16_t(val % 10000000000000000));
    516+YB_Impl_charconv_decimal_write_tail
    517+
    518+// NOTE: This can be used for 113-bit binary floating-point mantissas.
    519+YB_Impl_charconv_decimal_write_head(36)
    520+ using write32_t = rebind_t<32>;
    521+ const auto
    522+ d(typename _tTraits::value_type(10000000000000000) * 10000000000000000);
    523+
    524+ yconstraint(val < d * 10000U);
    525+ return val < d ? write32_t()(buf, val) : write32_t::traits_type::write(
    526+ rebind_t<4>()(buf, val / d), val % d);
    527+YB_Impl_charconv_decimal_write_tail
    528+
    529+// NOTE: This can be used for 128-bit unsigned integers.
    530+YB_Impl_charconv_decimal_write_head(38)
    531+ using write32_t = rebind_t<32>;
    532+ const auto
    533+ d(typename _tTraits::value_type(10000000000000000) * 10000000000000000);
    534+
    535+ yconstraint(val < d * 1000000U);
    536+ return val < d ? write32_t()(buf, val) : write32_t::traits_type::write(
    537+ rebind_t<6>()(buf, val / d), val % d);
    538+YB_Impl_charconv_decimal_write_tail
    539+#undef YB_Impl_charconv_decimal_write_tail
    540+#undef YB_Impl_charconv_decimal_write_tmpl_head
    541+//!@}
    542+
    543+template<size_t _vLen, typename _tRandom, class _tTraits = decimal_write_traits<
    544+ _vLen>, YB_Impl_charconv_decimal_write_tmpl_vtype(_tTraits)>
    545+YB_Impl_charconv_decimal_write_func_head(write_decimal, ynothrowv)
    546+{
    547+ return decimal_write<_vLen>()(buf, val);
    548+}
    549+#undef YB_Impl_charconv_decimal_write_tmpl_vtype
    550+#undef YB_Impl_charconv_decimal_write_func_head
    551+//!@}
    552+
    553+
    554+//! \brief 向第一参数指定的缓冲区写入第二参数指定的十进制整数值。
    555+template<typename _tRandom, typename _type>
    556+inline _tRandom
    557+write_decimal_integer(_tRandom buf, _type val)
    558+{
    559+ static yconstexpr const _type d(ystdex::upow(_type(10),
    560+ size_t(std::numeric_limits<_type>::digits10)));
    561+
    562+ if(val >= d)
    563+ {
    564+ using write1_t = decimal_write<1>;
    565+
    566+ write1_t::traits_type::value_type q(val / d);
    567+
    568+ YAssert(q > 0 && q < 10, "Invalid implemenation found.");
    569+
    570+ write1_t()(buf, q);
    571+ yunseq(val %= d, ++buf);
    572+ }
    573+ return
    574+ ystdex::write_decimal<std::numeric_limits<_type>::digits10>(buf, val);
    575+}
    576+//!@}
    577+
    578+} // namespace ystdex;
    579+
    580+#endif
    581+
    diff -r 3fe9fa0c6127 -r 74e1025f0a02 YBase/include/ystdex/chrono.hpp
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/YBase/include/ystdex/chrono.hpp Fri Apr 19 22:42:25 2024 +0800
    @@ -0,0 +1,742 @@
    1+/*
    2+ © 2024 FrankHB.
    3+
    4+ This file is part of the YSLib project, and may only be used, modified,
    5+ and distributed under the terms of the YSLib project license.
    6+ By continuing to use, modify, or distribute this file you indicate that
    7+ you have read the license and understand and accept it fully.
    8+*/
    9+
    10+/*! \file chrono.hpp
    11+\ingroup YStandardEx
    12+\brief ISO C++ 日期和时间接口扩展。
    13+\version r741
    14+\author FrankHB <frankhb1989@gmail.com>
    15+\since build 983
    16+\par 创建时间:
    17+ 2024-03-22 23:53:00 +0800
    18+\par 修改时间:
    19+ 2024-04-13 02:25 +0800
    20+\par 文本编码:
    21+ UTF-8
    22+\par 模块名称:
    23+ YStandardEx::Chrono
    24+*/
    25+
    26+
    27+#ifndef YB_INC_ystdex_chrono_hpp_
    28+#define YB_INC_ystdex_chrono_hpp_ 1
    29+
    30+#include "type_op.hpp" // for false_, void_t, and_, is_same, enable_if, true_,
    31+// is_instance_of, vseq::_a, enable_if_t, is_unsigned, or_,
    32+// is_floating_point, is_class, YB_HAS_NOEXCEPT, bool_, std::declval;
    33+#include "arithmetic.hpp" // for internal "cstdint.hpp" (implying
    34+// <libdefect/limits.hpp>), std::numeric_limits (with fixes),
    35+// is_unbounded_number, throw_underflow_error, throw_overflow_error,
    36+// ystdex::checked_constant_multiply, intmax_t;
    37+#include <chrono> // for std::chrono;
    38+#include <ratio> // for std::ratio_mutiply, std::ratio_divide, std::nano;
    39+#include "ctime.h" // for is_timespec_like;
    40+#include <cmath> // for std::float_t;
    41+
    42+namespace ystdex
    43+{
    44+
    45+//! \since build 983
    46+namespace chrono
    47+{
    48+
    49+inline namespace cpp2011
    50+{
    51+
    52+using std::chrono::duration;
    53+
    54+using std::chrono::time_point;
    55+
    56+using std::chrono::treat_as_floating_point;
    57+using std::chrono::duration_values;
    58+
    59+using std::chrono::nanoseconds;
    60+using std::chrono::microseconds;
    61+using std::chrono::milliseconds;
    62+using std::chrono::seconds;
    63+using std::chrono::minutes;
    64+using std::chrono::hours;
    65+
    66+using std::chrono::duration_cast;
    67+
    68+using std::chrono::nanoseconds;
    69+using std::chrono::microseconds;
    70+using std::chrono::milliseconds;
    71+using std::chrono::seconds;
    72+using std::chrono::minutes;
    73+using std::chrono::hours;
    74+using std::chrono::nanoseconds;
    75+using std::chrono::nanoseconds;
    76+using std::chrono::nanoseconds;
    77+
    78+using std::chrono::time_point_cast;
    79+
    80+using std::chrono::system_clock;
    81+using std::chrono::steady_clock;
    82+using std::chrono::high_resolution_clock;
    83+
    84+} // inline namespace cpp2011;
    85+
    86+// NOTE: This requires the support of some features of WG21 P0355R7, without
    87+// some features interfering ABI stability. See
    88+// https://docs.microsoft.com/cpp/visual-cpp-language-conformance,
    89+// https://docs.microsoft.com/cpp/preprocessor/predefined-macros and
    90+// https://learn.microsoft.com/cpp/overview/compiler-versions
    91+#if (YB_IMPL_MSCPP >= 1929 && _MSC_FULL_VER >= 192930129L \
    92+ && _MSVC_LANG >= 202002L) || __cplusplus >= 202002L
    93+# define YB_Impl_Chrono_has_cpp20_chrono_stable true
    94+#else
    95+# define YB_Impl_Chrono_has_cpp20_chrono_stable false
    96+#endif
    97+#if YB_Impl_Chrono_has_cpp20_chrono_stable && !defined _LIBCPP_VERSION
    98+# define YB_Impl_Chrono_has_cpp20_chrono_is_clock true
    99+#else
    100+# define YB_Impl_Chrono_has_cpp20_chrono_is_clock false
    101+#endif
    102+
    103+namespace details
    104+{
    105+
    106+#if !YB_Impl_Chrono_has_cpp20_chrono_is_clock
    107+template<typename, typename = void>
    108+struct is_clock : false_
    109+{};
    110+
    111+template<typename _type>
    112+struct is_clock<_type, void_t<typename _type::rep, typename _type::period,
    113+ // XXX: ISO C++20 [time.traits.is.clock]/1 reuires member %time_point as a
    114+ // type, but Cpp17Clock requirements requires more on this type. Use its
    115+ // member to provide stricter check (see below).
    116+ typename _type::druation, typename _type::time_point::duration,
    117+ decltype(_type::is_steady), decltype(_type::now())>>
    118+ // XXX: Follows libstdc++ here for unspecified checks on ISO C++20
    119+ // [time.traits.is.clock]/1. Note %_type here shall be complete, which is
    120+ // implied by the requirements on nested members, so potentionally
    121+ // overloaded '&' can be used.
    122+ : and_<is_same<typename _type::duration, duration<typename _type::rep,
    123+ typename _type::period>>, is_same<typename _type::time_point::duration,
    124+ typename _type::duration>, is_same<decltype(&_type::is_steady),
    125+ const bool*>, is_same<decltype(_type::now()), typename _type::time_point>>
    126+{};
    127+#endif
    128+
    129+template<typename _type, typename = void>
    130+struct unchecked_rep : treat_as_floating_point<_type>
    131+{};
    132+
    133+template<typename _type>
    134+struct unchecked_rep<_type, enable_if<is_unbounded_number<_type>{}>> : true_
    135+{};
    136+
    137+} // namespace details;
    138+
    139+inline namespace cpp2020
    140+{
    141+
    142+#if YB_Impl_Chrono_has_cpp20_chrono_is_clock
    143+using std::chrono::is_clock;
    144+#else
    145+//! \ingroup YBase_replacement_features unary_type_traits
    146+template<typename _tClock>
    147+struct is_clock : details::is_clock<_tClock>
    148+{};
    149+#endif
    150+
    151+#if __cplusplus >= 202002L
    152+using std::chrono::days;
    153+using std::chrono::weeks;
    154+using std::chrono::years;
    155+using std::chrono::months;
    156+#else
    157+// XXX: The representation type is enough here by specification. Use %hours
    158+// because it is just shortest. Ignore any other possibility of using different
    159+// types in ISO C++11 modes onwards (if supported by the implementation).
    160+using days = duration<hours::rep,
    161+ std::ratio_multiply<std::ratio<24>, hours::period>>;
    162+using weeks = duration<hours::rep,
    163+ std::ratio_multiply<std::ratio<7>, hours::period>>;
    164+using years = duration<hours::rep,
    165+ std::ratio_multiply<std::ratio<146097, 400>, hours::period>>;
    166+using months = duration<hours::rep,
    167+ std::ratio_divide<years::period, std::ratio<12>>>;
    168+#endif
    169+
    170+#if YB_Impl_Chrono_has_cpp20_chrono_stable
    171+using std::chrono::sys_time;
    172+using std::chrono::sys_seconds;
    173+using std::chrono::sys_days;
    174+#else
    175+//! \ingroup YBase_replacement_features
    176+//!@{
    177+template<class _tDuration>
    178+using sys_time = time_point<system_clock, _tDuration>;
    179+
    180+using sys_seconds = sys_time<seconds>;
    181+
    182+using sys_days = sys_time<days>;
    183+//!@}
    184+#endif
    185+
    186+#undef YB_Impl_Chrono_has_cpp20_chrono_is_clock
    187+#undef YB_Impl_Chrono_has_cpp20_chrono_stable
    188+
    189+} // inline namespace cpp2020;
    190+
    191+//! \ingroup unary_type_traits
    192+//!@{
    193+//! \brief 判断指定类型是否是时间间隔。
    194+template<typename _type>
    195+struct is_duration : is_instance_of<_type, vseq::_a<duration>>
    196+{};
    197+
    198+//! \brief 判断指定类型是否是时间点。
    199+template<typename _type>
    200+struct is_time_point : is_instance_of<_type, vseq::_a<time_point>>
    201+{};
    202+//!@}
    203+
    204+/*!
    205+\ingroup trasformation_traits
    206+\sa enable_if_t
    207+*/
    208+//!@{
    209+//! \sa is_duration
    210+template<typename _type>
    211+using enable_if_duration_t = enable_if_t<is_duration<_type>{}, _type>;
    212+
    213+//! \sa is_time_point
    214+template<typename _type>
    215+using enable_if_time_point_t = enable_if_t<is_time_point<_type>{}, _type>;
    216+//!@}
    217+
    218+/*!
    219+\ingroup customization_points unary_type_traits
    220+\brief 指定不需要检查溢出。
    221+\sa treat_as_floating_point
    222+
    223+指定不视为可溢出而需要检查的表示类型。
    224+以下类型默认视为不需要检查溢出:
    225+ 满足 treat_as_floating_point 的类型。
    226+ 特化 std::numeric_limits 为无界数的类型。
    227+程序可特化类型改变以上默认行为。
    228+*/
    229+template<typename _type>
    230+struct unchecked_rep : details::unchecked_rep<_type>
    231+{};
    232+
    233+
    234+/*!
    235+\tparam _tTimeSpec 转换的结果类型,和 ISO C++17 std::timespec 兼容。
    236+\tparam _tRep 时间间隔的表示类型。
    237+\note 兼容指具有同名的整数类型成员且涵盖表示范围。
    238+\see WG21 P0972R0 。
    239+*/
    240+//!@{
    241+//! \brief 转换纳秒计数的时间间隔和 ISO C++17 \c std::timespec 兼容的类型的值。
    242+template<class _tTimeSpec, typename _tRep>
    243+YB_ATTR_nodiscard YB_STATELESS yconstfn_relaxed
    244+ enable_if_t<is_timespec_like<_tTimeSpec>{}, _tTimeSpec>
    245+ns_to_timespec(duration<_tRep, std::nano> ns) ynothrow
    246+{
    247+ static_assert(duration_values<_tRep>::max() >= std::nano::den - 1,
    248+ "Invalid representation type for nanoseconds found.");
    249+ const auto s(duration_cast<duration<_tRep>>(ns));
    250+ _tTimeSpec ts;
    251+ using ts_sec_t = decltype(ts.tv_sec);
    252+ // XXX: Non-throwing, see $2024-03 %Documentation::Workflow.
    253+ const auto ts_sec_max(duration_values<ts_sec_t>::max());
    254+ const auto c(s.count());
    255+
    256+ if(c < ts_sec_max)
    257+ yunseq(ts.tv_sec = ts_sec_t(c),
    258+ ts.tv_nsec = decltype(ts.tv_nsec)((ns - s).count()));
    259+ else
    260+ yunseq(ts.tv_sec = ts_sec_max, ts.tv_nsec = std::nano::den - 1);
    261+ return ts;
    262+}
    263+
    264+/*!
    265+\brief ISO C++17 \c std::timespec 兼容的类型的值到纳秒计数的时间间隔。
    266+\pre 断言:纳秒数小于 \c std::nano::den 。
    267+*/
    268+template<typename _tRep, class _tTimeSpec>
    269+YB_ATTR_nodiscard YB_STATELESS yconstfn_relaxed
    270+ enable_if_t<is_timespec_like<_tTimeSpec>{}, duration<_tRep, std::nano>>
    271+timespec_to_ns(_tTimeSpec ts)
    272+{
    273+ static_assert(duration_values<_tRep>::max() >= std::nano::den - 1,
    274+ "Invalid representation type for nanoseconds found.");
    275+ using ns_t = duration<_tRep, std::nano>;
    276+
    277+ YAssert(ts.tv_nsec < std::nano::den, "Invalid nanoseconds count found.");
    278+ return duration_cast<ns_t>(duration<_tRep>(ts.tv_sec))
    279+ + ns_t(ts.tv_nsec);
    280+}
    281+//!@}
    282+
    283+
    284+namespace details
    285+{
    286+
    287+template<typename _tTo, typename _tFrom, bool = is_unsigned<_tTo>{}>
    288+struct min_rep_check final
    289+{
    290+ static void
    291+ check_underflow(const _tFrom& x)
    292+ {
    293+ if(YB_UNLIKELY(x < duration_values<_tTo>::min()))
    294+ throw_underflow_error("Value underflow detected in cast.");
    295+ }
    296+};
    297+
    298+template<typename _tTo, typename _tFrom>
    299+struct min_rep_check<_tTo, _tFrom, true> final
    300+{
    301+ static void
    302+ check_underflow(const _tFrom& x)
    303+ {
    304+ // XXX: Duration representations are required having zero values. More
    305+ // general types may be not, and the %_tFrom may be non-integral (but
    306+ // an integer-like class). So this is kept here instead
    307+ // %CStandardInteger.
    308+ if(YB_UNLIKELY(x < duration_values<_tFrom>::zero()))
    309+ throw_underflow_error("Value underflow detected in cast.");
    310+ }
    311+};
    312+
    313+
    314+template<typename _tTo, typename _tFrom>
    315+struct max_rep_check final
    316+{
    317+ static void
    318+ check_overflow(const _tFrom& x)
    319+ {
    320+ if(YB_UNLIKELY(x > duration_values<_tTo>::max()))
    321+ throw_overflow_error("Value overflow detected in cast.");
    322+ }
    323+};
    324+
    325+
    326+//! \ingroup functors
    327+//!@{
    328+template<typename _tTo, typename _tFrom, bool, bool>
    329+struct checked_rep_int
    330+{
    331+ YB_ATTR_nodiscard YB_PURE _tTo
    332+ operator()(const _tFrom& x) const
    333+ {
    334+ max_rep_check<_tTo, _tFrom>::check_overflow(x);
    335+ min_rep_check<_tTo, _tFrom>::check_underflow(x);
    336+ return static_cast<_tTo>(x);
    337+ }
    338+};
    339+
    340+template<typename _tTo, typename _tFrom>
    341+struct checked_rep_int<_tTo, _tFrom, true, false>
    342+{
    343+ YB_ATTR_nodiscard YB_PURE _tTo
    344+ operator()(const _tFrom& x) const
    345+ {
    346+ max_rep_check<_tTo, _tFrom>::check_overflow(x);
    347+ return static_cast<_tTo>(x);
    348+ }
    349+};
    350+
    351+template<typename _tTo, typename _tFrom>
    352+struct checked_rep_int<_tTo, _tFrom, false, true>
    353+{
    354+ YB_ATTR_nodiscard YB_PURE _tTo
    355+ operator()(const _tFrom& x) const
    356+ {
    357+ min_rep_check<_tTo, _tFrom>::check_underflow(x);
    358+ return static_cast<_tTo>(x);
    359+ }
    360+};
    361+
    362+template<typename _tTo, typename _tFrom>
    363+struct checked_rep_int<_tTo, _tFrom, false, false>
    364+{
    365+ // XXX: Only conversions without exception are supported.
    366+ YB_ATTR_nodiscard YB_PURE _tTo
    367+ operator()(const _tFrom& x) const ynothrow
    368+ {
    369+ return static_cast<_tTo>(x);
    370+ }
    371+};
    372+//!@}
    373+
    374+} // namespace details;
    375+
    376+//! \ingroup functors
    377+//!@{
    378+//! \brief 检查溢出的表示转换函数。
    379+template<typename _tTo, typename _tFrom, bool = treat_as_floating_point<_tTo>{}>
    380+struct checked_rep_caster
    381+{
    382+ // XXX: Only conversions without exception are supported.
    383+ YB_PURE yconstfn _tTo
    384+ operator()(const _tFrom& x) const ynothrow
    385+ {
    386+ return static_cast<_tTo>(x);
    387+ }
    388+};
    389+
    390+template<typename _tTo, typename _tFrom>
    391+struct checked_rep_caster<_tTo, _tFrom, false>
    392+ : details::checked_rep_int<_tTo, _tFrom, (std::float_t(duration_values<_tTo>
    393+ ::max()) < std::float_t(duration_values<_tFrom>::max())),
    394+ (std::float_t(duration_values<_tTo>::min())
    395+ > std::float_t(duration_values<_tFrom>::min()))>
    396+{};
    397+
    398+template<typename _tTo>
    399+struct checked_rep_caster<_tTo, _tTo, false>
    400+{
    401+ YB_PURE yconstfn _tTo
    402+ operator()(const _tTo& x) const ynothrow
    403+ {
    404+ return x;
    405+ }
    406+};
    407+
    408+
    409+//! \brief 检查上溢的表示转换函数。
    410+template<typename _tTo, typename _tFrom, bool = treat_as_floating_point<_tTo>{}>
    411+struct checked_max_rep_caster
    412+{
    413+ // XXX: Ditto.
    414+ YB_PURE yconstfn _tTo
    415+ operator()(const _tFrom& x) const ynothrow
    416+ {
    417+ return static_cast<_tTo>(x);
    418+ }
    419+};
    420+
    421+template<typename _tTo, typename _tFrom>
    422+struct checked_max_rep_caster<_tTo, _tFrom, false>
    423+ : details::checked_rep_int<_tTo, _tFrom, (std::float_t(duration_values<_tTo>
    424+ ::max()) < std::float_t(duration_values<_tFrom>::max())), false>
    425+{};
    426+
    427+template<typename _tTo>
    428+struct checked_max_rep_caster<_tTo, _tTo, false>
    429+{
    430+ YB_PURE yconstfn _tTo
    431+ operator()(const _tTo& x) const ynothrow
    432+ {
    433+ return x;
    434+ }
    435+};
    436+
    437+
    438+//! \brief 检查下溢的表示转换函数。
    439+template<typename _tTo, typename _tFrom, bool = treat_as_floating_point<_tTo>{}>
    440+struct checked_min_rep_caster
    441+{
    442+ // XXX: Ditto.
    443+ YB_PURE yconstfn _tTo
    444+ operator()(const _tFrom& x) const ynothrow
    445+ {
    446+ return static_cast<_tTo>(x);
    447+ }
    448+};
    449+
    450+template<typename _tTo, typename _tFrom>
    451+struct checked_min_rep_caster<_tTo, _tFrom, false>
    452+ : details::checked_rep_int<_tTo, _tFrom, false, (std::float_t(
    453+ duration_values<_tTo>::min())
    454+ > std::float_t(duration_values<_tFrom>::min()))>
    455+{};
    456+
    457+template<typename _tTo>
    458+struct checked_min_rep_caster<_tTo, _tTo, false>
    459+{
    460+ YB_PURE yconstfn _tTo
    461+ operator()(const _tTo& x) const ynothrow
    462+ {
    463+ return x;
    464+ }
    465+};
    466+//!@}
    467+
    468+
    469+/*!
    470+\brief 检查溢出的表示转换。
    471+\tparam _tDst 目标类型。
    472+\tparam _tSrc 源类型。
    473+*/
    474+//!@{
    475+template<typename _tDst, typename _tSrc,
    476+ bool _vAsFloat = treat_as_floating_point<_tDst>{}>
    477+yconstfn _tDst
    478+checked_rep_cast(_tSrc v)
    479+{
    480+ return checked_rep_caster<_tDst, _tSrc, _vAsFloat>()(v);
    481+}
    482+
    483+template<typename _tDst, typename _tSrc,
    484+ bool _vAsFloat = treat_as_floating_point<_tDst>{}>
    485+yconstfn _tDst
    486+checked_max_rep_cast(_tSrc v)
    487+{
    488+ return checked_max_rep_caster<_tDst, _tSrc, _vAsFloat>()(v);
    489+}
    490+
    491+template<typename _tDst, typename _tSrc,
    492+ bool _vAsFloat = treat_as_floating_point<_tDst>{}>
    493+yconstfn _tDst
    494+checked_min_rep_cast(_tSrc v)
    495+{
    496+ return checked_min_rep_caster<_tDst, _tSrc, _vAsFloat>()(v);
    497+}
    498+//!@}
    499+
    500+
    501+namespace details
    502+{
    503+
    504+template<typename _tDst, _tDst _vMul, typename _tSrc>
    505+YB_ATTR_nodiscard inline auto
    506+multiply_time(_tSrc x, false_) -> decltype(_vMul * _vMul)
    507+{
    508+ return ystdex::checked_constant_multiply<_tDst, _vMul>(
    509+ checked_rep_caster<_tDst, _tSrc, false>()(x));
    510+}
    511+template<typename _tDst, _tDst _vMul, typename _tSrc>
    512+YB_ATTR_nodiscard YB_STATELESS yconstfn auto
    513+multiply_time(_tSrc x, true_) ynoexcept_spec(_vMul * _vMul)
    514+ -> decltype(_vMul * _vMul)
    515+{
    516+ static_assert(or_<is_floating_point<_tDst>, is_class<_tDst>>(),
    517+ "Invalid destination representation type found.");
    518+
    519+ return _tDst(x) * _vMul;
    520+}
    521+
    522+} // namespace details;
    523+
    524+/*!
    525+\brief 检查参数表示的时间间隔表示值经模板参数指定的时钟转换时的溢出。
    526+\pre 第一模板参数指定的时钟满足 ISO C++20 Cpp17Clock 要求。
    527+\pre 第二模板参数指定的时钟的时间间隔是显式特化了 std::numeric_limits 的类型。
    528+\exception std::overflow 上溢:计算结果大于结果类型可表示的最大值。
    529+\exception std::overflow 下溢:计算结果小于结果类型可表示的最小值。
    530+\note 函数参数可以是 \c std::time_t 或无符号整数类型的值。
    531+*/
    532+template<typename _tDst, _tDst _vMul, typename _tRep>
    533+yconstfn auto
    534+multiply_time(_tRep t) ynoexcept_spec(details::multiply_time<_tDst, _vMul>(t,
    535+ treat_as_floating_point<_tDst>())) -> yimpl(decltype(
    536+ details::multiply_time<_tDst, _vMul>(t, unchecked_rep<_tDst>())))
    537+{
    538+ return details::multiply_time<_tDst, _vMul>(t, unchecked_rep<_tDst>());
    539+}
    540+
    541+/*!
    542+\brief 检查参数表示的时间间隔表示值经模板参数指定的时钟转换时的溢出。
    543+\pre 第一模板参数指定的时钟满足 ISO C++20 Cpp17Clock 要求。
    544+\pre 第二模板参数指定的时钟的时间间隔是显式特化了 std::numeric_limits 的类型。
    545+\exception std::overflow 上溢。
    546+\exception std::overflow 下溢。
    547+\note 函数参数可以是 \c std::time_t 或无符号整数类型的值。
    548+*/
    549+template<class _tClock, typename _tRep>
    550+inline auto
    551+multiply_time_on(_tRep t) ynoexcept_spec(chrono::multiply_time<
    552+ typename _tClock::rep, _tClock::period::num>(t)) -> yimpl(decltype(
    553+ chrono::multiply_time<typename _tClock::rep, _tClock::period::num>(t)))
    554+{
    555+ return
    556+ chrono::multiply_time<typename _tClock::rep, _tClock::period::num>(t);
    557+}
    558+
    559+/*!
    560+\note 不使用 common_type_t 以允许另行单独检查转换时可能的溢出。
    561+\exception std::overflow 上溢:转换的中间计算或结果的不能被最大值表示。
    562+\exception std::overflow 下溢:转换的中间计算或结果的不能被最小值表示。
    563+*/
    564+//!@{
    565+//! \brief 检查溢出的加法。
    566+template<typename _tRep, class _tPeriod,
    567+ typename = enable_if_t<!is_unbounded_number<_tRep>{}>>
    568+YB_ATTR_nodiscard YB_PURE duration<_tRep, _tPeriod>
    569+checked_plus(const duration<_tRep, _tPeriod>& x,
    570+ const duration<_tRep, _tPeriod>& y)
    571+{
    572+ return
    573+ duration<_tRep, _tPeriod>(ystdex::checked_plus(x.count(), y.count()));
    574+}
    575+
    576+//! \brief 检查溢出的减法。
    577+template<typename _tRep, class _tPeriod,
    578+ typename = enable_if_t<!is_unbounded_number<_tRep>{}>>
    579+YB_ATTR_nodiscard YB_PURE duration<_tRep, _tPeriod>
    580+checked_minus(const duration<_tRep, _tPeriod>& x,
    581+ const duration<_tRep, _tPeriod>& y)
    582+{
    583+ return
    584+ duration<_tRep, _tPeriod>(ystdex::checked_minus(x.count(), y.count()));
    585+}
    586+//!@}
    587+
    588+namespace details
    589+{
    590+
    591+template<class _tTo, class _tFrom>
    592+using conv_cr_t
    593+ = common_type_t<typename _tTo::rep, typename _tFrom::rep, intmax_t>;
    594+
    595+//! \ingroup functors
    596+//!@{
    597+template<class _tTo, class _tFrom, class _tPeriod = typename
    598+ std::ratio_divide<typename _tFrom::period, typename _tTo::period>::type,
    599+ bool = _tPeriod::num == 1, bool = _tPeriod::den == 1>
    600+struct checked_duration_cast_impl;
    601+
    602+template<class _tTo, class _tFrom, class _tPeriod>
    603+struct checked_duration_cast_impl<_tTo, _tFrom, _tPeriod, true, true>
    604+{
    605+ static_assert(_tPeriod::den > 0, "Invalid period type found.");
    606+ static_assert(_tPeriod::num > 0, "Invalid period type found.");
    607+
    608+ YB_ATTR_nodiscard YB_PURE yconstfn _tTo
    609+ operator()(const _tFrom& d) const
    610+ {
    611+ return _tTo(checked_rep_caster<typename _tTo::rep,
    612+ typename _tFrom::rep>()(d.count()));
    613+ }
    614+};
    615+
    616+template<class _tTo, class _tFrom, class _tPeriod>
    617+struct checked_duration_cast_impl<_tTo, _tFrom, _tPeriod, true, false>
    618+{
    619+ static_assert(_tPeriod::den > 0, "Invalid period type found.");
    620+ static_assert(_tPeriod::num > 0, "Invalid period type found.");
    621+
    622+ YB_ATTR_nodiscard YB_PURE yconstfn _tTo
    623+ operator()(const _tFrom& d) const
    624+ {
    625+ using cr_t = conv_cr_t<_tTo, _tFrom>;
    626+
    627+ return _tTo(checked_rep_caster<typename _tTo::rep, typename
    628+ _tFrom::rep>() (d.count()) / static_cast<cr_t>(_tPeriod::den));
    629+ }
    630+};
    631+
    632+template<class _tTo, class _tFrom, class _tPeriod>
    633+struct checked_duration_cast_impl<_tTo, _tFrom, _tPeriod, false, true>
    634+{
    635+ static_assert(_tPeriod::den > 0, "Invalid period type found.");
    636+ static_assert(_tPeriod::num > 0, "Invalid period type found.");
    637+
    638+ YB_ATTR_nodiscard YB_PURE yconstfn _tTo
    639+ operator()(const _tFrom& d) const
    640+ {
    641+ using cr_t = conv_cr_t<_tTo, _tFrom>;
    642+
    643+ return _tTo(chrono::multiply_time<cr_t, static_cast<cr_t>(
    644+ _tPeriod::num)>(d.count()));
    645+ }
    646+};
    647+
    648+template<class _tTo, class _tFrom, class _tPeriod>
    649+struct checked_duration_cast_impl<_tTo, _tFrom, _tPeriod, false, false>
    650+{
    651+ static_assert(_tPeriod::den > 0, "Invalid period type found.");
    652+ static_assert(_tPeriod::num > 0, "Invalid period type found.");
    653+
    654+ YB_ATTR_nodiscard YB_PURE yconstfn _tTo
    655+ operator()(const _tFrom& d) const
    656+ {
    657+ using cr_t = conv_cr_t<_tTo, _tFrom>;
    658+
    659+ return _tTo(chrono::multiply_time<cr_t, static_cast<cr_t>(
    660+ _tPeriod::num)>(d.count()) / static_cast<cr_t>(_tPeriod::den));
    661+ }
    662+};
    663+
    664+
    665+template<class _tDst, typename _tRep, class _tPeriod>
    666+struct checked_duration_cast_dispatch
    667+ : checked_duration_cast_impl<_tDst, duration<_tRep, _tPeriod>>
    668+{};
    669+
    670+template<typename _tRep, class _tPeriod>
    671+struct
    672+ checked_duration_cast_dispatch<duration<_tRep, _tPeriod>, _tRep, _tPeriod>
    673+{
    674+ YB_ATTR_nodiscard YB_PURE yconstfn duration<_tRep, _tPeriod>
    675+ operator()(const duration<_tRep, _tPeriod>& d) const ynothrow
    676+ {
    677+ return d;
    678+ }
    679+};
    680+//!@}
    681+
    682+//! \ingroup type_traits
    683+template<typename, typename, class, typename = void>
    684+struct duration_cast_spec : true_
    685+{};
    686+
    687+#if YB_HAS_NOEXCEPT
    688+template<typename _tDst, typename _tRep, class _tPeriod>
    689+struct duration_cast_spec<_tDst, _tRep, _tPeriod, enable_if_duration_t<_tDst>>
    690+ : bool_<noexcept(checked_duration_cast_dispatch<_tDst, _tRep, _tPeriod>()(
    691+ std::declval<const _tDst&>()))>
    692+{};
    693+#endif
    694+
    695+} // unnamed namespace;
    696+
    697+/*!
    698+\exception std::overflow 上溢:转换的中间计算或结果的不能被最大值表示。
    699+\exception std::overflow 下溢:转换的中间计算或结果的不能被最小值表示。
    700+\sa duration_cast
    701+\sa uncheced_rep
    702+*/
    703+//!@{
    704+/*!
    705+\brief 带有溢出检查的时间间隔转换。
    706+
    707+同 duration_cast ,但对不满足 unchecked_rep 的表示类型检查算术操作,
    708+ 以避免整数溢出。
    709+和 std::chrono::duration_cast 不同,
    710+ 结果转换为低精度时截断值而不一定具有实现相同的定义舍入行为。
    711+*/
    712+template<class _tDst, typename _tRep, class _tPeriod>
    713+YB_ATTR_nodiscard yconstfn_relaxed enable_if_duration_t<_tDst>
    714+checked_duration_cast(const duration<_tRep, _tPeriod>& d) ynoexcept(
    715+ details::duration_cast_spec<_tDst, _tRep, _tPeriod>())
    716+{
    717+ return details::checked_duration_cast_dispatch<_tDst, _tRep, _tPeriod>()(d);
    718+}
    719+
    720+/*!
    721+\brief 带有溢出检查的时间点转换。
    722+
    723+同 time_point_cast ,但使用 chrono::checked_duration_cast 检查,以避免整数溢出。
    724+*/
    725+template<class _tDst, class _tClock, class _tDuration>
    726+YB_ATTR_nodiscard yconstfn_relaxed
    727+ enable_if_t<is_duration<_tDst>{}, time_point<_tClock, _tDst>>
    728+checked_time_point_cast(const time_point<_tClock, _tDuration>& t)
    729+ ynoexcept(details::duration_cast_spec<_tDst, typename _tClock::rep,
    730+ typename _tClock::period>())
    731+{
    732+ return time_point<_tClock, _tDst>(
    733+ chrono::checked_duration_cast<_tDst>(t.time_since_epoch()));
    734+}
    735+//!@}
    736+
    737+} // namespace chrono;
    738+
    739+} // namespace ystdex;
    740+
    741+#endif
    742+
    diff -r 3fe9fa0c6127 -r 74e1025f0a02 YBase/include/ystdex/cstdint.hpp
    --- a/YBase/include/ystdex/cstdint.hpp Tue Feb 27 00:28:20 2024 +0800
    +++ b/YBase/include/ystdex/cstdint.hpp Fri Apr 19 22:42:25 2024 +0800
    @@ -1,5 +1,5 @@
    11 /*
    2- © 2012-2013, 2015-2016, 2018-2023 FrankHB.
    2+ © 2012-2013, 2015-2016, 2018-2024 FrankHB.
    33
    44 This file is part of the YSLib project, and may only be used, modified,
    55 and distributed under the terms of the YSLib project license.
    @@ -10,13 +10,13 @@
    1010 /*! \file cstdint.hpp
    1111 \ingroup YStandardEx
    1212 \brief ISO C 标准整数类型和相关扩展操作。
    13-\version r941
    13+\version r1160
    1414 \author FrankHB <frankhb1989@gmail.com>
    1515 \since build 245
    1616 \par 创建时间:
    1717 2013-08-24 20:28:18 +0800
    1818 \par 修改时间:
    19- 2023-12-17 00:10 +0800
    19+ 2024-04-14 22:20 +0800
    2020 \par 文本编码:
    2121 UTF-8
    2222 \par 模块名称:
    @@ -27,24 +27,60 @@
    2727 #ifndef YB_INC_ystdex_cstdint_hpp_
    2828 #define YB_INC_ystdex_cstdint_hpp_ 1
    2929
    30-#include "iterator_op.hpp" // for <cstdint>, CHAR_BIT, size_t_, make_signed,
    31-// make_unsigned, size_t, std::uint_fast8_t, std::int64_t, std::uint64_t,
    32-// is_signed, _t, common_type, cond_t, and_, is_unsigned, bool_,
    33-// std::uintmax_t, yconstraint, YB_VerifyIterator,
    34-// ystdex::make_reverse_iterator;
    35-#include <limits> // for std::numeric_limits;
    36-#include <numeric> // for std::accumulate;
    30+#include "iterator_op.hpp" // for <cstdint>, YB_Use_int128, is_same, int128_t,
    31+// uint128_t, std::intmax_t, std::uintmax_t, bool_, cond_t, size_t_,
    32+// bit_width_t, make_signed, make_unsigned, size_t, std::uint_fast8_t,
    33+// std::int64_t, std::uint64_t, is_signed, _t, common_type, and_, is_unsigned,
    34+// or_;
    35+#include "limits.hpp" // for internal "limits.hpp" (implying
    36+// <libdefect/limits.hpp>), is_bounded_binary_integer,
    37+// std::numeric_limits (with fixes);
    3738
    3839 namespace ystdex
    3940 {
    4041
    4142 /*!
    43+\brief 实现可能支持的最大整数类型。
    44+\see https://thephd.dev/intmax_t-hell-c++-c 。
    45+\see https://gcc.gnu.org/pipermail/libstdc++/2020-August/050792.html 。
    46+\see https://quuxplusone.github.io/blog/2019/02/28/is-int128-integral/ 。
    47+\since build 983
    48+
    49+实现支持的最大整数类型可能是非标准扩展整数类型。因为实现限制,此时这些整数不是
    50+ \c std::intmax_t 和 \c std::uintmax_t 。
    51+为解决这个问题,扩展整数类型在一些实现中不被支持为整数类型,如 libstdc++ 的标准模式。
    52+但是这种情形不能利用非标准库接口。在此提供有限的变通。
    53+在所有实现中:
    54+ intmax_t 至少具有 \c std::intmax_t 相同的位宽。
    55+ uintmax_t 至少具有 \c std::intmaix_t 相同的位宽。
    56+*/
    57+//!@{
    58+#if YB_Use_int128 > 0 && YB_Use_int128 < 3
    59+static_assert(!is_same<long long, int128_t>(), "Invalid implementation found.");
    60+static_assert(!is_same<unsigned long long, uint128_t>(),
    61+ "Invalid implementation found.");
    62+using intmax_t = int128_t;
    63+using uintmax_t = uint128_t;
    64+#else
    65+using intmax_t = std::intmax_t;
    66+using uintmax_t = std::uintmax_t;
    67+#endif
    68+//!@}
    69+
    70+
    71+/*!
    4272 \ingroup unary_type_traits
    43-\brief 取指定整数类型的位宽度。
    73+\brief 取指定整数类型的值表示的位宽度。
    74+\pre 参数是完整的表示整数的对象类型。
    75+\pre 参数类型具有 \c std::numeric_limits 特化或值表示和对象表示一致。
    4476 \since build 260
    4577 */
    46-template<typename _tInt>
    47-struct integer_width : size_t_<sizeof(_tInt) * CHAR_BIT>
    78+template<typename _type>
    79+// NOTE: Padding bits can be supported when the underlying standard library
    80+// implementation is conforming. See $2019-08 @ %Documentation::Workflow.
    81+struct integer_width : cond_t<is_bounded_binary_integer<_type>,
    82+ size_t_<std::numeric_limits<_type>::digits
    83+ + (std::numeric_limits<_type>::is_signed ? 1 : 0)>, bit_width_t<_type>>
    4884 {};
    4985
    5086
    @@ -64,6 +100,33 @@
    64100 //!@}
    65101
    66102
    103+//! \since build 983
    104+//!@{
    105+/*!
    106+\brief 提升确切位宽标准整数类型的连续支持的位宽值。
    107+*/
    108+YB_ATTR_nodiscard yconstfn size_t
    109+promote_std_integer_width(size_t w) ynothrow
    110+{
    111+ return w <= 8 ? 8 : (w <= 16 ? 16 : (w <= 32 ? 32 : 64));
    112+}
    113+
    114+/*!
    115+\brief 提升确切位宽整数类型的连续支持的位宽值。
    116+\since build 983
    117+*/
    118+YB_ATTR_nodiscard yconstfn size_t
    119+promote_integer_width(size_t w) ynothrow
    120+{
    121+#if YB_Use_int128 > 0
    122+ return w <= 64 ? promote_std_integer_width(w) : 128;
    123+#else
    124+ return promote_std_integer_width(w);
    125+#endif
    126+}
    127+//!@}
    128+
    129+
    67130 /*!
    68131 \ingroup meta_operations
    69132 \brief 取按指定宽度的整数类型。
    @@ -72,20 +135,11 @@
    72135 */
    73136 //!@{
    74137 template<size_t _vWidth>
    75-struct make_width_int
    138+// XXX: Using a function call in the template argument is friendly to
    139+// IntelliSense int Visual Studio Code (at least with vscode-cpptools v1.19.9).
    140+struct make_width_int : make_width_int<ystdex::promote_integer_width(_vWidth)>
    76141 {
    77- static_assert(_vWidth <= 64, "Width too large found.");
    78-
    79- using fast_type = typename make_width_int<(_vWidth <= 8U ? 8U
    80- : (_vWidth <= 16U ? 16U : (_vWidth <= 32U ? 32U : 64U)))>::fast_type;
    81- using unsigned_fast_type = typename make_width_int<(_vWidth <= 8U ? 8U
    82- : (_vWidth <= 16U ? 16U : (_vWidth <= 32U ? 32U : 64U)))>
    83- ::unsigned_fast_type;
    84- using least_type = typename make_width_int<(_vWidth <= 8U ? 8U
    85- : (_vWidth <= 16U ? 16U : (_vWidth <= 32U ? 32U : 64U)))>::least_type;
    86- using unsigned_least_type = typename make_width_int<(_vWidth <= 8U ? 8U
    87- : (_vWidth <= 16U ? 16U : (_vWidth <= 32U ? 32U : 64U)))>
    88- ::unsigned_least_type;
    142+ static_assert(_vWidth <= YB_MaxIntBits, "Width too large found.");
    89143 };
    90144
    91145 template<>
    @@ -131,6 +185,22 @@
    131185 using least_type = std::int_least64_t;
    132186 using unsigned_least_type = std::uint_least64_t;
    133187 };
    188+
    189+#if YB_Use_int128 > 0
    190+//! \since build 983
    191+template<>
    192+struct make_width_int<128U>
    193+{
    194+ using type = int128_t;
    195+ using unsigned_type = uint128_t;
    196+ // XXX: The following are heuristics without further information specific to
    197+ // the concrete implementation.
    198+ using fast_type = int128_t;
    199+ using unsigned_fast_type = uint128_t;
    200+ using least_type = int128_t;
    201+ using unsigned_least_type = uint128_t;
    202+};
    203+#endif
    134204 //!@}
    135205
    136206
    @@ -140,8 +210,8 @@
    140210 \brief 位加倍扩展。
    141211 \since build 587
    142212 \note 可用于定点数乘除法中间类型。
    143-\todo 使用扩展整数类型保持 64 位类型精度。
    144213 */
    214+//!@{
    145215 template<typename _type, bool _bSigned = is_signed<_type>{}>
    146216 struct make_widen_int
    147217 {
    @@ -150,9 +220,34 @@
    150220
    151221 public:
    152222 using type = _t<make_signed_c<_t<make_width_int<
    153- (width() << 1) <= 64 ? width() << 1 : width()>>, _bSigned>>;
    223+ (width() << 1) <= YB_MaxIntBits ? width() << 1 : width()>>, _bSigned>>;
    154224 };
    155225
    226+//! \since build 983
    227+//!@{
    228+template<typename _type, bool _bSigned = is_signed<_type>{}>
    229+using make_widen_int_t = _t<make_widen_int<_type, _bSigned>>;
    230+
    231+template<typename _type, bool _bSigned>
    232+struct make_widen_int<const _type, _bSigned>
    233+{
    234+ using type = const make_widen_int_t<_type, _bSigned>;
    235+};
    236+
    237+template<typename _type, bool _bSigned>
    238+struct make_widen_int<volatile _type, _bSigned>
    239+{
    240+ using type = volatile make_widen_int_t<_type, _bSigned>;
    241+};
    242+
    243+template<typename _type, bool _bSigned>
    244+struct make_widen_int<const volatile _type, _bSigned>
    245+{
    246+ using type = const volatile make_widen_int_t<_type, _bSigned>;
    247+};
    248+//!@}
    249+//!@}
    250+
    156251
    157252 /*!
    158253 \brief 公共整数类型。
    @@ -165,6 +260,10 @@
    165260 struct common_int_type : common_type<_types...>
    166261 {};
    167262
    263+//! \since build 983
    264+template<typename... _types>
    265+using common_int_type_t = _t<common_int_type<_types...>>;
    266+
    168267 template<typename _type1, typename _type2, typename... _types>
    169268 struct common_int_type<_type1, _type2, _types...>
    170269 {
    @@ -174,7 +273,7 @@
    174273 public:
    175274 using type = typename common_int_type<cond_t<
    176275 and_<is_unsigned<common_t>, or_<is_signed<_type1>, is_signed<_type2>>>,
    177- _t<make_widen_int<common_t, true>>, common_t>, _types...>::type;
    276+ make_widen_int_t<common_t, true>, common_t>, _types...>::type;
    178277 };
    179278 //!@}
    180279 //!@}
    @@ -182,16 +281,16 @@
    182281
    183282 /*!
    184283 \ingroup metafunctions
    185-\brief 模算术特性:取得不超过模值的最大值。
    284+\brief 模算术特征:取得不超过模值的最大值。
    186285 \note 不保证值是整数,因此不从 std::integral_constant 派生。
    187286 \note 模值 0 表示模为平凡值 1 或不支持模算术。
    188-\note 正确性由用户保证。一般应至少保证 + 和 * 以及相关赋值操作满足模算术语义。
    287+\note 正确性由程序保证。一般应至少保证 + 和 * 以及相关赋值操作满足模算术语义。
    189288 \since build 440
    190289 */
    191290 template<typename _type>
    192291 struct modular_arithmetic
    193292 {
    194- static yconstexpr const _type value = is_unsigned<_type>()
    293+ static yconstexpr const _type value = std::numeric_limits<_type>::is_modulo
    195294 ? std::numeric_limits<_type>::max() : _type(0);
    196295 };
    197296
    @@ -202,114 +301,10 @@
    202301 \since build 440
    203302 */
    204303 template<typename _type1, typename _type2>
    205-struct have_same_modulo : bool_<std::uintmax_t(modular_arithmetic<
    206- _type1>()) != 0 && std::uintmax_t(modular_arithmetic<_type1>())
    207- == std::uintmax_t(modular_arithmetic<_type2>())>
    304+struct have_same_modulo : bool_<modular_arithmetic<_type1>() != 0
    305+ && modular_arithmetic<_type1>() == modular_arithmetic<_type2>()>
    208306 {};
    209307
    210-
    211-//! \pre 静态断言:整数宽度非零且为 byte 类型宽度的整数倍。
    212-//!@{
    213-/*!
    214-\brief 使用迭代器对指定的范围中的字节表示的序列构造无符号整数。
    215-\pre 范围中的迭代器可解引用。
    216-\since build 603
    217-*/
    218-template<size_t _vWidth, typename _tIn>
    219-YB_ATTR_nodiscard YB_PURE typename make_width_int<_vWidth>::unsigned_type
    220-pack_uint(_tIn first, _tIn last) ynothrowv
    221-{
    222- static_assert(_vWidth != 0 && _vWidth
    223- % std::numeric_limits<unsigned char>::digits == 0,
    224- "Invalid integer width found.");
    225- using utype = typename make_width_int<_vWidth>::unsigned_type;
    226-
    227- YB_VerifyIterator(first);
    228- return std::accumulate(first, last, utype(), [](utype x, byte y){
    229- return utype(x << std::numeric_limits<unsigned char>::digits
    230- | utype(y));
    231- });
    232-}
    233-
    234-/*!
    235-\brief 分解无符号整数到迭代器对指定的字节范围。
    236-\pre 断言:范围中的迭代器可解引用。
    237-\since build 604
    238-*/
    239-template<size_t _vWidth, typename _tOut>
    240-void
    241-unpack_uint(typename ystdex::make_width_int<_vWidth>::unsigned_type value,
    242- _tOut result) ynothrow
    243-{
    244- static_assert(_vWidth != 0 && _vWidth % std::numeric_limits<
    245- unsigned char>::digits == 0, "Invalid integer width found.");
    246- auto n(_vWidth);
    247-
    248- while(!(_vWidth < (n -= std::numeric_limits<unsigned char>::digits)))
    249- {
    250- YB_VerifyIterator(result);
    251- *result = byte(value >> n);
    252- ++result;
    253- }
    254-}
    255-//!@}
    256-
    257-//! \pre 指针参数非空。
    258-//!@{
    259-/*!
    260-\brief 从字节缓冲区读取指定宽的大端序无符号整数。
    261-\since build 623
    262-*/
    263-template<size_t _vWidth>
    264-YB_ATTR_nodiscard YB_NONNULL(1) YB_PURE inline
    265- typename make_width_int<_vWidth>::unsigned_type
    266-read_uint_be(const byte* buf) ynothrowv
    267-{
    268- yconstraint(buf);
    269- return ystdex::pack_uint<_vWidth>(buf,
    270- buf + _vWidth / std::numeric_limits<unsigned char>::digits);
    271-}
    272-
    273-//! \since build 608
    274-//!@{
    275-//! \brief 从字节缓冲区读取指定宽的小端序无符号整数。
    276-template<size_t _vWidth>
    277-YB_ATTR_nodiscard YB_NONNULL(1) YB_PURE inline
    278- typename make_width_int<_vWidth>::unsigned_type
    279-read_uint_le(const byte* buf) ynothrowv
    280-{
    281- yconstraint(buf);
    282- return ystdex::pack_uint<_vWidth>(ystdex::make_reverse_iterator(
    283- buf + _vWidth / std::numeric_limits<unsigned char>::digits),
    284- ystdex::make_reverse_iterator(buf));
    285-}
    286-
    287-/*!
    288-\brief 向字节缓冲区写入指定宽的大端序无符号整数。
    289-\since build 623
    290-*/
    291-template<size_t _vWidth>
    292-YB_NONNULL(1) inline void
    293-write_uint_be(byte* buf, typename make_width_int<_vWidth>::unsigned_type val)
    294- ynothrowv
    295-{
    296- yconstraint(buf);
    297- ystdex::unpack_uint<_vWidth>(val, buf);
    298-}
    299-
    300-//! \brief 向字节缓冲区写入指定宽的小端序无符号整数。
    301-template<size_t _vWidth>
    302-YB_NONNULL(1) inline void
    303-write_uint_le(byte* buf, typename make_width_int<_vWidth>::unsigned_type val)
    304- ynothrowv
    305-{
    306- yconstraint(buf);
    307- ystdex::unpack_uint<_vWidth>(val, ystdex::make_reverse_iterator(buf
    308- + _vWidth / std::numeric_limits<unsigned char>::digits));
    309-}
    310-//!@}
    311-//!@}
    312-
    313308 } // namespace ystdex;
    314309
    315310 #endif
    diff -r 3fe9fa0c6127 -r 74e1025f0a02 YBase/include/ystdex/ctime.h
    --- a/YBase/include/ystdex/ctime.h Tue Feb 27 00:28:20 2024 +0800
    +++ b/YBase/include/ystdex/ctime.h Fri Apr 19 22:42:25 2024 +0800
    @@ -1,23 +1,22 @@
    11 /*
    2- © 2016 FrankHB.
    2+ © 2016, 2024 FrankHB.
    33
    4- This file is part of the YSLib project, and may only be used,
    5- modified, and distributed under the terms of the YSLib project
    6- license, LICENSE.TXT. By continuing to use, modify, or distribute
    7- this file you indicate that you have read the license and
    8- understand and accept it fully.
    4+ This file is part of the YSLib project, and may only be used, modified,
    5+ and distributed under the terms of the YSLib project license.
    6+ By continuing to use, modify, or distribute this file you indicate that
    7+ you have read the license and understand and accept it fully.
    98 */
    109
    1110 /*! \file ctime.h
    1211 \ingroup YStandardEx
    1312 \brief ISO C 日期和时间接口扩展。
    14-\version r57
    13+\version r98
    1514 \author FrankHB <frankhb1989@gmail.com>
    1615 \since build 513
    1716 \par 创建时间:
    1817 2016-06-23 09:48:32 +0800
    1918 \par 修改时间:
    20- 2015-06-23 09:52 +0800
    19+ 2024-04-06 15:26 +0800
    2120 \par 文本编码:
    2221 UTF-8
    2322 \par 模块名称:
    @@ -28,14 +27,16 @@
    2827 #ifndef YB_INC_ystdex_ctime_h_
    2928 #define YB_INC_ystdex_ctime_h_ 1
    3029
    31-#include "../ydef.h" // for yconstfn;
    32-#include <ctime> // for std::tm;
    30+#include "meta.hpp" // for yconstfn, false_, void_t, enable_if, is_trivial,
    31+// is_arithmetic, is_integral, true_;
    32+#include <ctime> // for <ctime>, std::tm;
    33+#include <libdefect/limits.hpp> // for std::numeric_limits (with fixes);
    3334
    3435 namespace ystdex
    3536 {
    3637
    3738 //! \since build 704
    38-//@{
    39+//!@{
    3940 //! \brief 判断 std::tm 的日期数据成员范围是否有效。
    4041 yconstfn bool
    4142 is_date_range_valid(const std::tm& t)
    @@ -50,7 +51,43 @@
    5051 return !(t.tm_hour < 0 || 23 < t.tm_hour || t.tm_hour < 0 || 59 < t.tm_min
    5152 || t.tm_sec < 0 || 59 < t.tm_min);
    5253 }
    53-//@}
    54+//!@}
    55+
    56+
    57+//! \since build 983
    58+namespace details
    59+{
    60+
    61+template<typename _type, typename = void>
    62+struct is_timespec_like : false_
    63+{};
    64+
    65+template<typename _type>
    66+struct is_timespec_like<_type, void_t<enable_if<is_trivial<_type>{}>,
    67+ is_arithmetic<decltype(_type().tv_sec)>, is_integral<decltype(_type()
    68+ .tv_nsec)>, enable_if<(std::numeric_limits<decltype(_type().tv_sec)>::max()
    69+ > 0)>, enable_if<(std::numeric_limits<decltype(_type().tv_nsec)>::max()
    70+ >= 999999999LL)>>> : true_
    71+{};
    72+
    73+} // unnamed namespace details;
    74+
    75+/*!
    76+\ingroup unary_type_traits
    77+\brief 判断指定类型是否是类似 ISO C++17 \c std::timespec 的类型。
    78+\since build 983
    79+
    80+判断模板参数指定的类型是否类似 ISO C++17 \c std::timespec 类型,即满足以下要求:
    81+ 是平凡类型。
    82+ 具有算术类型非静态数据成员 \c tv_sec ,最大值不小于 0 。
    83+ 具有整数类型非静态数据成员 \c tv_nsec ,最大值不小于 999999999 。
    84+仅要求默认构造,不限制布局和
    85+不限制 \c tv_sec 的具体类型,以同时兼容不同实现的 \c std::time_t 。
    86+不限制 \c tv_nsec 的具体类型,以兼容 ISO C23 的 \c ::timespec 。
    87+*/
    88+template<typename _type>
    89+struct is_timespec_like : details::is_timespec_like<_type>
    90+{};
    5491
    5592 } // namespace ystdex;
    5693
    diff -r 3fe9fa0c6127 -r 74e1025f0a02 YBase/include/ystdex/exception.h
    --- a/YBase/include/ystdex/exception.h Tue Feb 27 00:28:20 2024 +0800
    +++ b/YBase/include/ystdex/exception.h Fri Apr 19 22:42:25 2024 +0800
    @@ -1,5 +1,5 @@
    11 /*
    2- © 2014-2018, 2020-2023 FrankHB.
    2+ © 2014-2018, 2020-2024 FrankHB.
    33
    44 This file is part of the YSLib project, and may only be used, modified,
    55 and distributed under the terms of the YSLib project license.
    @@ -10,13 +10,13 @@
    1010 /*! \file exception.h
    1111 \ingroup YStandardEx
    1212 \brief 标准库异常扩展接口。
    13-\version r357
    13+\version r373
    1414 \author FrankHB <frankhb1989@gmail.com>
    1515 \since build 522
    1616 \par 创建时间:
    1717 2014-07-25 20:14:51 +0800
    1818 \par 修改时间:
    19- 2023-12-20 20:32 +0800
    19+ 2024-04-12 23:30 +0800
    2020 \par 文本编码:
    2121 UTF-8
    2222 \par 模块名称:
    @@ -232,6 +232,24 @@
    232232 //!@}
    233233
    234234
    235+//! \since build 983
    236+//!@{
    237+/*!
    238+\brief 抛出参数指定消息的 \c std::overflow_error 异常。
    239+\throw std::overflow_error
    240+*/
    241+YB_NORETURN YB_API YB_NONNULL(1) void
    242+throw_overflow_error(const char* = "Value overflow detected.");
    243+
    244+/*!
    245+\brief 抛出参数指定消息的 \c std::underflow_error 异常。
    246+\throw std::underflow_error
    247+*/
    248+YB_NORETURN YB_API YB_NONNULL(1) void
    249+throw_underflow_error(const char* = "Value underflow detected.");
    250+//!@}
    251+
    252+
    235253 /*!
    236254 \brief 抛出错误:\c std::system_error 或允许相同构造函数参数的异常。
    237255 \throw _type 使用参数构造的异常。
    diff -r 3fe9fa0c6127 -r 74e1025f0a02 YBase/include/ystdex/iterator.hpp
    --- a/YBase/include/ystdex/iterator.hpp Tue Feb 27 00:28:20 2024 +0800
    +++ b/YBase/include/ystdex/iterator.hpp Fri Apr 19 22:42:25 2024 +0800
    @@ -1,5 +1,5 @@
    11 /*
    2- © 2011-2023 FrankHB.
    2+ © 2011-2024 FrankHB.
    33
    44 This file is part of the YSLib project, and may only be used, modified,
    55 and distributed under the terms of the YSLib project license.
    @@ -10,13 +10,13 @@
    1010 /*! \file iterator.hpp
    1111 \ingroup YStandardEx
    1212 \brief 通用迭代器。
    13-\version r6283
    13+\version r6367
    1414 \author FrankHB <frankhb1989@gmail.com>
    1515 \since 早于 build 189
    1616 \par 创建时间:
    1717 2011-01-27 23:01:00 +0800
    1818 \par 修改时间:
    19- 2023-07-06 21:58 +0800
    19+ 2024-04-17 02:28 +0800
    2020 \par 文本编码:
    2121 UTF-8
    2222 \par 模块名称:
    @@ -29,9 +29,10 @@
    2929
    3030 #include "pointer.hpp" // for "iterator_op.hpp", iterator_operators_t,
    3131 // std::iterator_traits, is_bitwise_swappable, _t, pointer_classify, cond_t,
    32-// exclude_self_t, enable_if_convertible_t, and_, std::input_iterator_tag,
    33-// ystdex::swap_dependent, YB_VerifyIterator, is_undereferenceable, yassume,
    34-// yconstraint, random_access_iteratable;
    32+// void_t, decrement_t, exclude_self_t, enable_if_convertible_t, and_,
    33+// plus_assignment_t, minus_assignment_t, less_t, minus_t,
    34+// std::input_iterator_tag, ystdex::swap_dependent, YB_VerifyIterator,
    35+// is_undereferenceable, yassume, yconstraint, random_access_iteratable;
    3536 #include "type_op.hpp" // for first_tag, second_tag;
    3637 #include <tuple> // for std::tuple, std::get, std::tuple_size;
    3738 #include "integer_sequence.hpp" // for make_index_sequence, index_sequence;
    @@ -181,24 +182,33 @@
    181182 using value_type = remove_reference_t<reference>;
    182183 /*!
    183184 \since build 667
    184- \todo 测试 operator-> 并支持代理指针。
    185+ \todo 测试 \c operator-> 并支持代理指针。
    185186 */
    186187 using pointer = value_type*;
    187188 };
    188189
    190+//! \since build 983
    191+template<typename... _types>
    192+auto
    193+chk_decrement(std::tuple<_types...>) -> void_t<decrement_t<_types&>...>;
    194+
    189195 } // namespace details;
    190196
    191197
    192198 /*!
    193199 \ingroup iterator_adaptors
    194200 \brief 变换迭代器。
    195-\pre 变换器必须满足 DefaultConstructible ,否则不保证可默认构造。
    196201 \note 对返回新值的二元操作复制的转换器基于第一操作数。
    197202 \warning 非虚析构。
    198203 \since build 532
    199204
    200205 使用指定参数转换得到新迭代器的间接操作替代指定原始类型的间接操作的迭代器适配器。
    206+第一模板参数指定被变换原迭代器类型,应为满足迭代器要求的迭代器。
    207+第二模板参数指定实现变换的变换器类型。
    208+第三模板参数指定引用类型。
    201209 被替代的原始类型是迭代器类型,或除间接操作(可以不存在)外符合迭代器要求的类型。
    210+实例满足第一参数对应的迭代器要求,
    211+ 仅当第二参数满足 DefaultConstructible 且第三参数是引用。
    202212 */
    203213 template<typename _tIter, typename _fTrans, typename _tReference = void>
    204214 class transformed_iterator : public iterator_operators_t<transformed_iterator<
    @@ -306,7 +316,9 @@
    306316 transformed_iterator&
    307317 operator=(transformed_iterator&&) = default;
    308318
    309- //! \since build 910
    319+ //! \since build 983
    320+ template<yimpl(typename _type = iterator_type,
    321+ typename = plus_assignment_t<_type&, difference_type&>)>
    310322 transformed_iterator&
    311323 operator+=(difference_type n)
    312324 ynoexcept_spec(std::declval<transformed_iterator&>().get() += n)
    @@ -315,7 +327,9 @@
    315327 return *this;
    316328 }
    317329
    318- //! \since build 910
    330+ //! \since build 983
    331+ template<yimpl(typename _type = iterator_type,
    332+ typename = minus_assignment_t<_type&, difference_type&>)>
    319333 transformed_iterator&
    320334 operator-=(difference_type n)
    321335 ynoexcept_spec(std::declval<transformed_iterator&>().get() -= n)
    @@ -341,7 +355,9 @@
    341355 return *this;
    342356 }
    343357
    344- //! \since build 665
    358+ //! \since build 983
    359+ template<yimpl(typename _type = iterator_type,
    360+ typename = decrement_t<_type&>)>
    345361 transformed_iterator&
    346362 operator--()
    347363 {
    @@ -366,14 +382,16 @@
    366382 return x.get() == y;
    367383 }
    368384
    369- template<yimpl(typename = void)>
    385+ template<yimpl(typename _type = iterator_type,
    386+ typename = less_t<const _type&>)>
    370387 friend yconstfn bool
    371388 operator<(const transformed_iterator& x, const transformed_iterator& y)
    372389 ynoexcept_spec(bool(x.get() < y.get()))
    373390 {
    374391 return bool(x.get() < y.get());
    375392 }
    376- template<yimpl(typename = void)>
    393+ template<yimpl(typename _type = iterator_type,
    394+ typename = less_t<const _type&>)>
    377395 friend yconstfn bool
    378396 operator<(const transformed_iterator& x, const iterator_type& y)
    379397 ynoexcept_spec(bool(x.get() < y))
    @@ -381,21 +399,24 @@
    381399 return bool(x.get() < y);
    382400 }
    383401
    384- template<yimpl(typename = void)>
    402+ template<yimpl(typename _type = iterator_type,
    403+ typename = minus_t<const _type&>)>
    385404 friend yconstfn difference_type
    386405 operator-(const transformed_iterator& x, const transformed_iterator& y)
    387406 ynoexcept_spec(difference_type(x.get() - y.get()))
    388407 {
    389408 return difference_type(x.get() - y.get());
    390409 }
    391- template<yimpl(typename = void)>
    410+ template<yimpl(typename _type = iterator_type,
    411+ typename = minus_t<const _type&>)>
    392412 friend yconstfn difference_type
    393413 operator-(const transformed_iterator& x, const iterator_type& y)
    394414 ynoexcept_spec(difference_type(x.get() - y))
    395415 {
    396416 return difference_type(x.get() - y);
    397417 }
    398- template<yimpl(typename = void)>
    418+ template<yimpl(typename _type = iterator_type,
    419+ typename = minus_t<const _type&>)>
    399420 friend yconstfn difference_type
    400421 operator-(const iterator_type& x, const transformed_iterator& y)
    401422 ynoexcept_spec(difference_type(x - y.get()))
    @@ -634,11 +655,12 @@
    634655 \since build 595
    635656
    636657 拼接迭代器和其它对象类型对得到的迭代器适配器。
    658+第二参数指定的迭代器特征应被第一参数支持。否则,不保证提供的操作可用而满足对应特征。
    637659 */
    638660 template<typename _tIter, class _tTraits = std::iterator_traits<_tIter>,
    639661 typename... _tSlaves>
    640-class tuple_iterator : private std::tuple<_tIter, _tSlaves...>, public
    641- iterator_operators_t<tuple_iterator<_tIter, _tTraits, _tSlaves...>,
    662+class tuple_iterator : private std::tuple<_tIter, _tSlaves...>,
    663+ public iterator_operators_t<tuple_iterator<_tIter, _tTraits, _tSlaves...>,
    642664 _tTraits>
    643665 {
    644666 public:
    @@ -654,6 +676,18 @@
    654676 private:
    655677 using seq_type = make_index_sequence<std::tuple_size<base_type>{}>;
    656678
    679+ //! \since build 983
    680+ template<typename... _types>
    681+ static auto
    682+ chk_plus_assignment(std::tuple<_types...>)
    683+ -> void_t<plus_assignment_t<_types&, difference_type>...>;
    684+
    685+ //! \since build 983
    686+ template<typename... _types>
    687+ static auto
    688+ chk_minus_assignment(std::tuple<_types...>)
    689+ -> void_t<minus_assignment_t<_types&, difference_type>...>;
    690+
    657691 public:
    658692 yconstfn
    659693 tuple_iterator() = default;
    @@ -676,6 +710,13 @@
    676710 tuple_iterator&
    677711 operator=(tuple_iterator&&) = default;
    678712
    713+ /*!
    714+ \note 满足随机访问迭代器要求。
    715+ \since build 984
    716+ */
    717+ //!@{
    718+ template<yimpl(typename _tBase = base_type,
    719+ typename = decltype(chk_plus_assignment(std::declval<_tBase>())))>
    679720 tuple_iterator&
    680721 operator+=(difference_type n) ynoexcept_spec(
    681722 yimpl(std::declval<tuple_iterator&>().add(n, seq_type())))
    @@ -684,6 +725,8 @@
    684725 return *this;
    685726 }
    686727
    728+ template<yimpl(typename _tBase = base_type,
    729+ typename = decltype(chk_minus_assignment(std::declval<_tBase>())))>
    687730 tuple_iterator&
    688731 operator-=(difference_type n) ynoexcept_spec(
    689732 yimpl(std::declval<tuple_iterator&>().subtract(n, seq_type())))
    @@ -691,8 +734,9 @@
    691734 subtract(n, seq_type());
    692735 return *this;
    693736 }
    737+ //!@}
    694738
    695- //! \brief 满足输入迭代器要求。
    739+ //! \note 满足输入迭代器要求。
    696740 //!@{
    697741 YB_ATTR_nodiscard yconstfn reference
    698742 operator*() const
    @@ -710,7 +754,12 @@
    710754 }
    711755 //!@}
    712756
    713- //! \brief 满足双向迭代器要求。
    757+ /*!
    758+ \note 满足双向迭代器要求。
    759+ \since build 984
    760+ */
    761+ template<yimpl(typename _tBase = base_type,
    762+ typename = decltype(details::chk_decrement(std::declval<_tBase>())))>
    714763 tuple_iterator&
    715764 operator--()
    716765 ynoexcept_spec(yimpl(std::declval<tuple_iterator&>().dec(seq_type())))
    @@ -726,6 +775,27 @@
    726775 return x.get() == y.get();
    727776 }
    728777
    778+ //! \since build 983
    779+ //!@{
    780+ template<yimpl(typename _type = iterator_type,
    781+ typename = less_t<const _type&>)>
    782+ friend yconstfn bool
    783+ operator<(const tuple_iterator& x, const tuple_iterator& y)
    784+ ynoexcept_spec(bool(x.get() < y.get()))
    785+ {
    786+ return bool(x.get() < y.get());
    787+ }
    788+
    789+ template<yimpl(typename _type = iterator_type,
    790+ typename = minus_t<const _type&>)>
    791+ friend yconstfn difference_type
    792+ operator-(const tuple_iterator& x, const tuple_iterator& y)
    793+ ynoexcept_spec(difference_type(x.get() - y.get()))
    794+ {
    795+ return difference_type(x.get() - y.get());
    796+ }
    797+ //!@}
    798+
    729799 private:
    730800 template<size_t... _vSeq>
    731801 void
    diff -r 3fe9fa0c6127 -r 74e1025f0a02 YBase/include/ystdex/limits.hpp
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/YBase/include/ystdex/limits.hpp Fri Apr 19 22:42:25 2024 +0800
    @@ -0,0 +1,158 @@
    1+/*
    2+ © 2024 FrankHB.
    3+
    4+ This file is part of the YSLib project, and may only be used, modified,
    5+ and distributed under the terms of the YSLib project license.
    6+ By continuing to use, modify, or distribute this file you indicate that
    7+ you have read the license and understand and accept it fully.
    8+*/
    9+
    10+/*! \file limits.hpp
    11+\ingroup YStandardEx
    12+\brief 实现限制。
    13+\version r157
    14+\author FrankHB <frankhb1989@gmail.com>
    15+\since build 983
    16+\par 创建时间:
    17+ 2024-04-08 02:17:53 +0800
    18+\par 修改时间:
    19+ 2024-04-15 20:41 +0800
    20+\par 文本编码:
    21+ UTF-8
    22+\par 模块名称:
    23+ YStandardEx::Limits
    24+*/
    25+
    26+
    27+#ifndef YB_INC_ystdex_limits_hpp_
    28+#define YB_INC_ystdex_limits_hpp_ 1
    29+
    30+#include <libdefect/limits.hpp> // for <libdefect/limits.hpp>,
    31+// std::numeric_limits (with fixes);
    32+#include "integral_constant.hpp" // for bool_;
    33+
    34+namespace ystdex
    35+{
    36+
    37+//! \since build 983
    38+//!@{
    39+/*!
    40+\ingroup traits
    41+\brief 数值特征。
    42+*/
    43+template<class _type>
    44+struct numeric_traits : std::numeric_limits<_type>
    45+{
    46+ using base = std::numeric_limits<_type>;
    47+
    48+ //! \brief 判断是否为有界整数。
    49+ static yconstexpr bool is_bounded_integer = base::is_specialized
    50+ && base::is_integer && base::is_bounded;
    51+ //! \brief 判断是否为二进制有界整数。
    52+ static yconstexpr bool is_bounded_binary_integer
    53+ = is_bounded_integer && base::radix == 2;
    54+ //! \brief 判断是否为无界数。
    55+ static yconstexpr bool is_unbounded
    56+ = base::is_specialized && !base::is_bounded;
    57+ //! \brief 判断是否为任意界限的无界数。
    58+#if YB_IMPL_GNUCPP || YB_IMPL_CLANGPP
    59+ YB_Diag_Push
    60+ YB_Diag_Ignore(float-equal)
    61+#endif
    62+ static yconstexpr bool is_arbitrary_unbounded = is_unbounded
    63+ && base::max() == 0 && base::min() == 0;
    64+#if YB_IMPL_GNUCPP || YB_IMPL_CLANGPP
    65+ YB_Diag_Pop
    66+#endif
    67+ //! \brief 判断是否具有特殊值。
    68+ static yconstexpr bool has_special_value
    69+ = base::is_specialized && base::has_infinity && base::has_quiet_NaN;
    70+};
    71+
    72+
    73+//! \ingroup unary_type_traits
    74+//!@{
    75+//! \brief 判断指定类型是否为二进制整数类型。
    76+template<typename _type>
    77+struct is_bounded_integer
    78+ : bool_<numeric_traits<_type>::is_bounded_integer>
    79+{};
    80+
    81+//! \brief 判断指定类型是否为二进制有界整数类型。
    82+template<typename _type>
    83+struct is_bounded_binary_integer
    84+ : bool_<numeric_traits<_type>::is_bounded_binary_integer>
    85+{};
    86+
    87+//! \brief 判断参数指定的类型是否为无界数值类型。
    88+template<typename _type>
    89+struct is_unbounded_number : bool_<numeric_traits<_type>::is_unbounded>
    90+{};
    91+
    92+//! \brief 判断参数指定的类型是否为无界数值类型。
    93+template<typename _type>
    94+struct is_arbitrary_unbounded_number
    95+ : bool_<numeric_traits<_type>::is_arbitrary_unbounded>
    96+{};
    97+
    98+
    99+//! \brief 判断参数指定的类型是否具有特殊值。
    100+template<typename _type>
    101+struct has_special_value : bool_<numeric_traits<_type>::has_special_value>
    102+{};
    103+//!@}
    104+//!@}
    105+
    106+
    107+namespace details
    108+{
    109+
    110+template<typename _type, typename _type2, typename = void>
    111+struct is_in_subrange_of : is_arbitrary_unbounded_number<_type2>
    112+{};
    113+
    114+template<typename _type, typename _type2>
    115+struct is_in_subrange_of<_type, _type2, void_t<bool_<(std::numeric_limits<_type>
    116+ ::max() <= std::numeric_limits<_type2>::max() && std::numeric_limits<_type>
    117+ ::min() >= std::numeric_limits<_type2>::min())>>>
    118+ : or_<is_arbitrary_unbounded_number<_type2>, bool_<(std::numeric_limits<
    119+ _type>::max() <= std::numeric_limits<_type2>::max()
    120+ && std::numeric_limits<_type>::min()
    121+ >= std::numeric_limits<_type2>::min())>>
    122+{};
    123+
    124+} // namespace details;
    125+
    126+/*!
    127+\ingroup unary_type_traits
    128+\brief 判断第一参数指定的类型是否在第二参数指定的类型的范围内。
    129+\note 判断值域是否被涵盖,不保证第二个参数中存在无法准确表示第一参数类型的值的情形。
    130+*/
    131+template<typename _type, typename... _types>
    132+struct is_in_subrange_of : and_<details::is_in_subrange_of<_type, _types>...>
    133+{};
    134+
    135+
    136+/*!
    137+\ingroup traits
    138+\brief 判断指定类型是否可作为十进制连续数字的表示。
    139+
    140+作为十进制数字表示的类型是不少于指定十进制位数的无符号整数。
    141+*/
    142+template<size_t _vLen, typename _type>
    143+using rep_in_digits10 = bool_<std::numeric_limits<_type>::is_integer
    144+ && !std::numeric_limits<_type>::is_signed
    145+ && std::numeric_limits<_type>::digits10 >= _vLen>;
    146+
    147+/*!
    148+\ingroup metafunctions
    149+\sa enable_if_t
    150+*/
    151+template<size_t _vLen, typename _type>
    152+using enable_if_rep_in_digits10
    153+ = enable_if_t<rep_in_digits10<_vLen, _type>{}, _type>;
    154+
    155+} // namespace ystdex;
    156+
    157+#endif
    158+
    diff -r 3fe9fa0c6127 -r 74e1025f0a02 YBase/include/ystdex/list.hpp
    --- a/YBase/include/ystdex/list.hpp Tue Feb 27 00:28:20 2024 +0800
    +++ b/YBase/include/ystdex/list.hpp Fri Apr 19 22:42:25 2024 +0800
    @@ -1,23 +1,22 @@
    11 /*
    2- © 2019-2023 FrankHB.
    2+ © 2019-2024 FrankHB.
    33
    4- This file is part of the YSLib project, and may only be used,
    5- modified, and distributed under the terms of the YSLib project
    6- license, LICENSE.TXT. By continuing to use, modify, or distribute
    7- this file you indicate that you have read the license and
    8- understand and accept it fully.
    4+ This file is part of the YSLib project, and may only be used, modified,
    5+ and distributed under the terms of the YSLib project license.
    6+ By continuing to use, modify, or distribute this file you indicate that
    7+ you have read the license and understand and accept it fully.
    98 */
    109
    1110 /*! \file list.hpp
    1211 \ingroup YStandardEx
    1312 \brief 列表容器。
    14-\version r1881
    13+\version r1891
    1514 \author FrankHB <frankhb1989@gmail.com>
    1615 \since build 864
    1716 \par 创建时间:
    1817 2019-08-14 14:48:52 +0800
    1918 \par 修改时间:
    20- 2023-02-13 05:13 +0800
    19+ 2024-04-06 15:30 +0800
    2120 \par 文本编码:
    2221 UTF-8
    2322 \par 模块名称:
    @@ -48,7 +47,7 @@
    4847 // less;
    4948 #include "compressed_pair.hpp" // for compressed_base;
    5049 #include "base.h" // for noncopyable, nonmovable;
    51-#include <limits> // for std::numeric_limits;
    50+#include <libdefect/limits.hpp> // for std::numeric_limits (with fixes);
    5251 #include "iterator_trait.hpp" // for enable_for_input_iterator_t;
    5352
    5453 namespace ystdex
    @@ -1025,7 +1024,7 @@
    10251024
    10261025 for(bool init(true); ; init = {})
    10271026 {
    1028- // NOTE: [first, mid) and [mid, last) are sorted and non-empty.
    1027+ // NOTE: [first, mid) and [mid, last) are sorted and nonempty.
    10291028 // XXX: Use %YB_VerifyIterator?
    10301029 yverify(mid != end());
    10311030 yverify(first != end());
    @@ -1200,8 +1199,8 @@
    12001199 // %std::allocator_traits::is_always_equal trait of the internal node. In
    12011200 // ISO C++17 there is no explicit exception specification.
    12021201 list(list&& x, const allocator_type& a)
    1203- yimpl(ynoexcept(is_nothrow_constructible<
    1204- rep_type, rep_type&&, const allocator_type&>()))
    1202+ yimpl(ynoexcept(is_nothrow_constructible<rep_type, rep_type&&,
    1203+ const allocator_type&>()))
    12051204 : rep(std::move(x.rep), a)
    12061205 {}
    12071206
    diff -r 3fe9fa0c6127 -r 74e1025f0a02 YBase/include/ystdex/meta.hpp
    --- a/YBase/include/ystdex/meta.hpp Tue Feb 27 00:28:20 2024 +0800
    +++ b/YBase/include/ystdex/meta.hpp Fri Apr 19 22:42:25 2024 +0800
    @@ -1,23 +1,22 @@
    11 /*
    2- © 2011-2016, 2018-2023 FrankHB.
    2+ © 2011-2016, 2018-2024 FrankHB.
    33
    4- This file is part of the YSLib project, and may only be used,
    5- modified, and distributed under the terms of the YSLib project
    6- license, LICENSE.TXT. By continuing to use, modify, or distribute
    7- this file you indicate that you have read the license and
    8- understand and accept it fully.
    4+ This file is part of the YSLib project, and may only be used, modified,
    5+ and distributed under the terms of the YSLib project license.
    6+ By continuing to use, modify, or distribute this file you indicate that
    7+ you have read the license and understand and accept it fully.
    98 */
    109
    1110 /*! \file meta.hpp
    1211 \ingroup YStandardEx
    1312 \brief 通用元编程设施。
    14-\version r2119
    13+\version r2562
    1514 \author FrankHB <frankhb1989@gmail.com>
    1615 \since build 832
    1716 \par 创建时间:
    1817 2018-07-23 17:22:28 +0800
    1918 \par 修改时间:
    20- 2023-04-12 12:08 +0800
    19+ 2024-04-05 03:31 +0800
    2120 \par 文本编码:
    2221 UTF-8
    2322 \par 模块名称:
    @@ -30,9 +29,8 @@
    3029
    3130 #include "type_inspection.hpp" // for "type_inspection.hpp", <type_traits>,
    3231 // __cpp_lib_transformation_trait_aliases, __cpp_lib_remove_cvref,
    33-// __cpp_lib_void_t, __cpp_lib_type_identity, true_, is_same, is_convertible,
    34-// or_, nor_, and_, is_class, is_union, is_trivial, not_, is_final, size_t_,
    35-// is_unsigned;
    32+// __cpp_lib_void_t, __cpp_lib_type_identity, _t, true_, is_same,
    33+// is_convertible, size_t_, is_unsigned;
    3634
    3735 /*!
    3836 \brief \c \<type_traits> 特性测试宏。
    @@ -85,14 +83,6 @@
    8583 {
    8684
    8785 /*!
    88-\ingroup metafunctions
    89-\brief 嵌套类型别名。
    90-\since build 649
    91-*/
    92-template<class _type>
    93-using _t = typename _type::type;
    94-
    95-/*!
    9686 \brief 包含 ISO C++ 2011 引入的名称的命名空间。
    9787 \since build 607
    9888 */
    @@ -112,8 +102,45 @@
    112102 using std::add_lvalue_reference;
    113103 using std::add_rvalue_reference;
    114104
    105+#if YB_Impl_ext_int128
    106+/*!
    107+\ingroup YBase_replacement_features unary_type_traits
    108+\since build 983
    109+*/
    110+//!@{
    111+# define YB_Impl_Meta_tt_primary(_n) \
    112+ template<typename _type> \
    113+ struct _n : std::_n<_type> \
    114+ {};
    115+# define YB_Impl_Meta_tt_spec(_n, _t, _t2) \
    116+ template<> \
    117+ struct _n<_t> \
    118+ { \
    119+ using type = _t2; \
    120+ };
    121+# define YB_Impl_Meta_tt_specs(_n, _t, _t2) \
    122+ YB_Impl_Meta_tt_spec(_n, _t, _t2) \
    123+ YB_Impl_Meta_tt_spec(_n, const _t, const _t2) \
    124+ YB_Impl_Meta_tt_spec(_n, volatile _t, volatile _t2) \
    125+ YB_Impl_Meta_tt_spec(_n, const volatile _t, const volatile _t2)
    126+# define YB_Impl_Meta_tt_ext_int128(_n, _t) \
    127+ YB_Impl_Meta_tt_primary(_n) \
    128+ YB_Impl_Meta_tt_spec(_n, int128_t, _t) \
    129+ YB_Impl_Meta_tt_spec(_n, uint128_t, _t)
    130+
    131+YB_Impl_Meta_tt_ext_int128(make_signed, int128_t)
    132+
    133+YB_Impl_Meta_tt_ext_int128(make_unsigned, uint128_t)
    134+
    135+# undef YB_Impl_Meta_tt_ext_int128
    136+# undef YB_Impl_Meta_tt_specs
    137+# undef YB_Impl_Meta_tt_spec
    138+# undef YB_Impl_Meta_tt_primary
    139+//!@}
    140+#else
    115141 using std::make_signed;
    116142 using std::make_unsigned;
    143+#endif
    117144
    118145 using std::remove_extent;
    119146 using std::remove_all_extents;
    @@ -178,76 +205,76 @@
    178205 //! \since build 340
    179206 //!@{
    180207 template<typename _type>
    181-using remove_const_t = typename remove_const<_type>::type;
    182-
    183-template<typename _type>
    184-using remove_volatile_t = typename remove_volatile<_type>::type;
    208+using remove_const_t = _t<remove_const<_type>>;
    185209
    186210 template<typename _type>
    187-using remove_cv_t = typename remove_cv<_type>::type;
    211+using remove_volatile_t = _t<remove_volatile<_type>>;
    188212
    189213 template<typename _type>
    190-using add_const_t = typename add_const<_type>::type;
    214+using remove_cv_t = _t<remove_cv<_type>>;
    191215
    192216 template<typename _type>
    193-using add_volatile_t = typename add_volatile<_type>::type;
    217+using add_const_t = _t<add_const<_type>>;
    194218
    195219 template<typename _type>
    196-using add_cv_t = typename add_cv<_type>::type;
    220+using add_volatile_t = _t<add_volatile<_type>>;
    221+
    222+template<typename _type>
    223+using add_cv_t = _t<add_cv<_type>>;
    197224
    198225
    199226 template<typename _type>
    200-using remove_reference_t = typename remove_reference<_type>::type;
    227+using remove_reference_t = _t<remove_reference<_type>>;
    201228
    202229 template<typename _type>
    203-using add_lvalue_reference_t = typename add_lvalue_reference<_type>::type;
    230+using add_lvalue_reference_t = _t<add_lvalue_reference<_type>>;
    204231
    205232 template<typename _type>
    206-using add_rvalue_reference_t = typename add_rvalue_reference<_type>::type;
    233+using add_rvalue_reference_t = _t<add_rvalue_reference<_type>>;
    207234
    208235
    209236 template<typename _type>
    210-using make_signed_t = typename make_signed<_type>::type;
    237+using make_signed_t = _t<make_signed<_type>>;
    211238
    212239 template<typename _type>
    213-using make_unsigned_t = typename make_unsigned<_type>::type;
    240+using make_unsigned_t = _t<make_unsigned<_type>>;
    214241
    215242
    216243 template<typename _type>
    217-using remove_extent_t = typename remove_extent<_type>::type;
    244+using remove_extent_t = _t<remove_extent<_type>>;
    218245
    219246 template<typename _type>
    220-using remove_all_extents_t = typename remove_all_extents<_type>::type;
    247+using remove_all_extents_t = _t<remove_all_extents<_type>>;
    221248
    222249
    223250 template<typename _type>
    224-using remove_pointer_t = typename remove_pointer<_type>::type;
    251+using remove_pointer_t = _t<remove_pointer<_type>>;
    225252
    226253 template<typename _type>
    227-using add_pointer_t = typename add_pointer<_type>::type;
    254+using add_pointer_t = _t<add_pointer<_type>>;
    228255
    229256
    230257 template<size_t _vLen,
    231258 size_t _vAlign = yalignof(typename aligned_storage<_vLen>::type)>
    232-using aligned_storage_t = typename aligned_storage<_vLen, _vAlign>::type;
    259+using aligned_storage_t = _t<aligned_storage<_vLen, _vAlign>>;
    233260 //!@}
    234261
    235262 //! \since build 339
    236263 //!@{
    237264 template<size_t _vLen, typename... _types>
    238-using aligned_union_t = typename aligned_union<_vLen, _types...>::type;
    265+using aligned_union_t = _t<aligned_union<_vLen, _types...>>;
    239266
    240267 template<typename _type>
    241-using decay_t = typename decay<_type>::type;
    268+using decay_t = _t<decay<_type>>;
    242269
    243270 template<bool _bCond, typename _type = void>
    244-using enable_if_t = typename enable_if<_bCond, _type>::type;
    271+using enable_if_t = _t<enable_if<_bCond, _type>>;
    245272
    246273 template<bool _bCond, typename _type, typename _type2>
    247-using conditional_t = typename conditional<_bCond, _type, _type2>::type;
    274+using conditional_t = _t<conditional<_bCond, _type, _type2>>;
    248275
    249276 template<typename _type>
    250-using underlying_type_t = typename underlying_type<_type>::type;
    277+using underlying_type_t = _t<underlying_type<_type>>;
    251278 //!@}
    252279 #endif
    253280 //!@}
    @@ -297,8 +324,15 @@
    297324 */
    298325 //!@{
    299326 template<typename _type>
    327+#if __has_builtin(__remove_cvref)
    328+struct remove_cvref
    329+{
    330+ using type = __remove_cvref(_type);
    331+};
    332+#else
    300333 struct remove_cvref : remove_cv<remove_reference_t<_type>>
    301334 {};
    335+#endif
    302336
    303337 //! \since build 833
    304338 template<typename _type>
    @@ -372,7 +406,7 @@
    372406
    373407 //! \since build 340
    374408 template<typename... _types>
    375-using common_type_t = typename common_type<_types...>::type;
    409+using common_type_t = _t<common_type<_types...>>;
    376410 //!@}
    377411 //!@}
    378412 #endif
    @@ -414,7 +448,7 @@
    414448 using well_formed_t = _type;
    415449 #else
    416450 template<typename _type, typename... _types>
    417-using well_formed_t = typename always<_type>::template apply<_types...>::type;
    451+using well_formed_t = _t<always<_type>::template apply<_types...>>;
    418452 #endif
    419453
    420454 //! \since build 831
    @@ -539,6 +573,7 @@
    539573
    540574 } // namespace details;
    541575 #endif
    576+#undef YB_Impl_TypeTraits_has_cpp20_common_type
    542577
    543578
    544579 /*!
    @@ -552,6 +587,7 @@
    552587
    553588
    554589 /*!
    590+\ingroup YBase_replacement_features
    555591 \brief 不接受任意参数类型构造的类型。
    556592 \see WG21 N4502 6.6 。
    557593 \since build 649
    @@ -591,18 +627,6 @@
    591627 using type = _gOp<_tParams...>;
    592628 };
    593629
    594-
    595-//! \since build 867
    596-//!@{
    597-template<typename _type1, typename _type2, bool = is_same<_type1, _type2>{}>
    598-struct is_same_or_convertible : is_convertible<_type1, _type2>
    599-{};
    600-
    601-template<typename _type1, typename _type2>
    602-struct is_same_or_convertible<_type1, _type2, true> : true_
    603-{};
    604-//!@}
    605-
    606630 } // namespace details;
    607631
    608632 //! \ingroup YBase_replacement_features
    @@ -631,382 +655,6 @@
    631655 = is_convertible<detected_t<_gOp, _tParams...>, _tTo>;
    632656 //!@}
    633657 //!@}
    634-
    635-
    636-/*!
    637-\ingroup unary_type_traits
    638-\tparam _type 需要判断特征的类型参数。
    639-*/
    640-//!@{
    641-//! \note 以下参数可能是 cv 修饰的类型,结果和去除 cv 修饰符的类型一致。
    642-//!@{
    643-/*!
    644-\brief 判断是否为未知大小的数组类型。
    645-\since build 651
    646-*/
    647-template<typename _type>
    648-struct is_array_of_unknown_bound
    649- : bool_<is_array<_type>() && extent<_type>() == 0>
    650-{};
    651-
    652-
    653-/*!
    654-\brief 判断指定类型是否为对象或 void 类型。
    655-\since build 630
    656-*/
    657-template<typename _type>
    658-struct is_object_or_void : or_<is_object<_type>, is_void<_type>>
    659-{};
    660-
    661-
    662-//! \since build 694
    663-namespace details
    664-{
    665-
    666-template<typename _type>
    667-struct is_referenceable_function : false_
    668-{};
    669-
    670-template<typename _tRes, typename... _tParams ynoexcept_param(ne)>
    671-struct is_referenceable_function<_tRes(_tParams...) ynoexcept_qual(ne)> : true_
    672-{};
    673-
    674-template<typename _tRes, typename... _tParams ynoexcept_param(ne)>
    675-struct is_referenceable_function<_tRes(_tParams..., ...) ynoexcept_qual(ne)>
    676- : true_
    677-{};
    678-
    679-} // namespace details;
    680-
    681-/*!
    682-\brief 判断指定类型是否为可引用类型。
    683-\see ISO C++11 17.3.20 [defns.referenceable] 。
    684-\since build 694
    685-*/
    686-template<typename _type>
    687-struct is_referenceable : or_<is_object<_type>, is_reference<_type>,
    688- details::is_referenceable_function<_type>>
    689-{};
    690-
    691-
    692-/*!
    693-\brief 判断指定类型是否可作为返回类型。
    694-\note 即排除数组类型、抽象类类型和函数类型的所有类型。
    695-\see ISO C++11 8.3.5/8 和 ISO C++11 10.4/3 。
    696-\since build 333
    697-*/
    698-template<typename _type>
    699-struct is_returnable
    700- : nor_<is_array<_type>, is_abstract<_type>, is_function<_type>>
    701-{};
    702-
    703-
    704-/*!
    705-\brief 判断指定类型是否是类类型。
    706-\since build 588
    707-*/
    708-template<typename _type>
    709-struct is_class_type
    710- : or_<is_class<_type>, is_union<_type>>
    711-{};
    712-
    713-
    714-/*!
    715-\brief 判断类型是否为非 const 对象类型。
    716-\since build 650
    717-*/
    718-template<typename _type>
    719-struct is_nonconst_object
    720- : and_<is_object<_type>, is_same<add_const_t<_type>, _type>>
    721-{};
    722-
    723-
    724-//! \since build 630
    725-//!@{
    726-//! \brief 判断指定类型是否是指向对象类型的指针。
    727-template<typename _type>
    728-struct is_pointer_to_object
    729- : and_<is_pointer<_type>, is_object<remove_pointer_t<_type>>>
    730-{};
    731-
    732-
    733-//! \brief 判断指定类型是否是指向对象类型的指针。
    734-template<typename _type>
    735-struct is_object_pointer
    736- : and_<is_pointer<_type>, is_object_or_void<remove_pointer_t<_type>>>
    737-{};
    738-
    739-
    740-//! \brief 判断指定类型是否是指向函数类型的指针。
    741-template<typename _type>
    742-struct is_function_pointer
    743- : and_<is_pointer<_type>, is_function<remove_pointer_t<_type>>>
    744-{};
    745-//!@}
    746-
    747-
    748-//! \since build 333
    749-//!@{
    750-//! \brief 判断指定类型是否是指向类类型的指针。
    751-template<typename _type>
    752-struct is_class_pointer
    753- : and_<is_pointer<_type>, is_class<remove_pointer_t<_type>>>
    754-{};
    755-
    756-
    757-//! \brief 判断指定类型是否是类类型左值引用。
    758-template<typename _type>
    759-struct is_lvalue_class_reference
    760- : and_<is_lvalue_reference<_type>, is_class<remove_reference_t<_type>>>
    761-{};
    762-
    763-
    764-//! \brief 判断指定类型是否是类类型右值引用。
    765-template<typename _type>
    766-struct is_rvalue_class_reference
    767- : and_<is_rvalue_reference<_type>, is_class<remove_reference_t<_type>>>
    768-{};
    769-//!@}
    770-
    771-
    772-/*!
    773-\pre remove_all_extents\<_type> 是完整类型或(可能 cv 修饰的) \c void 。
    774-\see ISO C++17 [class.prop]/2 。
    775-\since build 853
    776-*/
    777-//!@{
    778-/*!
    779-\brief 判断指定类型是否是平凡的非联合类类型。
    780-\note 注意和 ISO C++ 的 \c std::is_class 类似,排除联合。
    781-*/
    782-template<typename _type>
    783-struct is_trivial_class : and_<is_trivial<_type>, is_class<_type>>
    784-{};
    785-
    786-template<typename _type>
    787-struct is_trivial_class_type : and_<is_trivial<_type>, is_class_type<_type>>
    788-{};
    789-
    790-//! \brief 判断指定类型是否是平凡的联合类型。
    791-template<typename _type>
    792-struct is_trivial_union : and_<is_trivial<_type>, is_union<_type>>
    793-{};
    794-//!@}
    795-
    796-
    797-/*!
    798-\brief 判断指定类型是否是可被继承的类类型。
    799-\since build 940
    800-*/
    801-template<typename _type>
    802-struct is_inheritable_class : and_<is_class<_type>, not_<is_final<_type>>>
    803-{};
    804-//!@}
    805-
    806-
    807-/*!
    808-\brief 判断指定类型是否为 const 或 volatile 类型。
    809-\since build 590
    810-*/
    811-template<typename _type>
    812-struct is_cv : or_<is_const<_type>, is_volatile<_type>>
    813-{};
    814-//!@}
    815-
    816-
    817-/*!
    818-\brief 判断指定类型是否可分解为一个参数为类型的模板和类型参数。
    819-\since build 683
    820-*/
    821-//!@{
    822-template<typename>
    823-struct is_decomposable : false_
    824-{};
    825-
    826-template<template<typename...> class _gOp, typename... _types>
    827-struct is_decomposable<_gOp<_types...>> : true_
    828-{};
    829-//!@}
    830-
    831-
    832-/*!
    833-\pre remove_all_extents\<_type> 是完整类型、(可能 cv 修饰的) \c void ,
    834- 或未知大小的数组。
    835-\since build 630
    836-*/
    837-//!@{
    838-template<typename _type>
    839-struct is_copyable
    840- : and_<is_copy_constructible<_type>, is_copy_assignable<_type>>
    841-{};
    842-
    843-
    844-template<typename _type>
    845-struct is_moveable
    846- : and_<is_move_constructible<_type>, is_move_assignable<_type>>
    847-{};
    848-
    849-
    850-template<typename _type>
    851-struct is_nothrow_copyable : and_<is_nothrow_copy_constructible<_type>,
    852- is_nothrow_copy_assignable<_type>>
    853-{};
    854-
    855-
    856-template<typename _type>
    857-struct is_nothrow_moveable : and_<is_nothrow_move_constructible<_type>,
    858- is_nothrow_move_assignable<_type>>
    859-{};
    860-
    861-
    862-template<typename _type>
    863-struct is_trivially_copyable : and_<is_trivially_copy_constructible<_type>,
    864- is_trivially_copy_assignable<_type>>
    865-{};
    866-
    867-
    868-template<typename _type>
    869-struct is_trivially_moveable : and_<is_trivially_move_constructible<_type>,
    870- is_trivially_move_assignable<_type>>
    871-{};
    872-
    873-
    874-/*!
    875-\brief 判断指定类型是否为可复制构造但不可无抛出异常地转移构造的类型。
    876-\note 和 std::move_if_noexcept 需要选择复制的条件相同。
    877-\since build 865
    878-*/
    879-template<typename _type>
    880-struct is_throwing_move_copyable : and_<is_copy_constructible<_type>,
    881- not_<is_nothrow_move_constructible<_type>>>
    882-{};
    883-//!@}
    884-//!@}
    885-
    886-
    887-//! \note 参数可以是不完整类型。
    888-//!@{
    889-//! \ingroup type_traits_operations
    890-//!@{
    891-/*!
    892-\brief 判断指定类型是否已退化为指定类型。
    893-\since build 841
    894-*/
    895-template<typename _type, typename _tTo = _type>
    896-struct is_decayed : is_same<_type, decay_t<_tTo>>
    897-{};
    898-
    899-
    900-/*!
    901-\brief 判断指定类型是否为无限定的指定类型。
    902-\since build 865
    903-*/
    904-template<typename _type, typename _tTo = _type>
    905-struct is_unqualified : is_same<_type, remove_cv_t<_tTo>>
    906-{};
    907-//!@}
    908-
    909-
    910-//! \ingroup unary_type_trait
    911-//!@{
    912-/*!
    913-\brief 判断类型是否为非 const 对象类型。
    914-\since build 867
    915-*/
    916-template<typename _type>
    917-struct is_unqualified_object : and_<is_object<_type>, is_unqualified<_type>>
    918-{};
    919-
    920-
    921-/*!
    922-\brief 判断类型是否为非 const 对象的数组类型。
    923-\since build 972
    924-*/
    925-template<typename _type>
    926-struct is_array_of_unqualified_object : and_<is_array<_type>,
    927- is_unqualified_object<remove_extent_t<_type>>>
    928-{};
    929-//!@}
    930-//!@}
    931-
    932-
    933-//! \ingroup binary_type_traits
    934-//!@{
    935-/*!
    936-\brief 判断指定类型之间是否相同或可转换。
    937-\note 类似 is_convertible ,但不要求完整类型。
    938-\since build 850
    939-*/
    940-template<typename _type1, typename _type2>
    941-struct is_same_or_convertible : details::is_same_or_convertible<_type1, _type2>
    942-{};
    943-
    944-
    945-/*!
    946-\brief 判断指定类型之间是否相同或可互相转换。
    947-\since build 575
    948-*/
    949-template<typename _type1, typename _type2>
    950-struct is_interoperable : or_<is_same_or_convertible<_type1, _type2>,
    951- is_convertible<_type2, _type1>>
    952-{};
    953-
    954-
    955-//! \since build 832
    956-//!@{
    957-//! \brief 判断指定类型是否可被指定参数类型构造且要求显式构造。
    958-template <typename _type, typename _tFrom>
    959-struct is_explicitly_constructible : and_<is_constructible<_type, _tFrom>,
    960- not_<is_convertible<_tFrom, _type>>>
    961-{};
    962-
    963-
    964-//! \brief 判断指定类型是否可被指定参数类型无异常抛出构造且要求显式构造。
    965-template <typename _type, typename _tFrom>
    966-struct is_explicitly_nothrow_constructible : and_<is_nothrow_constructible<
    967- _type, _tFrom>, not_<is_convertible<_tFrom, _type>>>
    968-{};
    969-
    970-
    971-//! \brief 判断指定类型是否可被指定参数类型构造且可隐式构造。
    972-template <typename _type, typename _tFrom>
    973-struct is_implicitly_constructible : and_<is_constructible<_type, _tFrom>,
    974- is_convertible<_tFrom, _type>>
    975-{};
    976-
    977-
    978-//! \brief 判断指定类型是否可被指定参数类型无异常抛出构造且可隐式构造。
    979-template <typename _type, typename _tFrom>
    980-struct is_implicitly_nothrow_constructible : and_<is_nothrow_constructible<
    981- _type, _tFrom>, is_convertible<_tFrom, _type>>
    982-{};
    983-//!@}
    984-
    985-
    986-/*!
    987-\brief 判断第一参数和第二参数指定的参数类型相同。
    988-\since build 865
    989-*/
    990-template<typename _type, typename _tParam>
    991-struct is_same_param : is_same<_type&, decay_t<_tParam>&>
    992-{};
    993-//!@}
    994-
    995-
    996-/*!
    997-\ingroup metafunctions
    998-\since build 671
    999-*/
    1000-//!@{
    1001-//! \brief 判断第一参数和之后的参数指定的类型相同。
    1002-template<typename _type, typename... _types>
    1003-struct are_same : and_<is_same<_type, _types>...>
    1004-{};
    1005-
    1006-//! \brief 判断第一参数在之后参数指定的类型中出现。
    1007-template<typename _type, typename... _types>
    1008-struct is_in_types : or_<is_same<_type, _types>...>
    1009-{};
    1010658 //!@}
    1011659
    1012660
    @@ -1087,24 +735,73 @@
    1087735 //!@}
    1088736
    1089737
    1090-/*!
    1091-\ingroup transformation_traits
    1092-\since build 942
    1093-*/
    1094-//!@{
    738+//! \since build 942
    1095739 template<typename... _types>
    1096740 using empty_pack_t = bool_<sizeof...(_types) == 0>;
    1097741
    742+//! \since build 942
    1098743 template<typename... _types>
    1099744 using sizeof_pack_t = size_t_<sizeof...(_types)>;
    745+
    746+
    747+//! \since build 983
    748+//!@{
    749+/*!
    750+\brief 复制第二模板参数的 cv 限定符到第一模板参数指定的类型。
    751+\see https://www.boost.org/doc/libs/1_84_0/libs/type_traits/doc/html/boost_typetraits/reference/copy_cv.html 。
    752+*/
    753+//!@{
    754+template<typename _type, typename _type2>
    755+struct copy_cv
    756+{
    757+private:
    758+ using ctype = cond_t<is_const<_type2>, add_const<_type>, _type>;
    759+
    760+public:
    761+ using type = cond_t<is_volatile<_type2>, add_volatile_t<ctype>, ctype>;
    762+};
    763+
    764+template<typename _type, typename _type2>
    765+using copy_cv_t = _t<copy_cv<_type, _type2>>;
    1100766 //!@}
    1101767
    768+
    1102769 /*!
    1103-\ingroup unary_type_traits
    1104-\since build 843
    770+\brief 复制第二模板参数的引用类型限定符到第一模板参数指定的类型。
    771+\note 结果类型中的引用限定符按引用折叠规则合并两个模板参数中的引用限定符。
    772+\see https://www.boost.org/doc/libs/1_84_0/libs/type_traits/doc/html/boost_typetraits/reference/copy_reference.html 。
    1105773 */
    1106-template<typename _type>
    1107-using sizeof_t = size_t_<sizeof(_type)>;
    774+//!@{
    775+template<typename _type, typename _type2>
    776+struct copy_reference
    777+{
    778+ using type = cond_t<is_rvalue_reference<_type2>,
    779+ add_rvalue_reference_t<_type>, cond_t<is_lvalue_reference<_type2>,
    780+ add_lvalue_reference<_type>, _type>>;
    781+};
    782+
    783+template<typename _type, typename _type2>
    784+using copy_reference_t = _t<copy_reference<_type, _type2>>;
    785+//!@}
    786+
    787+
    788+/*!
    789+\brief 复制第二模板参数的 cv 和引用类型限定符到第一模板参数指定的类型。
    790+\note 和 \c boost::copy_cv_ref 不同,遵循 remove_cvref 的命名,不添加过多 \c _ 。
    791+\see https://www.boost.org/doc/libs/1_84_0/libs/type_traits/doc/html/boost_typetraits/reference/copy_cv_ref.html 。
    792+*/
    793+//!@{
    794+template<typename _type, typename _type2>
    795+struct copy_cvref
    796+{
    797+ using type = copy_reference_t<
    798+ copy_cv_t<_type, remove_reference_t<_type2>>, _type2>;
    799+};
    800+
    801+template<typename _type, typename _type2>
    802+using copy_cvref_t = _t<copy_cvref<_type, _type2>>;
    803+//!@}
    804+//!@}
    1108805
    1109806
    1110807 /*!
    @@ -1155,6 +852,14 @@
    1155852 = enable_if_t<is_same_param<_type1, _type2>{}, _type>;
    1156853
    1157854 /*!
    855+\brief 启用浮点数类型参数的重载。
    856+\since build 983
    857+*/
    858+template<typename _tParam, typename _type = remove_cvref_t<_tParam>>
    859+using enable_if_floating_point_t
    860+ = enable_if_t<is_floating_point<remove_cvref_t<_tParam>>{}, _type>;
    861+
    862+/*!
    1158863 \brief 启用无符号类型参数的重载。
    1159864 \since build 933
    1160865 */
    diff -r 3fe9fa0c6127 -r 74e1025f0a02 YBase/include/ystdex/optional.h
    --- a/YBase/include/ystdex/optional.h Tue Feb 27 00:28:20 2024 +0800
    +++ b/YBase/include/ystdex/optional.h Fri Apr 19 22:42:25 2024 +0800
    @@ -1,23 +1,22 @@
    11 /*
    2- © 2015-2023 FrankHB.
    2+ © 2015-2024 FrankHB.
    33
    4- This file is part of the YSLib project, and may only be used,
    5- modified, and distributed under the terms of the YSLib project
    6- license, LICENSE.TXT. By continuing to use, modify, or distribute
    7- this file you indicate that you have read the license and
    8- understand and accept it fully.
    4+ This file is part of the YSLib project, and may only be used, modified,
    5+ and distributed under the terms of the YSLib project license.
    6+ By continuing to use, modify, or distribute this file you indicate that
    7+ you have read the license and understand and accept it fully.
    98 */
    109
    1110 /*! \file optional.h
    1211 \ingroup YStandardEx
    1312 \brief 可选值包装类型。
    14-\version r1424
    13+\version r1435
    1514 \author FrankHB <frankhb1989@gmail.com>
    1615 \since build 590
    1716 \par 创建时间:
    1817 2015-04-09 21:35:21 +0800
    1918 \par 修改时间:
    20- 2023-02-07 22:08 +0800
    19+ 2024-03-30 23:43 +0800
    2120 \par 文本编码:
    2221 UTF-8
    2322 \par 模块名称:
    @@ -55,7 +54,7 @@
    5554 #if YB_Has_optional != 1
    5655 # include "operators.hpp" // for or_, is_constructible,
    5756 // is_trivially_destructible, is_cv, std::move, empty_base,
    58-// is_nothrow_moveable, and_, nullptr_t, remove_cv_t, totally_ordered, nand_,
    57+// is_nothrow_movable, and_, nullptr_t, remove_cv_t, totally_ordered, nand_,
    5958 // is_reference, is_same, is_nothrow_destructible, is_object, enable_if_t,
    6059 // not_, decay_t, is_nothrow_swappable, ystdex::addressof, is_copyable;
    6160 # include <initializer_list> // for std::initializer_list;
    @@ -192,7 +191,7 @@
    192191 }
    193192 //! \since build 630
    194193 optional_base&
    195- operator=(optional_base&& s) ynoexcept(is_nothrow_moveable<_type>())
    194+ operator=(optional_base&& s) ynoexcept(is_nothrow_movable<_type>())
    196195 {
    197196 return assign(std::move(s.value));
    198197 }
    @@ -201,7 +200,7 @@
    201200 template<typename _tParam>
    202201 optional_base&
    203202 assign(_tParam&& arg) ynoexcept(and_<is_rvalue_reference<_tParam&&>,
    204- is_nothrow_moveable<_type>>())
    203+ is_nothrow_movable<_type>>())
    205204 {
    206205 if(has_value() && arg.has_value())
    207206 value = yforward(arg);
    @@ -344,7 +343,7 @@
    344343 \ingroup YBase_replacement_features
    345344 \brief 可选值对象包装。
    346345 \note 值语义。基本接口和语义同 std::experimental::optional 提议
    347- 和 boost::optional (对应接口以前者为准)。
    346+ 和 boost::optional(对应接口以前者为准)。
    348347 \warning 非虚析构。
    349348 \see WG21 N4606 20.6.3[optional.object] 。
    350349 \todo allocator_arg 支持。
    @@ -477,7 +476,7 @@
    477476 }
    478477 //! \since build 630
    479478 optional&
    480- operator=(optional&& o) ynoexcept(is_nothrow_moveable<_type>())
    479+ operator=(optional&& o) ynoexcept(is_nothrow_movable<_type>())
    481480 {
    482481 get_base() = std::move(o.get_base());
    483482 return *this;
    diff -r 3fe9fa0c6127 -r 74e1025f0a02 YBase/include/ystdex/set.hpp
    --- a/YBase/include/ystdex/set.hpp Tue Feb 27 00:28:20 2024 +0800
    +++ b/YBase/include/ystdex/set.hpp Fri Apr 19 22:42:25 2024 +0800
    @@ -1,23 +1,22 @@
    11 /*
    22 © 2016-2019, 2021, 2023 FrankHB.
    33
    4- This file is part of the YSLib project, and may only be used,
    5- modified, and distributed under the terms of the YSLib project
    6- license, LICENSE.TXT. By continuing to use, modify, or distribute
    7- this file you indicate that you have read the license and
    8- understand and accept it fully.
    4+ This file is part of the YSLib project, and may only be used, modified,
    5+ and distributed under the terms of the YSLib project license.
    6+ By continuing to use, modify, or distribute this file you indicate that
    7+ you have read the license and understand and accept it fully.
    98 */
    109
    1110 /*! \file set.hpp
    1211 \ingroup YStandardEx
    1312 \brief 集合容器。
    14-\version r2073
    13+\version r2084
    1514 \author FrankHB <frankhb1989@gmail.com>
    1615 \since build 665
    1716 \par 创建时间:
    1817 2016-01-23 20:13:53 +0800
    1918 \par 修改时间:
    20- 2023-02-13 20:13 +0800
    19+ 2024-04-10 22:42 +0800
    2120 \par 文本编码:
    2221 UTF-8
    2322 \par 模块名称:
    @@ -622,9 +621,9 @@
    622621 // away now (with %YB_Impl_Set_UseGenericLookup).
    623622 // XXX: G++ 5.2.0 rejects generic associative lookup in debug mode of %std::map.
    624623 // TODO: Find precise version supporting debug mode.
    625-#if ((__cpp_lib_generic_associative_lookup >= 201304L \
    626- || __cplusplus >= 201402L) && !(defined(__GLIBCXX__) \
    627- && defined(_GLIBCXX_DEBUG)))
    624+#if (__cpp_lib_generic_associative_lookup >= 201304L \
    625+ || __cplusplus >= 201402L) \
    626+ && !(defined __GLIBCXX__ && defined _GLIBCXX_DEBUG)
    628627 # define YB_Impl_MappedSet_UseGenericLookup true
    629628 #else
    630629 # define YB_Impl_MappedSet_UseGenericLookup false
    @@ -797,7 +796,6 @@
    797796 \brief 允许指定不同于值类型的键的集合。
    798797 \warning 若修改的值使键不等价,行为未定义。
    799798 \sa mapped_set_traits
    800-\sa ystdex::try_emplace
    801799 \see WG21 N3456 23.2.4 [associative.reqmts] 。
    802800 \see Documentation::YBase @2.1.4.1 。
    803801 \see Documentation::YBase @2.1.4.2 。
    @@ -1205,9 +1203,9 @@
    12051203
    12061204 // XXX: The exception specification is changed. See the comment for the
    12071205 // function %swap of %ystdex::map.
    1208- //! \since build 967
    1206+ //! \since build 983
    12091207 void
    1210- swap(mapped_set& s) ynoexcept_spec(is_nothrow_move_assignable<_fComp>())
    1208+ swap(mapped_set& s) ynoexcept(is_nothrow_move_assignable<_fComp>())
    12111209 {
    12121210 m_map.swap(s.m_map);
    12131211 }
    diff -r 3fe9fa0c6127 -r 74e1025f0a02 YBase/include/ystdex/string.hpp
    --- a/YBase/include/ystdex/string.hpp Tue Feb 27 00:28:20 2024 +0800
    +++ b/YBase/include/ystdex/string.hpp Fri Apr 19 22:42:25 2024 +0800
    @@ -1,5 +1,5 @@
    11 /*
    2- © 2012-2023 FrankHB.
    2+ © 2012-2024 FrankHB.
    33
    44 This file is part of the YSLib project, and may only be used, modified,
    55 and distributed under the terms of the YSLib project license.
    @@ -10,13 +10,13 @@
    1010 /*! \file string.hpp
    1111 \ingroup YStandardEx
    1212 \brief ISO C++ 标准字符串扩展。
    13-\version r4006
    13+\version r4160
    1414 \author FrankHB <frankhb1989@gmail.com>
    1515 \since build 304
    1616 \par 创建时间:
    1717 2012-04-26 20:12:19 +0800
    1818 \par 修改时间:
    19- 2023-05-27 21:51 +0800
    19+ 2024-04-18 22:25 +0800
    2020 \par 文本编码:
    2121 UTF-8
    2222 \par 模块名称:
    @@ -28,18 +28,20 @@
    2828 #define YB_INC_ystdex_string_hpp_ 1
    2929
    3030 #include "string_view.hpp" // for internal "string_view.hpp" (implying
    31-// "range.hpp" and "<libdefect/string.h>"), std::basic_string,
    31+// "range.hpp" and <libdefect/string.h>), std::basic_string,
    3232 // std::char_traits, or_, std::initializer_list, hash, std::hash,
    3333 // basic_string_view, is_fast_hash, false_, remove_cvref_t, std::declval,
    3434 // enable_if_inconvertible_t, enable_if_t, is_object,
    3535 // decay_t, true_, std::bidirectional_iterator_tag, is_class, is_equal,
    36-// is_same, std::to_string, is_enum;
    36+// std::to_string, is_signed, is_arithmetic, is_integral, is_enum, is_same;
    3737 #include "allocator.hpp" // for internal "allocator.hpp", std::allocator,
    3838 // allocator_traits, nested_allocator, yconstraint, yassume,
    3939 // ystdex::make_obj_using_allocator, YAssert;
    4040 #include "container.hpp" // for "container.hpp", enable_for_input_iterator_t,
    4141 // make_index_sequence, index_sequence, begin, end, empty, size,
    4242 // ystdex::sort_unique, ystdex::underlying;
    43+#include "charconv.h" // for "charconv.h", std::numeric_limits (with fixes),
    44+// ystdex::write_decimal_integer;
    4345 #include "cstring.h" // for ystdex::ntctslen, ystdex::is_null;
    4446 #include "array.hpp" // for to_array;
    4547 #include <istream> // for std::basic_istream;
    @@ -861,6 +863,18 @@
    861863 {};
    862864
    863865
    866+//! \since build 983
    867+namespace details
    868+{
    869+
    870+// XXX: Not using '__cpp_lib_string_resize_and_overwrite >= 202110L' because
    871+// types other than %std::basic_string can also have such interface.
    872+template<typename _type, typename... _tParams>
    873+using mem_resize_and_overwrite_t = decltype(std::declval<_type&>()
    874+ .resize_and_overwrite(std::declval<_tParams>()...));
    875+
    876+} // namespace details;
    877+
    864878 /*!
    865879 \ingroup traits
    866880 \brief 字符串特征。
    @@ -885,6 +899,14 @@
    885899 using pointer = value_type*;
    886900 using const_pointer = const value_type*;
    887901 using initializer = std::initializer_list<value_type>;
    902+ /*!
    903+ \brief 具有兼容 ISO C++23 的成员 \c resize_and_overwrite 。
    904+ \sa WG21 P1072R10 。
    905+ \since build 983
    906+ */
    907+ using has_member_resize_and_overwrite
    908+ = is_detected_exact<void, details::mem_resize_and_overwrite_t, _tString,
    909+ size_type, size_type(&)(pointer, size_type)>;
    888910 };
    889911
    890912
    @@ -2006,53 +2028,170 @@
    20062028 result_type, _tString>;
    20072029 };
    20082030
    2009-template<typename _type>
    2010-using excluded_tostr
    2011- = or_<is_same<_type, unsigned short>, is_same<_type, unsigned char>>;
    2031+//! \since build 983
    2032+//!@{
    2033+template<class _tString, typename _type>
    2034+void
    2035+write_string_int(_tString& buf, _type val, false_)
    2036+{
    2037+ buf.resize(std::numeric_limits<_type>::digits10 + 2);
    20122038
    2013-template<typename _type>
    2014-YB_ATTR_nodiscard inline auto
    2015-arithmetic_to_string(_type val, false_) -> decltype(std::to_string(val))
    2039+ auto p(&buf[0]);
    2040+
    2041+ if(val < 0)
    2042+ yunseq(*p++ = '-', val = -val);
    2043+ buf.resize(typename _tString::size_type(ystdex::write_decimal_integer(p,
    2044+ make_unsigned_t<_type>(val)) - &buf[0]));
    2045+}
    2046+template<class _tString, typename _type>
    2047+void
    2048+write_string_int(_tString& buf, _type val, true_)
    20162049 {
    2017- return std::to_string(val);
    2050+ buf.resize_and_overwrite(std::numeric_limits<_type>::digits10 + 2,
    2051+ [&] YB_LAMBDA_ANNOTATE((char* p, typename _tString::size_type),
    2052+ ynothrowv, nonnull(2)){
    2053+ if(val < 0)
    2054+ yunseq(*p++ = '-', val = -val);
    2055+ return typename _tString::size_type(ystdex::write_decimal_integer(p,
    2056+ make_unsigned_t<_type>(val)) - &buf[0]);
    2057+ });
    20182058 }
    2019-YB_ATTR_nodiscard inline string
    2020-arithmetic_to_string(unsigned val, true_)
    2059+template<class _tString, typename _type>
    2060+void
    2061+write_string_int(_tString& buf, _type val)
    20212062 {
    2022- return std::to_string(val);
    2063+ details::write_string_int(buf, val,
    2064+ typename string_traits<_tString>::has_member_resize_and_overwrite());
    20232065 }
    20242066
    2025-template<typename _type>
    2026-YB_ATTR_nodiscard inline auto
    2027-arithmetic_to_wstring(_type val, false_) -> decltype(std::to_wstring(val))
    2067+template<class _tString, typename _type>
    2068+void
    2069+write_string_uint(_tString& buf, _type val, false_)
    20282070 {
    2029- return std::to_wstring(val);
    2071+ buf.resize(std::numeric_limits<_type>::digits10 + 1);
    2072+ buf.resize(typename _tString::size_type(
    2073+ ystdex::write_decimal_integer(&buf[0], val) - &buf[0]));
    20302074 }
    2031-YB_ATTR_nodiscard inline wstring
    2032-arithmetic_to_wstring(unsigned val, true_)
    2075+template<class _tString, typename _type>
    2076+void
    2077+write_string_uint(_tString& buf, _type val, true_)
    20332078 {
    2034- return std::to_wstring(val);
    2079+ buf.resize_and_overwrite(std::numeric_limits<_type>::digits10 + 1,
    2080+ [&] YB_LAMBDA_ANNOTATE((char* p, typename _tString::size_type),
    2081+ ynothrowv, nonnull(2)){
    2082+ return typename
    2083+ _tString::size_type(ystdex::write_decimal_integer(p, val) - p);
    2084+ });
    20352085 }
    2086+template<class _tString, typename _type>
    2087+void
    2088+write_string_uint(_tString& buf, _type val)
    2089+{
    2090+ details::write_string_uint(buf, val,
    2091+ typename string_traits<_tString>::has_member_resize_and_overwrite());
    2092+}
    2093+
    2094+template<class _tString, typename _type, typename... _tParams>
    2095+YB_ATTR_nodiscard YB_PURE inline _tString
    2096+integral_to_string(_type val, false_, _tParams&&... args)
    2097+{
    2098+ _tString buf(yforward(args)...);
    2099+
    2100+ details::write_string_uint(buf, val);
    2101+ return buf;
    2102+}
    2103+template<class _tString, typename _type, typename... _tParams>
    2104+YB_ATTR_nodiscard YB_PURE inline _tString
    2105+integral_to_string(_type val, true_, _tParams&&... args)
    2106+{
    2107+ _tString buf(yforward(args)...);
    2108+
    2109+ details::write_string_int(buf, val);
    2110+ return buf;
    2111+}
    2112+
    2113+template<class _tString, typename _type>
    2114+YB_ATTR_nodiscard inline auto
    2115+arithmetic_to_string(_type val, false_)
    2116+ -> decltype(_tString(std::to_string(val)))
    2117+{
    2118+ return _tString(std::to_string(val));
    2119+}
    2120+template<class _tString, typename _type, class _tAlloc>
    2121+YB_ATTR_nodiscard inline auto
    2122+arithmetic_to_string(_type val, false_, const _tAlloc& a)
    2123+ -> decltype(_tString(std::to_string(val), a))
    2124+{
    2125+ return _tString(std::to_string(val), a);
    2126+}
    2127+template<class _tString, typename _type>
    2128+YB_ATTR_nodiscard YB_PURE inline _tString
    2129+arithmetic_to_string(_type val, true_)
    2130+{
    2131+ return details::integral_to_string<_tString>(val, is_signed<_type>());
    2132+}
    2133+template<class _tString, typename _type, class _tAlloc>
    2134+YB_ATTR_nodiscard YB_PURE inline _tString
    2135+arithmetic_to_string(_type val, true_, const _tAlloc& a)
    2136+{
    2137+ return details::integral_to_string<_tString>(val, is_signed<_type>(), a);
    2138+}
    2139+
    2140+template<class _tString, typename _type>
    2141+YB_ATTR_nodiscard inline auto
    2142+arithmetic_to_wstring(_type val, false_)
    2143+ -> decltype(_tString(std::to_wstring(val)))
    2144+{
    2145+ return _tString(std::to_wstring(val));
    2146+}
    2147+template<class _tString, typename _type, class _tAlloc>
    2148+YB_ATTR_nodiscard inline auto
    2149+arithmetic_to_wstring(_type val, false_, const _tAlloc& a)
    2150+ -> decltype(std::to_wstring(val))
    2151+{
    2152+ return _tString(std::to_wstring(val), a);
    2153+}
    2154+template<class _tString, typename _type>
    2155+YB_ATTR_nodiscard YB_PURE inline _tString
    2156+arithmetic_to_wstring(_type val, true_)
    2157+{
    2158+ return details::integral_to_string<_tString>(val, is_signed<_type>());
    2159+}
    2160+template<class _tString, typename _type, class _tAlloc>
    2161+YB_ATTR_nodiscard YB_PURE inline _tString
    2162+arithmetic_to_wstring(_type val, true_, const _tAlloc& a)
    2163+{
    2164+ return details::integral_to_string<_tString>(val, is_signed<_type>(), a);
    2165+}
    2166+//!@}
    20362167
    20372168 } // namespace details;
    20382169
    20392170 /*!
    20402171 \brief 转换为字符串:basic_string 的实例对象。
    2041-\note 可与标准库的同名函数共用以避免某些类型转换警告,如 G++ 的 [-Wsign-promo] 。
    2172+\sa WG21 P1072R10 。
    20422173 \since build 928
    2174+
    2175+和标准库不同,可通过第一模板参数指定字符串,并可选通过结尾的函数参数支持分配器。
    2176+指定的字符串应和 \c std::basic_string 兼容,即任意接口若存在,
    2177+ 其行为和 \c std::basic_string 一致。
    2178+特定版本的 \c std::basic_string 可被自动检查并依赖:
    2179+ \li \c 成员 overwrite_for_resize 。
    2180+可与标准库的同名函数共用以避免某些类型转换警告,如 G++ 的 [-Wsign-promo] 。
    20432181 */
    20442182 //!@{
    20452183 template<class _tString = string, typename _type>
    20462184 YB_ATTR_nodiscard inline yimpl(enable_if_t)<is_arithmetic<_type>{}, _tString>
    20472185 to_string(_type val)
    20482186 {
    2049- return details::arithmetic_to_string(val, details::excluded_tostr<_type>());
    2187+ return details::arithmetic_to_string<_tString>(val, is_integral<_type>());
    20502188 }
    20512189 template<class _tString = string, typename _type>
    20522190 YB_ATTR_nodiscard inline yimpl(enable_if_t)<is_arithmetic<_type>{}, _tString>
    20532191 to_string(_type val, typename _tString::allocator_type a)
    20542192 {
    2055- return _tString(ystdex::to_string(val), a);
    2193+ return
    2194+ details::arithmetic_to_string<_tString>(val, is_integral<_type>(), a);
    20562195 }
    20572196 template<class _tString = string, typename _type>
    20582197 YB_ATTR_nodiscard inline yimpl(enable_if_t)<is_enum<_type>{}, _tString>
    @@ -2102,13 +2241,14 @@
    21022241 YB_ATTR_nodiscard inline yimpl(enable_if_t)<is_arithmetic<_type>{}, _tString>
    21032242 to_wstring(_type val)
    21042243 {
    2105- return details::arithmetic_to_wstring(val, details::excluded_tostr<_type>());
    2244+ return details::arithmetic_to_wstring<_tString>(val, is_integral<_type>());
    21062245 }
    21072246 template<class _tString = wstring, typename _type>
    21082247 YB_ATTR_nodiscard inline yimpl(enable_if_t)<is_arithmetic<_type>{}, _tString>
    21092248 to_wstring(_type val, typename _tString::allocator_type a)
    21102249 {
    2111- return _tString(ystdex::to_wstring(val), a);
    2250+ return
    2251+ details::arithmetic_to_wstring<_tString>(val, is_integral<_type>(), a);
    21122252 }
    21132253 template<class _tString = wstring, typename _type>
    21142254 YB_ATTR_nodiscard inline yimpl(enable_if_t)<is_enum<_type>{}, _tString>
    diff -r 3fe9fa0c6127 -r 74e1025f0a02 YBase/include/ystdex/type_inspection.hpp
    --- a/YBase/include/ystdex/type_inspection.hpp Tue Feb 27 00:28:20 2024 +0800
    +++ b/YBase/include/ystdex/type_inspection.hpp Fri Apr 19 22:42:25 2024 +0800
    @@ -1,5 +1,5 @@
    11 /*
    2- © 2011-2013, 2016, 2018-2019, 2021-2023 FrankHB.
    2+ © 2011-2013, 2016, 2018-2019, 2021-2024 FrankHB.
    33
    44 This file is part of the YSLib project, and may only be used, modified,
    55 and distributed under the terms of the YSLib project license.
    @@ -10,13 +10,13 @@
    1010 /*! \file type_inspection.hpp
    1111 \ingroup YStandardEx
    1212 \brief 类型检查元编程设施。
    13-\version r2050
    13+\version r2576
    1414 \author FrankHB <frankhb1989@gmail.com>
    1515 \since build 832
    1616 \par 创建时间:
    1717 2018-07-23 17:54:58 +0800
    1818 \par 修改时间:
    19- 2023-09-13 05:45 +0800
    19+ 2024-04-04 21:51 +0800
    2020 \par 文本编码:
    2121 UTF-8
    2222 \par 模块名称:
    @@ -28,8 +28,11 @@
    2828 #define YB_INC_ystdex_type_inspection_hpp_ 1
    2929
    3030 #include "integral_constant.hpp" // for "integral_constant.hpp", <type_traits>,
    31-// __cpp_lib_is_null_pointer, __cpp_lib_is_final, std::remove_cv_t, nullptr_t,
    32-// bool_, __has_extension, false_;
    31+// __cpp_lib_is_null_pointer, __cpp_lib_is_final, std::remove_cv, nullptr_t,
    32+// bool_, __has_extension, false_, YB_Use_int128, or_, int128_t, uint128_t,
    33+// and_, not_, std::add_const, std::remove_reference, std::remove_pointer,
    34+// true_, nor_, size_t_, std::add_cv;
    35+#include <climits> // for CHAR_BIT;
    3336
    3437 /*!
    3538 \brief \c \<type_traits> 特性测试宏。
    @@ -58,6 +61,7 @@
    5861 /*! \defgroup type_traits_operations Type Traits Operations
    5962 \ingroup metafunctions traits
    6063 \brief 类型特征操作。
    64+\note 同 [meta.rqmts] ,除非另行指定,允许不完整类型作为模板参数的特定使用。
    6165 \since build 306
    6266 */
    6367
    @@ -84,6 +88,15 @@
    8488
    8589
    8690 /*!
    91+\ingroup metafunctions
    92+\brief 嵌套类型别名。
    93+\since build 649
    94+*/
    95+template<class _type>
    96+using _t = typename _type::type;
    97+
    98+
    99+/*!
    87100 \brief 包含 ISO C++ 2011 引入的名称的命名空间。
    88101 \since build 607
    89102 */
    @@ -91,9 +104,80 @@
    91104 {
    92105
    93106 //! \since build 245
    107+using std::is_void;
    108+
    109+} // inline namespace cpp2011;
    110+
    111+/*!
    112+\brief 包含 ISO C++ 2014 引入的名称的命名空间。
    113+\since build 607
    114+*/
    115+inline namespace cpp2014
    116+{
    117+
    118+/*!
    119+\see LWG 2247 。
    120+\since build 832
    121+*/
    94122 //!@{
    95-using std::is_void;
    123+#if __cpp_lib_is_null_pointer >= 201309L
    124+using std::is_null_pointer;
    125+#else
    126+//! \ingroup YBase_replacement_features unary_type_traits
    127+template<typename _type>
    128+struct is_null_pointer : std::is_same<_t<std::remove_cv<_type>>, nullptr_t>
    129+{};
    130+#endif
    131+//!@}
    132+} // inline namespace cpp2014;
    133+
    134+inline namespace cpp2011
    135+{
    136+
    137+// NOTE: See $2024-03 @ %Documentation::Workflow.
    138+#if YB_Use_int128 > 0 && ((defined __GLIBCXX__ && defined __STRICT_ANSI__) \
    139+ || (defined _LIBCPP_VERSION && _LIBCPP_VERSION <= 1101))
    140+# define YB_Impl_ext_int128 true
    141+#else
    142+# define YB_Impl_ext_int128 false
    143+#endif
    144+
    145+#if !YB_HAS_BUILTIN_NULLPTR || YB_Impl_ext_int128
    146+# define YB_Impl_TypeInspection_ut_primary(_n) \
    147+ template<typename _type> \
    148+ struct _n : std::_n<_type> \
    149+ {};
    150+#endif
    151+
    152+#if YB_Impl_ext_int128
    153+# define YB_Impl_TypeInspection_ut_spec(_n, _t) \
    154+ template<> \
    155+ struct _n<_t> : true_ \
    156+ {};
    157+# define YB_Impl_TypeInspection_ut_specs(_n, _t) \
    158+ YB_Impl_TypeInspection_ut_spec(_n, _t) \
    159+ YB_Impl_TypeInspection_ut_spec(_n, const _t) \
    160+ YB_Impl_TypeInspection_ut_spec(_n, volatile _t) \
    161+ YB_Impl_TypeInspection_ut_spec(_n, const volatile _t)
    162+# define YB_Impl_TypeInspection_ut_ext_int128(_n) \
    163+ YB_Impl_TypeInspection_ut_primary(_n) \
    164+ YB_Impl_TypeInspection_ut_specs(_n, int128_t) \
    165+ YB_Impl_TypeInspection_ut_specs(_n, uint128_t)
    166+#endif
    167+
    168+//! \since build 245
    169+//!@{
    170+#if YB_Impl_ext_int128
    171+/*!
    172+\ingroup YBase_replacement_features unary_type_traits
    173+\since build 983
    174+*/
    175+//!@{
    176+YB_Impl_TypeInspection_ut_ext_int128(is_integral)
    177+//!@}
    178+#else
    96179 using std::is_integral;
    180+#endif
    97181 using std::is_floating_point;
    98182 using std::is_array;
    99183 using std::is_pointer;
    @@ -102,31 +186,122 @@
    102186 using std::is_member_object_pointer;
    103187 using std::is_member_function_pointer;
    104188 using std::is_enum;
    189+#if YB_HAS_BUILTIN_NULLPTR
    105190 using std::is_class;
    191+#else
    192+/*!
    193+\ingroup YBase_replacement_features unary_type_traits
    194+\since build 983
    195+*/
    196+template<typename _type>
    197+struct is_class : and_<std::is_class<_type>, not_<is_null_pointer<_type>>>
    198+{};
    199+#endif
    106200 using std::is_union;
    107201 using std::is_function;
    108202
    109203 using std::is_reference;
    204+#if YB_Impl_ext_int128
    205+/*!
    206+\ingroup YBase_replacement_features unary_type_traits
    207+\since build 983
    208+*/
    209+//!@{
    210+YB_Impl_TypeInspection_ut_ext_int128(is_arithmetic)
    211+//!@}
    212+#else
    110213 using std::is_arithmetic;
    214+#endif
    215+#if !YB_HAS_BUILTIN_NULLPTR || YB_Impl_ext_int128
    216+/*!
    217+\ingroup YBase_replacement_features unary_type_traits
    218+\since build 983
    219+*/
    220+//!@{
    221+YB_Impl_TypeInspection_ut_ext_int128(is_fundamental)
    222+//!@}
    223+#else
    111224 using std::is_fundamental;
    225+#endif
    112226 using std::is_object;
    227+#if !YB_HAS_BUILTIN_NULLPTR || YB_Impl_ext_int128
    228+/*!
    229+\ingroup YBase_replacement_features unary_type_traits
    230+\since build 983
    231+*/
    232+//!@{
    233+# if YB_HAS_BUILTIN_NULLPTR
    234+YB_Impl_TypeInspection_ut_primary(is_scalar)
    235+
    236+YB_Impl_TypeInspection_ut_primary(is_compound)
    237+# else
    238+template<typename _type>
    239+struct is_scalar : or_<std::is_scalar<_type>, is_null_pointer<_type>>
    240+{};
    241+
    242+template<typename _type>
    243+struct is_compound : or_<std::is_compound<_type>, not_<is_null_pointer<_type>>>
    244+{};
    245+# endif
    246+
    247+# if YB_Impl_ext_int128
    248+YB_Impl_TypeInspection_ut_specs(is_scalar, int128_t)
    249+YB_Impl_TypeInspection_ut_specs(is_scalar, uint128_t)
    250+
    251+YB_Impl_TypeInspection_ut_specs(is_compound, int128_t)
    252+YB_Impl_TypeInspection_ut_specs(is_compound, uint128_t)
    253+# endif
    254+//!@}
    255+#else
    113256 using std::is_scalar;
    114257 using std::is_compound;
    258+#endif
    115259 using std::is_member_pointer;
    116260
    117261 using std::is_const;
    118262 using std::is_volatile;
    119263 using std::is_trivial;
    120-// using std::is_trivially_copyable;
    264+/*!
    265+\since build 983
    266+\see CWG 1734 。
    267+*/
    268+// NOTE: It is unspecified whether the resolution of CWG 1734 is applied. See
    269+// also $2024-03 @ %Documentation::Workflow.
    270+using std::is_trivially_copyable;
    121271 using std::is_standard_layout;
    122272 using std::is_empty;
    123273 using std::is_polymorphic;
    124274 using std::is_abstract;
    125275
    276+#if YB_Impl_ext_int128
    277+/*!
    278+\ingroup YBase_replacement_features unary_type_traits
    279+\since build 983
    280+*/
    281+//!@{
    282+YB_Impl_TypeInspection_ut_primary(is_signed)
    283+YB_Impl_TypeInspection_ut_specs(is_signed, int128_t)
    284+
    285+YB_Impl_TypeInspection_ut_primary(is_unsigned)
    286+YB_Impl_TypeInspection_ut_specs(is_unsigned, uint128_t)
    287+//!@}
    288+#else
    126289 using std::is_signed;
    127290 using std::is_unsigned;
    291+#endif
    292+
    293+#if YB_Impl_ext_int128
    294+# undef YB_Impl_TypeInspection_ut_ext_int128
    295+# undef YB_Impl_TypeInspection_ut_specs
    296+# undef YB_Impl_TypeInspection_ut_spec
    297+#endif
    298+
    299+#if !YB_HAS_BUILTIN_NULLPTR || YB_Impl_ext_int128
    300+# undef YB_Impl_TypeInspection_ut_primary
    301+#endif
    128302
    129303 using std::is_constructible;
    304+//!@}
    130305 //! \since build 551
    131306 //!@{
    132307 using std::is_default_constructible;
    @@ -168,6 +343,8 @@
    168343 using std::is_nothrow_destructible;
    169344 //!@}
    170345
    346+//! \since build 245
    347+//!@{
    171348 using std::has_virtual_destructor;
    172349
    173350 using std::alignment_of;
    @@ -181,30 +358,8 @@
    181358
    182359 } // inline namespace cpp2011;
    183360
    184-
    185-/*!
    186-\brief 包含 ISO C++ 2014 引入的名称的命名空间。
    187-\since build 607
    188-*/
    189361 inline namespace cpp2014
    190362 {
    191-
    192-/*!
    193-\see LWG 2247 。
    194-\since build 832
    195-*/
    196-//!@{
    197-#if __cpp_lib_is_null_pointer >= 201309L
    198-using std::is_null_pointer;
    199-#else
    200-//! \ingroup YBase_replacement_features unary_type_traits
    201-template<typename _type>
    202-struct is_null_pointer
    203- : is_same<typename std::remove_cv<_type>::type, nullptr_t>
    204-{};
    205-#endif
    206-//!@}
    207-
    208363 /*!
    209364 \see LWG 2112 。
    210365 \since build 938
    @@ -236,6 +391,459 @@
    236391 //!@}
    237392
    238393 } // inline namespace cpp2014;
    394+
    395+
    396+/*!
    397+\ingroup unary_type_traits
    398+\tparam _type 需要判断特征的类型参数。
    399+*/
    400+//!@{
    401+//! \note 以下参数可能是 cv 修饰的类型,结果和去除 cv 修饰符的类型一致。
    402+//!@{
    403+/*!
    404+\brief 判断指定类型是否为扩展整数:不属于标准整数类型但视为整数处理的对象类型。
    405+\since build 983
    406+*/
    407+template<typename _type>
    408+struct is_extended_integer
    409+#if YB_Use_int128 > 0
    410+ : or_<is_same<_t<std::remove_cv<_type>>, int128_t>,
    411+ is_same<_t<std::remove_cv<_type>>, uint128_t>>
    412+#else
    413+ : false_
    414+#endif
    415+{};
    416+
    417+
    418+/*!
    419+\brief 判断是否为未知大小的数组类型。
    420+\since build 651
    421+*/
    422+template<typename _type>
    423+struct is_array_of_unknown_bound
    424+ : bool_<is_array<_type>() && extent<_type>() == 0>
    425+{};
    426+
    427+
    428+/*!
    429+\brief 判断指定类型是否为非 \c cv 限定对象的数组类型。
    430+\since build 972
    431+*/
    432+template<typename>
    433+struct is_array_of_unqualified_object;
    434+
    435+
    436+/*!
    437+\brief 判断指定类型是否为可被继承的类类型。
    438+\since build 940
    439+*/
    440+template<typename _type>
    441+struct is_inheritable_class : and_<is_class<_type>, not_<is_final<_type>>>
    442+{};
    443+
    444+
    445+/*!
    446+\brief 判断指定类型是否为非 const 对象类型。
    447+\since build 650
    448+*/
    449+template<typename _type>
    450+struct is_nonconst_object
    451+ : and_<is_object<_type>, is_same<_t<std::add_const<_type>>, _type>>
    452+{};
    453+
    454+
    455+//! \since build 333
    456+//!@{
    457+//! \brief 判断指定类型是否为类类型左值引用。
    458+template<typename _type>
    459+struct is_lvalue_class_reference : and_<is_lvalue_reference<_type>,
    460+ is_class<_t<std::remove_reference<_type>>>>
    461+{};
    462+
    463+
    464+//! \brief 判断指定类型是否为类类型右值引用。
    465+template<typename _type>
    466+struct is_rvalue_class_reference : and_<is_rvalue_reference<_type>,
    467+ is_class<_t<std::remove_pointer<_type>>>>
    468+{};
    469+
    470+
    471+//! \brief 判断指定类型是否为指向类类型的指针。
    472+template<typename _type>
    473+struct is_class_pointer
    474+ : and_<is_pointer<_type>, is_class<_t<std::remove_pointer<_type>>>>
    475+{};
    476+//!@}
    477+
    478+
    479+//! \since build 630
    480+//!@{
    481+//! \brief 判断指定类型是否为指向函数类型的指针。
    482+template<typename _type>
    483+struct is_function_pointer
    484+ : and_<is_pointer<_type>, is_function<_t<std::remove_pointer<_type>>>>
    485+{};
    486+
    487+
    488+//! \brief 判断指定类型是否为对象或 void 类型。
    489+template<typename _type>
    490+struct is_object_or_void : or_<is_object<_type>, is_void<_type>>
    491+{};
    492+
    493+
    494+//! \brief 判断指定类型是否为指向对象或空类型的指针。
    495+template<typename _type>
    496+struct is_object_pointer
    497+ : and_<is_pointer<_type>, is_object_or_void<_t<std::remove_pointer<_type>>>>
    498+{};
    499+
    500+
    501+//! \brief 判断指定类型是否为指向对象类型的指针。
    502+template<typename _type>
    503+struct is_pointer_to_object
    504+ : and_<is_pointer<_type>, is_object<_t<std::remove_pointer<_type>>>>
    505+{};
    506+//!@}
    507+
    508+
    509+/*!
    510+\brief 判断指定类型是否为类类型。
    511+\since build 588
    512+*/
    513+template<typename _type>
    514+struct is_class_type
    515+ : or_<is_class<_type>, is_union<_type>>
    516+{};
    517+
    518+
    519+//! \since build 694
    520+namespace details
    521+{
    522+
    523+template<typename _type>
    524+struct is_referenceable_function : false_
    525+{};
    526+
    527+template<typename _tRes, typename... _tParams ynoexcept_param(ne)>
    528+struct is_referenceable_function<_tRes(_tParams...) ynoexcept_qual(ne)> : true_
    529+{};
    530+
    531+template<typename _tRes, typename... _tParams ynoexcept_param(ne)>
    532+struct is_referenceable_function<_tRes(_tParams..., ...) ynoexcept_qual(ne)>
    533+ : true_
    534+{};
    535+
    536+
    537+//! \since build 867
    538+//!@{
    539+template<typename _type1, typename _type2, bool = is_same<_type1, _type2>{}>
    540+struct is_same_or_convertible : is_convertible<_type1, _type2>
    541+{};
    542+
    543+template<typename _type1, typename _type2>
    544+struct is_same_or_convertible<_type1, _type2, true> : true_
    545+{};
    546+//!@}
    547+
    548+} // namespace details;
    549+
    550+/*!
    551+\brief 判断指定类型是否为可引用类型。
    552+\see ISO C++11 17.3.20 [defns.referenceable] 。
    553+\since build 694
    554+*/
    555+template<typename _type>
    556+struct is_referenceable : or_<is_object<_type>, is_reference<_type>,
    557+ details::is_referenceable_function<_type>>
    558+{};
    559+
    560+
    561+/*!
    562+\brief 判断指定类型是否可作为返回类型。
    563+\pre 类型参数满足同 ISO C++ 对 is_abstract 的要求。
    564+\note 即排除数组类型、抽象类类型和函数类型的所有类型。
    565+\see ISO C++11 8.3.5/8 和 ISO C++11 10.4/3 。
    566+\since build 333
    567+
    568+对类型参数的具体要求如下:
    569+若类型参数是一个非联合体的类类型,类型参数是完整类型。
    570+*/
    571+template<typename _type>
    572+struct is_returnable
    573+ : nor_<is_array<_type>, is_abstract<_type>, is_function<_type>>
    574+{};
    575+
    576+
    577+/*!
    578+\pre remove_all_extents\<_type> 是完整类型或(可能 cv 修饰的) \c void 。
    579+\see ISO C++17 [class.prop]/2 。
    580+\since build 853
    581+*/
    582+//!@{
    583+/*!
    584+\brief 判断指定类型是否为平凡的非联合类类型。
    585+\note 注意和 ISO C++ 的 \c std::is_class 类似,排除联合。
    586+*/
    587+template<typename _type>
    588+struct is_trivial_class : and_<is_trivial<_type>, is_class<_type>>
    589+{};
    590+
    591+template<typename _type>
    592+struct is_trivial_class_type : and_<is_trivial<_type>, is_class_type<_type>>
    593+{};
    594+
    595+//! \brief 判断指定类型是否为平凡的联合类型。
    596+template<typename _type>
    597+struct is_trivial_union : and_<is_trivial<_type>, is_union<_type>>
    598+{};
    599+//!@}
    600+//!@}
    601+
    602+
    603+/*!
    604+\brief 判断指定类型是否为 \c const 或 \c volatile 类型。
    605+\since build 590
    606+*/
    607+template<typename _type>
    608+struct is_cv : or_<is_const<_type>, is_volatile<_type>>
    609+{};
    610+
    611+
    612+/*!
    613+\brief 判断指定类型是否已退化为指定类型。
    614+\since build 841
    615+*/
    616+template<typename _type, typename _tTo = _type>
    617+struct is_decayed : is_same<_type, _t<std::decay<_tTo>>>
    618+{};
    619+
    620+
    621+/*!
    622+\brief 判断指定类型是否可分解为一个参数为类型的模板和类型参数。
    623+\since build 683
    624+*/
    625+//!@{
    626+template<typename>
    627+struct is_decomposable : false_
    628+{};
    629+
    630+template<template<typename...> class _gOp, typename... _types>
    631+struct is_decomposable<_gOp<_types...>> : true_
    632+{};
    633+//!@}
    634+
    635+
    636+/*!
    637+\brief 判断指定类型是否为非限定的指定类型。
    638+\since build 865
    639+*/
    640+template<typename _type, typename _tTo = _type>
    641+struct is_unqualified : is_same<_type, _t<std::remove_cv<_tTo>>>
    642+{};
    643+
    644+
    645+/*!
    646+\brief 判断指定类型是否为非 \c cv 限定对象类型。
    647+\since build 867
    648+*/
    649+template<typename _type>
    650+struct is_unqualified_object : and_<is_object<_type>, is_unqualified<_type>>
    651+{};
    652+
    653+
    654+template<typename _type>
    655+struct is_array_of_unqualified_object : and_<is_array<_type>,
    656+ is_unqualified_object<_t<std::remove_extent<_type>>>>
    657+{};
    658+
    659+
    660+/*!
    661+\pre 类型参数满足同 ISO C++ \c is_trivial 参数的要求。
    662+\see LWG 2116 。
    663+\see LWG 2827 。
    664+\see WG21 P2842R0 。
    665+\since build 630
    666+
    667+对类型参数 \c _type ,具体的要求是 remove_all_extents\<_type> 满足以下之一:
    668+ 完整类型。
    669+ (可能 cv 修饰的) \c void 。
    670+ 未知大小的数组。
    671+当前对 WG21 P2842R0 中立,即是否要求平凡或无异常析构未指定。
    672+按 WG21 P2842R0 建议的现行 ISO C++ 规则,一般仅要求可访问的析构函数存在。
    673+*/
    674+//!@{
    675+template<typename _type>
    676+struct is_copyable
    677+ : and_<is_copy_constructible<_type>, is_copy_assignable<_type>>
    678+{};
    679+
    680+
    681+//! \since build 983
    682+template<typename _type>
    683+struct is_movable
    684+ : and_<is_move_constructible<_type>, is_move_assignable<_type>>
    685+{};
    686+
    687+
    688+template<typename _type>
    689+struct is_nothrow_copyable : and_<is_nothrow_copy_constructible<_type>,
    690+ is_nothrow_copy_assignable<_type>>
    691+{};
    692+
    693+
    694+//! \since build 983
    695+template<typename _type>
    696+struct is_nothrow_movable : and_<is_nothrow_move_constructible<_type>,
    697+ is_nothrow_move_assignable<_type>>
    698+{};
    699+
    700+
    701+/*!
    702+\brief 判断指定类型是否为可复制构造但不可无抛出异常地转移构造的类型。
    703+\note 和 std::move_if_noexcept 需要选择复制的条件相同。
    704+\since build 865
    705+*/
    706+template<typename _type>
    707+struct is_throwing_move_copyable : and_<is_copy_constructible<_type>,
    708+ not_<is_nothrow_move_constructible<_type>>>
    709+{};
    710+//!@}
    711+
    712+
    713+//! \pre 参数是完整的对象类型。
    714+//!@{
    715+//! \since build 983
    716+template<typename _type>
    717+using bit_width_t = size_t_<sizeof(_type) * CHAR_BIT>;
    718+
    719+//! \since build 843
    720+template<typename _type>
    721+using sizeof_t = size_t_<sizeof(_type)>;
    722+//!@}
    723+//!@}
    724+
    725+
    726+//! \ingroup binary_type_traits
    727+//!@{
    728+/*!
    729+\pre 类型参数相同或满足同 ISO C++ 对 is_convertible 的要求。
    730+\since build 832
    731+
    732+对类型参数的具体要求是两个类型参数都满足以下之一:
    733+ 完整类型。
    734+ (可能 cv 修饰的) \c void 。
    735+ 未知大小的数组。
    736+*/
    737+//!@{
    738+//! \brief 判断指定类型是否可被指定参数类型构造且要求显式构造。
    739+template <typename _type, typename _tFrom>
    740+struct is_explicitly_constructible : and_<is_constructible<_type, _tFrom>,
    741+ not_<is_convertible<_tFrom, _type>>>
    742+{};
    743+
    744+
    745+//! \brief 判断指定类型是否可被指定参数类型无异常抛出构造且要求显式构造。
    746+template <typename _type, typename _tFrom>
    747+struct is_explicitly_nothrow_constructible : and_<is_nothrow_constructible<
    748+ _type, _tFrom>, not_<is_convertible<_tFrom, _type>>>
    749+{};
    750+
    751+
    752+//! \brief 判断指定类型是否可被指定参数类型构造且可隐式构造。
    753+template <typename _type, typename _tFrom>
    754+struct is_implicitly_constructible : and_<is_constructible<_type, _tFrom>,
    755+ is_convertible<_tFrom, _type>>
    756+{};
    757+
    758+
    759+//! \brief 判断指定类型是否可被指定参数类型无异常抛出构造且可隐式构造。
    760+template <typename _type, typename _tFrom>
    761+struct is_implicitly_nothrow_constructible : and_<is_nothrow_constructible<
    762+ _type, _tFrom>, is_convertible<_tFrom, _type>>
    763+{};
    764+//!@}
    765+
    766+
    767+/*!
    768+\brief 判断指定类型之间添加 cv 限定符后是否相同。
    769+\since build 983
    770+*/
    771+template<typename _type1, typename _type2>
    772+struct is_affinity : is_same<_t<std::add_cv<_type1>>, _t<std::add_cv<_type2>>>
    773+{};
    774+
    775+
    776+/*!
    777+\pre 类型参数相同或满足同 ISO C++ 对 is_convertible 的要求。
    778+
    779+对类型参数的具体要求是满足以下之一:
    780+ 两个类型参数相同。
    781+ 两个类型参数都满足以下之一:
    782+ 完整类型。
    783+ (可能 cv 修饰的) \c void 。
    784+ 未知大小的数组。
    785+*/
    786+//!@{
    787+/*!
    788+\brief 判断指定类型之间是否相同或可转换。
    789+\note 类似 is_convertible ,但类型相同时不要求完整类型。
    790+\since build 850
    791+*/
    792+template<typename _type1, typename _type2>
    793+struct is_same_or_convertible : details::is_same_or_convertible<_type1, _type2>
    794+{};
    795+
    796+
    797+/*!
    798+\brief 判断指定类型之间是否相同或可互相转换。
    799+\since build 575
    800+*/
    801+template<typename _type1, typename _type2>
    802+struct is_interoperable : or_<is_same_or_convertible<_type1, _type2>,
    803+ is_same_or_convertible<_type2, _type1>>
    804+{};
    805+//!@}
    806+
    807+
    808+/*!
    809+\brief 判断第一参数和第二参数指定的参数类型相同。
    810+\since build 865
    811+*/
    812+template<typename _type, typename _tParam>
    813+struct is_same_param : is_same<_type&, _t<std::decay<_tParam>>&>
    814+{};
    815+//!@}
    816+
    817+
    818+//! \ingroup unary_type_traits
    819+//!@{
    820+//! \since build 671
    821+//!@{
    822+//! \brief 判断第一参数和之后的参数指定的类型相同。
    823+template<typename _type, typename... _types>
    824+struct are_same : and_<is_same<_type, _types>...>
    825+{};
    826+
    827+
    828+//! \brief 判断第一参数在之后参数指定的类型中出现。
    829+template<typename _type, typename... _types>
    830+struct is_in_types : or_<is_same<_type, _types>...>
    831+{};
    832+//!@}
    833+
    834+
    835+//!@{
    836+//! \brief 判断第一参数和之后的参数指定的类型添加 cv 限定符后相同。
    837+template<typename _type, typename... _types>
    838+struct are_affinity : and_<is_affinity<_type, _types>...>
    839+{};
    840+
    841+
    842+//! \brief 判断第一参数和之后的参数指定的类型添加 cv 限定符后相同。
    843+template<typename _type, typename... _types>
    844+struct is_in_affinity_types : or_<is_affinity<_type, _types>...>
    845+{};
    846+//!@}
    239847 //!@}
    240848
    241849 } // namespace ystdex;
    diff -r 3fe9fa0c6127 -r 74e1025f0a02 YBase/include/ystdex/type_traits.hpp
    --- a/YBase/include/ystdex/type_traits.hpp Tue Feb 27 00:28:20 2024 +0800
    +++ b/YBase/include/ystdex/type_traits.hpp Fri Apr 19 22:42:25 2024 +0800
    @@ -1,23 +1,22 @@
    11 /*
    2- © 2011-2019, 2021 FrankHB.
    2+ © 2011-2019, 2021, 2024 FrankHB.
    33
    4- This file is part of the YSLib project, and may only be used,
    5- modified, and distributed under the terms of the YSLib project
    6- license, LICENSE.TXT. By continuing to use, modify, or distribute
    7- this file you indicate that you have read the license and
    8- understand and accept it fully.
    4+ This file is part of the YSLib project, and may only be used, modified,
    5+ and distributed under the terms of the YSLib project license.
    6+ By continuing to use, modify, or distribute this file you indicate that
    7+ you have read the license and understand and accept it fully.
    98 */
    109
    1110 /*! \file type_traits.hpp
    1211 \ingroup YStandardEx
    1312 \brief ISO C++ 类型特征扩展。
    14-\version r2038
    13+\version r2122
    1514 \author FrankHB <frankhb1989@gmail.com>
    1615 \since build 201
    1716 \par 创建时间:
    1817 2015-11-04 09:34:17 +0800
    1918 \par 修改时间:
    20- 2021-11-11 20:32 +0800
    19+ 2024-04-16 22:20 +0800
    2120 \par 文本编码:
    2221 UTF-8
    2322 \par 模块名称:
    @@ -37,7 +36,7 @@
    3736 {
    3837
    3938 //! \ingroup transformation_traits
    40-//@{
    39+//!@{
    4140 /*!
    4241 \note 参数可能是不完整类型。
    4342 \note 保证不依赖非推导上下文实现简单类型操作,可用于可推导的转换函数的名称。
    @@ -45,7 +44,7 @@
    4544 \sa CWG 395
    4645 \since build 756
    4746 */
    48-//@{
    47+//!@{
    4948 template<typename _type>
    5049 using id_t = _type;
    5150
    @@ -57,76 +56,151 @@
    5756
    5857 template<typename _type>
    5958 using add_rref_t = _type&&;
    60-//@}
    59+//!@}
    6160
    6261
    62+//! \since build 983
    63+//!@{
    64+#define YB_Impl_TypeTraits_unary_op_t(_n, _op) \
    65+ template<typename _type> \
    66+ using _n = decltype(_op std::declval<_type>());
    67+
    6368 //! \since build 669
    64-//@{
    65-template<typename _type>
    66-using addrof_t = decltype(&std::declval<_type>());
    69+//!@{
    70+YB_Impl_TypeTraits_unary_op_t(addrof_t, &)
    6771
    68-template<typename _type>
    69-using indirect_t = decltype(*std::declval<_type>());
    70-//@}
    72+YB_Impl_TypeTraits_unary_op_t(indirect_t, *)
    73+//!@}
    7174
    7275 //! \since build 671
    7376 template<typename _type>
    7477 using indirect_element_t = remove_reference_t<indirect_t<_type>>;
    7578
    79+#define YB_Impl_TypeTraits_unary_post_op_t(_n, _op) \
    80+ template<typename _type> \
    81+ using _n = decltype(std::declval<_type>() _op);
    82+
    7683 //! \since build 865
    77-template<typename _type>
    78-using increment_t = decltype(++std::declval<_type>());
    84+YB_Impl_TypeTraits_unary_op_t(increment_t, ++)
    7985
    8086 //! \since build 867
    81-//@{
    82-template<typename _type>
    83-using increment_post_t = decltype(std::declval<_type>()--);
    87+//!@{
    88+YB_Impl_TypeTraits_unary_post_op_t(increment_post_t, ++)
    8489
    85-template<typename _type>
    86-using decrement_t = decltype(++std::declval<_type>());
    90+YB_Impl_TypeTraits_unary_op_t(decrement_t, --)
    8791
    88-template<typename _type>
    89-using decrement_post_t = decltype(std::declval<_type>()--);
    92+YB_Impl_TypeTraits_unary_post_op_t(decrement_post_t, --)
    9093
    9194 template<typename _type, typename _type2>
    9295 using subscript_t = decltype(std::declval<_type>()[std::declval<_type2>()]);
    96+//!@}
    9397
    98+#undef YB_Impl_TypeTraits_unary_post_op_t
    99+
    100+#define YB_Impl_TypeTraits_binary_op_t(_n, _op) \
    101+ template<typename _type, typename _type2 = _type> \
    102+ using _n = decltype(std::declval<_type>() _op std::declval<_type2>());
    103+
    104+YB_Impl_TypeTraits_binary_op_t(plus_t, +)
    105+
    106+YB_Impl_TypeTraits_binary_op_t(minus_t, -)
    107+
    108+YB_Impl_TypeTraits_binary_op_t(multiplies_t, *)
    109+
    110+YB_Impl_TypeTraits_binary_op_t(divides_t, /)
    111+
    112+YB_Impl_TypeTraits_binary_op_t(modulus_t, %)
    113+
    114+YB_Impl_TypeTraits_unary_op_t(negate, -)
    115+
    116+//! \since build 867
    117+//!@{
    94118 #if YB_IMPL_GNUCPP || YB_IMPL_CLANGPP
    95119 YB_Diag_Push
    96120 YB_Diag_Ignore(float-equal)
    97121 #endif
    98-template<typename _type, typename _type2 = _type>
    99-using equal_t = decltype(std::declval<_type>() == std::declval<_type2>());
    122+YB_Impl_TypeTraits_binary_op_t(equal_t, ==)
    100123
    101-template<typename _type, typename _type2 = _type>
    102-using not_equal_t = decltype(std::declval<_type>() != std::declval<_type2>());
    124+YB_Impl_TypeTraits_binary_op_t(not_equal_t, !=)
    103125 #if YB_IMPL_GNUCPP || YB_IMPL_CLANGPP
    104126 YB_Diag_Pop
    105127 #endif
    106-//@}
    128+//!@}
    129+
    130+YB_Impl_TypeTraits_binary_op_t(greater_t, >)
    131+
    132+YB_Impl_TypeTraits_binary_op_t(less_t, <)
    133+
    134+YB_Impl_TypeTraits_binary_op_t(greater_equal_t, >=)
    135+
    136+YB_Impl_TypeTraits_binary_op_t(less_equal_t, <=)
    137+
    138+YB_Impl_TypeTraits_binary_op_t(right_shift_t, >>)
    139+
    140+YB_Impl_TypeTraits_binary_op_t(left_shift_t, <<)
    141+
    142+YB_Impl_TypeTraits_binary_op_t(logical_and_t, &&)
    143+
    144+YB_Impl_TypeTraits_binary_op_t(logical_or_t, ||)
    145+
    146+YB_Impl_TypeTraits_unary_op_t(logical_not_t, !)
    147+
    148+YB_Impl_TypeTraits_binary_op_t(bit_and_t, &)
    149+
    150+YB_Impl_TypeTraits_binary_op_t(bit_or_t, |)
    151+
    152+YB_Impl_TypeTraits_binary_op_t(bit_xor_t, ^)
    153+
    154+YB_Impl_TypeTraits_unary_op_t(bit_not_t, ~)
    155+
    156+YB_Impl_TypeTraits_binary_op_t(assignment_t, =)
    157+
    158+YB_Impl_TypeTraits_binary_op_t(plus_assignment_t, +=)
    159+
    160+YB_Impl_TypeTraits_binary_op_t(minus_assignment_t, -=)
    161+
    162+YB_Impl_TypeTraits_binary_op_t(multiplies_assignment_t, *=)
    163+
    164+YB_Impl_TypeTraits_binary_op_t(divides_assignment_t, /=)
    165+
    166+YB_Impl_TypeTraits_binary_op_t(modulus_assignment_t, %=)
    167+
    168+YB_Impl_TypeTraits_binary_op_t(right_shift_assignment_t, >>=)
    169+
    170+YB_Impl_TypeTraits_binary_op_t(left_shift_assignment_t, <<=)
    171+
    172+YB_Impl_TypeTraits_binary_op_t(bit_and_assignment_t, &=)
    173+
    174+YB_Impl_TypeTraits_binary_op_t(bit_or_assignment_t, |=)
    175+
    176+YB_Impl_TypeTraits_binary_op_t(bit_xor_assignment_t, ^=)
    177+
    178+#undef YB_Impl_TypeTraits_binary_op_t
    179+#undef YB_Impl_TypeTraits_unary_op_t
    180+//!@}
    107181
    108182
    109183 //! \since build 830
    110-//@{
    184+//!@{
    111185 template<typename _type>
    112186 using first_t = decltype(std::declval<_type>().first);
    113187
    114188 template<typename _type>
    115189 using second_t = decltype(std::declval<_type>().second);
    116-//@}
    117-//@}
    118-//@}
    190+//!@}
    191+//!@}
    192+//!@}
    119193
    120194
    121195 //! \ingroup binary_type_traits
    122-//@{
    196+//!@{
    123197 /*!
    124198 \brief 判断是否存在合式的结果为非 void 类型的 [] 操作符接受指定类型的表达式。
    125199 \since build 399
    126200 */
    127201 template<typename _type1, typename _type2>
    128202 struct has_subscription
    129- : bool_<is_detected<subscript_t, _type1, _type2>::value
    203+ : bool_<is_detected<subscript_t, _type1, _type2>()
    130204 && !is_void<detected_t<subscript_t, _type1, _type2>>::value>
    131205 {};
    132206
    @@ -139,7 +213,7 @@
    139213 struct has_equality_operator
    140214 : is_detected_convertible<bool, equal_t, _type, _type2>
    141215 {};
    142-//@}
    216+//!@}
    143217
    144218 } // namespace ystdex;
    145219
    diff -r 3fe9fa0c6127 -r 74e1025f0a02 YBase/source/ystdex/exception.cpp
    --- a/YBase/source/ystdex/exception.cpp Tue Feb 27 00:28:20 2024 +0800
    +++ b/YBase/source/ystdex/exception.cpp Fri Apr 19 22:42:25 2024 +0800
    @@ -1,23 +1,22 @@
    11 /*
    2- © 2014, 2016, 2018 FrankHB.
    2+ © 2014, 2016, 2018, 2024 FrankHB.
    33
    4- This file is part of the YSLib project, and may only be used,
    5- modified, and distributed under the terms of the YSLib project
    6- license, LICENSE.TXT. By continuing to use, modify, or distribute
    7- this file you indicate that you have read the license and
    8- understand and accept it fully.
    4+ This file is part of the YSLib project, and may only be used, modified,
    5+ and distributed under the terms of the YSLib project license.
    6+ By continuing to use, modify, or distribute this file you indicate that
    7+ you have read the license and understand and accept it fully.
    98 */
    109
    1110 /*! \file exception.cpp
    1211 \ingroup YStandardEx
    1312 \brief 标准库异常扩展接口。
    14-\version r59
    13+\version r75
    1514 \author FrankHB <frankhb1989@gmail.com>
    1615 \since build 556
    1716 \par 创建时间:
    1817 2014-11-28 12:15:16 +0800
    1918 \par 修改时间:
    20- 2018-12-26 19:45 +0800
    19+ 2024-04-12 23:34 +0800
    2120 \par 文本编码:
    2221 UTF-8
    2322 \par 模块名称:
    @@ -64,5 +63,18 @@
    6463 throw allocator_mismatch_error();
    6564 }
    6665
    66+
    67+void
    68+throw_overflow_error(const char* what_arg)
    69+{
    70+ throw std::overflow_error(what_arg);
    71+}
    72+
    73+void
    74+throw_underflow_error(const char* what_arg)
    75+{
    76+ throw std::underflow_error(what_arg);
    77+}
    78+
    6779 } // namespace ystdex;
    6880
    diff -r 3fe9fa0c6127 -r 74e1025f0a02 YFramework/include/YSLib/Core/YCoreUtilities.h
    --- a/YFramework/include/YSLib/Core/YCoreUtilities.h Tue Feb 27 00:28:20 2024 +0800
    +++ b/YFramework/include/YSLib/Core/YCoreUtilities.h Fri Apr 19 22:42:25 2024 +0800
    @@ -1,23 +1,22 @@
    11 /*
    2- © 2010-2023 FrankHB.
    2+ © 2010-2024 FrankHB.
    33
    4- This file is part of the YSLib project, and may only be used,
    5- modified, and distributed under the terms of the YSLib project
    6- license, LICENSE.TXT. By continuing to use, modify, or distribute
    7- this file you indicate that you have read the license and
    8- understand and accept it fully.
    4+ This file is part of the YSLib project, and may only be used, modified,
    5+ and distributed under the terms of the YSLib project license.
    6+ By continuing to use, modify, or distribute this file you indicate that
    7+ you have read the license and understand and accept it fully.
    98 */
    109
    1110 /*! \file YCoreUtilities.h
    1211 \ingroup Core
    1312 \brief 核心实用模块。
    14-\version r2719
    13+\version r2740
    1514 \author FrankHB <frankhb1989@gmail.com>
    1615 \since build 539
    1716 \par 创建时间:
    1817 2010-05-23 06:10:59 +0800
    1918 \par 修改时间:
    20- 2023-03-26 02:57 +0800
    19+ 2024-04-07 00:09 +0800
    2120 \par 文本编码:
    2221 UTF-8
    2322 \par 模块名称:
    @@ -32,7 +31,9 @@
    3231 #include YFM_YSLib_Core_YException // for LoggedEvent, string, string_view,
    3332 // std::string, std::exception, size_t, ExtractException, FatalError,
    3433 // to_std_string, make_string_view, linked_map;
    35-#include <ystdex/algorithm.hpp> // for ystdex::clamp;
    34+#include <ystdex/algorithm.hpp> // for ystdex::clamp, ystdex::trivially_fill_n;
    35+#include <ystdex/cstdint.hpp> // for ystdex::common_int_type_t,
    36+// std::numeric_limits (with fixes);
    3637
    3738 namespace YSLib
    3839 {
    @@ -320,10 +321,9 @@
    320321 inline _tDst
    321322 CheckLowerBound(_type val, const string& name = {}, RecordLevel lv = Err)
    322323 {
    323- using namespace ystdex;
    324324 // XXX: See WG21 N3387.
    325325 // TODO: Add and use safe %common_arithmetic_type interface instead?
    326- using common_t = typename ystdex::common_int_type<_tDst, _type>::type;
    326+ using common_t = ystdex::common_int_type_t<_tDst, _type>;
    327327
    328328 if(!(common_t(val) < common_t(std::numeric_limits<_tDst>::min())))
    329329 return _tDst(val);
    @@ -336,11 +336,10 @@
    336336 inline _tDst
    337337 CheckUpperBound(_type val, const string& name = {}, RecordLevel lv = Err)
    338338 {
    339- using namespace ystdex;
    340339 // XXX: See WG21 N3387.
    341340 // TODO: Add and use safe %common_arithmetic_type interface instead?
    342341 // TODO: Add direct integer rank comparison?
    343- using common_t = typename ystdex::common_int_type<_tDst, _type>::type;
    342+ using common_t = ystdex::common_int_type_t<_tDst, _type>;
    344343
    345344 if((std::is_signed<common_t>() && std::is_unsigned<_tDst>()
    346345 && ystdex::integer_width<common_t>() <= ystdex::integer_width<_tDst>())
    @@ -385,21 +384,14 @@
    385384
    386385 /*!
    387386 \brief 清除指定的连续对象。
    388-\pre 设类型 \c T 为 ystdex::decay_t<decltype(*dst)>,则应满足
    389- <tt>std::is_trivial\<T>() || (std::is_nothrow_default_constructible\<T>()
    390- && std::is_nothrow_assignable\<T, T>())</tt> 。
    387+\pre 满足 \c ystdex::trivially_fill_n 相同的要求。
    391388 \since build 624
    392389 */
    393390 template<typename _tOut>
    394391 inline void
    395392 ClearSequence(_tOut dst, size_t n) ynothrowv
    396393 {
    397- using _type = ystdex::decay_t<decltype(*dst)>;
    398- static_assert(std::is_trivial<_type>()
    399- || (std::is_nothrow_default_constructible<_type>()
    400- && std::is_nothrow_assignable<_type, _type>()), "Invalid type found.");
    401-
    402- std::fill_n(dst, n, _type());
    394+ ystdex::trivially_fill_n(dst, n);
    403395 }
    404396
    405397
    diff -r 3fe9fa0c6127 -r 74e1025f0a02 YFramework/include/YSLib/Core/YGDIBase.h
    --- a/YFramework/include/YSLib/Core/YGDIBase.h Tue Feb 27 00:28:20 2024 +0800
    +++ b/YFramework/include/YSLib/Core/YGDIBase.h Fri Apr 19 22:42:25 2024 +0800
    @@ -1,5 +1,5 @@
    11 /*
    2- © 2011-2016, 2018-2021, 2023 FrankHB.
    2+ © 2011-2016, 2018-2021, 2023-2024 FrankHB.
    33
    44 This file is part of the YSLib project, and may only be used, modified,
    55 and distributed under the terms of the YSLib project license.
    @@ -10,13 +10,13 @@
    1010 /*! \file YGDIBase.h
    1111 \ingroup Core
    1212 \brief 平台无关的基础图形学对象。
    13-\version r2645
    13+\version r2647
    1414 \author FrankHB <frankhb1989@gmail.com>
    1515 \since build 563
    1616 \par 创建时间:
    1717 2011-05-03 07:20:51 +0800
    1818 \par 修改时间:
    19- 2023-11-09 15:36 +0800
    19+ 2024-04-06 16:27 +0800
    2020 \par 文本编码:
    2121 UTF-8
    2222 \par 模块名称:
    @@ -30,7 +30,7 @@
    3030 #include "YModules.h"
    3131 #include YFM_YSLib_Core_YCoreUtilities // for octet, size_t, Pixel,
    3232 // ystdex::min, ystdex::max, YSLib::HalfDifference;
    33-#include <limits> // for std::numeric_limits;
    33+#include <libdefect/limits.hpp> // for std::numeric_limits (with fixes);
    3434 #include <ystdex/operators.hpp> // for ystdex::equality_comparable;
    3535 #include <ystdex/string.hpp> // for ystdex::quote;
    3636
    diff -r 3fe9fa0c6127 -r 74e1025f0a02 YFramework/include/YSLib/Service/YGDI.h
    --- a/YFramework/include/YSLib/Service/YGDI.h Tue Feb 27 00:28:20 2024 +0800
    +++ b/YFramework/include/YSLib/Service/YGDI.h Fri Apr 19 22:42:25 2024 +0800
    @@ -1,5 +1,5 @@
    11 /*
    2- © 2009-2017, 2019, 2021-2023 FrankHB.
    2+ © 2009-2017, 2019, 2021-2024 FrankHB.
    33
    44 This file is part of the YSLib project, and may only be used, modified,
    55 and distributed under the terms of the YSLib project license.
    @@ -10,13 +10,13 @@
    1010 /*! \file YGDI.h
    1111 \ingroup Service
    1212 \brief 平台无关的图形设备接口。
    13-\version r4084
    13+\version r4089
    1414 \author FrankHB <frankhb1989@gmail.com>
    1515 \since build 566
    1616 \par 创建时间:
    1717 2009-12-14 18:29:46 +0800
    1818 \par 修改时间:
    19- 2023-12-20 20:26 +0800
    19+ 2024-03-30 23:45 +0800
    2020 \par 文本编码:
    2121 UTF-8
    2222 \par 模块名称:
    @@ -224,7 +224,7 @@
    224224
    225225 /*!
    226226 \brief 标准矩形像素图缓冲区。
    227-\post 满足 \c ystdex::is_nothrow_moveable<CompactPixmap>()</tt> 。
    227+\post 满足 \c ystdex::is_nothrow_movable<CompactPixmap>()</tt> 。
    228228 \note 保证像素数据连续。
    229229 \since build 418
    230230 */
    @@ -325,13 +325,13 @@
    325325 \relates CompactPixmap
    326326 \since build 630
    327327 */
    328-static_assert(ystdex::is_nothrow_moveable<CompactPixmap>(),
    328+static_assert(ystdex::is_nothrow_movable<CompactPixmap>(),
    329329 "Postcondition failed.");
    330330
    331331
    332332 /*!
    333333 \brief 使用 8 位 Alpha 扩展的标准矩形像素图缓冲区。
    334-\post 满足 \c ystdex::is_nothrow_moveable<CompactPixmapEx>()</tt> 。
    334+\post 满足 \c ystdex::is_nothrow_movable<CompactPixmapEx>()</tt> 。
    335335 \note 保证像素数据和 Alpha 数据分别连续。
    336336 */
    337337 class YF_API CompactPixmapEx : public CompactPixmap
    @@ -405,7 +405,7 @@
    405405 \relates CompactPixmapEx
    406406 \since build 630
    407407 */
    408-static_assert(ystdex::is_nothrow_moveable<CompactPixmapEx>(),
    408+static_assert(ystdex::is_nothrow_movable<CompactPixmapEx>(),
    409409 "Postcondition failed.");
    410410
    411411
    diff -r 3fe9fa0c6127 -r 74e1025f0a02 doc/ChangeLog.V0.9.txt
    --- a/doc/ChangeLog.V0.9.txt Tue Feb 27 00:28:20 2024 +0800
    +++ b/doc/ChangeLog.V0.9.txt Fri Apr 19 22:42:25 2024 +0800
    @@ -10,13 +10,13 @@
    1010 /*! \file ChangeLog.V0.9.txt
    1111 \ingroup Documentation
    1212 \brief 版本更新历史记录 - V0.9 。
    13-\version r20590
    13+\version r20988
    1414 \author FrankHB <frankhb1989@gmail.com>
    1515 \since build 900
    1616 \par 创建时间:
    1717 2020-10-12 17:19:23 +0800
    1818 \par 修改时间:
    19- 2024-02-27 00:28 +0800
    19+ 2024-04-19 22:27 +0800
    2020 \par 文本编码:
    2121 UTF-8
    2222 \par 模块名称:
    @@ -31,6 +31,405 @@
    3131
    3232 $now
    3333 (
    34+ / "name with 'moveable'" => 'movable' @ "unary type traits %(is_moveable, \
    35+ is_nothrow_moveable)" $effective @ %(YBase.YStandardEx.(Meta, Optional),
    36+ YFramework.YSLib.Service.YGDI) $dep_to "renamed moveable",
    37+ // See $2024-03 @ %Documentation::Workflow.
    38+ / %YBase $=
    39+ (
    40+ / %YDefinition $=
    41+ (
    42+ + $re_add(b962) "macro %_SILENCE_CXX23_DENORM_DEPRECATION_WARNING \
    43+ if not defined" @ 'YB_IMPL_MSCPP >= 1937',
    44+ / $re_add(b977) "all accessible URLs" ^ 'https://' ~ 'http://',
    45+ + $re_add(b831)
    46+ "conditionally-defined macro %__has_constexpr_builtin",
    47+ (
    48+ + "macro %YB_HAS_int128";
    49+ + "macro %YB_Use_int128 if not defined";
    50+ + "macro %YB_MaxIntBits",
    51+ + "aliases %(int128_t, uint128_t)" @ 'YB_Use_int128 > 0'
    52+ )
    53+ ),
    54+ + %Limits @ %LibDefects,
    55+ / %YStandardEx $=
    56+ (
    57+ / %TypeInspection $=
    58+ (
    59+ / ^ $dep_from ("%_t" @ %Meta) $=
    60+ (
    61+ / DLDI "simplified %is_null_pointer"
    62+ @ '__cpp_lib_is_null_pointer >= 201309L',
    63+ + "unary type trait %is_extended_integer"
    64+ ^ $dep_from ("%(int128_t, uint128_t)" @ %YDefinition)
    65+ ),
    66+ * $re_add(b969) DD "unbalanced Doxygen group markers"
    67+ $since b669,
    68+ + "unary type trait %bit_width_t",
    69+ // No %bit_width, and %std::bit_width is not for types.
    70+ (
    71+ + "binary type trait %is_affinity";
    72+ + "unary type traits %(are_affinity, is_in_affinity_types)"
    73+ ),
    74+ + "support of optional 128-bit integers" $effective
    75+ @ "unary type traits %(is_integral, is_arithmetic, \
    76+ is_fundamental, is_scalar, is_coumpound, is_signed, \
    77+ is_unsigned)" ^ $dep_from ("%YB_Use_int128" @ %YDefinition),
    78+ * "wrong result for possibly cv-qualified %nullptr_t"
    79+ @ '!YB_HAS_BUILTIN_NULLPTR' $effective @ "unary type \
    80+ traits %(is_class, is_arithmetic, is_fundamental, \
    81+ is_scalar, is_compound)" $orig
    82+ (@ '!YCL_HAS_BUILTIN_NULLPTR' @ %TypeOperations $since b245)
    83+ // There was %YCL_HAS_BUILTIN_NULLPTR since b245 which was \
    84+ renamed to %YB_HAS_BUILTIN_NULLPTR in b313.
    85+ ),
    86+ / %Meta $=
    87+ (
    88+ + DD '\ingroup YBase_replacement_features' @ "Doxygen comment"
    89+ @ "struct %nonesuch",
    90+ * $re_add(b937) $lib $impl "missing undefining \
    91+ 'YB_Impl_TypeTraits_has_cpp20_common_type'" $since b938,
    92+ (
    93+ / "metafunction %_t" >> %TypeInspection;
    94+ / DLDI "simplified all alias templates with '_t' as the suffix \
    95+ of name for accessing member 'type' of type trait class \
    96+ templates" ^ "%_t" ~ 'typename'
    97+ ),
    98+ * "inconsistent type traits %(is_trivially_copyable, \
    99+ is_trivially_moveable)" $orig (@ %TypeOperation $since b630)
    100+ $=
    101+ (
    102+ // See $2024-03 @ %Documentation::Workflow.
    103+ / $re_add(b727) $revert_ex(b650) "%unary_type_trait \
    104+ is_trivially_copyable"
    105+ -> ('using std::is_trivially_copyable'
    106+ @ "inline namespace %cpp2011" @ %TypeInspection),
    107+ - $revert(b630) "unary type trait %is_trivially_moveable"
    108+ ),
    109+ (
    110+ / DD @ "Doxygen comment" @ "unary type traits \
    111+ %(is_unqualified_object, is_array_of_unqualified_object)" $=
    112+ (
    113+ * "wrong group name" $since b867
    114+ $= (/ 'unary_type_trait' -> 'unary_type_traits'),
    115+ * "wrong description" @ "'\brief' command"
    116+ @ ("%is_unqualified_object" $since b867,
    117+ "%is_array_of_unqualified_object" $since b972)
    118+ ),
    119+ * DD "missing type requirement" @ "Doxygen comment"
    120+ @ ("unary type trait %is_returnable"
    121+ $orig (@ %TypeOperation $since b333),
    122+ "unary type trait %sizeof_t" $since b843) $=
    123+ (+ $impl "'\pre' command and detailed description"),
    124+ / "unary type trait %is_array_of_unqualified_object"
    125+ >> %TypeInspection
    126+ ^ DLDI "%(_t, std::remove_extent)" ~ "%remove_extent_t",
    127+ * "missing the check of %is_trivially_destructible"
    128+ @ "unary type trait %is_trivially_movable" $sice
    129+ $dep_from "renamed moveable";
    130+ / $lib "all unary type traits" >> %TypeInspection
    131+ ),
    132+ (
    133+ / $lib "unary type trait %is_nonconst_object" >> %TypeInspection
    134+ $= (/ $dev $detail $impl "%(_t, std::add_const)"
    135+ $dep_from "%_t" ~ "%add_const_t"),
    136+ * DD "incorrect description" @ "'\brief' command"
    137+ @ "Doxygen comment" @ "unary type trait %is_object_pointer"
    138+ $since b522;
    139+ // This was wrongly same to that in %is_pointer_to_object,
    140+ / $lib "unary type trait %(is_pointer_to_object, \
    141+ is_object_pointer, is_function_pointer, is_class_pointer, \
    142+ is_lvalue_class_reference, is_rvalue_class_reference)"
    143+ >> %TypeInspection
    144+ $= (/ $dev $detail $impl "%(_t, std::remove_pointer)"
    145+ $dep_from "%_t" ~ "%remove_pointer_t")
    146+ ),
    147+ (
    148+ / $lib ("unary type trait %is_decayed",
    149+ "binary type trait %is_same_param") >> %TypeInspection
    150+ $= (/ $dev $detail $impl ^ "%(_t, std::decay)"
    151+ $dep_from "%_t" ~ "%decay_t"),
    152+ / $lib "unary type trait %is_unqualified" >> %TypeInspection
    153+ $= (/ $dev $detail $impl ^ "%(_t, std::remove_cv)"
    154+ $dep_from "%_t" ~ "%remove_cv_t");
    155+ / $lib ("unary type traits %(is_decayed, is_unqualified)",
    156+ "binary type trait %is_same_param")
    157+ @ "Doxygen group %type_traits_operations"
    158+ >> ("Doxygen group %unary_type_traits" @ %TypeInspection)
    159+ ),
    160+ / $lib ("unary type traits %(are_same, is_in_types)")
    161+ @ "Doxygen group %metafunctions"
    162+ >> ("Doxygen group %unary_type_traits" @ %TypeInspection)
    163+ (
    164+ * $re_add(b722) "wrongly relied on the complete template \
    165+ argument types" @ "binary type trait %is_interoperable"
    166+ $since b722
    167+ // The change on the implementation was incomplete.
    168+ $= (/ $impl ^ "%is_same_or_convertible"
    169+ ~ "%is_convertible"),
    170+ * DD "missing type requirement" @ "Doxygen comment"
    171+ ("binary type trait %is_interoperable" $since b575,
    172+ "binary type traits %(is_explicitly_constructible, \
    173+ is_explicitly_nothrow_constructible, \
    174+ is_implicitly_constructible, \
    175+ is_implicitly_nothrow_constructible)" $since b832)
    176+ (+ $impl "'\pre' command and detailed description");
    177+ / "binary type traits %(is_same_or_convertible, \
    178+ is_interoperable, is_explicitly_constructible, \
    179+ is_explicitly_nothrow_constructible, \
    180+ is_implicitly_constructible, \
    181+ is_implicitly_nothrow_constructible)" >> %TypeInspection
    182+ ),
    183+ + "transformation traits %((copy_cv; copy_cv_t), \
    184+ (copy_reference; copy_reference_t); copy_cvref; \
    185+ copy_cvref_t)",
    186+ / DLI "optimized transforamtion type trait %remove_cvref"
    187+ @ '__has_builtin(__remove_cvref)',
    188+ + "support of optional 128-bit integers" $effective
    189+ @ "transformation type traits %(make_signed, make_unsigned)"
    190+ ^ $dep_from ("%YB_Use_int128" @ %YDefinition),
    191+ + "transformation trait %enable_if_floating_point_t"
    192+ ),
    193+ + %Limits $=
    194+ (
    195+ + "traits %numeric_traits";
    196+ + "unary type traits %(is_bounded_integer, \
    197+ is_bounded_binary_integer, is_unbounded_number, \
    198+ (is_arbitrary_unbounded_number; is_in_subrange_of), \
    199+ has_special_value)",
    200+ + ("type trait %rep_in_digits10";
    201+ "metafunction %enable_if_rep_in_digits10_t")
    202+ ),
    203+ / %CStandardInteger $=
    204+ (
    205+ + "aliases %(intmax_t, uintmax_t)" ^ $dep_from
    206+ ((%YB_Use_int128, int128_t, uint128_t) @ %YDefinition),
    207+ (
    208+ + "yconstfn function %promote_std_integer_width";
    209+ + "yconstfn function %promote_integer_width"
    210+ ^ $dep_from ("%YB_Use_int128" @ %YDefinition),
    211+ / $comp "opted-in support of 128-bit integers"
    212+ @ "transformation trait %make_signed_c"
    213+ $dep_from ("%(make_signed, make_unsigned)" @ %Meta),
    214+ / $lib $impl @ "class template %make_width_int" $=
    215+ (
    216+ (
    217+ / $dev "loosed the static assertion"
    218+ ^ $dep_from ("%YB_MaxIntBits" @ %YDefinition) ~ '64';
    219+ / $dev "simplified primary class template"
    220+ ^ "%promote_integer_width"
    221+ ),
    222+ + "optional specialization for 128-bit integers"
    223+ @ 'YB_Use_int128 > 0' $dep_to "128-bit widen integer"
    224+ $= (/ (^ $dep_from "%(int128_t, uint128_t")
    225+ @ %YDefinition, $dep_from "%make_signed_c"))
    226+ )
    227+ ),
    228+ / "opted-in support of 128-bit integers"
    229+ ^ ("%YB_MaxIntBits" @ %YDefinition) ~ '64'
    230+ $dep_from "128-bit widen integer",
    231+ (
    232+ + "alias template %make_widen_int_t";
    233+ + "specialization of class template %make_widen_int for \
    234+ cv-qualified types",
    235+ / DLDI "simplified specialization of %common_int_type"
    236+ ^ "%make_widen_int_t" ~ "%(_t, make_widen_int)"
    237+ ),
    238+ / @ "unary type trait %integer_width" $=
    239+ (
    240+ / DLDI "simplified" ^ $dep_from ("%bit_width_t"
    241+ @ "%TypeInspection") ~ "%size_t_",
    242+ * "missing support types with different value \
    243+ representation than the object representation"
    244+ $orig (@ %TypeOperation $since b260)
    245+ $= (/ $impl ^ ("%is_bounded_binary_integer"
    246+ @ %Limits, "%std::numeric_limits"))
    247+ ),
    248+ (
    249+ * "invalid cast to %uintmax_t"
    250+ @ "binary type trait %have_same_modulo" $since b440;
    251+ // This was not working on non-integer types and 128-bit \
    252+ types which are larger than %uintmax_t.
    253+ * "missing support of types other than unsigned integers"
    254+ @ "unary type trait %modular_arithmetic" $since b440
    255+ $= (/ $impl ^ "%std::numeric_limits" ~ "%is_signed")
    256+ ),
    257+ + "transformation trait %common_int_t"
    258+ ),
    259+ + "functions %(throw_overflow_error, throw_underflow_error)"
    260+ @ %Exception,
    261+ + "%Arithmetic" $=
    262+ (
    263+ + "function template %upow",
    264+ + "transformation traits %((extend_additive_overflow; \
    265+ extend_additive_overflow_t, extend_additive_underflow; \
    266+ extend_additive_underflow_t), (extend_product; \
    267+ extend_product_t))"
    268+ ^ ("%remove_cv", $dep_from ("%copy_cv_t" @ %Meta)),
    269+ + "function templates %(checked_plus, checked_minus, \
    270+ checked_multiply, extended_plus, extended_minus, \
    271+ extended_multiply)" ^ $dep_from ("%is_unbounded_number"
    272+ @ Limits, "functions %(throw_overflow_error, \
    273+ throw_underflow_error)" @ %Exception),
    274+ + "function template %checked_constant_multiply"
    275+ ),
    276+ + "unary type trait %is_timespec_like" @ %CTime,
    277+ + %Chrono $=
    278+ (
    279+ + "namespace %ystdex::chrono" ^ $dep_from ("function \
    280+ template %checked_constant_multiply" @ %Arithmetic,
    281+ "alias %intmax_t" @ %CStandardInteger) $=
    282+ (
    283+ + "inline namespace cpp2011";
    284+ + "inline namespace cpp2020",
    285+ + "function templates %(ns_to_timespec, timespec_to_ns)"
    286+ ^ $dep_from ("%is_timespec_like" @ %CTime),
    287+ + "type traits %(is_duration; enable_if_duration_t), \
    288+ (is_time_point; enable_if_time_point_t)",
    289+ + "type traits unchecked_rep"
    290+ ^ $dep_from ("%is_unbounded_number" @ %Limits),
    291+ (
    292+ + "functors %(checked_rep_caster, checked_max_rep_caster, \
    293+ checked_min_rep_caster)"
    294+ ^ $dep_from ("functions %(throw_overflow_error, \
    295+ throw_underflow_error)" @ %Exception);
    296+ + "function templates %(checked_rep_cast, \
    297+ checked_max_rep_cast, checked_min_rep_cast)";
    298+ + "function templates %(multiply_time, multiply_time_on)"
    299+ ^ $dep_from ("%ystdex::checked_constant_multiply"
    300+ @ %CStandardInteger);
    301+ + "function template %checked_duration_cast"
    302+ ^ $dep_from "%enable_if_duration_t";
    303+ + "function template %checked_time_point_cast"
    304+ ^ $dep_from "%is_duration",
    305+ ),
    306+ + "function templates %(checked_plus, checked_minus)"
    307+ ^ $dep_from
    308+ ("%ystdex::(checked_plus, checked_minus)" @ %Arithmetic)
    309+ )
    310+ ),
    311+ / DLDI "simplified functions %(floor_lb, ceiling_lb)" @ %Bit
    312+ ^ $dep_from ("%bit_width_t" @ %TypeInspection) ~ "%size_t_",
    313+ * $re_ex(b967) "exception specification" @ "function %swap"
    314+ @ "class template %mapped_set" @ %Set $since b830,
    315+ - $re_add(b982) DLDI "redundant parentheses around 'defined' \
    316+ operator" @ "preprocessing directives" @ %(Allocator, Set),
    317+ / %Allocator $=
    318+ (
    319+ / DD $re_add(b982) "merged multiple '\ingroup' commands"
    320+ @ "Doxygen comment",
    321+ + "workaround"
    322+ @ '__cplusplus >= 202002L && _LIBCPP_VERSION <= 160000'
    323+ ),
    324+ / %TypeTraits $=
    325+ (
    326+ / $re_add(b982) DLDI "all '::value' not forming an operand to \
    327+ an operator and not after a qualified type-id in class \
    328+ scope" @ "other value contexts" -> '()' $effective
    329+ @ "binary type trait %has_subscription",
    330+ + "transformation traits %(plus_t, minus_t, multiplies_t, \
    331+ divides_t, modulus_t, negate_t, greater_t, less_t, \
    332+ greater_equal_t, less_equal_t, right_shift_t, \
    333+ left_shift_t, logical_and_t, logical_or_t, logical_not_t, \
    334+ bit_and_t, bit_or_t, bit_xor_t, bit_not_t, assignment_t, \
    335+ plus_assignment_t, minus_assignment_t, \
    336+ multiplies_assignment_t, divides_assignment_t, \
    337+ modulus_assignment_t, right_shift_assignment_t, \
    338+ left_shift_assignment_t, bit_and_assignment_t, \
    339+ bit_or_assignment_t, bit_xor_assignment_t)",
    340+ / DLDI "simplified transformation traits" ^ "macros"
    341+ ),
    342+ / %Iterator $=
    343+ (
    344+ / @ "class template %transformed_iterator" $=
    345+ (
    346+ * "missing SFINAE-friendly condition for overloaded \
    347+ operators" $effecitve @ ($re_ex(b685) ("all 2 friend \
    348+ function templates %operator<" $since b600 ^ $dep_from
    349+ ("%less_t" @ %TypeTraits), "function %operator--"
    350+ $since b665 ^ ("%decrement_t" @ %TypeTraits), "all 3 \
    351+ friend function templates %operator-" $since b667
    352+ ^ $dep_from ("%minus_t" @ %TypeTraits), "functions \
    353+ %operator(+=, -=)" $orig (@ "friend function"
    354+ since b600) ^ $dep_from ("%(plus_assignment_t, \
    355+ minus_assignment_t)" @ %TypeTraits)),
    356+ // See $2024-03 @ %Documentation::Workflow.
    357+ * DD "wrong command" @ "Dogygen comments" @ "functions \
    358+ %operator(*, ++, --)"
    359+ $since b576 (/ $impl '\brief' -> '\note')
    360+ ),
    361+ / @ "class template %tuple_iterator" $=
    362+ (
    363+ * "missing SFINAE-friendly condition for overloaded \
    364+ operators" $effecitve @ ($re_ex(b685) ("all 2 friend \
    365+ function templates %operator<" $since b600 ^ $dep_from
    366+ ("%less_t" @ %TypeTraits), "function %operator--"
    367+ $since b665 ^ ("%decrement_t" @ %TypeTraits), "all 3 \
    368+ friend function templates %operator-" $since b667
    369+ ^ $dep_from ("%minus_t" @ %TypeTraits), "functions \
    370+ %operator(+=, -=)" $orig (@ "friend function"
    371+ since b600) ^ $dep_from ("%(plus_assignment_t, \
    372+ minus_assignment_t)" @ %TypeTraits)),
    373+ )
    374+ ),
    375+ + "member type %has_member_overwrite_and_resize"
    376+ @ "trait %string_traits" @ %String,
    377+ (
    378+ + %CharacterConversion;
    379+ (
    380+ + "header inclusion %CharacterConversion" @ %String;
    381+ / ("header inclusion <numeric>", "function templates %(pack_uint, \
    382+ unpack_uint, read_uint_be, read_uint_le, write_uint_be, \
    383+ write_uint_le)") >> %CharacterConversion;
    384+ / DLI "lambda-expression" @ "function template %pack_uint"
    385+ @ %CharacterConversion ^ "%(YB_LAMBDA_ANNOTATE, ynothrow, pure)"
    386+ ),
    387+ / @ %CharacterConversion $=
    388+ (
    389+ + "transformation trait %decimal_min_uint_t",
    390+ + "trait %double_digits_write_traits";
    391+ + "trait %decimal_write_traits";
    392+ + "class template %decimal_write"
    393+ ^ $dep_from ("%enable_if_rep_in_digits10_t" @ %Limits);
    394+ + "function tempate %write_decimal"
    395+ ^ $dep_from ("%upow" @ %Arithmetic);
    396+ + "function template %write_decimal_integer"
    397+ ^ ("%upow" @ %Arithmetic)
    398+ );
    399+ / "%to_string" @ %String $=
    400+ (
    401+ / $impl ^ $dep_from ("%write_decimal_integer"
    402+ @ "%CharacterConversion",
    403+ "%string_traits::has_member_overwrite_and_resize");
    404+ + $comp "support of 128-bit integers if available"
    405+ ^ $dep_from ("%is_integral" @ %TypeInspection)
    406+ )
    407+ )
    408+ )
    409+ ),
    410+ / $impl ^ "libstdc++ fixes of %std::numeric_limits fixes"
    411+ ^ $dep_from %YBase.LibDefect.Limits $=
    412+ // See $2024-04 @ %Documentation::Workflow.
    413+ (
    414+ + "header inclusion %YBase.YStandardEx.CStandardInteger" $effective
    415+ @ %YFramework.YSLib.Core.YCoreUtilities;
    416+ / "header inclusion <limits>" -> "%YBase.LibDefect.Limits" $effective
    417+ @ %(YBase.YStandardEx.(Bit, CStandardInteger, CTime, Cast, List),
    418+ YFramework.YSLib.Core.YGDIBase)
    419+ ),
    420+ / $lib $impl %YFramework.YSLib.Core.YCoreUtilities $=
    421+ (
    422+ / "simplified function template %ClearSequence"
    423+ ^ "%ystdex::trivially_fill_n",
    424+ / $dev $detail "function templates %(CheckLowerBound, \
    425+ CheckUpperBound)" ^ ("%ystdex::common_int_type_t"
    426+ @ %YBase.YStandardEx.CStandardInteger)
    427+ ~ "%ysdex::common_int_type"
    428+ )
    429+),
    430+
    431+b982
    432+(
    34433 / %YBase $=
    35434 (
    36435 / %YStandardEx $=
    diff -r 3fe9fa0c6127 -r 74e1025f0a02 doc/Workflow.txt
    --- a/doc/Workflow.txt Tue Feb 27 00:28:20 2024 +0800
    +++ b/doc/Workflow.txt Fri Apr 19 22:42:25 2024 +0800
    @@ -1,5 +1,5 @@
    11 /*
    2- © 2013-2023 FrankHB.
    2+ © 2013-2024 FrankHB.
    33
    44 This file is part of the YSLib project, and may only be used, modified,
    55 and distributed under the terms of the YSLib project license.
    @@ -10,13 +10,13 @@
    1010 /*! \file Workflow.txt
    1111 \ingroup Documentation
    1212 \brief 工作流汇总报告。
    13-\version r5998
    13+\version r6202
    1414 \author FrankHB <frankhb1989@gmail.com>
    1515 \since build 433
    1616 \par 创建时间:
    1717 2013-07-31 01:27:41 +0800
    1818 \par 修改时间:
    19- 2023-09-20 10:44 +0800
    19+ 2024-04-16 02:15 +0800
    2020 \par 文本编码:
    2121 UTF-8
    2222 \par 模块名称:
    @@ -5658,5 +5658,212 @@
    56585658 However, whether the implementation is required by newer standard not, this is at least not guaranteed to work by ISO C++11.
    56595659 As a result, the status of YSLib issue 40 is not changed.
    56605660
    5661+2024-03:
    5662+
    5663+report.impl:
    5664+YBase API is improved.
    5665+ Type traits in YBase are refactored, reworked and enhanced.
    5666+ Many traits are now moved to YBase module YStandardEx.TypeInspection from module YStandardEx.Meta, and a few new ones are added.
    5667+ These unary type traits are moved: 'is_array_of_unknown_bound', 'is_object_or_void', 'is_referenceable', 'is_returnable', 'is_class_type', 'is_trivial_class', 'is_trivial_class_type', 'is_trivial_union', 'is_inheritable_class', 'is_cv', 'is_decomposable', 'is_copyable, is_movable', 'is_nothrow_copyable', 'is_nothrow_movable', 'is_trivially_movable', 'is_throwing_move_copyable', 'is_unqualified_object', 'is_array_of_unqualified_object' and 'sizeof_t'.
    5668+ These type traits are added: 'is_affinity', 'are_affinity', 'is_in_affinity_types'.
    5669+ Additionally, type traits like 'is_extended_integer' are added to support 128-bit integers (see below).
    5670+ Some type traits are modified to support 128-bit integers (see below).
    5671+ Some traits are moved to 'unary_type_traits' Doxygen group since they have only one mandated template parameter and others are optional, which meets the unary type traits requirements in ISO C++.
    5672+ Some traits are revised and fixed.
    5673+ Type traits about trivility are reworked.
    5674+ The trait 'std::is_trivially_copyable' is used instead of the class template, which has different meaning.
    5675+ The was comment out in module YStandardEx.TypeOperation since build 245, due to the fact that libstdc++ from GCC 4.x had not implemented it (and other 'is_trivial_*' traits).
    5676+ This is available since GCC 5.
    5677+ The declaration of 'is_trivial_*' were once guarded by '!YB_IMPL_GNUC || YB_IMPL_GNUCPP >= 50000'.
    5678+ The minimum version requirement of GCC was then improved. The guards are removed in build 727 after these declarations being transferred to module YStandardEx.TypeTraits (but before to module YStandardEx.Meta in build 832).
    5679+ However, when other 'is_trivial_*' are already used, 'is_trivially_copyable' was omitted.
    5680+ The unary type trait with same name but different meaning was added to module YStandardEx.TypeOperation unfortunately then, since build 630.
    5681+ The differences are crucial.
    5682+ The standard one is weak as it does not care about the existence of the well-formed copy constriction and copy assignment.
    5683+ The class template defines one with strong assumptions of availablity of both well-formed trivial copy construction and trivial copy assignment.
    5684+ See https://www.foonathan.net/2021/03/trivially-copyable/.
    5685+ Now it has been fixed by using the standard trait.
    5686+ However, there are other issue for this trait in ISO C++. Notably, it has been changed since ISO C++17.
    5687+ See CWG 1734.
    5688+ This can have ABI compact and the results can be differ for classes with a deleted copy constructor.
    5689+ See https://bugs.llvm.org/show_bug.cgi?id=39050.
    5690+ The differences are not relying on at the code base. It is unspecified that 'ystdex::is_trivially_copyable' behaves with or without the change.
    5691+ The class template 'is_trivially_moveable' was introduced together with 'is_trivially_copyable'.
    5692+ This was the conterpart to 'is_trivially_copyable'.
    5693+ This is now removed, as there is no counterpart logically similar to 'std::is_trivially_copyable', and there is no actual use in the current code base.
    5694+ Names 'moveable' are replaced to 'movable' globally.
    5695+ This (only) affects on the traits names here.
    5696+ This excludes 'is_trivially_moveable' which is to be removed.
    5697+ The old names are not ungrammatical, but following modern and the ISO C++ parlance is better, and more importantly, more consistent (e.g. with 'ystdex::nonmovable' in module YStandardEx.Base).
    5698+ Both contemporary British and American English users may tend to use "movable" instead of "moveable".
    5699+ ISO C++ uses "movable" in its text, but no "moveable" at all.
    5700+ On the other hand, 'MakeMoveableGlobalMemory' in YFramework module YCLib.HostedGUI implementation is held, to be consistent with Win32 API name 'GMEM_MOVEABLE'.
    5701+ Unary type traits not respecting the fact that 'nullptr_t' can be a YStandardEx library type (rather than 'std::nullptr_t') are fixed.
    5702+ These include 'is_class', 'is_arithmetic', 'is_fundamental', 'is_scalar' and 'is_compound'.
    5703+ The order of declarations is adjusted. The declaration of 'is_null_pointer' is lifted before these traits to ease the implementation.
    5704+ Actually it is now just after 'is_void'.
    5705+ Support of integer types are improved.
    5706+ Support of 128-bit integer is opted in.
    5707+ The types '__int128' and 'unsigned __int128' are supported by GCC and Clang, and YFramework module NPL.NPLAMath has been already enabled it.
    5708+ See $2021-10 report.impl.
    5709+ They requires '__extension__' to prevent pedantic diagnostic with the compiler option '-Wpedantic' or '-pedantic-errors'.
    5710+ GCC still does not count them as extended integer types, even the compilers (gcc and g++) support all arithmetic operations supposed working on the extended integer types.
    5711+ See https://gcc.gnu.org/onlinedocs/gcc/Integers-implementation.html.
    5712+ This is far from ideal, but it works in practice.
    5713+ It has basically no issue in C besides not representable in 'intmax_t' and 'uintmax_t' for most platforms.
    5714+ This would be a problem for preprocessing phase evaluation (e.g. in '#if' directives).
    5715+ In fact the detection is a bit tricky in YBase module YDefinition for this reason, in particluar where <cstdint> cannot be used (so no portable macros can be used for '#if').
    5716+ For C++ the standard library may need some additional works (see below).
    5717+ There are different issues around C++ standard library support (as extensions).
    5718+ See https://quuxplusone.github.io/blog/2019/02/28/is-int128-integral/.
    5719+ For some historical reasons, only GNU modes enables the support of 128-bit integers in libstdc++.
    5720+ See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=40856.
    5721+ Actually libstdc++ adds additional specializations for strict standard modes when it is needed, see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96710.
    5722+ In some old days the <type_trait> support was missing also in GNU extension modes.
    5723+ It was fixed since GCC 4.7. See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=50441.
    5724+ Since '__int128' is considered an extended integer type (hence an integral type) in libc++, it does not make much headache for implementation to adapt it.
    5725+ Support of type traits for 128-bit integers has been improved to work around the problems caused by these integers not treated extended integers.
    5726+ Now in YBase module YStandardEx.TypeInspection, the standard type traits concerned with 128-bit integer types are not simple declarations by 'using' when necessary.
    5727+ This is opted in when necessary, although the condition can be false positive.
    5728+ Having more alternative traits shall have no harm because the identities of the traits are not assumed at all, as per the rules for replacement interface in https://frankhb.github.io/YSLib-book/StandardUsing.en-US.html.
    5729+ The condition still works at the reasonaly best effort to be precise.
    5730+ Ideally no unnecessary alternatives are declared.
    5731+ This is better for translation-time performance.
    5732+ There is no '#undef' directive to undefine the internal macro to indicate the condition, so it can be used in other modules like YStandardEx.Meta.
    5733+ The condition to enable the alternative implementation with specializations integers in namespace 'ystdex' instead of 'using' declarations is based on the standard library implementations.
    5734+ When the condition is true, alternative implementation for type traits are used with the same name of their 'std' counterpart, despite in libstdc++ with standard modes they can be missing (while still conforming).
    5735+ These traits include 'is_integral', 'is_arithmetic', 'is_fundamental', 'is_scalar', 'is_coumpound', 'is_signed', 'is_unsigned', 'make_signed' and 'make_unsigned'.
    5736+ Support of 128-bit integers in libstdc++ denpends on the current mode being used.
    5737+ For GNU modes, additional features will be enabled, and there is no need to add more alternatives for type traits
    5738+ Though 'std::numeric_limits' still need additional work elsewhere (see below about 'ystdex::integer_width' for example).
    5739+ GCC < 5 is not supported here, so it is not tested in the conditon to work around the bug fixed before GCC 5.
    5740+ Support of 128-bit integers in libc++ is neutral to the standard modes.
    5741+ No configurations of 'defined(_LIBCPP_HAS_NO_INT128)' but '!__SIZEOF_INT128__' are supported, as it is always implied in <__config>.
    5742+ The condition only enables it for old implementations not guaranteed to have the feature.
    5743+ See https://reviews.llvm.org/D122351.
    5744+ ABI issues of extended integers are studied.
    5745+ See https://stackoverflow.com/questions/29927562 for actual ABI compatibility issues about extended integer types.
    5746+ It also reported Clang++ did not support any extended integer types and '__int128' is not treated extended integer types. This is not in https://clang.llvm.org/cxx_status.html now.
    5747+ Excluding 128-bit integers out of extended integer is concerned with 'intmax_t' and 'uintmax_t'.
    5748+ This is more about a specification issue, to avoiding the clash with 'intmax_t' and 'uintmax_t'.
    5749+ The 128-bit integers larger than 'std::intmax_t' is one of the infamous issue for C compatibiltiy.
    5750+ Even C++ can do better, nothing sensible are done by the vendors of the implementations.
    5751+ See https://thephd.dev/intmax_t-hell-c++-c.
    5752+ Nevertheless, if keeping things like 'intmax_t' away, it still can work.
    5753+ Clang at current supports '_ExtInt(N)' (and now deprecated in favor of ISO C23's '_BitInt(N)' types as extended integer types.
    5754+ See https://clang.llvm.org/docs/LanguageExtensions.html#id49.
    5755+ See https://blog.llvm.org/2020/04/the-new-clang-extint-feature-provides.html.
    5756+ This was proposed to ISO C and adopted.
    5757+ See WG14 N2768.
    5758+ See https://reviews.llvm.org/D108643.
    5759+ Technically they are named bit-precise integer types, rather than extended integer type.
    5760+ The maximum bit width varies.
    5761+ See https://releases.llvm.org/14.0.0/tools/clang/docs/ReleaseNotes.html#id13.
    5762+ See https://releases.llvm.org/16.0.0/tools/clang/docs/ReleaseNotes.html#id101.
    5763+ Additional types 'intmax_t' and 'uintmax_t' are introduced in namespace 'ystdex' to keep the assumptions at cost of ABI incompitibility (to 'std' ones).
    5764+ They are new so there is no ABI brakage with old code.
    5765+ Types provided by the GCC compiler frontend like '__GLIBCXX_TYPE_INT_N_0' are not used directly
    5766+ Though introduced for MSP430's '__int20' (see below), the type is just the 128-bit signed integer in some other platforms.
    5767+ Since there is currently no platform uses it other than 128-bit integer type and '__SIZEOF_INT128__' is sufficient to detect the type, this is not relied on.
    5768+ See also $2021-05 report.impl.
    5769+ Support of integers in module YStandardEx.CStandardInteger is enhanced.
    5770+ The addition of support for native 128-bit integers are taken into account.
    5771+ An additional fix is to support padding bits in the integer types.
    5772+ There may be some bugs in the implementation.
    5773+ See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97798 for example.
    5774+ The initial work for MSP430 with '__int20' did it correctly in the same time for the comilper frontend and libstdc++'s <limits>.
    5775+ This also includes '__GLIBCXX_TYPE_INT_N_0' and related changes, intialliy, not specific to 128-bit integer types.
    5776+ See https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;h=78a7c3172fe2e6cd959abb8bfc69f6b0dc747d49.
    5777+ Nevertheless, padding bits are only in 'bool'. There are no supported platform actually relies on the feature.
    5778+ There is no workaround for buggy implementations. Just use the underlying support.
    5779+ The unary type trait 'ystdex::integer_width' now correctly respects optional padding bits for types having the specialization of 'std::numeric_limits'.
    5780+ If there is the specialization, it shall be an interger type. This precondition is remained unchanged. Violation of the precondition is not checked.
    5781+ Otherwise, any integer type with value representation same to the object representation can be supported.
    5782+ That is, it has no padding bits in its object representation.
    5783+ In particular, '__int128' and 'unsigned __int128' may not have the 'std::numeric_limits' specialization for older version of libstdc++.
    5784+ See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96042.
    5785+ Since supported 128-bit integers have no padding bits, there is no need to add the 'std::numeric_limits' specializations for them even when the specializations do not exist.
    5786+ Traits 'extend_additive_overflow', 'extend_additive_underflow' and 'extend_product' are introduced to get the result type of arithmetic operations without overflow.
    5787+ They can help in cases where the usual arithmetic conversion rules in the core language resulting in a type not having sufficient range.
    5788+ In the case of potential arithmetic overflow, these traits lift the result to a floating-point type.
    5789+ The floating-point type is 'std::float_t' for maximum performance.
    5790+ It can be more efficient than using 'float', 'double' or 'long double' directly.
    5791+ See C99 Rationale: http://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf.
    5792+ Actually for x87, native floating-point format in register is 80-bit, it suffers from conversion overhead to 'float' or 'double'.
    5793+ For compatiblity of memory representations and sakes of interoperations, 'float' and 'double' sticking to ISO/IEC/IEEE 60559 (IEEE-754) might be more appropriate.
    5794+ This need additional tweaks in the call sites since the purporse can not be judged here neutrally.
    5795+ Utilities for time in YStandardEx in YBase are improved.
    5796+ Support of types like ISO C++17's 'std::timespec' in metaprogramming has been added in module YStandardEx.CTime.
    5797+ A new header-only module Chrono extending the ISO C++'s <chorno> is added with direct replecement for ISO C++20's 'chrono::is_clock', checked cast interface and a bit more.
    5798+ The detailed implementation relying on further refactor and improvement of on YStandardEx headers (e.g. optional but robust 128-bit integer support).
    5799+ Some instances of 'std::duration_cast' are checked to see if it is appropriate to be replaced by 'ystdex::chrono::checked_duraion_cast'.
    5800+Using of non-throwing interface of 'std::chrono::duration_values' is acknowledged in the whole project.
    5801+ This is neutral to WG21 P0972R0.
    5802+ Even without WG21 P0972R0 adoopted, the calls to 'max', 'min' and 'zero' have already been non-throwing as per the previous standard wording.
    5803+ Although mentioned in $2014-03 report.impl, 'duration_values' has never been used in this project. The type of 'noexcept' specifier has never been relied on, anyway.
    5804+
    5805+2024-04:
    5806+
    5807+report.impl:
    5808+YBase improvement of numeric types continued.
    5809+ The workaround for old libstdc++ is added as a new header-only module LibDefect.Limits.
    5810+ This should be compatible to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96042.
    5811+ To be consistent, header inclusion <libdefect/limits.hpp> should replace <limits> in all use sites unless the added specializations are never used.
    5812+ Some are not subject to the change.
    5813+ The following modules do not require specializations of non-standard integer types because only specializations of known standard integers are used, so no changes are required:
    5814+ YBase modules HashTable, Memory, StringView and Tree in YStandardEx;
    5815+ Implementations of YFramework modules YCLib.Host, YCLib.YCommon and YSLib.UI.Loader;
    5816+ Implementation of YSTest module DSReader.
    5817+ YFramework module NPL.NPLAMath does not suuport the use on the 'std::numeric_limits' specializations for integer types.
    5818+ The diagnostics are to be improved for unsupported specializations.
    5819+ The implementation also does not use non-standard integers as the template argument of 'std::numeric_limits'.
    5820+ YBase module YStandardEx.Rational is depending on the change, but it transparent after the planned change in YBase module YStandardEx.CStandardInteger.
    5821+ Some need to be adjusted.
    5822+ YBase module YStandardEx.Chrono does not depend on the 'std::numeric_limits' specializations for non-standard integer types, but if instantiated, it would violate [temp.expl.spec]/7.
    5823+ Some need additional explicit header inclusion of <libdefect/limits.hpp> because they depended on the specializations without available explicitly included <limits> and the indirectly included headers are insufficient to guarntee <libdefect/limits.hpp> is included even after the planned changes here.
    5824+ YBase module YStandardEx.String ('ystdex::stoa') does depend on the specializations, and there is no explicit <limits> included (implied by module YStandardEx.StringView but not planned supporting the specializations).
    5825+ YBase module YStandardEx.Rational and YFramework module YSLib.Core.YCoreUtilites also have no explicit <limits> included.
    5826+ The remaining affected modules including explicit <limits> (to be changed to <libdefect/limits.hpp>) are:
    5827+ YBase modules Bit, Cast, CStandardInteger, CTime, Hash and List in YStandardEx.
    5828+ YFramework module YSLib.Core.YGDIBase.
    5829+ By specifying YStandardEx.CStandardInteger including <libdefect/limits.hpp>, some indirect dependencies can be implied and some are not needed to be adjusted any more.
    5830+ These include YBase modules YStandardEx.Chrono, YStandardEx.Hash and YStandardEx.Rational.
    5831+ Instead of <libdefect/limits.hpp>, YFramework module YSLib.Core.YCoreUtilites further needs <ystde/cstdint.hpp>.
    5832+ The redundant header inclusion <limits> (if any) can be removed later.
    5833+ However, new headers may include YStandardEx.CStandardInteger, see below.
    5834+ A new header-only module YStandardEx.Limits is added.
    5835+ This encapsulate the newly added YBase module LibDefect.Limits with some additional traits.
    5836+ This also addresses the problem that no appropriate place is in YBase for traits not specific to integer types (which are previously added to YStandardEx.CStandardInteger).
    5837+ This header can sometimes replace <libdefect/limits.hpp>.
    5838+ A new header-only module YStandardEx.Arithmetic is added.
    5839+ Integer arithmetics aware of overflow (and underflow) are added here rather than in YStandardEx.CStandardInteger.
    5840+ The module YStandardEx.Chrono is adjusted to use the implementation here.
    5841+ Bugs of lacking of SFINAE-friend in some member functions in iterators in YBase module YStandardEx.Iterator have been fixed.
    5842+ The bug affects iterator adaptors supporting a wider range of operations than the adapted iterators.
    5843+ If some adapted iterator type does not support specific operations, the adaptor should not assume they are available unless the iterator requirements (or iterator concepts since ISO C++20) guarantees they must exist.
    5844+ Ill-formed expressions implied by the instantiation in the noexcept-specificiation shall be prevented even when the underlying iterator does not have the required operations.
    5845+ Such bugs may affect the well-formedness without invoking the operations.
    5846+ The bug on 'operator-' of 'ystdex::transformed_iterator' would cause an iterator not satisfying 'RandomAccessIterator' concept failed at 'iter_difference' check in ISO C++20 modes, at least with Clang++ 17 and libc++.
    5847+ A new module YStandardEx.CharacterConversion is added.
    5848+ As ISO C++17's <charconv>, this is to support primitive numeric conversions.
    5849+ As suggested by its name, this should extend <charconv>, but not at current.
    5850+ This is currently header-only.
    5851+ In particular, conversions from internal representations of external representations of numeric values are supported here, as the basis for other headers.
    5852+ This is like the case that the standard header <format> (ISO C++20 onwards) can share some implementation from <charconv>.
    5853+ This provides underlying implementation of integer 'to_string' conversions for the module YStandard.String (see below).
    5854+ The interface is actually a generalized form of numeric conversions in the implementation of YFramework module NPL.NPLAMath.
    5855+ The module NPL.NPLAMath is to be simplified by reusing these interface.
    5856+ Conversion functions 'ystdex::to_string' in module YStandardEx.String are improved.
    5857+ The overloads to support 128-bit integers (if any), as well as overloads with allocator support, are added.
    5858+ The implementation now uses the underlying implementation from the module YStandardEx.CharacterConversion.
    5859+ All the standard implementations of 'std::to_string' for integers are replaced.
    5860+ The overloads for integer parameters to replace 'std::to_string' and the overloads with allocator support share the underlying code.
    5861+ This is different to other replacement features which use the existing standard library implementation as possible unless it is not available under the current standard mode or there are conforming bugs.
    5862+ This prevents the inconsistency between any 'std::to_string' implementations and additional overloads (e.g. due to bugs).
    5863+ This also prevent some code bloat by different code paths when these overloads are used together via 'ystdex::to_string', albeit not when 'std::to_string' is used explicitly.
    5864+ This should also be more efficient than a loop of division 10 (as in Microsft STL) filling the buffer backwards.
    5865+ By including <ystdex/charconv.h>, there is no needed to explicitly include <libdefect/limits.hpp>.
    5866+ There is no need to include <libdefect/limits.h> separatedly in module YStandardEx.String.
    5867+
    56615868 ////
    56625869
    diff -r 3fe9fa0c6127 -r 74e1025f0a02 doc/YBase.txt
    --- a/doc/YBase.txt Tue Feb 27 00:28:20 2024 +0800
    +++ b/doc/YBase.txt Fri Apr 19 22:42:25 2024 +0800
    @@ -1,23 +1,22 @@
    11 /*
    2- © 2012-2023 FrankHB.
    2+ © 2012-2024 FrankHB.
    33
    4- This file is part of the YSLib project, and may only be used,
    5- modified, and distributed under the terms of the YSLib project
    6- license, LICENSE.TXT. By continuing to use, modify, or distribute
    7- this file you indicate that you have read the license and
    8- understand and accept it fully.
    4+ This file is part of the YSLib project, and may only be used, modified,
    5+ and distributed under the terms of the YSLib project license.
    6+ By continuing to use, modify, or distribute this file you indicate that
    7+ you have read the license and understand and accept it fully.
    98 */
    109
    1110 /*! \file YBase.txt
    1211 \ingroup Documentation
    1312 \brief YBase 说明。
    14-\version r2063
    13+\version r2180
    1514 \author FrankHB <frankhb1989@gmail.com>
    1615 \since build 305
    1716 \par 创建时间:
    1817 2012-04-29 17:11:42 +0800
    1918 \par 修改时间:
    20- 2023-02-20 19:21 +0800
    19+ 2024-04-14 22:06 +0800
    2120 \par 文本编码:
    2221 UTF-8
    2322 \par 模块名称:
    @@ -74,9 +73,12 @@
    7473 尽可能严格遵守 ISO C++ ,涉及未指定行为和实现定义的行为时应由文档说明。
    7574 特性使用的基本规则参见 [Documentation::ProjectRules @@1.3.1] ,应符合其中的基准实现要求。
    7675 据此,语言特性指定保持以下原则:
    77-默认使用 ISO C++11 的一个严格子集;
    78-可选使用之后版本的标准兼容的特性;
    79-使用的特性应使代码保持和已出版的最新标准兼容。
    76+ 默认使用 ISO C++11 的一个严格子集。
    77+ 可选使用之后版本的标准兼容的特性。
    78+ 使用的特性应使代码保持和已出版的最新标准兼容。
    79+ 仅在必要时非标准的特定实现的公开特性,这些特性被实现使用或包装为兼容支持的平台的接口。
    80+ **注释** 为检查特性可用性,可能依赖使用特定实现的公开接口(如实现相关的宏定义)。
    81+ **注释** 详见扩展特性(@2.1.1.2) 。
    8082 可选使用的标准兼容的特性可用于支持对 ISO C++ 自身可能具有的缺陷的修正。
    8183 除使用标准库明确依赖多线程环境的接口外,YBase 严格不依赖运行时具有的多线程执行环境。
    8284 在 YDefinition 和 YStandardEx 提供标准库替代接口时,视语义在被 ISO C++ 允许(这是一般情形)的前提下可提供更多的 [[nodiscard]](以 YB_ATTR_nodiscard 的形式)和 noexcept(以 ynothrow 等形式)的异常规范。
    @@ -85,6 +87,7 @@
    8587 关于对语言的使用,另见 [Documentation::LanguageConvention @@5] 和 [Documentation::LanguageConvention @@6] 。
    8688
    8789 @2.1.1.1 预处理指令:
    90+除非另行指定,头文件包含同库使用约定([Documentation::CommonRules @@3.13.2]) 。
    8891 允许在预处理指令中使用特定实现的宏检查支持的特性作为变通。
    8992 正式的变通使用的宏仅限公开支持的宏或者 YDefinition 提供的宏。
    9093 其中,在条件包含中可使用除符合 ISO C++ 当前草案的 __has_cpp_attribute 和 __has_include 外,还可使用由 https://clang.llvm.org/docs/LanguageExtensions.html 约定含义的以下特性检查扩展:
    @@ -99,12 +102,14 @@
    99102 @2.1.1.2 内建和扩展特性:
    100103 若内建特性在 YDefinition 提供宏支持且可用,以 YDefinition 宏替代直接的使用。
    101104 假定可能支持的特性(除非另行指定,按 https://clang.llvm.org/docs/LanguageExtensions.html 约定含义 )在本节列出。
    105+使用 __extension__ 标注支持 GNU 扩展以支持在严格标准模式下使用:
    106+ __int128 和 __uint128 类型。
    102107 使用 Microsoft VC++ 支持的 #pragma intrinsic 引入的内建特性:
    103108 _BitScanForward
    104109 _BitScanForward64
    105110 _BitScanReverse
    106111 _BitScanReverse64
    107-使用以下可用 __has_builtin 检查的内建特性(返回为 true ):
    112+使用以下可用 __has_builtin 检查的内建特性(支持时返回非零值):
    108113 __builtin_addressof
    109114 __builtin_assume
    110115 __builtin_assume_aligned
    @@ -115,14 +120,20 @@
    115120 __builtin_ctzl
    116121 __builtin_ctzll
    117122 __builtin_expect
    123+__builtin_add_overflow
    124+__builtin_mul_overflow
    125+__builtin_sub_overflow
    118126 __builtin_trap
    119127 __builtin_unreachable
    128+__remove_cvref
    120129 在特定实现还可能使用以下可用 __has_builtin 检查的内建特性:
    121130 __builtin_constant_p
    122131 __builtin_ia32_bsrdi
    123132 __builtin_ia32_bsrsi
    124133 使用以下可用 __has_extension 检查的扩展特性(返回为 true ):
    125134 __is_final
    135+特定实现使用以下特性:
    136+__integer_pack
    126137 外部参考列表:
    127138 https://docs.microsoft.com/en-us/cpp/intrinsics/bitscanforward-bitscanforward64
    128139 https://docs.microsoft.com/en-us/cpp/intrinsics/bitscanreverse-bitscanreverse64
    @@ -170,7 +181,7 @@
    170181 当前这些替代实现包括:
    171182 YStandardEx::Bit(@2.5.7.6) 使用 GCC 时,对 i386 和 x86_64 的部分实现使用特定体系结构的替代实现,以避免代码生成的性能缺陷。
    172183 参见 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=29776 。
    173- 替代实现优先检查可使用的 GCC 内建特性(@2.1.1.2) ;否则,使用内联汇编。
    184+ 替代实现优先检查可使用的 GCC 内建特性(@2.1.1.2) ;否则,使用内联汇编。
    174185
    175186 @2.1.2 安全性:
    176187 基本内容参见 [Documentation::CommonRules @@3.11] 。另见 @2.1.1 。
    @@ -247,6 +258,7 @@
    247258 YDefinition 在 @2.1.1 的基础上支持更多实现,且提供特定 ISO C++11 关键字的替代。
    248259 YDefinition 中的特性应保证在被替代的关键字不被支持时仍可以被实现接受。
    249260 文件內容为系统环境和公用类型和宏的基础定义,包括对实现环境的检测、实现特性的封装、部分未被实现关键字替代以及一些语言层次上的公共基础设施。
    261+因为提供对实现环境的选项(例如消除 Microsoft Visual C++ 的标准库警告的宏定义),直接或间接包含这个头文件时一般应保证置于其它标准库头的包含之前(关于头文件顺序,另见 [Documentation::CommonRules @@3.13.2.2] )。
    250262 以下名称以 y 起始的宏是表达式宏([Documentation::CommonRules @@5.10]) 或替代关键字(@2.4.7) 。
    251263
    252264 @2.4.1 实现标记宏:
    @@ -334,9 +346,11 @@
    334346 "tuple.hpp" 依赖 "apply.hpp" ;
    335347 "memory.hpp" 依赖 "pointer.hpp" 和 "allocator.hpp" ;
    336348 "functional.hpp" 依赖 "invoke.hpp" 、"ref.hpp" 、"functor.hpp" 、"bind.hpp" 、"function.hpp" 和 "hash.hpp";
    349+"string.hpp" 依赖 <libdefect/string.h> ;
    337350 "string.hpp" 、"array.hpp" 、"string_view" 、"list.hpp" 、"map.hpp" 和 "set.hpp" 依赖 "range.hpp" ;
    338351 "iterator.hpp" 依赖 "iterator_op.hpp" 。
    339352 因其它接口设计原因,以下依赖性作为接口公开:
    353+"integral_constant.hpp" 依赖 "cstddef.h" ;
    340354 "type_inspection.hpp" 依赖 "integral_constant.hpp" ;
    341355 "meta.hpp" 依赖 "type_inspection.hpp" ;
    342356 "variadic.hpp" 和 "invoke.hpp" 依赖 "meta.hpp" ;
    @@ -344,26 +358,31 @@
    344358 "iterator_op.hpp" 依赖 "operators.hpp" ;
    345359 "placement.hpp" 、"range.hpp" 和 "operators.hpp" 依赖 "addressof.hpp" ;
    346360 "pointer.hpp" 和 "memory.hpp" 依赖 "iterator_op.hpp" ;
    361+"cstdint.hpp" 、"charconv.h" 和 "chrono.hpp" 依赖 <libdefect/limits.hpp> ;
    347362 "apply.hpp" 依赖 "invoke.hpp" ;
    348363 "string_view.hpp" 依赖 <libdefect/string.h> ;
    349364 "hash.hpp" 和 "mixin.hpp" 依赖 "tuple.hpp" ;
    350365 "functor.hpp" 依赖 "ref.hpp" 和 "type_traits.hpp" ;
    351366 "function_adaptor.hpp" 依赖 "bind.hpp" 和 "compose.hpp" ;
    352367 "functional.hpp" 依赖 "function_adaptor.hpp" 和 "expanded_function.hpp" ;
    368+"arithmetic.hpp" 依赖 "cstdint.hpp" 、"limits.hpp" 、<cmath> 和 "exception.h" ;
    353369 "tree.h" 、"hash_table.h" 、"container.hpp" 、"flat_map.hpp" 和 "flat_set.hpp" 依赖 "range.hpp" ;
    354-"tree.h" 和 "hash_table.h" 依赖 "node_handle.hpp" ;
    370+"tree.h" 和 "hash_table.h" 依赖 "node_handle.hpp" ;
    355371 "hash_table.h" 依赖 "hash.hpp" ;
    356-"string.hpp" 依赖 "container.hpp" ;
    372+"string.hpp" 依赖 "container.hpp" 和 "charconv.h" ;
    357373 "list.hpp" 依赖 "node_base.h" 。
    358374 "map.hpp" 和 "set.hpp" 依赖 "tree.h" ;
    359375 "unordered_map.hpp" 和 "unordered_set.hpp" 依赖 "hash_table.h" ;
    360376 "any_iterator.hpp" 依赖 "any.h" 。
    361-另见 @2.5.4 和以下各节。
    377+另见不依赖其它 YStandardEx 文件的基本头文件(@2.5.4) 和以下各节。
    378+**原理**
    379+因为接口设计公开依赖的常见情形是接口使用类型具有依赖,需要确保使用前引入适当的声明。
    362380 **注释**
    363381 "range.hpp" 被多个容器相关的头文件公开依赖,类似 ISO C++ [iterator.range]/1 对 <iterator> 外的多个标准库头提供自定义范围访问的约定。
    364382
    365383 @2.5.1.2 内部头文件依赖性:
    366-除对标准库头的公开依赖外,当前实现保持以下内部直接依赖(及通过传递闭包蕴含实现的公开依赖)供实现参考,可简化头文件包含和避免循环引用:
    384+除对标准库头的公开依赖外,当前实现保持以下内部直接依赖(及通过传递闭包蕴含实现的公开依赖)供 YBase 实现参考,可简化头文件包含和避免循环引用:
    385+"integral_constant.hpp" 依赖 "cstddef.h" ;
    367386 "type_inspection.hpp" 依赖 "integral_constant.hpp" ;
    368387 "meta.hpp" 依赖 "type_inspection.hpp" ;
    369388 "variadic.hpp" 和 "invoke.hpp" 依赖 "meta.hpp" ;
    @@ -384,6 +403,7 @@
    384403 "apply.hpp" 依赖 "invoke.hpp" ;
    385404 "tuple.hpp" 依赖 "apply.hpp" ;
    386405 "pointer.hpp" 依赖 "iterator_op.hpp" ;
    406+"cstdint.hpp" 、"charconv.h" 和 "chrono.hpp" 内部依赖 "limits.hpp"(蕴含公开依赖 <libdefect/limits.hpp> );
    387407 "allocator.hpp" 内部依赖 "type_op.hpp" 和 "pointer.hpp" ;
    388408 "memory.hpp" 依赖 "pointer.hpp" 和 "allocator.hpp" ;
    389409 "memory.hpp" 内部依赖 "placement.hpp" 和 "ref.hpp" ;
    @@ -398,6 +418,7 @@
    398418 "expanded_function.hpp" 内部依赖 "function.hpp" ;
    399419 "functional.hpp" 依赖 "invoke.hpp" 、"ref.hpp" 、"functor.hpp" 、"bind.hpp" 、"function.hpp" 、"hash.hpp" 、"function_adaptor.hpp" 和 "expanded_function.hpp" ;
    400420 "any.h" 内部依赖 "typeinfo.h" 和 "utility.hpp" ;
    421+"arithmetic.hpp" 依赖 "cstdint.hpp" 和 "limits.hpp" ;
    401422 "iterator.hpp" 依赖 "iterator_op.hpp" ;
    402423 "iterator.hpp" 内部依赖 "ref.hpp" ;
    403424 "string_view.hpp" 依赖 "range.hpp" ;
    @@ -408,20 +429,27 @@
    408429 "container.hpp" 依赖 "range.hpp" ;
    409430 "container.hpp" 内部依赖 "integer_sequence.hpp" ;
    410431 "any_iterator.hpp" 依赖 "any.h" ;
    411-"string.hpp" 依赖 "container.hpp" ;
    412-"string.hpp" 内部依赖 "allocator.hpp" 和 "string_view.hpp"(蕴含公开依赖 "range.hpp" );
    432+"string.hpp" 依赖 "container.hpp" 和 "charconv.h" ;
    433+"string.hpp" 内部依赖 "allocator.hpp" 和 "string_view.hpp"(蕴含公开依赖 "range.hpp" 和 <libdefect/string.h> );
    413434 "list.hpp" 依赖 "range.hpp" ;
    414435 "map.hpp" 和 "set.hpp" 依赖 "tree.h"(蕴含公开依赖 "range.hpp" );
    415436 "unordered_map.hpp" 和 "unordered_set.hpp" 依赖 "hash_table.h"(蕴含公开依赖 "range.hpp" );
    416437 "flat_map.hpp" 和 "flat_set.hpp" 依赖 "range.hpp" ;
    417438 "scope_guard.hpp" 内部依赖 "function.hpp" 。
    418439 除此之外,内部依赖对标准库头的依赖也视为内部依赖。
    440+**注释** 内部依赖可能在未来改变而不视为接口变更。YBase 外的实现应避免假定具体的内部依赖存在。
    419441
    420442 @2.5.2 命名空间和模板特化:
    421-除在块作用域、非公开的实现命名空间和此处列明的例外,禁止其它的别名声明引入 std 成员命名空间:
    422-ystdex 中对标准库的元编程和类型特征名称使用别名声明;
    423-文档指定的以实现为 ADL([Documentation::LanguageConvention @@5.2.4.1]) 提供并行重载为目的的别名声明。
    443+除在块作用域、非公开的实现命名空间和此处指定的例外,禁止其它的别名声明引入 std 成员命名空间:
    444+ ystdex 中对标准库的元编程和类型特征名称使用别名声明。
    445+ 文档指定的以实现为 ADL([Documentation::LanguageConvention @@5.2.4.1]) 提供并行重载为目的的别名声明。
    424446 ystdex 的类型在声明所在的同一头文件中,可能存在 std 命名空间中的类模板的对应特化。
    447+**注释** 以下类似 ISO C++ [namespace.std] ;变量模板没有被当前实现依赖。
    448+除非另行指定,在公开命名空间(@2.5.2.2) 中添加声明,程序的行为未定义。
    449+除非显式禁止,当满足以下条件时,程序可为公开命名空间中的类模板添加模板特化:
    450+ 添加的声明至少依赖一个程序定义的(program-defined) 类型。
    451+ 特化满足被特化模板的原始要求。
    452+除非另行指定,声明显式或偏特化变量模板的程序的行为未定义。
    425453
    426454 @2.5.2.1 非公开实现命名空间:
    427455 命名空间 ystdex 内 details 命名空间和声明以宏 yimpl(@2.4.3) 修饰的命名空间保留为非公开实现。
    @@ -434,6 +462,9 @@
    434462 ystdex :YStandardEx 使用的默认命名空间。
    435463 ystdex::any_ops :ystdex::any 相关的底层操作接口。
    436464 ystdex::bases :隔离 ADL 的基类命名空间。
    465+ystdex::chrono :替代 std::chrono 的命名空间。
    466+inline ystdex::chrono::cpp2011 包含 ISO C++ 2011 引入的 std::chrono 名称或更新实体特性的命名空间。
    467+inline ystdex::chrono::cpp2020 包含 ISO C++ 2020 引入的 std::chrono 名称或更新实体特性的命名空间。
    437468 inline ystdex::cpp2011 包含 ISO C++ 2011 引入的 std 名称或更新实体特性的命名空间。
    438469 inline ystdex::cpp2014 包含 ISO C++ 2014 引入的 std 名称或更新实体特性的命名空间。
    439470 inline ystdex::cpp2017 包含 ISO C++ 2017 引入的 std 名称或更新实体特性的命名空间。
    @@ -442,7 +473,7 @@
    442473 ystdex::fseq :变长序列函数模板操作。
    443474 ystdex::nodep :隔离 ADL 的基类以外的命名空间。
    444475 ystdex::pmr :替代 std::pmr 的命名空间。
    445-inline ystdex::pmr::cpp2017 :包含 ISO C++ 2017 引入的 std::pmr 名称的命名空间。
    476+inline ystdex::pmr::cpp2017 :包含 ISO C++ 2017 引入的 std::pmr 名称或更新实体特性的命名空间。
    446477 ystdex::threading :线程相关操作。
    447478 ystdex::uniformed_tags :对非模板和不同模板参数相同的类型标签接口。
    448479 ystdex::vseq :变长序列元函数操作。
    @@ -467,6 +498,7 @@
    467498 不以别名声明时,为不同实体,同时使用(如作为重载函数的参数)时需要分别处理,避免违反 ODR([Documentation::LanguageConvention @@5.1.8]) ;
    468499 不保证变更接口时会不在上述类别之间迁移。
    469500 除非文档说明,保证使用 YStandard 接口可替换标准库接口或 TS 接口,但不保证逆向替换可行( YStandardEx 可扩展标准库中不具备的特性)。
    501+部分头文件对标准库提供扩展或替代。这些扩展和替代被分组,以下描述中每一节对应一个分组。除非存在包含依赖要求,每组内同被扩展和替代或接口在标准文档中相同的章节顺序。
    470502 以下文档概要仅包括头文件没有详细明确的部分。
    471503
    472504 @2.5.4 不依赖其它 YStandardEx 文件的基本头文件:
    @@ -477,7 +509,8 @@
    477509
    478510 @2.5.5 基本 ISO C 标准库扩展:
    479511 提供 ISO C 标准库的扩展,可能具有实现文件。
    480-头文件和实现文件的头文件依赖要求同 @2.5.4 。
    512+头文件和实现文件的头文件依赖要求同不依赖其它 YStandardEx 文件的基本头文件(@2.5.4) 。
    513+**注释** 不满足此要求的 ISO C 标准库扩展可能作为以下的 ISO C++ 标准库扩展的一部分。
    481514
    482515 @2.5.5.1 ISO C 标准库类型定义扩展 CStandardDefinition :
    483516 头文件扩展标准库头 <cstddef> ,提供一些替代实现。
    @@ -525,7 +558,7 @@
    525558
    526559 @2.5.7 核心扩展库:
    527560 用于构建其它库的通用元编程以外的设施。
    528-依赖规则同 @2.5.6 。
    561+依赖规则同通用元编程库(@2.5.6) 。
    529562
    530563 @2.5.7.1 解引用操作 DereferenceOperation :
    531564 提供解引用操作检查的模板,作为迭代器操作的基础。
    @@ -572,20 +605,21 @@
    572605 以下头文件扩展 ISO C++ 标准定义的语言支持库([support.general]) 中的至少一个并可能扩展其它标准库头,提供对应的相似接口,不依赖以上文件外的 YStandardEx 头文件。
    573606
    574607 @2.5.8.1 ISO C 标准整数类型操作 CStandardInteger :
    575-头文件间接扩展标准库头 <cstdint> ,提供一些类型操作和一些整数类型的模板特化以及模算术的基本支持。
    608+间接扩展标准库头 <cstdint> ,提供一些类型操作和一些整数类型的模板特化以及模算术的基本支持。
    576609
    577-@2.5.8.2 标准库异常扩展接口 Exception :
    578-扩展标准库头 <exception> 、<stdexcept> 和 <system_error> ,提供便利接口和若干异常基类。
    610+@2.5.8.2 实现限制 Limits :
    611+扩展标准库头 <limits> ,提供一些扩展的特征和元编程设施。
    579612
    580613 @2.5.8.3 ISO C++ 类型信息扩展 TypeInfo :
    581614 头文件扩展标准库头 <typeinfo> ,提供了无 RTTI 开销的静态类型信息类和兼容接口。
    582615
    583-@2.5.8.4 ISO C++ 类型信息扩展 TypeIndex :
    584-头文件扩展标准库头 <typeindex> ,提供了无 RTTI 开销的静态类型索引类和兼容接口。
    616+@2.5.8.4 标准库异常扩展接口 Exception :
    617+扩展标准库头 <exception> 、<stdexcept> 和 <system_error> ,提供便利接口和若干异常基类。
    585618
    586619 @2.5.9 基本 ISO C++ 标准库扩展和替代:
    587-扩展或替代标准库文件,提供和标准库对应的相似接口,但不包含基本 ISO C 标准库扩展(@2.5.5) 和 ISO C++ 标准库字符串和模板库组件扩展和替代(@2.5.9) 。
    588-除 @2.5.1.2 外,不依赖之前提及以外的 YStandardEx 头文件。
    620+扩展或替代标准库文件或作为这些头文件依赖的接口的一部分,提供和标准库对应的相似接口,但不包含基本 ISO C 标准库扩展(@2.5.5) 和 ISO C++ 标准库字符串和模板库组件扩展和替代(@2.5.9) 。
    621+ISO C++ 标准库字符串和模板库组件扩展和替代可能依赖的 ISO C 标准库扩展在此视为基本 ISO C++ 标准库扩展。
    622+除指定依赖的头文件(@2.5.1.2) 外,不依赖之前提及以外的 YStandardEx 头文件。
    589623
    590624 @2.5.9.1 ISO C++ 类型特征扩展 TypeTraits :
    591625 间接扩展标准库头 <type_traits> ,包括元编程设施等。
    @@ -617,7 +651,8 @@
    617651 相对地,ystdex::pmr::new_delete_resource 蕴含的 ystdex::pmr::new_delete_resource_t 类型被作为公开接口直接提供。若有必要,用户可在每个翻译单元中定义和使用单独的资源对象,以避免潜在的生存期问题。
    618652 但是因为没有使用 nifty counter 等方式定义在头文件,用户仍应确保跨翻译单元的资源初始化和释放顺序符合预期而避免未定义行为。
    619653
    620-@2.5.9.9 ISO C 标准字符串扩展 CString
    654+@2.5.9.9 ISO C 标准字符串扩展 CString :
    655+扩展标准库头 <cstring> 。
    621656
    622657 @2.5.9.10 只读字符串视图 StringView :
    623658 提供 ISO C++17 标准库头 <string_view> 的替代接口和实现。
    @@ -643,20 +678,31 @@
    643678 @2.5.9.17 展开调用的函数对象 ExpandedFunction :
    644679 提供通用的允许实际参数列表的后缀在调用时被忽略的调用接口和对应的调用包装。
    645680
    646-@2.5.9.18 函数和可调用对象 Functional :
    647-扩展标准库头 <functional> ,提供函数类型操作和各种一般调用的实现。
    648-
    649-@2.5.9.19 可选对象类型 Optional :
    681+@2.5.9.18 可选对象类型 Optional :
    650682 提供 ISO C++17 标准库头 <optional> 的替代接口和实现,并提供一些扩展。
    651683
    652-@2.5.9.20 动态泛型类型 Any :
    684+@2.5.9.19 动态泛型类型 Any :
    653685 主要提供 Boost.Any 和提议的 ISO C++ std::experiment::any 的类似的基于类型擦除实现的用于保存运行时确定类型的值的对象,默认使用和 libstdc++ 5 类似的小对象优化实现。
    654686 命名空间 any_ops 提供更多可供用户调整的内部接口。
    655687 提供了一些其它不和 any 类直接相关的类型擦除接口。
    656688 使用非零宏 YB_Use_LightweightTypeID 指定不依赖 RTTI 的 type_info 。
    657689
    690+@2.5.9.20 函数和可调用对象 Functional :
    691+扩展标准库头 <functional> ,提供函数类型操作和各种一般调用的实现。
    692+
    693+@2.5.9.21 ISO C++ 类型信息扩展 TypeIndex :
    694+头文件扩展标准库头 <typeindex> ,提供了无 RTTI 开销的静态类型索引类和兼容接口。
    695+
    696+@2.5.9.22 算术类型和操作 Arithmetic :
    697+提供基于 CStandardInteger(@2.5.8.1) 和 Limits(@2.5.8.2) 的算术类型和操作。
    698+
    699+@2.5.9.23 数值的字符表示和转换操作 CharacterConversion :
    700+提供数值字符表示和转换操作。
    701+提供类似 ISO C++23 <charconv> 的部分功能,但当前没有扩展 <charconv> 。这可能会在以后改变。
    702+
    658703 @2.5.10 ISO C++ 标准库字符串和模板库组件扩展和替代:
    659-同 @2.5.9 ,直接或间接扩展字符串、<iterator> 、<algorithm> 、容器、流或并发 API 的头文件,或提供这些头文件的内部实现基础。
    704+同基本 ISO C++ 标准库扩展和替代(@2.5.9) ,直接或间接扩展字符串、容器、迭代器、算法、流或并发 API 的头文件,或提供这些头文件的内部实现基础。
    705+**注释** 因为依赖性,部分扩展出现的顺序和标准文档中描述的顺序(@2.5.3) 不同。
    660706
    661707 @2.5.10.1 通用迭代器 Iterator :
    662708 间接扩展标准库头 <iterator> ,提供若干迭代器适配器和相关操作。
    @@ -668,75 +714,85 @@
    668714 扩展标准库头 <algorithm> ,提供一些泛型算法。
    669715 除非另行指定,使用 first 和 last 为名称的参数指定同一个范围,否则不保证结果正确,可能引起未定义行为。
    670716
    671-@2.5.10.4 ISO C++ 标准字符串扩展 String :
    717+@2.5.10.4 通用容器操作 Container :
    718+实现通用容器适配器模板和对容器类型及构建数组容器的操作。
    719+参数限制同 Algorithm(@2.5.10.3) 。
    720+
    721+@2.5.10.5 ISO C++ 标准字符串扩展 String :
    672722 间接扩展标准库头 <string> ,提供 std::char_traits 的扩展功能和对 std::basic_string 及类似类型的操作。
    673723
    674-@2.5.10.5 指定结束字符的只读字符串视图 TStringView :
    724+@2.5.10.6 指定结束字符的只读字符串视图 TStringView :
    675725 基于 StringView(@2.5.9.10) 提供近似标准库头 <string_view> 中的 string_view 的扩展类型。
    676726
    677-@2.5.10.6 数组操作 Array :
    727+@2.5.10.7 数组操作 Array :
    678728 扩展标准库头 <array> ,提供内建数组和 std::array 相关类型的操作。
    679729
    680-@2.5.10.7 作为节点序列容器实现的节点基础 NodeBase :
    730+@2.5.10.8 作为节点序列容器实现的节点基础 NodeBase :
    681731 提供一些例程用于作为基于节点的序列容器实现的基础。
    682732 当前暂时不公开 API ,但其中的 API 已被 List(@2.5.10.8) 中的容器二进制依赖。未来可能会提供基于节点实现关联容器公共 API 。
    683733
    684-@2.5.10.8 列表容器 List :
    734+@2.5.10.9 列表容器 List :
    685735 扩展标准库头 <list> ,提供类模板作为和 ISO C++17 std::list 类似且提供标准草案的一些其它接口。未来可能提供其它关联的 API 。
    686736 附加 ISO C++11 不保证的附加特性不依赖 ISO C++17 及其具体实现。
    687737
    688-@2.5.10.9 作为关联容器和无序容器实现的节点句柄 NodeHandle :
    738+@2.5.10.10 作为关联容器和无序容器实现的节点句柄 NodeHandle :
    689739 提供关联容器和无序容器实现的相关类型。
    690740 当前暂时不公开 API ,但其中的 API 已被 Tree(@2.5.10.10) 和 HashTable(@2.5.10.13) 中的容器二进制依赖。
    691741
    692-@2.5.10.10 作为关联容器实现的树 Tree :
    742+@2.5.10.11 作为关联容器实现的树 Tree :
    693743 提供一些例程用于作为关联容器实现的基础。
    694744 当前暂时不公开 API ,但其中的 API 已被 Map(@2.5.10.10) 和 Set(@2.5.10.11) 中的容器二进制依赖。未来可能会提供基于树实现关联容器公共 API 。
    695745
    696-@2.5.10.11 映射容器 Map :
    746+@2.5.10.12 映射容器 Map :
    697747 扩展标准库头 <map> ,提供类模板作为和 ISO C++17 std::map 类似且支持不完整的键类型的实现。
    698748 附加 ISO C++11 不保证的附加特性不依赖 ISO C++17 及其具体实现。
    699749
    700-@2.5.10.12 集合容器 Set :
    750+@2.5.10.13 集合容器 Set :
    701751 扩展标准库头 <set> ,提供类模板作为和 ISO C++17 std::set 类似且支持不完整的键类型的实现。
    702752 附加 ISO C++11 不保证的附加特性不依赖 ISO C++17 及其具体实现。
    703753 同时扩展标准库头 <map> ,提供和 std::set 类似的容器。
    704754
    705-@2.5.10.13 作为无序容器实现的散列表 HashTable :
    755+@2.5.10.14 作为无序容器实现的散列表 HashTable :
    706756 提供一些例程用于作为无序容器实现的基础。
    707757 当前暂时不公开 API ,但其中的 API 已被 UnorderedMap(@2.5.10.14) 和 UnorderedSet(@2.5.10.15) 中的容器二进制依赖。
    708758
    709-@2.5.10.14 无序映射容器 UnorderedMap :
    759+@2.5.10.15 无序映射容器 UnorderedMap :
    710760 扩展标准库头 <unordered_map> ,提供类模板作为和 ISO C++20 std::unordered_map 类似且支持不完整的键类型的实现。
    711761 附加 ISO C++11 不保证的附加特性不依赖 ISO C++20 及其具体实现。
    712762
    713-@2.5.10.15 无序集合容器 UnorderedSet :
    763+@2.5.10.16 无序集合容器 UnorderedSet :
    714764 扩展标准库头 <unordered_set> ,提供类模板作为和 ISO C++20 std::unordered_set 类似且支持不完整的键类型的实现。
    715765 附加 ISO C++11 不保证的附加特性不依赖 ISO C++20 及其具体实现。
    716766
    717-@2.5.10.16 平坦映射容器 FlatMap :
    767+@2.5.10.17 平坦映射容器 FlatMap :
    718768 提供 ISO C++23 标准库头 <flat_map> 的替代接口和实现。
    719769 不支持 <compare> 。
    720770 不支持 from_range_t 构造。
    721771
    722-@2.5.10.17 平坦集合容器 FlatSet :
    772+@2.5.10.18 平坦集合容器 FlatSet :
    723773 提供 ISO C++23 标准库头 <flat_set> 的替代接口和实现。
    724774 不支持 <compare> 。
    725775 不支持 from_range_t 构造。
    726776
    727-@2.5.10.18 ISO C++ 标准流缓冲扩展 StreamBuffer :
    777+@2.5.10.19 ISO C++ 标准流缓冲扩展 StreamBuffer :
    728778 扩展标准库头 <streambuf> 。
    729779
    730-@2.5.10.19 ISO C++ 标准输入流扩展 InputStream :
    780+@2.5.10.20 ISO C++ 标准输入流扩展 InputStream :
    731781 扩展标准库头 <istream> 。
    732782
    733-@2.5.10.20 ISO C 标准输入/输出扩展 CStandardIO :
    783+@2.5.10.21 ISO C++ 时间接口扩展 Chrono :
    784+扩展标准库头 <chrono> 。
    785+
    786+@2.5.10.22 ISO C 日期和时间接口扩展 CTime :
    787+头文件扩展标准库头 <ctime> 。
    788+
    789+@2.5.10.23 ISO C 标准输入/输出扩展 CStandardIO :
    734790 头文件扩展标准库头 <cstdio> ,提供 C/C++ 流操作模式参数的转换和 C 标准库输入的迭代器包装。
    735791
    736-@2.5.10.21 ISO C++ <future> 扩展 Future :
    792+@2.5.10.24 ISO C++ <future> 扩展 Future :
    737793 扩展标准库头 <future> ,提供一些别名模板和便利接口。
    738794
    739-@2.5.10.22 伪互斥量 PseudoMutex :
    795+@2.5.10.25 伪互斥量 PseudoMutex :
    740796 提供单线程环境下互斥量和锁接口,作为标准库 <mutex> 的替代。
    741797
    742798 @2.5.11 其它扩展接口:
    @@ -748,35 +804,31 @@
    748804 @2.5.11.2 C++ 转换模板 Cast :
    749805 实现各种带类型限制的转换模板。
    750806
    751-@2.5.11.3 通用容器操作 Container :
    752-实现通用容器适配器模板和对容器类型及构建数组容器的操作。
    753-参数限制同 Algorithm(@2.5.10.3) 。
    754-
    755-@2.5.11.4 动态泛型迭代器 AnyIterator :
    807+@2.5.11.3 动态泛型迭代器 AnyIterator :
    756808 基于 Any(@2.5.9.20) 实现的用于保存运行时确定类型迭代器的对象。
    757809
    758-@2.5.11.5 基于类继承的混入接口 Mixin :
    810+@2.5.11.4 基于类继承的混入接口 Mixin :
    759811 提供基本的混入接口类型。
    760812
    761-@2.5.11.6 间接和惰性求值 Thunk :
    813+@2.5.11.5 间接和惰性求值 Thunk :
    762814 提供组合惰性求值的可调用对象。
    763815
    764-@2.5.11.7 作用域守卫 ScopeGuard
    816+@2.5.11.6 作用域守卫 ScopeGuard
    765817 提供若干恢复状态的 RAII 包装。
    766818
    767-@2.5.11.8 有理数运算 Rational :
    819+@2.5.11.7 有理数运算 Rational :
    768820 提供定点数模板等有理数算术类型接口。
    769821
    770-@2.5.11.9 位段数据结构和访问 BitSegment :
    822+@2.5.11.8 位段数据结构和访问 BitSegment :
    771823 提供访问位集合的类型和操作。
    772824
    773-@2.5.11.10 并发操作 Concurrency :
    825+@2.5.11.9 并发操作 Concurrency :
    774826 提供线程池等实用并发特性。
    775827
    776-@2.5.11.11 抽象路径模板 Path :
    828+@2.5.11.10 抽象路径模板 Path :
    777829 提供抽象的路径模板及操作。
    778830
    779-@2.5.11.12 高速缓冲容器模板 Cache :
    831+@2.5.11.11 高速缓冲容器模板 Cache :
    780832 提供抽象的缓冲容器模板及操作。
    781833
    782834 @2.6 LibDefect :
    Show on old repository browser