自己动手实现STL 03:内存基本处理工具(stl_uninitialized.h)
2014-11-18 21:06
531 查看
一、前言
前面两篇已经编写了内存配置器和建构解构工具函数。这里,就准备编写并介绍下内存基本处理工具函数。比如uninitialized_copy()、uninitialized_copy和 uninitialized_copy_n()等的实现。二、内存工具函数简介
1.uninitialized_copy函数
uninitialized_copy()使我们能够将内存的配置与对象的建构行为分离开来。如果作为输出目的地的[result, result+(last-first))范围内的每一个迭代器都指向未初始化区域,则uninitialized_copy()会使用copy construct,为身为输入来源[first, last)范围内的每一个对象产生一份复制品,放进输出范围中。如果你需要初始化一个容器的话,这个函数可以其很大最用。通过用两步完成:配置内存区块;然后使用uninitizlied_copy,在该内存区块上建构元素。
c++标准还规定uninitialized_copy()具有"commit or rollback"语意。即,要么建构出所有元素,要么不建构任何东西,不能存在半建构状态。
下面是uninitialized_copy函数调用结构图:
/************************************************************************* > File Name: stl_uninitialized_wjzh.h > Author: wjzh > Mail: wangjzh_1@163.com > Created Time: 2014年11月04日 星期二 17时09分15秒 ************************************************************************/ // 该文件中提供五个全局函数,作用于未初始化空间上 #ifndef __SGI_STL_INTERNAL_UNINITIALIZED_WJZH_H #define __SGI_STL_INTERNAL_UNINITIALIZED_WJZH_H __STL_BEGIN_NAMESPACE // uninitialized_copy的实现 // 如果是POD型别,那么copy construction 等同于 assignment,而且 // destruction 是trivial,以下就有效 // 执行流程就会转进到以下函数。 // POD 意指Plain Old Data,指标量型别或者是传统的C Struct型别 // POD型别必须拥有trivial ctor/dtor/copy/assignment函数 // 这是藉由function template的参数推导机制而得 template <class InputIterator, class ForwardIterator> inline ForwardIterator __uninitialized_copy_aux(InputIterator first, InputIterator last, ForwardIterator result, __true_type) { //这里的_true_type 代表迭代器指向的类型是POD型别,不用构造,可以 //直接拷贝 return copy(first, last, result); } template <class InputIterator, class ForwardIterator> ForwardIerator __uninitialized_copy_aux(InputIterator first, InputIterator last, ForwardIterator result, __false_type) { //这里的_false_type 代表迭代器指向的类型非POD型别, //不能直接拷贝,需要一个一个的调用其构造函数 ForwardIterator cur = result; __STL_TRY { for (; first != last; ++first, ++cur) construct(&*cur, *first); return cur; } //commit or rollback __STL_UNWIND(destroy(result, cur)); } // __uninitialized_copy-->__uninitilaized_copy_aux // 是为利用编译器的类型参数推导,判断是否是POD类型 template <class InputIterator, class ForwardIterator, class T> inline ForwardIterator __uninitialized_copy(InputItearator first, InputIeratorlast, ForwardIterator result, T*) { // is_POD 是一种类型,或者是__true_type代表为真,__ // false_type代表为否,假 // 利用is_POD的不同定义,生成不同的临时对象,用其进行重载 typedef typename __type_traits<T>::is_POD_type is_POD; return __uninitialized_copy_aux(first, last, result, is_POD()); } // uninitialized_copy 的函数模板 // uninitialized_copy -> __uninitialized_copy // 利用编译器的类型推导,萃取处迭代器指向的类型 // 以便最后通过类型萃取__type_traits机制获取迭代器指向类型的一些属性 template <class InputIterator, class ForwardIterator> inline ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator result) { // value_type是个模板函数,萃取迭代器指向类型,用该类型生成临时对象, // 再利用类型推导 return __uninitialized_copy(first, last, result, value_type(result)); } // uninitialized_copy 对于char* 的特化版本 inline char* uninitialized_cpoy(const char* first, const char* last, char* result) { //对于char *对其使用memmove效率最高 memmove(result, first, last - first); return result + (last - first); } // unitialized_copy 对于 wchar_t* 的特化版本 inline wchar_t* uninitialized_copy(const wchar_t* first, const wchar_t* last, wchar_t* result) { //同样对于wchar_t *对其使用memmove效率最高 memmove(result, first, sizeof(wchar_t) * (last - first)); return result + (last - first); } // uninitialized_copy_n 的实现 // input_iterator_tag 是迭代器的分类中的一种,利用迭代器分类类型的不同 // 可以进行重载,不同的迭代器的类型,会针对其有特定的最优实现 template <class InputItearator, class Size, class ForwardIterator> pair<InputIterator, ForwardIterator> __uninitialized_copy_n(InputIterator first, Size count, ForwardIterator result, input_ierator_tag) { // 对于input_iterator_tag类型的迭代器,只能逐个调用构造 ForwardIterator cur = result; __STL_TRY { for (; count > 0; --count, ++first, ++cur) construct(&*cur, *first); return pair<InputIterator, ForwardIterator>(first, cur); } // commit or rollback __STL_UNWIND(destroy(result, cur)); } template <class RandomAccessItearator, class Size, class ForwardIterator> inline pair<RandomAccessIterator, ForwardIterator> __uninitialized_copy_n(RandomAccessIterator first, Size count, ForwardIterator result, random_ierator_tag) { // 对于random_iterator_tag类型的迭代器 // 可以利用first和count计算出last迭代器 // 然后利用uninitialized_copy(first, last, result) // 然而对于input_iterator_tag,就不能 RandomAccessIterator last = first _count; return make_pair(last, uninitialized_copy(first, last, result)); } template <class InputIterator, class Size, class ForwardIterator> inline pair<InputIterator, ForwardIterator> uninitialized_copy_n(InputIterator first, Size count, ForwardIterator result) { // 利用模板函数iterator_category提取出first迭代器的分类型别 // 然后利用其型别进行重载,对于不同的型别进行不同的优化处理 return __uninitialized_copy_n(first, count, result, iterator_category(first)); } // uninitialized_fii 的实现 // 如果是POD型别,那么copy construction 等同于 assignment,而且 // destructor 是trivial,以下就有效 // 执行流程就会转进到以下函数。 template <class ForwardIterator, class T> inline void __uninitialized_fill_aux(ForwardIterator first, ForwardIterator last, const T& x, __true_type) { // isPOD的类型定义为__true_type,表示是POD类型 fill(first, last, x); //调用STL算法fill() } template <class ForwardIterator, class T> void __uninitialized_fill_aux(ForwardIterator first, ForwardIterator last, const T& x, __false_type) { // is_POD定义为__false_type表示不是POD类型,所以只能逐个构造 ForwardIterator cur = first; __STL_TRY { for (; cur != last; ++cur) construct(&*cur, x); } // commit or rollback __STL_UNWIND(destroy(first, cur)); } // 内部的第二层,用于提取迭代器指向的类型是否是POD类型 // 并利用其进行重载 template <class ForwardIterator, class T, class T1> inline void __uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& x, T1*) { // 利用__type_traits来萃取is_POD_type定义的类型 // 并利用其调用更底层的重载实现 typedef typename __type_traits<T1>::is_POD_type is_POD; __uninitialized_fill_aux(first, last, x, is_POD()); } // uninitialized_fill()对外接口 template <class ForwardIterator, class T> inline void uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& x) { __uninitialized_fill(first, last, x, value_type(first)); } // uninitialized_fill_n的实现 // 基本原理于uninitialized_copy_n一样 template <class ForwardIterator, class Size, class T> inline ForwardIterator __uninitialized_fill_n_aux(ForwardIterator first, Size n, const T& x, __true_type) { return fill_n(first, n, x); } template <class ForwardIterator, class Size, class T> ForwardIterator __uninitialized_fill_n_aux(ForwardIterator first, Size n, const T& x, __false_type) { ForwardIterator cur = first; __STL_TRY { for (; n > 0; --n, ++cur) construct(&*cur, x); return cur; } __STL_UNWIND(destroy(first, cur)); } template <class ForwardIterator, class Size, class T, class T1> inline ForwardIterator __uninitialized_fill_n(ForwardIterator first, Size n, const T& x, T1*) { typedef typename __type_traits<T1>::is_POD_type is_POD; return __uninitialized_fill_n_aux(first, n, x, is_POD()); } // uninitialized_fill_n对外接口 template <class ForwardIterator, class Size, class T> inline ForwardIterator uninitialized_fill_n(ForwardIterator first,Size n, const T& x) { return __uninitialized_fill_n(first, n, value_type(first)); } // 拷贝[first1, last1)到[result, result + (last1 - first1)) // 同时拷贝[first2, last2)到 // [result + (last1 - first1), result + (last1 - first1) + (last2 - first2)] template <class InputIterator1, class InputIterator2, class ForwardIterator> inline ForwardIterator __uninitialized_copy_copy(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator last2, ForwardIterator result) { ForwardIterator mid = uninitialized_copy(first1, last1, reuslt); __STL_TRY { return uninitialized_copy(first2, last2, mid); } __STL_UNWIND(destroy(result, mid)); } // 用x填充[result, mid),同时拷贝[first, last)到[mid, mid + (last - first)) template <class ForwardIterator, class T, class InputIterator> inline ForwardIterator __uninitialized_fill_copy(ForwardIterator result, ForwardIterator mid, const T& x, InputIterator first, InputIterator last) { uninitialized_fill(result, mid, x); __STL_TRY { return uninitialized_copy(first, last, mid); } __STL_UNWIND(destroy(result, mid)); } // 拷贝[first1, last1)到[first2, first2 + (last1 - first1)) // 并且用x填充[first2 + (last1 - first1), last2] template <class InputIterator, class ForwardIterator, class T> inline void __uninitialized_copy_fill(InputIterator first1, InputIterator last1, ForwardIterator first2, ForwardIterator last2, const T& x) { ForwardIterator mid2 = uninitialized_copy(first1, last1, first2); __STL_TRY { uninitialized_fill(mid2, last2, x); } __STL_UNWIND(destroy(first2, mid2)); } __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_UNINITIALIZED_WJZH_H*/ // End
View Code
相关文章推荐
- STL源码剖析 [特殊的空间配置器](内存基本处理工具stl_uninitialized.h)
- 自己动手实现STL 02:构造析构的基本工具construct()和destroy()(stl_construct.h)
- STL内存基本处理工具(stl_uninitialized.h)
- STL — 内存基本处理工具(<stl_uninitialized.h>)
- STL源码:内存基本处理工具
- 自己动手实现STL 01:内存配置器的实现(stl_alloc.h)
- stl_内存基本处理工具
- stl_内存基本处理工具
- STL——内存基本处理工具
- STL内存基本处理工具(整理)
- 自己实现基本的C标准库字符串处理函数——基本问题
- 动手实现自己的 STL 容器 《1》---- vector
- 自己动手实现操作系统引导程序(OS bootloader)——借助QEMU/GDB/losetup/dd等工具
- 《stl源码剖析》-- 内存基本处理工具
- 自己实现基本的C标准库字符串处理函数——基本问题(转载)
- STL源码剖析(2):内存基本处理工具
- 内存基本处理工具
- 【深度探索STL】空间配置器(四) 内存基本处理
- 自己实现基本的C标准库字符串处理函数——实现strcpy
- STL学习】自己动手C++编程实现hash table(散列表)