您的位置:首页 > 其它

自己动手实现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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: