You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

238 lines
5.0 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#pragma once
#include <vector>
#include <afx.h>
#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<CString>& 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<std::string>()(str.GetString());
}
};
/**
* 删除对象并将指针置为 nullptr
*
* \param pointer
*/
template <typename T>
void SafeDelete(T*& pointer)
{
delete pointer;
pointer = nullptr;
}
/**
* 用于删除数组并将指针设置为 nullptr
*
* \param pointer
*/
template <typename T>
void SafeDeleteArray(T*& pointer)
{
delete[] pointer;
pointer = nullptr;
}
template <typename T>
void ClonePointer(T*& destination, const T* source)
{
delete destination;
destination = nullptr;
if (source != nullptr)
{
destination = new T();
*destination = const_cast<T&>(*source);
}
}