//类模板
//若类型T支持memcpy,则该模板类是AcArrayMemCopyReallocator,进行memcpy的数组分配器类
template <class T> class AcArrayMemCopyReallocator
{
public:
static void copyItems(T* pDest, size_t nBufLen, const T * pSource, size_t nCount)
{
AcArrayValidateParams<T>(false, pDest, nBufLen, pSource, nCount);
if (nCount > 0)
memcpy_s(pDest, nBufLen * sizeof(T), pSource, nCount * sizeof(T));
}
static void moveItems(T* pDest, size_t nBufLen, T * pSource, size_t nCount,
bool bSameBuffer)
{
AcArrayValidateParams<T>(bSameBuffer, pDest, nBufLen, pSource, nCount);
if (nCount > 0) {
// If bSameBuffer is true, then we are moving elements left or right in a buffer,
// and so we have to do that in a safe way without clobbering source data.
if (bSameBuffer)
memmove_s(pDest, nBufLen * sizeof(T), pSource, nCount * sizeof(T));
else
memcpy_s(pDest, nBufLen * sizeof(T), pSource, nCount * sizeof(T));
}
}
};
//若类型T不支持memcpy,需要对类型T重新定义实现memcopy函数,则是AcArraybjectCopyReallocator,进行ObjectCpy的数组分配器类
template <class T> class AcArrayObjectCopyReallocator
{
public:
// Copy from source to existing items, using copy assignment operator
static void copyItems(T* pDest, size_t nBufLen, const T * pSource, size_t nCount)
{
AcArrayValidateParams<T>(false, pDest, nBufLen, pSource, nCount);
while (nCount--) {
*pDest = *pSource;
pDest++;
pSource++;
}
}
// Move from source to initialized items, using move assignment operator
static void moveItems(T* pDest, size_t nBufLen, T * pSource, size_t nCount,
bool bSameBuffer)
{
AcArrayValidateParams<T>(bSameBuffer, pDest, nBufLen, pSource, nCount);
while (nCount--) {
*pDest = std::move(*pSource);
pDest++;
pSource++;
}
}
};
//结构体模板
//该结构体模板是,由类型T和bool决定的,拷贝项目的数组选择器;
//该选择器结构体,仅包含一个分配器类,进行memcpy的数组分配器类或者进行ObjectCpy的数组分配器类
template<typename T, bool>
struct AcArrayItemCopierSelector;
template<typename T>
struct AcArrayItemCopierSelector<T, false>
{
typedef AcArrayObjectCopyReallocator<T> allocator;
};
template<typename T>
struct AcArrayItemCopierSelector<T, true>
{
typedef AcArrayMemCopyReallocator<T> allocator;
};
// 类模板
// AcArray为由类型T和R定义的类模板
// 类型R = 分配器类allocator,由类型T支不支持memcpy,决定allocator种类
// std::is_trivial<T>::value 为true或false
template <typename T, typename R = typename AcArrayItemCopierSelector<T, std::is_trivial<T>::value>::allocator > class AcArray
{
public:
AcArray(int initPhysicalLength = 0, int initGrowLength = 8);
AcArray(const AcArray<T,R>&);
AcArray(AcArray<T,R>&&);
~AcArray();
typedef T Type;
typedef R Allocator;
// Useful for validating that an AcArray uses the efficient copy method.
// E.g.: static_assert(AcArray<MyType>::eUsesMemCopy, "AcArray<MyType> uses slow copy!");
enum {eUsesMemCopy = std::is_same<R, AcArrayMemCopyReallocator<T> >::value};
// Assignment and == operators.
//
AcArray<T,R>& operator = (const AcArray<T,R>&);
AcArray<T,R>& operator = (AcArray<T,R>&&);
bool operator == (const AcArray<T,R>&) const;
protected:
T* mpArray;
int mPhysicalLen;// Actual buffer length.
int mLogicalLen;// Number of items in the array.
int mGrowLen; // Buffer grows by this value.
void insertSpace(int nIndex);
void copyOtherIntoThis(const AcArray<T,R>& otherArray);
void moveOtherIntoThis(AcArray<T,R>& otherArray);
bool isValid (int) const;
};