一、内存基本处理工具
STL定义有五个全局函数,作用于未初始化空间上。前两个函数是用于构造的 construct() 和用于析构的 destroy(),另三个函数 uninitialized_copy(),uninitialized_fill(),uninitialized_fill_n(),分别对应于高层次函数 copy()、fill()、fill_n() —— 这些都是STL算法。SGI把它们都定义于<stl_uninitialized>。
1. uninitialized_copy
// 如果 copy construction 等同于 assignment,而且 destructor 是 trivial,以下就有效
template <class InputIterator, class ForwardIterator>
inline ForwardIterator
__uninitialized_copy_aux(InputIterator first, InputIterator last,
ForwardIterator result,
__true_type) {
return copy(first, last, result); // 调用 STL 算法 copy()
}
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));
}
// POD 意指 Plain Old Data,也就是标量型别(scalar types)或传统的 C struct 型别。
// POD 型别必然拥有 trivial ctor/dtor/copy/assignment函数。
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());
// 利用 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));
// 利用 value_type() 取出 result 的 value type
}
// 针对 char * 和 wchar_t * 两种型别,可以采用最具效率的做法 memmove(直接
// 移动内存内容)来执行复制行为
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);
}
uninitialized_copy() 使我们能够将内存的配置与对象的构造行为分离开来。如果作为输出目的地的 [result, result + (last - first)) 范围内的每一个迭代器都指向未初始化区域,则 uninitialized_copy() 会使用 copy constructor,给身为输入来源之 [first, last) 范围内的每一个对象产生一份复制品,放进输出范围中。
C++标准规格书要求 uninitialized_copy() 具有 “commit or rollback” 语意,意思是要么“构造出所有必要元素”,要么(当有任何一个 copy constructor失败时)“不构造任何东西”。
2. 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() 也能够使我们将内存配置与对象的构造行为分离开来。如果[first, last) 范围内的每个迭代器都指向未初始话的内存,那么uninitialized_fill() 会在该范围内产生 x(上式第三个参数)的复制品。
与 uninitialized_copy() 一样,uninitialized_fill() 必须具备 “commit or rollback” 语意。
3. 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));
}
uninitialized_fill_n() 能够使我们将内存配置与对象构造行为分离开来。它会为指定范围内的所有元素设定相同的初值。如果 [ first, first + n) 范围内的每一个迭代器都指向未初始化的内存,那么 uninitialized_fill_n() 会调用 copy constructor,在该范围内产生 x(上式第三个参数)的复制品。
uninitialized_fill_n() 也具有 "commit or rollback"语意。