123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916 |
- #pragma once
- #ifndef ASSERT
- #include <cassert>
- #define ASSERT assert
- #endif
- //-----------------------------------------------------------------------------
- // 字符串格式化
- // 思路主要来自祈宇的文章:
- // <实现一个简单的字符串格式化方法>
- // https://www.cnblogs.com/qicosmos/p/3825612.html
- //-----------------------------------------------------------------------------
- #include <tuple>
- #include <type_traits>
- #include <string>
- #include <inttypes.h>
- #include <cctype>
- #include <stdexcept>
- #include <codecvt>
- #include <chrono>
- #include <cstdint> // 标准整数类型
- #include <cstdio> // snprintf函数
- #include <cstring> // 字符串操作函数
- #include <locale>
- // Linux下移除Windows特有警告禁用,替换为GCC兼容的警告处理(如需)
- #ifdef __GNUC__
- #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
- #endif
- namespace ZSKK::Utility::String
- {
- template <typename> constexpr bool dependent_false = false;
- template <typename T>
- inline std::string ToString(const T& value)
- {
- static_assert(dependent_false<T>, "You must implement ToString for type T with Partial template specialization !");
- return std::string();
- }
- }
- // 针对 bool 的模板偏特化
- namespace ZSKK::Utility::String
- {
- template <> inline std::string ToString(const bool& value)
- {
- static const auto strTrue = std::string("true");
- static const auto strFalse = std::string("false");
- return value ? strTrue : strFalse;
- }
- }
- namespace ZSKK::Utility::String
- {
- static const char __MsgOfNull_[] = "null";
- static const int __LenOfNull_ = sizeof(__MsgOfNull_) - 1;
- template <typename tDeriveClass>
- class _string_format_detail
- {
- protected:
- char* m_BufferOrg;
- char* m_Buffer;
- int m_NbOfChar;
- protected:
- inline int NbOfRemain() const
- {
- return m_NbOfChar - int(m_Buffer - m_BufferOrg);
- }
- private:
- template <typename arg>
- int _my_sprintf(char* buf, int NbOfChar, const char* fmt, arg a)
- {
- assert(false);
- return 22;
- }
- public:
- inline _string_format_detail(char* buf, int NbOfChar) // 缓冲区指针, 缓冲区长度 (字节计数)
- {
- assert(buf);
- m_BufferOrg = m_Buffer = buf;
- m_NbOfChar = NbOfChar;
- }
- protected:
- inline void CharFormatArg(char ch)
- {
- assert(9 <= ch && ch <= 127); // 确保非控制字符
- *m_Buffer = ch;
- m_Buffer++;
- }
- // 有符号整数格式化 - 使用重载而非特化
- inline void sDigitFormatArg(int i)
- {
- int len = std::snprintf(m_Buffer, NbOfRemain(), "%d", i);
- if (len > 0)
- m_Buffer += len;
- }
- inline void sDigitFormatArg(short i)
- {
- int len = std::snprintf(m_Buffer, NbOfRemain(), "%hd", i);
- if (len > 0)
- m_Buffer += len;
- }
- inline void sDigitFormatArg(int64_t i)
- {
- int len = std::snprintf(m_Buffer, NbOfRemain(), "%lld", i);
- if (len > 0)
- m_Buffer += len;
- }
- // 无符号整数格式化 - 使用重载而非特化
- inline void uDigitFormatArg(unsigned int i)
- {
- int len = std::snprintf(m_Buffer, NbOfRemain(), "%u", i);
- if (len > 0)
- m_Buffer += len;
- }
- /* inline void uDigitFormatArg(unsigned long i)
- {
- int len = std::snprintf(m_Buffer, NbOfRemain(), "%lu", i);
- if (len > 0)
- m_Buffer += len;
- }*/
- inline void uDigitFormatArg(unsigned short i)
- {
- int len = std::snprintf(m_Buffer, NbOfRemain(), "%hu", i);
- if (len > 0)
- m_Buffer += len;
- }
- inline void uDigitFormatArg(uint64_t i)
- {
- int len = std::snprintf(m_Buffer, NbOfRemain(), "%llu", i);
- if (len > 0)
- m_Buffer += len;
- }
- // 带格式的整数格式化 - 使用重载而非特化
- inline void DigitFormatArg(int i, const char* fmt)
- {
- // 实现代码保持不变
- assert(fmt && fmt[0]);
- auto chfmt = fmt[0];
- if (chfmt == 'c' || chfmt == 'C')
- {
- CharFormatArg(static_cast<char>(i));
- return;
- }
- if (chfmt == 'D') chfmt = 'd'; // 统一为小写格式符
- if (chfmt == 'U') chfmt = 'u';
- auto rc = (chfmt == 'd' || chfmt == 'u' || chfmt == 'X' || chfmt == 'x');
- if (!rc)
- {
- rc = (chfmt == 'f' || chfmt == 'F');
- if (rc)
- {
- FormatArg(static_cast<double>(i), fmt);
- return;
- }
- }
- assert(rc);
- if (!rc) return;
- char tofmt[8] = { '%', };
- // 处理格式数字(如D023 -> %023d)
- if (std::isdigit(fmt[1]))
- {
- int iFmtChar = 2;
- for (int Index = 1; Index <= 3; ++Index)
- {
- if (std::isdigit(fmt[Index]))
- {
- tofmt[Index] = fmt[Index];
- iFmtChar = Index + 1;
- }
- else
- break;
- }
- tofmt[iFmtChar] = chfmt;
- }
- else
- {
- tofmt[1] = chfmt;
- tofmt[2] = 0;
- }
- auto pT = static_cast<tDeriveClass*>(this);
- auto r = pT->_my_sprintf(m_Buffer, NbOfRemain(), tofmt, i);
- m_Buffer += r;
- }
- // 64位有符号整数带格式重载
- inline void DigitFormatArg(int64_t i, const char* fmt)
- {
- // 实现代码保持不变
- assert(fmt && fmt[0]);
- auto chfmt = fmt[0];
- if (chfmt == 'c' || chfmt == 'C')
- {
- CharFormatArg(static_cast<char>(i));
- return;
- }
- if (chfmt == 'D') chfmt = 'd';
- if (chfmt == 'U') chfmt = 'u';
- auto rc = (chfmt == 'd' || chfmt == 'u' || chfmt == 'X' || chfmt == 'x');
- assert(rc);
- if (!rc) return;
- // Linux下64位整数格式符为%lld/%llx,无需Windows的%I64d
- char tofmt[8] = { '%', };
- if (chfmt == 'd' || chfmt == 'i')
- std::strcpy(tofmt, "%lld");
- else if (chfmt == 'x')
- std::strcpy(tofmt, "%llx");
- else if (chfmt == 'X')
- std::strcpy(tofmt, "%llX");
- else if (chfmt == 'u')
- std::strcpy(tofmt, "%llu");
- auto pT = static_cast<tDeriveClass*>(this);
- auto r = pT->_my_sprintf(m_Buffer, NbOfRemain(), tofmt, i);
- m_Buffer += r;
- }
- // 64位无符号整数带格式重载
- inline void DigitFormatArg(uint64_t i, const char* fmt)
- {
- DigitFormatArg(static_cast<int64_t>(i), fmt);
- }
- // 字符格式化(无格式)
- inline void FormatArg(char ch) { CharFormatArg(ch); }
- inline void FormatArg(unsigned char ch) { uDigitFormatArg(static_cast<unsigned short>(ch)); }
- // 字符格式化(带格式,按整数处理)
- inline void FormatArg(char ch, const char* fmt) { DigitFormatArg(static_cast<int>(ch), fmt); }
- inline void FormatArg(unsigned char ch, const char* fmt) { DigitFormatArg(static_cast<int>(ch), fmt); }
- // 各种整数类型格式化
- inline void FormatArg(int i) { sDigitFormatArg(i); }
- //inline void FormatArg(long i) { sDigitFormatArg(i); }
- inline void FormatArg(short i) { sDigitFormatArg(i); }
- inline void FormatArg(unsigned int i) { uDigitFormatArg(i); }
- //inline void FormatArg(unsigned long i) { uDigitFormatArg(i); }
- inline void FormatArg(unsigned short i) { uDigitFormatArg(i); }
- // 整数带格式格式化
- inline void FormatArg(int i, const char* fmt) { DigitFormatArg(i, fmt); }
- inline void FormatArg(unsigned int i, const char* fmt) { DigitFormatArg(i, fmt); }
- //inline void FormatArg(long i, const char* fmt) { DigitFormatArg(i, fmt); }
- //inline void FormatArg(unsigned long i, const char* fmt) { DigitFormatArg(i, fmt); }
- inline void FormatArg(short i, const char* fmt) { DigitFormatArg(i, fmt); }
- inline void FormatArg(unsigned short i, const char* fmt) { DigitFormatArg(i, fmt); }
- // 64位整数格式化
- inline void FormatArg(int64_t i) { sDigitFormatArg(i); }
- inline void FormatArg(uint64_t i) { uDigitFormatArg(i); }
- inline void FormatArg(int64_t i, const char* fmt) { DigitFormatArg(i, fmt); }
- inline void FormatArg(uint64_t i, const char* fmt) { DigitFormatArg(i, fmt); }
- // 浮点数格式化(默认精度)
- inline void FormatArg(double i)
- {
- auto pT = static_cast<tDeriveClass*>(this);
- auto r = pT->_my_sprintf(m_Buffer, NbOfRemain(), "%f", i);
- m_Buffer += r;
- }
- // 浮点数带格式格式化(如F3 -> 保留3位小数)
- inline void FormatArg(double i, const char* fmt)
- {
- assert(fmt && fmt[0]);
- char tofmt[8] = { '%', '.', };
- auto chfmt = fmt[0];
- if (std::isdigit(fmt[1]))
- {
- int iFmtChar = 2;
- for (int Index = 1; Index <= 3; ++Index)
- {
- if (std::isdigit(fmt[Index]))
- {
- tofmt[Index + 1] = fmt[Index];
- iFmtChar = Index + 2;
- }
- else
- break;
- }
- tofmt[iFmtChar] = chfmt;
- }
- else
- {
- tofmt[1] = chfmt;
- tofmt[2] = 0;
- }
- auto pT = static_cast<tDeriveClass*>(this);
- auto r = pT->_my_sprintf(m_Buffer, NbOfRemain(), tofmt, i);
- m_Buffer += r;
- }
- // 浮点数(float)格式化
- inline void FormatArg(float f) { FormatArg(static_cast<double>(f)); }
- inline void FormatArg(float f, const char* fmt) { FormatArg(static_cast<double>(f), fmt); }
- // 字符串格式化(无格式)
- inline void FormatArg(const char* p)
- {
- if (!p)
- {
- std::memcpy(m_Buffer, __MsgOfNull_, __LenOfNull_);
- m_Buffer += __LenOfNull_;
- return;
- }
- int len = static_cast<int>(std::strlen(p));
- std::memcpy(m_Buffer, p, len);
- m_Buffer += len;
- }
- // 字符串带格式格式化(对齐处理)
- inline void FormatArg(const char* p, const char* fmt)
- {
- if (!p)
- {
- std::memcpy(m_Buffer, __MsgOfNull_, __LenOfNull_);
- m_Buffer += __LenOfNull_;
- return;
- }
- int len = static_cast<int>(std::strlen(p));
- _StringFormatArg(p, len, fmt);
- }
- inline void FormatArg(char* p) { FormatArg(static_cast<const char*>(p)); }
- inline void FormatArg(char* p, const char* fmt) { FormatArg(static_cast<const char*>(p), fmt); }
- // 字符串格式处理实现(对齐)
- inline void _StringFormatArg(const char* p, int len, const char* fmt)
- {
- if (!p)
- {
- std::memcpy(m_Buffer, __MsgOfNull_, __LenOfNull_);
- m_Buffer += __LenOfNull_;
- return;
- }
- if (fmt[0] == '-') // 左对齐
- {
- fmt++;
- auto i = std::atoi(fmt);
- if (i > len)
- {
- std::memcpy(m_Buffer, p, len);
- m_Buffer += len;
- std::memset(m_Buffer, ' ', i - len);
- m_Buffer += i - len;
- }
- else
- {
- std::memcpy(m_Buffer, p, len);
- m_Buffer += len;
- }
- }
- else // 右对齐
- {
- if (fmt[0] == '+') fmt++;
- auto i = std::atoi(fmt);
- if (i > len)
- {
- std::memset(m_Buffer, ' ', i - len);
- m_Buffer += i - len;
- std::memcpy(m_Buffer, p, len);
- m_Buffer += len;
- }
- else
- {
- std::memcpy(m_Buffer, p, len);
- m_Buffer += len;
- }
- }
- }
- // bool类型格式化
- void FormatArg(bool b)
- {
- if (b)
- {
- *m_Buffer++ = 't';
- *m_Buffer++ = 'r';
- *m_Buffer++ = 'u';
- *m_Buffer++ = 'e';
- }
- else
- {
- *m_Buffer++ = 'f';
- *m_Buffer++ = 'a';
- *m_Buffer++ = 'l';
- *m_Buffer++ = 's';
- *m_Buffer++ = 'e';
- }
- }
- // 指针类型格式化
- template <typename UNP>
- inline void FormatArg(const UNP* ptr)
- {
- auto pT = static_cast<tDeriveClass*>(this);
- auto r = pT->_my_sprintf(m_Buffer, NbOfRemain(), "%p", ptr);
- m_Buffer += r;
- }
- // 指针带格式格式化(按整数处理)
- template <typename UNP>
- inline void FormatArg(const UNP* ptr, const char* fmt)
- {
- DigitFormatArg(static_cast<uintptr_t>(ptr), fmt);
- }
- // 非const指针格式化
- template <typename UNP>
- inline void FormatArg(UNP* ptr)
- {
- auto pT = static_cast<tDeriveClass*>(this);
- auto r = pT->_my_sprintf(m_Buffer, NbOfRemain(), "%p", ptr);
- m_Buffer += r;
- }
- // 非const指针带格式格式化
- template <typename UNP>
- inline void FormatArg(UNP* ptr, const char* fmt)
- {
- DigitFormatArg(static_cast<uintptr_t>(ptr), fmt);
- }
- protected:
- // string_view格式化
- inline void FormatArg(const std::string_view& s)
- {
- std::memcpy(m_Buffer, s.data(), s.size());
- m_Buffer += s.size();
- }
- inline void FormatArg(const std::string_view& s, const char* fmt)
- {
- _StringFormatArg(s.data(), static_cast<int>(s.size()), fmt);
- }
- // wstring_view格式化(Linux下宽字符转多字节)
- inline void FormatArg(const std::wstring_view& s)
- {
- std::wstring_convert<std::codecvt<wchar_t, char, std::mbstate_t>> converter;
- auto str = converter.to_bytes(s.data(), s.data() + s.size());
- FormatArg(str);
- }
- inline void FormatArg(const std::wstring_view& s, const char* fmt)
- {
- std::wstring_convert<std::codecvt<wchar_t, char, std::mbstate_t>> converter;
- auto str = converter.to_bytes(s.data(), s.data() + s.size());
- FormatArg(str, fmt);
- }
- #ifdef __Utility_String_StringView__
- inline void FormatArg(const DStringView& s)
- {
- std::memcpy(m_Buffer, s.constBuffer(), s.Length());
- m_Buffer += s.Length();
- }
- inline void FormatArg(const DStringView& s, const char* fmt)
- {
- _StringFormatArg(s.constBuffer(), s.Length(), fmt);
- }
- #endif
- #ifdef DSTRING_API
- inline void FormatArg(const DString& s)
- {
- std::memcpy(m_Buffer, s.constBuffer(), s.GetLength());
- m_Buffer += s.GetLength();
- }
- inline void FormatArg(const DString& s, const char* fmt)
- {
- _StringFormatArg(s.constBuffer(), s.GetLength(), fmt);
- }
- #endif
- // std::string格式化
- inline void FormatArg(const std::string& s)
- {
- std::memcpy(m_Buffer, s.data(), s.size());
- m_Buffer += s.size();
- }
- inline void FormatArg(const std::string& s, const char* fmt)
- {
- _StringFormatArg(s.data(), static_cast<int>(s.size()), fmt);
- }
- #ifdef WSTRING_API
- inline void FormatArg(const wchar_t* p)
- {
- if (!p)
- {
- std::memcpy(m_Buffer, __MsgOfNull_, __LenOfNull_);
- m_Buffer += __LenOfNull_;
- return;
- }
- auto dp = WString(WStringView(p)).ToDString();
- FormatArg(dp);
- }
- inline void FormatArg(const wchar_t* p, const char* fmt)
- {
- if (!p)
- {
- std::memcpy(m_Buffer, __MsgOfNull_, __LenOfNull_);
- m_Buffer += __LenOfNull_;
- return;
- }
- auto dp = WString(WStringView(p)).ToDString();
- FormatArg(dp, fmt);
- }
- inline void FormatArg(const WString& s)
- {
- auto dp = s.ToDString();
- FormatArg(dp);
- }
- inline void FormatArg(const WString& s, const char* fmt)
- {
- auto dp = s.ToDString();
- FormatArg(dp, fmt);
- }
- inline void FormatArg(const std::wstring& s)
- {
- auto dp = WString(s.c_str()).ToDString();
- FormatArg(dp);
- }
- inline void FormatArg(const std::wstring& s, const char* fmt)
- {
- auto dp = WString(s.c_str()).ToDString();
- FormatArg(dp, fmt);
- }
- inline void FormatArg(const WStringView& ws)
- {
- auto ds = WString(ws).ToDString();
- FormatArg(ds);
- }
- inline void FormatArg(const WStringView& ws, const char* fmt)
- {
- auto ds = WString(ws).ToDString();
- FormatArg(ds, fmt);
- }
- #endif
- #if 1
- template <typename TO>
- inline void FormatArg(const TO& _val)
- {
- auto dp = ZSKK::Utility::String::ToString<TO>(_val);
- FormatArg(dp);
- }
- template <typename TO>
- inline void FormatArg(const TO& _val, const char* fmt)
- {
- auto dp = ZSKK::Utility::String::ToString<TO>(_val);
- FormatArg(dp, fmt);
- }
- #endif
- protected:
- // 元组参数索引访问(无格式)
- template <size_t k, typename Tuple>
- typename std::enable_if<(k == std::tuple_size<Tuple>::value)>::type
- inline GetArgByIndex(size_t, Tuple&)
- {
- #ifdef _DEBUG
- // throw std::invalid_argument("arg index out of range");
- #endif
- }
- template <size_t k = 0, typename Tuple>
- typename std::enable_if<(k < std::tuple_size<Tuple>::value)>::type
- inline GetArgByIndex(size_t index, Tuple& tp)
- {
- if (k == index)
- {
- FormatArg(std::get<k>(tp));
- }
- else
- {
- GetArgByIndex<k + 1>(index, tp);
- }
- }
- // 元组参数索引访问(带格式)
- template <size_t k, typename Tuple>
- typename std::enable_if<(k == std::tuple_size<Tuple>::value)>::type
- inline GetArgByIndex(size_t, Tuple&, const char* fmt)
- {
- #ifdef _DEBUG
- // throw std::invalid_argument("arg index out of range");
- #endif
- }
- template <size_t k = 0, typename Tuple>
- typename std::enable_if<(k < std::tuple_size<Tuple>::value)>::type
- inline GetArgByIndex(size_t index, Tuple& tp, const char* fmt)
- {
- if (k == index)
- {
- FormatArg(std::get<k>(tp), fmt);
- }
- else
- {
- GetArgByIndex<k + 1>(index, tp, fmt);
- }
- }
- // 格式解析辅助函数:查找$符号
- static inline const char* FirstDollar(const char*& p)
- {
- while (*p != '}' && *p != '\0')
- {
- if ('$' == (*p))
- return p;
- p++;
- }
- return nullptr;
- }
- // 格式解析辅助函数:查找数字
- static inline const char* FirstDigit(const char*& p)
- {
- while (*p != '}' && *p != '\0')
- {
- if (std::isdigit(*p))
- return p;
- p++;
- }
- return nullptr;
- }
- // 格式解析辅助函数:查找最后一个数字
- static inline const char* LastDigit(const char*& p)
- {
- while (*p != '}' && *p != '\0')
- {
- if (!std::isdigit(*p))
- return p - 1;
- p++;
- }
- return p - 1;
- }
- // 格式解析辅助函数:查找冒号
- static inline const char* FindColon(const char*& p)
- {
- while (*p != '}' && *p != '\0')
- {
- if (*p == ':')
- return p;
- p++;
- }
- return nullptr;
- }
- // 格式解析辅助函数:查找右括号
- static inline const char* FindRightBrace(const char*& p)
- {
- while (*p != '\0')
- {
- if (*p == '}')
- return p;
- p++;
- }
- return nullptr;
- }
- // 解析参数索引
- static inline int GetIndex(const char*& p, const char*& fmt, int prevIndex)
- {
- auto bp = p; // 备份当前位置
- auto pDollar = FirstDollar(p);
- if (pDollar)
- {
- auto pc = FindColon(p);
- auto _ = FindRightBrace(p);
- if (pc)
- fmt = pc + 1;
- return prevIndex + 1;
- }
- p = bp;
- auto pd = FirstDigit(p);
- auto pl = LastDigit(p);
- auto pc = FindColon(p);
- auto _ = FindRightBrace(p);
- if (!pd) return -1;
- auto ii = pl + 1 - pd;
- assert(ii <= 2);
- if (ii <= 0) return -1;
- char temp[3] = {};
- temp[0] = *pd; pd++;
- temp[1] = *pd;
- auto index = std::atoi(temp);
- if (pc)
- fmt = pc + 1;
- return index;
- }
- public:
- // 格式化入口(const char*)
- template <typename... Args>
- inline int Format(const char* fmt, Args&&... args)
- {
- int fmtlen = static_cast<int>(std::strlen(fmt));
- return DoFormat(fmtlen, fmt, std::forward<Args>(args)...);
- }
- #ifdef __Utility_String_StringView__
- // 格式化入口(DStringView)
- template <typename... Args>
- inline int Format(const eSTR::StringView& fmt, Args&&... args)
- {
- int fmtlen = fmt.GetLength();
- return DoFormat(fmtlen, fmt, std::forward<Args>(args)...);
- }
- #endif
- // 格式化入口(std::string_view)
- template <typename... Args>
- inline int Format(const std::string_view& fmt, Args&&... args)
- {
- int fmtlen = static_cast<int>(fmt.size());
- return DoFormat(fmtlen, fmt, std::forward<Args>(args)...);
- }
- protected:
- // 格式化实现(const char*)
- template <typename... Args>
- inline int DoFormat(int fmtlen, const char* fmt, Args&&... args)
- {
- assert(fmt);
- if (!fmt)
- {
- m_Buffer[0] = 0;
- return 0;
- }
- if (sizeof...(args) == 0)
- {
- std::strcpy(m_Buffer, fmt);
- return fmtlen;
- }
- auto tp = std::tuple<Args...>(std::forward<Args>(args)...);
- return DoFormat(fmtlen, fmt, std::move(tp));
- }
- // 格式化实现(元组参数)
- template <typename... Args>
- inline int DoFormat(int fmtlen, const char* fmt, std::tuple<Args...>&& tp)
- {
- assert(fmt);
- if (!fmt)
- {
- m_Buffer[0] = 0;
- return 0;
- }
- m_Buffer = m_BufferOrg;
- const char* p = fmt;
- const char* original = p;
- int last = 0;
- int Index = -1;
- while (true)
- {
- if (*p == '{')
- {
- // 复制{之前的内容
- last = static_cast<int>(p - original);
- if (last)
- {
- std::memcpy(m_Buffer, original, last);
- m_Buffer += last;
- }
- // 解析参数索引和格式
- const char* tmpfmt = nullptr;
- Index = GetIndex(p, tmpfmt, Index);
- if (Index >= 0)
- {
- if (tmpfmt)
- GetArgByIndex<0>(Index, tp, tmpfmt);
- else
- GetArgByIndex<0>(Index, tp);
- }
- // 跳过}
- original = p + 1;
- }
- else if (*p == '\0')
- {
- // 复制剩余内容
- last = static_cast<int>(p - original);
- if (last == 0)
- *m_Buffer = 0;
- else
- {
- std::memcpy(m_Buffer, original, last + 1); // 包含终止符
- m_Buffer += last;
- }
- break;
- }
- p++;
- }
- auto delta = m_Buffer - m_BufferOrg;
- #ifdef _DEBUG
- int len = static_cast<int>(std::strlen(m_BufferOrg));
- assert((delta - len) == 0);
- #endif
- return static_cast<int>(delta);
- }
- };
- // 字符串格式化实现类(替换Windows的sprintf_s为Linux的snprintf)
- class StringFormat : public _string_format_detail<StringFormat>
- {
- public:
- inline StringFormat(char* buf, int NbOfChar) : _string_format_detail(buf, NbOfChar) {}
- public:
- template <typename arg>
- inline int _my_sprintf(char* buf, int NbOfChar, const char* fmt, arg a)
- {
- // Linux下用snprintf替换Windows的sprintf_s
- return std::snprintf(buf, NbOfChar, fmt, a);
- }
- };
- }
- //-----------------------------------------------------------------------------
- // 设计说明 (2021-06-18):
- // 1. 为什么只能支持 3 个数字 (即 最大只能是 {$:d999} 或 {$:f999})
- // 1) 预留的 Buffer 一般大小是 8192, 见 DString::Format 及 TLSLog
- // 2) 最终会调用 snprintf (buffer, len, ...)
- // 3) 当 buffer 不足时, 上述函数会截断输出, 避免程序崩溃
- //-----------------------------------------------------------------------------
- //-----------------------------------------------------------------------------
- // 自定义类型的格式化 (2023-05-15)
- /*
- class TestMyClass
- {
- public:
- TestMyClass() = default;
- };
- namespace ZSKK::Utility::String
- {
- template <> inline std::string ToString(const TestMyClass& value)
- {
- return std::string("it is TestMyClass !");
- }
- }
- */
- // assert(eSTR::DString::FromFormat("{$}{$}-{$}"_sv, 11, 22, TestMyClass()) == eSTR::DString("1122-it is TestMyClass !"));
- //-----------------------------------------------------------------------------
|