封装STL中vector提供MFC中的CArry接口
简介:通过封装STL模板库中vector数组,提供MFC中的CArray的相关功能,同时提供vector访问接口
//
// 通过封装STL模板库中vector数组,提供MFC中的CArray的相关功能,同时提供vector访问接口
//
#ifndef __CARRAYEX_H__
#define __CARRAYEX_H__
#include <vector>
#if !defined(_WIN32)
#include <stdexcept>
#endif
//数组模板类
template<class TYPE>
class CArrayEx
{
public:
typedef TYPE _Ty;
typedef CArrayEx<TYPE> _Myt;
typedef typename std::vector<TYPE>::size_type size_type;
typedef typename std::vector<TYPE>::const_iterator const_iterator;
typedef typename std::vector<TYPE>::iterator iterator;
typedef typename std::vector<TYPE>::const_reverse_iterator const_reverse_iterator;
typedef typename std::vector<TYPE>::reverse_iterator reverse_iterator;
typedef typename std::vector<TYPE>::const_reference const_reference;
typedef typename std::vector<TYPE>::reference reference;
// 构造函数
CArrayEx();
// 析构函数
~CArrayEx();
// 获取大小
INT_PTR GetSize() const;
// 获取个数
INT_PTR GetCount() const;
// 当前数组是否为空
BOOL IsEmpty() const;
// 获取数组下标上界,如果数组为空,则为-1
INT_PTR GetUpperBound() const;
// 设置数组大小
void SetSize(INT_PTR nNewSize, INT_PTR nGrowBy = -1);
// 获取指定位置只读元素
const TYPE& GetAt(INT_PTR nIndex) const;
// 获取指定位置元素
TYPE& GetAt(INT_PTR nIndex);
// 设置指定位置元素
void SetAt(INT_PTR nIndex, TYPE const& newElement);
// 获取指定位置的只读元素
const TYPE& ElementAt(INT_PTR nIndex) const;
// 获取指定位置的元素
TYPE& ElementAt(INT_PTR nIndex);
// 获取数组的数据首地址,返回只读
const TYPE* GetData() const;
// 获取数组的首地址,可写
TYPE* GetData();
// 直接获取内部数组
std::vector<TYPE>* GetArray();
// 将元素放在指定的位置,若该位置超出数组长度,则自动增长
void SetAtGrow(INT_PTR nIndex, TYPE const& newElement);
// 将当前的数据加到数组末尾
INT_PTR Add(TYPE const& newElement);
// 拼接两个数组,将指定的数组放到当前数组末尾
INT_PTR Append(const CArrayEx& src);
// 数组拷贝,将另一个数组的数据拷贝过来
void Copy(const CArrayEx& src);
// 操作符重载
// 下标操作符重载,返回指定位置只读元素
const TYPE& operator[](INT_PTR nIndex) const;
// 下标操作符重载,返回指定位置元素
TYPE& operator[](INT_PTR nIndex);
// 在指定位置插入指定个数元素
void InsertAt(INT_PTR nIndex, TYPE const& newElement, INT_PTR nCount = 1);
// 删除指定位置元素
void RemoveAt(INT_PTR nIndex, INT_PTR nCount = 1);
// 在指定位置插入另一个数组
void InsertAt(INT_PTR nStartIndex, CArrayEx const *pNewArray);
// 清空额外分配的内存
void FreeExtra();
// 删除数组内所有元素
void RemoveAll();
//如下函数使CArrayEx仍能按照vector来访问,且未增加任何成员变量,所有函数均内联
void reserve(size_type _Count) { m_vtArray.reserve(_Count);}
size_type capacity() const { return m_vtArray.capacity();}
iterator begin() { return m_vtArray.begin();}
const_iterator begin() const { return m_vtArray.begin();}
iterator end() { return m_vtArray.end();}
const_iterator end() const { return m_vtArray.end();}
reverse_iterator rbegin() { return m_vtArray.rbegin();}
const_reverse_iterator rbegin() const { return m_vtArray.rbegin();}
reverse_iterator rend() { return m_vtArray.rend();}
const_reverse_iterator rend() const { return m_vtArray.rend();}
void resize(size_type _Newsize) { m_vtArray.resize(_Newsize);}
void resize(size_type _Newsize, TYPE _Val) { m_vtArray.resize(_Newsize,_Val);}
size_type size() const { return m_vtArray.size();}
size_type max_size() const { return m_vtArray.max_size();}
bool empty() const { return m_vtArray.empty();}
const_reference at(size_type _Pos) const{ return m_vtArray.at(_Pos);}
reference at(size_type _Pos) { return m_vtArray.at(_Pos);}
reference front() { return m_vtArray.front();}
const_reference front() const { return m_vtArray.front();}
reference back() { return m_vtArray.back();}
const_reference back() const { return m_vtArray.back();}
void push_back(const TYPE& _Val) { m_vtArray.push_back(_Val);}
void pop_back() { m_vtArray.pop_back();}
template<class _Iter>
void assign(_Iter _First, _Iter _Last) { m_vtArray.template assign<_Iter>(_First, _Last);}
void assign(size_type _Count, const _Ty& _Val) { m_vtArray.assign(_Count, _Val);}
iterator insert(iterator _Where, const _Ty& _Val) { return m_vtArray.insert(_Where, _Val);}
void insert(iterator _Where, size_type _Count, const _Ty& _Val) { m_vtArray.insert(_Where, _Count, _Val);}
template<class _Iter>
void insert(iterator _Where, _Iter _First, _Iter _Last) { m_vtArray.template insert<_Iter>(_Where, _First, _Last);}
iterator erase(iterator _Where) { return m_vtArray.erase(_Where);}
void clear() { m_vtArray.clear();}
void swap(_Myt& _Right) { m_vtArray.swap(_Right.m_vtArray);}
protected:
std::vector<TYPE> m_vtArray;// 内部数据使用vector
friend bool operator== (CArrayEx<TYPE> const &lhs, CArrayEx<TYPE> const &rhs);
};
//
// 构造函数
template<class TYPE>
CArrayEx<TYPE>::CArrayEx()
{
}
// 析构函数
template<class TYPE>
CArrayEx<TYPE>::~CArrayEx()
{
m_vtArray.clear();
}
// 获取大小
template<class TYPE>
inline INT_PTR CArrayEx<TYPE>::GetSize() const
{
return static_cast<INT_PTR>(m_vtArray.size());
}
// 获取个数
template<class TYPE>
inline INT_PTR CArrayEx<TYPE>::GetCount() const
{
return static_cast<INT_PTR>(m_vtArray.size());
}
// 当前数组是否为空
template<class TYPE>
inline BOOL CArrayEx<TYPE>::IsEmpty() const
{
return m_vtArray.empty() ? TRUE : FALSE;
}
// 获取数组下标上界,如果数组为空,则为-1
template<class TYPE>
inline INT_PTR CArrayEx<TYPE>::GetUpperBound() const
{
return static_cast<INT_PTR>(m_vtArray.size()) - 1;
}
// 设置数组大小,理解vector动态内存增长原理
template<class TYPE>
void CArrayEx<TYPE>::SetSize(INT_PTR nNewSize, INT_PTR /*nGrowBy = -1*/)
{
m_vtArray.resize(nNewSize);
}
// 获取指定位置只读元素
template<class TYPE>
const TYPE& CArrayEx<TYPE>::GetAt(INT_PTR nIndex) const
{
// 当前下标在数组范围内,返回元素
if (nIndex >= 0 && nIndex < static_cast<INT_PTR>(m_vtArray.size()))
return m_vtArray[nIndex];
throw std::runtime_error("Invalid array index!");
}
// 获取指定位置元素
template<class TYPE>
TYPE& CArrayEx<TYPE>::GetAt(INT_PTR nIndex)
{
// 当前下标在数组范围内,返回元素
return m_vtArray.at(nIndex);
}
// 设置指定位置元素
template<class TYPE>
void CArrayEx<TYPE>::SetAt(INT_PTR nIndex, TYPE const& newElement)
{
// 当前下标在数组范围内,获取元素并修改值
if (nIndex >= 0 && nIndex < static_cast<INT_PTR>(m_vtArray.size()))
m_vtArray[nIndex] = newElement;
else
throw std::runtime_error("Invalid array index!");
}
// 获取指定位置的只读元素
template<class TYPE>
const TYPE& CArrayEx<TYPE>::ElementAt(INT_PTR nIndex) const
{
// 当前下标在数组范围内,返回元素
if (nIndex >= 0 && nIndex < static_cast<INT_PTR>(m_vtArray.size()))
return m_vtArray[nIndex];
throw std::runtime_error("Invalid array index!");
}
// 获取指定位置的元素
template<class TYPE>
TYPE& CArrayEx<TYPE>::ElementAt(INT_PTR nIndex)
{
// 当前下标在数组范围内,返回元素
if (nIndex >= 0 && nIndex < static_cast<INT_PTR>(m_vtArray.size()))
return m_vtArray[nIndex];
throw std::runtime_error("Invalid array index!");
}
// 获取数组的数据首地址,返回只读
template<class TYPE>
inline const TYPE* CArrayEx<TYPE>::GetData() const
{
// 数组有内容存在,返回首地址
if( !m_vtArray.empty() )
{
return &m_vtArray[0];
}
// 无内容,返回空
return NULL;
}
// 获取数组的首地址,可写
template<class TYPE>
inline TYPE* CArrayEx<TYPE>::GetData()
{
// 数组有内容存在,返回首地址
if( !m_vtArray.empty() )
{
return &m_vtArray[0];
}
// 无内容,返回空
return NULL;
}
// 直接获取内部数组
template<class TYPE>
inline std::vector<TYPE>* CArrayEx<TYPE>::GetArray()
{
return &m_vtArray;
}
// 将元素放在指定的位置,若该位置超出数组长度,则自动增长
template<class TYPE>
void CArrayEx<TYPE>::SetAtGrow(INT_PTR nIndex, TYPE const& newElement)
{
// 指定的位置不能小于0
if (nIndex >= 0)
{
if (nIndex >= static_cast<INT_PTR>(m_vtArray.size()))
m_vtArray.resize(nIndex + 1, newElement);
else
m_vtArray[nIndex] = newElement;
}
}
// 将当前的数据加到数组末尾
template<class TYPE>
inline INT_PTR CArrayEx<TYPE>::Add(TYPE const& newElement)
{
m_vtArray.push_back(newElement);
return static_cast<INT_PTR>(m_vtArray.size() - 1);
}
// 拼接两个数组,将指定的数组放到当前数组末尾
template<class TYPE>
INT_PTR CArrayEx<TYPE>::Append(const CArrayEx& src)
{
if (src.m_vtArray.empty())
return -1;
INT_PTR iOldIndex = static_cast<INT_PTR>(m_vtArray.size());
m_vtArray.insert(m_vtArray.end(), src.m_vtArray.begin(), src.m_vtArray.end());
return iOldIndex;
}
// 数组拷贝,将另一个数组的数据拷贝过来
template<class TYPE>
inline void CArrayEx<TYPE>::Copy(const CArrayEx& src)
{
m_vtArray.assign(src.m_vtArray.begin(), src.m_vtArray.end());
}
// 下标操作符重载,返回指定位置只读元素
template<class TYPE>
inline const TYPE& CArrayEx<TYPE>::operator[](INT_PTR nIndex) const
{
return m_vtArray[nIndex];
}
// 下标操作符重载,返回指定位置元素
template<class TYPE>
inline TYPE& CArrayEx<TYPE>::operator[](INT_PTR nIndex)
{
return m_vtArray[nIndex];
}
// 在指定位置插入指定个数元素
template<class TYPE>
void CArrayEx<TYPE>::InsertAt(INT_PTR nIndex, TYPE const& newElement, INT_PTR nCount /*= 1*/)
{
//参数检查
if (nCount <= 0)
return;
//插入的位置比当前长度长,插入到指定位置
if (nIndex >= static_cast<INT_PTR>(m_vtArray.size()))
{
m_vtArray.resize(nIndex + nCount, newElement);
}
//插入到中间位置
else
{
m_vtArray.insert(m_vtArray.begin() + nIndex, nCount, newElement);
}
}
// 删除指定位置元素
template<class TYPE>
void CArrayEx<TYPE>::RemoveAt(INT_PTR nIndex, INT_PTR nCount /*= 1*/)
{
//需要删除的位置必须在数组长度范围内
if (nIndex >= 0 && nIndex < static_cast<INT_PTR>(m_vtArray.size()) && nCount > 0)
{
INT_PTR iLeaveCount = static_cast<INT_PTR>(m_vtArray.end() - (m_vtArray.begin() + nIndex));
iLeaveCount = iLeaveCount > nCount ? nCount : iLeaveCount;
m_vtArray.erase(m_vtArray.begin() + nIndex, m_vtArray.begin() + nIndex + iLeaveCount);
}
}
// 在指定位置插入另一个数组
template<class TYPE>
void CArrayEx<TYPE>::InsertAt(INT_PTR nStartIndex, CArrayEx<TYPE> const *pNewArray)
{
//需要插入的数组必须存在
if (!pNewArray)
return;
if (pNewArray->m_vtArray.empty())
return;
//插入的位置比当前长度长,插入到指定位置
if (nStartIndex >= static_cast<INT_PTR>(m_vtArray.size()))
{
m_vtArray.resize(nStartIndex + 1);
m_vtArray.insert(m_vtArray.end(), pNewArray->m_vtArray.begin(), pNewArray->m_vtArray.end());
}
//插入到中间位置
else
{
m_vtArray.insert(m_vtArray.begin() + nStartIndex, pNewArray->m_vtArray.begin(), pNewArray->m_vtArray.end());
}
}
// 清空额外分配的内存
template<class TYPE>
inline void CArrayEx<TYPE>::FreeExtra()
{
return;
}
// 删除数组内所有元素
template<class TYPE>
inline void CArrayEx<TYPE>::RemoveAll()
{
m_vtArray.clear();
}
template<class TYPE>
inline bool operator== (CArrayEx<TYPE> const &lhs, CArrayEx<TYPE> const &rhs)
{
return lhs.m_vtArray == rhs.m_vtArray;
}
//
#endif