模版函数,用来使标准库容器支持MFC的Serialize

// 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

 

posted on 2005-11-25 16:11  mslk  阅读(1067)  评论(0)    收藏  举报