// title:模版函数,用来使标准库容器支持MFC的Serialize
/*!
实现日期:2004-10-26
注:需要Boost库
例子
例如:class CNeedSerializationCustomType:public CObject{...};//需要SERIAL宏
//类CXYZClass的如下成员
std::vector<CNeedSerializationCustomType*> m_pDataVector; // 存储对象指针
std::vector<CNeedSerializationCustomType> m_clsDataVector; // 存储对象
这两个容器Serialize分别只需要一行代码
void CXYZClass::Serialize(CArchive &ar)
{
MSLK_Utility::CommonObjectPointerCollectSerialize(ar,m_pDataVector);
// 智能指针同样可以
MSLK_Utility::CommonObjectCollectSerialize(ar,m_clsDataVector); //
}
*/
#ifndef mslk_utility_h_12345
#define mslk_utility_h_12345
#include <boost/type_traits.hpp> // for boost::type_traits
#include <cassert> // for assert
#include <vector> // for std::vector
#include <memory> // for std::auto_ptr
#include <afxtempl.h> // for mfc::collect
namespace MSLK_Utility{
namespace detail{ /// support smart_ptr
template<bool bIsPtr>
struct SerialzeElem // pointer
{
template<typename T>
static void do_write(CArchive &ar,T const& op)
{
CObject *pOb = dynamic_cast<CObject*>(op);
assert(NULL != pOb);
ar<<pOb;
}
template<typename T>
static void do_read(CArchive &ar,T& op)
{
CObject *pOb=NULL;
ar>>pOb;
op = dynamic_cast<T>(pOb);
assert(NULL != op);
}
};
template<>
struct SerialzeElem<false> // smart_ptr
{
template<typename T>
static void do_write(CArchive &ar,T const& sp)
{
CObject *pOb = dynamic_cast<CObject*>(sp.get());
assert(NULL != pOb);
ar<<pOb;
}
template<typename T>
static void do_read(CArchive &ar,T& sp)
{
CObject *pOb=NULL;
ar>>pOb;
T::element_type* p = dynamic_cast<T::element_type*>(pOb);
assert(NULL != p);
sp = T(p);
}
};
} // end: detail
// 10.26 update: 添加特性,支持元素类型为Smart_ptr的集合
// 通用对象指针的serialize
template<typename T> // T ==> std::list<…>;std::vector<…>
void CommonObjectPointerCollectSerialize( CArchive &ar, T
&refAnyDataCollect )
{
DWORD dwCount;
if (ar.IsStoring())
{
dwCount = refAnyDataCollect.size();
ar<<dwCount;
assert(dwCount>=0);
T::iterator itBeg(refAnyDataCollect.begin()),itEnd(refAnyDataCollect.end());
for(; itBeg!=itEnd; ++itBeg)
{
sw::detail::SerialzeElem<boost::is_pointer<T::value_type>::value
>::do_write(ar,*itBeg);
}
}
else
{
ar>>dwCount;
assert(dwCount>=0);
while (dwCount--)
{
T::value_type v;
sw::detail::SerialzeElem<boost::is_pointer<T::value_type>::value
>::do_read(ar,v);
refAnyDataCollect.push_back( v );
}
}
}
// 通用的容器数组serialize
template<typename T>
void CommonObjectCollectSerialize( CArchive &ar, T &refAnyDataCollect )
{
DWORD dwCount;
if (ar.IsStoring())
{
dwCount = refAnyDataCollect.size();
ar<<dwCount;
assert(dwCount>=0);
T::iterator itBeg(refAnyDataCollect.begin()),itEnd(refAnyDataCollect.end());
for(; itBeg!=itEnd; ++itBeg)
{
ar << *itBeg;
}
}
else
{
ar>>dwCount;
assert(dwCount>=0);
while (dwCount--)
{
T::value_type v;
ar >> v;
refAnyDataCollect.push_back( v );
}
}
}
template<typename T,typename argT> // 转换一个MFC数组到标准库数组,以便使用 <Algorithm>
std::auto_ptr<std::vector<T> > ConvertCArray2Std_Vector(
CArray<T,argT> const& array)
{
std::auto_ptr<std::vector<T> > apVec( new std::vector<T>(array.GetSize()) );
for (int i=0; i<apVec->size(); ++i)
{
apVec->operator [](i) = array[i];
}
return apVec;
}
template<typename T> // 转换 MFC链表到标准库数组
std::auto_ptr<std::vector<T> > ConvertCTypedPtrList2Std_Vector(
CTypedPtrList<CObList,T> const &ll)
{
std::auto_ptr<std::vector<T> > apVec( new std::vector<T>(ll.GetSize()) );
POSITION pos=ll.GetHeadPosition();
for (int i=0; pos!=NULL; )
{
apVec->operator [](i++) = ll.GetNext(pos);
}
return apVec;
}
} //namespace MSLK_Utility
#endif //mslk_utility_h_12345
浙公网安备 33010602011771号