深度剖析空间配置器(三)内存处理函数

空间配置器

主要分三个文件实现,我们已经介绍过第一个文件了(对象的构造和析构   http://blog.csdn.net/hj605635529/article/details/70238270),

第二个(http://blog.csdn.net/hj605635529/article/details/70238728  一二级配置器)

现在我们来介绍第三个文件 stl_uninitialized.h 这里定义了一些全局函数,用来填充(fill)或复制(copy)大块内存数据

uninitialized_copy(),uninitialized_copy_n(),uninitialized_fill(),uninitialized_fill_n()   (由函数名可知,是对未初始化空间的初始化操作,即通过复制或赋值的方式初始化未初始化的空间)

先学习 uninitiated_copy()

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. //stl source code(v3.3)  
  2. //defined in <stl_uninitialized.h>  
  3. inline char* uninitialized_copy(const char* __first, const char* __last, char* __result)   
  4. {  
  5.     memmove(__result, __first, __last - __first);  
  6.     return __result + (__last - __first);  //返回该连续区域的末尾  
  7. }  
  8.   
  9. inline wchar_t*   // typedef unsigned short wchar_t;  
  10. uninitialized_copy(const wchar_t* __first, const wchar_t* __last, wchar_t* __result)  
  11. {  
  12.     memmove(__result, __first, sizeof(wchar_t)* (__last - __first));  
  13.     return __result + (__last - __first);  
  14. }  
上面两个是对两种特化类型的处理,下面为泛化版本

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. template <class _InputIter, class _ForwardIter>  
  2. inline _ForwardIter  
  3. uninitialized_copy(_InputIter __first, _InputIter __last, _ForwardIter __result)  
  4. {     
  5.     //根据数值型别决议出最佳效率的函数  
  6.     return __uninitialized_copy(__first, __last, __result, __VALUE_TYPE(__result));  
  7. }  
  8.   
  9. template <class _InputIter, class _ForwardIter, class _Tp>  
  10. inline _ForwardIter  
  11. __uninitialized_copy(_InputIter __first, _InputIter __last, _ForwardIter __result, _Tp*)  
  12. {  
  13.     typedef typename __type_traits<_Tp>::is_POD_type _Is_POD;   //判断数值型别  
  14.     //在C++中,我们把传统的C风格的struct叫做POD(Plain Old Data)对象  
  15.   
  16.     return __uninitialized_copy_aux(__first, __last, __result, _Is_POD());  
  17. }  
  18.   
  19. //如果copy construction 和 operator = 等效(POD type),并且 destructor is trivial 的情况   
  20. template <class _InputIter, class _ForwardIter>  
  21. inline _ForwardIter  
  22. __uninitialized_copy_aux(_InputIter __first, _InputIter __last, _ForwardIter __result, __true_type)  
  23. {  
  24.     /*针对POD对象,其二进制内容是可以随便复制的*/  
  25.     return copy(__first, __last, __result);  
  26.   
  27.     /*简化处理,详见<stl_algobase.h> 
  28.     inline _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) 
  29.     { 
  30.         memmove(__result, __first, sizeof(_Tp) * (__last - __first)); 
  31.         return __result + (__last - __first); 
  32.     } 
  33.     */  
  34. }  
  35.   
  36. /*如果copy construction 和 operator = 不等效,就需要调用 construct() 构造 */  
  37. template <class _InputIter, class _ForwardIter>  
  38. _ForwardIter  
  39. __uninitialized_copy_aux(_InputIter __first, _InputIter __last, _ForwardIter __result, __false_type)  
  40. {  
  41.     _ForwardIter __cur = __result;  
  42.   
  43.     /*下面就是捕捉异常处理*/  
  44.     __STL_TRY{    //#define __STL_TRY  try  
  45.         for (; __first != __last; ++__first, ++__cur) //一个一个元素的构造,无法批量进行  
  46.         _Construct(&*__cur, *__first);   //每个对象都以其它对象为蓝本进行构造,使用的是 placement new  
  47.         return __cur;  
  48.     }  
  49.     /*commit or rollback:要么构造出所有必要元素, 
  50.     要么(当有任何一个 copy construct 失败时)不构造任何东西,保证所有对象都被析构*/  
  51.     __STL_UNWIND(_Destroy(__result, __cur));  
  52.     //#define __STL_UNMIND(action)  catch(...) { action; throw;}  
  53. }  
POD就是标量型别或传统的C struct 型别,POD 型别必然拥有 trivial ctor / dtor / copy / assignment 函数,因此我们可以对POD型别进行判断,从而决议出最有效率的初值填写手法

不难发现上面 uninitiated_copy() 后,返回的是指向 copy 后的区块末端。

uninitiated_copy_n() 则是向指定欲初始化空间初始化(复制)指定大小已初始化空间的指定值(有点拗口)。

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. template <class _InputIter, class _Size, class _ForwardIter>  
  2. inline pair<_InputIter, _ForwardIter>  
  3. uninitialized_copy_n(_InputIter __first, _Size __count, _ForwardIter __result)  
  4. {  
  5.     //最后一个形参判断迭代器 first 的类别  
  6.     return __uninitialized_copy_n(__first, __count, __result, __ITERATOR_CATEGORY(__first));  
  7. }  
  8.   
  9. //函数返回两个值,采用 pair 对组  
  10. //迭代器型别为支持随机存取的迭代器,涵盖所有指针运算能力,可以直接使用uninitialized_copy()进行复制  
  11. template <class _RandomAccessIter, class _Size, class _ForwardIter>  
  12. inline pair<_RandomAccessIter, _ForwardIter>  
  13. __uninitialized_copy_n(_RandomAccessIter __first, _Size __count, _ForwardIter __result, random_access_iterator_tag)  
  14. {  
  15.     _RandomAccessIter __last = __first + __count;  
  16.     return pair<_RandomAccessIter, _ForwardIter>(__last, uninitialized_copy(__first, __last, __result));  
  17. }  
  18.   
  19. //迭代器为只读型别,所指的对象不允许外界改变  
  20. template <class _InputIter, class _Size, class _ForwardIter>  
  21. pair<_InputIter, _ForwardIter>  
  22. __uninitialized_copy_n(_InputIter __first, _Size __count, _ForwardIter __result, input_iterator_tag)  
  23. {  
  24.     /*针对输入范围内的每一个迭代器,函数会调用construct()函数产生迭代器所指对象的复制品, 
  25.     放置于输出范围的相应位置上*/  
  26.     _ForwardIter __cur = __result;  
  27.     __STL_TRY{          
  28.         for (; __count > 0; --__count, ++__first, ++__cur)  
  29.         _Construct(&*__cur, *__first);  
  30.         return pair<_InputIter, _ForwardIter>(__first, __cur);  
  31.     }  
  32.     __STL_UNWIND(_Destroy(__result, __cur));  
  33. }  
上面函数都是返回 pair 对组类型。其实就是返回两个值,一个是 “只读” 型别的迭代器(_InputIter),一个是允许 “写入型” 的迭代器(_ForwardIter)。
下面这个函数 uninitiated_fill() 和 uninitiated_copy() 操作很像,只不过前者是赋值,后者是复制。

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. //迭代器类型为“写入型”。该函数的功能就是给迭代器指定范围内赋值  
  2. //具体实现过程参考函数 uninitialized_copy()  
  3. template <class _ForwardIter, class _Tp>  
  4. inline void uninitialized_fill(_ForwardIter __first, _ForwardIter __last, const _Tp& __x)  
  5. {  
  6.     __uninitialized_fill(__first, __last, __x, __VALUE_TYPE(__first));  
  7. }  
  8.   
  9. //判断数值型别,同 uninitialized_copy()  
  10. template <class _ForwardIter, class _Tp, class _Tp1>  
  11. inline void __uninitialized_fill(_ForwardIter __first, _ForwardIter __last, const _Tp& __x, _Tp1*)  
  12. {  
  13.     typedef typename __type_traits<_Tp1>::is_POD_type _Is_POD;  
  14.     __uninitialized_fill_aux(__first, __last, __x, _Is_POD());  
  15. }  
  16.   
  17. template <class _ForwardIter, class _Tp>  
  18. inline void  
  19. __uninitialized_fill_aux(_ForwardIter __first, _ForwardIter __last, const _Tp& __x, __true_type)  
  20. {  
  21.     fill(__first, __last, __x);  
  22.     /*简化处理,参见<stl_algobase.h> 
  23.     template <class _ForwardIter, class _Tp> 
  24.     void fill(_ForwardIter __first, _ForwardIter __last, const _Tp& __value)  
  25.     { 
  26.         for ( ; __first != __last; ++__first) 
  27.             *__first = __value; 
  28.     } 
  29.     */  
  30. }  
  31.   
  32. template <class _ForwardIter, class _Tp>  
  33. void  
  34. __uninitialized_fill_aux(_ForwardIter __first, _ForwardIter __last, const _Tp& __x, __false_type)  
  35. {  
  36.     _ForwardIter __cur = __first;  
  37.     __STL_TRY{  
  38.         for (; __cur != __last; ++__cur)  
  39.         _Construct(&*__cur, __x);  
  40.     }  
  41.     __STL_UNWIND(_Destroy(__first, __cur));  
  42. }  
下面的函数 uninitiated_fill_n() 则是向指定欲初始化空间初始化(赋值)指定大小空间的指定值。

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. template <class _ForwardIter, class _Size, class _Tp>  
  2. inline _ForwardIter  
  3. uninitialized_fill_n(_ForwardIter __first, _Size __n, const _Tp& __x)  
  4. {  
  5.     return __uninitialized_fill_n(__first, __n, __x, __VALUE_TYPE(__first));  
  6. }  
  7.   
  8. template <class _ForwardIter, class _Size, class _Tp, class _Tp1>  
  9. inline _ForwardIter  
  10. __uninitialized_fill_n(_ForwardIter __first, _Size __n, const _Tp& __x, _Tp1*)  
  11. {  
  12.     typedef typename __type_traits<_Tp1>::is_POD_type _Is_POD;  
  13.     return __uninitialized_fill_n_aux(__first, __n, __x, _Is_POD());  
  14. }  
  15.   
  16. template <class _ForwardIter, class _Size, class _Tp>  
  17. _ForwardIter  
  18. __uninitialized_fill_n_aux(_ForwardIter __first, _Size __n, const _Tp& __x, __false_type)  
  19. {  
  20.     _ForwardIter __cur = __first;  
  21.     __STL_TRY{  
  22.         for (; __n > 0; --__n, ++__cur)  
  23.         _Construct(&*__cur, __x);  
  24.         return __cur;  
  25.     }  
  26.     __STL_UNWIND(_Destroy(__first, __cur));  
  27. }  
  28.   
  29. template <class _ForwardIter, class _Size, class _Tp>  
  30. inline _ForwardIter  
  31. __uninitialized_fill_n_aux(_ForwardIter __first, _Size __n, const _Tp& __x, __true_type)  
  32. {  
  33.     return fill_n(__first, __n, __x);  
  34.     /*简化处理,参见<stl_algobase.h> 
  35.     template <class _OutputIter, class _Size, class _Tp> 
  36.     _OutputIter fill_n(_OutputIter __first, _Size __n, const _Tp& __value) 
  37.     { 
  38.         for ( ; __n > 0; --__n, ++__first) 
  39.             *__first = __value; 
  40.         return __first; 
  41.     } 
  42.     */  
  43. }  


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值