copy进行复制操作,复制操作不外乎运用assignment operator或copy constructor,有些元素类型拥有trivial assignment operator可以使用内存复制如memmove或memcpy可节省大量时间。
copy算法使用的assignment operator,算法中使用函数重载、类型特性type traits、偏特性等特性技巧,目的加强效率。
copy算法完整脉络如下:
copy_barward实现技巧与copy类似,将[first, last)区间内元素以逆行方向复制到result-1为起点,方向逆行的区间上,执行的赋值操作*(result-1) = *(last -1), *(result-2) = *(last-2), …返回迭代器result-(last-first)。
copy_backward接受的迭代器必须是BidirectionalIterator。
namespace std _GLIBCXX_VISIBILITY(default)
{
template<bool, bool, typename> //模板类__copy_move<bool, bool, typename>
struct __copy_move
{
template<typename _II, typename _OI>
static _OI //静态成员函数
__copy_m(_II __first, _II __last, _OI __result) //拷贝迭代器[first, last)内容至result
{
for (; __first != __last; ++__result, (void)++__first) //执行[first, last)循环,result前向+1
*__result = *__first; //result赋值为[first, last)内容
return __result; //返回迭代器result
}
};
template<typename _Category> //模板类__copy_move<typename _Category>
struct __copy_move<true, false, _Category>
{
template<typename _II, typename _OI>
static _OI
__copy_m(_II __first, _II __last, _OI __result) //移动迭代器[first, last)内容至result
{
for (; __first != __last; ++__result, (void)++__first)
*__result = std::move(*__first); //将迭代器first中内容移动至result
return __result; //返回result,移动完成后[first, last)中内容为空
}
};
template<> //模板类特例化版本__copy_move<false, false, random_access_iterator_tag>
struct __copy_move<false, false, random_access_iterator_tag>
{
template<typename _II, typename _OI> //迭代器类型为随机访问迭代器
static _OI
__copy_m(_II __first, _II __last, _OI __result) //拷贝迭代器[first, last)内容至result
{
typedef typename iterator_traits<_II>::difference_type _Distance; //表迭代器之间距离的类型
for(_Distance __n = __last - __first; __n > 0; --__n) //执行距离循环
{
*__result = *__first;
++__first;
++__result;
}
return __result;
}
};
template<> //模板类特例化版本__copy_move<true, false, random_access_iterator_tag>
struct __copy_move<true, false, random_access_iterator_tag>
{
template<typename _II, typename _OI> //随机访问迭代器
static _OI
__copy_m(_II __first, _II __last, _OI __result) //移动迭代器[first, last)内容至result
{
typedef typename iterator_traits<_II>::difference_type _Distance; //表迭代器之间距离的类型
for(_Distance __n = __last - __first; __n > 0; --__n) //执行距离循环
{
*__result = std::move(*__first); //将迭代器first中内容移动至result
++__first;
++__result;
}
return __result; //返回result,移动完成后[first, last)中内容为空
}
};
template<bool _IsMove> //模板类__copy_move<bool _IsMove>
struct __copy_move<_IsMove, true, random_access_iterator_tag>
{
template<typename _Tp>
static _Tp*
__copy_m(const _Tp* __first, const _Tp* __last, _Tp* __result) //拷贝指针范围[first, last)内容至result
{
using __assignable = conditional<_IsMove,
is_move_assignable<_Tp>,
is_copy_assignable<_Tp>>;
static_assert( __assignable::type::value, "type is not assignable" );
const ptrdiff_t _Num = __last - __first; //表指针之间的距离
if (_Num)
__builtin_memmove(__result, __first, sizeof(_Tp) * _Num); //使用内建memmove函数实现拷贝
return __result + _Num;
}
};
template<bool _IsMove, typename _II, typename _OI> //模板类__copy_move_a<bool, typename, typename>
inline _OI
__copy_move_a(_II __first, _II __last, _OI __result)
{
typedef typename iterator_traits<_II>::value_type _ValueTypeI; //迭代器_II所指内容类型I
typedef typename iterator_traits<_OI>::value_type _ValueTypeO; //迭代器_OI所指内容类型O
typedef typename iterator_traits<_II>::iterator_category _Category; //迭代器_II类型
const bool __simple = (__is_trivial(_ValueTypeI) //__is_trivial判断类型I是否存在默认构造函数、拷贝构造函数、赋值操作、析构函数
&& __is_pointer<_II>::__value //判断类型I是否为指针
&& __is_pointer<_OI>::__value //判断类型O是否为指针
&& __are_same<_ValueTypeI, _ValueTypeO>::__value); //判断类型I和O是否为同一类型
//__simple为true时使用内建memmove函数完成拷贝操作,为false时执行循环根据_IsMove决定拷贝副本或移动元素
return std::__copy_move<_IsMove, __simple,
_Category>::__copy_m(__first, __last, __result);
}
//以下为辅助流迭代器内容,包括输入流和输出流
template<typename _CharT>
struct char_traits;
//写入流迭代器
template<typename _CharT, typename _Traits>
class istreambuf_iterator;
//输出流迭代器
template<typename _CharT, typename _Traits>
class ostreambuf_iterator;
//输出流迭代器拷贝
template<bool _IsMove, typename _CharT>
typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
ostreambuf_iterator<_CharT, char_traits<_CharT> > >::__type
__copy_move_a2(_CharT*, _CharT*,
ostreambuf_iterator<_CharT, char_traits<_CharT> >);
//输出流迭代器const拷贝
template<bool _IsMove, typename _CharT>
typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
ostreambuf_iterator<_CharT, char_traits<_CharT> > >::__type
__copy_move_a2(const _CharT*, const _CharT*,
ostreambuf_iterator<_CharT, char_traits<_CharT> >);
//写入流迭代器拷贝
template<bool _IsMove, typename _CharT>
typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
_CharT*>::__type
__copy_move_a2(istreambuf_iterator<_CharT, char_traits<_CharT> >,
istreambuf_iterator<_CharT, char_traits<_CharT> >, _CharT*);
template<bool _IsMove, typename _II, typename _OI> //模板函数__copy_move_a2<bool, typename, typename>
inline _OI
__copy_move_a2(_II __first, _II __last, _OI __result)
{
return _OI(std::__copy_move_a<_IsMove>(std::__niter_base(__first), //根据_IsMove决定调用__copy_move_a2<true>或<false>版本完成拷贝
std::__niter_base(__last), //__niter_base移除__normal_iterator包装器
std::__niter_base(__result))); //__niter_base返回指针类型时需调用相应指针类型版本
}
template<typename _II, typename _OI> //模板函数copy,拷贝序列元素到另一序列
inline _OI
copy(_II __first, _II __last, _OI __result)
{
__glibcxx_function_requires(_InputIteratorConcept<_II>)
__glibcxx_function_requires(_OutputIteratorConcept<_OI,
typename iterator_traits<_II>::value_type>) //迭代器_II所指内容类型
__glibcxx_requires_valid_range(__first, __last);
return (std::__copy_move_a2<__is_move_iterator<_II>::__value> //__is_move_iterator判断迭代器是否为移动迭代器
(std::__miter_base(__first), std::__miter_base(__last), //__miter_base移除move_iterator包装器
__result));
//调用__copy_move_a2<true>或<false>版本完成拷贝,模板参数赋值_IsMove
//__copy_move_a2包括流迭代器,根据传入模板参数true或false调用__copy_move_a<_IsMove>
//__copy_move_a中根据__simple决定使用内建memmove函数或循环赋值方式完成拷贝操作
//_IsMove决定拷贝操作是拷贝副本还是移动元素
//首先移除移动迭代器包装,再移除正常迭代器包装,__copy_move定义了指针类型和自定义数据类型版本
}
template<typename _II, typename _OI> //模板函数move,移动序列元素到另一序列
inline _OI
move(_II __first, _II __last, _OI __result)
{
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_II>)
__glibcxx_function_requires(_OutputIteratorConcept<_OI,
typename iterator_traits<_II>::value_type>) //迭代器_II所指内容类型
__glibcxx_requires_valid_range(__first, __last);
//直接调用__copy_move_a2<true>完成移动操作
return std::__copy_move_a2<true>(std::__miter_base(__first), //移除move_iterator包装器
std::__miter_base(__last), __result);
}
#define _GLIBCXX_MOVE3(_Tp, _Up, _Vp) std::move(_Tp, _Up, _Vp)
template<bool, bool, typename> //模板类__copy_move_backward<bool, bool, typename>
struct __copy_move_backward //拷贝序列元素至另一序列,拷贝方式为反向前进
{
template<typename _BI1, typename _BI2>
static _BI2
__copy_move_b(_BI1 __first, _BI1 __last, _BI2 __result)
{
while (__first != __last)
*--__result = *--__last; //迭代器反向-1
return __result;
}
};
template<typename _Category> //模板类__copy_move_backward<_Category>
struct __copy_move_backward<true, false, _Category> //移动序列元素至另一序列,反向前进移动
{
template<typename _BI1, typename _BI2>
static _BI2
__copy_move_b(_BI1 __first, _BI1 __last, _BI2 __result)
{
while (__first != __last)
*--__result = std::move(*--__last); //反向-1移动元素
return __result;
}
};
template<> //模板类特例化版本__copy_move_backward<false, false, random_access_iterator_tag>
struct __copy_move_backward<false, false, random_access_iterator_tag>
{
template<typename _BI1, typename _BI2>
static _BI2
__copy_move_b(_BI1 __first, _BI1 __last, _BI2 __result)
{
typename iterator_traits<_BI1>::difference_type __n; //表迭代器之间距离的类型
for (__n = __last - __first; __n > 0; --__n)
*--__result = *--__last; //拷贝元素副本
return __result;
}
};
template<> //模板类特例化版本__copy_move_backward<true, false, random_access_iterator_tag>
struct __copy_move_backward<true, false, random_access_iterator_tag>
{
template<typename _BI1, typename _BI2>
static _BI2
__copy_move_b(_BI1 __first, _BI1 __last, _BI2 __result)
{
typename iterator_traits<_BI1>::difference_type __n; //表迭代器之间距离的类型
for (__n = __last - __first; __n > 0; --__n)
*--__result = std::move(*--__last); //移动元素
return __result;
}
};
template<bool _IsMove> //模板类__copy_move_backward<bool _IsMove>
struct __copy_move_backward<_IsMove, true, random_access_iterator_tag>
{
template<typename _Tp>
static _Tp*
__copy_move_b(const _Tp* __first, const _Tp* __last, _Tp* __result)
{
using __assignable = conditional<_IsMove,
is_move_assignable<_Tp>,
is_copy_assignable<_Tp>>;
static_assert( __assignable::type::value, "type is not assignable" );
const ptrdiff_t _Num = __last - __first;
if (_Num)
__builtin_memmove(__result - _Num, __first, sizeof(_Tp) * _Num); //使用内建memmove移动元素
return __result - _Num;
}
};
template<bool _IsMove, typename _BI1, typename _BI2> //模板函数__copy_move_backward_a
inline _BI2
__copy_move_backward_a(_BI1 __first, _BI1 __last, _BI2 __result)
{
typedef typename iterator_traits<_BI1>::value_type _ValueType1;
typedef typename iterator_traits<_BI2>::value_type _ValueType2;
typedef typename iterator_traits<_BI1>::iterator_category _Category;
const bool __simple = (__is_trivial(_ValueType1)
&& __is_pointer<_BI1>::__value
&& __is_pointer<_BI2>::__value
&& __are_same<_ValueType1, _ValueType2>::__value);
//__simple为true时使用内建memmove函数拷贝元素,为false时执行循环根据_IsMove决定拷贝副本或移动元素
return std::__copy_move_backward<_IsMove, __simple,
_Category>::__copy_move_b(__first,
__last,
__result);
}
template<bool _IsMove, typename _BI1, typename _BI2> //模板函数__copy_move_backward_a2
inline _BI2
__copy_move_backward_a2(_BI1 __first, _BI1 __last, _BI2 __result)
{
return _BI2(std::__copy_move_backward_a<_IsMove>
(std::__niter_base(__first), std::__niter_base(__last),
std::__niter_base(__result)));
}
template<typename _BI1, typename _BI2> //模板函数copy_backward,调用与copy相似
inline _BI2
copy_backward(_BI1 __first, _BI1 __last, _BI2 __result)
{
// concept requirements
__glibcxx_function_requires(_BidirectionalIteratorConcept<_BI1>)
__glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept<_BI2>)
__glibcxx_function_requires(_ConvertibleConcept<
typename iterator_traits<_BI1>::value_type,
typename iterator_traits<_BI2>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
return (std::__copy_move_backward_a2<__is_move_iterator<_BI1>::__value>
(std::__miter_base(__first), std::__miter_base(__last),
__result));
}
template<typename _BI1, typename _BI2> //模板函数move_backward,调用与move相似
inline _BI2
move_backward(_BI1 __first, _BI1 __last, _BI2 __result)
{
// concept requirements
__glibcxx_function_requires(_BidirectionalIteratorConcept<_BI1>)
__glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept<_BI2>)
__glibcxx_function_requires(_ConvertibleConcept<
typename iterator_traits<_BI1>::value_type,
typename iterator_traits<_BI2>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
return std::__copy_move_backward_a2<true>(std::__miter_base(__first),
std::__miter_base(__last),
__result);
}
#define _GLIBCXX_MOVE_BACKWARD3(_Tp, _Up, _Vp) std::move_backward(_Tp, _Up, _Vp)
} // namespace std