#pragma once #include #include #include "TypeDefine.h" /** * CList 遍历宏 * * \list CList 链表 * \pos POSITION 变量,元素的位置,要取对应的请使用 list.GetAt(pos) */ #define CListForEach(pos, list) \ for (POSITION pos = (list).GetHeadPosition(); pos != nullptr; (list).GetNext(pos)) /** * \brief 检查一个CString是否以给定的前缀开头 * \param str 要检查的CString * \param prefix 前缀字符串 * \return 如果CString以前缀开头,则返回true;否则返回false */ inline bool StartsWith(const CString& str, const TCHAR *prefix) { assert(prefix != nullptr); size_t prefixLength = _tcslen(prefix); if (str.GetLength() < prefixLength) { return false; } return _tcsncmp(str.GetString(), prefix, prefixLength) == 0; } /** * \brief 检查一个CString是否以另一个CString作为前缀开头 * \param str 要检查的CString * \param prefix 前缀CString * \return 如果CString以前缀开头,则返回true;否则返回false */ inline bool StartsWith(const CString& str, const CString &prefix) { if (str.GetLength() < prefix.GetLength()) { return false; } return _tcsncmp(str.GetString(), prefix.GetString(), prefix.GetLength()) == 0; } /** * \brief 检查一个CString是否以另一个CString作为后缀结尾 * \param str 要检查的CString * \param suffix 后缀CString * \return 如果CString以后缀结尾,则返回true;否则返回false */ inline bool EndsWith(const CString& str, const CString& suffix) { int strLength = str.GetLength(); int suffixLength = suffix.GetLength(); if (strLength < suffixLength) { return false; } return (str.Right(suffixLength) == suffix); } /** * \brief 将一个CString的向量用指定的分隔符连接起来 * \param strings 包含多个CString的向量 * \param delimiter 分隔符CString * \return 连接后的CString */ inline CString Join(const std::vector& strings, const CString& delimiter) { CString joinedString; for (int i = 0; i < strings.size(); i++) { joinedString += strings[i]; if (i != strings.size() - 1) joinedString += delimiter; } return joinedString; } /** * \brief 获取 path 的父路径 * * \param path * \return */ inline CString LayerParentPath(CString& path) { int pos = path.ReverseFind(_T('\\')); if (pos != -1) { return path.Left(pos); } return ""; } /** * \brief 判断两个路径父路径是否相同 * * \param path1 * \param path2 * \return */ inline bool IsSameParentPath(CString& path1, CString& path2) { CString parentPath1 = LayerParentPath(path1); CString parentPath2 = LayerParentPath(path2); return parentPath1.CompareNoCase(parentPath2) == 0; } /** * \brief 判断一个路径是否是另一个路径的下级(下下级...)路径 * * \param childPath 子路径 * \param parentPath 父级路径 * \return */ inline bool IsSubPath(const CString& childPath, const CString& parentPath) { if (EndsWith(parentPath, _T("\\"))) { return StartsWith(childPath, parentPath); } return StartsWith(childPath, parentPath + _T("\\")); } inline void MarkSectionBegin(CArchive& ar, const short& ver) { int beginType = SECTION_BEGIN; pf.WriteElementType(ar, beginType, ver); } inline void MarkSectionEnd(CArchive& ar, const short& ver) { int endType = SECTION_END; pf.WriteElementType(ar, endType, ver); } inline void VerifySectionBegin(CArchive& ar, const short& ver) { int beginType = 0; pf.ReadElementType(ar, beginType, ver); if (beginType != SECTION_BEGIN) { throw new CArchiveException(CArchiveException::badClass); } } inline void VerifySectionEnd(CArchive& ar, const short& ver) { int endType = 0; pf.ReadElementType(ar, endType, ver); if (endType != SECTION_END) { throw new CArchiveException(CArchiveException::badClass); } } /** * 将小数保留指定小数位数 * * \param value 要被截断的数字 * \param precision 保留几位小数,如果 < 0 什么也不做 * \return */ inline double TruncToPrecision(double value, int precision) { if (precision < 0) { return value; } if (precision == 0) { return std::trunc(value); } double factor = std::pow(10.0, precision); // 10^n return std::trunc(value * factor) / factor; // 截断到指定小数位 } struct CStringHash { size_t operator()(const CString& str) const { // 使用 CString 的底层字符串进行哈希计算 return std::hash()(str.GetString()); } }; /** * 删除对象并将指针置为 nullptr * * \param pointer */ template void SafeDelete(T*& pointer) { delete pointer; pointer = nullptr; } /** * 用于删除数组并将指针设置为 nullptr * * \param pointer */ template void SafeDeleteArray(T*& pointer) { delete[] pointer; pointer = nullptr; } template void ClonePointer(T*& destination, const T* source) { delete destination; destination = nullptr; if (source != nullptr) { destination = new T(); *destination = const_cast(*source); } }