123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744 |
- #pragma once
- #include <stdlib.h>
- #include <string>
- #include <functional>
- #include <list>
- #include <vector>
- #include "String.StringView.hpp"
- #ifdef DSTRING_EXPORTS
- #define DSTRING_API _declspec(dllexport)
- #else
- #define DSTRING_API _declspec(dllimport)
- #endif
- #ifdef _DSTRING_STATIC_
- #undef DSTRING_API
- #define DSTRING_API
- #endif
- #ifndef DSTRING_EXPORTS
- #ifdef _WIN64
- #ifdef _DEBUG
- #pragma comment (lib, "ECOM.Utility.DString64D.lib")
- #else
- #pragma comment (lib, "ECOM.Utility.DString64.lib")
- #endif
- #else // X86
- #endif
- #endif // DSTRING_EXPORTS
- namespace ECOM::Utility::String
- {
- class WString;
- // using size_type = unsigned int; // 用 unsigned int 比较好, 但是会造成很多编译警告
- using size_type = int;
- //-----------------------------------------------------------------------------
- // DStringData
- //-----------------------------------------------------------------------------
- namespace
- {
- struct DStringData
- {
- long nRefs; // reference count
- size_type nDataLength; // length of data (including terminator)
- size_type nAllocLength; // length of allocation
- // char data[nAllocLength]
- char * data () // char* to managed data
- {
- return (char *) (this + 1);
- }
- };
- }
- //-----------------------------------------------------------------------------
- // DString
- //-----------------------------------------------------------------------------
- class DSTRING_API DString
- {
- public:
- using value_type = DString;
- using reference = value_type &;
- using const_reference = const value_type &;
- public:
- // Constructors
- DString ();
- // DString (const char * lpsz);
- DString (const char * lpsz, int nLength);
- // DString (const unsigned char * lpsz) { Init(); *this = (const char *) lpsz; }
- // std::string 支持 std::string (char * p), 即支持隐式从 char * 构造,
- // 因此这里变成显示的构造, 以避免 DString (const char *) 的默认构造
- explicit DString (const std::string & Src);
- DString (const DString & Src);
- DString (DString && Src);
- public:
- ~DString ();
- public:
- // get data length
- size_type GetLength () const;
- size_type GetByteLength () const { return GetLength (); }
- size_type GetAllocLength () const { return GetData ()->nAllocLength; }
- size_type size () const { return GetLength (); };
- public:
- bool empty () const { return IsEmpty (); }
- bool IsEmpty () const { return GetLength () <= 0; }
- void Clear ();
- void Release ();
- public:
- char GetAt (int nIndex) const
- {
- // ASSERT(nIndex >= 0);
- // ASSERT(nIndex < GetData()->nDataLength);
- return m_pchData [nIndex];
- }
- char operator [] (int nIndex) const { return GetAt (nIndex); }
- void SetAt (int nIndex, char ch);
- int Count (char ch) const;
- int Count (const StringView & Sub) const;
- public:
- DString & operator = (const char *) = delete;
- DString & operator = (const DString & S);
- DString & operator = (DString && S);
- DString & operator = (char ch);
- DString & operator = (const std::string & S) { AssignCopy (static_cast <int> (S.size ()), S.c_str ()); return (*this); }
- DString & operator = (const StringView & S) { return Assign (S); }
- DString & operator = (std::initializer_list <StringView> lst) { return Assign (lst); }
- DString & operator = (std::initializer_list <const char *> lst) { return Assign (lst); }
- public:
- //< 这些函数被声明为废除, 避免误写误用. 如果不废除, 编译器将认为/转化为 Append (char)
- // 当然可以设计成自动转换 { return Append (From (v)); }
- // 但是万一用户真是写错了, 自动转换就变成帮倒忙了
- // 2022-12-26
- DString & Append (const char * v) = delete; // 改用 "..."_sv 代替
- DString & Append (int v) = delete;
- DString & Append (unsigned int v) = delete;
- DString & Append (short v) = delete;
- DString & Append (unsigned short v) = delete;
- DString & Append (long v) = delete;
- DString & Append (unsigned long v) = delete;
- DString & Append (float v) = delete;
- DString & Append (double v) = delete;
- //>
- DString & Append (unsigned char ch)
- {
- return Append (static_cast <char> (ch));
- }
- DString & Append (char ch)
- {
- ConcatInPlace (1, &ch);
- return *this;
- }
- DString & Append (const DString & S)
- {
- ConcatInPlace (S.GetData ()->nDataLength, S.m_pchData);
- return *this;
- }
- DString & Append (const StringView & S);
- DString & Append (const std::string_view & S);
- DString & Append (const std::string & S)
- {
- ConcatInPlace (static_cast <int> (S.length ()), S.c_str());
- return *this;
- }
- // DString & operator += (const char * lpsz) = delete; // 改用 "..."_sv 代替
- DString & operator += (const DString & S) { return Append (S); }
- DString & operator += (char ch) { return Append (ch); }
- DString & operator += (const StringView & S) { return Append (S); }
- // DString & operator += (const std::string & S) { return Append (S); }
- DString & operator += (std::initializer_list <StringView> lst) { return Append (lst); }
- //< DString & operator << (const char * lpsz) = delete; // 改用 "..."_sv 代替
- // 不废除了, 某些强制赋值还是需要的.
- // 如果不做提前声明, 编译时发生 C2678: 无法找到匹配的运算符
- // 2023-11-14
- //>
- DString & operator << (const DString & S) { return Append (S); }
- DString & operator << (char ch) { return Append (ch); }
- DString & operator << (const StringView & S) { return Append (S); }
- DString & operator << (short v) { return Append (From (v)); }
- DString & operator << (int v) { return Append (From (v)); }
- DString & operator << (long v) { return Append (From (v)); }
- DString & operator << (UINT16 v) { return Append (From (v)); }
- DString & operator << (UINT32 v) { return Append (From (v)); }
- DString & operator << (unsigned long v) { return Append (From (v)); }
- // DString & operator << (const std::string & S) { return Append (S); }
- DString & operator << (std::initializer_list <StringView> lst) { return Append (lst); }
- public:
- int Compare (const char * With) const;
- int CompareNoCase (const char * With) const;
- int Compare (const DStringView & With) const;
- int Compare (const DString & With) const;
- //< 增加命名空间后, std::map <DString, ...> 就需要如下内置比较函数
- bool operator == (const DString & with) const { return Compare (with) == 0; }
- bool operator != (const DString & with) const { return Compare (with) != 0; }
- bool operator < (const DString & with) const { return Compare (with) < 0; }
- bool operator > (const DString & with) const { return Compare (with) > 0; }
- bool operator <= (const DString & with) const { return Compare (with) <= 0; }
- bool operator >= (const DString & with) const { return Compare (with) >= 0; }
- //>
- public:
- DString Mid (int nFirst, int nCount) const;
- DString Mid (int nFirst) const;
- DString Left (int nCount) const;
- DString Right (int nCount) const;
- // characters from beginning that are also in passed string
- DString SpanIncluding (const char * lpszCharSet) const;
- // characters from beginning that are not also in passed string
- DString SpanExcluding (const char * lpszCharSet) const;
- public:
- void MakeUpper ();
- void MakeLower ();
- void MakeReverse ();
- public:
- int TrimLeft (); // 返回去除的字符数
- int TrimRight (); // 返回去除的字符数
- void TrimLeft (char chTarget);
- void TrimLeft (const StringView & szTargets);
- void TrimRight (char chTarget);
- void TrimRight (const StringView & szTargets);
- DString Trim () const { DString copy = *this; copy.TrimRight (); copy.TrimLeft (); return copy; }
- public:
- // 用指定的字符填充左边/右边/中间, 直到总长度达到指定值为止
- void JustLeft (int ToLength, char ch = ' ');
- void JustRight (int ToLength, char ch = ' ');
- void JustCenter (int ToLength, char ch = ' ');
- public:
- int Replace (char chOld, char chNew);
- int Replace (const DString & Old, const StringView & New);
- int Replace (const StringView & Old, const StringView & New);
- int NCReplace (const StringView & Old, const StringView & New);
- int ReplaceTabs (int abstand);
- int Remove (const StringView & Sub);
- int Remove (char chRemove);
- int RemoveSpace ();
- int RemovePunctuation ();
- int RemoveControl ();
- // 用谓词函数来判断单个字符是否应该删除, 如果返回 true 就删除
- int Remove (std::function <bool (int)> pred);
- int NCRemove (const StringView & Sub);
- int NCRemove (char chRemove);
- public:
- int Insert (int nIndex, char ch);
- int Insert (int nIndex, const StringView & Sub);
- int Delete (int nIndex, int nCount = 1);
- void Repeat (char ch, int n);
- void Repeat (const StringView & S, int n);
- public:
- // Pred 返回 true, 表明找到, 否则下一个字符
- using tPred = std::function <bool (char ch)>;
- public:
- int Find (char ch, int nStart = 0) const;
- int Find (tPred && pred, int nStart = 0) const;
- int Find (const StringView & Sub, int nStart = 0) const;
- int Find (const DString & Sub, int nStart = 0) const;
- int ReverseFind (char ch, int nStart = 0) const;
- int ReverseFind (const StringView & Sub, int nStart = 0) const;
- bool StartWith (const StringView & Sub, int iStart = 0) const;
- bool EndWith (const StringView & Sub, int iStart = 0) const;
- bool StartWith (const DString & Sub, int iStart = 0) const { return StartWith (Sub.To <StringView> (), iStart); }
- bool EndWith (const DString & Sub, int iStart = 0) const { return EndWith (Sub.To <StringView> (), iStart); }
- bool StartWith (char ch, int iStart = 0) const;
- bool EndWith (char ch, int iStart = 0) const;
- int NCFind (char ch) const;
- int NCFind (const StringView & Sub) const;
- public:
- // start 是起始位置
- using tvCallback = std::function <void (CV_String & sub)>;
- // 如果回调返回 true, 则继续, 否则停止. Index=第几次回调
- using tbCallback = std::function <bool (int Index, CV_String & sub)>;
- int Split (char ch , tvCallback && onFound, int start = 0) const;
- int Split (tPred && pred, tvCallback && onFound, int start = 0) const;
- int SplitIf (char ch , tbCallback && onFound, int start = 0) const;
- int SplitIf (tPred && pred, tbCallback && onFound, int start = 0) const;
- // 分割成列表
- auto SplitTo (char ch , int start = 0) const -> std::list <DString>;
- auto SplitTo (tPred && pred, int start = 0) const -> std::list <DString>;
- // 分割成数组, 最多 Max 个
- auto SplitMax (int Max, char ch , int start = 0) const -> std::vector <DString>;
- auto SplitMax (int Max, tPred && pred, int start = 0) const -> std::vector <DString>;
- // 返回指定 Index 的某一个, 如果找不到: 当 Index=0 时返回本串, 否则返回空串
- auto SplitOne (int atIndex, char ch , int start = 0) const -> DString;
- auto SplitOne (int atIndex, tPred && pred, int start = 0) const -> DString;
- // Cast
- public:
- // return pointer to const string
- operator const char * () const { return m_pchData; }
- const char * constBuffer () const { return m_pchData; }
- char * data () const { return m_pchData; }
- const char * c_str () const { return m_pchData; }
- operator bool () const = delete;
- // 用于自动判别类型
- public:
- template <typename T> bool Is () const { return false; }
- template <> bool Is <DString> () const { return true; }
- template <> bool Is <WString> () const { return false; }
- public:
- static DString From (const int i);
- static DString From (const long i);
- static DString From (const unsigned int u);
- static DString From (const unsigned long u);
- static DString From (const __int64 i);
- static DString From (const unsigned __int64 u);
- static DString From (const double d);
- static DString From (const std::string_view & Src);
- static DString From (CV_String & Src) { return DString (Src); }
- static DString From (const DString & Src) { return DString (Src); }
- // repeat a single character
- [[nodiscard]]
- static DString FromRepeat (char ch, int nRepeat);
- public: // 为了支持部分组件能与 8.0 一致, 加入如下功能
- template <typename... Args>
- [[nodiscard]]
- static inline DString FromFormat (const StringView & szFormat, Args && ... args);
- template <typename... Args>
- inline void Format (const StringView & szFormat, Args && ... args);
- // append with the formatted string
- template <typename... Args>
- void AppendFormat (const StringView & szFormat, Args && ... args);
- [[nodiscard]]
- static DString FromErrorCode (DWORD errorCode); // 通过调用 FormtMessage, 把 Win32 错误码转换成字符串
- public:
- // Access to string implementation buffer as "C" character array
- // get pointer to modifiable buffer at least as long as nMinBufLength
- char * GetBuffer (int nMinBufLength);
- // release buffer, setting length to nNewLength (or to first nul if -1)
- void ReleaseBuffer (int nNewLength = -1);
- // get pointer to modifiable buffer exactly as long as nNewLength
- char * GetBufferSetLength (int nNewLength);
- void Reserve (int nMinBufLength) { GetBuffer (nMinBufLength); }
- void reserve (int nMinBufLength) { GetBuffer (nMinBufLength); }
-
- public:
- // 转换函数
- double Double () const { return atof (m_pchData); }
- int Int () const { int i = atoi (m_pchData); if (i) return i; return strtol (m_pchData, nullptr, 16); }
- long Long () const { long l = atol (m_pchData); if (l) return l; return strtol (m_pchData, nullptr, 16); }
- char Char () const { return m_pchData[0]; }
- bool Bool () const;
- __int64 Int64 () const { __int64 i = _atoi64 (m_pchData); if (i) return i; return _strtoi64 (m_pchData, nullptr, 16); }
- template <typename T> T To () const = delete;
- template <> int To () const { return Int (); }
- template <> double To () const { return Double (); }
- template <> float To () const { return (float) Double (); }
- template <> long To () const { return Long (); }
- template <> bool To () const { return Bool (); }
- template <> __int64 To () const { return Int64 (); }
- template <> unsigned int To () const { return Int (); }
- template <> unsigned __int64 To () const { return Int64 (); }
- template <> unsigned long To () const { return Long (); }
- template <> DString To () const { return *this; }
- template <> std::string To () const { return std::string { m_pchData, static_cast <std::string::size_type> (GetLength ())}; }
- template <> std::string_view To () const { return std::string_view { m_pchData, static_cast <std::string_view::size_type> (GetLength ()) }; }
- public: // 与 StringView 的转换,构造,赋值等
- DString (const StringView & Src);
- //DString (const std::string_view & Src); // 不能定义这个构造函数, 否则, 编译 eSTR::DString Path (szPath) 时, 编译器会发生警告: 重载函数的调用不明确
- public:
- operator StringView () const noexcept;
- operator std::string_view () const noexcept;
- // ? 不能定义这个强制转换函数, 否则, 编译 Hash (DString) 时, 编译器会发生警告: 重载函数的调用不明确
- public:
- template <> StringView To () const;
- template <> const StringView To () const;
- DString & Assign (const StringView & _Right);
- DString & Assign (const std::string_view & _Right);
- DString & Append (std::initializer_list <StringView> lst);
- DString & Append (std::initializer_list <std::string_view> lst);
- DString & Append (std::initializer_list <const char *> lst);
- DString & Assign (std::initializer_list <StringView> lst);
- DString & Assign (std::initializer_list <std::string_view> lst);
- DString & Assign (std::initializer_list <const char *> lst);
- // 万一编译器警告: 调用不明确, 就用模板函数显式告诉编译器
- template <typename T> static DString From (std::initializer_list <T> lst) { DString rc; rc.Assign (lst); return rc; }
- static DString From (std::initializer_list <StringView> lst) { DString rc; rc.Assign (lst); return rc; }
- static DString From (std::initializer_list <std::string_view> lst) { DString rc; rc.Assign (lst); return rc; }
- static DString From (std::initializer_list <const char *> lst) { DString rc; rc.Assign (lst); return rc; }
- public:
- // 判断整个字符串是否是某一类字符组成
- bool IsDigit () const;
- bool IsAlNum () const;
- bool IsAlpha () const;
- bool IsUpper () const;
- bool IsLower () const;
- bool IsSpace () const;
- // 判断某个字符是否是某一类字符组成
- bool IsDigit (int nPos) const;
- bool IsAlNum (int nPos) const;
- bool IsAlpha (int nPos) const;
- bool IsUpper (int nPos) const;
- bool IsLower (int nPos) const;
- bool IsSpace (int nPos) const;
- public:
- bool ToCharacterSet (unsigned int CodePage);
- bool FromCharacterSet (unsigned int CodePage);
- public:
- // release memory allocated to but unused by string
- void FreeExtra ();
- protected:
- char * m_pchData; // pointer to ref counted string data
- // implementation helpers
- DStringData * GetData () const
- {
- return ((DStringData *) m_pchData)-1;
- }
- bool IsNil () const; // 用来判断 m_pchData 是否等于 DStringPchNil
- void Init ();
- void AllocCopy (DString & dest, int nCopyLen, int nCopyIndex, int nExtraLen) const;
- void AllocBuffer (int nLen);
- void AssignCopy (int Len, const char * S);
- void ConcatCopy (int L1, const char * S1, int L2, const char * S2);
- void ConcatInPlace (int Len, const char * S);
- void CopyBeforeWrite ();
- void AllocBeforeWrite (int nLen);
- DString & Assign (const DString & Src); // 拷贝赋值
- void MoveAssign (DString & Src);
- void MoveAssign (DString && Src);
- protected:
- static void Release (DStringData * pData);
- static void FreeData (DStringData * pData);
- //-----------------------------------------------------------------------------
- // Token类用来对字符串进行标识符切分
- //-----------------------------------------------------------------------------
- public:
- class DSTRING_API Token
- {
- public:
- Token (const DString & str, bool bSkipPunctuation = false) :
- m_Str (str),
- m_bSkipPunctuation (bSkipPunctuation)
- {
- // 在Restart之前先初始化这个变量,因为Restart之后需要立即调用Next,
- // 而Next函数需要这个变量
- Restart ();
- }
- public:
- operator bool () const { return m_bContinue; };
- operator DString () const { return Current (); };
- public:
- // 定位到下一个标识符
- bool Next (void);
- // 定位到下一个标识符,但是以出作为分割符
- bool Next (char sep);
- // 定位到行尾,Current返回直到行尾的所有字符,但是不包括行尾的回车或换行
- bool NextLine (void);
- DString Current (void) const; // 获得当前标识符,或者当前行
- bool IsValid () const { return (m_nL <= m_nR); };
- void Clear (void)
- {
- m_nL = 0;
- m_nR = -1;
- m_nNext = 0;
- m_bContinue = true;
- m_nStrLength = 0;
- }
- void Restart (void) // 重新开始
- {
- m_szDoc = m_Str;
- Clear ();
- m_nStrLength = (int) strlen (m_szDoc);
- Next ();
- }
- bool SkipPunctuation (bool bSkipPunctuation)
- {
- bool tmp = m_bSkipPunctuation;
- m_bSkipPunctuation =bSkipPunctuation;
- return tmp;
- }
- void operator ++ () // ++Token; prevfix
- {
- Next ();
- }
- void operator ++ (int) // Token++; postfix
- {
- Next ();
- }
- DString operator () (void) const
- {
- return Current ();
- }
- protected:
- int FindWhitespace (int nChar) const; // 从nChar开始,定位到下一个非空字符,并返回这个位置的索引,如果找不到,返回-1
- int FindChar (int nChar, char ch) const; // 从nChar开始,在字符串中寻找与ch相同的下一个ch,并返回这个位置的索引,如果找不到,返回-1
- protected:
- const DString & m_Str;
- const char * m_szDoc;
- int m_nL; // 当前标识符的左边界
- int m_nR; // 当前标识符的右边界
- int m_nNext; // 下一个标识符的初始位置
- bool m_bContinue; // 可用继续迭代吗?
- int m_nStrLength; // 字符串长度;
- bool m_bSkipPunctuation; // Next()时跳过标点符号,即Current()不会返回遇到的标点符号
- };
- };
- }
- namespace eSTR = ECOM::Utility::String;
- DSTRING_API eSTR::DString operator + (const eSTR::DString & S1, const eSTR::DString & S2);
- DSTRING_API eSTR::DString operator + (const eSTR::DString & S, char ch);
- DSTRING_API eSTR::DString operator + (const eSTR::DString & S1, const eSTR::StringView & S2);
- DSTRING_API eSTR::DString operator + (const eSTR::StringView & S1, const eSTR::DString & S2);
- DSTRING_API eSTR::DString operator + (const eSTR::StringView & S1, char ch);
- DSTRING_API eSTR::DString operator + (char ch, const eSTR::DString & S);
- DSTRING_API eSTR::DString operator + (const eSTR::DString & S1, const std::string_view & S2);
- DSTRING_API eSTR::DString operator + (const std::string_view & S1, const eSTR::DString & S2);
- DSTRING_API eSTR::DString operator + (const std::string_view & S1, char ch);
- DSTRING_API eSTR::DString operator + (const eSTR::DString & S1, const std::string & S2);
- DSTRING_API eSTR::DString operator + (const std::string & S1, const eSTR::DString & S2);
- DSTRING_API eSTR::DString operator + (const eSTR::StringView & S1, const eSTR::StringView & S2);
- // Compare helpers
- #if 0 // 如下比较重载将导致编译器无法选择, 因此注释掉
- DSTRING_API inline bool operator == (const eSTR::DString & s1, const eSTR::DString & s2) { return s1.Compare (s2) == 0; }
- DSTRING_API inline bool operator != (const eSTR::DString & s1, const eSTR::DString & s2) { return s1.Compare (s2) != 0; }
- DSTRING_API inline bool operator < (const eSTR::DString & s1, const eSTR::DString & s2) { return s1.Compare (s2) < 0; }
- DSTRING_API inline bool operator > (const eSTR::DString & s1, const eSTR::DString & s2) { return s1.Compare (s2) > 0; }
- DSTRING_API inline bool operator <= (const eSTR::DString & s1, const eSTR::DString & s2) { return s1.Compare (s2) <= 0; }
- DSTRING_API inline bool operator >= (const eSTR::DString & s1, const eSTR::DString & s2) { return s1.Compare (s2) >= 0; }
- #endif
- DSTRING_API inline bool operator == (const eSTR::DString & s1, const eSTR::StringView s2) { return s1.Compare (s2) == 0; }
- DSTRING_API inline bool operator != (const eSTR::DString & s1, const eSTR::StringView s2) { return s1.Compare (s2) != 0; }
- DSTRING_API inline bool operator < (const eSTR::DString & s1, const eSTR::StringView s2) { return s1.Compare (s2) < 0; }
- DSTRING_API inline bool operator > (const eSTR::DString & s1, const eSTR::StringView s2) { return s1.Compare (s2) > 0; }
- DSTRING_API inline bool operator <= (const eSTR::DString & s1, const eSTR::StringView s2) { return s1.Compare (s2) <= 0; }
- DSTRING_API inline bool operator >= (const eSTR::DString & s1, const eSTR::StringView s2) { return s1.Compare (s2) >= 0; }
- #if 1
- inline bool operator == (const eSTR::DString & s1, const char * s2) = delete;
- inline bool operator != (const eSTR::DString & s1, const char * s2) = delete;
- inline bool operator < (const eSTR::DString & s1, const char * s2) = delete;
- inline bool operator > (const eSTR::DString & s1, const char * s2) = delete;
- inline bool operator <= (const eSTR::DString & s1, const char * s2) = delete;
- inline bool operator >= (const eSTR::DString & s1, const char * s2) = delete;
- #else
- DSTRING_API inline bool operator == (const eSTR::DString & s1, const char * s2) { return s1.Compare (s2) == 0; }
- DSTRING_API inline bool operator != (const eSTR::DString & s1, const char * s2) { return s1.Compare (s2) != 0; }
- DSTRING_API inline bool operator < (const eSTR::DString & s1, const char * s2) { return s1.Compare (s2) < 0; }
- DSTRING_API inline bool operator > (const eSTR::DString & s1, const char * s2) { return s1.Compare (s2) > 0; }
- DSTRING_API inline bool operator <= (const eSTR::DString & s1, const char * s2) { return s1.Compare (s2) <= 0; }
- DSTRING_API inline bool operator >= (const eSTR::DString & s1, const char * s2) { return s1.Compare (s2) >= 0; }
- #endif
- DSTRING_API inline bool operator == (const eSTR::StringView & s1, const eSTR::DString & s2) { return s2.Compare (s1) == 0; }
- DSTRING_API inline bool operator != (const eSTR::StringView & s1, const eSTR::DString & s2) { return s2.Compare (s1) != 0; }
- DSTRING_API inline bool operator < (const eSTR::StringView & s1, const eSTR::DString & s2) { return s2.Compare (s1) > 0; }
- DSTRING_API inline bool operator > (const eSTR::StringView & s1, const eSTR::DString & s2) { return s2.Compare (s1) < 0; }
- DSTRING_API inline bool operator <= (const eSTR::StringView & s1, const eSTR::DString & s2) { return s2.Compare (s1) >= 0; }
- DSTRING_API inline bool operator >= (const eSTR::StringView & s1, const eSTR::DString & s2) { return s2.Compare (s1) <= 0; }
- #if 1
- inline bool operator == (const char * s1, const eSTR::DString & s2) = delete;
- inline bool operator != (const char * s1, const eSTR::DString & s2) = delete;
- inline bool operator < (const char * s1, const eSTR::DString & s2) = delete;
- inline bool operator > (const char * s1, const eSTR::DString & s2) = delete;
- inline bool operator <= (const char * s1, const eSTR::DString & s2) = delete;
- inline bool operator >= (const char * s1, const eSTR::DString & s2) = delete;
- #else
- DSTRING_API inline bool operator == (const char * s1, const eSTR::DString & s2) { return s2.Compare (s1) == 0; }
- DSTRING_API inline bool operator != (const char * s1, const eSTR::DString & s2) { return s2.Compare (s1) != 0; }
- DSTRING_API inline bool operator < (const char * s1, const eSTR::DString & s2) { return s2.Compare (s1) > 0; }
- DSTRING_API inline bool operator > (const char * s1, const eSTR::DString & s2) { return s2.Compare (s1) < 0; }
- DSTRING_API inline bool operator <= (const char * s1, const eSTR::DString & s2) { return s2.Compare (s1) >= 0; }
- DSTRING_API inline bool operator >= (const char * s1, const eSTR::DString & s2) { return s2.Compare (s1) <= 0; }
- #endif
- #include "String.Format.tlh"
- template <typename... Args>
- inline void eSTR::DString::Format (const StringView & szFormat, Args && ... args)
- {
- char * DString_TLSBuffer_Get ();
- int DString_TLSBuffer_Size ();
- auto pb = DString_TLSBuffer_Get ();
- auto sz = DString_TLSBuffer_Size ();
- if (! pb)
- {
- this->Init ();
- return;
- }
- auto len = StringFormat (pb, sz).Format (szFormat, std::forward <Args> (args)...);
- auto pc = GetBufferSetLength (len);
- memcpy_s (pc, len, pb, len);
- }
- template <typename... Args>
- static inline eSTR::DString eSTR::DString::FromFormat (const StringView & szFormat, Args && ... args)
- {
- DString rc;
- rc.Format (szFormat, std::forward <Args> (args)...);
- return std::move (rc);
- }
- template <typename... Args>
- inline void eSTR::DString::AppendFormat (const StringView & szFormat, Args && ... args)
- {
- DString rc;
- rc.Format (szFormat, std::forward <Args> (args)...);
- Append (rc);
- }
- template <>
- struct std::hash <eSTR::DString>
- {
- size_t operator() (const char * pc) const noexcept
- {
- auto len = strlen (pc);
- return std::_Hash_array_representation (pc, len);
- }
- size_t operator () (const eSTR::DString & from) const noexcept
- {
- auto pc = from.constBuffer ();
- auto len = from.GetLength ();
- return std::_Hash_array_representation (pc, len);
- }
- };
- #include "Hash.String.hpp"
- //< 针对 DString 的 Hash. 目的是避免编译器的错误: 重载函数调用不明确
- namespace ECOM::Utility
- {
- inline constexpr size_t Hash (const String::DString & SV)
- {
- return (Hash (SV.To <String::DStringView> ()));
- }
- }
|