您的位置:首页 > 其它

STL源码剖析(2):内存基本处理工具

2015-06-18 09:31 281 查看
内存基本处理工具:

  STL有五个全局函数,作用于未初始化空间上,它们分别是:construct(), destroy(), uninialized_copy(), uninialized_fill()和uninialized_fill_n()。

  前两个函数前面文章有介绍,下面介绍后三个函数。

  uninitialized_copy()使我们能够将内存的配置与对象的构造行为分离开来。如果作为输出目的地的[result, result+(last-first))范围内的每一个迭代器都指向未初始化区域,则uninitialized_copy()会使用copy construct,为身为输入来源[first, last)范围内的每一个对象产生一份复制品,放进输出范围中。

  如果你需要初始化一个容器的话,这个函数很有用。通过用两步完成:

  1)配置内存区块,足以包含范围内所有元素;

  2)使用uninitizlied_copy,在该内存区块上构造元素。

  c++标准还规定uninitialized_copy()具有”commit or rollback”功能。要么构造出所有元素,要么不构造任何东西,不能存在半构造状态。

  在uninitialized_copy()内调用了一个内部的实现函数__uninitialized_copy(),利用编译器的类型推导功能,萃取迭代器的指向对象的类型。来看代码:

template <class InputIterator, class ForwardIterator>
inline ForwardIterator
__uninitialized_copy_aux(InputIterator first, InputIterator last,
ForwardIterator result,
__true_type) {
return copy(first, last, result);
}

template <class InputIterator, class ForwardIterator>
ForwardIterator
__uninitialized_copy_aux(InputIterator first, InputIterator last,
ForwardIterator result,
__false_type) {
ForwardIterator cur = result;
__STL_TRY {
for ( ; first != last; ++first, ++cur)
construct(&*cur, *first);
return cur;
}
__STL_UNWIND(destroy(result, cur));
}

template <class InputIterator, class ForwardIterator, class T>
inline ForwardIterator
__uninitialized_copy(InputIterator first, InputIterator last,
ForwardIterator result, T*) {
typedef typename __type_traits<T>::is_POD_type is_POD;
return __uninitialized_copy_aux(first, last, result, is_POD());
}

template <class InputIterator, class ForwardIterator>
inline ForwardIterator
uninitialized_copy(InputIterator first, InputIterator last,
ForwardIterator result) {
return __uninitialized_copy(first, last, result, value_type(result));
}

inline char* uninitialized_copy(const char* first, const char* last,
char* result) {
memmove(result, first, last - first);
return result + (last - first);
}

inline wchar_t* uninitialized_copy(const wchar_t* first, const wchar_t* last,
wchar_t* result) {
memmove(result, first, sizeof(wchar_t) * (last - first));
return result + (last - first);
}


  这里的POD 意指 Plain Old Data,也就是标量型别(scalar types)或传统的 C struct 型别。POD 型别必然拥有 trivial ctor/dtor/copy/assignment函数。



  

  uninitialized_fill(),uninitialized_copy(),uninitialized_fill_n()差不多的,举一反三。 三者都具有”commit or rollback”语意。

  uninitialized_fill:

template <class ForwardIterator, class T>
inline void
__uninitialized_fill_aux(ForwardIterator first, ForwardIterator last,
const T& x, __true_type)
{
fill(first, last, x);
}

template <class ForwardIterator, class T>
void
__uninitialized_fill_aux(ForwardIterator first, ForwardIterator last,
const T& x, __false_type)
{
ForwardIterator cur = first;
__STL_TRY {
for ( ; cur != last; ++cur)
construct(&*cur, x);
}
__STL_UNWIND(destroy(first, cur));
}

template <class ForwardIterator, class T, class T1>
inline void __uninitialized_fill(ForwardIterator first, ForwardIterator last,
const T& x, T1*) {
typedef typename __type_traits<T1>::is_POD_type is_POD;
__uninitialized_fill_aux(first, last, x, is_POD());

}

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:

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());

}

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